Path: blob/main/contrib/llvm-project/llvm/lib/Target/X86/MCTargetDesc/X86WinCOFFObjectWriter.cpp
35294 views
//===-- X86WinCOFFObjectWriter.cpp - X86 Win COFF Writer ------------------===//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#include "MCTargetDesc/X86FixupKinds.h"9#include "MCTargetDesc/X86MCTargetDesc.h"10#include "llvm/BinaryFormat/COFF.h"11#include "llvm/MC/MCContext.h"12#include "llvm/MC/MCExpr.h"13#include "llvm/MC/MCFixup.h"14#include "llvm/MC/MCObjectWriter.h"15#include "llvm/MC/MCValue.h"16#include "llvm/MC/MCWinCOFFObjectWriter.h"17#include "llvm/Support/ErrorHandling.h"1819using namespace llvm;2021namespace {2223class X86WinCOFFObjectWriter : public MCWinCOFFObjectTargetWriter {24public:25X86WinCOFFObjectWriter(bool Is64Bit);26~X86WinCOFFObjectWriter() override = default;2728unsigned getRelocType(MCContext &Ctx, const MCValue &Target,29const MCFixup &Fixup, bool IsCrossSection,30const MCAsmBackend &MAB) const override;31};3233} // end anonymous namespace3435X86WinCOFFObjectWriter::X86WinCOFFObjectWriter(bool Is64Bit)36: MCWinCOFFObjectTargetWriter(Is64Bit ? COFF::IMAGE_FILE_MACHINE_AMD6437: COFF::IMAGE_FILE_MACHINE_I386) {}3839unsigned X86WinCOFFObjectWriter::getRelocType(MCContext &Ctx,40const MCValue &Target,41const MCFixup &Fixup,42bool IsCrossSection,43const MCAsmBackend &MAB) const {44const bool Is64Bit = getMachine() == COFF::IMAGE_FILE_MACHINE_AMD64;45unsigned FixupKind = Fixup.getKind();46if (IsCrossSection) {47// IMAGE_REL_AMD64_REL64 does not exist. We treat FK_Data_8 as FK_PCRel_4 so48// that .quad a-b can lower to IMAGE_REL_AMD64_REL32. This allows generic49// instrumentation to not bother with the COFF limitation. A negative value50// needs attention.51if (FixupKind == FK_Data_4 || FixupKind == llvm::X86::reloc_signed_4byte ||52(FixupKind == FK_Data_8 && Is64Bit)) {53FixupKind = FK_PCRel_4;54} else {55Ctx.reportError(Fixup.getLoc(), "Cannot represent this expression");56return COFF::IMAGE_REL_AMD64_ADDR32;57}58}5960MCSymbolRefExpr::VariantKind Modifier = Target.isAbsolute() ?61MCSymbolRefExpr::VK_None : Target.getSymA()->getKind();6263if (Is64Bit) {64switch (FixupKind) {65case FK_PCRel_4:66case X86::reloc_riprel_4byte:67case X86::reloc_riprel_4byte_movq_load:68case X86::reloc_riprel_4byte_relax:69case X86::reloc_riprel_4byte_relax_rex:70case X86::reloc_branch_4byte_pcrel:71return COFF::IMAGE_REL_AMD64_REL32;72case FK_Data_4:73case X86::reloc_signed_4byte:74case X86::reloc_signed_4byte_relax:75if (Modifier == MCSymbolRefExpr::VK_COFF_IMGREL32)76return COFF::IMAGE_REL_AMD64_ADDR32NB;77if (Modifier == MCSymbolRefExpr::VK_SECREL)78return COFF::IMAGE_REL_AMD64_SECREL;79return COFF::IMAGE_REL_AMD64_ADDR32;80case FK_Data_8:81return COFF::IMAGE_REL_AMD64_ADDR64;82case FK_SecRel_2:83return COFF::IMAGE_REL_AMD64_SECTION;84case FK_SecRel_4:85return COFF::IMAGE_REL_AMD64_SECREL;86default:87Ctx.reportError(Fixup.getLoc(), "unsupported relocation type");88return COFF::IMAGE_REL_AMD64_ADDR32;89}90} else if (getMachine() == COFF::IMAGE_FILE_MACHINE_I386) {91switch (FixupKind) {92case FK_PCRel_4:93case X86::reloc_riprel_4byte:94case X86::reloc_riprel_4byte_movq_load:95return COFF::IMAGE_REL_I386_REL32;96case FK_Data_4:97case X86::reloc_signed_4byte:98case X86::reloc_signed_4byte_relax:99if (Modifier == MCSymbolRefExpr::VK_COFF_IMGREL32)100return COFF::IMAGE_REL_I386_DIR32NB;101if (Modifier == MCSymbolRefExpr::VK_SECREL)102return COFF::IMAGE_REL_I386_SECREL;103return COFF::IMAGE_REL_I386_DIR32;104case FK_SecRel_2:105return COFF::IMAGE_REL_I386_SECTION;106case FK_SecRel_4:107return COFF::IMAGE_REL_I386_SECREL;108default:109Ctx.reportError(Fixup.getLoc(), "unsupported relocation type");110return COFF::IMAGE_REL_I386_DIR32;111}112} else113llvm_unreachable("Unsupported COFF machine type.");114}115116std::unique_ptr<MCObjectTargetWriter>117llvm::createX86WinCOFFObjectWriter(bool Is64Bit) {118return std::make_unique<X86WinCOFFObjectWriter>(Is64Bit);119}120121122