Path: blob/main/contrib/llvm-project/llvm/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldMachOI386.h
35294 views
//===---- RuntimeDyldMachOI386.h ---- MachO/I386 specific code. ---*- C++ -*-=//1//2// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.3// See https://llvm.org/LICENSE.txt for license information.4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception5//6//===----------------------------------------------------------------------===//78#ifndef LLVM_LIB_EXECUTIONENGINE_RUNTIMEDYLD_TARGETS_RUNTIMEDYLDMACHOI386_H9#define LLVM_LIB_EXECUTIONENGINE_RUNTIMEDYLD_TARGETS_RUNTIMEDYLDMACHOI386_H1011#include "../RuntimeDyldMachO.h"1213#define DEBUG_TYPE "dyld"1415namespace llvm {1617class RuntimeDyldMachOI38618: public RuntimeDyldMachOCRTPBase<RuntimeDyldMachOI386> {19public:2021typedef uint32_t TargetPtrT;2223RuntimeDyldMachOI386(RuntimeDyld::MemoryManager &MM,24JITSymbolResolver &Resolver)25: RuntimeDyldMachOCRTPBase(MM, Resolver) {}2627unsigned getMaxStubSize() const override { return 0; }2829Align getStubAlignment() override { return Align(1); }3031Expected<relocation_iterator>32processRelocationRef(unsigned SectionID, relocation_iterator RelI,33const ObjectFile &BaseObjT,34ObjSectionToIDMap &ObjSectionToID,35StubMap &Stubs) override {36const MachOObjectFile &Obj =37static_cast<const MachOObjectFile &>(BaseObjT);38MachO::any_relocation_info RelInfo =39Obj.getRelocation(RelI->getRawDataRefImpl());40uint32_t RelType = Obj.getAnyRelocationType(RelInfo);4142if (Obj.isRelocationScattered(RelInfo)) {43if (RelType == MachO::GENERIC_RELOC_SECTDIFF ||44RelType == MachO::GENERIC_RELOC_LOCAL_SECTDIFF)45return processSECTDIFFRelocation(SectionID, RelI, Obj,46ObjSectionToID);47else if (RelType == MachO::GENERIC_RELOC_VANILLA)48return processScatteredVANILLA(SectionID, RelI, Obj, ObjSectionToID);49return make_error<RuntimeDyldError>(("Unhandled I386 scattered relocation "50"type: " + Twine(RelType)).str());51}5253switch (RelType) {54UNIMPLEMENTED_RELOC(MachO::GENERIC_RELOC_PAIR);55UNIMPLEMENTED_RELOC(MachO::GENERIC_RELOC_PB_LA_PTR);56UNIMPLEMENTED_RELOC(MachO::GENERIC_RELOC_TLV);57default:58if (RelType > MachO::GENERIC_RELOC_TLV)59return make_error<RuntimeDyldError>(("MachO I386 relocation type " +60Twine(RelType) +61" is out of range").str());62break;63}6465RelocationEntry RE(getRelocationEntry(SectionID, Obj, RelI));66RE.Addend = memcpyAddend(RE);67RelocationValueRef Value;68if (auto ValueOrErr = getRelocationValueRef(Obj, RelI, RE, ObjSectionToID))69Value = *ValueOrErr;70else71return ValueOrErr.takeError();7273// Addends for external, PC-rel relocations on i386 point back to the zero74// offset. Calculate the final offset from the relocation target instead.75// This allows us to use the same logic for both external and internal76// relocations in resolveI386RelocationRef.77// bool IsExtern = Obj.getPlainRelocationExternal(RelInfo);78// if (IsExtern && RE.IsPCRel) {79// uint64_t RelocAddr = 0;80// RelI->getAddress(RelocAddr);81// Value.Addend += RelocAddr + 4;82// }83if (RE.IsPCRel)84makeValueAddendPCRel(Value, RelI, 1 << RE.Size);8586RE.Addend = Value.Offset;8788if (Value.SymbolName)89addRelocationForSymbol(RE, Value.SymbolName);90else91addRelocationForSection(RE, Value.SectionID);9293return ++RelI;94}9596void resolveRelocation(const RelocationEntry &RE, uint64_t Value) override {97LLVM_DEBUG(dumpRelocationToResolve(RE, Value));9899const SectionEntry &Section = Sections[RE.SectionID];100uint8_t *LocalAddress = Section.getAddressWithOffset(RE.Offset);101102if (RE.IsPCRel) {103uint64_t FinalAddress = Section.getLoadAddressWithOffset(RE.Offset);104Value -= FinalAddress + 4; // see MachOX86_64::resolveRelocation.105}106107switch (RE.RelType) {108case MachO::GENERIC_RELOC_VANILLA:109writeBytesUnaligned(Value + RE.Addend, LocalAddress, 1 << RE.Size);110break;111case MachO::GENERIC_RELOC_SECTDIFF:112case MachO::GENERIC_RELOC_LOCAL_SECTDIFF: {113uint64_t SectionABase = Sections[RE.Sections.SectionA].getLoadAddress();114uint64_t SectionBBase = Sections[RE.Sections.SectionB].getLoadAddress();115assert((Value == SectionABase || Value == SectionBBase) &&116"Unexpected SECTDIFF relocation value.");117Value = SectionABase - SectionBBase + RE.Addend;118writeBytesUnaligned(Value, LocalAddress, 1 << RE.Size);119break;120}121default:122llvm_unreachable("Invalid relocation type!");123}124}125126Error finalizeSection(const ObjectFile &Obj, unsigned SectionID,127const SectionRef &Section) {128StringRef Name;129if (Expected<StringRef> NameOrErr = Section.getName())130Name = *NameOrErr;131else132consumeError(NameOrErr.takeError());133134if (Name == "__jump_table")135return populateJumpTable(cast<MachOObjectFile>(Obj), Section, SectionID);136else if (Name == "__pointers")137return populateIndirectSymbolPointersSection(cast<MachOObjectFile>(Obj),138Section, SectionID);139return Error::success();140}141142private:143Expected<relocation_iterator>144processSECTDIFFRelocation(unsigned SectionID, relocation_iterator RelI,145const ObjectFile &BaseObjT,146ObjSectionToIDMap &ObjSectionToID) {147const MachOObjectFile &Obj =148static_cast<const MachOObjectFile&>(BaseObjT);149MachO::any_relocation_info RE =150Obj.getRelocation(RelI->getRawDataRefImpl());151152SectionEntry &Section = Sections[SectionID];153uint32_t RelocType = Obj.getAnyRelocationType(RE);154bool IsPCRel = Obj.getAnyRelocationPCRel(RE);155unsigned Size = Obj.getAnyRelocationLength(RE);156uint64_t Offset = RelI->getOffset();157uint8_t *LocalAddress = Section.getAddressWithOffset(Offset);158unsigned NumBytes = 1 << Size;159uint64_t Addend = readBytesUnaligned(LocalAddress, NumBytes);160161++RelI;162MachO::any_relocation_info RE2 =163Obj.getRelocation(RelI->getRawDataRefImpl());164165uint32_t AddrA = Obj.getScatteredRelocationValue(RE);166section_iterator SAI = getSectionByAddress(Obj, AddrA);167assert(SAI != Obj.section_end() && "Can't find section for address A");168uint64_t SectionABase = SAI->getAddress();169uint64_t SectionAOffset = AddrA - SectionABase;170SectionRef SectionA = *SAI;171bool IsCode = SectionA.isText();172uint32_t SectionAID = ~0U;173if (auto SectionAIDOrErr =174findOrEmitSection(Obj, SectionA, IsCode, ObjSectionToID))175SectionAID = *SectionAIDOrErr;176else177return SectionAIDOrErr.takeError();178179uint32_t AddrB = Obj.getScatteredRelocationValue(RE2);180section_iterator SBI = getSectionByAddress(Obj, AddrB);181assert(SBI != Obj.section_end() && "Can't find section for address B");182uint64_t SectionBBase = SBI->getAddress();183uint64_t SectionBOffset = AddrB - SectionBBase;184SectionRef SectionB = *SBI;185uint32_t SectionBID = ~0U;186if (auto SectionBIDOrErr =187findOrEmitSection(Obj, SectionB, IsCode, ObjSectionToID))188SectionBID = *SectionBIDOrErr;189else190return SectionBIDOrErr.takeError();191192// Compute the addend 'C' from the original expression 'A - B + C'.193Addend -= AddrA - AddrB;194195LLVM_DEBUG(dbgs() << "Found SECTDIFF: AddrA: " << AddrA196<< ", AddrB: " << AddrB << ", Addend: " << Addend197<< ", SectionA ID: " << SectionAID << ", SectionAOffset: "198<< SectionAOffset << ", SectionB ID: " << SectionBID199<< ", SectionBOffset: " << SectionBOffset << "\n");200RelocationEntry R(SectionID, Offset, RelocType, Addend, SectionAID,201SectionAOffset, SectionBID, SectionBOffset,202IsPCRel, Size);203204addRelocationForSection(R, SectionAID);205206return ++RelI;207}208209// Populate stubs in __jump_table section.210Error populateJumpTable(const MachOObjectFile &Obj,211const SectionRef &JTSection,212unsigned JTSectionID) {213MachO::dysymtab_command DySymTabCmd = Obj.getDysymtabLoadCommand();214MachO::section Sec32 = Obj.getSection(JTSection.getRawDataRefImpl());215uint32_t JTSectionSize = Sec32.size;216unsigned FirstIndirectSymbol = Sec32.reserved1;217unsigned JTEntrySize = Sec32.reserved2;218unsigned NumJTEntries = JTSectionSize / JTEntrySize;219uint8_t *JTSectionAddr = getSectionAddress(JTSectionID);220unsigned JTEntryOffset = 0;221222if (JTSectionSize % JTEntrySize != 0)223return make_error<RuntimeDyldError>("Jump-table section does not contain "224"a whole number of stubs?");225226for (unsigned i = 0; i < NumJTEntries; ++i) {227unsigned SymbolIndex =228Obj.getIndirectSymbolTableEntry(DySymTabCmd, FirstIndirectSymbol + i);229symbol_iterator SI = Obj.getSymbolByIndex(SymbolIndex);230Expected<StringRef> IndirectSymbolName = SI->getName();231if (!IndirectSymbolName)232return IndirectSymbolName.takeError();233uint8_t *JTEntryAddr = JTSectionAddr + JTEntryOffset;234createStubFunction(JTEntryAddr);235RelocationEntry RE(JTSectionID, JTEntryOffset + 1,236MachO::GENERIC_RELOC_VANILLA, 0, true, 2);237addRelocationForSymbol(RE, *IndirectSymbolName);238JTEntryOffset += JTEntrySize;239}240241return Error::success();242}243244};245}246247#undef DEBUG_TYPE248249#endif250251252