106 lines · cpp
1//===-- ARMWinCOFFObjectWriter.cpp - ARM 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 "MCTargetDesc/ARMFixupKinds.h"10#include "MCTargetDesc/ARMMCAsmInfo.h"11#include "llvm/ADT/Twine.h"12#include "llvm/BinaryFormat/COFF.h"13#include "llvm/MC/MCAsmBackend.h"14#include "llvm/MC/MCContext.h"15#include "llvm/MC/MCExpr.h"16#include "llvm/MC/MCFixup.h"17#include "llvm/MC/MCObjectWriter.h"18#include "llvm/MC/MCValue.h"19#include "llvm/MC/MCWinCOFFObjectWriter.h"20#include "llvm/Support/ErrorHandling.h"21 22using namespace llvm;23 24namespace {25 26class ARMWinCOFFObjectWriter : public MCWinCOFFObjectTargetWriter {27public:28 ARMWinCOFFObjectWriter()29 : MCWinCOFFObjectTargetWriter(COFF::IMAGE_FILE_MACHINE_ARMNT) {30 }31 32 ~ARMWinCOFFObjectWriter() override = default;33 34 unsigned getRelocType(MCContext &Ctx, const MCValue &Target,35 const MCFixup &Fixup, bool IsCrossSection,36 const MCAsmBackend &MAB) const override;37 38 bool recordRelocation(const MCFixup &) const override;39};40 41} // end anonymous namespace42 43unsigned ARMWinCOFFObjectWriter::getRelocType(MCContext &Ctx,44 const MCValue &Target,45 const MCFixup &Fixup,46 bool IsCrossSection,47 const MCAsmBackend &MAB) const {48 auto Spec = Target.getSpecifier();49 unsigned FixupKind = Fixup.getKind();50 bool PCRel = false;51 if (IsCrossSection) {52 if (PCRel || FixupKind != FK_Data_4) {53 Ctx.reportError(Fixup.getLoc(), "Cannot represent this expression");54 return COFF::IMAGE_REL_ARM_ADDR32;55 }56 FixupKind = FK_Data_4;57 PCRel = true;58 }59 60 61 switch (FixupKind) {62 default: {63 Ctx.reportError(Fixup.getLoc(), "unsupported relocation type");64 return COFF::IMAGE_REL_ARM_ABSOLUTE;65 }66 case FK_Data_4:67 if (PCRel)68 return COFF::IMAGE_REL_ARM_REL32;69 switch (Spec) {70 case MCSymbolRefExpr::VK_COFF_IMGREL32:71 return COFF::IMAGE_REL_ARM_ADDR32NB;72 case ARM::S_COFF_SECREL:73 return COFF::IMAGE_REL_ARM_SECREL;74 default:75 return COFF::IMAGE_REL_ARM_ADDR32;76 }77 case FK_SecRel_2:78 return COFF::IMAGE_REL_ARM_SECTION;79 case FK_SecRel_4:80 return COFF::IMAGE_REL_ARM_SECREL;81 case ARM::fixup_t2_condbranch:82 return COFF::IMAGE_REL_ARM_BRANCH20T;83 case ARM::fixup_t2_uncondbranch:84 case ARM::fixup_arm_thumb_bl:85 return COFF::IMAGE_REL_ARM_BRANCH24T;86 case ARM::fixup_arm_thumb_blx:87 return COFF::IMAGE_REL_ARM_BLX23T;88 case ARM::fixup_t2_movw_lo16:89 case ARM::fixup_t2_movt_hi16:90 return COFF::IMAGE_REL_ARM_MOV32T;91 }92}93 94bool ARMWinCOFFObjectWriter::recordRelocation(const MCFixup &Fixup) const {95 return static_cast<unsigned>(Fixup.getKind()) != ARM::fixup_t2_movt_hi16;96}97 98namespace llvm {99 100std::unique_ptr<MCObjectTargetWriter>101createARMWinCOFFObjectWriter() {102 return std::make_unique<ARMWinCOFFObjectWriter>();103}104 105} // end namespace llvm106