RuntimeDyldELF.cpp revision 858143816d43e58b17bfd11cb1b57afbd7f0f893
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 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" 1976463fdeb603e1d89b05f094bfd6fe73b90d0b61Eli Bendersky#include "RuntimeDyldELF.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 15761425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbachvoid RuntimeDyldELF::resolveRelocations() { 15861425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach // FIXME: deprecated. should be changed to use the by-section 15961425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach // allocation and relocation scheme. 16061425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach 16161425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach // Just iterate over the symbols in our symbol table and assign their 16261425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach // addresses. 16361425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach StringMap<SymbolLoc>::iterator i = SymbolTable.begin(); 16461425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach StringMap<SymbolLoc>::iterator e = SymbolTable.end(); 16561425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach for (;i != e; ++i) { 16661425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach assert (i->getValue().second == 0 && "non-zero offset in by-function sym!"); 16761425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach reassignSymbolAddress(i->getKey(), 16861425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach (uint8_t*)Sections[i->getValue().first].base()); 16961425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach } 17061425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach} 17161425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach 172a66a18505e07a4e72d6fa7e85663937a257577f3Eli Benderskyvoid RuntimeDyldELF::resolveX86_64Relocation(StringRef Name, 173a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky uint8_t *Addr, 174a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky const RelocationEntry &RE) { 175a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky uint8_t *TargetAddr; 176a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky if (RE.IsFunctionRelative) { 17761425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach StringMap<SymbolLoc>::const_iterator Loc = SymbolTable.find(RE.Target); 17861425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach assert(Loc != SymbolTable.end() && "Function for relocation not found"); 17961425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach TargetAddr = 18061425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach reinterpret_cast<uint8_t*>(Sections[Loc->second.first].base()) + 18161425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach Loc->second.second + RE.Offset; 182a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky } else { 183a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky // FIXME: Get the address of the target section and add that to RE.Offset 184408a25c583f3d3e7e9b6ef90a56ce435022591dfDuncan Sands llvm_unreachable("Non-function relocation not implemented yet!"); 185a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky } 186a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky 187a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky switch (RE.Type) { 188858143816d43e58b17bfd11cb1b57afbd7f0f893Craig Topper default: llvm_unreachable("Relocation type not implemented yet!"); 189a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky case ELF::R_X86_64_64: { 190a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky uint8_t **Target = reinterpret_cast<uint8_t**>(TargetAddr); 191a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky *Target = Addr + RE.Addend; 192a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky break; 193a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky } 194a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky case ELF::R_X86_64_32: 195a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky case ELF::R_X86_64_32S: { 196a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky uint64_t Value = reinterpret_cast<uint64_t>(Addr) + RE.Addend; 197a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky // FIXME: Handle the possibility of this assertion failing 1989223822b85080aae1e13ed00d88faaf7eba47d67Eli Bendersky assert((RE.Type == ELF::R_X86_64_32 && !(Value & 0xFFFFFFFF00000000ULL)) || 199a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky (RE.Type == ELF::R_X86_64_32S && 2009223822b85080aae1e13ed00d88faaf7eba47d67Eli Bendersky (Value & 0xFFFFFFFF00000000ULL) == 0xFFFFFFFF00000000ULL)); 201a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky uint32_t TruncatedAddr = (Value & 0xFFFFFFFF); 202a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky uint32_t *Target = reinterpret_cast<uint32_t*>(TargetAddr); 203a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky *Target = TruncatedAddr; 204a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky break; 205a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky } 206a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky case ELF::R_X86_64_PC32: { 207a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky uint32_t *Placeholder = reinterpret_cast<uint32_t*>(TargetAddr); 208a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky uint64_t RealOffset = *Placeholder + 209a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky reinterpret_cast<uint64_t>(Addr) + 210a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky RE.Addend - reinterpret_cast<uint64_t>(TargetAddr); 211a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky assert((RealOffset & 0xFFFFFFFF) == RealOffset); 212a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky uint32_t TruncOffset = (RealOffset & 0xFFFFFFFF); 213a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky *Placeholder = TruncOffset; 214a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky break; 215a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky } 216a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky } 217a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky} 218a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky 219a66a18505e07a4e72d6fa7e85663937a257577f3Eli Benderskyvoid RuntimeDyldELF::resolveX86Relocation(StringRef Name, 220a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky uint8_t *Addr, 221a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky const RelocationEntry &RE) { 222a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky uint8_t *TargetAddr; 223a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky if (RE.IsFunctionRelative) { 22461425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach StringMap<SymbolLoc>::const_iterator Loc = SymbolTable.find(RE.Target); 22561425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach assert(Loc != SymbolTable.end() && "Function for relocation not found"); 22661425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach TargetAddr = 22761425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach reinterpret_cast<uint8_t*>(Sections[Loc->second.first].base()) + 22861425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach Loc->second.second + RE.Offset; 229a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky } else { 230a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky // FIXME: Get the address of the target section and add that to RE.Offset 231408a25c583f3d3e7e9b6ef90a56ce435022591dfDuncan Sands llvm_unreachable("Non-function relocation not implemented yet!"); 232a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky } 233a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky 234a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky switch (RE.Type) { 235a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky case ELF::R_386_32: { 236a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky uint8_t **Target = reinterpret_cast<uint8_t**>(TargetAddr); 237a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky *Target = Addr + RE.Addend; 238a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky break; 239a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky } 240a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky case ELF::R_386_PC32: { 241a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky uint32_t *Placeholder = reinterpret_cast<uint32_t*>(TargetAddr); 242a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky uint32_t RealOffset = *Placeholder + reinterpret_cast<uintptr_t>(Addr) + 243a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky RE.Addend - reinterpret_cast<uintptr_t>(TargetAddr); 244a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky *Placeholder = RealOffset; 245a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky break; 246a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky } 247a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky default: 248a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky // There are other relocation types, but it appears these are the 249a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky // only ones currently used by the LLVM ELF object writer 250858143816d43e58b17bfd11cb1b57afbd7f0f893Craig Topper llvm_unreachable("Relocation type not implemented yet!"); 251a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky } 252a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky} 253a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky 254a66a18505e07a4e72d6fa7e85663937a257577f3Eli Benderskyvoid RuntimeDyldELF::resolveArmRelocation(StringRef Name, 255a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky uint8_t *Addr, 256a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky const RelocationEntry &RE) { 257a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky} 258a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky 259a66a18505e07a4e72d6fa7e85663937a257577f3Eli Benderskyvoid RuntimeDyldELF::resolveRelocation(StringRef Name, 260a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky uint8_t *Addr, 261a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky const RelocationEntry &RE) { 262a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky switch (Arch) { 263a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky case Triple::x86_64: 264a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky resolveX86_64Relocation(Name, Addr, RE); 265a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky break; 266a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky case Triple::x86: 267a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky resolveX86Relocation(Name, Addr, RE); 268a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky break; 269a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky case Triple::arm: 270a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky resolveArmRelocation(Name, Addr, RE); 271a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky break; 272858143816d43e58b17bfd11cb1b57afbd7f0f893Craig Topper default: llvm_unreachable("Unsupported CPU type!"); 273a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky } 274a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky} 275a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky 276a66a18505e07a4e72d6fa7e85663937a257577f3Eli Benderskyvoid RuntimeDyldELF::reassignSymbolAddress(StringRef Name, uint8_t *Addr) { 27761425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach // FIXME: deprecated. switch to reassignSectionAddress() instead. 27861425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach // 27961425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach // Actually moving the symbol address requires by-section mapping. 28061425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach assert(Sections[SymbolTable.lookup(Name).first].base() == (void*)Addr && 28161425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach "Unable to relocate section in by-function JIT allocation model!"); 282a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky 283a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky RelocationList &Relocs = Relocations[Name]; 284a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky for (unsigned i = 0, e = Relocs.size(); i != e; ++i) { 285a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky RelocationEntry &RE = Relocs[i]; 286a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky resolveRelocation(Name, Addr, RE); 287a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky } 288a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky} 289a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky 29061425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach// Assign an address to a symbol name and resolve all the relocations 29161425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach// associated with it. 29261425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbachvoid RuntimeDyldELF::reassignSectionAddress(unsigned SectionID, uint64_t Addr) { 29361425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach // The address to use for relocation resolution is not 29461425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach // the address of the local section buffer. We must be doing 29561425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach // a remote execution environment of some sort. Re-apply any 29661425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach // relocations referencing this section with the given address. 29761425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach // 29861425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach // Addr is a uint64_t because we can't assume the pointer width 29961425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach // of the target is the same as that of the host. Just use a generic 30061425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach // "big enough" type. 30161425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach assert(0); 30261425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach} 30361425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach 304a66a18505e07a4e72d6fa7e85663937a257577f3Eli Benderskybool RuntimeDyldELF::isCompatibleFormat(const MemoryBuffer *InputBuffer) const { 305a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky StringRef Magic = InputBuffer->getBuffer().slice(0, ELF::EI_NIDENT); 306a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky return (memcmp(Magic.data(), ELF::ElfMagic, strlen(ELF::ElfMagic))) == 0; 307a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky} 308a66a18505e07a4e72d6fa7e85663937a257577f3Eli Bendersky} // namespace llvm 309