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" 153f23cef24fc9200def464bd4bce820678b5715deAndrew Kaylor#include "JITRegistrar.h" 163f23cef24fc9200def464bd4bce820678b5715deAndrew Kaylor#include "ObjectImageCommon.h" 17d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm/ADT/IntervalMap.h" 18a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky#include "llvm/ADT/STLExtras.h" 19d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm/ADT/StringRef.h" 20a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky#include "llvm/ADT/Triple.h" 21d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm/ExecutionEngine/ObjectBuffer.h" 22d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm/ExecutionEngine/ObjectImage.h" 23081a1941b595f6294e4ce678fd61ef56a2ceb51eMichael J. Spencer#include "llvm/Object/ELFObjectFile.h" 24d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm/Object/ObjectFile.h" 25d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm/Support/ELF.h" 2636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#include "llvm/Support/MemoryBuffer.h" 2736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 28a66a18505e07a4e72d6fa7e85663937a257577f3Eli Benderskyusing namespace llvm; 29a66a18505e07a4e72d6fa7e85663937a257577f3Eli Benderskyusing namespace llvm::object; 30a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky 31dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines#define DEBUG_TYPE "dyld" 32dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 33689ff9c00f4f3dcf3491778bcdbda79e19e2285dPreston Gurdnamespace { 34689ff9c00f4f3dcf3491778bcdbda79e19e2285dPreston Gurd 35cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hinesstatic inline std::error_code check(std::error_code Err) { 366e8946c5280ad6071d21013651745a9478f063edAdhemerval Zanella if (Err) { 376e8946c5280ad6071d21013651745a9478f063edAdhemerval Zanella report_fatal_error(Err.message()); 386e8946c5280ad6071d21013651745a9478f063edAdhemerval Zanella } 396e8946c5280ad6071d21013651745a9478f063edAdhemerval Zanella return Err; 406e8946c5280ad6071d21013651745a9478f063edAdhemerval Zanella} 416e8946c5280ad6071d21013651745a9478f063edAdhemerval Zanella 4236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinestemplate <class ELFT> class DyldELFObject : public ELFObjectFile<ELFT> { 4343239078adac6f32315cadbef9709f2f0f499707Rafael Espindola LLVM_ELF_IMPORT_TYPES_ELFT(ELFT) 44689ff9c00f4f3dcf3491778bcdbda79e19e2285dPreston Gurd 45ac97f5ce486d1ca2967607028eacddd860aaddd0Michael J. Spencer typedef Elf_Shdr_Impl<ELFT> Elf_Shdr; 46ac97f5ce486d1ca2967607028eacddd860aaddd0Michael J. Spencer typedef Elf_Sym_Impl<ELFT> Elf_Sym; 4736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines typedef Elf_Rel_Impl<ELFT, false> Elf_Rel; 4836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines typedef Elf_Rel_Impl<ELFT, true> Elf_Rela; 49689ff9c00f4f3dcf3491778bcdbda79e19e2285dPreston Gurd 50ac97f5ce486d1ca2967607028eacddd860aaddd0Michael J. Spencer typedef Elf_Ehdr_Impl<ELFT> Elf_Ehdr; 51689ff9c00f4f3dcf3491778bcdbda79e19e2285dPreston Gurd 5236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines typedef typename ELFDataTypeTypedefHelper<ELFT>::value_type addr_type; 53689ff9c00f4f3dcf3491778bcdbda79e19e2285dPreston Gurd 54dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines std::unique_ptr<ObjectFile> UnderlyingFile; 55dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 56689ff9c00f4f3dcf3491778bcdbda79e19e2285dPreston Gurdpublic: 57dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines DyldELFObject(std::unique_ptr<ObjectFile> UnderlyingFile, 58cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines std::unique_ptr<MemoryBuffer> Wrapper, std::error_code &ec); 59dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 60cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines DyldELFObject(std::unique_ptr<MemoryBuffer> Wrapper, std::error_code &ec); 61689ff9c00f4f3dcf3491778bcdbda79e19e2285dPreston Gurd 62689ff9c00f4f3dcf3491778bcdbda79e19e2285dPreston Gurd void updateSectionAddress(const SectionRef &Sec, uint64_t Addr); 63689ff9c00f4f3dcf3491778bcdbda79e19e2285dPreston Gurd void updateSymbolAddress(const SymbolRef &Sym, uint64_t Addr); 64689ff9c00f4f3dcf3491778bcdbda79e19e2285dPreston Gurd 652e319870f17a090e47540e2a821eac33c495bf59Andrew Kaylor // Methods for type inquiry through isa, cast and dyn_cast 66689ff9c00f4f3dcf3491778bcdbda79e19e2285dPreston Gurd static inline bool classof(const Binary *v) { 6736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return (isa<ELFObjectFile<ELFT>>(v) && 6836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines classof(cast<ELFObjectFile<ELFT>>(v))); 69689ff9c00f4f3dcf3491778bcdbda79e19e2285dPreston Gurd } 7036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines static inline bool classof(const ELFObjectFile<ELFT> *v) { 71689ff9c00f4f3dcf3491778bcdbda79e19e2285dPreston Gurd return v->isDyldType(); 72689ff9c00f4f3dcf3491778bcdbda79e19e2285dPreston Gurd } 73689ff9c00f4f3dcf3491778bcdbda79e19e2285dPreston Gurd}; 74689ff9c00f4f3dcf3491778bcdbda79e19e2285dPreston Gurd 7536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinestemplate <class ELFT> class ELFObjectImage : public ObjectImageCommon { 7636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines bool Registered; 77689ff9c00f4f3dcf3491778bcdbda79e19e2285dPreston Gurd 7836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinespublic: 79dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines ELFObjectImage(ObjectBuffer *Input, std::unique_ptr<DyldELFObject<ELFT>> Obj) 80dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines : ObjectImageCommon(Input, std::move(Obj)), Registered(false) {} 81689ff9c00f4f3dcf3491778bcdbda79e19e2285dPreston Gurd 8236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines virtual ~ELFObjectImage() { 8336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (Registered) 8436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines deregisterWithDebugger(); 8536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 86689ff9c00f4f3dcf3491778bcdbda79e19e2285dPreston Gurd 8736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // Subclasses can override these methods to update the image with loaded 8836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // addresses for sections and common symbols 8936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines void updateSectionAddress(const SectionRef &Sec, uint64_t Addr) override { 90dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines static_cast<DyldELFObject<ELFT>*>(getObjectFile()) 91dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines ->updateSectionAddress(Sec, Addr); 9236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 9336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 9436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines void updateSymbolAddress(const SymbolRef &Sym, uint64_t Addr) override { 95dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines static_cast<DyldELFObject<ELFT>*>(getObjectFile()) 96dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines ->updateSymbolAddress(Sym, Addr); 9736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 9836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 9936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines void registerWithDebugger() override { 10036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines JITRegistrar::getGDBRegistrar().registerObject(*Buffer); 10136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Registered = true; 10236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 10336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines void deregisterWithDebugger() override { 10436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines JITRegistrar::getGDBRegistrar().deregisterObject(*Buffer); 10536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 106689ff9c00f4f3dcf3491778bcdbda79e19e2285dPreston Gurd}; 107689ff9c00f4f3dcf3491778bcdbda79e19e2285dPreston Gurd 1083f23cef24fc9200def464bd4bce820678b5715deAndrew Kaylor// The MemoryBuffer passed into this constructor is just a wrapper around the 1093f23cef24fc9200def464bd4bce820678b5715deAndrew Kaylor// actual memory. Ultimately, the Binary parent class will take ownership of 1103f23cef24fc9200def464bd4bce820678b5715deAndrew Kaylor// this MemoryBuffer object but not the underlying memory. 11136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinestemplate <class ELFT> 112cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen HinesDyldELFObject<ELFT>::DyldELFObject(std::unique_ptr<MemoryBuffer> Wrapper, 113cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines std::error_code &EC) 114cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines : ELFObjectFile<ELFT>(std::move(Wrapper), EC) { 115689ff9c00f4f3dcf3491778bcdbda79e19e2285dPreston Gurd this->isDyldELFObject = true; 116689ff9c00f4f3dcf3491778bcdbda79e19e2285dPreston Gurd} 117689ff9c00f4f3dcf3491778bcdbda79e19e2285dPreston Gurd 11836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinestemplate <class ELFT> 119dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen HinesDyldELFObject<ELFT>::DyldELFObject(std::unique_ptr<ObjectFile> UnderlyingFile, 120cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines std::unique_ptr<MemoryBuffer> Wrapper, 121cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines std::error_code &EC) 122cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines : ELFObjectFile<ELFT>(std::move(Wrapper), EC), 123dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines UnderlyingFile(std::move(UnderlyingFile)) { 124dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines this->isDyldELFObject = true; 125dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines} 126dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 127dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinestemplate <class ELFT> 128ac97f5ce486d1ca2967607028eacddd860aaddd0Michael J. Spencervoid DyldELFObject<ELFT>::updateSectionAddress(const SectionRef &Sec, 129ac97f5ce486d1ca2967607028eacddd860aaddd0Michael J. Spencer uint64_t Addr) { 130689ff9c00f4f3dcf3491778bcdbda79e19e2285dPreston Gurd DataRefImpl ShdrRef = Sec.getRawDataRefImpl(); 13136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Elf_Shdr *shdr = 13236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines const_cast<Elf_Shdr *>(reinterpret_cast<const Elf_Shdr *>(ShdrRef.p)); 133689ff9c00f4f3dcf3491778bcdbda79e19e2285dPreston Gurd 134689ff9c00f4f3dcf3491778bcdbda79e19e2285dPreston Gurd // This assumes the address passed in matches the target address bitness 135689ff9c00f4f3dcf3491778bcdbda79e19e2285dPreston Gurd // The template-based type cast handles everything else. 136689ff9c00f4f3dcf3491778bcdbda79e19e2285dPreston Gurd shdr->sh_addr = static_cast<addr_type>(Addr); 137689ff9c00f4f3dcf3491778bcdbda79e19e2285dPreston Gurd} 138689ff9c00f4f3dcf3491778bcdbda79e19e2285dPreston Gurd 13936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinestemplate <class ELFT> 140ac97f5ce486d1ca2967607028eacddd860aaddd0Michael J. Spencervoid DyldELFObject<ELFT>::updateSymbolAddress(const SymbolRef &SymRef, 141ac97f5ce486d1ca2967607028eacddd860aaddd0Michael J. Spencer uint64_t Addr) { 142689ff9c00f4f3dcf3491778bcdbda79e19e2285dPreston Gurd 14336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Elf_Sym *sym = const_cast<Elf_Sym *>( 14436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines ELFObjectFile<ELFT>::getSymbol(SymRef.getRawDataRefImpl())); 145689ff9c00f4f3dcf3491778bcdbda79e19e2285dPreston Gurd 146689ff9c00f4f3dcf3491778bcdbda79e19e2285dPreston Gurd // This assumes the address passed in matches the target address bitness 147689ff9c00f4f3dcf3491778bcdbda79e19e2285dPreston Gurd // The template-based type cast handles everything else. 148689ff9c00f4f3dcf3491778bcdbda79e19e2285dPreston Gurd sym->st_value = static_cast<addr_type>(Addr); 149689ff9c00f4f3dcf3491778bcdbda79e19e2285dPreston Gurd} 150689ff9c00f4f3dcf3491778bcdbda79e19e2285dPreston Gurd 151689ff9c00f4f3dcf3491778bcdbda79e19e2285dPreston Gurd} // namespace 152689ff9c00f4f3dcf3491778bcdbda79e19e2285dPreston Gurd 153a66a18505e07a4e72d6fa7e85663937a257577f3Eli Benderskynamespace llvm { 154a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky 155528f6d787b1a847e61eb2f1114559f423fdeb68cAndrew Kaylorvoid RuntimeDyldELF::registerEHFrames() { 156528f6d787b1a847e61eb2f1114559f423fdeb68cAndrew Kaylor if (!MemMgr) 157528f6d787b1a847e61eb2f1114559f423fdeb68cAndrew Kaylor return; 158528f6d787b1a847e61eb2f1114559f423fdeb68cAndrew Kaylor for (int i = 0, e = UnregisteredEHFrameSections.size(); i != e; ++i) { 159528f6d787b1a847e61eb2f1114559f423fdeb68cAndrew Kaylor SID EHFrameSID = UnregisteredEHFrameSections[i]; 160528f6d787b1a847e61eb2f1114559f423fdeb68cAndrew Kaylor uint8_t *EHFrameAddr = Sections[EHFrameSID].Address; 161528f6d787b1a847e61eb2f1114559f423fdeb68cAndrew Kaylor uint64_t EHFrameLoadAddr = Sections[EHFrameSID].LoadAddress; 162528f6d787b1a847e61eb2f1114559f423fdeb68cAndrew Kaylor size_t EHFrameSize = Sections[EHFrameSID].Size; 163528f6d787b1a847e61eb2f1114559f423fdeb68cAndrew Kaylor MemMgr->registerEHFrames(EHFrameAddr, EHFrameLoadAddr, EHFrameSize); 16443507d026bef31100cb0c35614bcf419029a265bAndrew Kaylor RegisteredEHFrameSections.push_back(EHFrameSID); 165a2e40fbd624916c187a95ed76939ca7f02ed3e53Rafael Espindola } 166528f6d787b1a847e61eb2f1114559f423fdeb68cAndrew Kaylor UnregisteredEHFrameSections.clear(); 167a2e40fbd624916c187a95ed76939ca7f02ed3e53Rafael Espindola} 168a2e40fbd624916c187a95ed76939ca7f02ed3e53Rafael Espindola 16943507d026bef31100cb0c35614bcf419029a265bAndrew Kaylorvoid RuntimeDyldELF::deregisterEHFrames() { 17043507d026bef31100cb0c35614bcf419029a265bAndrew Kaylor if (!MemMgr) 17143507d026bef31100cb0c35614bcf419029a265bAndrew Kaylor return; 17243507d026bef31100cb0c35614bcf419029a265bAndrew Kaylor for (int i = 0, e = RegisteredEHFrameSections.size(); i != e; ++i) { 17343507d026bef31100cb0c35614bcf419029a265bAndrew Kaylor SID EHFrameSID = RegisteredEHFrameSections[i]; 17443507d026bef31100cb0c35614bcf419029a265bAndrew Kaylor uint8_t *EHFrameAddr = Sections[EHFrameSID].Address; 17543507d026bef31100cb0c35614bcf419029a265bAndrew Kaylor uint64_t EHFrameLoadAddr = Sections[EHFrameSID].LoadAddress; 17643507d026bef31100cb0c35614bcf419029a265bAndrew Kaylor size_t EHFrameSize = Sections[EHFrameSID].Size; 17743507d026bef31100cb0c35614bcf419029a265bAndrew Kaylor MemMgr->deregisterEHFrames(EHFrameAddr, EHFrameLoadAddr, EHFrameSize); 17843507d026bef31100cb0c35614bcf419029a265bAndrew Kaylor } 17943507d026bef31100cb0c35614bcf419029a265bAndrew Kaylor RegisteredEHFrameSections.clear(); 18043507d026bef31100cb0c35614bcf419029a265bAndrew Kaylor} 18143507d026bef31100cb0c35614bcf419029a265bAndrew Kaylor 18236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen HinesObjectImage * 183dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen HinesRuntimeDyldELF::createObjectImageFromFile(std::unique_ptr<object::ObjectFile> ObjFile) { 18436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (!ObjFile) 185dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines return nullptr; 18636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 187cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines std::error_code ec; 188cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines std::unique_ptr<MemoryBuffer> Buffer( 189cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines MemoryBuffer::getMemBuffer(ObjFile->getData(), "", false)); 19036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 19136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (ObjFile->getBytesInAddress() == 4 && ObjFile->isLittleEndian()) { 192dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines auto Obj = 193dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines llvm::make_unique<DyldELFObject<ELFType<support::little, 2, false>>>( 194cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines std::move(ObjFile), std::move(Buffer), ec); 195dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines return new ELFObjectImage<ELFType<support::little, 2, false>>( 196dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines nullptr, std::move(Obj)); 19736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } else if (ObjFile->getBytesInAddress() == 4 && !ObjFile->isLittleEndian()) { 198dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines auto Obj = 199dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines llvm::make_unique<DyldELFObject<ELFType<support::big, 2, false>>>( 200cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines std::move(ObjFile), std::move(Buffer), ec); 201dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines return new ELFObjectImage<ELFType<support::big, 2, false>>(nullptr, std::move(Obj)); 20236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } else if (ObjFile->getBytesInAddress() == 8 && !ObjFile->isLittleEndian()) { 203dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines auto Obj = llvm::make_unique<DyldELFObject<ELFType<support::big, 2, true>>>( 204cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines std::move(ObjFile), std::move(Buffer), ec); 205dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines return new ELFObjectImage<ELFType<support::big, 2, true>>(nullptr, 206dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines std::move(Obj)); 20736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } else if (ObjFile->getBytesInAddress() == 8 && ObjFile->isLittleEndian()) { 208dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines auto Obj = 209dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines llvm::make_unique<DyldELFObject<ELFType<support::little, 2, true>>>( 210cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines std::move(ObjFile), std::move(Buffer), ec); 211dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines return new ELFObjectImage<ELFType<support::little, 2, true>>( 212dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines nullptr, std::move(Obj)); 21336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } else 21436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines llvm_unreachable("Unexpected ELF format"); 21536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines} 21636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 2173f23cef24fc9200def464bd4bce820678b5715deAndrew KaylorObjectImage *RuntimeDyldELF::createObjectImage(ObjectBuffer *Buffer) { 2183f23cef24fc9200def464bd4bce820678b5715deAndrew Kaylor if (Buffer->getBufferSize() < ELF::EI_NIDENT) 2193f23cef24fc9200def464bd4bce820678b5715deAndrew Kaylor llvm_unreachable("Unexpected ELF object size"); 22036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines std::pair<unsigned char, unsigned char> Ident = 22136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines std::make_pair((uint8_t)Buffer->getBufferStart()[ELF::EI_CLASS], 22236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines (uint8_t)Buffer->getBufferStart()[ELF::EI_DATA]); 223cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines std::error_code ec; 224cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines 225cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines std::unique_ptr<MemoryBuffer> Buf(Buffer->getMemBuffer()); 226689ff9c00f4f3dcf3491778bcdbda79e19e2285dPreston Gurd 227689ff9c00f4f3dcf3491778bcdbda79e19e2285dPreston Gurd if (Ident.first == ELF::ELFCLASS32 && Ident.second == ELF::ELFDATA2LSB) { 228dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines auto Obj = 229dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines llvm::make_unique<DyldELFObject<ELFType<support::little, 4, false>>>( 230cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines std::move(Buf), ec); 231dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines return new ELFObjectImage<ELFType<support::little, 4, false>>( 232dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines Buffer, std::move(Obj)); 23336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } else if (Ident.first == ELF::ELFCLASS32 && 23436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Ident.second == ELF::ELFDATA2MSB) { 235dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines auto Obj = 236dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines llvm::make_unique<DyldELFObject<ELFType<support::big, 4, false>>>( 237cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines std::move(Buf), ec); 238dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines return new ELFObjectImage<ELFType<support::big, 4, false>>(Buffer, 239dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines std::move(Obj)); 24036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } else if (Ident.first == ELF::ELFCLASS64 && 24136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Ident.second == ELF::ELFDATA2MSB) { 242dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines auto Obj = llvm::make_unique<DyldELFObject<ELFType<support::big, 8, true>>>( 243cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines std::move(Buf), ec); 244dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines return new ELFObjectImage<ELFType<support::big, 8, true>>(Buffer, std::move(Obj)); 24536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } else if (Ident.first == ELF::ELFCLASS64 && 24636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Ident.second == ELF::ELFDATA2LSB) { 247dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines auto Obj = 248dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines llvm::make_unique<DyldELFObject<ELFType<support::little, 8, true>>>( 249cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines std::move(Buf), ec); 250dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines return new ELFObjectImage<ELFType<support::little, 8, true>>(Buffer, std::move(Obj)); 25136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } else 252689ff9c00f4f3dcf3491778bcdbda79e19e2285dPreston Gurd llvm_unreachable("Unexpected ELF format"); 253689ff9c00f4f3dcf3491778bcdbda79e19e2285dPreston Gurd} 254689ff9c00f4f3dcf3491778bcdbda79e19e2285dPreston Gurd 25536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen HinesRuntimeDyldELF::~RuntimeDyldELF() {} 256a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky 257a307a1cf859f4a523951ac887d094039547adeb5Andrew Kaylorvoid RuntimeDyldELF::resolveX86_64Relocation(const SectionEntry &Section, 25836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines uint64_t Offset, uint64_t Value, 25936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines uint32_t Type, int64_t Addend, 260ff9fa05905be716435460b5f6d32689041bf895bAndrew Kaylor uint64_t SymOffset) { 2610e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev switch (Type) { 2620e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev default: 2630e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev llvm_unreachable("Relocation type not implemented yet!"); 26436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines break; 265a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky case ELF::R_X86_64_64: { 26636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines uint64_t *Target = reinterpret_cast<uint64_t *>(Section.Address + Offset); 2670e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev *Target = Value + Addend; 26836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines DEBUG(dbgs() << "Writing " << format("%p", (Value + Addend)) << " at " 26936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines << format("%p\n", Target)); 270a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky break; 271a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky } 272a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky case ELF::R_X86_64_32: 273a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky case ELF::R_X86_64_32S: { 2740e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev Value += Addend; 275d83a547d671a424294df2103c71801127e55db0fAndrew Kaylor assert((Type == ELF::R_X86_64_32 && (Value <= UINT32_MAX)) || 2764d9c5397b4a3be747bdb73f1d24c3fdbaaf438feMichael J. Spencer (Type == ELF::R_X86_64_32S && 27736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines ((int64_t)Value <= INT32_MAX && (int64_t)Value >= INT32_MIN))); 278a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky uint32_t TruncatedAddr = (Value & 0xFFFFFFFF); 27936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines uint32_t *Target = reinterpret_cast<uint32_t *>(Section.Address + Offset); 280a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky *Target = TruncatedAddr; 28136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines DEBUG(dbgs() << "Writing " << format("%p", TruncatedAddr) << " at " 28236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines << format("%p\n", Target)); 283a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky break; 284a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky } 285ff9fa05905be716435460b5f6d32689041bf895bAndrew Kaylor case ELF::R_X86_64_GOTPCREL: { 286ff9fa05905be716435460b5f6d32689041bf895bAndrew Kaylor // findGOTEntry returns the 'G + GOT' part of the relocation calculation 287ff9fa05905be716435460b5f6d32689041bf895bAndrew Kaylor // based on the load/target address of the GOT (not the current/local addr). 288ff9fa05905be716435460b5f6d32689041bf895bAndrew Kaylor uint64_t GOTAddr = findGOTEntry(Value, SymOffset); 28936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines uint32_t *Target = reinterpret_cast<uint32_t *>(Section.Address + Offset); 29036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines uint64_t FinalAddress = Section.LoadAddress + Offset; 291ff9fa05905be716435460b5f6d32689041bf895bAndrew Kaylor // The processRelocationRef method combines the symbol offset and the addend 292ff9fa05905be716435460b5f6d32689041bf895bAndrew Kaylor // and in most cases that's what we want. For this relocation type, we need 293ff9fa05905be716435460b5f6d32689041bf895bAndrew Kaylor // the raw addend, so we subtract the symbol offset to get it. 294ff9fa05905be716435460b5f6d32689041bf895bAndrew Kaylor int64_t RealOffset = GOTAddr + Addend - SymOffset - FinalAddress; 295ff9fa05905be716435460b5f6d32689041bf895bAndrew Kaylor assert(RealOffset <= INT32_MAX && RealOffset >= INT32_MIN); 296ff9fa05905be716435460b5f6d32689041bf895bAndrew Kaylor int32_t TruncOffset = (RealOffset & 0xFFFFFFFF); 297ff9fa05905be716435460b5f6d32689041bf895bAndrew Kaylor *Target = TruncOffset; 298ff9fa05905be716435460b5f6d32689041bf895bAndrew Kaylor break; 299ff9fa05905be716435460b5f6d32689041bf895bAndrew Kaylor } 300a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky case ELF::R_X86_64_PC32: { 301a307a1cf859f4a523951ac887d094039547adeb5Andrew Kaylor // Get the placeholder value from the generated object since 302a307a1cf859f4a523951ac887d094039547adeb5Andrew Kaylor // a previous relocation attempt may have overwritten the loaded version 30336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines uint32_t *Placeholder = 30436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines reinterpret_cast<uint32_t *>(Section.ObjAddress + Offset); 30536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines uint32_t *Target = reinterpret_cast<uint32_t *>(Section.Address + Offset); 30636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines uint64_t FinalAddress = Section.LoadAddress + Offset; 3070e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev int64_t RealOffset = *Placeholder + Value + Addend - FinalAddress; 308d83a547d671a424294df2103c71801127e55db0fAndrew Kaylor assert(RealOffset <= INT32_MAX && RealOffset >= INT32_MIN); 3090e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev int32_t TruncOffset = (RealOffset & 0xFFFFFFFF); 310a307a1cf859f4a523951ac887d094039547adeb5Andrew Kaylor *Target = TruncOffset; 311a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky break; 312a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky } 313ff9fa05905be716435460b5f6d32689041bf895bAndrew Kaylor case ELF::R_X86_64_PC64: { 314ff9fa05905be716435460b5f6d32689041bf895bAndrew Kaylor // Get the placeholder value from the generated object since 315ff9fa05905be716435460b5f6d32689041bf895bAndrew Kaylor // a previous relocation attempt may have overwritten the loaded version 31636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines uint64_t *Placeholder = 31736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines reinterpret_cast<uint64_t *>(Section.ObjAddress + Offset); 31836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines uint64_t *Target = reinterpret_cast<uint64_t *>(Section.Address + Offset); 31936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines uint64_t FinalAddress = Section.LoadAddress + Offset; 320ff9fa05905be716435460b5f6d32689041bf895bAndrew Kaylor *Target = *Placeholder + Value + Addend - FinalAddress; 321ff9fa05905be716435460b5f6d32689041bf895bAndrew Kaylor break; 322ff9fa05905be716435460b5f6d32689041bf895bAndrew Kaylor } 323a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky } 324a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky} 325a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky 326a307a1cf859f4a523951ac887d094039547adeb5Andrew Kaylorvoid RuntimeDyldELF::resolveX86Relocation(const SectionEntry &Section, 32736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines uint64_t Offset, uint32_t Value, 32836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines uint32_t Type, int32_t Addend) { 3290e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev switch (Type) { 330a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky case ELF::R_386_32: { 331a307a1cf859f4a523951ac887d094039547adeb5Andrew Kaylor // Get the placeholder value from the generated object since 332a307a1cf859f4a523951ac887d094039547adeb5Andrew Kaylor // a previous relocation attempt may have overwritten the loaded version 33336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines uint32_t *Placeholder = 33436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines reinterpret_cast<uint32_t *>(Section.ObjAddress + Offset); 33536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines uint32_t *Target = reinterpret_cast<uint32_t *>(Section.Address + Offset); 336a307a1cf859f4a523951ac887d094039547adeb5Andrew Kaylor *Target = *Placeholder + Value + Addend; 337a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky break; 338a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky } 339a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky case ELF::R_386_PC32: { 340a307a1cf859f4a523951ac887d094039547adeb5Andrew Kaylor // Get the placeholder value from the generated object since 341a307a1cf859f4a523951ac887d094039547adeb5Andrew Kaylor // a previous relocation attempt may have overwritten the loaded version 34236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines uint32_t *Placeholder = 34336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines reinterpret_cast<uint32_t *>(Section.ObjAddress + Offset); 34436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines uint32_t *Target = reinterpret_cast<uint32_t *>(Section.Address + Offset); 34536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines uint32_t FinalAddress = ((Section.LoadAddress + Offset) & 0xFFFFFFFF); 3460e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev uint32_t RealOffset = *Placeholder + Value + Addend - FinalAddress; 347a307a1cf859f4a523951ac887d094039547adeb5Andrew Kaylor *Target = RealOffset; 348a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky break; 34936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 35036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines default: 35136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // There are other relocation types, but it appears these are the 35236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // only ones currently used by the LLVM ELF object writer 35336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines llvm_unreachable("Relocation type not implemented yet!"); 35436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines break; 355a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky } 356a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky} 357a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky 35885829bb98a998cff8f364c12d172da948ca225f4Tim Northovervoid RuntimeDyldELF::resolveAArch64Relocation(const SectionEntry &Section, 35936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines uint64_t Offset, uint64_t Value, 36036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines uint32_t Type, int64_t Addend) { 36136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines uint32_t *TargetPtr = reinterpret_cast<uint32_t *>(Section.Address + Offset); 36285829bb98a998cff8f364c12d172da948ca225f4Tim Northover uint64_t FinalAddress = Section.LoadAddress + Offset; 36385829bb98a998cff8f364c12d172da948ca225f4Tim Northover 36485829bb98a998cff8f364c12d172da948ca225f4Tim Northover DEBUG(dbgs() << "resolveAArch64Relocation, LocalAddress: 0x" 36585829bb98a998cff8f364c12d172da948ca225f4Tim Northover << format("%llx", Section.Address + Offset) 36636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines << " FinalAddress: 0x" << format("%llx", FinalAddress) 36736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines << " Value: 0x" << format("%llx", Value) << " Type: 0x" 36836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines << format("%x", Type) << " Addend: 0x" << format("%llx", Addend) 36985829bb98a998cff8f364c12d172da948ca225f4Tim Northover << "\n"); 37085829bb98a998cff8f364c12d172da948ca225f4Tim Northover 37185829bb98a998cff8f364c12d172da948ca225f4Tim Northover switch (Type) { 37285829bb98a998cff8f364c12d172da948ca225f4Tim Northover default: 37385829bb98a998cff8f364c12d172da948ca225f4Tim Northover llvm_unreachable("Relocation type not implemented yet!"); 37485829bb98a998cff8f364c12d172da948ca225f4Tim Northover break; 375d52eaae157e661f280d0a71aabc060602ffc4424Tim Northover case ELF::R_AARCH64_ABS64: { 37636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines uint64_t *TargetPtr = 37736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines reinterpret_cast<uint64_t *>(Section.Address + Offset); 378d52eaae157e661f280d0a71aabc060602ffc4424Tim Northover *TargetPtr = Value + Addend; 379d52eaae157e661f280d0a71aabc060602ffc4424Tim Northover break; 380d52eaae157e661f280d0a71aabc060602ffc4424Tim Northover } 381675b9e9f3d567bdf1a31ce9d9ce2451ae09dc9faTim Northover case ELF::R_AARCH64_PREL32: { 38285829bb98a998cff8f364c12d172da948ca225f4Tim Northover uint64_t Result = Value + Addend - FinalAddress; 383081a1941b595f6294e4ce678fd61ef56a2ceb51eMichael J. Spencer assert(static_cast<int64_t>(Result) >= INT32_MIN && 38485829bb98a998cff8f364c12d172da948ca225f4Tim Northover static_cast<int64_t>(Result) <= UINT32_MAX); 38585829bb98a998cff8f364c12d172da948ca225f4Tim Northover *TargetPtr = static_cast<uint32_t>(Result & 0xffffffffU); 38685829bb98a998cff8f364c12d172da948ca225f4Tim Northover break; 38785829bb98a998cff8f364c12d172da948ca225f4Tim Northover } 3884a9b6b798d5ea335f5f29d278db83b830ae4a564Tim Northover case ELF::R_AARCH64_CALL26: // fallthrough 3894a9b6b798d5ea335f5f29d278db83b830ae4a564Tim Northover case ELF::R_AARCH64_JUMP26: { 3904a9b6b798d5ea335f5f29d278db83b830ae4a564Tim Northover // Operation: S+A-P. Set Call or B immediate value to bits fff_fffc of the 3914a9b6b798d5ea335f5f29d278db83b830ae4a564Tim Northover // calculation. 3924a9b6b798d5ea335f5f29d278db83b830ae4a564Tim Northover uint64_t BranchImm = Value + Addend - FinalAddress; 3934a9b6b798d5ea335f5f29d278db83b830ae4a564Tim Northover 3944a9b6b798d5ea335f5f29d278db83b830ae4a564Tim Northover // "Check that -2^27 <= result < 2^27". 395081a1941b595f6294e4ce678fd61ef56a2ceb51eMichael J. Spencer assert(-(1LL << 27) <= static_cast<int64_t>(BranchImm) && 3964a9b6b798d5ea335f5f29d278db83b830ae4a564Tim Northover static_cast<int64_t>(BranchImm) < (1LL << 27)); 397675b9e9f3d567bdf1a31ce9d9ce2451ae09dc9faTim Northover 398675b9e9f3d567bdf1a31ce9d9ce2451ae09dc9faTim Northover // AArch64 code is emitted with .rela relocations. The data already in any 399675b9e9f3d567bdf1a31ce9d9ce2451ae09dc9faTim Northover // bits affected by the relocation on entry is garbage. 400675b9e9f3d567bdf1a31ce9d9ce2451ae09dc9faTim Northover *TargetPtr &= 0xfc000000U; 4014a9b6b798d5ea335f5f29d278db83b830ae4a564Tim Northover // Immediate goes in bits 25:0 of B and BL. 4024a9b6b798d5ea335f5f29d278db83b830ae4a564Tim Northover *TargetPtr |= static_cast<uint32_t>(BranchImm & 0xffffffcU) >> 2; 4034a9b6b798d5ea335f5f29d278db83b830ae4a564Tim Northover break; 4044a9b6b798d5ea335f5f29d278db83b830ae4a564Tim Northover } 405654c2d6b7a9274fc281c30c0e91419aadb6dc78aTim Northover case ELF::R_AARCH64_MOVW_UABS_G3: { 406654c2d6b7a9274fc281c30c0e91419aadb6dc78aTim Northover uint64_t Result = Value + Addend; 407675b9e9f3d567bdf1a31ce9d9ce2451ae09dc9faTim Northover 408675b9e9f3d567bdf1a31ce9d9ce2451ae09dc9faTim Northover // AArch64 code is emitted with .rela relocations. The data already in any 409675b9e9f3d567bdf1a31ce9d9ce2451ae09dc9faTim Northover // bits affected by the relocation on entry is garbage. 410107b2f26aa02a089a6b05ab86ebe033836fc06faTim Northover *TargetPtr &= 0xffe0001fU; 411654c2d6b7a9274fc281c30c0e91419aadb6dc78aTim Northover // Immediate goes in bits 20:5 of MOVZ/MOVK instruction 412654c2d6b7a9274fc281c30c0e91419aadb6dc78aTim Northover *TargetPtr |= Result >> (48 - 5); 4136711fc28a41c05e1c8398393c7794c41b2ee0202Tim Northover // Shift must be "lsl #48", in bits 22:21 4146711fc28a41c05e1c8398393c7794c41b2ee0202Tim Northover assert((*TargetPtr >> 21 & 0x3) == 3 && "invalid shift for relocation"); 415654c2d6b7a9274fc281c30c0e91419aadb6dc78aTim Northover break; 416654c2d6b7a9274fc281c30c0e91419aadb6dc78aTim Northover } 417654c2d6b7a9274fc281c30c0e91419aadb6dc78aTim Northover case ELF::R_AARCH64_MOVW_UABS_G2_NC: { 418654c2d6b7a9274fc281c30c0e91419aadb6dc78aTim Northover uint64_t Result = Value + Addend; 419675b9e9f3d567bdf1a31ce9d9ce2451ae09dc9faTim Northover 420675b9e9f3d567bdf1a31ce9d9ce2451ae09dc9faTim Northover // AArch64 code is emitted with .rela relocations. The data already in any 421675b9e9f3d567bdf1a31ce9d9ce2451ae09dc9faTim Northover // bits affected by the relocation on entry is garbage. 422107b2f26aa02a089a6b05ab86ebe033836fc06faTim Northover *TargetPtr &= 0xffe0001fU; 423654c2d6b7a9274fc281c30c0e91419aadb6dc78aTim Northover // Immediate goes in bits 20:5 of MOVZ/MOVK instruction 424654c2d6b7a9274fc281c30c0e91419aadb6dc78aTim Northover *TargetPtr |= ((Result & 0xffff00000000ULL) >> (32 - 5)); 4256711fc28a41c05e1c8398393c7794c41b2ee0202Tim Northover // Shift must be "lsl #32", in bits 22:21 4266711fc28a41c05e1c8398393c7794c41b2ee0202Tim Northover assert((*TargetPtr >> 21 & 0x3) == 2 && "invalid shift for relocation"); 427654c2d6b7a9274fc281c30c0e91419aadb6dc78aTim Northover break; 428654c2d6b7a9274fc281c30c0e91419aadb6dc78aTim Northover } 429654c2d6b7a9274fc281c30c0e91419aadb6dc78aTim Northover case ELF::R_AARCH64_MOVW_UABS_G1_NC: { 430654c2d6b7a9274fc281c30c0e91419aadb6dc78aTim Northover uint64_t Result = Value + Addend; 431675b9e9f3d567bdf1a31ce9d9ce2451ae09dc9faTim Northover 432675b9e9f3d567bdf1a31ce9d9ce2451ae09dc9faTim Northover // AArch64 code is emitted with .rela relocations. The data already in any 433675b9e9f3d567bdf1a31ce9d9ce2451ae09dc9faTim Northover // bits affected by the relocation on entry is garbage. 434107b2f26aa02a089a6b05ab86ebe033836fc06faTim Northover *TargetPtr &= 0xffe0001fU; 435654c2d6b7a9274fc281c30c0e91419aadb6dc78aTim Northover // Immediate goes in bits 20:5 of MOVZ/MOVK instruction 436654c2d6b7a9274fc281c30c0e91419aadb6dc78aTim Northover *TargetPtr |= ((Result & 0xffff0000U) >> (16 - 5)); 4376711fc28a41c05e1c8398393c7794c41b2ee0202Tim Northover // Shift must be "lsl #16", in bits 22:2 4386711fc28a41c05e1c8398393c7794c41b2ee0202Tim Northover assert((*TargetPtr >> 21 & 0x3) == 1 && "invalid shift for relocation"); 439654c2d6b7a9274fc281c30c0e91419aadb6dc78aTim Northover break; 440654c2d6b7a9274fc281c30c0e91419aadb6dc78aTim Northover } 441654c2d6b7a9274fc281c30c0e91419aadb6dc78aTim Northover case ELF::R_AARCH64_MOVW_UABS_G0_NC: { 442654c2d6b7a9274fc281c30c0e91419aadb6dc78aTim Northover uint64_t Result = Value + Addend; 443675b9e9f3d567bdf1a31ce9d9ce2451ae09dc9faTim Northover 444675b9e9f3d567bdf1a31ce9d9ce2451ae09dc9faTim Northover // AArch64 code is emitted with .rela relocations. The data already in any 445675b9e9f3d567bdf1a31ce9d9ce2451ae09dc9faTim Northover // bits affected by the relocation on entry is garbage. 446107b2f26aa02a089a6b05ab86ebe033836fc06faTim Northover *TargetPtr &= 0xffe0001fU; 447654c2d6b7a9274fc281c30c0e91419aadb6dc78aTim Northover // Immediate goes in bits 20:5 of MOVZ/MOVK instruction 448654c2d6b7a9274fc281c30c0e91419aadb6dc78aTim Northover *TargetPtr |= ((Result & 0xffffU) << 5); 4496711fc28a41c05e1c8398393c7794c41b2ee0202Tim Northover // Shift must be "lsl #0", in bits 22:21. 4506711fc28a41c05e1c8398393c7794c41b2ee0202Tim Northover assert((*TargetPtr >> 21 & 0x3) == 0 && "invalid shift for relocation"); 451654c2d6b7a9274fc281c30c0e91419aadb6dc78aTim Northover break; 452654c2d6b7a9274fc281c30c0e91419aadb6dc78aTim Northover } 45336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines case ELF::R_AARCH64_ADR_PREL_PG_HI21: { 45436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // Operation: Page(S+A) - Page(P) 45536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines uint64_t Result = 45636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines ((Value + Addend) & ~0xfffULL) - (FinalAddress & ~0xfffULL); 45736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 45836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // Check that -2^32 <= X < 2^32 45936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines assert(static_cast<int64_t>(Result) >= (-1LL << 32) && 46036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines static_cast<int64_t>(Result) < (1LL << 32) && 46136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines "overflow check failed for relocation"); 46236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 46336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // AArch64 code is emitted with .rela relocations. The data already in any 46436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // bits affected by the relocation on entry is garbage. 46536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines *TargetPtr &= 0x9f00001fU; 46636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // Immediate goes in bits 30:29 + 5:23 of ADRP instruction, taken 46736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // from bits 32:12 of X. 46836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines *TargetPtr |= ((Result & 0x3000U) << (29 - 12)); 46936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines *TargetPtr |= ((Result & 0x1ffffc000ULL) >> (14 - 5)); 47036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines break; 47136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 47236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines case ELF::R_AARCH64_LDST32_ABS_LO12_NC: { 47336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // Operation: S + A 47436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines uint64_t Result = Value + Addend; 47536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 47636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // AArch64 code is emitted with .rela relocations. The data already in any 47736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // bits affected by the relocation on entry is garbage. 47836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines *TargetPtr &= 0xffc003ffU; 47936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // Immediate goes in bits 21:10 of LD/ST instruction, taken 48036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // from bits 11:2 of X 48136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines *TargetPtr |= ((Result & 0xffc) << (10 - 2)); 48236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines break; 48336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 48436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines case ELF::R_AARCH64_LDST64_ABS_LO12_NC: { 48536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // Operation: S + A 48636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines uint64_t Result = Value + Addend; 48736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 48836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // AArch64 code is emitted with .rela relocations. The data already in any 48936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // bits affected by the relocation on entry is garbage. 49036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines *TargetPtr &= 0xffc003ffU; 49136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // Immediate goes in bits 21:10 of LD/ST instruction, taken 49236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // from bits 11:3 of X 49336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines *TargetPtr |= ((Result & 0xff8) << (10 - 3)); 49436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines break; 49536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 49685829bb98a998cff8f364c12d172da948ca225f4Tim Northover } 49785829bb98a998cff8f364c12d172da948ca225f4Tim Northover} 49885829bb98a998cff8f364c12d172da948ca225f4Tim Northover 499a307a1cf859f4a523951ac887d094039547adeb5Andrew Kaylorvoid RuntimeDyldELF::resolveARMRelocation(const SectionEntry &Section, 50036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines uint64_t Offset, uint32_t Value, 50136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines uint32_t Type, int32_t Addend) { 5020e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev // TODO: Add Thumb relocations. 50336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines uint32_t *Placeholder = 50436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines reinterpret_cast<uint32_t *>(Section.ObjAddress + Offset); 50536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines uint32_t *TargetPtr = (uint32_t *)(Section.Address + Offset); 506a307a1cf859f4a523951ac887d094039547adeb5Andrew Kaylor uint32_t FinalAddress = ((Section.LoadAddress + Offset) & 0xFFFFFFFF); 5070e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev Value += Addend; 5080e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev 509a307a1cf859f4a523951ac887d094039547adeb5Andrew Kaylor DEBUG(dbgs() << "resolveARMRelocation, LocalAddress: " 510a307a1cf859f4a523951ac887d094039547adeb5Andrew Kaylor << Section.Address + Offset 51136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines << " FinalAddress: " << format("%p", FinalAddress) << " Value: " 51236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines << format("%x", Value) << " Type: " << format("%x", Type) 51336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines << " Addend: " << format("%x", Addend) << "\n"); 5140e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev 51536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines switch (Type) { 5160e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev default: 5170e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev llvm_unreachable("Not implemented relocation type!"); 5180e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev 51936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines case ELF::R_ARM_NONE: 52036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines break; 5214d9c5397b4a3be747bdb73f1d24c3fdbaaf438feMichael J. Spencer // Write a 32bit value to relocation address, taking into account the 522565ebde5fea42789c7df8a49ce1e270d49d525a1Tim Northover // implicit addend encoded in the target. 52336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines case ELF::R_ARM_PREL31: 524e274b476de33ee4f2e90a3eb3a56b5cdd619eb82Tim Northover case ELF::R_ARM_TARGET1: 525e274b476de33ee4f2e90a3eb3a56b5cdd619eb82Tim Northover case ELF::R_ARM_ABS32: 526e274b476de33ee4f2e90a3eb3a56b5cdd619eb82Tim Northover *TargetPtr = *Placeholder + Value; 5270e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev break; 5280e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev // Write first 16 bit of 32 bit value to the mov instruction. 5290e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev // Last 4 bit should be shifted. 530e274b476de33ee4f2e90a3eb3a56b5cdd619eb82Tim Northover case ELF::R_ARM_MOVW_ABS_NC: 531565ebde5fea42789c7df8a49ce1e270d49d525a1Tim Northover // We are not expecting any other addend in the relocation address. 5324d9c5397b4a3be747bdb73f1d24c3fdbaaf438feMichael J. Spencer // Using 0x000F0FFF because MOVW has its 16 bit immediate split into 2 533565ebde5fea42789c7df8a49ce1e270d49d525a1Tim Northover // non-contiguous fields. 534e274b476de33ee4f2e90a3eb3a56b5cdd619eb82Tim Northover assert((*Placeholder & 0x000F0FFF) == 0); 5350e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev Value = Value & 0xFFFF; 536e274b476de33ee4f2e90a3eb3a56b5cdd619eb82Tim Northover *TargetPtr = *Placeholder | (Value & 0xFFF); 5370e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev *TargetPtr |= ((Value >> 12) & 0xF) << 16; 5380e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev break; 5390e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev // Write last 16 bit of 32 bit value to the mov instruction. 5400e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev // Last 4 bit should be shifted. 541e274b476de33ee4f2e90a3eb3a56b5cdd619eb82Tim Northover case ELF::R_ARM_MOVT_ABS: 542565ebde5fea42789c7df8a49ce1e270d49d525a1Tim Northover // We are not expecting any other addend in the relocation address. 543565ebde5fea42789c7df8a49ce1e270d49d525a1Tim Northover // Use 0x000F0FFF for the same reason as R_ARM_MOVW_ABS_NC. 544e274b476de33ee4f2e90a3eb3a56b5cdd619eb82Tim Northover assert((*Placeholder & 0x000F0FFF) == 0); 545e274b476de33ee4f2e90a3eb3a56b5cdd619eb82Tim Northover 5460e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev Value = (Value >> 16) & 0xFFFF; 547e274b476de33ee4f2e90a3eb3a56b5cdd619eb82Tim Northover *TargetPtr = *Placeholder | (Value & 0xFFF); 5480e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev *TargetPtr |= ((Value >> 12) & 0xF) << 16; 5490e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev break; 5500e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev // Write 24 bit relative value to the branch instruction. 55136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines case ELF::R_ARM_PC24: // Fall through. 55236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines case ELF::R_ARM_CALL: // Fall through. 553e274b476de33ee4f2e90a3eb3a56b5cdd619eb82Tim Northover case ELF::R_ARM_JUMP24: { 5540e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev int32_t RelValue = static_cast<int32_t>(Value - FinalAddress - 8); 5550e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev RelValue = (RelValue & 0x03FFFFFC) >> 2; 556e274b476de33ee4f2e90a3eb3a56b5cdd619eb82Tim Northover assert((*TargetPtr & 0xFFFFFF) == 0xFFFFFE); 5570e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev *TargetPtr &= 0xFF000000; 5580e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev *TargetPtr |= RelValue; 5590e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev break; 5600e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev } 561e274b476de33ee4f2e90a3eb3a56b5cdd619eb82Tim Northover case ELF::R_ARM_PRIVATE_0: 562e274b476de33ee4f2e90a3eb3a56b5cdd619eb82Tim Northover // This relocation is reserved by the ARM ELF ABI for internal use. We 563e274b476de33ee4f2e90a3eb3a56b5cdd619eb82Tim Northover // appropriate it here to act as an R_ARM_ABS32 without any addend for use 564e274b476de33ee4f2e90a3eb3a56b5cdd619eb82Tim Northover // in the stubs created during JIT (which can't put an addend into the 565e274b476de33ee4f2e90a3eb3a56b5cdd619eb82Tim Northover // original object file). 566e274b476de33ee4f2e90a3eb3a56b5cdd619eb82Tim Northover *TargetPtr = Value; 567e274b476de33ee4f2e90a3eb3a56b5cdd619eb82Tim Northover break; 568e274b476de33ee4f2e90a3eb3a56b5cdd619eb82Tim Northover } 569a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky} 570a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky 571a307a1cf859f4a523951ac887d094039547adeb5Andrew Kaylorvoid RuntimeDyldELF::resolveMIPSRelocation(const SectionEntry &Section, 57236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines uint64_t Offset, uint32_t Value, 57336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines uint32_t Type, int32_t Addend) { 57436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines uint32_t *Placeholder = 57536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines reinterpret_cast<uint32_t *>(Section.ObjAddress + Offset); 57636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines uint32_t *TargetPtr = (uint32_t *)(Section.Address + Offset); 577b889e0cd2fea4afee623d5be603b912b955a2ecaAkira Hatanaka Value += Addend; 578b889e0cd2fea4afee623d5be603b912b955a2ecaAkira Hatanaka 579a307a1cf859f4a523951ac887d094039547adeb5Andrew Kaylor DEBUG(dbgs() << "resolveMipselocation, LocalAddress: " 58036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines << Section.Address + Offset << " FinalAddress: " 58136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines << format("%p", Section.LoadAddress + Offset) << " Value: " 58236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines << format("%x", Value) << " Type: " << format("%x", Type) 58336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines << " Addend: " << format("%x", Addend) << "\n"); 584b889e0cd2fea4afee623d5be603b912b955a2ecaAkira Hatanaka 58536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines switch (Type) { 586b889e0cd2fea4afee623d5be603b912b955a2ecaAkira Hatanaka default: 587b889e0cd2fea4afee623d5be603b912b955a2ecaAkira Hatanaka llvm_unreachable("Not implemented relocation type!"); 588b889e0cd2fea4afee623d5be603b912b955a2ecaAkira Hatanaka break; 589b889e0cd2fea4afee623d5be603b912b955a2ecaAkira Hatanaka case ELF::R_MIPS_32: 5903af1c9d3343357849f19f7467f9c16220ad37ca4Akira Hatanaka *TargetPtr = Value + (*Placeholder); 591b889e0cd2fea4afee623d5be603b912b955a2ecaAkira Hatanaka break; 592b889e0cd2fea4afee623d5be603b912b955a2ecaAkira Hatanaka case ELF::R_MIPS_26: 59336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines *TargetPtr = ((*Placeholder) & 0xfc000000) | ((Value & 0x0fffffff) >> 2); 594b889e0cd2fea4afee623d5be603b912b955a2ecaAkira Hatanaka break; 595b889e0cd2fea4afee623d5be603b912b955a2ecaAkira Hatanaka case ELF::R_MIPS_HI16: 596b889e0cd2fea4afee623d5be603b912b955a2ecaAkira Hatanaka // Get the higher 16-bits. Also add 1 if bit 15 is 1. 5973af1c9d3343357849f19f7467f9c16220ad37ca4Akira Hatanaka Value += ((*Placeholder) & 0x0000ffff) << 16; 59836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines *TargetPtr = 59936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines ((*Placeholder) & 0xffff0000) | (((Value + 0x8000) >> 16) & 0xffff); 6003af1c9d3343357849f19f7467f9c16220ad37ca4Akira Hatanaka break; 6013af1c9d3343357849f19f7467f9c16220ad37ca4Akira Hatanaka case ELF::R_MIPS_LO16: 6023af1c9d3343357849f19f7467f9c16220ad37ca4Akira Hatanaka Value += ((*Placeholder) & 0x0000ffff); 6033af1c9d3343357849f19f7467f9c16220ad37ca4Akira Hatanaka *TargetPtr = ((*Placeholder) & 0xffff0000) | (Value & 0xffff); 6043af1c9d3343357849f19f7467f9c16220ad37ca4Akira Hatanaka break; 6053af1c9d3343357849f19f7467f9c16220ad37ca4Akira Hatanaka case ELF::R_MIPS_UNUSED1: 6063af1c9d3343357849f19f7467f9c16220ad37ca4Akira Hatanaka // Similar to ELF::R_ARM_PRIVATE_0, R_MIPS_UNUSED1 and R_MIPS_UNUSED2 6073af1c9d3343357849f19f7467f9c16220ad37ca4Akira Hatanaka // are used for internal JIT purpose. These relocations are similar to 6083af1c9d3343357849f19f7467f9c16220ad37ca4Akira Hatanaka // R_MIPS_HI16 and R_MIPS_LO16, but they do not take any addend into 6093af1c9d3343357849f19f7467f9c16220ad37ca4Akira Hatanaka // account. 61036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines *TargetPtr = 61136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines ((*TargetPtr) & 0xffff0000) | (((Value + 0x8000) >> 16) & 0xffff); 612b889e0cd2fea4afee623d5be603b912b955a2ecaAkira Hatanaka break; 6133af1c9d3343357849f19f7467f9c16220ad37ca4Akira Hatanaka case ELF::R_MIPS_UNUSED2: 614b889e0cd2fea4afee623d5be603b912b955a2ecaAkira Hatanaka *TargetPtr = ((*TargetPtr) & 0xffff0000) | (Value & 0xffff); 615b889e0cd2fea4afee623d5be603b912b955a2ecaAkira Hatanaka break; 61636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 617b889e0cd2fea4afee623d5be603b912b955a2ecaAkira Hatanaka} 618b889e0cd2fea4afee623d5be603b912b955a2ecaAkira Hatanaka 619cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines// Return the .TOC. section and offset. 620cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hinesvoid RuntimeDyldELF::findPPC64TOCSection(ObjectImage &Obj, 621cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines ObjSectionToIDMap &LocalSections, 622cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines RelocationValueRef &Rel) { 623cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines // Set a default SectionID in case we do not find a TOC section below. 624cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines // This may happen for references to TOC base base (sym@toc, .odp 625cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines // relocation) without a .toc directive. In this case just use the 626cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines // first section (which is usually the .odp) since the code won't 627cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines // reference the .toc base directly. 628cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines Rel.SymbolName = NULL; 629cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines Rel.SectionID = 0; 630cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines 6316e8946c5280ad6071d21013651745a9478f063edAdhemerval Zanella // The TOC consists of sections .got, .toc, .tocbss, .plt in that 6326e8946c5280ad6071d21013651745a9478f063edAdhemerval Zanella // order. The TOC starts where the first of these sections starts. 633cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines for (section_iterator si = Obj.begin_sections(), se = Obj.end_sections(); 634cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines si != se; ++si) { 635cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines 636cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines StringRef SectionName; 637cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines check(si->getName(SectionName)); 638cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines 639cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines if (SectionName == ".got" 640cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines || SectionName == ".toc" 641cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines || SectionName == ".tocbss" 642cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines || SectionName == ".plt") { 643cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines Rel.SectionID = findOrEmitSection(Obj, *si, false, LocalSections); 6446e8946c5280ad6071d21013651745a9478f063edAdhemerval Zanella break; 645cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines } 6466e8946c5280ad6071d21013651745a9478f063edAdhemerval Zanella } 647cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines 6486e8946c5280ad6071d21013651745a9478f063edAdhemerval Zanella // Per the ppc64-elf-linux ABI, The TOC base is TOC value plus 0x8000 6496e8946c5280ad6071d21013651745a9478f063edAdhemerval Zanella // thus permitting a full 64 Kbytes segment. 650cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines Rel.Addend = 0x8000; 6516e8946c5280ad6071d21013651745a9478f063edAdhemerval Zanella} 6526e8946c5280ad6071d21013651745a9478f063edAdhemerval Zanella 6536e8946c5280ad6071d21013651745a9478f063edAdhemerval Zanella// Returns the sections and offset associated with the ODP entry referenced 6546e8946c5280ad6071d21013651745a9478f063edAdhemerval Zanella// by Symbol. 6556e8946c5280ad6071d21013651745a9478f063edAdhemerval Zanellavoid RuntimeDyldELF::findOPDEntrySection(ObjectImage &Obj, 6566e8946c5280ad6071d21013651745a9478f063edAdhemerval Zanella ObjSectionToIDMap &LocalSections, 6576e8946c5280ad6071d21013651745a9478f063edAdhemerval Zanella RelocationValueRef &Rel) { 6586e8946c5280ad6071d21013651745a9478f063edAdhemerval Zanella // Get the ELF symbol value (st_value) to compare with Relocation offset in 6596e8946c5280ad6071d21013651745a9478f063edAdhemerval Zanella // .opd entries 66036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines for (section_iterator si = Obj.begin_sections(), se = Obj.end_sections(); 66136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines si != se; ++si) { 66215e5c46e49b5ab02fee6d1da53cb9c129cab5165Rafael Espindola section_iterator RelSecI = si->getRelocatedSection(); 66315e5c46e49b5ab02fee6d1da53cb9c129cab5165Rafael Espindola if (RelSecI == Obj.end_sections()) 66415e5c46e49b5ab02fee6d1da53cb9c129cab5165Rafael Espindola continue; 66515e5c46e49b5ab02fee6d1da53cb9c129cab5165Rafael Espindola 66615e5c46e49b5ab02fee6d1da53cb9c129cab5165Rafael Espindola StringRef RelSectionName; 66715e5c46e49b5ab02fee6d1da53cb9c129cab5165Rafael Espindola check(RelSecI->getName(RelSectionName)); 66815e5c46e49b5ab02fee6d1da53cb9c129cab5165Rafael Espindola if (RelSectionName != ".opd") 6696e8946c5280ad6071d21013651745a9478f063edAdhemerval Zanella continue; 6706e8946c5280ad6071d21013651745a9478f063edAdhemerval Zanella 67136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines for (relocation_iterator i = si->relocation_begin(), 67236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines e = si->relocation_end(); 67336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines i != e;) { 6746e8946c5280ad6071d21013651745a9478f063edAdhemerval Zanella // The R_PPC64_ADDR64 relocation indicates the first field 6756e8946c5280ad6071d21013651745a9478f063edAdhemerval Zanella // of a .opd entry 6766e8946c5280ad6071d21013651745a9478f063edAdhemerval Zanella uint64_t TypeFunc; 6776e8946c5280ad6071d21013651745a9478f063edAdhemerval Zanella check(i->getType(TypeFunc)); 6786e8946c5280ad6071d21013651745a9478f063edAdhemerval Zanella if (TypeFunc != ELF::R_PPC64_ADDR64) { 67936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines ++i; 6806e8946c5280ad6071d21013651745a9478f063edAdhemerval Zanella continue; 6816e8946c5280ad6071d21013651745a9478f063edAdhemerval Zanella } 6826e8946c5280ad6071d21013651745a9478f063edAdhemerval Zanella 6836e8946c5280ad6071d21013651745a9478f063edAdhemerval Zanella uint64_t TargetSymbolOffset; 6846c1202c459ffa6d693ad92fa84e43902bc780bcaRafael Espindola symbol_iterator TargetSymbol = i->getSymbol(); 6856e8946c5280ad6071d21013651745a9478f063edAdhemerval Zanella check(i->getOffset(TargetSymbolOffset)); 686167957fa095bc7200b908e6e142be3e604bcfeeaRafael Espindola int64_t Addend; 687167957fa095bc7200b908e6e142be3e604bcfeeaRafael Espindola check(getELFRelocationAddend(*i, Addend)); 6886e8946c5280ad6071d21013651745a9478f063edAdhemerval Zanella 68936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines ++i; 6906e8946c5280ad6071d21013651745a9478f063edAdhemerval Zanella if (i == e) 6916e8946c5280ad6071d21013651745a9478f063edAdhemerval Zanella break; 6926e8946c5280ad6071d21013651745a9478f063edAdhemerval Zanella 6936e8946c5280ad6071d21013651745a9478f063edAdhemerval Zanella // Just check if following relocation is a R_PPC64_TOC 6946e8946c5280ad6071d21013651745a9478f063edAdhemerval Zanella uint64_t TypeTOC; 6956e8946c5280ad6071d21013651745a9478f063edAdhemerval Zanella check(i->getType(TypeTOC)); 6966e8946c5280ad6071d21013651745a9478f063edAdhemerval Zanella if (TypeTOC != ELF::R_PPC64_TOC) 6976e8946c5280ad6071d21013651745a9478f063edAdhemerval Zanella continue; 6986e8946c5280ad6071d21013651745a9478f063edAdhemerval Zanella 6996e8946c5280ad6071d21013651745a9478f063edAdhemerval Zanella // Finally compares the Symbol value and the target symbol offset 7006e8946c5280ad6071d21013651745a9478f063edAdhemerval Zanella // to check if this .opd entry refers to the symbol the relocation 7016e8946c5280ad6071d21013651745a9478f063edAdhemerval Zanella // points to. 702ff9fa05905be716435460b5f6d32689041bf895bAndrew Kaylor if (Rel.Addend != (int64_t)TargetSymbolOffset) 7036e8946c5280ad6071d21013651745a9478f063edAdhemerval Zanella continue; 7046e8946c5280ad6071d21013651745a9478f063edAdhemerval Zanella 7056e8946c5280ad6071d21013651745a9478f063edAdhemerval Zanella section_iterator tsi(Obj.end_sections()); 7066c1202c459ffa6d693ad92fa84e43902bc780bcaRafael Espindola check(TargetSymbol->getSection(tsi)); 70736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines bool IsCode = false; 70836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines tsi->isText(IsCode); 70936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Rel.SectionID = findOrEmitSection(Obj, (*tsi), IsCode, LocalSections); 710167957fa095bc7200b908e6e142be3e604bcfeeaRafael Espindola Rel.Addend = (intptr_t)Addend; 7116e8946c5280ad6071d21013651745a9478f063edAdhemerval Zanella return; 7126e8946c5280ad6071d21013651745a9478f063edAdhemerval Zanella } 7136e8946c5280ad6071d21013651745a9478f063edAdhemerval Zanella } 7146e8946c5280ad6071d21013651745a9478f063edAdhemerval Zanella llvm_unreachable("Attempting to get address of ODP entry!"); 7156e8946c5280ad6071d21013651745a9478f063edAdhemerval Zanella} 7166e8946c5280ad6071d21013651745a9478f063edAdhemerval Zanella 717cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines// Relocation masks following the #lo(value), #hi(value), #ha(value), 718cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines// #higher(value), #highera(value), #highest(value), and #highesta(value) 719cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines// macros defined in section 4.5.1. Relocation Types of the PPC-elf64abi 720cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines// document. 721cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines 72236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesstatic inline uint16_t applyPPClo(uint64_t value) { return value & 0xffff; } 7236e8946c5280ad6071d21013651745a9478f063edAdhemerval Zanella 72436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesstatic inline uint16_t applyPPChi(uint64_t value) { 7256e8946c5280ad6071d21013651745a9478f063edAdhemerval Zanella return (value >> 16) & 0xffff; 7266e8946c5280ad6071d21013651745a9478f063edAdhemerval Zanella} 7276e8946c5280ad6071d21013651745a9478f063edAdhemerval Zanella 728cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hinesstatic inline uint16_t applyPPCha (uint64_t value) { 729cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines return ((value + 0x8000) >> 16) & 0xffff; 730cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines} 731cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines 73236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesstatic inline uint16_t applyPPChigher(uint64_t value) { 7336e8946c5280ad6071d21013651745a9478f063edAdhemerval Zanella return (value >> 32) & 0xffff; 7346e8946c5280ad6071d21013651745a9478f063edAdhemerval Zanella} 7356e8946c5280ad6071d21013651745a9478f063edAdhemerval Zanella 736cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hinesstatic inline uint16_t applyPPChighera (uint64_t value) { 737cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines return ((value + 0x8000) >> 32) & 0xffff; 738cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines} 739cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines 74036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesstatic inline uint16_t applyPPChighest(uint64_t value) { 7416e8946c5280ad6071d21013651745a9478f063edAdhemerval Zanella return (value >> 48) & 0xffff; 7426e8946c5280ad6071d21013651745a9478f063edAdhemerval Zanella} 7436e8946c5280ad6071d21013651745a9478f063edAdhemerval Zanella 744cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hinesstatic inline uint16_t applyPPChighesta (uint64_t value) { 745cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines return ((value + 0x8000) >> 48) & 0xffff; 746cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines} 747cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines 748a307a1cf859f4a523951ac887d094039547adeb5Andrew Kaylorvoid RuntimeDyldELF::resolvePPC64Relocation(const SectionEntry &Section, 74936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines uint64_t Offset, uint64_t Value, 75036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines uint32_t Type, int64_t Addend) { 75136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines uint8_t *LocalAddress = Section.Address + Offset; 7526e8946c5280ad6071d21013651745a9478f063edAdhemerval Zanella switch (Type) { 7536e8946c5280ad6071d21013651745a9478f063edAdhemerval Zanella default: 7546e8946c5280ad6071d21013651745a9478f063edAdhemerval Zanella llvm_unreachable("Relocation type not implemented yet!"); 7556e8946c5280ad6071d21013651745a9478f063edAdhemerval Zanella break; 756cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines case ELF::R_PPC64_ADDR16: 757cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines writeInt16BE(LocalAddress, applyPPClo(Value + Addend)); 758cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines break; 759cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines case ELF::R_PPC64_ADDR16_DS: 760cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines writeInt16BE(LocalAddress, applyPPClo(Value + Addend) & ~3); 761cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines break; 76236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines case ELF::R_PPC64_ADDR16_LO: 76336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines writeInt16BE(LocalAddress, applyPPClo(Value + Addend)); 76436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines break; 765cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines case ELF::R_PPC64_ADDR16_LO_DS: 766cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines writeInt16BE(LocalAddress, applyPPClo(Value + Addend) & ~3); 767cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines break; 76836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines case ELF::R_PPC64_ADDR16_HI: 76936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines writeInt16BE(LocalAddress, applyPPChi(Value + Addend)); 7706e8946c5280ad6071d21013651745a9478f063edAdhemerval Zanella break; 771cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines case ELF::R_PPC64_ADDR16_HA: 772cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines writeInt16BE(LocalAddress, applyPPCha(Value + Addend)); 773cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines break; 77436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines case ELF::R_PPC64_ADDR16_HIGHER: 77536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines writeInt16BE(LocalAddress, applyPPChigher(Value + Addend)); 7766e8946c5280ad6071d21013651745a9478f063edAdhemerval Zanella break; 777cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines case ELF::R_PPC64_ADDR16_HIGHERA: 778cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines writeInt16BE(LocalAddress, applyPPChighera(Value + Addend)); 779cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines break; 78036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines case ELF::R_PPC64_ADDR16_HIGHEST: 78136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines writeInt16BE(LocalAddress, applyPPChighest(Value + Addend)); 7826e8946c5280ad6071d21013651745a9478f063edAdhemerval Zanella break; 783cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines case ELF::R_PPC64_ADDR16_HIGHESTA: 784cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines writeInt16BE(LocalAddress, applyPPChighesta(Value + Addend)); 785cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines break; 78636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines case ELF::R_PPC64_ADDR14: { 7876e8946c5280ad6071d21013651745a9478f063edAdhemerval Zanella assert(((Value + Addend) & 3) == 0); 7886e8946c5280ad6071d21013651745a9478f063edAdhemerval Zanella // Preserve the AA/LK bits in the branch instruction 78936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines uint8_t aalk = *(LocalAddress + 3); 7906e8946c5280ad6071d21013651745a9478f063edAdhemerval Zanella writeInt16BE(LocalAddress + 2, (aalk & 3) | ((Value + Addend) & 0xfffc)); 7916e8946c5280ad6071d21013651745a9478f063edAdhemerval Zanella } break; 792cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines case ELF::R_PPC64_REL16_LO: { 793cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines uint64_t FinalAddress = (Section.LoadAddress + Offset); 794cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines uint64_t Delta = Value - FinalAddress + Addend; 795cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines writeInt16BE(LocalAddress, applyPPClo(Delta)); 796cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines } break; 797cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines case ELF::R_PPC64_REL16_HI: { 798cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines uint64_t FinalAddress = (Section.LoadAddress + Offset); 799cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines uint64_t Delta = Value - FinalAddress + Addend; 800cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines writeInt16BE(LocalAddress, applyPPChi(Delta)); 801cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines } break; 802cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines case ELF::R_PPC64_REL16_HA: { 803cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines uint64_t FinalAddress = (Section.LoadAddress + Offset); 804cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines uint64_t Delta = Value - FinalAddress + Addend; 805cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines writeInt16BE(LocalAddress, applyPPCha(Delta)); 806cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines } break; 80736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines case ELF::R_PPC64_ADDR32: { 8087b449889e7886b263718b5103538970f287bc37eAdhemerval Zanella int32_t Result = static_cast<int32_t>(Value + Addend); 8097b449889e7886b263718b5103538970f287bc37eAdhemerval Zanella if (SignExtend32<32>(Result) != Result) 810a1db5de9e70dd8ffda57b1a4373915ea866b6f1dAdhemerval Zanella llvm_unreachable("Relocation R_PPC64_ADDR32 overflow"); 8117b449889e7886b263718b5103538970f287bc37eAdhemerval Zanella writeInt32BE(LocalAddress, Result); 8127b449889e7886b263718b5103538970f287bc37eAdhemerval Zanella } break; 81336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines case ELF::R_PPC64_REL24: { 814a307a1cf859f4a523951ac887d094039547adeb5Andrew Kaylor uint64_t FinalAddress = (Section.LoadAddress + Offset); 8156e8946c5280ad6071d21013651745a9478f063edAdhemerval Zanella int32_t delta = static_cast<int32_t>(Value - FinalAddress + Addend); 8166e8946c5280ad6071d21013651745a9478f063edAdhemerval Zanella if (SignExtend32<24>(delta) != delta) 8176e8946c5280ad6071d21013651745a9478f063edAdhemerval Zanella llvm_unreachable("Relocation R_PPC64_REL24 overflow"); 8186e8946c5280ad6071d21013651745a9478f063edAdhemerval Zanella // Generates a 'bl <address>' instruction 8196e8946c5280ad6071d21013651745a9478f063edAdhemerval Zanella writeInt32BE(LocalAddress, 0x48000001 | (delta & 0x03FFFFFC)); 8206e8946c5280ad6071d21013651745a9478f063edAdhemerval Zanella } break; 82136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines case ELF::R_PPC64_REL32: { 822a1db5de9e70dd8ffda57b1a4373915ea866b6f1dAdhemerval Zanella uint64_t FinalAddress = (Section.LoadAddress + Offset); 823a1db5de9e70dd8ffda57b1a4373915ea866b6f1dAdhemerval Zanella int32_t delta = static_cast<int32_t>(Value - FinalAddress + Addend); 824a1db5de9e70dd8ffda57b1a4373915ea866b6f1dAdhemerval Zanella if (SignExtend32<32>(delta) != delta) 825a1db5de9e70dd8ffda57b1a4373915ea866b6f1dAdhemerval Zanella llvm_unreachable("Relocation R_PPC64_REL32 overflow"); 826a1db5de9e70dd8ffda57b1a4373915ea866b6f1dAdhemerval Zanella writeInt32BE(LocalAddress, delta); 827a1db5de9e70dd8ffda57b1a4373915ea866b6f1dAdhemerval Zanella } break; 828f51d7e76ae2c56588b162d84da54d5c3f0b66b51Adhemerval Zanella case ELF::R_PPC64_REL64: { 829f51d7e76ae2c56588b162d84da54d5c3f0b66b51Adhemerval Zanella uint64_t FinalAddress = (Section.LoadAddress + Offset); 830f51d7e76ae2c56588b162d84da54d5c3f0b66b51Adhemerval Zanella uint64_t Delta = Value - FinalAddress + Addend; 831f51d7e76ae2c56588b162d84da54d5c3f0b66b51Adhemerval Zanella writeInt64BE(LocalAddress, Delta); 832f51d7e76ae2c56588b162d84da54d5c3f0b66b51Adhemerval Zanella } break; 83336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines case ELF::R_PPC64_ADDR64: 8346e8946c5280ad6071d21013651745a9478f063edAdhemerval Zanella writeInt64BE(LocalAddress, Value + Addend); 8356e8946c5280ad6071d21013651745a9478f063edAdhemerval Zanella break; 8366e8946c5280ad6071d21013651745a9478f063edAdhemerval Zanella } 8376e8946c5280ad6071d21013651745a9478f063edAdhemerval Zanella} 8386e8946c5280ad6071d21013651745a9478f063edAdhemerval Zanella 8396fc2ad62e23673ef829c9c4bbf62743d30928a5bRichard Sandifordvoid RuntimeDyldELF::resolveSystemZRelocation(const SectionEntry &Section, 84036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines uint64_t Offset, uint64_t Value, 84136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines uint32_t Type, int64_t Addend) { 8426fc2ad62e23673ef829c9c4bbf62743d30928a5bRichard Sandiford uint8_t *LocalAddress = Section.Address + Offset; 8436fc2ad62e23673ef829c9c4bbf62743d30928a5bRichard Sandiford switch (Type) { 8446fc2ad62e23673ef829c9c4bbf62743d30928a5bRichard Sandiford default: 8456fc2ad62e23673ef829c9c4bbf62743d30928a5bRichard Sandiford llvm_unreachable("Relocation type not implemented yet!"); 8466fc2ad62e23673ef829c9c4bbf62743d30928a5bRichard Sandiford break; 8476fc2ad62e23673ef829c9c4bbf62743d30928a5bRichard Sandiford case ELF::R_390_PC16DBL: 8486fc2ad62e23673ef829c9c4bbf62743d30928a5bRichard Sandiford case ELF::R_390_PLT16DBL: { 8496fc2ad62e23673ef829c9c4bbf62743d30928a5bRichard Sandiford int64_t Delta = (Value + Addend) - (Section.LoadAddress + Offset); 8506fc2ad62e23673ef829c9c4bbf62743d30928a5bRichard Sandiford assert(int16_t(Delta / 2) * 2 == Delta && "R_390_PC16DBL overflow"); 8516fc2ad62e23673ef829c9c4bbf62743d30928a5bRichard Sandiford writeInt16BE(LocalAddress, Delta / 2); 8526fc2ad62e23673ef829c9c4bbf62743d30928a5bRichard Sandiford break; 8536fc2ad62e23673ef829c9c4bbf62743d30928a5bRichard Sandiford } 8546fc2ad62e23673ef829c9c4bbf62743d30928a5bRichard Sandiford case ELF::R_390_PC32DBL: 8556fc2ad62e23673ef829c9c4bbf62743d30928a5bRichard Sandiford case ELF::R_390_PLT32DBL: { 8566fc2ad62e23673ef829c9c4bbf62743d30928a5bRichard Sandiford int64_t Delta = (Value + Addend) - (Section.LoadAddress + Offset); 8576fc2ad62e23673ef829c9c4bbf62743d30928a5bRichard Sandiford assert(int32_t(Delta / 2) * 2 == Delta && "R_390_PC32DBL overflow"); 8586fc2ad62e23673ef829c9c4bbf62743d30928a5bRichard Sandiford writeInt32BE(LocalAddress, Delta / 2); 8596fc2ad62e23673ef829c9c4bbf62743d30928a5bRichard Sandiford break; 8606fc2ad62e23673ef829c9c4bbf62743d30928a5bRichard Sandiford } 8616fc2ad62e23673ef829c9c4bbf62743d30928a5bRichard Sandiford case ELF::R_390_PC32: { 8626fc2ad62e23673ef829c9c4bbf62743d30928a5bRichard Sandiford int64_t Delta = (Value + Addend) - (Section.LoadAddress + Offset); 8636fc2ad62e23673ef829c9c4bbf62743d30928a5bRichard Sandiford assert(int32_t(Delta) == Delta && "R_390_PC32 overflow"); 8646fc2ad62e23673ef829c9c4bbf62743d30928a5bRichard Sandiford writeInt32BE(LocalAddress, Delta); 8656fc2ad62e23673ef829c9c4bbf62743d30928a5bRichard Sandiford break; 8666fc2ad62e23673ef829c9c4bbf62743d30928a5bRichard Sandiford } 8676fc2ad62e23673ef829c9c4bbf62743d30928a5bRichard Sandiford case ELF::R_390_64: 8686fc2ad62e23673ef829c9c4bbf62743d30928a5bRichard Sandiford writeInt64BE(LocalAddress, Value + Addend); 8696fc2ad62e23673ef829c9c4bbf62743d30928a5bRichard Sandiford break; 8706fc2ad62e23673ef829c9c4bbf62743d30928a5bRichard Sandiford } 8716fc2ad62e23673ef829c9c4bbf62743d30928a5bRichard Sandiford} 8726fc2ad62e23673ef829c9c4bbf62743d30928a5bRichard Sandiford 87332bd10b1a33df2cc4d067a16901d56665f4ba085Andrew Kaylor// The target location for the relocation is described by RE.SectionID and 87432bd10b1a33df2cc4d067a16901d56665f4ba085Andrew Kaylor// RE.Offset. RE.SectionID can be used to find the SectionEntry. Each 87532bd10b1a33df2cc4d067a16901d56665f4ba085Andrew Kaylor// SectionEntry has three members describing its location. 87632bd10b1a33df2cc4d067a16901d56665f4ba085Andrew Kaylor// SectionEntry::Address is the address at which the section has been loaded 87732bd10b1a33df2cc4d067a16901d56665f4ba085Andrew Kaylor// into memory in the current (host) process. SectionEntry::LoadAddress is the 87832bd10b1a33df2cc4d067a16901d56665f4ba085Andrew Kaylor// address that the section will have in the target process. 87932bd10b1a33df2cc4d067a16901d56665f4ba085Andrew Kaylor// SectionEntry::ObjAddress is the address of the bits for this section in the 88032bd10b1a33df2cc4d067a16901d56665f4ba085Andrew Kaylor// original emitted object image (also in the current address space). 88132bd10b1a33df2cc4d067a16901d56665f4ba085Andrew Kaylor// 88232bd10b1a33df2cc4d067a16901d56665f4ba085Andrew Kaylor// Relocations will be applied as if the section were loaded at 88332bd10b1a33df2cc4d067a16901d56665f4ba085Andrew Kaylor// SectionEntry::LoadAddress, but they will be applied at an address based 88432bd10b1a33df2cc4d067a16901d56665f4ba085Andrew Kaylor// on SectionEntry::Address. SectionEntry::ObjAddress will be used to refer to 88532bd10b1a33df2cc4d067a16901d56665f4ba085Andrew Kaylor// Target memory contents if they are required for value calculations. 88632bd10b1a33df2cc4d067a16901d56665f4ba085Andrew Kaylor// 88732bd10b1a33df2cc4d067a16901d56665f4ba085Andrew Kaylor// The Value parameter here is the load address of the symbol for the 88832bd10b1a33df2cc4d067a16901d56665f4ba085Andrew Kaylor// relocation to be applied. For relocations which refer to symbols in the 88932bd10b1a33df2cc4d067a16901d56665f4ba085Andrew Kaylor// current object Value will be the LoadAddress of the section in which 89032bd10b1a33df2cc4d067a16901d56665f4ba085Andrew Kaylor// the symbol resides (RE.Addend provides additional information about the 89132bd10b1a33df2cc4d067a16901d56665f4ba085Andrew Kaylor// symbol location). For external symbols, Value will be the address of the 89232bd10b1a33df2cc4d067a16901d56665f4ba085Andrew Kaylor// symbol in the target address space. 89387b5017139e9d8ac9b046b3284a9cc68c76185d6Rafael Espindolavoid RuntimeDyldELF::resolveRelocation(const RelocationEntry &RE, 89432bd10b1a33df2cc4d067a16901d56665f4ba085Andrew Kaylor uint64_t Value) { 89587b5017139e9d8ac9b046b3284a9cc68c76185d6Rafael Espindola const SectionEntry &Section = Sections[RE.SectionID]; 896ff9fa05905be716435460b5f6d32689041bf895bAndrew Kaylor return resolveRelocation(Section, RE.Offset, Value, RE.RelType, RE.Addend, 897ff9fa05905be716435460b5f6d32689041bf895bAndrew Kaylor RE.SymOffset); 89887b5017139e9d8ac9b046b3284a9cc68c76185d6Rafael Espindola} 89987b5017139e9d8ac9b046b3284a9cc68c76185d6Rafael Espindola 900a307a1cf859f4a523951ac887d094039547adeb5Andrew Kaylorvoid RuntimeDyldELF::resolveRelocation(const SectionEntry &Section, 90136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines uint64_t Offset, uint64_t Value, 90236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines uint32_t Type, int64_t Addend, 903ff9fa05905be716435460b5f6d32689041bf895bAndrew Kaylor uint64_t SymOffset) { 904a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky switch (Arch) { 905a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky case Triple::x86_64: 906ff9fa05905be716435460b5f6d32689041bf895bAndrew Kaylor resolveX86_64Relocation(Section, Offset, Value, Type, Addend, SymOffset); 907a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky break; 908a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky case Triple::x86: 90936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines resolveX86Relocation(Section, Offset, (uint32_t)(Value & 0xffffffffL), Type, 9100e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev (uint32_t)(Addend & 0xffffffffL)); 911a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky break; 91285829bb98a998cff8f364c12d172da948ca225f4Tim Northover case Triple::aarch64: 91336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines case Triple::aarch64_be: 914dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines case Triple::arm64: 915dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines case Triple::arm64_be: 91685829bb98a998cff8f364c12d172da948ca225f4Tim Northover resolveAArch64Relocation(Section, Offset, Value, Type, Addend); 91785829bb98a998cff8f364c12d172da948ca225f4Tim Northover break; 91836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines case Triple::arm: // Fall through. 91936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines case Triple::armeb: 9200e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev case Triple::thumb: 92136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines case Triple::thumbeb: 92236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines resolveARMRelocation(Section, Offset, (uint32_t)(Value & 0xffffffffL), Type, 9230e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev (uint32_t)(Addend & 0xffffffffL)); 924a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky break; 92536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines case Triple::mips: // Fall through. 926b889e0cd2fea4afee623d5be603b912b955a2ecaAkira Hatanaka case Triple::mipsel: 92736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines resolveMIPSRelocation(Section, Offset, (uint32_t)(Value & 0xffffffffL), 92836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Type, (uint32_t)(Addend & 0xffffffffL)); 929b889e0cd2fea4afee623d5be603b912b955a2ecaAkira Hatanaka break; 93036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines case Triple::ppc64: // Fall through. 931f38cc38fa647d4e72c053c39bbe0cdec1342535fBill Schmidt case Triple::ppc64le: 932a307a1cf859f4a523951ac887d094039547adeb5Andrew Kaylor resolvePPC64Relocation(Section, Offset, Value, Type, Addend); 9336e8946c5280ad6071d21013651745a9478f063edAdhemerval Zanella break; 9346fc2ad62e23673ef829c9c4bbf62743d30928a5bRichard Sandiford case Triple::systemz: 9356fc2ad62e23673ef829c9c4bbf62743d30928a5bRichard Sandiford resolveSystemZRelocation(Section, Offset, Value, Type, Addend); 9366fc2ad62e23673ef829c9c4bbf62743d30928a5bRichard Sandiford break; 93736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines default: 93836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines llvm_unreachable("Unsupported CPU type!"); 939a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky } 940a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky} 941a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky 94236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesrelocation_iterator RuntimeDyldELF::processRelocationRef( 94336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines unsigned SectionID, relocation_iterator RelI, ObjectImage &Obj, 94436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines ObjSectionToIDMap &ObjSectionToID, const SymbolTableMap &Symbols, 94536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines StubMap &Stubs) { 946efa91f6475f6e96552986104ab4857db46185a2aRafael Espindola uint64_t RelType; 94736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Check(RelI->getType(RelType)); 948efa91f6475f6e96552986104ab4857db46185a2aRafael Espindola int64_t Addend; 94936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Check(getELFRelocationAddend(*RelI, Addend)); 95036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines symbol_iterator Symbol = RelI->getSymbol(); 951c201e6eaf165c83f0092c43b371e509fa8eaf4ccEli Bendersky 952c201e6eaf165c83f0092c43b371e509fa8eaf4ccEli Bendersky // Obtain the symbol name which is referenced in the relocation 953c201e6eaf165c83f0092c43b371e509fa8eaf4ccEli Bendersky StringRef TargetName; 9540962b1683f242cd6274423c24f0059832284b1c8Rafael Espindola if (Symbol != Obj.end_symbols()) 9550962b1683f242cd6274423c24f0059832284b1c8Rafael Espindola Symbol->getName(TargetName); 95636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines DEBUG(dbgs() << "\t\tRelType: " << RelType << " Addend: " << Addend 95736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines << " TargetName: " << TargetName << "\n"); 958c201e6eaf165c83f0092c43b371e509fa8eaf4ccEli Bendersky RelocationValueRef Value; 959c201e6eaf165c83f0092c43b371e509fa8eaf4ccEli Bendersky // First search for the symbol in the local symbol table 9600962b1683f242cd6274423c24f0059832284b1c8Rafael Espindola SymbolTableMap::const_iterator lsi = Symbols.end(); 9610962b1683f242cd6274423c24f0059832284b1c8Rafael Espindola SymbolRef::Type SymType = SymbolRef::ST_Unknown; 9620962b1683f242cd6274423c24f0059832284b1c8Rafael Espindola if (Symbol != Obj.end_symbols()) { 9630962b1683f242cd6274423c24f0059832284b1c8Rafael Espindola lsi = Symbols.find(TargetName.data()); 9640962b1683f242cd6274423c24f0059832284b1c8Rafael Espindola Symbol->getType(SymType); 9650962b1683f242cd6274423c24f0059832284b1c8Rafael Espindola } 9660e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev if (lsi != Symbols.end()) { 9670e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev Value.SectionID = lsi->second.first; 968ff9fa05905be716435460b5f6d32689041bf895bAndrew Kaylor Value.Offset = lsi->second.second; 96903f018a71348893d567d5062987dfbc52b8560e3Ulrich Weigand Value.Addend = lsi->second.second + Addend; 9700e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev } else { 971c201e6eaf165c83f0092c43b371e509fa8eaf4ccEli Bendersky // Search for the symbol in the global symbol table 9720962b1683f242cd6274423c24f0059832284b1c8Rafael Espindola SymbolTableMap::const_iterator gsi = GlobalSymbolTable.end(); 9730962b1683f242cd6274423c24f0059832284b1c8Rafael Espindola if (Symbol != Obj.end_symbols()) 9740962b1683f242cd6274423c24f0059832284b1c8Rafael Espindola gsi = GlobalSymbolTable.find(TargetName.data()); 975d98c9e918c9750d965c1efe9efcc9e13feacbe13Eli Bendersky if (gsi != GlobalSymbolTable.end()) { 9760e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev Value.SectionID = gsi->second.first; 977ff9fa05905be716435460b5f6d32689041bf895bAndrew Kaylor Value.Offset = gsi->second.second; 97803f018a71348893d567d5062987dfbc52b8560e3Ulrich Weigand Value.Addend = gsi->second.second + Addend; 9790e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev } else { 9800e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev switch (SymType) { 98136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines case SymbolRef::ST_Debug: { 98236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // TODO: Now ELF SymbolRef::ST_Debug = STT_SECTION, it's not obviously 98336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // and can be changed by another developers. Maybe best way is add 98436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // a new symbol type ST_Section to SymbolRef and use it. 98536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines section_iterator si(Obj.end_sections()); 98636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Symbol->getSection(si); 98736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (si == Obj.end_sections()) 98836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines llvm_unreachable("Symbol section not found, bad object file format!"); 98936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines DEBUG(dbgs() << "\t\tThis is section symbol\n"); 99036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // Default to 'true' in case isText fails (though it never does). 99136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines bool isCode = true; 99236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines si->isText(isCode); 99336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Value.SectionID = findOrEmitSection(Obj, (*si), isCode, ObjSectionToID); 99436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Value.Addend = Addend; 99536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines break; 99636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 99736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines case SymbolRef::ST_Data: 99836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines case SymbolRef::ST_Unknown: { 99936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Value.SymbolName = TargetName.data(); 100036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Value.Addend = Addend; 100136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 100236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // Absolute relocations will have a zero symbol ID (STN_UNDEF), which 100336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // will manifest here as a NULL symbol name. 100436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // We can set this as a valid (but empty) symbol name, and rely 100536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // on addRelocationForSymbol to handle this. 100636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (!Value.SymbolName) 100736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Value.SymbolName = ""; 100836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines break; 100936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 101036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines default: 101136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines llvm_unreachable("Unresolved symbol type!"); 101236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines break; 10130e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev } 10140e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev } 1015a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky } 1016efa91f6475f6e96552986104ab4857db46185a2aRafael Espindola uint64_t Offset; 101736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Check(RelI->getOffset(Offset)); 1018efa91f6475f6e96552986104ab4857db46185a2aRafael Espindola 101936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines DEBUG(dbgs() << "\t\tSectionID: " << SectionID << " Offset: " << Offset 10200e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev << "\n"); 1021dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines if ((Arch == Triple::aarch64 || Arch == Triple::aarch64_be || 1022dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines Arch == Triple::arm64 || Arch == Triple::arm64_be) && 102336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines (RelType == ELF::R_AARCH64_CALL26 || RelType == ELF::R_AARCH64_JUMP26)) { 10244a9b6b798d5ea335f5f29d278db83b830ae4a564Tim Northover // This is an AArch64 branch relocation, need to use a stub function. 10254a9b6b798d5ea335f5f29d278db83b830ae4a564Tim Northover DEBUG(dbgs() << "\t\tThis is an AArch64 branch relocation."); 10264a9b6b798d5ea335f5f29d278db83b830ae4a564Tim Northover SectionEntry &Section = Sections[SectionID]; 10274a9b6b798d5ea335f5f29d278db83b830ae4a564Tim Northover 10284a9b6b798d5ea335f5f29d278db83b830ae4a564Tim Northover // Look for an existing stub. 10294a9b6b798d5ea335f5f29d278db83b830ae4a564Tim Northover StubMap::const_iterator i = Stubs.find(Value); 10304a9b6b798d5ea335f5f29d278db83b830ae4a564Tim Northover if (i != Stubs.end()) { 103136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines resolveRelocation(Section, Offset, (uint64_t)Section.Address + i->second, 103236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines RelType, 0); 10334a9b6b798d5ea335f5f29d278db83b830ae4a564Tim Northover DEBUG(dbgs() << " Stub function found\n"); 10344a9b6b798d5ea335f5f29d278db83b830ae4a564Tim Northover } else { 10354a9b6b798d5ea335f5f29d278db83b830ae4a564Tim Northover // Create a new stub function. 10364a9b6b798d5ea335f5f29d278db83b830ae4a564Tim Northover DEBUG(dbgs() << " Create a new stub function\n"); 10374a9b6b798d5ea335f5f29d278db83b830ae4a564Tim Northover Stubs[Value] = Section.StubOffset; 103836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines uint8_t *StubTargetAddr = 103936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines createStubFunction(Section.Address + Section.StubOffset); 10404a9b6b798d5ea335f5f29d278db83b830ae4a564Tim Northover 104136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines RelocationEntry REmovz_g3(SectionID, StubTargetAddr - Section.Address, 10424a9b6b798d5ea335f5f29d278db83b830ae4a564Tim Northover ELF::R_AARCH64_MOVW_UABS_G3, Value.Addend); 104336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines RelocationEntry REmovk_g2(SectionID, StubTargetAddr - Section.Address + 4, 10444a9b6b798d5ea335f5f29d278db83b830ae4a564Tim Northover ELF::R_AARCH64_MOVW_UABS_G2_NC, Value.Addend); 104536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines RelocationEntry REmovk_g1(SectionID, StubTargetAddr - Section.Address + 8, 10464a9b6b798d5ea335f5f29d278db83b830ae4a564Tim Northover ELF::R_AARCH64_MOVW_UABS_G1_NC, Value.Addend); 10474a9b6b798d5ea335f5f29d278db83b830ae4a564Tim Northover RelocationEntry REmovk_g0(SectionID, 10484a9b6b798d5ea335f5f29d278db83b830ae4a564Tim Northover StubTargetAddr - Section.Address + 12, 10494a9b6b798d5ea335f5f29d278db83b830ae4a564Tim Northover ELF::R_AARCH64_MOVW_UABS_G0_NC, Value.Addend); 10504a9b6b798d5ea335f5f29d278db83b830ae4a564Tim Northover 10514a9b6b798d5ea335f5f29d278db83b830ae4a564Tim Northover if (Value.SymbolName) { 10524a9b6b798d5ea335f5f29d278db83b830ae4a564Tim Northover addRelocationForSymbol(REmovz_g3, Value.SymbolName); 10534a9b6b798d5ea335f5f29d278db83b830ae4a564Tim Northover addRelocationForSymbol(REmovk_g2, Value.SymbolName); 10544a9b6b798d5ea335f5f29d278db83b830ae4a564Tim Northover addRelocationForSymbol(REmovk_g1, Value.SymbolName); 10554a9b6b798d5ea335f5f29d278db83b830ae4a564Tim Northover addRelocationForSymbol(REmovk_g0, Value.SymbolName); 10564a9b6b798d5ea335f5f29d278db83b830ae4a564Tim Northover } else { 10574a9b6b798d5ea335f5f29d278db83b830ae4a564Tim Northover addRelocationForSection(REmovz_g3, Value.SectionID); 10584a9b6b798d5ea335f5f29d278db83b830ae4a564Tim Northover addRelocationForSection(REmovk_g2, Value.SectionID); 10594a9b6b798d5ea335f5f29d278db83b830ae4a564Tim Northover addRelocationForSection(REmovk_g1, Value.SectionID); 10604a9b6b798d5ea335f5f29d278db83b830ae4a564Tim Northover addRelocationForSection(REmovk_g0, Value.SectionID); 10614a9b6b798d5ea335f5f29d278db83b830ae4a564Tim Northover } 10624a9b6b798d5ea335f5f29d278db83b830ae4a564Tim Northover resolveRelocation(Section, Offset, 106336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines (uint64_t)Section.Address + Section.StubOffset, RelType, 106436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 0); 10654a9b6b798d5ea335f5f29d278db83b830ae4a564Tim Northover Section.StubOffset += getMaxStubSize(); 10664a9b6b798d5ea335f5f29d278db83b830ae4a564Tim Northover } 10674a9b6b798d5ea335f5f29d278db83b830ae4a564Tim Northover } else if (Arch == Triple::arm && 106836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines (RelType == ELF::R_ARM_PC24 || RelType == ELF::R_ARM_CALL || 106936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines RelType == ELF::R_ARM_JUMP24)) { 10700e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev // This is an ARM branch relocation, need to use a stub function. 10710e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev DEBUG(dbgs() << "\t\tThis is an ARM branch relocation."); 1072efa91f6475f6e96552986104ab4857db46185a2aRafael Espindola SectionEntry &Section = Sections[SectionID]; 10730e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev 1074bf261f11a0142ce315e9bb5a2412419a777460a9Eric Christopher // Look for an existing stub. 10750e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev StubMap::const_iterator i = Stubs.find(Value); 10760e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev if (i != Stubs.end()) { 107736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines resolveRelocation(Section, Offset, (uint64_t)Section.Address + i->second, 107836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines RelType, 0); 10790e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev DEBUG(dbgs() << " Stub function found\n"); 10800e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev } else { 10810e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev // Create a new stub function. 10820e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev DEBUG(dbgs() << " Create a new stub function\n"); 10830e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev Stubs[Value] = Section.StubOffset; 108436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines uint8_t *StubTargetAddr = 108536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines createStubFunction(Section.Address + Section.StubOffset); 1086efa91f6475f6e96552986104ab4857db46185a2aRafael Espindola RelocationEntry RE(SectionID, StubTargetAddr - Section.Address, 1087e274b476de33ee4f2e90a3eb3a56b5cdd619eb82Tim Northover ELF::R_ARM_PRIVATE_0, Value.Addend); 1088c201e6eaf165c83f0092c43b371e509fa8eaf4ccEli Bendersky if (Value.SymbolName) 1089c201e6eaf165c83f0092c43b371e509fa8eaf4ccEli Bendersky addRelocationForSymbol(RE, Value.SymbolName); 1090c201e6eaf165c83f0092c43b371e509fa8eaf4ccEli Bendersky else 1091c201e6eaf165c83f0092c43b371e509fa8eaf4ccEli Bendersky addRelocationForSection(RE, Value.SectionID); 1092c201e6eaf165c83f0092c43b371e509fa8eaf4ccEli Bendersky 1093efa91f6475f6e96552986104ab4857db46185a2aRafael Espindola resolveRelocation(Section, Offset, 109436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines (uint64_t)Section.Address + Section.StubOffset, RelType, 109536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 0); 10960e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev Section.StubOffset += getMaxStubSize(); 10970e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev } 1098ade047463fd6e0fbb447145eb06015b8e7836482Akira Hatanaka } else if ((Arch == Triple::mipsel || Arch == Triple::mips) && 1099ade047463fd6e0fbb447145eb06015b8e7836482Akira Hatanaka RelType == ELF::R_MIPS_26) { 1100b889e0cd2fea4afee623d5be603b912b955a2ecaAkira Hatanaka // This is an Mips branch relocation, need to use a stub function. 1101b889e0cd2fea4afee623d5be603b912b955a2ecaAkira Hatanaka DEBUG(dbgs() << "\t\tThis is a Mips branch relocation."); 1102efa91f6475f6e96552986104ab4857db46185a2aRafael Espindola SectionEntry &Section = Sections[SectionID]; 1103efa91f6475f6e96552986104ab4857db46185a2aRafael Espindola uint8_t *Target = Section.Address + Offset; 1104b889e0cd2fea4afee623d5be603b912b955a2ecaAkira Hatanaka uint32_t *TargetAddress = (uint32_t *)Target; 1105b889e0cd2fea4afee623d5be603b912b955a2ecaAkira Hatanaka 1106b889e0cd2fea4afee623d5be603b912b955a2ecaAkira Hatanaka // Extract the addend from the instruction. 1107b889e0cd2fea4afee623d5be603b912b955a2ecaAkira Hatanaka uint32_t Addend = ((*TargetAddress) & 0x03ffffff) << 2; 1108b889e0cd2fea4afee623d5be603b912b955a2ecaAkira Hatanaka 1109b889e0cd2fea4afee623d5be603b912b955a2ecaAkira Hatanaka Value.Addend += Addend; 1110b889e0cd2fea4afee623d5be603b912b955a2ecaAkira Hatanaka 1111b889e0cd2fea4afee623d5be603b912b955a2ecaAkira Hatanaka // Look up for existing stub. 1112b889e0cd2fea4afee623d5be603b912b955a2ecaAkira Hatanaka StubMap::const_iterator i = Stubs.find(Value); 1113b889e0cd2fea4afee623d5be603b912b955a2ecaAkira Hatanaka if (i != Stubs.end()) { 11140ff917e85472b98aec8f9d48647cde6941a5ea27Petar Jovanovic RelocationEntry RE(SectionID, Offset, RelType, i->second); 11150ff917e85472b98aec8f9d48647cde6941a5ea27Petar Jovanovic addRelocationForSection(RE, SectionID); 1116b889e0cd2fea4afee623d5be603b912b955a2ecaAkira Hatanaka DEBUG(dbgs() << " Stub function found\n"); 1117b889e0cd2fea4afee623d5be603b912b955a2ecaAkira Hatanaka } else { 1118b889e0cd2fea4afee623d5be603b912b955a2ecaAkira Hatanaka // Create a new stub function. 1119b889e0cd2fea4afee623d5be603b912b955a2ecaAkira Hatanaka DEBUG(dbgs() << " Create a new stub function\n"); 1120b889e0cd2fea4afee623d5be603b912b955a2ecaAkira Hatanaka Stubs[Value] = Section.StubOffset; 112136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines uint8_t *StubTargetAddr = 112236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines createStubFunction(Section.Address + Section.StubOffset); 1123b889e0cd2fea4afee623d5be603b912b955a2ecaAkira Hatanaka 1124b889e0cd2fea4afee623d5be603b912b955a2ecaAkira Hatanaka // Creating Hi and Lo relocations for the filled stub instructions. 112536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines RelocationEntry REHi(SectionID, StubTargetAddr - Section.Address, 11263af1c9d3343357849f19f7467f9c16220ad37ca4Akira Hatanaka ELF::R_MIPS_UNUSED1, Value.Addend); 112736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines RelocationEntry RELo(SectionID, StubTargetAddr - Section.Address + 4, 11283af1c9d3343357849f19f7467f9c16220ad37ca4Akira Hatanaka ELF::R_MIPS_UNUSED2, Value.Addend); 1129b889e0cd2fea4afee623d5be603b912b955a2ecaAkira Hatanaka 1130b889e0cd2fea4afee623d5be603b912b955a2ecaAkira Hatanaka if (Value.SymbolName) { 1131b889e0cd2fea4afee623d5be603b912b955a2ecaAkira Hatanaka addRelocationForSymbol(REHi, Value.SymbolName); 1132b889e0cd2fea4afee623d5be603b912b955a2ecaAkira Hatanaka addRelocationForSymbol(RELo, Value.SymbolName); 1133b889e0cd2fea4afee623d5be603b912b955a2ecaAkira Hatanaka } else { 1134b889e0cd2fea4afee623d5be603b912b955a2ecaAkira Hatanaka addRelocationForSection(REHi, Value.SectionID); 1135b889e0cd2fea4afee623d5be603b912b955a2ecaAkira Hatanaka addRelocationForSection(RELo, Value.SectionID); 1136b889e0cd2fea4afee623d5be603b912b955a2ecaAkira Hatanaka } 1137b889e0cd2fea4afee623d5be603b912b955a2ecaAkira Hatanaka 11380ff917e85472b98aec8f9d48647cde6941a5ea27Petar Jovanovic RelocationEntry RE(SectionID, Offset, RelType, Section.StubOffset); 11390ff917e85472b98aec8f9d48647cde6941a5ea27Petar Jovanovic addRelocationForSection(RE, SectionID); 1140b889e0cd2fea4afee623d5be603b912b955a2ecaAkira Hatanaka Section.StubOffset += getMaxStubSize(); 1141b889e0cd2fea4afee623d5be603b912b955a2ecaAkira Hatanaka } 1142f38cc38fa647d4e72c053c39bbe0cdec1342535fBill Schmidt } else if (Arch == Triple::ppc64 || Arch == Triple::ppc64le) { 11436e8946c5280ad6071d21013651745a9478f063edAdhemerval Zanella if (RelType == ELF::R_PPC64_REL24) { 11446e8946c5280ad6071d21013651745a9478f063edAdhemerval Zanella // A PPC branch relocation will need a stub function if the target is 11456e8946c5280ad6071d21013651745a9478f063edAdhemerval Zanella // an external symbol (Symbol::ST_Unknown) or if the target address 11466e8946c5280ad6071d21013651745a9478f063edAdhemerval Zanella // is not within the signed 24-bits branch address. 1147efa91f6475f6e96552986104ab4857db46185a2aRafael Espindola SectionEntry &Section = Sections[SectionID]; 1148efa91f6475f6e96552986104ab4857db46185a2aRafael Espindola uint8_t *Target = Section.Address + Offset; 11496e8946c5280ad6071d21013651745a9478f063edAdhemerval Zanella bool RangeOverflow = false; 11506e8946c5280ad6071d21013651745a9478f063edAdhemerval Zanella if (SymType != SymbolRef::ST_Unknown) { 115136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // A function call may points to the .opd entry, so the final symbol 115236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // value 11536e8946c5280ad6071d21013651745a9478f063edAdhemerval Zanella // in calculated based in the relocation values in .opd section. 11546e8946c5280ad6071d21013651745a9478f063edAdhemerval Zanella findOPDEntrySection(Obj, ObjSectionToID, Value); 11556e8946c5280ad6071d21013651745a9478f063edAdhemerval Zanella uint8_t *RelocTarget = Sections[Value.SectionID].Address + Value.Addend; 11566e8946c5280ad6071d21013651745a9478f063edAdhemerval Zanella int32_t delta = static_cast<int32_t>(Target - RelocTarget); 11576e8946c5280ad6071d21013651745a9478f063edAdhemerval Zanella // If it is within 24-bits branch range, just set the branch target 11586e8946c5280ad6071d21013651745a9478f063edAdhemerval Zanella if (SignExtend32<24>(delta) == delta) { 1159efa91f6475f6e96552986104ab4857db46185a2aRafael Espindola RelocationEntry RE(SectionID, Offset, RelType, Value.Addend); 11606e8946c5280ad6071d21013651745a9478f063edAdhemerval Zanella if (Value.SymbolName) 11616e8946c5280ad6071d21013651745a9478f063edAdhemerval Zanella addRelocationForSymbol(RE, Value.SymbolName); 11626e8946c5280ad6071d21013651745a9478f063edAdhemerval Zanella else 11636e8946c5280ad6071d21013651745a9478f063edAdhemerval Zanella addRelocationForSection(RE, Value.SectionID); 11646e8946c5280ad6071d21013651745a9478f063edAdhemerval Zanella } else { 11656e8946c5280ad6071d21013651745a9478f063edAdhemerval Zanella RangeOverflow = true; 11666e8946c5280ad6071d21013651745a9478f063edAdhemerval Zanella } 11676e8946c5280ad6071d21013651745a9478f063edAdhemerval Zanella } 11686e8946c5280ad6071d21013651745a9478f063edAdhemerval Zanella if (SymType == SymbolRef::ST_Unknown || RangeOverflow == true) { 11696e8946c5280ad6071d21013651745a9478f063edAdhemerval Zanella // It is an external symbol (SymbolRef::ST_Unknown) or within a range 11706e8946c5280ad6071d21013651745a9478f063edAdhemerval Zanella // larger than 24-bits. 11716e8946c5280ad6071d21013651745a9478f063edAdhemerval Zanella StubMap::const_iterator i = Stubs.find(Value); 11726e8946c5280ad6071d21013651745a9478f063edAdhemerval Zanella if (i != Stubs.end()) { 11736e8946c5280ad6071d21013651745a9478f063edAdhemerval Zanella // Symbol function stub already created, just relocate to it 1174efa91f6475f6e96552986104ab4857db46185a2aRafael Espindola resolveRelocation(Section, Offset, 1175a307a1cf859f4a523951ac887d094039547adeb5Andrew Kaylor (uint64_t)Section.Address + i->second, RelType, 0); 11766e8946c5280ad6071d21013651745a9478f063edAdhemerval Zanella DEBUG(dbgs() << " Stub function found\n"); 11776e8946c5280ad6071d21013651745a9478f063edAdhemerval Zanella } else { 11786e8946c5280ad6071d21013651745a9478f063edAdhemerval Zanella // Create a new stub function. 11796e8946c5280ad6071d21013651745a9478f063edAdhemerval Zanella DEBUG(dbgs() << " Create a new stub function\n"); 11806e8946c5280ad6071d21013651745a9478f063edAdhemerval Zanella Stubs[Value] = Section.StubOffset; 118136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines uint8_t *StubTargetAddr = 118236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines createStubFunction(Section.Address + Section.StubOffset); 1183efa91f6475f6e96552986104ab4857db46185a2aRafael Espindola RelocationEntry RE(SectionID, StubTargetAddr - Section.Address, 11846e8946c5280ad6071d21013651745a9478f063edAdhemerval Zanella ELF::R_PPC64_ADDR64, Value.Addend); 11856e8946c5280ad6071d21013651745a9478f063edAdhemerval Zanella 11866e8946c5280ad6071d21013651745a9478f063edAdhemerval Zanella // Generates the 64-bits address loads as exemplified in section 1187cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines // 4.5.1 in PPC64 ELF ABI. Note that the relocations need to 1188cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines // apply to the low part of the instructions, so we have to update 1189cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines // the offset according to the target endianness. 1190cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines uint64_t StubRelocOffset = StubTargetAddr - Section.Address; 1191cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines if (!IsTargetLittleEndian) 1192cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines StubRelocOffset += 2; 1193cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines 1194cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines RelocationEntry REhst(SectionID, StubRelocOffset + 0, 11956e8946c5280ad6071d21013651745a9478f063edAdhemerval Zanella ELF::R_PPC64_ADDR16_HIGHEST, Value.Addend); 1196cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines RelocationEntry REhr(SectionID, StubRelocOffset + 4, 11976e8946c5280ad6071d21013651745a9478f063edAdhemerval Zanella ELF::R_PPC64_ADDR16_HIGHER, Value.Addend); 1198cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines RelocationEntry REh(SectionID, StubRelocOffset + 12, 11996e8946c5280ad6071d21013651745a9478f063edAdhemerval Zanella ELF::R_PPC64_ADDR16_HI, Value.Addend); 1200cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines RelocationEntry REl(SectionID, StubRelocOffset + 16, 12016e8946c5280ad6071d21013651745a9478f063edAdhemerval Zanella ELF::R_PPC64_ADDR16_LO, Value.Addend); 12026e8946c5280ad6071d21013651745a9478f063edAdhemerval Zanella 12036e8946c5280ad6071d21013651745a9478f063edAdhemerval Zanella if (Value.SymbolName) { 12046e8946c5280ad6071d21013651745a9478f063edAdhemerval Zanella addRelocationForSymbol(REhst, Value.SymbolName); 120536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines addRelocationForSymbol(REhr, Value.SymbolName); 120636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines addRelocationForSymbol(REh, Value.SymbolName); 120736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines addRelocationForSymbol(REl, Value.SymbolName); 12086e8946c5280ad6071d21013651745a9478f063edAdhemerval Zanella } else { 12096e8946c5280ad6071d21013651745a9478f063edAdhemerval Zanella addRelocationForSection(REhst, Value.SectionID); 121036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines addRelocationForSection(REhr, Value.SectionID); 121136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines addRelocationForSection(REh, Value.SectionID); 121236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines addRelocationForSection(REl, Value.SectionID); 12136e8946c5280ad6071d21013651745a9478f063edAdhemerval Zanella } 12146e8946c5280ad6071d21013651745a9478f063edAdhemerval Zanella 1215efa91f6475f6e96552986104ab4857db46185a2aRafael Espindola resolveRelocation(Section, Offset, 1216a307a1cf859f4a523951ac887d094039547adeb5Andrew Kaylor (uint64_t)Section.Address + Section.StubOffset, 1217a307a1cf859f4a523951ac887d094039547adeb5Andrew Kaylor RelType, 0); 12186e8946c5280ad6071d21013651745a9478f063edAdhemerval Zanella Section.StubOffset += getMaxStubSize(); 12196e8946c5280ad6071d21013651745a9478f063edAdhemerval Zanella } 122036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (SymType == SymbolRef::ST_Unknown) 122136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // Restore the TOC for external calls 122236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines writeInt32BE(Target + 4, 0xE8410028); // ld r2,40(r1) 12236e8946c5280ad6071d21013651745a9478f063edAdhemerval Zanella } 1224cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines } else if (RelType == ELF::R_PPC64_TOC16 || 1225cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines RelType == ELF::R_PPC64_TOC16_DS || 1226cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines RelType == ELF::R_PPC64_TOC16_LO || 1227cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines RelType == ELF::R_PPC64_TOC16_LO_DS || 1228cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines RelType == ELF::R_PPC64_TOC16_HI || 1229cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines RelType == ELF::R_PPC64_TOC16_HA) { 1230cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines // These relocations are supposed to subtract the TOC address from 1231cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines // the final value. This does not fit cleanly into the RuntimeDyld 1232cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines // scheme, since there may be *two* sections involved in determining 1233cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines // the relocation value (the section of the symbol refered to by the 1234cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines // relocation, and the TOC section associated with the current module). 1235cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines // 1236cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines // Fortunately, these relocations are currently only ever generated 1237cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines // refering to symbols that themselves reside in the TOC, which means 1238cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines // that the two sections are actually the same. Thus they cancel out 1239cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines // and we can immediately resolve the relocation right now. 1240cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines switch (RelType) { 1241cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines case ELF::R_PPC64_TOC16: RelType = ELF::R_PPC64_ADDR16; break; 1242cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines case ELF::R_PPC64_TOC16_DS: RelType = ELF::R_PPC64_ADDR16_DS; break; 1243cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines case ELF::R_PPC64_TOC16_LO: RelType = ELF::R_PPC64_ADDR16_LO; break; 1244cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines case ELF::R_PPC64_TOC16_LO_DS: RelType = ELF::R_PPC64_ADDR16_LO_DS; break; 1245cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines case ELF::R_PPC64_TOC16_HI: RelType = ELF::R_PPC64_ADDR16_HI; break; 1246cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines case ELF::R_PPC64_TOC16_HA: RelType = ELF::R_PPC64_ADDR16_HA; break; 1247cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines default: llvm_unreachable("Wrong relocation type."); 1248cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines } 1249cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines 1250cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines RelocationValueRef TOCValue; 1251cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines findPPC64TOCSection(Obj, ObjSectionToID, TOCValue); 1252cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines if (Value.SymbolName || Value.SectionID != TOCValue.SectionID) 1253cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines llvm_unreachable("Unsupported TOC relocation."); 1254cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines Value.Addend -= TOCValue.Addend; 1255cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines resolveRelocation(Sections[SectionID], Offset, Value.Addend, RelType, 0); 12566e8946c5280ad6071d21013651745a9478f063edAdhemerval Zanella } else { 1257cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines // There are two ways to refer to the TOC address directly: either 1258cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines // via a ELF::R_PPC64_TOC relocation (where both symbol and addend are 1259cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines // ignored), or via any relocation that refers to the magic ".TOC." 1260cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines // symbols (in which case the addend is respected). 1261cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines if (RelType == ELF::R_PPC64_TOC) { 1262cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines RelType = ELF::R_PPC64_ADDR64; 1263cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines findPPC64TOCSection(Obj, ObjSectionToID, Value); 1264cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines } else if (TargetName == ".TOC.") { 1265cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines findPPC64TOCSection(Obj, ObjSectionToID, Value); 1266cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines Value.Addend += Addend; 1267cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines } 1268cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines 1269efa91f6475f6e96552986104ab4857db46185a2aRafael Espindola RelocationEntry RE(SectionID, Offset, RelType, Value.Addend); 1270b0f79298851836cdfcca90252260d007d7561cadRichard Mitton 1271b0f79298851836cdfcca90252260d007d7561cadRichard Mitton if (Value.SymbolName) 12726e8946c5280ad6071d21013651745a9478f063edAdhemerval Zanella addRelocationForSymbol(RE, Value.SymbolName); 12736e8946c5280ad6071d21013651745a9478f063edAdhemerval Zanella else 12746e8946c5280ad6071d21013651745a9478f063edAdhemerval Zanella addRelocationForSection(RE, Value.SectionID); 12756e8946c5280ad6071d21013651745a9478f063edAdhemerval Zanella } 12766fc2ad62e23673ef829c9c4bbf62743d30928a5bRichard Sandiford } else if (Arch == Triple::systemz && 127736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines (RelType == ELF::R_390_PLT32DBL || RelType == ELF::R_390_GOTENT)) { 12786fc2ad62e23673ef829c9c4bbf62743d30928a5bRichard Sandiford // Create function stubs for both PLT and GOT references, regardless of 12796fc2ad62e23673ef829c9c4bbf62743d30928a5bRichard Sandiford // whether the GOT reference is to data or code. The stub contains the 12806fc2ad62e23673ef829c9c4bbf62743d30928a5bRichard Sandiford // full address of the symbol, as needed by GOT references, and the 12816fc2ad62e23673ef829c9c4bbf62743d30928a5bRichard Sandiford // executable part only adds an overhead of 8 bytes. 12826fc2ad62e23673ef829c9c4bbf62743d30928a5bRichard Sandiford // 12836fc2ad62e23673ef829c9c4bbf62743d30928a5bRichard Sandiford // We could try to conserve space by allocating the code and data 12846fc2ad62e23673ef829c9c4bbf62743d30928a5bRichard Sandiford // parts of the stub separately. However, as things stand, we allocate 12856fc2ad62e23673ef829c9c4bbf62743d30928a5bRichard Sandiford // a stub for every relocation, so using a GOT in JIT code should be 12866fc2ad62e23673ef829c9c4bbf62743d30928a5bRichard Sandiford // no less space efficient than using an explicit constant pool. 12876fc2ad62e23673ef829c9c4bbf62743d30928a5bRichard Sandiford DEBUG(dbgs() << "\t\tThis is a SystemZ indirect relocation."); 12886fc2ad62e23673ef829c9c4bbf62743d30928a5bRichard Sandiford SectionEntry &Section = Sections[SectionID]; 12896fc2ad62e23673ef829c9c4bbf62743d30928a5bRichard Sandiford 12906fc2ad62e23673ef829c9c4bbf62743d30928a5bRichard Sandiford // Look for an existing stub. 12916fc2ad62e23673ef829c9c4bbf62743d30928a5bRichard Sandiford StubMap::const_iterator i = Stubs.find(Value); 12926fc2ad62e23673ef829c9c4bbf62743d30928a5bRichard Sandiford uintptr_t StubAddress; 12936fc2ad62e23673ef829c9c4bbf62743d30928a5bRichard Sandiford if (i != Stubs.end()) { 12946fc2ad62e23673ef829c9c4bbf62743d30928a5bRichard Sandiford StubAddress = uintptr_t(Section.Address) + i->second; 12956fc2ad62e23673ef829c9c4bbf62743d30928a5bRichard Sandiford DEBUG(dbgs() << " Stub function found\n"); 12966fc2ad62e23673ef829c9c4bbf62743d30928a5bRichard Sandiford } else { 12976fc2ad62e23673ef829c9c4bbf62743d30928a5bRichard Sandiford // Create a new stub function. 12986fc2ad62e23673ef829c9c4bbf62743d30928a5bRichard Sandiford DEBUG(dbgs() << " Create a new stub function\n"); 12996fc2ad62e23673ef829c9c4bbf62743d30928a5bRichard Sandiford 13006fc2ad62e23673ef829c9c4bbf62743d30928a5bRichard Sandiford uintptr_t BaseAddress = uintptr_t(Section.Address); 13016fc2ad62e23673ef829c9c4bbf62743d30928a5bRichard Sandiford uintptr_t StubAlignment = getStubAlignment(); 130236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines StubAddress = (BaseAddress + Section.StubOffset + StubAlignment - 1) & 130336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines -StubAlignment; 13046fc2ad62e23673ef829c9c4bbf62743d30928a5bRichard Sandiford unsigned StubOffset = StubAddress - BaseAddress; 13056fc2ad62e23673ef829c9c4bbf62743d30928a5bRichard Sandiford 13066fc2ad62e23673ef829c9c4bbf62743d30928a5bRichard Sandiford Stubs[Value] = StubOffset; 13076fc2ad62e23673ef829c9c4bbf62743d30928a5bRichard Sandiford createStubFunction((uint8_t *)StubAddress); 130836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines RelocationEntry RE(SectionID, StubOffset + 8, ELF::R_390_64, 130936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Value.Addend - Addend); 13106fc2ad62e23673ef829c9c4bbf62743d30928a5bRichard Sandiford if (Value.SymbolName) 13116fc2ad62e23673ef829c9c4bbf62743d30928a5bRichard Sandiford addRelocationForSymbol(RE, Value.SymbolName); 13126fc2ad62e23673ef829c9c4bbf62743d30928a5bRichard Sandiford else 13136fc2ad62e23673ef829c9c4bbf62743d30928a5bRichard Sandiford addRelocationForSection(RE, Value.SectionID); 13146fc2ad62e23673ef829c9c4bbf62743d30928a5bRichard Sandiford Section.StubOffset = StubOffset + getMaxStubSize(); 13156fc2ad62e23673ef829c9c4bbf62743d30928a5bRichard Sandiford } 13166fc2ad62e23673ef829c9c4bbf62743d30928a5bRichard Sandiford 13176fc2ad62e23673ef829c9c4bbf62743d30928a5bRichard Sandiford if (RelType == ELF::R_390_GOTENT) 131836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines resolveRelocation(Section, Offset, StubAddress + 8, ELF::R_390_PC32DBL, 131936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Addend); 13206fc2ad62e23673ef829c9c4bbf62743d30928a5bRichard Sandiford else 13216fc2ad62e23673ef829c9c4bbf62743d30928a5bRichard Sandiford resolveRelocation(Section, Offset, StubAddress, RelType, Addend); 1322ff9fa05905be716435460b5f6d32689041bf895bAndrew Kaylor } else if (Arch == Triple::x86_64 && RelType == ELF::R_X86_64_PLT32) { 132336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // The way the PLT relocations normally work is that the linker allocates 132436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // the 1325ff9fa05905be716435460b5f6d32689041bf895bAndrew Kaylor // PLT and this relocation makes a PC-relative call into the PLT. The PLT 132636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // entry will then jump to an address provided by the GOT. On first call, 132736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // the 132836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // GOT address will point back into PLT code that resolves the symbol. After 1329ff9fa05905be716435460b5f6d32689041bf895bAndrew Kaylor // the first call, the GOT entry points to the actual function. 1330ff9fa05905be716435460b5f6d32689041bf895bAndrew Kaylor // 1331ff9fa05905be716435460b5f6d32689041bf895bAndrew Kaylor // For local functions we're ignoring all of that here and just replacing 1332ff9fa05905be716435460b5f6d32689041bf895bAndrew Kaylor // the PLT32 relocation type with PC32, which will translate the relocation 1333ff9fa05905be716435460b5f6d32689041bf895bAndrew Kaylor // into a PC-relative call directly to the function. For external symbols we 1334ff9fa05905be716435460b5f6d32689041bf895bAndrew Kaylor // can't be sure the function will be within 2^32 bytes of the call site, so 1335ff9fa05905be716435460b5f6d32689041bf895bAndrew Kaylor // we need to create a stub, which calls into the GOT. This case is 1336ff9fa05905be716435460b5f6d32689041bf895bAndrew Kaylor // equivalent to the usual PLT implementation except that we use the stub 1337ff9fa05905be716435460b5f6d32689041bf895bAndrew Kaylor // mechanism in RuntimeDyld (which puts stubs at the end of the section) 1338ff9fa05905be716435460b5f6d32689041bf895bAndrew Kaylor // rather than allocating a PLT section. 1339ff9fa05905be716435460b5f6d32689041bf895bAndrew Kaylor if (Value.SymbolName) { 1340ff9fa05905be716435460b5f6d32689041bf895bAndrew Kaylor // This is a call to an external function. 1341ff9fa05905be716435460b5f6d32689041bf895bAndrew Kaylor // Look for an existing stub. 1342ff9fa05905be716435460b5f6d32689041bf895bAndrew Kaylor SectionEntry &Section = Sections[SectionID]; 1343ff9fa05905be716435460b5f6d32689041bf895bAndrew Kaylor StubMap::const_iterator i = Stubs.find(Value); 1344ff9fa05905be716435460b5f6d32689041bf895bAndrew Kaylor uintptr_t StubAddress; 1345ff9fa05905be716435460b5f6d32689041bf895bAndrew Kaylor if (i != Stubs.end()) { 1346ff9fa05905be716435460b5f6d32689041bf895bAndrew Kaylor StubAddress = uintptr_t(Section.Address) + i->second; 1347ff9fa05905be716435460b5f6d32689041bf895bAndrew Kaylor DEBUG(dbgs() << " Stub function found\n"); 1348ff9fa05905be716435460b5f6d32689041bf895bAndrew Kaylor } else { 1349ff9fa05905be716435460b5f6d32689041bf895bAndrew Kaylor // Create a new stub function (equivalent to a PLT entry). 1350ff9fa05905be716435460b5f6d32689041bf895bAndrew Kaylor DEBUG(dbgs() << " Create a new stub function\n"); 1351ff9fa05905be716435460b5f6d32689041bf895bAndrew Kaylor 1352ff9fa05905be716435460b5f6d32689041bf895bAndrew Kaylor uintptr_t BaseAddress = uintptr_t(Section.Address); 1353ff9fa05905be716435460b5f6d32689041bf895bAndrew Kaylor uintptr_t StubAlignment = getStubAlignment(); 135436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines StubAddress = (BaseAddress + Section.StubOffset + StubAlignment - 1) & 135536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines -StubAlignment; 1356ff9fa05905be716435460b5f6d32689041bf895bAndrew Kaylor unsigned StubOffset = StubAddress - BaseAddress; 1357ff9fa05905be716435460b5f6d32689041bf895bAndrew Kaylor Stubs[Value] = StubOffset; 1358ff9fa05905be716435460b5f6d32689041bf895bAndrew Kaylor createStubFunction((uint8_t *)StubAddress); 1359ff9fa05905be716435460b5f6d32689041bf895bAndrew Kaylor 1360ff9fa05905be716435460b5f6d32689041bf895bAndrew Kaylor // Create a GOT entry for the external function. 1361ff9fa05905be716435460b5f6d32689041bf895bAndrew Kaylor GOTEntries.push_back(Value); 1362ff9fa05905be716435460b5f6d32689041bf895bAndrew Kaylor 1363ff9fa05905be716435460b5f6d32689041bf895bAndrew Kaylor // Make our stub function a relative call to the GOT entry. 136436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines RelocationEntry RE(SectionID, StubOffset + 2, ELF::R_X86_64_GOTPCREL, 136536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines -4); 1366ff9fa05905be716435460b5f6d32689041bf895bAndrew Kaylor addRelocationForSymbol(RE, Value.SymbolName); 1367ff9fa05905be716435460b5f6d32689041bf895bAndrew Kaylor 1368ff9fa05905be716435460b5f6d32689041bf895bAndrew Kaylor // Bump our stub offset counter 1369ff9fa05905be716435460b5f6d32689041bf895bAndrew Kaylor Section.StubOffset = StubOffset + getMaxStubSize(); 1370ff9fa05905be716435460b5f6d32689041bf895bAndrew Kaylor } 1371ff9fa05905be716435460b5f6d32689041bf895bAndrew Kaylor 1372ff9fa05905be716435460b5f6d32689041bf895bAndrew Kaylor // Make the target call a call into the stub table. 137336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines resolveRelocation(Section, Offset, StubAddress, ELF::R_X86_64_PC32, 137436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Addend); 1375ff9fa05905be716435460b5f6d32689041bf895bAndrew Kaylor } else { 1376ff9fa05905be716435460b5f6d32689041bf895bAndrew Kaylor RelocationEntry RE(SectionID, Offset, ELF::R_X86_64_PC32, Value.Addend, 1377ff9fa05905be716435460b5f6d32689041bf895bAndrew Kaylor Value.Offset); 1378ff9fa05905be716435460b5f6d32689041bf895bAndrew Kaylor addRelocationForSection(RE, Value.SectionID); 1379ff9fa05905be716435460b5f6d32689041bf895bAndrew Kaylor } 1380c201e6eaf165c83f0092c43b371e509fa8eaf4ccEli Bendersky } else { 1381ff9fa05905be716435460b5f6d32689041bf895bAndrew Kaylor if (Arch == Triple::x86_64 && RelType == ELF::R_X86_64_GOTPCREL) { 1382ff9fa05905be716435460b5f6d32689041bf895bAndrew Kaylor GOTEntries.push_back(Value); 1383ff9fa05905be716435460b5f6d32689041bf895bAndrew Kaylor } 1384ff9fa05905be716435460b5f6d32689041bf895bAndrew Kaylor RelocationEntry RE(SectionID, Offset, RelType, Value.Addend, Value.Offset); 1385c201e6eaf165c83f0092c43b371e509fa8eaf4ccEli Bendersky if (Value.SymbolName) 1386c201e6eaf165c83f0092c43b371e509fa8eaf4ccEli Bendersky addRelocationForSymbol(RE, Value.SymbolName); 1387c201e6eaf165c83f0092c43b371e509fa8eaf4ccEli Bendersky else 1388c201e6eaf165c83f0092c43b371e509fa8eaf4ccEli Bendersky addRelocationForSection(RE, Value.SectionID); 1389c201e6eaf165c83f0092c43b371e509fa8eaf4ccEli Bendersky } 139036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return ++RelI; 139161425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach} 139261425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach 1393ff9fa05905be716435460b5f6d32689041bf895bAndrew Kaylorvoid RuntimeDyldELF::updateGOTEntries(StringRef Name, uint64_t Addr) { 13949cffedbbfd009131699c4fcbcb2f820555762812Andrew Kaylor 139536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines SmallVectorImpl<std::pair<SID, GOTRelocations>>::iterator it; 139636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines SmallVectorImpl<std::pair<SID, GOTRelocations>>::iterator end = GOTs.end(); 13979cffedbbfd009131699c4fcbcb2f820555762812Andrew Kaylor 13989cffedbbfd009131699c4fcbcb2f820555762812Andrew Kaylor for (it = GOTs.begin(); it != end; ++it) { 13999cffedbbfd009131699c4fcbcb2f820555762812Andrew Kaylor GOTRelocations &GOTEntries = it->second; 14009cffedbbfd009131699c4fcbcb2f820555762812Andrew Kaylor for (int i = 0, e = GOTEntries.size(); i != e; ++i) { 1401dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines if (GOTEntries[i].SymbolName != nullptr && 1402dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines GOTEntries[i].SymbolName == Name) { 14039cffedbbfd009131699c4fcbcb2f820555762812Andrew Kaylor GOTEntries[i].Offset = Addr; 14049cffedbbfd009131699c4fcbcb2f820555762812Andrew Kaylor } 1405ff9fa05905be716435460b5f6d32689041bf895bAndrew Kaylor } 1406ff9fa05905be716435460b5f6d32689041bf895bAndrew Kaylor } 1407ff9fa05905be716435460b5f6d32689041bf895bAndrew Kaylor} 1408ff9fa05905be716435460b5f6d32689041bf895bAndrew Kaylor 1409ff9fa05905be716435460b5f6d32689041bf895bAndrew Kaylorsize_t RuntimeDyldELF::getGOTEntrySize() { 1410ff9fa05905be716435460b5f6d32689041bf895bAndrew Kaylor // We don't use the GOT in all of these cases, but it's essentially free 1411ff9fa05905be716435460b5f6d32689041bf895bAndrew Kaylor // to put them all here. 1412ff9fa05905be716435460b5f6d32689041bf895bAndrew Kaylor size_t Result = 0; 1413ff9fa05905be716435460b5f6d32689041bf895bAndrew Kaylor switch (Arch) { 1414ff9fa05905be716435460b5f6d32689041bf895bAndrew Kaylor case Triple::x86_64: 1415ff9fa05905be716435460b5f6d32689041bf895bAndrew Kaylor case Triple::aarch64: 1416dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines case Triple::aarch64_be: 1417dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines case Triple::arm64: 1418dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines case Triple::arm64_be: 1419ff9fa05905be716435460b5f6d32689041bf895bAndrew Kaylor case Triple::ppc64: 1420ff9fa05905be716435460b5f6d32689041bf895bAndrew Kaylor case Triple::ppc64le: 1421ff9fa05905be716435460b5f6d32689041bf895bAndrew Kaylor case Triple::systemz: 1422ff9fa05905be716435460b5f6d32689041bf895bAndrew Kaylor Result = sizeof(uint64_t); 1423ff9fa05905be716435460b5f6d32689041bf895bAndrew Kaylor break; 1424ff9fa05905be716435460b5f6d32689041bf895bAndrew Kaylor case Triple::x86: 1425ff9fa05905be716435460b5f6d32689041bf895bAndrew Kaylor case Triple::arm: 1426ff9fa05905be716435460b5f6d32689041bf895bAndrew Kaylor case Triple::thumb: 1427ff9fa05905be716435460b5f6d32689041bf895bAndrew Kaylor case Triple::mips: 1428ff9fa05905be716435460b5f6d32689041bf895bAndrew Kaylor case Triple::mipsel: 1429ff9fa05905be716435460b5f6d32689041bf895bAndrew Kaylor Result = sizeof(uint32_t); 1430ff9fa05905be716435460b5f6d32689041bf895bAndrew Kaylor break; 143136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines default: 143236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines llvm_unreachable("Unsupported CPU type!"); 1433ff9fa05905be716435460b5f6d32689041bf895bAndrew Kaylor } 1434ff9fa05905be716435460b5f6d32689041bf895bAndrew Kaylor return Result; 1435ff9fa05905be716435460b5f6d32689041bf895bAndrew Kaylor} 1436ff9fa05905be716435460b5f6d32689041bf895bAndrew Kaylor 143736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesuint64_t RuntimeDyldELF::findGOTEntry(uint64_t LoadAddress, uint64_t Offset) { 1438ff9fa05905be716435460b5f6d32689041bf895bAndrew Kaylor 14399cffedbbfd009131699c4fcbcb2f820555762812Andrew Kaylor const size_t GOTEntrySize = getGOTEntrySize(); 14409cffedbbfd009131699c4fcbcb2f820555762812Andrew Kaylor 144136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines SmallVectorImpl<std::pair<SID, GOTRelocations>>::const_iterator it; 144236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines SmallVectorImpl<std::pair<SID, GOTRelocations>>::const_iterator end = 144336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines GOTs.end(); 1444ff9fa05905be716435460b5f6d32689041bf895bAndrew Kaylor 1445ff9fa05905be716435460b5f6d32689041bf895bAndrew Kaylor int GOTIndex = -1; 14469cffedbbfd009131699c4fcbcb2f820555762812Andrew Kaylor for (it = GOTs.begin(); it != end; ++it) { 14479cffedbbfd009131699c4fcbcb2f820555762812Andrew Kaylor SID GOTSectionID = it->first; 14489cffedbbfd009131699c4fcbcb2f820555762812Andrew Kaylor const GOTRelocations &GOTEntries = it->second; 14499cffedbbfd009131699c4fcbcb2f820555762812Andrew Kaylor 14509cffedbbfd009131699c4fcbcb2f820555762812Andrew Kaylor // Find the matching entry in our vector. 14519cffedbbfd009131699c4fcbcb2f820555762812Andrew Kaylor uint64_t SymbolOffset = 0; 14529cffedbbfd009131699c4fcbcb2f820555762812Andrew Kaylor for (int i = 0, e = GOTEntries.size(); i != e; ++i) { 1453dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines if (!GOTEntries[i].SymbolName) { 14549cffedbbfd009131699c4fcbcb2f820555762812Andrew Kaylor if (getSectionLoadAddress(GOTEntries[i].SectionID) == LoadAddress && 14559cffedbbfd009131699c4fcbcb2f820555762812Andrew Kaylor GOTEntries[i].Offset == Offset) { 14569cffedbbfd009131699c4fcbcb2f820555762812Andrew Kaylor GOTIndex = i; 14579cffedbbfd009131699c4fcbcb2f820555762812Andrew Kaylor SymbolOffset = GOTEntries[i].Offset; 14589cffedbbfd009131699c4fcbcb2f820555762812Andrew Kaylor break; 14599cffedbbfd009131699c4fcbcb2f820555762812Andrew Kaylor } 14609cffedbbfd009131699c4fcbcb2f820555762812Andrew Kaylor } else { 14619cffedbbfd009131699c4fcbcb2f820555762812Andrew Kaylor // GOT entries for external symbols use the addend as the address when 14629cffedbbfd009131699c4fcbcb2f820555762812Andrew Kaylor // the external symbol has been resolved. 14639cffedbbfd009131699c4fcbcb2f820555762812Andrew Kaylor if (GOTEntries[i].Offset == LoadAddress) { 14649cffedbbfd009131699c4fcbcb2f820555762812Andrew Kaylor GOTIndex = i; 14659cffedbbfd009131699c4fcbcb2f820555762812Andrew Kaylor // Don't use the Addend here. The relocation handler will use it. 14669cffedbbfd009131699c4fcbcb2f820555762812Andrew Kaylor break; 14679cffedbbfd009131699c4fcbcb2f820555762812Andrew Kaylor } 1468ff9fa05905be716435460b5f6d32689041bf895bAndrew Kaylor } 1469ff9fa05905be716435460b5f6d32689041bf895bAndrew Kaylor } 1470ff9fa05905be716435460b5f6d32689041bf895bAndrew Kaylor 14719cffedbbfd009131699c4fcbcb2f820555762812Andrew Kaylor if (GOTIndex != -1) { 14729cffedbbfd009131699c4fcbcb2f820555762812Andrew Kaylor if (GOTEntrySize == sizeof(uint64_t)) { 147336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines uint64_t *LocalGOTAddr = (uint64_t *)getSectionAddress(GOTSectionID); 14749cffedbbfd009131699c4fcbcb2f820555762812Andrew Kaylor // Fill in this entry with the address of the symbol being referenced. 14759cffedbbfd009131699c4fcbcb2f820555762812Andrew Kaylor LocalGOTAddr[GOTIndex] = LoadAddress + SymbolOffset; 14769cffedbbfd009131699c4fcbcb2f820555762812Andrew Kaylor } else { 147736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines uint32_t *LocalGOTAddr = (uint32_t *)getSectionAddress(GOTSectionID); 14789cffedbbfd009131699c4fcbcb2f820555762812Andrew Kaylor // Fill in this entry with the address of the symbol being referenced. 14799cffedbbfd009131699c4fcbcb2f820555762812Andrew Kaylor LocalGOTAddr[GOTIndex] = (uint32_t)(LoadAddress + SymbolOffset); 14809cffedbbfd009131699c4fcbcb2f820555762812Andrew Kaylor } 14819cffedbbfd009131699c4fcbcb2f820555762812Andrew Kaylor 14829cffedbbfd009131699c4fcbcb2f820555762812Andrew Kaylor // Calculate the load address of this entry 14839cffedbbfd009131699c4fcbcb2f820555762812Andrew Kaylor return getSectionLoadAddress(GOTSectionID) + (GOTIndex * GOTEntrySize); 14849cffedbbfd009131699c4fcbcb2f820555762812Andrew Kaylor } 1485ff9fa05905be716435460b5f6d32689041bf895bAndrew Kaylor } 1486ff9fa05905be716435460b5f6d32689041bf895bAndrew Kaylor 14879cffedbbfd009131699c4fcbcb2f820555762812Andrew Kaylor assert(GOTIndex != -1 && "Unable to find requested GOT entry."); 14889cffedbbfd009131699c4fcbcb2f820555762812Andrew Kaylor return 0; 1489ff9fa05905be716435460b5f6d32689041bf895bAndrew Kaylor} 1490ff9fa05905be716435460b5f6d32689041bf895bAndrew Kaylor 1491dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesvoid RuntimeDyldELF::finalizeLoad(ObjectImage &ObjImg, 1492dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines ObjSectionToIDMap &SectionMap) { 1493528f6d787b1a847e61eb2f1114559f423fdeb68cAndrew Kaylor // If necessary, allocate the global offset table 14949cffedbbfd009131699c4fcbcb2f820555762812Andrew Kaylor if (MemMgr) { 14959cffedbbfd009131699c4fcbcb2f820555762812Andrew Kaylor // Allocate the GOT if necessary 14969cffedbbfd009131699c4fcbcb2f820555762812Andrew Kaylor size_t numGOTEntries = GOTEntries.size(); 14979cffedbbfd009131699c4fcbcb2f820555762812Andrew Kaylor if (numGOTEntries != 0) { 14989cffedbbfd009131699c4fcbcb2f820555762812Andrew Kaylor // Allocate memory for the section 14999cffedbbfd009131699c4fcbcb2f820555762812Andrew Kaylor unsigned SectionID = Sections.size(); 15009cffedbbfd009131699c4fcbcb2f820555762812Andrew Kaylor size_t TotalSize = numGOTEntries * getGOTEntrySize(); 15019cffedbbfd009131699c4fcbcb2f820555762812Andrew Kaylor uint8_t *Addr = MemMgr->allocateDataSection(TotalSize, getGOTEntrySize(), 15029cffedbbfd009131699c4fcbcb2f820555762812Andrew Kaylor SectionID, ".got", false); 15039cffedbbfd009131699c4fcbcb2f820555762812Andrew Kaylor if (!Addr) 15049cffedbbfd009131699c4fcbcb2f820555762812Andrew Kaylor report_fatal_error("Unable to allocate memory for GOT!"); 15059cffedbbfd009131699c4fcbcb2f820555762812Andrew Kaylor 15069cffedbbfd009131699c4fcbcb2f820555762812Andrew Kaylor GOTs.push_back(std::make_pair(SectionID, GOTEntries)); 15079cffedbbfd009131699c4fcbcb2f820555762812Andrew Kaylor Sections.push_back(SectionEntry(".got", Addr, TotalSize, 0)); 15089cffedbbfd009131699c4fcbcb2f820555762812Andrew Kaylor // For now, initialize all GOT entries to zero. We'll fill them in as 15099cffedbbfd009131699c4fcbcb2f820555762812Andrew Kaylor // needed when GOT-based relocations are applied. 15109cffedbbfd009131699c4fcbcb2f820555762812Andrew Kaylor memset(Addr, 0, TotalSize); 15119cffedbbfd009131699c4fcbcb2f820555762812Andrew Kaylor } 151236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } else { 15139cffedbbfd009131699c4fcbcb2f820555762812Andrew Kaylor report_fatal_error("Unable to allocate memory for GOT!"); 1514ff9fa05905be716435460b5f6d32689041bf895bAndrew Kaylor } 1515528f6d787b1a847e61eb2f1114559f423fdeb68cAndrew Kaylor 1516528f6d787b1a847e61eb2f1114559f423fdeb68cAndrew Kaylor // Look for and record the EH frame section. 1517528f6d787b1a847e61eb2f1114559f423fdeb68cAndrew Kaylor ObjSectionToIDMap::iterator i, e; 1518528f6d787b1a847e61eb2f1114559f423fdeb68cAndrew Kaylor for (i = SectionMap.begin(), e = SectionMap.end(); i != e; ++i) { 1519528f6d787b1a847e61eb2f1114559f423fdeb68cAndrew Kaylor const SectionRef &Section = i->first; 1520528f6d787b1a847e61eb2f1114559f423fdeb68cAndrew Kaylor StringRef Name; 1521528f6d787b1a847e61eb2f1114559f423fdeb68cAndrew Kaylor Section.getName(Name); 1522528f6d787b1a847e61eb2f1114559f423fdeb68cAndrew Kaylor if (Name == ".eh_frame") { 1523528f6d787b1a847e61eb2f1114559f423fdeb68cAndrew Kaylor UnregisteredEHFrameSections.push_back(i->second); 1524528f6d787b1a847e61eb2f1114559f423fdeb68cAndrew Kaylor break; 1525528f6d787b1a847e61eb2f1114559f423fdeb68cAndrew Kaylor } 1526528f6d787b1a847e61eb2f1114559f423fdeb68cAndrew Kaylor } 1527ff9fa05905be716435460b5f6d32689041bf895bAndrew Kaylor} 1528ff9fa05905be716435460b5f6d32689041bf895bAndrew Kaylor 15293f23cef24fc9200def464bd4bce820678b5715deAndrew Kaylorbool RuntimeDyldELF::isCompatibleFormat(const ObjectBuffer *Buffer) const { 15303f23cef24fc9200def464bd4bce820678b5715deAndrew Kaylor if (Buffer->getBufferSize() < strlen(ELF::ElfMagic)) 15313f23cef24fc9200def464bd4bce820678b5715deAndrew Kaylor return false; 153236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return (memcmp(Buffer->getBufferStart(), ELF::ElfMagic, 153336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines strlen(ELF::ElfMagic))) == 0; 1534a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky} 153536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 153636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesbool RuntimeDyldELF::isCompatibleFile(const object::ObjectFile *Obj) const { 153736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return Obj->isELF(); 153836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines} 153936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 1540a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky} // namespace llvm 1541