1//===-- RuntimeDyldELF.cpp - Run-time dynamic linker for MC-JIT -*- C++ -*-===//
2//
3//                     The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// Implementation of ELF support for the MC-JIT runtime dynamic linker.
11//
12//===----------------------------------------------------------------------===//
13
14#define DEBUG_TYPE "dyld"
15#include "llvm/ADT/OwningPtr.h"
16#include "llvm/ADT/StringRef.h"
17#include "llvm/ADT/STLExtras.h"
18#include "llvm/ADT/IntervalMap.h"
19#include "RuntimeDyldELF.h"
20#include "llvm/Object/ObjectFile.h"
21#include "llvm/Support/ELF.h"
22#include "llvm/ADT/Triple.h"
23#include "llvm/Object/ELF.h"
24#include "JITRegistrar.h"
25using namespace llvm;
26using namespace llvm::object;
27
28namespace {
29
30template<support::endianness target_endianness, bool is64Bits>
31class DyldELFObject : public ELFObjectFile<target_endianness, is64Bits> {
32  LLVM_ELF_IMPORT_TYPES(target_endianness, is64Bits)
33
34  typedef Elf_Shdr_Impl<target_endianness, is64Bits> Elf_Shdr;
35  typedef Elf_Sym_Impl<target_endianness, is64Bits> Elf_Sym;
36  typedef Elf_Rel_Impl<target_endianness, is64Bits, false> Elf_Rel;
37  typedef Elf_Rel_Impl<target_endianness, is64Bits, true> Elf_Rela;
38
39  typedef Elf_Ehdr_Impl<target_endianness, is64Bits> Elf_Ehdr;
40
41  typedef typename ELFDataTypeTypedefHelper<
42          target_endianness, is64Bits>::value_type addr_type;
43
44protected:
45  // This duplicates the 'Data' member in the 'Binary' base class
46  // but it is necessary to workaround a bug in gcc 4.2
47  MemoryBuffer *InputData;
48
49public:
50  DyldELFObject(MemoryBuffer *Object, error_code &ec);
51
52  void updateSectionAddress(const SectionRef &Sec, uint64_t Addr);
53  void updateSymbolAddress(const SymbolRef &Sym, uint64_t Addr);
54
55  const MemoryBuffer& getBuffer() const { return *InputData; }
56
57  // Methods for type inquiry through isa, cast and dyn_cast
58  static inline bool classof(const Binary *v) {
59    return (isa<ELFObjectFile<target_endianness, is64Bits> >(v)
60            && classof(cast<ELFObjectFile<target_endianness, is64Bits> >(v)));
61  }
62  static inline bool classof(
63      const ELFObjectFile<target_endianness, is64Bits> *v) {
64    return v->isDyldType();
65  }
66  static inline bool classof(const DyldELFObject *v) {
67    return true;
68  }
69};
70
71template<support::endianness target_endianness, bool is64Bits>
72class ELFObjectImage : public ObjectImage {
73  protected:
74    DyldELFObject<target_endianness, is64Bits> *DyldObj;
75    bool Registered;
76
77  public:
78    ELFObjectImage(DyldELFObject<target_endianness, is64Bits> *Obj)
79    : ObjectImage(Obj),
80      DyldObj(Obj),
81      Registered(false) {}
82
83    virtual ~ELFObjectImage() {
84      if (Registered)
85        deregisterWithDebugger();
86    }
87
88    // Subclasses can override these methods to update the image with loaded
89    // addresses for sections and common symbols
90    virtual void updateSectionAddress(const SectionRef &Sec, uint64_t Addr)
91    {
92      DyldObj->updateSectionAddress(Sec, Addr);
93    }
94
95    virtual void updateSymbolAddress(const SymbolRef &Sym, uint64_t Addr)
96    {
97      DyldObj->updateSymbolAddress(Sym, Addr);
98    }
99
100    virtual void registerWithDebugger()
101    {
102      JITRegistrar::getGDBRegistrar().registerObject(DyldObj->getBuffer());
103      Registered = true;
104    }
105    virtual void deregisterWithDebugger()
106    {
107      JITRegistrar::getGDBRegistrar().deregisterObject(DyldObj->getBuffer());
108    }
109};
110
111template<support::endianness target_endianness, bool is64Bits>
112DyldELFObject<target_endianness, is64Bits>::DyldELFObject(MemoryBuffer *Object,
113                                                          error_code &ec)
114  : ELFObjectFile<target_endianness, is64Bits>(Object, ec),
115    InputData(Object) {
116  this->isDyldELFObject = true;
117}
118
119template<support::endianness target_endianness, bool is64Bits>
120void DyldELFObject<target_endianness, is64Bits>::updateSectionAddress(
121                                                       const SectionRef &Sec,
122                                                       uint64_t Addr) {
123  DataRefImpl ShdrRef = Sec.getRawDataRefImpl();
124  Elf_Shdr *shdr = const_cast<Elf_Shdr*>(
125                          reinterpret_cast<const Elf_Shdr *>(ShdrRef.p));
126
127  // This assumes the address passed in matches the target address bitness
128  // The template-based type cast handles everything else.
129  shdr->sh_addr = static_cast<addr_type>(Addr);
130}
131
132template<support::endianness target_endianness, bool is64Bits>
133void DyldELFObject<target_endianness, is64Bits>::updateSymbolAddress(
134                                                       const SymbolRef &SymRef,
135                                                       uint64_t Addr) {
136
137  Elf_Sym *sym = const_cast<Elf_Sym*>(
138                                 ELFObjectFile<target_endianness, is64Bits>::
139                                   getSymbol(SymRef.getRawDataRefImpl()));
140
141  // This assumes the address passed in matches the target address bitness
142  // The template-based type cast handles everything else.
143  sym->st_value = static_cast<addr_type>(Addr);
144}
145
146} // namespace
147
148
149namespace llvm {
150
151ObjectImage *RuntimeDyldELF::createObjectImage(
152                                         const MemoryBuffer *ConstInputBuffer) {
153  MemoryBuffer *InputBuffer = const_cast<MemoryBuffer*>(ConstInputBuffer);
154  std::pair<unsigned char, unsigned char> Ident = getElfArchType(InputBuffer);
155  error_code ec;
156
157  if (Ident.first == ELF::ELFCLASS32 && Ident.second == ELF::ELFDATA2LSB) {
158    DyldELFObject<support::little, false> *Obj =
159           new DyldELFObject<support::little, false>(InputBuffer, ec);
160    return new ELFObjectImage<support::little, false>(Obj);
161  }
162  else if (Ident.first == ELF::ELFCLASS32 && Ident.second == ELF::ELFDATA2MSB) {
163    DyldELFObject<support::big, false> *Obj =
164           new DyldELFObject<support::big, false>(InputBuffer, ec);
165    return new ELFObjectImage<support::big, false>(Obj);
166  }
167  else if (Ident.first == ELF::ELFCLASS64 && Ident.second == ELF::ELFDATA2MSB) {
168    DyldELFObject<support::big, true> *Obj =
169           new DyldELFObject<support::big, true>(InputBuffer, ec);
170    return new ELFObjectImage<support::big, true>(Obj);
171  }
172  else if (Ident.first == ELF::ELFCLASS64 && Ident.second == ELF::ELFDATA2LSB) {
173    DyldELFObject<support::little, true> *Obj =
174           new DyldELFObject<support::little, true>(InputBuffer, ec);
175    return new ELFObjectImage<support::little, true>(Obj);
176  }
177  else
178    llvm_unreachable("Unexpected ELF format");
179}
180
181void RuntimeDyldELF::handleObjectLoaded(ObjectImage *Obj)
182{
183  Obj->registerWithDebugger();
184  // Save the loaded object.  It will deregister itself when deleted
185  LoadedObject = Obj;
186}
187
188RuntimeDyldELF::~RuntimeDyldELF() {
189  if (LoadedObject)
190    delete LoadedObject;
191}
192
193void RuntimeDyldELF::resolveX86_64Relocation(uint8_t *LocalAddress,
194                                             uint64_t FinalAddress,
195                                             uint64_t Value,
196                                             uint32_t Type,
197                                             int64_t Addend) {
198  switch (Type) {
199  default:
200    llvm_unreachable("Relocation type not implemented yet!");
201  break;
202  case ELF::R_X86_64_64: {
203    uint64_t *Target = (uint64_t*)(LocalAddress);
204    *Target = Value + Addend;
205    break;
206  }
207  case ELF::R_X86_64_32:
208  case ELF::R_X86_64_32S: {
209    Value += Addend;
210    assert((Type == ELF::R_X86_64_32 && (Value <= UINT32_MAX)) ||
211           (Type == ELF::R_X86_64_32S &&
212             ((int64_t)Value <= INT32_MAX && (int64_t)Value >= INT32_MIN)));
213    uint32_t TruncatedAddr = (Value & 0xFFFFFFFF);
214    uint32_t *Target = reinterpret_cast<uint32_t*>(LocalAddress);
215    *Target = TruncatedAddr;
216    break;
217  }
218  case ELF::R_X86_64_PC32: {
219    uint32_t *Placeholder = reinterpret_cast<uint32_t*>(LocalAddress);
220    int64_t RealOffset = *Placeholder + Value + Addend - FinalAddress;
221    assert(RealOffset <= INT32_MAX && RealOffset >= INT32_MIN);
222    int32_t TruncOffset = (RealOffset & 0xFFFFFFFF);
223    *Placeholder = TruncOffset;
224    break;
225  }
226  }
227}
228
229void RuntimeDyldELF::resolveX86Relocation(uint8_t *LocalAddress,
230                                          uint32_t FinalAddress,
231                                          uint32_t Value,
232                                          uint32_t Type,
233                                          int32_t Addend) {
234  switch (Type) {
235  case ELF::R_386_32: {
236    uint32_t *Target = (uint32_t*)(LocalAddress);
237    uint32_t Placeholder = *Target;
238    *Target = Placeholder + Value + Addend;
239    break;
240  }
241  case ELF::R_386_PC32: {
242    uint32_t *Placeholder = reinterpret_cast<uint32_t*>(LocalAddress);
243    uint32_t RealOffset = *Placeholder + Value + Addend - FinalAddress;
244    *Placeholder = RealOffset;
245    break;
246    }
247    default:
248      // There are other relocation types, but it appears these are the
249      // only ones currently used by the LLVM ELF object writer
250      llvm_unreachable("Relocation type not implemented yet!");
251      break;
252  }
253}
254
255void RuntimeDyldELF::resolveARMRelocation(uint8_t *LocalAddress,
256                                          uint32_t FinalAddress,
257                                          uint32_t Value,
258                                          uint32_t Type,
259                                          int32_t Addend) {
260  // TODO: Add Thumb relocations.
261  uint32_t* TargetPtr = (uint32_t*)LocalAddress;
262  Value += Addend;
263
264  DEBUG(dbgs() << "resolveARMRelocation, LocalAddress: " << LocalAddress
265               << " FinalAddress: " << format("%p",FinalAddress)
266               << " Value: " << format("%x",Value)
267               << " Type: " << format("%x",Type)
268               << " Addend: " << format("%x",Addend)
269               << "\n");
270
271  switch(Type) {
272  default:
273    llvm_unreachable("Not implemented relocation type!");
274
275  // Just write 32bit value to relocation address
276  case ELF::R_ARM_ABS32 :
277    *TargetPtr = Value;
278    break;
279
280  // Write first 16 bit of 32 bit value to the mov instruction.
281  // Last 4 bit should be shifted.
282  case ELF::R_ARM_MOVW_ABS_NC :
283    Value = Value & 0xFFFF;
284    *TargetPtr |= Value & 0xFFF;
285    *TargetPtr |= ((Value >> 12) & 0xF) << 16;
286    break;
287
288  // Write last 16 bit of 32 bit value to the mov instruction.
289  // Last 4 bit should be shifted.
290  case ELF::R_ARM_MOVT_ABS :
291    Value = (Value >> 16) & 0xFFFF;
292    *TargetPtr |= Value & 0xFFF;
293    *TargetPtr |= ((Value >> 12) & 0xF) << 16;
294    break;
295
296  // Write 24 bit relative value to the branch instruction.
297  case ELF::R_ARM_PC24 :    // Fall through.
298  case ELF::R_ARM_CALL :    // Fall through.
299  case ELF::R_ARM_JUMP24 :
300    int32_t RelValue = static_cast<int32_t>(Value - FinalAddress - 8);
301    RelValue = (RelValue & 0x03FFFFFC) >> 2;
302    *TargetPtr &= 0xFF000000;
303    *TargetPtr |= RelValue;
304    break;
305  }
306}
307
308void RuntimeDyldELF::resolveMIPSRelocation(uint8_t *LocalAddress,
309                                           uint32_t FinalAddress,
310                                           uint32_t Value,
311                                           uint32_t Type,
312                                           int32_t Addend) {
313  uint32_t* TargetPtr = (uint32_t*)LocalAddress;
314  Value += Addend;
315
316  DEBUG(dbgs() << "resolveMipselocation, LocalAddress: " << LocalAddress
317               << " FinalAddress: " << format("%p",FinalAddress)
318               << " Value: " << format("%x",Value)
319               << " Type: " << format("%x",Type)
320               << " Addend: " << format("%x",Addend)
321               << "\n");
322
323  switch(Type) {
324  default:
325    llvm_unreachable("Not implemented relocation type!");
326    break;
327  case ELF::R_MIPS_32:
328    *TargetPtr = Value + (*TargetPtr);
329    break;
330  case ELF::R_MIPS_26:
331    *TargetPtr = ((*TargetPtr) & 0xfc000000) | (( Value & 0x0fffffff) >> 2);
332    break;
333  case ELF::R_MIPS_HI16:
334    // Get the higher 16-bits. Also add 1 if bit 15 is 1.
335    Value += ((*TargetPtr) & 0x0000ffff) << 16;
336    *TargetPtr = ((*TargetPtr) & 0xffff0000) |
337                 (((Value + 0x8000) >> 16) & 0xffff);
338    break;
339   case ELF::R_MIPS_LO16:
340    Value += ((*TargetPtr) & 0x0000ffff);
341    *TargetPtr = ((*TargetPtr) & 0xffff0000) | (Value & 0xffff);
342    break;
343   }
344}
345
346void RuntimeDyldELF::resolveRelocation(uint8_t *LocalAddress,
347                                       uint64_t FinalAddress,
348                                       uint64_t Value,
349                                       uint32_t Type,
350                                       int64_t Addend) {
351  switch (Arch) {
352  case Triple::x86_64:
353    resolveX86_64Relocation(LocalAddress, FinalAddress, Value, Type, Addend);
354    break;
355  case Triple::x86:
356    resolveX86Relocation(LocalAddress, (uint32_t)(FinalAddress & 0xffffffffL),
357                         (uint32_t)(Value & 0xffffffffL), Type,
358                         (uint32_t)(Addend & 0xffffffffL));
359    break;
360  case Triple::arm:    // Fall through.
361  case Triple::thumb:
362    resolveARMRelocation(LocalAddress, (uint32_t)(FinalAddress & 0xffffffffL),
363                         (uint32_t)(Value & 0xffffffffL), Type,
364                         (uint32_t)(Addend & 0xffffffffL));
365    break;
366  case Triple::mips:    // Fall through.
367  case Triple::mipsel:
368    resolveMIPSRelocation(LocalAddress, (uint32_t)(FinalAddress & 0xffffffffL),
369                          (uint32_t)(Value & 0xffffffffL), Type,
370                          (uint32_t)(Addend & 0xffffffffL));
371    break;
372  default: llvm_unreachable("Unsupported CPU type!");
373  }
374}
375
376void RuntimeDyldELF::processRelocationRef(const ObjRelocationInfo &Rel,
377                                          ObjectImage &Obj,
378                                          ObjSectionToIDMap &ObjSectionToID,
379                                          const SymbolTableMap &Symbols,
380                                          StubMap &Stubs) {
381
382  uint32_t RelType = (uint32_t)(Rel.Type & 0xffffffffL);
383  intptr_t Addend = (intptr_t)Rel.AdditionalInfo;
384  const SymbolRef &Symbol = Rel.Symbol;
385
386  // Obtain the symbol name which is referenced in the relocation
387  StringRef TargetName;
388  Symbol.getName(TargetName);
389  DEBUG(dbgs() << "\t\tRelType: " << RelType
390               << " Addend: " << Addend
391               << " TargetName: " << TargetName
392               << "\n");
393  RelocationValueRef Value;
394  // First search for the symbol in the local symbol table
395  SymbolTableMap::const_iterator lsi = Symbols.find(TargetName.data());
396  if (lsi != Symbols.end()) {
397    Value.SectionID = lsi->second.first;
398    Value.Addend = lsi->second.second;
399  } else {
400    // Search for the symbol in the global symbol table
401    SymbolTableMap::const_iterator gsi =
402        GlobalSymbolTable.find(TargetName.data());
403    if (gsi != GlobalSymbolTable.end()) {
404      Value.SectionID = gsi->second.first;
405      Value.Addend = gsi->second.second;
406    } else {
407      SymbolRef::Type SymType;
408      Symbol.getType(SymType);
409      switch (SymType) {
410        case SymbolRef::ST_Debug: {
411          // TODO: Now ELF SymbolRef::ST_Debug = STT_SECTION, it's not obviously
412          // and can be changed by another developers. Maybe best way is add
413          // a new symbol type ST_Section to SymbolRef and use it.
414          section_iterator si(Obj.end_sections());
415          Symbol.getSection(si);
416          if (si == Obj.end_sections())
417            llvm_unreachable("Symbol section not found, bad object file format!");
418          DEBUG(dbgs() << "\t\tThis is section symbol\n");
419          Value.SectionID = findOrEmitSection(Obj, (*si), true, ObjSectionToID);
420          Value.Addend = Addend;
421          break;
422        }
423        case SymbolRef::ST_Unknown: {
424          Value.SymbolName = TargetName.data();
425          Value.Addend = Addend;
426          break;
427        }
428        default:
429          llvm_unreachable("Unresolved symbol type!");
430          break;
431      }
432    }
433  }
434  DEBUG(dbgs() << "\t\tRel.SectionID: " << Rel.SectionID
435               << " Rel.Offset: " << Rel.Offset
436               << "\n");
437  if (Arch == Triple::arm &&
438      (RelType == ELF::R_ARM_PC24 ||
439       RelType == ELF::R_ARM_CALL ||
440       RelType == ELF::R_ARM_JUMP24)) {
441    // This is an ARM branch relocation, need to use a stub function.
442    DEBUG(dbgs() << "\t\tThis is an ARM branch relocation.");
443    SectionEntry &Section = Sections[Rel.SectionID];
444    uint8_t *Target = Section.Address + Rel.Offset;
445
446    //  Look up for existing stub.
447    StubMap::const_iterator i = Stubs.find(Value);
448    if (i != Stubs.end()) {
449      resolveRelocation(Target, (uint64_t)Target, (uint64_t)Section.Address +
450                        i->second, RelType, 0);
451      DEBUG(dbgs() << " Stub function found\n");
452    } else {
453      // Create a new stub function.
454      DEBUG(dbgs() << " Create a new stub function\n");
455      Stubs[Value] = Section.StubOffset;
456      uint8_t *StubTargetAddr = createStubFunction(Section.Address +
457                                                   Section.StubOffset);
458      RelocationEntry RE(Rel.SectionID, StubTargetAddr - Section.Address,
459                         ELF::R_ARM_ABS32, Value.Addend);
460      if (Value.SymbolName)
461        addRelocationForSymbol(RE, Value.SymbolName);
462      else
463        addRelocationForSection(RE, Value.SectionID);
464
465      resolveRelocation(Target, (uint64_t)Target, (uint64_t)Section.Address +
466                        Section.StubOffset, RelType, 0);
467      Section.StubOffset += getMaxStubSize();
468    }
469  } else if (Arch == Triple::mipsel && RelType == ELF::R_MIPS_26) {
470    // This is an Mips branch relocation, need to use a stub function.
471    DEBUG(dbgs() << "\t\tThis is a Mips branch relocation.");
472    SectionEntry &Section = Sections[Rel.SectionID];
473    uint8_t *Target = Section.Address + Rel.Offset;
474    uint32_t *TargetAddress = (uint32_t *)Target;
475
476    // Extract the addend from the instruction.
477    uint32_t Addend = ((*TargetAddress) & 0x03ffffff) << 2;
478
479    Value.Addend += Addend;
480
481    //  Look up for existing stub.
482    StubMap::const_iterator i = Stubs.find(Value);
483    if (i != Stubs.end()) {
484      resolveRelocation(Target, (uint64_t)Target,
485                        (uint64_t)Section.Address +
486                        i->second, RelType, 0);
487      DEBUG(dbgs() << " Stub function found\n");
488    } else {
489      // Create a new stub function.
490      DEBUG(dbgs() << " Create a new stub function\n");
491      Stubs[Value] = Section.StubOffset;
492      uint8_t *StubTargetAddr = createStubFunction(Section.Address +
493                                                   Section.StubOffset);
494
495      // Creating Hi and Lo relocations for the filled stub instructions.
496      RelocationEntry REHi(Rel.SectionID,
497                           StubTargetAddr - Section.Address,
498                           ELF::R_MIPS_HI16, Value.Addend);
499      RelocationEntry RELo(Rel.SectionID,
500                           StubTargetAddr - Section.Address + 4,
501                           ELF::R_MIPS_LO16, Value.Addend);
502
503      if (Value.SymbolName) {
504        addRelocationForSymbol(REHi, Value.SymbolName);
505        addRelocationForSymbol(RELo, Value.SymbolName);
506      } else {
507        addRelocationForSection(REHi, Value.SectionID);
508        addRelocationForSection(RELo, Value.SectionID);
509      }
510
511      resolveRelocation(Target, (uint64_t)Target,
512                        (uint64_t)Section.Address +
513                        Section.StubOffset, RelType, 0);
514      Section.StubOffset += getMaxStubSize();
515    }
516  } else {
517    RelocationEntry RE(Rel.SectionID, Rel.Offset, RelType, Value.Addend);
518    if (Value.SymbolName)
519      addRelocationForSymbol(RE, Value.SymbolName);
520    else
521      addRelocationForSection(RE, Value.SectionID);
522  }
523}
524
525bool RuntimeDyldELF::isCompatibleFormat(const MemoryBuffer *InputBuffer) const {
526  StringRef Magic = InputBuffer->getBuffer().slice(0, ELF::EI_NIDENT);
527  return (memcmp(Magic.data(), ELF::ElfMagic, strlen(ELF::ElfMagic))) == 0;
528}
529} // namespace llvm
530