1e0934bee3a4f40731169bc42b15a39ce39978175Jim Grosbach//===-- RuntimeDyldELF.cpp - Run-time dynamic linker for MC-JIT -*- C++ -*-===//
2a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky//
3a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky//                     The LLVM Compiler Infrastructure
4a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky//
5a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky// This file is distributed under the University of Illinois Open Source
6a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky// License. See LICENSE.TXT for details.
7a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky//
8a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky//===----------------------------------------------------------------------===//
9a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky//
10a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky// Implementation of ELF support for the MC-JIT runtime dynamic linker.
11a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky//
12a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky//===----------------------------------------------------------------------===//
13a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky
143f23cef24fc9200def464bd4bce820678b5715deAndrew Kaylor#include "RuntimeDyldELF.h"
150c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar#include "RuntimeDyldCheckerImpl.h"
16d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm/ADT/IntervalMap.h"
17a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky#include "llvm/ADT/STLExtras.h"
18d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm/ADT/StringRef.h"
19a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky#include "llvm/ADT/Triple.h"
20ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines#include "llvm/MC/MCStreamer.h"
21081a1941b595f6294e4ce678fd61ef56a2ceb51eMichael J. Spencer#include "llvm/Object/ELFObjectFile.h"
22d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm/Object/ObjectFile.h"
23d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm/Support/ELF.h"
2437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines#include "llvm/Support/Endian.h"
2536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#include "llvm/Support/MemoryBuffer.h"
26ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines#include "llvm/Support/TargetRegistry.h"
2736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
28a66a18505e07a4e72d6fa7e85663937a257577f3Eli Benderskyusing namespace llvm;
29a66a18505e07a4e72d6fa7e85663937a257577f3Eli Benderskyusing namespace llvm::object;
30a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky
31dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines#define DEBUG_TYPE "dyld"
32dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
33ebe69fe11e48d322045d5949c83283927a0d790bStephen Hinesnamespace {
34ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines
3536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinestemplate <class ELFT> class DyldELFObject : public ELFObjectFile<ELFT> {
3643239078adac6f32315cadbef9709f2f0f499707Rafael Espindola  LLVM_ELF_IMPORT_TYPES_ELFT(ELFT)
37689ff9c00f4f3dcf3491778bcdbda79e19e2285dPreston Gurd
38ac97f5ce486d1ca2967607028eacddd860aaddd0Michael J. Spencer  typedef Elf_Shdr_Impl<ELFT> Elf_Shdr;
39ac97f5ce486d1ca2967607028eacddd860aaddd0Michael J. Spencer  typedef Elf_Sym_Impl<ELFT> Elf_Sym;
4036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  typedef Elf_Rel_Impl<ELFT, false> Elf_Rel;
4136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  typedef Elf_Rel_Impl<ELFT, true> Elf_Rela;
42689ff9c00f4f3dcf3491778bcdbda79e19e2285dPreston Gurd
43ac97f5ce486d1ca2967607028eacddd860aaddd0Michael J. Spencer  typedef Elf_Ehdr_Impl<ELFT> Elf_Ehdr;
44689ff9c00f4f3dcf3491778bcdbda79e19e2285dPreston Gurd
4536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  typedef typename ELFDataTypeTypedefHelper<ELFT>::value_type addr_type;
46689ff9c00f4f3dcf3491778bcdbda79e19e2285dPreston Gurd
47689ff9c00f4f3dcf3491778bcdbda79e19e2285dPreston Gurdpublic:
4837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  DyldELFObject(MemoryBufferRef Wrapper, std::error_code &ec);
49689ff9c00f4f3dcf3491778bcdbda79e19e2285dPreston Gurd
50689ff9c00f4f3dcf3491778bcdbda79e19e2285dPreston Gurd  void updateSectionAddress(const SectionRef &Sec, uint64_t Addr);
51ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines
52ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  void updateSymbolAddress(const SymbolRef &SymRef, uint64_t Addr);
53689ff9c00f4f3dcf3491778bcdbda79e19e2285dPreston Gurd
542e319870f17a090e47540e2a821eac33c495bf59Andrew Kaylor  // Methods for type inquiry through isa, cast and dyn_cast
55689ff9c00f4f3dcf3491778bcdbda79e19e2285dPreston Gurd  static inline bool classof(const Binary *v) {
5636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return (isa<ELFObjectFile<ELFT>>(v) &&
5736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines            classof(cast<ELFObjectFile<ELFT>>(v)));
58689ff9c00f4f3dcf3491778bcdbda79e19e2285dPreston Gurd  }
5936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  static inline bool classof(const ELFObjectFile<ELFT> *v) {
60689ff9c00f4f3dcf3491778bcdbda79e19e2285dPreston Gurd    return v->isDyldType();
61689ff9c00f4f3dcf3491778bcdbda79e19e2285dPreston Gurd  }
62ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines};
6336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
6436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
65689ff9c00f4f3dcf3491778bcdbda79e19e2285dPreston Gurd
663f23cef24fc9200def464bd4bce820678b5715deAndrew Kaylor// The MemoryBuffer passed into this constructor is just a wrapper around the
673f23cef24fc9200def464bd4bce820678b5715deAndrew Kaylor// actual memory.  Ultimately, the Binary parent class will take ownership of
683f23cef24fc9200def464bd4bce820678b5715deAndrew Kaylor// this MemoryBuffer object but not the underlying memory.
6936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinestemplate <class ELFT>
7037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen HinesDyldELFObject<ELFT>::DyldELFObject(MemoryBufferRef Wrapper, std::error_code &EC)
7137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    : ELFObjectFile<ELFT>(Wrapper, EC) {
72689ff9c00f4f3dcf3491778bcdbda79e19e2285dPreston Gurd  this->isDyldELFObject = true;
73689ff9c00f4f3dcf3491778bcdbda79e19e2285dPreston Gurd}
74689ff9c00f4f3dcf3491778bcdbda79e19e2285dPreston Gurd
7536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinestemplate <class ELFT>
76ac97f5ce486d1ca2967607028eacddd860aaddd0Michael J. Spencervoid DyldELFObject<ELFT>::updateSectionAddress(const SectionRef &Sec,
77ac97f5ce486d1ca2967607028eacddd860aaddd0Michael J. Spencer                                               uint64_t Addr) {
78689ff9c00f4f3dcf3491778bcdbda79e19e2285dPreston Gurd  DataRefImpl ShdrRef = Sec.getRawDataRefImpl();
7936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  Elf_Shdr *shdr =
8036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      const_cast<Elf_Shdr *>(reinterpret_cast<const Elf_Shdr *>(ShdrRef.p));
81689ff9c00f4f3dcf3491778bcdbda79e19e2285dPreston Gurd
82689ff9c00f4f3dcf3491778bcdbda79e19e2285dPreston Gurd  // This assumes the address passed in matches the target address bitness
83689ff9c00f4f3dcf3491778bcdbda79e19e2285dPreston Gurd  // The template-based type cast handles everything else.
84689ff9c00f4f3dcf3491778bcdbda79e19e2285dPreston Gurd  shdr->sh_addr = static_cast<addr_type>(Addr);
85689ff9c00f4f3dcf3491778bcdbda79e19e2285dPreston Gurd}
86689ff9c00f4f3dcf3491778bcdbda79e19e2285dPreston Gurd
8736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinestemplate <class ELFT>
88ac97f5ce486d1ca2967607028eacddd860aaddd0Michael J. Spencervoid DyldELFObject<ELFT>::updateSymbolAddress(const SymbolRef &SymRef,
89ac97f5ce486d1ca2967607028eacddd860aaddd0Michael J. Spencer                                              uint64_t Addr) {
90689ff9c00f4f3dcf3491778bcdbda79e19e2285dPreston Gurd
9136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  Elf_Sym *sym = const_cast<Elf_Sym *>(
9236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      ELFObjectFile<ELFT>::getSymbol(SymRef.getRawDataRefImpl()));
93689ff9c00f4f3dcf3491778bcdbda79e19e2285dPreston Gurd
94689ff9c00f4f3dcf3491778bcdbda79e19e2285dPreston Gurd  // This assumes the address passed in matches the target address bitness
95689ff9c00f4f3dcf3491778bcdbda79e19e2285dPreston Gurd  // The template-based type cast handles everything else.
96689ff9c00f4f3dcf3491778bcdbda79e19e2285dPreston Gurd  sym->st_value = static_cast<addr_type>(Addr);
97689ff9c00f4f3dcf3491778bcdbda79e19e2285dPreston Gurd}
98689ff9c00f4f3dcf3491778bcdbda79e19e2285dPreston Gurd
99f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainarclass LoadedELFObjectInfo final
1006948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    : public RuntimeDyld::LoadedObjectInfoHelper<LoadedELFObjectInfo> {
101ebe69fe11e48d322045d5949c83283927a0d790bStephen Hinespublic:
102f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  LoadedELFObjectInfo(RuntimeDyldImpl &RTDyld, ObjSectionToIDMap ObjSecToIDMap)
103f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      : LoadedObjectInfoHelper(RTDyld, std::move(ObjSecToIDMap)) {}
104ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines
105ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  OwningBinary<ObjectFile>
106ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  getObjectForDebug(const ObjectFile &Obj) const override;
107ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines};
108ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines
109ebe69fe11e48d322045d5949c83283927a0d790bStephen Hinestemplate <typename ELFT>
110ebe69fe11e48d322045d5949c83283927a0d790bStephen Hinesstd::unique_ptr<DyldELFObject<ELFT>>
111ebe69fe11e48d322045d5949c83283927a0d790bStephen HinescreateRTDyldELFObject(MemoryBufferRef Buffer,
112f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar                      const ObjectFile &SourceObject,
113ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines                      const LoadedELFObjectInfo &L,
114ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines                      std::error_code &ec) {
115ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  typedef typename ELFFile<ELFT>::Elf_Shdr Elf_Shdr;
116ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  typedef typename ELFDataTypeTypedefHelper<ELFT>::value_type addr_type;
117ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines
118ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  std::unique_ptr<DyldELFObject<ELFT>> Obj =
119ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    llvm::make_unique<DyldELFObject<ELFT>>(Buffer, ec);
120ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines
121ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  // Iterate over all sections in the object.
122f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  auto SI = SourceObject.section_begin();
123ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  for (const auto &Sec : Obj->sections()) {
124ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    StringRef SectionName;
125ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    Sec.getName(SectionName);
126ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    if (SectionName != "") {
127ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      DataRefImpl ShdrRef = Sec.getRawDataRefImpl();
128ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      Elf_Shdr *shdr = const_cast<Elf_Shdr *>(
129ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines          reinterpret_cast<const Elf_Shdr *>(ShdrRef.p));
130ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines
131f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      if (uint64_t SecLoadAddr = L.getSectionLoadAddress(*SI)) {
132ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines        // This assumes that the address passed in matches the target address
133ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines        // bitness. The template-based type cast handles everything else.
134ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines        shdr->sh_addr = static_cast<addr_type>(SecLoadAddr);
135ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      }
136ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    }
137f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    ++SI;
138ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  }
139ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines
140ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  return Obj;
141ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines}
142ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines
143ebe69fe11e48d322045d5949c83283927a0d790bStephen HinesOwningBinary<ObjectFile> createELFDebugObject(const ObjectFile &Obj,
144ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines                                              const LoadedELFObjectInfo &L) {
145ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  assert(Obj.isELF() && "Not an ELF object file.");
146ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines
147ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  std::unique_ptr<MemoryBuffer> Buffer =
148ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    MemoryBuffer::getMemBufferCopy(Obj.getData(), Obj.getFileName());
149ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines
150ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  std::error_code ec;
151ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines
152ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  std::unique_ptr<ObjectFile> DebugObj;
153ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  if (Obj.getBytesInAddress() == 4 && Obj.isLittleEndian()) {
1546948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    typedef ELFType<support::little, false> ELF32LE;
155f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    DebugObj = createRTDyldELFObject<ELF32LE>(Buffer->getMemBufferRef(), Obj, L,
156f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar                                              ec);
157ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  } else if (Obj.getBytesInAddress() == 4 && !Obj.isLittleEndian()) {
1586948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    typedef ELFType<support::big, false> ELF32BE;
159f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    DebugObj = createRTDyldELFObject<ELF32BE>(Buffer->getMemBufferRef(), Obj, L,
160f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar                                              ec);
161ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  } else if (Obj.getBytesInAddress() == 8 && !Obj.isLittleEndian()) {
1626948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    typedef ELFType<support::big, true> ELF64BE;
163f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    DebugObj = createRTDyldELFObject<ELF64BE>(Buffer->getMemBufferRef(), Obj, L,
164f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar                                              ec);
165ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  } else if (Obj.getBytesInAddress() == 8 && Obj.isLittleEndian()) {
1666948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    typedef ELFType<support::little, true> ELF64LE;
167f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    DebugObj = createRTDyldELFObject<ELF64LE>(Buffer->getMemBufferRef(), Obj, L,
168f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar                                              ec);
169ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  } else
170ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    llvm_unreachable("Unexpected ELF format");
171ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines
172ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  assert(!ec && "Could not construct copy ELF object file");
173ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines
174ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  return OwningBinary<ObjectFile>(std::move(DebugObj), std::move(Buffer));
175ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines}
176ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines
177ebe69fe11e48d322045d5949c83283927a0d790bStephen HinesOwningBinary<ObjectFile>
178ebe69fe11e48d322045d5949c83283927a0d790bStephen HinesLoadedELFObjectInfo::getObjectForDebug(const ObjectFile &Obj) const {
179ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  return createELFDebugObject(Obj, *this);
180ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines}
181ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines
182f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar} // anonymous namespace
183689ff9c00f4f3dcf3491778bcdbda79e19e2285dPreston Gurd
184a66a18505e07a4e72d6fa7e85663937a257577f3Eli Benderskynamespace llvm {
185a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky
1860c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga NainarRuntimeDyldELF::RuntimeDyldELF(RuntimeDyld::MemoryManager &MemMgr,
1870c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar                               RuntimeDyld::SymbolResolver &Resolver)
1880c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    : RuntimeDyldImpl(MemMgr, Resolver), GOTSectionID(0), CurrentGOTIndex(0) {}
189ebe69fe11e48d322045d5949c83283927a0d790bStephen HinesRuntimeDyldELF::~RuntimeDyldELF() {}
190ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines
191528f6d787b1a847e61eb2f1114559f423fdeb68cAndrew Kaylorvoid RuntimeDyldELF::registerEHFrames() {
192528f6d787b1a847e61eb2f1114559f423fdeb68cAndrew Kaylor  for (int i = 0, e = UnregisteredEHFrameSections.size(); i != e; ++i) {
193528f6d787b1a847e61eb2f1114559f423fdeb68cAndrew Kaylor    SID EHFrameSID = UnregisteredEHFrameSections[i];
194f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    uint8_t *EHFrameAddr = Sections[EHFrameSID].getAddress();
195f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    uint64_t EHFrameLoadAddr = Sections[EHFrameSID].getLoadAddress();
196f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    size_t EHFrameSize = Sections[EHFrameSID].getSize();
1970c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    MemMgr.registerEHFrames(EHFrameAddr, EHFrameLoadAddr, EHFrameSize);
19843507d026bef31100cb0c35614bcf419029a265bAndrew Kaylor    RegisteredEHFrameSections.push_back(EHFrameSID);
199a2e40fbd624916c187a95ed76939ca7f02ed3e53Rafael Espindola  }
200528f6d787b1a847e61eb2f1114559f423fdeb68cAndrew Kaylor  UnregisteredEHFrameSections.clear();
201a2e40fbd624916c187a95ed76939ca7f02ed3e53Rafael Espindola}
202a2e40fbd624916c187a95ed76939ca7f02ed3e53Rafael Espindola
20343507d026bef31100cb0c35614bcf419029a265bAndrew Kaylorvoid RuntimeDyldELF::deregisterEHFrames() {
20443507d026bef31100cb0c35614bcf419029a265bAndrew Kaylor  for (int i = 0, e = RegisteredEHFrameSections.size(); i != e; ++i) {
20543507d026bef31100cb0c35614bcf419029a265bAndrew Kaylor    SID EHFrameSID = RegisteredEHFrameSections[i];
206f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    uint8_t *EHFrameAddr = Sections[EHFrameSID].getAddress();
207f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    uint64_t EHFrameLoadAddr = Sections[EHFrameSID].getLoadAddress();
208f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    size_t EHFrameSize = Sections[EHFrameSID].getSize();
2090c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    MemMgr.deregisterEHFrames(EHFrameAddr, EHFrameLoadAddr, EHFrameSize);
21043507d026bef31100cb0c35614bcf419029a265bAndrew Kaylor  }
21143507d026bef31100cb0c35614bcf419029a265bAndrew Kaylor  RegisteredEHFrameSections.clear();
21243507d026bef31100cb0c35614bcf419029a265bAndrew Kaylor}
21343507d026bef31100cb0c35614bcf419029a265bAndrew Kaylor
214ebe69fe11e48d322045d5949c83283927a0d790bStephen Hinesstd::unique_ptr<RuntimeDyld::LoadedObjectInfo>
215ebe69fe11e48d322045d5949c83283927a0d790bStephen HinesRuntimeDyldELF::loadObject(const object::ObjectFile &O) {
216de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  if (auto ObjSectionToIDOrErr = loadObjectImpl(O))
217de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    return llvm::make_unique<LoadedELFObjectInfo>(*this, *ObjSectionToIDOrErr);
218de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  else {
219de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    HasError = true;
220de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    raw_string_ostream ErrStream(ErrorStr);
221de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    logAllUnhandledErrors(ObjSectionToIDOrErr.takeError(), ErrStream, "");
222de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    return nullptr;
223de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  }
22436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines}
22536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
226a307a1cf859f4a523951ac887d094039547adeb5Andrew Kaylorvoid RuntimeDyldELF::resolveX86_64Relocation(const SectionEntry &Section,
22736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                                             uint64_t Offset, uint64_t Value,
22836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                                             uint32_t Type, int64_t Addend,
229ff9fa05905be716435460b5f6d32689041bf895bAndrew Kaylor                                             uint64_t SymOffset) {
2300e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev  switch (Type) {
2310e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev  default:
2320e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev    llvm_unreachable("Relocation type not implemented yet!");
23336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    break;
234a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky  case ELF::R_X86_64_64: {
235f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    support::ulittle64_t::ref(Section.getAddressWithOffset(Offset)) =
236f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar        Value + Addend;
23736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    DEBUG(dbgs() << "Writing " << format("%p", (Value + Addend)) << " at "
238f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar                 << format("%p\n", Section.getAddressWithOffset(Offset)));
239a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky    break;
240a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky  }
241a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky  case ELF::R_X86_64_32:
242a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky  case ELF::R_X86_64_32S: {
2430e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev    Value += Addend;
244d83a547d671a424294df2103c71801127e55db0fAndrew Kaylor    assert((Type == ELF::R_X86_64_32 && (Value <= UINT32_MAX)) ||
2454d9c5397b4a3be747bdb73f1d24c3fdbaaf438feMichael J. Spencer           (Type == ELF::R_X86_64_32S &&
24636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines            ((int64_t)Value <= INT32_MAX && (int64_t)Value >= INT32_MIN)));
247a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky    uint32_t TruncatedAddr = (Value & 0xFFFFFFFF);
248f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    support::ulittle32_t::ref(Section.getAddressWithOffset(Offset)) =
249f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar        TruncatedAddr;
25036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    DEBUG(dbgs() << "Writing " << format("%p", TruncatedAddr) << " at "
251f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar                 << format("%p\n", Section.getAddressWithOffset(Offset)));
252f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    break;
253f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  }
254f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  case ELF::R_X86_64_PC8: {
255f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    uint64_t FinalAddress = Section.getLoadAddressWithOffset(Offset);
256f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    int64_t RealOffset = Value + Addend - FinalAddress;
257f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    assert(isInt<8>(RealOffset));
258f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    int8_t TruncOffset = (RealOffset & 0xFF);
259f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    Section.getAddress()[Offset] = TruncOffset;
260a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky    break;
261a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky  }
262a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky  case ELF::R_X86_64_PC32: {
263f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    uint64_t FinalAddress = Section.getLoadAddressWithOffset(Offset);
2640c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    int64_t RealOffset = Value + Addend - FinalAddress;
2656948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    assert(isInt<32>(RealOffset));
2660e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev    int32_t TruncOffset = (RealOffset & 0xFFFFFFFF);
267f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    support::ulittle32_t::ref(Section.getAddressWithOffset(Offset)) =
268f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar        TruncOffset;
269a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky    break;
270a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky  }
271ff9fa05905be716435460b5f6d32689041bf895bAndrew Kaylor  case ELF::R_X86_64_PC64: {
272f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    uint64_t FinalAddress = Section.getLoadAddressWithOffset(Offset);
2730c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    int64_t RealOffset = Value + Addend - FinalAddress;
274f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    support::ulittle64_t::ref(Section.getAddressWithOffset(Offset)) =
275f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar        RealOffset;
276ff9fa05905be716435460b5f6d32689041bf895bAndrew Kaylor    break;
277ff9fa05905be716435460b5f6d32689041bf895bAndrew Kaylor  }
278a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky  }
279a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky}
280a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky
281a307a1cf859f4a523951ac887d094039547adeb5Andrew Kaylorvoid RuntimeDyldELF::resolveX86Relocation(const SectionEntry &Section,
28236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                                          uint64_t Offset, uint32_t Value,
28336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                                          uint32_t Type, int32_t Addend) {
2840e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev  switch (Type) {
285a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky  case ELF::R_386_32: {
286f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    support::ulittle32_t::ref(Section.getAddressWithOffset(Offset)) =
287f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar        Value + Addend;
288a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky    break;
289a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky  }
290a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky  case ELF::R_386_PC32: {
291f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    uint32_t FinalAddress =
292f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar        Section.getLoadAddressWithOffset(Offset) & 0xFFFFFFFF;
2936948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    uint32_t RealOffset = Value + Addend - FinalAddress;
294f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    support::ulittle32_t::ref(Section.getAddressWithOffset(Offset)) =
295f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar        RealOffset;
296a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky    break;
29736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  }
29836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  default:
29936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    // There are other relocation types, but it appears these are the
30036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    // only ones currently used by the LLVM ELF object writer
30136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    llvm_unreachable("Relocation type not implemented yet!");
30236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    break;
303a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky  }
304a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky}
305a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky
30685829bb98a998cff8f364c12d172da948ca225f4Tim Northovervoid RuntimeDyldELF::resolveAArch64Relocation(const SectionEntry &Section,
30736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                                              uint64_t Offset, uint64_t Value,
30836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                                              uint32_t Type, int64_t Addend) {
309f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  uint32_t *TargetPtr =
310f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      reinterpret_cast<uint32_t *>(Section.getAddressWithOffset(Offset));
311f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  uint64_t FinalAddress = Section.getLoadAddressWithOffset(Offset);
31285829bb98a998cff8f364c12d172da948ca225f4Tim Northover
31385829bb98a998cff8f364c12d172da948ca225f4Tim Northover  DEBUG(dbgs() << "resolveAArch64Relocation, LocalAddress: 0x"
314f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar               << format("%llx", Section.getAddressWithOffset(Offset))
31536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines               << " FinalAddress: 0x" << format("%llx", FinalAddress)
31636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines               << " Value: 0x" << format("%llx", Value) << " Type: 0x"
31736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines               << format("%x", Type) << " Addend: 0x" << format("%llx", Addend)
31885829bb98a998cff8f364c12d172da948ca225f4Tim Northover               << "\n");
31985829bb98a998cff8f364c12d172da948ca225f4Tim Northover
32085829bb98a998cff8f364c12d172da948ca225f4Tim Northover  switch (Type) {
32185829bb98a998cff8f364c12d172da948ca225f4Tim Northover  default:
32285829bb98a998cff8f364c12d172da948ca225f4Tim Northover    llvm_unreachable("Relocation type not implemented yet!");
32385829bb98a998cff8f364c12d172da948ca225f4Tim Northover    break;
324d52eaae157e661f280d0a71aabc060602ffc4424Tim Northover  case ELF::R_AARCH64_ABS64: {
32536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    uint64_t *TargetPtr =
326f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar        reinterpret_cast<uint64_t *>(Section.getAddressWithOffset(Offset));
327d52eaae157e661f280d0a71aabc060602ffc4424Tim Northover    *TargetPtr = Value + Addend;
328d52eaae157e661f280d0a71aabc060602ffc4424Tim Northover    break;
329d52eaae157e661f280d0a71aabc060602ffc4424Tim Northover  }
330675b9e9f3d567bdf1a31ce9d9ce2451ae09dc9faTim Northover  case ELF::R_AARCH64_PREL32: {
33185829bb98a998cff8f364c12d172da948ca225f4Tim Northover    uint64_t Result = Value + Addend - FinalAddress;
332081a1941b595f6294e4ce678fd61ef56a2ceb51eMichael J. Spencer    assert(static_cast<int64_t>(Result) >= INT32_MIN &&
33385829bb98a998cff8f364c12d172da948ca225f4Tim Northover           static_cast<int64_t>(Result) <= UINT32_MAX);
33485829bb98a998cff8f364c12d172da948ca225f4Tim Northover    *TargetPtr = static_cast<uint32_t>(Result & 0xffffffffU);
33585829bb98a998cff8f364c12d172da948ca225f4Tim Northover    break;
33685829bb98a998cff8f364c12d172da948ca225f4Tim Northover  }
3374a9b6b798d5ea335f5f29d278db83b830ae4a564Tim Northover  case ELF::R_AARCH64_CALL26: // fallthrough
3384a9b6b798d5ea335f5f29d278db83b830ae4a564Tim Northover  case ELF::R_AARCH64_JUMP26: {
3394a9b6b798d5ea335f5f29d278db83b830ae4a564Tim Northover    // Operation: S+A-P. Set Call or B immediate value to bits fff_fffc of the
3404a9b6b798d5ea335f5f29d278db83b830ae4a564Tim Northover    // calculation.
3414a9b6b798d5ea335f5f29d278db83b830ae4a564Tim Northover    uint64_t BranchImm = Value + Addend - FinalAddress;
3424a9b6b798d5ea335f5f29d278db83b830ae4a564Tim Northover
3434a9b6b798d5ea335f5f29d278db83b830ae4a564Tim Northover    // "Check that -2^27 <= result < 2^27".
3446948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    assert(isInt<28>(BranchImm));
345675b9e9f3d567bdf1a31ce9d9ce2451ae09dc9faTim Northover
346675b9e9f3d567bdf1a31ce9d9ce2451ae09dc9faTim Northover    // AArch64 code is emitted with .rela relocations. The data already in any
347675b9e9f3d567bdf1a31ce9d9ce2451ae09dc9faTim Northover    // bits affected by the relocation on entry is garbage.
348675b9e9f3d567bdf1a31ce9d9ce2451ae09dc9faTim Northover    *TargetPtr &= 0xfc000000U;
3494a9b6b798d5ea335f5f29d278db83b830ae4a564Tim Northover    // Immediate goes in bits 25:0 of B and BL.
3504a9b6b798d5ea335f5f29d278db83b830ae4a564Tim Northover    *TargetPtr |= static_cast<uint32_t>(BranchImm & 0xffffffcU) >> 2;
3514a9b6b798d5ea335f5f29d278db83b830ae4a564Tim Northover    break;
3524a9b6b798d5ea335f5f29d278db83b830ae4a564Tim Northover  }
353654c2d6b7a9274fc281c30c0e91419aadb6dc78aTim Northover  case ELF::R_AARCH64_MOVW_UABS_G3: {
354654c2d6b7a9274fc281c30c0e91419aadb6dc78aTim Northover    uint64_t Result = Value + Addend;
355675b9e9f3d567bdf1a31ce9d9ce2451ae09dc9faTim Northover
356675b9e9f3d567bdf1a31ce9d9ce2451ae09dc9faTim Northover    // AArch64 code is emitted with .rela relocations. The data already in any
357675b9e9f3d567bdf1a31ce9d9ce2451ae09dc9faTim Northover    // bits affected by the relocation on entry is garbage.
358107b2f26aa02a089a6b05ab86ebe033836fc06faTim Northover    *TargetPtr &= 0xffe0001fU;
359654c2d6b7a9274fc281c30c0e91419aadb6dc78aTim Northover    // Immediate goes in bits 20:5 of MOVZ/MOVK instruction
360654c2d6b7a9274fc281c30c0e91419aadb6dc78aTim Northover    *TargetPtr |= Result >> (48 - 5);
3616711fc28a41c05e1c8398393c7794c41b2ee0202Tim Northover    // Shift must be "lsl #48", in bits 22:21
3626711fc28a41c05e1c8398393c7794c41b2ee0202Tim Northover    assert((*TargetPtr >> 21 & 0x3) == 3 && "invalid shift for relocation");
363654c2d6b7a9274fc281c30c0e91419aadb6dc78aTim Northover    break;
364654c2d6b7a9274fc281c30c0e91419aadb6dc78aTim Northover  }
365654c2d6b7a9274fc281c30c0e91419aadb6dc78aTim Northover  case ELF::R_AARCH64_MOVW_UABS_G2_NC: {
366654c2d6b7a9274fc281c30c0e91419aadb6dc78aTim Northover    uint64_t Result = Value + Addend;
367675b9e9f3d567bdf1a31ce9d9ce2451ae09dc9faTim Northover
368675b9e9f3d567bdf1a31ce9d9ce2451ae09dc9faTim Northover    // AArch64 code is emitted with .rela relocations. The data already in any
369675b9e9f3d567bdf1a31ce9d9ce2451ae09dc9faTim Northover    // bits affected by the relocation on entry is garbage.
370107b2f26aa02a089a6b05ab86ebe033836fc06faTim Northover    *TargetPtr &= 0xffe0001fU;
371654c2d6b7a9274fc281c30c0e91419aadb6dc78aTim Northover    // Immediate goes in bits 20:5 of MOVZ/MOVK instruction
372654c2d6b7a9274fc281c30c0e91419aadb6dc78aTim Northover    *TargetPtr |= ((Result & 0xffff00000000ULL) >> (32 - 5));
3736711fc28a41c05e1c8398393c7794c41b2ee0202Tim Northover    // Shift must be "lsl #32", in bits 22:21
3746711fc28a41c05e1c8398393c7794c41b2ee0202Tim Northover    assert((*TargetPtr >> 21 & 0x3) == 2 && "invalid shift for relocation");
375654c2d6b7a9274fc281c30c0e91419aadb6dc78aTim Northover    break;
376654c2d6b7a9274fc281c30c0e91419aadb6dc78aTim Northover  }
377654c2d6b7a9274fc281c30c0e91419aadb6dc78aTim Northover  case ELF::R_AARCH64_MOVW_UABS_G1_NC: {
378654c2d6b7a9274fc281c30c0e91419aadb6dc78aTim Northover    uint64_t Result = Value + Addend;
379675b9e9f3d567bdf1a31ce9d9ce2451ae09dc9faTim Northover
380675b9e9f3d567bdf1a31ce9d9ce2451ae09dc9faTim Northover    // AArch64 code is emitted with .rela relocations. The data already in any
381675b9e9f3d567bdf1a31ce9d9ce2451ae09dc9faTim Northover    // bits affected by the relocation on entry is garbage.
382107b2f26aa02a089a6b05ab86ebe033836fc06faTim Northover    *TargetPtr &= 0xffe0001fU;
383654c2d6b7a9274fc281c30c0e91419aadb6dc78aTim Northover    // Immediate goes in bits 20:5 of MOVZ/MOVK instruction
384654c2d6b7a9274fc281c30c0e91419aadb6dc78aTim Northover    *TargetPtr |= ((Result & 0xffff0000U) >> (16 - 5));
3856711fc28a41c05e1c8398393c7794c41b2ee0202Tim Northover    // Shift must be "lsl #16", in bits 22:2
3866711fc28a41c05e1c8398393c7794c41b2ee0202Tim Northover    assert((*TargetPtr >> 21 & 0x3) == 1 && "invalid shift for relocation");
387654c2d6b7a9274fc281c30c0e91419aadb6dc78aTim Northover    break;
388654c2d6b7a9274fc281c30c0e91419aadb6dc78aTim Northover  }
389654c2d6b7a9274fc281c30c0e91419aadb6dc78aTim Northover  case ELF::R_AARCH64_MOVW_UABS_G0_NC: {
390654c2d6b7a9274fc281c30c0e91419aadb6dc78aTim Northover    uint64_t Result = Value + Addend;
391675b9e9f3d567bdf1a31ce9d9ce2451ae09dc9faTim Northover
392675b9e9f3d567bdf1a31ce9d9ce2451ae09dc9faTim Northover    // AArch64 code is emitted with .rela relocations. The data already in any
393675b9e9f3d567bdf1a31ce9d9ce2451ae09dc9faTim Northover    // bits affected by the relocation on entry is garbage.
394107b2f26aa02a089a6b05ab86ebe033836fc06faTim Northover    *TargetPtr &= 0xffe0001fU;
395654c2d6b7a9274fc281c30c0e91419aadb6dc78aTim Northover    // Immediate goes in bits 20:5 of MOVZ/MOVK instruction
396654c2d6b7a9274fc281c30c0e91419aadb6dc78aTim Northover    *TargetPtr |= ((Result & 0xffffU) << 5);
3976711fc28a41c05e1c8398393c7794c41b2ee0202Tim Northover    // Shift must be "lsl #0", in bits 22:21.
3986711fc28a41c05e1c8398393c7794c41b2ee0202Tim Northover    assert((*TargetPtr >> 21 & 0x3) == 0 && "invalid shift for relocation");
399654c2d6b7a9274fc281c30c0e91419aadb6dc78aTim Northover    break;
400654c2d6b7a9274fc281c30c0e91419aadb6dc78aTim Northover  }
40136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  case ELF::R_AARCH64_ADR_PREL_PG_HI21: {
40236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    // Operation: Page(S+A) - Page(P)
40336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    uint64_t Result =
40436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        ((Value + Addend) & ~0xfffULL) - (FinalAddress & ~0xfffULL);
40536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
40636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    // Check that -2^32 <= X < 2^32
4076948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    assert(isInt<33>(Result) && "overflow check failed for relocation");
40836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
40936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    // AArch64 code is emitted with .rela relocations. The data already in any
41036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    // bits affected by the relocation on entry is garbage.
41136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    *TargetPtr &= 0x9f00001fU;
41236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    // Immediate goes in bits 30:29 + 5:23 of ADRP instruction, taken
41336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    // from bits 32:12 of X.
41436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    *TargetPtr |= ((Result & 0x3000U) << (29 - 12));
41536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    *TargetPtr |= ((Result & 0x1ffffc000ULL) >> (14 - 5));
41636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    break;
41736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  }
41836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  case ELF::R_AARCH64_LDST32_ABS_LO12_NC: {
41936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    // Operation: S + A
42036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    uint64_t Result = Value + Addend;
42136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
42236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    // AArch64 code is emitted with .rela relocations. The data already in any
42336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    // bits affected by the relocation on entry is garbage.
42436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    *TargetPtr &= 0xffc003ffU;
42536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    // Immediate goes in bits 21:10 of LD/ST instruction, taken
42636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    // from bits 11:2 of X
42736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    *TargetPtr |= ((Result & 0xffc) << (10 - 2));
42836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    break;
42936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  }
43036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  case ELF::R_AARCH64_LDST64_ABS_LO12_NC: {
43136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    // Operation: S + A
43236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    uint64_t Result = Value + Addend;
43336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
43436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    // AArch64 code is emitted with .rela relocations. The data already in any
43536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    // bits affected by the relocation on entry is garbage.
43636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    *TargetPtr &= 0xffc003ffU;
43736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    // Immediate goes in bits 21:10 of LD/ST instruction, taken
43836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    // from bits 11:3 of X
43936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    *TargetPtr |= ((Result & 0xff8) << (10 - 3));
44036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    break;
44136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  }
44285829bb98a998cff8f364c12d172da948ca225f4Tim Northover  }
44385829bb98a998cff8f364c12d172da948ca225f4Tim Northover}
44485829bb98a998cff8f364c12d172da948ca225f4Tim Northover
445a307a1cf859f4a523951ac887d094039547adeb5Andrew Kaylorvoid RuntimeDyldELF::resolveARMRelocation(const SectionEntry &Section,
44636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                                          uint64_t Offset, uint32_t Value,
44736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                                          uint32_t Type, int32_t Addend) {
4480e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev  // TODO: Add Thumb relocations.
449f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  uint32_t *TargetPtr =
450f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      reinterpret_cast<uint32_t *>(Section.getAddressWithOffset(Offset));
451f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  uint32_t FinalAddress = Section.getLoadAddressWithOffset(Offset) & 0xFFFFFFFF;
4520e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev  Value += Addend;
4530e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev
454a307a1cf859f4a523951ac887d094039547adeb5Andrew Kaylor  DEBUG(dbgs() << "resolveARMRelocation, LocalAddress: "
455f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar               << Section.getAddressWithOffset(Offset)
45636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines               << " FinalAddress: " << format("%p", FinalAddress) << " Value: "
45736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines               << format("%x", Value) << " Type: " << format("%x", Type)
45836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines               << " Addend: " << format("%x", Addend) << "\n");
4590e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev
46036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  switch (Type) {
4610e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev  default:
4620e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev    llvm_unreachable("Not implemented relocation type!");
4630e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev
46436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  case ELF::R_ARM_NONE:
46536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    break;
46636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  case ELF::R_ARM_PREL31:
467e274b476de33ee4f2e90a3eb3a56b5cdd619eb82Tim Northover  case ELF::R_ARM_TARGET1:
468e274b476de33ee4f2e90a3eb3a56b5cdd619eb82Tim Northover  case ELF::R_ARM_ABS32:
4696948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    *TargetPtr = Value;
4700e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev    break;
4716948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    // Write first 16 bit of 32 bit value to the mov instruction.
4726948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    // Last 4 bit should be shifted.
473e274b476de33ee4f2e90a3eb3a56b5cdd619eb82Tim Northover  case ELF::R_ARM_MOVW_ABS_NC:
474e274b476de33ee4f2e90a3eb3a56b5cdd619eb82Tim Northover  case ELF::R_ARM_MOVT_ABS:
4756948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    if (Type == ELF::R_ARM_MOVW_ABS_NC)
4766948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar      Value = Value & 0xFFFF;
4776948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    else if (Type == ELF::R_ARM_MOVT_ABS)
4786948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar      Value = (Value >> 16) & 0xFFFF;
4796948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    *TargetPtr &= ~0x000F0FFF;
4806948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    *TargetPtr |= Value & 0xFFF;
4810e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev    *TargetPtr |= ((Value >> 12) & 0xF) << 16;
4820e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev    break;
4836948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    // Write 24 bit relative value to the branch instruction.
48436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  case ELF::R_ARM_PC24: // Fall through.
48536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  case ELF::R_ARM_CALL: // Fall through.
4866948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  case ELF::R_ARM_JUMP24:
4870e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev    int32_t RelValue = static_cast<int32_t>(Value - FinalAddress - 8);
4880e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev    RelValue = (RelValue & 0x03FFFFFC) >> 2;
489e274b476de33ee4f2e90a3eb3a56b5cdd619eb82Tim Northover    assert((*TargetPtr & 0xFFFFFF) == 0xFFFFFE);
4900e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev    *TargetPtr &= 0xFF000000;
4910e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev    *TargetPtr |= RelValue;
4920e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev    break;
4930e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev  }
494a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky}
495a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky
496a307a1cf859f4a523951ac887d094039547adeb5Andrew Kaylorvoid RuntimeDyldELF::resolveMIPSRelocation(const SectionEntry &Section,
49736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                                           uint64_t Offset, uint32_t Value,
49836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                                           uint32_t Type, int32_t Addend) {
499f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  uint8_t *TargetPtr = Section.getAddressWithOffset(Offset);
500b889e0cd2fea4afee623d5be603b912b955a2ecaAkira Hatanaka  Value += Addend;
501b889e0cd2fea4afee623d5be603b912b955a2ecaAkira Hatanaka
5026948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  DEBUG(dbgs() << "resolveMIPSRelocation, LocalAddress: "
503f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar               << Section.getAddressWithOffset(Offset) << " FinalAddress: "
504f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar               << format("%p", Section.getLoadAddressWithOffset(Offset))
505f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar               << " Value: " << format("%x", Value)
506f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar               << " Type: " << format("%x", Type)
50736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines               << " Addend: " << format("%x", Addend) << "\n");
508b889e0cd2fea4afee623d5be603b912b955a2ecaAkira Hatanaka
5096948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  uint32_t Insn = readBytesUnaligned(TargetPtr, 4);
5106948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar
51136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  switch (Type) {
512b889e0cd2fea4afee623d5be603b912b955a2ecaAkira Hatanaka  default:
513b889e0cd2fea4afee623d5be603b912b955a2ecaAkira Hatanaka    llvm_unreachable("Not implemented relocation type!");
514b889e0cd2fea4afee623d5be603b912b955a2ecaAkira Hatanaka    break;
515b889e0cd2fea4afee623d5be603b912b955a2ecaAkira Hatanaka  case ELF::R_MIPS_32:
5166948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    writeBytesUnaligned(Value, TargetPtr, 4);
517b889e0cd2fea4afee623d5be603b912b955a2ecaAkira Hatanaka    break;
518b889e0cd2fea4afee623d5be603b912b955a2ecaAkira Hatanaka  case ELF::R_MIPS_26:
5196948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    Insn &= 0xfc000000;
5206948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    Insn |= (Value & 0x0fffffff) >> 2;
5216948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    writeBytesUnaligned(Insn, TargetPtr, 4);
522b889e0cd2fea4afee623d5be603b912b955a2ecaAkira Hatanaka    break;
523b889e0cd2fea4afee623d5be603b912b955a2ecaAkira Hatanaka  case ELF::R_MIPS_HI16:
524b889e0cd2fea4afee623d5be603b912b955a2ecaAkira Hatanaka    // Get the higher 16-bits. Also add 1 if bit 15 is 1.
5256948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    Insn &= 0xffff0000;
5266948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    Insn |= ((Value + 0x8000) >> 16) & 0xffff;
5276948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    writeBytesUnaligned(Insn, TargetPtr, 4);
5283af1c9d3343357849f19f7467f9c16220ad37ca4Akira Hatanaka    break;
5293af1c9d3343357849f19f7467f9c16220ad37ca4Akira Hatanaka  case ELF::R_MIPS_LO16:
5306948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    Insn &= 0xffff0000;
5316948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    Insn |= Value & 0xffff;
5326948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    writeBytesUnaligned(Insn, TargetPtr, 4);
5333af1c9d3343357849f19f7467f9c16220ad37ca4Akira Hatanaka    break;
534f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  case ELF::R_MIPS_PC32: {
535f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    uint32_t FinalAddress = Section.getLoadAddressWithOffset(Offset);
536f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    writeBytesUnaligned(Value - FinalAddress, (uint8_t *)TargetPtr, 4);
537f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    break;
538f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  }
539f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  case ELF::R_MIPS_PC16: {
540f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    uint32_t FinalAddress = Section.getLoadAddressWithOffset(Offset);
541f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    Insn &= 0xffff0000;
542f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    Insn |= ((Value - FinalAddress) >> 2) & 0xffff;
543f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    writeBytesUnaligned(Insn, TargetPtr, 4);
544f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    break;
545f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  }
546f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  case ELF::R_MIPS_PC19_S2: {
547f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    uint32_t FinalAddress = Section.getLoadAddressWithOffset(Offset);
548f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    Insn &= 0xfff80000;
549f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    Insn |= ((Value - (FinalAddress & ~0x3)) >> 2) & 0x7ffff;
550f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    writeBytesUnaligned(Insn, TargetPtr, 4);
5516948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    break;
5526948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  }
553f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  case ELF::R_MIPS_PC21_S2: {
554f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    uint32_t FinalAddress = Section.getLoadAddressWithOffset(Offset);
555f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    Insn &= 0xffe00000;
556f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    Insn |= ((Value - FinalAddress) >> 2) & 0x1fffff;
557f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    writeBytesUnaligned(Insn, TargetPtr, 4);
558f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    break;
559f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  }
560f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  case ELF::R_MIPS_PC26_S2: {
561f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    uint32_t FinalAddress = Section.getLoadAddressWithOffset(Offset);
562f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    Insn &= 0xfc000000;
563f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    Insn |= ((Value - FinalAddress) >> 2) & 0x3ffffff;
564f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    writeBytesUnaligned(Insn, TargetPtr, 4);
565f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    break;
566f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  }
567f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  case ELF::R_MIPS_PCHI16: {
568f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    uint32_t FinalAddress = Section.getLoadAddressWithOffset(Offset);
569f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    Insn &= 0xffff0000;
570f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    Insn |= ((Value - FinalAddress + 0x8000) >> 16) & 0xffff;
571f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    writeBytesUnaligned(Insn, TargetPtr, 4);
572f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    break;
573f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  }
574f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  case ELF::R_MIPS_PCLO16: {
575f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    uint32_t FinalAddress = Section.getLoadAddressWithOffset(Offset);
576f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    Insn &= 0xffff0000;
577f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    Insn |= (Value - FinalAddress) & 0xffff;
578f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    writeBytesUnaligned(Insn, TargetPtr, 4);
579f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    break;
580f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  }
581f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  }
5826948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar}
5836948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar
5846948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainarvoid RuntimeDyldELF::setMipsABI(const ObjectFile &Obj) {
5856948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  if (Arch == Triple::UnknownArch ||
5866948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar      !StringRef(Triple::getArchTypePrefix(Arch)).equals("mips")) {
5876948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    IsMipsO32ABI = false;
5886948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    IsMipsN64ABI = false;
5896948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    return;
5906948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  }
5916948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  unsigned AbiVariant;
5926948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  Obj.getPlatformFlags(AbiVariant);
5936948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  IsMipsO32ABI = AbiVariant & ELF::EF_MIPS_ABI_O32;
5946948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  IsMipsN64ABI = Obj.getFileFormatName().equals("ELF64-mips");
5956948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  if (AbiVariant & ELF::EF_MIPS_ABI2)
5966948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    llvm_unreachable("Mips N32 ABI is not supported yet");
5976948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar}
5986948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar
5996948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainarvoid RuntimeDyldELF::resolveMIPS64Relocation(const SectionEntry &Section,
6006948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar                                             uint64_t Offset, uint64_t Value,
6016948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar                                             uint32_t Type, int64_t Addend,
6026948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar                                             uint64_t SymOffset,
6036948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar                                             SID SectionID) {
6046948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  uint32_t r_type = Type & 0xff;
6056948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  uint32_t r_type2 = (Type >> 8) & 0xff;
6066948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  uint32_t r_type3 = (Type >> 16) & 0xff;
6076948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar
6086948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  // RelType is used to keep information for which relocation type we are
6096948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  // applying relocation.
6106948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  uint32_t RelType = r_type;
6116948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  int64_t CalculatedValue = evaluateMIPS64Relocation(Section, Offset, Value,
6126948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar                                                     RelType, Addend,
6136948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar                                                     SymOffset, SectionID);
6146948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  if (r_type2 != ELF::R_MIPS_NONE) {
6156948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    RelType = r_type2;
6166948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    CalculatedValue = evaluateMIPS64Relocation(Section, Offset, 0, RelType,
6176948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar                                               CalculatedValue, SymOffset,
6186948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar                                               SectionID);
6196948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  }
6206948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  if (r_type3 != ELF::R_MIPS_NONE) {
6216948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    RelType = r_type3;
6226948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    CalculatedValue = evaluateMIPS64Relocation(Section, Offset, 0, RelType,
6236948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar                                               CalculatedValue, SymOffset,
6246948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar                                               SectionID);
6256948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  }
626f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  applyMIPS64Relocation(Section.getAddressWithOffset(Offset), CalculatedValue,
627f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar                        RelType);
6286948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar}
6296948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar
6306948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainarint64_t
6316948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga NainarRuntimeDyldELF::evaluateMIPS64Relocation(const SectionEntry &Section,
6326948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar                                         uint64_t Offset, uint64_t Value,
6336948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar                                         uint32_t Type, int64_t Addend,
6346948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar                                         uint64_t SymOffset, SID SectionID) {
6356948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar
6366948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  DEBUG(dbgs() << "evaluateMIPS64Relocation, LocalAddress: 0x"
637f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar               << format("%llx", Section.getAddressWithOffset(Offset))
6386948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar               << " FinalAddress: 0x"
639f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar               << format("%llx", Section.getLoadAddressWithOffset(Offset))
6406948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar               << " Value: 0x" << format("%llx", Value) << " Type: 0x"
6416948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar               << format("%x", Type) << " Addend: 0x" << format("%llx", Addend)
642f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar               << " SymOffset: " << format("%x", SymOffset) << "\n");
6436948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar
6446948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  switch (Type) {
6456948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  default:
6466948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    llvm_unreachable("Not implemented relocation type!");
647b889e0cd2fea4afee623d5be603b912b955a2ecaAkira Hatanaka    break;
6486948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  case ELF::R_MIPS_JALR:
6496948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  case ELF::R_MIPS_NONE:
650b889e0cd2fea4afee623d5be603b912b955a2ecaAkira Hatanaka    break;
6516948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  case ELF::R_MIPS_32:
6526948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  case ELF::R_MIPS_64:
6536948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    return Value + Addend;
6546948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  case ELF::R_MIPS_26:
6556948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    return ((Value + Addend) >> 2) & 0x3ffffff;
6566948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  case ELF::R_MIPS_GPREL16: {
6576948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    uint64_t GOTAddr = getSectionLoadAddress(SectionToGOTMap[SectionID]);
6586948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    return Value + Addend - (GOTAddr + 0x7ff0);
6596948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  }
6606948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  case ELF::R_MIPS_SUB:
6616948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    return Value - Addend;
6626948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  case ELF::R_MIPS_HI16:
6636948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    // Get the higher 16-bits. Also add 1 if bit 15 is 1.
6646948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    return ((Value + Addend + 0x8000) >> 16) & 0xffff;
6656948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  case ELF::R_MIPS_LO16:
6666948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    return (Value + Addend) & 0xffff;
6676948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  case ELF::R_MIPS_CALL16:
6686948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  case ELF::R_MIPS_GOT_DISP:
6696948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  case ELF::R_MIPS_GOT_PAGE: {
6706948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    uint8_t *LocalGOTAddr =
6716948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar        getSectionAddress(SectionToGOTMap[SectionID]) + SymOffset;
6726948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    uint64_t GOTEntry = readBytesUnaligned(LocalGOTAddr, 8);
6736948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar
6746948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    Value += Addend;
6756948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    if (Type == ELF::R_MIPS_GOT_PAGE)
6766948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar      Value = (Value + 0x8000) & ~0xffff;
6776948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar
6786948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    if (GOTEntry)
6796948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar      assert(GOTEntry == Value &&
6806948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar                   "GOT entry has two different addresses.");
6816948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    else
6826948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar      writeBytesUnaligned(Value, LocalGOTAddr, 8);
6836948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar
6846948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    return (SymOffset - 0x7ff0) & 0xffff;
6856948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  }
6866948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  case ELF::R_MIPS_GOT_OFST: {
6876948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    int64_t page = (Value + Addend + 0x8000) & ~0xffff;
6886948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    return (Value + Addend - page) & 0xffff;
6896948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  }
6906948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  case ELF::R_MIPS_GPREL32: {
6916948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    uint64_t GOTAddr = getSectionLoadAddress(SectionToGOTMap[SectionID]);
6926948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    return Value + Addend - (GOTAddr + 0x7ff0);
6936948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  }
6946948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  case ELF::R_MIPS_PC16: {
695f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    uint64_t FinalAddress = Section.getLoadAddressWithOffset(Offset);
696f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    return ((Value + Addend - FinalAddress) >> 2) & 0xffff;
69736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  }
6986948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  case ELF::R_MIPS_PC32: {
699f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    uint64_t FinalAddress = Section.getLoadAddressWithOffset(Offset);
7006948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    return Value + Addend - FinalAddress;
7016948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  }
7026948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  case ELF::R_MIPS_PC18_S3: {
703f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    uint64_t FinalAddress = Section.getLoadAddressWithOffset(Offset);
704f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    return ((Value + Addend - (FinalAddress & ~0x7)) >> 3) & 0x3ffff;
7056948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  }
7066948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  case ELF::R_MIPS_PC19_S2: {
707f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    uint64_t FinalAddress = Section.getLoadAddressWithOffset(Offset);
708f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    return ((Value + Addend - (FinalAddress & ~0x3)) >> 2) & 0x7ffff;
7096948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  }
7106948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  case ELF::R_MIPS_PC21_S2: {
711f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    uint64_t FinalAddress = Section.getLoadAddressWithOffset(Offset);
7126948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    return ((Value + Addend - FinalAddress) >> 2) & 0x1fffff;
7136948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  }
7146948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  case ELF::R_MIPS_PC26_S2: {
715f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    uint64_t FinalAddress = Section.getLoadAddressWithOffset(Offset);
7166948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    return ((Value + Addend - FinalAddress) >> 2) & 0x3ffffff;
7176948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  }
7186948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  case ELF::R_MIPS_PCHI16: {
719f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    uint64_t FinalAddress = Section.getLoadAddressWithOffset(Offset);
7206948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    return ((Value + Addend - FinalAddress + 0x8000) >> 16) & 0xffff;
7216948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  }
7226948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  case ELF::R_MIPS_PCLO16: {
723f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    uint64_t FinalAddress = Section.getLoadAddressWithOffset(Offset);
7246948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    return (Value + Addend - FinalAddress) & 0xffff;
7256948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  }
7266948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  }
7276948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  return 0;
7286948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar}
7296948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar
7306948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainarvoid RuntimeDyldELF::applyMIPS64Relocation(uint8_t *TargetPtr,
7316948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar                                           int64_t CalculatedValue,
7326948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar                                           uint32_t Type) {
7336948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  uint32_t Insn = readBytesUnaligned(TargetPtr, 4);
7346948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar
7356948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  switch (Type) {
7366948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    default:
7376948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar      break;
7386948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    case ELF::R_MIPS_32:
7396948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    case ELF::R_MIPS_GPREL32:
7406948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    case ELF::R_MIPS_PC32:
7416948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar      writeBytesUnaligned(CalculatedValue & 0xffffffff, TargetPtr, 4);
7426948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar      break;
7436948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    case ELF::R_MIPS_64:
7446948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    case ELF::R_MIPS_SUB:
7456948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar      writeBytesUnaligned(CalculatedValue, TargetPtr, 8);
7466948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar      break;
7476948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    case ELF::R_MIPS_26:
7486948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    case ELF::R_MIPS_PC26_S2:
7496948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar      Insn = (Insn & 0xfc000000) | CalculatedValue;
7506948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar      writeBytesUnaligned(Insn, TargetPtr, 4);
7516948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar      break;
7526948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    case ELF::R_MIPS_GPREL16:
7536948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar      Insn = (Insn & 0xffff0000) | (CalculatedValue & 0xffff);
7546948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar      writeBytesUnaligned(Insn, TargetPtr, 4);
7556948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar      break;
7566948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    case ELF::R_MIPS_HI16:
7576948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    case ELF::R_MIPS_LO16:
7586948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    case ELF::R_MIPS_PCHI16:
7596948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    case ELF::R_MIPS_PCLO16:
7606948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    case ELF::R_MIPS_PC16:
7616948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    case ELF::R_MIPS_CALL16:
7626948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    case ELF::R_MIPS_GOT_DISP:
7636948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    case ELF::R_MIPS_GOT_PAGE:
7646948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    case ELF::R_MIPS_GOT_OFST:
7656948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar      Insn = (Insn & 0xffff0000) | CalculatedValue;
7666948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar      writeBytesUnaligned(Insn, TargetPtr, 4);
7676948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar      break;
7686948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    case ELF::R_MIPS_PC18_S3:
7696948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar      Insn = (Insn & 0xfffc0000) | CalculatedValue;
7706948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar      writeBytesUnaligned(Insn, TargetPtr, 4);
7716948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar      break;
7726948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    case ELF::R_MIPS_PC19_S2:
7736948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar      Insn = (Insn & 0xfff80000) | CalculatedValue;
7746948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar      writeBytesUnaligned(Insn, TargetPtr, 4);
7756948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar      break;
7766948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    case ELF::R_MIPS_PC21_S2:
7776948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar      Insn = (Insn & 0xffe00000) | CalculatedValue;
7786948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar      writeBytesUnaligned(Insn, TargetPtr, 4);
7796948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar      break;
7806948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    }
781b889e0cd2fea4afee623d5be603b912b955a2ecaAkira Hatanaka}
782b889e0cd2fea4afee623d5be603b912b955a2ecaAkira Hatanaka
783c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines// Return the .TOC. section and offset.
784de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga NainarError RuntimeDyldELF::findPPC64TOCSection(const ELFObjectFileBase &Obj,
785de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar                                          ObjSectionToIDMap &LocalSections,
786de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar                                          RelocationValueRef &Rel) {
787c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  // Set a default SectionID in case we do not find a TOC section below.
788c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  // This may happen for references to TOC base base (sym@toc, .odp
789c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  // relocation) without a .toc directive.  In this case just use the
790c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  // first section (which is usually the .odp) since the code won't
791c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  // reference the .toc base directly.
792f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  Rel.SymbolName = nullptr;
793c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  Rel.SectionID = 0;
794c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines
7956e8946c5280ad6071d21013651745a9478f063edAdhemerval Zanella  // The TOC consists of sections .got, .toc, .tocbss, .plt in that
7966e8946c5280ad6071d21013651745a9478f063edAdhemerval Zanella  // order. The TOC starts where the first of these sections starts.
7976948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  for (auto &Section: Obj.sections()) {
798c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines    StringRef SectionName;
799de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    if (auto EC = Section.getName(SectionName))
800de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      return errorCodeToError(EC);
801c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines
802c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines    if (SectionName == ".got"
803c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines        || SectionName == ".toc"
804c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines        || SectionName == ".tocbss"
805c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines        || SectionName == ".plt") {
806de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      if (auto SectionIDOrErr =
807de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar            findOrEmitSection(Obj, Section, false, LocalSections))
808de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar        Rel.SectionID = *SectionIDOrErr;
809de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      else
810de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar        return SectionIDOrErr.takeError();
8116e8946c5280ad6071d21013651745a9478f063edAdhemerval Zanella      break;
812c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines    }
8136e8946c5280ad6071d21013651745a9478f063edAdhemerval Zanella  }
814c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines
8156e8946c5280ad6071d21013651745a9478f063edAdhemerval Zanella  // Per the ppc64-elf-linux ABI, The TOC base is TOC value plus 0x8000
8166e8946c5280ad6071d21013651745a9478f063edAdhemerval Zanella  // thus permitting a full 64 Kbytes segment.
817c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  Rel.Addend = 0x8000;
818de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar
819de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  return Error::success();
8206e8946c5280ad6071d21013651745a9478f063edAdhemerval Zanella}
8216e8946c5280ad6071d21013651745a9478f063edAdhemerval Zanella
8226e8946c5280ad6071d21013651745a9478f063edAdhemerval Zanella// Returns the sections and offset associated with the ODP entry referenced
8236e8946c5280ad6071d21013651745a9478f063edAdhemerval Zanella// by Symbol.
824de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga NainarError RuntimeDyldELF::findOPDEntrySection(const ELFObjectFileBase &Obj,
825de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar                                          ObjSectionToIDMap &LocalSections,
826de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar                                          RelocationValueRef &Rel) {
8276e8946c5280ad6071d21013651745a9478f063edAdhemerval Zanella  // Get the ELF symbol value (st_value) to compare with Relocation offset in
8286e8946c5280ad6071d21013651745a9478f063edAdhemerval Zanella  // .opd entries
829ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  for (section_iterator si = Obj.section_begin(), se = Obj.section_end();
83036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines       si != se; ++si) {
83115e5c46e49b5ab02fee6d1da53cb9c129cab5165Rafael Espindola    section_iterator RelSecI = si->getRelocatedSection();
832ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    if (RelSecI == Obj.section_end())
83315e5c46e49b5ab02fee6d1da53cb9c129cab5165Rafael Espindola      continue;
83415e5c46e49b5ab02fee6d1da53cb9c129cab5165Rafael Espindola
83515e5c46e49b5ab02fee6d1da53cb9c129cab5165Rafael Espindola    StringRef RelSectionName;
836de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    if (auto EC = RelSecI->getName(RelSectionName))
837de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      return errorCodeToError(EC);
838de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar
83915e5c46e49b5ab02fee6d1da53cb9c129cab5165Rafael Espindola    if (RelSectionName != ".opd")
8406e8946c5280ad6071d21013651745a9478f063edAdhemerval Zanella      continue;
8416e8946c5280ad6071d21013651745a9478f063edAdhemerval Zanella
842f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    for (elf_relocation_iterator i = si->relocation_begin(),
843f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar                                 e = si->relocation_end();
84436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines         i != e;) {
8456e8946c5280ad6071d21013651745a9478f063edAdhemerval Zanella      // The R_PPC64_ADDR64 relocation indicates the first field
8466e8946c5280ad6071d21013651745a9478f063edAdhemerval Zanella      // of a .opd entry
847f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      uint64_t TypeFunc = i->getType();
8486e8946c5280ad6071d21013651745a9478f063edAdhemerval Zanella      if (TypeFunc != ELF::R_PPC64_ADDR64) {
84936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        ++i;
8506e8946c5280ad6071d21013651745a9478f063edAdhemerval Zanella        continue;
8516e8946c5280ad6071d21013651745a9478f063edAdhemerval Zanella      }
8526e8946c5280ad6071d21013651745a9478f063edAdhemerval Zanella
853f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      uint64_t TargetSymbolOffset = i->getOffset();
8546c1202c459ffa6d693ad92fa84e43902bc780bcaRafael Espindola      symbol_iterator TargetSymbol = i->getSymbol();
855de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      int64_t Addend;
856de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      if (auto AddendOrErr = i->getAddend())
857de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar        Addend = *AddendOrErr;
858de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      else
859de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar        return errorCodeToError(AddendOrErr.getError());
8606e8946c5280ad6071d21013651745a9478f063edAdhemerval Zanella
86136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      ++i;
8626e8946c5280ad6071d21013651745a9478f063edAdhemerval Zanella      if (i == e)
8636e8946c5280ad6071d21013651745a9478f063edAdhemerval Zanella        break;
8646e8946c5280ad6071d21013651745a9478f063edAdhemerval Zanella
8656e8946c5280ad6071d21013651745a9478f063edAdhemerval Zanella      // Just check if following relocation is a R_PPC64_TOC
866f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      uint64_t TypeTOC = i->getType();
8676e8946c5280ad6071d21013651745a9478f063edAdhemerval Zanella      if (TypeTOC != ELF::R_PPC64_TOC)
8686e8946c5280ad6071d21013651745a9478f063edAdhemerval Zanella        continue;
8696e8946c5280ad6071d21013651745a9478f063edAdhemerval Zanella
8706e8946c5280ad6071d21013651745a9478f063edAdhemerval Zanella      // Finally compares the Symbol value and the target symbol offset
8716e8946c5280ad6071d21013651745a9478f063edAdhemerval Zanella      // to check if this .opd entry refers to the symbol the relocation
8726e8946c5280ad6071d21013651745a9478f063edAdhemerval Zanella      // points to.
873ff9fa05905be716435460b5f6d32689041bf895bAndrew Kaylor      if (Rel.Addend != (int64_t)TargetSymbolOffset)
8746e8946c5280ad6071d21013651745a9478f063edAdhemerval Zanella        continue;
8756e8946c5280ad6071d21013651745a9478f063edAdhemerval Zanella
876de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      section_iterator TSI = Obj.section_end();
877de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      if (auto TSIOrErr = TargetSymbol->getSection())
878de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar        TSI = *TSIOrErr;
879de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      else
880de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar        return TSIOrErr.takeError();
881de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      assert(TSI != Obj.section_end() && "TSI should refer to a valid section");
882de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar
883de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      bool IsCode = TSI->isText();
884de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      if (auto SectionIDOrErr = findOrEmitSection(Obj, *TSI, IsCode,
885de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar                                                  LocalSections))
886de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar        Rel.SectionID = *SectionIDOrErr;
887de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      else
888de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar        return SectionIDOrErr.takeError();
889167957fa095bc7200b908e6e142be3e604bcfeeaRafael Espindola      Rel.Addend = (intptr_t)Addend;
890de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      return Error::success();
8916e8946c5280ad6071d21013651745a9478f063edAdhemerval Zanella    }
8926e8946c5280ad6071d21013651745a9478f063edAdhemerval Zanella  }
8936e8946c5280ad6071d21013651745a9478f063edAdhemerval Zanella  llvm_unreachable("Attempting to get address of ODP entry!");
8946e8946c5280ad6071d21013651745a9478f063edAdhemerval Zanella}
8956e8946c5280ad6071d21013651745a9478f063edAdhemerval Zanella
896c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines// Relocation masks following the #lo(value), #hi(value), #ha(value),
897c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines// #higher(value), #highera(value), #highest(value), and #highesta(value)
898c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines// macros defined in section 4.5.1. Relocation Types of the PPC-elf64abi
899c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines// document.
900c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines
90136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesstatic inline uint16_t applyPPClo(uint64_t value) { return value & 0xffff; }
9026e8946c5280ad6071d21013651745a9478f063edAdhemerval Zanella
90336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesstatic inline uint16_t applyPPChi(uint64_t value) {
9046e8946c5280ad6071d21013651745a9478f063edAdhemerval Zanella  return (value >> 16) & 0xffff;
9056e8946c5280ad6071d21013651745a9478f063edAdhemerval Zanella}
9066e8946c5280ad6071d21013651745a9478f063edAdhemerval Zanella
907c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hinesstatic inline uint16_t applyPPCha (uint64_t value) {
908c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  return ((value + 0x8000) >> 16) & 0xffff;
909c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines}
910c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines
91136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesstatic inline uint16_t applyPPChigher(uint64_t value) {
9126e8946c5280ad6071d21013651745a9478f063edAdhemerval Zanella  return (value >> 32) & 0xffff;
9136e8946c5280ad6071d21013651745a9478f063edAdhemerval Zanella}
9146e8946c5280ad6071d21013651745a9478f063edAdhemerval Zanella
915c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hinesstatic inline uint16_t applyPPChighera (uint64_t value) {
916c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  return ((value + 0x8000) >> 32) & 0xffff;
917c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines}
918c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines
91936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesstatic inline uint16_t applyPPChighest(uint64_t value) {
9206e8946c5280ad6071d21013651745a9478f063edAdhemerval Zanella  return (value >> 48) & 0xffff;
9216e8946c5280ad6071d21013651745a9478f063edAdhemerval Zanella}
9226e8946c5280ad6071d21013651745a9478f063edAdhemerval Zanella
923c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hinesstatic inline uint16_t applyPPChighesta (uint64_t value) {
924c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  return ((value + 0x8000) >> 48) & 0xffff;
925c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines}
926c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines
927f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainarvoid RuntimeDyldELF::resolvePPC32Relocation(const SectionEntry &Section,
928f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar                                            uint64_t Offset, uint64_t Value,
929f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar                                            uint32_t Type, int64_t Addend) {
930f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  uint8_t *LocalAddress = Section.getAddressWithOffset(Offset);
931f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  switch (Type) {
932f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  default:
933f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    llvm_unreachable("Relocation type not implemented yet!");
934f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    break;
935f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  case ELF::R_PPC_ADDR16_LO:
936f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    writeInt16BE(LocalAddress, applyPPClo(Value + Addend));
937f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    break;
938f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  case ELF::R_PPC_ADDR16_HI:
939f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    writeInt16BE(LocalAddress, applyPPChi(Value + Addend));
940f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    break;
941f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  case ELF::R_PPC_ADDR16_HA:
942f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    writeInt16BE(LocalAddress, applyPPCha(Value + Addend));
943f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    break;
944f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  }
945f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar}
946f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
947a307a1cf859f4a523951ac887d094039547adeb5Andrew Kaylorvoid RuntimeDyldELF::resolvePPC64Relocation(const SectionEntry &Section,
94836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                                            uint64_t Offset, uint64_t Value,
94936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                                            uint32_t Type, int64_t Addend) {
950f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  uint8_t *LocalAddress = Section.getAddressWithOffset(Offset);
9516e8946c5280ad6071d21013651745a9478f063edAdhemerval Zanella  switch (Type) {
9526e8946c5280ad6071d21013651745a9478f063edAdhemerval Zanella  default:
9536e8946c5280ad6071d21013651745a9478f063edAdhemerval Zanella    llvm_unreachable("Relocation type not implemented yet!");
9546e8946c5280ad6071d21013651745a9478f063edAdhemerval Zanella    break;
955c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  case ELF::R_PPC64_ADDR16:
956c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines    writeInt16BE(LocalAddress, applyPPClo(Value + Addend));
957c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines    break;
958c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  case ELF::R_PPC64_ADDR16_DS:
959c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines    writeInt16BE(LocalAddress, applyPPClo(Value + Addend) & ~3);
960c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines    break;
96136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  case ELF::R_PPC64_ADDR16_LO:
96236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    writeInt16BE(LocalAddress, applyPPClo(Value + Addend));
96336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    break;
964c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  case ELF::R_PPC64_ADDR16_LO_DS:
965c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines    writeInt16BE(LocalAddress, applyPPClo(Value + Addend) & ~3);
966c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines    break;
96736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  case ELF::R_PPC64_ADDR16_HI:
96836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    writeInt16BE(LocalAddress, applyPPChi(Value + Addend));
9696e8946c5280ad6071d21013651745a9478f063edAdhemerval Zanella    break;
970c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  case ELF::R_PPC64_ADDR16_HA:
971c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines    writeInt16BE(LocalAddress, applyPPCha(Value + Addend));
972c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines    break;
97336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  case ELF::R_PPC64_ADDR16_HIGHER:
97436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    writeInt16BE(LocalAddress, applyPPChigher(Value + Addend));
9756e8946c5280ad6071d21013651745a9478f063edAdhemerval Zanella    break;
976c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  case ELF::R_PPC64_ADDR16_HIGHERA:
977c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines    writeInt16BE(LocalAddress, applyPPChighera(Value + Addend));
978c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines    break;
97936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  case ELF::R_PPC64_ADDR16_HIGHEST:
98036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    writeInt16BE(LocalAddress, applyPPChighest(Value + Addend));
9816e8946c5280ad6071d21013651745a9478f063edAdhemerval Zanella    break;
982c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  case ELF::R_PPC64_ADDR16_HIGHESTA:
983c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines    writeInt16BE(LocalAddress, applyPPChighesta(Value + Addend));
984c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines    break;
98536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  case ELF::R_PPC64_ADDR14: {
9866e8946c5280ad6071d21013651745a9478f063edAdhemerval Zanella    assert(((Value + Addend) & 3) == 0);
9876e8946c5280ad6071d21013651745a9478f063edAdhemerval Zanella    // Preserve the AA/LK bits in the branch instruction
98836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    uint8_t aalk = *(LocalAddress + 3);
9896e8946c5280ad6071d21013651745a9478f063edAdhemerval Zanella    writeInt16BE(LocalAddress + 2, (aalk & 3) | ((Value + Addend) & 0xfffc));
9906e8946c5280ad6071d21013651745a9478f063edAdhemerval Zanella  } break;
991c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  case ELF::R_PPC64_REL16_LO: {
992f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    uint64_t FinalAddress = Section.getLoadAddressWithOffset(Offset);
993c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines    uint64_t Delta = Value - FinalAddress + Addend;
994c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines    writeInt16BE(LocalAddress, applyPPClo(Delta));
995c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  } break;
996c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  case ELF::R_PPC64_REL16_HI: {
997f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    uint64_t FinalAddress = Section.getLoadAddressWithOffset(Offset);
998c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines    uint64_t Delta = Value - FinalAddress + Addend;
999c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines    writeInt16BE(LocalAddress, applyPPChi(Delta));
1000c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  } break;
1001c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  case ELF::R_PPC64_REL16_HA: {
1002f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    uint64_t FinalAddress = Section.getLoadAddressWithOffset(Offset);
1003c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines    uint64_t Delta = Value - FinalAddress + Addend;
1004c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines    writeInt16BE(LocalAddress, applyPPCha(Delta));
1005c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  } break;
100636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  case ELF::R_PPC64_ADDR32: {
10077b449889e7886b263718b5103538970f287bc37eAdhemerval Zanella    int32_t Result = static_cast<int32_t>(Value + Addend);
10087b449889e7886b263718b5103538970f287bc37eAdhemerval Zanella    if (SignExtend32<32>(Result) != Result)
1009a1db5de9e70dd8ffda57b1a4373915ea866b6f1dAdhemerval Zanella      llvm_unreachable("Relocation R_PPC64_ADDR32 overflow");
10107b449889e7886b263718b5103538970f287bc37eAdhemerval Zanella    writeInt32BE(LocalAddress, Result);
10117b449889e7886b263718b5103538970f287bc37eAdhemerval Zanella  } break;
101236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  case ELF::R_PPC64_REL24: {
1013f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    uint64_t FinalAddress = Section.getLoadAddressWithOffset(Offset);
10146e8946c5280ad6071d21013651745a9478f063edAdhemerval Zanella    int32_t delta = static_cast<int32_t>(Value - FinalAddress + Addend);
1015f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    if (SignExtend32<26>(delta) != delta)
10166e8946c5280ad6071d21013651745a9478f063edAdhemerval Zanella      llvm_unreachable("Relocation R_PPC64_REL24 overflow");
10176e8946c5280ad6071d21013651745a9478f063edAdhemerval Zanella    // Generates a 'bl <address>' instruction
10186e8946c5280ad6071d21013651745a9478f063edAdhemerval Zanella    writeInt32BE(LocalAddress, 0x48000001 | (delta & 0x03FFFFFC));
10196e8946c5280ad6071d21013651745a9478f063edAdhemerval Zanella  } break;
102036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  case ELF::R_PPC64_REL32: {
1021f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    uint64_t FinalAddress = Section.getLoadAddressWithOffset(Offset);
1022a1db5de9e70dd8ffda57b1a4373915ea866b6f1dAdhemerval Zanella    int32_t delta = static_cast<int32_t>(Value - FinalAddress + Addend);
1023a1db5de9e70dd8ffda57b1a4373915ea866b6f1dAdhemerval Zanella    if (SignExtend32<32>(delta) != delta)
1024a1db5de9e70dd8ffda57b1a4373915ea866b6f1dAdhemerval Zanella      llvm_unreachable("Relocation R_PPC64_REL32 overflow");
1025a1db5de9e70dd8ffda57b1a4373915ea866b6f1dAdhemerval Zanella    writeInt32BE(LocalAddress, delta);
1026a1db5de9e70dd8ffda57b1a4373915ea866b6f1dAdhemerval Zanella  } break;
1027f51d7e76ae2c56588b162d84da54d5c3f0b66b51Adhemerval Zanella  case ELF::R_PPC64_REL64: {
1028f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    uint64_t FinalAddress = Section.getLoadAddressWithOffset(Offset);
1029f51d7e76ae2c56588b162d84da54d5c3f0b66b51Adhemerval Zanella    uint64_t Delta = Value - FinalAddress + Addend;
1030f51d7e76ae2c56588b162d84da54d5c3f0b66b51Adhemerval Zanella    writeInt64BE(LocalAddress, Delta);
1031f51d7e76ae2c56588b162d84da54d5c3f0b66b51Adhemerval Zanella  } break;
103236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  case ELF::R_PPC64_ADDR64:
10336e8946c5280ad6071d21013651745a9478f063edAdhemerval Zanella    writeInt64BE(LocalAddress, Value + Addend);
10346e8946c5280ad6071d21013651745a9478f063edAdhemerval Zanella    break;
10356e8946c5280ad6071d21013651745a9478f063edAdhemerval Zanella  }
10366e8946c5280ad6071d21013651745a9478f063edAdhemerval Zanella}
10376e8946c5280ad6071d21013651745a9478f063edAdhemerval Zanella
10386fc2ad62e23673ef829c9c4bbf62743d30928a5bRichard Sandifordvoid RuntimeDyldELF::resolveSystemZRelocation(const SectionEntry &Section,
103936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                                              uint64_t Offset, uint64_t Value,
104036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                                              uint32_t Type, int64_t Addend) {
1041f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  uint8_t *LocalAddress = Section.getAddressWithOffset(Offset);
10426fc2ad62e23673ef829c9c4bbf62743d30928a5bRichard Sandiford  switch (Type) {
10436fc2ad62e23673ef829c9c4bbf62743d30928a5bRichard Sandiford  default:
10446fc2ad62e23673ef829c9c4bbf62743d30928a5bRichard Sandiford    llvm_unreachable("Relocation type not implemented yet!");
10456fc2ad62e23673ef829c9c4bbf62743d30928a5bRichard Sandiford    break;
10466fc2ad62e23673ef829c9c4bbf62743d30928a5bRichard Sandiford  case ELF::R_390_PC16DBL:
10476fc2ad62e23673ef829c9c4bbf62743d30928a5bRichard Sandiford  case ELF::R_390_PLT16DBL: {
1048f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    int64_t Delta = (Value + Addend) - Section.getLoadAddressWithOffset(Offset);
10496fc2ad62e23673ef829c9c4bbf62743d30928a5bRichard Sandiford    assert(int16_t(Delta / 2) * 2 == Delta && "R_390_PC16DBL overflow");
10506fc2ad62e23673ef829c9c4bbf62743d30928a5bRichard Sandiford    writeInt16BE(LocalAddress, Delta / 2);
10516fc2ad62e23673ef829c9c4bbf62743d30928a5bRichard Sandiford    break;
10526fc2ad62e23673ef829c9c4bbf62743d30928a5bRichard Sandiford  }
10536fc2ad62e23673ef829c9c4bbf62743d30928a5bRichard Sandiford  case ELF::R_390_PC32DBL:
10546fc2ad62e23673ef829c9c4bbf62743d30928a5bRichard Sandiford  case ELF::R_390_PLT32DBL: {
1055f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    int64_t Delta = (Value + Addend) - Section.getLoadAddressWithOffset(Offset);
10566fc2ad62e23673ef829c9c4bbf62743d30928a5bRichard Sandiford    assert(int32_t(Delta / 2) * 2 == Delta && "R_390_PC32DBL overflow");
10576fc2ad62e23673ef829c9c4bbf62743d30928a5bRichard Sandiford    writeInt32BE(LocalAddress, Delta / 2);
10586fc2ad62e23673ef829c9c4bbf62743d30928a5bRichard Sandiford    break;
10596fc2ad62e23673ef829c9c4bbf62743d30928a5bRichard Sandiford  }
10606fc2ad62e23673ef829c9c4bbf62743d30928a5bRichard Sandiford  case ELF::R_390_PC32: {
1061f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    int64_t Delta = (Value + Addend) - Section.getLoadAddressWithOffset(Offset);
10626fc2ad62e23673ef829c9c4bbf62743d30928a5bRichard Sandiford    assert(int32_t(Delta) == Delta && "R_390_PC32 overflow");
10636fc2ad62e23673ef829c9c4bbf62743d30928a5bRichard Sandiford    writeInt32BE(LocalAddress, Delta);
10646fc2ad62e23673ef829c9c4bbf62743d30928a5bRichard Sandiford    break;
10656fc2ad62e23673ef829c9c4bbf62743d30928a5bRichard Sandiford  }
10666fc2ad62e23673ef829c9c4bbf62743d30928a5bRichard Sandiford  case ELF::R_390_64:
10676fc2ad62e23673ef829c9c4bbf62743d30928a5bRichard Sandiford    writeInt64BE(LocalAddress, Value + Addend);
10686fc2ad62e23673ef829c9c4bbf62743d30928a5bRichard Sandiford    break;
1069de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  case ELF::R_390_PC64: {
1070de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    int64_t Delta = (Value + Addend) - Section.getLoadAddressWithOffset(Offset);
1071de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    writeInt64BE(LocalAddress, Delta);
1072de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    break;
1073de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  }
10746fc2ad62e23673ef829c9c4bbf62743d30928a5bRichard Sandiford  }
10756fc2ad62e23673ef829c9c4bbf62743d30928a5bRichard Sandiford}
10766fc2ad62e23673ef829c9c4bbf62743d30928a5bRichard Sandiford
107732bd10b1a33df2cc4d067a16901d56665f4ba085Andrew Kaylor// The target location for the relocation is described by RE.SectionID and
107832bd10b1a33df2cc4d067a16901d56665f4ba085Andrew Kaylor// RE.Offset.  RE.SectionID can be used to find the SectionEntry.  Each
107932bd10b1a33df2cc4d067a16901d56665f4ba085Andrew Kaylor// SectionEntry has three members describing its location.
108032bd10b1a33df2cc4d067a16901d56665f4ba085Andrew Kaylor// SectionEntry::Address is the address at which the section has been loaded
108132bd10b1a33df2cc4d067a16901d56665f4ba085Andrew Kaylor// into memory in the current (host) process.  SectionEntry::LoadAddress is the
108232bd10b1a33df2cc4d067a16901d56665f4ba085Andrew Kaylor// address that the section will have in the target process.
108332bd10b1a33df2cc4d067a16901d56665f4ba085Andrew Kaylor// SectionEntry::ObjAddress is the address of the bits for this section in the
108432bd10b1a33df2cc4d067a16901d56665f4ba085Andrew Kaylor// original emitted object image (also in the current address space).
108532bd10b1a33df2cc4d067a16901d56665f4ba085Andrew Kaylor//
108632bd10b1a33df2cc4d067a16901d56665f4ba085Andrew Kaylor// Relocations will be applied as if the section were loaded at
108732bd10b1a33df2cc4d067a16901d56665f4ba085Andrew Kaylor// SectionEntry::LoadAddress, but they will be applied at an address based
108832bd10b1a33df2cc4d067a16901d56665f4ba085Andrew Kaylor// on SectionEntry::Address.  SectionEntry::ObjAddress will be used to refer to
108932bd10b1a33df2cc4d067a16901d56665f4ba085Andrew Kaylor// Target memory contents if they are required for value calculations.
109032bd10b1a33df2cc4d067a16901d56665f4ba085Andrew Kaylor//
109132bd10b1a33df2cc4d067a16901d56665f4ba085Andrew Kaylor// The Value parameter here is the load address of the symbol for the
109232bd10b1a33df2cc4d067a16901d56665f4ba085Andrew Kaylor// relocation to be applied.  For relocations which refer to symbols in the
109332bd10b1a33df2cc4d067a16901d56665f4ba085Andrew Kaylor// current object Value will be the LoadAddress of the section in which
109432bd10b1a33df2cc4d067a16901d56665f4ba085Andrew Kaylor// the symbol resides (RE.Addend provides additional information about the
109532bd10b1a33df2cc4d067a16901d56665f4ba085Andrew Kaylor// symbol location).  For external symbols, Value will be the address of the
109632bd10b1a33df2cc4d067a16901d56665f4ba085Andrew Kaylor// symbol in the target address space.
109787b5017139e9d8ac9b046b3284a9cc68c76185d6Rafael Espindolavoid RuntimeDyldELF::resolveRelocation(const RelocationEntry &RE,
109832bd10b1a33df2cc4d067a16901d56665f4ba085Andrew Kaylor                                       uint64_t Value) {
109987b5017139e9d8ac9b046b3284a9cc68c76185d6Rafael Espindola  const SectionEntry &Section = Sections[RE.SectionID];
1100ff9fa05905be716435460b5f6d32689041bf895bAndrew Kaylor  return resolveRelocation(Section, RE.Offset, Value, RE.RelType, RE.Addend,
11016948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar                           RE.SymOffset, RE.SectionID);
110287b5017139e9d8ac9b046b3284a9cc68c76185d6Rafael Espindola}
110387b5017139e9d8ac9b046b3284a9cc68c76185d6Rafael Espindola
1104a307a1cf859f4a523951ac887d094039547adeb5Andrew Kaylorvoid RuntimeDyldELF::resolveRelocation(const SectionEntry &Section,
110536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                                       uint64_t Offset, uint64_t Value,
110636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                                       uint32_t Type, int64_t Addend,
11076948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar                                       uint64_t SymOffset, SID SectionID) {
1108a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky  switch (Arch) {
1109a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky  case Triple::x86_64:
1110ff9fa05905be716435460b5f6d32689041bf895bAndrew Kaylor    resolveX86_64Relocation(Section, Offset, Value, Type, Addend, SymOffset);
1111a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky    break;
1112a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky  case Triple::x86:
111336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    resolveX86Relocation(Section, Offset, (uint32_t)(Value & 0xffffffffL), Type,
11140e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev                         (uint32_t)(Addend & 0xffffffffL));
1115a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky    break;
111685829bb98a998cff8f364c12d172da948ca225f4Tim Northover  case Triple::aarch64:
111736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  case Triple::aarch64_be:
111885829bb98a998cff8f364c12d172da948ca225f4Tim Northover    resolveAArch64Relocation(Section, Offset, Value, Type, Addend);
111985829bb98a998cff8f364c12d172da948ca225f4Tim Northover    break;
112036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  case Triple::arm: // Fall through.
112136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  case Triple::armeb:
11220e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev  case Triple::thumb:
112336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  case Triple::thumbeb:
112436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    resolveARMRelocation(Section, Offset, (uint32_t)(Value & 0xffffffffL), Type,
11250e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev                         (uint32_t)(Addend & 0xffffffffL));
1126a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky    break;
112736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  case Triple::mips: // Fall through.
1128b889e0cd2fea4afee623d5be603b912b955a2ecaAkira Hatanaka  case Triple::mipsel:
11296948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  case Triple::mips64:
11306948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  case Triple::mips64el:
11316948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    if (IsMipsO32ABI)
11326948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar      resolveMIPSRelocation(Section, Offset, (uint32_t)(Value & 0xffffffffL),
11336948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar                            Type, (uint32_t)(Addend & 0xffffffffL));
11346948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    else if (IsMipsN64ABI)
11356948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar      resolveMIPS64Relocation(Section, Offset, Value, Type, Addend, SymOffset,
11366948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar                              SectionID);
11376948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    else
11386948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar      llvm_unreachable("Mips ABI not handled");
1139b889e0cd2fea4afee623d5be603b912b955a2ecaAkira Hatanaka    break;
1140f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  case Triple::ppc:
1141f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    resolvePPC32Relocation(Section, Offset, Value, Type, Addend);
1142f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    break;
114336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  case Triple::ppc64: // Fall through.
1144f38cc38fa647d4e72c053c39bbe0cdec1342535fBill Schmidt  case Triple::ppc64le:
1145a307a1cf859f4a523951ac887d094039547adeb5Andrew Kaylor    resolvePPC64Relocation(Section, Offset, Value, Type, Addend);
11466e8946c5280ad6071d21013651745a9478f063edAdhemerval Zanella    break;
11476fc2ad62e23673ef829c9c4bbf62743d30928a5bRichard Sandiford  case Triple::systemz:
11486fc2ad62e23673ef829c9c4bbf62743d30928a5bRichard Sandiford    resolveSystemZRelocation(Section, Offset, Value, Type, Addend);
11496fc2ad62e23673ef829c9c4bbf62743d30928a5bRichard Sandiford    break;
115036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  default:
115136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    llvm_unreachable("Unsupported CPU type!");
1152a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky  }
1153a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky}
1154a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky
11556948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainarvoid *RuntimeDyldELF::computePlaceholderAddress(unsigned SectionID, uint64_t Offset) const {
1156f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  return (void *)(Sections[SectionID].getObjAddress() + Offset);
11576948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar}
11586948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar
11596948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainarvoid RuntimeDyldELF::processSimpleRelocation(unsigned SectionID, uint64_t Offset, unsigned RelType, RelocationValueRef Value) {
11606948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  RelocationEntry RE(SectionID, Offset, RelType, Value.Addend, Value.Offset);
11616948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  if (Value.SymbolName)
11626948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    addRelocationForSymbol(RE, Value.SymbolName);
11636948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  else
11646948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    addRelocationForSection(RE, Value.SectionID);
11656948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar}
11666948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar
1167f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainaruint32_t RuntimeDyldELF::getMatchingLoRelocation(uint32_t RelType,
1168f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar                                                 bool IsLocal) const {
1169f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  switch (RelType) {
1170f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  case ELF::R_MICROMIPS_GOT16:
1171f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    if (IsLocal)
1172f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      return ELF::R_MICROMIPS_LO16;
1173f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    break;
1174f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  case ELF::R_MICROMIPS_HI16:
1175f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    return ELF::R_MICROMIPS_LO16;
1176f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  case ELF::R_MIPS_GOT16:
1177f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    if (IsLocal)
1178f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      return ELF::R_MIPS_LO16;
1179f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    break;
1180f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  case ELF::R_MIPS_HI16:
1181f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    return ELF::R_MIPS_LO16;
1182f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  case ELF::R_MIPS_PCHI16:
1183f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    return ELF::R_MIPS_PCLO16;
1184f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  default:
1185f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    break;
1186f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  }
1187f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  return ELF::R_MIPS_NONE;
1188f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar}
1189f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
1190de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga NainarExpected<relocation_iterator>
1191de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga NainarRuntimeDyldELF::processRelocationRef(
1192f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    unsigned SectionID, relocation_iterator RelI, const ObjectFile &O,
1193f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    ObjSectionToIDMap &ObjSectionToID, StubMap &Stubs) {
1194f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  const auto &Obj = cast<ELFObjectFileBase>(O);
1195f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  uint64_t RelType = RelI->getType();
1196f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  ErrorOr<int64_t> AddendOrErr = ELFRelocationRef(*RelI).getAddend();
1197f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  int64_t Addend = AddendOrErr ? *AddendOrErr : 0;
1198f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  elf_symbol_iterator Symbol = RelI->getSymbol();
1199c201e6eaf165c83f0092c43b371e509fa8eaf4ccEli Bendersky
1200c201e6eaf165c83f0092c43b371e509fa8eaf4ccEli Bendersky  // Obtain the symbol name which is referenced in the relocation
1201c201e6eaf165c83f0092c43b371e509fa8eaf4ccEli Bendersky  StringRef TargetName;
1202f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  if (Symbol != Obj.symbol_end()) {
1203de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    if (auto TargetNameOrErr = Symbol->getName())
1204de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      TargetName = *TargetNameOrErr;
1205de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    else
1206de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      return TargetNameOrErr.takeError();
1207f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  }
120836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  DEBUG(dbgs() << "\t\tRelType: " << RelType << " Addend: " << Addend
120936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines               << " TargetName: " << TargetName << "\n");
1210c201e6eaf165c83f0092c43b371e509fa8eaf4ccEli Bendersky  RelocationValueRef Value;
1211c201e6eaf165c83f0092c43b371e509fa8eaf4ccEli Bendersky  // First search for the symbol in the local symbol table
12120962b1683f242cd6274423c24f0059832284b1c8Rafael Espindola  SymbolRef::Type SymType = SymbolRef::ST_Unknown;
1213ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines
1214ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  // Search for the symbol in the global symbol table
1215ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  RTDyldSymbolTable::const_iterator gsi = GlobalSymbolTable.end();
1216ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  if (Symbol != Obj.symbol_end()) {
1217ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    gsi = GlobalSymbolTable.find(TargetName.data());
1218de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    Expected<SymbolRef::Type> SymTypeOrErr = Symbol->getType();
1219de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    if (!SymTypeOrErr) {
1220de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      std::string Buf;
1221de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      raw_string_ostream OS(Buf);
1222de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      logAllUnhandledErrors(SymTypeOrErr.takeError(), OS, "");
1223de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      OS.flush();
1224de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      report_fatal_error(Buf);
1225de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    }
1226de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    SymType = *SymTypeOrErr;
12270962b1683f242cd6274423c24f0059832284b1c8Rafael Espindola  }
1228ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  if (gsi != GlobalSymbolTable.end()) {
1229ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    const auto &SymInfo = gsi->second;
1230ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    Value.SectionID = SymInfo.getSectionID();
1231ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    Value.Offset = SymInfo.getOffset();
1232ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    Value.Addend = SymInfo.getOffset() + Addend;
12330e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev  } else {
1234ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    switch (SymType) {
1235ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    case SymbolRef::ST_Debug: {
1236ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      // TODO: Now ELF SymbolRef::ST_Debug = STT_SECTION, it's not obviously
1237ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      // and can be changed by another developers. Maybe best way is add
1238ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      // a new symbol type ST_Section to SymbolRef and use it.
1239de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      auto SectionOrErr = Symbol->getSection();
1240de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      if (!SectionOrErr) {
1241de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar        std::string Buf;
1242de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar        raw_string_ostream OS(Buf);
1243de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar        logAllUnhandledErrors(SectionOrErr.takeError(), OS, "");
1244de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar        OS.flush();
1245de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar        report_fatal_error(Buf);
1246de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      }
1247de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      section_iterator si = *SectionOrErr;
1248ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      if (si == Obj.section_end())
1249ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines        llvm_unreachable("Symbol section not found, bad object file format!");
1250ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      DEBUG(dbgs() << "\t\tThis is section symbol\n");
1251ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      bool isCode = si->isText();
1252de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      if (auto SectionIDOrErr = findOrEmitSection(Obj, (*si), isCode,
1253de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar                                                  ObjSectionToID))
1254de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar        Value.SectionID = *SectionIDOrErr;
1255de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      else
1256de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar        return SectionIDOrErr.takeError();
1257ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      Value.Addend = Addend;
1258ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      break;
1259ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    }
1260ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    case SymbolRef::ST_Data:
1261ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    case SymbolRef::ST_Unknown: {
1262ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      Value.SymbolName = TargetName.data();
1263ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      Value.Addend = Addend;
1264ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines
1265ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      // Absolute relocations will have a zero symbol ID (STN_UNDEF), which
1266ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      // will manifest here as a NULL symbol name.
1267ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      // We can set this as a valid (but empty) symbol name, and rely
1268ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      // on addRelocationForSymbol to handle this.
1269ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      if (!Value.SymbolName)
1270ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines        Value.SymbolName = "";
1271ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      break;
1272ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    }
1273ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    default:
1274ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      llvm_unreachable("Unresolved symbol type!");
1275ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      break;
12760e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev    }
1277a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky  }
1278ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines
1279f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  uint64_t Offset = RelI->getOffset();
1280efa91f6475f6e96552986104ab4857db46185a2aRafael Espindola
128136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  DEBUG(dbgs() << "\t\tSectionID: " << SectionID << " Offset: " << Offset
12820e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev               << "\n");
128337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  if ((Arch == Triple::aarch64 || Arch == Triple::aarch64_be) &&
128436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      (RelType == ELF::R_AARCH64_CALL26 || RelType == ELF::R_AARCH64_JUMP26)) {
12854a9b6b798d5ea335f5f29d278db83b830ae4a564Tim Northover    // This is an AArch64 branch relocation, need to use a stub function.
12864a9b6b798d5ea335f5f29d278db83b830ae4a564Tim Northover    DEBUG(dbgs() << "\t\tThis is an AArch64 branch relocation.");
12874a9b6b798d5ea335f5f29d278db83b830ae4a564Tim Northover    SectionEntry &Section = Sections[SectionID];
12884a9b6b798d5ea335f5f29d278db83b830ae4a564Tim Northover
12894a9b6b798d5ea335f5f29d278db83b830ae4a564Tim Northover    // Look for an existing stub.
12904a9b6b798d5ea335f5f29d278db83b830ae4a564Tim Northover    StubMap::const_iterator i = Stubs.find(Value);
12914a9b6b798d5ea335f5f29d278db83b830ae4a564Tim Northover    if (i != Stubs.end()) {
1292f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      resolveRelocation(Section, Offset,
1293f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar                        (uint64_t)Section.getAddressWithOffset(i->second),
129436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                        RelType, 0);
12954a9b6b798d5ea335f5f29d278db83b830ae4a564Tim Northover      DEBUG(dbgs() << " Stub function found\n");
12964a9b6b798d5ea335f5f29d278db83b830ae4a564Tim Northover    } else {
12974a9b6b798d5ea335f5f29d278db83b830ae4a564Tim Northover      // Create a new stub function.
12984a9b6b798d5ea335f5f29d278db83b830ae4a564Tim Northover      DEBUG(dbgs() << " Create a new stub function\n");
1299f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      Stubs[Value] = Section.getStubOffset();
1300f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      uint8_t *StubTargetAddr = createStubFunction(
1301f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar          Section.getAddressWithOffset(Section.getStubOffset()));
13024a9b6b798d5ea335f5f29d278db83b830ae4a564Tim Northover
1303f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      RelocationEntry REmovz_g3(SectionID,
1304f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar                                StubTargetAddr - Section.getAddress(),
13054a9b6b798d5ea335f5f29d278db83b830ae4a564Tim Northover                                ELF::R_AARCH64_MOVW_UABS_G3, Value.Addend);
1306f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      RelocationEntry REmovk_g2(SectionID, StubTargetAddr -
1307f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar                                               Section.getAddress() + 4,
13084a9b6b798d5ea335f5f29d278db83b830ae4a564Tim Northover                                ELF::R_AARCH64_MOVW_UABS_G2_NC, Value.Addend);
1309f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      RelocationEntry REmovk_g1(SectionID, StubTargetAddr -
1310f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar                                               Section.getAddress() + 8,
13114a9b6b798d5ea335f5f29d278db83b830ae4a564Tim Northover                                ELF::R_AARCH64_MOVW_UABS_G1_NC, Value.Addend);
1312f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      RelocationEntry REmovk_g0(SectionID, StubTargetAddr -
1313f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar                                               Section.getAddress() + 12,
13144a9b6b798d5ea335f5f29d278db83b830ae4a564Tim Northover                                ELF::R_AARCH64_MOVW_UABS_G0_NC, Value.Addend);
13154a9b6b798d5ea335f5f29d278db83b830ae4a564Tim Northover
13164a9b6b798d5ea335f5f29d278db83b830ae4a564Tim Northover      if (Value.SymbolName) {
13174a9b6b798d5ea335f5f29d278db83b830ae4a564Tim Northover        addRelocationForSymbol(REmovz_g3, Value.SymbolName);
13184a9b6b798d5ea335f5f29d278db83b830ae4a564Tim Northover        addRelocationForSymbol(REmovk_g2, Value.SymbolName);
13194a9b6b798d5ea335f5f29d278db83b830ae4a564Tim Northover        addRelocationForSymbol(REmovk_g1, Value.SymbolName);
13204a9b6b798d5ea335f5f29d278db83b830ae4a564Tim Northover        addRelocationForSymbol(REmovk_g0, Value.SymbolName);
13214a9b6b798d5ea335f5f29d278db83b830ae4a564Tim Northover      } else {
13224a9b6b798d5ea335f5f29d278db83b830ae4a564Tim Northover        addRelocationForSection(REmovz_g3, Value.SectionID);
13234a9b6b798d5ea335f5f29d278db83b830ae4a564Tim Northover        addRelocationForSection(REmovk_g2, Value.SectionID);
13244a9b6b798d5ea335f5f29d278db83b830ae4a564Tim Northover        addRelocationForSection(REmovk_g1, Value.SectionID);
13254a9b6b798d5ea335f5f29d278db83b830ae4a564Tim Northover        addRelocationForSection(REmovk_g0, Value.SectionID);
13264a9b6b798d5ea335f5f29d278db83b830ae4a564Tim Northover      }
13274a9b6b798d5ea335f5f29d278db83b830ae4a564Tim Northover      resolveRelocation(Section, Offset,
1328f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar                        reinterpret_cast<uint64_t>(Section.getAddressWithOffset(
1329f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar                            Section.getStubOffset())),
1330f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar                        RelType, 0);
1331f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      Section.advanceStubOffset(getMaxStubSize());
13324a9b6b798d5ea335f5f29d278db83b830ae4a564Tim Northover    }
13336948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  } else if (Arch == Triple::arm) {
13346948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    if (RelType == ELF::R_ARM_PC24 || RelType == ELF::R_ARM_CALL ||
13356948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar      RelType == ELF::R_ARM_JUMP24) {
13366948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar      // This is an ARM branch relocation, need to use a stub function.
1337de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      DEBUG(dbgs() << "\t\tThis is an ARM branch relocation.\n");
13386948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar      SectionEntry &Section = Sections[SectionID];
13390e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev
13406948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar      // Look for an existing stub.
13416948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar      StubMap::const_iterator i = Stubs.find(Value);
13426948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar      if (i != Stubs.end()) {
1343f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar        resolveRelocation(
1344f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar            Section, Offset,
1345f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar            reinterpret_cast<uint64_t>(Section.getAddressWithOffset(i->second)),
1346f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar            RelType, 0);
13476948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar        DEBUG(dbgs() << " Stub function found\n");
13486948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar      } else {
13496948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar        // Create a new stub function.
13506948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar        DEBUG(dbgs() << " Create a new stub function\n");
1351f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar        Stubs[Value] = Section.getStubOffset();
1352f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar        uint8_t *StubTargetAddr = createStubFunction(
1353f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar            Section.getAddressWithOffset(Section.getStubOffset()));
1354f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar        RelocationEntry RE(SectionID, StubTargetAddr - Section.getAddress(),
1355f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar                           ELF::R_ARM_ABS32, Value.Addend);
13566948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar        if (Value.SymbolName)
13576948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar          addRelocationForSymbol(RE, Value.SymbolName);
13586948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar        else
13596948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar          addRelocationForSection(RE, Value.SectionID);
13606948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar
1361f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar        resolveRelocation(Section, Offset, reinterpret_cast<uint64_t>(
1362f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar                                               Section.getAddressWithOffset(
1363f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar                                                   Section.getStubOffset())),
1364f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar                          RelType, 0);
1365f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar        Section.advanceStubOffset(getMaxStubSize());
13666948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar      }
13676948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    } else {
13686948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar      uint32_t *Placeholder =
13696948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar        reinterpret_cast<uint32_t*>(computePlaceholderAddress(SectionID, Offset));
13706948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar      if (RelType == ELF::R_ARM_PREL31 || RelType == ELF::R_ARM_TARGET1 ||
13716948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar          RelType == ELF::R_ARM_ABS32) {
13726948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar        Value.Addend += *Placeholder;
13736948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar      } else if (RelType == ELF::R_ARM_MOVW_ABS_NC || RelType == ELF::R_ARM_MOVT_ABS) {
13746948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar        // See ELF for ARM documentation
13756948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar        Value.Addend += (int16_t)((*Placeholder & 0xFFF) | (((*Placeholder >> 16) & 0xF) << 12));
13766948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar      }
13776948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar      processSimpleRelocation(SectionID, Offset, RelType, Value);
13780e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev    }
13796948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  } else if (IsMipsO32ABI) {
13806948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    uint8_t *Placeholder = reinterpret_cast<uint8_t *>(
13816948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar        computePlaceholderAddress(SectionID, Offset));
13826948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    uint32_t Opcode = readBytesUnaligned(Placeholder, 4);
13836948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    if (RelType == ELF::R_MIPS_26) {
13846948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar      // This is an Mips branch relocation, need to use a stub function.
13856948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar      DEBUG(dbgs() << "\t\tThis is a Mips branch relocation.");
13866948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar      SectionEntry &Section = Sections[SectionID];
1387b889e0cd2fea4afee623d5be603b912b955a2ecaAkira Hatanaka
13886948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar      // Extract the addend from the instruction.
13896948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar      // We shift up by two since the Value will be down shifted again
13906948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar      // when applying the relocation.
13916948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar      uint32_t Addend = (Opcode & 0x03ffffff) << 2;
1392b889e0cd2fea4afee623d5be603b912b955a2ecaAkira Hatanaka
13936948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar      Value.Addend += Addend;
1394b889e0cd2fea4afee623d5be603b912b955a2ecaAkira Hatanaka
13956948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar      //  Look up for existing stub.
13966948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar      StubMap::const_iterator i = Stubs.find(Value);
13976948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar      if (i != Stubs.end()) {
13986948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar        RelocationEntry RE(SectionID, Offset, RelType, i->second);
13996948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar        addRelocationForSection(RE, SectionID);
14006948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar        DEBUG(dbgs() << " Stub function found\n");
14016948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar      } else {
14026948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar        // Create a new stub function.
14036948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar        DEBUG(dbgs() << " Create a new stub function\n");
1404f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar        Stubs[Value] = Section.getStubOffset();
1405f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar        uint8_t *StubTargetAddr = createStubFunction(
1406f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar            Section.getAddressWithOffset(Section.getStubOffset()));
1407b889e0cd2fea4afee623d5be603b912b955a2ecaAkira Hatanaka
14086948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar        // Creating Hi and Lo relocations for the filled stub instructions.
1409f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar        RelocationEntry REHi(SectionID, StubTargetAddr - Section.getAddress(),
1410f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar                             ELF::R_MIPS_HI16, Value.Addend);
1411f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar        RelocationEntry RELo(SectionID,
1412f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar                             StubTargetAddr - Section.getAddress() + 4,
1413f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar                             ELF::R_MIPS_LO16, Value.Addend);
1414b889e0cd2fea4afee623d5be603b912b955a2ecaAkira Hatanaka
14156948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar        if (Value.SymbolName) {
14166948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar          addRelocationForSymbol(REHi, Value.SymbolName);
14176948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar          addRelocationForSymbol(RELo, Value.SymbolName);
14186948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar        }
14196948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar        else {
14206948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar          addRelocationForSection(REHi, Value.SectionID);
14216948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar          addRelocationForSection(RELo, Value.SectionID);
14226948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar        }
1423b889e0cd2fea4afee623d5be603b912b955a2ecaAkira Hatanaka
1424f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar        RelocationEntry RE(SectionID, Offset, RelType, Section.getStubOffset());
14256948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar        addRelocationForSection(RE, SectionID);
1426f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar        Section.advanceStubOffset(getMaxStubSize());
14276948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar      }
1428f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    } else if (RelType == ELF::R_MIPS_HI16 || RelType == ELF::R_MIPS_PCHI16) {
1429f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      int64_t Addend = (Opcode & 0x0000ffff) << 16;
1430f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      RelocationEntry RE(SectionID, Offset, RelType, Addend);
1431f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      PendingRelocs.push_back(std::make_pair(Value, RE));
1432f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    } else if (RelType == ELF::R_MIPS_LO16 || RelType == ELF::R_MIPS_PCLO16) {
1433f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      int64_t Addend = Value.Addend + SignExtend32<16>(Opcode & 0x0000ffff);
1434f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      for (auto I = PendingRelocs.begin(); I != PendingRelocs.end();) {
1435f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar        const RelocationValueRef &MatchingValue = I->first;
1436f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar        RelocationEntry &Reloc = I->second;
1437f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar        if (MatchingValue == Value &&
1438f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar            RelType == getMatchingLoRelocation(Reloc.RelType) &&
1439f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar            SectionID == Reloc.SectionID) {
1440f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar          Reloc.Addend += Addend;
1441f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar          if (Value.SymbolName)
1442f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar            addRelocationForSymbol(Reloc, Value.SymbolName);
1443f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar          else
1444f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar            addRelocationForSection(Reloc, Value.SectionID);
1445f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar          I = PendingRelocs.erase(I);
1446f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar        } else
1447f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar          ++I;
1448f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      }
1449f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      RelocationEntry RE(SectionID, Offset, RelType, Addend);
1450f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      if (Value.SymbolName)
1451f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar        addRelocationForSymbol(RE, Value.SymbolName);
1452f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      else
1453f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar        addRelocationForSection(RE, Value.SectionID);
14546948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    } else {
1455f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      if (RelType == ELF::R_MIPS_32)
14566948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar        Value.Addend += Opcode;
1457f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      else if (RelType == ELF::R_MIPS_PC16)
1458f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar        Value.Addend += SignExtend32<18>((Opcode & 0x0000ffff) << 2);
1459f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      else if (RelType == ELF::R_MIPS_PC19_S2)
1460f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar        Value.Addend += SignExtend32<21>((Opcode & 0x0007ffff) << 2);
1461f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      else if (RelType == ELF::R_MIPS_PC21_S2)
1462f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar        Value.Addend += SignExtend32<23>((Opcode & 0x001fffff) << 2);
1463f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      else if (RelType == ELF::R_MIPS_PC26_S2)
1464f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar        Value.Addend += SignExtend32<28>((Opcode & 0x03ffffff) << 2);
14656948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar      processSimpleRelocation(SectionID, Offset, RelType, Value);
1466b889e0cd2fea4afee623d5be603b912b955a2ecaAkira Hatanaka    }
14676948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  } else if (IsMipsN64ABI) {
14686948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    uint32_t r_type = RelType & 0xff;
14696948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    RelocationEntry RE(SectionID, Offset, RelType, Value.Addend);
14706948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    if (r_type == ELF::R_MIPS_CALL16 || r_type == ELF::R_MIPS_GOT_PAGE
14716948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar        || r_type == ELF::R_MIPS_GOT_DISP) {
14726948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar      StringMap<uint64_t>::iterator i = GOTSymbolOffsets.find(TargetName);
14736948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar      if (i != GOTSymbolOffsets.end())
14746948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar        RE.SymOffset = i->second;
14756948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar      else {
14766948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar        RE.SymOffset = allocateGOTEntries(SectionID, 1);
14776948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar        GOTSymbolOffsets[TargetName] = RE.SymOffset;
14786948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar      }
14796948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    }
14806948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    if (Value.SymbolName)
14816948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar      addRelocationForSymbol(RE, Value.SymbolName);
14826948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    else
14836948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar      addRelocationForSection(RE, Value.SectionID);
1484f38cc38fa647d4e72c053c39bbe0cdec1342535fBill Schmidt  } else if (Arch == Triple::ppc64 || Arch == Triple::ppc64le) {
14856e8946c5280ad6071d21013651745a9478f063edAdhemerval Zanella    if (RelType == ELF::R_PPC64_REL24) {
148637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      // Determine ABI variant in use for this object.
148737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      unsigned AbiVariant;
1488ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      Obj.getPlatformFlags(AbiVariant);
148937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      AbiVariant &= ELF::EF_PPC64_ABI;
14906e8946c5280ad6071d21013651745a9478f063edAdhemerval Zanella      // A PPC branch relocation will need a stub function if the target is
14916e8946c5280ad6071d21013651745a9478f063edAdhemerval Zanella      // an external symbol (Symbol::ST_Unknown) or if the target address
14926e8946c5280ad6071d21013651745a9478f063edAdhemerval Zanella      // is not within the signed 24-bits branch address.
1493efa91f6475f6e96552986104ab4857db46185a2aRafael Espindola      SectionEntry &Section = Sections[SectionID];
1494f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      uint8_t *Target = Section.getAddressWithOffset(Offset);
14956e8946c5280ad6071d21013651745a9478f063edAdhemerval Zanella      bool RangeOverflow = false;
14966e8946c5280ad6071d21013651745a9478f063edAdhemerval Zanella      if (SymType != SymbolRef::ST_Unknown) {
149737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines        if (AbiVariant != 2) {
149837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines          // In the ELFv1 ABI, a function call may point to the .opd entry,
149937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines          // so the final symbol value is calculated based on the relocation
150037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines          // values in the .opd section.
1501de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar          if (auto Err = findOPDEntrySection(Obj, ObjSectionToID, Value))
1502de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar            return std::move(Err);
150337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines        } else {
150437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines          // In the ELFv2 ABI, a function symbol may provide a local entry
150537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines          // point, which must be used for direct calls.
1506f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar          uint8_t SymOther = Symbol->getOther();
150737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines          Value.Addend += ELF::decodePPC64LocalEntryOffset(SymOther);
150837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines        }
1509f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar        uint8_t *RelocTarget =
1510f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar            Sections[Value.SectionID].getAddressWithOffset(Value.Addend);
15116e8946c5280ad6071d21013651745a9478f063edAdhemerval Zanella        int32_t delta = static_cast<int32_t>(Target - RelocTarget);
1512f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar        // If it is within 26-bits branch range, just set the branch target
1513f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar        if (SignExtend32<26>(delta) == delta) {
1514efa91f6475f6e96552986104ab4857db46185a2aRafael Espindola          RelocationEntry RE(SectionID, Offset, RelType, Value.Addend);
15156e8946c5280ad6071d21013651745a9478f063edAdhemerval Zanella          if (Value.SymbolName)
15166e8946c5280ad6071d21013651745a9478f063edAdhemerval Zanella            addRelocationForSymbol(RE, Value.SymbolName);
15176e8946c5280ad6071d21013651745a9478f063edAdhemerval Zanella          else
15186e8946c5280ad6071d21013651745a9478f063edAdhemerval Zanella            addRelocationForSection(RE, Value.SectionID);
15196e8946c5280ad6071d21013651745a9478f063edAdhemerval Zanella        } else {
15206e8946c5280ad6071d21013651745a9478f063edAdhemerval Zanella          RangeOverflow = true;
15216e8946c5280ad6071d21013651745a9478f063edAdhemerval Zanella        }
15226e8946c5280ad6071d21013651745a9478f063edAdhemerval Zanella      }
15234c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar      if (SymType == SymbolRef::ST_Unknown || RangeOverflow) {
15246e8946c5280ad6071d21013651745a9478f063edAdhemerval Zanella        // It is an external symbol (SymbolRef::ST_Unknown) or within a range
15256e8946c5280ad6071d21013651745a9478f063edAdhemerval Zanella        // larger than 24-bits.
15266e8946c5280ad6071d21013651745a9478f063edAdhemerval Zanella        StubMap::const_iterator i = Stubs.find(Value);
15276e8946c5280ad6071d21013651745a9478f063edAdhemerval Zanella        if (i != Stubs.end()) {
15286e8946c5280ad6071d21013651745a9478f063edAdhemerval Zanella          // Symbol function stub already created, just relocate to it
1529efa91f6475f6e96552986104ab4857db46185a2aRafael Espindola          resolveRelocation(Section, Offset,
1530f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar                            reinterpret_cast<uint64_t>(
1531f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar                                Section.getAddressWithOffset(i->second)),
1532f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar                            RelType, 0);
15336e8946c5280ad6071d21013651745a9478f063edAdhemerval Zanella          DEBUG(dbgs() << " Stub function found\n");
15346e8946c5280ad6071d21013651745a9478f063edAdhemerval Zanella        } else {
15356e8946c5280ad6071d21013651745a9478f063edAdhemerval Zanella          // Create a new stub function.
15366e8946c5280ad6071d21013651745a9478f063edAdhemerval Zanella          DEBUG(dbgs() << " Create a new stub function\n");
1537f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar          Stubs[Value] = Section.getStubOffset();
1538f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar          uint8_t *StubTargetAddr = createStubFunction(
1539f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar              Section.getAddressWithOffset(Section.getStubOffset()),
1540f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar              AbiVariant);
1541f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar          RelocationEntry RE(SectionID, StubTargetAddr - Section.getAddress(),
15426e8946c5280ad6071d21013651745a9478f063edAdhemerval Zanella                             ELF::R_PPC64_ADDR64, Value.Addend);
15436e8946c5280ad6071d21013651745a9478f063edAdhemerval Zanella
15446e8946c5280ad6071d21013651745a9478f063edAdhemerval Zanella          // Generates the 64-bits address loads as exemplified in section
1545c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines          // 4.5.1 in PPC64 ELF ABI.  Note that the relocations need to
1546c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines          // apply to the low part of the instructions, so we have to update
1547c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines          // the offset according to the target endianness.
1548f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar          uint64_t StubRelocOffset = StubTargetAddr - Section.getAddress();
1549c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines          if (!IsTargetLittleEndian)
1550c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines            StubRelocOffset += 2;
1551c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines
1552c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines          RelocationEntry REhst(SectionID, StubRelocOffset + 0,
15536e8946c5280ad6071d21013651745a9478f063edAdhemerval Zanella                                ELF::R_PPC64_ADDR16_HIGHEST, Value.Addend);
1554c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines          RelocationEntry REhr(SectionID, StubRelocOffset + 4,
15556e8946c5280ad6071d21013651745a9478f063edAdhemerval Zanella                               ELF::R_PPC64_ADDR16_HIGHER, Value.Addend);
1556c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines          RelocationEntry REh(SectionID, StubRelocOffset + 12,
15576e8946c5280ad6071d21013651745a9478f063edAdhemerval Zanella                              ELF::R_PPC64_ADDR16_HI, Value.Addend);
1558c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines          RelocationEntry REl(SectionID, StubRelocOffset + 16,
15596e8946c5280ad6071d21013651745a9478f063edAdhemerval Zanella                              ELF::R_PPC64_ADDR16_LO, Value.Addend);
15606e8946c5280ad6071d21013651745a9478f063edAdhemerval Zanella
15616e8946c5280ad6071d21013651745a9478f063edAdhemerval Zanella          if (Value.SymbolName) {
15626e8946c5280ad6071d21013651745a9478f063edAdhemerval Zanella            addRelocationForSymbol(REhst, Value.SymbolName);
156336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines            addRelocationForSymbol(REhr, Value.SymbolName);
156436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines            addRelocationForSymbol(REh, Value.SymbolName);
156536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines            addRelocationForSymbol(REl, Value.SymbolName);
15666e8946c5280ad6071d21013651745a9478f063edAdhemerval Zanella          } else {
15676e8946c5280ad6071d21013651745a9478f063edAdhemerval Zanella            addRelocationForSection(REhst, Value.SectionID);
156836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines            addRelocationForSection(REhr, Value.SectionID);
156936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines            addRelocationForSection(REh, Value.SectionID);
157036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines            addRelocationForSection(REl, Value.SectionID);
15716e8946c5280ad6071d21013651745a9478f063edAdhemerval Zanella          }
15726e8946c5280ad6071d21013651745a9478f063edAdhemerval Zanella
1573f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar          resolveRelocation(Section, Offset, reinterpret_cast<uint64_t>(
1574f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar                                                 Section.getAddressWithOffset(
1575f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar                                                     Section.getStubOffset())),
1576a307a1cf859f4a523951ac887d094039547adeb5Andrew Kaylor                            RelType, 0);
1577f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar          Section.advanceStubOffset(getMaxStubSize());
15786e8946c5280ad6071d21013651745a9478f063edAdhemerval Zanella        }
157937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines        if (SymType == SymbolRef::ST_Unknown) {
158036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines          // Restore the TOC for external calls
158137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines          if (AbiVariant == 2)
158237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines            writeInt32BE(Target + 4, 0xE8410018); // ld r2,28(r1)
158337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines          else
158437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines            writeInt32BE(Target + 4, 0xE8410028); // ld r2,40(r1)
158537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines        }
15866e8946c5280ad6071d21013651745a9478f063edAdhemerval Zanella      }
1587c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines    } else if (RelType == ELF::R_PPC64_TOC16 ||
1588c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines               RelType == ELF::R_PPC64_TOC16_DS ||
1589c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines               RelType == ELF::R_PPC64_TOC16_LO ||
1590c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines               RelType == ELF::R_PPC64_TOC16_LO_DS ||
1591c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines               RelType == ELF::R_PPC64_TOC16_HI ||
1592c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines               RelType == ELF::R_PPC64_TOC16_HA) {
1593c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines      // These relocations are supposed to subtract the TOC address from
1594c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines      // the final value.  This does not fit cleanly into the RuntimeDyld
1595c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines      // scheme, since there may be *two* sections involved in determining
1596f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      // the relocation value (the section of the symbol referred to by the
1597c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines      // relocation, and the TOC section associated with the current module).
1598c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines      //
1599c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines      // Fortunately, these relocations are currently only ever generated
1600f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      // referring to symbols that themselves reside in the TOC, which means
1601c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines      // that the two sections are actually the same.  Thus they cancel out
1602c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines      // and we can immediately resolve the relocation right now.
1603c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines      switch (RelType) {
1604c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines      case ELF::R_PPC64_TOC16: RelType = ELF::R_PPC64_ADDR16; break;
1605c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines      case ELF::R_PPC64_TOC16_DS: RelType = ELF::R_PPC64_ADDR16_DS; break;
1606c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines      case ELF::R_PPC64_TOC16_LO: RelType = ELF::R_PPC64_ADDR16_LO; break;
1607c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines      case ELF::R_PPC64_TOC16_LO_DS: RelType = ELF::R_PPC64_ADDR16_LO_DS; break;
1608c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines      case ELF::R_PPC64_TOC16_HI: RelType = ELF::R_PPC64_ADDR16_HI; break;
1609c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines      case ELF::R_PPC64_TOC16_HA: RelType = ELF::R_PPC64_ADDR16_HA; break;
1610c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines      default: llvm_unreachable("Wrong relocation type.");
1611c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines      }
1612c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines
1613c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines      RelocationValueRef TOCValue;
1614de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      if (auto Err = findPPC64TOCSection(Obj, ObjSectionToID, TOCValue))
1615de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar        return std::move(Err);
1616c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines      if (Value.SymbolName || Value.SectionID != TOCValue.SectionID)
1617c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines        llvm_unreachable("Unsupported TOC relocation.");
1618c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines      Value.Addend -= TOCValue.Addend;
1619c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines      resolveRelocation(Sections[SectionID], Offset, Value.Addend, RelType, 0);
16206e8946c5280ad6071d21013651745a9478f063edAdhemerval Zanella    } else {
1621c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines      // There are two ways to refer to the TOC address directly: either
1622c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines      // via a ELF::R_PPC64_TOC relocation (where both symbol and addend are
1623c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines      // ignored), or via any relocation that refers to the magic ".TOC."
1624c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines      // symbols (in which case the addend is respected).
1625c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines      if (RelType == ELF::R_PPC64_TOC) {
1626c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines        RelType = ELF::R_PPC64_ADDR64;
1627de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar        if (auto Err = findPPC64TOCSection(Obj, ObjSectionToID, Value))
1628de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar          return std::move(Err);
1629c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines      } else if (TargetName == ".TOC.") {
1630de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar        if (auto Err = findPPC64TOCSection(Obj, ObjSectionToID, Value))
1631de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar          return std::move(Err);
1632c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines        Value.Addend += Addend;
1633c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines      }
1634c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines
1635efa91f6475f6e96552986104ab4857db46185a2aRafael Espindola      RelocationEntry RE(SectionID, Offset, RelType, Value.Addend);
1636b0f79298851836cdfcca90252260d007d7561cadRichard Mitton
1637b0f79298851836cdfcca90252260d007d7561cadRichard Mitton      if (Value.SymbolName)
16386e8946c5280ad6071d21013651745a9478f063edAdhemerval Zanella        addRelocationForSymbol(RE, Value.SymbolName);
16396e8946c5280ad6071d21013651745a9478f063edAdhemerval Zanella      else
16406e8946c5280ad6071d21013651745a9478f063edAdhemerval Zanella        addRelocationForSection(RE, Value.SectionID);
16416e8946c5280ad6071d21013651745a9478f063edAdhemerval Zanella    }
16426fc2ad62e23673ef829c9c4bbf62743d30928a5bRichard Sandiford  } else if (Arch == Triple::systemz &&
164336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines             (RelType == ELF::R_390_PLT32DBL || RelType == ELF::R_390_GOTENT)) {
16446fc2ad62e23673ef829c9c4bbf62743d30928a5bRichard Sandiford    // Create function stubs for both PLT and GOT references, regardless of
16456fc2ad62e23673ef829c9c4bbf62743d30928a5bRichard Sandiford    // whether the GOT reference is to data or code.  The stub contains the
16466fc2ad62e23673ef829c9c4bbf62743d30928a5bRichard Sandiford    // full address of the symbol, as needed by GOT references, and the
16476fc2ad62e23673ef829c9c4bbf62743d30928a5bRichard Sandiford    // executable part only adds an overhead of 8 bytes.
16486fc2ad62e23673ef829c9c4bbf62743d30928a5bRichard Sandiford    //
16496fc2ad62e23673ef829c9c4bbf62743d30928a5bRichard Sandiford    // We could try to conserve space by allocating the code and data
16506fc2ad62e23673ef829c9c4bbf62743d30928a5bRichard Sandiford    // parts of the stub separately.  However, as things stand, we allocate
16516fc2ad62e23673ef829c9c4bbf62743d30928a5bRichard Sandiford    // a stub for every relocation, so using a GOT in JIT code should be
16526fc2ad62e23673ef829c9c4bbf62743d30928a5bRichard Sandiford    // no less space efficient than using an explicit constant pool.
16536fc2ad62e23673ef829c9c4bbf62743d30928a5bRichard Sandiford    DEBUG(dbgs() << "\t\tThis is a SystemZ indirect relocation.");
16546fc2ad62e23673ef829c9c4bbf62743d30928a5bRichard Sandiford    SectionEntry &Section = Sections[SectionID];
16556fc2ad62e23673ef829c9c4bbf62743d30928a5bRichard Sandiford
16566fc2ad62e23673ef829c9c4bbf62743d30928a5bRichard Sandiford    // Look for an existing stub.
16576fc2ad62e23673ef829c9c4bbf62743d30928a5bRichard Sandiford    StubMap::const_iterator i = Stubs.find(Value);
16586fc2ad62e23673ef829c9c4bbf62743d30928a5bRichard Sandiford    uintptr_t StubAddress;
16596fc2ad62e23673ef829c9c4bbf62743d30928a5bRichard Sandiford    if (i != Stubs.end()) {
1660f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      StubAddress = uintptr_t(Section.getAddressWithOffset(i->second));
16616fc2ad62e23673ef829c9c4bbf62743d30928a5bRichard Sandiford      DEBUG(dbgs() << " Stub function found\n");
16626fc2ad62e23673ef829c9c4bbf62743d30928a5bRichard Sandiford    } else {
16636fc2ad62e23673ef829c9c4bbf62743d30928a5bRichard Sandiford      // Create a new stub function.
16646fc2ad62e23673ef829c9c4bbf62743d30928a5bRichard Sandiford      DEBUG(dbgs() << " Create a new stub function\n");
16656fc2ad62e23673ef829c9c4bbf62743d30928a5bRichard Sandiford
1666f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      uintptr_t BaseAddress = uintptr_t(Section.getAddress());
16676fc2ad62e23673ef829c9c4bbf62743d30928a5bRichard Sandiford      uintptr_t StubAlignment = getStubAlignment();
1668f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      StubAddress =
1669f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar          (BaseAddress + Section.getStubOffset() + StubAlignment - 1) &
1670f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar          -StubAlignment;
16716fc2ad62e23673ef829c9c4bbf62743d30928a5bRichard Sandiford      unsigned StubOffset = StubAddress - BaseAddress;
16726fc2ad62e23673ef829c9c4bbf62743d30928a5bRichard Sandiford
16736fc2ad62e23673ef829c9c4bbf62743d30928a5bRichard Sandiford      Stubs[Value] = StubOffset;
16746fc2ad62e23673ef829c9c4bbf62743d30928a5bRichard Sandiford      createStubFunction((uint8_t *)StubAddress);
167536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      RelocationEntry RE(SectionID, StubOffset + 8, ELF::R_390_64,
167637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines                         Value.Offset);
16776fc2ad62e23673ef829c9c4bbf62743d30928a5bRichard Sandiford      if (Value.SymbolName)
16786fc2ad62e23673ef829c9c4bbf62743d30928a5bRichard Sandiford        addRelocationForSymbol(RE, Value.SymbolName);
16796fc2ad62e23673ef829c9c4bbf62743d30928a5bRichard Sandiford      else
16806fc2ad62e23673ef829c9c4bbf62743d30928a5bRichard Sandiford        addRelocationForSection(RE, Value.SectionID);
1681f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      Section.advanceStubOffset(getMaxStubSize());
16826fc2ad62e23673ef829c9c4bbf62743d30928a5bRichard Sandiford    }
16836fc2ad62e23673ef829c9c4bbf62743d30928a5bRichard Sandiford
16846fc2ad62e23673ef829c9c4bbf62743d30928a5bRichard Sandiford    if (RelType == ELF::R_390_GOTENT)
168536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      resolveRelocation(Section, Offset, StubAddress + 8, ELF::R_390_PC32DBL,
168636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                        Addend);
16876fc2ad62e23673ef829c9c4bbf62743d30928a5bRichard Sandiford    else
16886fc2ad62e23673ef829c9c4bbf62743d30928a5bRichard Sandiford      resolveRelocation(Section, Offset, StubAddress, RelType, Addend);
16896948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  } else if (Arch == Triple::x86_64) {
16906948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    if (RelType == ELF::R_X86_64_PLT32) {
16916948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar      // The way the PLT relocations normally work is that the linker allocates
16926948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar      // the
16936948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar      // PLT and this relocation makes a PC-relative call into the PLT.  The PLT
16946948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar      // entry will then jump to an address provided by the GOT.  On first call,
16956948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar      // the
16966948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar      // GOT address will point back into PLT code that resolves the symbol. After
16976948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar      // the first call, the GOT entry points to the actual function.
16986948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar      //
16996948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar      // For local functions we're ignoring all of that here and just replacing
17006948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar      // the PLT32 relocation type with PC32, which will translate the relocation
17016948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar      // into a PC-relative call directly to the function. For external symbols we
17026948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar      // can't be sure the function will be within 2^32 bytes of the call site, so
17036948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar      // we need to create a stub, which calls into the GOT.  This case is
17046948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar      // equivalent to the usual PLT implementation except that we use the stub
17056948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar      // mechanism in RuntimeDyld (which puts stubs at the end of the section)
17066948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar      // rather than allocating a PLT section.
17076948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar      if (Value.SymbolName) {
17086948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar        // This is a call to an external function.
17096948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar        // Look for an existing stub.
17106948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar        SectionEntry &Section = Sections[SectionID];
17116948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar        StubMap::const_iterator i = Stubs.find(Value);
17126948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar        uintptr_t StubAddress;
17136948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar        if (i != Stubs.end()) {
1714f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar          StubAddress = uintptr_t(Section.getAddress()) + i->second;
1715f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar          DEBUG(dbgs() << " Stub function found\n");
17166948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar        } else {
1717f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar          // Create a new stub function (equivalent to a PLT entry).
1718f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar          DEBUG(dbgs() << " Create a new stub function\n");
1719ff9fa05905be716435460b5f6d32689041bf895bAndrew Kaylor
1720f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar          uintptr_t BaseAddress = uintptr_t(Section.getAddress());
1721f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar          uintptr_t StubAlignment = getStubAlignment();
1722f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar          StubAddress =
1723f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar              (BaseAddress + Section.getStubOffset() + StubAlignment - 1) &
1724f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar              -StubAlignment;
1725f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar          unsigned StubOffset = StubAddress - BaseAddress;
1726f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar          Stubs[Value] = StubOffset;
1727f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar          createStubFunction((uint8_t *)StubAddress);
1728ff9fa05905be716435460b5f6d32689041bf895bAndrew Kaylor
1729f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar          // Bump our stub offset counter
1730f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar          Section.advanceStubOffset(getMaxStubSize());
17310c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar
1732f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar          // Allocate a GOT Entry
1733f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar          uint64_t GOTOffset = allocateGOTEntries(SectionID, 1);
17340c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar
1735f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar          // The load of the GOT address has an addend of -4
1736f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar          resolveGOTOffsetRelocation(SectionID, StubOffset + 2, GOTOffset - 4);
17370c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar
1738f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar          // Fill in the value of the symbol we're targeting into the GOT
1739f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar          addRelocationForSymbol(
1740f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar              computeGOTOffsetRE(SectionID, GOTOffset, 0, ELF::R_X86_64_64),
1741f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar              Value.SymbolName);
17426948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar        }
17436948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar
17446948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar        // Make the target call a call into the stub table.
17456948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar        resolveRelocation(Section, Offset, StubAddress, ELF::R_X86_64_PC32,
1746f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar                          Addend);
17476948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar      } else {
17486948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar        RelocationEntry RE(SectionID, Offset, ELF::R_X86_64_PC32, Value.Addend,
17496948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar                  Value.Offset);
17506948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar        addRelocationForSection(RE, Value.SectionID);
1751ff9fa05905be716435460b5f6d32689041bf895bAndrew Kaylor      }
1752de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    } else if (RelType == ELF::R_X86_64_GOTPCREL ||
1753de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar               RelType == ELF::R_X86_64_GOTPCRELX ||
1754de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar               RelType == ELF::R_X86_64_REX_GOTPCRELX) {
17556948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar      uint64_t GOTOffset = allocateGOTEntries(SectionID, 1);
17566948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar      resolveGOTOffsetRelocation(SectionID, Offset, GOTOffset + Addend);
1757ff9fa05905be716435460b5f6d32689041bf895bAndrew Kaylor
17586948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar      // Fill in the value of the symbol we're targeting into the GOT
17596948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar      RelocationEntry RE = computeGOTOffsetRE(SectionID, GOTOffset, Value.Offset, ELF::R_X86_64_64);
17606948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar      if (Value.SymbolName)
17616948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar        addRelocationForSymbol(RE, Value.SymbolName);
17626948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar      else
17636948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar        addRelocationForSection(RE, Value.SectionID);
17646948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    } else if (RelType == ELF::R_X86_64_PC32) {
17656948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar      Value.Addend += support::ulittle32_t::ref(computePlaceholderAddress(SectionID, Offset));
17666948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar      processSimpleRelocation(SectionID, Offset, RelType, Value);
17676948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    } else if (RelType == ELF::R_X86_64_PC64) {
17686948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar      Value.Addend += support::ulittle64_t::ref(computePlaceholderAddress(SectionID, Offset));
17696948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar      processSimpleRelocation(SectionID, Offset, RelType, Value);
1770ff9fa05905be716435460b5f6d32689041bf895bAndrew Kaylor    } else {
17716948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar      processSimpleRelocation(SectionID, Offset, RelType, Value);
1772ff9fa05905be716435460b5f6d32689041bf895bAndrew Kaylor    }
1773c201e6eaf165c83f0092c43b371e509fa8eaf4ccEli Bendersky  } else {
17746948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    if (Arch == Triple::x86) {
17756948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar      Value.Addend += support::ulittle32_t::ref(computePlaceholderAddress(SectionID, Offset));
17766948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    }
17776948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    processSimpleRelocation(SectionID, Offset, RelType, Value);
1778c201e6eaf165c83f0092c43b371e509fa8eaf4ccEli Bendersky  }
177936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  return ++RelI;
178061425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach}
178161425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach
1782ff9fa05905be716435460b5f6d32689041bf895bAndrew Kaylorsize_t RuntimeDyldELF::getGOTEntrySize() {
1783ff9fa05905be716435460b5f6d32689041bf895bAndrew Kaylor  // We don't use the GOT in all of these cases, but it's essentially free
1784ff9fa05905be716435460b5f6d32689041bf895bAndrew Kaylor  // to put them all here.
1785ff9fa05905be716435460b5f6d32689041bf895bAndrew Kaylor  size_t Result = 0;
1786ff9fa05905be716435460b5f6d32689041bf895bAndrew Kaylor  switch (Arch) {
1787ff9fa05905be716435460b5f6d32689041bf895bAndrew Kaylor  case Triple::x86_64:
1788ff9fa05905be716435460b5f6d32689041bf895bAndrew Kaylor  case Triple::aarch64:
1789dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case Triple::aarch64_be:
1790ff9fa05905be716435460b5f6d32689041bf895bAndrew Kaylor  case Triple::ppc64:
1791ff9fa05905be716435460b5f6d32689041bf895bAndrew Kaylor  case Triple::ppc64le:
1792ff9fa05905be716435460b5f6d32689041bf895bAndrew Kaylor  case Triple::systemz:
1793ff9fa05905be716435460b5f6d32689041bf895bAndrew Kaylor    Result = sizeof(uint64_t);
1794ff9fa05905be716435460b5f6d32689041bf895bAndrew Kaylor    break;
1795ff9fa05905be716435460b5f6d32689041bf895bAndrew Kaylor  case Triple::x86:
1796ff9fa05905be716435460b5f6d32689041bf895bAndrew Kaylor  case Triple::arm:
1797ff9fa05905be716435460b5f6d32689041bf895bAndrew Kaylor  case Triple::thumb:
17986948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    Result = sizeof(uint32_t);
17996948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    break;
1800ff9fa05905be716435460b5f6d32689041bf895bAndrew Kaylor  case Triple::mips:
1801ff9fa05905be716435460b5f6d32689041bf895bAndrew Kaylor  case Triple::mipsel:
18026948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  case Triple::mips64:
18036948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  case Triple::mips64el:
18046948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    if (IsMipsO32ABI)
18056948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar      Result = sizeof(uint32_t);
18066948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    else if (IsMipsN64ABI)
18076948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar      Result = sizeof(uint64_t);
18086948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    else
18096948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar      llvm_unreachable("Mips ABI not handled");
1810ff9fa05905be716435460b5f6d32689041bf895bAndrew Kaylor    break;
181136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  default:
181236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    llvm_unreachable("Unsupported CPU type!");
1813ff9fa05905be716435460b5f6d32689041bf895bAndrew Kaylor  }
1814ff9fa05905be716435460b5f6d32689041bf895bAndrew Kaylor  return Result;
1815ff9fa05905be716435460b5f6d32689041bf895bAndrew Kaylor}
1816ff9fa05905be716435460b5f6d32689041bf895bAndrew Kaylor
18170c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainaruint64_t RuntimeDyldELF::allocateGOTEntries(unsigned SectionID, unsigned no)
18180c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar{
18190c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  (void)SectionID; // The GOT Section is the same for all section in the object file
18200c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  if (GOTSectionID == 0) {
18210c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    GOTSectionID = Sections.size();
18220c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    // Reserve a section id. We'll allocate the section later
18230c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    // once we know the total size
1824f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    Sections.push_back(SectionEntry(".got", nullptr, 0, 0, 0));
1825ff9fa05905be716435460b5f6d32689041bf895bAndrew Kaylor  }
18260c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  uint64_t StartOffset = CurrentGOTIndex * getGOTEntrySize();
18270c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  CurrentGOTIndex += no;
18280c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  return StartOffset;
18290c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar}
1830ff9fa05905be716435460b5f6d32689041bf895bAndrew Kaylor
18310c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainarvoid RuntimeDyldELF::resolveGOTOffsetRelocation(unsigned SectionID, uint64_t Offset, uint64_t GOTOffset)
18320c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar{
18330c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  // Fill in the relative address of the GOT Entry into the stub
18340c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  RelocationEntry GOTRE(SectionID, Offset, ELF::R_X86_64_PC32, GOTOffset);
18350c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  addRelocationForSection(GOTRE, GOTSectionID);
18360c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar}
18370c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar
18380c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga NainarRelocationEntry RuntimeDyldELF::computeGOTOffsetRE(unsigned SectionID, uint64_t GOTOffset, uint64_t SymbolOffset,
18390c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar                                                   uint32_t Type)
18400c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar{
18410c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  (void)SectionID; // The GOT Section is the same for all section in the object file
18420c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  return RelocationEntry(GOTSectionID, GOTOffset, Type, SymbolOffset);
1843ff9fa05905be716435460b5f6d32689041bf895bAndrew Kaylor}
1844ff9fa05905be716435460b5f6d32689041bf895bAndrew Kaylor
1845de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga NainarError RuntimeDyldELF::finalizeLoad(const ObjectFile &Obj,
1846dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                                  ObjSectionToIDMap &SectionMap) {
1847f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  if (IsMipsO32ABI)
1848f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    if (!PendingRelocs.empty())
1849de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      return make_error<RuntimeDyldError>("Can't find matching LO16 reloc");
1850f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
1851528f6d787b1a847e61eb2f1114559f423fdeb68cAndrew Kaylor  // If necessary, allocate the global offset table
18520c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  if (GOTSectionID != 0) {
18530c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    // Allocate memory for the section
18540c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    size_t TotalSize = CurrentGOTIndex * getGOTEntrySize();
18550c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    uint8_t *Addr = MemMgr.allocateDataSection(TotalSize, getGOTEntrySize(),
18560c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar                                                GOTSectionID, ".got", false);
18570c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    if (!Addr)
1858de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      return make_error<RuntimeDyldError>("Unable to allocate memory for GOT!");
18590c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar
1860f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    Sections[GOTSectionID] =
1861f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar        SectionEntry(".got", Addr, TotalSize, TotalSize, 0);
18620c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar
18630c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    if (Checker)
18640c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar      Checker->registerSection(Obj.getFileName(), GOTSectionID);
18650c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar
18660c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    // For now, initialize all GOT entries to zero.  We'll fill them in as
18670c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    // needed when GOT-based relocations are applied.
18680c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    memset(Addr, 0, TotalSize);
18696948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    if (IsMipsN64ABI) {
18706948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar      // To correctly resolve Mips GOT relocations, we need a mapping from
18716948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar      // object's sections to GOTs.
18726948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar      for (section_iterator SI = Obj.section_begin(), SE = Obj.section_end();
18736948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar           SI != SE; ++SI) {
18746948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar        if (SI->relocation_begin() != SI->relocation_end()) {
18756948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar          section_iterator RelocatedSection = SI->getRelocatedSection();
18766948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar          ObjSectionToIDMap::iterator i = SectionMap.find(*RelocatedSection);
18776948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar          assert (i != SectionMap.end());
18786948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar          SectionToGOTMap[i->second] = GOTSectionID;
18796948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar        }
18806948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar      }
18816948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar      GOTSymbolOffsets.clear();
18826948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    }
1883ff9fa05905be716435460b5f6d32689041bf895bAndrew Kaylor  }
1884528f6d787b1a847e61eb2f1114559f423fdeb68cAndrew Kaylor
1885528f6d787b1a847e61eb2f1114559f423fdeb68cAndrew Kaylor  // Look for and record the EH frame section.
1886528f6d787b1a847e61eb2f1114559f423fdeb68cAndrew Kaylor  ObjSectionToIDMap::iterator i, e;
1887528f6d787b1a847e61eb2f1114559f423fdeb68cAndrew Kaylor  for (i = SectionMap.begin(), e = SectionMap.end(); i != e; ++i) {
1888528f6d787b1a847e61eb2f1114559f423fdeb68cAndrew Kaylor    const SectionRef &Section = i->first;
1889528f6d787b1a847e61eb2f1114559f423fdeb68cAndrew Kaylor    StringRef Name;
1890528f6d787b1a847e61eb2f1114559f423fdeb68cAndrew Kaylor    Section.getName(Name);
1891528f6d787b1a847e61eb2f1114559f423fdeb68cAndrew Kaylor    if (Name == ".eh_frame") {
1892528f6d787b1a847e61eb2f1114559f423fdeb68cAndrew Kaylor      UnregisteredEHFrameSections.push_back(i->second);
1893528f6d787b1a847e61eb2f1114559f423fdeb68cAndrew Kaylor      break;
1894528f6d787b1a847e61eb2f1114559f423fdeb68cAndrew Kaylor    }
1895528f6d787b1a847e61eb2f1114559f423fdeb68cAndrew Kaylor  }
18960c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar
18970c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  GOTSectionID = 0;
18980c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  CurrentGOTIndex = 0;
1899de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar
1900de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  return Error::success();
1901ff9fa05905be716435460b5f6d32689041bf895bAndrew Kaylor}
1902ff9fa05905be716435460b5f6d32689041bf895bAndrew Kaylor
1903ebe69fe11e48d322045d5949c83283927a0d790bStephen Hinesbool RuntimeDyldELF::isCompatibleFile(const object::ObjectFile &Obj) const {
1904ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  return Obj.isELF();
190536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines}
190636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
1907f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainarbool RuntimeDyldELF::relocationNeedsStub(const RelocationRef &R) const {
1908f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  if (Arch != Triple::x86_64)
1909f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    return true;  // Conservative answer
1910f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
1911f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  switch (R.getType()) {
1912f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  default:
1913f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    return true;  // Conservative answer
1914f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
1915f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
1916f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  case ELF::R_X86_64_GOTPCREL:
1917de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  case ELF::R_X86_64_GOTPCRELX:
1918de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  case ELF::R_X86_64_REX_GOTPCRELX:
1919f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  case ELF::R_X86_64_PC32:
1920f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  case ELF::R_X86_64_PC64:
1921f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  case ELF::R_X86_64_64:
1922f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    // We know that these reloation types won't need a stub function.  This list
1923f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    // can be extended as needed.
1924f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    return false;
1925f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  }
1926f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar}
1927f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
1928a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky} // namespace llvm
1929