LLVM  10.0.0svn
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 a
57  // whitelist 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
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 {
83 
84  if (IsPCRel) {
85  switch (Fixup.getTargetKind()) {
86  default:
87  Ctx.reportFatalError(Fixup.getLoc(), "unsupported relocation on symbol");
88  return ELF::R_ARM_NONE;
89  case FK_Data_4:
90  switch (Modifier) {
91  default:
92  llvm_unreachable("Unsupported Modifier");
93  case MCSymbolRefExpr::VK_None:
94  return ELF::R_ARM_REL32;
95  case MCSymbolRefExpr::VK_GOTTPOFF:
96  return ELF::R_ARM_TLS_IE32;
97  case MCSymbolRefExpr::VK_ARM_GOT_PREL:
98  return ELF::R_ARM_GOT_PREL;
99  case MCSymbolRefExpr::VK_ARM_PREL31:
100  return ELF::R_ARM_PREL31;
101  }
102  case ARM::fixup_arm_blx:
104  switch (Modifier) {
105  case MCSymbolRefExpr::VK_PLT:
106  return ELF::R_ARM_CALL;
107  case MCSymbolRefExpr::VK_TLSCALL:
108  return ELF::R_ARM_TLS_CALL;
109  default:
110  return ELF::R_ARM_CALL;
111  }
115  return ELF::R_ARM_JUMP24;
117  return ELF::R_ARM_THM_JUMP19;
119  return ELF::R_ARM_THM_JUMP24;
121  return ELF::R_ARM_MOVT_PREL;
123  return ELF::R_ARM_MOVW_PREL_NC;
125  return ELF::R_ARM_THM_MOVT_PREL;
127  return ELF::R_ARM_THM_MOVW_PREL_NC;
129  return ELF::R_ARM_THM_JUMP11;
131  return ELF::R_ARM_THM_JUMP8;
134  switch (Modifier) {
135  case MCSymbolRefExpr::VK_TLSCALL:
136  return ELF::R_ARM_THM_TLS_CALL;
137  default:
138  return ELF::R_ARM_THM_CALL;
139  }
141  return ELF::R_ARM_THM_BF16;
143  return ELF::R_ARM_THM_BF12;
145  return ELF::R_ARM_THM_BF18;
146  }
147  }
148  switch (Fixup.getTargetKind()) {
149  default:
150  Ctx.reportFatalError(Fixup.getLoc(), "unsupported relocation on symbol");
151  return ELF::R_ARM_NONE;
152  case FK_NONE:
153  return ELF::R_ARM_NONE;
154  case FK_Data_1:
155  switch (Modifier) {
156  default:
157  llvm_unreachable("unsupported Modifier");
158  case MCSymbolRefExpr::VK_None:
159  return ELF::R_ARM_ABS8;
160  }
161  case FK_Data_2:
162  switch (Modifier) {
163  default:
164  llvm_unreachable("unsupported modifier");
165  case MCSymbolRefExpr::VK_None:
166  return ELF::R_ARM_ABS16;
167  }
168  case FK_Data_4:
169  switch (Modifier) {
170  default:
171  llvm_unreachable("Unsupported Modifier");
172  case MCSymbolRefExpr::VK_ARM_NONE:
173  return ELF::R_ARM_NONE;
174  case MCSymbolRefExpr::VK_GOT:
175  return ELF::R_ARM_GOT_BREL;
176  case MCSymbolRefExpr::VK_TLSGD:
177  return ELF::R_ARM_TLS_GD32;
178  case MCSymbolRefExpr::VK_TPOFF:
179  return ELF::R_ARM_TLS_LE32;
180  case MCSymbolRefExpr::VK_GOTTPOFF:
181  return ELF::R_ARM_TLS_IE32;
182  case MCSymbolRefExpr::VK_None:
183  return ELF::R_ARM_ABS32;
184  case MCSymbolRefExpr::VK_GOTOFF:
185  return ELF::R_ARM_GOTOFF32;
186  case MCSymbolRefExpr::VK_ARM_GOT_PREL:
187  return ELF::R_ARM_GOT_PREL;
188  case MCSymbolRefExpr::VK_ARM_TARGET1:
189  return ELF::R_ARM_TARGET1;
190  case MCSymbolRefExpr::VK_ARM_TARGET2:
191  return ELF::R_ARM_TARGET2;
192  case MCSymbolRefExpr::VK_ARM_PREL31:
193  return ELF::R_ARM_PREL31;
194  case MCSymbolRefExpr::VK_ARM_SBREL:
195  return ELF::R_ARM_SBREL32;
196  case MCSymbolRefExpr::VK_ARM_TLSLDO:
197  return ELF::R_ARM_TLS_LDO32;
198  case MCSymbolRefExpr::VK_TLSCALL:
199  return ELF::R_ARM_TLS_CALL;
200  case MCSymbolRefExpr::VK_TLSDESC:
201  return ELF::R_ARM_TLS_GOTDESC;
202  case MCSymbolRefExpr::VK_TLSLDM:
203  return ELF::R_ARM_TLS_LDM32;
204  case MCSymbolRefExpr::VK_ARM_TLSDESCSEQ:
205  return ELF::R_ARM_TLS_DESCSEQ;
206  }
209  return ELF::R_ARM_JUMP24;
211  switch (Modifier) {
212  default:
213  llvm_unreachable("Unsupported Modifier");
214  case MCSymbolRefExpr::VK_None:
215  return ELF::R_ARM_MOVT_ABS;
216  case MCSymbolRefExpr::VK_ARM_SBREL:
217  return ELF::R_ARM_MOVT_BREL;
218  }
220  switch (Modifier) {
221  default:
222  llvm_unreachable("Unsupported Modifier");
223  case MCSymbolRefExpr::VK_None:
224  return ELF::R_ARM_MOVW_ABS_NC;
225  case MCSymbolRefExpr::VK_ARM_SBREL:
226  return ELF::R_ARM_MOVW_BREL_NC;
227  }
229  switch (Modifier) {
230  default:
231  llvm_unreachable("Unsupported Modifier");
232  case MCSymbolRefExpr::VK_None:
233  return ELF::R_ARM_THM_MOVT_ABS;
234  case MCSymbolRefExpr::VK_ARM_SBREL:
235  return ELF::R_ARM_THM_MOVT_BREL;
236  }
238  switch (Modifier) {
239  default:
240  llvm_unreachable("Unsupported Modifier");
241  case MCSymbolRefExpr::VK_None:
242  return ELF::R_ARM_THM_MOVW_ABS_NC;
243  case MCSymbolRefExpr::VK_ARM_SBREL:
244  return ELF::R_ARM_THM_MOVW_BREL_NC;
245  }
246  }
247 }
248 
249 void ARMELFObjectWriter::addTargetSectionFlags(MCContext &Ctx,
250  MCSectionELF &Sec) {
251  // The mix of execute-only and non-execute-only at link time is
252  // non-execute-only. To avoid the empty implicitly created .text
253  // section from making the whole .text section non-execute-only, we
254  // mark it execute-only if it is empty and there is at least one
255  // execute-only section in the object.
256  MCSectionELF *TextSection =
257  static_cast<MCSectionELF *>(Ctx.getObjectFileInfo()->getTextSection());
258  if (Sec.getKind().isExecuteOnly() && !TextSection->hasInstructions() &&
259  !TextSection->hasData()) {
260  TextSection->setFlags(TextSection->getFlags() | ELF::SHF_ARM_PURECODE);
261  }
262 }
263 
264 std::unique_ptr<MCObjectTargetWriter>
266  return std::make_unique<ARMELFObjectWriter>(OSABI);
267 }
SectionKind getKind() const
Definition: MCSection.h:106
bool hasInstructions() const
Definition: MCSection.h:141
This class represents lattice values for constants.
Definition: AllocatorList.h:23
This represents an "assembler immediate".
Definition: MCValue.h:39
MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...
Definition: MCSymbol.h:41
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:77
static unsigned getRelocType(const MCValue &Target, const MCFixupKind FixupKind, const bool IsPCRel)
Translates generic PPC fixup kind to Mach-O/PPC relocation type enum.
A four-byte fixup.
Definition: MCFixup.h:26
Context object for machine code objects.
Definition: MCContext.h:65
LLVM_ATTRIBUTE_NORETURN void reportFatalError(SMLoc L, const Twine &Msg)
Definition: MCContext.cpp:716
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:74
const MCObjectFileInfo * getObjectFileInfo() const
Definition: MCContext.h:322
std::unique_ptr< MCObjectTargetWriter > createARMELFObjectWriter(uint8_t OSABI)
Construct an ELF Mach-O object writer.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
A one-byte fixup.
Definition: MCFixup.h:24
PowerPC TLS Dynamic Call Fixup
bool hasData() const
Definition: MCSection.h:144
SMLoc getLoc() const
Definition: MCFixup.h:197
A no-op fixup.
Definition: MCFixup.h:23
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:128
bool isExecuteOnly() const
Definition: SectionKind.h:120
unsigned getFlags() const
Definition: MCSectionELF.h:72
A two-byte fixup.
Definition: MCFixup.h:25