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