]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/lib/Target/ARM/MCTargetDesc/ARMELFObjectWriter.cpp
Merge clang 7.0.1 and several follow-up changes
[FreeBSD/FreeBSD.git] / contrib / llvm / lib / Target / ARM / MCTargetDesc / ARMELFObjectWriter.cpp
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
10 #include "MCTargetDesc/ARMFixupKinds.h"
11 #include "MCTargetDesc/ARMMCTargetDesc.h"
12 #include "llvm/BinaryFormat/ELF.h"
13 #include "llvm/MC/MCContext.h"
14 #include "llvm/MC/MCELFObjectWriter.h"
15 #include "llvm/MC/MCExpr.h"
16 #include "llvm/MC/MCFixup.h"
17 #include "llvm/MC/MCObjectWriter.h"
18 #include "llvm/MC/MCValue.h"
19 #include "llvm/Support/ErrorHandling.h"
20 #include "llvm/Support/raw_ostream.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
45 } // end anonymous namespace
46
47 ARMELFObjectWriter::ARMELFObjectWriter(uint8_t OSABI)
48   : MCELFObjectTargetWriter(/*Is64Bit*/ false, OSABI,
49                             ELF::EM_ARM,
50                             /*HasRelocationAddend*/ false) {}
51
52 bool ARMELFObjectWriter::needsRelocateWithSymbol(const MCSymbol &Sym,
53                                                  unsigned Type) const {
54   // FIXME: This is extremely conservative. This really needs to use a
55   // whitelist with a clear explanation for why each realocation needs to
56   // point to the symbol, not to the section.
57   switch (Type) {
58   default:
59     return true;
60
61   case ELF::R_ARM_PREL31:
62   case ELF::R_ARM_ABS32:
63     return false;
64   }
65 }
66
67 // Need to examine the Fixup when determining whether to
68 // emit the relocation as an explicit symbol or as a section relative
69 // offset
70 unsigned ARMELFObjectWriter::getRelocType(MCContext &Ctx, const MCValue &Target,
71                                           const MCFixup &Fixup,
72                                           bool IsPCRel) const {
73   return GetRelocTypeInner(Target, Fixup, IsPCRel, Ctx);
74 }
75
76 unsigned ARMELFObjectWriter::GetRelocTypeInner(const MCValue &Target,
77                                                const MCFixup &Fixup,
78                                                bool IsPCRel,
79                                                MCContext &Ctx) const {
80   MCSymbolRefExpr::VariantKind Modifier = Target.getAccessVariant();
81
82   if (IsPCRel) {
83     switch ((unsigned)Fixup.getKind()) {
84     default:
85       Ctx.reportFatalError(Fixup.getLoc(), "unsupported relocation on symbol");
86       return ELF::R_ARM_NONE;
87     case FK_Data_4:
88       switch (Modifier) {
89       default:
90         llvm_unreachable("Unsupported Modifier");
91       case MCSymbolRefExpr::VK_None:
92         return ELF::R_ARM_REL32;
93       case MCSymbolRefExpr::VK_GOTTPOFF:
94         return ELF::R_ARM_TLS_IE32;
95       case MCSymbolRefExpr::VK_ARM_GOT_PREL:
96         return ELF::R_ARM_GOT_PREL;
97       case MCSymbolRefExpr::VK_ARM_PREL31:
98         return ELF::R_ARM_PREL31;
99       }
100     case ARM::fixup_arm_blx:
101     case ARM::fixup_arm_uncondbl:
102       switch (Modifier) {
103       case MCSymbolRefExpr::VK_PLT:
104         return ELF::R_ARM_CALL;
105       case MCSymbolRefExpr::VK_TLSCALL:
106         return ELF::R_ARM_TLS_CALL;
107       default:
108         return ELF::R_ARM_CALL;
109       }
110     case ARM::fixup_arm_condbl:
111     case ARM::fixup_arm_condbranch:
112     case ARM::fixup_arm_uncondbranch:
113       return ELF::R_ARM_JUMP24;
114     case ARM::fixup_t2_condbranch:
115       return ELF::R_ARM_THM_JUMP19;
116     case ARM::fixup_t2_uncondbranch:
117       return ELF::R_ARM_THM_JUMP24;
118     case ARM::fixup_arm_movt_hi16:
119       return ELF::R_ARM_MOVT_PREL;
120     case ARM::fixup_arm_movw_lo16:
121       return ELF::R_ARM_MOVW_PREL_NC;
122     case ARM::fixup_t2_movt_hi16:
123       return ELF::R_ARM_THM_MOVT_PREL;
124     case ARM::fixup_t2_movw_lo16:
125       return ELF::R_ARM_THM_MOVW_PREL_NC;
126     case ARM::fixup_arm_thumb_br:
127       return ELF::R_ARM_THM_JUMP11;
128     case ARM::fixup_arm_thumb_bcc:
129       return ELF::R_ARM_THM_JUMP8;
130     case ARM::fixup_arm_thumb_bl:
131     case ARM::fixup_arm_thumb_blx:
132       switch (Modifier) {
133       case MCSymbolRefExpr::VK_TLSCALL:
134         return ELF::R_ARM_THM_TLS_CALL;
135       default:
136         return ELF::R_ARM_THM_CALL;
137       }
138     }
139   }
140   switch ((unsigned)Fixup.getKind()) {
141   default:
142     Ctx.reportFatalError(Fixup.getLoc(), "unsupported relocation on symbol");
143     return ELF::R_ARM_NONE;
144   case FK_Data_1:
145     switch (Modifier) {
146     default:
147       llvm_unreachable("unsupported Modifier");
148     case MCSymbolRefExpr::VK_None:
149       return ELF::R_ARM_ABS8;
150     }
151   case FK_Data_2:
152     switch (Modifier) {
153     default:
154       llvm_unreachable("unsupported modifier");
155     case MCSymbolRefExpr::VK_None:
156       return ELF::R_ARM_ABS16;
157     }
158   case FK_Data_4:
159     switch (Modifier) {
160     default:
161       llvm_unreachable("Unsupported Modifier");
162     case MCSymbolRefExpr::VK_ARM_NONE:
163       return ELF::R_ARM_NONE;
164     case MCSymbolRefExpr::VK_GOT:
165       return ELF::R_ARM_GOT_BREL;
166     case MCSymbolRefExpr::VK_TLSGD:
167       return ELF::R_ARM_TLS_GD32;
168     case MCSymbolRefExpr::VK_TPOFF:
169       return ELF::R_ARM_TLS_LE32;
170     case MCSymbolRefExpr::VK_GOTTPOFF:
171       return ELF::R_ARM_TLS_IE32;
172     case MCSymbolRefExpr::VK_None:
173       return ELF::R_ARM_ABS32;
174     case MCSymbolRefExpr::VK_GOTOFF:
175       return ELF::R_ARM_GOTOFF32;
176     case MCSymbolRefExpr::VK_ARM_GOT_PREL:
177       return ELF::R_ARM_GOT_PREL;
178     case MCSymbolRefExpr::VK_ARM_TARGET1:
179       return ELF::R_ARM_TARGET1;
180     case MCSymbolRefExpr::VK_ARM_TARGET2:
181       return ELF::R_ARM_TARGET2;
182     case MCSymbolRefExpr::VK_ARM_PREL31:
183       return ELF::R_ARM_PREL31;
184     case MCSymbolRefExpr::VK_ARM_SBREL:
185       return ELF::R_ARM_SBREL32;
186     case MCSymbolRefExpr::VK_ARM_TLSLDO:
187       return ELF::R_ARM_TLS_LDO32;
188     case MCSymbolRefExpr::VK_TLSCALL:
189       return ELF::R_ARM_TLS_CALL;
190     case MCSymbolRefExpr::VK_TLSDESC:
191       return ELF::R_ARM_TLS_GOTDESC;
192     case MCSymbolRefExpr::VK_TLSLDM:
193       return ELF::R_ARM_TLS_LDM32;
194     case MCSymbolRefExpr::VK_ARM_TLSDESCSEQ:
195       return ELF::R_ARM_TLS_DESCSEQ;
196     }
197   case ARM::fixup_arm_condbranch:
198   case ARM::fixup_arm_uncondbranch:
199     return ELF::R_ARM_JUMP24;
200   case ARM::fixup_arm_movt_hi16:
201     switch (Modifier) {
202     default:
203       llvm_unreachable("Unsupported Modifier");
204     case MCSymbolRefExpr::VK_None:
205       return ELF::R_ARM_MOVT_ABS;
206     case MCSymbolRefExpr::VK_ARM_SBREL:
207       return ELF::R_ARM_MOVT_BREL;
208     }
209   case ARM::fixup_arm_movw_lo16:
210     switch (Modifier) {
211     default:
212       llvm_unreachable("Unsupported Modifier");
213     case MCSymbolRefExpr::VK_None:
214       return ELF::R_ARM_MOVW_ABS_NC;
215     case MCSymbolRefExpr::VK_ARM_SBREL:
216       return ELF::R_ARM_MOVW_BREL_NC;
217     }
218   case ARM::fixup_t2_movt_hi16:
219     switch (Modifier) {
220     default:
221       llvm_unreachable("Unsupported Modifier");
222     case MCSymbolRefExpr::VK_None:
223       return ELF::R_ARM_THM_MOVT_ABS;
224     case MCSymbolRefExpr::VK_ARM_SBREL:
225       return ELF::R_ARM_THM_MOVT_BREL;
226     }
227   case ARM::fixup_t2_movw_lo16:
228     switch (Modifier) {
229     default:
230       llvm_unreachable("Unsupported Modifier");
231     case MCSymbolRefExpr::VK_None:
232       return ELF::R_ARM_THM_MOVW_ABS_NC;
233     case MCSymbolRefExpr::VK_ARM_SBREL:
234       return ELF::R_ARM_THM_MOVW_BREL_NC;
235     }
236   }
237 }
238
239 std::unique_ptr<MCObjectTargetWriter>
240 llvm::createARMELFObjectWriter(uint8_t OSABI) {
241   return llvm::make_unique<ARMELFObjectWriter>(OSABI);
242 }