Restore 2002 ChangeLog history.
[platform/upstream/binutils.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          0,                     /* size (0 = byte, 1 = short, 2 = long) */
192          0,                     /* 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          0,                     /* src_mask */
200          0,                     /* 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
562   /* GNU extension to record C++ vtable hierarchy */
563 static reloc_howto_type elf32_arm_vtinherit_howto =
564   HOWTO (R_ARM_GNU_VTINHERIT, /* type */
565          0,                     /* rightshift */
566          2,                     /* size (0 = byte, 1 = short, 2 = long) */
567          0,                     /* bitsize */
568          FALSE,                 /* pc_relative */
569          0,                     /* bitpos */
570          complain_overflow_dont, /* complain_on_overflow */
571          NULL,                  /* special_function */
572          "R_ARM_GNU_VTINHERIT", /* name */
573          FALSE,                 /* partial_inplace */
574          0,                     /* src_mask */
575          0,                     /* dst_mask */
576          FALSE);                /* pcrel_offset */
577
578   /* GNU extension to record C++ vtable member usage */
579 static reloc_howto_type elf32_arm_vtentry_howto =
580   HOWTO (R_ARM_GNU_VTENTRY,     /* type */
581          0,                     /* rightshift */
582          2,                     /* size (0 = byte, 1 = short, 2 = long) */
583          0,                     /* bitsize */
584          FALSE,                 /* pc_relative */
585          0,                     /* bitpos */
586          complain_overflow_dont, /* complain_on_overflow */
587          _bfd_elf_rel_vtable_reloc_fn,  /* special_function */
588          "R_ARM_GNU_VTENTRY",   /* name */
589          FALSE,                 /* partial_inplace */
590          0,                     /* src_mask */
591          0,                     /* dst_mask */
592          FALSE);                /* pcrel_offset */
593
594   /* 12 bit pc relative */
595 static reloc_howto_type elf32_arm_thm_pc11_howto =
596   HOWTO (R_ARM_THM_PC11,        /* type */
597          1,                     /* rightshift */
598          1,                     /* size (0 = byte, 1 = short, 2 = long) */
599          11,                    /* bitsize */
600          TRUE,                  /* pc_relative */
601          0,                     /* bitpos */
602          complain_overflow_signed,      /* complain_on_overflow */
603          bfd_elf_generic_reloc, /* special_function */
604          "R_ARM_THM_PC11",      /* name */
605          FALSE,                 /* partial_inplace */
606          0x000007ff,            /* src_mask */
607          0x000007ff,            /* dst_mask */
608          TRUE);                 /* pcrel_offset */
609
610   /* 12 bit pc relative */
611 static reloc_howto_type elf32_arm_thm_pc9_howto =
612   HOWTO (R_ARM_THM_PC9,         /* type */
613          1,                     /* rightshift */
614          1,                     /* size (0 = byte, 1 = short, 2 = long) */
615          8,                     /* bitsize */
616          TRUE,                  /* pc_relative */
617          0,                     /* bitpos */
618          complain_overflow_signed,      /* complain_on_overflow */
619          bfd_elf_generic_reloc, /* special_function */
620          "R_ARM_THM_PC9",       /* name */
621          FALSE,                 /* partial_inplace */
622          0x000000ff,            /* src_mask */
623          0x000000ff,            /* dst_mask */
624          TRUE);                 /* pcrel_offset */
625
626 static void elf32_arm_info_to_howto
627   PARAMS ((bfd *, arelent *, Elf_Internal_Rela *));
628
629 static void
630 elf32_arm_info_to_howto (abfd, bfd_reloc, elf_reloc)
631      bfd * abfd ATTRIBUTE_UNUSED;
632      arelent * bfd_reloc;
633      Elf_Internal_Rela * elf_reloc;
634 {
635   unsigned int r_type;
636
637   r_type = ELF32_R_TYPE (elf_reloc->r_info);
638
639   switch (r_type)
640     {
641     case R_ARM_GNU_VTINHERIT:
642       bfd_reloc->howto = & elf32_arm_vtinherit_howto;
643       break;
644
645     case R_ARM_GNU_VTENTRY:
646       bfd_reloc->howto = & elf32_arm_vtentry_howto;
647       break;
648
649     case R_ARM_THM_PC11:
650       bfd_reloc->howto = & elf32_arm_thm_pc11_howto;
651       break;
652
653     case R_ARM_THM_PC9:
654       bfd_reloc->howto = & elf32_arm_thm_pc9_howto;
655       break;
656
657     default:
658       if (r_type >= NUM_ELEM (elf32_arm_howto_table))
659         bfd_reloc->howto = NULL;
660       else
661         bfd_reloc->howto = & elf32_arm_howto_table[r_type];
662       break;
663     }
664 }
665
666 struct elf32_arm_reloc_map
667   {
668     bfd_reloc_code_real_type  bfd_reloc_val;
669     unsigned char             elf_reloc_val;
670   };
671
672 static const struct elf32_arm_reloc_map elf32_arm_reloc_map[] =
673   {
674     {BFD_RELOC_NONE,                 R_ARM_NONE},
675     {BFD_RELOC_ARM_PCREL_BRANCH,     R_ARM_PC24},
676     {BFD_RELOC_ARM_PCREL_BLX,        R_ARM_XPC25},
677     {BFD_RELOC_THUMB_PCREL_BLX,      R_ARM_THM_XPC22},
678     {BFD_RELOC_32,                   R_ARM_ABS32},
679     {BFD_RELOC_32_PCREL,             R_ARM_REL32},
680     {BFD_RELOC_8,                    R_ARM_ABS8},
681     {BFD_RELOC_16,                   R_ARM_ABS16},
682     {BFD_RELOC_ARM_OFFSET_IMM,       R_ARM_ABS12},
683     {BFD_RELOC_ARM_THUMB_OFFSET,     R_ARM_THM_ABS5},
684     {BFD_RELOC_THUMB_PCREL_BRANCH23, R_ARM_THM_PC22},
685     {BFD_RELOC_ARM_COPY,             R_ARM_COPY},
686     {BFD_RELOC_ARM_GLOB_DAT,         R_ARM_GLOB_DAT},
687     {BFD_RELOC_ARM_JUMP_SLOT,        R_ARM_JUMP_SLOT},
688     {BFD_RELOC_ARM_RELATIVE,         R_ARM_RELATIVE},
689     {BFD_RELOC_ARM_GOTOFF,           R_ARM_GOTOFF},
690     {BFD_RELOC_ARM_GOTPC,            R_ARM_GOTPC},
691     {BFD_RELOC_ARM_GOT32,            R_ARM_GOT32},
692     {BFD_RELOC_ARM_PLT32,            R_ARM_PLT32}
693   };
694
695 static reloc_howto_type *
696 elf32_arm_reloc_type_lookup (abfd, code)
697      bfd *abfd ATTRIBUTE_UNUSED;
698      bfd_reloc_code_real_type code;
699 {
700   unsigned int i;
701
702   switch (code)
703     {
704     case BFD_RELOC_VTABLE_INHERIT:
705       return & elf32_arm_vtinherit_howto;
706
707     case BFD_RELOC_VTABLE_ENTRY:
708       return & elf32_arm_vtentry_howto;
709
710     case BFD_RELOC_THUMB_PCREL_BRANCH12:
711       return & elf32_arm_thm_pc11_howto;
712
713     case BFD_RELOC_THUMB_PCREL_BRANCH9:
714       return & elf32_arm_thm_pc9_howto;
715
716     default:
717       for (i = 0; i < NUM_ELEM (elf32_arm_reloc_map); i ++)
718         if (elf32_arm_reloc_map[i].bfd_reloc_val == code)
719           return & elf32_arm_howto_table[elf32_arm_reloc_map[i].elf_reloc_val];
720
721       return NULL;
722    }
723 }
724
725 /* Support for core dump NOTE sections */
726 static bfd_boolean
727 elf32_arm_nabi_grok_prstatus (abfd, note)
728      bfd *abfd;
729      Elf_Internal_Note *note;
730 {
731   int offset;
732   size_t raw_size;
733
734   switch (note->descsz)
735     {
736       default:
737         return FALSE;
738
739       case 148:         /* Linux/ARM 32-bit*/
740         /* pr_cursig */
741         elf_tdata (abfd)->core_signal = bfd_get_16 (abfd, note->descdata + 12);
742
743         /* pr_pid */
744         elf_tdata (abfd)->core_pid = bfd_get_32 (abfd, note->descdata + 24);
745
746         /* pr_reg */
747         offset = 72;
748         raw_size = 72;
749
750         break;
751     }
752
753   /* Make a ".reg/999" section.  */
754   return _bfd_elfcore_make_pseudosection (abfd, ".reg",
755                                           raw_size, note->descpos + offset);
756 }
757
758 static bfd_boolean
759 elf32_arm_nabi_grok_psinfo (abfd, note)
760      bfd *abfd;
761      Elf_Internal_Note *note;
762 {
763   switch (note->descsz)
764     {
765       default:
766         return FALSE;
767
768       case 124:         /* Linux/ARM elf_prpsinfo */
769         elf_tdata (abfd)->core_program
770          = _bfd_elfcore_strndup (abfd, note->descdata + 28, 16);
771         elf_tdata (abfd)->core_command
772          = _bfd_elfcore_strndup (abfd, note->descdata + 44, 80);
773     }
774
775   /* Note that for some reason, a spurious space is tacked
776      onto the end of the args in some (at least one anyway)
777      implementations, so strip it off if it exists.  */
778
779   {
780     char *command = elf_tdata (abfd)->core_command;
781     int n = strlen (command);
782
783     if (0 < n && command[n - 1] == ' ')
784       command[n - 1] = '\0';
785   }
786
787   return TRUE;
788 }
789
790 #define elf_backend_grok_prstatus       elf32_arm_nabi_grok_prstatus
791 #define elf_backend_grok_psinfo         elf32_arm_nabi_grok_psinfo
792
793 #include "elf32-arm.h"