* elf32-arm.c (elf32_arm_relocate_section): Use
[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           && h != NULL
2293           && splt != NULL
2294           && h->plt.offset != (bfd_vma) -1)
2295         {
2296           /* If we've created a .plt section, and assigned a PLT entry to
2297              this function, it should not be known to bind locally.  If
2298              it were, we would have cleared the PLT entry.  */
2299           BFD_ASSERT (!SYMBOL_CALLS_LOCAL (info, h));
2300
2301           value = (splt->output_section->vma
2302                    + splt->output_offset
2303                    + h->plt.offset);
2304           return _bfd_final_link_relocate (howto, input_bfd, input_section,
2305                                            contents, rel->r_offset, value,
2306                                            (bfd_vma) 0);
2307         }
2308
2309       /* When generating a shared object, these relocations are copied
2310          into the output file to be resolved at run time.  */
2311       if (info->shared
2312           && (input_section->flags & SEC_ALLOC)
2313           && (r_type != R_ARM_REL32
2314               || !SYMBOL_CALLS_LOCAL (info, h))
2315           && (h == NULL
2316               || ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
2317               || h->root.type != bfd_link_hash_undefweak)
2318           && r_type != R_ARM_PC24
2319 #ifndef OLD_ARM_ABI
2320           && r_type != R_ARM_CALL
2321           && r_type != R_ARM_JUMP24
2322           && r_type != R_ARM_PREL31
2323 #endif
2324           && r_type != R_ARM_PLT32)
2325         {
2326           Elf_Internal_Rela outrel;
2327           bfd_byte *loc;
2328           bfd_boolean skip, relocate;
2329
2330           if (sreloc == NULL)
2331             {
2332               const char * name;
2333
2334               name = (bfd_elf_string_from_elf_section
2335                       (input_bfd,
2336                        elf_elfheader (input_bfd)->e_shstrndx,
2337                        elf_section_data (input_section)->rel_hdr.sh_name));
2338               if (name == NULL)
2339                 return bfd_reloc_notsupported;
2340
2341               BFD_ASSERT (strncmp (name, ".rel", 4) == 0
2342                           && strcmp (bfd_get_section_name (input_bfd,
2343                                                            input_section),
2344                                      name + 4) == 0);
2345
2346               sreloc = bfd_get_section_by_name (dynobj, name);
2347               BFD_ASSERT (sreloc != NULL);
2348             }
2349
2350           skip = FALSE;
2351           relocate = FALSE;
2352
2353           outrel.r_offset =
2354             _bfd_elf_section_offset (output_bfd, info, input_section,
2355                                      rel->r_offset);
2356           if (outrel.r_offset == (bfd_vma) -1)
2357             skip = TRUE;
2358           else if (outrel.r_offset == (bfd_vma) -2)
2359             skip = TRUE, relocate = TRUE;
2360           outrel.r_offset += (input_section->output_section->vma
2361                               + input_section->output_offset);
2362
2363           if (skip)
2364             memset (&outrel, 0, sizeof outrel);
2365           else if (h != NULL
2366                    && h->dynindx != -1
2367                    && (!info->shared
2368                        || !info->symbolic
2369                        || !h->def_regular))
2370             outrel.r_info = ELF32_R_INFO (h->dynindx, r_type);
2371           else
2372             {
2373               int symbol;
2374
2375               /* This symbol is local, or marked to become local.  */
2376               relocate = TRUE;
2377               if (globals->symbian_p)
2378                 {
2379                   /* On Symbian OS, the data segment and text segement
2380                      can be relocated independently.  Therefore, we
2381                      must indicate the segment to which this
2382                      relocation is relative.  The BPABI allows us to
2383                      use any symbol in the right segment; we just use
2384                      the section symbol as it is convenient.  (We
2385                      cannot use the symbol given by "h" directly as it
2386                      will not appear in the dynamic symbol table.)  */
2387                   symbol = elf_section_data (sym_sec->output_section)->dynindx;
2388                   BFD_ASSERT (symbol != 0);
2389                 }
2390               else
2391                 /* On SVR4-ish systems, the dynamic loader cannot
2392                    relocate the text and data segments independently,
2393                    so the symbol does not matter.  */
2394                 symbol = 0;
2395               outrel.r_info = ELF32_R_INFO (symbol, R_ARM_RELATIVE);
2396             }
2397
2398           loc = sreloc->contents;
2399           loc += sreloc->reloc_count++ * sizeof (Elf32_External_Rel);
2400           bfd_elf32_swap_reloc_out (output_bfd, &outrel, loc);
2401
2402           /* If this reloc is against an external symbol, we do not want to
2403              fiddle with the addend.  Otherwise, we need to include the symbol
2404              value so that it becomes an addend for the dynamic reloc.  */
2405           if (! relocate)
2406             return bfd_reloc_ok;
2407
2408           return _bfd_final_link_relocate (howto, input_bfd, input_section,
2409                                            contents, rel->r_offset, value,
2410                                            (bfd_vma) 0);
2411         }
2412       else switch (r_type)
2413         {
2414 #ifndef OLD_ARM_ABI
2415         case R_ARM_XPC25:         /* Arm BLX instruction.  */
2416         case R_ARM_CALL:
2417         case R_ARM_JUMP24:
2418 #endif
2419         case R_ARM_PC24:          /* Arm B/BL instruction */
2420         case R_ARM_PLT32:
2421 #ifndef OLD_ARM_ABI
2422           if (r_type == R_ARM_XPC25)
2423             {
2424               /* Check for Arm calling Arm function.  */
2425               /* FIXME: Should we translate the instruction into a BL
2426                  instruction instead ?  */
2427               if (sym_flags != STT_ARM_TFUNC)
2428                 (*_bfd_error_handler)
2429                   (_("\%B: Warning: Arm BLX instruction targets Arm function '%s'."),
2430                    input_bfd,
2431                    h ? h->root.root.string : "(local)");
2432             }
2433           else
2434 #endif
2435             {
2436               /* Check for Arm calling Thumb function.  */
2437               if (sym_flags == STT_ARM_TFUNC)
2438                 {
2439                   elf32_arm_to_thumb_stub (info, sym_name, input_bfd,
2440                                            output_bfd, input_section,
2441                                            hit_data, sym_sec, rel->r_offset,
2442                                            signed_addend, value);
2443                   return bfd_reloc_ok;
2444                 }
2445             }
2446
2447           if (   strcmp (bfd_get_target (input_bfd), "elf32-littlearm-oabi") == 0
2448               || strcmp (bfd_get_target (input_bfd), "elf32-bigarm-oabi") == 0)
2449             {
2450               /* The old way of doing things.  Trearing the addend as a
2451                  byte sized field and adding in the pipeline offset.  */
2452               value -= (input_section->output_section->vma
2453                         + input_section->output_offset);
2454               value -= rel->r_offset;
2455               value += addend;
2456
2457               if (! globals->no_pipeline_knowledge)
2458                 value -= 8;
2459             }
2460           else
2461             {
2462               /* The ARM ELF ABI says that this reloc is computed as: S - P + A
2463                  where:
2464                   S is the address of the symbol in the relocation.
2465                   P is address of the instruction being relocated.
2466                   A is the addend (extracted from the instruction) in bytes.
2467
2468                  S is held in 'value'.
2469                  P is the base address of the section containing the
2470                    instruction plus the offset of the reloc into that
2471                    section, ie:
2472                      (input_section->output_section->vma +
2473                       input_section->output_offset +
2474                       rel->r_offset).
2475                  A is the addend, converted into bytes, ie:
2476                      (signed_addend * 4)
2477
2478                  Note: None of these operations have knowledge of the pipeline
2479                  size of the processor, thus it is up to the assembler to
2480                  encode this information into the addend.  */
2481               value -= (input_section->output_section->vma
2482                         + input_section->output_offset);
2483               value -= rel->r_offset;
2484               value += (signed_addend << howto->size);
2485
2486               /* Previous versions of this code also used to add in the
2487                  pipeline offset here.  This is wrong because the linker is
2488                  not supposed to know about such things, and one day it might
2489                  change.  In order to support old binaries that need the old
2490                  behaviour however, so we attempt to detect which ABI was
2491                  used to create the reloc.  */
2492               if (! globals->no_pipeline_knowledge)
2493                 {
2494                   Elf_Internal_Ehdr * i_ehdrp; /* Elf file header, internal form */
2495
2496                   i_ehdrp = elf_elfheader (input_bfd);
2497
2498                   if (i_ehdrp->e_ident[EI_OSABI] == 0)
2499                     value -= 8;
2500                 }
2501             }
2502
2503           signed_addend = value;
2504           signed_addend >>= howto->rightshift;
2505
2506           /* It is not an error for an undefined weak reference to be
2507              out of range.  Any program that branches to such a symbol
2508              is going to crash anyway, so there is no point worrying
2509              about getting the destination exactly right.  */
2510           if (! h || h->root.type != bfd_link_hash_undefweak)
2511             {
2512               /* Perform a signed range check.  */
2513               if (   signed_addend >   ((bfd_signed_vma)  (howto->dst_mask >> 1))
2514                   || signed_addend < - ((bfd_signed_vma) ((howto->dst_mask + 1) >> 1)))
2515                 return bfd_reloc_overflow;
2516             }
2517
2518 #ifndef OLD_ARM_ABI
2519           /* If necessary set the H bit in the BLX instruction.  */
2520           if (r_type == R_ARM_XPC25 && ((value & 2) == 2))
2521             value = (signed_addend & howto->dst_mask)
2522               | (bfd_get_32 (input_bfd, hit_data) & (~ howto->dst_mask))
2523               | (1 << 24);
2524           else
2525 #endif
2526             value = (signed_addend & howto->dst_mask)
2527               | (bfd_get_32 (input_bfd, hit_data) & (~ howto->dst_mask));
2528           break;
2529
2530         case R_ARM_ABS32:
2531           value += addend;
2532           if (sym_flags == STT_ARM_TFUNC)
2533             value |= 1;
2534           break;
2535
2536         case R_ARM_REL32:
2537           value -= (input_section->output_section->vma
2538                     + input_section->output_offset + rel->r_offset);
2539           value += addend;
2540           break;
2541
2542 #ifndef OLD_ARM_ABI
2543         case R_ARM_PREL31:
2544           value -= (input_section->output_section->vma
2545                     + input_section->output_offset + rel->r_offset);
2546           value += signed_addend;
2547           if (! h || h->root.type != bfd_link_hash_undefweak)
2548             {
2549               /* Check for overflow */
2550               if ((value ^ (value >> 1)) & (1 << 30))
2551                 return bfd_reloc_overflow;
2552             }
2553           value &= 0x7fffffff;
2554           value |= (bfd_get_32 (input_bfd, hit_data) & 0x80000000);
2555           if (sym_flags == STT_ARM_TFUNC)
2556             value |= 1;
2557           break;
2558 #endif
2559         }
2560
2561       bfd_put_32 (input_bfd, value, hit_data);
2562       return bfd_reloc_ok;
2563
2564     case R_ARM_ABS8:
2565       value += addend;
2566       if ((long) value > 0x7f || (long) value < -0x80)
2567         return bfd_reloc_overflow;
2568
2569       bfd_put_8 (input_bfd, value, hit_data);
2570       return bfd_reloc_ok;
2571
2572     case R_ARM_ABS16:
2573       value += addend;
2574
2575       if ((long) value > 0x7fff || (long) value < -0x8000)
2576         return bfd_reloc_overflow;
2577
2578       bfd_put_16 (input_bfd, value, hit_data);
2579       return bfd_reloc_ok;
2580
2581     case R_ARM_ABS12:
2582       /* Support ldr and str instruction for the arm */
2583       /* Also thumb b (unconditional branch).  ??? Really?  */
2584       value += addend;
2585
2586       if ((long) value > 0x7ff || (long) value < -0x800)
2587         return bfd_reloc_overflow;
2588
2589       value |= (bfd_get_32 (input_bfd, hit_data) & 0xfffff000);
2590       bfd_put_32 (input_bfd, value, hit_data);
2591       return bfd_reloc_ok;
2592
2593     case R_ARM_THM_ABS5:
2594       /* Support ldr and str instructions for the thumb.  */
2595 #if USE_REL
2596       /* Need to refetch addend.  */
2597       addend = bfd_get_16 (input_bfd, hit_data) & howto->src_mask;
2598       /* ??? Need to determine shift amount from operand size.  */
2599       addend >>= howto->rightshift;
2600 #endif
2601       value += addend;
2602
2603       /* ??? Isn't value unsigned?  */
2604       if ((long) value > 0x1f || (long) value < -0x10)
2605         return bfd_reloc_overflow;
2606
2607       /* ??? Value needs to be properly shifted into place first.  */
2608       value |= bfd_get_16 (input_bfd, hit_data) & 0xf83f;
2609       bfd_put_16 (input_bfd, value, hit_data);
2610       return bfd_reloc_ok;
2611
2612 #ifndef OLD_ARM_ABI
2613     case R_ARM_THM_XPC22:
2614 #endif
2615     case R_ARM_THM_PC22:
2616       /* Thumb BL (branch long instruction).  */
2617       {
2618         bfd_vma relocation;
2619         bfd_boolean overflow = FALSE;
2620         bfd_vma upper_insn = bfd_get_16 (input_bfd, hit_data);
2621         bfd_vma lower_insn = bfd_get_16 (input_bfd, hit_data + 2);
2622         bfd_signed_vma reloc_signed_max = ((1 << (howto->bitsize - 1)) - 1) >> howto->rightshift;
2623         bfd_signed_vma reloc_signed_min = ~ reloc_signed_max;
2624         bfd_vma check;
2625         bfd_signed_vma signed_check;
2626
2627 #if USE_REL
2628         /* Need to refetch the addend and squish the two 11 bit pieces
2629            together.  */
2630         {
2631           bfd_vma upper = upper_insn & 0x7ff;
2632           bfd_vma lower = lower_insn & 0x7ff;
2633           upper = (upper ^ 0x400) - 0x400; /* Sign extend.  */
2634           addend = (upper << 12) | (lower << 1);
2635           signed_addend = addend;
2636         }
2637 #endif
2638 #ifndef OLD_ARM_ABI
2639         if (r_type == R_ARM_THM_XPC22)
2640           {
2641             /* Check for Thumb to Thumb call.  */
2642             /* FIXME: Should we translate the instruction into a BL
2643                instruction instead ?  */
2644             if (sym_flags == STT_ARM_TFUNC)
2645               (*_bfd_error_handler)
2646                 (_("%B: Warning: Thumb BLX instruction targets thumb function '%s'."),
2647                  input_bfd,
2648                  h ? h->root.root.string : "(local)");
2649           }
2650         else
2651 #endif
2652           {
2653             /* If it is not a call to Thumb, assume call to Arm.
2654                If it is a call relative to a section name, then it is not a
2655                function call at all, but rather a long jump.  */
2656             if (sym_flags != STT_ARM_TFUNC && sym_flags != STT_SECTION)
2657               {
2658                 if (elf32_thumb_to_arm_stub
2659                     (info, sym_name, input_bfd, output_bfd, input_section,
2660                      hit_data, sym_sec, rel->r_offset, signed_addend, value))
2661                   return bfd_reloc_ok;
2662                 else
2663                   return bfd_reloc_dangerous;
2664               }
2665           }
2666
2667         relocation = value + signed_addend;
2668
2669         relocation -= (input_section->output_section->vma
2670                        + input_section->output_offset
2671                        + rel->r_offset);
2672
2673         if (! globals->no_pipeline_knowledge)
2674           {
2675             Elf_Internal_Ehdr * i_ehdrp; /* Elf file header, internal form.  */
2676
2677             i_ehdrp = elf_elfheader (input_bfd);
2678
2679             /* Previous versions of this code also used to add in the pipline
2680                offset here.  This is wrong because the linker is not supposed
2681                to know about such things, and one day it might change.  In order
2682                to support old binaries that need the old behaviour however, so
2683                we attempt to detect which ABI was used to create the reloc.  */
2684             if (   strcmp (bfd_get_target (input_bfd), "elf32-littlearm-oabi") == 0
2685                 || strcmp (bfd_get_target (input_bfd), "elf32-bigarm-oabi") == 0
2686                 || i_ehdrp->e_ident[EI_OSABI] == 0)
2687               relocation += 4;
2688           }
2689
2690         check = relocation >> howto->rightshift;
2691
2692         /* If this is a signed value, the rightshift just dropped
2693            leading 1 bits (assuming twos complement).  */
2694         if ((bfd_signed_vma) relocation >= 0)
2695           signed_check = check;
2696         else
2697           signed_check = check | ~((bfd_vma) -1 >> howto->rightshift);
2698
2699         /* Assumes two's complement.  */
2700         if (signed_check > reloc_signed_max || signed_check < reloc_signed_min)
2701           overflow = TRUE;
2702
2703 #ifndef OLD_ARM_ABI
2704         if (r_type == R_ARM_THM_XPC22
2705             && ((lower_insn & 0x1800) == 0x0800))
2706           /* For a BLX instruction, make sure that the relocation is rounded up
2707              to a word boundary.  This follows the semantics of the instruction
2708              which specifies that bit 1 of the target address will come from bit
2709              1 of the base address.  */
2710           relocation = (relocation + 2) & ~ 3;
2711 #endif
2712         /* Put RELOCATION back into the insn.  */
2713         upper_insn = (upper_insn & ~(bfd_vma) 0x7ff) | ((relocation >> 12) & 0x7ff);
2714         lower_insn = (lower_insn & ~(bfd_vma) 0x7ff) | ((relocation >> 1) & 0x7ff);
2715
2716         /* Put the relocated value back in the object file:  */
2717         bfd_put_16 (input_bfd, upper_insn, hit_data);
2718         bfd_put_16 (input_bfd, lower_insn, hit_data + 2);
2719
2720         return (overflow ? bfd_reloc_overflow : bfd_reloc_ok);
2721       }
2722       break;
2723
2724     case R_ARM_THM_PC11:
2725       /* Thumb B (branch) instruction).  */
2726       {
2727         bfd_signed_vma relocation;
2728         bfd_signed_vma reloc_signed_max = (1 << (howto->bitsize - 1)) - 1;
2729         bfd_signed_vma reloc_signed_min = ~ reloc_signed_max;
2730         bfd_signed_vma signed_check;
2731
2732 #if USE_REL
2733         /* Need to refetch addend.  */
2734         addend = bfd_get_16 (input_bfd, hit_data) & howto->src_mask;
2735         if (addend & ((howto->src_mask + 1) >> 1))
2736           {
2737             signed_addend = -1;
2738             signed_addend &= ~ howto->src_mask;
2739             signed_addend |= addend;
2740           }
2741         else
2742           signed_addend = addend;
2743         /* The value in the insn has been right shifted.  We need to
2744            undo this, so that we can perform the address calculation
2745            in terms of bytes.  */
2746         signed_addend <<= howto->rightshift;
2747 #endif
2748         relocation = value + signed_addend;
2749
2750         relocation -= (input_section->output_section->vma
2751                        + input_section->output_offset
2752                        + rel->r_offset);
2753
2754         relocation >>= howto->rightshift;
2755         signed_check = relocation;
2756         relocation &= howto->dst_mask;
2757         relocation |= (bfd_get_16 (input_bfd, hit_data) & (~ howto->dst_mask));
2758
2759         bfd_put_16 (input_bfd, relocation, hit_data);
2760
2761         /* Assumes two's complement.  */
2762         if (signed_check > reloc_signed_max || signed_check < reloc_signed_min)
2763           return bfd_reloc_overflow;
2764
2765         return bfd_reloc_ok;
2766       }
2767
2768 #ifndef OLD_ARM_ABI
2769     case R_ARM_ALU_PCREL7_0:
2770     case R_ARM_ALU_PCREL15_8:
2771     case R_ARM_ALU_PCREL23_15:
2772       {
2773         bfd_vma insn;
2774         bfd_vma relocation;
2775
2776         insn = bfd_get_32 (input_bfd, hit_data);
2777 #if USE_REL
2778         /* Extract the addend.  */
2779         addend = (insn & 0xff) << ((insn & 0xf00) >> 7);
2780         signed_addend = addend;
2781 #endif
2782         relocation = value + signed_addend;
2783
2784         relocation -= (input_section->output_section->vma
2785                        + input_section->output_offset
2786                        + rel->r_offset);
2787         insn = (insn & ~0xfff)
2788                | ((howto->bitpos << 7) & 0xf00)
2789                | ((relocation >> howto->bitpos) & 0xff);
2790         bfd_put_32 (input_bfd, value, hit_data);
2791       }
2792       return bfd_reloc_ok;
2793 #endif
2794
2795     case R_ARM_GNU_VTINHERIT:
2796     case R_ARM_GNU_VTENTRY:
2797       return bfd_reloc_ok;
2798
2799     case R_ARM_COPY:
2800       return bfd_reloc_notsupported;
2801
2802     case R_ARM_GLOB_DAT:
2803       return bfd_reloc_notsupported;
2804
2805     case R_ARM_JUMP_SLOT:
2806       return bfd_reloc_notsupported;
2807
2808     case R_ARM_RELATIVE:
2809       return bfd_reloc_notsupported;
2810
2811     case R_ARM_GOTOFF:
2812       /* Relocation is relative to the start of the
2813          global offset table.  */
2814
2815       BFD_ASSERT (sgot != NULL);
2816       if (sgot == NULL)
2817         return bfd_reloc_notsupported;
2818
2819       /* If we are addressing a Thumb function, we need to adjust the
2820          address by one, so that attempts to call the function pointer will
2821          correctly interpret it as Thumb code.  */
2822       if (sym_flags == STT_ARM_TFUNC)
2823         value += 1;
2824
2825       /* Note that sgot->output_offset is not involved in this
2826          calculation.  We always want the start of .got.  If we
2827          define _GLOBAL_OFFSET_TABLE in a different way, as is
2828          permitted by the ABI, we might have to change this
2829          calculation.  */
2830       value -= sgot->output_section->vma;
2831       return _bfd_final_link_relocate (howto, input_bfd, input_section,
2832                                        contents, rel->r_offset, value,
2833                                        (bfd_vma) 0);
2834
2835     case R_ARM_GOTPC:
2836       /* Use global offset table as symbol value.  */
2837       BFD_ASSERT (sgot != NULL);
2838
2839       if (sgot == NULL)
2840         return bfd_reloc_notsupported;
2841
2842       value = sgot->output_section->vma;
2843       return _bfd_final_link_relocate (howto, input_bfd, input_section,
2844                                        contents, rel->r_offset, value,
2845                                        (bfd_vma) 0);
2846
2847     case R_ARM_GOT32:
2848 #ifndef OLD_ARM_ABI
2849     case R_ARM_GOT_PREL:
2850 #endif
2851       /* Relocation is to the entry for this symbol in the
2852          global offset table.  */
2853       if (sgot == NULL)
2854         return bfd_reloc_notsupported;
2855
2856       if (h != NULL)
2857         {
2858           bfd_vma off;
2859           bfd_boolean dyn;
2860
2861           off = h->got.offset;
2862           BFD_ASSERT (off != (bfd_vma) -1);
2863           dyn = globals->root.dynamic_sections_created;
2864
2865           if (! WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, info->shared, h)
2866               || (info->shared
2867                   && SYMBOL_REFERENCES_LOCAL (info, h))
2868               || (ELF_ST_VISIBILITY (h->other)
2869                   && h->root.type == bfd_link_hash_undefweak))
2870             {
2871               /* This is actually a static link, or it is a -Bsymbolic link
2872                  and the symbol is defined locally.  We must initialize this
2873                  entry in the global offset table.  Since the offset must
2874                  always be a multiple of 4, we use the least significant bit
2875                  to record whether we have initialized it already.
2876
2877                  When doing a dynamic link, we create a .rel.got relocation
2878                  entry to initialize the value.  This is done in the
2879                  finish_dynamic_symbol routine.  */
2880               if ((off & 1) != 0)
2881                 off &= ~1;
2882               else
2883                 {
2884                   /* If we are addressing a Thumb function, we need to
2885                      adjust the address by one, so that attempts to
2886                      call the function pointer will correctly
2887                      interpret it as Thumb code.  */
2888                   if (sym_flags == STT_ARM_TFUNC)
2889                     value |= 1;
2890
2891                   bfd_put_32 (output_bfd, value, sgot->contents + off);
2892                   h->got.offset |= 1;
2893                 }
2894             }
2895
2896           value = sgot->output_offset + off;
2897         }
2898       else
2899         {
2900           bfd_vma off;
2901
2902           BFD_ASSERT (local_got_offsets != NULL &&
2903                       local_got_offsets[r_symndx] != (bfd_vma) -1);
2904
2905           off = local_got_offsets[r_symndx];
2906
2907           /* The offset must always be a multiple of 4.  We use the
2908              least significant bit to record whether we have already
2909              generated the necessary reloc.  */
2910           if ((off & 1) != 0)
2911             off &= ~1;
2912           else
2913             {
2914               bfd_put_32 (output_bfd, value, sgot->contents + off);
2915
2916               if (info->shared)
2917                 {
2918                   asection * srelgot;
2919                   Elf_Internal_Rela outrel;
2920                   bfd_byte *loc;
2921
2922                   srelgot = bfd_get_section_by_name (dynobj, ".rel.got");
2923                   BFD_ASSERT (srelgot != NULL);
2924
2925                   outrel.r_offset = (sgot->output_section->vma
2926                                      + sgot->output_offset
2927                                      + off);
2928                   outrel.r_info = ELF32_R_INFO (0, R_ARM_RELATIVE);
2929                   loc = srelgot->contents;
2930                   loc += srelgot->reloc_count++ * sizeof (Elf32_External_Rel);
2931                   bfd_elf32_swap_reloc_out (output_bfd, &outrel, loc);
2932                 }
2933
2934               local_got_offsets[r_symndx] |= 1;
2935             }
2936
2937           value = sgot->output_offset + off;
2938         }
2939       if (r_type != R_ARM_GOT32)
2940         value += sgot->output_section->vma;
2941
2942       return _bfd_final_link_relocate (howto, input_bfd, input_section,
2943                                        contents, rel->r_offset, value,
2944                                        (bfd_vma) 0);
2945
2946     case R_ARM_SBREL32:
2947       return bfd_reloc_notsupported;
2948
2949     case R_ARM_AMP_VCALL9:
2950       return bfd_reloc_notsupported;
2951
2952     case R_ARM_RSBREL32:
2953       return bfd_reloc_notsupported;
2954
2955     case R_ARM_THM_RPC22:
2956       return bfd_reloc_notsupported;
2957
2958     case R_ARM_RREL32:
2959       return bfd_reloc_notsupported;
2960
2961     case R_ARM_RABS32:
2962       return bfd_reloc_notsupported;
2963
2964     case R_ARM_RPC24:
2965       return bfd_reloc_notsupported;
2966
2967     case R_ARM_RBASE:
2968       return bfd_reloc_notsupported;
2969
2970     default:
2971       return bfd_reloc_notsupported;
2972     }
2973 }
2974
2975 #if USE_REL
2976 /* Add INCREMENT to the reloc (of type HOWTO) at ADDRESS.  */
2977 static void
2978 arm_add_to_rel (bfd *              abfd,
2979                 bfd_byte *         address,
2980                 reloc_howto_type * howto,
2981                 bfd_signed_vma     increment)
2982 {
2983   bfd_signed_vma addend;
2984
2985   if (howto->type == R_ARM_THM_PC22)
2986     {
2987       int upper_insn, lower_insn;
2988       int upper, lower;
2989
2990       upper_insn = bfd_get_16 (abfd, address);
2991       lower_insn = bfd_get_16 (abfd, address + 2);
2992       upper = upper_insn & 0x7ff;
2993       lower = lower_insn & 0x7ff;
2994
2995       addend = (upper << 12) | (lower << 1);
2996       addend += increment;
2997       addend >>= 1;
2998
2999       upper_insn = (upper_insn & 0xf800) | ((addend >> 11) & 0x7ff);
3000       lower_insn = (lower_insn & 0xf800) | (addend & 0x7ff);
3001
3002       bfd_put_16 (abfd, (bfd_vma) upper_insn, address);
3003       bfd_put_16 (abfd, (bfd_vma) lower_insn, address + 2);
3004     }
3005   else
3006     {
3007       bfd_vma        contents;
3008
3009       contents = bfd_get_32 (abfd, address);
3010
3011       /* Get the (signed) value from the instruction.  */
3012       addend = contents & howto->src_mask;
3013       if (addend & ((howto->src_mask + 1) >> 1))
3014         {
3015           bfd_signed_vma mask;
3016
3017           mask = -1;
3018           mask &= ~ howto->src_mask;
3019           addend |= mask;
3020         }
3021
3022       /* Add in the increment, (which is a byte value).  */
3023       switch (howto->type)
3024         {
3025         default:
3026           addend += increment;
3027           break;
3028
3029         case R_ARM_PC24:
3030 #ifndef OLD_ARM_ABI
3031         case R_ARM_CALL:
3032         case R_ARM_JUMP24:
3033 #endif
3034           addend <<= howto->size;
3035           addend += increment;
3036
3037           /* Should we check for overflow here ?  */
3038
3039           /* Drop any undesired bits.  */
3040           addend >>= howto->rightshift;
3041           break;
3042         }
3043
3044       contents = (contents & ~ howto->dst_mask) | (addend & howto->dst_mask);
3045
3046       bfd_put_32 (abfd, contents, address);
3047     }
3048 }
3049 #endif /* USE_REL */
3050
3051 /* Relocate an ARM ELF section.  */
3052 static bfd_boolean
3053 elf32_arm_relocate_section (bfd *                  output_bfd,
3054                             struct bfd_link_info * info,
3055                             bfd *                  input_bfd,
3056                             asection *             input_section,
3057                             bfd_byte *             contents,
3058                             Elf_Internal_Rela *    relocs,
3059                             Elf_Internal_Sym *     local_syms,
3060                             asection **            local_sections)
3061 {
3062   Elf_Internal_Shdr *symtab_hdr;
3063   struct elf_link_hash_entry **sym_hashes;
3064   Elf_Internal_Rela *rel;
3065   Elf_Internal_Rela *relend;
3066   const char *name;
3067   struct elf32_arm_link_hash_table * globals;
3068
3069 #if !USE_REL
3070   if (info->relocatable)
3071     return TRUE;
3072 #endif
3073
3074   globals = elf32_arm_hash_table (info);
3075   symtab_hdr = & elf_tdata (input_bfd)->symtab_hdr;
3076   sym_hashes = elf_sym_hashes (input_bfd);
3077
3078   rel = relocs;
3079   relend = relocs + input_section->reloc_count;
3080   for (; rel < relend; rel++)
3081     {
3082       int                          r_type;
3083       reloc_howto_type *           howto;
3084       unsigned long                r_symndx;
3085       Elf_Internal_Sym *           sym;
3086       asection *                   sec;
3087       struct elf_link_hash_entry * h;
3088       bfd_vma                      relocation;
3089       bfd_reloc_status_type        r;
3090       arelent                      bfd_reloc;
3091
3092       r_symndx = ELF32_R_SYM (rel->r_info);
3093       r_type   = ELF32_R_TYPE (rel->r_info);
3094       r_type   = arm_real_reloc_type (globals, r_type);
3095
3096       if (   r_type == R_ARM_GNU_VTENTRY
3097           || r_type == R_ARM_GNU_VTINHERIT)
3098         continue;
3099
3100       bfd_reloc.howto = elf32_arm_howto_from_type (r_type);
3101       howto = bfd_reloc.howto;
3102
3103 #if USE_REL
3104       if (info->relocatable)
3105         {
3106           /* This is a relocatable link.  We don't have to change
3107              anything, unless the reloc is against a section symbol,
3108              in which case we have to adjust according to where the
3109              section symbol winds up in the output section.  */
3110           if (r_symndx < symtab_hdr->sh_info)
3111             {
3112               sym = local_syms + r_symndx;
3113               if (ELF_ST_TYPE (sym->st_info) == STT_SECTION)
3114                 {
3115                   sec = local_sections[r_symndx];
3116                   arm_add_to_rel (input_bfd, contents + rel->r_offset,
3117                                   howto,
3118                                   (bfd_signed_vma) (sec->output_offset
3119                                                     + sym->st_value));
3120                 }
3121             }
3122
3123           continue;
3124         }
3125 #endif
3126
3127       /* This is a final link.  */
3128       h = NULL;
3129       sym = NULL;
3130       sec = NULL;
3131
3132       if (r_symndx < symtab_hdr->sh_info)
3133         {
3134           sym = local_syms + r_symndx;
3135           sec = local_sections[r_symndx];
3136 #if USE_REL
3137           relocation = (sec->output_section->vma
3138                         + sec->output_offset
3139                         + sym->st_value);
3140           if ((sec->flags & SEC_MERGE)
3141                    && ELF_ST_TYPE (sym->st_info) == STT_SECTION)
3142             {
3143               asection *msec;
3144               bfd_vma addend, value;
3145
3146               if (howto->rightshift)
3147                 {
3148                   (*_bfd_error_handler)
3149                     (_("%B(%A+0x%lx): %s relocation against SEC_MERGE section"),
3150                      input_bfd, input_section,
3151                      (long) rel->r_offset, howto->name);
3152                   return FALSE;
3153                 }
3154
3155               value = bfd_get_32 (input_bfd, contents + rel->r_offset);
3156
3157               /* Get the (signed) value from the instruction.  */
3158               addend = value & howto->src_mask;
3159               if (addend & ((howto->src_mask + 1) >> 1))
3160                 {
3161                   bfd_signed_vma mask;
3162
3163                   mask = -1;
3164                   mask &= ~ howto->src_mask;
3165                   addend |= mask;
3166                 }
3167               msec = sec;
3168               addend =
3169                 _bfd_elf_rel_local_sym (output_bfd, sym, &msec, addend)
3170                 - relocation;
3171               addend += msec->output_section->vma + msec->output_offset;
3172               value = (value & ~ howto->dst_mask) | (addend & howto->dst_mask);
3173               bfd_put_32 (input_bfd, value, contents + rel->r_offset);
3174             }
3175 #else
3176           relocation = _bfd_elf_rela_local_sym (output_bfd, sym, &sec, rel);
3177 #endif
3178         }
3179       else
3180         {
3181           bfd_boolean warned;
3182           bfd_boolean unresolved_reloc;
3183
3184           RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel,
3185                                    r_symndx, symtab_hdr, sym_hashes,
3186                                    h, sec, relocation,
3187                                    unresolved_reloc, warned);
3188
3189           if (unresolved_reloc || relocation != 0)
3190             {
3191               /* In these cases, we don't need the relocation value.
3192                  We check specially because in some obscure cases
3193                  sec->output_section will be NULL.  */
3194               switch (r_type)
3195                 {
3196                 case R_ARM_PC24:
3197 #ifndef OLD_ARM_ABI
3198                 case R_ARM_CALL:
3199                 case R_ARM_JUMP24:
3200                 case R_ARM_PREL31:
3201 #endif
3202                 case R_ARM_ABS32:
3203                 case R_ARM_THM_PC22:
3204                 case R_ARM_PLT32:
3205
3206                   if (info->shared
3207                       && ((!info->symbolic && h->dynindx != -1)
3208                           || !h->def_regular)
3209                       && ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
3210                       && ((input_section->flags & SEC_ALLOC) != 0
3211                           /* DWARF will emit R_ARM_ABS32 relocations in its
3212                              sections against symbols defined externally
3213                              in shared libraries.  We can't do anything
3214                              with them here.  */
3215                           || ((input_section->flags & SEC_DEBUGGING) != 0
3216                               && h->def_dynamic))
3217                       )
3218                     relocation = 0;
3219                   break;
3220
3221                 case R_ARM_GOTPC:
3222                   relocation = 0;
3223                   break;
3224
3225                 case R_ARM_GOT32:
3226 #ifndef OLD_ARM_ABI
3227                 case R_ARM_GOT_PREL:
3228 #endif
3229                   if ((WILL_CALL_FINISH_DYNAMIC_SYMBOL
3230                        (elf_hash_table (info)->dynamic_sections_created,
3231                         info->shared, h))
3232                       && (!info->shared
3233                           || (!info->symbolic && h->dynindx != -1)
3234                           || !h->def_regular))
3235                     relocation = 0;
3236                   break;
3237
3238                 default:
3239                   if (unresolved_reloc)
3240                     _bfd_error_handler
3241                       (_("%B(%A): warning: unresolvable relocation %d against symbol `%s'"),
3242                        input_bfd, input_section,
3243                        r_type,
3244                        h->root.root.string);
3245                   break;
3246                 }
3247             }
3248         }
3249
3250       if (h != NULL)
3251         name = h->root.root.string;
3252       else
3253         {
3254           name = (bfd_elf_string_from_elf_section
3255                   (input_bfd, symtab_hdr->sh_link, sym->st_name));
3256           if (name == NULL || *name == '\0')
3257             name = bfd_section_name (input_bfd, sec);
3258         }
3259
3260       r = elf32_arm_final_link_relocate (howto, input_bfd, output_bfd,
3261                                          input_section, contents, rel,
3262                                          relocation, info, sec, name,
3263                                          (h ? ELF_ST_TYPE (h->type) :
3264                                           ELF_ST_TYPE (sym->st_info)), h);
3265
3266       if (r != bfd_reloc_ok)
3267         {
3268           const char * msg = (const char *) 0;
3269
3270           switch (r)
3271             {
3272             case bfd_reloc_overflow:
3273               /* If the overflowing reloc was to an undefined symbol,
3274                  we have already printed one error message and there
3275                  is no point complaining again.  */
3276               if ((! h ||
3277                    h->root.type != bfd_link_hash_undefined)
3278                   && (!((*info->callbacks->reloc_overflow)
3279                         (info, (h ? &h->root : NULL), name, howto->name,
3280                          (bfd_vma) 0, input_bfd, input_section,
3281                          rel->r_offset))))
3282                   return FALSE;
3283               break;
3284
3285             case bfd_reloc_undefined:
3286               if (!((*info->callbacks->undefined_symbol)
3287                     (info, name, input_bfd, input_section,
3288                      rel->r_offset, TRUE)))
3289                 return FALSE;
3290               break;
3291
3292             case bfd_reloc_outofrange:
3293               msg = _("internal error: out of range error");
3294               goto common_error;
3295
3296             case bfd_reloc_notsupported:
3297               msg = _("internal error: unsupported relocation error");
3298               goto common_error;
3299
3300             case bfd_reloc_dangerous:
3301               msg = _("internal error: dangerous error");
3302               goto common_error;
3303
3304             default:
3305               msg = _("internal error: unknown error");
3306               /* fall through */
3307
3308             common_error:
3309               if (!((*info->callbacks->warning)
3310                     (info, msg, name, input_bfd, input_section,
3311                      rel->r_offset)))
3312                 return FALSE;
3313               break;
3314             }
3315         }
3316     }
3317
3318   return TRUE;
3319 }
3320
3321 /* Set the right machine number.  */
3322
3323 static bfd_boolean
3324 elf32_arm_object_p (bfd *abfd)
3325 {
3326   unsigned int mach;
3327
3328   mach = bfd_arm_get_mach_from_notes (abfd, ARM_NOTE_SECTION);
3329
3330   if (mach != bfd_mach_arm_unknown)
3331     bfd_default_set_arch_mach (abfd, bfd_arch_arm, mach);
3332
3333   else if (elf_elfheader (abfd)->e_flags & EF_ARM_MAVERICK_FLOAT)
3334     bfd_default_set_arch_mach (abfd, bfd_arch_arm, bfd_mach_arm_ep9312);
3335
3336   else
3337     bfd_default_set_arch_mach (abfd, bfd_arch_arm, mach);
3338
3339   return TRUE;
3340 }
3341
3342 /* Function to keep ARM specific flags in the ELF header.  */
3343
3344 static bfd_boolean
3345 elf32_arm_set_private_flags (bfd *abfd, flagword flags)
3346 {
3347   if (elf_flags_init (abfd)
3348       && elf_elfheader (abfd)->e_flags != flags)
3349     {
3350       if (EF_ARM_EABI_VERSION (flags) == EF_ARM_EABI_UNKNOWN)
3351         {
3352           if (flags & EF_ARM_INTERWORK)
3353             (*_bfd_error_handler)
3354               (_("Warning: Not setting interworking flag of %B since it has already been specified as non-interworking"),
3355                abfd);
3356           else
3357             _bfd_error_handler
3358               (_("Warning: Clearing the interworking flag of %B due to outside request"),
3359                abfd);
3360         }
3361     }
3362   else
3363     {
3364       elf_elfheader (abfd)->e_flags = flags;
3365       elf_flags_init (abfd) = TRUE;
3366     }
3367
3368   return TRUE;
3369 }
3370
3371 /* Copy backend specific data from one object module to another.  */
3372
3373 static bfd_boolean
3374 elf32_arm_copy_private_bfd_data (bfd *ibfd, bfd *obfd)
3375 {
3376   flagword in_flags;
3377   flagword out_flags;
3378
3379   if (   bfd_get_flavour (ibfd) != bfd_target_elf_flavour
3380       || bfd_get_flavour (obfd) != bfd_target_elf_flavour)
3381     return TRUE;
3382
3383   in_flags  = elf_elfheader (ibfd)->e_flags;
3384   out_flags = elf_elfheader (obfd)->e_flags;
3385
3386   if (elf_flags_init (obfd)
3387       && EF_ARM_EABI_VERSION (out_flags) == EF_ARM_EABI_UNKNOWN
3388       && in_flags != out_flags)
3389     {
3390       /* Cannot mix APCS26 and APCS32 code.  */
3391       if ((in_flags & EF_ARM_APCS_26) != (out_flags & EF_ARM_APCS_26))
3392         return FALSE;
3393
3394       /* Cannot mix float APCS and non-float APCS code.  */
3395       if ((in_flags & EF_ARM_APCS_FLOAT) != (out_flags & EF_ARM_APCS_FLOAT))
3396         return FALSE;
3397
3398       /* If the src and dest have different interworking flags
3399          then turn off the interworking bit.  */
3400       if ((in_flags & EF_ARM_INTERWORK) != (out_flags & EF_ARM_INTERWORK))
3401         {
3402           if (out_flags & EF_ARM_INTERWORK)
3403             _bfd_error_handler
3404               (_("Warning: Clearing the interworking flag of %B because non-interworking code in %B has been linked with it"),
3405                obfd, ibfd);
3406
3407           in_flags &= ~EF_ARM_INTERWORK;
3408         }
3409
3410       /* Likewise for PIC, though don't warn for this case.  */
3411       if ((in_flags & EF_ARM_PIC) != (out_flags & EF_ARM_PIC))
3412         in_flags &= ~EF_ARM_PIC;
3413     }
3414
3415   elf_elfheader (obfd)->e_flags = in_flags;
3416   elf_flags_init (obfd) = TRUE;
3417
3418   return TRUE;
3419 }
3420
3421 /* Merge backend specific data from an object file to the output
3422    object file when linking.  */
3423
3424 static bfd_boolean
3425 elf32_arm_merge_private_bfd_data (bfd * ibfd, bfd * obfd)
3426 {
3427   flagword out_flags;
3428   flagword in_flags;
3429   bfd_boolean flags_compatible = TRUE;
3430   asection *sec;
3431
3432   /* Check if we have the same endianess.  */
3433   if (! _bfd_generic_verify_endian_match (ibfd, obfd))
3434     return FALSE;
3435
3436   if (   bfd_get_flavour (ibfd) != bfd_target_elf_flavour
3437       || bfd_get_flavour (obfd) != bfd_target_elf_flavour)
3438     return TRUE;
3439
3440   /* The input BFD must have had its flags initialised.  */
3441   /* The following seems bogus to me -- The flags are initialized in
3442      the assembler but I don't think an elf_flags_init field is
3443      written into the object.  */
3444   /* BFD_ASSERT (elf_flags_init (ibfd)); */
3445
3446   in_flags  = elf_elfheader (ibfd)->e_flags;
3447   out_flags = elf_elfheader (obfd)->e_flags;
3448
3449   if (!elf_flags_init (obfd))
3450     {
3451       /* If the input is the default architecture and had the default
3452          flags then do not bother setting the flags for the output
3453          architecture, instead allow future merges to do this.  If no
3454          future merges ever set these flags then they will retain their
3455          uninitialised values, which surprise surprise, correspond
3456          to the default values.  */
3457       if (bfd_get_arch_info (ibfd)->the_default
3458           && elf_elfheader (ibfd)->e_flags == 0)
3459         return TRUE;
3460
3461       elf_flags_init (obfd) = TRUE;
3462       elf_elfheader (obfd)->e_flags = in_flags;
3463
3464       if (bfd_get_arch (obfd) == bfd_get_arch (ibfd)
3465           && bfd_get_arch_info (obfd)->the_default)
3466         return bfd_set_arch_mach (obfd, bfd_get_arch (ibfd), bfd_get_mach (ibfd));
3467
3468       return TRUE;
3469     }
3470
3471   /* Determine what should happen if the input ARM architecture
3472      does not match the output ARM architecture.  */
3473   if (! bfd_arm_merge_machines (ibfd, obfd))
3474     return FALSE;
3475
3476   /* Identical flags must be compatible.  */
3477   if (in_flags == out_flags)
3478     return TRUE;
3479
3480   /* Check to see if the input BFD actually contains any sections.  If
3481      not, its flags may not have been initialised either, but it
3482      cannot actually cause any incompatibility.  Do not short-circuit
3483      dynamic objects; their section list may be emptied by
3484     elf_link_add_object_symbols.
3485
3486     Also check to see if there are no code sections in the input.
3487     In this case there is no need to check for code specific flags.
3488     XXX - do we need to worry about floating-point format compatability
3489     in data sections ?  */
3490   if (!(ibfd->flags & DYNAMIC))
3491     {
3492       bfd_boolean null_input_bfd = TRUE;
3493       bfd_boolean only_data_sections = TRUE;
3494
3495       for (sec = ibfd->sections; sec != NULL; sec = sec->next)
3496         {
3497           /* Ignore synthetic glue sections.  */
3498           if (strcmp (sec->name, ".glue_7")
3499               && strcmp (sec->name, ".glue_7t"))
3500             {
3501               if ((bfd_get_section_flags (ibfd, sec)
3502                    & (SEC_LOAD | SEC_CODE | SEC_HAS_CONTENTS))
3503                   == (SEC_LOAD | SEC_CODE | SEC_HAS_CONTENTS))
3504                 only_data_sections = FALSE;
3505
3506               null_input_bfd = FALSE;
3507               break;
3508             }
3509         }
3510
3511       if (null_input_bfd || only_data_sections)
3512         return TRUE;
3513     }
3514
3515   /* Complain about various flag mismatches.  */
3516   if (EF_ARM_EABI_VERSION (in_flags) != EF_ARM_EABI_VERSION (out_flags))
3517     {
3518       _bfd_error_handler
3519         (_("ERROR: Source object %B has EABI version %d, but target %B has EABI version %d"),
3520          ibfd, obfd,
3521          (in_flags & EF_ARM_EABIMASK) >> 24,
3522          (out_flags & EF_ARM_EABIMASK) >> 24);
3523       return FALSE;
3524     }
3525
3526   /* Not sure what needs to be checked for EABI versions >= 1.  */
3527   if (EF_ARM_EABI_VERSION (in_flags) == EF_ARM_EABI_UNKNOWN)
3528     {
3529       if ((in_flags & EF_ARM_APCS_26) != (out_flags & EF_ARM_APCS_26))
3530         {
3531           _bfd_error_handler
3532             (_("ERROR: %B is compiled for APCS-%d, whereas target %B uses APCS-%d"),
3533              ibfd, obfd,
3534              in_flags & EF_ARM_APCS_26 ? 26 : 32,
3535              out_flags & EF_ARM_APCS_26 ? 26 : 32);
3536           flags_compatible = FALSE;
3537         }
3538
3539       if ((in_flags & EF_ARM_APCS_FLOAT) != (out_flags & EF_ARM_APCS_FLOAT))
3540         {
3541           if (in_flags & EF_ARM_APCS_FLOAT)
3542             _bfd_error_handler
3543               (_("ERROR: %B passes floats in float registers, whereas %B passes them in integer registers"),
3544                ibfd, obfd);
3545           else
3546             _bfd_error_handler
3547               (_("ERROR: %B passes floats in integer registers, whereas %B passes them in float registers"),
3548                ibfd, obfd);
3549
3550           flags_compatible = FALSE;
3551         }
3552
3553       if ((in_flags & EF_ARM_VFP_FLOAT) != (out_flags & EF_ARM_VFP_FLOAT))
3554         {
3555           if (in_flags & EF_ARM_VFP_FLOAT)
3556             _bfd_error_handler
3557               (_("ERROR: %B uses VFP instructions, whereas %B does not"),
3558                ibfd, obfd);
3559           else
3560             _bfd_error_handler
3561               (_("ERROR: %B uses FPA instructions, whereas %B does not"),
3562                ibfd, obfd);
3563
3564           flags_compatible = FALSE;
3565         }
3566
3567       if ((in_flags & EF_ARM_MAVERICK_FLOAT) != (out_flags & EF_ARM_MAVERICK_FLOAT))
3568         {
3569           if (in_flags & EF_ARM_MAVERICK_FLOAT)
3570             _bfd_error_handler
3571               (_("ERROR: %B uses Maverick instructions, whereas %B does not"),
3572                ibfd, obfd);
3573           else
3574             _bfd_error_handler
3575               (_("ERROR: %B does not use Maverick instructions, whereas %B does"),
3576                ibfd, obfd);
3577
3578           flags_compatible = FALSE;
3579         }
3580
3581 #ifdef EF_ARM_SOFT_FLOAT
3582       if ((in_flags & EF_ARM_SOFT_FLOAT) != (out_flags & EF_ARM_SOFT_FLOAT))
3583         {
3584           /* We can allow interworking between code that is VFP format
3585              layout, and uses either soft float or integer regs for
3586              passing floating point arguments and results.  We already
3587              know that the APCS_FLOAT flags match; similarly for VFP
3588              flags.  */
3589           if ((in_flags & EF_ARM_APCS_FLOAT) != 0
3590               || (in_flags & EF_ARM_VFP_FLOAT) == 0)
3591             {
3592               if (in_flags & EF_ARM_SOFT_FLOAT)
3593                 _bfd_error_handler
3594                   (_("ERROR: %B uses software FP, whereas %B uses hardware FP"),
3595                    ibfd, obfd);
3596               else
3597                 _bfd_error_handler
3598                   (_("ERROR: %B uses hardware FP, whereas %B uses software FP"),
3599                    ibfd, obfd);
3600
3601               flags_compatible = FALSE;
3602             }
3603         }
3604 #endif
3605
3606       /* Interworking mismatch is only a warning.  */
3607       if ((in_flags & EF_ARM_INTERWORK) != (out_flags & EF_ARM_INTERWORK))
3608         {
3609           if (in_flags & EF_ARM_INTERWORK)
3610             {
3611               _bfd_error_handler
3612                 (_("Warning: %B supports interworking, whereas %B does not"),
3613                  ibfd, obfd);
3614             }
3615           else
3616             {
3617               _bfd_error_handler
3618                 (_("Warning: %B does not support interworking, whereas %B does"),
3619                  ibfd, obfd);
3620             }
3621         }
3622     }
3623
3624   return flags_compatible;
3625 }
3626
3627 /* Display the flags field.  */
3628
3629 static bfd_boolean
3630 elf32_arm_print_private_bfd_data (bfd *abfd, void * ptr)
3631 {
3632   FILE * file = (FILE *) ptr;
3633   unsigned long flags;
3634
3635   BFD_ASSERT (abfd != NULL && ptr != NULL);
3636
3637   /* Print normal ELF private data.  */
3638   _bfd_elf_print_private_bfd_data (abfd, ptr);
3639
3640   flags = elf_elfheader (abfd)->e_flags;
3641   /* Ignore init flag - it may not be set, despite the flags field
3642      containing valid data.  */
3643
3644   /* xgettext:c-format */
3645   fprintf (file, _("private flags = %lx:"), elf_elfheader (abfd)->e_flags);
3646
3647   switch (EF_ARM_EABI_VERSION (flags))
3648     {
3649     case EF_ARM_EABI_UNKNOWN:
3650       /* The following flag bits are GNU extensions and not part of the
3651          official ARM ELF extended ABI.  Hence they are only decoded if
3652          the EABI version is not set.  */
3653       if (flags & EF_ARM_INTERWORK)
3654         fprintf (file, _(" [interworking enabled]"));
3655
3656       if (flags & EF_ARM_APCS_26)
3657         fprintf (file, " [APCS-26]");
3658       else
3659         fprintf (file, " [APCS-32]");
3660
3661       if (flags & EF_ARM_VFP_FLOAT)
3662         fprintf (file, _(" [VFP float format]"));
3663       else if (flags & EF_ARM_MAVERICK_FLOAT)
3664         fprintf (file, _(" [Maverick float format]"));
3665       else
3666         fprintf (file, _(" [FPA float format]"));
3667
3668       if (flags & EF_ARM_APCS_FLOAT)
3669         fprintf (file, _(" [floats passed in float registers]"));
3670
3671       if (flags & EF_ARM_PIC)
3672         fprintf (file, _(" [position independent]"));
3673
3674       if (flags & EF_ARM_NEW_ABI)
3675         fprintf (file, _(" [new ABI]"));
3676
3677       if (flags & EF_ARM_OLD_ABI)
3678         fprintf (file, _(" [old ABI]"));
3679
3680       if (flags & EF_ARM_SOFT_FLOAT)
3681         fprintf (file, _(" [software FP]"));
3682
3683       flags &= ~(EF_ARM_INTERWORK | EF_ARM_APCS_26 | EF_ARM_APCS_FLOAT
3684                  | EF_ARM_PIC | EF_ARM_NEW_ABI | EF_ARM_OLD_ABI
3685                  | EF_ARM_SOFT_FLOAT | EF_ARM_VFP_FLOAT
3686                  | EF_ARM_MAVERICK_FLOAT);
3687       break;
3688
3689     case EF_ARM_EABI_VER1:
3690       fprintf (file, _(" [Version1 EABI]"));
3691
3692       if (flags & EF_ARM_SYMSARESORTED)
3693         fprintf (file, _(" [sorted symbol table]"));
3694       else
3695         fprintf (file, _(" [unsorted symbol table]"));
3696
3697       flags &= ~ EF_ARM_SYMSARESORTED;
3698       break;
3699
3700     case EF_ARM_EABI_VER2:
3701       fprintf (file, _(" [Version2 EABI]"));
3702
3703       if (flags & EF_ARM_SYMSARESORTED)
3704         fprintf (file, _(" [sorted symbol table]"));
3705       else
3706         fprintf (file, _(" [unsorted symbol table]"));
3707
3708       if (flags & EF_ARM_DYNSYMSUSESEGIDX)
3709         fprintf (file, _(" [dynamic symbols use segment index]"));
3710
3711       if (flags & EF_ARM_MAPSYMSFIRST)
3712         fprintf (file, _(" [mapping symbols precede others]"));
3713
3714       flags &= ~(EF_ARM_SYMSARESORTED | EF_ARM_DYNSYMSUSESEGIDX
3715                  | EF_ARM_MAPSYMSFIRST);
3716       break;
3717
3718     case EF_ARM_EABI_VER3:
3719       fprintf (file, _(" [Version3 EABI]"));
3720       break;
3721
3722     case EF_ARM_EABI_VER4:
3723       fprintf (file, _(" [Version4 EABI]"));
3724
3725       if (flags & EF_ARM_BE8)
3726         fprintf (file, _(" [BE8]"));
3727
3728       if (flags & EF_ARM_LE8)
3729         fprintf (file, _(" [LE8]"));
3730
3731       flags &= ~(EF_ARM_LE8 | EF_ARM_BE8);
3732       break;
3733
3734     default:
3735       fprintf (file, _(" <EABI version unrecognised>"));
3736       break;
3737     }
3738
3739   flags &= ~ EF_ARM_EABIMASK;
3740
3741   if (flags & EF_ARM_RELEXEC)
3742     fprintf (file, _(" [relocatable executable]"));
3743
3744   if (flags & EF_ARM_HASENTRY)
3745     fprintf (file, _(" [has entry point]"));
3746
3747   flags &= ~ (EF_ARM_RELEXEC | EF_ARM_HASENTRY);
3748
3749   if (flags)
3750     fprintf (file, _("<Unrecognised flag bits set>"));
3751
3752   fputc ('\n', file);
3753
3754   return TRUE;
3755 }
3756
3757 static int
3758 elf32_arm_get_symbol_type (Elf_Internal_Sym * elf_sym, int type)
3759 {
3760   switch (ELF_ST_TYPE (elf_sym->st_info))
3761     {
3762     case STT_ARM_TFUNC:
3763       return ELF_ST_TYPE (elf_sym->st_info);
3764
3765     case STT_ARM_16BIT:
3766       /* If the symbol is not an object, return the STT_ARM_16BIT flag.
3767          This allows us to distinguish between data used by Thumb instructions
3768          and non-data (which is probably code) inside Thumb regions of an
3769          executable.  */
3770       if (type != STT_OBJECT)
3771         return ELF_ST_TYPE (elf_sym->st_info);
3772       break;
3773
3774     default:
3775       break;
3776     }
3777
3778   return type;
3779 }
3780
3781 static asection *
3782 elf32_arm_gc_mark_hook (asection *                   sec,
3783                         struct bfd_link_info *       info ATTRIBUTE_UNUSED,
3784                         Elf_Internal_Rela *          rel,
3785                         struct elf_link_hash_entry * h,
3786                         Elf_Internal_Sym *           sym)
3787 {
3788   if (h != NULL)
3789     {
3790       switch (ELF32_R_TYPE (rel->r_info))
3791       {
3792       case R_ARM_GNU_VTINHERIT:
3793       case R_ARM_GNU_VTENTRY:
3794         break;
3795
3796       default:
3797         switch (h->root.type)
3798           {
3799           case bfd_link_hash_defined:
3800           case bfd_link_hash_defweak:
3801             return h->root.u.def.section;
3802
3803           case bfd_link_hash_common:
3804             return h->root.u.c.p->section;
3805
3806           default:
3807             break;
3808           }
3809        }
3810      }
3811    else
3812      return bfd_section_from_elf_index (sec->owner, sym->st_shndx);
3813
3814   return NULL;
3815 }
3816
3817 /* Update the got entry reference counts for the section being removed.  */
3818
3819 static bfd_boolean
3820 elf32_arm_gc_sweep_hook (bfd *                     abfd ATTRIBUTE_UNUSED,
3821                          struct bfd_link_info *    info ATTRIBUTE_UNUSED,
3822                          asection *                sec ATTRIBUTE_UNUSED,
3823                          const Elf_Internal_Rela * relocs ATTRIBUTE_UNUSED)
3824 {
3825   Elf_Internal_Shdr *symtab_hdr;
3826   struct elf_link_hash_entry **sym_hashes;
3827   bfd_signed_vma *local_got_refcounts;
3828   const Elf_Internal_Rela *rel, *relend;
3829   unsigned long r_symndx;
3830   struct elf_link_hash_entry *h;
3831   struct elf32_arm_link_hash_table * globals;
3832
3833   globals = elf32_arm_hash_table (info);
3834
3835   elf_section_data (sec)->local_dynrel = NULL;
3836
3837   symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
3838   sym_hashes = elf_sym_hashes (abfd);
3839   local_got_refcounts = elf_local_got_refcounts (abfd);
3840
3841   relend = relocs + sec->reloc_count;
3842   for (rel = relocs; rel < relend; rel++)
3843     {
3844       int r_type;
3845
3846       r_type = ELF32_R_TYPE (rel->r_info);
3847 #ifndef OLD_ARM_ABI
3848       r_type = arm_real_reloc_type (globals, r_type);
3849 #endif
3850       switch (r_type)
3851         {
3852         case R_ARM_GOT32:
3853 #ifndef OLD_ARM_ABI
3854         case R_ARM_GOT_PREL:
3855 #endif
3856           r_symndx = ELF32_R_SYM (rel->r_info);
3857           if (r_symndx >= symtab_hdr->sh_info)
3858             {
3859               h = sym_hashes[r_symndx - symtab_hdr->sh_info];
3860               if (h->got.refcount > 0)
3861                 h->got.refcount -= 1;
3862             }
3863           else if (local_got_refcounts != NULL)
3864             {
3865               if (local_got_refcounts[r_symndx] > 0)
3866                 local_got_refcounts[r_symndx] -= 1;
3867             }
3868           break;
3869
3870         case R_ARM_ABS32:
3871         case R_ARM_REL32:
3872         case R_ARM_PC24:
3873         case R_ARM_PLT32:
3874 #ifndef OLD_ARM_ABI
3875         case R_ARM_CALL:
3876         case R_ARM_JUMP24:
3877         case R_ARM_PREL31:
3878 #endif
3879           r_symndx = ELF32_R_SYM (rel->r_info);
3880           if (r_symndx >= symtab_hdr->sh_info)
3881             {
3882               struct elf32_arm_link_hash_entry *eh;
3883               struct elf32_arm_relocs_copied **pp;
3884               struct elf32_arm_relocs_copied *p;
3885
3886               h = sym_hashes[r_symndx - symtab_hdr->sh_info];
3887
3888               if (h->plt.refcount > 0)
3889                 h->plt.refcount -= 1;
3890
3891               if (r_type == R_ARM_ABS32
3892                   || r_type == R_ARM_REL32)
3893                 {
3894                   eh = (struct elf32_arm_link_hash_entry *) h;
3895
3896                   for (pp = &eh->relocs_copied; (p = *pp) != NULL;
3897                        pp = &p->next)
3898                   if (p->section == sec)
3899                     {
3900                       p->count -= 1;
3901                       if (p->count == 0)
3902                         *pp = p->next;
3903                       break;
3904                     }
3905                 }
3906             }
3907           break;
3908
3909         default:
3910           break;
3911         }
3912     }
3913
3914   return TRUE;
3915 }
3916
3917 /* Look through the relocs for a section during the first phase.  */
3918
3919 static bfd_boolean
3920 elf32_arm_check_relocs (bfd *abfd, struct bfd_link_info *info,
3921                         asection *sec, const Elf_Internal_Rela *relocs)
3922 {
3923   Elf_Internal_Shdr *symtab_hdr;
3924   struct elf_link_hash_entry **sym_hashes;
3925   struct elf_link_hash_entry **sym_hashes_end;
3926   const Elf_Internal_Rela *rel;
3927   const Elf_Internal_Rela *rel_end;
3928   bfd *dynobj;
3929   asection *sreloc;
3930   bfd_vma *local_got_offsets;
3931   struct elf32_arm_link_hash_table *htab;
3932
3933   if (info->relocatable)
3934     return TRUE;
3935
3936   htab = elf32_arm_hash_table (info);
3937   sreloc = NULL;
3938
3939   dynobj = elf_hash_table (info)->dynobj;
3940   local_got_offsets = elf_local_got_offsets (abfd);
3941
3942   symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
3943   sym_hashes = elf_sym_hashes (abfd);
3944   sym_hashes_end = sym_hashes
3945     + symtab_hdr->sh_size / sizeof (Elf32_External_Sym);
3946
3947   if (!elf_bad_symtab (abfd))
3948     sym_hashes_end -= symtab_hdr->sh_info;
3949
3950   rel_end = relocs + sec->reloc_count;
3951   for (rel = relocs; rel < rel_end; rel++)
3952     {
3953       struct elf_link_hash_entry *h;
3954       unsigned long r_symndx;
3955       int r_type;
3956
3957       r_symndx = ELF32_R_SYM (rel->r_info);
3958       r_type = ELF32_R_TYPE (rel->r_info);
3959 #ifndef OLD_ARM_ABI
3960       r_type = arm_real_reloc_type (htab, r_type);
3961 #endif
3962       if (r_symndx < symtab_hdr->sh_info)
3963         h = NULL;
3964       else
3965         h = sym_hashes[r_symndx - symtab_hdr->sh_info];
3966
3967       switch (r_type)
3968         {
3969           case R_ARM_GOT32:
3970 #ifndef OLD_ARM_ABI
3971           case R_ARM_GOT_PREL:
3972 #endif
3973             /* This symbol requires a global offset table entry.  */
3974             if (h != NULL)
3975               {
3976                 h->got.refcount++;
3977               }
3978             else
3979               {
3980                 bfd_signed_vma *local_got_refcounts;
3981
3982                 /* This is a global offset table entry for a local symbol.  */
3983                 local_got_refcounts = elf_local_got_refcounts (abfd);
3984                 if (local_got_refcounts == NULL)
3985                   {
3986                     bfd_size_type size;
3987
3988                     size = symtab_hdr->sh_info;
3989                     size *= (sizeof (bfd_signed_vma) + sizeof (char));
3990                     local_got_refcounts = bfd_zalloc (abfd, size);
3991                     if (local_got_refcounts == NULL)
3992                       return FALSE;
3993                     elf_local_got_refcounts (abfd) = local_got_refcounts;
3994                   }
3995                 local_got_refcounts[r_symndx] += 1;
3996               }
3997             if (r_type == R_ARM_GOT32)
3998               break;
3999             /* Fall through.  */
4000
4001           case R_ARM_GOTOFF:
4002           case R_ARM_GOTPC:
4003             if (htab->sgot == NULL)
4004               {
4005                 if (htab->root.dynobj == NULL)
4006                   htab->root.dynobj = abfd;
4007                 if (!create_got_section (htab->root.dynobj, info))
4008                   return FALSE;
4009               }
4010             break;
4011
4012           case R_ARM_ABS32:
4013           case R_ARM_REL32:
4014           case R_ARM_PC24:
4015           case R_ARM_PLT32:
4016 #ifndef OLD_ARM_ABI
4017           case R_ARM_CALL:
4018           case R_ARM_JUMP24:
4019           case R_ARM_PREL31:
4020 #endif
4021             if (h != NULL)
4022               {
4023                 /* If this reloc is in a read-only section, we might
4024                    need a copy reloc.  We can't check reliably at this
4025                    stage whether the section is read-only, as input
4026                    sections have not yet been mapped to output sections.
4027                    Tentatively set the flag for now, and correct in
4028                    adjust_dynamic_symbol.  */
4029                 if (!info->shared)
4030                   h->non_got_ref = 1;
4031
4032                 /* We may need a .plt entry if the function this reloc
4033                    refers to is in a different object.  We can't tell for
4034                    sure yet, because something later might force the
4035                    symbol local.  */
4036                 if (r_type == R_ARM_PC24
4037 #ifndef OLD_ARM_ABI
4038                     || r_type == R_ARM_CALL
4039                     || r_type == R_ARM_JUMP24
4040                     || r_type == R_ARM_PREL31
4041 #endif
4042                     || r_type == R_ARM_PLT32)
4043                   h->needs_plt = 1;
4044
4045                 /* If we create a PLT entry, this relocation will reference
4046                    it, even if it's an ABS32 relocation.  */
4047                 h->plt.refcount += 1;
4048               }
4049
4050             /* If we are creating a shared library, and this is a reloc
4051                against a global symbol, or a non PC relative reloc
4052                against a local symbol, then we need to copy the reloc
4053                into the shared library.  However, if we are linking with
4054                -Bsymbolic, we do not need to copy a reloc against a
4055                global symbol which is defined in an object we are
4056                including in the link (i.e., DEF_REGULAR is set).  At
4057                this point we have not seen all the input files, so it is
4058                possible that DEF_REGULAR is not set now but will be set
4059                later (it is never cleared).  We account for that
4060                possibility below by storing information in the
4061                relocs_copied field of the hash table entry.  */
4062             if (info->shared
4063                 && (sec->flags & SEC_ALLOC) != 0
4064                 && ((r_type != R_ARM_PC24
4065                      && r_type != R_ARM_PLT32
4066 #ifndef OLD_ARM_ABI
4067                      && r_type != R_ARM_CALL
4068                      && r_type != R_ARM_JUMP24
4069                      && r_type != R_ARM_PREL31
4070 #endif
4071                      && r_type != R_ARM_REL32)
4072                     || (h != NULL
4073                         && (! info->symbolic
4074                             || !h->def_regular))))
4075               {
4076                 struct elf32_arm_relocs_copied *p, **head;
4077
4078                 /* When creating a shared object, we must copy these
4079                    reloc types into the output file.  We create a reloc
4080                    section in dynobj and make room for this reloc.  */
4081                 if (sreloc == NULL)
4082                   {
4083                     const char * name;
4084
4085                     name = (bfd_elf_string_from_elf_section
4086                             (abfd,
4087                              elf_elfheader (abfd)->e_shstrndx,
4088                              elf_section_data (sec)->rel_hdr.sh_name));
4089                     if (name == NULL)
4090                       return FALSE;
4091
4092                     BFD_ASSERT (strncmp (name, ".rel", 4) == 0
4093                                 && strcmp (bfd_get_section_name (abfd, sec),
4094                                            name + 4) == 0);
4095
4096                     sreloc = bfd_get_section_by_name (dynobj, name);
4097                     if (sreloc == NULL)
4098                       {
4099                         flagword flags;
4100
4101                         sreloc = bfd_make_section (dynobj, name);
4102                         flags = (SEC_HAS_CONTENTS | SEC_READONLY
4103                                  | SEC_IN_MEMORY | SEC_LINKER_CREATED);
4104                         if ((sec->flags & SEC_ALLOC) != 0
4105                             /* BPABI objects never have dynamic
4106                                relocations mapped.  */
4107                             && !htab->symbian_p)
4108                           flags |= SEC_ALLOC | SEC_LOAD;
4109                         if (sreloc == NULL
4110                             || ! bfd_set_section_flags (dynobj, sreloc, flags)
4111                             || ! bfd_set_section_alignment (dynobj, sreloc, 2))
4112                           return FALSE;
4113                       }
4114
4115                     elf_section_data (sec)->sreloc = sreloc;
4116                   }
4117
4118                 /* If this is a global symbol, we count the number of
4119                    relocations we need for this symbol.  */
4120                 if (h != NULL)
4121                   {
4122                     head = &((struct elf32_arm_link_hash_entry *) h)->relocs_copied;
4123                   }
4124                 else
4125                   {
4126                     /* Track dynamic relocs needed for local syms too.
4127                        We really need local syms available to do this
4128                        easily.  Oh well.  */
4129
4130                     asection *s;
4131                     s = bfd_section_from_r_symndx (abfd, &htab->sym_sec,
4132                                                    sec, r_symndx);
4133                     if (s == NULL)
4134                       return FALSE;
4135
4136                     head = ((struct elf32_arm_relocs_copied **)
4137                             &elf_section_data (s)->local_dynrel);
4138                   }
4139
4140                 p = *head;
4141                 if (p == NULL || p->section != sec)
4142                   {
4143                     bfd_size_type amt = sizeof *p;
4144
4145                     p = bfd_alloc (htab->root.dynobj, amt);
4146                     if (p == NULL)
4147                       return FALSE;
4148                     p->next = *head;
4149                     *head = p;
4150                     p->section = sec;
4151                     p->count = 0;
4152                   }
4153
4154                 if (r_type == R_ARM_ABS32
4155                     || r_type == R_ARM_REL32)
4156                   p->count += 1;
4157               }
4158             break;
4159
4160         /* This relocation describes the C++ object vtable hierarchy.
4161            Reconstruct it for later use during GC.  */
4162         case R_ARM_GNU_VTINHERIT:
4163           if (!bfd_elf_gc_record_vtinherit (abfd, sec, h, rel->r_offset))
4164             return FALSE;
4165           break;
4166
4167         /* This relocation describes which C++ vtable entries are actually
4168            used.  Record for later use during GC.  */
4169         case R_ARM_GNU_VTENTRY:
4170           if (!bfd_elf_gc_record_vtentry (abfd, sec, h, rel->r_offset))
4171             return FALSE;
4172           break;
4173         }
4174     }
4175
4176   return TRUE;
4177 }
4178
4179 static bfd_boolean
4180 is_arm_mapping_symbol_name (const char * name)
4181 {
4182   return (name != NULL)
4183     && (name[0] == '$')
4184     && ((name[1] == 'a') || (name[1] == 't') || (name[1] == 'd'))
4185     && (name[2] == 0);
4186 }
4187
4188 /* Treat mapping symbols as special target symbols.  */
4189
4190 static bfd_boolean
4191 elf32_arm_is_target_special_symbol (bfd * abfd ATTRIBUTE_UNUSED, asymbol * sym)
4192 {
4193   return is_arm_mapping_symbol_name (sym->name);
4194 }
4195
4196 /* This is a copy of elf_find_function() from elf.c except that
4197    ARM mapping symbols are ignored when looking for function names
4198    and STT_ARM_TFUNC is considered to a function type.  */
4199
4200 static bfd_boolean
4201 arm_elf_find_function (bfd *         abfd ATTRIBUTE_UNUSED,
4202                        asection *    section,
4203                        asymbol **    symbols,
4204                        bfd_vma       offset,
4205                        const char ** filename_ptr,
4206                        const char ** functionname_ptr)
4207 {
4208   const char * filename = NULL;
4209   asymbol * func = NULL;
4210   bfd_vma low_func = 0;
4211   asymbol ** p;
4212
4213   for (p = symbols; *p != NULL; p++)
4214     {
4215       elf_symbol_type *q;
4216
4217       q = (elf_symbol_type *) *p;
4218
4219       switch (ELF_ST_TYPE (q->internal_elf_sym.st_info))
4220         {
4221         default:
4222           break;
4223         case STT_FILE:
4224           filename = bfd_asymbol_name (&q->symbol);
4225           break;
4226         case STT_FUNC:
4227         case STT_ARM_TFUNC:
4228           /* Skip $a and $t symbols.  */
4229           if ((q->symbol.flags & BSF_LOCAL)
4230               && is_arm_mapping_symbol_name (q->symbol.name))
4231             continue;
4232           /* Fall through.  */
4233         case STT_NOTYPE:
4234           if (bfd_get_section (&q->symbol) == section
4235               && q->symbol.value >= low_func
4236               && q->symbol.value <= offset)
4237             {
4238               func = (asymbol *) q;
4239               low_func = q->symbol.value;
4240             }
4241           break;
4242         }
4243     }
4244
4245   if (func == NULL)
4246     return FALSE;
4247
4248   if (filename_ptr)
4249     *filename_ptr = filename;
4250   if (functionname_ptr)
4251     *functionname_ptr = bfd_asymbol_name (func);
4252
4253   return TRUE;
4254 }  
4255
4256
4257 /* Find the nearest line to a particular section and offset, for error
4258    reporting.   This code is a duplicate of the code in elf.c, except
4259    that it uses arm_elf_find_function.  */
4260
4261 static bfd_boolean
4262 elf32_arm_find_nearest_line (bfd *          abfd,
4263                              asection *     section,
4264                              asymbol **     symbols,
4265                              bfd_vma        offset,
4266                              const char **  filename_ptr,
4267                              const char **  functionname_ptr,
4268                              unsigned int * line_ptr)
4269 {
4270   bfd_boolean found = FALSE;
4271
4272   /* We skip _bfd_dwarf1_find_nearest_line since no known ARM toolchain uses it.  */
4273
4274   if (_bfd_dwarf2_find_nearest_line (abfd, section, symbols, offset,
4275                                      filename_ptr, functionname_ptr,
4276                                      line_ptr, 0,
4277                                      & elf_tdata (abfd)->dwarf2_find_line_info))
4278     {
4279       if (!*functionname_ptr)
4280         arm_elf_find_function (abfd, section, symbols, offset,
4281                                *filename_ptr ? NULL : filename_ptr,
4282                                functionname_ptr);
4283
4284       return TRUE;
4285     }
4286
4287   if (! _bfd_stab_section_find_nearest_line (abfd, symbols, section, offset,
4288                                              & found, filename_ptr,
4289                                              functionname_ptr, line_ptr,
4290                                              & elf_tdata (abfd)->line_info))
4291     return FALSE;
4292
4293   if (found && (*functionname_ptr || *line_ptr))
4294     return TRUE;
4295
4296   if (symbols == NULL)
4297     return FALSE;
4298
4299   if (! arm_elf_find_function (abfd, section, symbols, offset,
4300                                filename_ptr, functionname_ptr))
4301     return FALSE;
4302
4303   *line_ptr = 0;
4304   return TRUE;
4305 }
4306
4307 /* Adjust a symbol defined by a dynamic object and referenced by a
4308    regular object.  The current definition is in some section of the
4309    dynamic object, but we're not including those sections.  We have to
4310    change the definition to something the rest of the link can
4311    understand.  */
4312
4313 static bfd_boolean
4314 elf32_arm_adjust_dynamic_symbol (struct bfd_link_info * info,
4315                                  struct elf_link_hash_entry * h)
4316 {
4317   bfd * dynobj;
4318   asection * s;
4319   unsigned int power_of_two;
4320
4321   dynobj = elf_hash_table (info)->dynobj;
4322
4323   /* Make sure we know what is going on here.  */
4324   BFD_ASSERT (dynobj != NULL
4325               && (h->needs_plt
4326                   || h->u.weakdef != NULL
4327                   || (h->def_dynamic
4328                       && h->ref_regular
4329                       && !h->def_regular)));
4330
4331   /* If this is a function, put it in the procedure linkage table.  We
4332      will fill in the contents of the procedure linkage table later,
4333      when we know the address of the .got section.  */
4334   if (h->type == STT_FUNC
4335       || h->needs_plt)
4336     {
4337       if (h->plt.refcount <= 0
4338           || SYMBOL_CALLS_LOCAL (info, h)
4339           || (ELF_ST_VISIBILITY (h->other) != STV_DEFAULT
4340               && h->root.type == bfd_link_hash_undefweak))
4341         {
4342           /* This case can occur if we saw a PLT32 reloc in an input
4343              file, but the symbol was never referred to by a dynamic
4344              object, or if all references were garbage collected.  In
4345              such a case, we don't actually need to build a procedure
4346              linkage table, and we can just do a PC24 reloc instead.  */
4347           h->plt.offset = (bfd_vma) -1;
4348           h->needs_plt = 0;
4349         }
4350
4351       return TRUE;
4352     }
4353   else
4354     /* It's possible that we incorrectly decided a .plt reloc was
4355        needed for an R_ARM_PC24 or similar reloc to a non-function sym
4356        in check_relocs.  We can't decide accurately between function
4357        and non-function syms in check-relocs; Objects loaded later in
4358        the link may change h->type.  So fix it now.  */
4359     h->plt.offset = (bfd_vma) -1;
4360
4361   /* If this is a weak symbol, and there is a real definition, the
4362      processor independent code will have arranged for us to see the
4363      real definition first, and we can just use the same value.  */
4364   if (h->u.weakdef != NULL)
4365     {
4366       BFD_ASSERT (h->u.weakdef->root.type == bfd_link_hash_defined
4367                   || h->u.weakdef->root.type == bfd_link_hash_defweak);
4368       h->root.u.def.section = h->u.weakdef->root.u.def.section;
4369       h->root.u.def.value = h->u.weakdef->root.u.def.value;
4370       return TRUE;
4371     }
4372
4373   /* This is a reference to a symbol defined by a dynamic object which
4374      is not a function.  */
4375
4376   /* If we are creating a shared library, we must presume that the
4377      only references to the symbol are via the global offset table.
4378      For such cases we need not do anything here; the relocations will
4379      be handled correctly by relocate_section.  */
4380   if (info->shared)
4381     return TRUE;
4382
4383   /* We must allocate the symbol in our .dynbss section, which will
4384      become part of the .bss section of the executable.  There will be
4385      an entry for this symbol in the .dynsym section.  The dynamic
4386      object will contain position independent code, so all references
4387      from the dynamic object to this symbol will go through the global
4388      offset table.  The dynamic linker will use the .dynsym entry to
4389      determine the address it must put in the global offset table, so
4390      both the dynamic object and the regular object will refer to the
4391      same memory location for the variable.  */
4392   s = bfd_get_section_by_name (dynobj, ".dynbss");
4393   BFD_ASSERT (s != NULL);
4394
4395   /* We must generate a R_ARM_COPY reloc to tell the dynamic linker to
4396      copy the initial value out of the dynamic object and into the
4397      runtime process image.  We need to remember the offset into the
4398      .rel.bss section we are going to use.  */
4399   if ((h->root.u.def.section->flags & SEC_ALLOC) != 0)
4400     {
4401       asection *srel;
4402
4403       srel = bfd_get_section_by_name (dynobj, ".rel.bss");
4404       BFD_ASSERT (srel != NULL);
4405       srel->size += sizeof (Elf32_External_Rel);
4406       h->needs_copy = 1;
4407     }
4408
4409   /* We need to figure out the alignment required for this symbol.  I
4410      have no idea how ELF linkers handle this.  */
4411   power_of_two = bfd_log2 (h->size);
4412   if (power_of_two > 3)
4413     power_of_two = 3;
4414
4415   /* Apply the required alignment.  */
4416   s->size = BFD_ALIGN (s->size, (bfd_size_type) (1 << power_of_two));
4417   if (power_of_two > bfd_get_section_alignment (dynobj, s))
4418     {
4419       if (! bfd_set_section_alignment (dynobj, s, power_of_two))
4420         return FALSE;
4421     }
4422
4423   /* Define the symbol as being at this point in the section.  */
4424   h->root.u.def.section = s;
4425   h->root.u.def.value = s->size;
4426
4427   /* Increment the section size to make room for the symbol.  */
4428   s->size += h->size;
4429
4430   return TRUE;
4431 }
4432
4433 /* Allocate space in .plt, .got and associated reloc sections for
4434    dynamic relocs.  */
4435
4436 static bfd_boolean
4437 allocate_dynrelocs (struct elf_link_hash_entry *h, void * inf)
4438 {
4439   struct bfd_link_info *info;
4440   struct elf32_arm_link_hash_table *htab;
4441   struct elf32_arm_link_hash_entry *eh;
4442   struct elf32_arm_relocs_copied *p;
4443
4444   if (h->root.type == bfd_link_hash_indirect)
4445     return TRUE;
4446
4447   if (h->root.type == bfd_link_hash_warning)
4448     /* When warning symbols are created, they **replace** the "real"
4449        entry in the hash table, thus we never get to see the real
4450        symbol in a hash traversal.  So look at it now.  */
4451     h = (struct elf_link_hash_entry *) h->root.u.i.link;
4452
4453   info = (struct bfd_link_info *) inf;
4454   htab = elf32_arm_hash_table (info);
4455
4456   if (htab->root.dynamic_sections_created
4457       && h->plt.refcount > 0)
4458     {
4459       /* Make sure this symbol is output as a dynamic symbol.
4460          Undefined weak syms won't yet be marked as dynamic.  */
4461       if (h->dynindx == -1
4462           && !h->forced_local)
4463         {
4464           if (! bfd_elf_link_record_dynamic_symbol (info, h))
4465             return FALSE;
4466         }
4467
4468       if (info->shared
4469           || WILL_CALL_FINISH_DYNAMIC_SYMBOL (1, 0, h))
4470         {
4471           asection *s = htab->splt;
4472
4473           /* If this is the first .plt entry, make room for the special
4474              first entry.  */
4475           if (s->size == 0)
4476             s->size += htab->plt_header_size;
4477
4478           h->plt.offset = s->size;
4479
4480           /* If this symbol is not defined in a regular file, and we are
4481              not generating a shared library, then set the symbol to this
4482              location in the .plt.  This is required to make function
4483              pointers compare as equal between the normal executable and
4484              the shared library.  */
4485           if (! info->shared
4486               && !h->def_regular)
4487             {
4488               h->root.u.def.section = s;
4489               h->root.u.def.value = h->plt.offset;
4490             }
4491
4492           /* Make room for this entry.  */
4493           s->size += htab->plt_entry_size;
4494
4495           if (!htab->symbian_p)
4496             /* We also need to make an entry in the .got.plt section, which
4497                will be placed in the .got section by the linker script.  */
4498             htab->sgotplt->size += 4;
4499
4500           /* We also need to make an entry in the .rel.plt section.  */
4501           htab->srelplt->size += sizeof (Elf32_External_Rel);
4502         }
4503       else
4504         {
4505           h->plt.offset = (bfd_vma) -1;
4506           h->needs_plt = 0;
4507         }
4508     }
4509   else
4510     {
4511       h->plt.offset = (bfd_vma) -1;
4512       h->needs_plt = 0;
4513     }
4514
4515   if (h->got.refcount > 0)
4516     {
4517       asection *s;
4518       bfd_boolean dyn;
4519
4520       /* Make sure this symbol is output as a dynamic symbol.
4521          Undefined weak syms won't yet be marked as dynamic.  */
4522       if (h->dynindx == -1
4523           && !h->forced_local)
4524         {
4525           if (! bfd_elf_link_record_dynamic_symbol (info, h))
4526             return FALSE;
4527         }
4528
4529       if (!htab->symbian_p)
4530         {
4531           s = htab->sgot;
4532           h->got.offset = s->size;
4533           s->size += 4;
4534           dyn = htab->root.dynamic_sections_created;
4535           if ((ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
4536                || h->root.type != bfd_link_hash_undefweak)
4537               && (info->shared
4538                   || WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, 0, h)))
4539             htab->srelgot->size += sizeof (Elf32_External_Rel);
4540         }
4541     }
4542   else
4543     h->got.offset = (bfd_vma) -1;
4544
4545   eh = (struct elf32_arm_link_hash_entry *) h;
4546   if (eh->relocs_copied == NULL)
4547     return TRUE;
4548
4549   /* In the shared -Bsymbolic case, discard space allocated for
4550      dynamic pc-relative relocs against symbols which turn out to be
4551      defined in regular objects.  For the normal shared case, discard
4552      space for pc-relative relocs that have become local due to symbol
4553      visibility changes.  */
4554
4555   if (info->shared)
4556     {
4557       /* Discard relocs on undefined weak syms with non-default
4558          visibility.  */
4559       if (ELF_ST_VISIBILITY (h->other) != STV_DEFAULT
4560           && h->root.type == bfd_link_hash_undefweak)
4561         eh->relocs_copied = NULL;
4562     }
4563   else
4564     {
4565       /* For the non-shared case, discard space for relocs against
4566          symbols which turn out to need copy relocs or are not
4567          dynamic.  */
4568
4569       if (!h->non_got_ref
4570           && ((h->def_dynamic
4571                && !h->def_regular)
4572               || (htab->root.dynamic_sections_created
4573                   && (h->root.type == bfd_link_hash_undefweak
4574                       || h->root.type == bfd_link_hash_undefined))))
4575         {
4576           /* Make sure this symbol is output as a dynamic symbol.
4577              Undefined weak syms won't yet be marked as dynamic.  */
4578           if (h->dynindx == -1
4579               && !h->forced_local)
4580             {
4581               if (! bfd_elf_link_record_dynamic_symbol (info, h))
4582                 return FALSE;
4583             }
4584
4585           /* If that succeeded, we know we'll be keeping all the
4586              relocs.  */
4587           if (h->dynindx != -1)
4588             goto keep;
4589         }
4590
4591       eh->relocs_copied = NULL;
4592
4593     keep: ;
4594     }
4595
4596   /* Finally, allocate space.  */
4597   for (p = eh->relocs_copied; p != NULL; p = p->next)
4598     {
4599       asection *sreloc = elf_section_data (p->section)->sreloc;
4600       sreloc->size += p->count * sizeof (Elf32_External_Rel);
4601     }
4602
4603   return TRUE;
4604 }
4605
4606 /* Find any dynamic relocs that apply to read-only sections.  */
4607
4608 static bfd_boolean
4609 elf32_arm_readonly_dynrelocs (struct elf_link_hash_entry *h, PTR inf)
4610 {
4611   struct elf32_arm_link_hash_entry *eh;
4612   struct elf32_arm_relocs_copied *p;
4613
4614   if (h->root.type == bfd_link_hash_warning)
4615     h = (struct elf_link_hash_entry *) h->root.u.i.link;
4616
4617   eh = (struct elf32_arm_link_hash_entry *) h;
4618   for (p = eh->relocs_copied; p != NULL; p = p->next)
4619     {
4620       asection *s = p->section;
4621
4622       if (s != NULL && (s->flags & SEC_READONLY) != 0)
4623         {
4624           struct bfd_link_info *info = (struct bfd_link_info *) inf;
4625
4626           info->flags |= DF_TEXTREL;
4627
4628           /* Not an error, just cut short the traversal.  */
4629           return FALSE;
4630         }
4631     }
4632   return TRUE;
4633 }
4634
4635 /* Set the sizes of the dynamic sections.  */
4636
4637 static bfd_boolean
4638 elf32_arm_size_dynamic_sections (bfd * output_bfd ATTRIBUTE_UNUSED,
4639                                  struct bfd_link_info * info)
4640 {
4641   bfd * dynobj;
4642   asection * s;
4643   bfd_boolean plt;
4644   bfd_boolean relocs;
4645   bfd *ibfd;
4646   struct elf32_arm_link_hash_table *htab;
4647
4648   htab = elf32_arm_hash_table (info);
4649   dynobj = elf_hash_table (info)->dynobj;
4650   BFD_ASSERT (dynobj != NULL);
4651
4652   if (elf_hash_table (info)->dynamic_sections_created)
4653     {
4654       /* Set the contents of the .interp section to the interpreter.  */
4655       if (info->executable)
4656         {
4657           s = bfd_get_section_by_name (dynobj, ".interp");
4658           BFD_ASSERT (s != NULL);
4659           s->size = sizeof ELF_DYNAMIC_INTERPRETER;
4660           s->contents = (unsigned char *) ELF_DYNAMIC_INTERPRETER;
4661         }
4662     }
4663
4664   /* Set up .got offsets for local syms, and space for local dynamic
4665      relocs.  */
4666   for (ibfd = info->input_bfds; ibfd != NULL; ibfd = ibfd->link_next)
4667     {
4668       bfd_signed_vma *local_got;
4669       bfd_signed_vma *end_local_got;
4670       char *local_tls_type;
4671       bfd_size_type locsymcount;
4672       Elf_Internal_Shdr *symtab_hdr;
4673       asection *srel;
4674
4675       if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour)
4676         continue;
4677
4678       for (s = ibfd->sections; s != NULL; s = s->next)
4679         {
4680           struct elf32_arm_relocs_copied *p;
4681
4682           for (p = *((struct elf32_arm_relocs_copied **)
4683                      &elf_section_data (s)->local_dynrel);
4684                p != NULL;
4685                p = p->next)
4686             {
4687               if (!bfd_is_abs_section (p->section)
4688                   && bfd_is_abs_section (p->section->output_section))
4689                 {
4690                   /* Input section has been discarded, either because
4691                      it is a copy of a linkonce section or due to
4692                      linker script /DISCARD/, so we'll be discarding
4693                      the relocs too.  */
4694                 }
4695               else if (p->count != 0)
4696                 {
4697                   srel = elf_section_data (p->section)->sreloc;
4698                   srel->size += p->count * sizeof (Elf32_External_Rel);
4699                   if ((p->section->output_section->flags & SEC_READONLY) != 0)
4700                     info->flags |= DF_TEXTREL;
4701                 }
4702             }
4703         }
4704
4705       local_got = elf_local_got_refcounts (ibfd);
4706       if (!local_got)
4707         continue;
4708
4709       symtab_hdr = &elf_tdata (ibfd)->symtab_hdr;
4710       locsymcount = symtab_hdr->sh_info;
4711       end_local_got = local_got + locsymcount;
4712       s = htab->sgot;
4713       srel = htab->srelgot;
4714       for (; local_got < end_local_got; ++local_got, ++local_tls_type)
4715         {
4716           if (*local_got > 0)
4717             {
4718               *local_got = s->size;
4719               s->size += 4;
4720               if (info->shared)
4721                 srel->size += sizeof (Elf32_External_Rel);
4722             }
4723           else
4724             *local_got = (bfd_vma) -1;
4725         }
4726     }
4727
4728   /* Allocate global sym .plt and .got entries, and space for global
4729      sym dynamic relocs.  */
4730   elf_link_hash_traverse (& htab->root, allocate_dynrelocs, info);
4731
4732   /* The check_relocs and adjust_dynamic_symbol entry points have
4733      determined the sizes of the various dynamic sections.  Allocate
4734      memory for them.  */
4735   plt = FALSE;
4736   relocs = FALSE;
4737   for (s = dynobj->sections; s != NULL; s = s->next)
4738     {
4739       const char * name;
4740       bfd_boolean strip;
4741
4742       if ((s->flags & SEC_LINKER_CREATED) == 0)
4743         continue;
4744
4745       /* It's OK to base decisions on the section name, because none
4746          of the dynobj section names depend upon the input files.  */
4747       name = bfd_get_section_name (dynobj, s);
4748
4749       strip = FALSE;
4750
4751       if (strcmp (name, ".plt") == 0)
4752         {
4753           if (s->size == 0)
4754             {
4755               /* Strip this section if we don't need it; see the
4756                  comment below.  */
4757               strip = TRUE;
4758             }
4759           else
4760             {
4761               /* Remember whether there is a PLT.  */
4762               plt = TRUE;
4763             }
4764         }
4765       else if (strncmp (name, ".rel", 4) == 0)
4766         {
4767           if (s->size == 0)
4768             {
4769               /* If we don't need this section, strip it from the
4770                  output file.  This is mostly to handle .rel.bss and
4771                  .rel.plt.  We must create both sections in
4772                  create_dynamic_sections, because they must be created
4773                  before the linker maps input sections to output
4774                  sections.  The linker does that before
4775                  adjust_dynamic_symbol is called, and it is that
4776                  function which decides whether anything needs to go
4777                  into these sections.  */
4778               strip = TRUE;
4779             }
4780           else
4781             {
4782               /* Remember whether there are any reloc sections other
4783                  than .rel.plt.  */
4784               if (strcmp (name, ".rel.plt") != 0)
4785                 relocs = TRUE;
4786
4787               /* We use the reloc_count field as a counter if we need
4788                  to copy relocs into the output file.  */
4789               s->reloc_count = 0;
4790             }
4791         }
4792       else if (strncmp (name, ".got", 4) != 0)
4793         {
4794           /* It's not one of our sections, so don't allocate space.  */
4795           continue;
4796         }
4797
4798       if (strip)
4799         {
4800           _bfd_strip_section_from_output (info, s);
4801           continue;
4802         }
4803
4804       /* Allocate memory for the section contents.  */
4805       s->contents = (bfd_byte *) bfd_zalloc (dynobj, s->size);
4806       if (s->contents == NULL && s->size != 0)
4807         return FALSE;
4808     }
4809
4810   if (elf_hash_table (info)->dynamic_sections_created)
4811     {
4812       /* Add some entries to the .dynamic section.  We fill in the
4813          values later, in elf32_arm_finish_dynamic_sections, but we
4814          must add the entries now so that we get the correct size for
4815          the .dynamic section.  The DT_DEBUG entry is filled in by the
4816          dynamic linker and used by the debugger.  */
4817 #define add_dynamic_entry(TAG, VAL) \
4818   _bfd_elf_add_dynamic_entry (info, TAG, VAL)
4819
4820       if (!info->shared)
4821         {
4822           if (!add_dynamic_entry (DT_DEBUG, 0))
4823             return FALSE;
4824         }
4825
4826       if (plt)
4827         {
4828           if (   !add_dynamic_entry (DT_PLTGOT, 0)
4829               || !add_dynamic_entry (DT_PLTRELSZ, 0)
4830               || !add_dynamic_entry (DT_PLTREL, DT_REL)
4831               || !add_dynamic_entry (DT_JMPREL, 0))
4832             return FALSE;
4833         }
4834
4835       if (relocs)
4836         {
4837           if (   !add_dynamic_entry (DT_REL, 0)
4838               || !add_dynamic_entry (DT_RELSZ, 0)
4839               || !add_dynamic_entry (DT_RELENT, sizeof (Elf32_External_Rel)))
4840             return FALSE;
4841         }
4842
4843       /* If any dynamic relocs apply to a read-only section,
4844          then we need a DT_TEXTREL entry.  */
4845       if ((info->flags & DF_TEXTREL) == 0)
4846         elf_link_hash_traverse (&htab->root, elf32_arm_readonly_dynrelocs,
4847                                 (PTR) info);
4848
4849       if ((info->flags & DF_TEXTREL) != 0)
4850         {
4851           if (!add_dynamic_entry (DT_TEXTREL, 0))
4852             return FALSE;
4853           info->flags |= DF_TEXTREL;
4854         }
4855     }
4856 #undef add_synamic_entry
4857
4858   return TRUE;
4859 }
4860
4861 /* Finish up dynamic symbol handling.  We set the contents of various
4862    dynamic sections here.  */
4863
4864 static bfd_boolean
4865 elf32_arm_finish_dynamic_symbol (bfd * output_bfd, struct bfd_link_info * info,
4866                                  struct elf_link_hash_entry * h, Elf_Internal_Sym * sym)
4867 {
4868   bfd * dynobj;
4869   struct elf32_arm_link_hash_table *htab;
4870
4871   dynobj = elf_hash_table (info)->dynobj;
4872   htab = elf32_arm_hash_table (info);
4873
4874   if (h->plt.offset != (bfd_vma) -1)
4875     {
4876       asection * splt;
4877       asection * srel;
4878       bfd_byte *loc;
4879       bfd_vma plt_index;
4880       Elf_Internal_Rela rel;
4881
4882       /* This symbol has an entry in the procedure linkage table.  Set
4883          it up.  */
4884
4885       BFD_ASSERT (h->dynindx != -1);
4886
4887       splt = bfd_get_section_by_name (dynobj, ".plt");
4888       srel = bfd_get_section_by_name (dynobj, ".rel.plt");
4889       BFD_ASSERT (splt != NULL && srel != NULL);
4890
4891       /* Get the index in the procedure linkage table which
4892          corresponds to this symbol.  This is the index of this symbol
4893          in all the symbols for which we are making plt entries.  The
4894          first entry in the procedure linkage table is reserved.  */
4895       plt_index = ((h->plt.offset - htab->plt_header_size) 
4896                    / htab->plt_entry_size);
4897
4898       /* Fill in the entry in the procedure linkage table.  */
4899       if (htab->symbian_p)
4900         {
4901           unsigned i;
4902           for (i = 0; i < htab->plt_entry_size / 4; ++i)
4903             bfd_put_32 (output_bfd, 
4904                         elf32_arm_symbian_plt_entry[i],
4905                         splt->contents + h->plt.offset + 4 * i);
4906           
4907           /* Fill in the entry in the .rel.plt section.  */
4908           rel.r_offset = (splt->output_section->vma
4909                           + splt->output_offset
4910                           + h->plt.offset + 4 * (i - 1));
4911           rel.r_info = ELF32_R_INFO (h->dynindx, R_ARM_GLOB_DAT);
4912         }
4913       else
4914         {
4915           bfd_vma got_offset;
4916           bfd_vma got_displacement;
4917           asection * sgot;
4918           
4919           sgot = bfd_get_section_by_name (dynobj, ".got.plt");
4920           BFD_ASSERT (sgot != NULL);
4921
4922           /* Get the offset into the .got table of the entry that
4923              corresponds to this function.  Each .got entry is 4 bytes.
4924              The first three are reserved.  */
4925           got_offset = (plt_index + 3) * 4;
4926
4927           /* Calculate the displacement between the PLT slot and the
4928              entry in the GOT.  */
4929           got_displacement = (sgot->output_section->vma
4930                               + sgot->output_offset
4931                               + got_offset
4932                               - splt->output_section->vma
4933                               - splt->output_offset
4934                               - h->plt.offset
4935                               - 8);
4936
4937           BFD_ASSERT ((got_displacement & 0xf0000000) == 0);
4938
4939           bfd_put_32 (output_bfd, elf32_arm_plt_entry[0] | ((got_displacement & 0x0ff00000) >> 20),
4940                       splt->contents + h->plt.offset + 0);
4941           bfd_put_32 (output_bfd, elf32_arm_plt_entry[1] | ((got_displacement & 0x000ff000) >> 12),
4942                       splt->contents + h->plt.offset + 4);
4943           bfd_put_32 (output_bfd, elf32_arm_plt_entry[2] | (got_displacement & 0x00000fff),
4944                       splt->contents + h->plt.offset + 8);
4945 #ifdef FOUR_WORD_PLT
4946           bfd_put_32 (output_bfd, elf32_arm_plt_entry[3],
4947                       splt->contents + h->plt.offset + 12);
4948 #endif
4949
4950           /* Fill in the entry in the global offset table.  */
4951           bfd_put_32 (output_bfd,
4952                       (splt->output_section->vma
4953                        + splt->output_offset),
4954                       sgot->contents + got_offset);
4955           
4956           /* Fill in the entry in the .rel.plt section.  */
4957           rel.r_offset = (sgot->output_section->vma
4958                           + sgot->output_offset
4959                           + got_offset);
4960           rel.r_info = ELF32_R_INFO (h->dynindx, R_ARM_JUMP_SLOT);
4961         }
4962
4963       loc = srel->contents + plt_index * sizeof (Elf32_External_Rel);
4964       bfd_elf32_swap_reloc_out (output_bfd, &rel, loc);
4965
4966       if (!h->def_regular)
4967         {
4968           /* Mark the symbol as undefined, rather than as defined in
4969              the .plt section.  Leave the value alone.  */
4970           sym->st_shndx = SHN_UNDEF;
4971           /* If the symbol is weak, we do need to clear the value.
4972              Otherwise, the PLT entry would provide a definition for
4973              the symbol even if the symbol wasn't defined anywhere,
4974              and so the symbol would never be NULL.  */
4975           if (!h->ref_regular_nonweak)
4976             sym->st_value = 0;
4977         }
4978     }
4979
4980   if (h->got.offset != (bfd_vma) -1)
4981     {
4982       asection * sgot;
4983       asection * srel;
4984       Elf_Internal_Rela rel;
4985       bfd_byte *loc;
4986
4987       /* This symbol has an entry in the global offset table.  Set it
4988          up.  */
4989       sgot = bfd_get_section_by_name (dynobj, ".got");
4990       srel = bfd_get_section_by_name (dynobj, ".rel.got");
4991       BFD_ASSERT (sgot != NULL && srel != NULL);
4992
4993       rel.r_offset = (sgot->output_section->vma
4994                       + sgot->output_offset
4995                       + (h->got.offset &~ (bfd_vma) 1));
4996
4997       /* If this is a static link, or it is a -Bsymbolic link and the
4998          symbol is defined locally or was forced to be local because
4999          of a version file, we just want to emit a RELATIVE reloc.
5000          The entry in the global offset table will already have been
5001          initialized in the relocate_section function.  */
5002       if (info->shared
5003           && SYMBOL_REFERENCES_LOCAL (info, h))
5004         {
5005           BFD_ASSERT((h->got.offset & 1) != 0);
5006           rel.r_info = ELF32_R_INFO (0, R_ARM_RELATIVE);
5007         }
5008       else
5009         {
5010           BFD_ASSERT((h->got.offset & 1) == 0);
5011           bfd_put_32 (output_bfd, (bfd_vma) 0, sgot->contents + h->got.offset);
5012           rel.r_info = ELF32_R_INFO (h->dynindx, R_ARM_GLOB_DAT);
5013         }
5014
5015       loc = srel->contents + srel->reloc_count++ * sizeof (Elf32_External_Rel);
5016       bfd_elf32_swap_reloc_out (output_bfd, &rel, loc);
5017     }
5018
5019   if (h->needs_copy)
5020     {
5021       asection * s;
5022       Elf_Internal_Rela rel;
5023       bfd_byte *loc;
5024
5025       /* This symbol needs a copy reloc.  Set it up.  */
5026       BFD_ASSERT (h->dynindx != -1
5027                   && (h->root.type == bfd_link_hash_defined
5028                       || h->root.type == bfd_link_hash_defweak));
5029
5030       s = bfd_get_section_by_name (h->root.u.def.section->owner,
5031                                    ".rel.bss");
5032       BFD_ASSERT (s != NULL);
5033
5034       rel.r_offset = (h->root.u.def.value
5035                       + h->root.u.def.section->output_section->vma
5036                       + h->root.u.def.section->output_offset);
5037       rel.r_info = ELF32_R_INFO (h->dynindx, R_ARM_COPY);
5038       loc = s->contents + s->reloc_count++ * sizeof (Elf32_External_Rel);
5039       bfd_elf32_swap_reloc_out (output_bfd, &rel, loc);
5040     }
5041
5042   /* Mark _DYNAMIC and _GLOBAL_OFFSET_TABLE_ as absolute.  */
5043   if (strcmp (h->root.root.string, "_DYNAMIC") == 0
5044       || strcmp (h->root.root.string, "_GLOBAL_OFFSET_TABLE_") == 0)
5045     sym->st_shndx = SHN_ABS;
5046
5047   return TRUE;
5048 }
5049
5050 /* Finish up the dynamic sections.  */
5051
5052 static bfd_boolean
5053 elf32_arm_finish_dynamic_sections (bfd * output_bfd, struct bfd_link_info * info)
5054 {
5055   bfd * dynobj;
5056   asection * sgot;
5057   asection * sdyn;
5058
5059   dynobj = elf_hash_table (info)->dynobj;
5060
5061   sgot = bfd_get_section_by_name (dynobj, ".got.plt");
5062   BFD_ASSERT (elf32_arm_hash_table (info)->symbian_p || sgot != NULL);
5063   sdyn = bfd_get_section_by_name (dynobj, ".dynamic");
5064
5065   if (elf_hash_table (info)->dynamic_sections_created)
5066     {
5067       asection *splt;
5068       Elf32_External_Dyn *dyncon, *dynconend;
5069       struct elf32_arm_link_hash_table *htab;
5070
5071       htab = elf32_arm_hash_table (info);
5072       splt = bfd_get_section_by_name (dynobj, ".plt");
5073       BFD_ASSERT (splt != NULL && sdyn != NULL);
5074
5075       dyncon = (Elf32_External_Dyn *) sdyn->contents;
5076       dynconend = (Elf32_External_Dyn *) (sdyn->contents + sdyn->size);
5077
5078       for (; dyncon < dynconend; dyncon++)
5079         {
5080           Elf_Internal_Dyn dyn;
5081           const char * name;
5082           asection * s;
5083
5084           bfd_elf32_swap_dyn_in (dynobj, dyncon, &dyn);
5085
5086           switch (dyn.d_tag)
5087             {
5088               unsigned int type;
5089
5090             default:
5091               break;
5092
5093             case DT_HASH:
5094               name = ".hash";
5095               goto get_vma_if_bpabi;
5096             case DT_STRTAB:
5097               name = ".dynstr";
5098               goto get_vma_if_bpabi;
5099             case DT_SYMTAB:
5100               name = ".dynsym";
5101               goto get_vma_if_bpabi;
5102             case DT_VERSYM:
5103               name = ".gnu.version";
5104               goto get_vma_if_bpabi;
5105             case DT_VERDEF:
5106               name = ".gnu.version_d";
5107               goto get_vma_if_bpabi;
5108             case DT_VERNEED:
5109               name = ".gnu.version_r";
5110               goto get_vma_if_bpabi;
5111
5112             case DT_PLTGOT:
5113               name = ".got";
5114               goto get_vma;
5115             case DT_JMPREL:
5116               name = ".rel.plt";
5117             get_vma:
5118               s = bfd_get_section_by_name (output_bfd, name);
5119               BFD_ASSERT (s != NULL);
5120               if (!htab->symbian_p)
5121                 dyn.d_un.d_ptr = s->vma;
5122               else
5123                 /* In the BPABI, tags in the PT_DYNAMIC section point
5124                    at the file offset, not the memory address, for the
5125                    convenience of the post linker.  */
5126                 dyn.d_un.d_ptr = s->filepos;
5127               bfd_elf32_swap_dyn_out (output_bfd, &dyn, dyncon);
5128               break;
5129
5130             get_vma_if_bpabi:
5131               if (htab->symbian_p)
5132                 goto get_vma;
5133               break;
5134
5135             case DT_PLTRELSZ:
5136               s = bfd_get_section_by_name (output_bfd, ".rel.plt");
5137               BFD_ASSERT (s != NULL);
5138               dyn.d_un.d_val = s->size;
5139               bfd_elf32_swap_dyn_out (output_bfd, &dyn, dyncon);
5140               break;
5141               
5142             case DT_RELSZ:
5143               if (!htab->symbian_p)
5144                 {
5145                   /* My reading of the SVR4 ABI indicates that the
5146                      procedure linkage table relocs (DT_JMPREL) should be
5147                      included in the overall relocs (DT_REL).  This is
5148                      what Solaris does.  However, UnixWare can not handle
5149                      that case.  Therefore, we override the DT_RELSZ entry
5150                      here to make it not include the JMPREL relocs.  Since
5151                      the linker script arranges for .rel.plt to follow all
5152                      other relocation sections, we don't have to worry
5153                      about changing the DT_REL entry.  */
5154                   s = bfd_get_section_by_name (output_bfd, ".rel.plt");
5155                   if (s != NULL)
5156                     dyn.d_un.d_val -= s->size;
5157                   bfd_elf32_swap_dyn_out (output_bfd, &dyn, dyncon);
5158                   break;
5159                 }
5160               /* Fall through */
5161
5162             case DT_REL:
5163             case DT_RELA:
5164             case DT_RELASZ:
5165               /* In the BPABI, the DT_REL tag must point at the file
5166                  offset, not the VMA, of the first relocation
5167                  section.  So, we use code similar to that in
5168                  elflink.c, but do not check for SHF_ALLOC on the
5169                  relcoation section, since relocations sections are
5170                  never allocated under the BPABI.  The comments above
5171                  about Unixware notwithstanding, we include all of the
5172                  relocations here.  */
5173               if (htab->symbian_p)
5174                 {
5175                   unsigned int i;
5176                   type = ((dyn.d_tag == DT_REL || dyn.d_tag == DT_RELSZ)
5177                           ? SHT_REL : SHT_RELA);
5178                   dyn.d_un.d_val = 0;
5179                   for (i = 1; i < elf_numsections (output_bfd); i++)
5180                     {
5181                       Elf_Internal_Shdr *hdr 
5182                         = elf_elfsections (output_bfd)[i];
5183                       if (hdr->sh_type == type)
5184                         {
5185                           if (dyn.d_tag == DT_RELSZ 
5186                               || dyn.d_tag == DT_RELASZ)
5187                             dyn.d_un.d_val += hdr->sh_size;
5188                           else if (dyn.d_un.d_val == 0
5189                                    || hdr->sh_offset < dyn.d_un.d_val)
5190                             dyn.d_un.d_val = hdr->sh_offset;
5191                         }
5192                     }
5193                   bfd_elf32_swap_dyn_out (output_bfd, &dyn, dyncon);
5194                 }
5195               break;
5196
5197               /* Set the bottom bit of DT_INIT/FINI if the
5198                  corresponding function is Thumb.  */
5199             case DT_INIT:
5200               name = info->init_function;
5201               goto get_sym;
5202             case DT_FINI:
5203               name = info->fini_function;
5204             get_sym:
5205               /* If it wasn't set by elf_bfd_final_link
5206                  then there is nothing to adjust.  */
5207               if (dyn.d_un.d_val != 0)
5208                 {
5209                   struct elf_link_hash_entry * eh;
5210
5211                   eh = elf_link_hash_lookup (elf_hash_table (info), name,
5212                                              FALSE, FALSE, TRUE);
5213                   if (eh != (struct elf_link_hash_entry *) NULL
5214                       && ELF_ST_TYPE (eh->type) == STT_ARM_TFUNC)
5215                     {
5216                       dyn.d_un.d_val |= 1;
5217                       bfd_elf32_swap_dyn_out (output_bfd, &dyn, dyncon);
5218                     }
5219                 }
5220               break;
5221             }
5222         }
5223
5224       /* Fill in the first entry in the procedure linkage table.  */
5225       if (splt->size > 0 && elf32_arm_hash_table (info)->plt_header_size)
5226         {
5227           bfd_vma got_displacement;
5228
5229           /* Calculate the displacement between the PLT slot and &GOT[0].  */
5230           got_displacement = (sgot->output_section->vma
5231                               + sgot->output_offset
5232                               - splt->output_section->vma
5233                               - splt->output_offset
5234                               - 16);
5235
5236           bfd_put_32 (output_bfd, elf32_arm_plt0_entry[0], splt->contents +  0);
5237           bfd_put_32 (output_bfd, elf32_arm_plt0_entry[1], splt->contents +  4);
5238           bfd_put_32 (output_bfd, elf32_arm_plt0_entry[2], splt->contents +  8);
5239           bfd_put_32 (output_bfd, elf32_arm_plt0_entry[3], splt->contents + 12);
5240 #ifdef FOUR_WORD_PLT
5241           /* The displacement value goes in the otherwise-unused last word of
5242              the second entry.  */
5243           bfd_put_32 (output_bfd, got_displacement,        splt->contents + 28);
5244 #else
5245           bfd_put_32 (output_bfd, got_displacement,        splt->contents + 16);
5246 #endif
5247         }
5248
5249       /* UnixWare sets the entsize of .plt to 4, although that doesn't
5250          really seem like the right value.  */
5251       elf_section_data (splt->output_section)->this_hdr.sh_entsize = 4;
5252     }
5253
5254   /* Fill in the first three entries in the global offset table.  */
5255   if (sgot)
5256     {
5257       if (sgot->size > 0)
5258         {
5259           if (sdyn == NULL)
5260             bfd_put_32 (output_bfd, (bfd_vma) 0, sgot->contents);
5261           else
5262             bfd_put_32 (output_bfd,
5263                         sdyn->output_section->vma + sdyn->output_offset,
5264                         sgot->contents);
5265           bfd_put_32 (output_bfd, (bfd_vma) 0, sgot->contents + 4);
5266           bfd_put_32 (output_bfd, (bfd_vma) 0, sgot->contents + 8);
5267         }
5268
5269       elf_section_data (sgot->output_section)->this_hdr.sh_entsize = 4;
5270     }
5271
5272   return TRUE;
5273 }
5274
5275 static void
5276 elf32_arm_post_process_headers (bfd * abfd, struct bfd_link_info * link_info ATTRIBUTE_UNUSED)
5277 {
5278   Elf_Internal_Ehdr * i_ehdrp;  /* ELF file header, internal form.  */
5279   struct elf32_arm_link_hash_table *globals;
5280
5281   i_ehdrp = elf_elfheader (abfd);
5282
5283   i_ehdrp->e_ident[EI_OSABI]      = ARM_ELF_OS_ABI_VERSION;
5284   i_ehdrp->e_ident[EI_ABIVERSION] = ARM_ELF_ABI_VERSION;
5285
5286   if (link_info)
5287     {
5288       globals = elf32_arm_hash_table (link_info);
5289       if (globals->byteswap_code)
5290         i_ehdrp->e_flags |= EF_ARM_BE8;
5291     }
5292 }
5293
5294 static enum elf_reloc_type_class
5295 elf32_arm_reloc_type_class (const Elf_Internal_Rela *rela)
5296 {
5297   switch ((int) ELF32_R_TYPE (rela->r_info))
5298     {
5299     case R_ARM_RELATIVE:
5300       return reloc_class_relative;
5301     case R_ARM_JUMP_SLOT:
5302       return reloc_class_plt;
5303     case R_ARM_COPY:
5304       return reloc_class_copy;
5305     default:
5306       return reloc_class_normal;
5307     }
5308 }
5309
5310 /* Set the right machine number for an Arm ELF file.  */
5311
5312 static bfd_boolean
5313 elf32_arm_section_flags (flagword *flags, const Elf_Internal_Shdr *hdr)
5314 {
5315   if (hdr->sh_type == SHT_NOTE)
5316     *flags |= SEC_LINK_ONCE | SEC_LINK_DUPLICATES_SAME_CONTENTS;
5317
5318   return TRUE;
5319 }
5320
5321 static void
5322 elf32_arm_final_write_processing (bfd *abfd, bfd_boolean linker ATTRIBUTE_UNUSED)
5323 {
5324   bfd_arm_update_notes (abfd, ARM_NOTE_SECTION);
5325 }
5326
5327 /* Return TRUE if this is an unwinding table entry.  */
5328
5329 static bfd_boolean
5330 is_arm_elf_unwind_section_name (bfd * abfd ATTRIBUTE_UNUSED, const char * name)
5331 {
5332   size_t len1, len2;
5333
5334   len1 = sizeof (ELF_STRING_ARM_unwind) - 1;
5335   len2 = sizeof (ELF_STRING_ARM_unwind_once) - 1;
5336   return (strncmp (name, ELF_STRING_ARM_unwind, len1) == 0
5337           || strncmp (name, ELF_STRING_ARM_unwind_once, len2) == 0);
5338 }
5339
5340
5341 /* Set the type and flags for an ARM section.  We do this by
5342    the section name, which is a hack, but ought to work.  */
5343
5344 static bfd_boolean
5345 elf32_arm_fake_sections (bfd * abfd, Elf_Internal_Shdr * hdr, asection * sec)
5346 {
5347   const char * name;
5348
5349   name = bfd_get_section_name (abfd, sec);
5350
5351   if (is_arm_elf_unwind_section_name (abfd, name))
5352     {
5353       hdr->sh_type = SHT_ARM_EXIDX;
5354       hdr->sh_flags |= SHF_LINK_ORDER;
5355     }
5356   return TRUE;
5357 }
5358
5359 /* Handle an ARM specific section when reading an object file.
5360    This is called when elf.c finds a section with an unknown type.  */
5361
5362 static bfd_boolean
5363 elf32_arm_section_from_shdr (bfd *abfd,
5364                              Elf_Internal_Shdr * hdr,
5365                              const char *name)
5366 {
5367   /* There ought to be a place to keep ELF backend specific flags, but
5368      at the moment there isn't one.  We just keep track of the
5369      sections by their name, instead.  Fortunately, the ABI gives
5370      names for all the ARM specific sections, so we will probably get
5371      away with this.  */
5372   switch (hdr->sh_type)
5373     {
5374     case SHT_ARM_EXIDX:
5375       break;
5376
5377     default:
5378       return FALSE;
5379     }
5380
5381   if (! _bfd_elf_make_section_from_shdr (abfd, hdr, name))
5382     return FALSE;
5383
5384   return TRUE;
5385 }
5386
5387 /* Called for each symbol.  Builds a section map based on mapping symbols.
5388    Does not alter any of the symbols.  */
5389
5390 static bfd_boolean
5391 elf32_arm_output_symbol_hook (struct bfd_link_info *info,
5392                               const char *name,
5393                               Elf_Internal_Sym *elfsym,
5394                               asection *input_sec,
5395                               struct elf_link_hash_entry *h ATTRIBUTE_UNUSED)
5396 {
5397   int mapcount;
5398   elf32_arm_section_map *map;
5399   struct elf32_arm_link_hash_table *globals;
5400
5401   /* Only do this on final link.  */
5402   if (info->relocatable)
5403     return TRUE;
5404
5405   /* Only build a map if we need to byteswap code.  */
5406   globals = elf32_arm_hash_table (info);
5407   if (!globals->byteswap_code)
5408     return TRUE;
5409
5410   /* We only want mapping symbols.  */
5411   if (! is_arm_mapping_symbol_name (name))
5412     return TRUE;
5413
5414   mapcount = ++(elf32_arm_section_data (input_sec)->mapcount);
5415   map = elf32_arm_section_data (input_sec)->map;
5416   /* TODO: This may be inefficient, but we probably don't usually have many
5417      mapping symbols per section.  */
5418   map = bfd_realloc (map, mapcount * sizeof (elf32_arm_section_map));
5419   elf32_arm_section_data (input_sec)->map = map;
5420
5421   map[mapcount - 1].vma = elfsym->st_value;
5422   map[mapcount - 1].type = name[1];
5423   return TRUE;
5424 }
5425
5426
5427 /* Allocate target specific section data.  */
5428
5429 static bfd_boolean
5430 elf32_arm_new_section_hook (bfd *abfd, asection *sec)
5431 {
5432   struct _arm_elf_section_data *sdata;
5433   bfd_size_type amt = sizeof (*sdata);
5434
5435   sdata = bfd_zalloc (abfd, amt);
5436   if (sdata == NULL)
5437     return FALSE;
5438   sec->used_by_bfd = sdata;
5439
5440   return _bfd_elf_new_section_hook (abfd, sec);
5441 }
5442
5443
5444 /* Used to order a list of mapping symbols by address.  */
5445
5446 static int
5447 elf32_arm_compare_mapping (const void * a, const void * b)
5448 {
5449   return ((const elf32_arm_section_map *) a)->vma
5450          > ((const elf32_arm_section_map *) b)->vma;
5451 }
5452
5453
5454 /* Do code byteswapping.  Return FALSE afterwards so that the section is
5455    written out as normal.  */
5456
5457 static bfd_boolean
5458 elf32_arm_write_section (bfd *output_bfd ATTRIBUTE_UNUSED, asection *sec,
5459                          bfd_byte *contents)
5460 {
5461   int mapcount;
5462   elf32_arm_section_map *map;
5463   bfd_vma ptr;
5464   bfd_vma end;
5465   bfd_vma offset;
5466   bfd_byte tmp;
5467   int i;
5468
5469   mapcount = elf32_arm_section_data (sec)->mapcount;
5470   map = elf32_arm_section_data (sec)->map;
5471
5472   if (mapcount == 0)
5473     return FALSE;
5474
5475   qsort (map, mapcount, sizeof (elf32_arm_section_map),
5476          elf32_arm_compare_mapping);
5477
5478   offset = sec->output_section->vma + sec->output_offset;
5479   ptr = map[0].vma - offset;
5480   for (i = 0; i < mapcount; i++)
5481     {
5482       if (i == mapcount - 1)
5483         end = sec->size;
5484       else
5485         end = map[i + 1].vma - offset;
5486
5487       switch (map[i].type)
5488         {
5489         case 'a':
5490           /* Byte swap code words.  */
5491           while (ptr + 3 < end)
5492             {
5493               tmp = contents[ptr];
5494               contents[ptr] = contents[ptr + 3];
5495               contents[ptr + 3] = tmp;
5496               tmp = contents[ptr + 1];
5497               contents[ptr + 1] = contents[ptr + 2];
5498               contents[ptr + 2] = tmp;
5499               ptr += 4;
5500             }
5501           break;
5502
5503         case 't':
5504           /* Byte swap code halfwords.  */
5505           while (ptr + 1 < end)
5506             {
5507               tmp = contents[ptr];
5508               contents[ptr] = contents[ptr + 1];
5509               contents[ptr + 1] = tmp;
5510               ptr += 2;
5511             }
5512           break;
5513
5514         case 'd':
5515           /* Leave data alone.  */
5516           break;
5517         }
5518       ptr = end;
5519     }
5520   free (map);
5521   return FALSE;
5522 }
5523
5524 #define ELF_ARCH                        bfd_arch_arm
5525 #define ELF_MACHINE_CODE                EM_ARM
5526 #ifdef __QNXTARGET__
5527 #define ELF_MAXPAGESIZE                 0x1000
5528 #else
5529 #define ELF_MAXPAGESIZE                 0x8000
5530 #endif
5531
5532 #define bfd_elf32_bfd_copy_private_bfd_data     elf32_arm_copy_private_bfd_data
5533 #define bfd_elf32_bfd_merge_private_bfd_data    elf32_arm_merge_private_bfd_data
5534 #define bfd_elf32_bfd_set_private_flags         elf32_arm_set_private_flags
5535 #define bfd_elf32_bfd_print_private_bfd_data    elf32_arm_print_private_bfd_data
5536 #define bfd_elf32_bfd_link_hash_table_create    elf32_arm_link_hash_table_create
5537 #define bfd_elf32_bfd_reloc_type_lookup         elf32_arm_reloc_type_lookup
5538 #define bfd_elf32_find_nearest_line             elf32_arm_find_nearest_line
5539 #define bfd_elf32_new_section_hook              elf32_arm_new_section_hook
5540 #define bfd_elf32_bfd_is_target_special_symbol  elf32_arm_is_target_special_symbol
5541
5542 #define elf_backend_get_symbol_type             elf32_arm_get_symbol_type
5543 #define elf_backend_gc_mark_hook                elf32_arm_gc_mark_hook
5544 #define elf_backend_gc_sweep_hook               elf32_arm_gc_sweep_hook
5545 #define elf_backend_check_relocs                elf32_arm_check_relocs
5546 #define elf_backend_relocate_section            elf32_arm_relocate_section
5547 #define elf_backend_write_section               elf32_arm_write_section
5548 #define elf_backend_adjust_dynamic_symbol       elf32_arm_adjust_dynamic_symbol
5549 #define elf_backend_create_dynamic_sections     elf32_arm_create_dynamic_sections
5550 #define elf_backend_finish_dynamic_symbol       elf32_arm_finish_dynamic_symbol
5551 #define elf_backend_finish_dynamic_sections     elf32_arm_finish_dynamic_sections
5552 #define elf_backend_link_output_symbol_hook     elf32_arm_output_symbol_hook
5553 #define elf_backend_size_dynamic_sections       elf32_arm_size_dynamic_sections
5554 #define elf_backend_post_process_headers        elf32_arm_post_process_headers
5555 #define elf_backend_reloc_type_class            elf32_arm_reloc_type_class
5556 #define elf_backend_object_p                    elf32_arm_object_p
5557 #define elf_backend_section_flags               elf32_arm_section_flags
5558 #define elf_backend_fake_sections               elf32_arm_fake_sections
5559 #define elf_backend_section_from_shdr           elf32_arm_section_from_shdr
5560 #define elf_backend_final_write_processing      elf32_arm_final_write_processing
5561 #define elf_backend_copy_indirect_symbol        elf32_arm_copy_indirect_symbol
5562
5563 #define elf_backend_can_refcount    1
5564 #define elf_backend_can_gc_sections 1
5565 #define elf_backend_plt_readonly    1
5566 #define elf_backend_want_got_plt    1
5567 #define elf_backend_want_plt_sym    0
5568 #if !USE_REL
5569 #define elf_backend_rela_normal     1
5570 #endif
5571
5572 #define elf_backend_got_header_size     12
5573
5574 #include "elf32-target.h"
5575
5576 /* Symbian OS Targets */
5577
5578 #undef TARGET_LITTLE_SYM
5579 #define TARGET_LITTLE_SYM               bfd_elf32_littlearm_symbian_vec
5580 #undef TARGET_LITTLE_NAME
5581 #define TARGET_LITTLE_NAME              "elf32-littlearm-symbian"
5582 #undef TARGET_BIG_SYM
5583 #define TARGET_BIG_SYM                  bfd_elf32_bigarm_symbian_vec
5584 #undef TARGET_BIG_NAME
5585 #define TARGET_BIG_NAME                 "elf32-bigarm-symbian"
5586
5587 /* Like elf32_arm_link_hash_table_create -- but overrides
5588    appropriately for Symbian OS.  */
5589 static struct bfd_link_hash_table *
5590 elf32_arm_symbian_link_hash_table_create (bfd *abfd)
5591 {
5592   struct bfd_link_hash_table *ret;
5593
5594   ret = elf32_arm_link_hash_table_create (abfd);
5595   if (ret)
5596     {
5597       struct elf32_arm_link_hash_table *htab
5598         = (struct elf32_arm_link_hash_table *)ret;
5599       /* There is no PLT header for Symbian OS.  */
5600       htab->plt_header_size = 0;
5601       /* The PLT entries are each three instructions.  */
5602       htab->plt_entry_size = 4 * NUM_ELEM (elf32_arm_symbian_plt_entry);
5603       htab->symbian_p = 1;
5604     }
5605   return ret;
5606 }     
5607
5608 /* In a BPABI executable, the dynamic linking sections do not go in
5609    the loadable read-only segment.  The post-linker may wish to refer
5610    to these sections, but they are not part of the final program
5611    image.  */
5612 static struct bfd_elf_special_section const 
5613   elf32_arm_symbian_special_sections[]=
5614 {
5615   { ".dynamic",        8,  0, SHT_DYNAMIC,  0 },
5616   { ".dynstr",         7,  0, SHT_STRTAB,   0 },
5617   { ".dynsym",         7,  0, SHT_DYNSYM,   0 },
5618   { ".got",            4,  0, SHT_PROGBITS, 0 },
5619   { ".hash",           5,  0, SHT_HASH,     0 },
5620   { NULL,              0,  0, 0,            0 }
5621 };
5622
5623 static void
5624 elf32_arm_symbian_begin_write_processing (bfd *abfd, 
5625                                           struct bfd_link_info *link_info
5626                                             ATTRIBUTE_UNUSED)
5627 {
5628   /* BPABI objects are never loaded directly by an OS kernel; they are
5629      processed by a postlinker first, into an OS-specific format.  If
5630      the D_PAGED bit is set on the file, BFD will align segments on
5631      page boundaries, so that an OS can directly map the file.  With
5632      BPABI objects, that just results in wasted space.  In addition,
5633      because we clear the D_PAGED bit, map_sections_to_segments will
5634      recognize that the program headers should not be mapped into any
5635      loadable segment.  */
5636   abfd->flags &= ~D_PAGED;
5637 }
5638
5639 static bfd_boolean
5640 elf32_arm_symbian_modify_segment_map (bfd *abfd, 
5641                                       struct bfd_link_info *info 
5642                                         ATTRIBUTE_UNUSED)
5643 {
5644   struct elf_segment_map *m;
5645   asection *dynsec;
5646
5647   /* BPABI shared libraries and executables should have a PT_DYNAMIC
5648      segment.  However, because the .dynamic section is not marked
5649      with SEC_LOAD, the generic ELF code will not create such a
5650      segment.  */
5651   dynsec = bfd_get_section_by_name (abfd, ".dynamic");
5652   if (dynsec)
5653     {
5654       m = _bfd_elf_make_dynamic_segment (abfd, dynsec);
5655       m->next = elf_tdata (abfd)->segment_map;
5656       elf_tdata (abfd)->segment_map = m;
5657     }
5658
5659   return TRUE;
5660 }
5661
5662 #undef elf32_bed
5663 #define elf32_bed elf32_arm_symbian_bed
5664
5665 /* The dynamic sections are not allocated on SymbianOS; the postlinker
5666    will process them and then discard them.  */
5667 #undef ELF_DYNAMIC_SEC_FLAGS
5668 #define ELF_DYNAMIC_SEC_FLAGS \
5669   (SEC_HAS_CONTENTS | SEC_IN_MEMORY | SEC_LINKER_CREATED)
5670
5671 #undef bfd_elf32_bfd_link_hash_table_create
5672 #define bfd_elf32_bfd_link_hash_table_create \
5673   elf32_arm_symbian_link_hash_table_create
5674
5675 #undef elf_backend_special_sections
5676 #define elf_backend_special_sections elf32_arm_symbian_special_sections
5677
5678 #undef elf_backend_begin_write_processing
5679 #define elf_backend_begin_write_processing \
5680     elf32_arm_symbian_begin_write_processing
5681
5682 #undef elf_backend_modify_segment_map
5683 #define elf_backend_modify_segment_map elf32_arm_symbian_modify_segment_map
5684
5685 /* There is no .got section for BPABI objects, and hence no header.  */
5686 #undef elf_backend_got_header_size
5687 #define elf_backend_got_header_size 0
5688
5689 /* Similarly, there is no .got.plt section.  */
5690 #undef elf_backend_want_got_plt
5691 #define elf_backend_want_got_plt 0
5692
5693 #include "elf32-target.h"
5694