LLVM  14.0.0git
ARMELFObjectWriter.cpp
Go to the documentation of this file.
1 //===-- ARMELFObjectWriter.cpp - ARM ELF 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-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
11 #include "llvm/BinaryFormat/ELF.h"
12 #include "llvm/MC/MCContext.h"
14 #include "llvm/MC/MCExpr.h"
15 #include "llvm/MC/MCFixup.h"
17 #include "llvm/MC/MCObjectWriter.h"
18 #include "llvm/MC/MCValue.h"
21 #include <cstdint>
22 
23 using namespace llvm;
24 
25 namespace {
26 
27  class ARMELFObjectWriter : public MCELFObjectTargetWriter {
28  enum { DefaultEABIVersion = 0x05000000U };
29 
30  unsigned GetRelocTypeInner(const MCValue &Target, const MCFixup &Fixup,
31  bool IsPCRel, MCContext &Ctx) const;
32 
33  public:
34  ARMELFObjectWriter(uint8_t OSABI);
35 
36  ~ARMELFObjectWriter() override = default;
37 
38  unsigned getRelocType(MCContext &Ctx, const MCValue &Target,
39  const MCFixup &Fixup, bool IsPCRel) const override;
40 
41  bool needsRelocateWithSymbol(const MCSymbol &Sym,
42  unsigned Type) const override;
43 
44  void addTargetSectionFlags(MCContext &Ctx, MCSectionELF &Sec) override;
45  };
46 
47 } // end anonymous namespace
48 
49 ARMELFObjectWriter::ARMELFObjectWriter(uint8_t OSABI)
50  : MCELFObjectTargetWriter(/*Is64Bit*/ false, OSABI,
51  ELF::EM_ARM,
52  /*HasRelocationAddend*/ false) {}
53 
54 bool ARMELFObjectWriter::needsRelocateWithSymbol(const MCSymbol &Sym,
55  unsigned Type) const {
56  // FIXME: This is extremely conservative. This really needs to use an
57  // explicit list with a clear explanation for why each realocation needs to
58  // point to the symbol, not to the section.
59  switch (Type) {
60  default:
61  return true;
62 
63  case ELF::R_ARM_PREL31:
64  case ELF::R_ARM_ABS32:
65  return false;
66  }
67 }
68 
69 // Need to examine the Fixup when determining whether to
70 // emit the relocation as an explicit symbol or as a section relative
71 // offset
72 unsigned ARMELFObjectWriter::getRelocType(MCContext &Ctx, const MCValue &Target,
73  const MCFixup &Fixup,
74  bool IsPCRel) const {
75  return GetRelocTypeInner(Target, Fixup, IsPCRel, Ctx);
76 }
77 
78 unsigned ARMELFObjectWriter::GetRelocTypeInner(const MCValue &Target,
79  const MCFixup &Fixup,
80  bool IsPCRel,
81  MCContext &Ctx) const {
82  unsigned Kind = Fixup.getTargetKind();
85  MCSymbolRefExpr::VariantKind Modifier = Target.getAccessVariant();
86 
87  if (IsPCRel) {
88  switch (Fixup.getTargetKind()) {
89  default:
90  Ctx.reportFatalError(Fixup.getLoc(), "unsupported relocation on symbol");
91  return ELF::R_ARM_NONE;
92  case FK_Data_4:
93  switch (Modifier) {
94  default:
95  Ctx.reportError(Fixup.getLoc(),
96  "invalid fixup for 4-byte pc-relative data relocation");
97  return ELF::R_ARM_NONE;
98  case MCSymbolRefExpr::VK_None: {
99  if (const MCSymbolRefExpr *SymRef = Target.getSymA()) {
100  // For GNU AS compatibility expressions such as
101  // _GLOBAL_OFFSET_TABLE_ - label emit a R_ARM_BASE_PREL relocation.
102  if (SymRef->getSymbol().getName() == "_GLOBAL_OFFSET_TABLE_")
103  return ELF::R_ARM_BASE_PREL;
104  }
105  return ELF::R_ARM_REL32;
106  }
107  case MCSymbolRefExpr::VK_GOTTPOFF:
108  return ELF::R_ARM_TLS_IE32;
109  case MCSymbolRefExpr::VK_ARM_GOT_PREL:
110  return ELF::R_ARM_GOT_PREL;
111  case MCSymbolRefExpr::VK_ARM_PREL31:
112  return ELF::R_ARM_PREL31;
113  }
114  case ARM::fixup_arm_blx:
116  switch (Modifier) {
117  case MCSymbolRefExpr::VK_PLT:
118  return ELF::R_ARM_CALL;
119  case MCSymbolRefExpr::VK_TLSCALL:
120  return ELF::R_ARM_TLS_CALL;
121  default:
122  return ELF::R_ARM_CALL;
123  }
127  return ELF::R_ARM_JUMP24;
129  return ELF::R_ARM_THM_JUMP19;
131  return ELF::R_ARM_THM_JUMP24;
133  return ELF::R_ARM_MOVT_PREL;
135  return ELF::R_ARM_MOVW_PREL_NC;
137  return ELF::R_ARM_THM_MOVT_PREL;
139  return ELF::R_ARM_THM_MOVW_PREL_NC;
141  return ELF::R_ARM_THM_JUMP11;
143  return ELF::R_ARM_THM_JUMP8;
146  switch (Modifier) {
147  case MCSymbolRefExpr::VK_TLSCALL:
148  return ELF::R_ARM_THM_TLS_CALL;
149  default:
150  return ELF::R_ARM_THM_CALL;
151  }
153  return ELF::R_ARM_THM_BF16;
155  return ELF::R_ARM_THM_BF12;
157  return ELF::R_ARM_THM_BF18;
158  }
159  }
160  switch (Kind) {
161  default:
162  Ctx.reportFatalError(Fixup.getLoc(), "unsupported relocation on symbol");
163  return ELF::R_ARM_NONE;
164  case FK_Data_1:
165  switch (Modifier) {
166  default:
167  Ctx.reportError(Fixup.getLoc(),
168  "invalid fixup for 1-byte data relocation");
169  return ELF::R_ARM_NONE;
170  case MCSymbolRefExpr::VK_None:
171  return ELF::R_ARM_ABS8;
172  }
173  case FK_Data_2:
174  switch (Modifier) {
175  default:
176  Ctx.reportError(Fixup.getLoc(),
177  "invalid fixup for 2-byte data relocation");
178  return ELF::R_ARM_NONE;
179  case MCSymbolRefExpr::VK_None:
180  return ELF::R_ARM_ABS16;
181  }
182  case FK_Data_4:
183  switch (Modifier) {
184  default:
185  Ctx.reportError(Fixup.getLoc(),
186  "invalid fixup for 4-byte data relocation");
187  return ELF::R_ARM_NONE;
188  case MCSymbolRefExpr::VK_ARM_NONE:
189  return ELF::R_ARM_NONE;
190  case MCSymbolRefExpr::VK_GOT:
191  return ELF::R_ARM_GOT_BREL;
192  case MCSymbolRefExpr::VK_TLSGD:
193  return ELF::R_ARM_TLS_GD32;
194  case MCSymbolRefExpr::VK_TPOFF:
195  return ELF::R_ARM_TLS_LE32;
196  case MCSymbolRefExpr::VK_GOTTPOFF:
197  return ELF::R_ARM_TLS_IE32;
198  case MCSymbolRefExpr::VK_None:
199  return ELF::R_ARM_ABS32;
200  case MCSymbolRefExpr::VK_GOTOFF:
201  return ELF::R_ARM_GOTOFF32;
202  case MCSymbolRefExpr::VK_ARM_GOT_PREL:
203  return ELF::R_ARM_GOT_PREL;
204  case MCSymbolRefExpr::VK_ARM_TARGET1:
205  return ELF::R_ARM_TARGET1;
206  case MCSymbolRefExpr::VK_ARM_TARGET2:
207  return ELF::R_ARM_TARGET2;
208  case MCSymbolRefExpr::VK_ARM_PREL31:
209  return ELF::R_ARM_PREL31;
210  case MCSymbolRefExpr::VK_ARM_SBREL:
211  return ELF::R_ARM_SBREL32;
212  case MCSymbolRefExpr::VK_ARM_TLSLDO:
213  return ELF::R_ARM_TLS_LDO32;
214  case MCSymbolRefExpr::VK_TLSCALL:
215  return ELF::R_ARM_TLS_CALL;
216  case MCSymbolRefExpr::VK_TLSDESC:
217  return ELF::R_ARM_TLS_GOTDESC;
218  case MCSymbolRefExpr::VK_TLSLDM:
219  return ELF::R_ARM_TLS_LDM32;
220  case MCSymbolRefExpr::VK_ARM_TLSDESCSEQ:
221  return ELF::R_ARM_TLS_DESCSEQ;
222  }
225  return ELF::R_ARM_JUMP24;
227  switch (Modifier) {
228  default:
229  Ctx.reportError(Fixup.getLoc(), "invalid fixup for ARM MOVT instruction");
230  return ELF::R_ARM_NONE;
231  case MCSymbolRefExpr::VK_None:
232  return ELF::R_ARM_MOVT_ABS;
233  case MCSymbolRefExpr::VK_ARM_SBREL:
234  return ELF::R_ARM_MOVT_BREL;
235  }
237  switch (Modifier) {
238  default:
239  Ctx.reportError(Fixup.getLoc(), "invalid fixup for ARM MOVW instruction");
240  return ELF::R_ARM_NONE;
241  case MCSymbolRefExpr::VK_None:
242  return ELF::R_ARM_MOVW_ABS_NC;
243  case MCSymbolRefExpr::VK_ARM_SBREL:
244  return ELF::R_ARM_MOVW_BREL_NC;
245  }
247  switch (Modifier) {
248  default:
249  Ctx.reportError(Fixup.getLoc(),
250  "invalid fixup for Thumb MOVT instruction");
251  return ELF::R_ARM_NONE;
252  case MCSymbolRefExpr::VK_None:
253  return ELF::R_ARM_THM_MOVT_ABS;
254  case MCSymbolRefExpr::VK_ARM_SBREL:
255  return ELF::R_ARM_THM_MOVT_BREL;
256  }
258  switch (Modifier) {
259  default:
260  Ctx.reportError(Fixup.getLoc(),
261  "invalid fixup for Thumb MOVW instruction");
262  return ELF::R_ARM_NONE;
263  case MCSymbolRefExpr::VK_None:
264  return ELF::R_ARM_THM_MOVW_ABS_NC;
265  case MCSymbolRefExpr::VK_ARM_SBREL:
266  return ELF::R_ARM_THM_MOVW_BREL_NC;
267  }
268  }
269 }
270 
271 void ARMELFObjectWriter::addTargetSectionFlags(MCContext &Ctx,
272  MCSectionELF &Sec) {
273  // The mix of execute-only and non-execute-only at link time is
274  // non-execute-only. To avoid the empty implicitly created .text
275  // section from making the whole .text section non-execute-only, we
276  // mark it execute-only if it is empty and there is at least one
277  // execute-only section in the object.
278  MCSectionELF *TextSection =
279  static_cast<MCSectionELF *>(Ctx.getObjectFileInfo()->getTextSection());
280  if (Sec.getKind().isExecuteOnly() && !TextSection->hasInstructions()) {
281  for (auto &F : TextSection->getFragmentList())
282  if (auto *DF = dyn_cast<MCDataFragment>(&F))
283  if (!DF->getContents().empty())
284  return;
285  TextSection->setFlags(TextSection->getFlags() | ELF::SHF_ARM_PURECODE);
286  }
287 }
288 
289 std::unique_ptr<MCObjectTargetWriter>
291  return std::make_unique<ARMELFObjectWriter>(OSABI);
292 }
llvm::MCContext::getObjectFileInfo
const MCObjectFileInfo * getObjectFileInfo() const
Definition: MCContext.h:427
llvm
---------------------— PointerInfo ------------------------------------—
Definition: AllocatorList.h:23
llvm::MCSymbol
MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...
Definition: MCSymbol.h:41
ARMMCTargetDesc.h
llvm::ELF::EM_ARM
@ EM_ARM
Definition: ELF.h:157
llvm::MCContext
Context object for machine code objects.
Definition: MCContext.h:72
llvm::Target
Target - Wrapper for Target specific information.
Definition: TargetRegistry.h:137
ErrorHandling.h
MCObjectFileInfo.h
llvm::Type
The instances of the Type class are immutable: once they are created, they are never changed.
Definition: Type.h:45
llvm::ARM::fixup_bfl_target
@ fixup_bfl_target
Definition: ARMFixupKinds.h:111
llvm::MCSectionELF
This represents a section on linux, lots of unix variants and some bare metal systems.
Definition: MCSectionELF.h:28
llvm::ARM::fixup_arm_movt_hi16
@ fixup_arm_movt_hi16
Definition: ARMFixupKinds.h:97
llvm::MCSection::getFragmentList
MCSection::FragmentListType & getFragmentList()
Definition: MCSection.h:164
F
#define F(x, y, z)
Definition: MD5.cpp:56
llvm::ARM::fixup_t2_uncondbranch
@ fixup_t2_uncondbranch
Definition: ARMFixupKinds.h:57
ARMFixupKinds.h
llvm::FirstLiteralRelocationKind
@ FirstLiteralRelocationKind
The range [FirstLiteralRelocationKind, MaxTargetFixupKind) is used for relocations coming from ....
Definition: MCFixup.h:50
llvm::FK_Data_4
@ FK_Data_4
A four-byte fixup.
Definition: MCFixup.h:25
ELF.h
llvm::ARM::fixup_arm_thumb_br
@ fixup_arm_thumb_br
Definition: ARMFixupKinds.h:60
MCContext.h
false
Definition: StackSlotColoring.cpp:142
llvm::ARM::fixup_bfc_target
@ fixup_bfc_target
Definition: ARMFixupKinds.h:112
llvm::ARM::fixup_arm_uncondbl
@ fixup_arm_uncondbl
Definition: ARMFixupKinds.h:72
llvm::MCELFObjectTargetWriter
Definition: MCELFObjectWriter.h:53
llvm::MCObjectFileInfo::getTextSection
MCSection * getTextSection() const
Definition: MCObjectFileInfo.h:258
llvm::ARM::fixup_arm_condbranch
@ fixup_arm_condbranch
Definition: ARMFixupKinds.h:49
llvm::MCContext::reportFatalError
void reportFatalError(SMLoc L, const Twine &Msg)
Definition: MCContext.cpp:982
llvm::lltok::Kind
Kind
Definition: LLToken.h:18
DF
static RegisterPass< DebugifyFunctionPass > DF("debugify-function", "Attach debug info to a function")
llvm::ARM::fixup_arm_movw_lo16
@ fixup_arm_movw_lo16
Definition: ARMFixupKinds.h:98
llvm::ARM::fixup_arm_thumb_bl
@ fixup_arm_thumb_bl
Definition: ARMFixupKinds.h:81
llvm::MCSymbolRefExpr::VariantKind
VariantKind
Definition: MCExpr.h:194
MCELFObjectWriter.h
llvm::ARM::fixup_arm_thumb_blx
@ fixup_arm_thumb_blx
Definition: ARMFixupKinds.h:84
llvm::ARM::fixup_t2_movt_hi16
@ fixup_t2_movt_hi16
Definition: ARMFixupKinds.h:99
llvm::ELF::SHF_ARM_PURECODE
@ SHF_ARM_PURECODE
Definition: ELF.h:1080
llvm::MCContext::reportError
void reportError(SMLoc L, const Twine &Msg)
Definition: MCContext.cpp:963
llvm::FK_Data_1
@ FK_Data_1
A one-byte fixup.
Definition: MCFixup.h:23
llvm::MCSymbolRefExpr
Represent a reference to a symbol from inside an expression.
Definition: MCExpr.h:192
llvm::MCSectionELF::getFlags
unsigned getFlags() const
Definition: MCSectionELF.h:75
llvm::ARM::fixup_bf_target
@ fixup_bf_target
Definition: ARMFixupKinds.h:110
Fixup
PowerPC TLS Dynamic Call Fixup
Definition: PPCTLSDynamicCall.cpp:235
llvm::ARM::fixup_arm_thumb_bcc
@ fixup_arm_thumb_bcc
Definition: ARMFixupKinds.h:93
llvm::MCSectionELF::setFlags
void setFlags(unsigned F)
Definition: MCSectionELF.h:77
MCFixup.h
llvm::ARM::fixup_arm_uncondbranch
@ fixup_arm_uncondbranch
Definition: ARMFixupKinds.h:51
llvm::ARM::fixup_arm_condbl
@ fixup_arm_condbl
Definition: ARMFixupKinds.h:75
MCObjectWriter.h
llvm::ARM::fixup_t2_movw_lo16
@ fixup_t2_movw_lo16
Definition: ARMFixupKinds.h:100
llvm::MCSection::hasInstructions
bool hasInstructions() const
Definition: MCSection.h:158
llvm::ARM::fixup_t2_condbranch
@ fixup_t2_condbranch
Definition: ARMFixupKinds.h:54
MCValue.h
llvm::MCSection::getKind
SectionKind getKind() const
Definition: MCSection.h:123
llvm::MCValue
This represents an "assembler immediate".
Definition: MCValue.h:37
llvm::ARM::fixup_arm_blx
@ fixup_arm_blx
Definition: ARMFixupKinds.h:78
raw_ostream.h
llvm::FK_Data_2
@ FK_Data_2
A two-byte fixup.
Definition: MCFixup.h:24
MCExpr.h
llvm::MCFixup
Encode information on a single operation to perform on a byte sequence (e.g., an encoded instruction)...
Definition: MCFixup.h:71
llvm::SectionKind::isExecuteOnly
bool isExecuteOnly() const
Definition: SectionKind.h:123
llvm::createARMELFObjectWriter
std::unique_ptr< MCObjectTargetWriter > createARMELFObjectWriter(uint8_t OSABI)
Construct an ELF Mach-O object writer.
Definition: ARMELFObjectWriter.cpp:290