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