LLVM  8.0.1
ARMELFObjectWriter.cpp
Go to the documentation of this file.
1 //===-- ARMELFObjectWriter.cpp - ARM ELF Writer ---------------------------===//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 
12 #include "llvm/BinaryFormat/ELF.h"
13 #include "llvm/MC/MCContext.h"
15 #include "llvm/MC/MCExpr.h"
16 #include "llvm/MC/MCFixup.h"
18 #include "llvm/MC/MCObjectWriter.h"
19 #include "llvm/MC/MCValue.h"
22 #include <cstdint>
23 
24 using namespace llvm;
25 
26 namespace {
27 
28  class ARMELFObjectWriter : public MCELFObjectTargetWriter {
29  enum { DefaultEABIVersion = 0x05000000U };
30 
31  unsigned GetRelocTypeInner(const MCValue &Target, const MCFixup &Fixup,
32  bool IsPCRel, MCContext &Ctx) const;
33 
34  public:
35  ARMELFObjectWriter(uint8_t OSABI);
36 
37  ~ARMELFObjectWriter() override = default;
38 
39  unsigned getRelocType(MCContext &Ctx, const MCValue &Target,
40  const MCFixup &Fixup, bool IsPCRel) const override;
41 
42  bool needsRelocateWithSymbol(const MCSymbol &Sym,
43  unsigned Type) const override;
44 
45  void addTargetSectionFlags(MCContext &Ctx, MCSectionELF &Sec) override;
46  };
47 
48 } // end anonymous namespace
49 
50 ARMELFObjectWriter::ARMELFObjectWriter(uint8_t OSABI)
51  : MCELFObjectTargetWriter(/*Is64Bit*/ false, OSABI,
52  ELF::EM_ARM,
53  /*HasRelocationAddend*/ false) {}
54 
55 bool ARMELFObjectWriter::needsRelocateWithSymbol(const MCSymbol &Sym,
56  unsigned Type) const {
57  // FIXME: This is extremely conservative. This really needs to use a
58  // whitelist with a clear explanation for why each realocation needs to
59  // point to the symbol, not to the section.
60  switch (Type) {
61  default:
62  return true;
63 
64  case ELF::R_ARM_PREL31:
65  case ELF::R_ARM_ABS32:
66  return false;
67  }
68 }
69 
70 // Need to examine the Fixup when determining whether to
71 // emit the relocation as an explicit symbol or as a section relative
72 // offset
74  const MCFixup &Fixup,
75  bool IsPCRel) const {
76  return GetRelocTypeInner(Target, Fixup, IsPCRel, Ctx);
77 }
78 
79 unsigned ARMELFObjectWriter::GetRelocTypeInner(const MCValue &Target,
80  const MCFixup &Fixup,
81  bool IsPCRel,
82  MCContext &Ctx) const {
84 
85  if (IsPCRel) {
86  switch ((unsigned)Fixup.getKind()) {
87  default:
88  Ctx.reportFatalError(Fixup.getLoc(), "unsupported relocation on symbol");
89  return ELF::R_ARM_NONE;
90  case FK_Data_4:
91  switch (Modifier) {
92  default:
93  llvm_unreachable("Unsupported Modifier");
94  case MCSymbolRefExpr::VK_None:
95  return ELF::R_ARM_REL32;
96  case MCSymbolRefExpr::VK_GOTTPOFF:
97  return ELF::R_ARM_TLS_IE32;
98  case MCSymbolRefExpr::VK_ARM_GOT_PREL:
99  return ELF::R_ARM_GOT_PREL;
100  case MCSymbolRefExpr::VK_ARM_PREL31:
101  return ELF::R_ARM_PREL31;
102  }
103  case ARM::fixup_arm_blx:
105  switch (Modifier) {
106  case MCSymbolRefExpr::VK_PLT:
107  return ELF::R_ARM_CALL;
108  case MCSymbolRefExpr::VK_TLSCALL:
109  return ELF::R_ARM_TLS_CALL;
110  default:
111  return ELF::R_ARM_CALL;
112  }
116  return ELF::R_ARM_JUMP24;
118  return ELF::R_ARM_THM_JUMP19;
120  return ELF::R_ARM_THM_JUMP24;
122  return ELF::R_ARM_MOVT_PREL;
124  return ELF::R_ARM_MOVW_PREL_NC;
126  return ELF::R_ARM_THM_MOVT_PREL;
128  return ELF::R_ARM_THM_MOVW_PREL_NC;
130  return ELF::R_ARM_THM_JUMP11;
132  return ELF::R_ARM_THM_JUMP8;
135  switch (Modifier) {
136  case MCSymbolRefExpr::VK_TLSCALL:
137  return ELF::R_ARM_THM_TLS_CALL;
138  default:
139  return ELF::R_ARM_THM_CALL;
140  }
141  }
142  }
143  switch ((unsigned)Fixup.getKind()) {
144  default:
145  Ctx.reportFatalError(Fixup.getLoc(), "unsupported relocation on symbol");
146  return ELF::R_ARM_NONE;
147  case FK_Data_1:
148  switch (Modifier) {
149  default:
150  llvm_unreachable("unsupported Modifier");
151  case MCSymbolRefExpr::VK_None:
152  return ELF::R_ARM_ABS8;
153  }
154  case FK_Data_2:
155  switch (Modifier) {
156  default:
157  llvm_unreachable("unsupported modifier");
158  case MCSymbolRefExpr::VK_None:
159  return ELF::R_ARM_ABS16;
160  }
161  case FK_Data_4:
162  switch (Modifier) {
163  default:
164  llvm_unreachable("Unsupported Modifier");
165  case MCSymbolRefExpr::VK_ARM_NONE:
166  return ELF::R_ARM_NONE;
167  case MCSymbolRefExpr::VK_GOT:
168  return ELF::R_ARM_GOT_BREL;
169  case MCSymbolRefExpr::VK_TLSGD:
170  return ELF::R_ARM_TLS_GD32;
171  case MCSymbolRefExpr::VK_TPOFF:
172  return ELF::R_ARM_TLS_LE32;
173  case MCSymbolRefExpr::VK_GOTTPOFF:
174  return ELF::R_ARM_TLS_IE32;
175  case MCSymbolRefExpr::VK_None:
176  return ELF::R_ARM_ABS32;
177  case MCSymbolRefExpr::VK_GOTOFF:
178  return ELF::R_ARM_GOTOFF32;
179  case MCSymbolRefExpr::VK_ARM_GOT_PREL:
180  return ELF::R_ARM_GOT_PREL;
181  case MCSymbolRefExpr::VK_ARM_TARGET1:
182  return ELF::R_ARM_TARGET1;
183  case MCSymbolRefExpr::VK_ARM_TARGET2:
184  return ELF::R_ARM_TARGET2;
185  case MCSymbolRefExpr::VK_ARM_PREL31:
186  return ELF::R_ARM_PREL31;
187  case MCSymbolRefExpr::VK_ARM_SBREL:
188  return ELF::R_ARM_SBREL32;
189  case MCSymbolRefExpr::VK_ARM_TLSLDO:
190  return ELF::R_ARM_TLS_LDO32;
191  case MCSymbolRefExpr::VK_TLSCALL:
192  return ELF::R_ARM_TLS_CALL;
193  case MCSymbolRefExpr::VK_TLSDESC:
194  return ELF::R_ARM_TLS_GOTDESC;
195  case MCSymbolRefExpr::VK_TLSLDM:
196  return ELF::R_ARM_TLS_LDM32;
197  case MCSymbolRefExpr::VK_ARM_TLSDESCSEQ:
198  return ELF::R_ARM_TLS_DESCSEQ;
199  }
202  return ELF::R_ARM_JUMP24;
204  switch (Modifier) {
205  default:
206  llvm_unreachable("Unsupported Modifier");
207  case MCSymbolRefExpr::VK_None:
208  return ELF::R_ARM_MOVT_ABS;
209  case MCSymbolRefExpr::VK_ARM_SBREL:
210  return ELF::R_ARM_MOVT_BREL;
211  }
213  switch (Modifier) {
214  default:
215  llvm_unreachable("Unsupported Modifier");
216  case MCSymbolRefExpr::VK_None:
217  return ELF::R_ARM_MOVW_ABS_NC;
218  case MCSymbolRefExpr::VK_ARM_SBREL:
219  return ELF::R_ARM_MOVW_BREL_NC;
220  }
222  switch (Modifier) {
223  default:
224  llvm_unreachable("Unsupported Modifier");
225  case MCSymbolRefExpr::VK_None:
226  return ELF::R_ARM_THM_MOVT_ABS;
227  case MCSymbolRefExpr::VK_ARM_SBREL:
228  return ELF::R_ARM_THM_MOVT_BREL;
229  }
231  switch (Modifier) {
232  default:
233  llvm_unreachable("Unsupported Modifier");
234  case MCSymbolRefExpr::VK_None:
235  return ELF::R_ARM_THM_MOVW_ABS_NC;
236  case MCSymbolRefExpr::VK_ARM_SBREL:
237  return ELF::R_ARM_THM_MOVW_BREL_NC;
238  }
239  }
240 }
241 
242 void ARMELFObjectWriter::addTargetSectionFlags(MCContext &Ctx,
243  MCSectionELF &Sec) {
244  // The mix of execute-only and non-execute-only at link time is
245  // non-execute-only. To avoid the empty implicitly created .text
246  // section from making the whole .text section non-execute-only, we
247  // mark it execute-only if it is empty and there is at least one
248  // execute-only section in the object.
249  MCSectionELF *TextSection =
250  static_cast<MCSectionELF *>(Ctx.getObjectFileInfo()->getTextSection());
251  if (Sec.getKind().isExecuteOnly() && !TextSection->hasInstructions() &&
252  !TextSection->hasData()) {
253  TextSection->setFlags(TextSection->getFlags() | ELF::SHF_ARM_PURECODE);
254  }
255 }
256 
257 std::unique_ptr<MCObjectTargetWriter>
259  return llvm::make_unique<ARMELFObjectWriter>(OSABI);
260 }
SectionKind getKind() const
Definition: MCSection.h:106
bool hasInstructions() const
Definition: MCSection.h:141
This class represents lattice values for constants.
Definition: AllocatorList.h:24
This represents an "assembler immediate".
Definition: MCValue.h:40
MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...
Definition: MCSymbol.h:42
MCSymbolRefExpr::VariantKind getAccessVariant() const
Definition: MCValue.cpp:47
Encode information on a single operation to perform on a byte sequence (e.g., an encoded instruction)...
Definition: MCFixup.h:74
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:63
LLVM_ATTRIBUTE_NORETURN void reportFatalError(SMLoc L, const Twine &Msg)
Definition: MCContext.cpp:626
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:77
const MCObjectFileInfo * getObjectFileInfo() const
Definition: MCContext.h:297
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:166
Target - Wrapper for Target specific information.
This represents a section on linux, lots of unix variants and some bare metal systems.
Definition: MCSectionELF.h:28
MCSection * getTextSection() const
bool isExecuteOnly() const
Definition: SectionKind.h:121
unsigned getFlags() const
Definition: MCSectionELF.h:75
A two-byte fixup.
Definition: MCFixup.h:25
MCFixupKind getKind() const
Definition: MCFixup.h:123