* elf32-arm.c (elf32_arm_symbian_begin_write_processing): Clear
[external/binutils.git] / bfd / elf32-arm.c
1 /* 32-bit ELF support for ARM
2    Copyright 1998, 1999, 2000, 2001, 2002, 2003, 2004
3    Free Software Foundation, Inc.
4
5    This file is part of BFD, the Binary File Descriptor library.
6
7    This program is free software; you can redistribute it and/or modify
8    it under the terms of the GNU General Public License as published by
9    the Free Software Foundation; either version 2 of the License, or
10    (at your option) any later version.
11
12    This program is distributed in the hope that it will be useful,
13    but WITHOUT ANY WARRANTY; without even the implied warranty of
14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15    GNU General Public License for more details.
16
17    You should have received a copy of the GNU General Public License
18    along with this program; if not, write to the Free Software
19    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
20
21 #include "elf/arm.h"
22 #include "bfd.h"
23 #include "sysdep.h"
24 #include "libbfd.h"
25 #include "elf-bfd.h"
26
27 #ifndef NUM_ELEM
28 #define NUM_ELEM(a)  (sizeof (a) / (sizeof (a)[0]))
29 #endif
30
31 #define USE_REL 1
32
33 #define elf_info_to_howto               0
34 #define elf_info_to_howto_rel           elf32_arm_info_to_howto
35
36 #define ARM_ELF_ABI_VERSION             0
37 #define ARM_ELF_OS_ABI_VERSION          ELFOSABI_ARM
38
39 static reloc_howto_type * elf32_arm_reloc_type_lookup
40   PARAMS ((bfd * abfd, bfd_reloc_code_real_type code));
41 static bfd_boolean elf32_arm_nabi_grok_prstatus
42   PARAMS ((bfd *abfd, Elf_Internal_Note *note));
43 static bfd_boolean elf32_arm_nabi_grok_psinfo
44   PARAMS ((bfd *abfd, Elf_Internal_Note *note));
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          0x0000ffff,            /* src_mask */
138          0x0000ffff,            /* 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          2,                     /* size (0 = byte, 1 = short, 2 = long) */
188          32,                    /* 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          0xffffffff,            /* src_mask */
196          0xffffffff,            /* 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   HOWTO (R_ARM_CALL,            /* type */
458          2,                     /* rightshift */
459          2,                     /* size (0 = byte, 1 = short, 2 = long) */
460          24,                    /* bitsize */
461          TRUE,                  /* pc_relative */
462          0,                     /* bitpos */
463          complain_overflow_signed,/* complain_on_overflow */
464          bfd_elf_generic_reloc, /* special_function */
465          "R_ARM_CALL",          /* name */
466          FALSE,                 /* partial_inplace */
467          0x00ffffff,            /* src_mask */
468          0x00ffffff,            /* dst_mask */
469          TRUE),                 /* pcrel_offset */
470
471   HOWTO (R_ARM_JUMP24,          /* type */
472          2,                     /* rightshift */
473          2,                     /* size (0 = byte, 1 = short, 2 = long) */
474          24,                    /* bitsize */
475          TRUE,                  /* pc_relative */
476          0,                     /* bitpos */
477          complain_overflow_signed,/* complain_on_overflow */
478          bfd_elf_generic_reloc, /* special_function */
479          "R_ARM_JUMP24",        /* name */
480          FALSE,                 /* partial_inplace */
481          0x00ffffff,            /* src_mask */
482          0x00ffffff,            /* dst_mask */
483          TRUE),                 /* pcrel_offset */
484
485   HOWTO (R_ARM_NONE,            /* type */
486          0,                     /* rightshift */
487          0,                     /* size (0 = byte, 1 = short, 2 = long) */
488          0,                     /* bitsize */
489          FALSE,                 /* pc_relative */
490          0,                     /* bitpos */
491          complain_overflow_dont,/* complain_on_overflow */
492          bfd_elf_generic_reloc, /* special_function */
493          "R_ARM_unknown_30",    /* name */
494          FALSE,                 /* partial_inplace */
495          0,                     /* src_mask */
496          0,                     /* dst_mask */
497          FALSE),                /* pcrel_offset */
498
499   HOWTO (R_ARM_NONE,            /* type */
500          0,                     /* rightshift */
501          0,                     /* size (0 = byte, 1 = short, 2 = long) */
502          0,                     /* bitsize */
503          FALSE,                 /* pc_relative */
504          0,                     /* bitpos */
505          complain_overflow_dont,/* complain_on_overflow */
506          bfd_elf_generic_reloc, /* special_function */
507          "R_ARM_unknown_31",    /* name */
508          FALSE,                 /* partial_inplace */
509          0,                     /* src_mask */
510          0,                     /* dst_mask */
511          FALSE),                /* pcrel_offset */
512
513   HOWTO (R_ARM_ALU_PCREL7_0,    /* type */
514          0,                     /* rightshift */
515          2,                     /* size (0 = byte, 1 = short, 2 = long) */
516          12,                    /* bitsize */
517          TRUE,                  /* pc_relative */
518          0,                     /* bitpos */
519          complain_overflow_dont,/* complain_on_overflow */
520          bfd_elf_generic_reloc, /* special_function */
521          "R_ARM_ALU_PCREL_7_0", /* name */
522          FALSE,                 /* partial_inplace */
523          0x00000fff,            /* src_mask */
524          0x00000fff,            /* dst_mask */
525          TRUE),                 /* pcrel_offset */
526
527   HOWTO (R_ARM_ALU_PCREL15_8,   /* type */
528          0,                     /* rightshift */
529          2,                     /* size (0 = byte, 1 = short, 2 = long) */
530          12,                    /* bitsize */
531          TRUE,                  /* pc_relative */
532          8,                     /* bitpos */
533          complain_overflow_dont,/* complain_on_overflow */
534          bfd_elf_generic_reloc, /* special_function */
535          "R_ARM_ALU_PCREL_15_8",/* name */
536          FALSE,                 /* partial_inplace */
537          0x00000fff,            /* src_mask */
538          0x00000fff,            /* dst_mask */
539          TRUE),                 /* pcrel_offset */
540
541   HOWTO (R_ARM_ALU_PCREL23_15,  /* type */
542          0,                     /* rightshift */
543          2,                     /* size (0 = byte, 1 = short, 2 = long) */
544          12,                    /* bitsize */
545          TRUE,                  /* pc_relative */
546          16,                    /* bitpos */
547          complain_overflow_dont,/* complain_on_overflow */
548          bfd_elf_generic_reloc, /* special_function */
549          "R_ARM_ALU_PCREL_23_15",/* name */
550          FALSE,                 /* partial_inplace */
551          0x00000fff,            /* src_mask */
552          0x00000fff,            /* dst_mask */
553          TRUE),                 /* pcrel_offset */
554
555   HOWTO (R_ARM_LDR_SBREL_11_0,  /* type */
556          0,                     /* rightshift */
557          2,                     /* size (0 = byte, 1 = short, 2 = long) */
558          12,                    /* bitsize */
559          FALSE,                 /* pc_relative */
560          0,                     /* bitpos */
561          complain_overflow_dont,/* complain_on_overflow */
562          bfd_elf_generic_reloc, /* special_function */
563          "R_ARM_LDR_SBREL_11_0",/* name */
564          FALSE,                 /* partial_inplace */
565          0x00000fff,            /* src_mask */
566          0x00000fff,            /* dst_mask */
567          FALSE),                /* pcrel_offset */
568
569   HOWTO (R_ARM_ALU_SBREL_19_12, /* type */
570          0,                     /* rightshift */
571          2,                     /* size (0 = byte, 1 = short, 2 = long) */
572          8,                     /* bitsize */
573          FALSE,                 /* pc_relative */
574          12,                    /* bitpos */
575          complain_overflow_dont,/* complain_on_overflow */
576          bfd_elf_generic_reloc, /* special_function */
577          "R_ARM_ALU_SBREL_19_12",/* name */
578          FALSE,                 /* partial_inplace */
579          0x000ff000,            /* src_mask */
580          0x000ff000,            /* dst_mask */
581          FALSE),                /* pcrel_offset */
582
583   HOWTO (R_ARM_ALU_SBREL_27_20, /* type */
584          0,                     /* rightshift */
585          2,                     /* size (0 = byte, 1 = short, 2 = long) */
586          8,                     /* bitsize */
587          FALSE,                 /* pc_relative */
588          20,                    /* bitpos */
589          complain_overflow_dont,/* complain_on_overflow */
590          bfd_elf_generic_reloc, /* special_function */
591          "R_ARM_ALU_SBREL_27_20",/* name */
592          FALSE,                 /* partial_inplace */
593          0x0ff00000,            /* src_mask */
594          0x0ff00000,            /* dst_mask */
595          FALSE),                /* pcrel_offset */
596
597   HOWTO (R_ARM_TARGET1,         /* type */
598          0,                     /* rightshift */
599          2,                     /* size (0 = byte, 1 = short, 2 = long) */
600          32,                    /* bitsize */
601          FALSE,                 /* pc_relative */
602          0,                     /* bitpos */
603          complain_overflow_dont,/* complain_on_overflow */
604          bfd_elf_generic_reloc, /* special_function */
605          "R_ARM_TARGET1",       /* name */
606          FALSE,                 /* partial_inplace */
607          0xffffffff,            /* src_mask */
608          0xffffffff,            /* dst_mask */
609          FALSE),                /* pcrel_offset */
610
611   HOWTO (R_ARM_ROSEGREL32,      /* type */
612          0,                     /* rightshift */
613          2,                     /* size (0 = byte, 1 = short, 2 = long) */
614          32,                    /* bitsize */
615          FALSE,                 /* pc_relative */
616          0,                     /* bitpos */
617          complain_overflow_dont,/* complain_on_overflow */
618          bfd_elf_generic_reloc, /* special_function */
619          "R_ARM_ROSEGREL32",    /* name */
620          FALSE,                 /* partial_inplace */
621          0xffffffff,            /* src_mask */
622          0xffffffff,            /* dst_mask */
623          FALSE),                /* pcrel_offset */
624
625   HOWTO (R_ARM_V4BX,            /* type */
626          0,                     /* rightshift */
627          2,                     /* size (0 = byte, 1 = short, 2 = long) */
628          32,                    /* bitsize */
629          FALSE,                 /* pc_relative */
630          0,                     /* bitpos */
631          complain_overflow_dont,/* complain_on_overflow */
632          bfd_elf_generic_reloc, /* special_function */
633          "R_ARM_V4BX",          /* name */
634          FALSE,                 /* partial_inplace */
635          0xffffffff,            /* src_mask */
636          0xffffffff,            /* dst_mask */
637          FALSE),                /* pcrel_offset */
638
639   HOWTO (R_ARM_TARGET2,         /* type */
640          0,                     /* rightshift */
641          2,                     /* size (0 = byte, 1 = short, 2 = long) */
642          32,                    /* bitsize */
643          FALSE,                 /* pc_relative */
644          0,                     /* bitpos */
645          complain_overflow_signed,/* complain_on_overflow */
646          bfd_elf_generic_reloc, /* special_function */
647          "R_ARM_TARGET2",       /* name */
648          FALSE,                 /* partial_inplace */
649          0xffffffff,            /* src_mask */
650          0xffffffff,            /* dst_mask */
651          TRUE),                 /* pcrel_offset */
652
653   HOWTO (R_ARM_PREL31,          /* type */
654          0,                     /* rightshift */
655          2,                     /* size (0 = byte, 1 = short, 2 = long) */
656          31,                    /* bitsize */
657          TRUE,                  /* pc_relative */
658          0,                     /* bitpos */
659          complain_overflow_signed,/* complain_on_overflow */
660          bfd_elf_generic_reloc, /* special_function */
661          "R_ARM_PREL31",        /* name */
662          FALSE,                 /* partial_inplace */
663          0x7fffffff,            /* src_mask */
664          0x7fffffff,            /* dst_mask */
665          TRUE),                 /* pcrel_offset */
666 };
667
668   /* GNU extension to record C++ vtable hierarchy */
669 static reloc_howto_type elf32_arm_vtinherit_howto =
670   HOWTO (R_ARM_GNU_VTINHERIT, /* type */
671          0,                     /* rightshift */
672          2,                     /* size (0 = byte, 1 = short, 2 = long) */
673          0,                     /* bitsize */
674          FALSE,                 /* pc_relative */
675          0,                     /* bitpos */
676          complain_overflow_dont, /* complain_on_overflow */
677          NULL,                  /* special_function */
678          "R_ARM_GNU_VTINHERIT", /* name */
679          FALSE,                 /* partial_inplace */
680          0,                     /* src_mask */
681          0,                     /* dst_mask */
682          FALSE);                /* pcrel_offset */
683
684   /* GNU extension to record C++ vtable member usage */
685 static reloc_howto_type elf32_arm_vtentry_howto =
686   HOWTO (R_ARM_GNU_VTENTRY,     /* type */
687          0,                     /* rightshift */
688          2,                     /* size (0 = byte, 1 = short, 2 = long) */
689          0,                     /* bitsize */
690          FALSE,                 /* pc_relative */
691          0,                     /* bitpos */
692          complain_overflow_dont, /* complain_on_overflow */
693          _bfd_elf_rel_vtable_reloc_fn,  /* special_function */
694          "R_ARM_GNU_VTENTRY",   /* name */
695          FALSE,                 /* partial_inplace */
696          0,                     /* src_mask */
697          0,                     /* dst_mask */
698          FALSE);                /* pcrel_offset */
699
700   /* 12 bit pc relative */
701 static reloc_howto_type elf32_arm_thm_pc11_howto =
702   HOWTO (R_ARM_THM_PC11,        /* type */
703          1,                     /* rightshift */
704          1,                     /* size (0 = byte, 1 = short, 2 = long) */
705          11,                    /* bitsize */
706          TRUE,                  /* pc_relative */
707          0,                     /* bitpos */
708          complain_overflow_signed,      /* complain_on_overflow */
709          bfd_elf_generic_reloc, /* special_function */
710          "R_ARM_THM_PC11",      /* name */
711          FALSE,                 /* partial_inplace */
712          0x000007ff,            /* src_mask */
713          0x000007ff,            /* dst_mask */
714          TRUE);                 /* pcrel_offset */
715
716   /* 12 bit pc relative */
717 static reloc_howto_type elf32_arm_thm_pc9_howto =
718   HOWTO (R_ARM_THM_PC9,         /* type */
719          1,                     /* rightshift */
720          1,                     /* size (0 = byte, 1 = short, 2 = long) */
721          8,                     /* bitsize */
722          TRUE,                  /* pc_relative */
723          0,                     /* bitpos */
724          complain_overflow_signed,      /* complain_on_overflow */
725          bfd_elf_generic_reloc, /* special_function */
726          "R_ARM_THM_PC9",       /* name */
727          FALSE,                 /* partial_inplace */
728          0x000000ff,            /* src_mask */
729          0x000000ff,            /* dst_mask */
730          TRUE);                 /* pcrel_offset */
731
732 /* Place relative GOT-indirect.  */
733 static reloc_howto_type elf32_arm_got_prel =
734   HOWTO (R_ARM_GOT_PREL,        /* type */
735          0,                     /* rightshift */
736          2,                     /* size (0 = byte, 1 = short, 2 = long) */
737          32,                    /* bitsize */
738          TRUE,                  /* pc_relative */
739          0,                     /* bitpos */
740          complain_overflow_dont,        /* complain_on_overflow */
741          bfd_elf_generic_reloc, /* special_function */
742          "R_ARM_GOT_PREL",      /* name */
743          FALSE,                 /* partial_inplace */
744          0xffffffff,            /* src_mask */
745          0xffffffff,            /* dst_mask */
746          TRUE);                 /* pcrel_offset */
747
748 /* Currently unused relocations.  */
749 static reloc_howto_type elf32_arm_r_howto[4] =
750 {
751   HOWTO (R_ARM_RREL32,          /* type */
752          0,                     /* rightshift */
753          0,                     /* size (0 = byte, 1 = short, 2 = long) */
754          0,                     /* bitsize */
755          FALSE,                 /* pc_relative */
756          0,                     /* bitpos */
757          complain_overflow_dont,/* complain_on_overflow */
758          bfd_elf_generic_reloc, /* special_function */
759          "R_ARM_RREL32",        /* name */
760          FALSE,                 /* partial_inplace */
761          0,                     /* src_mask */
762          0,                     /* dst_mask */
763          FALSE),                /* pcrel_offset */
764
765   HOWTO (R_ARM_RABS32,          /* type */
766          0,                     /* rightshift */
767          0,                     /* size (0 = byte, 1 = short, 2 = long) */
768          0,                     /* bitsize */
769          FALSE,                 /* pc_relative */
770          0,                     /* bitpos */
771          complain_overflow_dont,/* complain_on_overflow */
772          bfd_elf_generic_reloc, /* special_function */
773          "R_ARM_RABS32",        /* name */
774          FALSE,                 /* partial_inplace */
775          0,                     /* src_mask */
776          0,                     /* dst_mask */
777          FALSE),                /* pcrel_offset */
778
779   HOWTO (R_ARM_RPC24,           /* type */
780          0,                     /* rightshift */
781          0,                     /* size (0 = byte, 1 = short, 2 = long) */
782          0,                     /* bitsize */
783          FALSE,                 /* pc_relative */
784          0,                     /* bitpos */
785          complain_overflow_dont,/* complain_on_overflow */
786          bfd_elf_generic_reloc, /* special_function */
787          "R_ARM_RPC24",         /* name */
788          FALSE,                 /* partial_inplace */
789          0,                     /* src_mask */
790          0,                     /* dst_mask */
791          FALSE),                /* pcrel_offset */
792
793   HOWTO (R_ARM_RBASE,           /* type */
794          0,                     /* rightshift */
795          0,                     /* size (0 = byte, 1 = short, 2 = long) */
796          0,                     /* bitsize */
797          FALSE,                 /* pc_relative */
798          0,                     /* bitpos */
799          complain_overflow_dont,/* complain_on_overflow */
800          bfd_elf_generic_reloc, /* special_function */
801          "R_ARM_RBASE",         /* name */
802          FALSE,                 /* partial_inplace */
803          0,                     /* src_mask */
804          0,                     /* dst_mask */
805          FALSE)                 /* pcrel_offset */
806 };
807
808 static reloc_howto_type *
809 elf32_arm_howto_from_type (unsigned int r_type)
810 {
811   if (r_type < NUM_ELEM (elf32_arm_howto_table))
812     return &elf32_arm_howto_table[r_type];
813     
814   switch (r_type)
815     {
816     case R_ARM_GOT_PREL:
817       return &elf32_arm_got_prel;
818
819     case R_ARM_GNU_VTINHERIT:
820       return &elf32_arm_vtinherit_howto;
821
822     case R_ARM_GNU_VTENTRY:
823       return &elf32_arm_vtentry_howto;
824
825     case R_ARM_THM_PC11:
826       return &elf32_arm_thm_pc11_howto;
827
828     case R_ARM_THM_PC9:
829       return &elf32_arm_thm_pc9_howto;
830
831     case R_ARM_RREL32:
832     case R_ARM_RABS32:
833     case R_ARM_RPC24:
834     case R_ARM_RBASE:
835       return &elf32_arm_r_howto[r_type - R_ARM_RREL32];
836
837     default:
838       return NULL;
839     }
840 }
841
842 static void
843 elf32_arm_info_to_howto (bfd * abfd ATTRIBUTE_UNUSED, arelent * bfd_reloc,
844                          Elf_Internal_Rela * elf_reloc)
845 {
846   unsigned int r_type;
847
848   r_type = ELF32_R_TYPE (elf_reloc->r_info);
849   bfd_reloc->howto = elf32_arm_howto_from_type (r_type);
850 }
851
852 struct elf32_arm_reloc_map
853   {
854     bfd_reloc_code_real_type  bfd_reloc_val;
855     unsigned char             elf_reloc_val;
856   };
857
858 /* All entries in this list must also be present in elf32_arm_howto_table.  */
859 static const struct elf32_arm_reloc_map elf32_arm_reloc_map[] =
860   {
861     {BFD_RELOC_NONE,                 R_ARM_NONE},
862     {BFD_RELOC_ARM_PCREL_BRANCH,     R_ARM_PC24},
863     {BFD_RELOC_ARM_PCREL_BLX,        R_ARM_XPC25},
864     {BFD_RELOC_THUMB_PCREL_BLX,      R_ARM_THM_XPC22},
865     {BFD_RELOC_32,                   R_ARM_ABS32},
866     {BFD_RELOC_32_PCREL,             R_ARM_REL32},
867     {BFD_RELOC_8,                    R_ARM_ABS8},
868     {BFD_RELOC_16,                   R_ARM_ABS16},
869     {BFD_RELOC_ARM_OFFSET_IMM,       R_ARM_ABS12},
870     {BFD_RELOC_ARM_THUMB_OFFSET,     R_ARM_THM_ABS5},
871     {BFD_RELOC_THUMB_PCREL_BRANCH23, R_ARM_THM_PC22},
872     {BFD_RELOC_ARM_COPY,             R_ARM_COPY},
873     {BFD_RELOC_ARM_GLOB_DAT,         R_ARM_GLOB_DAT},
874     {BFD_RELOC_ARM_JUMP_SLOT,        R_ARM_JUMP_SLOT},
875     {BFD_RELOC_ARM_RELATIVE,         R_ARM_RELATIVE},
876     {BFD_RELOC_ARM_GOTOFF,           R_ARM_GOTOFF},
877     {BFD_RELOC_ARM_GOTPC,            R_ARM_GOTPC},
878     {BFD_RELOC_ARM_GOT32,            R_ARM_GOT32},
879     {BFD_RELOC_ARM_PLT32,            R_ARM_PLT32},
880     {BFD_RELOC_ARM_TARGET1,          R_ARM_TARGET1},
881     {BFD_RELOC_ARM_ROSEGREL32,       R_ARM_ROSEGREL32},
882     {BFD_RELOC_ARM_SBREL32,          R_ARM_SBREL32},
883     {BFD_RELOC_ARM_PREL31,           R_ARM_PREL31},
884     {BFD_RELOC_ARM_TARGET2,          R_ARM_TARGET2}
885   };
886
887 static reloc_howto_type *
888 elf32_arm_reloc_type_lookup (abfd, code)
889      bfd *abfd ATTRIBUTE_UNUSED;
890      bfd_reloc_code_real_type code;
891 {
892   unsigned int i;
893
894   switch (code)
895     {
896     case BFD_RELOC_VTABLE_INHERIT:
897       return & elf32_arm_vtinherit_howto;
898
899     case BFD_RELOC_VTABLE_ENTRY:
900       return & elf32_arm_vtentry_howto;
901
902     case BFD_RELOC_THUMB_PCREL_BRANCH12:
903       return & elf32_arm_thm_pc11_howto;
904
905     case BFD_RELOC_THUMB_PCREL_BRANCH9:
906       return & elf32_arm_thm_pc9_howto;
907
908     default:
909       for (i = 0; i < NUM_ELEM (elf32_arm_reloc_map); i ++)
910         if (elf32_arm_reloc_map[i].bfd_reloc_val == code)
911           return & elf32_arm_howto_table[elf32_arm_reloc_map[i].elf_reloc_val];
912
913       return NULL;
914    }
915 }
916
917 /* Support for core dump NOTE sections */
918 static bfd_boolean
919 elf32_arm_nabi_grok_prstatus (abfd, note)
920      bfd *abfd;
921      Elf_Internal_Note *note;
922 {
923   int offset;
924   size_t size;
925
926   switch (note->descsz)
927     {
928       default:
929         return FALSE;
930
931       case 148:         /* Linux/ARM 32-bit*/
932         /* pr_cursig */
933         elf_tdata (abfd)->core_signal = bfd_get_16 (abfd, note->descdata + 12);
934
935         /* pr_pid */
936         elf_tdata (abfd)->core_pid = bfd_get_32 (abfd, note->descdata + 24);
937
938         /* pr_reg */
939         offset = 72;
940         size = 72;
941
942         break;
943     }
944
945   /* Make a ".reg/999" section.  */
946   return _bfd_elfcore_make_pseudosection (abfd, ".reg",
947                                           size, note->descpos + offset);
948 }
949
950 static bfd_boolean
951 elf32_arm_nabi_grok_psinfo (abfd, note)
952      bfd *abfd;
953      Elf_Internal_Note *note;
954 {
955   switch (note->descsz)
956     {
957       default:
958         return FALSE;
959
960       case 124:         /* Linux/ARM elf_prpsinfo */
961         elf_tdata (abfd)->core_program
962          = _bfd_elfcore_strndup (abfd, note->descdata + 28, 16);
963         elf_tdata (abfd)->core_command
964          = _bfd_elfcore_strndup (abfd, note->descdata + 44, 80);
965     }
966
967   /* Note that for some reason, a spurious space is tacked
968      onto the end of the args in some (at least one anyway)
969      implementations, so strip it off if it exists.  */
970
971   {
972     char *command = elf_tdata (abfd)->core_command;
973     int n = strlen (command);
974
975     if (0 < n && command[n - 1] == ' ')
976       command[n - 1] = '\0';
977   }
978
979   return TRUE;
980 }
981
982 #define TARGET_LITTLE_SYM               bfd_elf32_littlearm_vec
983 #define TARGET_LITTLE_NAME              "elf32-littlearm"
984 #define TARGET_BIG_SYM                  bfd_elf32_bigarm_vec
985 #define TARGET_BIG_NAME                 "elf32-bigarm"
986
987 #define elf_backend_grok_prstatus       elf32_arm_nabi_grok_prstatus
988 #define elf_backend_grok_psinfo         elf32_arm_nabi_grok_psinfo
989
990 #ifndef USE_REL
991 #define USE_REL 0
992 #endif
993
994 typedef unsigned long int insn32;
995 typedef unsigned short int insn16;
996
997 /* In lieu of proper flags, assume all EABIv4 objects are interworkable.  */
998 #define INTERWORK_FLAG(abfd)  \
999   (EF_ARM_EABI_VERSION (elf_elfheader (abfd)->e_flags) == EF_ARM_EABI_VER4 \
1000   || (elf_elfheader (abfd)->e_flags & EF_ARM_INTERWORK))
1001
1002 /* The linker script knows the section names for placement.
1003    The entry_names are used to do simple name mangling on the stubs.
1004    Given a function name, and its type, the stub can be found. The
1005    name can be changed. The only requirement is the %s be present.  */
1006 #define THUMB2ARM_GLUE_SECTION_NAME ".glue_7t"
1007 #define THUMB2ARM_GLUE_ENTRY_NAME   "__%s_from_thumb"
1008
1009 #define ARM2THUMB_GLUE_SECTION_NAME ".glue_7"
1010 #define ARM2THUMB_GLUE_ENTRY_NAME   "__%s_from_arm"
1011
1012 /* The name of the dynamic interpreter.  This is put in the .interp
1013    section.  */
1014 #define ELF_DYNAMIC_INTERPRETER     "/usr/lib/ld.so.1"
1015
1016 #ifdef FOUR_WORD_PLT
1017
1018 /* The first entry in a procedure linkage table looks like
1019    this.  It is set up so that any shared library function that is
1020    called before the relocation has been set up calls the dynamic
1021    linker first.  */
1022 static const bfd_vma elf32_arm_plt0_entry [] =
1023   {
1024     0xe52de004,         /* str   lr, [sp, #-4]! */
1025     0xe59fe010,         /* ldr   lr, [pc, #16]  */
1026     0xe08fe00e,         /* add   lr, pc, lr     */
1027     0xe5bef008,         /* ldr   pc, [lr, #8]!  */
1028   };
1029
1030 /* Subsequent entries in a procedure linkage table look like
1031    this.  */
1032 static const bfd_vma elf32_arm_plt_entry [] =
1033   {
1034     0xe28fc600,         /* add   ip, pc, #NN    */
1035     0xe28cca00,         /* add   ip, ip, #NN    */
1036     0xe5bcf000,         /* ldr   pc, [ip, #NN]! */
1037     0x00000000,         /* unused               */
1038   };
1039
1040 #else
1041
1042 /* The first entry in a procedure linkage table looks like
1043    this.  It is set up so that any shared library function that is
1044    called before the relocation has been set up calls the dynamic
1045    linker first.  */
1046 static const bfd_vma elf32_arm_plt0_entry [] =
1047   {
1048     0xe52de004,         /* str   lr, [sp, #-4]! */
1049     0xe59fe004,         /* ldr   lr, [pc, #4]   */
1050     0xe08fe00e,         /* add   lr, pc, lr     */
1051     0xe5bef008,         /* ldr   pc, [lr, #8]!  */
1052     0x00000000,         /* &GOT[0] - .          */
1053   };
1054
1055 /* Subsequent entries in a procedure linkage table look like
1056    this.  */
1057 static const bfd_vma elf32_arm_plt_entry [] =
1058   {
1059     0xe28fc600,         /* add   ip, pc, #0xNN00000 */
1060     0xe28cca00,         /* add   ip, ip, #0xNN000   */
1061     0xe5bcf000,         /* ldr   pc, [ip, #0xNNN]!  */
1062   };
1063
1064 #endif
1065
1066 /* The entries in a PLT when using a DLL-based target with multiple
1067    address spaces.  */
1068 static const bfd_vma elf32_arm_symbian_plt_entry [] = 
1069   {
1070     0xe51ff004,         /* ldr   pr, [pc, #-4] */
1071     0x00000000,         /* dcd   R_ARM_GLOB_DAT(X) */
1072   };
1073
1074 /* Used to build a map of a section.  This is required for mixed-endian
1075    code/data.  */
1076
1077 typedef struct elf32_elf_section_map
1078 {
1079   bfd_vma vma;
1080   char type;
1081 }
1082 elf32_arm_section_map;
1083
1084 struct _arm_elf_section_data
1085 {
1086   struct bfd_elf_section_data elf;
1087   int mapcount;
1088   elf32_arm_section_map *map;
1089 };
1090
1091 #define elf32_arm_section_data(sec) \
1092   ((struct _arm_elf_section_data *) elf_section_data (sec))
1093
1094 /* The ARM linker needs to keep track of the number of relocs that it
1095    decides to copy in check_relocs for each symbol.  This is so that
1096    it can discard PC relative relocs if it doesn't need them when
1097    linking with -Bsymbolic.  We store the information in a field
1098    extending the regular ELF linker hash table.  */
1099
1100 /* This structure keeps track of the number of PC relative relocs we
1101    have copied for a given symbol.  */
1102 struct elf32_arm_relocs_copied
1103   {
1104     /* Next section.  */
1105     struct elf32_arm_relocs_copied * next;
1106     /* A section in dynobj.  */
1107     asection * section;
1108     /* Number of relocs copied in this section.  */
1109     bfd_size_type count;
1110   };
1111
1112 /* Arm ELF linker hash entry.  */
1113 struct elf32_arm_link_hash_entry
1114   {
1115     struct elf_link_hash_entry root;
1116
1117     /* Number of PC relative relocs copied for this symbol.  */
1118     struct elf32_arm_relocs_copied * relocs_copied;
1119   };
1120
1121 /* Traverse an arm ELF linker hash table.  */
1122 #define elf32_arm_link_hash_traverse(table, func, info)                 \
1123   (elf_link_hash_traverse                                               \
1124    (&(table)->root,                                                     \
1125     (bfd_boolean (*) (struct elf_link_hash_entry *, void *))) (func), \
1126     (info)))
1127
1128 /* Get the ARM elf linker hash table from a link_info structure.  */
1129 #define elf32_arm_hash_table(info) \
1130   ((struct elf32_arm_link_hash_table *) ((info)->hash))
1131
1132 /* ARM ELF linker hash table.  */
1133 struct elf32_arm_link_hash_table
1134   {
1135     /* The main hash table.  */
1136     struct elf_link_hash_table root;
1137
1138     /* The size in bytes of the section containing the Thumb-to-ARM glue.  */
1139     bfd_size_type thumb_glue_size;
1140
1141     /* The size in bytes of the section containing the ARM-to-Thumb glue.  */
1142     bfd_size_type arm_glue_size;
1143
1144     /* An arbitrary input BFD chosen to hold the glue sections.  */
1145     bfd * bfd_of_glue_owner;
1146
1147     /* A boolean indicating whether knowledge of the ARM's pipeline
1148        length should be applied by the linker.  */
1149     int no_pipeline_knowledge;
1150
1151     /* Nonzero to output a BE8 image.  */
1152     int byteswap_code;
1153
1154     /* Zero if R_ARM_TARGET1 means R_ARM_ABS32.
1155        Nonzero if R_ARM_TARGET1 means R_ARM_ABS32.  */
1156     int target1_is_rel;
1157
1158     /* The relocation to use for R_ARM_TARGET2 relocations.  */
1159     int target2_reloc;
1160
1161     /* The number of bytes in the initial entry in the PLT.  */
1162     bfd_size_type plt_header_size;
1163
1164     /* The number of bytes in the subsequent PLT etries.  */
1165     bfd_size_type plt_entry_size;
1166
1167     /* True if the target system is Symbian OS.  */
1168     int symbian_p;
1169
1170     /* Short-cuts to get to dynamic linker sections.  */
1171     asection *sgot;
1172     asection *sgotplt;
1173     asection *srelgot;
1174     asection *splt;
1175     asection *srelplt;
1176     asection *sdynbss;
1177     asection *srelbss;
1178
1179     /* Small local sym to section mapping cache.  */
1180     struct sym_sec_cache sym_sec;
1181   };
1182
1183 /* Create an entry in an ARM ELF linker hash table.  */
1184
1185 static struct bfd_hash_entry *
1186 elf32_arm_link_hash_newfunc (struct bfd_hash_entry * entry,
1187                              struct bfd_hash_table * table,
1188                              const char * string)
1189 {
1190   struct elf32_arm_link_hash_entry * ret =
1191     (struct elf32_arm_link_hash_entry *) entry;
1192
1193   /* Allocate the structure if it has not already been allocated by a
1194      subclass.  */
1195   if (ret == (struct elf32_arm_link_hash_entry *) NULL)
1196     ret = bfd_hash_allocate (table, sizeof (struct elf32_arm_link_hash_entry));
1197   if (ret == NULL)
1198     return (struct bfd_hash_entry *) ret;
1199
1200   /* Call the allocation method of the superclass.  */
1201   ret = ((struct elf32_arm_link_hash_entry *)
1202          _bfd_elf_link_hash_newfunc ((struct bfd_hash_entry *) ret,
1203                                      table, string));
1204   if (ret != NULL)
1205     ret->relocs_copied = NULL;
1206
1207   return (struct bfd_hash_entry *) ret;
1208 }
1209
1210 /* Create .got, .gotplt, and .rel.got sections in DYNOBJ, and set up
1211    shortcuts to them in our hash table.  */
1212
1213 static bfd_boolean
1214 create_got_section (bfd *dynobj, struct bfd_link_info *info)
1215 {
1216   struct elf32_arm_link_hash_table *htab;
1217
1218   htab = elf32_arm_hash_table (info);
1219   /* BPABI objects never have a GOT, or associated sections.  */
1220   if (htab->symbian_p)
1221     return TRUE;
1222
1223   if (! _bfd_elf_create_got_section (dynobj, info))
1224     return FALSE;
1225
1226   htab->sgot = bfd_get_section_by_name (dynobj, ".got");
1227   htab->sgotplt = bfd_get_section_by_name (dynobj, ".got.plt");
1228   if (!htab->sgot || !htab->sgotplt)
1229     abort ();
1230
1231   htab->srelgot = bfd_make_section (dynobj, ".rel.got");
1232   if (htab->srelgot == NULL
1233       || ! bfd_set_section_flags (dynobj, htab->srelgot,
1234                                   (SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS
1235                                    | SEC_IN_MEMORY | SEC_LINKER_CREATED
1236                                    | SEC_READONLY))
1237       || ! bfd_set_section_alignment (dynobj, htab->srelgot, 2))
1238     return FALSE;
1239   return TRUE;
1240 }
1241
1242 /* Create .plt, .rel.plt, .got, .got.plt, .rel.got, .dynbss, and
1243    .rel.bss sections in DYNOBJ, and set up shortcuts to them in our
1244    hash table.  */
1245
1246 static bfd_boolean
1247 elf32_arm_create_dynamic_sections (bfd *dynobj, struct bfd_link_info *info)
1248 {
1249   struct elf32_arm_link_hash_table *htab;
1250
1251   htab = elf32_arm_hash_table (info);
1252   if (!htab->sgot && !create_got_section (dynobj, info))
1253     return FALSE;
1254
1255   if (!_bfd_elf_create_dynamic_sections (dynobj, info))
1256     return FALSE;
1257
1258   htab->splt = bfd_get_section_by_name (dynobj, ".plt");
1259   htab->srelplt = bfd_get_section_by_name (dynobj, ".rel.plt");
1260   htab->sdynbss = bfd_get_section_by_name (dynobj, ".dynbss");
1261   if (!info->shared)
1262     htab->srelbss = bfd_get_section_by_name (dynobj, ".rel.bss");
1263
1264   if (!htab->splt 
1265       || !htab->srelplt
1266       || !htab->sdynbss
1267       || (!info->shared && !htab->srelbss))
1268     abort ();
1269
1270   return TRUE;
1271 }
1272
1273 /* Copy the extra info we tack onto an elf_link_hash_entry.  */
1274
1275 static void
1276 elf32_arm_copy_indirect_symbol (const struct elf_backend_data *bed,
1277                                 struct elf_link_hash_entry *dir,
1278                                 struct elf_link_hash_entry *ind)
1279 {
1280   struct elf32_arm_link_hash_entry *edir, *eind;
1281
1282   edir = (struct elf32_arm_link_hash_entry *) dir;
1283   eind = (struct elf32_arm_link_hash_entry *) ind;
1284
1285   if (eind->relocs_copied != NULL)
1286     {
1287       if (edir->relocs_copied != NULL)
1288         {
1289           struct elf32_arm_relocs_copied **pp;
1290           struct elf32_arm_relocs_copied *p;
1291
1292           if (ind->root.type == bfd_link_hash_indirect)
1293             abort ();
1294
1295           /* Add reloc counts against the weak sym to the strong sym
1296              list.  Merge any entries against the same section.  */
1297           for (pp = &eind->relocs_copied; (p = *pp) != NULL; )
1298             {
1299               struct elf32_arm_relocs_copied *q;
1300
1301               for (q = edir->relocs_copied; q != NULL; q = q->next)
1302                 if (q->section == p->section)
1303                   {
1304                     q->count += p->count;
1305                     *pp = p->next;
1306                     break;
1307                   }
1308               if (q == NULL)
1309                 pp = &p->next;
1310             }
1311           *pp = edir->relocs_copied;
1312         }
1313
1314       edir->relocs_copied = eind->relocs_copied;
1315       eind->relocs_copied = NULL;
1316     }
1317
1318   _bfd_elf_link_hash_copy_indirect (bed, dir, ind);
1319 }
1320
1321 /* Create an ARM elf linker hash table.  */
1322
1323 static struct bfd_link_hash_table *
1324 elf32_arm_link_hash_table_create (bfd *abfd)
1325 {
1326   struct elf32_arm_link_hash_table *ret;
1327   bfd_size_type amt = sizeof (struct elf32_arm_link_hash_table);
1328
1329   ret = bfd_malloc (amt);
1330   if (ret == NULL)
1331     return NULL;
1332
1333   if (!_bfd_elf_link_hash_table_init (& ret->root, abfd,
1334                                       elf32_arm_link_hash_newfunc))
1335     {
1336       free (ret);
1337       return NULL;
1338     }
1339
1340   ret->sgot = NULL;
1341   ret->sgotplt = NULL;
1342   ret->srelgot = NULL;
1343   ret->splt = NULL;
1344   ret->srelplt = NULL;
1345   ret->sdynbss = NULL;
1346   ret->srelbss = NULL;
1347   ret->thumb_glue_size = 0;
1348   ret->arm_glue_size = 0;
1349   ret->bfd_of_glue_owner = NULL;
1350   ret->no_pipeline_knowledge = 0;
1351   ret->byteswap_code = 0;
1352   ret->target1_is_rel = 0;
1353   ret->target2_reloc = R_ARM_NONE;
1354 #ifdef FOUR_WORD_PLT
1355   ret->plt_header_size = 16;
1356   ret->plt_entry_size = 16;
1357 #else
1358   ret->plt_header_size = 20;
1359   ret->plt_entry_size = 12;
1360 #endif
1361   ret->symbian_p = 0;
1362   ret->sym_sec.abfd = NULL;
1363
1364   return &ret->root.root;
1365 }
1366
1367 /* Locate the Thumb encoded calling stub for NAME.  */
1368
1369 static struct elf_link_hash_entry *
1370 find_thumb_glue (struct bfd_link_info *link_info,
1371                  const char *name,
1372                  bfd *input_bfd)
1373 {
1374   char *tmp_name;
1375   struct elf_link_hash_entry *hash;
1376   struct elf32_arm_link_hash_table *hash_table;
1377
1378   /* We need a pointer to the armelf specific hash table.  */
1379   hash_table = elf32_arm_hash_table (link_info);
1380
1381   tmp_name = bfd_malloc ((bfd_size_type) strlen (name)
1382                          + strlen (THUMB2ARM_GLUE_ENTRY_NAME) + 1);
1383
1384   BFD_ASSERT (tmp_name);
1385
1386   sprintf (tmp_name, THUMB2ARM_GLUE_ENTRY_NAME, name);
1387
1388   hash = elf_link_hash_lookup
1389     (&(hash_table)->root, tmp_name, FALSE, FALSE, TRUE);
1390
1391   if (hash == NULL)
1392     /* xgettext:c-format */
1393     (*_bfd_error_handler) (_("%B: unable to find THUMB glue '%s' for `%s'"),
1394                            input_bfd, tmp_name, name);
1395
1396   free (tmp_name);
1397
1398   return hash;
1399 }
1400
1401 /* Locate the ARM encoded calling stub for NAME.  */
1402
1403 static struct elf_link_hash_entry *
1404 find_arm_glue (struct bfd_link_info *link_info,
1405                const char *name,
1406                bfd *input_bfd)
1407 {
1408   char *tmp_name;
1409   struct elf_link_hash_entry *myh;
1410   struct elf32_arm_link_hash_table *hash_table;
1411
1412   /* We need a pointer to the elfarm specific hash table.  */
1413   hash_table = elf32_arm_hash_table (link_info);
1414
1415   tmp_name = bfd_malloc ((bfd_size_type) strlen (name)
1416                          + strlen (ARM2THUMB_GLUE_ENTRY_NAME) + 1);
1417
1418   BFD_ASSERT (tmp_name);
1419
1420   sprintf (tmp_name, ARM2THUMB_GLUE_ENTRY_NAME, name);
1421
1422   myh = elf_link_hash_lookup
1423     (&(hash_table)->root, tmp_name, FALSE, FALSE, TRUE);
1424
1425   if (myh == NULL)
1426     /* xgettext:c-format */
1427     (*_bfd_error_handler) (_("%B: unable to find ARM glue '%s' for `%s'"),
1428                            input_bfd, tmp_name, name);
1429
1430   free (tmp_name);
1431
1432   return myh;
1433 }
1434
1435 /* ARM->Thumb glue:
1436
1437    .arm
1438    __func_from_arm:
1439    ldr r12, __func_addr
1440    bx  r12
1441    __func_addr:
1442    .word func    @ behave as if you saw a ARM_32 reloc.  */
1443
1444 #define ARM2THUMB_GLUE_SIZE 12
1445 static const insn32 a2t1_ldr_insn = 0xe59fc000;
1446 static const insn32 a2t2_bx_r12_insn = 0xe12fff1c;
1447 static const insn32 a2t3_func_addr_insn = 0x00000001;
1448
1449 /* Thumb->ARM:                          Thumb->(non-interworking aware) ARM
1450
1451    .thumb                               .thumb
1452    .align 2                             .align 2
1453    __func_from_thumb:              __func_from_thumb:
1454    bx pc                                push {r6, lr}
1455    nop                                  ldr  r6, __func_addr
1456    .arm                                         mov  lr, pc
1457    __func_change_to_arm:                        bx   r6
1458    b func                       .arm
1459    __func_back_to_thumb:
1460    ldmia r13! {r6, lr}
1461    bx    lr
1462    __func_addr:
1463    .word        func  */
1464
1465 #define THUMB2ARM_GLUE_SIZE 8
1466 static const insn16 t2a1_bx_pc_insn = 0x4778;
1467 static const insn16 t2a2_noop_insn = 0x46c0;
1468 static const insn32 t2a3_b_insn = 0xea000000;
1469
1470 #ifndef ELFARM_NABI_C_INCLUDED
1471 bfd_boolean
1472 bfd_elf32_arm_allocate_interworking_sections (struct bfd_link_info * info)
1473 {
1474   asection * s;
1475   bfd_byte * foo;
1476   struct elf32_arm_link_hash_table * globals;
1477
1478   globals = elf32_arm_hash_table (info);
1479
1480   BFD_ASSERT (globals != NULL);
1481
1482   if (globals->arm_glue_size != 0)
1483     {
1484       BFD_ASSERT (globals->bfd_of_glue_owner != NULL);
1485
1486       s = bfd_get_section_by_name (globals->bfd_of_glue_owner,
1487                                    ARM2THUMB_GLUE_SECTION_NAME);
1488
1489       BFD_ASSERT (s != NULL);
1490
1491       foo = bfd_alloc (globals->bfd_of_glue_owner, globals->arm_glue_size);
1492
1493       s->size = globals->arm_glue_size;
1494       s->contents = foo;
1495     }
1496
1497   if (globals->thumb_glue_size != 0)
1498     {
1499       BFD_ASSERT (globals->bfd_of_glue_owner != NULL);
1500
1501       s = bfd_get_section_by_name
1502         (globals->bfd_of_glue_owner, THUMB2ARM_GLUE_SECTION_NAME);
1503
1504       BFD_ASSERT (s != NULL);
1505
1506       foo = bfd_alloc (globals->bfd_of_glue_owner, globals->thumb_glue_size);
1507
1508       s->size = globals->thumb_glue_size;
1509       s->contents = foo;
1510     }
1511
1512   return TRUE;
1513 }
1514
1515 static void
1516 record_arm_to_thumb_glue (struct bfd_link_info * link_info,
1517                           struct elf_link_hash_entry * h)
1518 {
1519   const char * name = h->root.root.string;
1520   asection * s;
1521   char * tmp_name;
1522   struct elf_link_hash_entry * myh;
1523   struct bfd_link_hash_entry * bh;
1524   struct elf32_arm_link_hash_table * globals;
1525   bfd_vma val;
1526
1527   globals = elf32_arm_hash_table (link_info);
1528
1529   BFD_ASSERT (globals != NULL);
1530   BFD_ASSERT (globals->bfd_of_glue_owner != NULL);
1531
1532   s = bfd_get_section_by_name
1533     (globals->bfd_of_glue_owner, ARM2THUMB_GLUE_SECTION_NAME);
1534
1535   BFD_ASSERT (s != NULL);
1536
1537   tmp_name = bfd_malloc ((bfd_size_type) strlen (name) + strlen (ARM2THUMB_GLUE_ENTRY_NAME) + 1);
1538
1539   BFD_ASSERT (tmp_name);
1540
1541   sprintf (tmp_name, ARM2THUMB_GLUE_ENTRY_NAME, name);
1542
1543   myh = elf_link_hash_lookup
1544     (&(globals)->root, tmp_name, FALSE, FALSE, TRUE);
1545
1546   if (myh != NULL)
1547     {
1548       /* We've already seen this guy.  */
1549       free (tmp_name);
1550       return;
1551     }
1552
1553   /* The only trick here is using hash_table->arm_glue_size as the value.
1554      Even though the section isn't allocated yet, this is where we will be
1555      putting it.  */
1556   bh = NULL;
1557   val = globals->arm_glue_size + 1;
1558   _bfd_generic_link_add_one_symbol (link_info, globals->bfd_of_glue_owner,
1559                                     tmp_name, BSF_GLOBAL, s, val,
1560                                     NULL, TRUE, FALSE, &bh);
1561
1562   free (tmp_name);
1563
1564   globals->arm_glue_size += ARM2THUMB_GLUE_SIZE;
1565
1566   return;
1567 }
1568
1569 static void
1570 record_thumb_to_arm_glue (struct bfd_link_info *link_info,
1571                           struct elf_link_hash_entry *h)
1572 {
1573   const char *name = h->root.root.string;
1574   asection *s;
1575   char *tmp_name;
1576   struct elf_link_hash_entry *myh;
1577   struct bfd_link_hash_entry *bh;
1578   struct elf32_arm_link_hash_table *hash_table;
1579   char bind;
1580   bfd_vma val;
1581
1582   hash_table = elf32_arm_hash_table (link_info);
1583
1584   BFD_ASSERT (hash_table != NULL);
1585   BFD_ASSERT (hash_table->bfd_of_glue_owner != NULL);
1586
1587   s = bfd_get_section_by_name
1588     (hash_table->bfd_of_glue_owner, THUMB2ARM_GLUE_SECTION_NAME);
1589
1590   BFD_ASSERT (s != NULL);
1591
1592   tmp_name = bfd_malloc ((bfd_size_type) strlen (name)
1593                          + strlen (THUMB2ARM_GLUE_ENTRY_NAME) + 1);
1594
1595   BFD_ASSERT (tmp_name);
1596
1597   sprintf (tmp_name, THUMB2ARM_GLUE_ENTRY_NAME, name);
1598
1599   myh = elf_link_hash_lookup
1600     (&(hash_table)->root, tmp_name, FALSE, FALSE, TRUE);
1601
1602   if (myh != NULL)
1603     {
1604       /* We've already seen this guy.  */
1605       free (tmp_name);
1606       return;
1607     }
1608
1609   bh = NULL;
1610   val = hash_table->thumb_glue_size + 1;
1611   _bfd_generic_link_add_one_symbol (link_info, hash_table->bfd_of_glue_owner,
1612                                     tmp_name, BSF_GLOBAL, s, val,
1613                                     NULL, TRUE, FALSE, &bh);
1614
1615   /* If we mark it 'Thumb', the disassembler will do a better job.  */
1616   myh = (struct elf_link_hash_entry *) bh;
1617   bind = ELF_ST_BIND (myh->type);
1618   myh->type = ELF_ST_INFO (bind, STT_ARM_TFUNC);
1619
1620   free (tmp_name);
1621
1622 #define CHANGE_TO_ARM "__%s_change_to_arm"
1623 #define BACK_FROM_ARM "__%s_back_from_arm"
1624
1625   /* Allocate another symbol to mark where we switch to Arm mode.  */
1626   tmp_name = bfd_malloc ((bfd_size_type) strlen (name)
1627                          + strlen (CHANGE_TO_ARM) + 1);
1628
1629   BFD_ASSERT (tmp_name);
1630
1631   sprintf (tmp_name, CHANGE_TO_ARM, name);
1632
1633   bh = NULL;
1634   val = hash_table->thumb_glue_size + 4,
1635   _bfd_generic_link_add_one_symbol (link_info, hash_table->bfd_of_glue_owner,
1636                                     tmp_name, BSF_LOCAL, s, val,
1637                                     NULL, TRUE, FALSE, &bh);
1638
1639   free (tmp_name);
1640
1641   hash_table->thumb_glue_size += THUMB2ARM_GLUE_SIZE;
1642
1643   return;
1644 }
1645
1646 /* Add the glue sections to ABFD.  This function is called from the
1647    linker scripts in ld/emultempl/{armelf}.em.  */
1648
1649 bfd_boolean
1650 bfd_elf32_arm_add_glue_sections_to_bfd (bfd *abfd,
1651                                         struct bfd_link_info *info)
1652 {
1653   flagword flags;
1654   asection *sec;
1655
1656   /* If we are only performing a partial
1657      link do not bother adding the glue.  */
1658   if (info->relocatable)
1659     return TRUE;
1660
1661   sec = bfd_get_section_by_name (abfd, ARM2THUMB_GLUE_SECTION_NAME);
1662
1663   if (sec == NULL)
1664     {
1665       /* Note: we do not include the flag SEC_LINKER_CREATED, as this
1666          will prevent elf_link_input_bfd() from processing the contents
1667          of this section.  */
1668       flags = SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS | SEC_IN_MEMORY | SEC_CODE | SEC_READONLY;
1669
1670       sec = bfd_make_section (abfd, ARM2THUMB_GLUE_SECTION_NAME);
1671
1672       if (sec == NULL
1673           || !bfd_set_section_flags (abfd, sec, flags)
1674           || !bfd_set_section_alignment (abfd, sec, 2))
1675         return FALSE;
1676
1677       /* Set the gc mark to prevent the section from being removed by garbage
1678          collection, despite the fact that no relocs refer to this section.  */
1679       sec->gc_mark = 1;
1680     }
1681
1682   sec = bfd_get_section_by_name (abfd, THUMB2ARM_GLUE_SECTION_NAME);
1683
1684   if (sec == NULL)
1685     {
1686       flags = SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS | SEC_IN_MEMORY
1687         | SEC_CODE | SEC_READONLY;
1688
1689       sec = bfd_make_section (abfd, THUMB2ARM_GLUE_SECTION_NAME);
1690
1691       if (sec == NULL
1692           || !bfd_set_section_flags (abfd, sec, flags)
1693           || !bfd_set_section_alignment (abfd, sec, 2))
1694         return FALSE;
1695
1696       sec->gc_mark = 1;
1697     }
1698
1699   return TRUE;
1700 }
1701
1702 /* Select a BFD to be used to hold the sections used by the glue code.
1703    This function is called from the linker scripts in ld/emultempl/
1704    {armelf/pe}.em  */
1705
1706 bfd_boolean
1707 bfd_elf32_arm_get_bfd_for_interworking (bfd *abfd, struct bfd_link_info *info)
1708 {
1709   struct elf32_arm_link_hash_table *globals;
1710
1711   /* If we are only performing a partial link
1712      do not bother getting a bfd to hold the glue.  */
1713   if (info->relocatable)
1714     return TRUE;
1715
1716   globals = elf32_arm_hash_table (info);
1717
1718   BFD_ASSERT (globals != NULL);
1719
1720   if (globals->bfd_of_glue_owner != NULL)
1721     return TRUE;
1722
1723   /* Save the bfd for later use.  */
1724   globals->bfd_of_glue_owner = abfd;
1725
1726   return TRUE;
1727 }
1728
1729 bfd_boolean
1730 bfd_elf32_arm_process_before_allocation (bfd *abfd,
1731                                          struct bfd_link_info *link_info,
1732                                          int no_pipeline_knowledge,
1733                                          int byteswap_code)
1734 {
1735   Elf_Internal_Shdr *symtab_hdr;
1736   Elf_Internal_Rela *internal_relocs = NULL;
1737   Elf_Internal_Rela *irel, *irelend;
1738   bfd_byte *contents = NULL;
1739
1740   asection *sec;
1741   struct elf32_arm_link_hash_table *globals;
1742
1743   /* If we are only performing a partial link do not bother
1744      to construct any glue.  */
1745   if (link_info->relocatable)
1746     return TRUE;
1747
1748   /* Here we have a bfd that is to be included on the link.  We have a hook
1749      to do reloc rummaging, before section sizes are nailed down.  */
1750   globals = elf32_arm_hash_table (link_info);
1751
1752   BFD_ASSERT (globals != NULL);
1753   BFD_ASSERT (globals->bfd_of_glue_owner != NULL);
1754
1755   globals->no_pipeline_knowledge = no_pipeline_knowledge;
1756
1757   if (byteswap_code && !bfd_big_endian (abfd))
1758     {
1759       _bfd_error_handler (_("%B: BE8 images only valid in big-endian mode."),
1760                           abfd);
1761       return FALSE;
1762     }
1763   globals->byteswap_code = byteswap_code;
1764
1765   /* Rummage around all the relocs and map the glue vectors.  */
1766   sec = abfd->sections;
1767
1768   if (sec == NULL)
1769     return TRUE;
1770
1771   for (; sec != NULL; sec = sec->next)
1772     {
1773       if (sec->reloc_count == 0)
1774         continue;
1775
1776       symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
1777
1778       /* Load the relocs.  */
1779       internal_relocs
1780         = _bfd_elf_link_read_relocs (abfd, sec, (void *) NULL,
1781                                      (Elf_Internal_Rela *) NULL, FALSE);
1782
1783       if (internal_relocs == NULL)
1784         goto error_return;
1785
1786       irelend = internal_relocs + sec->reloc_count;
1787       for (irel = internal_relocs; irel < irelend; irel++)
1788         {
1789           long r_type;
1790           unsigned long r_index;
1791
1792           struct elf_link_hash_entry *h;
1793
1794           r_type = ELF32_R_TYPE (irel->r_info);
1795           r_index = ELF32_R_SYM (irel->r_info);
1796
1797           /* These are the only relocation types we care about.  */
1798           if (   r_type != R_ARM_PC24
1799 #ifndef OLD_ARM_ABI
1800               && r_type != R_ARM_CALL
1801               && r_type != R_ARM_JUMP24
1802 #endif
1803               && r_type != R_ARM_THM_PC22)
1804             continue;
1805
1806           /* Get the section contents if we haven't done so already.  */
1807           if (contents == NULL)
1808             {
1809               /* Get cached copy if it exists.  */
1810               if (elf_section_data (sec)->this_hdr.contents != NULL)
1811                 contents = elf_section_data (sec)->this_hdr.contents;
1812               else
1813                 {
1814                   /* Go get them off disk.  */
1815                   if (! bfd_malloc_and_get_section (abfd, sec, &contents))
1816                     goto error_return;
1817                 }
1818             }
1819
1820           /* If the relocation is not against a symbol it cannot concern us.  */
1821           h = NULL;
1822
1823           /* We don't care about local symbols.  */
1824           if (r_index < symtab_hdr->sh_info)
1825             continue;
1826
1827           /* This is an external symbol.  */
1828           r_index -= symtab_hdr->sh_info;
1829           h = (struct elf_link_hash_entry *)
1830             elf_sym_hashes (abfd)[r_index];
1831
1832           /* If the relocation is against a static symbol it must be within
1833              the current section and so cannot be a cross ARM/Thumb relocation.  */
1834           if (h == NULL)
1835             continue;
1836
1837           switch (r_type)
1838             {
1839             case R_ARM_PC24:
1840 #ifndef OLD_ARM_ABI
1841             case R_ARM_CALL:
1842             case R_ARM_JUMP24:
1843 #endif
1844               /* This one is a call from arm code.  We need to look up
1845                  the target of the call.  If it is a thumb target, we
1846                  insert glue.  */
1847               if (ELF_ST_TYPE(h->type) == STT_ARM_TFUNC)
1848                 record_arm_to_thumb_glue (link_info, h);
1849               break;
1850
1851             case R_ARM_THM_PC22:
1852               /* This one is a call from thumb code.  We look
1853                  up the target of the call.  If it is not a thumb
1854                  target, we insert glue.  */
1855               if (ELF_ST_TYPE (h->type) != STT_ARM_TFUNC)
1856                 record_thumb_to_arm_glue (link_info, h);
1857               break;
1858
1859             default:
1860               break;
1861             }
1862         }
1863
1864       if (contents != NULL
1865           && elf_section_data (sec)->this_hdr.contents != contents)
1866         free (contents);
1867       contents = NULL;
1868
1869       if (internal_relocs != NULL
1870           && elf_section_data (sec)->relocs != internal_relocs)
1871         free (internal_relocs);
1872       internal_relocs = NULL;
1873     }
1874
1875   return TRUE;
1876
1877 error_return:
1878   if (contents != NULL
1879       && elf_section_data (sec)->this_hdr.contents != contents)
1880     free (contents);
1881   if (internal_relocs != NULL
1882       && elf_section_data (sec)->relocs != internal_relocs)
1883     free (internal_relocs);
1884
1885   return FALSE;
1886 }
1887 #endif
1888
1889
1890 #ifndef OLD_ARM_ABI
1891 /* Set target relocation values needed during linking.  */
1892
1893 void
1894 bfd_elf32_arm_set_target_relocs (struct bfd_link_info *link_info,
1895                                  int target1_is_rel,
1896                                  char * target2_type)
1897 {
1898   struct elf32_arm_link_hash_table *globals;
1899
1900   globals = elf32_arm_hash_table (link_info);
1901
1902   globals->target1_is_rel = target1_is_rel;
1903   if (strcmp (target2_type, "rel") == 0)
1904     globals->target2_reloc = R_ARM_REL32;
1905   else if (strcmp (target2_type, "abs") == 0)
1906     globals->target2_reloc = R_ARM_ABS32;
1907   else if (strcmp (target2_type, "got-rel") == 0)
1908     globals->target2_reloc = R_ARM_GOT_PREL;
1909   else
1910     {
1911       _bfd_error_handler (_("Invalid TARGET2 relocation type '%s'."),
1912                           target2_type);
1913     }
1914 }
1915 #endif
1916
1917 /* The thumb form of a long branch is a bit finicky, because the offset
1918    encoding is split over two fields, each in it's own instruction. They
1919    can occur in any order. So given a thumb form of long branch, and an
1920    offset, insert the offset into the thumb branch and return finished
1921    instruction.
1922
1923    It takes two thumb instructions to encode the target address. Each has
1924    11 bits to invest. The upper 11 bits are stored in one (identified by
1925    H-0.. see below), the lower 11 bits are stored in the other (identified
1926    by H-1).
1927
1928    Combine together and shifted left by 1 (it's a half word address) and
1929    there you have it.
1930
1931    Op: 1111 = F,
1932    H-0, upper address-0 = 000
1933    Op: 1111 = F,
1934    H-1, lower address-0 = 800
1935
1936    They can be ordered either way, but the arm tools I've seen always put
1937    the lower one first. It probably doesn't matter. krk@cygnus.com
1938
1939    XXX:  Actually the order does matter.  The second instruction (H-1)
1940    moves the computed address into the PC, so it must be the second one
1941    in the sequence.  The problem, however is that whilst little endian code
1942    stores the instructions in HI then LOW order, big endian code does the
1943    reverse.  nickc@cygnus.com.  */
1944
1945 #define LOW_HI_ORDER      0xF800F000
1946 #define HI_LOW_ORDER      0xF000F800
1947
1948 static insn32
1949 insert_thumb_branch (insn32 br_insn, int rel_off)
1950 {
1951   unsigned int low_bits;
1952   unsigned int high_bits;
1953
1954   BFD_ASSERT ((rel_off & 1) != 1);
1955
1956   rel_off >>= 1;                                /* Half word aligned address.  */
1957   low_bits = rel_off & 0x000007FF;              /* The bottom 11 bits.  */
1958   high_bits = (rel_off >> 11) & 0x000007FF;     /* The top 11 bits.  */
1959
1960   if ((br_insn & LOW_HI_ORDER) == LOW_HI_ORDER)
1961     br_insn = LOW_HI_ORDER | (low_bits << 16) | high_bits;
1962   else if ((br_insn & HI_LOW_ORDER) == HI_LOW_ORDER)
1963     br_insn = HI_LOW_ORDER | (high_bits << 16) | low_bits;
1964   else
1965     /* FIXME: abort is probably not the right call. krk@cygnus.com  */
1966     abort ();   /* Error - not a valid branch instruction form.  */
1967
1968   return br_insn;
1969 }
1970
1971 /* Thumb code calling an ARM function.  */
1972
1973 static int
1974 elf32_thumb_to_arm_stub (struct bfd_link_info * info,
1975                          const char *           name,
1976                          bfd *                  input_bfd,
1977                          bfd *                  output_bfd,
1978                          asection *             input_section,
1979                          bfd_byte *             hit_data,
1980                          asection *             sym_sec,
1981                          bfd_vma                offset,
1982                          bfd_signed_vma         addend,
1983                          bfd_vma                val)
1984 {
1985   asection * s = 0;
1986   bfd_vma my_offset;
1987   unsigned long int tmp;
1988   long int ret_offset;
1989   struct elf_link_hash_entry * myh;
1990   struct elf32_arm_link_hash_table * globals;
1991
1992   myh = find_thumb_glue (info, name, input_bfd);
1993   if (myh == NULL)
1994     return FALSE;
1995
1996   globals = elf32_arm_hash_table (info);
1997
1998   BFD_ASSERT (globals != NULL);
1999   BFD_ASSERT (globals->bfd_of_glue_owner != NULL);
2000
2001   my_offset = myh->root.u.def.value;
2002
2003   s = bfd_get_section_by_name (globals->bfd_of_glue_owner,
2004                                THUMB2ARM_GLUE_SECTION_NAME);
2005
2006   BFD_ASSERT (s != NULL);
2007   BFD_ASSERT (s->contents != NULL);
2008   BFD_ASSERT (s->output_section != NULL);
2009
2010   if ((my_offset & 0x01) == 0x01)
2011     {
2012       if (sym_sec != NULL
2013           && sym_sec->owner != NULL
2014           && !INTERWORK_FLAG (sym_sec->owner))
2015         {
2016           (*_bfd_error_handler)
2017             (_("%B(%s): warning: interworking not enabled.\n"
2018                "  first occurrence: %B: thumb call to arm"),
2019              sym_sec->owner, input_bfd, name);
2020
2021           return FALSE;
2022         }
2023
2024       --my_offset;
2025       myh->root.u.def.value = my_offset;
2026
2027       bfd_put_16 (output_bfd, (bfd_vma) t2a1_bx_pc_insn,
2028                   s->contents + my_offset);
2029
2030       bfd_put_16 (output_bfd, (bfd_vma) t2a2_noop_insn,
2031                   s->contents + my_offset + 2);
2032
2033       ret_offset =
2034         /* Address of destination of the stub.  */
2035         ((bfd_signed_vma) val)
2036         - ((bfd_signed_vma)
2037            /* Offset from the start of the current section
2038               to the start of the stubs.  */
2039            (s->output_offset
2040             /* Offset of the start of this stub from the start of the stubs.  */
2041             + my_offset
2042             /* Address of the start of the current section.  */
2043             + s->output_section->vma)
2044            /* The branch instruction is 4 bytes into the stub.  */
2045            + 4
2046            /* ARM branches work from the pc of the instruction + 8.  */
2047            + 8);
2048
2049       bfd_put_32 (output_bfd,
2050                   (bfd_vma) t2a3_b_insn | ((ret_offset >> 2) & 0x00FFFFFF),
2051                   s->contents + my_offset + 4);
2052     }
2053
2054   BFD_ASSERT (my_offset <= globals->thumb_glue_size);
2055
2056   /* Now go back and fix up the original BL insn to point to here.  */
2057   ret_offset =
2058     /* Address of where the stub is located.  */
2059     (s->output_section->vma + s->output_offset + my_offset)
2060      /* Address of where the BL is located.  */
2061     - (input_section->output_section->vma + input_section->output_offset
2062        + offset)
2063     /* Addend in the relocation.  */
2064     - addend
2065     /* Biassing for PC-relative addressing.  */
2066     - 8;
2067
2068   tmp = bfd_get_32 (input_bfd, hit_data
2069                     - input_section->vma);
2070
2071   bfd_put_32 (output_bfd,
2072               (bfd_vma) insert_thumb_branch (tmp, ret_offset),
2073               hit_data - input_section->vma);
2074
2075   return TRUE;
2076 }
2077
2078 /* Arm code calling a Thumb function.  */
2079
2080 static int
2081 elf32_arm_to_thumb_stub (struct bfd_link_info * info,
2082                          const char *           name,
2083                          bfd *                  input_bfd,
2084                          bfd *                  output_bfd,
2085                          asection *             input_section,
2086                          bfd_byte *             hit_data,
2087                          asection *             sym_sec,
2088                          bfd_vma                offset,
2089                          bfd_signed_vma         addend,
2090                          bfd_vma                val)
2091 {
2092   unsigned long int tmp;
2093   bfd_vma my_offset;
2094   asection * s;
2095   long int ret_offset;
2096   struct elf_link_hash_entry * myh;
2097   struct elf32_arm_link_hash_table * globals;
2098
2099   myh = find_arm_glue (info, name, input_bfd);
2100   if (myh == NULL)
2101     return FALSE;
2102
2103   globals = elf32_arm_hash_table (info);
2104
2105   BFD_ASSERT (globals != NULL);
2106   BFD_ASSERT (globals->bfd_of_glue_owner != NULL);
2107
2108   my_offset = myh->root.u.def.value;
2109   s = bfd_get_section_by_name (globals->bfd_of_glue_owner,
2110                                ARM2THUMB_GLUE_SECTION_NAME);
2111   BFD_ASSERT (s != NULL);
2112   BFD_ASSERT (s->contents != NULL);
2113   BFD_ASSERT (s->output_section != NULL);
2114
2115   if ((my_offset & 0x01) == 0x01)
2116     {
2117       if (sym_sec != NULL
2118           && sym_sec->owner != NULL
2119           && !INTERWORK_FLAG (sym_sec->owner))
2120         {
2121           (*_bfd_error_handler)
2122             (_("%B(%s): warning: interworking not enabled.\n"
2123                "  first occurrence: %B: arm call to thumb"),
2124              sym_sec->owner, input_bfd, name);
2125         }
2126
2127       --my_offset;
2128       myh->root.u.def.value = my_offset;
2129
2130       bfd_put_32 (output_bfd, (bfd_vma) a2t1_ldr_insn,
2131                   s->contents + my_offset);
2132
2133       bfd_put_32 (output_bfd, (bfd_vma) a2t2_bx_r12_insn,
2134                   s->contents + my_offset + 4);
2135
2136       /* It's a thumb address.  Add the low order bit.  */
2137       bfd_put_32 (output_bfd, val | a2t3_func_addr_insn,
2138                   s->contents + my_offset + 8);
2139     }
2140
2141   BFD_ASSERT (my_offset <= globals->arm_glue_size);
2142
2143   tmp = bfd_get_32 (input_bfd, hit_data);
2144   tmp = tmp & 0xFF000000;
2145
2146   /* Somehow these are both 4 too far, so subtract 8.  */
2147   ret_offset = (s->output_offset
2148                 + my_offset
2149                 + s->output_section->vma
2150                 - (input_section->output_offset
2151                    + input_section->output_section->vma
2152                    + offset + addend)
2153                 - 8);
2154
2155   tmp = tmp | ((ret_offset >> 2) & 0x00FFFFFF);
2156
2157   bfd_put_32 (output_bfd, (bfd_vma) tmp, hit_data - input_section->vma);
2158
2159   return TRUE;
2160 }
2161
2162
2163 #ifndef OLD_ARM_ABI
2164 /* Some relocations map to different relocations depending on the
2165    target.  Return the real relocation.  */
2166 static int
2167 arm_real_reloc_type (struct elf32_arm_link_hash_table * globals,
2168                      int r_type)
2169 {
2170   switch (r_type)
2171     {
2172     case R_ARM_TARGET1:
2173       if (globals->target1_is_rel)
2174         return R_ARM_REL32;
2175       else
2176         return R_ARM_ABS32;
2177
2178     case R_ARM_TARGET2:
2179       return globals->target2_reloc;
2180
2181     default:
2182       return r_type;
2183     }
2184 }
2185 #endif /* OLD_ARM_ABI */
2186
2187
2188 /* Perform a relocation as part of a final link.  */
2189
2190 static bfd_reloc_status_type
2191 elf32_arm_final_link_relocate (reloc_howto_type *           howto,
2192                                bfd *                        input_bfd,
2193                                bfd *                        output_bfd,
2194                                asection *                   input_section,
2195                                bfd_byte *                   contents,
2196                                Elf_Internal_Rela *          rel,
2197                                bfd_vma                      value,
2198                                struct bfd_link_info *       info,
2199                                asection *                   sym_sec,
2200                                const char *                 sym_name,
2201                                int                          sym_flags,
2202                                struct elf_link_hash_entry * h)
2203 {
2204   unsigned long                 r_type = howto->type;
2205   unsigned long                 r_symndx;
2206   bfd_byte *                    hit_data = contents + rel->r_offset;
2207   bfd *                         dynobj = NULL;
2208   Elf_Internal_Shdr *           symtab_hdr;
2209   struct elf_link_hash_entry ** sym_hashes;
2210   bfd_vma *                     local_got_offsets;
2211   asection *                    sgot = NULL;
2212   asection *                    splt = NULL;
2213   asection *                    sreloc = NULL;
2214   bfd_vma                       addend;
2215   bfd_signed_vma                signed_addend;
2216   struct elf32_arm_link_hash_table * globals;
2217
2218   globals = elf32_arm_hash_table (info);
2219
2220 #ifndef OLD_ARM_ABI
2221   /* Some relocation type map to different relocations depending on the
2222      target.  We pick the right one here.  */
2223   r_type = arm_real_reloc_type (globals, r_type);
2224   if (r_type != howto->type)
2225     howto = elf32_arm_howto_from_type (r_type);
2226 #endif /* OLD_ARM_ABI */
2227
2228   /* If the start address has been set, then set the EF_ARM_HASENTRY
2229      flag.  Setting this more than once is redundant, but the cost is
2230      not too high, and it keeps the code simple.
2231
2232      The test is done  here, rather than somewhere else, because the
2233      start address is only set just before the final link commences.
2234
2235      Note - if the user deliberately sets a start address of 0, the
2236      flag will not be set.  */
2237   if (bfd_get_start_address (output_bfd) != 0)
2238     elf_elfheader (output_bfd)->e_flags |= EF_ARM_HASENTRY;
2239
2240   dynobj = elf_hash_table (info)->dynobj;
2241   if (dynobj)
2242     {
2243       sgot = bfd_get_section_by_name (dynobj, ".got");
2244       splt = bfd_get_section_by_name (dynobj, ".plt");
2245     }
2246   symtab_hdr = & elf_tdata (input_bfd)->symtab_hdr;
2247   sym_hashes = elf_sym_hashes (input_bfd);
2248   local_got_offsets = elf_local_got_offsets (input_bfd);
2249   r_symndx = ELF32_R_SYM (rel->r_info);
2250
2251 #if USE_REL
2252   addend = bfd_get_32 (input_bfd, hit_data) & howto->src_mask;
2253
2254   if (addend & ((howto->src_mask + 1) >> 1))
2255     {
2256       signed_addend = -1;
2257       signed_addend &= ~ howto->src_mask;
2258       signed_addend |= addend;
2259     }
2260   else
2261     signed_addend = addend;
2262 #else
2263   addend = signed_addend = rel->r_addend;
2264 #endif
2265
2266   switch (r_type)
2267     {
2268     case R_ARM_NONE:
2269       return bfd_reloc_ok;
2270
2271     case R_ARM_PC24:
2272     case R_ARM_ABS32:
2273     case R_ARM_REL32:
2274 #ifndef OLD_ARM_ABI
2275     case R_ARM_CALL:
2276     case R_ARM_JUMP24:
2277     case R_ARM_XPC25:
2278     case R_ARM_PREL31:
2279 #endif
2280     case R_ARM_PLT32:
2281       /* r_symndx will be zero only for relocs against symbols
2282          from removed linkonce sections, or sections discarded by
2283          a linker script.  */
2284       if (r_symndx == 0)
2285         return bfd_reloc_ok;
2286
2287       /* Handle relocations which should use the PLT entry.  ABS32/REL32
2288          will use the symbol's value, which may point to a PLT entry, but we
2289          don't need to handle that here.  If we created a PLT entry, all
2290          branches in this object should go to it.  */
2291       if ((r_type != R_ARM_ABS32 && r_type != R_ARM_REL32
2292 #ifndef OLD_ARM_ABI
2293            && r_type != R_ARM_PREL31
2294 #endif
2295            )
2296           && h != NULL
2297           && splt != NULL
2298           && h->plt.offset != (bfd_vma) -1)
2299         {
2300           /* If we've created a .plt section, and assigned a PLT entry to
2301              this function, it should not be known to bind locally.  If
2302              it were, we would have cleared the PLT entry.  */
2303           BFD_ASSERT (!SYMBOL_CALLS_LOCAL (info, h));
2304
2305           value = (splt->output_section->vma
2306                    + splt->output_offset
2307                    + h->plt.offset);
2308           return _bfd_final_link_relocate (howto, input_bfd, input_section,
2309                                            contents, rel->r_offset, value,
2310                                            (bfd_vma) 0);
2311         }
2312
2313       /* When generating a shared object, these relocations are copied
2314          into the output file to be resolved at run time.  */
2315       if (info->shared
2316           && (input_section->flags & SEC_ALLOC)
2317           && ((r_type != R_ARM_REL32
2318 #ifndef OLD_ARM_ABI
2319               && r_type != R_ARM_PREL31
2320 #endif
2321               ) || !SYMBOL_CALLS_LOCAL (info, h))
2322           && (h == NULL
2323               || ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
2324               || h->root.type != bfd_link_hash_undefweak)
2325           && r_type != R_ARM_PC24
2326 #ifndef OLD_ARM_ABI
2327           && r_type != R_ARM_CALL
2328           && r_type != R_ARM_JUMP24
2329 #endif
2330           && r_type != R_ARM_PLT32)
2331         {
2332           Elf_Internal_Rela outrel;
2333           bfd_byte *loc;
2334           bfd_boolean skip, relocate;
2335
2336           if (sreloc == NULL)
2337             {
2338               const char * name;
2339
2340               name = (bfd_elf_string_from_elf_section
2341                       (input_bfd,
2342                        elf_elfheader (input_bfd)->e_shstrndx,
2343                        elf_section_data (input_section)->rel_hdr.sh_name));
2344               if (name == NULL)
2345                 return bfd_reloc_notsupported;
2346
2347               BFD_ASSERT (strncmp (name, ".rel", 4) == 0
2348                           && strcmp (bfd_get_section_name (input_bfd,
2349                                                            input_section),
2350                                      name + 4) == 0);
2351
2352               sreloc = bfd_get_section_by_name (dynobj, name);
2353               BFD_ASSERT (sreloc != NULL);
2354             }
2355
2356           skip = FALSE;
2357           relocate = FALSE;
2358
2359           outrel.r_offset =
2360             _bfd_elf_section_offset (output_bfd, info, input_section,
2361                                      rel->r_offset);
2362           if (outrel.r_offset == (bfd_vma) -1)
2363             skip = TRUE;
2364           else if (outrel.r_offset == (bfd_vma) -2)
2365             skip = TRUE, relocate = TRUE;
2366           outrel.r_offset += (input_section->output_section->vma
2367                               + input_section->output_offset);
2368
2369           if (skip)
2370             memset (&outrel, 0, sizeof outrel);
2371           else if (h != NULL
2372                    && h->dynindx != -1
2373                    && (!info->shared
2374                        || !info->symbolic
2375                        || !h->def_regular))
2376             outrel.r_info = ELF32_R_INFO (h->dynindx, r_type);
2377           else
2378             {
2379               /* This symbol is local, or marked to become local.  */
2380               relocate = TRUE;
2381               outrel.r_info = ELF32_R_INFO (0, R_ARM_RELATIVE);
2382             }
2383
2384           loc = sreloc->contents;
2385           loc += sreloc->reloc_count++ * sizeof (Elf32_External_Rel);
2386           bfd_elf32_swap_reloc_out (output_bfd, &outrel, loc);
2387
2388           /* If this reloc is against an external symbol, we do not want to
2389              fiddle with the addend.  Otherwise, we need to include the symbol
2390              value so that it becomes an addend for the dynamic reloc.  */
2391           if (! relocate)
2392             return bfd_reloc_ok;
2393
2394           return _bfd_final_link_relocate (howto, input_bfd, input_section,
2395                                            contents, rel->r_offset, value,
2396                                            (bfd_vma) 0);
2397         }
2398       else switch (r_type)
2399         {
2400 #ifndef OLD_ARM_ABI
2401         case R_ARM_XPC25:         /* Arm BLX instruction.  */
2402         case R_ARM_CALL:
2403         case R_ARM_JUMP24:
2404 #endif
2405         case R_ARM_PC24:          /* Arm B/BL instruction */
2406         case R_ARM_PLT32:
2407 #ifndef OLD_ARM_ABI
2408           if (r_type == R_ARM_XPC25)
2409             {
2410               /* Check for Arm calling Arm function.  */
2411               /* FIXME: Should we translate the instruction into a BL
2412                  instruction instead ?  */
2413               if (sym_flags != STT_ARM_TFUNC)
2414                 (*_bfd_error_handler)
2415                   (_("\%B: Warning: Arm BLX instruction targets Arm function '%s'."),
2416                    input_bfd,
2417                    h ? h->root.root.string : "(local)");
2418             }
2419           else
2420 #endif
2421             {
2422               /* Check for Arm calling Thumb function.  */
2423               if (sym_flags == STT_ARM_TFUNC)
2424                 {
2425                   elf32_arm_to_thumb_stub (info, sym_name, input_bfd,
2426                                            output_bfd, input_section,
2427                                            hit_data, sym_sec, rel->r_offset,
2428                                            signed_addend, value);
2429                   return bfd_reloc_ok;
2430                 }
2431             }
2432
2433           if (   strcmp (bfd_get_target (input_bfd), "elf32-littlearm-oabi") == 0
2434               || strcmp (bfd_get_target (input_bfd), "elf32-bigarm-oabi") == 0)
2435             {
2436               /* The old way of doing things.  Trearing the addend as a
2437                  byte sized field and adding in the pipeline offset.  */
2438               value -= (input_section->output_section->vma
2439                         + input_section->output_offset);
2440               value -= rel->r_offset;
2441               value += addend;
2442
2443               if (! globals->no_pipeline_knowledge)
2444                 value -= 8;
2445             }
2446           else
2447             {
2448               /* The ARM ELF ABI says that this reloc is computed as: S - P + A
2449                  where:
2450                   S is the address of the symbol in the relocation.
2451                   P is address of the instruction being relocated.
2452                   A is the addend (extracted from the instruction) in bytes.
2453
2454                  S is held in 'value'.
2455                  P is the base address of the section containing the
2456                    instruction plus the offset of the reloc into that
2457                    section, ie:
2458                      (input_section->output_section->vma +
2459                       input_section->output_offset +
2460                       rel->r_offset).
2461                  A is the addend, converted into bytes, ie:
2462                      (signed_addend * 4)
2463
2464                  Note: None of these operations have knowledge of the pipeline
2465                  size of the processor, thus it is up to the assembler to
2466                  encode this information into the addend.  */
2467               value -= (input_section->output_section->vma
2468                         + input_section->output_offset);
2469               value -= rel->r_offset;
2470               value += (signed_addend << howto->size);
2471
2472               /* Previous versions of this code also used to add in the
2473                  pipeline offset here.  This is wrong because the linker is
2474                  not supposed to know about such things, and one day it might
2475                  change.  In order to support old binaries that need the old
2476                  behaviour however, so we attempt to detect which ABI was
2477                  used to create the reloc.  */
2478               if (! globals->no_pipeline_knowledge)
2479                 {
2480                   Elf_Internal_Ehdr * i_ehdrp; /* Elf file header, internal form */
2481
2482                   i_ehdrp = elf_elfheader (input_bfd);
2483
2484                   if (i_ehdrp->e_ident[EI_OSABI] == 0)
2485                     value -= 8;
2486                 }
2487             }
2488
2489           signed_addend = value;
2490           signed_addend >>= howto->rightshift;
2491
2492           /* It is not an error for an undefined weak reference to be
2493              out of range.  Any program that branches to such a symbol
2494              is going to crash anyway, so there is no point worrying
2495              about getting the destination exactly right.  */
2496           if (! h || h->root.type != bfd_link_hash_undefweak)
2497             {
2498               /* Perform a signed range check.  */
2499               if (   signed_addend >   ((bfd_signed_vma)  (howto->dst_mask >> 1))
2500                   || signed_addend < - ((bfd_signed_vma) ((howto->dst_mask + 1) >> 1)))
2501                 return bfd_reloc_overflow;
2502             }
2503
2504 #ifndef OLD_ARM_ABI
2505           /* If necessary set the H bit in the BLX instruction.  */
2506           if (r_type == R_ARM_XPC25 && ((value & 2) == 2))
2507             value = (signed_addend & howto->dst_mask)
2508               | (bfd_get_32 (input_bfd, hit_data) & (~ howto->dst_mask))
2509               | (1 << 24);
2510           else
2511 #endif
2512             value = (signed_addend & howto->dst_mask)
2513               | (bfd_get_32 (input_bfd, hit_data) & (~ howto->dst_mask));
2514           break;
2515
2516         case R_ARM_ABS32:
2517           value += addend;
2518           if (sym_flags == STT_ARM_TFUNC)
2519             value |= 1;
2520           break;
2521
2522         case R_ARM_REL32:
2523           value -= (input_section->output_section->vma
2524                     + input_section->output_offset + rel->r_offset);
2525           value += addend;
2526           break;
2527
2528 #ifndef OLD_ARM_ABI
2529         case R_ARM_PREL31:
2530           value -= (input_section->output_section->vma
2531                     + input_section->output_offset + rel->r_offset);
2532           value += signed_addend;
2533           if (! h || h->root.type != bfd_link_hash_undefweak)
2534             {
2535               /* Check for overflow */
2536               if ((value ^ (value >> 1)) & (1 << 30))
2537                 return bfd_reloc_overflow;
2538             }
2539           value &= 0x7fffffff;
2540           value |= (bfd_get_32 (input_bfd, hit_data) & 0x80000000);
2541           if (sym_flags == STT_ARM_TFUNC)
2542             value |= 1;
2543           break;
2544 #endif
2545         }
2546
2547       bfd_put_32 (input_bfd, value, hit_data);
2548       return bfd_reloc_ok;
2549
2550     case R_ARM_ABS8:
2551       value += addend;
2552       if ((long) value > 0x7f || (long) value < -0x80)
2553         return bfd_reloc_overflow;
2554
2555       bfd_put_8 (input_bfd, value, hit_data);
2556       return bfd_reloc_ok;
2557
2558     case R_ARM_ABS16:
2559       value += addend;
2560
2561       if ((long) value > 0x7fff || (long) value < -0x8000)
2562         return bfd_reloc_overflow;
2563
2564       bfd_put_16 (input_bfd, value, hit_data);
2565       return bfd_reloc_ok;
2566
2567     case R_ARM_ABS12:
2568       /* Support ldr and str instruction for the arm */
2569       /* Also thumb b (unconditional branch).  ??? Really?  */
2570       value += addend;
2571
2572       if ((long) value > 0x7ff || (long) value < -0x800)
2573         return bfd_reloc_overflow;
2574
2575       value |= (bfd_get_32 (input_bfd, hit_data) & 0xfffff000);
2576       bfd_put_32 (input_bfd, value, hit_data);
2577       return bfd_reloc_ok;
2578
2579     case R_ARM_THM_ABS5:
2580       /* Support ldr and str instructions for the thumb.  */
2581 #if USE_REL
2582       /* Need to refetch addend.  */
2583       addend = bfd_get_16 (input_bfd, hit_data) & howto->src_mask;
2584       /* ??? Need to determine shift amount from operand size.  */
2585       addend >>= howto->rightshift;
2586 #endif
2587       value += addend;
2588
2589       /* ??? Isn't value unsigned?  */
2590       if ((long) value > 0x1f || (long) value < -0x10)
2591         return bfd_reloc_overflow;
2592
2593       /* ??? Value needs to be properly shifted into place first.  */
2594       value |= bfd_get_16 (input_bfd, hit_data) & 0xf83f;
2595       bfd_put_16 (input_bfd, value, hit_data);
2596       return bfd_reloc_ok;
2597
2598 #ifndef OLD_ARM_ABI
2599     case R_ARM_THM_XPC22:
2600 #endif
2601     case R_ARM_THM_PC22:
2602       /* Thumb BL (branch long instruction).  */
2603       {
2604         bfd_vma relocation;
2605         bfd_boolean overflow = FALSE;
2606         bfd_vma upper_insn = bfd_get_16 (input_bfd, hit_data);
2607         bfd_vma lower_insn = bfd_get_16 (input_bfd, hit_data + 2);
2608         bfd_signed_vma reloc_signed_max = ((1 << (howto->bitsize - 1)) - 1) >> howto->rightshift;
2609         bfd_signed_vma reloc_signed_min = ~ reloc_signed_max;
2610         bfd_vma check;
2611         bfd_signed_vma signed_check;
2612
2613 #if USE_REL
2614         /* Need to refetch the addend and squish the two 11 bit pieces
2615            together.  */
2616         {
2617           bfd_vma upper = upper_insn & 0x7ff;
2618           bfd_vma lower = lower_insn & 0x7ff;
2619           upper = (upper ^ 0x400) - 0x400; /* Sign extend.  */
2620           addend = (upper << 12) | (lower << 1);
2621           signed_addend = addend;
2622         }
2623 #endif
2624 #ifndef OLD_ARM_ABI
2625         if (r_type == R_ARM_THM_XPC22)
2626           {
2627             /* Check for Thumb to Thumb call.  */
2628             /* FIXME: Should we translate the instruction into a BL
2629                instruction instead ?  */
2630             if (sym_flags == STT_ARM_TFUNC)
2631               (*_bfd_error_handler)
2632                 (_("%B: Warning: Thumb BLX instruction targets thumb function '%s'."),
2633                  input_bfd,
2634                  h ? h->root.root.string : "(local)");
2635           }
2636         else
2637 #endif
2638           {
2639             /* If it is not a call to Thumb, assume call to Arm.
2640                If it is a call relative to a section name, then it is not a
2641                function call at all, but rather a long jump.  */
2642             if (sym_flags != STT_ARM_TFUNC && sym_flags != STT_SECTION)
2643               {
2644                 if (elf32_thumb_to_arm_stub
2645                     (info, sym_name, input_bfd, output_bfd, input_section,
2646                      hit_data, sym_sec, rel->r_offset, signed_addend, value))
2647                   return bfd_reloc_ok;
2648                 else
2649                   return bfd_reloc_dangerous;
2650               }
2651           }
2652
2653         relocation = value + signed_addend;
2654
2655         relocation -= (input_section->output_section->vma
2656                        + input_section->output_offset
2657                        + rel->r_offset);
2658
2659         if (! globals->no_pipeline_knowledge)
2660           {
2661             Elf_Internal_Ehdr * i_ehdrp; /* Elf file header, internal form.  */
2662
2663             i_ehdrp = elf_elfheader (input_bfd);
2664
2665             /* Previous versions of this code also used to add in the pipline
2666                offset here.  This is wrong because the linker is not supposed
2667                to know about such things, and one day it might change.  In order
2668                to support old binaries that need the old behaviour however, so
2669                we attempt to detect which ABI was used to create the reloc.  */
2670             if (   strcmp (bfd_get_target (input_bfd), "elf32-littlearm-oabi") == 0
2671                 || strcmp (bfd_get_target (input_bfd), "elf32-bigarm-oabi") == 0
2672                 || i_ehdrp->e_ident[EI_OSABI] == 0)
2673               relocation += 4;
2674           }
2675
2676         check = relocation >> howto->rightshift;
2677
2678         /* If this is a signed value, the rightshift just dropped
2679            leading 1 bits (assuming twos complement).  */
2680         if ((bfd_signed_vma) relocation >= 0)
2681           signed_check = check;
2682         else
2683           signed_check = check | ~((bfd_vma) -1 >> howto->rightshift);
2684
2685         /* Assumes two's complement.  */
2686         if (signed_check > reloc_signed_max || signed_check < reloc_signed_min)
2687           overflow = TRUE;
2688
2689 #ifndef OLD_ARM_ABI
2690         if (r_type == R_ARM_THM_XPC22
2691             && ((lower_insn & 0x1800) == 0x0800))
2692           /* For a BLX instruction, make sure that the relocation is rounded up
2693              to a word boundary.  This follows the semantics of the instruction
2694              which specifies that bit 1 of the target address will come from bit
2695              1 of the base address.  */
2696           relocation = (relocation + 2) & ~ 3;
2697 #endif
2698         /* Put RELOCATION back into the insn.  */
2699         upper_insn = (upper_insn & ~(bfd_vma) 0x7ff) | ((relocation >> 12) & 0x7ff);
2700         lower_insn = (lower_insn & ~(bfd_vma) 0x7ff) | ((relocation >> 1) & 0x7ff);
2701
2702         /* Put the relocated value back in the object file:  */
2703         bfd_put_16 (input_bfd, upper_insn, hit_data);
2704         bfd_put_16 (input_bfd, lower_insn, hit_data + 2);
2705
2706         return (overflow ? bfd_reloc_overflow : bfd_reloc_ok);
2707       }
2708       break;
2709
2710     case R_ARM_THM_PC11:
2711       /* Thumb B (branch) instruction).  */
2712       {
2713         bfd_signed_vma relocation;
2714         bfd_signed_vma reloc_signed_max = (1 << (howto->bitsize - 1)) - 1;
2715         bfd_signed_vma reloc_signed_min = ~ reloc_signed_max;
2716         bfd_signed_vma signed_check;
2717
2718 #if USE_REL
2719         /* Need to refetch addend.  */
2720         addend = bfd_get_16 (input_bfd, hit_data) & howto->src_mask;
2721         if (addend & ((howto->src_mask + 1) >> 1))
2722           {
2723             signed_addend = -1;
2724             signed_addend &= ~ howto->src_mask;
2725             signed_addend |= addend;
2726           }
2727         else
2728           signed_addend = addend;
2729         /* The value in the insn has been right shifted.  We need to
2730            undo this, so that we can perform the address calculation
2731            in terms of bytes.  */
2732         signed_addend <<= howto->rightshift;
2733 #endif
2734         relocation = value + signed_addend;
2735
2736         relocation -= (input_section->output_section->vma
2737                        + input_section->output_offset
2738                        + rel->r_offset);
2739
2740         relocation >>= howto->rightshift;
2741         signed_check = relocation;
2742         relocation &= howto->dst_mask;
2743         relocation |= (bfd_get_16 (input_bfd, hit_data) & (~ howto->dst_mask));
2744
2745         bfd_put_16 (input_bfd, relocation, hit_data);
2746
2747         /* Assumes two's complement.  */
2748         if (signed_check > reloc_signed_max || signed_check < reloc_signed_min)
2749           return bfd_reloc_overflow;
2750
2751         return bfd_reloc_ok;
2752       }
2753
2754 #ifndef OLD_ARM_ABI
2755     case R_ARM_ALU_PCREL7_0:
2756     case R_ARM_ALU_PCREL15_8:
2757     case R_ARM_ALU_PCREL23_15:
2758       {
2759         bfd_vma insn;
2760         bfd_vma relocation;
2761
2762         insn = bfd_get_32 (input_bfd, hit_data);
2763 #if USE_REL
2764         /* Extract the addend.  */
2765         addend = (insn & 0xff) << ((insn & 0xf00) >> 7);
2766         signed_addend = addend;
2767 #endif
2768         relocation = value + signed_addend;
2769
2770         relocation -= (input_section->output_section->vma
2771                        + input_section->output_offset
2772                        + rel->r_offset);
2773         insn = (insn & ~0xfff)
2774                | ((howto->bitpos << 7) & 0xf00)
2775                | ((relocation >> howto->bitpos) & 0xff);
2776         bfd_put_32 (input_bfd, value, hit_data);
2777       }
2778       return bfd_reloc_ok;
2779 #endif
2780
2781     case R_ARM_GNU_VTINHERIT:
2782     case R_ARM_GNU_VTENTRY:
2783       return bfd_reloc_ok;
2784
2785     case R_ARM_COPY:
2786       return bfd_reloc_notsupported;
2787
2788     case R_ARM_GLOB_DAT:
2789       return bfd_reloc_notsupported;
2790
2791     case R_ARM_JUMP_SLOT:
2792       return bfd_reloc_notsupported;
2793
2794     case R_ARM_RELATIVE:
2795       return bfd_reloc_notsupported;
2796
2797     case R_ARM_GOTOFF:
2798       /* Relocation is relative to the start of the
2799          global offset table.  */
2800
2801       BFD_ASSERT (sgot != NULL);
2802       if (sgot == NULL)
2803         return bfd_reloc_notsupported;
2804
2805       /* If we are addressing a Thumb function, we need to adjust the
2806          address by one, so that attempts to call the function pointer will
2807          correctly interpret it as Thumb code.  */
2808       if (sym_flags == STT_ARM_TFUNC)
2809         value += 1;
2810
2811       /* Note that sgot->output_offset is not involved in this
2812          calculation.  We always want the start of .got.  If we
2813          define _GLOBAL_OFFSET_TABLE in a different way, as is
2814          permitted by the ABI, we might have to change this
2815          calculation.  */
2816       value -= sgot->output_section->vma;
2817       return _bfd_final_link_relocate (howto, input_bfd, input_section,
2818                                        contents, rel->r_offset, value,
2819                                        (bfd_vma) 0);
2820
2821     case R_ARM_GOTPC:
2822       /* Use global offset table as symbol value.  */
2823       BFD_ASSERT (sgot != NULL);
2824
2825       if (sgot == NULL)
2826         return bfd_reloc_notsupported;
2827
2828       value = sgot->output_section->vma;
2829       return _bfd_final_link_relocate (howto, input_bfd, input_section,
2830                                        contents, rel->r_offset, value,
2831                                        (bfd_vma) 0);
2832
2833     case R_ARM_GOT32:
2834 #ifndef OLD_ARM_ABI
2835     case R_ARM_GOT_PREL:
2836 #endif
2837       /* Relocation is to the entry for this symbol in the
2838          global offset table.  */
2839       if (sgot == NULL)
2840         return bfd_reloc_notsupported;
2841
2842       if (h != NULL)
2843         {
2844           bfd_vma off;
2845           bfd_boolean dyn;
2846
2847           off = h->got.offset;
2848           BFD_ASSERT (off != (bfd_vma) -1);
2849           dyn = globals->root.dynamic_sections_created;
2850
2851           if (! WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, info->shared, h)
2852               || (info->shared
2853                   && SYMBOL_REFERENCES_LOCAL (info, h))
2854               || (ELF_ST_VISIBILITY (h->other)
2855                   && h->root.type == bfd_link_hash_undefweak))
2856             {
2857               /* This is actually a static link, or it is a -Bsymbolic link
2858                  and the symbol is defined locally.  We must initialize this
2859                  entry in the global offset table.  Since the offset must
2860                  always be a multiple of 4, we use the least significant bit
2861                  to record whether we have initialized it already.
2862
2863                  When doing a dynamic link, we create a .rel.got relocation
2864                  entry to initialize the value.  This is done in the
2865                  finish_dynamic_symbol routine.  */
2866               if ((off & 1) != 0)
2867                 off &= ~1;
2868               else
2869                 {
2870                   /* If we are addressing a Thumb function, we need to
2871                      adjust the address by one, so that attempts to
2872                      call the function pointer will correctly
2873                      interpret it as Thumb code.  */
2874                   if (sym_flags == STT_ARM_TFUNC)
2875                     value |= 1;
2876
2877                   bfd_put_32 (output_bfd, value, sgot->contents + off);
2878                   h->got.offset |= 1;
2879                 }
2880             }
2881
2882           value = sgot->output_offset + off;
2883         }
2884       else
2885         {
2886           bfd_vma off;
2887
2888           BFD_ASSERT (local_got_offsets != NULL &&
2889                       local_got_offsets[r_symndx] != (bfd_vma) -1);
2890
2891           off = local_got_offsets[r_symndx];
2892
2893           /* The offset must always be a multiple of 4.  We use the
2894              least significant bit to record whether we have already
2895              generated the necessary reloc.  */
2896           if ((off & 1) != 0)
2897             off &= ~1;
2898           else
2899             {
2900               bfd_put_32 (output_bfd, value, sgot->contents + off);
2901
2902               if (info->shared)
2903                 {
2904                   asection * srelgot;
2905                   Elf_Internal_Rela outrel;
2906                   bfd_byte *loc;
2907
2908                   srelgot = bfd_get_section_by_name (dynobj, ".rel.got");
2909                   BFD_ASSERT (srelgot != NULL);
2910
2911                   outrel.r_offset = (sgot->output_section->vma
2912                                      + sgot->output_offset
2913                                      + off);
2914                   outrel.r_info = ELF32_R_INFO (0, R_ARM_RELATIVE);
2915                   loc = srelgot->contents;
2916                   loc += srelgot->reloc_count++ * sizeof (Elf32_External_Rel);
2917                   bfd_elf32_swap_reloc_out (output_bfd, &outrel, loc);
2918                 }
2919
2920               local_got_offsets[r_symndx] |= 1;
2921             }
2922
2923           value = sgot->output_offset + off;
2924         }
2925       if (r_type != R_ARM_GOT32)
2926         value += sgot->output_section->vma;
2927
2928       return _bfd_final_link_relocate (howto, input_bfd, input_section,
2929                                        contents, rel->r_offset, value,
2930                                        (bfd_vma) 0);
2931
2932     case R_ARM_SBREL32:
2933       return bfd_reloc_notsupported;
2934
2935     case R_ARM_AMP_VCALL9:
2936       return bfd_reloc_notsupported;
2937
2938     case R_ARM_RSBREL32:
2939       return bfd_reloc_notsupported;
2940
2941     case R_ARM_THM_RPC22:
2942       return bfd_reloc_notsupported;
2943
2944     case R_ARM_RREL32:
2945       return bfd_reloc_notsupported;
2946
2947     case R_ARM_RABS32:
2948       return bfd_reloc_notsupported;
2949
2950     case R_ARM_RPC24:
2951       return bfd_reloc_notsupported;
2952
2953     case R_ARM_RBASE:
2954       return bfd_reloc_notsupported;
2955
2956     default:
2957       return bfd_reloc_notsupported;
2958     }
2959 }
2960
2961 #if USE_REL
2962 /* Add INCREMENT to the reloc (of type HOWTO) at ADDRESS.  */
2963 static void
2964 arm_add_to_rel (bfd *              abfd,
2965                 bfd_byte *         address,
2966                 reloc_howto_type * howto,
2967                 bfd_signed_vma     increment)
2968 {
2969   bfd_signed_vma addend;
2970
2971   if (howto->type == R_ARM_THM_PC22)
2972     {
2973       int upper_insn, lower_insn;
2974       int upper, lower;
2975
2976       upper_insn = bfd_get_16 (abfd, address);
2977       lower_insn = bfd_get_16 (abfd, address + 2);
2978       upper = upper_insn & 0x7ff;
2979       lower = lower_insn & 0x7ff;
2980
2981       addend = (upper << 12) | (lower << 1);
2982       addend += increment;
2983       addend >>= 1;
2984
2985       upper_insn = (upper_insn & 0xf800) | ((addend >> 11) & 0x7ff);
2986       lower_insn = (lower_insn & 0xf800) | (addend & 0x7ff);
2987
2988       bfd_put_16 (abfd, (bfd_vma) upper_insn, address);
2989       bfd_put_16 (abfd, (bfd_vma) lower_insn, address + 2);
2990     }
2991   else
2992     {
2993       bfd_vma        contents;
2994
2995       contents = bfd_get_32 (abfd, address);
2996
2997       /* Get the (signed) value from the instruction.  */
2998       addend = contents & howto->src_mask;
2999       if (addend & ((howto->src_mask + 1) >> 1))
3000         {
3001           bfd_signed_vma mask;
3002
3003           mask = -1;
3004           mask &= ~ howto->src_mask;
3005           addend |= mask;
3006         }
3007
3008       /* Add in the increment, (which is a byte value).  */
3009       switch (howto->type)
3010         {
3011         default:
3012           addend += increment;
3013           break;
3014
3015         case R_ARM_PC24:
3016 #ifndef OLD_ARM_ABI
3017         case R_ARM_CALL:
3018         case R_ARM_JUMP24:
3019 #endif
3020           addend <<= howto->size;
3021           addend += increment;
3022
3023           /* Should we check for overflow here ?  */
3024
3025           /* Drop any undesired bits.  */
3026           addend >>= howto->rightshift;
3027           break;
3028         }
3029
3030       contents = (contents & ~ howto->dst_mask) | (addend & howto->dst_mask);
3031
3032       bfd_put_32 (abfd, contents, address);
3033     }
3034 }
3035 #endif /* USE_REL */
3036
3037 /* Relocate an ARM ELF section.  */
3038 static bfd_boolean
3039 elf32_arm_relocate_section (bfd *                  output_bfd,
3040                             struct bfd_link_info * info,
3041                             bfd *                  input_bfd,
3042                             asection *             input_section,
3043                             bfd_byte *             contents,
3044                             Elf_Internal_Rela *    relocs,
3045                             Elf_Internal_Sym *     local_syms,
3046                             asection **            local_sections)
3047 {
3048   Elf_Internal_Shdr *symtab_hdr;
3049   struct elf_link_hash_entry **sym_hashes;
3050   Elf_Internal_Rela *rel;
3051   Elf_Internal_Rela *relend;
3052   const char *name;
3053
3054 #if !USE_REL
3055   if (info->relocatable)
3056     return TRUE;
3057 #endif
3058
3059   symtab_hdr = & elf_tdata (input_bfd)->symtab_hdr;
3060   sym_hashes = elf_sym_hashes (input_bfd);
3061
3062   rel = relocs;
3063   relend = relocs + input_section->reloc_count;
3064   for (; rel < relend; rel++)
3065     {
3066       int                          r_type;
3067       reloc_howto_type *           howto;
3068       unsigned long                r_symndx;
3069       Elf_Internal_Sym *           sym;
3070       asection *                   sec;
3071       struct elf_link_hash_entry * h;
3072       bfd_vma                      relocation;
3073       bfd_reloc_status_type        r;
3074       arelent                      bfd_reloc;
3075
3076       r_symndx = ELF32_R_SYM (rel->r_info);
3077       r_type   = ELF32_R_TYPE (rel->r_info);
3078
3079       if (   r_type == R_ARM_GNU_VTENTRY
3080           || r_type == R_ARM_GNU_VTINHERIT)
3081         continue;
3082
3083       elf32_arm_info_to_howto (input_bfd, & bfd_reloc, rel);
3084       howto = bfd_reloc.howto;
3085
3086 #if USE_REL
3087       if (info->relocatable)
3088         {
3089           /* This is a relocatable link.  We don't have to change
3090              anything, unless the reloc is against a section symbol,
3091              in which case we have to adjust according to where the
3092              section symbol winds up in the output section.  */
3093           if (r_symndx < symtab_hdr->sh_info)
3094             {
3095               sym = local_syms + r_symndx;
3096               if (ELF_ST_TYPE (sym->st_info) == STT_SECTION)
3097                 {
3098                   sec = local_sections[r_symndx];
3099                   arm_add_to_rel (input_bfd, contents + rel->r_offset,
3100                                   howto,
3101                                   (bfd_signed_vma) (sec->output_offset
3102                                                     + sym->st_value));
3103                 }
3104             }
3105
3106           continue;
3107         }
3108 #endif
3109
3110       /* This is a final link.  */
3111       h = NULL;
3112       sym = NULL;
3113       sec = NULL;
3114
3115       if (r_symndx < symtab_hdr->sh_info)
3116         {
3117           sym = local_syms + r_symndx;
3118           sec = local_sections[r_symndx];
3119 #if USE_REL
3120           relocation = (sec->output_section->vma
3121                         + sec->output_offset
3122                         + sym->st_value);
3123           if ((sec->flags & SEC_MERGE)
3124                    && ELF_ST_TYPE (sym->st_info) == STT_SECTION)
3125             {
3126               asection *msec;
3127               bfd_vma addend, value;
3128
3129               if (howto->rightshift)
3130                 {
3131                   (*_bfd_error_handler)
3132                     (_("%B(%A+0x%lx): %s relocation against SEC_MERGE section"),
3133                      input_bfd, input_section,
3134                      (long) rel->r_offset, howto->name);
3135                   return FALSE;
3136                 }
3137
3138               value = bfd_get_32 (input_bfd, contents + rel->r_offset);
3139
3140               /* Get the (signed) value from the instruction.  */
3141               addend = value & howto->src_mask;
3142               if (addend & ((howto->src_mask + 1) >> 1))
3143                 {
3144                   bfd_signed_vma mask;
3145
3146                   mask = -1;
3147                   mask &= ~ howto->src_mask;
3148                   addend |= mask;
3149                 }
3150               msec = sec;
3151               addend =
3152                 _bfd_elf_rel_local_sym (output_bfd, sym, &msec, addend)
3153                 - relocation;
3154               addend += msec->output_section->vma + msec->output_offset;
3155               value = (value & ~ howto->dst_mask) | (addend & howto->dst_mask);
3156               bfd_put_32 (input_bfd, value, contents + rel->r_offset);
3157             }
3158 #else
3159           relocation = _bfd_elf_rela_local_sym (output_bfd, sym, &sec, rel);
3160 #endif
3161         }
3162       else
3163         {
3164           bfd_boolean warned;
3165           bfd_boolean unresolved_reloc;
3166
3167           RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel,
3168                                    r_symndx, symtab_hdr, sym_hashes,
3169                                    h, sec, relocation,
3170                                    unresolved_reloc, warned);
3171
3172           if (unresolved_reloc || relocation != 0)
3173             {
3174               /* In these cases, we don't need the relocation value.
3175                  We check specially because in some obscure cases
3176                  sec->output_section will be NULL.  */
3177               switch (r_type)
3178                 {
3179                 case R_ARM_PC24:
3180 #ifndef OLD_ARM_ABI
3181                 case R_ARM_CALL:
3182                 case R_ARM_JUMP24:
3183 #endif
3184                 case R_ARM_ABS32:
3185                 case R_ARM_THM_PC22:
3186                 case R_ARM_PLT32:
3187
3188                   if (info->shared
3189                       && ((!info->symbolic && h->dynindx != -1)
3190                           || !h->def_regular)
3191                       && ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
3192                       && ((input_section->flags & SEC_ALLOC) != 0
3193                           /* DWARF will emit R_ARM_ABS32 relocations in its
3194                              sections against symbols defined externally
3195                              in shared libraries.  We can't do anything
3196                              with them here.  */
3197                           || ((input_section->flags & SEC_DEBUGGING) != 0
3198                               && h->def_dynamic))
3199                       )
3200                     relocation = 0;
3201                   break;
3202
3203                 case R_ARM_GOTPC:
3204                   relocation = 0;
3205                   break;
3206
3207                 case R_ARM_GOT32:
3208 #ifndef OLD_ARM_ABI
3209                 case R_ARM_GOT_PREL:
3210 #endif
3211                   if ((WILL_CALL_FINISH_DYNAMIC_SYMBOL
3212                        (elf_hash_table (info)->dynamic_sections_created,
3213                         info->shared, h))
3214                       && (!info->shared
3215                           || (!info->symbolic && h->dynindx != -1)
3216                           || !h->def_regular))
3217                     relocation = 0;
3218                   break;
3219
3220                 default:
3221                   if (unresolved_reloc)
3222                     _bfd_error_handler
3223                       (_("%B(%A): warning: unresolvable relocation %d against symbol `%s'"),
3224                        input_bfd, input_section,
3225                        r_type,
3226                        h->root.root.string);
3227                   break;
3228                 }
3229             }
3230         }
3231
3232       if (h != NULL)
3233         name = h->root.root.string;
3234       else
3235         {
3236           name = (bfd_elf_string_from_elf_section
3237                   (input_bfd, symtab_hdr->sh_link, sym->st_name));
3238           if (name == NULL || *name == '\0')
3239             name = bfd_section_name (input_bfd, sec);
3240         }
3241
3242       r = elf32_arm_final_link_relocate (howto, input_bfd, output_bfd,
3243                                          input_section, contents, rel,
3244                                          relocation, info, sec, name,
3245                                          (h ? ELF_ST_TYPE (h->type) :
3246                                           ELF_ST_TYPE (sym->st_info)), h);
3247
3248       if (r != bfd_reloc_ok)
3249         {
3250           const char * msg = (const char *) 0;
3251
3252           switch (r)
3253             {
3254             case bfd_reloc_overflow:
3255               /* If the overflowing reloc was to an undefined symbol,
3256                  we have already printed one error message and there
3257                  is no point complaining again.  */
3258               if ((! h ||
3259                    h->root.type != bfd_link_hash_undefined)
3260                   && (!((*info->callbacks->reloc_overflow)
3261                         (info, (h ? &h->root : NULL), name, howto->name,
3262                          (bfd_vma) 0, input_bfd, input_section,
3263                          rel->r_offset))))
3264                   return FALSE;
3265               break;
3266
3267             case bfd_reloc_undefined:
3268               if (!((*info->callbacks->undefined_symbol)
3269                     (info, name, input_bfd, input_section,
3270                      rel->r_offset, TRUE)))
3271                 return FALSE;
3272               break;
3273
3274             case bfd_reloc_outofrange:
3275               msg = _("internal error: out of range error");
3276               goto common_error;
3277
3278             case bfd_reloc_notsupported:
3279               msg = _("internal error: unsupported relocation error");
3280               goto common_error;
3281
3282             case bfd_reloc_dangerous:
3283               msg = _("internal error: dangerous error");
3284               goto common_error;
3285
3286             default:
3287               msg = _("internal error: unknown error");
3288               /* fall through */
3289
3290             common_error:
3291               if (!((*info->callbacks->warning)
3292                     (info, msg, name, input_bfd, input_section,
3293                      rel->r_offset)))
3294                 return FALSE;
3295               break;
3296             }
3297         }
3298     }
3299
3300   return TRUE;
3301 }
3302
3303 /* Set the right machine number.  */
3304
3305 static bfd_boolean
3306 elf32_arm_object_p (bfd *abfd)
3307 {
3308   unsigned int mach;
3309
3310   mach = bfd_arm_get_mach_from_notes (abfd, ARM_NOTE_SECTION);
3311
3312   if (mach != bfd_mach_arm_unknown)
3313     bfd_default_set_arch_mach (abfd, bfd_arch_arm, mach);
3314
3315   else if (elf_elfheader (abfd)->e_flags & EF_ARM_MAVERICK_FLOAT)
3316     bfd_default_set_arch_mach (abfd, bfd_arch_arm, bfd_mach_arm_ep9312);
3317
3318   else
3319     bfd_default_set_arch_mach (abfd, bfd_arch_arm, mach);
3320
3321   return TRUE;
3322 }
3323
3324 /* Function to keep ARM specific flags in the ELF header.  */
3325
3326 static bfd_boolean
3327 elf32_arm_set_private_flags (bfd *abfd, flagword flags)
3328 {
3329   if (elf_flags_init (abfd)
3330       && elf_elfheader (abfd)->e_flags != flags)
3331     {
3332       if (EF_ARM_EABI_VERSION (flags) == EF_ARM_EABI_UNKNOWN)
3333         {
3334           if (flags & EF_ARM_INTERWORK)
3335             (*_bfd_error_handler)
3336               (_("Warning: Not setting interworking flag of %B since it has already been specified as non-interworking"),
3337                abfd);
3338           else
3339             _bfd_error_handler
3340               (_("Warning: Clearing the interworking flag of %B due to outside request"),
3341                abfd);
3342         }
3343     }
3344   else
3345     {
3346       elf_elfheader (abfd)->e_flags = flags;
3347       elf_flags_init (abfd) = TRUE;
3348     }
3349
3350   return TRUE;
3351 }
3352
3353 /* Copy backend specific data from one object module to another.  */
3354
3355 static bfd_boolean
3356 elf32_arm_copy_private_bfd_data (bfd *ibfd, bfd *obfd)
3357 {
3358   flagword in_flags;
3359   flagword out_flags;
3360
3361   if (   bfd_get_flavour (ibfd) != bfd_target_elf_flavour
3362       || bfd_get_flavour (obfd) != bfd_target_elf_flavour)
3363     return TRUE;
3364
3365   in_flags  = elf_elfheader (ibfd)->e_flags;
3366   out_flags = elf_elfheader (obfd)->e_flags;
3367
3368   if (elf_flags_init (obfd)
3369       && EF_ARM_EABI_VERSION (out_flags) == EF_ARM_EABI_UNKNOWN
3370       && in_flags != out_flags)
3371     {
3372       /* Cannot mix APCS26 and APCS32 code.  */
3373       if ((in_flags & EF_ARM_APCS_26) != (out_flags & EF_ARM_APCS_26))
3374         return FALSE;
3375
3376       /* Cannot mix float APCS and non-float APCS code.  */
3377       if ((in_flags & EF_ARM_APCS_FLOAT) != (out_flags & EF_ARM_APCS_FLOAT))
3378         return FALSE;
3379
3380       /* If the src and dest have different interworking flags
3381          then turn off the interworking bit.  */
3382       if ((in_flags & EF_ARM_INTERWORK) != (out_flags & EF_ARM_INTERWORK))
3383         {
3384           if (out_flags & EF_ARM_INTERWORK)
3385             _bfd_error_handler
3386               (_("Warning: Clearing the interworking flag of %B because non-interworking code in %B has been linked with it"),
3387                obfd, ibfd);
3388
3389           in_flags &= ~EF_ARM_INTERWORK;
3390         }
3391
3392       /* Likewise for PIC, though don't warn for this case.  */
3393       if ((in_flags & EF_ARM_PIC) != (out_flags & EF_ARM_PIC))
3394         in_flags &= ~EF_ARM_PIC;
3395     }
3396
3397   elf_elfheader (obfd)->e_flags = in_flags;
3398   elf_flags_init (obfd) = TRUE;
3399
3400   return TRUE;
3401 }
3402
3403 /* Merge backend specific data from an object file to the output
3404    object file when linking.  */
3405
3406 static bfd_boolean
3407 elf32_arm_merge_private_bfd_data (bfd * ibfd, bfd * obfd)
3408 {
3409   flagword out_flags;
3410   flagword in_flags;
3411   bfd_boolean flags_compatible = TRUE;
3412   asection *sec;
3413
3414   /* Check if we have the same endianess.  */
3415   if (! _bfd_generic_verify_endian_match (ibfd, obfd))
3416     return FALSE;
3417
3418   if (   bfd_get_flavour (ibfd) != bfd_target_elf_flavour
3419       || bfd_get_flavour (obfd) != bfd_target_elf_flavour)
3420     return TRUE;
3421
3422   /* The input BFD must have had its flags initialised.  */
3423   /* The following seems bogus to me -- The flags are initialized in
3424      the assembler but I don't think an elf_flags_init field is
3425      written into the object.  */
3426   /* BFD_ASSERT (elf_flags_init (ibfd)); */
3427
3428   in_flags  = elf_elfheader (ibfd)->e_flags;
3429   out_flags = elf_elfheader (obfd)->e_flags;
3430
3431   if (!elf_flags_init (obfd))
3432     {
3433       /* If the input is the default architecture and had the default
3434          flags then do not bother setting the flags for the output
3435          architecture, instead allow future merges to do this.  If no
3436          future merges ever set these flags then they will retain their
3437          uninitialised values, which surprise surprise, correspond
3438          to the default values.  */
3439       if (bfd_get_arch_info (ibfd)->the_default
3440           && elf_elfheader (ibfd)->e_flags == 0)
3441         return TRUE;
3442
3443       elf_flags_init (obfd) = TRUE;
3444       elf_elfheader (obfd)->e_flags = in_flags;
3445
3446       if (bfd_get_arch (obfd) == bfd_get_arch (ibfd)
3447           && bfd_get_arch_info (obfd)->the_default)
3448         return bfd_set_arch_mach (obfd, bfd_get_arch (ibfd), bfd_get_mach (ibfd));
3449
3450       return TRUE;
3451     }
3452
3453   /* Determine what should happen if the input ARM architecture
3454      does not match the output ARM architecture.  */
3455   if (! bfd_arm_merge_machines (ibfd, obfd))
3456     return FALSE;
3457
3458   /* Identical flags must be compatible.  */
3459   if (in_flags == out_flags)
3460     return TRUE;
3461
3462   /* Check to see if the input BFD actually contains any sections.  If
3463      not, its flags may not have been initialised either, but it
3464      cannot actually cause any incompatibility.  Do not short-circuit
3465      dynamic objects; their section list may be emptied by
3466     elf_link_add_object_symbols.
3467
3468     Also check to see if there are no code sections in the input.
3469     In this case there is no need to check for code specific flags.
3470     XXX - do we need to worry about floating-point format compatability
3471     in data sections ?  */
3472   if (!(ibfd->flags & DYNAMIC))
3473     {
3474       bfd_boolean null_input_bfd = TRUE;
3475       bfd_boolean only_data_sections = TRUE;
3476
3477       for (sec = ibfd->sections; sec != NULL; sec = sec->next)
3478         {
3479           /* Ignore synthetic glue sections.  */
3480           if (strcmp (sec->name, ".glue_7")
3481               && strcmp (sec->name, ".glue_7t"))
3482             {
3483               if ((bfd_get_section_flags (ibfd, sec)
3484                    & (SEC_LOAD | SEC_CODE | SEC_HAS_CONTENTS))
3485                   == (SEC_LOAD | SEC_CODE | SEC_HAS_CONTENTS))
3486                 only_data_sections = FALSE;
3487
3488               null_input_bfd = FALSE;
3489               break;
3490             }
3491         }
3492
3493       if (null_input_bfd || only_data_sections)
3494         return TRUE;
3495     }
3496
3497   /* Complain about various flag mismatches.  */
3498   if (EF_ARM_EABI_VERSION (in_flags) != EF_ARM_EABI_VERSION (out_flags))
3499     {
3500       _bfd_error_handler
3501         (_("ERROR: Source object %B has EABI version %d, but target %B has EABI version %d"),
3502          ibfd, obfd,
3503          (in_flags & EF_ARM_EABIMASK) >> 24,
3504          (out_flags & EF_ARM_EABIMASK) >> 24);
3505       return FALSE;
3506     }
3507
3508   /* Not sure what needs to be checked for EABI versions >= 1.  */
3509   if (EF_ARM_EABI_VERSION (in_flags) == EF_ARM_EABI_UNKNOWN)
3510     {
3511       if ((in_flags & EF_ARM_APCS_26) != (out_flags & EF_ARM_APCS_26))
3512         {
3513           _bfd_error_handler
3514             (_("ERROR: %B is compiled for APCS-%d, whereas target %B uses APCS-%d"),
3515              ibfd, obfd,
3516              in_flags & EF_ARM_APCS_26 ? 26 : 32,
3517              out_flags & EF_ARM_APCS_26 ? 26 : 32);
3518           flags_compatible = FALSE;
3519         }
3520
3521       if ((in_flags & EF_ARM_APCS_FLOAT) != (out_flags & EF_ARM_APCS_FLOAT))
3522         {
3523           if (in_flags & EF_ARM_APCS_FLOAT)
3524             _bfd_error_handler
3525               (_("ERROR: %B passes floats in float registers, whereas %B passes them in integer registers"),
3526                ibfd, obfd);
3527           else
3528             _bfd_error_handler
3529               (_("ERROR: %B passes floats in integer registers, whereas %B passes them in float registers"),
3530                ibfd, obfd);
3531
3532           flags_compatible = FALSE;
3533         }
3534
3535       if ((in_flags & EF_ARM_VFP_FLOAT) != (out_flags & EF_ARM_VFP_FLOAT))
3536         {
3537           if (in_flags & EF_ARM_VFP_FLOAT)
3538             _bfd_error_handler
3539               (_("ERROR: %B uses VFP instructions, whereas %B does not"),
3540                ibfd, obfd);
3541           else
3542             _bfd_error_handler
3543               (_("ERROR: %B uses FPA instructions, whereas %B does not"),
3544                ibfd, obfd);
3545
3546           flags_compatible = FALSE;
3547         }
3548
3549       if ((in_flags & EF_ARM_MAVERICK_FLOAT) != (out_flags & EF_ARM_MAVERICK_FLOAT))
3550         {
3551           if (in_flags & EF_ARM_MAVERICK_FLOAT)
3552             _bfd_error_handler
3553               (_("ERROR: %B uses Maverick instructions, whereas %B does not"),
3554                ibfd, obfd);
3555           else
3556             _bfd_error_handler
3557               (_("ERROR: %B does not use Maverick instructions, whereas %B does"),
3558                ibfd, obfd);
3559
3560           flags_compatible = FALSE;
3561         }
3562
3563 #ifdef EF_ARM_SOFT_FLOAT
3564       if ((in_flags & EF_ARM_SOFT_FLOAT) != (out_flags & EF_ARM_SOFT_FLOAT))
3565         {
3566           /* We can allow interworking between code that is VFP format
3567              layout, and uses either soft float or integer regs for
3568              passing floating point arguments and results.  We already
3569              know that the APCS_FLOAT flags match; similarly for VFP
3570              flags.  */
3571           if ((in_flags & EF_ARM_APCS_FLOAT) != 0
3572               || (in_flags & EF_ARM_VFP_FLOAT) == 0)
3573             {
3574               if (in_flags & EF_ARM_SOFT_FLOAT)
3575                 _bfd_error_handler
3576                   (_("ERROR: %B uses software FP, whereas %B uses hardware FP"),
3577                    ibfd, obfd);
3578               else
3579                 _bfd_error_handler
3580                   (_("ERROR: %B uses hardware FP, whereas %B uses software FP"),
3581                    ibfd, obfd);
3582
3583               flags_compatible = FALSE;
3584             }
3585         }
3586 #endif
3587
3588       /* Interworking mismatch is only a warning.  */
3589       if ((in_flags & EF_ARM_INTERWORK) != (out_flags & EF_ARM_INTERWORK))
3590         {
3591           if (in_flags & EF_ARM_INTERWORK)
3592             {
3593               _bfd_error_handler
3594                 (_("Warning: %B supports interworking, whereas %B does not"),
3595                  ibfd, obfd);
3596             }
3597           else
3598             {
3599               _bfd_error_handler
3600                 (_("Warning: %B does not support interworking, whereas %B does"),
3601                  ibfd, obfd);
3602             }
3603         }
3604     }
3605
3606   return flags_compatible;
3607 }
3608
3609 /* Display the flags field.  */
3610
3611 static bfd_boolean
3612 elf32_arm_print_private_bfd_data (bfd *abfd, void * ptr)
3613 {
3614   FILE * file = (FILE *) ptr;
3615   unsigned long flags;
3616
3617   BFD_ASSERT (abfd != NULL && ptr != NULL);
3618
3619   /* Print normal ELF private data.  */
3620   _bfd_elf_print_private_bfd_data (abfd, ptr);
3621
3622   flags = elf_elfheader (abfd)->e_flags;
3623   /* Ignore init flag - it may not be set, despite the flags field
3624      containing valid data.  */
3625
3626   /* xgettext:c-format */
3627   fprintf (file, _("private flags = %lx:"), elf_elfheader (abfd)->e_flags);
3628
3629   switch (EF_ARM_EABI_VERSION (flags))
3630     {
3631     case EF_ARM_EABI_UNKNOWN:
3632       /* The following flag bits are GNU extensions and not part of the
3633          official ARM ELF extended ABI.  Hence they are only decoded if
3634          the EABI version is not set.  */
3635       if (flags & EF_ARM_INTERWORK)
3636         fprintf (file, _(" [interworking enabled]"));
3637
3638       if (flags & EF_ARM_APCS_26)
3639         fprintf (file, " [APCS-26]");
3640       else
3641         fprintf (file, " [APCS-32]");
3642
3643       if (flags & EF_ARM_VFP_FLOAT)
3644         fprintf (file, _(" [VFP float format]"));
3645       else if (flags & EF_ARM_MAVERICK_FLOAT)
3646         fprintf (file, _(" [Maverick float format]"));
3647       else
3648         fprintf (file, _(" [FPA float format]"));
3649
3650       if (flags & EF_ARM_APCS_FLOAT)
3651         fprintf (file, _(" [floats passed in float registers]"));
3652
3653       if (flags & EF_ARM_PIC)
3654         fprintf (file, _(" [position independent]"));
3655
3656       if (flags & EF_ARM_NEW_ABI)
3657         fprintf (file, _(" [new ABI]"));
3658
3659       if (flags & EF_ARM_OLD_ABI)
3660         fprintf (file, _(" [old ABI]"));
3661
3662       if (flags & EF_ARM_SOFT_FLOAT)
3663         fprintf (file, _(" [software FP]"));
3664
3665       flags &= ~(EF_ARM_INTERWORK | EF_ARM_APCS_26 | EF_ARM_APCS_FLOAT
3666                  | EF_ARM_PIC | EF_ARM_NEW_ABI | EF_ARM_OLD_ABI
3667                  | EF_ARM_SOFT_FLOAT | EF_ARM_VFP_FLOAT
3668                  | EF_ARM_MAVERICK_FLOAT);
3669       break;
3670
3671     case EF_ARM_EABI_VER1:
3672       fprintf (file, _(" [Version1 EABI]"));
3673
3674       if (flags & EF_ARM_SYMSARESORTED)
3675         fprintf (file, _(" [sorted symbol table]"));
3676       else
3677         fprintf (file, _(" [unsorted symbol table]"));
3678
3679       flags &= ~ EF_ARM_SYMSARESORTED;
3680       break;
3681
3682     case EF_ARM_EABI_VER2:
3683       fprintf (file, _(" [Version2 EABI]"));
3684
3685       if (flags & EF_ARM_SYMSARESORTED)
3686         fprintf (file, _(" [sorted symbol table]"));
3687       else
3688         fprintf (file, _(" [unsorted symbol table]"));
3689
3690       if (flags & EF_ARM_DYNSYMSUSESEGIDX)
3691         fprintf (file, _(" [dynamic symbols use segment index]"));
3692
3693       if (flags & EF_ARM_MAPSYMSFIRST)
3694         fprintf (file, _(" [mapping symbols precede others]"));
3695
3696       flags &= ~(EF_ARM_SYMSARESORTED | EF_ARM_DYNSYMSUSESEGIDX
3697                  | EF_ARM_MAPSYMSFIRST);
3698       break;
3699
3700     case EF_ARM_EABI_VER3:
3701       fprintf (file, _(" [Version3 EABI]"));
3702       break;
3703
3704     case EF_ARM_EABI_VER4:
3705       fprintf (file, _(" [Version4 EABI]"));
3706
3707       if (flags & EF_ARM_BE8)
3708         fprintf (file, _(" [BE8]"));
3709
3710       if (flags & EF_ARM_LE8)
3711         fprintf (file, _(" [LE8]"));
3712
3713       flags &= ~(EF_ARM_LE8 | EF_ARM_BE8);
3714       break;
3715
3716     default:
3717       fprintf (file, _(" <EABI version unrecognised>"));
3718       break;
3719     }
3720
3721   flags &= ~ EF_ARM_EABIMASK;
3722
3723   if (flags & EF_ARM_RELEXEC)
3724     fprintf (file, _(" [relocatable executable]"));
3725
3726   if (flags & EF_ARM_HASENTRY)
3727     fprintf (file, _(" [has entry point]"));
3728
3729   flags &= ~ (EF_ARM_RELEXEC | EF_ARM_HASENTRY);
3730
3731   if (flags)
3732     fprintf (file, _("<Unrecognised flag bits set>"));
3733
3734   fputc ('\n', file);
3735
3736   return TRUE;
3737 }
3738
3739 static int
3740 elf32_arm_get_symbol_type (Elf_Internal_Sym * elf_sym, int type)
3741 {
3742   switch (ELF_ST_TYPE (elf_sym->st_info))
3743     {
3744     case STT_ARM_TFUNC:
3745       return ELF_ST_TYPE (elf_sym->st_info);
3746
3747     case STT_ARM_16BIT:
3748       /* If the symbol is not an object, return the STT_ARM_16BIT flag.
3749          This allows us to distinguish between data used by Thumb instructions
3750          and non-data (which is probably code) inside Thumb regions of an
3751          executable.  */
3752       if (type != STT_OBJECT)
3753         return ELF_ST_TYPE (elf_sym->st_info);
3754       break;
3755
3756     default:
3757       break;
3758     }
3759
3760   return type;
3761 }
3762
3763 static asection *
3764 elf32_arm_gc_mark_hook (asection *                   sec,
3765                         struct bfd_link_info *       info ATTRIBUTE_UNUSED,
3766                         Elf_Internal_Rela *          rel,
3767                         struct elf_link_hash_entry * h,
3768                         Elf_Internal_Sym *           sym)
3769 {
3770   if (h != NULL)
3771     {
3772       switch (ELF32_R_TYPE (rel->r_info))
3773       {
3774       case R_ARM_GNU_VTINHERIT:
3775       case R_ARM_GNU_VTENTRY:
3776         break;
3777
3778       default:
3779         switch (h->root.type)
3780           {
3781           case bfd_link_hash_defined:
3782           case bfd_link_hash_defweak:
3783             return h->root.u.def.section;
3784
3785           case bfd_link_hash_common:
3786             return h->root.u.c.p->section;
3787
3788           default:
3789             break;
3790           }
3791        }
3792      }
3793    else
3794      return bfd_section_from_elf_index (sec->owner, sym->st_shndx);
3795
3796   return NULL;
3797 }
3798
3799 /* Update the got entry reference counts for the section being removed.  */
3800
3801 static bfd_boolean
3802 elf32_arm_gc_sweep_hook (bfd *                     abfd ATTRIBUTE_UNUSED,
3803                          struct bfd_link_info *    info ATTRIBUTE_UNUSED,
3804                          asection *                sec ATTRIBUTE_UNUSED,
3805                          const Elf_Internal_Rela * relocs ATTRIBUTE_UNUSED)
3806 {
3807   Elf_Internal_Shdr *symtab_hdr;
3808   struct elf_link_hash_entry **sym_hashes;
3809   bfd_signed_vma *local_got_refcounts;
3810   const Elf_Internal_Rela *rel, *relend;
3811   unsigned long r_symndx;
3812   struct elf_link_hash_entry *h;
3813   struct elf32_arm_link_hash_table * globals;
3814
3815   globals = elf32_arm_hash_table (info);
3816
3817   elf_section_data (sec)->local_dynrel = NULL;
3818
3819   symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
3820   sym_hashes = elf_sym_hashes (abfd);
3821   local_got_refcounts = elf_local_got_refcounts (abfd);
3822
3823   relend = relocs + sec->reloc_count;
3824   for (rel = relocs; rel < relend; rel++)
3825     {
3826       int r_type;
3827
3828       r_type = ELF32_R_TYPE (rel->r_info);
3829 #ifndef OLD_ARM_ABI
3830       r_type = arm_real_reloc_type (globals, r_type);
3831 #endif
3832       switch (r_type)
3833         {
3834         case R_ARM_GOT32:
3835 #ifndef OLD_ARM_ABI
3836         case R_ARM_GOT_PREL:
3837 #endif
3838           r_symndx = ELF32_R_SYM (rel->r_info);
3839           if (r_symndx >= symtab_hdr->sh_info)
3840             {
3841               h = sym_hashes[r_symndx - symtab_hdr->sh_info];
3842               if (h->got.refcount > 0)
3843                 h->got.refcount -= 1;
3844             }
3845           else if (local_got_refcounts != NULL)
3846             {
3847               if (local_got_refcounts[r_symndx] > 0)
3848                 local_got_refcounts[r_symndx] -= 1;
3849             }
3850           break;
3851
3852         case R_ARM_ABS32:
3853         case R_ARM_REL32:
3854         case R_ARM_PC24:
3855         case R_ARM_PLT32:
3856 #ifndef OLD_ARM_ABI
3857         case R_ARM_CALL:
3858         case R_ARM_JUMP24:
3859         case R_ARM_PREL31:
3860 #endif
3861           r_symndx = ELF32_R_SYM (rel->r_info);
3862           if (r_symndx >= symtab_hdr->sh_info)
3863             {
3864               struct elf32_arm_link_hash_entry *eh;
3865               struct elf32_arm_relocs_copied **pp;
3866               struct elf32_arm_relocs_copied *p;
3867
3868               h = sym_hashes[r_symndx - symtab_hdr->sh_info];
3869
3870               if (h->plt.refcount > 0)
3871                 h->plt.refcount -= 1;
3872
3873               if (r_type == R_ARM_ABS32
3874 #ifndef OLD_ARM_ABI
3875                   || r_type == R_ARM_PREL31
3876 #endif
3877                   || r_type == R_ARM_REL32)
3878                 {
3879                   eh = (struct elf32_arm_link_hash_entry *) h;
3880
3881                   for (pp = &eh->relocs_copied; (p = *pp) != NULL;
3882                        pp = &p->next)
3883                   if (p->section == sec)
3884                     {
3885                       p->count -= 1;
3886                       if (p->count == 0)
3887                         *pp = p->next;
3888                       break;
3889                     }
3890                 }
3891             }
3892           break;
3893
3894         default:
3895           break;
3896         }
3897     }
3898
3899   return TRUE;
3900 }
3901
3902 /* Look through the relocs for a section during the first phase.  */
3903
3904 static bfd_boolean
3905 elf32_arm_check_relocs (bfd *abfd, struct bfd_link_info *info,
3906                         asection *sec, const Elf_Internal_Rela *relocs)
3907 {
3908   Elf_Internal_Shdr *symtab_hdr;
3909   struct elf_link_hash_entry **sym_hashes;
3910   struct elf_link_hash_entry **sym_hashes_end;
3911   const Elf_Internal_Rela *rel;
3912   const Elf_Internal_Rela *rel_end;
3913   bfd *dynobj;
3914   asection *sreloc;
3915   bfd_vma *local_got_offsets;
3916   struct elf32_arm_link_hash_table *htab;
3917
3918   if (info->relocatable)
3919     return TRUE;
3920
3921   htab = elf32_arm_hash_table (info);
3922   sreloc = NULL;
3923
3924   dynobj = elf_hash_table (info)->dynobj;
3925   local_got_offsets = elf_local_got_offsets (abfd);
3926
3927   symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
3928   sym_hashes = elf_sym_hashes (abfd);
3929   sym_hashes_end = sym_hashes
3930     + symtab_hdr->sh_size / sizeof (Elf32_External_Sym);
3931
3932   if (!elf_bad_symtab (abfd))
3933     sym_hashes_end -= symtab_hdr->sh_info;
3934
3935   rel_end = relocs + sec->reloc_count;
3936   for (rel = relocs; rel < rel_end; rel++)
3937     {
3938       struct elf_link_hash_entry *h;
3939       unsigned long r_symndx;
3940       int r_type;
3941
3942       r_symndx = ELF32_R_SYM (rel->r_info);
3943       r_type = ELF32_R_TYPE (rel->r_info);
3944 #ifndef OLD_ARM_ABI
3945       r_type = arm_real_reloc_type (htab, r_type);
3946 #endif
3947       if (r_symndx < symtab_hdr->sh_info)
3948         h = NULL;
3949       else
3950         h = sym_hashes[r_symndx - symtab_hdr->sh_info];
3951
3952       switch (r_type)
3953         {
3954           case R_ARM_GOT32:
3955 #ifndef OLD_ARM_ABI
3956           case R_ARM_GOT_PREL:
3957 #endif
3958             /* This symbol requires a global offset table entry.  */
3959             if (h != NULL)
3960               {
3961                 h->got.refcount++;
3962               }
3963             else
3964               {
3965                 bfd_signed_vma *local_got_refcounts;
3966
3967                 /* This is a global offset table entry for a local symbol.  */
3968                 local_got_refcounts = elf_local_got_refcounts (abfd);
3969                 if (local_got_refcounts == NULL)
3970                   {
3971                     bfd_size_type size;
3972
3973                     size = symtab_hdr->sh_info;
3974                     size *= (sizeof (bfd_signed_vma) + sizeof (char));
3975                     local_got_refcounts = bfd_zalloc (abfd, size);
3976                     if (local_got_refcounts == NULL)
3977                       return FALSE;
3978                     elf_local_got_refcounts (abfd) = local_got_refcounts;
3979                   }
3980                 local_got_refcounts[r_symndx] += 1;
3981               }
3982             if (r_type == R_ARM_GOT32)
3983               break;
3984             /* Fall through.  */
3985
3986           case R_ARM_GOTOFF:
3987           case R_ARM_GOTPC:
3988             if (htab->sgot == NULL)
3989               {
3990                 if (htab->root.dynobj == NULL)
3991                   htab->root.dynobj = abfd;
3992                 if (!create_got_section (htab->root.dynobj, info))
3993                   return FALSE;
3994               }
3995             break;
3996
3997           case R_ARM_ABS32:
3998           case R_ARM_REL32:
3999           case R_ARM_PC24:
4000           case R_ARM_PLT32:
4001 #ifndef OLD_ARM_ABI
4002           case R_ARM_CALL:
4003           case R_ARM_JUMP24:
4004           case R_ARM_PREL31:
4005 #endif
4006             if (h != NULL)
4007               {
4008                 /* If this reloc is in a read-only section, we might
4009                    need a copy reloc.  We can't check reliably at this
4010                    stage whether the section is read-only, as input
4011                    sections have not yet been mapped to output sections.
4012                    Tentatively set the flag for now, and correct in
4013                    adjust_dynamic_symbol.  */
4014                 if (!info->shared)
4015                   h->non_got_ref = 1;
4016
4017                 /* We may need a .plt entry if the function this reloc
4018                    refers to is in a different object.  We can't tell for
4019                    sure yet, because something later might force the
4020                    symbol local.  */
4021                 if (r_type == R_ARM_PC24
4022 #ifndef OLD_ARM_ABI
4023                     || r_type == R_ARM_CALL
4024                     || r_type == R_ARM_JUMP24
4025 #endif
4026                     || r_type == R_ARM_PLT32)
4027                   h->needs_plt = 1;
4028
4029                 /* If we create a PLT entry, this relocation will reference
4030                    it, even if it's an ABS32 relocation.  */
4031                 h->plt.refcount += 1;
4032               }
4033
4034             /* If we are creating a shared library, and this is a reloc
4035                against a global symbol, or a non PC relative reloc
4036                against a local symbol, then we need to copy the reloc
4037                into the shared library.  However, if we are linking with
4038                -Bsymbolic, we do not need to copy a reloc against a
4039                global symbol which is defined in an object we are
4040                including in the link (i.e., DEF_REGULAR is set).  At
4041                this point we have not seen all the input files, so it is
4042                possible that DEF_REGULAR is not set now but will be set
4043                later (it is never cleared).  We account for that
4044                possibility below by storing information in the
4045                relocs_copied field of the hash table entry.  */
4046             if (info->shared
4047                 && (sec->flags & SEC_ALLOC) != 0
4048                 && ((r_type != R_ARM_PC24
4049                      && r_type != R_ARM_PLT32
4050 #ifndef OLD_ARM_ABI
4051                      && r_type != R_ARM_CALL
4052                      && r_type != R_ARM_JUMP24
4053                      && r_type != R_ARM_PREL31
4054 #endif
4055                      && r_type != R_ARM_REL32)
4056                     || (h != NULL
4057                         && (! info->symbolic
4058                             || !h->def_regular))))
4059               {
4060                 struct elf32_arm_relocs_copied *p, **head;
4061
4062                 /* When creating a shared object, we must copy these
4063                    reloc types into the output file.  We create a reloc
4064                    section in dynobj and make room for this reloc.  */
4065                 if (sreloc == NULL)
4066                   {
4067                     const char * name;
4068
4069                     name = (bfd_elf_string_from_elf_section
4070                             (abfd,
4071                              elf_elfheader (abfd)->e_shstrndx,
4072                              elf_section_data (sec)->rel_hdr.sh_name));
4073                     if (name == NULL)
4074                       return FALSE;
4075
4076                     BFD_ASSERT (strncmp (name, ".rel", 4) == 0
4077                                 && strcmp (bfd_get_section_name (abfd, sec),
4078                                            name + 4) == 0);
4079
4080                     sreloc = bfd_get_section_by_name (dynobj, name);
4081                     if (sreloc == NULL)
4082                       {
4083                         flagword flags;
4084
4085                         sreloc = bfd_make_section (dynobj, name);
4086                         flags = (SEC_HAS_CONTENTS | SEC_READONLY
4087                                  | SEC_IN_MEMORY | SEC_LINKER_CREATED);
4088                         if ((sec->flags & SEC_ALLOC) != 0
4089                             /* BPABI objects never have dynamic
4090                                relocations mapped.  */
4091                             && !htab->symbian_p)
4092                           flags |= SEC_ALLOC | SEC_LOAD;
4093                         if (sreloc == NULL
4094                             || ! bfd_set_section_flags (dynobj, sreloc, flags)
4095                             || ! bfd_set_section_alignment (dynobj, sreloc, 2))
4096                           return FALSE;
4097                       }
4098
4099                     elf_section_data (sec)->sreloc = sreloc;
4100                   }
4101
4102                 /* If this is a global symbol, we count the number of
4103                    relocations we need for this symbol.  */
4104                 if (h != NULL)
4105                   {
4106                     head = &((struct elf32_arm_link_hash_entry *) h)->relocs_copied;
4107                   }
4108                 else
4109                   {
4110                     /* Track dynamic relocs needed for local syms too.
4111                        We really need local syms available to do this
4112                        easily.  Oh well.  */
4113
4114                     asection *s;
4115                     s = bfd_section_from_r_symndx (abfd, &htab->sym_sec,
4116                                                    sec, r_symndx);
4117                     if (s == NULL)
4118                       return FALSE;
4119
4120                     head = ((struct elf32_arm_relocs_copied **)
4121                             &elf_section_data (s)->local_dynrel);
4122                   }
4123
4124                 p = *head;
4125                 if (p == NULL || p->section != sec)
4126                   {
4127                     bfd_size_type amt = sizeof *p;
4128
4129                     p = bfd_alloc (htab->root.dynobj, amt);
4130                     if (p == NULL)
4131                       return FALSE;
4132                     p->next = *head;
4133                     *head = p;
4134                     p->section = sec;
4135                     p->count = 0;
4136                   }
4137
4138                 if (r_type == R_ARM_ABS32
4139 #ifndef OLD_ARM_ABI
4140                     || r_type == R_ARM_PREL31
4141 #endif
4142                     || r_type == R_ARM_REL32)
4143                   p->count += 1;
4144               }
4145             break;
4146
4147         /* This relocation describes the C++ object vtable hierarchy.
4148            Reconstruct it for later use during GC.  */
4149         case R_ARM_GNU_VTINHERIT:
4150           if (!bfd_elf_gc_record_vtinherit (abfd, sec, h, rel->r_offset))
4151             return FALSE;
4152           break;
4153
4154         /* This relocation describes which C++ vtable entries are actually
4155            used.  Record for later use during GC.  */
4156         case R_ARM_GNU_VTENTRY:
4157           if (!bfd_elf_gc_record_vtentry (abfd, sec, h, rel->r_offset))
4158             return FALSE;
4159           break;
4160         }
4161     }
4162
4163   return TRUE;
4164 }
4165
4166 static bfd_boolean
4167 is_arm_mapping_symbol_name (const char * name)
4168 {
4169   return (name != NULL)
4170     && (name[0] == '$')
4171     && ((name[1] == 'a') || (name[1] == 't') || (name[1] == 'd'))
4172     && (name[2] == 0);
4173 }
4174
4175 /* Treat mapping symbols as special target symbols.  */
4176
4177 static bfd_boolean
4178 elf32_arm_is_target_special_symbol (bfd * abfd ATTRIBUTE_UNUSED, asymbol * sym)
4179 {
4180   return is_arm_mapping_symbol_name (sym->name);
4181 }
4182
4183 /* This is a copy of elf_find_function() from elf.c except that
4184    ARM mapping symbols are ignored when looking for function names
4185    and STT_ARM_TFUNC is considered to a function type.  */
4186
4187 static bfd_boolean
4188 arm_elf_find_function (bfd *         abfd ATTRIBUTE_UNUSED,
4189                        asection *    section,
4190                        asymbol **    symbols,
4191                        bfd_vma       offset,
4192                        const char ** filename_ptr,
4193                        const char ** functionname_ptr)
4194 {
4195   const char * filename = NULL;
4196   asymbol * func = NULL;
4197   bfd_vma low_func = 0;
4198   asymbol ** p;
4199
4200   for (p = symbols; *p != NULL; p++)
4201     {
4202       elf_symbol_type *q;
4203
4204       q = (elf_symbol_type *) *p;
4205
4206       switch (ELF_ST_TYPE (q->internal_elf_sym.st_info))
4207         {
4208         default:
4209           break;
4210         case STT_FILE:
4211           filename = bfd_asymbol_name (&q->symbol);
4212           break;
4213         case STT_FUNC:
4214         case STT_ARM_TFUNC:
4215           /* Skip $a and $t symbols.  */
4216           if ((q->symbol.flags & BSF_LOCAL)
4217               && is_arm_mapping_symbol_name (q->symbol.name))
4218             continue;
4219           /* Fall through.  */
4220         case STT_NOTYPE:
4221           if (bfd_get_section (&q->symbol) == section
4222               && q->symbol.value >= low_func
4223               && q->symbol.value <= offset)
4224             {
4225               func = (asymbol *) q;
4226               low_func = q->symbol.value;
4227             }
4228           break;
4229         }
4230     }
4231
4232   if (func == NULL)
4233     return FALSE;
4234
4235   if (filename_ptr)
4236     *filename_ptr = filename;
4237   if (functionname_ptr)
4238     *functionname_ptr = bfd_asymbol_name (func);
4239
4240   return TRUE;
4241 }  
4242
4243
4244 /* Find the nearest line to a particular section and offset, for error
4245    reporting.   This code is a duplicate of the code in elf.c, except
4246    that it uses arm_elf_find_function.  */
4247
4248 static bfd_boolean
4249 elf32_arm_find_nearest_line (bfd *          abfd,
4250                              asection *     section,
4251                              asymbol **     symbols,
4252                              bfd_vma        offset,
4253                              const char **  filename_ptr,
4254                              const char **  functionname_ptr,
4255                              unsigned int * line_ptr)
4256 {
4257   bfd_boolean found = FALSE;
4258
4259   /* We skip _bfd_dwarf1_find_nearest_line since no known ARM toolchain uses it.  */
4260
4261   if (_bfd_dwarf2_find_nearest_line (abfd, section, symbols, offset,
4262                                      filename_ptr, functionname_ptr,
4263                                      line_ptr, 0,
4264                                      & elf_tdata (abfd)->dwarf2_find_line_info))
4265     {
4266       if (!*functionname_ptr)
4267         arm_elf_find_function (abfd, section, symbols, offset,
4268                                *filename_ptr ? NULL : filename_ptr,
4269                                functionname_ptr);
4270
4271       return TRUE;
4272     }
4273
4274   if (! _bfd_stab_section_find_nearest_line (abfd, symbols, section, offset,
4275                                              & found, filename_ptr,
4276                                              functionname_ptr, line_ptr,
4277                                              & elf_tdata (abfd)->line_info))
4278     return FALSE;
4279
4280   if (found && (*functionname_ptr || *line_ptr))
4281     return TRUE;
4282
4283   if (symbols == NULL)
4284     return FALSE;
4285
4286   if (! arm_elf_find_function (abfd, section, symbols, offset,
4287                                filename_ptr, functionname_ptr))
4288     return FALSE;
4289
4290   *line_ptr = 0;
4291   return TRUE;
4292 }
4293
4294 /* Adjust a symbol defined by a dynamic object and referenced by a
4295    regular object.  The current definition is in some section of the
4296    dynamic object, but we're not including those sections.  We have to
4297    change the definition to something the rest of the link can
4298    understand.  */
4299
4300 static bfd_boolean
4301 elf32_arm_adjust_dynamic_symbol (struct bfd_link_info * info,
4302                                  struct elf_link_hash_entry * h)
4303 {
4304   bfd * dynobj;
4305   asection * s;
4306   unsigned int power_of_two;
4307
4308   dynobj = elf_hash_table (info)->dynobj;
4309
4310   /* Make sure we know what is going on here.  */
4311   BFD_ASSERT (dynobj != NULL
4312               && (h->needs_plt
4313                   || h->u.weakdef != NULL
4314                   || (h->def_dynamic
4315                       && h->ref_regular
4316                       && !h->def_regular)));
4317
4318   /* If this is a function, put it in the procedure linkage table.  We
4319      will fill in the contents of the procedure linkage table later,
4320      when we know the address of the .got section.  */
4321   if (h->type == STT_FUNC
4322       || h->needs_plt)
4323     {
4324       if (h->plt.refcount <= 0
4325           || SYMBOL_CALLS_LOCAL (info, h)
4326           || (ELF_ST_VISIBILITY (h->other) != STV_DEFAULT
4327               && h->root.type == bfd_link_hash_undefweak))
4328         {
4329           /* This case can occur if we saw a PLT32 reloc in an input
4330              file, but the symbol was never referred to by a dynamic
4331              object, or if all references were garbage collected.  In
4332              such a case, we don't actually need to build a procedure
4333              linkage table, and we can just do a PC24 reloc instead.  */
4334           h->plt.offset = (bfd_vma) -1;
4335           h->needs_plt = 0;
4336         }
4337
4338       return TRUE;
4339     }
4340   else
4341     /* It's possible that we incorrectly decided a .plt reloc was
4342        needed for an R_ARM_PC24 or similar reloc to a non-function sym
4343        in check_relocs.  We can't decide accurately between function
4344        and non-function syms in check-relocs; Objects loaded later in
4345        the link may change h->type.  So fix it now.  */
4346     h->plt.offset = (bfd_vma) -1;
4347
4348   /* If this is a weak symbol, and there is a real definition, the
4349      processor independent code will have arranged for us to see the
4350      real definition first, and we can just use the same value.  */
4351   if (h->u.weakdef != NULL)
4352     {
4353       BFD_ASSERT (h->u.weakdef->root.type == bfd_link_hash_defined
4354                   || h->u.weakdef->root.type == bfd_link_hash_defweak);
4355       h->root.u.def.section = h->u.weakdef->root.u.def.section;
4356       h->root.u.def.value = h->u.weakdef->root.u.def.value;
4357       return TRUE;
4358     }
4359
4360   /* This is a reference to a symbol defined by a dynamic object which
4361      is not a function.  */
4362
4363   /* If we are creating a shared library, we must presume that the
4364      only references to the symbol are via the global offset table.
4365      For such cases we need not do anything here; the relocations will
4366      be handled correctly by relocate_section.  */
4367   if (info->shared)
4368     return TRUE;
4369
4370   /* We must allocate the symbol in our .dynbss section, which will
4371      become part of the .bss section of the executable.  There will be
4372      an entry for this symbol in the .dynsym section.  The dynamic
4373      object will contain position independent code, so all references
4374      from the dynamic object to this symbol will go through the global
4375      offset table.  The dynamic linker will use the .dynsym entry to
4376      determine the address it must put in the global offset table, so
4377      both the dynamic object and the regular object will refer to the
4378      same memory location for the variable.  */
4379   s = bfd_get_section_by_name (dynobj, ".dynbss");
4380   BFD_ASSERT (s != NULL);
4381
4382   /* We must generate a R_ARM_COPY reloc to tell the dynamic linker to
4383      copy the initial value out of the dynamic object and into the
4384      runtime process image.  We need to remember the offset into the
4385      .rel.bss section we are going to use.  */
4386   if ((h->root.u.def.section->flags & SEC_ALLOC) != 0)
4387     {
4388       asection *srel;
4389
4390       srel = bfd_get_section_by_name (dynobj, ".rel.bss");
4391       BFD_ASSERT (srel != NULL);
4392       srel->size += sizeof (Elf32_External_Rel);
4393       h->needs_copy = 1;
4394     }
4395
4396   /* We need to figure out the alignment required for this symbol.  I
4397      have no idea how ELF linkers handle this.  */
4398   power_of_two = bfd_log2 (h->size);
4399   if (power_of_two > 3)
4400     power_of_two = 3;
4401
4402   /* Apply the required alignment.  */
4403   s->size = BFD_ALIGN (s->size, (bfd_size_type) (1 << power_of_two));
4404   if (power_of_two > bfd_get_section_alignment (dynobj, s))
4405     {
4406       if (! bfd_set_section_alignment (dynobj, s, power_of_two))
4407         return FALSE;
4408     }
4409
4410   /* Define the symbol as being at this point in the section.  */
4411   h->root.u.def.section = s;
4412   h->root.u.def.value = s->size;
4413
4414   /* Increment the section size to make room for the symbol.  */
4415   s->size += h->size;
4416
4417   return TRUE;
4418 }
4419
4420 /* Allocate space in .plt, .got and associated reloc sections for
4421    dynamic relocs.  */
4422
4423 static bfd_boolean
4424 allocate_dynrelocs (struct elf_link_hash_entry *h, void * inf)
4425 {
4426   struct bfd_link_info *info;
4427   struct elf32_arm_link_hash_table *htab;
4428   struct elf32_arm_link_hash_entry *eh;
4429   struct elf32_arm_relocs_copied *p;
4430
4431   if (h->root.type == bfd_link_hash_indirect)
4432     return TRUE;
4433
4434   if (h->root.type == bfd_link_hash_warning)
4435     /* When warning symbols are created, they **replace** the "real"
4436        entry in the hash table, thus we never get to see the real
4437        symbol in a hash traversal.  So look at it now.  */
4438     h = (struct elf_link_hash_entry *) h->root.u.i.link;
4439
4440   info = (struct bfd_link_info *) inf;
4441   htab = elf32_arm_hash_table (info);
4442
4443   if (htab->root.dynamic_sections_created
4444       && h->plt.refcount > 0)
4445     {
4446       /* Make sure this symbol is output as a dynamic symbol.
4447          Undefined weak syms won't yet be marked as dynamic.  */
4448       if (h->dynindx == -1
4449           && !h->forced_local)
4450         {
4451           if (! bfd_elf_link_record_dynamic_symbol (info, h))
4452             return FALSE;
4453         }
4454
4455       if (info->shared
4456           || WILL_CALL_FINISH_DYNAMIC_SYMBOL (1, 0, h))
4457         {
4458           asection *s = htab->splt;
4459
4460           /* If this is the first .plt entry, make room for the special
4461              first entry.  */
4462           if (s->size == 0)
4463             s->size += htab->plt_header_size;
4464
4465           h->plt.offset = s->size;
4466
4467           /* If this symbol is not defined in a regular file, and we are
4468              not generating a shared library, then set the symbol to this
4469              location in the .plt.  This is required to make function
4470              pointers compare as equal between the normal executable and
4471              the shared library.  */
4472           if (! info->shared
4473               && !h->def_regular)
4474             {
4475               h->root.u.def.section = s;
4476               h->root.u.def.value = h->plt.offset;
4477             }
4478
4479           /* Make room for this entry.  */
4480           s->size += htab->plt_entry_size;
4481
4482           if (!htab->symbian_p)
4483             /* We also need to make an entry in the .got.plt section, which
4484                will be placed in the .got section by the linker script.  */
4485             htab->sgotplt->size += 4;
4486
4487           /* We also need to make an entry in the .rel.plt section.  */
4488           htab->srelplt->size += sizeof (Elf32_External_Rel);
4489         }
4490       else
4491         {
4492           h->plt.offset = (bfd_vma) -1;
4493           h->needs_plt = 0;
4494         }
4495     }
4496   else
4497     {
4498       h->plt.offset = (bfd_vma) -1;
4499       h->needs_plt = 0;
4500     }
4501
4502   if (h->got.refcount > 0)
4503     {
4504       asection *s;
4505       bfd_boolean dyn;
4506
4507       /* Make sure this symbol is output as a dynamic symbol.
4508          Undefined weak syms won't yet be marked as dynamic.  */
4509       if (h->dynindx == -1
4510           && !h->forced_local)
4511         {
4512           if (! bfd_elf_link_record_dynamic_symbol (info, h))
4513             return FALSE;
4514         }
4515
4516       if (!htab->symbian_p)
4517         {
4518           s = htab->sgot;
4519           h->got.offset = s->size;
4520           s->size += 4;
4521           dyn = htab->root.dynamic_sections_created;
4522           if ((ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
4523                || h->root.type != bfd_link_hash_undefweak)
4524               && (info->shared
4525                   || WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, 0, h)))
4526             htab->srelgot->size += sizeof (Elf32_External_Rel);
4527         }
4528     }
4529   else
4530     h->got.offset = (bfd_vma) -1;
4531
4532   eh = (struct elf32_arm_link_hash_entry *) h;
4533   if (eh->relocs_copied == NULL)
4534     return TRUE;
4535
4536   /* In the shared -Bsymbolic case, discard space allocated for
4537      dynamic pc-relative relocs against symbols which turn out to be
4538      defined in regular objects.  For the normal shared case, discard
4539      space for pc-relative relocs that have become local due to symbol
4540      visibility changes.  */
4541
4542   if (info->shared)
4543     {
4544       /* Discard relocs on undefined weak syms with non-default
4545          visibility.  */
4546       if (ELF_ST_VISIBILITY (h->other) != STV_DEFAULT
4547           && h->root.type == bfd_link_hash_undefweak)
4548         eh->relocs_copied = NULL;
4549     }
4550   else
4551     {
4552       /* For the non-shared case, discard space for relocs against
4553          symbols which turn out to need copy relocs or are not
4554          dynamic.  */
4555
4556       if (!h->non_got_ref
4557           && ((h->def_dynamic
4558                && !h->def_regular)
4559               || (htab->root.dynamic_sections_created
4560                   && (h->root.type == bfd_link_hash_undefweak
4561                       || h->root.type == bfd_link_hash_undefined))))
4562         {
4563           /* Make sure this symbol is output as a dynamic symbol.
4564              Undefined weak syms won't yet be marked as dynamic.  */
4565           if (h->dynindx == -1
4566               && !h->forced_local)
4567             {
4568               if (! bfd_elf_link_record_dynamic_symbol (info, h))
4569                 return FALSE;
4570             }
4571
4572           /* If that succeeded, we know we'll be keeping all the
4573              relocs.  */
4574           if (h->dynindx != -1)
4575             goto keep;
4576         }
4577
4578       eh->relocs_copied = NULL;
4579
4580     keep: ;
4581     }
4582
4583   /* Finally, allocate space.  */
4584   for (p = eh->relocs_copied; p != NULL; p = p->next)
4585     {
4586       asection *sreloc = elf_section_data (p->section)->sreloc;
4587       sreloc->size += p->count * sizeof (Elf32_External_Rel);
4588     }
4589
4590   return TRUE;
4591 }
4592
4593 /* Set the sizes of the dynamic sections.  */
4594
4595 static bfd_boolean
4596 elf32_arm_size_dynamic_sections (bfd * output_bfd ATTRIBUTE_UNUSED,
4597                                  struct bfd_link_info * info)
4598 {
4599   bfd * dynobj;
4600   asection * s;
4601   bfd_boolean plt;
4602   bfd_boolean relocs;
4603   bfd *ibfd;
4604   struct elf32_arm_link_hash_table *htab;
4605
4606   htab = elf32_arm_hash_table (info);
4607   dynobj = elf_hash_table (info)->dynobj;
4608   BFD_ASSERT (dynobj != NULL);
4609
4610   if (elf_hash_table (info)->dynamic_sections_created)
4611     {
4612       /* Set the contents of the .interp section to the interpreter.  */
4613       if (info->executable)
4614         {
4615           s = bfd_get_section_by_name (dynobj, ".interp");
4616           BFD_ASSERT (s != NULL);
4617           s->size = sizeof ELF_DYNAMIC_INTERPRETER;
4618           s->contents = (unsigned char *) ELF_DYNAMIC_INTERPRETER;
4619         }
4620     }
4621
4622   /* Set up .got offsets for local syms, and space for local dynamic
4623      relocs.  */
4624   for (ibfd = info->input_bfds; ibfd != NULL; ibfd = ibfd->link_next)
4625     {
4626       bfd_signed_vma *local_got;
4627       bfd_signed_vma *end_local_got;
4628       char *local_tls_type;
4629       bfd_size_type locsymcount;
4630       Elf_Internal_Shdr *symtab_hdr;
4631       asection *srel;
4632
4633       if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour)
4634         continue;
4635
4636       for (s = ibfd->sections; s != NULL; s = s->next)
4637         {
4638           struct elf32_arm_relocs_copied *p;
4639
4640           for (p = *((struct elf32_arm_relocs_copied **)
4641                      &elf_section_data (s)->local_dynrel);
4642                p != NULL;
4643                p = p->next)
4644             {
4645               if (!bfd_is_abs_section (p->section)
4646                   && bfd_is_abs_section (p->section->output_section))
4647                 {
4648                   /* Input section has been discarded, either because
4649                      it is a copy of a linkonce section or due to
4650                      linker script /DISCARD/, so we'll be discarding
4651                      the relocs too.  */
4652                 }
4653               else if (p->count != 0)
4654                 {
4655                   srel = elf_section_data (p->section)->sreloc;
4656                   srel->size += p->count * sizeof (Elf32_External_Rel);
4657                   if ((p->section->output_section->flags & SEC_READONLY) != 0)
4658                     info->flags |= DF_TEXTREL;
4659                 }
4660             }
4661         }
4662
4663       local_got = elf_local_got_refcounts (ibfd);
4664       if (!local_got)
4665         continue;
4666
4667       symtab_hdr = &elf_tdata (ibfd)->symtab_hdr;
4668       locsymcount = symtab_hdr->sh_info;
4669       end_local_got = local_got + locsymcount;
4670       s = htab->sgot;
4671       srel = htab->srelgot;
4672       for (; local_got < end_local_got; ++local_got, ++local_tls_type)
4673         {
4674           if (*local_got > 0)
4675             {
4676               *local_got = s->size;
4677               s->size += 4;
4678               if (info->shared)
4679                 srel->size += sizeof (Elf32_External_Rel);
4680             }
4681           else
4682             *local_got = (bfd_vma) -1;
4683         }
4684     }
4685
4686   /* Allocate global sym .plt and .got entries, and space for global
4687      sym dynamic relocs.  */
4688   elf_link_hash_traverse (& htab->root, allocate_dynrelocs, info);
4689
4690   /* The check_relocs and adjust_dynamic_symbol entry points have
4691      determined the sizes of the various dynamic sections.  Allocate
4692      memory for them.  */
4693   plt = FALSE;
4694   relocs = FALSE;
4695   for (s = dynobj->sections; s != NULL; s = s->next)
4696     {
4697       const char * name;
4698       bfd_boolean strip;
4699
4700       if ((s->flags & SEC_LINKER_CREATED) == 0)
4701         continue;
4702
4703       /* It's OK to base decisions on the section name, because none
4704          of the dynobj section names depend upon the input files.  */
4705       name = bfd_get_section_name (dynobj, s);
4706
4707       strip = FALSE;
4708
4709       if (strcmp (name, ".plt") == 0)
4710         {
4711           if (s->size == 0)
4712             {
4713               /* Strip this section if we don't need it; see the
4714                  comment below.  */
4715               strip = TRUE;
4716             }
4717           else
4718             {
4719               /* Remember whether there is a PLT.  */
4720               plt = TRUE;
4721             }
4722         }
4723       else if (strncmp (name, ".rel", 4) == 0)
4724         {
4725           if (s->size == 0)
4726             {
4727               /* If we don't need this section, strip it from the
4728                  output file.  This is mostly to handle .rel.bss and
4729                  .rel.plt.  We must create both sections in
4730                  create_dynamic_sections, because they must be created
4731                  before the linker maps input sections to output
4732                  sections.  The linker does that before
4733                  adjust_dynamic_symbol is called, and it is that
4734                  function which decides whether anything needs to go
4735                  into these sections.  */
4736               strip = TRUE;
4737             }
4738           else
4739             {
4740               /* Remember whether there are any reloc sections other
4741                  than .rel.plt.  */
4742               if (strcmp (name, ".rel.plt") != 0)
4743                 relocs = TRUE;
4744
4745               /* We use the reloc_count field as a counter if we need
4746                  to copy relocs into the output file.  */
4747               s->reloc_count = 0;
4748             }
4749         }
4750       else if (strncmp (name, ".got", 4) != 0)
4751         {
4752           /* It's not one of our sections, so don't allocate space.  */
4753           continue;
4754         }
4755
4756       if (strip)
4757         {
4758           _bfd_strip_section_from_output (info, s);
4759           continue;
4760         }
4761
4762       /* Allocate memory for the section contents.  */
4763       s->contents = (bfd_byte *) bfd_zalloc (dynobj, s->size);
4764       if (s->contents == NULL && s->size != 0)
4765         return FALSE;
4766     }
4767
4768   if (elf_hash_table (info)->dynamic_sections_created)
4769     {
4770       /* Add some entries to the .dynamic section.  We fill in the
4771          values later, in elf32_arm_finish_dynamic_sections, but we
4772          must add the entries now so that we get the correct size for
4773          the .dynamic section.  The DT_DEBUG entry is filled in by the
4774          dynamic linker and used by the debugger.  */
4775 #define add_dynamic_entry(TAG, VAL) \
4776   _bfd_elf_add_dynamic_entry (info, TAG, VAL)
4777
4778       if (!info->shared)
4779         {
4780           if (!add_dynamic_entry (DT_DEBUG, 0))
4781             return FALSE;
4782         }
4783
4784       if (plt)
4785         {
4786           if (   !add_dynamic_entry (DT_PLTGOT, 0)
4787               || !add_dynamic_entry (DT_PLTRELSZ, 0)
4788               || !add_dynamic_entry (DT_PLTREL, DT_REL)
4789               || !add_dynamic_entry (DT_JMPREL, 0))
4790             return FALSE;
4791         }
4792
4793       if (relocs)
4794         {
4795           if (   !add_dynamic_entry (DT_REL, 0)
4796               || !add_dynamic_entry (DT_RELSZ, 0)
4797               || !add_dynamic_entry (DT_RELENT, sizeof (Elf32_External_Rel)))
4798             return FALSE;
4799         }
4800
4801       if ((info->flags & DF_TEXTREL) != 0)
4802         {
4803           if (!add_dynamic_entry (DT_TEXTREL, 0))
4804             return FALSE;
4805           info->flags |= DF_TEXTREL;
4806         }
4807     }
4808 #undef add_synamic_entry
4809
4810   return TRUE;
4811 }
4812
4813 /* Finish up dynamic symbol handling.  We set the contents of various
4814    dynamic sections here.  */
4815
4816 static bfd_boolean
4817 elf32_arm_finish_dynamic_symbol (bfd * output_bfd, struct bfd_link_info * info,
4818                                  struct elf_link_hash_entry * h, Elf_Internal_Sym * sym)
4819 {
4820   bfd * dynobj;
4821   struct elf32_arm_link_hash_table *htab;
4822
4823   dynobj = elf_hash_table (info)->dynobj;
4824   htab = elf32_arm_hash_table (info);
4825
4826   if (h->plt.offset != (bfd_vma) -1)
4827     {
4828       asection * splt;
4829       asection * srel;
4830       bfd_byte *loc;
4831       bfd_vma plt_index;
4832       Elf_Internal_Rela rel;
4833
4834       /* This symbol has an entry in the procedure linkage table.  Set
4835          it up.  */
4836
4837       BFD_ASSERT (h->dynindx != -1);
4838
4839       splt = bfd_get_section_by_name (dynobj, ".plt");
4840       srel = bfd_get_section_by_name (dynobj, ".rel.plt");
4841       BFD_ASSERT (splt != NULL && srel != NULL);
4842
4843       /* Get the index in the procedure linkage table which
4844          corresponds to this symbol.  This is the index of this symbol
4845          in all the symbols for which we are making plt entries.  The
4846          first entry in the procedure linkage table is reserved.  */
4847       plt_index = ((h->plt.offset - htab->plt_header_size) 
4848                    / htab->plt_entry_size);
4849
4850       /* Fill in the entry in the procedure linkage table.  */
4851       if (htab->symbian_p)
4852         {
4853           unsigned i;
4854           for (i = 0; i < htab->plt_entry_size / 4; ++i)
4855             bfd_put_32 (output_bfd, 
4856                         elf32_arm_symbian_plt_entry[i],
4857                         splt->contents + h->plt.offset + 4 * i);
4858           
4859           /* Fill in the entry in the .rel.plt section.  */
4860           rel.r_offset = (splt->output_section->vma
4861                           + splt->output_offset
4862                           + h->plt.offset + 4 * (i - 1));
4863           rel.r_info = ELF32_R_INFO (h->dynindx, R_ARM_GLOB_DAT);
4864         }
4865       else
4866         {
4867           bfd_vma got_offset;
4868           bfd_vma got_displacement;
4869           asection * sgot;
4870           
4871           sgot = bfd_get_section_by_name (dynobj, ".got.plt");
4872           BFD_ASSERT (sgot != NULL);
4873
4874           /* Get the offset into the .got table of the entry that
4875              corresponds to this function.  Each .got entry is 4 bytes.
4876              The first three are reserved.  */
4877           got_offset = (plt_index + 3) * 4;
4878
4879           /* Calculate the displacement between the PLT slot and the
4880              entry in the GOT.  */
4881           got_displacement = (sgot->output_section->vma
4882                               + sgot->output_offset
4883                               + got_offset
4884                               - splt->output_section->vma
4885                               - splt->output_offset
4886                               - h->plt.offset
4887                               - 8);
4888
4889           BFD_ASSERT ((got_displacement & 0xf0000000) == 0);
4890
4891           bfd_put_32 (output_bfd, elf32_arm_plt_entry[0] | ((got_displacement & 0x0ff00000) >> 20),
4892                       splt->contents + h->plt.offset + 0);
4893           bfd_put_32 (output_bfd, elf32_arm_plt_entry[1] | ((got_displacement & 0x000ff000) >> 12),
4894                       splt->contents + h->plt.offset + 4);
4895           bfd_put_32 (output_bfd, elf32_arm_plt_entry[2] | (got_displacement & 0x00000fff),
4896                       splt->contents + h->plt.offset + 8);
4897 #ifdef FOUR_WORD_PLT
4898           bfd_put_32 (output_bfd, elf32_arm_plt_entry[3],
4899                       splt->contents + h->plt.offset + 12);
4900 #endif
4901
4902           /* Fill in the entry in the global offset table.  */
4903           bfd_put_32 (output_bfd,
4904                       (splt->output_section->vma
4905                        + splt->output_offset),
4906                       sgot->contents + got_offset);
4907           
4908           /* Fill in the entry in the .rel.plt section.  */
4909           rel.r_offset = (sgot->output_section->vma
4910                           + sgot->output_offset
4911                           + got_offset);
4912           rel.r_info = ELF32_R_INFO (h->dynindx, R_ARM_JUMP_SLOT);
4913         }
4914
4915       loc = srel->contents + plt_index * sizeof (Elf32_External_Rel);
4916       bfd_elf32_swap_reloc_out (output_bfd, &rel, loc);
4917
4918       if (!h->def_regular)
4919         {
4920           /* Mark the symbol as undefined, rather than as defined in
4921              the .plt section.  Leave the value alone.  */
4922           sym->st_shndx = SHN_UNDEF;
4923           /* If the symbol is weak, we do need to clear the value.
4924              Otherwise, the PLT entry would provide a definition for
4925              the symbol even if the symbol wasn't defined anywhere,
4926              and so the symbol would never be NULL.  */
4927           if (!h->ref_regular_nonweak)
4928             sym->st_value = 0;
4929         }
4930     }
4931
4932   if (h->got.offset != (bfd_vma) -1)
4933     {
4934       asection * sgot;
4935       asection * srel;
4936       Elf_Internal_Rela rel;
4937       bfd_byte *loc;
4938
4939       /* This symbol has an entry in the global offset table.  Set it
4940          up.  */
4941       sgot = bfd_get_section_by_name (dynobj, ".got");
4942       srel = bfd_get_section_by_name (dynobj, ".rel.got");
4943       BFD_ASSERT (sgot != NULL && srel != NULL);
4944
4945       rel.r_offset = (sgot->output_section->vma
4946                       + sgot->output_offset
4947                       + (h->got.offset &~ (bfd_vma) 1));
4948
4949       /* If this is a static link, or it is a -Bsymbolic link and the
4950          symbol is defined locally or was forced to be local because
4951          of a version file, we just want to emit a RELATIVE reloc.
4952          The entry in the global offset table will already have been
4953          initialized in the relocate_section function.  */
4954       if (info->shared
4955           && SYMBOL_REFERENCES_LOCAL (info, h))
4956         {
4957           BFD_ASSERT((h->got.offset & 1) != 0);
4958           rel.r_info = ELF32_R_INFO (0, R_ARM_RELATIVE);
4959         }
4960       else
4961         {
4962           BFD_ASSERT((h->got.offset & 1) == 0);
4963           bfd_put_32 (output_bfd, (bfd_vma) 0, sgot->contents + h->got.offset);
4964           rel.r_info = ELF32_R_INFO (h->dynindx, R_ARM_GLOB_DAT);
4965         }
4966
4967       loc = srel->contents + srel->reloc_count++ * sizeof (Elf32_External_Rel);
4968       bfd_elf32_swap_reloc_out (output_bfd, &rel, loc);
4969     }
4970
4971   if (h->needs_copy)
4972     {
4973       asection * s;
4974       Elf_Internal_Rela rel;
4975       bfd_byte *loc;
4976
4977       /* This symbol needs a copy reloc.  Set it up.  */
4978       BFD_ASSERT (h->dynindx != -1
4979                   && (h->root.type == bfd_link_hash_defined
4980                       || h->root.type == bfd_link_hash_defweak));
4981
4982       s = bfd_get_section_by_name (h->root.u.def.section->owner,
4983                                    ".rel.bss");
4984       BFD_ASSERT (s != NULL);
4985
4986       rel.r_offset = (h->root.u.def.value
4987                       + h->root.u.def.section->output_section->vma
4988                       + h->root.u.def.section->output_offset);
4989       rel.r_info = ELF32_R_INFO (h->dynindx, R_ARM_COPY);
4990       loc = s->contents + s->reloc_count++ * sizeof (Elf32_External_Rel);
4991       bfd_elf32_swap_reloc_out (output_bfd, &rel, loc);
4992     }
4993
4994   /* Mark _DYNAMIC and _GLOBAL_OFFSET_TABLE_ as absolute.  */
4995   if (strcmp (h->root.root.string, "_DYNAMIC") == 0
4996       || strcmp (h->root.root.string, "_GLOBAL_OFFSET_TABLE_") == 0)
4997     sym->st_shndx = SHN_ABS;
4998
4999   return TRUE;
5000 }
5001
5002 /* Finish up the dynamic sections.  */
5003
5004 static bfd_boolean
5005 elf32_arm_finish_dynamic_sections (bfd * output_bfd, struct bfd_link_info * info)
5006 {
5007   bfd * dynobj;
5008   asection * sgot;
5009   asection * sdyn;
5010
5011   dynobj = elf_hash_table (info)->dynobj;
5012
5013   sgot = bfd_get_section_by_name (dynobj, ".got.plt");
5014   BFD_ASSERT (elf32_arm_hash_table (info)->symbian_p || sgot != NULL);
5015   sdyn = bfd_get_section_by_name (dynobj, ".dynamic");
5016
5017   if (elf_hash_table (info)->dynamic_sections_created)
5018     {
5019       asection *splt;
5020       Elf32_External_Dyn *dyncon, *dynconend;
5021       struct elf32_arm_link_hash_table *htab;
5022
5023       htab = elf32_arm_hash_table (info);
5024       splt = bfd_get_section_by_name (dynobj, ".plt");
5025       BFD_ASSERT (splt != NULL && sdyn != NULL);
5026
5027       dyncon = (Elf32_External_Dyn *) sdyn->contents;
5028       dynconend = (Elf32_External_Dyn *) (sdyn->contents + sdyn->size);
5029
5030       for (; dyncon < dynconend; dyncon++)
5031         {
5032           Elf_Internal_Dyn dyn;
5033           const char * name;
5034           asection * s;
5035
5036           bfd_elf32_swap_dyn_in (dynobj, dyncon, &dyn);
5037
5038           switch (dyn.d_tag)
5039             {
5040               unsigned int type;
5041
5042             default:
5043               break;
5044
5045             case DT_HASH:
5046               name = ".hash";
5047               goto get_vma_if_bpabi;
5048             case DT_STRTAB:
5049               name = ".dynstr";
5050               goto get_vma_if_bpabi;
5051             case DT_SYMTAB:
5052               name = ".dynsym";
5053               goto get_vma_if_bpabi;
5054             case DT_VERSYM:
5055               name = ".gnu.version";
5056               goto get_vma_if_bpabi;
5057             case DT_VERDEF:
5058               name = ".gnu.version_d";
5059               goto get_vma_if_bpabi;
5060             case DT_VERNEED:
5061               name = ".gnu.version_r";
5062               goto get_vma_if_bpabi;
5063
5064             case DT_PLTGOT:
5065               name = ".got";
5066               goto get_vma;
5067             case DT_JMPREL:
5068               name = ".rel.plt";
5069             get_vma:
5070               s = bfd_get_section_by_name (output_bfd, name);
5071               BFD_ASSERT (s != NULL);
5072               if (!htab->symbian_p)
5073                 dyn.d_un.d_ptr = s->vma;
5074               else
5075                 /* In the BPABI, tags in the PT_DYNAMIC section point
5076                    at the file offset, not the memory address, for the
5077                    convenience of the post linker.  */
5078                 dyn.d_un.d_ptr = s->filepos;
5079               bfd_elf32_swap_dyn_out (output_bfd, &dyn, dyncon);
5080               break;
5081
5082             get_vma_if_bpabi:
5083               if (htab->symbian_p)
5084                 goto get_vma;
5085               break;
5086
5087             case DT_PLTRELSZ:
5088               s = bfd_get_section_by_name (output_bfd, ".rel.plt");
5089               BFD_ASSERT (s != NULL);
5090               dyn.d_un.d_val = s->size;
5091               bfd_elf32_swap_dyn_out (output_bfd, &dyn, dyncon);
5092               break;
5093               
5094             case DT_RELSZ:
5095               if (!htab->symbian_p)
5096                 {
5097                   /* My reading of the SVR4 ABI indicates that the
5098                      procedure linkage table relocs (DT_JMPREL) should be
5099                      included in the overall relocs (DT_REL).  This is
5100                      what Solaris does.  However, UnixWare can not handle
5101                      that case.  Therefore, we override the DT_RELSZ entry
5102                      here to make it not include the JMPREL relocs.  Since
5103                      the linker script arranges for .rel.plt to follow all
5104                      other relocation sections, we don't have to worry
5105                      about changing the DT_REL entry.  */
5106                   s = bfd_get_section_by_name (output_bfd, ".rel.plt");
5107                   if (s != NULL)
5108                     dyn.d_un.d_val -= s->size;
5109                   bfd_elf32_swap_dyn_out (output_bfd, &dyn, dyncon);
5110                   break;
5111                 }
5112               /* Fall through */
5113
5114             case DT_REL:
5115             case DT_RELA:
5116             case DT_RELASZ:
5117               /* In the BPABI, the DT_REL tag must point at the file
5118                  offset, not the VMA, of the first relocation
5119                  section.  So, we use code similar to that in
5120                  elflink.c, but do not check for SHF_ALLOC on the
5121                  relcoation section, since relocations sections are
5122                  never allocated under the BPABI.  The comments above
5123                  about Unixware notwithstanding, we include all of the
5124                  relocations here.  */
5125               if (htab->symbian_p)
5126                 {
5127                   unsigned int i;
5128                   type = ((dyn.d_tag == DT_REL || dyn.d_tag == DT_RELSZ)
5129                           ? SHT_REL : SHT_RELA);
5130                   dyn.d_un.d_val = 0;
5131                   for (i = 1; i < elf_numsections (output_bfd); i++)
5132                     {
5133                       Elf_Internal_Shdr *hdr 
5134                         = elf_elfsections (output_bfd)[i];
5135                       if (hdr->sh_type == type)
5136                         {
5137                           if (dyn.d_tag == DT_RELSZ 
5138                               || dyn.d_tag == DT_RELASZ)
5139                             dyn.d_un.d_val += hdr->sh_size;
5140                           else if (dyn.d_un.d_val == 0
5141                                    || hdr->sh_offset < dyn.d_un.d_val)
5142                             dyn.d_un.d_val = hdr->sh_offset;
5143                         }
5144                     }
5145                   bfd_elf32_swap_dyn_out (output_bfd, &dyn, dyncon);
5146                 }
5147               break;
5148
5149               /* Set the bottom bit of DT_INIT/FINI if the
5150                  corresponding function is Thumb.  */
5151             case DT_INIT:
5152               name = info->init_function;
5153               goto get_sym;
5154             case DT_FINI:
5155               name = info->fini_function;
5156             get_sym:
5157               /* If it wasn't set by elf_bfd_final_link
5158                  then there is nothing to adjust.  */
5159               if (dyn.d_un.d_val != 0)
5160                 {
5161                   struct elf_link_hash_entry * eh;
5162
5163                   eh = elf_link_hash_lookup (elf_hash_table (info), name,
5164                                              FALSE, FALSE, TRUE);
5165                   if (eh != (struct elf_link_hash_entry *) NULL
5166                       && ELF_ST_TYPE (eh->type) == STT_ARM_TFUNC)
5167                     {
5168                       dyn.d_un.d_val |= 1;
5169                       bfd_elf32_swap_dyn_out (output_bfd, &dyn, dyncon);
5170                     }
5171                 }
5172               break;
5173             }
5174         }
5175
5176       /* Fill in the first entry in the procedure linkage table.  */
5177       if (splt->size > 0 && elf32_arm_hash_table (info)->plt_header_size)
5178         {
5179           bfd_vma got_displacement;
5180
5181           /* Calculate the displacement between the PLT slot and &GOT[0].  */
5182           got_displacement = (sgot->output_section->vma
5183                               + sgot->output_offset
5184                               - splt->output_section->vma
5185                               - splt->output_offset
5186                               - 16);
5187
5188           bfd_put_32 (output_bfd, elf32_arm_plt0_entry[0], splt->contents +  0);
5189           bfd_put_32 (output_bfd, elf32_arm_plt0_entry[1], splt->contents +  4);
5190           bfd_put_32 (output_bfd, elf32_arm_plt0_entry[2], splt->contents +  8);
5191           bfd_put_32 (output_bfd, elf32_arm_plt0_entry[3], splt->contents + 12);
5192 #ifdef FOUR_WORD_PLT
5193           /* The displacement value goes in the otherwise-unused last word of
5194              the second entry.  */
5195           bfd_put_32 (output_bfd, got_displacement,        splt->contents + 28);
5196 #else
5197           bfd_put_32 (output_bfd, got_displacement,        splt->contents + 16);
5198 #endif
5199         }
5200
5201       /* UnixWare sets the entsize of .plt to 4, although that doesn't
5202          really seem like the right value.  */
5203       elf_section_data (splt->output_section)->this_hdr.sh_entsize = 4;
5204     }
5205
5206   /* Fill in the first three entries in the global offset table.  */
5207   if (sgot)
5208     {
5209       if (sgot->size > 0)
5210         {
5211           if (sdyn == NULL)
5212             bfd_put_32 (output_bfd, (bfd_vma) 0, sgot->contents);
5213           else
5214             bfd_put_32 (output_bfd,
5215                         sdyn->output_section->vma + sdyn->output_offset,
5216                         sgot->contents);
5217           bfd_put_32 (output_bfd, (bfd_vma) 0, sgot->contents + 4);
5218           bfd_put_32 (output_bfd, (bfd_vma) 0, sgot->contents + 8);
5219         }
5220
5221       elf_section_data (sgot->output_section)->this_hdr.sh_entsize = 4;
5222     }
5223
5224   return TRUE;
5225 }
5226
5227 static void
5228 elf32_arm_post_process_headers (bfd * abfd, struct bfd_link_info * link_info ATTRIBUTE_UNUSED)
5229 {
5230   Elf_Internal_Ehdr * i_ehdrp;  /* ELF file header, internal form.  */
5231   struct elf32_arm_link_hash_table *globals;
5232
5233   i_ehdrp = elf_elfheader (abfd);
5234
5235   i_ehdrp->e_ident[EI_OSABI]      = ARM_ELF_OS_ABI_VERSION;
5236   i_ehdrp->e_ident[EI_ABIVERSION] = ARM_ELF_ABI_VERSION;
5237
5238   if (link_info)
5239     {
5240       globals = elf32_arm_hash_table (link_info);
5241       if (globals->byteswap_code)
5242         i_ehdrp->e_flags |= EF_ARM_BE8;
5243     }
5244 }
5245
5246 static enum elf_reloc_type_class
5247 elf32_arm_reloc_type_class (const Elf_Internal_Rela *rela)
5248 {
5249   switch ((int) ELF32_R_TYPE (rela->r_info))
5250     {
5251     case R_ARM_RELATIVE:
5252       return reloc_class_relative;
5253     case R_ARM_JUMP_SLOT:
5254       return reloc_class_plt;
5255     case R_ARM_COPY:
5256       return reloc_class_copy;
5257     default:
5258       return reloc_class_normal;
5259     }
5260 }
5261
5262 /* Set the right machine number for an Arm ELF file.  */
5263
5264 static bfd_boolean
5265 elf32_arm_section_flags (flagword *flags, const Elf_Internal_Shdr *hdr)
5266 {
5267   if (hdr->sh_type == SHT_NOTE)
5268     *flags |= SEC_LINK_ONCE | SEC_LINK_DUPLICATES_SAME_CONTENTS;
5269
5270   return TRUE;
5271 }
5272
5273 static void
5274 elf32_arm_final_write_processing (bfd *abfd, bfd_boolean linker ATTRIBUTE_UNUSED)
5275 {
5276   bfd_arm_update_notes (abfd, ARM_NOTE_SECTION);
5277 }
5278
5279 /* Return TRUE if this is an unwinding table entry.  */
5280
5281 static bfd_boolean
5282 is_arm_elf_unwind_section_name (bfd * abfd ATTRIBUTE_UNUSED, const char * name)
5283 {
5284   size_t len1, len2;
5285
5286   len1 = sizeof (ELF_STRING_ARM_unwind) - 1;
5287   len2 = sizeof (ELF_STRING_ARM_unwind_once) - 1;
5288   return (strncmp (name, ELF_STRING_ARM_unwind, len1) == 0
5289           || strncmp (name, ELF_STRING_ARM_unwind_once, len2) == 0);
5290 }
5291
5292
5293 /* Set the type and flags for an ARM section.  We do this by
5294    the section name, which is a hack, but ought to work.  */
5295
5296 static bfd_boolean
5297 elf32_arm_fake_sections (bfd * abfd, Elf_Internal_Shdr * hdr, asection * sec)
5298 {
5299   const char * name;
5300
5301   name = bfd_get_section_name (abfd, sec);
5302
5303   if (is_arm_elf_unwind_section_name (abfd, name))
5304     {
5305       hdr->sh_type = SHT_ARM_EXIDX;
5306       hdr->sh_flags |= SHF_LINK_ORDER;
5307     }
5308   return TRUE;
5309 }
5310
5311 /* Handle an ARM specific section when reading an object file.
5312    This is called when elf.c finds a section with an unknown type.  */
5313
5314 static bfd_boolean
5315 elf32_arm_section_from_shdr (bfd *abfd,
5316                              Elf_Internal_Shdr * hdr,
5317                              const char *name)
5318 {
5319   /* There ought to be a place to keep ELF backend specific flags, but
5320      at the moment there isn't one.  We just keep track of the
5321      sections by their name, instead.  Fortunately, the ABI gives
5322      names for all the ARM specific sections, so we will probably get
5323      away with this.  */
5324   switch (hdr->sh_type)
5325     {
5326     case SHT_ARM_EXIDX:
5327       break;
5328
5329     default:
5330       return FALSE;
5331     }
5332
5333   if (! _bfd_elf_make_section_from_shdr (abfd, hdr, name))
5334     return FALSE;
5335
5336   return TRUE;
5337 }
5338
5339 /* Called for each symbol.  Builds a section map based on mapping symbols.
5340    Does not alter any of the symbols.  */
5341
5342 static bfd_boolean
5343 elf32_arm_output_symbol_hook (struct bfd_link_info *info,
5344                               const char *name,
5345                               Elf_Internal_Sym *elfsym,
5346                               asection *input_sec,
5347                               struct elf_link_hash_entry *h ATTRIBUTE_UNUSED)
5348 {
5349   int mapcount;
5350   elf32_arm_section_map *map;
5351   struct elf32_arm_link_hash_table *globals;
5352
5353   /* Only do this on final link.  */
5354   if (info->relocatable)
5355     return TRUE;
5356
5357   /* Only build a map if we need to byteswap code.  */
5358   globals = elf32_arm_hash_table (info);
5359   if (!globals->byteswap_code)
5360     return TRUE;
5361
5362   /* We only want mapping symbols.  */
5363   if (! is_arm_mapping_symbol_name (name))
5364     return TRUE;
5365
5366   mapcount = ++(elf32_arm_section_data (input_sec)->mapcount);
5367   map = elf32_arm_section_data (input_sec)->map;
5368   /* TODO: This may be inefficient, but we probably don't usually have many
5369      mapping symbols per section.  */
5370   map = bfd_realloc (map, mapcount * sizeof (elf32_arm_section_map));
5371   elf32_arm_section_data (input_sec)->map = map;
5372
5373   map[mapcount - 1].vma = elfsym->st_value;
5374   map[mapcount - 1].type = name[1];
5375   return TRUE;
5376 }
5377
5378
5379 /* Allocate target specific section data.  */
5380
5381 static bfd_boolean
5382 elf32_arm_new_section_hook (bfd *abfd, asection *sec)
5383 {
5384   struct _arm_elf_section_data *sdata;
5385   bfd_size_type amt = sizeof (*sdata);
5386
5387   sdata = bfd_zalloc (abfd, amt);
5388   if (sdata == NULL)
5389     return FALSE;
5390   sec->used_by_bfd = sdata;
5391
5392   return _bfd_elf_new_section_hook (abfd, sec);
5393 }
5394
5395
5396 /* Used to order a list of mapping symbols by address.  */
5397
5398 static int
5399 elf32_arm_compare_mapping (const void * a, const void * b)
5400 {
5401   return ((const elf32_arm_section_map *) a)->vma
5402          > ((const elf32_arm_section_map *) b)->vma;
5403 }
5404
5405
5406 /* Do code byteswapping.  Return FALSE afterwards so that the section is
5407    written out as normal.  */
5408
5409 static bfd_boolean
5410 elf32_arm_write_section (bfd *output_bfd ATTRIBUTE_UNUSED, asection *sec,
5411                          bfd_byte *contents)
5412 {
5413   int mapcount;
5414   elf32_arm_section_map *map;
5415   bfd_vma ptr;
5416   bfd_vma end;
5417   bfd_vma offset;
5418   bfd_byte tmp;
5419   int i;
5420
5421   mapcount = elf32_arm_section_data (sec)->mapcount;
5422   map = elf32_arm_section_data (sec)->map;
5423
5424   if (mapcount == 0)
5425     return FALSE;
5426
5427   qsort (map, mapcount, sizeof (elf32_arm_section_map),
5428          elf32_arm_compare_mapping);
5429
5430   offset = sec->output_section->vma + sec->output_offset;
5431   ptr = map[0].vma - offset;
5432   for (i = 0; i < mapcount; i++)
5433     {
5434       if (i == mapcount - 1)
5435         end = sec->size;
5436       else
5437         end = map[i + 1].vma - offset;
5438
5439       switch (map[i].type)
5440         {
5441         case 'a':
5442           /* Byte swap code words.  */
5443           while (ptr + 3 < end)
5444             {
5445               tmp = contents[ptr];
5446               contents[ptr] = contents[ptr + 3];
5447               contents[ptr + 3] = tmp;
5448               tmp = contents[ptr + 1];
5449               contents[ptr + 1] = contents[ptr + 2];
5450               contents[ptr + 2] = tmp;
5451               ptr += 4;
5452             }
5453           break;
5454
5455         case 't':
5456           /* Byte swap code halfwords.  */
5457           while (ptr + 1 < end)
5458             {
5459               tmp = contents[ptr];
5460               contents[ptr] = contents[ptr + 1];
5461               contents[ptr + 1] = tmp;
5462               ptr += 2;
5463             }
5464           break;
5465
5466         case 'd':
5467           /* Leave data alone.  */
5468           break;
5469         }
5470       ptr = end;
5471     }
5472   free (map);
5473   return FALSE;
5474 }
5475
5476 #define ELF_ARCH                        bfd_arch_arm
5477 #define ELF_MACHINE_CODE                EM_ARM
5478 #ifdef __QNXTARGET__
5479 #define ELF_MAXPAGESIZE                 0x1000
5480 #else
5481 #define ELF_MAXPAGESIZE                 0x8000
5482 #endif
5483
5484 #define bfd_elf32_bfd_copy_private_bfd_data     elf32_arm_copy_private_bfd_data
5485 #define bfd_elf32_bfd_merge_private_bfd_data    elf32_arm_merge_private_bfd_data
5486 #define bfd_elf32_bfd_set_private_flags         elf32_arm_set_private_flags
5487 #define bfd_elf32_bfd_print_private_bfd_data    elf32_arm_print_private_bfd_data
5488 #define bfd_elf32_bfd_link_hash_table_create    elf32_arm_link_hash_table_create
5489 #define bfd_elf32_bfd_reloc_type_lookup         elf32_arm_reloc_type_lookup
5490 #define bfd_elf32_find_nearest_line             elf32_arm_find_nearest_line
5491 #define bfd_elf32_new_section_hook              elf32_arm_new_section_hook
5492 #define bfd_elf32_bfd_is_target_special_symbol  elf32_arm_is_target_special_symbol
5493
5494 #define elf_backend_get_symbol_type             elf32_arm_get_symbol_type
5495 #define elf_backend_gc_mark_hook                elf32_arm_gc_mark_hook
5496 #define elf_backend_gc_sweep_hook               elf32_arm_gc_sweep_hook
5497 #define elf_backend_check_relocs                elf32_arm_check_relocs
5498 #define elf_backend_relocate_section            elf32_arm_relocate_section
5499 #define elf_backend_write_section               elf32_arm_write_section
5500 #define elf_backend_adjust_dynamic_symbol       elf32_arm_adjust_dynamic_symbol
5501 #define elf_backend_create_dynamic_sections     elf32_arm_create_dynamic_sections
5502 #define elf_backend_finish_dynamic_symbol       elf32_arm_finish_dynamic_symbol
5503 #define elf_backend_finish_dynamic_sections     elf32_arm_finish_dynamic_sections
5504 #define elf_backend_link_output_symbol_hook     elf32_arm_output_symbol_hook
5505 #define elf_backend_size_dynamic_sections       elf32_arm_size_dynamic_sections
5506 #define elf_backend_post_process_headers        elf32_arm_post_process_headers
5507 #define elf_backend_reloc_type_class            elf32_arm_reloc_type_class
5508 #define elf_backend_object_p                    elf32_arm_object_p
5509 #define elf_backend_section_flags               elf32_arm_section_flags
5510 #define elf_backend_fake_sections               elf32_arm_fake_sections
5511 #define elf_backend_section_from_shdr           elf32_arm_section_from_shdr
5512 #define elf_backend_final_write_processing      elf32_arm_final_write_processing
5513 #define elf_backend_copy_indirect_symbol        elf32_arm_copy_indirect_symbol
5514
5515 #define elf_backend_can_refcount    1
5516 #define elf_backend_can_gc_sections 1
5517 #define elf_backend_plt_readonly    1
5518 #define elf_backend_want_got_plt    1
5519 #define elf_backend_want_plt_sym    0
5520 #if !USE_REL
5521 #define elf_backend_rela_normal     1
5522 #endif
5523
5524 #define elf_backend_got_header_size     12
5525
5526 #include "elf32-target.h"
5527
5528 /* Symbian OS Targets */
5529
5530 #undef TARGET_LITTLE_SYM
5531 #define TARGET_LITTLE_SYM               bfd_elf32_littlearm_symbian_vec
5532 #undef TARGET_LITTLE_NAME
5533 #define TARGET_LITTLE_NAME              "elf32-littlearm-symbian"
5534 #undef TARGET_BIG_SYM
5535 #define TARGET_BIG_SYM                  bfd_elf32_bigarm_symbian_vec
5536 #undef TARGET_BIG_NAME
5537 #define TARGET_BIG_NAME                 "elf32-bigarm-symbian"
5538
5539 /* Like elf32_arm_link_hash_table_create -- but overrides
5540    appropriately for Symbian OS.  */
5541 static struct bfd_link_hash_table *
5542 elf32_arm_symbian_link_hash_table_create (bfd *abfd)
5543 {
5544   struct bfd_link_hash_table *ret;
5545
5546   ret = elf32_arm_link_hash_table_create (abfd);
5547   if (ret)
5548     {
5549       struct elf32_arm_link_hash_table *htab
5550         = (struct elf32_arm_link_hash_table *)ret;
5551       /* There is no PLT header for Symbian OS.  */
5552       htab->plt_header_size = 0;
5553       /* The PLT entries are each three instructions.  */
5554       htab->plt_entry_size = 4 * NUM_ELEM (elf32_arm_symbian_plt_entry);
5555       htab->symbian_p = 1;
5556     }
5557   return ret;
5558 }     
5559
5560 /* In a BPABI executable, the dynamic linking sections do not go in
5561    the loadable read-only segment.  The post-linker may wish to refer
5562    to these sections, but they are not part of the final program
5563    image.  */
5564 static struct bfd_elf_special_section const 
5565   elf32_arm_symbian_special_sections[]=
5566 {
5567   { ".dynamic",        8,  0, SHT_DYNAMIC,  0 },
5568   { ".dynstr",         7,  0, SHT_STRTAB,   0 },
5569   { ".dynsym",         7,  0, SHT_DYNSYM,   0 },
5570   { ".got",            4,  0, SHT_PROGBITS, 0 },
5571   { ".hash",           5,  0, SHT_HASH,     0 },
5572   { NULL,              0,  0, 0,            0 }
5573 };
5574
5575 static bfd_boolean
5576 elf32_arm_symbian_modify_segment_map
5577   PARAMS ((bfd *, struct bfd_link_info *));
5578 static void
5579 elf32_arm_symbian_begin_write_processing
5580   PARAMS ((bfd *, bfd_boolean));
5581
5582 static void
5583 elf32_arm_symbian_begin_write_processing (abfd, linker)
5584      bfd *abfd;
5585      bfd_boolean linker;
5586 {
5587   /* BPABI objects are never loaded directly by an OS kernel; they are
5588      processed by a postlinker first, into an OS-specific format.  If
5589      the D_PAGED bit is set on the file, BFD will align segments on
5590      page boundaries, so that an OS can directly map the file.  With
5591      BPABI objects, that just results in wasted space.  In addition,
5592      because we clear the D_PAGED bit, map_sections_to_segments will
5593      recognize that the program headers should not be mapped into any
5594      loadable segment.  */
5595   abfd->flags &= ~D_PAGED;
5596 }
5597
5598 static bfd_boolean
5599 elf32_arm_symbian_modify_segment_map (abfd, info)
5600      bfd *abfd;
5601      struct bfd_link_info *info ATTRIBUTE_UNUSED;
5602 {
5603   struct elf_segment_map *m;
5604   asection *dynsec;
5605
5606   /* BPABI shared libraries and executables should have a PT_DYNAMIC
5607      segment.  However, because the .dynamic section is not marked
5608      with SEC_LOAD, the generic ELF code will not create such a
5609      segment.  */
5610   dynsec = bfd_get_section_by_name (abfd, ".dynamic");
5611   if (dynsec)
5612     {
5613       m = _bfd_elf_make_dynamic_segment (abfd, dynsec);
5614       m->next = elf_tdata (abfd)->segment_map;
5615       elf_tdata (abfd)->segment_map = m;
5616     }
5617
5618   return TRUE;
5619 }
5620
5621 #undef elf32_bed
5622 #define elf32_bed elf32_arm_symbian_bed
5623
5624 /* The dynamic sections are not allocated on SymbianOS; the postlinker
5625    will process them and then discard them.  */
5626 #undef ELF_DYNAMIC_SEC_FLAGS
5627 #define ELF_DYNAMIC_SEC_FLAGS \
5628   (SEC_HAS_CONTENTS | SEC_IN_MEMORY | SEC_LINKER_CREATED)
5629
5630 #undef bfd_elf32_bfd_link_hash_table_create
5631 #define bfd_elf32_bfd_link_hash_table_create \
5632   elf32_arm_symbian_link_hash_table_create
5633
5634 #undef elf_backend_special_sections
5635 #define elf_backend_special_sections elf32_arm_symbian_special_sections
5636
5637 #undef elf_backend_begin_write_processing
5638 #define elf_backend_begin_write_processing \
5639     elf32_arm_symbian_begin_write_processing
5640
5641 #undef elf_backend_modify_segment_map
5642 #define elf_backend_modify_segment_map elf32_arm_symbian_modify_segment_map
5643
5644 /* There is no .got section for BPABI objects, and hence no header.  */
5645 #undef elf_backend_got_header_size
5646 #define elf_backend_got_header_size 0
5647
5648 /* Similarly, there is no .got.plt section.  */
5649 #undef elf_backend_want_got_plt
5650 #define elf_backend_want_got_plt 0
5651
5652 #include "elf32-target.h"
5653