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