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