Home | History | Annotate | Download | only in RuntimeDyld
      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"
     25 using namespace llvm;
     26 using namespace llvm::object;
     27 
     28 namespace {
     29 
     30 template<support::endianness target_endianness, bool is64Bits>
     31 class 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 typename ELFObjectFile<target_endianness, is64Bits>::
     40     Elf_Ehdr Elf_Ehdr;
     41 
     42   typedef typename ELFDataTypeTypedefHelper<
     43           target_endianness, is64Bits>::value_type addr_type;
     44 
     45 protected:
     46   // This duplicates the 'Data' member in the 'Binary' base class
     47   // but it is necessary to workaround a bug in gcc 4.2
     48   MemoryBuffer *InputData;
     49 
     50 public:
     51   DyldELFObject(MemoryBuffer *Object, error_code &ec);
     52 
     53   void updateSectionAddress(const SectionRef &Sec, uint64_t Addr);
     54   void updateSymbolAddress(const SymbolRef &Sym, uint64_t Addr);
     55 
     56   const MemoryBuffer& getBuffer() const { return *InputData; }
     57 
     58   // Methods for type inquiry through isa, cast, and dyn_cast
     59   static inline bool classof(const Binary *v) {
     60     return (isa<ELFObjectFile<target_endianness, is64Bits> >(v)
     61             && classof(cast<ELFObjectFile<target_endianness, is64Bits> >(v)));
     62   }
     63   static inline bool classof(
     64       const ELFObjectFile<target_endianness, is64Bits> *v) {
     65     return v->isDyldType();
     66   }
     67   static inline bool classof(const DyldELFObject *v) {
     68     return true;
     69   }
     70 };
     71 
     72 template<support::endianness target_endianness, bool is64Bits>
     73 class ELFObjectImage : public ObjectImage {
     74   protected:
     75     DyldELFObject<target_endianness, is64Bits> *DyldObj;
     76     bool Registered;
     77 
     78   public:
     79     ELFObjectImage(DyldELFObject<target_endianness, is64Bits> *Obj)
     80     : ObjectImage(Obj),
     81       DyldObj(Obj),
     82       Registered(false) {}
     83 
     84     virtual ~ELFObjectImage() {
     85       if (Registered)
     86         deregisterWithDebugger();
     87     }
     88 
     89     // Subclasses can override these methods to update the image with loaded
     90     // addresses for sections and common symbols
     91     virtual void updateSectionAddress(const SectionRef &Sec, uint64_t Addr)
     92     {
     93       DyldObj->updateSectionAddress(Sec, Addr);
     94     }
     95 
     96     virtual void updateSymbolAddress(const SymbolRef &Sym, uint64_t Addr)
     97     {
     98       DyldObj->updateSymbolAddress(Sym, Addr);
     99     }
    100 
    101     virtual void registerWithDebugger()
    102     {
    103       JITRegistrar::getGDBRegistrar().registerObject(DyldObj->getBuffer());
    104       Registered = true;
    105     }
    106     virtual void deregisterWithDebugger()
    107     {
    108       JITRegistrar::getGDBRegistrar().deregisterObject(DyldObj->getBuffer());
    109     }
    110 };
    111 
    112 template<support::endianness target_endianness, bool is64Bits>
    113 DyldELFObject<target_endianness, is64Bits>::DyldELFObject(MemoryBuffer *Object,
    114                                                           error_code &ec)
    115   : ELFObjectFile<target_endianness, is64Bits>(Object, ec),
    116     InputData(Object) {
    117   this->isDyldELFObject = true;
    118 }
    119 
    120 template<support::endianness target_endianness, bool is64Bits>
    121 void DyldELFObject<target_endianness, is64Bits>::updateSectionAddress(
    122                                                        const SectionRef &Sec,
    123                                                        uint64_t Addr) {
    124   DataRefImpl ShdrRef = Sec.getRawDataRefImpl();
    125   Elf_Shdr *shdr = const_cast<Elf_Shdr*>(
    126                           reinterpret_cast<const Elf_Shdr *>(ShdrRef.p));
    127 
    128   // This assumes the address passed in matches the target address bitness
    129   // The template-based type cast handles everything else.
    130   shdr->sh_addr = static_cast<addr_type>(Addr);
    131 }
    132 
    133 template<support::endianness target_endianness, bool is64Bits>
    134 void DyldELFObject<target_endianness, is64Bits>::updateSymbolAddress(
    135                                                        const SymbolRef &SymRef,
    136                                                        uint64_t Addr) {
    137 
    138   Elf_Sym *sym = const_cast<Elf_Sym*>(
    139                                  ELFObjectFile<target_endianness, is64Bits>::
    140                                    getSymbol(SymRef.getRawDataRefImpl()));
    141 
    142   // This assumes the address passed in matches the target address bitness
    143   // The template-based type cast handles everything else.
    144   sym->st_value = static_cast<addr_type>(Addr);
    145 }
    146 
    147 } // namespace
    148 
    149 
    150 namespace llvm {
    151 
    152 ObjectImage *RuntimeDyldELF::createObjectImage(
    153                                          const MemoryBuffer *ConstInputBuffer) {
    154   MemoryBuffer *InputBuffer = const_cast<MemoryBuffer*>(ConstInputBuffer);
    155   std::pair<unsigned char, unsigned char> Ident = getElfArchType(InputBuffer);
    156   error_code ec;
    157 
    158   if (Ident.first == ELF::ELFCLASS32 && Ident.second == ELF::ELFDATA2LSB) {
    159     DyldELFObject<support::little, false> *Obj =
    160            new DyldELFObject<support::little, false>(InputBuffer, ec);
    161     return new ELFObjectImage<support::little, false>(Obj);
    162   }
    163   else if (Ident.first == ELF::ELFCLASS32 && Ident.second == ELF::ELFDATA2MSB) {
    164     DyldELFObject<support::big, false> *Obj =
    165            new DyldELFObject<support::big, false>(InputBuffer, ec);
    166     return new ELFObjectImage<support::big, false>(Obj);
    167   }
    168   else if (Ident.first == ELF::ELFCLASS64 && Ident.second == ELF::ELFDATA2MSB) {
    169     DyldELFObject<support::big, true> *Obj =
    170            new DyldELFObject<support::big, true>(InputBuffer, ec);
    171     return new ELFObjectImage<support::big, true>(Obj);
    172   }
    173   else if (Ident.first == ELF::ELFCLASS64 && Ident.second == ELF::ELFDATA2LSB) {
    174     DyldELFObject<support::little, true> *Obj =
    175            new DyldELFObject<support::little, true>(InputBuffer, ec);
    176     return new ELFObjectImage<support::little, true>(Obj);
    177   }
    178   else
    179     llvm_unreachable("Unexpected ELF format");
    180 }
    181 
    182 void RuntimeDyldELF::handleObjectLoaded(ObjectImage *Obj)
    183 {
    184   Obj->registerWithDebugger();
    185   // Save the loaded object.  It will deregister itself when deleted
    186   LoadedObject = Obj;
    187 }
    188 
    189 RuntimeDyldELF::~RuntimeDyldELF() {
    190   if (LoadedObject)
    191     delete LoadedObject;
    192 }
    193 
    194 void RuntimeDyldELF::resolveX86_64Relocation(uint8_t *LocalAddress,
    195                                              uint64_t FinalAddress,
    196                                              uint64_t Value,
    197                                              uint32_t Type,
    198                                              int64_t Addend) {
    199   switch (Type) {
    200   default:
    201     llvm_unreachable("Relocation type not implemented yet!");
    202   break;
    203   case ELF::R_X86_64_64: {
    204     uint64_t *Target = (uint64_t*)(LocalAddress);
    205     *Target = Value + Addend;
    206     break;
    207   }
    208   case ELF::R_X86_64_32:
    209   case ELF::R_X86_64_32S: {
    210     Value += Addend;
    211     // FIXME: Handle the possibility of this assertion failing
    212     assert((Type == ELF::R_X86_64_32 && !(Value & 0xFFFFFFFF00000000ULL)) ||
    213            (Type == ELF::R_X86_64_32S &&
    214             (Value & 0xFFFFFFFF00000000ULL) == 0xFFFFFFFF00000000ULL));
    215     uint32_t TruncatedAddr = (Value & 0xFFFFFFFF);
    216     uint32_t *Target = reinterpret_cast<uint32_t*>(LocalAddress);
    217     *Target = TruncatedAddr;
    218     break;
    219   }
    220   case ELF::R_X86_64_PC32: {
    221     uint32_t *Placeholder = reinterpret_cast<uint32_t*>(LocalAddress);
    222     int64_t RealOffset = *Placeholder + Value + Addend - FinalAddress;
    223     assert(RealOffset <= 214783647 && RealOffset >= -214783648);
    224     int32_t TruncOffset = (RealOffset & 0xFFFFFFFF);
    225     *Placeholder = TruncOffset;
    226     break;
    227   }
    228   }
    229 }
    230 
    231 void RuntimeDyldELF::resolveX86Relocation(uint8_t *LocalAddress,
    232                                           uint32_t FinalAddress,
    233                                           uint32_t Value,
    234                                           uint32_t Type,
    235                                           int32_t Addend) {
    236   switch (Type) {
    237   case ELF::R_386_32: {
    238     uint32_t *Target = (uint32_t*)(LocalAddress);
    239     uint32_t Placeholder = *Target;
    240     *Target = Placeholder + Value + Addend;
    241     break;
    242   }
    243   case ELF::R_386_PC32: {
    244     uint32_t *Placeholder = reinterpret_cast<uint32_t*>(LocalAddress);
    245     uint32_t RealOffset = *Placeholder + Value + Addend - FinalAddress;
    246     *Placeholder = RealOffset;
    247     break;
    248     }
    249     default:
    250       // There are other relocation types, but it appears these are the
    251       //  only ones currently used by the LLVM ELF object writer
    252       llvm_unreachable("Relocation type not implemented yet!");
    253       break;
    254   }
    255 }
    256 
    257 void RuntimeDyldELF::resolveARMRelocation(uint8_t *LocalAddress,
    258                                           uint32_t FinalAddress,
    259                                           uint32_t Value,
    260                                           uint32_t Type,
    261                                           int32_t Addend) {
    262   // TODO: Add Thumb relocations.
    263   uint32_t* TargetPtr = (uint32_t*)LocalAddress;
    264   Value += Addend;
    265 
    266   DEBUG(dbgs() << "resolveARMRelocation, LocalAddress: " << LocalAddress
    267                << " FinalAddress: " << format("%p",FinalAddress)
    268                << " Value: " << format("%x",Value)
    269                << " Type: " << format("%x",Type)
    270                << " Addend: " << format("%x",Addend)
    271                << "\n");
    272 
    273   switch(Type) {
    274   default:
    275     llvm_unreachable("Not implemented relocation type!");
    276 
    277   // Just write 32bit value to relocation address
    278   case ELF::R_ARM_ABS32 :
    279     *TargetPtr = Value;
    280     break;
    281 
    282   // Write first 16 bit of 32 bit value to the mov instruction.
    283   // Last 4 bit should be shifted.
    284   case ELF::R_ARM_MOVW_ABS_NC :
    285     Value = Value & 0xFFFF;
    286     *TargetPtr |= Value & 0xFFF;
    287     *TargetPtr |= ((Value >> 12) & 0xF) << 16;
    288     break;
    289 
    290   // Write last 16 bit of 32 bit value to the mov instruction.
    291   // Last 4 bit should be shifted.
    292   case ELF::R_ARM_MOVT_ABS :
    293     Value = (Value >> 16) & 0xFFFF;
    294     *TargetPtr |= Value & 0xFFF;
    295     *TargetPtr |= ((Value >> 12) & 0xF) << 16;
    296     break;
    297 
    298   // Write 24 bit relative value to the branch instruction.
    299   case ELF::R_ARM_PC24 :    // Fall through.
    300   case ELF::R_ARM_CALL :    // Fall through.
    301   case ELF::R_ARM_JUMP24 :
    302     int32_t RelValue = static_cast<int32_t>(Value - FinalAddress - 8);
    303     RelValue = (RelValue & 0x03FFFFFC) >> 2;
    304     *TargetPtr &= 0xFF000000;
    305     *TargetPtr |= RelValue;
    306     break;
    307   }
    308 }
    309 
    310 void RuntimeDyldELF::resolveRelocation(uint8_t *LocalAddress,
    311                                        uint64_t FinalAddress,
    312                                        uint64_t Value,
    313                                        uint32_t Type,
    314                                        int64_t Addend) {
    315   switch (Arch) {
    316   case Triple::x86_64:
    317     resolveX86_64Relocation(LocalAddress, FinalAddress, Value, Type, Addend);
    318     break;
    319   case Triple::x86:
    320     resolveX86Relocation(LocalAddress, (uint32_t)(FinalAddress & 0xffffffffL),
    321                          (uint32_t)(Value & 0xffffffffL), Type,
    322                          (uint32_t)(Addend & 0xffffffffL));
    323     break;
    324   case Triple::arm:    // Fall through.
    325   case Triple::thumb:
    326     resolveARMRelocation(LocalAddress, (uint32_t)(FinalAddress & 0xffffffffL),
    327                          (uint32_t)(Value & 0xffffffffL), Type,
    328                          (uint32_t)(Addend & 0xffffffffL));
    329     break;
    330   default: llvm_unreachable("Unsupported CPU type!");
    331   }
    332 }
    333 
    334 void RuntimeDyldELF::processRelocationRef(const ObjRelocationInfo &Rel,
    335                                           ObjectImage &Obj,
    336                                           ObjSectionToIDMap &ObjSectionToID,
    337                                           LocalSymbolMap &Symbols,
    338                                           StubMap &Stubs) {
    339 
    340   uint32_t RelType = (uint32_t)(Rel.Type & 0xffffffffL);
    341   intptr_t Addend = (intptr_t)Rel.AdditionalInfo;
    342   RelocationValueRef Value;
    343   StringRef TargetName;
    344   const SymbolRef &Symbol = Rel.Symbol;
    345   Symbol.getName(TargetName);
    346   DEBUG(dbgs() << "\t\tRelType: " << RelType
    347                << " Addend: " << Addend
    348                << " TargetName: " << TargetName
    349                << "\n");
    350   // First look the symbol in object file symbols.
    351   LocalSymbolMap::iterator lsi = Symbols.find(TargetName.data());
    352   if (lsi != Symbols.end()) {
    353     Value.SectionID = lsi->second.first;
    354     Value.Addend = lsi->second.second;
    355   } else {
    356     // Second look the symbol in global symbol table.
    357     StringMap<SymbolLoc>::iterator gsi = SymbolTable.find(TargetName.data());
    358     if (gsi != SymbolTable.end()) {
    359       Value.SectionID = gsi->second.first;
    360       Value.Addend = gsi->second.second;
    361     } else {
    362       SymbolRef::Type SymType;
    363       Symbol.getType(SymType);
    364       switch (SymType) {
    365         case SymbolRef::ST_Debug: {
    366           // TODO: Now ELF SymbolRef::ST_Debug = STT_SECTION, it's not obviously
    367           // and can be changed by another developers. Maybe best way is add
    368           // a new symbol type ST_Section to SymbolRef and use it.
    369           section_iterator si = Obj.end_sections();
    370           Symbol.getSection(si);
    371           if (si == Obj.end_sections())
    372             llvm_unreachable("Symbol section not found, bad object file format!");
    373           DEBUG(dbgs() << "\t\tThis is section symbol\n");
    374           Value.SectionID = findOrEmitSection(Obj, (*si), true, ObjSectionToID);
    375           Value.Addend = Addend;
    376           break;
    377         }
    378         case SymbolRef::ST_Unknown: {
    379           Value.SymbolName = TargetName.data();
    380           Value.Addend = Addend;
    381           break;
    382         }
    383         default:
    384           llvm_unreachable("Unresolved symbol type!");
    385           break;
    386       }
    387     }
    388   }
    389   DEBUG(dbgs() << "\t\tRel.SectionID: " << Rel.SectionID
    390                << " Rel.Offset: " << Rel.Offset
    391                << "\n");
    392   if (Arch == Triple::arm &&
    393       (RelType == ELF::R_ARM_PC24 ||
    394        RelType == ELF::R_ARM_CALL ||
    395        RelType == ELF::R_ARM_JUMP24)) {
    396     // This is an ARM branch relocation, need to use a stub function.
    397     DEBUG(dbgs() << "\t\tThis is an ARM branch relocation.");
    398     SectionEntry &Section = Sections[Rel.SectionID];
    399     uint8_t *Target = Section.Address + Rel.Offset;
    400 
    401     //  Look up for existing stub.
    402     StubMap::const_iterator i = Stubs.find(Value);
    403     if (i != Stubs.end()) {
    404       resolveRelocation(Target, (uint64_t)Target, (uint64_t)Section.Address +
    405                         i->second, RelType, 0);
    406       DEBUG(dbgs() << " Stub function found\n");
    407     } else {
    408       // Create a new stub function.
    409       DEBUG(dbgs() << " Create a new stub function\n");
    410       Stubs[Value] = Section.StubOffset;
    411       uint8_t *StubTargetAddr = createStubFunction(Section.Address +
    412                                                    Section.StubOffset);
    413       AddRelocation(Value, Rel.SectionID,
    414                     StubTargetAddr - Section.Address, ELF::R_ARM_ABS32);
    415       resolveRelocation(Target, (uint64_t)Target, (uint64_t)Section.Address +
    416                         Section.StubOffset, RelType, 0);
    417       Section.StubOffset += getMaxStubSize();
    418     }
    419   } else
    420     AddRelocation(Value, Rel.SectionID, Rel.Offset, RelType);
    421 }
    422 
    423 bool RuntimeDyldELF::isCompatibleFormat(const MemoryBuffer *InputBuffer) const {
    424   StringRef Magic = InputBuffer->getBuffer().slice(0, ELF::EI_NIDENT);
    425   return (memcmp(Magic.data(), ELF::ElfMagic, strlen(ELF::ElfMagic))) == 0;
    426 }
    427 } // namespace llvm
    428