brintos

brintos / llvm-project-archived public Read only

0
0
Text · 4.7 KiB · 0bfc0e0 Raw
130 lines · cpp
1//===-- X86WinCOFFObjectWriter.cpp - X86 Win COFF Writer ------------------===//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#include "MCTargetDesc/X86FixupKinds.h"10#include "MCTargetDesc/X86MCAsmInfo.h"11#include "MCTargetDesc/X86MCTargetDesc.h"12#include "llvm/BinaryFormat/COFF.h"13#include "llvm/MC/MCContext.h"14#include "llvm/MC/MCExpr.h"15#include "llvm/MC/MCFixup.h"16#include "llvm/MC/MCObjectWriter.h"17#include "llvm/MC/MCValue.h"18#include "llvm/MC/MCWinCOFFObjectWriter.h"19#include "llvm/Support/ErrorHandling.h"20 21using namespace llvm;22 23namespace {24 25class X86WinCOFFObjectWriter : public MCWinCOFFObjectTargetWriter {26public:27  X86WinCOFFObjectWriter(bool Is64Bit);28  ~X86WinCOFFObjectWriter() override = default;29 30  unsigned getRelocType(MCContext &Ctx, const MCValue &Target,31                        const MCFixup &Fixup, bool IsCrossSection,32                        const MCAsmBackend &MAB) const override;33};34 35} // end anonymous namespace36 37X86WinCOFFObjectWriter::X86WinCOFFObjectWriter(bool Is64Bit)38    : MCWinCOFFObjectTargetWriter(Is64Bit ? COFF::IMAGE_FILE_MACHINE_AMD6439                                          : COFF::IMAGE_FILE_MACHINE_I386) {}40 41unsigned X86WinCOFFObjectWriter::getRelocType(MCContext &Ctx,42                                              const MCValue &Target,43                                              const MCFixup &Fixup,44                                              bool IsCrossSection,45                                              const MCAsmBackend &MAB) const {46  const bool Is64Bit = getMachine() == COFF::IMAGE_FILE_MACHINE_AMD64;47  unsigned FixupKind = Fixup.getKind();48  bool PCRel = Fixup.isPCRel();49  if (IsCrossSection) {50    // IMAGE_REL_AMD64_REL64 does not exist. We treat FK_Data_8 as FK_PCRel_4 so51    // that .quad a-b can lower to IMAGE_REL_AMD64_REL32. This allows generic52    // instrumentation to not bother with the COFF limitation. A negative value53    // needs attention.54    if (!PCRel &&55        (FixupKind == FK_Data_4 || FixupKind == llvm::X86::reloc_signed_4byte ||56         (FixupKind == FK_Data_8 && Is64Bit))) {57      FixupKind = FK_Data_4;58      PCRel = true;59    } else {60      Ctx.reportError(Fixup.getLoc(), "Cannot represent this expression");61      return COFF::IMAGE_REL_AMD64_ADDR32;62    }63  }64 65  auto Spec = Target.getSpecifier();66  if (Is64Bit) {67    switch (FixupKind) {68    case X86::reloc_riprel_4byte:69    case X86::reloc_riprel_4byte_movq_load:70    case X86::reloc_riprel_4byte_movq_load_rex2:71    case X86::reloc_riprel_4byte_relax:72    case X86::reloc_riprel_4byte_relax_rex:73    case X86::reloc_riprel_4byte_relax_rex2:74    case X86::reloc_riprel_4byte_relax_evex:75    case X86::reloc_branch_4byte_pcrel:76      return COFF::IMAGE_REL_AMD64_REL32;77    case FK_Data_4:78      if (PCRel)79        return COFF::IMAGE_REL_AMD64_REL32;80      [[fallthrough]];81    case X86::reloc_signed_4byte:82    case X86::reloc_signed_4byte_relax:83      if (Spec == MCSymbolRefExpr::VK_COFF_IMGREL32)84        return COFF::IMAGE_REL_AMD64_ADDR32NB;85      if (Spec == X86::S_COFF_SECREL)86        return COFF::IMAGE_REL_AMD64_SECREL;87      return COFF::IMAGE_REL_AMD64_ADDR32;88    case FK_Data_8:89      return COFF::IMAGE_REL_AMD64_ADDR64;90    case FK_SecRel_2:91      return COFF::IMAGE_REL_AMD64_SECTION;92    case FK_SecRel_4:93      return COFF::IMAGE_REL_AMD64_SECREL;94    default:95      Ctx.reportError(Fixup.getLoc(), "unsupported relocation type");96      return COFF::IMAGE_REL_AMD64_ADDR32;97    }98  } else if (getMachine() == COFF::IMAGE_FILE_MACHINE_I386) {99    switch (FixupKind) {100    case X86::reloc_riprel_4byte:101    case X86::reloc_riprel_4byte_movq_load:102      return COFF::IMAGE_REL_I386_REL32;103    case FK_Data_4:104      if (PCRel)105        return COFF::IMAGE_REL_I386_REL32;106      [[fallthrough]];107    case X86::reloc_signed_4byte:108    case X86::reloc_signed_4byte_relax:109      if (Spec == MCSymbolRefExpr::VK_COFF_IMGREL32)110        return COFF::IMAGE_REL_I386_DIR32NB;111      if (Spec == X86::S_COFF_SECREL)112        return COFF::IMAGE_REL_I386_SECREL;113      return COFF::IMAGE_REL_I386_DIR32;114    case FK_SecRel_2:115      return COFF::IMAGE_REL_I386_SECTION;116    case FK_SecRel_4:117      return COFF::IMAGE_REL_I386_SECREL;118    default:119      Ctx.reportError(Fixup.getLoc(), "unsupported relocation type");120      return COFF::IMAGE_REL_I386_DIR32;121    }122  } else123    llvm_unreachable("Unsupported COFF machine type.");124}125 126std::unique_ptr<MCObjectTargetWriter>127llvm::createX86WinCOFFObjectWriter(bool Is64Bit) {128  return std::make_unique<X86WinCOFFObjectWriter>(Is64Bit);129}130