Path: blob/main/contrib/llvm-project/llvm/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldCOFFI386.h
35294 views
//===--- RuntimeDyldCOFFI386.h --- COFF/X86_64 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//===----------------------------------------------------------------------===//7//8// COFF x86 support for MC-JIT runtime dynamic linker.9//10//===----------------------------------------------------------------------===//1112#ifndef LLVM_LIB_EXECUTIONENGINE_RUNTIMEDYLD_TARGETS_RUNTIMEDYLDCOFFI386_H13#define LLVM_LIB_EXECUTIONENGINE_RUNTIMEDYLD_TARGETS_RUNTIMEDYLDCOFFI386_H1415#include "../RuntimeDyldCOFF.h"16#include "llvm/BinaryFormat/COFF.h"17#include "llvm/Object/COFF.h"1819#define DEBUG_TYPE "dyld"2021namespace llvm {2223class RuntimeDyldCOFFI386 : public RuntimeDyldCOFF {24public:25RuntimeDyldCOFFI386(RuntimeDyld::MemoryManager &MM,26JITSymbolResolver &Resolver)27: RuntimeDyldCOFF(MM, Resolver, 4, COFF::IMAGE_REL_I386_DIR32) {}2829unsigned getMaxStubSize() const override {30return 8; // 2-byte jmp instruction + 32-bit relative address + 2 byte pad31}3233Align getStubAlignment() override { return Align(1); }3435Expected<object::relocation_iterator>36processRelocationRef(unsigned SectionID,37object::relocation_iterator RelI,38const object::ObjectFile &Obj,39ObjSectionToIDMap &ObjSectionToID,40StubMap &Stubs) override {4142auto Symbol = RelI->getSymbol();43if (Symbol == Obj.symbol_end())44report_fatal_error("Unknown symbol in relocation");4546Expected<StringRef> TargetNameOrErr = Symbol->getName();47if (!TargetNameOrErr)48return TargetNameOrErr.takeError();49StringRef TargetName = *TargetNameOrErr;5051auto SectionOrErr = Symbol->getSection();52if (!SectionOrErr)53return SectionOrErr.takeError();54auto Section = *SectionOrErr;55bool IsExtern = Section == Obj.section_end();5657uint64_t RelType = RelI->getType();58uint64_t Offset = RelI->getOffset();5960unsigned TargetSectionID = -1;61uint64_t TargetOffset = -1;62if (TargetName.starts_with(getImportSymbolPrefix())) {63TargetSectionID = SectionID;64TargetOffset = getDLLImportOffset(SectionID, Stubs, TargetName, true);65TargetName = StringRef();66IsExtern = false;67} else if (!IsExtern) {68if (auto TargetSectionIDOrErr = findOrEmitSection(69Obj, *Section, Section->isText(), ObjSectionToID))70TargetSectionID = *TargetSectionIDOrErr;71else72return TargetSectionIDOrErr.takeError();73if (RelType != COFF::IMAGE_REL_I386_SECTION)74TargetOffset = getSymbolOffset(*Symbol);75}7677// Determine the Addend used to adjust the relocation value.78uint64_t Addend = 0;79SectionEntry &AddendSection = Sections[SectionID];80uintptr_t ObjTarget = AddendSection.getObjAddress() + Offset;81uint8_t *Displacement = (uint8_t *)ObjTarget;8283switch (RelType) {84case COFF::IMAGE_REL_I386_DIR32:85case COFF::IMAGE_REL_I386_DIR32NB:86case COFF::IMAGE_REL_I386_SECREL:87case COFF::IMAGE_REL_I386_REL32: {88Addend = readBytesUnaligned(Displacement, 4);89break;90}91default:92break;93}9495#if !defined(NDEBUG)96SmallString<32> RelTypeName;97RelI->getTypeName(RelTypeName);98#endif99LLVM_DEBUG(dbgs() << "\t\tIn Section " << SectionID << " Offset " << Offset100<< " RelType: " << RelTypeName << " TargetName: "101<< TargetName << " Addend " << Addend << "\n");102103if (IsExtern) {104RelocationEntry RE(SectionID, Offset, RelType, 0, -1, 0, 0, 0, false, 0);105addRelocationForSymbol(RE, TargetName);106} else {107108switch (RelType) {109case COFF::IMAGE_REL_I386_ABSOLUTE:110// This relocation is ignored.111break;112case COFF::IMAGE_REL_I386_DIR32:113case COFF::IMAGE_REL_I386_DIR32NB:114case COFF::IMAGE_REL_I386_REL32: {115RelocationEntry RE =116RelocationEntry(SectionID, Offset, RelType, Addend, TargetSectionID,117TargetOffset, 0, 0, false, 0);118addRelocationForSection(RE, TargetSectionID);119break;120}121case COFF::IMAGE_REL_I386_SECTION: {122RelocationEntry RE =123RelocationEntry(TargetSectionID, Offset, RelType, 0);124addRelocationForSection(RE, TargetSectionID);125break;126}127case COFF::IMAGE_REL_I386_SECREL: {128RelocationEntry RE =129RelocationEntry(SectionID, Offset, RelType, TargetOffset + Addend);130addRelocationForSection(RE, TargetSectionID);131break;132}133default:134llvm_unreachable("unsupported relocation type");135}136}137138return ++RelI;139}140141void resolveRelocation(const RelocationEntry &RE, uint64_t Value) override {142const auto Section = Sections[RE.SectionID];143uint8_t *Target = Section.getAddressWithOffset(RE.Offset);144145switch (RE.RelType) {146case COFF::IMAGE_REL_I386_ABSOLUTE:147// This relocation is ignored.148break;149case COFF::IMAGE_REL_I386_DIR32: {150// The target's 32-bit VA.151uint64_t Result =152RE.Sections.SectionA == static_cast<uint32_t>(-1)153? Value154: Sections[RE.Sections.SectionA].getLoadAddressWithOffset(155RE.Addend);156assert(Result <= UINT32_MAX && "relocation overflow");157LLVM_DEBUG(dbgs() << "\t\tOffset: " << RE.Offset158<< " RelType: IMAGE_REL_I386_DIR32"159<< " TargetSection: " << RE.Sections.SectionA160<< " Value: " << format("0x%08" PRIx32, Result)161<< '\n');162writeBytesUnaligned(Result, Target, 4);163break;164}165case COFF::IMAGE_REL_I386_DIR32NB: {166// The target's 32-bit RVA.167// NOTE: use Section[0].getLoadAddress() as an approximation of ImageBase168uint64_t Result =169Sections[RE.Sections.SectionA].getLoadAddressWithOffset(RE.Addend) -170Sections[0].getLoadAddress();171assert(Result <= UINT32_MAX && "relocation overflow");172LLVM_DEBUG(dbgs() << "\t\tOffset: " << RE.Offset173<< " RelType: IMAGE_REL_I386_DIR32NB"174<< " TargetSection: " << RE.Sections.SectionA175<< " Value: " << format("0x%08" PRIx32, Result)176<< '\n');177writeBytesUnaligned(Result, Target, 4);178break;179}180case COFF::IMAGE_REL_I386_REL32: {181// 32-bit relative displacement to the target.182uint64_t Result = RE.Sections.SectionA == static_cast<uint32_t>(-1)183? Value184: Sections[RE.Sections.SectionA].getLoadAddress();185Result = Result - Section.getLoadAddress() + RE.Addend - 4 - RE.Offset;186assert(static_cast<int64_t>(Result) <= INT32_MAX &&187"relocation overflow");188assert(static_cast<int64_t>(Result) >= INT32_MIN &&189"relocation underflow");190LLVM_DEBUG(dbgs() << "\t\tOffset: " << RE.Offset191<< " RelType: IMAGE_REL_I386_REL32"192<< " TargetSection: " << RE.Sections.SectionA193<< " Value: " << format("0x%08" PRIx32, Result)194<< '\n');195writeBytesUnaligned(Result, Target, 4);196break;197}198case COFF::IMAGE_REL_I386_SECTION:199// 16-bit section index of the section that contains the target.200assert(static_cast<uint32_t>(RE.SectionID) <= UINT16_MAX &&201"relocation overflow");202LLVM_DEBUG(dbgs() << "\t\tOffset: " << RE.Offset203<< " RelType: IMAGE_REL_I386_SECTION Value: "204<< RE.SectionID << '\n');205writeBytesUnaligned(RE.SectionID, Target, 2);206break;207case COFF::IMAGE_REL_I386_SECREL:208// 32-bit offset of the target from the beginning of its section.209assert(static_cast<uint64_t>(RE.Addend) <= UINT32_MAX &&210"relocation overflow");211LLVM_DEBUG(dbgs() << "\t\tOffset: " << RE.Offset212<< " RelType: IMAGE_REL_I386_SECREL Value: "213<< RE.Addend << '\n');214writeBytesUnaligned(RE.Addend, Target, 4);215break;216default:217llvm_unreachable("unsupported relocation type");218}219}220221void registerEHFrames() override {}222};223224}225226#endif227228229230