brintos

brintos / llvm-project-archived public Read only

0
0
Text · 9.5 KiB · a983e22 Raw
251 lines · c
1//===---- RuntimeDyldMachOI386.h ---- MachO/I386 specific code. ---*- C++ -*-=//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8 9#ifndef LLVM_LIB_EXECUTIONENGINE_RUNTIMEDYLD_TARGETS_RUNTIMEDYLDMACHOI386_H10#define LLVM_LIB_EXECUTIONENGINE_RUNTIMEDYLD_TARGETS_RUNTIMEDYLDMACHOI386_H11 12#include "../RuntimeDyldMachO.h"13 14#define DEBUG_TYPE "dyld"15 16namespace llvm {17 18class RuntimeDyldMachOI38619    : public RuntimeDyldMachOCRTPBase<RuntimeDyldMachOI386> {20public:21 22  typedef uint32_t TargetPtrT;23 24  RuntimeDyldMachOI386(RuntimeDyld::MemoryManager &MM,25                       JITSymbolResolver &Resolver)26      : RuntimeDyldMachOCRTPBase(MM, Resolver) {}27 28  unsigned getMaxStubSize() const override { return 0; }29 30  Align getStubAlignment() override { return Align(1); }31 32  Expected<relocation_iterator>33  processRelocationRef(unsigned SectionID, relocation_iterator RelI,34                       const ObjectFile &BaseObjT,35                       ObjSectionToIDMap &ObjSectionToID,36                       StubMap &Stubs) override {37    const MachOObjectFile &Obj =38        static_cast<const MachOObjectFile &>(BaseObjT);39    MachO::any_relocation_info RelInfo =40        Obj.getRelocation(RelI->getRawDataRefImpl());41    uint32_t RelType = Obj.getAnyRelocationType(RelInfo);42 43    if (Obj.isRelocationScattered(RelInfo)) {44      if (RelType == MachO::GENERIC_RELOC_SECTDIFF ||45          RelType == MachO::GENERIC_RELOC_LOCAL_SECTDIFF)46        return processSECTDIFFRelocation(SectionID, RelI, Obj,47                                         ObjSectionToID);48      else if (RelType == MachO::GENERIC_RELOC_VANILLA)49        return processScatteredVANILLA(SectionID, RelI, Obj, ObjSectionToID);50      return make_error<RuntimeDyldError>(("Unhandled I386 scattered relocation "51                                           "type: " + Twine(RelType)).str());52    }53 54    switch (RelType) {55    UNIMPLEMENTED_RELOC(MachO::GENERIC_RELOC_PAIR);56    UNIMPLEMENTED_RELOC(MachO::GENERIC_RELOC_PB_LA_PTR);57    UNIMPLEMENTED_RELOC(MachO::GENERIC_RELOC_TLV);58    default:59      if (RelType > MachO::GENERIC_RELOC_TLV)60        return make_error<RuntimeDyldError>(("MachO I386 relocation type " +61                                             Twine(RelType) +62                                             " is out of range").str());63      break;64    }65 66    RelocationEntry RE(getRelocationEntry(SectionID, Obj, RelI));67    RE.Addend = memcpyAddend(RE);68    RelocationValueRef Value;69    if (auto ValueOrErr = getRelocationValueRef(Obj, RelI, RE, ObjSectionToID))70      Value = *ValueOrErr;71    else72      return ValueOrErr.takeError();73 74    // Addends for external, PC-rel relocations on i386 point back to the zero75    // offset. Calculate the final offset from the relocation target instead.76    // This allows us to use the same logic for both external and internal77    // relocations in resolveI386RelocationRef.78    // bool IsExtern = Obj.getPlainRelocationExternal(RelInfo);79    // if (IsExtern && RE.IsPCRel) {80    //   uint64_t RelocAddr = 0;81    //   RelI->getAddress(RelocAddr);82    //   Value.Addend += RelocAddr + 4;83    // }84    if (RE.IsPCRel)85      makeValueAddendPCRel(Value, RelI, 1 << RE.Size);86 87    RE.Addend = Value.Offset;88 89    if (Value.SymbolName)90      addRelocationForSymbol(RE, Value.SymbolName);91    else92      addRelocationForSection(RE, Value.SectionID);93 94    return ++RelI;95  }96 97  void resolveRelocation(const RelocationEntry &RE, uint64_t Value) override {98    LLVM_DEBUG(dumpRelocationToResolve(RE, Value));99 100    const SectionEntry &Section = Sections[RE.SectionID];101    uint8_t *LocalAddress = Section.getAddressWithOffset(RE.Offset);102 103    if (RE.IsPCRel) {104      uint64_t FinalAddress = Section.getLoadAddressWithOffset(RE.Offset);105      Value -= FinalAddress + 4; // see MachOX86_64::resolveRelocation.106    }107 108    switch (RE.RelType) {109    case MachO::GENERIC_RELOC_VANILLA:110      writeBytesUnaligned(Value + RE.Addend, LocalAddress, 1 << RE.Size);111      break;112    case MachO::GENERIC_RELOC_SECTDIFF:113    case MachO::GENERIC_RELOC_LOCAL_SECTDIFF: {114      uint64_t SectionABase = Sections[RE.Sections.SectionA].getLoadAddress();115      uint64_t SectionBBase = Sections[RE.Sections.SectionB].getLoadAddress();116      assert((Value == SectionABase || Value == SectionBBase) &&117             "Unexpected SECTDIFF relocation value.");118      Value = SectionABase - SectionBBase + RE.Addend;119      writeBytesUnaligned(Value, LocalAddress, 1 << RE.Size);120      break;121    }122    default:123      llvm_unreachable("Invalid relocation type!");124    }125  }126 127  Error finalizeSection(const ObjectFile &Obj, unsigned SectionID,128                       const SectionRef &Section) {129    StringRef Name;130    if (Expected<StringRef> NameOrErr = Section.getName())131      Name = *NameOrErr;132    else133      consumeError(NameOrErr.takeError());134 135    if (Name == "__jump_table")136      return populateJumpTable(cast<MachOObjectFile>(Obj), Section, SectionID);137    else if (Name == "__pointers")138      return populateIndirectSymbolPointersSection(cast<MachOObjectFile>(Obj),139                                                   Section, SectionID);140    return Error::success();141  }142 143private:144  Expected<relocation_iterator>145  processSECTDIFFRelocation(unsigned SectionID, relocation_iterator RelI,146                            const ObjectFile &BaseObjT,147                            ObjSectionToIDMap &ObjSectionToID) {148    const MachOObjectFile &Obj =149        static_cast<const MachOObjectFile&>(BaseObjT);150    MachO::any_relocation_info RE =151        Obj.getRelocation(RelI->getRawDataRefImpl());152 153    SectionEntry &Section = Sections[SectionID];154    uint32_t RelocType = Obj.getAnyRelocationType(RE);155    bool IsPCRel = Obj.getAnyRelocationPCRel(RE);156    unsigned Size = Obj.getAnyRelocationLength(RE);157    uint64_t Offset = RelI->getOffset();158    uint8_t *LocalAddress = Section.getAddressWithOffset(Offset);159    unsigned NumBytes = 1 << Size;160    uint64_t Addend = readBytesUnaligned(LocalAddress, NumBytes);161 162    ++RelI;163    MachO::any_relocation_info RE2 =164        Obj.getRelocation(RelI->getRawDataRefImpl());165 166    uint32_t AddrA = Obj.getScatteredRelocationValue(RE);167    section_iterator SAI = getSectionByAddress(Obj, AddrA);168    assert(SAI != Obj.section_end() && "Can't find section for address A");169    uint64_t SectionABase = SAI->getAddress();170    uint64_t SectionAOffset = AddrA - SectionABase;171    SectionRef SectionA = *SAI;172    bool IsCode = SectionA.isText();173    uint32_t SectionAID = ~0U;174    if (auto SectionAIDOrErr =175        findOrEmitSection(Obj, SectionA, IsCode, ObjSectionToID))176      SectionAID = *SectionAIDOrErr;177    else178      return SectionAIDOrErr.takeError();179 180    uint32_t AddrB = Obj.getScatteredRelocationValue(RE2);181    section_iterator SBI = getSectionByAddress(Obj, AddrB);182    assert(SBI != Obj.section_end() && "Can't find section for address B");183    uint64_t SectionBBase = SBI->getAddress();184    uint64_t SectionBOffset = AddrB - SectionBBase;185    SectionRef SectionB = *SBI;186    uint32_t SectionBID = ~0U;187    if (auto SectionBIDOrErr =188        findOrEmitSection(Obj, SectionB, IsCode, ObjSectionToID))189      SectionBID = *SectionBIDOrErr;190    else191      return SectionBIDOrErr.takeError();192 193    // Compute the addend 'C' from the original expression 'A - B + C'.194    Addend -= AddrA - AddrB;195 196    LLVM_DEBUG(dbgs() << "Found SECTDIFF: AddrA: " << AddrA197                      << ", AddrB: " << AddrB << ", Addend: " << Addend198                      << ", SectionA ID: " << SectionAID << ", SectionAOffset: "199                      << SectionAOffset << ", SectionB ID: " << SectionBID200                      << ", SectionBOffset: " << SectionBOffset << "\n");201    RelocationEntry R(SectionID, Offset, RelocType, Addend, SectionAID,202                      SectionAOffset, SectionBID, SectionBOffset,203                      IsPCRel, Size);204 205    addRelocationForSection(R, SectionAID);206 207    return ++RelI;208  }209 210  // Populate stubs in __jump_table section.211  Error populateJumpTable(const MachOObjectFile &Obj,212                          const SectionRef &JTSection,213                         unsigned JTSectionID) {214    MachO::dysymtab_command DySymTabCmd = Obj.getDysymtabLoadCommand();215    MachO::section Sec32 = Obj.getSection(JTSection.getRawDataRefImpl());216    uint32_t JTSectionSize = Sec32.size;217    unsigned FirstIndirectSymbol = Sec32.reserved1;218    unsigned JTEntrySize = Sec32.reserved2;219    unsigned NumJTEntries = JTSectionSize / JTEntrySize;220    uint8_t *JTSectionAddr = getSectionAddress(JTSectionID);221    unsigned JTEntryOffset = 0;222 223    if (JTSectionSize % JTEntrySize != 0)224      return make_error<RuntimeDyldError>("Jump-table section does not contain "225                                          "a whole number of stubs?");226 227    for (unsigned i = 0; i < NumJTEntries; ++i) {228      unsigned SymbolIndex =229          Obj.getIndirectSymbolTableEntry(DySymTabCmd, FirstIndirectSymbol + i);230      symbol_iterator SI = Obj.getSymbolByIndex(SymbolIndex);231      Expected<StringRef> IndirectSymbolName = SI->getName();232      if (!IndirectSymbolName)233        return IndirectSymbolName.takeError();234      uint8_t *JTEntryAddr = JTSectionAddr + JTEntryOffset;235      createStubFunction(JTEntryAddr);236      RelocationEntry RE(JTSectionID, JTEntryOffset + 1,237                         MachO::GENERIC_RELOC_VANILLA, 0, true, 2);238      addRelocationForSymbol(RE, *IndirectSymbolName);239      JTEntryOffset += JTEntrySize;240    }241 242    return Error::success();243  }244 245};246}247 248#undef DEBUG_TYPE249 250#endif251