2001-01-03 Kazu Hirata <kazu@hxi.com>
[external/binutils.git] / bfd / elfarm-nabi.c
1 /* 32-bit ELF support for ARM new abi option.
2    Copyright 1999 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
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
46 /* Note: code such as elf32_arm_reloc_type_lookup expect to use e.g.
47    R_ARM_PC24 as an index into this, and find the R_ARM_PC24 HOWTO
48    in that slot.  */
49
50 static reloc_howto_type elf32_arm_howto_table[] =
51 {
52   /* No relocation */
53   HOWTO (R_ARM_NONE,            /* type */
54          0,                     /* rightshift */
55          0,                     /* size (0 = byte, 1 = short, 2 = long) */
56          0,                     /* bitsize */
57          false,                 /* pc_relative */
58          0,                     /* bitpos */
59          complain_overflow_dont,/* complain_on_overflow */
60          bfd_elf_generic_reloc, /* special_function */
61          "R_ARM_NONE",          /* name */
62          false,                 /* partial_inplace */
63          0,                     /* src_mask */
64          0,                     /* dst_mask */
65          false),                /* pcrel_offset */
66
67   HOWTO (R_ARM_PC24,            /* type */
68          2,                     /* rightshift */
69          2,                     /* size (0 = byte, 1 = short, 2 = long) */
70          24,                    /* bitsize */
71          true,                  /* pc_relative */
72          0,                     /* bitpos */
73          complain_overflow_signed,/* complain_on_overflow */
74          bfd_elf_generic_reloc, /* special_function */
75          "R_ARM_PC24",          /* name */
76          false,                 /* partial_inplace */
77          0x00ffffff,            /* src_mask */
78          0x00ffffff,            /* dst_mask */
79          true),                 /* pcrel_offset */
80
81   /* 32 bit absolute */
82   HOWTO (R_ARM_ABS32,           /* type */
83          0,                     /* rightshift */
84          2,                     /* size (0 = byte, 1 = short, 2 = long) */
85          32,                    /* bitsize */
86          false,                 /* pc_relative */
87          0,                     /* bitpos */
88          complain_overflow_bitfield,/* complain_on_overflow */
89          bfd_elf_generic_reloc, /* special_function */
90          "R_ARM_ABS32",         /* name */
91          false,                 /* partial_inplace */
92          0xffffffff,            /* src_mask */
93          0xffffffff,            /* dst_mask */
94          false),                /* pcrel_offset */
95
96   /* standard 32bit pc-relative reloc */
97   HOWTO (R_ARM_REL32,           /* type */
98          0,                     /* rightshift */
99          2,                     /* size (0 = byte, 1 = short, 2 = long) */
100          32,                    /* bitsize */
101          true,                  /* pc_relative */
102          0,                     /* bitpos */
103          complain_overflow_bitfield,/* complain_on_overflow */
104          bfd_elf_generic_reloc, /* special_function */
105          "R_ARM_REL32",         /* name */
106          false,                 /* partial_inplace */
107          0xffffffff,            /* src_mask */
108          0xffffffff,            /* dst_mask */
109          true),                 /* pcrel_offset */
110
111   /* 8 bit absolute */
112   HOWTO (R_ARM_PC13,            /* type */
113          0,                     /* rightshift */
114          0,                     /* size (0 = byte, 1 = short, 2 = long) */
115          8,                     /* bitsize */
116          false,                 /* pc_relative */
117          0,                     /* bitpos */
118          complain_overflow_bitfield,/* complain_on_overflow */
119          bfd_elf_generic_reloc, /* special_function */
120          "R_ARM_PC13",          /* name */
121          false,                 /* partial_inplace */
122          0x000000ff,            /* src_mask */
123          0x000000ff,            /* dst_mask */
124          false),                /* pcrel_offset */
125
126    /* 16 bit absolute */
127   HOWTO (R_ARM_ABS16,           /* type */
128          0,                     /* rightshift */
129          1,                     /* size (0 = byte, 1 = short, 2 = long) */
130          16,                    /* bitsize */
131          false,                 /* pc_relative */
132          0,                     /* bitpos */
133          complain_overflow_bitfield,/* complain_on_overflow */
134          bfd_elf_generic_reloc, /* special_function */
135          "R_ARM_ABS16",         /* name */
136          false,                 /* partial_inplace */
137          0,                     /* src_mask */
138          0,                     /* dst_mask */
139          false),                /* pcrel_offset */
140
141   /* 12 bit absolute */
142   HOWTO (R_ARM_ABS12,           /* type */
143          0,                     /* rightshift */
144          2,                     /* size (0 = byte, 1 = short, 2 = long) */
145          12,                    /* bitsize */
146          false,                 /* pc_relative */
147          0,                     /* bitpos */
148          complain_overflow_bitfield,/* complain_on_overflow */
149          bfd_elf_generic_reloc, /* special_function */
150          "R_ARM_ABS12",         /* name */
151          false,                 /* partial_inplace */
152          0x000008ff,            /* src_mask */
153          0x000008ff,            /* dst_mask */
154          false),                /* pcrel_offset */
155
156   HOWTO (R_ARM_THM_ABS5,        /* type */
157          6,                     /* rightshift */
158          1,                     /* size (0 = byte, 1 = short, 2 = long) */
159          5,                     /* bitsize */
160          false,                 /* pc_relative */
161          0,                     /* bitpos */
162          complain_overflow_bitfield,/* complain_on_overflow */
163          bfd_elf_generic_reloc, /* special_function */
164          "R_ARM_THM_ABS5",      /* name */
165          false,                 /* partial_inplace */
166          0x000007e0,            /* src_mask */
167          0x000007e0,            /* dst_mask */
168          false),                /* pcrel_offset */
169
170   /* 8 bit absolute */
171   HOWTO (R_ARM_ABS8,            /* type */
172          0,                     /* rightshift */
173          0,                     /* size (0 = byte, 1 = short, 2 = long) */
174          8,                     /* bitsize */
175          false,                 /* pc_relative */
176          0,                     /* bitpos */
177          complain_overflow_bitfield,/* complain_on_overflow */
178          bfd_elf_generic_reloc, /* special_function */
179          "R_ARM_ABS8",          /* name */
180          false,                 /* partial_inplace */
181          0x000000ff,            /* src_mask */
182          0x000000ff,            /* dst_mask */
183          false),                /* pcrel_offset */
184
185   HOWTO (R_ARM_SBREL32,         /* type */
186          0,                     /* rightshift */
187          0,                     /* size (0 = byte, 1 = short, 2 = long) */
188          0,                     /* bitsize */
189          false,                 /* pc_relative */
190          0,                     /* bitpos */
191          complain_overflow_dont,/* complain_on_overflow */
192          bfd_elf_generic_reloc, /* special_function */
193          "R_ARM_SBREL32",       /* name */
194          false,                 /* partial_inplace */
195          0,                     /* src_mask */
196          0,                     /* dst_mask */
197          false),                /* pcrel_offset */
198
199   HOWTO (R_ARM_THM_PC22,        /* type */
200          1,                     /* rightshift */
201          2,                     /* size (0 = byte, 1 = short, 2 = long) */
202          23,                    /* bitsize */
203          true,                  /* pc_relative */
204          0,                     /* bitpos */
205          complain_overflow_signed,/* complain_on_overflow */
206          bfd_elf_generic_reloc, /* special_function */
207          "R_ARM_THM_PC22",      /* name */
208          false,                 /* partial_inplace */
209          0x07ff07ff,            /* src_mask */
210          0x07ff07ff,            /* dst_mask */
211          true),                 /* pcrel_offset */
212
213   HOWTO (R_ARM_THM_PC8,         /* type */
214          1,                     /* rightshift */
215          1,                     /* size (0 = byte, 1 = short, 2 = long) */
216          8,                     /* bitsize */
217          true,                  /* pc_relative */
218          0,                     /* bitpos */
219          complain_overflow_signed,/* complain_on_overflow */
220          bfd_elf_generic_reloc, /* special_function */
221          "R_ARM_THM_PC8",       /* name */
222          false,                 /* partial_inplace */
223          0x000000ff,            /* src_mask */
224          0x000000ff,            /* dst_mask */
225          true),                 /* pcrel_offset */
226
227   HOWTO (R_ARM_AMP_VCALL9,      /* type */
228          1,                     /* rightshift */
229          1,                     /* size (0 = byte, 1 = short, 2 = long) */
230          8,                     /* bitsize */
231          true,                  /* pc_relative */
232          0,                     /* bitpos */
233          complain_overflow_signed,/* complain_on_overflow */
234          bfd_elf_generic_reloc, /* special_function */
235          "R_ARM_AMP_VCALL9",    /* name */
236          false,                 /* partial_inplace */
237          0x000000ff,            /* src_mask */
238          0x000000ff,            /* dst_mask */
239          true),                 /* pcrel_offset */
240
241   HOWTO (R_ARM_SWI24,           /* type */
242          0,                     /* rightshift */
243          0,                     /* size (0 = byte, 1 = short, 2 = long) */
244          0,                     /* bitsize */
245          false,                 /* pc_relative */
246          0,                     /* bitpos */
247          complain_overflow_signed,/* complain_on_overflow */
248          bfd_elf_generic_reloc, /* special_function */
249          "R_ARM_SWI24",         /* name */
250          false,                 /* partial_inplace */
251          0x00000000,            /* src_mask */
252          0x00000000,            /* dst_mask */
253          false),                /* pcrel_offset */
254
255   HOWTO (R_ARM_THM_SWI8,        /* type */
256          0,                     /* rightshift */
257          0,                     /* size (0 = byte, 1 = short, 2 = long) */
258          0,                     /* bitsize */
259          false,                 /* pc_relative */
260          0,                     /* bitpos */
261          complain_overflow_signed,/* complain_on_overflow */
262          bfd_elf_generic_reloc, /* special_function */
263          "R_ARM_SWI8",          /* name */
264          false,                 /* partial_inplace */
265          0x00000000,            /* src_mask */
266          0x00000000,            /* dst_mask */
267          false),                /* pcrel_offset */
268
269   /* BLX instruction for the ARM.  */
270   HOWTO (R_ARM_XPC25,           /* type */
271          2,                     /* rightshift */
272          2,                     /* size (0 = byte, 1 = short, 2 = long) */
273          25,                    /* bitsize */
274          true,                  /* pc_relative */
275          0,                     /* bitpos */
276          complain_overflow_signed,/* complain_on_overflow */
277          bfd_elf_generic_reloc, /* special_function */
278          "R_ARM_XPC25",         /* name */
279          false,                 /* partial_inplace */
280          0x00ffffff,            /* src_mask */
281          0x00ffffff,            /* dst_mask */
282          true),                 /* pcrel_offset */
283
284   /* BLX instruction for the Thumb.  */
285   HOWTO (R_ARM_THM_XPC22,       /* type */
286          2,                     /* rightshift */
287          2,                     /* size (0 = byte, 1 = short, 2 = long) */
288          22,                    /* bitsize */
289          true,                  /* pc_relative */
290          0,                     /* bitpos */
291          complain_overflow_signed,/* complain_on_overflow */
292          bfd_elf_generic_reloc, /* special_function */
293          "R_ARM_THM_XPC22",     /* name */
294          false,                 /* partial_inplace */
295          0x07ff07ff,            /* src_mask */
296          0x07ff07ff,            /* dst_mask */
297          true),                 /* pcrel_offset */
298
299   /* These next three relocs are not defined, but we need to fill the space.  */
300
301   HOWTO (R_ARM_NONE,            /* type */
302          0,                     /* rightshift */
303          0,                     /* size (0 = byte, 1 = short, 2 = long) */
304          0,                     /* bitsize */
305          false,                 /* pc_relative */
306          0,                     /* bitpos */
307          complain_overflow_dont,/* complain_on_overflow */
308          bfd_elf_generic_reloc, /* special_function */
309          "R_ARM_unknown_17",    /* name */
310          false,                 /* partial_inplace */
311          0,                     /* src_mask */
312          0,                     /* dst_mask */
313          false),                /* pcrel_offset */
314
315   HOWTO (R_ARM_NONE,            /* type */
316          0,                     /* rightshift */
317          0,                     /* size (0 = byte, 1 = short, 2 = long) */
318          0,                     /* bitsize */
319          false,                 /* pc_relative */
320          0,                     /* bitpos */
321          complain_overflow_dont,/* complain_on_overflow */
322          bfd_elf_generic_reloc, /* special_function */
323          "R_ARM_unknown_18",    /* name */
324          false,                 /* partial_inplace */
325          0,                     /* src_mask */
326          0,                     /* dst_mask */
327          false),                /* pcrel_offset */
328
329   HOWTO (R_ARM_NONE,            /* type */
330          0,                     /* rightshift */
331          0,                     /* size (0 = byte, 1 = short, 2 = long) */
332          0,                     /* bitsize */
333          false,                 /* pc_relative */
334          0,                     /* bitpos */
335          complain_overflow_dont,/* complain_on_overflow */
336          bfd_elf_generic_reloc, /* special_function */
337          "R_ARM_unknown_19",    /* name */
338          false,                 /* partial_inplace */
339          0,                     /* src_mask */
340          0,                     /* dst_mask */
341          false),                /* pcrel_offset */
342
343   /* Relocs used in ARM Linux */
344
345   HOWTO (R_ARM_COPY,            /* type */
346          0,                     /* rightshift */
347          2,                     /* size (0 = byte, 1 = short, 2 = long) */
348          32,                    /* bitsize */
349          false,                 /* pc_relative */
350          0,                     /* bitpos */
351          complain_overflow_bitfield,/* complain_on_overflow */
352          bfd_elf_generic_reloc, /* special_function */
353          "R_ARM_COPY",          /* name */
354          true,                  /* partial_inplace */
355          0xffffffff,            /* src_mask */
356          0xffffffff,            /* dst_mask */
357          false),                /* pcrel_offset */
358
359   HOWTO (R_ARM_GLOB_DAT,        /* type */
360          0,                     /* rightshift */
361          2,                     /* size (0 = byte, 1 = short, 2 = long) */
362          32,                    /* bitsize */
363          false,                 /* pc_relative */
364          0,                     /* bitpos */
365          complain_overflow_bitfield,/* complain_on_overflow */
366          bfd_elf_generic_reloc, /* special_function */
367          "R_ARM_GLOB_DAT",      /* name */
368          true,                  /* partial_inplace */
369          0xffffffff,            /* src_mask */
370          0xffffffff,            /* dst_mask */
371          false),                /* pcrel_offset */
372
373   HOWTO (R_ARM_JUMP_SLOT,       /* type */
374          0,                     /* rightshift */
375          2,                     /* size (0 = byte, 1 = short, 2 = long) */
376          32,                    /* bitsize */
377          false,                 /* pc_relative */
378          0,                     /* bitpos */
379          complain_overflow_bitfield,/* complain_on_overflow */
380          bfd_elf_generic_reloc, /* special_function */
381          "R_ARM_JUMP_SLOT",     /* name */
382          true,                  /* partial_inplace */
383          0xffffffff,            /* src_mask */
384          0xffffffff,            /* dst_mask */
385          false),                /* pcrel_offset */
386
387   HOWTO (R_ARM_RELATIVE,        /* type */
388          0,                     /* rightshift */
389          2,                     /* size (0 = byte, 1 = short, 2 = long) */
390          32,                    /* bitsize */
391          false,                 /* pc_relative */
392          0,                     /* bitpos */
393          complain_overflow_bitfield,/* complain_on_overflow */
394          bfd_elf_generic_reloc, /* special_function */
395          "R_ARM_RELATIVE",      /* name */
396          true,                  /* partial_inplace */
397          0xffffffff,            /* src_mask */
398          0xffffffff,            /* dst_mask */
399          false),                /* pcrel_offset */
400
401   HOWTO (R_ARM_GOTOFF,          /* type */
402          0,                     /* rightshift */
403          2,                     /* size (0 = byte, 1 = short, 2 = long) */
404          32,                    /* bitsize */
405          false,                 /* pc_relative */
406          0,                     /* bitpos */
407          complain_overflow_bitfield,/* complain_on_overflow */
408          bfd_elf_generic_reloc, /* special_function */
409          "R_ARM_GOTOFF",        /* name */
410          true,                  /* partial_inplace */
411          0xffffffff,            /* src_mask */
412          0xffffffff,            /* dst_mask */
413          false),                /* pcrel_offset */
414
415   HOWTO (R_ARM_GOTPC,           /* type */
416          0,                     /* rightshift */
417          2,                     /* size (0 = byte, 1 = short, 2 = long) */
418          32,                    /* bitsize */
419          true,                  /* pc_relative */
420          0,                     /* bitpos */
421          complain_overflow_bitfield,/* complain_on_overflow */
422          bfd_elf_generic_reloc, /* special_function */
423          "R_ARM_GOTPC",         /* name */
424          true,                  /* partial_inplace */
425          0xffffffff,            /* src_mask */
426          0xffffffff,            /* dst_mask */
427          true),                 /* pcrel_offset */
428
429   HOWTO (R_ARM_GOT32,           /* type */
430          0,                     /* rightshift */
431          2,                     /* size (0 = byte, 1 = short, 2 = long) */
432          32,                    /* bitsize */
433          false,                 /* pc_relative */
434          0,                     /* bitpos */
435          complain_overflow_bitfield,/* complain_on_overflow */
436          bfd_elf_generic_reloc, /* special_function */
437          "R_ARM_GOT32",         /* name */
438          true,                  /* partial_inplace */
439          0xffffffff,            /* src_mask */
440          0xffffffff,            /* dst_mask */
441          false),                /* pcrel_offset */
442
443   HOWTO (R_ARM_PLT32,           /* type */
444          2,                     /* rightshift */
445          2,                     /* size (0 = byte, 1 = short, 2 = long) */
446          26,                    /* bitsize */
447          true,                  /* pc_relative */
448          0,                     /* bitpos */
449          complain_overflow_bitfield,/* complain_on_overflow */
450          bfd_elf_generic_reloc, /* special_function */
451          "R_ARM_PLT32",         /* name */
452          true,                  /* partial_inplace */
453          0x00ffffff,            /* src_mask */
454          0x00ffffff,            /* dst_mask */
455          true),                 /* pcrel_offset */
456
457   /* End of relocs used in ARM Linux */
458
459   HOWTO (R_ARM_RREL32,          /* type */
460          0,                     /* rightshift */
461          0,                     /* size (0 = byte, 1 = short, 2 = long) */
462          0,                     /* bitsize */
463          false,                 /* pc_relative */
464          0,                     /* bitpos */
465          complain_overflow_dont,/* complain_on_overflow */
466          bfd_elf_generic_reloc, /* special_function */
467          "R_ARM_RREL32",        /* name */
468          false,                 /* partial_inplace */
469          0,                     /* src_mask */
470          0,                     /* dst_mask */
471          false),                /* pcrel_offset */
472
473   HOWTO (R_ARM_RABS32,          /* type */
474          0,                     /* rightshift */
475          0,                     /* size (0 = byte, 1 = short, 2 = long) */
476          0,                     /* bitsize */
477          false,                 /* pc_relative */
478          0,                     /* bitpos */
479          complain_overflow_dont,/* complain_on_overflow */
480          bfd_elf_generic_reloc, /* special_function */
481          "R_ARM_RABS32",        /* name */
482          false,                 /* partial_inplace */
483          0,                     /* src_mask */
484          0,                     /* dst_mask */
485          false),                /* pcrel_offset */
486
487   HOWTO (R_ARM_RPC24,           /* type */
488          0,                     /* rightshift */
489          0,                     /* size (0 = byte, 1 = short, 2 = long) */
490          0,                     /* bitsize */
491          false,                 /* pc_relative */
492          0,                     /* bitpos */
493          complain_overflow_dont,/* complain_on_overflow */
494          bfd_elf_generic_reloc, /* special_function */
495          "R_ARM_RPC24",         /* name */
496          false,                 /* partial_inplace */
497          0,                     /* src_mask */
498          0,                     /* dst_mask */
499          false),                /* pcrel_offset */
500
501   HOWTO (R_ARM_RBASE,           /* type */
502          0,                     /* rightshift */
503          0,                     /* size (0 = byte, 1 = short, 2 = long) */
504          0,                     /* bitsize */
505          false,                 /* pc_relative */
506          0,                     /* bitpos */
507          complain_overflow_dont,/* complain_on_overflow */
508          bfd_elf_generic_reloc, /* special_function */
509          "R_ARM_RBASE",         /* name */
510          false,                 /* partial_inplace */
511          0,                     /* src_mask */
512          0,                     /* dst_mask */
513          false),                /* pcrel_offset */
514
515 };
516
517   /* GNU extension to record C++ vtable hierarchy */
518 static reloc_howto_type elf32_arm_vtinherit_howto =
519   HOWTO (R_ARM_GNU_VTINHERIT, /* type */
520          0,                     /* rightshift */
521          2,                     /* size (0 = byte, 1 = short, 2 = long) */
522          0,                     /* bitsize */
523          false,                 /* pc_relative */
524          0,                     /* bitpos */
525          complain_overflow_dont, /* complain_on_overflow */
526          NULL,                  /* special_function */
527          "R_ARM_GNU_VTINHERIT", /* name */
528          false,                 /* partial_inplace */
529          0,                     /* src_mask */
530          0,                     /* dst_mask */
531          false);                /* pcrel_offset */
532
533   /* GNU extension to record C++ vtable member usage */
534 static reloc_howto_type elf32_arm_vtentry_howto =
535   HOWTO (R_ARM_GNU_VTENTRY,     /* type */
536          0,                     /* rightshift */
537          2,                     /* size (0 = byte, 1 = short, 2 = long) */
538          0,                     /* bitsize */
539          false,                 /* pc_relative */
540          0,                     /* bitpos */
541          complain_overflow_dont, /* complain_on_overflow */
542          _bfd_elf_rel_vtable_reloc_fn,  /* special_function */
543          "R_ARM_GNU_VTENTRY",   /* name */
544          false,                 /* partial_inplace */
545          0,                     /* src_mask */
546          0,                     /* dst_mask */
547          false);                /* pcrel_offset */
548
549   /* 12 bit pc relative */
550 static reloc_howto_type elf32_arm_thm_pc11_howto =
551   HOWTO (R_ARM_THM_PC11,        /* type */
552          1,                     /* rightshift */
553          1,                     /* size (0 = byte, 1 = short, 2 = long) */
554          11,                    /* bitsize */
555          true,                  /* pc_relative */
556          0,                     /* bitpos */
557          complain_overflow_signed,      /* complain_on_overflow */
558          bfd_elf_generic_reloc, /* special_function */
559          "R_ARM_THM_PC11",      /* name */
560          false,                 /* partial_inplace */
561          0x000007ff,            /* src_mask */
562          0x000007ff,            /* dst_mask */
563          true);                 /* pcrel_offset */
564
565   /* 12 bit pc relative */
566 static reloc_howto_type elf32_arm_thm_pc9_howto =
567   HOWTO (R_ARM_THM_PC9,         /* type */
568          1,                     /* rightshift */
569          1,                     /* size (0 = byte, 1 = short, 2 = long) */
570          8,                     /* bitsize */
571          true,                  /* pc_relative */
572          0,                     /* bitpos */
573          complain_overflow_signed,      /* complain_on_overflow */
574          bfd_elf_generic_reloc, /* special_function */
575          "R_ARM_THM_PC9",       /* name */
576          false,                 /* partial_inplace */
577          0x000000ff,            /* src_mask */
578          0x000000ff,            /* dst_mask */
579          true);                 /* pcrel_offset */
580
581 static void
582 elf32_arm_info_to_howto (abfd, bfd_reloc, elf_reloc)
583      bfd * abfd ATTRIBUTE_UNUSED;
584      arelent * bfd_reloc;
585      Elf32_Internal_Rel * elf_reloc;
586 {
587   unsigned int r_type;
588
589   r_type = ELF32_R_TYPE (elf_reloc->r_info);
590
591   switch (r_type)
592     {
593     case R_ARM_GNU_VTINHERIT:
594       bfd_reloc->howto = & elf32_arm_vtinherit_howto;
595       break;
596
597     case R_ARM_GNU_VTENTRY:
598       bfd_reloc->howto = & elf32_arm_vtentry_howto;
599       break;
600
601     case R_ARM_THM_PC11:
602       bfd_reloc->howto = & elf32_arm_thm_pc11_howto;
603       break;
604
605     case R_ARM_THM_PC9:
606       bfd_reloc->howto = & elf32_arm_thm_pc9_howto;
607       break;
608
609     default:
610       if (r_type >= NUM_ELEM (elf32_arm_howto_table))
611         bfd_reloc->howto = NULL;
612       else
613         bfd_reloc->howto = & elf32_arm_howto_table[r_type];
614       break;
615     }
616 }
617
618 struct elf32_arm_reloc_map
619   {
620     bfd_reloc_code_real_type  bfd_reloc_val;
621     unsigned char             elf_reloc_val;
622   };
623
624 static const struct elf32_arm_reloc_map elf32_arm_reloc_map[] =
625 {
626   {BFD_RELOC_NONE,                 R_ARM_NONE},
627   {BFD_RELOC_ARM_PCREL_BRANCH,     R_ARM_PC24},
628   {BFD_RELOC_ARM_PCREL_BLX,        R_ARM_XPC25},
629   {BFD_RELOC_THUMB_PCREL_BLX,      R_ARM_THM_XPC22},
630   {BFD_RELOC_32,                   R_ARM_ABS32},
631   {BFD_RELOC_32_PCREL,             R_ARM_REL32},
632   {BFD_RELOC_8,                    R_ARM_ABS8},
633   {BFD_RELOC_16,                   R_ARM_ABS16},
634   {BFD_RELOC_ARM_OFFSET_IMM,       R_ARM_ABS12},
635   {BFD_RELOC_ARM_THUMB_OFFSET,     R_ARM_THM_ABS5},
636   {BFD_RELOC_THUMB_PCREL_BRANCH23, R_ARM_THM_PC22},
637   {BFD_RELOC_ARM_COPY,             R_ARM_COPY},
638   {BFD_RELOC_ARM_GLOB_DAT,         R_ARM_GLOB_DAT},
639   {BFD_RELOC_ARM_JUMP_SLOT,        R_ARM_JUMP_SLOT},
640   {BFD_RELOC_ARM_RELATIVE,         R_ARM_RELATIVE},
641   {BFD_RELOC_ARM_GOTOFF,           R_ARM_GOTOFF},
642   {BFD_RELOC_ARM_GOTPC,            R_ARM_GOTPC},
643   {BFD_RELOC_ARM_GOT32,            R_ARM_GOT32},
644   {BFD_RELOC_ARM_PLT32,            R_ARM_PLT32}
645 };
646
647 static reloc_howto_type *
648 elf32_arm_reloc_type_lookup (abfd, code)
649      bfd *abfd ATTRIBUTE_UNUSED;
650      bfd_reloc_code_real_type code;
651 {
652   unsigned int i;
653
654   switch (code)
655     {
656     case BFD_RELOC_VTABLE_INHERIT:
657       return & elf32_arm_vtinherit_howto;
658
659     case BFD_RELOC_VTABLE_ENTRY:
660       return & elf32_arm_vtentry_howto;
661
662     case BFD_RELOC_THUMB_PCREL_BRANCH12:
663       return & elf32_arm_thm_pc11_howto;
664
665     case BFD_RELOC_THUMB_PCREL_BRANCH9:
666       return & elf32_arm_thm_pc9_howto;
667
668     default:
669       for (i = 0; i < NUM_ELEM (elf32_arm_reloc_map); i ++)
670         if (elf32_arm_reloc_map[i].bfd_reloc_val == code)
671           return & elf32_arm_howto_table[elf32_arm_reloc_map[i].elf_reloc_val];
672
673       return NULL;
674    }
675 }
676
677 #include "elf32-arm.h"