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