RuntimeDyldELF.cpp revision 9223822b85080aae1e13ed00d88faaf7eba47d67
1a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky//===-- 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 14a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky#define DEBUG_TYPE "dyld" 15a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky#include "llvm/ADT/OwningPtr.h" 16a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky#include "llvm/ADT/StringRef.h" 17a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky#include "llvm/ADT/STLExtras.h" 18a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky#include "llvm/ADT/IntervalMap.h" 19a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky#include "RuntimeDyldImpl.h" 20a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky#include "llvm/Object/ObjectFile.h" 21a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky#include "llvm/Support/ELF.h" 22a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky#include "llvm/ADT/Triple.h" 23a66a18505e07a4e72d6fa7e85663937a257577f3Eli Benderskyusing namespace llvm; 24a66a18505e07a4e72d6fa7e85663937a257577f3Eli Benderskyusing namespace llvm::object; 25a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky 26a66a18505e07a4e72d6fa7e85663937a257577f3Eli Benderskynamespace llvm { 27a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky 28a66a18505e07a4e72d6fa7e85663937a257577f3Eli Benderskynamespace { 29a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky 30a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky// FIXME: this function should probably not live here... 31a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky// 32a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky// Returns the name and address of an unrelocated symbol in an ELF section 33a66a18505e07a4e72d6fa7e85663937a257577f3Eli Benderskyvoid getSymbolInfo(symbol_iterator Sym, uint64_t &Addr, StringRef &Name) { 34a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky //FIXME: error checking here required to catch corrupt ELF objects... 35a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky error_code Err = Sym->getName(Name); 36a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky 37a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky uint64_t AddrInSection; 38a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky Err = Sym->getAddress(AddrInSection); 39a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky 40a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky SectionRef empty_section; 41a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky section_iterator Section(empty_section); 42a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky Err = Sym->getSection(Section); 43a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky 44a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky StringRef SectionContents; 45a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky Section->getContents(SectionContents); 46a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky 47a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky Addr = reinterpret_cast<uint64_t>(SectionContents.data()) + AddrInSection; 48a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky} 49a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky 50a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky} 51a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky 52a66a18505e07a4e72d6fa7e85663937a257577f3Eli Benderskybool RuntimeDyldELF::loadObject(MemoryBuffer *InputBuffer) { 53a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky if (!isCompatibleFormat(InputBuffer)) 54a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky return true; 55a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky 56a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky OwningPtr<ObjectFile> Obj(ObjectFile::createELFObjectFile(InputBuffer)); 57a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky 58a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky Arch = Obj->getArch(); 59a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky 60a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky // Map address in the Object file image to function names 61a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky IntervalMap<uint64_t, StringRef>::Allocator A; 62a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky IntervalMap<uint64_t, StringRef> FuncMap(A); 63a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky 64a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky // This is a bit of a hack. The ObjectFile we've just loaded reports 65a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky // section addresses as 0 and doesn't provide access to the section 66a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky // offset (from which we could calculate the address. Instead, 67a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky // we're storing the address when it comes up in the ST_Debug case 68a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky // below. 69a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky // 70a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky StringMap<uint64_t> DebugSymbolMap; 71a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky 72a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky symbol_iterator SymEnd = Obj->end_symbols(); 73a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky error_code Err; 74a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky for (symbol_iterator Sym = Obj->begin_symbols(); 75a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky Sym != SymEnd; Sym.increment(Err)) { 76a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky SymbolRef::Type Type; 77a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky Sym->getType(Type); 78a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky if (Type == SymbolRef::ST_Function) { 79a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky StringRef Name; 80a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky uint64_t Addr; 81a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky getSymbolInfo(Sym, Addr, Name); 82a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky 83a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky uint64_t Size; 84a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky Err = Sym->getSize(Size); 85a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky 86a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky uint8_t *Start; 87a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky uint8_t *End; 88a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky Start = reinterpret_cast<uint8_t*>(Addr); 89a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky End = reinterpret_cast<uint8_t*>(Addr + Size - 1); 90a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky 91a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky extractFunction(Name, Start, End); 92a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky FuncMap.insert(Addr, Addr + Size - 1, Name); 93a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky } else if (Type == SymbolRef::ST_Debug) { 94a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky // This case helps us find section addresses 95a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky StringRef Name; 96a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky uint64_t Addr; 97a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky getSymbolInfo(Sym, Addr, Name); 98a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky DebugSymbolMap[Name] = Addr; 99a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky } 100a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky } 101a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky 102a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky // Iterate through the relocations for this object 103a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky section_iterator SecEnd = Obj->end_sections(); 104a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky for (section_iterator Sec = Obj->begin_sections(); 105a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky Sec != SecEnd; Sec.increment(Err)) { 106a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky StringRef SecName; 107a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky uint64_t SecAddr; 108a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky Sec->getName(SecName); 109a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky // Ignore sections that aren't in our map 110a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky if (DebugSymbolMap.find(SecName) == DebugSymbolMap.end()) { 111a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky continue; 112a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky } 113a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky SecAddr = DebugSymbolMap[SecName]; 114a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky relocation_iterator RelEnd = Sec->end_relocations(); 115a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky for (relocation_iterator Rel = Sec->begin_relocations(); 116a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky Rel != RelEnd; Rel.increment(Err)) { 117a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky uint64_t RelOffset; 118a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky uint64_t RelType; 119a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky int64_t RelAddend; 120a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky SymbolRef RelSym; 121a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky StringRef SymName; 122a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky uint64_t SymAddr; 123a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky uint64_t SymOffset; 124a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky 125a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky Rel->getAddress(RelOffset); 126a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky Rel->getType(RelType); 127a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky Rel->getAdditionalInfo(RelAddend); 128a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky Rel->getSymbol(RelSym); 129a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky RelSym.getName(SymName); 130a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky RelSym.getAddress(SymAddr); 131a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky RelSym.getFileOffset(SymOffset); 132a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky 133a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky // If this relocation is inside a function, we want to store the 134a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky // function name and a function-relative offset 135a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky IntervalMap<uint64_t, StringRef>::iterator ContainingFunc 136a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky = FuncMap.find(SecAddr + RelOffset); 137a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky if (ContainingFunc.valid()) { 138a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky // Re-base the relocation to make it relative to the target function 139a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky RelOffset = (SecAddr + RelOffset) - ContainingFunc.start(); 140a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky Relocations[SymName].push_back(RelocationEntry(ContainingFunc.value(), 141a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky RelOffset, 142a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky RelType, 143a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky RelAddend, 144a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky true)); 145a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky } else { 146a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky Relocations[SymName].push_back(RelocationEntry(SecName, 147a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky RelOffset, 148a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky RelType, 149a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky RelAddend, 150a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky false)); 151a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky } 152a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky } 153a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky } 154a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky return false; 155a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky} 156a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky 157a66a18505e07a4e72d6fa7e85663937a257577f3Eli Benderskyvoid RuntimeDyldELF::resolveX86_64Relocation(StringRef Name, 158a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky uint8_t *Addr, 159a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky const RelocationEntry &RE) { 160a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky uint8_t *TargetAddr; 161a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky if (RE.IsFunctionRelative) { 162a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky StringMap<sys::MemoryBlock>::iterator ContainingFunc 163a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky = Functions.find(RE.Target); 164a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky assert(ContainingFunc != Functions.end() 165a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky && "Function for relocation not found"); 166a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky TargetAddr = reinterpret_cast<uint8_t*>(ContainingFunc->getValue().base()) + 167a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky RE.Offset; 168a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky } else { 169a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky // FIXME: Get the address of the target section and add that to RE.Offset 170a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky assert(0 && ("Non-function relocation not implemented yet!")); 171a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky } 172a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky 173a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky switch (RE.Type) { 174a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky default: 175a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky assert(0 && ("Relocation type not implemented yet!")); 176a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky break; 177a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky case ELF::R_X86_64_64: { 178a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky uint8_t **Target = reinterpret_cast<uint8_t**>(TargetAddr); 179a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky *Target = Addr + RE.Addend; 180a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky break; 181a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky } 182a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky case ELF::R_X86_64_32: 183a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky case ELF::R_X86_64_32S: { 184a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky uint64_t Value = reinterpret_cast<uint64_t>(Addr) + RE.Addend; 185a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky // FIXME: Handle the possibility of this assertion failing 1869223822b85080aae1e13ed00d88faaf7eba47d67Eli Bendersky assert((RE.Type == ELF::R_X86_64_32 && !(Value & 0xFFFFFFFF00000000ULL)) || 187a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky (RE.Type == ELF::R_X86_64_32S && 1889223822b85080aae1e13ed00d88faaf7eba47d67Eli Bendersky (Value & 0xFFFFFFFF00000000ULL) == 0xFFFFFFFF00000000ULL)); 189a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky uint32_t TruncatedAddr = (Value & 0xFFFFFFFF); 190a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky uint32_t *Target = reinterpret_cast<uint32_t*>(TargetAddr); 191a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky *Target = TruncatedAddr; 192a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky break; 193a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky } 194a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky case ELF::R_X86_64_PC32: { 195a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky uint32_t *Placeholder = reinterpret_cast<uint32_t*>(TargetAddr); 196a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky uint64_t RealOffset = *Placeholder + 197a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky reinterpret_cast<uint64_t>(Addr) + 198a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky RE.Addend - reinterpret_cast<uint64_t>(TargetAddr); 199a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky assert((RealOffset & 0xFFFFFFFF) == RealOffset); 200a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky uint32_t TruncOffset = (RealOffset & 0xFFFFFFFF); 201a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky *Placeholder = TruncOffset; 202a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky break; 203a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky } 204a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky } 205a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky} 206a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky 207a66a18505e07a4e72d6fa7e85663937a257577f3Eli Benderskyvoid RuntimeDyldELF::resolveX86Relocation(StringRef Name, 208a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky uint8_t *Addr, 209a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky const RelocationEntry &RE) { 210a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky uint8_t *TargetAddr; 211a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky if (RE.IsFunctionRelative) { 212a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky StringMap<sys::MemoryBlock>::iterator ContainingFunc 213a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky = Functions.find(RE.Target); 214a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky assert(ContainingFunc != Functions.end() 215a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky && "Function for relocation not found"); 216a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky TargetAddr = reinterpret_cast<uint8_t*>( 217a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky ContainingFunc->getValue().base()) + RE.Offset; 218a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky } else { 219a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky // FIXME: Get the address of the target section and add that to RE.Offset 220a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky assert(0 && ("Non-function relocation not implemented yet!")); 221a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky } 222a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky 223a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky switch (RE.Type) { 224a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky case ELF::R_386_32: { 225a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky uint8_t **Target = reinterpret_cast<uint8_t**>(TargetAddr); 226a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky *Target = Addr + RE.Addend; 227a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky break; 228a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky } 229a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky case ELF::R_386_PC32: { 230a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky uint32_t *Placeholder = reinterpret_cast<uint32_t*>(TargetAddr); 231a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky uint32_t RealOffset = *Placeholder + reinterpret_cast<uintptr_t>(Addr) + 232a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky RE.Addend - reinterpret_cast<uintptr_t>(TargetAddr); 233a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky *Placeholder = RealOffset; 234a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky break; 235a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky } 236a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky default: 237a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky // There are other relocation types, but it appears these are the 238a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky // only ones currently used by the LLVM ELF object writer 239a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky assert(0 && ("Relocation type not implemented yet!")); 240a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky break; 241a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky } 242a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky} 243a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky 244a66a18505e07a4e72d6fa7e85663937a257577f3Eli Benderskyvoid RuntimeDyldELF::resolveArmRelocation(StringRef Name, 245a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky uint8_t *Addr, 246a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky const RelocationEntry &RE) { 247a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky} 248a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky 249a66a18505e07a4e72d6fa7e85663937a257577f3Eli Benderskyvoid RuntimeDyldELF::resolveRelocation(StringRef Name, 250a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky uint8_t *Addr, 251a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky const RelocationEntry &RE) { 252a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky switch (Arch) { 253a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky case Triple::x86_64: 254a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky resolveX86_64Relocation(Name, Addr, RE); 255a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky break; 256a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky case Triple::x86: 257a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky resolveX86Relocation(Name, Addr, RE); 258a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky break; 259a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky case Triple::arm: 260a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky resolveArmRelocation(Name, Addr, RE); 261a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky break; 262a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky default: 263a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky assert(0 && "Unsupported CPU type!"); 264a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky break; 265a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky } 266a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky} 267a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky 268a66a18505e07a4e72d6fa7e85663937a257577f3Eli Benderskyvoid RuntimeDyldELF::reassignSymbolAddress(StringRef Name, uint8_t *Addr) { 269a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky SymbolTable[Name] = Addr; 270a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky 271a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky RelocationList &Relocs = Relocations[Name]; 272a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky for (unsigned i = 0, e = Relocs.size(); i != e; ++i) { 273a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky RelocationEntry &RE = Relocs[i]; 274a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky resolveRelocation(Name, Addr, RE); 275a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky } 276a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky} 277a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky 278a66a18505e07a4e72d6fa7e85663937a257577f3Eli Benderskybool RuntimeDyldELF::isCompatibleFormat(const MemoryBuffer *InputBuffer) const { 279a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky StringRef Magic = InputBuffer->getBuffer().slice(0, ELF::EI_NIDENT); 280a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky return (memcmp(Magic.data(), ELF::ElfMagic, strlen(ELF::ElfMagic))) == 0; 281a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky} 282a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky} // namespace llvm 283