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