]> Git Repo - binutils.git/blob - bfd/elfarm-oabi.c
Return bfd_error_wrong_format on a format mismatch.
[binutils.git] / bfd / elfarm-oabi.c
1 /* 32-bit ELF support for ARM old 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-oabi.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_RELA
31
32 #define TARGET_LITTLE_SYM               bfd_elf32_littlearm_oabi_vec
33 #define TARGET_LITTLE_NAME              "elf32-littlearm-oabi"
34 #define TARGET_BIG_SYM                  bfd_elf32_bigarm_oabi_vec
35 #define TARGET_BIG_NAME                 "elf32-bigarm-oabi"
36
37 #define elf_info_to_howto               elf32_arm_info_to_howto
38 #define elf_info_to_howto_rel           0
39
40 #define ARM_ELF_ABI_VERSION             0
41 #define ARM_ELF_OS_ABI_VERSION          0
42
43 static reloc_howto_type elf32_arm_howto_table[] =
44 {
45   /* No relocation */
46   HOWTO (R_ARM_NONE,            /* type */
47          0,                     /* rightshift */
48          0,                     /* size (0 = byte, 1 = short, 2 = long) */
49          0,                     /* bitsize */
50          false,                 /* pc_relative */
51          0,                     /* bitpos */
52          complain_overflow_dont,        /* complain_on_overflow */
53          bfd_elf_generic_reloc, /* special_function */
54          "R_ARM_NONE",          /* name */
55          false,                 /* partial_inplace */
56          0,                     /* src_mask */
57          0,                     /* dst_mask */
58          false),                /* pcrel_offset */
59
60   HOWTO (R_ARM_PC24,            /* type */
61          2,                     /* rightshift */
62          2,                     /* size (0 = byte, 1 = short, 2 = long) */
63          24,                    /* bitsize */
64          true,                  /* pc_relative */
65          0,                     /* bitpos */
66          complain_overflow_signed,      /* complain_on_overflow */
67          bfd_elf_generic_reloc, /* special_function */
68          "R_ARM_PC24",          /* name */
69          false,                 /* partial_inplace */
70          0x00ffffff,            /* src_mask */
71          0x00ffffff,            /* dst_mask */
72          true),                 /* pcrel_offset */
73
74   /* 32 bit absolute */
75   HOWTO (R_ARM_ABS32,           /* type */
76          0,                     /* rightshift */
77          2,                     /* size (0 = byte, 1 = short, 2 = long) */
78          32,                    /* bitsize */
79          false,                 /* pc_relative */
80          0,                     /* bitpos */
81          complain_overflow_bitfield,    /* complain_on_overflow */
82          bfd_elf_generic_reloc, /* special_function */
83          "R_ARM_ABS32",         /* name */
84          false,                 /* partial_inplace */
85          0xffffffff,            /* src_mask */
86          0xffffffff,            /* dst_mask */
87          false),                /* pcrel_offset */
88
89   /* standard 32bit pc-relative reloc */
90   HOWTO (R_ARM_REL32,           /* type */
91          0,                     /* rightshift */
92          2,                     /* size (0 = byte, 1 = short, 2 = long) */
93          32,                    /* bitsize */
94          true,                  /* pc_relative */
95          0,                     /* bitpos */
96          complain_overflow_bitfield,    /* complain_on_overflow */
97          bfd_elf_generic_reloc, /* special_function */
98          "R_ARM_REL32",         /* name */
99          false,                 /* partial_inplace */
100          0xffffffff,            /* src_mask */
101          0xffffffff,            /* dst_mask */
102          true),                 /* pcrel_offset */
103
104   /* 8 bit absolute */
105   HOWTO (R_ARM_ABS8,            /* type */
106          0,                     /* rightshift */
107          0,                     /* size (0 = byte, 1 = short, 2 = long) */
108          8,                     /* bitsize */
109          false,                 /* pc_relative */
110          0,                     /* bitpos */
111          complain_overflow_bitfield,    /* complain_on_overflow */
112          bfd_elf_generic_reloc, /* special_function */
113          "R_ARM_ABS8",          /* name */
114          false,                 /* partial_inplace */
115          0x000000ff,            /* src_mask */
116          0x000000ff,            /* dst_mask */
117          false),                /* pcrel_offset */
118
119    /* 16 bit absolute */
120   HOWTO (R_ARM_ABS16,           /* type */
121          0,                     /* rightshift */
122          1,                     /* size (0 = byte, 1 = short, 2 = long) */
123          16,                    /* bitsize */
124          false,                 /* pc_relative */
125          0,                     /* bitpos */
126          complain_overflow_bitfield,    /* complain_on_overflow */
127          bfd_elf_generic_reloc, /* special_function */
128          "R_ARM_ABS16",         /* name */
129          false,                 /* partial_inplace */
130          0,                     /* src_mask */
131          0,                     /* dst_mask */
132          false),                /* pcrel_offset */
133
134   /* 12 bit absolute */
135   HOWTO (R_ARM_ABS12,           /* type */
136          0,                     /* rightshift */
137          2,                     /* size (0 = byte, 1 = short, 2 = long) */
138          12,                    /* bitsize */
139          false,                 /* pc_relative */
140          0,                     /* bitpos */
141          complain_overflow_bitfield,    /* complain_on_overflow */
142          bfd_elf_generic_reloc, /* special_function */
143          "R_ARM_ABS12",         /* name */
144          false,                 /* partial_inplace */
145          0x000008ff,            /* src_mask */
146          0x000008ff,            /* dst_mask */
147          false),                /* pcrel_offset */
148
149   HOWTO (R_ARM_THM_ABS5,        /* type */
150          6,                     /* rightshift */
151          1,                     /* size (0 = byte, 1 = short, 2 = long) */
152          5,                     /* bitsize */
153          false,                 /* pc_relative */
154          0,                     /* bitpos */
155          complain_overflow_bitfield,    /* complain_on_overflow */
156          bfd_elf_generic_reloc, /* special_function */
157          "R_ARM_THM_ABS5",      /* name */
158          false,                 /* partial_inplace */
159          0x000007e0,            /* src_mask */
160          0x000007e0,            /* dst_mask */
161          false),                /* pcrel_offset */
162
163   HOWTO (R_ARM_THM_PC22,        /* type */
164          1,                     /* rightshift */
165          2,                     /* size (0 = byte, 1 = short, 2 = long) */
166          23,                    /* bitsize */
167          true,                  /* pc_relative */
168          0,                     /* bitpos */
169          complain_overflow_signed,      /* complain_on_overflow */
170          bfd_elf_generic_reloc, /* special_function */
171          "R_ARM_THM_PC22",      /* name */
172          false,                 /* partial_inplace */
173          0x07ff07ff,            /* src_mask */
174          0x07ff07ff,            /* dst_mask */
175          true),                 /* pcrel_offset */
176
177   HOWTO (R_ARM_SBREL32,         /* type */
178          0,                     /* rightshift */
179          0,                     /* size (0 = byte, 1 = short, 2 = long) */
180          0,                     /* bitsize */
181          false,                 /* pc_relative */
182          0,                     /* bitpos */
183          complain_overflow_dont,/* complain_on_overflow */
184          bfd_elf_generic_reloc, /* special_function */
185          "R_ARM_SBREL32",       /* name */
186          false,                 /* partial_inplace */
187          0,                     /* src_mask */
188          0,                     /* dst_mask */
189          false),                /* pcrel_offset */
190
191   HOWTO (R_ARM_AMP_VCALL9,      /* type */
192          1,                     /* rightshift */
193          1,                     /* size (0 = byte, 1 = short, 2 = long) */
194          8,                     /* bitsize */
195          true,                  /* pc_relative */
196          0,                     /* bitpos */
197          complain_overflow_signed,      /* complain_on_overflow */
198          bfd_elf_generic_reloc, /* special_function */
199          "R_ARM_AMP_VCALL9",    /* name */
200          false,                 /* partial_inplace */
201          0x000000ff,            /* src_mask */
202          0x000000ff,            /* dst_mask */
203          true),                 /* pcrel_offset */
204
205   /* 12 bit pc relative */
206   HOWTO (R_ARM_THM_PC11,        /* type */
207          1,                     /* rightshift */
208          1,                     /* size (0 = byte, 1 = short, 2 = long) */
209          11,                    /* bitsize */
210          true,                  /* pc_relative */
211          0,                     /* bitpos */
212          complain_overflow_signed,      /* complain_on_overflow */
213          bfd_elf_generic_reloc, /* special_function */
214          "R_ARM_THM_PC11",      /* name */
215          false,                 /* partial_inplace */
216          0x000007ff,            /* src_mask */
217          0x000007ff,            /* dst_mask */
218          true),                 /* pcrel_offset */
219
220   /* 12 bit pc relative */
221   HOWTO (R_ARM_THM_PC9,         /* 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_THM_PC9",       /* name */
230          false,                 /* partial_inplace */
231          0x000000ff,            /* src_mask */
232          0x000000ff,            /* dst_mask */
233          true),                 /* pcrel_offset */
234
235   /* GNU extension to record C++ vtable hierarchy */
236   HOWTO (R_ARM_GNU_VTINHERIT, /* type */
237          0,                     /* rightshift */
238          2,                     /* size (0 = byte, 1 = short, 2 = long) */
239          0,                     /* bitsize */
240          false,                 /* pc_relative */
241          0,                     /* bitpos */
242          complain_overflow_dont, /* complain_on_overflow */
243          NULL,                  /* special_function */
244          "R_ARM_GNU_VTINHERIT", /* name */
245          false,                 /* partial_inplace */
246          0,                     /* src_mask */
247          0,                     /* dst_mask */
248          false),                /* pcrel_offset */
249
250   /* GNU extension to record C++ vtable member usage */
251   HOWTO (R_ARM_GNU_VTENTRY,     /* type */
252          0,                     /* rightshift */
253          2,                     /* size (0 = byte, 1 = short, 2 = long) */
254          0,                     /* bitsize */
255          false,                 /* pc_relative */
256          0,                     /* bitpos */
257          complain_overflow_dont, /* complain_on_overflow */
258          _bfd_elf_rel_vtable_reloc_fn,  /* special_function */
259          "R_ARM_GNU_VTENTRY",   /* name */
260          false,                 /* partial_inplace */
261          0,                     /* src_mask */
262          0,                     /* dst_mask */
263          false),                /* pcrel_offset */
264
265   /* XXX - gap in index numbering here.  */
266   
267   HOWTO (R_ARM_PLT32,           /* type */
268          2,                     /* rightshift */
269          2,                     /* size (0 = byte, 1 = short, 2 = long) */
270          26,                    /* bitsize */
271          true,                  /* pc_relative */
272          0,                     /* bitpos */
273          complain_overflow_bitfield,/* complain_on_overflow */
274          bfd_elf_generic_reloc, /* special_function */
275          "R_ARM_PLT32",         /* name */
276          true,                  /* partial_inplace */
277          0x00ffffff,            /* src_mask */
278          0x00ffffff,            /* dst_mask */
279          true),                 /* pcrel_offset */
280   
281   /* XXX - gap in index numbering here.  */
282
283   HOWTO (R_ARM_RREL32,          /* type */
284          0,                     /* rightshift */
285          0,                     /* size (0 = byte, 1 = short, 2 = long) */
286          0,                     /* bitsize */
287          false,                 /* pc_relative */
288          0,                     /* bitpos */
289          complain_overflow_dont,        /* complain_on_overflow */
290          bfd_elf_generic_reloc, /* special_function */
291          "R_ARM_RREL32",        /* name */
292          false,                 /* partial_inplace */
293          0,                     /* src_mask */
294          0,                     /* dst_mask */
295          false),                /* pcrel_offset */
296
297   HOWTO (R_ARM_RABS32,          /* type */
298          0,                     /* rightshift */
299          0,                     /* size (0 = byte, 1 = short, 2 = long) */
300          0,                     /* bitsize */
301          false,                 /* pc_relative */
302          0,                     /* bitpos */
303          complain_overflow_dont,        /* complain_on_overflow */
304          bfd_elf_generic_reloc, /* special_function */
305          "R_ARM_RABS32",        /* name */
306          false,                 /* partial_inplace */
307          0,                     /* src_mask */
308          0,                     /* dst_mask */
309          false),                /* pcrel_offset */
310
311   HOWTO (R_ARM_RPC24,           /* type */
312          0,                     /* rightshift */
313          0,                     /* size (0 = byte, 1 = short, 2 = long) */
314          0,                     /* bitsize */
315          false,                 /* pc_relative */
316          0,                     /* bitpos */
317          complain_overflow_dont,        /* complain_on_overflow */
318          bfd_elf_generic_reloc, /* special_function */
319          "R_ARM_RPC24",         /* name */
320          false,                 /* partial_inplace */
321          0,                     /* src_mask */
322          0,                     /* dst_mask */
323          false),                /* pcrel_offset */
324
325   HOWTO (R_ARM_RBASE,           /* type */
326          0,                     /* rightshift */
327          0,                     /* size (0 = byte, 1 = short, 2 = long) */
328          0,                     /* bitsize */
329          false,                 /* pc_relative */
330          0,                     /* bitpos */
331          complain_overflow_dont,        /* complain_on_overflow */
332          bfd_elf_generic_reloc, /* special_function */
333          "R_ARM_RBASE",         /* name */
334          false,                 /* partial_inplace */
335          0,                     /* src_mask */
336          0,                     /* dst_mask */
337          false)                 /* pcrel_offset */
338 };
339
340 /* Locate a reloc in the howto table.  This function must be used
341    when the entry number is is > R_ARM_GNU_VTINHERIT.  */
342 static reloc_howto_type *
343 find_howto (r_type)
344      unsigned int r_type;
345 {
346   int i;
347   
348   for (i = NUM_ELEM (elf32_arm_howto_table); i--;)
349     if (elf32_arm_howto_table [i].type == r_type)
350       return elf32_arm_howto_table + i;
351
352   return NULL;
353 }
354
355 static void
356 elf32_arm_info_to_howto (abfd, bfd_reloc, elf_reloc)
357      bfd *abfd ATTRIBUTE_UNUSED;
358      arelent *bfd_reloc;
359      Elf32_Internal_Rela *elf_reloc;
360 {
361   unsigned int r_type;
362
363   r_type = ELF32_R_TYPE (elf_reloc->r_info);
364
365   if (r_type <= R_ARM_GNU_VTINHERIT)
366     bfd_reloc->howto = & elf32_arm_howto_table[r_type];
367   else
368     bfd_reloc->howto = find_howto (r_type);
369 }
370
371 struct elf32_arm_reloc_map
372   {
373     bfd_reloc_code_real_type bfd_reloc_val;
374     unsigned char elf_reloc_val;
375   };
376
377 static const struct elf32_arm_reloc_map elf32_arm_reloc_map[] =
378 {
379   {BFD_RELOC_NONE,                 R_ARM_NONE },
380   {BFD_RELOC_ARM_PCREL_BRANCH,     R_ARM_PC24 },
381   {BFD_RELOC_32,                   R_ARM_ABS32 },
382   {BFD_RELOC_32_PCREL,             R_ARM_REL32 },
383   {BFD_RELOC_8,                    R_ARM_ABS8 },
384   {BFD_RELOC_16,                   R_ARM_ABS16 },
385   {BFD_RELOC_ARM_OFFSET_IMM,       R_ARM_ABS12 },
386   {BFD_RELOC_ARM_THUMB_OFFSET,     R_ARM_THM_ABS5 },
387   {BFD_RELOC_THUMB_PCREL_BRANCH23, R_ARM_THM_PC22 },
388   {BFD_RELOC_NONE,                 R_ARM_SBREL32 },
389   {BFD_RELOC_NONE,                 R_ARM_AMP_VCALL9 },
390   {BFD_RELOC_THUMB_PCREL_BRANCH12, R_ARM_THM_PC11 },
391   {BFD_RELOC_THUMB_PCREL_BRANCH9,  R_ARM_THM_PC9 },  
392   {BFD_RELOC_VTABLE_INHERIT,       R_ARM_GNU_VTINHERIT },
393   {BFD_RELOC_VTABLE_ENTRY,         R_ARM_GNU_VTENTRY }
394 };
395
396 static reloc_howto_type *
397 elf32_arm_reloc_type_lookup (abfd, code)
398      bfd * abfd ATTRIBUTE_UNUSED;
399      bfd_reloc_code_real_type code;
400 {
401   unsigned int i;
402
403   for (i = NUM_ELEM (elf32_arm_reloc_map); i--;)
404     if (elf32_arm_reloc_map[i].bfd_reloc_val == code)
405       return & elf32_arm_howto_table [elf32_arm_reloc_map[i].elf_reloc_val];
406
407   if (code == BFD_RELOC_ARM_PLT32)
408     return find_howto (R_ARM_PLT32);
409   
410   return NULL;
411 }
412
413 #define bfd_elf32_arm_allocate_interworking_sections \
414         bfd_elf32_arm_oabi_allocate_interworking_sections
415 #define bfd_elf32_arm_get_bfd_for_interworking \
416         bfd_elf32_arm_oabi_get_bfd_for_interworking
417 #define bfd_elf32_arm_process_before_allocation \
418         bfd_elf32_arm_oabi_process_before_allocation
419
420 #include "elf32-arm.h"
This page took 0.048251 seconds and 4 git commands to generate.