1 //===-- HexagonELFObjectWriter.cpp - Hexagon Target Descriptions ----------===//
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 
9 #include "MCTargetDesc/HexagonFixupKinds.h"
10 #include "MCTargetDesc/HexagonMCTargetDesc.h"
11 #include "llvm/MC/MCAssembler.h"
12 #include "llvm/MC/MCELFObjectWriter.h"
13 #include "llvm/MC/MCObjectWriter.h"
14 #include "llvm/MC/MCValue.h"
15 #include "llvm/Support/Debug.h"
16 #include "llvm/Support/raw_ostream.h"
17 
18 #define DEBUG_TYPE "hexagon-elf-writer"
19 
20 using namespace llvm;
21 using namespace Hexagon;
22 
23 namespace {
24 
25 class HexagonELFObjectWriter : public MCELFObjectTargetWriter {
26 private:
27   StringRef CPU;
28 
29 public:
30   HexagonELFObjectWriter(uint8_t OSABI, StringRef C);
31 
32   unsigned getRelocType(MCContext &Ctx, MCValue const &Target,
33                         MCFixup const &Fixup, bool IsPCRel) const override;
34 };
35 }
36 
HexagonELFObjectWriter(uint8_t OSABI,StringRef C)37 HexagonELFObjectWriter::HexagonELFObjectWriter(uint8_t OSABI, StringRef C)
38     : MCELFObjectTargetWriter(/*Is64bit*/ false, OSABI, ELF::EM_HEXAGON,
39                               /*HasRelocationAddend*/ true),
40       CPU(C) {}
41 
getRelocType(MCContext & Ctx,MCValue const & Target,MCFixup const & Fixup,bool IsPCRel) const42 unsigned HexagonELFObjectWriter::getRelocType(MCContext &Ctx,
43                                               MCValue const &Target,
44                                               MCFixup const &Fixup,
45                                               bool IsPCRel) const {
46   MCSymbolRefExpr::VariantKind Variant = Target.getAccessVariant();
47   switch (Fixup.getTargetKind()) {
48   default:
49     report_fatal_error("Unrecognized relocation type");
50     break;
51   case FK_Data_4:
52     switch(Variant) {
53     case MCSymbolRefExpr::VariantKind::VK_DTPREL:
54       return ELF::R_HEX_DTPREL_32;
55     case MCSymbolRefExpr::VariantKind::VK_GOT:
56       return ELF::R_HEX_GOT_32;
57     case MCSymbolRefExpr::VariantKind::VK_GOTREL:
58       return ELF::R_HEX_GOTREL_32;
59     case MCSymbolRefExpr::VariantKind::VK_Hexagon_GD_GOT:
60       return ELF::R_HEX_GD_GOT_32;
61     case MCSymbolRefExpr::VariantKind::VK_Hexagon_IE:
62       return ELF::R_HEX_IE_32;
63     case MCSymbolRefExpr::VariantKind::VK_Hexagon_IE_GOT:
64       return ELF::R_HEX_IE_GOT_32;
65     case MCSymbolRefExpr::VariantKind::VK_Hexagon_LD_GOT:
66       return ELF::R_HEX_LD_GOT_32;
67     case MCSymbolRefExpr::VariantKind::VK_PCREL:
68       return ELF::R_HEX_32_PCREL;
69     case MCSymbolRefExpr::VariantKind::VK_TPREL:
70       return ELF::R_HEX_TPREL_32;
71     case MCSymbolRefExpr::VariantKind::VK_None:
72       return IsPCRel ? ELF::R_HEX_32_PCREL : ELF::R_HEX_32;
73     default:
74       report_fatal_error("Unrecognized variant type");
75     };
76   case FK_PCRel_4:
77     return ELF::R_HEX_32_PCREL;
78   case FK_Data_2:
79     switch(Variant) {
80     case MCSymbolRefExpr::VariantKind::VK_DTPREL:
81       return ELF::R_HEX_DTPREL_16;
82     case MCSymbolRefExpr::VariantKind::VK_GOT:
83       return ELF::R_HEX_GOT_16;
84     case MCSymbolRefExpr::VariantKind::VK_Hexagon_GD_GOT:
85       return ELF::R_HEX_GD_GOT_16;
86     case MCSymbolRefExpr::VariantKind::VK_Hexagon_IE_GOT:
87       return ELF::R_HEX_IE_GOT_16;
88     case MCSymbolRefExpr::VariantKind::VK_Hexagon_LD_GOT:
89       return ELF::R_HEX_LD_GOT_16;
90     case MCSymbolRefExpr::VariantKind::VK_TPREL:
91       return ELF::R_HEX_TPREL_16;
92     case MCSymbolRefExpr::VariantKind::VK_None:
93       return ELF::R_HEX_16;
94     default:
95       report_fatal_error("Unrecognized variant type");
96     };
97   case FK_Data_1:
98     return ELF::R_HEX_8;
99   case fixup_Hexagon_B22_PCREL:
100     return ELF::R_HEX_B22_PCREL;
101   case fixup_Hexagon_B15_PCREL:
102     return ELF::R_HEX_B15_PCREL;
103   case fixup_Hexagon_B7_PCREL:
104     return ELF::R_HEX_B7_PCREL;
105   case fixup_Hexagon_LO16:
106     return ELF::R_HEX_LO16;
107   case fixup_Hexagon_HI16:
108     return ELF::R_HEX_HI16;
109   case fixup_Hexagon_32:
110     return ELF::R_HEX_32;
111   case fixup_Hexagon_16:
112     return ELF::R_HEX_16;
113   case fixup_Hexagon_8:
114     return ELF::R_HEX_8;
115   case fixup_Hexagon_GPREL16_0:
116     return ELF::R_HEX_GPREL16_0;
117   case fixup_Hexagon_GPREL16_1:
118     return ELF::R_HEX_GPREL16_1;
119   case fixup_Hexagon_GPREL16_2:
120     return ELF::R_HEX_GPREL16_2;
121   case fixup_Hexagon_GPREL16_3:
122     return ELF::R_HEX_GPREL16_3;
123   case fixup_Hexagon_HL16:
124     return ELF::R_HEX_HL16;
125   case fixup_Hexagon_B13_PCREL:
126     return ELF::R_HEX_B13_PCREL;
127   case fixup_Hexagon_B9_PCREL:
128     return ELF::R_HEX_B9_PCREL;
129   case fixup_Hexagon_B32_PCREL_X:
130     return ELF::R_HEX_B32_PCREL_X;
131   case fixup_Hexagon_32_6_X:
132     return ELF::R_HEX_32_6_X;
133   case fixup_Hexagon_B22_PCREL_X:
134     return ELF::R_HEX_B22_PCREL_X;
135   case fixup_Hexagon_B15_PCREL_X:
136     return ELF::R_HEX_B15_PCREL_X;
137   case fixup_Hexagon_B13_PCREL_X:
138     return ELF::R_HEX_B13_PCREL_X;
139   case fixup_Hexagon_B9_PCREL_X:
140     return ELF::R_HEX_B9_PCREL_X;
141   case fixup_Hexagon_B7_PCREL_X:
142     return ELF::R_HEX_B7_PCREL_X;
143   case fixup_Hexagon_16_X:
144     return ELF::R_HEX_16_X;
145   case fixup_Hexagon_12_X:
146     return ELF::R_HEX_12_X;
147   case fixup_Hexagon_11_X:
148     return ELF::R_HEX_11_X;
149   case fixup_Hexagon_10_X:
150     return ELF::R_HEX_10_X;
151   case fixup_Hexagon_9_X:
152     return ELF::R_HEX_9_X;
153   case fixup_Hexagon_8_X:
154     return ELF::R_HEX_8_X;
155   case fixup_Hexagon_7_X:
156     return ELF::R_HEX_7_X;
157   case fixup_Hexagon_6_X:
158     return ELF::R_HEX_6_X;
159   case fixup_Hexagon_32_PCREL:
160     return ELF::R_HEX_32_PCREL;
161   case fixup_Hexagon_COPY:
162     return ELF::R_HEX_COPY;
163   case fixup_Hexagon_GLOB_DAT:
164     return ELF::R_HEX_GLOB_DAT;
165   case fixup_Hexagon_JMP_SLOT:
166     return ELF::R_HEX_JMP_SLOT;
167   case fixup_Hexagon_RELATIVE:
168     return ELF::R_HEX_RELATIVE;
169   case fixup_Hexagon_PLT_B22_PCREL:
170     return ELF::R_HEX_PLT_B22_PCREL;
171   case fixup_Hexagon_GOTREL_LO16:
172     return ELF::R_HEX_GOTREL_LO16;
173   case fixup_Hexagon_GOTREL_HI16:
174     return ELF::R_HEX_GOTREL_HI16;
175   case fixup_Hexagon_GOTREL_32:
176     return ELF::R_HEX_GOTREL_32;
177   case fixup_Hexagon_GOT_LO16:
178     return ELF::R_HEX_GOT_LO16;
179   case fixup_Hexagon_GOT_HI16:
180     return ELF::R_HEX_GOT_HI16;
181   case fixup_Hexagon_GOT_32:
182     return ELF::R_HEX_GOT_32;
183   case fixup_Hexagon_GOT_16:
184     return ELF::R_HEX_GOT_16;
185   case fixup_Hexagon_DTPMOD_32:
186     return ELF::R_HEX_DTPMOD_32;
187   case fixup_Hexagon_DTPREL_LO16:
188     return ELF::R_HEX_DTPREL_LO16;
189   case fixup_Hexagon_DTPREL_HI16:
190     return ELF::R_HEX_DTPREL_HI16;
191   case fixup_Hexagon_DTPREL_32:
192     return ELF::R_HEX_DTPREL_32;
193   case fixup_Hexagon_DTPREL_16:
194     return ELF::R_HEX_DTPREL_16;
195   case fixup_Hexagon_GD_PLT_B22_PCREL:
196     return ELF::R_HEX_GD_PLT_B22_PCREL;
197   case fixup_Hexagon_LD_PLT_B22_PCREL:
198     return ELF::R_HEX_LD_PLT_B22_PCREL;
199   case fixup_Hexagon_GD_GOT_LO16:
200     return ELF::R_HEX_GD_GOT_LO16;
201   case fixup_Hexagon_GD_GOT_HI16:
202     return ELF::R_HEX_GD_GOT_HI16;
203   case fixup_Hexagon_GD_GOT_32:
204     return ELF::R_HEX_GD_GOT_32;
205   case fixup_Hexagon_GD_GOT_16:
206     return ELF::R_HEX_GD_GOT_16;
207   case fixup_Hexagon_LD_GOT_LO16:
208     return ELF::R_HEX_LD_GOT_LO16;
209   case fixup_Hexagon_LD_GOT_HI16:
210     return ELF::R_HEX_LD_GOT_HI16;
211   case fixup_Hexagon_LD_GOT_32:
212     return ELF::R_HEX_LD_GOT_32;
213   case fixup_Hexagon_LD_GOT_16:
214     return ELF::R_HEX_LD_GOT_16;
215   case fixup_Hexagon_IE_LO16:
216     return ELF::R_HEX_IE_LO16;
217   case fixup_Hexagon_IE_HI16:
218     return ELF::R_HEX_IE_HI16;
219   case fixup_Hexagon_IE_32:
220     return ELF::R_HEX_IE_32;
221   case fixup_Hexagon_IE_GOT_LO16:
222     return ELF::R_HEX_IE_GOT_LO16;
223   case fixup_Hexagon_IE_GOT_HI16:
224     return ELF::R_HEX_IE_GOT_HI16;
225   case fixup_Hexagon_IE_GOT_32:
226     return ELF::R_HEX_IE_GOT_32;
227   case fixup_Hexagon_IE_GOT_16:
228     return ELF::R_HEX_IE_GOT_16;
229   case fixup_Hexagon_TPREL_LO16:
230     return ELF::R_HEX_TPREL_LO16;
231   case fixup_Hexagon_TPREL_HI16:
232     return ELF::R_HEX_TPREL_HI16;
233   case fixup_Hexagon_TPREL_32:
234     return ELF::R_HEX_TPREL_32;
235   case fixup_Hexagon_TPREL_16:
236     return ELF::R_HEX_TPREL_16;
237   case fixup_Hexagon_6_PCREL_X:
238     return ELF::R_HEX_6_PCREL_X;
239   case fixup_Hexagon_GOTREL_32_6_X:
240     return ELF::R_HEX_GOTREL_32_6_X;
241   case fixup_Hexagon_GOTREL_16_X:
242     return ELF::R_HEX_GOTREL_16_X;
243   case fixup_Hexagon_GOTREL_11_X:
244     return ELF::R_HEX_GOTREL_11_X;
245   case fixup_Hexagon_GOT_32_6_X:
246     return ELF::R_HEX_GOT_32_6_X;
247   case fixup_Hexagon_GOT_16_X:
248     return ELF::R_HEX_GOT_16_X;
249   case fixup_Hexagon_GOT_11_X:
250     return ELF::R_HEX_GOT_11_X;
251   case fixup_Hexagon_DTPREL_32_6_X:
252     return ELF::R_HEX_DTPREL_32_6_X;
253   case fixup_Hexagon_DTPREL_16_X:
254     return ELF::R_HEX_DTPREL_16_X;
255   case fixup_Hexagon_DTPREL_11_X:
256     return ELF::R_HEX_DTPREL_11_X;
257   case fixup_Hexagon_GD_GOT_32_6_X:
258     return ELF::R_HEX_GD_GOT_32_6_X;
259   case fixup_Hexagon_GD_GOT_16_X:
260     return ELF::R_HEX_GD_GOT_16_X;
261   case fixup_Hexagon_GD_GOT_11_X:
262     return ELF::R_HEX_GD_GOT_11_X;
263   case fixup_Hexagon_LD_GOT_32_6_X:
264     return ELF::R_HEX_LD_GOT_32_6_X;
265   case fixup_Hexagon_LD_GOT_16_X:
266     return ELF::R_HEX_LD_GOT_16_X;
267   case fixup_Hexagon_LD_GOT_11_X:
268     return ELF::R_HEX_LD_GOT_11_X;
269   case fixup_Hexagon_IE_32_6_X:
270     return ELF::R_HEX_IE_32_6_X;
271   case fixup_Hexagon_IE_16_X:
272     return ELF::R_HEX_IE_16_X;
273   case fixup_Hexagon_IE_GOT_32_6_X:
274     return ELF::R_HEX_IE_GOT_32_6_X;
275   case fixup_Hexagon_IE_GOT_16_X:
276     return ELF::R_HEX_IE_GOT_16_X;
277   case fixup_Hexagon_IE_GOT_11_X:
278     return ELF::R_HEX_IE_GOT_11_X;
279   case fixup_Hexagon_TPREL_32_6_X:
280     return ELF::R_HEX_TPREL_32_6_X;
281   case fixup_Hexagon_TPREL_16_X:
282     return ELF::R_HEX_TPREL_16_X;
283   case fixup_Hexagon_TPREL_11_X:
284     return ELF::R_HEX_TPREL_11_X;
285   case fixup_Hexagon_23_REG:
286     return ELF::R_HEX_23_REG;
287   case fixup_Hexagon_27_REG:
288     return ELF::R_HEX_27_REG;
289   case fixup_Hexagon_GD_PLT_B22_PCREL_X:
290     return ELF::R_HEX_GD_PLT_B22_PCREL_X;
291   case fixup_Hexagon_GD_PLT_B32_PCREL_X:
292     return ELF::R_HEX_GD_PLT_B32_PCREL_X;
293   case fixup_Hexagon_LD_PLT_B22_PCREL_X:
294     return ELF::R_HEX_LD_PLT_B22_PCREL_X;
295   case fixup_Hexagon_LD_PLT_B32_PCREL_X:
296     return ELF::R_HEX_LD_PLT_B32_PCREL_X;
297   }
298 }
299 
300 std::unique_ptr<MCObjectTargetWriter>
createHexagonELFObjectWriter(uint8_t OSABI,StringRef CPU)301 llvm::createHexagonELFObjectWriter(uint8_t OSABI, StringRef CPU) {
302   return std::make_unique<HexagonELFObjectWriter>(OSABI, CPU);
303 }
304