bfd/
[deliverable/binutils-gdb.git] / bfd / elfarm-nabi.c
1 /* 32-bit ELF support for ARM new abi option.
2 Copyright 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
3
4 This file is part of BFD, the Binary File Descriptor library.
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
19
20 #include "elf/arm.h"
21 #include "bfd.h"
22 #include "sysdep.h"
23 #include "libbfd.h"
24 #include "elf-bfd.h"
25
26 #ifndef NUM_ELEM
27 #define NUM_ELEM(a) (sizeof (a) / (sizeof (a)[0]))
28 #endif
29
30 #define USE_REL 1
31
32 #define TARGET_LITTLE_SYM bfd_elf32_littlearm_vec
33 #define TARGET_LITTLE_NAME "elf32-littlearm"
34 #define TARGET_BIG_SYM bfd_elf32_bigarm_vec
35 #define TARGET_BIG_NAME "elf32-bigarm"
36
37 #define elf_info_to_howto 0
38 #define elf_info_to_howto_rel elf32_arm_info_to_howto
39
40 #define ARM_ELF_ABI_VERSION 0
41 #define ARM_ELF_OS_ABI_VERSION ELFOSABI_ARM
42
43 static reloc_howto_type * elf32_arm_reloc_type_lookup
44 PARAMS ((bfd * abfd, bfd_reloc_code_real_type code));
45 static bfd_boolean elf32_arm_nabi_grok_prstatus
46 PARAMS ((bfd *abfd, Elf_Internal_Note *note));
47 static bfd_boolean elf32_arm_nabi_grok_psinfo
48 PARAMS ((bfd *abfd, Elf_Internal_Note *note));
49
50 /* Note: code such as elf32_arm_reloc_type_lookup expect to use e.g.
51 R_ARM_PC24 as an index into this, and find the R_ARM_PC24 HOWTO
52 in that slot. */
53
54 static reloc_howto_type elf32_arm_howto_table[] =
55 {
56 /* No relocation */
57 HOWTO (R_ARM_NONE, /* type */
58 0, /* rightshift */
59 0, /* size (0 = byte, 1 = short, 2 = long) */
60 0, /* bitsize */
61 FALSE, /* pc_relative */
62 0, /* bitpos */
63 complain_overflow_dont,/* complain_on_overflow */
64 bfd_elf_generic_reloc, /* special_function */
65 "R_ARM_NONE", /* name */
66 FALSE, /* partial_inplace */
67 0, /* src_mask */
68 0, /* dst_mask */
69 FALSE), /* pcrel_offset */
70
71 HOWTO (R_ARM_PC24, /* type */
72 2, /* rightshift */
73 2, /* size (0 = byte, 1 = short, 2 = long) */
74 24, /* bitsize */
75 TRUE, /* pc_relative */
76 0, /* bitpos */
77 complain_overflow_signed,/* complain_on_overflow */
78 bfd_elf_generic_reloc, /* special_function */
79 "R_ARM_PC24", /* name */
80 FALSE, /* partial_inplace */
81 0x00ffffff, /* src_mask */
82 0x00ffffff, /* dst_mask */
83 TRUE), /* pcrel_offset */
84
85 /* 32 bit absolute */
86 HOWTO (R_ARM_ABS32, /* type */
87 0, /* rightshift */
88 2, /* size (0 = byte, 1 = short, 2 = long) */
89 32, /* bitsize */
90 FALSE, /* pc_relative */
91 0, /* bitpos */
92 complain_overflow_bitfield,/* complain_on_overflow */
93 bfd_elf_generic_reloc, /* special_function */
94 "R_ARM_ABS32", /* name */
95 FALSE, /* partial_inplace */
96 0xffffffff, /* src_mask */
97 0xffffffff, /* dst_mask */
98 FALSE), /* pcrel_offset */
99
100 /* standard 32bit pc-relative reloc */
101 HOWTO (R_ARM_REL32, /* type */
102 0, /* rightshift */
103 2, /* size (0 = byte, 1 = short, 2 = long) */
104 32, /* bitsize */
105 TRUE, /* pc_relative */
106 0, /* bitpos */
107 complain_overflow_bitfield,/* complain_on_overflow */
108 bfd_elf_generic_reloc, /* special_function */
109 "R_ARM_REL32", /* name */
110 FALSE, /* partial_inplace */
111 0xffffffff, /* src_mask */
112 0xffffffff, /* dst_mask */
113 TRUE), /* pcrel_offset */
114
115 /* 8 bit absolute */
116 HOWTO (R_ARM_PC13, /* type */
117 0, /* rightshift */
118 0, /* size (0 = byte, 1 = short, 2 = long) */
119 8, /* bitsize */
120 FALSE, /* pc_relative */
121 0, /* bitpos */
122 complain_overflow_bitfield,/* complain_on_overflow */
123 bfd_elf_generic_reloc, /* special_function */
124 "R_ARM_PC13", /* name */
125 FALSE, /* partial_inplace */
126 0x000000ff, /* src_mask */
127 0x000000ff, /* dst_mask */
128 FALSE), /* pcrel_offset */
129
130 /* 16 bit absolute */
131 HOWTO (R_ARM_ABS16, /* type */
132 0, /* rightshift */
133 1, /* size (0 = byte, 1 = short, 2 = long) */
134 16, /* bitsize */
135 FALSE, /* pc_relative */
136 0, /* bitpos */
137 complain_overflow_bitfield,/* complain_on_overflow */
138 bfd_elf_generic_reloc, /* special_function */
139 "R_ARM_ABS16", /* name */
140 FALSE, /* partial_inplace */
141 0x0000ffff, /* src_mask */
142 0x0000ffff, /* dst_mask */
143 FALSE), /* pcrel_offset */
144
145 /* 12 bit absolute */
146 HOWTO (R_ARM_ABS12, /* type */
147 0, /* rightshift */
148 2, /* size (0 = byte, 1 = short, 2 = long) */
149 12, /* bitsize */
150 FALSE, /* pc_relative */
151 0, /* bitpos */
152 complain_overflow_bitfield,/* complain_on_overflow */
153 bfd_elf_generic_reloc, /* special_function */
154 "R_ARM_ABS12", /* name */
155 FALSE, /* partial_inplace */
156 0x000008ff, /* src_mask */
157 0x000008ff, /* dst_mask */
158 FALSE), /* pcrel_offset */
159
160 HOWTO (R_ARM_THM_ABS5, /* type */
161 6, /* rightshift */
162 1, /* size (0 = byte, 1 = short, 2 = long) */
163 5, /* bitsize */
164 FALSE, /* pc_relative */
165 0, /* bitpos */
166 complain_overflow_bitfield,/* complain_on_overflow */
167 bfd_elf_generic_reloc, /* special_function */
168 "R_ARM_THM_ABS5", /* name */
169 FALSE, /* partial_inplace */
170 0x000007e0, /* src_mask */
171 0x000007e0, /* dst_mask */
172 FALSE), /* pcrel_offset */
173
174 /* 8 bit absolute */
175 HOWTO (R_ARM_ABS8, /* type */
176 0, /* rightshift */
177 0, /* size (0 = byte, 1 = short, 2 = long) */
178 8, /* bitsize */
179 FALSE, /* pc_relative */
180 0, /* bitpos */
181 complain_overflow_bitfield,/* complain_on_overflow */
182 bfd_elf_generic_reloc, /* special_function */
183 "R_ARM_ABS8", /* name */
184 FALSE, /* partial_inplace */
185 0x000000ff, /* src_mask */
186 0x000000ff, /* dst_mask */
187 FALSE), /* pcrel_offset */
188
189 HOWTO (R_ARM_SBREL32, /* type */
190 0, /* rightshift */
191 2, /* size (0 = byte, 1 = short, 2 = long) */
192 32, /* bitsize */
193 FALSE, /* pc_relative */
194 0, /* bitpos */
195 complain_overflow_dont,/* complain_on_overflow */
196 bfd_elf_generic_reloc, /* special_function */
197 "R_ARM_SBREL32", /* name */
198 FALSE, /* partial_inplace */
199 0xffffffff, /* src_mask */
200 0xffffffff, /* dst_mask */
201 FALSE), /* pcrel_offset */
202
203 HOWTO (R_ARM_THM_PC22, /* type */
204 1, /* rightshift */
205 2, /* size (0 = byte, 1 = short, 2 = long) */
206 23, /* bitsize */
207 TRUE, /* pc_relative */
208 0, /* bitpos */
209 complain_overflow_signed,/* complain_on_overflow */
210 bfd_elf_generic_reloc, /* special_function */
211 "R_ARM_THM_PC22", /* name */
212 FALSE, /* partial_inplace */
213 0x07ff07ff, /* src_mask */
214 0x07ff07ff, /* dst_mask */
215 TRUE), /* pcrel_offset */
216
217 HOWTO (R_ARM_THM_PC8, /* type */
218 1, /* rightshift */
219 1, /* size (0 = byte, 1 = short, 2 = long) */
220 8, /* bitsize */
221 TRUE, /* pc_relative */
222 0, /* bitpos */
223 complain_overflow_signed,/* complain_on_overflow */
224 bfd_elf_generic_reloc, /* special_function */
225 "R_ARM_THM_PC8", /* name */
226 FALSE, /* partial_inplace */
227 0x000000ff, /* src_mask */
228 0x000000ff, /* dst_mask */
229 TRUE), /* pcrel_offset */
230
231 HOWTO (R_ARM_AMP_VCALL9, /* type */
232 1, /* rightshift */
233 1, /* size (0 = byte, 1 = short, 2 = long) */
234 8, /* bitsize */
235 TRUE, /* pc_relative */
236 0, /* bitpos */
237 complain_overflow_signed,/* complain_on_overflow */
238 bfd_elf_generic_reloc, /* special_function */
239 "R_ARM_AMP_VCALL9", /* name */
240 FALSE, /* partial_inplace */
241 0x000000ff, /* src_mask */
242 0x000000ff, /* dst_mask */
243 TRUE), /* pcrel_offset */
244
245 HOWTO (R_ARM_SWI24, /* type */
246 0, /* rightshift */
247 0, /* size (0 = byte, 1 = short, 2 = long) */
248 0, /* bitsize */
249 FALSE, /* pc_relative */
250 0, /* bitpos */
251 complain_overflow_signed,/* complain_on_overflow */
252 bfd_elf_generic_reloc, /* special_function */
253 "R_ARM_SWI24", /* name */
254 FALSE, /* partial_inplace */
255 0x00000000, /* src_mask */
256 0x00000000, /* dst_mask */
257 FALSE), /* pcrel_offset */
258
259 HOWTO (R_ARM_THM_SWI8, /* type */
260 0, /* rightshift */
261 0, /* size (0 = byte, 1 = short, 2 = long) */
262 0, /* bitsize */
263 FALSE, /* pc_relative */
264 0, /* bitpos */
265 complain_overflow_signed,/* complain_on_overflow */
266 bfd_elf_generic_reloc, /* special_function */
267 "R_ARM_SWI8", /* name */
268 FALSE, /* partial_inplace */
269 0x00000000, /* src_mask */
270 0x00000000, /* dst_mask */
271 FALSE), /* pcrel_offset */
272
273 /* BLX instruction for the ARM. */
274 HOWTO (R_ARM_XPC25, /* type */
275 2, /* rightshift */
276 2, /* size (0 = byte, 1 = short, 2 = long) */
277 25, /* bitsize */
278 TRUE, /* pc_relative */
279 0, /* bitpos */
280 complain_overflow_signed,/* complain_on_overflow */
281 bfd_elf_generic_reloc, /* special_function */
282 "R_ARM_XPC25", /* name */
283 FALSE, /* partial_inplace */
284 0x00ffffff, /* src_mask */
285 0x00ffffff, /* dst_mask */
286 TRUE), /* pcrel_offset */
287
288 /* BLX instruction for the Thumb. */
289 HOWTO (R_ARM_THM_XPC22, /* type */
290 2, /* rightshift */
291 2, /* size (0 = byte, 1 = short, 2 = long) */
292 22, /* bitsize */
293 TRUE, /* pc_relative */
294 0, /* bitpos */
295 complain_overflow_signed,/* complain_on_overflow */
296 bfd_elf_generic_reloc, /* special_function */
297 "R_ARM_THM_XPC22", /* name */
298 FALSE, /* partial_inplace */
299 0x07ff07ff, /* src_mask */
300 0x07ff07ff, /* dst_mask */
301 TRUE), /* pcrel_offset */
302
303 /* These next three relocs are not defined, but we need to fill the space. */
304
305 HOWTO (R_ARM_NONE, /* type */
306 0, /* rightshift */
307 0, /* size (0 = byte, 1 = short, 2 = long) */
308 0, /* bitsize */
309 FALSE, /* pc_relative */
310 0, /* bitpos */
311 complain_overflow_dont,/* complain_on_overflow */
312 bfd_elf_generic_reloc, /* special_function */
313 "R_ARM_unknown_17", /* name */
314 FALSE, /* partial_inplace */
315 0, /* src_mask */
316 0, /* dst_mask */
317 FALSE), /* pcrel_offset */
318
319 HOWTO (R_ARM_NONE, /* type */
320 0, /* rightshift */
321 0, /* size (0 = byte, 1 = short, 2 = long) */
322 0, /* bitsize */
323 FALSE, /* pc_relative */
324 0, /* bitpos */
325 complain_overflow_dont,/* complain_on_overflow */
326 bfd_elf_generic_reloc, /* special_function */
327 "R_ARM_unknown_18", /* name */
328 FALSE, /* partial_inplace */
329 0, /* src_mask */
330 0, /* dst_mask */
331 FALSE), /* pcrel_offset */
332
333 HOWTO (R_ARM_NONE, /* type */
334 0, /* rightshift */
335 0, /* size (0 = byte, 1 = short, 2 = long) */
336 0, /* bitsize */
337 FALSE, /* pc_relative */
338 0, /* bitpos */
339 complain_overflow_dont,/* complain_on_overflow */
340 bfd_elf_generic_reloc, /* special_function */
341 "R_ARM_unknown_19", /* name */
342 FALSE, /* partial_inplace */
343 0, /* src_mask */
344 0, /* dst_mask */
345 FALSE), /* pcrel_offset */
346
347 /* Relocs used in ARM Linux */
348
349 HOWTO (R_ARM_COPY, /* type */
350 0, /* rightshift */
351 2, /* size (0 = byte, 1 = short, 2 = long) */
352 32, /* bitsize */
353 FALSE, /* pc_relative */
354 0, /* bitpos */
355 complain_overflow_bitfield,/* complain_on_overflow */
356 bfd_elf_generic_reloc, /* special_function */
357 "R_ARM_COPY", /* name */
358 TRUE, /* partial_inplace */
359 0xffffffff, /* src_mask */
360 0xffffffff, /* dst_mask */
361 FALSE), /* pcrel_offset */
362
363 HOWTO (R_ARM_GLOB_DAT, /* type */
364 0, /* rightshift */
365 2, /* size (0 = byte, 1 = short, 2 = long) */
366 32, /* bitsize */
367 FALSE, /* pc_relative */
368 0, /* bitpos */
369 complain_overflow_bitfield,/* complain_on_overflow */
370 bfd_elf_generic_reloc, /* special_function */
371 "R_ARM_GLOB_DAT", /* name */
372 TRUE, /* partial_inplace */
373 0xffffffff, /* src_mask */
374 0xffffffff, /* dst_mask */
375 FALSE), /* pcrel_offset */
376
377 HOWTO (R_ARM_JUMP_SLOT, /* type */
378 0, /* rightshift */
379 2, /* size (0 = byte, 1 = short, 2 = long) */
380 32, /* bitsize */
381 FALSE, /* pc_relative */
382 0, /* bitpos */
383 complain_overflow_bitfield,/* complain_on_overflow */
384 bfd_elf_generic_reloc, /* special_function */
385 "R_ARM_JUMP_SLOT", /* name */
386 TRUE, /* partial_inplace */
387 0xffffffff, /* src_mask */
388 0xffffffff, /* dst_mask */
389 FALSE), /* pcrel_offset */
390
391 HOWTO (R_ARM_RELATIVE, /* type */
392 0, /* rightshift */
393 2, /* size (0 = byte, 1 = short, 2 = long) */
394 32, /* bitsize */
395 FALSE, /* pc_relative */
396 0, /* bitpos */
397 complain_overflow_bitfield,/* complain_on_overflow */
398 bfd_elf_generic_reloc, /* special_function */
399 "R_ARM_RELATIVE", /* name */
400 TRUE, /* partial_inplace */
401 0xffffffff, /* src_mask */
402 0xffffffff, /* dst_mask */
403 FALSE), /* pcrel_offset */
404
405 HOWTO (R_ARM_GOTOFF, /* type */
406 0, /* rightshift */
407 2, /* size (0 = byte, 1 = short, 2 = long) */
408 32, /* bitsize */
409 FALSE, /* pc_relative */
410 0, /* bitpos */
411 complain_overflow_bitfield,/* complain_on_overflow */
412 bfd_elf_generic_reloc, /* special_function */
413 "R_ARM_GOTOFF", /* name */
414 TRUE, /* partial_inplace */
415 0xffffffff, /* src_mask */
416 0xffffffff, /* dst_mask */
417 FALSE), /* pcrel_offset */
418
419 HOWTO (R_ARM_GOTPC, /* type */
420 0, /* rightshift */
421 2, /* size (0 = byte, 1 = short, 2 = long) */
422 32, /* bitsize */
423 TRUE, /* pc_relative */
424 0, /* bitpos */
425 complain_overflow_bitfield,/* complain_on_overflow */
426 bfd_elf_generic_reloc, /* special_function */
427 "R_ARM_GOTPC", /* name */
428 TRUE, /* partial_inplace */
429 0xffffffff, /* src_mask */
430 0xffffffff, /* dst_mask */
431 TRUE), /* pcrel_offset */
432
433 HOWTO (R_ARM_GOT32, /* type */
434 0, /* rightshift */
435 2, /* size (0 = byte, 1 = short, 2 = long) */
436 32, /* bitsize */
437 FALSE, /* pc_relative */
438 0, /* bitpos */
439 complain_overflow_bitfield,/* complain_on_overflow */
440 bfd_elf_generic_reloc, /* special_function */
441 "R_ARM_GOT32", /* name */
442 TRUE, /* partial_inplace */
443 0xffffffff, /* src_mask */
444 0xffffffff, /* dst_mask */
445 FALSE), /* pcrel_offset */
446
447 HOWTO (R_ARM_PLT32, /* type */
448 2, /* rightshift */
449 2, /* size (0 = byte, 1 = short, 2 = long) */
450 26, /* bitsize */
451 TRUE, /* pc_relative */
452 0, /* bitpos */
453 complain_overflow_bitfield,/* complain_on_overflow */
454 bfd_elf_generic_reloc, /* special_function */
455 "R_ARM_PLT32", /* name */
456 TRUE, /* partial_inplace */
457 0x00ffffff, /* src_mask */
458 0x00ffffff, /* dst_mask */
459 TRUE), /* pcrel_offset */
460
461 /* End of relocs used in ARM Linux */
462
463 HOWTO (R_ARM_RREL32, /* type */
464 0, /* rightshift */
465 0, /* size (0 = byte, 1 = short, 2 = long) */
466 0, /* bitsize */
467 FALSE, /* pc_relative */
468 0, /* bitpos */
469 complain_overflow_dont,/* complain_on_overflow */
470 bfd_elf_generic_reloc, /* special_function */
471 "R_ARM_RREL32", /* name */
472 FALSE, /* partial_inplace */
473 0, /* src_mask */
474 0, /* dst_mask */
475 FALSE), /* pcrel_offset */
476
477 HOWTO (R_ARM_RABS32, /* type */
478 0, /* rightshift */
479 0, /* size (0 = byte, 1 = short, 2 = long) */
480 0, /* bitsize */
481 FALSE, /* pc_relative */
482 0, /* bitpos */
483 complain_overflow_dont,/* complain_on_overflow */
484 bfd_elf_generic_reloc, /* special_function */
485 "R_ARM_RABS32", /* name */
486 FALSE, /* partial_inplace */
487 0, /* src_mask */
488 0, /* dst_mask */
489 FALSE), /* pcrel_offset */
490
491 HOWTO (R_ARM_RPC24, /* type */
492 0, /* rightshift */
493 0, /* size (0 = byte, 1 = short, 2 = long) */
494 0, /* bitsize */
495 FALSE, /* pc_relative */
496 0, /* bitpos */
497 complain_overflow_dont,/* complain_on_overflow */
498 bfd_elf_generic_reloc, /* special_function */
499 "R_ARM_RPC24", /* name */
500 FALSE, /* partial_inplace */
501 0, /* src_mask */
502 0, /* dst_mask */
503 FALSE), /* pcrel_offset */
504
505 HOWTO (R_ARM_RBASE, /* type */
506 0, /* rightshift */
507 0, /* size (0 = byte, 1 = short, 2 = long) */
508 0, /* bitsize */
509 FALSE, /* pc_relative */
510 0, /* bitpos */
511 complain_overflow_dont,/* complain_on_overflow */
512 bfd_elf_generic_reloc, /* special_function */
513 "R_ARM_RBASE", /* name */
514 FALSE, /* partial_inplace */
515 0, /* src_mask */
516 0, /* dst_mask */
517 FALSE), /* pcrel_offset */
518
519 HOWTO (R_ARM_ALU_PCREL7_0, /* type */
520 0, /* rightshift */
521 2, /* size (0 = byte, 1 = short, 2 = long) */
522 12, /* bitsize */
523 TRUE, /* pc_relative */
524 0, /* bitpos */
525 complain_overflow_dont,/* complain_on_overflow */
526 bfd_elf_generic_reloc, /* special_function */
527 "R_ARM_ALU_PCREL_7_0", /* name */
528 FALSE, /* partial_inplace */
529 0x00000fff, /* src_mask */
530 0x00000fff, /* dst_mask */
531 TRUE), /* pcrel_offset */
532
533 HOWTO (R_ARM_ALU_PCREL15_8, /* type */
534 0, /* rightshift */
535 2, /* size (0 = byte, 1 = short, 2 = long) */
536 12, /* bitsize */
537 TRUE, /* pc_relative */
538 8, /* bitpos */
539 complain_overflow_dont,/* complain_on_overflow */
540 bfd_elf_generic_reloc, /* special_function */
541 "R_ARM_ALU_PCREL_15_8",/* name */
542 FALSE, /* partial_inplace */
543 0x00000fff, /* src_mask */
544 0x00000fff, /* dst_mask */
545 TRUE), /* pcrel_offset */
546
547 HOWTO (R_ARM_ALU_PCREL23_15, /* type */
548 0, /* rightshift */
549 2, /* size (0 = byte, 1 = short, 2 = long) */
550 12, /* bitsize */
551 TRUE, /* pc_relative */
552 16, /* bitpos */
553 complain_overflow_dont,/* complain_on_overflow */
554 bfd_elf_generic_reloc, /* special_function */
555 "R_ARM_ALU_PCREL_23_15",/* name */
556 FALSE, /* partial_inplace */
557 0x00000fff, /* src_mask */
558 0x00000fff, /* dst_mask */
559 TRUE), /* pcrel_offset */
560
561 HOWTO (R_ARM_LDR_SBREL_11_0, /* type */
562 0, /* rightshift */
563 2, /* size (0 = byte, 1 = short, 2 = long) */
564 12, /* bitsize */
565 FALSE, /* pc_relative */
566 0, /* bitpos */
567 complain_overflow_dont,/* complain_on_overflow */
568 bfd_elf_generic_reloc, /* special_function */
569 "R_ARM_LDR_SBREL_11_0",/* name */
570 FALSE, /* partial_inplace */
571 0x00000fff, /* src_mask */
572 0x00000fff, /* dst_mask */
573 FALSE), /* pcrel_offset */
574
575 HOWTO (R_ARM_ALU_SBREL_19_12, /* type */
576 0, /* rightshift */
577 2, /* size (0 = byte, 1 = short, 2 = long) */
578 8, /* bitsize */
579 FALSE, /* pc_relative */
580 12, /* bitpos */
581 complain_overflow_dont,/* complain_on_overflow */
582 bfd_elf_generic_reloc, /* special_function */
583 "R_ARM_ALU_SBREL_19_12",/* name */
584 FALSE, /* partial_inplace */
585 0x000ff000, /* src_mask */
586 0x000ff000, /* dst_mask */
587 FALSE), /* pcrel_offset */
588
589 HOWTO (R_ARM_ALU_SBREL_27_20, /* type */
590 0, /* rightshift */
591 2, /* size (0 = byte, 1 = short, 2 = long) */
592 8, /* bitsize */
593 FALSE, /* pc_relative */
594 20, /* bitpos */
595 complain_overflow_dont,/* complain_on_overflow */
596 bfd_elf_generic_reloc, /* special_function */
597 "R_ARM_ALU_SBREL_27_20",/* name */
598 FALSE, /* partial_inplace */
599 0x0ff00000, /* src_mask */
600 0x0ff00000, /* dst_mask */
601 FALSE), /* pcrel_offset */
602
603 HOWTO (R_ARM_RELABS32, /* type */
604 0, /* rightshift */
605 2, /* size (0 = byte, 1 = short, 2 = long) */
606 32, /* bitsize */
607 FALSE, /* pc_relative */
608 0, /* bitpos */
609 complain_overflow_dont,/* complain_on_overflow */
610 bfd_elf_generic_reloc, /* special_function */
611 "R_ARM_RELABS32", /* name */
612 FALSE, /* partial_inplace */
613 0xffffffff, /* src_mask */
614 0xffffffff, /* dst_mask */
615 FALSE), /* pcrel_offset */
616
617 HOWTO (R_ARM_ROSEGREL32, /* type */
618 0, /* rightshift */
619 2, /* size (0 = byte, 1 = short, 2 = long) */
620 32, /* bitsize */
621 FALSE, /* pc_relative */
622 0, /* bitpos */
623 complain_overflow_dont,/* complain_on_overflow */
624 bfd_elf_generic_reloc, /* special_function */
625 "R_ARM_ROSEGREL32", /* name */
626 FALSE, /* partial_inplace */
627 0xffffffff, /* src_mask */
628 0xffffffff, /* dst_mask */
629 FALSE), /* pcrel_offset */
630
631 HOWTO (R_ARM_V4BX, /* type */
632 0, /* rightshift */
633 2, /* size (0 = byte, 1 = short, 2 = long) */
634 32, /* bitsize */
635 FALSE, /* pc_relative */
636 0, /* bitpos */
637 complain_overflow_dont,/* complain_on_overflow */
638 bfd_elf_generic_reloc, /* special_function */
639 "R_ARM_V4BX", /* name */
640 FALSE, /* partial_inplace */
641 0xffffffff, /* src_mask */
642 0xffffffff, /* dst_mask */
643 FALSE), /* pcrel_offset */
644 };
645
646 /* GNU extension to record C++ vtable hierarchy */
647 static reloc_howto_type elf32_arm_vtinherit_howto =
648 HOWTO (R_ARM_GNU_VTINHERIT, /* type */
649 0, /* rightshift */
650 2, /* size (0 = byte, 1 = short, 2 = long) */
651 0, /* bitsize */
652 FALSE, /* pc_relative */
653 0, /* bitpos */
654 complain_overflow_dont, /* complain_on_overflow */
655 NULL, /* special_function */
656 "R_ARM_GNU_VTINHERIT", /* name */
657 FALSE, /* partial_inplace */
658 0, /* src_mask */
659 0, /* dst_mask */
660 FALSE); /* pcrel_offset */
661
662 /* GNU extension to record C++ vtable member usage */
663 static reloc_howto_type elf32_arm_vtentry_howto =
664 HOWTO (R_ARM_GNU_VTENTRY, /* type */
665 0, /* rightshift */
666 2, /* size (0 = byte, 1 = short, 2 = long) */
667 0, /* bitsize */
668 FALSE, /* pc_relative */
669 0, /* bitpos */
670 complain_overflow_dont, /* complain_on_overflow */
671 _bfd_elf_rel_vtable_reloc_fn, /* special_function */
672 "R_ARM_GNU_VTENTRY", /* name */
673 FALSE, /* partial_inplace */
674 0, /* src_mask */
675 0, /* dst_mask */
676 FALSE); /* pcrel_offset */
677
678 /* 12 bit pc relative */
679 static reloc_howto_type elf32_arm_thm_pc11_howto =
680 HOWTO (R_ARM_THM_PC11, /* type */
681 1, /* rightshift */
682 1, /* size (0 = byte, 1 = short, 2 = long) */
683 11, /* bitsize */
684 TRUE, /* pc_relative */
685 0, /* bitpos */
686 complain_overflow_signed, /* complain_on_overflow */
687 bfd_elf_generic_reloc, /* special_function */
688 "R_ARM_THM_PC11", /* name */
689 FALSE, /* partial_inplace */
690 0x000007ff, /* src_mask */
691 0x000007ff, /* dst_mask */
692 TRUE); /* pcrel_offset */
693
694 /* 12 bit pc relative */
695 static reloc_howto_type elf32_arm_thm_pc9_howto =
696 HOWTO (R_ARM_THM_PC9, /* type */
697 1, /* rightshift */
698 1, /* size (0 = byte, 1 = short, 2 = long) */
699 8, /* bitsize */
700 TRUE, /* pc_relative */
701 0, /* bitpos */
702 complain_overflow_signed, /* complain_on_overflow */
703 bfd_elf_generic_reloc, /* special_function */
704 "R_ARM_THM_PC9", /* name */
705 FALSE, /* partial_inplace */
706 0x000000ff, /* src_mask */
707 0x000000ff, /* dst_mask */
708 TRUE); /* pcrel_offset */
709
710 static void elf32_arm_info_to_howto
711 PARAMS ((bfd *, arelent *, Elf_Internal_Rela *));
712
713 static void
714 elf32_arm_info_to_howto (abfd, bfd_reloc, elf_reloc)
715 bfd * abfd ATTRIBUTE_UNUSED;
716 arelent * bfd_reloc;
717 Elf_Internal_Rela * elf_reloc;
718 {
719 unsigned int r_type;
720
721 r_type = ELF32_R_TYPE (elf_reloc->r_info);
722
723 switch (r_type)
724 {
725 case R_ARM_GNU_VTINHERIT:
726 bfd_reloc->howto = & elf32_arm_vtinherit_howto;
727 break;
728
729 case R_ARM_GNU_VTENTRY:
730 bfd_reloc->howto = & elf32_arm_vtentry_howto;
731 break;
732
733 case R_ARM_THM_PC11:
734 bfd_reloc->howto = & elf32_arm_thm_pc11_howto;
735 break;
736
737 case R_ARM_THM_PC9:
738 bfd_reloc->howto = & elf32_arm_thm_pc9_howto;
739 break;
740
741 default:
742 if (r_type >= NUM_ELEM (elf32_arm_howto_table))
743 bfd_reloc->howto = NULL;
744 else
745 bfd_reloc->howto = & elf32_arm_howto_table[r_type];
746 break;
747 }
748 }
749
750 struct elf32_arm_reloc_map
751 {
752 bfd_reloc_code_real_type bfd_reloc_val;
753 unsigned char elf_reloc_val;
754 };
755
756 static const struct elf32_arm_reloc_map elf32_arm_reloc_map[] =
757 {
758 {BFD_RELOC_NONE, R_ARM_NONE},
759 {BFD_RELOC_ARM_PCREL_BRANCH, R_ARM_PC24},
760 {BFD_RELOC_ARM_PCREL_BLX, R_ARM_XPC25},
761 {BFD_RELOC_THUMB_PCREL_BLX, R_ARM_THM_XPC22},
762 {BFD_RELOC_32, R_ARM_ABS32},
763 {BFD_RELOC_32_PCREL, R_ARM_REL32},
764 {BFD_RELOC_8, R_ARM_ABS8},
765 {BFD_RELOC_16, R_ARM_ABS16},
766 {BFD_RELOC_ARM_OFFSET_IMM, R_ARM_ABS12},
767 {BFD_RELOC_ARM_THUMB_OFFSET, R_ARM_THM_ABS5},
768 {BFD_RELOC_THUMB_PCREL_BRANCH23, R_ARM_THM_PC22},
769 {BFD_RELOC_ARM_COPY, R_ARM_COPY},
770 {BFD_RELOC_ARM_GLOB_DAT, R_ARM_GLOB_DAT},
771 {BFD_RELOC_ARM_JUMP_SLOT, R_ARM_JUMP_SLOT},
772 {BFD_RELOC_ARM_RELATIVE, R_ARM_RELATIVE},
773 {BFD_RELOC_ARM_GOTOFF, R_ARM_GOTOFF},
774 {BFD_RELOC_ARM_GOTPC, R_ARM_GOTPC},
775 {BFD_RELOC_ARM_GOT32, R_ARM_GOT32},
776 {BFD_RELOC_ARM_PLT32, R_ARM_PLT32},
777 {BFD_RELOC_ARM_RELABS32, R_ARM_RELABS32},
778 {BFD_RELOC_ARM_ROSEGREL32, R_ARM_ROSEGREL32},
779 {BFD_RELOC_ARM_SBREL32, R_ARM_SBREL32}
780 };
781
782 static reloc_howto_type *
783 elf32_arm_reloc_type_lookup (abfd, code)
784 bfd *abfd ATTRIBUTE_UNUSED;
785 bfd_reloc_code_real_type code;
786 {
787 unsigned int i;
788
789 switch (code)
790 {
791 case BFD_RELOC_VTABLE_INHERIT:
792 return & elf32_arm_vtinherit_howto;
793
794 case BFD_RELOC_VTABLE_ENTRY:
795 return & elf32_arm_vtentry_howto;
796
797 case BFD_RELOC_THUMB_PCREL_BRANCH12:
798 return & elf32_arm_thm_pc11_howto;
799
800 case BFD_RELOC_THUMB_PCREL_BRANCH9:
801 return & elf32_arm_thm_pc9_howto;
802
803 default:
804 for (i = 0; i < NUM_ELEM (elf32_arm_reloc_map); i ++)
805 if (elf32_arm_reloc_map[i].bfd_reloc_val == code)
806 return & elf32_arm_howto_table[elf32_arm_reloc_map[i].elf_reloc_val];
807
808 return NULL;
809 }
810 }
811
812 /* Support for core dump NOTE sections */
813 static bfd_boolean
814 elf32_arm_nabi_grok_prstatus (abfd, note)
815 bfd *abfd;
816 Elf_Internal_Note *note;
817 {
818 int offset;
819 size_t size;
820
821 switch (note->descsz)
822 {
823 default:
824 return FALSE;
825
826 case 148: /* Linux/ARM 32-bit*/
827 /* pr_cursig */
828 elf_tdata (abfd)->core_signal = bfd_get_16 (abfd, note->descdata + 12);
829
830 /* pr_pid */
831 elf_tdata (abfd)->core_pid = bfd_get_32 (abfd, note->descdata + 24);
832
833 /* pr_reg */
834 offset = 72;
835 size = 72;
836
837 break;
838 }
839
840 /* Make a ".reg/999" section. */
841 return _bfd_elfcore_make_pseudosection (abfd, ".reg",
842 size, note->descpos + offset);
843 }
844
845 static bfd_boolean
846 elf32_arm_nabi_grok_psinfo (abfd, note)
847 bfd *abfd;
848 Elf_Internal_Note *note;
849 {
850 switch (note->descsz)
851 {
852 default:
853 return FALSE;
854
855 case 124: /* Linux/ARM elf_prpsinfo */
856 elf_tdata (abfd)->core_program
857 = _bfd_elfcore_strndup (abfd, note->descdata + 28, 16);
858 elf_tdata (abfd)->core_command
859 = _bfd_elfcore_strndup (abfd, note->descdata + 44, 80);
860 }
861
862 /* Note that for some reason, a spurious space is tacked
863 onto the end of the args in some (at least one anyway)
864 implementations, so strip it off if it exists. */
865
866 {
867 char *command = elf_tdata (abfd)->core_command;
868 int n = strlen (command);
869
870 if (0 < n && command[n - 1] == ' ')
871 command[n - 1] = '\0';
872 }
873
874 return TRUE;
875 }
876
877 #define elf_backend_grok_prstatus elf32_arm_nabi_grok_prstatus
878 #define elf_backend_grok_psinfo elf32_arm_nabi_grok_psinfo
879
880 #include "elf32-arm.h"
This page took 0.06262 seconds and 4 git commands to generate.