LLVM  12.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();
83  if (Kind >= FirstLiteralRelocationKind)
84  return Kind - FirstLiteralRelocationKind;
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 }
SectionKind getKind() const
Definition: MCSection.h:116
bool hasInstructions() const
Definition: MCSection.h:151
This class represents lattice values for constants.
Definition: AllocatorList.h:23
This represents an "assembler immediate".
Definition: MCValue.h:37
MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...
Definition: MCSymbol.h:41
F(f)
MCSymbolRefExpr::VariantKind getAccessVariant() const
Definition: MCValue.cpp:46
Encode information on a single operation to perform on a byte sequence (e.g., an encoded instruction)...
Definition: MCFixup.h:82
Represent a reference to a symbol from inside an expression.
Definition: MCExpr.h:192
The range [FirstLiteralRelocationKind, MaxTargetFixupKind) is used for relocations coming from ...
Definition: MCFixup.h:61
A four-byte fixup.
Definition: MCFixup.h:26
Context object for machine code objects.
Definition: MCContext.h:67
LLVM_ATTRIBUTE_NORETURN void reportFatalError(SMLoc L, const Twine &Msg)
Definition: MCContext.cpp:840
The instances of the Type class are immutable: once they are created, they are never changed...
Definition: Type.h:46
void setFlags(unsigned F)
Definition: MCSectionELF.h:73
const MCSymbolRefExpr * getSymA() const
Definition: MCValue.h:45
const MCObjectFileInfo * getObjectFileInfo() const
Definition: MCContext.h:367
void reportError(SMLoc L, const Twine &Msg)
Definition: MCContext.cpp:811
std::unique_ptr< MCObjectTargetWriter > createARMELFObjectWriter(uint8_t OSABI)
Construct an ELF Mach-O object writer.
A one-byte fixup.
Definition: MCFixup.h:24
static RegisterPass< DebugifyFunctionPass > DF("debugify-function", "Attach debug info to a function")
PowerPC TLS Dynamic Call Fixup
SMLoc getLoc() const
Definition: MCFixup.h:202
Target - Wrapper for Target specific information.
This represents a section on linux, lots of unix variants and some bare metal systems.
Definition: MCSectionELF.h:27
MCSection * getTextSection() const
unsigned getTargetKind() const
Definition: MCFixup.h:133
bool isExecuteOnly() const
Definition: SectionKind.h:120
unsigned getFlags() const
Definition: MCSectionELF.h:71
MCSection::FragmentListType & getFragmentList()
Definition: MCSection.h:157
A two-byte fixup.
Definition: MCFixup.h:25