fix spelling typo in ChangeLog entry
[binutils.git] / bfd / elfarm-nabi.c
blob3eb2cbdf59040c4ad4bb4f0dda394d8099809588
1 /* 32-bit ELF support for ARM new abi option.
2 Copyright 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
4 This file is part of BFD, the Binary File Descriptor library.
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.
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.
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. */
20 #include "elf/arm.h"
21 #include "bfd.h"
22 #include "sysdep.h"
23 #include "libbfd.h"
24 #include "elf-bfd.h"
26 #ifndef NUM_ELEM
27 #define NUM_ELEM(a) (sizeof (a) / (sizeof (a)[0]))
28 #endif
30 #define USE_REL 1
32 #define elf_info_to_howto 0
33 #define elf_info_to_howto_rel elf32_arm_info_to_howto
35 #define ARM_ELF_ABI_VERSION 0
36 #define ARM_ELF_OS_ABI_VERSION ELFOSABI_ARM
38 static reloc_howto_type * elf32_arm_reloc_type_lookup
39 PARAMS ((bfd * abfd, bfd_reloc_code_real_type code));
40 static bfd_boolean elf32_arm_nabi_grok_prstatus
41 PARAMS ((bfd *abfd, Elf_Internal_Note *note));
42 static bfd_boolean elf32_arm_nabi_grok_psinfo
43 PARAMS ((bfd *abfd, Elf_Internal_Note *note));
45 /* Note: code such as elf32_arm_reloc_type_lookup expect to use e.g.
46 R_ARM_PC24 as an index into this, and find the R_ARM_PC24 HOWTO
47 in that slot. */
49 static reloc_howto_type elf32_arm_howto_table[] =
51 /* No relocation */
52 HOWTO (R_ARM_NONE, /* type */
53 0, /* rightshift */
54 0, /* size (0 = byte, 1 = short, 2 = long) */
55 0, /* bitsize */
56 FALSE, /* pc_relative */
57 0, /* bitpos */
58 complain_overflow_dont,/* complain_on_overflow */
59 bfd_elf_generic_reloc, /* special_function */
60 "R_ARM_NONE", /* name */
61 FALSE, /* partial_inplace */
62 0, /* src_mask */
63 0, /* dst_mask */
64 FALSE), /* pcrel_offset */
66 HOWTO (R_ARM_PC24, /* type */
67 2, /* rightshift */
68 2, /* size (0 = byte, 1 = short, 2 = long) */
69 24, /* bitsize */
70 TRUE, /* pc_relative */
71 0, /* bitpos */
72 complain_overflow_signed,/* complain_on_overflow */
73 bfd_elf_generic_reloc, /* special_function */
74 "R_ARM_PC24", /* name */
75 FALSE, /* partial_inplace */
76 0x00ffffff, /* src_mask */
77 0x00ffffff, /* dst_mask */
78 TRUE), /* pcrel_offset */
80 /* 32 bit absolute */
81 HOWTO (R_ARM_ABS32, /* type */
82 0, /* rightshift */
83 2, /* size (0 = byte, 1 = short, 2 = long) */
84 32, /* bitsize */
85 FALSE, /* pc_relative */
86 0, /* bitpos */
87 complain_overflow_bitfield,/* complain_on_overflow */
88 bfd_elf_generic_reloc, /* special_function */
89 "R_ARM_ABS32", /* name */
90 FALSE, /* partial_inplace */
91 0xffffffff, /* src_mask */
92 0xffffffff, /* dst_mask */
93 FALSE), /* pcrel_offset */
95 /* standard 32bit pc-relative reloc */
96 HOWTO (R_ARM_REL32, /* type */
97 0, /* rightshift */
98 2, /* size (0 = byte, 1 = short, 2 = long) */
99 32, /* bitsize */
100 TRUE, /* pc_relative */
101 0, /* bitpos */
102 complain_overflow_bitfield,/* complain_on_overflow */
103 bfd_elf_generic_reloc, /* special_function */
104 "R_ARM_REL32", /* name */
105 FALSE, /* partial_inplace */
106 0xffffffff, /* src_mask */
107 0xffffffff, /* dst_mask */
108 TRUE), /* pcrel_offset */
110 /* 8 bit absolute */
111 HOWTO (R_ARM_PC13, /* type */
112 0, /* rightshift */
113 0, /* size (0 = byte, 1 = short, 2 = long) */
114 8, /* bitsize */
115 FALSE, /* pc_relative */
116 0, /* bitpos */
117 complain_overflow_bitfield,/* complain_on_overflow */
118 bfd_elf_generic_reloc, /* special_function */
119 "R_ARM_PC13", /* name */
120 FALSE, /* partial_inplace */
121 0x000000ff, /* src_mask */
122 0x000000ff, /* dst_mask */
123 FALSE), /* pcrel_offset */
125 /* 16 bit absolute */
126 HOWTO (R_ARM_ABS16, /* type */
127 0, /* rightshift */
128 1, /* size (0 = byte, 1 = short, 2 = long) */
129 16, /* bitsize */
130 FALSE, /* pc_relative */
131 0, /* bitpos */
132 complain_overflow_bitfield,/* complain_on_overflow */
133 bfd_elf_generic_reloc, /* special_function */
134 "R_ARM_ABS16", /* name */
135 FALSE, /* partial_inplace */
136 0x0000ffff, /* src_mask */
137 0x0000ffff, /* dst_mask */
138 FALSE), /* pcrel_offset */
140 /* 12 bit absolute */
141 HOWTO (R_ARM_ABS12, /* type */
142 0, /* rightshift */
143 2, /* size (0 = byte, 1 = short, 2 = long) */
144 12, /* bitsize */
145 FALSE, /* pc_relative */
146 0, /* bitpos */
147 complain_overflow_bitfield,/* complain_on_overflow */
148 bfd_elf_generic_reloc, /* special_function */
149 "R_ARM_ABS12", /* name */
150 FALSE, /* partial_inplace */
151 0x000008ff, /* src_mask */
152 0x000008ff, /* dst_mask */
153 FALSE), /* pcrel_offset */
155 HOWTO (R_ARM_THM_ABS5, /* type */
156 6, /* rightshift */
157 1, /* size (0 = byte, 1 = short, 2 = long) */
158 5, /* bitsize */
159 FALSE, /* pc_relative */
160 0, /* bitpos */
161 complain_overflow_bitfield,/* complain_on_overflow */
162 bfd_elf_generic_reloc, /* special_function */
163 "R_ARM_THM_ABS5", /* name */
164 FALSE, /* partial_inplace */
165 0x000007e0, /* src_mask */
166 0x000007e0, /* dst_mask */
167 FALSE), /* pcrel_offset */
169 /* 8 bit absolute */
170 HOWTO (R_ARM_ABS8, /* type */
171 0, /* rightshift */
172 0, /* size (0 = byte, 1 = short, 2 = long) */
173 8, /* bitsize */
174 FALSE, /* pc_relative */
175 0, /* bitpos */
176 complain_overflow_bitfield,/* complain_on_overflow */
177 bfd_elf_generic_reloc, /* special_function */
178 "R_ARM_ABS8", /* name */
179 FALSE, /* partial_inplace */
180 0x000000ff, /* src_mask */
181 0x000000ff, /* dst_mask */
182 FALSE), /* pcrel_offset */
184 HOWTO (R_ARM_SBREL32, /* type */
185 0, /* rightshift */
186 2, /* size (0 = byte, 1 = short, 2 = long) */
187 32, /* bitsize */
188 FALSE, /* pc_relative */
189 0, /* bitpos */
190 complain_overflow_dont,/* complain_on_overflow */
191 bfd_elf_generic_reloc, /* special_function */
192 "R_ARM_SBREL32", /* name */
193 FALSE, /* partial_inplace */
194 0xffffffff, /* src_mask */
195 0xffffffff, /* dst_mask */
196 FALSE), /* pcrel_offset */
198 HOWTO (R_ARM_THM_PC22, /* type */
199 1, /* rightshift */
200 2, /* size (0 = byte, 1 = short, 2 = long) */
201 23, /* bitsize */
202 TRUE, /* pc_relative */
203 0, /* bitpos */
204 complain_overflow_signed,/* complain_on_overflow */
205 bfd_elf_generic_reloc, /* special_function */
206 "R_ARM_THM_PC22", /* name */
207 FALSE, /* partial_inplace */
208 0x07ff07ff, /* src_mask */
209 0x07ff07ff, /* dst_mask */
210 TRUE), /* pcrel_offset */
212 HOWTO (R_ARM_THM_PC8, /* type */
213 1, /* rightshift */
214 1, /* size (0 = byte, 1 = short, 2 = long) */
215 8, /* bitsize */
216 TRUE, /* pc_relative */
217 0, /* bitpos */
218 complain_overflow_signed,/* complain_on_overflow */
219 bfd_elf_generic_reloc, /* special_function */
220 "R_ARM_THM_PC8", /* name */
221 FALSE, /* partial_inplace */
222 0x000000ff, /* src_mask */
223 0x000000ff, /* dst_mask */
224 TRUE), /* pcrel_offset */
226 HOWTO (R_ARM_AMP_VCALL9, /* type */
227 1, /* rightshift */
228 1, /* size (0 = byte, 1 = short, 2 = long) */
229 8, /* bitsize */
230 TRUE, /* pc_relative */
231 0, /* bitpos */
232 complain_overflow_signed,/* complain_on_overflow */
233 bfd_elf_generic_reloc, /* special_function */
234 "R_ARM_AMP_VCALL9", /* name */
235 FALSE, /* partial_inplace */
236 0x000000ff, /* src_mask */
237 0x000000ff, /* dst_mask */
238 TRUE), /* pcrel_offset */
240 HOWTO (R_ARM_SWI24, /* type */
241 0, /* rightshift */
242 0, /* size (0 = byte, 1 = short, 2 = long) */
243 0, /* bitsize */
244 FALSE, /* pc_relative */
245 0, /* bitpos */
246 complain_overflow_signed,/* complain_on_overflow */
247 bfd_elf_generic_reloc, /* special_function */
248 "R_ARM_SWI24", /* name */
249 FALSE, /* partial_inplace */
250 0x00000000, /* src_mask */
251 0x00000000, /* dst_mask */
252 FALSE), /* pcrel_offset */
254 HOWTO (R_ARM_THM_SWI8, /* type */
255 0, /* rightshift */
256 0, /* size (0 = byte, 1 = short, 2 = long) */
257 0, /* bitsize */
258 FALSE, /* pc_relative */
259 0, /* bitpos */
260 complain_overflow_signed,/* complain_on_overflow */
261 bfd_elf_generic_reloc, /* special_function */
262 "R_ARM_SWI8", /* name */
263 FALSE, /* partial_inplace */
264 0x00000000, /* src_mask */
265 0x00000000, /* dst_mask */
266 FALSE), /* pcrel_offset */
268 /* BLX instruction for the ARM. */
269 HOWTO (R_ARM_XPC25, /* type */
270 2, /* rightshift */
271 2, /* size (0 = byte, 1 = short, 2 = long) */
272 25, /* bitsize */
273 TRUE, /* pc_relative */
274 0, /* bitpos */
275 complain_overflow_signed,/* complain_on_overflow */
276 bfd_elf_generic_reloc, /* special_function */
277 "R_ARM_XPC25", /* name */
278 FALSE, /* partial_inplace */
279 0x00ffffff, /* src_mask */
280 0x00ffffff, /* dst_mask */
281 TRUE), /* pcrel_offset */
283 /* BLX instruction for the Thumb. */
284 HOWTO (R_ARM_THM_XPC22, /* type */
285 2, /* rightshift */
286 2, /* size (0 = byte, 1 = short, 2 = long) */
287 22, /* bitsize */
288 TRUE, /* pc_relative */
289 0, /* bitpos */
290 complain_overflow_signed,/* complain_on_overflow */
291 bfd_elf_generic_reloc, /* special_function */
292 "R_ARM_THM_XPC22", /* name */
293 FALSE, /* partial_inplace */
294 0x07ff07ff, /* src_mask */
295 0x07ff07ff, /* dst_mask */
296 TRUE), /* pcrel_offset */
298 /* These next three relocs are not defined, but we need to fill the space. */
300 HOWTO (R_ARM_NONE, /* type */
301 0, /* rightshift */
302 0, /* size (0 = byte, 1 = short, 2 = long) */
303 0, /* bitsize */
304 FALSE, /* pc_relative */
305 0, /* bitpos */
306 complain_overflow_dont,/* complain_on_overflow */
307 bfd_elf_generic_reloc, /* special_function */
308 "R_ARM_unknown_17", /* name */
309 FALSE, /* partial_inplace */
310 0, /* src_mask */
311 0, /* dst_mask */
312 FALSE), /* pcrel_offset */
314 HOWTO (R_ARM_NONE, /* type */
315 0, /* rightshift */
316 0, /* size (0 = byte, 1 = short, 2 = long) */
317 0, /* bitsize */
318 FALSE, /* pc_relative */
319 0, /* bitpos */
320 complain_overflow_dont,/* complain_on_overflow */
321 bfd_elf_generic_reloc, /* special_function */
322 "R_ARM_unknown_18", /* name */
323 FALSE, /* partial_inplace */
324 0, /* src_mask */
325 0, /* dst_mask */
326 FALSE), /* pcrel_offset */
328 HOWTO (R_ARM_NONE, /* type */
329 0, /* rightshift */
330 0, /* size (0 = byte, 1 = short, 2 = long) */
331 0, /* bitsize */
332 FALSE, /* pc_relative */
333 0, /* bitpos */
334 complain_overflow_dont,/* complain_on_overflow */
335 bfd_elf_generic_reloc, /* special_function */
336 "R_ARM_unknown_19", /* name */
337 FALSE, /* partial_inplace */
338 0, /* src_mask */
339 0, /* dst_mask */
340 FALSE), /* pcrel_offset */
342 /* Relocs used in ARM Linux */
344 HOWTO (R_ARM_COPY, /* type */
345 0, /* rightshift */
346 2, /* size (0 = byte, 1 = short, 2 = long) */
347 32, /* bitsize */
348 FALSE, /* pc_relative */
349 0, /* bitpos */
350 complain_overflow_bitfield,/* complain_on_overflow */
351 bfd_elf_generic_reloc, /* special_function */
352 "R_ARM_COPY", /* name */
353 TRUE, /* partial_inplace */
354 0xffffffff, /* src_mask */
355 0xffffffff, /* dst_mask */
356 FALSE), /* pcrel_offset */
358 HOWTO (R_ARM_GLOB_DAT, /* type */
359 0, /* rightshift */
360 2, /* size (0 = byte, 1 = short, 2 = long) */
361 32, /* bitsize */
362 FALSE, /* pc_relative */
363 0, /* bitpos */
364 complain_overflow_bitfield,/* complain_on_overflow */
365 bfd_elf_generic_reloc, /* special_function */
366 "R_ARM_GLOB_DAT", /* name */
367 TRUE, /* partial_inplace */
368 0xffffffff, /* src_mask */
369 0xffffffff, /* dst_mask */
370 FALSE), /* pcrel_offset */
372 HOWTO (R_ARM_JUMP_SLOT, /* type */
373 0, /* rightshift */
374 2, /* size (0 = byte, 1 = short, 2 = long) */
375 32, /* bitsize */
376 FALSE, /* pc_relative */
377 0, /* bitpos */
378 complain_overflow_bitfield,/* complain_on_overflow */
379 bfd_elf_generic_reloc, /* special_function */
380 "R_ARM_JUMP_SLOT", /* name */
381 TRUE, /* partial_inplace */
382 0xffffffff, /* src_mask */
383 0xffffffff, /* dst_mask */
384 FALSE), /* pcrel_offset */
386 HOWTO (R_ARM_RELATIVE, /* type */
387 0, /* rightshift */
388 2, /* size (0 = byte, 1 = short, 2 = long) */
389 32, /* bitsize */
390 FALSE, /* pc_relative */
391 0, /* bitpos */
392 complain_overflow_bitfield,/* complain_on_overflow */
393 bfd_elf_generic_reloc, /* special_function */
394 "R_ARM_RELATIVE", /* name */
395 TRUE, /* partial_inplace */
396 0xffffffff, /* src_mask */
397 0xffffffff, /* dst_mask */
398 FALSE), /* pcrel_offset */
400 HOWTO (R_ARM_GOTOFF, /* type */
401 0, /* rightshift */
402 2, /* size (0 = byte, 1 = short, 2 = long) */
403 32, /* bitsize */
404 FALSE, /* pc_relative */
405 0, /* bitpos */
406 complain_overflow_bitfield,/* complain_on_overflow */
407 bfd_elf_generic_reloc, /* special_function */
408 "R_ARM_GOTOFF", /* name */
409 TRUE, /* partial_inplace */
410 0xffffffff, /* src_mask */
411 0xffffffff, /* dst_mask */
412 FALSE), /* pcrel_offset */
414 HOWTO (R_ARM_GOTPC, /* type */
415 0, /* rightshift */
416 2, /* size (0 = byte, 1 = short, 2 = long) */
417 32, /* bitsize */
418 TRUE, /* pc_relative */
419 0, /* bitpos */
420 complain_overflow_bitfield,/* complain_on_overflow */
421 bfd_elf_generic_reloc, /* special_function */
422 "R_ARM_GOTPC", /* name */
423 TRUE, /* partial_inplace */
424 0xffffffff, /* src_mask */
425 0xffffffff, /* dst_mask */
426 TRUE), /* pcrel_offset */
428 HOWTO (R_ARM_GOT32, /* type */
429 0, /* rightshift */
430 2, /* size (0 = byte, 1 = short, 2 = long) */
431 32, /* bitsize */
432 FALSE, /* pc_relative */
433 0, /* bitpos */
434 complain_overflow_bitfield,/* complain_on_overflow */
435 bfd_elf_generic_reloc, /* special_function */
436 "R_ARM_GOT32", /* name */
437 TRUE, /* partial_inplace */
438 0xffffffff, /* src_mask */
439 0xffffffff, /* dst_mask */
440 FALSE), /* pcrel_offset */
442 HOWTO (R_ARM_PLT32, /* type */
443 2, /* rightshift */
444 2, /* size (0 = byte, 1 = short, 2 = long) */
445 26, /* bitsize */
446 TRUE, /* pc_relative */
447 0, /* bitpos */
448 complain_overflow_bitfield,/* complain_on_overflow */
449 bfd_elf_generic_reloc, /* special_function */
450 "R_ARM_PLT32", /* name */
451 TRUE, /* partial_inplace */
452 0x00ffffff, /* src_mask */
453 0x00ffffff, /* dst_mask */
454 TRUE), /* pcrel_offset */
456 /* End of relocs used in ARM Linux */
458 HOWTO (R_ARM_RREL32, /* type */
459 0, /* rightshift */
460 0, /* size (0 = byte, 1 = short, 2 = long) */
461 0, /* bitsize */
462 FALSE, /* pc_relative */
463 0, /* bitpos */
464 complain_overflow_dont,/* complain_on_overflow */
465 bfd_elf_generic_reloc, /* special_function */
466 "R_ARM_RREL32", /* name */
467 FALSE, /* partial_inplace */
468 0, /* src_mask */
469 0, /* dst_mask */
470 FALSE), /* pcrel_offset */
472 HOWTO (R_ARM_RABS32, /* type */
473 0, /* rightshift */
474 0, /* size (0 = byte, 1 = short, 2 = long) */
475 0, /* bitsize */
476 FALSE, /* pc_relative */
477 0, /* bitpos */
478 complain_overflow_dont,/* complain_on_overflow */
479 bfd_elf_generic_reloc, /* special_function */
480 "R_ARM_RABS32", /* name */
481 FALSE, /* partial_inplace */
482 0, /* src_mask */
483 0, /* dst_mask */
484 FALSE), /* pcrel_offset */
486 HOWTO (R_ARM_RPC24, /* type */
487 0, /* rightshift */
488 0, /* size (0 = byte, 1 = short, 2 = long) */
489 0, /* bitsize */
490 FALSE, /* pc_relative */
491 0, /* bitpos */
492 complain_overflow_dont,/* complain_on_overflow */
493 bfd_elf_generic_reloc, /* special_function */
494 "R_ARM_RPC24", /* name */
495 FALSE, /* partial_inplace */
496 0, /* src_mask */
497 0, /* dst_mask */
498 FALSE), /* pcrel_offset */
500 HOWTO (R_ARM_RBASE, /* type */
501 0, /* rightshift */
502 0, /* size (0 = byte, 1 = short, 2 = long) */
503 0, /* bitsize */
504 FALSE, /* pc_relative */
505 0, /* bitpos */
506 complain_overflow_dont,/* complain_on_overflow */
507 bfd_elf_generic_reloc, /* special_function */
508 "R_ARM_RBASE", /* name */
509 FALSE, /* partial_inplace */
510 0, /* src_mask */
511 0, /* dst_mask */
512 FALSE), /* pcrel_offset */
514 HOWTO (R_ARM_ALU_PCREL7_0, /* type */
515 0, /* rightshift */
516 2, /* size (0 = byte, 1 = short, 2 = long) */
517 12, /* bitsize */
518 TRUE, /* pc_relative */
519 0, /* bitpos */
520 complain_overflow_dont,/* complain_on_overflow */
521 bfd_elf_generic_reloc, /* special_function */
522 "R_ARM_ALU_PCREL_7_0", /* name */
523 FALSE, /* partial_inplace */
524 0x00000fff, /* src_mask */
525 0x00000fff, /* dst_mask */
526 TRUE), /* pcrel_offset */
528 HOWTO (R_ARM_ALU_PCREL15_8, /* type */
529 0, /* rightshift */
530 2, /* size (0 = byte, 1 = short, 2 = long) */
531 12, /* bitsize */
532 TRUE, /* pc_relative */
533 8, /* bitpos */
534 complain_overflow_dont,/* complain_on_overflow */
535 bfd_elf_generic_reloc, /* special_function */
536 "R_ARM_ALU_PCREL_15_8",/* name */
537 FALSE, /* partial_inplace */
538 0x00000fff, /* src_mask */
539 0x00000fff, /* dst_mask */
540 TRUE), /* pcrel_offset */
542 HOWTO (R_ARM_ALU_PCREL23_15, /* type */
543 0, /* rightshift */
544 2, /* size (0 = byte, 1 = short, 2 = long) */
545 12, /* bitsize */
546 TRUE, /* pc_relative */
547 16, /* bitpos */
548 complain_overflow_dont,/* complain_on_overflow */
549 bfd_elf_generic_reloc, /* special_function */
550 "R_ARM_ALU_PCREL_23_15",/* name */
551 FALSE, /* partial_inplace */
552 0x00000fff, /* src_mask */
553 0x00000fff, /* dst_mask */
554 TRUE), /* pcrel_offset */
556 HOWTO (R_ARM_LDR_SBREL_11_0, /* type */
557 0, /* rightshift */
558 2, /* size (0 = byte, 1 = short, 2 = long) */
559 12, /* bitsize */
560 FALSE, /* pc_relative */
561 0, /* bitpos */
562 complain_overflow_dont,/* complain_on_overflow */
563 bfd_elf_generic_reloc, /* special_function */
564 "R_ARM_LDR_SBREL_11_0",/* name */
565 FALSE, /* partial_inplace */
566 0x00000fff, /* src_mask */
567 0x00000fff, /* dst_mask */
568 FALSE), /* pcrel_offset */
570 HOWTO (R_ARM_ALU_SBREL_19_12, /* type */
571 0, /* rightshift */
572 2, /* size (0 = byte, 1 = short, 2 = long) */
573 8, /* bitsize */
574 FALSE, /* pc_relative */
575 12, /* bitpos */
576 complain_overflow_dont,/* complain_on_overflow */
577 bfd_elf_generic_reloc, /* special_function */
578 "R_ARM_ALU_SBREL_19_12",/* name */
579 FALSE, /* partial_inplace */
580 0x000ff000, /* src_mask */
581 0x000ff000, /* dst_mask */
582 FALSE), /* pcrel_offset */
584 HOWTO (R_ARM_ALU_SBREL_27_20, /* type */
585 0, /* rightshift */
586 2, /* size (0 = byte, 1 = short, 2 = long) */
587 8, /* bitsize */
588 FALSE, /* pc_relative */
589 20, /* bitpos */
590 complain_overflow_dont,/* complain_on_overflow */
591 bfd_elf_generic_reloc, /* special_function */
592 "R_ARM_ALU_SBREL_27_20",/* name */
593 FALSE, /* partial_inplace */
594 0x0ff00000, /* src_mask */
595 0x0ff00000, /* dst_mask */
596 FALSE), /* pcrel_offset */
598 HOWTO (R_ARM_TARGET1, /* type */
599 0, /* rightshift */
600 2, /* size (0 = byte, 1 = short, 2 = long) */
601 32, /* bitsize */
602 FALSE, /* pc_relative */
603 0, /* bitpos */
604 complain_overflow_dont,/* complain_on_overflow */
605 bfd_elf_generic_reloc, /* special_function */
606 "R_ARM_TARGET1", /* name */
607 FALSE, /* partial_inplace */
608 0xffffffff, /* src_mask */
609 0xffffffff, /* dst_mask */
610 FALSE), /* pcrel_offset */
612 HOWTO (R_ARM_ROSEGREL32, /* type */
613 0, /* rightshift */
614 2, /* size (0 = byte, 1 = short, 2 = long) */
615 32, /* bitsize */
616 FALSE, /* pc_relative */
617 0, /* bitpos */
618 complain_overflow_dont,/* complain_on_overflow */
619 bfd_elf_generic_reloc, /* special_function */
620 "R_ARM_ROSEGREL32", /* name */
621 FALSE, /* partial_inplace */
622 0xffffffff, /* src_mask */
623 0xffffffff, /* dst_mask */
624 FALSE), /* pcrel_offset */
626 HOWTO (R_ARM_V4BX, /* type */
627 0, /* rightshift */
628 2, /* size (0 = byte, 1 = short, 2 = long) */
629 32, /* bitsize */
630 FALSE, /* pc_relative */
631 0, /* bitpos */
632 complain_overflow_dont,/* complain_on_overflow */
633 bfd_elf_generic_reloc, /* special_function */
634 "R_ARM_V4BX", /* name */
635 FALSE, /* partial_inplace */
636 0xffffffff, /* src_mask */
637 0xffffffff, /* dst_mask */
638 FALSE), /* pcrel_offset */
640 HOWTO (R_ARM_TARGET2, /* type */
641 0, /* rightshift */
642 2, /* size (0 = byte, 1 = short, 2 = long) */
643 32, /* bitsize */
644 FALSE, /* pc_relative */
645 0, /* bitpos */
646 complain_overflow_signed,/* complain_on_overflow */
647 bfd_elf_generic_reloc, /* special_function */
648 "R_ARM_TARGET2", /* name */
649 FALSE, /* partial_inplace */
650 0xffffffff, /* src_mask */
651 0xffffffff, /* dst_mask */
652 TRUE), /* pcrel_offset */
654 HOWTO (R_ARM_PREL31, /* type */
655 0, /* rightshift */
656 2, /* size (0 = byte, 1 = short, 2 = long) */
657 31, /* bitsize */
658 TRUE, /* pc_relative */
659 0, /* bitpos */
660 complain_overflow_signed,/* complain_on_overflow */
661 bfd_elf_generic_reloc, /* special_function */
662 "R_ARM_PREL31", /* name */
663 FALSE, /* partial_inplace */
664 0x7fffffff, /* src_mask */
665 0x7fffffff, /* dst_mask */
666 TRUE), /* pcrel_offset */
669 /* GNU extension to record C++ vtable hierarchy */
670 static reloc_howto_type elf32_arm_vtinherit_howto =
671 HOWTO (R_ARM_GNU_VTINHERIT, /* type */
672 0, /* rightshift */
673 2, /* size (0 = byte, 1 = short, 2 = long) */
674 0, /* bitsize */
675 FALSE, /* pc_relative */
676 0, /* bitpos */
677 complain_overflow_dont, /* complain_on_overflow */
678 NULL, /* special_function */
679 "R_ARM_GNU_VTINHERIT", /* name */
680 FALSE, /* partial_inplace */
681 0, /* src_mask */
682 0, /* dst_mask */
683 FALSE); /* pcrel_offset */
685 /* GNU extension to record C++ vtable member usage */
686 static reloc_howto_type elf32_arm_vtentry_howto =
687 HOWTO (R_ARM_GNU_VTENTRY, /* type */
688 0, /* rightshift */
689 2, /* size (0 = byte, 1 = short, 2 = long) */
690 0, /* bitsize */
691 FALSE, /* pc_relative */
692 0, /* bitpos */
693 complain_overflow_dont, /* complain_on_overflow */
694 _bfd_elf_rel_vtable_reloc_fn, /* special_function */
695 "R_ARM_GNU_VTENTRY", /* name */
696 FALSE, /* partial_inplace */
697 0, /* src_mask */
698 0, /* dst_mask */
699 FALSE); /* pcrel_offset */
701 /* 12 bit pc relative */
702 static reloc_howto_type elf32_arm_thm_pc11_howto =
703 HOWTO (R_ARM_THM_PC11, /* type */
704 1, /* rightshift */
705 1, /* size (0 = byte, 1 = short, 2 = long) */
706 11, /* bitsize */
707 TRUE, /* pc_relative */
708 0, /* bitpos */
709 complain_overflow_signed, /* complain_on_overflow */
710 bfd_elf_generic_reloc, /* special_function */
711 "R_ARM_THM_PC11", /* name */
712 FALSE, /* partial_inplace */
713 0x000007ff, /* src_mask */
714 0x000007ff, /* dst_mask */
715 TRUE); /* pcrel_offset */
717 /* 12 bit pc relative */
718 static reloc_howto_type elf32_arm_thm_pc9_howto =
719 HOWTO (R_ARM_THM_PC9, /* type */
720 1, /* rightshift */
721 1, /* size (0 = byte, 1 = short, 2 = long) */
722 8, /* bitsize */
723 TRUE, /* pc_relative */
724 0, /* bitpos */
725 complain_overflow_signed, /* complain_on_overflow */
726 bfd_elf_generic_reloc, /* special_function */
727 "R_ARM_THM_PC9", /* name */
728 FALSE, /* partial_inplace */
729 0x000000ff, /* src_mask */
730 0x000000ff, /* dst_mask */
731 TRUE); /* pcrel_offset */
733 /* Place relative GOT-indirect. */
734 static reloc_howto_type elf32_arm_got_prel =
735 HOWTO (R_ARM_GOT_PREL, /* type */
736 0, /* rightshift */
737 2, /* size (0 = byte, 1 = short, 2 = long) */
738 32, /* bitsize */
739 TRUE, /* pc_relative */
740 0, /* bitpos */
741 complain_overflow_dont, /* complain_on_overflow */
742 bfd_elf_generic_reloc, /* special_function */
743 "R_ARM_GOT_PREL", /* name */
744 FALSE, /* partial_inplace */
745 0xffffffff, /* src_mask */
746 0xffffffff, /* dst_mask */
747 TRUE); /* pcrel_offset */
749 static reloc_howto_type *
750 elf32_arm_howto_from_type (unsigned int r_type)
752 if (r_type < NUM_ELEM (elf32_arm_howto_table))
753 return &elf32_arm_howto_table[r_type];
755 switch (r_type)
757 case R_ARM_GOT_PREL:
758 return &elf32_arm_got_prel;
760 case R_ARM_GNU_VTINHERIT:
761 return &elf32_arm_vtinherit_howto;
763 case R_ARM_GNU_VTENTRY:
764 return &elf32_arm_vtentry_howto;
766 case R_ARM_THM_PC11:
767 return &elf32_arm_thm_pc11_howto;
769 case R_ARM_THM_PC9:
770 return &elf32_arm_thm_pc9_howto;
772 default:
773 return NULL;
777 static void
778 elf32_arm_info_to_howto (bfd * abfd ATTRIBUTE_UNUSED, arelent * bfd_reloc,
779 Elf_Internal_Rela * elf_reloc)
781 unsigned int r_type;
783 r_type = ELF32_R_TYPE (elf_reloc->r_info);
784 bfd_reloc->howto = elf32_arm_howto_from_type (r_type);
787 struct elf32_arm_reloc_map
789 bfd_reloc_code_real_type bfd_reloc_val;
790 unsigned char elf_reloc_val;
793 /* All entries in this list must also be present in elf32_arm_howto_table. */
794 static const struct elf32_arm_reloc_map elf32_arm_reloc_map[] =
796 {BFD_RELOC_NONE, R_ARM_NONE},
797 {BFD_RELOC_ARM_PCREL_BRANCH, R_ARM_PC24},
798 {BFD_RELOC_ARM_PCREL_BLX, R_ARM_XPC25},
799 {BFD_RELOC_THUMB_PCREL_BLX, R_ARM_THM_XPC22},
800 {BFD_RELOC_32, R_ARM_ABS32},
801 {BFD_RELOC_32_PCREL, R_ARM_REL32},
802 {BFD_RELOC_8, R_ARM_ABS8},
803 {BFD_RELOC_16, R_ARM_ABS16},
804 {BFD_RELOC_ARM_OFFSET_IMM, R_ARM_ABS12},
805 {BFD_RELOC_ARM_THUMB_OFFSET, R_ARM_THM_ABS5},
806 {BFD_RELOC_THUMB_PCREL_BRANCH23, R_ARM_THM_PC22},
807 {BFD_RELOC_ARM_COPY, R_ARM_COPY},
808 {BFD_RELOC_ARM_GLOB_DAT, R_ARM_GLOB_DAT},
809 {BFD_RELOC_ARM_JUMP_SLOT, R_ARM_JUMP_SLOT},
810 {BFD_RELOC_ARM_RELATIVE, R_ARM_RELATIVE},
811 {BFD_RELOC_ARM_GOTOFF, R_ARM_GOTOFF},
812 {BFD_RELOC_ARM_GOTPC, R_ARM_GOTPC},
813 {BFD_RELOC_ARM_GOT32, R_ARM_GOT32},
814 {BFD_RELOC_ARM_PLT32, R_ARM_PLT32},
815 {BFD_RELOC_ARM_TARGET1, R_ARM_TARGET1},
816 {BFD_RELOC_ARM_ROSEGREL32, R_ARM_ROSEGREL32},
817 {BFD_RELOC_ARM_SBREL32, R_ARM_SBREL32},
818 {BFD_RELOC_ARM_PREL31, R_ARM_PREL31},
819 {BFD_RELOC_ARM_TARGET2, R_ARM_TARGET2}
822 static reloc_howto_type *
823 elf32_arm_reloc_type_lookup (abfd, code)
824 bfd *abfd ATTRIBUTE_UNUSED;
825 bfd_reloc_code_real_type code;
827 unsigned int i;
829 switch (code)
831 case BFD_RELOC_VTABLE_INHERIT:
832 return & elf32_arm_vtinherit_howto;
834 case BFD_RELOC_VTABLE_ENTRY:
835 return & elf32_arm_vtentry_howto;
837 case BFD_RELOC_THUMB_PCREL_BRANCH12:
838 return & elf32_arm_thm_pc11_howto;
840 case BFD_RELOC_THUMB_PCREL_BRANCH9:
841 return & elf32_arm_thm_pc9_howto;
843 default:
844 for (i = 0; i < NUM_ELEM (elf32_arm_reloc_map); i ++)
845 if (elf32_arm_reloc_map[i].bfd_reloc_val == code)
846 return & elf32_arm_howto_table[elf32_arm_reloc_map[i].elf_reloc_val];
848 return NULL;
852 /* Support for core dump NOTE sections */
853 static bfd_boolean
854 elf32_arm_nabi_grok_prstatus (abfd, note)
855 bfd *abfd;
856 Elf_Internal_Note *note;
858 int offset;
859 size_t size;
861 switch (note->descsz)
863 default:
864 return FALSE;
866 case 148: /* Linux/ARM 32-bit*/
867 /* pr_cursig */
868 elf_tdata (abfd)->core_signal = bfd_get_16 (abfd, note->descdata + 12);
870 /* pr_pid */
871 elf_tdata (abfd)->core_pid = bfd_get_32 (abfd, note->descdata + 24);
873 /* pr_reg */
874 offset = 72;
875 size = 72;
877 break;
880 /* Make a ".reg/999" section. */
881 return _bfd_elfcore_make_pseudosection (abfd, ".reg",
882 size, note->descpos + offset);
885 static bfd_boolean
886 elf32_arm_nabi_grok_psinfo (abfd, note)
887 bfd *abfd;
888 Elf_Internal_Note *note;
890 switch (note->descsz)
892 default:
893 return FALSE;
895 case 124: /* Linux/ARM elf_prpsinfo */
896 elf_tdata (abfd)->core_program
897 = _bfd_elfcore_strndup (abfd, note->descdata + 28, 16);
898 elf_tdata (abfd)->core_command
899 = _bfd_elfcore_strndup (abfd, note->descdata + 44, 80);
902 /* Note that for some reason, a spurious space is tacked
903 onto the end of the args in some (at least one anyway)
904 implementations, so strip it off if it exists. */
907 char *command = elf_tdata (abfd)->core_command;
908 int n = strlen (command);
910 if (0 < n && command[n - 1] == ' ')
911 command[n - 1] = '\0';
914 return TRUE;
917 #define TARGET_LITTLE_SYM bfd_elf32_littlearm_vec
918 #define TARGET_LITTLE_NAME "elf32-littlearm"
919 #define TARGET_BIG_SYM bfd_elf32_bigarm_vec
920 #define TARGET_BIG_NAME "elf32-bigarm"
922 #define elf_backend_grok_prstatus elf32_arm_nabi_grok_prstatus
923 #define elf_backend_grok_psinfo elf32_arm_nabi_grok_psinfo
925 #include "elf32-arm.h"
927 /* Symbian OS Targets */
929 #undef TARGET_LITTLE_SYM
930 #define TARGET_LITTLE_SYM bfd_elf32_littlearm_symbian_vec
931 #undef TARGET_LITTLE_NAME
932 #define TARGET_LITTLE_NAME "elf32-littlearm-symbian"
933 #undef TARGET_BIG_SYM
934 #define TARGET_BIG_SYM bfd_elf32_bigarm_symbian_vec
935 #undef TARGET_BIG_NAME
936 #define TARGET_BIG_NAME "elf32-bigarm-symbian"
938 /* Like elf32_arm_link_hash_table_create -- but overrides
939 appropriately for Symbian OS. */
940 static struct bfd_link_hash_table *
941 elf32_arm_symbian_link_hash_table_create (bfd *abfd)
943 struct bfd_link_hash_table *ret;
945 ret = elf32_arm_link_hash_table_create (abfd);
946 if (ret)
948 struct elf32_arm_link_hash_table *htab
949 = (struct elf32_arm_link_hash_table *)ret;
950 /* There is no PLT header for Symbian OS. */
951 htab->plt_header_size = 0;
952 /* The PLT entries are each three instructions. */
953 htab->plt_entry_size = 4 * NUM_ELEM (elf32_arm_symbian_plt_entry);
954 htab->symbian_p = 1;
956 return ret;
959 /* In a BPABI executable, the dynamic linking sections do not go in
960 the loadable read-only segment. The post-linker may wish to refer
961 to these sections, but they are not part of the final program
962 image. */
963 static struct bfd_elf_special_section const
964 elf32_arm_symbian_special_sections[]=
966 { ".dynamic", 8, 0, SHT_DYNAMIC, 0 },
967 { ".dynstr", 7, 0, SHT_STRTAB, 0 },
968 { ".dynsym", 7, 0, SHT_DYNSYM, 0 },
969 { ".got", 4, 0, SHT_PROGBITS, 0 },
970 { ".hash", 5, 0, SHT_HASH, 0 },
971 { NULL, 0, 0, 0, 0 }
974 static bfd_boolean
975 elf32_arm_symbian_modify_segment_map
976 PARAMS ((bfd *, struct bfd_link_info *));
978 static bfd_boolean
979 elf32_arm_symbian_modify_segment_map (abfd, info)
980 bfd *abfd;
981 struct bfd_link_info *info ATTRIBUTE_UNUSED;
983 struct elf_segment_map *m;
984 asection *dynsec;
986 /* The first PT_LOAD segment will have the program headers and file
987 headers in it by default -- but BPABI object files should not
988 include these headers in any loadable segment. */
989 for (m = elf_tdata (abfd)->segment_map; m != NULL; m = m->next)
990 if (m->p_type == PT_LOAD)
992 m->includes_filehdr = 0;
993 m->includes_phdrs = 0;
996 /* BPABI shared libraries and executables should have a PT_DYNAMIC
997 segment. However, because the .dynamic section is not marked
998 with SEC_LOAD, the generic ELF code will not create such a
999 segment. */
1000 dynsec = bfd_get_section_by_name (abfd, ".dynamic");
1001 if (dynsec)
1003 m = _bfd_elf_make_dynamic_segment (abfd, dynsec);
1004 m->next = elf_tdata (abfd)->segment_map;
1005 elf_tdata (abfd)->segment_map = m;
1008 return TRUE;
1011 #undef elf32_bed
1012 #define elf32_bed elf32_arm_symbian_bed
1014 #undef ELF_DYNAMIC_SEC_FLAGS
1015 #define ELF_DYNAMIC_SEC_FLAGS \
1016 (SEC_HAS_CONTENTS | SEC_IN_MEMORY | SEC_LINKER_CREATED)
1018 #undef bfd_elf32_bfd_link_hash_table_create
1019 #define bfd_elf32_bfd_link_hash_table_create \
1020 elf32_arm_symbian_link_hash_table_create
1022 #undef elf_backend_special_sections
1023 #define elf_backend_special_sections elf32_arm_symbian_special_sections
1025 #undef elf_backend_modify_segment_map
1026 #define elf_backend_modify_segment_map elf32_arm_symbian_modify_segment_map
1028 /* There is no .got section for BPABI objects, and hence no header. */
1029 #undef elf_backend_got_header_size
1030 #define elf_backend_got_header_size 0
1032 /* Similarly, there is no .got.plt section. */
1033 #undef elf_backend_want_got_plt
1034 #define elf_backend_want_got_plt 0
1036 #include "elf32-target.h"