xref: /openbsd-src/gnu/llvm/llvm/lib/Target/ARM/MCTargetDesc/ARMELFObjectWriter.cpp (revision d415bd752c734aee168c4ee86ff32e8cc249eb16)
109467b48Spatrick //===-- ARMELFObjectWriter.cpp - ARM ELF Writer ---------------------------===//
209467b48Spatrick //
309467b48Spatrick // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
409467b48Spatrick // See https://llvm.org/LICENSE.txt for license information.
509467b48Spatrick // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
609467b48Spatrick //
709467b48Spatrick //===----------------------------------------------------------------------===//
809467b48Spatrick 
909467b48Spatrick #include "MCTargetDesc/ARMFixupKinds.h"
1009467b48Spatrick #include "MCTargetDesc/ARMMCTargetDesc.h"
1109467b48Spatrick #include "llvm/BinaryFormat/ELF.h"
1209467b48Spatrick #include "llvm/MC/MCContext.h"
1309467b48Spatrick #include "llvm/MC/MCELFObjectWriter.h"
1409467b48Spatrick #include "llvm/MC/MCExpr.h"
1509467b48Spatrick #include "llvm/MC/MCFixup.h"
1609467b48Spatrick #include "llvm/MC/MCObjectFileInfo.h"
1709467b48Spatrick #include "llvm/MC/MCObjectWriter.h"
1809467b48Spatrick #include "llvm/MC/MCValue.h"
1909467b48Spatrick #include "llvm/Support/ErrorHandling.h"
2009467b48Spatrick #include "llvm/Support/raw_ostream.h"
2109467b48Spatrick #include <cstdint>
2209467b48Spatrick 
2309467b48Spatrick using namespace llvm;
2409467b48Spatrick 
2509467b48Spatrick namespace {
2609467b48Spatrick 
2709467b48Spatrick   class ARMELFObjectWriter : public MCELFObjectTargetWriter {
2809467b48Spatrick     enum { DefaultEABIVersion = 0x05000000U };
2909467b48Spatrick 
3009467b48Spatrick     unsigned GetRelocTypeInner(const MCValue &Target, const MCFixup &Fixup,
3109467b48Spatrick                                bool IsPCRel, MCContext &Ctx) const;
3209467b48Spatrick 
3309467b48Spatrick   public:
3409467b48Spatrick     ARMELFObjectWriter(uint8_t OSABI);
3509467b48Spatrick 
3609467b48Spatrick     ~ARMELFObjectWriter() override = default;
3709467b48Spatrick 
3809467b48Spatrick     unsigned getRelocType(MCContext &Ctx, const MCValue &Target,
3909467b48Spatrick                           const MCFixup &Fixup, bool IsPCRel) const override;
4009467b48Spatrick 
4109467b48Spatrick     bool needsRelocateWithSymbol(const MCSymbol &Sym,
4209467b48Spatrick                                  unsigned Type) const override;
4309467b48Spatrick 
4409467b48Spatrick     void addTargetSectionFlags(MCContext &Ctx, MCSectionELF &Sec) override;
4509467b48Spatrick   };
4609467b48Spatrick 
4709467b48Spatrick } // end anonymous namespace
4809467b48Spatrick 
ARMELFObjectWriter(uint8_t OSABI)4909467b48Spatrick ARMELFObjectWriter::ARMELFObjectWriter(uint8_t OSABI)
5009467b48Spatrick   : MCELFObjectTargetWriter(/*Is64Bit*/ false, OSABI,
5109467b48Spatrick                             ELF::EM_ARM,
5209467b48Spatrick                             /*HasRelocationAddend*/ false) {}
5309467b48Spatrick 
needsRelocateWithSymbol(const MCSymbol & Sym,unsigned Type) const5409467b48Spatrick bool ARMELFObjectWriter::needsRelocateWithSymbol(const MCSymbol &Sym,
5509467b48Spatrick                                                  unsigned Type) const {
56097a140dSpatrick   // FIXME: This is extremely conservative. This really needs to use an
57097a140dSpatrick   // explicit list with a clear explanation for why each realocation needs to
5809467b48Spatrick   // point to the symbol, not to the section.
5909467b48Spatrick   switch (Type) {
6009467b48Spatrick   default:
6109467b48Spatrick     return true;
6209467b48Spatrick 
6309467b48Spatrick   case ELF::R_ARM_PREL31:
6409467b48Spatrick   case ELF::R_ARM_ABS32:
6509467b48Spatrick     return false;
6609467b48Spatrick   }
6709467b48Spatrick }
6809467b48Spatrick 
6909467b48Spatrick // Need to examine the Fixup when determining whether to
7009467b48Spatrick // emit the relocation as an explicit symbol or as a section relative
7109467b48Spatrick // offset
getRelocType(MCContext & Ctx,const MCValue & Target,const MCFixup & Fixup,bool IsPCRel) const7209467b48Spatrick unsigned ARMELFObjectWriter::getRelocType(MCContext &Ctx, const MCValue &Target,
7309467b48Spatrick                                           const MCFixup &Fixup,
7409467b48Spatrick                                           bool IsPCRel) const {
7509467b48Spatrick   return GetRelocTypeInner(Target, Fixup, IsPCRel, Ctx);
7609467b48Spatrick }
7709467b48Spatrick 
GetRelocTypeInner(const MCValue & Target,const MCFixup & Fixup,bool IsPCRel,MCContext & Ctx) const7809467b48Spatrick unsigned ARMELFObjectWriter::GetRelocTypeInner(const MCValue &Target,
7909467b48Spatrick                                                const MCFixup &Fixup,
8009467b48Spatrick                                                bool IsPCRel,
8109467b48Spatrick                                                MCContext &Ctx) const {
82097a140dSpatrick   unsigned Kind = Fixup.getTargetKind();
83097a140dSpatrick   if (Kind >= FirstLiteralRelocationKind)
84097a140dSpatrick     return Kind - FirstLiteralRelocationKind;
8509467b48Spatrick   MCSymbolRefExpr::VariantKind Modifier = Target.getAccessVariant();
8609467b48Spatrick 
8709467b48Spatrick   if (IsPCRel) {
8809467b48Spatrick     switch (Fixup.getTargetKind()) {
8909467b48Spatrick     default:
90*d415bd75Srobert       Ctx.reportError(Fixup.getLoc(), "unsupported relocation on symbol");
9109467b48Spatrick       return ELF::R_ARM_NONE;
9209467b48Spatrick     case FK_Data_4:
9309467b48Spatrick       switch (Modifier) {
9409467b48Spatrick       default:
95097a140dSpatrick         Ctx.reportError(Fixup.getLoc(),
96097a140dSpatrick                         "invalid fixup for 4-byte pc-relative data relocation");
97097a140dSpatrick         return ELF::R_ARM_NONE;
98097a140dSpatrick       case MCSymbolRefExpr::VK_None: {
99097a140dSpatrick         if (const MCSymbolRefExpr *SymRef = Target.getSymA()) {
100097a140dSpatrick           // For GNU AS compatibility expressions such as
101097a140dSpatrick           // _GLOBAL_OFFSET_TABLE_ - label emit a R_ARM_BASE_PREL relocation.
102097a140dSpatrick           if (SymRef->getSymbol().getName() == "_GLOBAL_OFFSET_TABLE_")
103097a140dSpatrick             return ELF::R_ARM_BASE_PREL;
104097a140dSpatrick         }
10509467b48Spatrick         return ELF::R_ARM_REL32;
106097a140dSpatrick       }
10709467b48Spatrick       case MCSymbolRefExpr::VK_GOTTPOFF:
10809467b48Spatrick         return ELF::R_ARM_TLS_IE32;
10909467b48Spatrick       case MCSymbolRefExpr::VK_ARM_GOT_PREL:
11009467b48Spatrick         return ELF::R_ARM_GOT_PREL;
11109467b48Spatrick       case MCSymbolRefExpr::VK_ARM_PREL31:
11209467b48Spatrick         return ELF::R_ARM_PREL31;
11309467b48Spatrick       }
11409467b48Spatrick     case ARM::fixup_arm_blx:
11509467b48Spatrick     case ARM::fixup_arm_uncondbl:
11609467b48Spatrick       switch (Modifier) {
11709467b48Spatrick       case MCSymbolRefExpr::VK_PLT:
11809467b48Spatrick         return ELF::R_ARM_CALL;
11909467b48Spatrick       case MCSymbolRefExpr::VK_TLSCALL:
12009467b48Spatrick         return ELF::R_ARM_TLS_CALL;
12109467b48Spatrick       default:
12209467b48Spatrick         return ELF::R_ARM_CALL;
12309467b48Spatrick       }
12409467b48Spatrick     case ARM::fixup_arm_condbl:
12509467b48Spatrick     case ARM::fixup_arm_condbranch:
12609467b48Spatrick     case ARM::fixup_arm_uncondbranch:
12709467b48Spatrick       return ELF::R_ARM_JUMP24;
12809467b48Spatrick     case ARM::fixup_t2_condbranch:
12909467b48Spatrick       return ELF::R_ARM_THM_JUMP19;
13009467b48Spatrick     case ARM::fixup_t2_uncondbranch:
13109467b48Spatrick       return ELF::R_ARM_THM_JUMP24;
13209467b48Spatrick     case ARM::fixup_arm_movt_hi16:
13309467b48Spatrick       return ELF::R_ARM_MOVT_PREL;
13409467b48Spatrick     case ARM::fixup_arm_movw_lo16:
13509467b48Spatrick       return ELF::R_ARM_MOVW_PREL_NC;
13609467b48Spatrick     case ARM::fixup_t2_movt_hi16:
13709467b48Spatrick       return ELF::R_ARM_THM_MOVT_PREL;
13809467b48Spatrick     case ARM::fixup_t2_movw_lo16:
13909467b48Spatrick       return ELF::R_ARM_THM_MOVW_PREL_NC;
14009467b48Spatrick     case ARM::fixup_arm_thumb_br:
14109467b48Spatrick       return ELF::R_ARM_THM_JUMP11;
14209467b48Spatrick     case ARM::fixup_arm_thumb_bcc:
14309467b48Spatrick       return ELF::R_ARM_THM_JUMP8;
14409467b48Spatrick     case ARM::fixup_arm_thumb_bl:
14509467b48Spatrick     case ARM::fixup_arm_thumb_blx:
14609467b48Spatrick       switch (Modifier) {
14709467b48Spatrick       case MCSymbolRefExpr::VK_TLSCALL:
14809467b48Spatrick         return ELF::R_ARM_THM_TLS_CALL;
14909467b48Spatrick       default:
15009467b48Spatrick         return ELF::R_ARM_THM_CALL;
15109467b48Spatrick       }
15209467b48Spatrick     case ARM::fixup_bf_target:
15309467b48Spatrick       return ELF::R_ARM_THM_BF16;
15409467b48Spatrick     case ARM::fixup_bfc_target:
15509467b48Spatrick       return ELF::R_ARM_THM_BF12;
15609467b48Spatrick     case ARM::fixup_bfl_target:
15709467b48Spatrick       return ELF::R_ARM_THM_BF18;
15809467b48Spatrick     }
15909467b48Spatrick   }
160097a140dSpatrick   switch (Kind) {
16109467b48Spatrick   default:
162*d415bd75Srobert     Ctx.reportError(Fixup.getLoc(), "unsupported relocation on symbol");
16309467b48Spatrick     return ELF::R_ARM_NONE;
16409467b48Spatrick   case FK_Data_1:
16509467b48Spatrick     switch (Modifier) {
16609467b48Spatrick     default:
167097a140dSpatrick       Ctx.reportError(Fixup.getLoc(),
168097a140dSpatrick                       "invalid fixup for 1-byte data relocation");
169097a140dSpatrick       return ELF::R_ARM_NONE;
17009467b48Spatrick     case MCSymbolRefExpr::VK_None:
17109467b48Spatrick       return ELF::R_ARM_ABS8;
17209467b48Spatrick     }
17309467b48Spatrick   case FK_Data_2:
17409467b48Spatrick     switch (Modifier) {
17509467b48Spatrick     default:
176097a140dSpatrick       Ctx.reportError(Fixup.getLoc(),
177097a140dSpatrick                       "invalid fixup for 2-byte data relocation");
178097a140dSpatrick       return ELF::R_ARM_NONE;
17909467b48Spatrick     case MCSymbolRefExpr::VK_None:
18009467b48Spatrick       return ELF::R_ARM_ABS16;
18109467b48Spatrick     }
18209467b48Spatrick   case FK_Data_4:
18309467b48Spatrick     switch (Modifier) {
18409467b48Spatrick     default:
185097a140dSpatrick       Ctx.reportError(Fixup.getLoc(),
186097a140dSpatrick                       "invalid fixup for 4-byte data relocation");
187097a140dSpatrick       return ELF::R_ARM_NONE;
18809467b48Spatrick     case MCSymbolRefExpr::VK_ARM_NONE:
18909467b48Spatrick       return ELF::R_ARM_NONE;
19009467b48Spatrick     case MCSymbolRefExpr::VK_GOT:
19109467b48Spatrick       return ELF::R_ARM_GOT_BREL;
19209467b48Spatrick     case MCSymbolRefExpr::VK_TLSGD:
19309467b48Spatrick       return ELF::R_ARM_TLS_GD32;
19409467b48Spatrick     case MCSymbolRefExpr::VK_TPOFF:
19509467b48Spatrick       return ELF::R_ARM_TLS_LE32;
19609467b48Spatrick     case MCSymbolRefExpr::VK_GOTTPOFF:
19709467b48Spatrick       return ELF::R_ARM_TLS_IE32;
19809467b48Spatrick     case MCSymbolRefExpr::VK_None:
19909467b48Spatrick       return ELF::R_ARM_ABS32;
20009467b48Spatrick     case MCSymbolRefExpr::VK_GOTOFF:
20109467b48Spatrick       return ELF::R_ARM_GOTOFF32;
20209467b48Spatrick     case MCSymbolRefExpr::VK_ARM_GOT_PREL:
20309467b48Spatrick       return ELF::R_ARM_GOT_PREL;
20409467b48Spatrick     case MCSymbolRefExpr::VK_ARM_TARGET1:
20509467b48Spatrick       return ELF::R_ARM_TARGET1;
20609467b48Spatrick     case MCSymbolRefExpr::VK_ARM_TARGET2:
20709467b48Spatrick       return ELF::R_ARM_TARGET2;
20809467b48Spatrick     case MCSymbolRefExpr::VK_ARM_PREL31:
20909467b48Spatrick       return ELF::R_ARM_PREL31;
21009467b48Spatrick     case MCSymbolRefExpr::VK_ARM_SBREL:
21109467b48Spatrick       return ELF::R_ARM_SBREL32;
21209467b48Spatrick     case MCSymbolRefExpr::VK_ARM_TLSLDO:
21309467b48Spatrick       return ELF::R_ARM_TLS_LDO32;
21409467b48Spatrick     case MCSymbolRefExpr::VK_TLSCALL:
21509467b48Spatrick       return ELF::R_ARM_TLS_CALL;
21609467b48Spatrick     case MCSymbolRefExpr::VK_TLSDESC:
21709467b48Spatrick       return ELF::R_ARM_TLS_GOTDESC;
21809467b48Spatrick     case MCSymbolRefExpr::VK_TLSLDM:
21909467b48Spatrick       return ELF::R_ARM_TLS_LDM32;
22009467b48Spatrick     case MCSymbolRefExpr::VK_ARM_TLSDESCSEQ:
22109467b48Spatrick       return ELF::R_ARM_TLS_DESCSEQ;
22209467b48Spatrick     }
22309467b48Spatrick   case ARM::fixup_arm_condbranch:
22409467b48Spatrick   case ARM::fixup_arm_uncondbranch:
22509467b48Spatrick     return ELF::R_ARM_JUMP24;
22609467b48Spatrick   case ARM::fixup_arm_movt_hi16:
22709467b48Spatrick     switch (Modifier) {
22809467b48Spatrick     default:
229097a140dSpatrick       Ctx.reportError(Fixup.getLoc(), "invalid fixup for ARM MOVT instruction");
230097a140dSpatrick       return ELF::R_ARM_NONE;
23109467b48Spatrick     case MCSymbolRefExpr::VK_None:
23209467b48Spatrick       return ELF::R_ARM_MOVT_ABS;
23309467b48Spatrick     case MCSymbolRefExpr::VK_ARM_SBREL:
23409467b48Spatrick       return ELF::R_ARM_MOVT_BREL;
23509467b48Spatrick     }
23609467b48Spatrick   case ARM::fixup_arm_movw_lo16:
23709467b48Spatrick     switch (Modifier) {
23809467b48Spatrick     default:
239097a140dSpatrick       Ctx.reportError(Fixup.getLoc(), "invalid fixup for ARM MOVW instruction");
240097a140dSpatrick       return ELF::R_ARM_NONE;
24109467b48Spatrick     case MCSymbolRefExpr::VK_None:
24209467b48Spatrick       return ELF::R_ARM_MOVW_ABS_NC;
24309467b48Spatrick     case MCSymbolRefExpr::VK_ARM_SBREL:
24409467b48Spatrick       return ELF::R_ARM_MOVW_BREL_NC;
24509467b48Spatrick     }
24609467b48Spatrick   case ARM::fixup_t2_movt_hi16:
24709467b48Spatrick     switch (Modifier) {
24809467b48Spatrick     default:
249097a140dSpatrick       Ctx.reportError(Fixup.getLoc(),
250097a140dSpatrick                       "invalid fixup for Thumb MOVT instruction");
251097a140dSpatrick       return ELF::R_ARM_NONE;
25209467b48Spatrick     case MCSymbolRefExpr::VK_None:
25309467b48Spatrick       return ELF::R_ARM_THM_MOVT_ABS;
25409467b48Spatrick     case MCSymbolRefExpr::VK_ARM_SBREL:
25509467b48Spatrick       return ELF::R_ARM_THM_MOVT_BREL;
25609467b48Spatrick     }
25709467b48Spatrick   case ARM::fixup_t2_movw_lo16:
25809467b48Spatrick     switch (Modifier) {
25909467b48Spatrick     default:
260097a140dSpatrick       Ctx.reportError(Fixup.getLoc(),
261097a140dSpatrick                       "invalid fixup for Thumb MOVW instruction");
262097a140dSpatrick       return ELF::R_ARM_NONE;
26309467b48Spatrick     case MCSymbolRefExpr::VK_None:
26409467b48Spatrick       return ELF::R_ARM_THM_MOVW_ABS_NC;
26509467b48Spatrick     case MCSymbolRefExpr::VK_ARM_SBREL:
26609467b48Spatrick       return ELF::R_ARM_THM_MOVW_BREL_NC;
26709467b48Spatrick     }
26809467b48Spatrick   }
26909467b48Spatrick }
27009467b48Spatrick 
addTargetSectionFlags(MCContext & Ctx,MCSectionELF & Sec)27109467b48Spatrick void ARMELFObjectWriter::addTargetSectionFlags(MCContext &Ctx,
27209467b48Spatrick                                                MCSectionELF &Sec) {
27309467b48Spatrick   // The mix of execute-only and non-execute-only at link time is
27409467b48Spatrick   // non-execute-only. To avoid the empty implicitly created .text
27509467b48Spatrick   // section from making the whole .text section non-execute-only, we
27609467b48Spatrick   // mark it execute-only if it is empty and there is at least one
27709467b48Spatrick   // execute-only section in the object.
27809467b48Spatrick   MCSectionELF *TextSection =
27909467b48Spatrick       static_cast<MCSectionELF *>(Ctx.getObjectFileInfo()->getTextSection());
28009467b48Spatrick   if (Sec.getKind().isExecuteOnly() && !TextSection->hasInstructions()) {
28109467b48Spatrick     for (auto &F : TextSection->getFragmentList())
28209467b48Spatrick       if (auto *DF = dyn_cast<MCDataFragment>(&F))
28309467b48Spatrick         if (!DF->getContents().empty())
28409467b48Spatrick           return;
28509467b48Spatrick     TextSection->setFlags(TextSection->getFlags() | ELF::SHF_ARM_PURECODE);
28609467b48Spatrick   }
28709467b48Spatrick }
28809467b48Spatrick 
28909467b48Spatrick std::unique_ptr<MCObjectTargetWriter>
createARMELFObjectWriter(uint8_t OSABI)29009467b48Spatrick llvm::createARMELFObjectWriter(uint8_t OSABI) {
29109467b48Spatrick   return std::make_unique<ARMELFObjectWriter>(OSABI);
29209467b48Spatrick }
293