brintos

brintos / llvm-project-archived public Read only

0
0
Text · 5.6 KiB · 5fe9993 Raw
166 lines · cpp
1//= AArch64WinCOFFObjectWriter.cpp - AArch64 Windows COFF Object Writer 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#include "AArch64MCTargetDesc.h"10#include "MCTargetDesc/AArch64FixupKinds.h"11#include "MCTargetDesc/AArch64MCAsmInfo.h"12#include "llvm/ADT/Twine.h"13#include "llvm/BinaryFormat/COFF.h"14#include "llvm/MC/MCAsmBackend.h"15#include "llvm/MC/MCContext.h"16#include "llvm/MC/MCExpr.h"17#include "llvm/MC/MCFixup.h"18#include "llvm/MC/MCObjectWriter.h"19#include "llvm/MC/MCValue.h"20#include "llvm/MC/MCWinCOFFObjectWriter.h"21#include "llvm/Support/Casting.h"22#include "llvm/Support/ErrorHandling.h"23#include <cassert>24 25using namespace llvm;26 27namespace {28 29class AArch64WinCOFFObjectWriter : public MCWinCOFFObjectTargetWriter {30public:31  AArch64WinCOFFObjectWriter(const Triple &TheTriple)32      : MCWinCOFFObjectTargetWriter(TheTriple.isWindowsArm64EC()33                                        ? COFF::IMAGE_FILE_MACHINE_ARM64EC34                                        : COFF::IMAGE_FILE_MACHINE_ARM64) {}35 36  ~AArch64WinCOFFObjectWriter() override = default;37 38  unsigned getRelocType(MCContext &Ctx, const MCValue &Target,39                        const MCFixup &Fixup, bool IsCrossSection,40                        const MCAsmBackend &MAB) const override;41 42  bool recordRelocation(const MCFixup &) const override;43};44 45} // end anonymous namespace46 47unsigned AArch64WinCOFFObjectWriter::getRelocType(48    MCContext &Ctx, const MCValue &Target, const MCFixup &Fixup,49    bool IsCrossSection, const MCAsmBackend &MAB) const {50  unsigned FixupKind = Fixup.getKind();51  bool PCRel = Fixup.isPCRel();52  if (IsCrossSection) {53    // IMAGE_REL_ARM64_REL64 does not exist. We treat FK_Data_8 as FK_PCRel_4 so54    // that .xword a-b can lower to IMAGE_REL_ARM64_REL32. This allows generic55    // instrumentation to not bother with the COFF limitation. A negative value56    // needs attention.57    if (PCRel || (FixupKind != FK_Data_4 && FixupKind != FK_Data_8)) {58      Ctx.reportError(Fixup.getLoc(), "Cannot represent this expression");59      return COFF::IMAGE_REL_ARM64_ADDR32;60    }61    FixupKind = FK_Data_4;62    PCRel = true;63  }64 65  auto Spec = Target.getSpecifier();66  const MCExpr *Expr = Fixup.getValue();67 68  if (auto *A64E = dyn_cast<MCSpecifierExpr>(Expr)) {69    AArch64::Specifier Spec = A64E->getSpecifier();70    switch (AArch64::getSymbolLoc(Spec)) {71    case AArch64::S_ABS:72    case AArch64::S_SECREL:73      // Supported74      break;75    default:76      Ctx.reportError(Fixup.getLoc(),77                      "relocation specifier " +78                          AArch64::getSpecifierName(A64E->getSpecifier()) +79                          " unsupported on COFF targets");80      return COFF::IMAGE_REL_ARM64_ABSOLUTE; // Dummy return value81    }82  }83 84  switch (FixupKind) {85  default: {86    if (auto *A64E = dyn_cast<MCSpecifierExpr>(Expr)) {87      Ctx.reportError(Fixup.getLoc(),88                      "relocation specifier " +89                          AArch64::getSpecifierName(A64E->getSpecifier()) +90                          " unsupported on COFF targets");91    } else {92      MCFixupKindInfo Info = MAB.getFixupKindInfo(Fixup.getKind());93      Ctx.reportError(Fixup.getLoc(), Twine("relocation type ") + Info.Name +94                                          " unsupported on COFF targets");95    }96    return COFF::IMAGE_REL_ARM64_ABSOLUTE; // Dummy return value97  }98 99  case FK_Data_4:100    if (PCRel)101      return COFF::IMAGE_REL_ARM64_REL32;102    switch (Spec) {103    default:104      return COFF::IMAGE_REL_ARM64_ADDR32;105    case MCSymbolRefExpr::VK_COFF_IMGREL32:106      return COFF::IMAGE_REL_ARM64_ADDR32NB;107    }108 109  case FK_Data_8:110    return COFF::IMAGE_REL_ARM64_ADDR64;111 112  case FK_SecRel_2:113    return COFF::IMAGE_REL_ARM64_SECTION;114 115  case FK_SecRel_4:116    return COFF::IMAGE_REL_ARM64_SECREL;117 118  case AArch64::fixup_aarch64_add_imm12:119    if (auto *A64E = dyn_cast<MCSpecifierExpr>(Expr)) {120      AArch64::Specifier Spec = A64E->getSpecifier();121      if (Spec == AArch64::S_SECREL_LO12)122        return COFF::IMAGE_REL_ARM64_SECREL_LOW12A;123      if (Spec == AArch64::S_SECREL_HI12)124        return COFF::IMAGE_REL_ARM64_SECREL_HIGH12A;125    }126    return COFF::IMAGE_REL_ARM64_PAGEOFFSET_12A;127 128  case AArch64::fixup_aarch64_ldst_imm12_scale1:129  case AArch64::fixup_aarch64_ldst_imm12_scale2:130  case AArch64::fixup_aarch64_ldst_imm12_scale4:131  case AArch64::fixup_aarch64_ldst_imm12_scale8:132  case AArch64::fixup_aarch64_ldst_imm12_scale16:133    if (auto *A64E = dyn_cast<MCSpecifierExpr>(Expr)) {134      AArch64::Specifier Spec = A64E->getSpecifier();135      if (Spec == AArch64::S_SECREL_LO12)136        return COFF::IMAGE_REL_ARM64_SECREL_LOW12L;137    }138    return COFF::IMAGE_REL_ARM64_PAGEOFFSET_12L;139 140  case AArch64::fixup_aarch64_pcrel_adr_imm21:141    return COFF::IMAGE_REL_ARM64_REL21;142 143  case AArch64::fixup_aarch64_pcrel_adrp_imm21:144    return COFF::IMAGE_REL_ARM64_PAGEBASE_REL21;145 146  case AArch64::fixup_aarch64_pcrel_branch14:147    return COFF::IMAGE_REL_ARM64_BRANCH14;148 149  case AArch64::fixup_aarch64_pcrel_branch19:150    return COFF::IMAGE_REL_ARM64_BRANCH19;151 152  case AArch64::fixup_aarch64_pcrel_branch26:153  case AArch64::fixup_aarch64_pcrel_call26:154    return COFF::IMAGE_REL_ARM64_BRANCH26;155  }156}157 158bool AArch64WinCOFFObjectWriter::recordRelocation(const MCFixup &Fixup) const {159  return true;160}161 162std::unique_ptr<MCObjectTargetWriter>163llvm::createAArch64WinCOFFObjectWriter(const Triple &TheTriple) {164  return std::make_unique<AArch64WinCOFFObjectWriter>(TheTriple);165}166