xref: /illumos-gate/usr/src/lib/libdwarf/common/dwarf_elf_rel_detector.c (revision 4d9fdb46b215739778ebc12079842c9905586999)
1 /*
2 Copyright (c) 2019, David Anderson
3 All rights reserved.
4 cc
5 Redistribution and use in source and binary forms, with
6 or without modification, are permitted provided that the
7 following conditions are met:
8 
9     Redistributions of source code must retain the above
10     copyright notice, this list of conditions and the following
11     disclaimer.
12 
13     Redistributions in binary form must reproduce the above
14     copyright notice, this list of conditions and the following
15     disclaimer in the documentation and/or other materials
16     provided with the distribution.
17 
18 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
19 CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
20 INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
21 OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
23 CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24 SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
25 NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
26 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27 HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28 CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
29 OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
30 EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 */
32 
33 #include "config.h"
34 #include <stdio.h>
35 #include "dwarf_elf_defines.h"
36 #include "dwarf_elf_rel_detector.h"
37 
38 unsigned
_dwarf_is_32bit_abs_reloc(unsigned int type,unsigned machine)39 _dwarf_is_32bit_abs_reloc(unsigned int type, unsigned machine)
40 {
41     unsigned r = 0;
42 
43     switch (machine) {
44 #if defined(EM_MIPS) && defined (R_MIPS_32)
45     case EM_MIPS:
46         r =  (0
47 #if defined (R_MIPS_32)
48             | (type == R_MIPS_32)
49 #endif
50 #if defined (R_MIPS_TLS_DTPREL32)
51             | (type == R_MIPS_TLS_DTPREL32)
52 #endif /* DTPREL32 */
53             );
54         break;
55 #endif /* MIPS case */
56 #if defined(EM_SPARC32PLUS)  && defined (R_SPARC_UA32)
57     case EM_SPARC32PLUS:
58         r = (0
59 #if defined(R_SPARC_UA32)
60             | (type == R_SPARC_UA32)
61 #endif
62 #if defined(R_SPARC_TLS_DTPOFF32)
63             | (type == R_SPARC_TLS_DTPOFF32)
64 #endif
65             );
66         break;
67 #endif
68 #if defined(EM_SPARCV9)  && defined (R_SPARC_UA32)
69     case EM_SPARCV9:
70         r =  (type == R_SPARC_UA32);
71         break;
72 #endif
73 #if defined(EM_SPARC) && defined (R_SPARC_UA32)
74     case EM_SPARC:
75         r =  (0
76 #if defined(R_SPARC_UA32)
77             | (type == R_SPARC_UA32)
78 #endif
79 #if (R_SPARC_TLS_DTPOFF32)
80             | (type == R_SPARC_TLS_DTPOFF32)
81 #endif
82             );
83         break;
84 #endif /* EM_SPARC */
85 #if defined(EM_386) && defined (R_386_32) && defined (R_386_PC32)
86     case EM_386:
87         r = (0
88 #if defined (R_386_32)
89             |  (type == R_386_32)
90 #endif
91 #if defined (R_386_PC32)
92             |  (type == R_386_PC32)
93 #endif
94 #if defined (R_386_TLS_LDO_32)
95             | (type == R_386_TLS_LDO_32)
96 #endif
97 #if defined (R_386_TLS_DTPOFF32)
98             | (type == R_386_TLS_DTPOFF32)
99 #endif
100 #if defined (R_386_GOTPC)
101 	    | (type == R_386_GOTPC)
102 #endif
103             );
104         break;
105 #endif /* EM_386 */
106 
107 #if defined (EM_SH) && defined (R_SH_DIR32)
108     case EM_SH:
109         r = (0
110 #if defined (R_SH_DIR32)
111             | (type == R_SH_DIR32)
112 #endif
113 #if defined (R_SH_DTPOFF32)
114             | (type == R_SH_TLS_DTPOFF32)
115 #endif
116             );
117         break;
118 #endif /* SH */
119 
120 #if defined(EM_IA_64) && defined (R_IA64_SECREL32LSB)
121     case EM_IA_64:  /* 32bit? ! */
122         r = (0
123 #if defined (R_IA64_SECREL32LSB)
124             | (type == R_IA64_SECREL32LSB)
125 #endif
126 #if defined (R_IA64_DIR32LSB)
127             | (type == R_IA64_DIR32LSB)
128 #endif
129 #if defined (R_IA64_DTPREL32LSB)
130             | (type == R_IA64_DTPREL32LSB)
131 #endif
132             );
133         break;
134 #endif /* EM_IA_64 */
135 
136 #if defined(EM_ARM) && defined (R_ARM_ABS32)
137     case EM_ARM:
138     case EM_AARCH64:
139         r = (0
140 #if defined (R_ARM_ABS32)
141             | ( type == R_ARM_ABS32)
142 #endif
143 #if defined (R_AARCH64_ABS32)
144             | ( type == R_AARCH64_ABS32)
145 #endif
146 #if defined (R_ARM_TLS_LDO32)
147             | ( type == R_ARM_TLS_LDO32)
148 #endif
149             );
150         break;
151 #endif /* EM_ARM */
152 
153 /*  On FreeBSD xR_PPC64_ADDR32 not defined
154     so we use the xR_PPC_ names which
155     have the proper value.
156     Our headers have:
157     xR_PPC64_ADDR64   38
158     xR_PPC_ADDR32     1 so we use this one
159     xR_PPC64_ADDR32   R_PPC_ADDR32
160 
161     xR_PPC64_DTPREL32 110  which may be wrong/unavailable
162     xR_PPC64_DTPREL64 78
163     xR_PPC_DTPREL32   78
164     */
165 #if defined(EM_PPC64) && defined (R_PPC_ADDR32)
166     case EM_PPC64:
167         r = (0
168 #if defined(R_PPC_ADDR32)
169             | (type == R_PPC_ADDR32)
170 #endif
171 #if defined(R_PPC64_DTPREL32)
172             | (type == R_PPC64_DTPREL32)
173 #endif
174             );
175         break;
176 #endif /* EM_PPC64 */
177 
178 
179 #if defined(EM_PPC) && defined (R_PPC_ADDR32)
180     case EM_PPC:
181         r = (0
182 #if defined (R_PPC_ADDR32)
183             | (type == R_PPC_ADDR32)
184 #endif
185 #if defined (R_PPC_DTPREL32)
186             | (type == R_PPC_DTPREL32)
187 #endif
188             );
189         break;
190 #endif /* EM_PPC */
191 
192 #if defined(EM_S390) && defined (R_390_32)
193     case EM_S390:
194         r = (0
195 #if defined (R_390_32)
196             | (type == R_390_32)
197 #endif
198 #if defined (R_390_TLS_LDO32)
199             | (type == R_390_TLS_LDO32)
200 #endif
201             );
202         break;
203 #endif /* EM_S390 */
204 
205 #if defined(EM_X86_64) && ( defined(R_X86_64_32) || defined(R_X86_64_PC32) || defined(R_X86_64_DTPOFF32) )
206 #if defined(EM_K10M)
207     case EM_K10M:
208 #endif
209 #if defined(EM_L10M)
210     case EM_L10M:
211 #endif
212     case EM_X86_64:
213         r = (0
214 #if defined (R_X86_64_PC32)
215             | (type == R_X86_64_PC32)
216 #endif
217 #if defined (R_X86_64_32)
218             | (type == R_X86_64_32)
219 #endif
220 #if defined (R_X86_64_DTPOFF32)
221             | (type ==  R_X86_64_DTPOFF32)
222 #endif
223             );
224         break;
225 #endif /* EM_X86_64 */
226 
227     case  EM_QUALCOMM_DSP6:
228         r = (type == R_QUALCOMM_REL32);
229         break;
230     }
231     return r;
232 }
233 
234 unsigned
_dwarf_is_64bit_abs_reloc(unsigned int type,unsigned machine)235 _dwarf_is_64bit_abs_reloc(unsigned int type, unsigned machine)
236 {
237     unsigned r = 0;
238 
239     switch (machine) {
240 #if defined(EM_MIPS) && defined (R_MIPS_64)
241     case EM_MIPS:
242         r = (0
243 #if defined (R_MIPS_64)
244             | (type == R_MIPS_64)
245 #endif
246 #if defined (R_MIPS_32)
247             | (type == R_MIPS_32)
248 #endif
249 #if defined(R_MIPS_TLS_DTPREL64)
250             | (type == R_MIPS_TLS_DTPREL64)
251 #endif
252             );
253         break;
254 #endif /* EM_MIPS */
255 #if defined(EM_SPARC32PLUS) && defined (R_SPARC_UA64)
256     case EM_SPARC32PLUS:
257         r =  (type == R_SPARC_UA64);
258         break;
259 #endif
260 #if defined(EM_SPARCV9) && defined (R_SPARC_UA64)
261     case EM_SPARCV9:
262         r = (0
263 #if defined (R_SPARC_UA64)
264             | (type == R_SPARC_UA64)
265 #endif
266 #if defined (R_SPARC_TLS_DTPOFF64)
267             | (type == R_SPARC_TLS_DTPOFF64)
268 #endif
269             );
270         break;
271 #endif
272 #if defined(EM_SPARC) && defined (R_SPARC_UA64)
273     case EM_SPARC:
274         r = (0
275 #if defined(R_SPARC_UA64)
276             | (type == R_SPARC_UA64)
277 #endif
278 #if defined (R_SPARC_TLS_DTPOFF64)
279             | (type == R_SPARC_TLS_DTPOFF64)
280 #endif
281             );
282         break;
283 #endif /* EM_SPARC */
284 
285 #if defined(EM_IA_64) && defined (R_IA64_SECREL64LSB)
286     case EM_IA_64: /* 64bit */
287         r = (0
288 #if defined (R_IA64_SECREL64LSB)
289             | (type == R_IA64_SECREL64LSB)
290 #endif
291 #if defined (R_IA64_SECREL32LSB)
292             | (type == R_IA64_SECREL32LSB)
293 #endif
294 #if defined (R_IA64_DIR64LSB)
295             | (type == R_IA64_DIR64LSB)
296 #endif
297 #if defined (R_IA64_DTPREL64LSB)
298             | (type == R_IA64_DTPREL64LSB)
299 #endif
300 #if defined (R_IA64_REL32LSB)
301             | (type == R_IA64_REL32LSB)
302 #endif
303             );
304         break;
305 #endif /* EM_IA_64 */
306 
307 #if defined(EM_PPC64) && defined (R_PPC64_ADDR64)
308     case EM_PPC64:
309         r = (0
310 #if defined(R_PPC64_ADDR64)
311             | (type == R_PPC64_ADDR64)
312 #endif
313 #if defined(R_PPC64_DTPREL64)
314             | (type == R_PPC64_DTPREL64)
315 #endif
316             );
317         break;
318 #endif /* EM_PPC64 */
319 
320 #if defined(EM_S390) && defined (R_390_64)
321     case EM_S390:
322         r = (0
323 #if defined(R_390_64)
324             | (type == R_390_64)
325 #endif
326 #if defined(R_390_TLS_LDO64)
327             | (type == R_390_TLS_LDO64)
328 #endif
329             );
330         break;
331 #endif /* EM_390 */
332 
333 #if defined(EM_X86_64) && defined (R_X86_64_64)
334 #if defined(EM_K10M)
335     case EM_K10M:
336 #endif
337 #if defined(EM_L10M)
338     case EM_L10M:
339 #endif
340     case EM_X86_64:
341         r = (0
342 #if defined (R_X86_64_64)
343             | (type == R_X86_64_64)
344 #endif
345 #if defined (R_X86_64_DTPOFF32)
346             | (type == R_X86_64_DTPOFF64)
347 #endif
348             );
349         break;
350 #endif /* EM_X86_64 */
351 #if defined(EM_AARCH64) && defined (R_AARCH64_ABS64)
352     case EM_AARCH64:
353         r = (0
354 #if defined (R_AARCH64_ABS64)
355             | ( type == R_AARCH64_ABS64)
356 #endif
357             );
358         break;
359 #endif /* EM_AARCH64 */
360 
361     }
362     return r;
363 }
364