* elf32-arm.h (elf32_arm_reloc_map): Removed.
[platform/upstream/binutils.git] / bfd / elf32-arm.h
1 /* 32-bit ELF support for ARM
2    Copyright 1998, 1999 Free Software Foundation, Inc.
3
4    This file is part of BFD, the Binary File Descriptor library.
5
6    This program is free software; you can redistribute it and/or modify
7    it under the terms of the GNU General Public License as published by
8    the Free Software Foundation; either version 2 of the License, or
9    (at your option) any later version.
10
11    This program is distributed in the hope that it will be useful,
12    but WITHOUT ANY WARRANTY; without even the implied warranty of
13    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14    GNU General Public License for more details.
15
16    You should have received a copy of the GNU General Public License
17    along with this program; if not, write to the Free Software
18    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
19
20
21 typedef unsigned long int insn32;
22 typedef unsigned short int insn16;
23
24 static void elf32_arm_info_to_howto
25   PARAMS ((bfd *, arelent *, Elf32_Internal_Rela *));
26 static boolean elf32_arm_set_private_flags
27   PARAMS ((bfd *, flagword));
28 static boolean elf32_arm_copy_private_bfd_data
29   PARAMS ((bfd *, bfd *));
30 static boolean elf32_arm_merge_private_bfd_data
31   PARAMS ((bfd *, bfd *));
32 static boolean elf32_arm_print_private_bfd_data
33   PARAMS ((bfd *, PTR));
34 static int elf32_arm_get_symbol_type 
35   PARAMS (( Elf_Internal_Sym *, int));
36 static struct bfd_link_hash_table *elf32_arm_link_hash_table_create
37   PARAMS ((bfd *));
38
39
40 static insn32 insert_thumb_branch
41   PARAMS ((insn32, int));
42 static struct elf_link_hash_entry *find_thumb_glue
43   PARAMS ((struct bfd_link_info *, CONST char *, bfd *));
44 static struct elf_link_hash_entry *find_arm_glue
45   PARAMS ((struct bfd_link_info *, CONST char *, bfd *));
46 static void record_arm_to_thumb_glue
47   PARAMS ((struct bfd_link_info *, struct elf_link_hash_entry *));
48 static void record_thumb_to_arm_glue
49   PARAMS ((struct bfd_link_info *, struct elf_link_hash_entry *));
50
51 /* The linker script knows the section names for placement.
52    The entry_names are used to do simple name mangling on the stubs.
53    Given a function name, and its type, the stub can be found. The
54    name can be changed. The only requirement is the %s be present.
55  */
56
57 #define INTERWORK_FLAG( abfd )   (elf_elfheader (abfd)->e_flags & EF_INTERWORK)
58
59 #define THUMB2ARM_GLUE_SECTION_NAME ".glue_7t"
60 #define THUMB2ARM_GLUE_ENTRY_NAME   "__%s_from_thumb"
61
62 #define ARM2THUMB_GLUE_SECTION_NAME ".glue_7"
63 #define ARM2THUMB_GLUE_ENTRY_NAME   "__%s_from_arm"
64
65 /* Get the ARM elf linker hash table from a link_info structure.  */
66 #define elf32_arm_hash_table(info) \
67   ((struct elf32_arm_link_hash_table *) ((info)->hash))
68
69 /* ARM ELF linker hash table */
70 struct elf32_arm_link_hash_table
71   {
72     /* The main hash table.  */
73     struct elf_link_hash_table root;
74
75     /* The size in bytes of the section containg the Thumb-to-ARM glue.  */
76     long int thumb_glue_size;
77
78     /* The size in bytes of the section containg the ARM-to-Thumb glue.  */
79     long int arm_glue_size;
80
81     /* An arbitary input BFD chosen to hold the glue sections.  */
82     bfd *bfd_of_glue_owner;
83
84   };
85
86
87
88 /* Create an ARM elf linker hash table */
89
90 static struct bfd_link_hash_table *
91 elf32_arm_link_hash_table_create (abfd)
92      bfd *abfd;
93 {
94   struct elf32_arm_link_hash_table *ret;
95
96   ret = ((struct elf32_arm_link_hash_table *)
97          bfd_alloc (abfd, sizeof (struct elf32_arm_link_hash_table)));
98   if (ret == (struct elf32_arm_link_hash_table *) NULL)
99     return NULL;
100
101   if (!_bfd_elf_link_hash_table_init (&ret->root, abfd,
102                                       _bfd_elf_link_hash_newfunc))
103     {
104       bfd_release (abfd, ret);
105       return NULL;
106     }
107
108   ret->thumb_glue_size = 0;
109   ret->arm_glue_size = 0;
110   ret->bfd_of_glue_owner = NULL;
111
112   return &ret->root.root;
113 }
114
115 static struct elf_link_hash_entry *
116 find_thumb_glue (link_info, name, input_bfd)
117      struct bfd_link_info *link_info;
118      CONST char *name;
119      bfd *input_bfd;
120 {
121   char *tmp_name;
122   struct elf_link_hash_entry *hash;
123   struct elf32_arm_link_hash_table *hash_table;
124
125   /* We need a pointer to the armelf specific hash table.  */
126   hash_table = elf32_arm_hash_table (link_info);
127
128
129   tmp_name = ((char *)
130        bfd_malloc (strlen (name) + strlen (THUMB2ARM_GLUE_ENTRY_NAME) + 1));
131
132   BFD_ASSERT (tmp_name);
133
134   sprintf (tmp_name, THUMB2ARM_GLUE_ENTRY_NAME, name);
135
136   hash = elf_link_hash_lookup
137     (&(hash_table)->root, tmp_name, false, false, true);
138
139   if (hash == NULL)
140     /* xgettext:c-format */
141     _bfd_error_handler (_ ("%s: unable to find THUMB glue '%s' for `%s'"),
142                         bfd_get_filename (input_bfd), tmp_name, name);
143
144   free (tmp_name);
145
146   return hash;
147 }
148
149 static struct elf_link_hash_entry *
150 find_arm_glue (link_info, name, input_bfd)
151      struct bfd_link_info *link_info;
152      CONST char *name;
153      bfd *input_bfd;
154 {
155   char *tmp_name;
156   struct elf_link_hash_entry *myh;
157   struct elf32_arm_link_hash_table *hash_table;
158
159   /* We need a pointer to the elfarm specific hash table.  */
160   hash_table = elf32_arm_hash_table (link_info);
161
162   tmp_name = ((char *)
163        bfd_malloc (strlen (name) + strlen (ARM2THUMB_GLUE_ENTRY_NAME) + 1));
164
165   BFD_ASSERT (tmp_name);
166
167   sprintf (tmp_name, ARM2THUMB_GLUE_ENTRY_NAME, name);
168
169   myh = elf_link_hash_lookup
170     (&(hash_table)->root, tmp_name, false, false, true);
171
172   if (myh == NULL)
173     /* xgettext:c-format */
174     _bfd_error_handler (_ ("%s: unable to find ARM glue '%s' for `%s'"),
175                         bfd_get_filename (input_bfd), tmp_name, name);
176
177   free (tmp_name);
178
179   return myh;
180 }
181
182 /*
183    ARM->Thumb glue:
184
185    .arm
186    __func_from_arm:
187    ldr r12, __func_addr
188    bx  r12
189    __func_addr:
190    .word func    @ behave as if you saw a ARM_32 reloc
191  */
192
193 #define ARM2THUMB_GLUE_SIZE 12
194 static const insn32 a2t1_ldr_insn = 0xe59fc000;
195 static const insn32 a2t2_bx_r12_insn = 0xe12fff1c;
196 static const insn32 a2t3_func_addr_insn = 0x00000001;
197
198 /*
199    Thumb->ARM:                          Thumb->(non-interworking aware) ARM
200
201    .thumb                               .thumb
202    .align 2                             .align 2
203    __func_from_thumb:              __func_from_thumb:
204    bx pc                                push {r6, lr}
205    nop                                  ldr  r6, __func_addr
206    .arm                                         mov  lr, pc
207    __func_change_to_arm:                        bx   r6
208    b func                       .arm
209    __func_back_to_thumb:
210    ldmia r13! {r6, lr}
211    bx    lr
212    __func_addr:
213    .word        func 
214  */
215
216 #define THUMB2ARM_GLUE_SIZE 8
217 static const insn16 t2a1_bx_pc_insn = 0x4778;
218 static const insn16 t2a2_noop_insn = 0x46c0;
219 static const insn32 t2a3_b_insn = 0xea000000;
220
221 static const insn16 t2a1_push_insn = 0xb540;
222 static const insn16 t2a2_ldr_insn = 0x4e03;
223 static const insn16 t2a3_mov_insn = 0x46fe;
224 static const insn16 t2a4_bx_insn = 0x4730;
225 static const insn32 t2a5_pop_insn = 0xe8bd4040;
226 static const insn32 t2a6_bx_insn = 0xe12fff1e;
227
228 boolean
229 bfd_elf32_arm_allocate_interworking_sections (info)
230      struct bfd_link_info *info;
231 {
232   asection *s;
233   bfd_byte *foo;
234   struct elf32_arm_link_hash_table *globals;
235
236   globals = elf32_arm_hash_table (info);
237
238   BFD_ASSERT (globals != NULL);
239
240   if (globals->arm_glue_size != 0)
241     {
242       BFD_ASSERT (globals->bfd_of_glue_owner != NULL);
243
244       s = bfd_get_section_by_name
245         (globals->bfd_of_glue_owner, ARM2THUMB_GLUE_SECTION_NAME);
246
247       BFD_ASSERT (s != NULL);
248
249       foo = (bfd_byte *) bfd_alloc
250         (globals->bfd_of_glue_owner, globals->arm_glue_size);
251
252       s->_raw_size = s->_cooked_size = globals->arm_glue_size;
253       s->contents = foo;
254     }
255
256   if (globals->thumb_glue_size != 0)
257     {
258       BFD_ASSERT (globals->bfd_of_glue_owner != NULL);
259
260       s = bfd_get_section_by_name
261         (globals->bfd_of_glue_owner, THUMB2ARM_GLUE_SECTION_NAME);
262
263       BFD_ASSERT (s != NULL);
264
265       foo = (bfd_byte *) bfd_alloc
266         (globals->bfd_of_glue_owner, globals->thumb_glue_size);
267
268       s->_raw_size = s->_cooked_size = globals->thumb_glue_size;
269       s->contents = foo;
270     }
271
272   return true;
273 }
274
275 static void
276 record_arm_to_thumb_glue (link_info, h)
277      struct bfd_link_info *link_info;
278      struct elf_link_hash_entry *h;
279 {
280   const char *name = h->root.root.string;
281   register asection *s;
282   char *tmp_name;
283   struct elf_link_hash_entry *myh;
284   struct elf32_arm_link_hash_table *globals;
285
286   globals = elf32_arm_hash_table (link_info);
287
288   BFD_ASSERT (globals != NULL);
289   BFD_ASSERT (globals->bfd_of_glue_owner != NULL);
290
291   s = bfd_get_section_by_name
292     (globals->bfd_of_glue_owner, ARM2THUMB_GLUE_SECTION_NAME);
293
294
295   BFD_ASSERT (s != NULL);
296
297   tmp_name = ((char *)
298        bfd_malloc (strlen (name) + strlen (ARM2THUMB_GLUE_ENTRY_NAME) + 1));
299
300   BFD_ASSERT (tmp_name);
301
302   sprintf (tmp_name, ARM2THUMB_GLUE_ENTRY_NAME, name);
303
304   myh = elf_link_hash_lookup
305     (&(globals)->root, tmp_name, false, false, true);
306
307   if (myh != NULL)
308     {
309       free (tmp_name);
310       return;                   /* we've already seen this guy */
311     }
312
313   /* The only trick here is using hash_table->arm_glue_size as the value. Even
314      though the section isn't allocated yet, this is where we will be putting
315      it.  */
316
317   _bfd_generic_link_add_one_symbol (link_info, globals->bfd_of_glue_owner, tmp_name,
318                                     BSF_GLOBAL,
319                                     s, globals->arm_glue_size + 1,
320                                     NULL, true, false,
321                                     (struct bfd_link_hash_entry **) &myh);
322
323   free (tmp_name);
324
325   globals->arm_glue_size += ARM2THUMB_GLUE_SIZE;
326
327   return;
328 }
329
330 static void
331 record_thumb_to_arm_glue (link_info, h)
332      struct bfd_link_info *link_info;
333      struct elf_link_hash_entry *h;
334 {
335   const char *name = h->root.root.string;
336   register asection *s;
337   char *tmp_name;
338   struct elf_link_hash_entry *myh;
339   struct elf32_arm_link_hash_table *hash_table;
340   char bind;
341
342   hash_table = elf32_arm_hash_table (link_info);
343
344   BFD_ASSERT (hash_table != NULL);
345   BFD_ASSERT (hash_table->bfd_of_glue_owner != NULL);
346
347   s = bfd_get_section_by_name
348     (hash_table->bfd_of_glue_owner, THUMB2ARM_GLUE_SECTION_NAME);
349
350   BFD_ASSERT (s != NULL);
351
352   tmp_name = (char *) bfd_malloc (strlen (name) + strlen (THUMB2ARM_GLUE_ENTRY_NAME) + 1);
353
354   BFD_ASSERT (tmp_name);
355
356   sprintf (tmp_name, THUMB2ARM_GLUE_ENTRY_NAME, name);
357
358   myh = elf_link_hash_lookup
359     (&(hash_table)->root, tmp_name, false, false, true);
360
361   if (myh != NULL)
362     {
363       free (tmp_name);
364       return;                   /* we've already seen this guy */
365     }
366
367   _bfd_generic_link_add_one_symbol (link_info, hash_table->bfd_of_glue_owner, tmp_name,
368                              BSF_GLOBAL, s, hash_table->thumb_glue_size + 1,
369                                     NULL, true, false,
370                                     (struct bfd_link_hash_entry **) &myh);
371
372   /* If we mark it 'thumb', the disassembler will do a better job.  */
373   bind = ELF_ST_BIND (myh->type);
374   myh->type = ELF_ST_INFO (bind, STT_ARM_TFUNC);
375
376   free (tmp_name);
377
378   /* Allocate another symbol to mark where we switch to arm mode.  */
379
380 #define CHANGE_TO_ARM "__%s_change_to_arm"
381 #define BACK_FROM_ARM "__%s_back_from_arm"
382
383   tmp_name = (char *) bfd_malloc (strlen (name) + strlen (CHANGE_TO_ARM) + 1);
384
385   BFD_ASSERT (tmp_name);
386
387   sprintf (tmp_name, CHANGE_TO_ARM, name);
388
389   myh = NULL;
390
391   _bfd_generic_link_add_one_symbol (link_info, hash_table->bfd_of_glue_owner, tmp_name,
392                               BSF_LOCAL, s, hash_table->thumb_glue_size + 4,
393                                     NULL, true, false,
394                                     (struct bfd_link_hash_entry **) &myh);
395
396   free (tmp_name);
397
398   hash_table->thumb_glue_size += THUMB2ARM_GLUE_SIZE;
399
400   return;
401 }
402
403 /* Select a BFD to be used to hold the sections used by the glue code.
404    This function is called from the linker scripts in ld/emultempl/
405    {armelf/pe}.em  */
406 boolean
407 bfd_elf32_arm_get_bfd_for_interworking (abfd, info)
408      bfd *abfd;
409      struct bfd_link_info *info;
410 {
411   struct elf32_arm_link_hash_table *globals;
412   flagword flags;
413   asection *sec;
414
415   /* If we are only performing a partial link do not bother
416      getting a bfd to hold the glue.  */
417   if (info->relocateable)
418     return true;
419
420   globals = elf32_arm_hash_table (info);
421
422   BFD_ASSERT (globals != NULL);
423
424   if (globals->bfd_of_glue_owner != NULL)
425     return true;
426
427   sec = bfd_get_section_by_name (abfd, ARM2THUMB_GLUE_SECTION_NAME);
428
429   if (sec == NULL)
430     {
431       flags = SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS | SEC_IN_MEMORY;
432
433       sec = bfd_make_section (abfd, ARM2THUMB_GLUE_SECTION_NAME);
434
435       if (sec == NULL
436           || !bfd_set_section_flags (abfd, sec, flags)
437           || !bfd_set_section_alignment (abfd, sec, 2))
438         return false;
439     }
440
441   sec = bfd_get_section_by_name (abfd, THUMB2ARM_GLUE_SECTION_NAME);
442
443   if (sec == NULL)
444     {
445       flags = SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS | SEC_IN_MEMORY;
446
447       sec = bfd_make_section (abfd, THUMB2ARM_GLUE_SECTION_NAME);
448
449       if (sec == NULL
450           || !bfd_set_section_flags (abfd, sec, flags)
451           || !bfd_set_section_alignment (abfd, sec, 2))
452         return false;
453     }
454
455   /* Save the bfd for later use.  */
456   globals->bfd_of_glue_owner = abfd;
457
458   return true;
459 }
460
461 boolean
462 bfd_elf32_arm_process_before_allocation (abfd, link_info)
463      bfd *abfd;
464      struct bfd_link_info *link_info;
465 {
466   Elf_Internal_Shdr *symtab_hdr;
467   Elf_Internal_Rela *free_relocs = NULL;
468   Elf_Internal_Rela *irel, *irelend;
469   bfd_byte *contents = NULL;
470   bfd_byte *free_contents = NULL;
471   Elf32_External_Sym *extsyms = NULL;
472   Elf32_External_Sym *free_extsyms = NULL;
473
474   asection *sec;
475   struct elf32_arm_link_hash_table *globals;
476
477   /* If we are only performing a partial link do not bother
478      to construct any glue.  */
479   if (link_info->relocateable)
480     return true;
481
482   /* Here we have a bfd that is to be included on the link.  We have a hook
483      to do reloc rummaging, before section sizes are nailed down.  */
484
485   globals = elf32_arm_hash_table (link_info);
486
487   BFD_ASSERT (globals != NULL);
488   BFD_ASSERT (globals->bfd_of_glue_owner != NULL);
489
490   /* Rummage around all the relocs and map the glue vectors.  */
491   sec = abfd->sections;
492
493   if (sec == NULL)
494     return true;
495
496   for (; sec != NULL; sec = sec->next)
497     {
498       if (sec->reloc_count == 0)
499         continue;
500
501       symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
502       /* Load the relocs.  */
503
504       irel = (_bfd_elf32_link_read_relocs (abfd, sec, (PTR) NULL,
505                                         (Elf_Internal_Rela *) NULL, false));
506
507       BFD_ASSERT (irel != 0);
508
509       irelend = irel + sec->reloc_count;
510       for (; irel < irelend; irel++)
511         {
512           long r_type;
513           unsigned long r_index;
514           unsigned char code;
515
516           struct elf_link_hash_entry *h;
517
518           r_type = ELF32_R_TYPE (irel->r_info);
519           r_index = ELF32_R_SYM (irel->r_info);
520
521           /* These are the only relocation types we care about */
522           if (r_type != R_ARM_PC24
523               && r_type != R_ARM_THM_PC22)
524             continue;
525
526           /* Get the section contents if we haven't done so already.  */
527           if (contents == NULL)
528             {
529               /* Get cached copy if it exists.  */
530               if (elf_section_data (sec)->this_hdr.contents != NULL)
531                 contents = elf_section_data (sec)->this_hdr.contents;
532               else
533                 {
534                   /* Go get them off disk.  */
535                   contents = (bfd_byte *) bfd_malloc (sec->_raw_size);
536                   if (contents == NULL)
537                     goto error_return;
538                   free_contents = contents;
539
540                   if (!bfd_get_section_contents (abfd, sec, contents,
541                                               (file_ptr) 0, sec->_raw_size))
542                     goto error_return;
543                 }
544             }
545
546           /* Read this BFD's symbols if we haven't done so already.  */
547           if (extsyms == NULL)
548             {
549               /* Get cached copy if it exists.  */
550               if (symtab_hdr->contents != NULL)
551                 extsyms = (Elf32_External_Sym *) symtab_hdr->contents;
552               else
553                 {
554                   /* Go get them off disk.  */
555                   extsyms = ((Elf32_External_Sym *)
556                              bfd_malloc (symtab_hdr->sh_size));
557                   if (extsyms == NULL)
558                     goto error_return;
559                   free_extsyms = extsyms;
560                   if (bfd_seek (abfd, symtab_hdr->sh_offset, SEEK_SET) != 0
561                       || (bfd_read (extsyms, 1, symtab_hdr->sh_size, abfd)
562                           != symtab_hdr->sh_size))
563                     goto error_return;
564                 }
565             }
566
567           /* If the relocation is not against a symbol it cannot concern us. */
568
569           h = NULL;
570
571           /* We don't care about local symbols */
572           if (r_index < symtab_hdr->sh_info)
573             continue;
574
575           /* This is an external symbol */
576           r_index -= symtab_hdr->sh_info;
577           h = (struct elf_link_hash_entry *)
578             elf_sym_hashes (abfd)[r_index];
579
580           /* If the relocation is against a static symbol it must be within
581              the current section and so cannot be a cross ARM/Thumb relocation.  */
582           if (h == NULL)
583             continue;
584
585           switch (r_type)
586             {
587             case R_ARM_PC24:
588               /* This one is a call from arm code.  We need to look up
589                  the target of the call. If it is a thumb target, we
590                  insert glue.  */
591
592               if (ELF_ST_TYPE(h->type) == STT_ARM_TFUNC)
593                 record_arm_to_thumb_glue (link_info, h);
594               break;
595
596             case R_ARM_THM_PC22:
597               /* This one is a call from thumb code.  We look 
598                  up the target of the call. If it is not a thumb
599                  target, we insert glue. */ 
600
601               if (ELF_ST_TYPE (h->type) != STT_ARM_TFUNC)
602                 record_thumb_to_arm_glue (link_info, h);
603               break;
604
605             default:
606               break;
607             }
608         }
609     }
610
611   return true;
612 error_return:
613   if (free_relocs != NULL)
614     free (free_relocs);
615   if (free_contents != NULL)
616     free (free_contents);
617   if (free_extsyms != NULL)
618     free (free_extsyms);
619   return false;
620
621 }
622
623 /* The thumb form of a long branch is a bit finicky, because the offset
624    encoding is split over two fields, each in it's own instruction. They
625    can occur in any order. So given a thumb form of long branch, and an 
626    offset, insert the offset into the thumb branch and return finished
627    instruction. 
628
629    It takes two thumb instructions to encode the target address. Each has 
630    11 bits to invest. The upper 11 bits are stored in one (identifed by
631    H-0.. see below), the lower 11 bits are stored in the other (identified 
632    by H-1). 
633
634    Combine together and shifted left by 1 (it's a half word address) and 
635    there you have it.
636
637    Op: 1111 = F,
638    H-0, upper address-0 = 000
639    Op: 1111 = F,
640    H-1, lower address-0 = 800
641
642    They can be ordered either way, but the arm tools I've seen always put 
643    the lower one first. It probably doesn't matter. krk@cygnus.com
644
645    XXX:  Actually the order does matter.  The second instruction (H-1)
646    moves the computed address into the PC, so it must be the second one
647    in the sequence.  The problem, however is that whilst little endian code
648    stores the instructions in HI then LOW order, big endian code does the
649    reverse.  nickc@cygnus.com  */
650
651 #define LOW_HI_ORDER 0xF800F000
652 #define HI_LOW_ORDER 0xF000F800
653
654 static insn32
655 insert_thumb_branch (br_insn, rel_off)
656      insn32 br_insn;
657      int rel_off;
658 {
659   unsigned int low_bits;
660   unsigned int high_bits;
661
662
663   BFD_ASSERT ((rel_off & 1) != 1);
664
665   rel_off >>= 1;                /* half word aligned address */
666   low_bits = rel_off & 0x000007FF;      /* the bottom 11 bits */
667   high_bits = (rel_off >> 11) & 0x000007FF;     /* the top 11 bits */
668
669   if ((br_insn & LOW_HI_ORDER) == LOW_HI_ORDER)
670     br_insn = LOW_HI_ORDER | (low_bits << 16) | high_bits;
671   else if ((br_insn & HI_LOW_ORDER) == HI_LOW_ORDER)
672     br_insn = HI_LOW_ORDER | (high_bits << 16) | low_bits;
673   else
674     abort ();                   /* error - not a valid branch instruction form */
675
676   /* FIXME: abort is probably not the right call. krk@cygnus.com */
677
678   return br_insn;
679 }
680
681 /* Thumb code calling an ARM function */
682 int
683 elf32_thumb_to_arm_stub (info, name, input_bfd, output_bfd, input_section,
684                          hit_data, sym_sec, offset, addend, val)
685      struct bfd_link_info *info;
686      char *name;
687      bfd *input_bfd;
688      bfd *output_bfd;
689      asection *input_section;
690      bfd_byte *hit_data;
691      asection *sym_sec;
692      int offset;
693      int addend;
694      bfd_vma val;
695 {
696   asection *s = 0;
697   long int my_offset;
698   unsigned long int tmp;
699   long int ret_offset;
700   struct elf_link_hash_entry *myh;
701   struct elf32_arm_link_hash_table *globals;
702
703   myh = find_thumb_glue (info, name, input_bfd);
704   if (myh == NULL)
705     return false;
706
707   globals = elf32_arm_hash_table (info);
708
709   BFD_ASSERT (globals != NULL);
710   BFD_ASSERT (globals->bfd_of_glue_owner != NULL);
711
712   my_offset = myh->root.u.def.value;
713
714   s = bfd_get_section_by_name (globals->bfd_of_glue_owner,
715                                THUMB2ARM_GLUE_SECTION_NAME);
716
717   BFD_ASSERT (s != NULL);
718   BFD_ASSERT (s->contents != NULL);
719   BFD_ASSERT (s->output_section != NULL);
720
721   if ((my_offset & 0x01) == 0x01)
722     {
723       if (sym_sec != NULL
724           && sym_sec->owner != NULL
725           && !INTERWORK_FLAG (sym_sec->owner))
726         {
727           _bfd_error_handler
728             (_ ("%s(%s): warning: interworking not enabled."),
729              bfd_get_filename (sym_sec->owner), name);
730           _bfd_error_handler
731             (_ ("  first occurrence: %s: thumb call to arm"),
732              bfd_get_filename (input_bfd));
733
734           return false;
735         }
736
737       --my_offset;
738       myh->root.u.def.value = my_offset;
739
740       bfd_put_16 (output_bfd, t2a1_bx_pc_insn,
741                   s->contents + my_offset);
742
743       bfd_put_16 (output_bfd, t2a2_noop_insn,
744                   s->contents + my_offset + 2);
745
746       ret_offset =
747         ((bfd_signed_vma) val)  /* Address of destination of the stub */
748         - ((bfd_signed_vma)
749            (s->output_offset    /* Offset from the start of the current section to the start of the stubs.  */
750             + my_offset         /* Offset of the start of this stub from the start of the stubs.  */
751             + s->output_section->vma)   /* Address of the start of the current section.  */
752            + 4                  /* The branch instruction is 4 bytes into the stub.  */
753            + 8);                /* ARM branches work from the pc of the instruction + 8.  */
754
755       bfd_put_32 (output_bfd,
756                   t2a3_b_insn | ((ret_offset >> 2) & 0x00FFFFFF),
757                   s->contents + my_offset + 4);
758     }
759
760   BFD_ASSERT (my_offset <= globals->thumb_glue_size);
761
762   /* Now go back and fix up the original BL insn to point
763      to here.  */
764   ret_offset =
765     s->output_offset
766     + my_offset
767     - (input_section->output_offset
768        + offset + addend)
769     - 4;
770
771   tmp = bfd_get_32 (input_bfd, hit_data
772                     - input_section->vma);
773
774   bfd_put_32 (output_bfd,
775               insert_thumb_branch (tmp, ret_offset),
776               hit_data - input_section->vma);
777
778   return true;
779 }
780
781 /* Arm code calling a Thumb function */
782 int
783 elf32_arm_to_thumb_stub (info, name, input_bfd, output_bfd, input_section,
784                          hit_data, sym_sec, offset, addend, val)
785
786      struct bfd_link_info *info;
787      char *name;
788      bfd *input_bfd;
789      bfd *output_bfd;
790      asection *input_section;
791      bfd_byte *hit_data;
792      asection *sym_sec;
793      int offset;
794      int addend;
795      bfd_vma val;
796 {
797   unsigned long int tmp;
798   long int my_offset;
799   asection *s;
800   long int ret_offset;
801   struct elf_link_hash_entry *myh;
802   struct elf32_arm_link_hash_table *globals;
803
804   myh = find_arm_glue (info, name, input_bfd);
805   if (myh == NULL)
806     return false;
807
808   globals = elf32_arm_hash_table (info);
809
810   BFD_ASSERT (globals != NULL);
811   BFD_ASSERT (globals->bfd_of_glue_owner != NULL);
812
813   my_offset = myh->root.u.def.value;
814   s = bfd_get_section_by_name (globals->bfd_of_glue_owner,
815                                ARM2THUMB_GLUE_SECTION_NAME);
816   BFD_ASSERT (s != NULL);
817   BFD_ASSERT (s->contents != NULL);
818   BFD_ASSERT (s->output_section != NULL);
819
820   if ((my_offset & 0x01) == 0x01)
821     {
822       if (sym_sec != NULL
823           && sym_sec->owner != NULL
824           && !INTERWORK_FLAG (sym_sec->owner))
825         {
826           _bfd_error_handler
827             (_ ("%s(%s): warning: interworking not enabled."),
828              bfd_get_filename (sym_sec->owner), name);
829           _bfd_error_handler
830             (_ ("  first occurrence: %s: arm call to thumb"),
831              bfd_get_filename (input_bfd));
832         }
833       --my_offset;
834       myh->root.u.def.value = my_offset;
835
836       bfd_put_32 (output_bfd, a2t1_ldr_insn,
837                   s->contents + my_offset);
838
839       bfd_put_32 (output_bfd, a2t2_bx_r12_insn,
840                   s->contents + my_offset + 4);
841
842       /* It's a thumb address.  Add the low order bit.  */
843       bfd_put_32 (output_bfd, val | a2t3_func_addr_insn,
844                   s->contents + my_offset + 8);
845     }
846
847   BFD_ASSERT (my_offset <= globals->arm_glue_size);
848
849   tmp = bfd_get_32 (input_bfd, hit_data);
850   tmp = tmp & 0xFF000000;
851
852   /* Somehow these are both 4 too far, so subtract 8. */
853   ret_offset = s->output_offset
854     + my_offset
855     + s->output_section->vma
856     - (input_section->output_offset
857        + input_section->output_section->vma
858        + offset + addend)
859     - 8;
860
861   tmp = tmp | ((ret_offset >> 2) & 0x00FFFFFF);
862
863   bfd_put_32 (output_bfd, tmp, hit_data
864               - input_section->vma);
865
866
867   return true;
868 }
869
870 /* Perform a relocation as part of a final link.  */
871 static bfd_reloc_status_type
872 elf32_arm_final_link_relocate (howto, input_bfd, output_bfd,
873                                input_section, contents, offset, value,
874                                addend, info, sym_sec, sym_name, sym_flags)
875      reloc_howto_type *howto;
876      bfd *input_bfd;
877      bfd *output_bfd;
878      asection *input_section;
879      bfd_byte *contents;
880      bfd_vma offset;
881      bfd_vma value;
882      bfd_vma addend;
883      struct bfd_link_info *info;
884      asection *sym_sec;
885      const char *sym_name;
886      unsigned char sym_flags;
887 {
888   unsigned long r_type = howto->type;
889   bfd_byte *hit_data = contents + offset;
890
891   switch (r_type)
892     {
893
894     case R_ARM_NONE:
895       return bfd_reloc_ok;
896
897     case R_ARM_PC24:
898       /* Arm B/BL instruction */
899
900 #ifdef USE_REL
901       addend = (bfd_get_32 (input_bfd, hit_data) & howto->src_mask);
902 #endif
903       /* check for arm calling thumb function */
904       if (sym_flags == STT_ARM_TFUNC)
905         {
906           elf32_arm_to_thumb_stub (info, sym_name, input_bfd, output_bfd,
907                    input_section, hit_data, sym_sec, offset, addend, value);
908           return bfd_reloc_ok;
909         }
910
911       value = value + addend;
912       value -= (input_section->output_section->vma
913                 + input_section->output_offset + 8);
914       value -= offset;
915       value = value >> howto->rightshift;
916
917       value &= 0xffffff;
918       value |= (bfd_get_32 (input_bfd, hit_data) & 0xff000000);
919       bfd_put_32 (input_bfd, value, hit_data);
920       return bfd_reloc_ok;
921
922     case R_ARM_ABS32:
923 #ifdef USE_REL
924       addend = (bfd_get_32 (input_bfd, hit_data) & howto->src_mask);
925 #endif
926       value += addend;
927       if (sym_flags == STT_ARM_TFUNC)
928         value |= 1;
929       bfd_put_32 (input_bfd, value, hit_data);
930       return bfd_reloc_ok;
931
932     case R_ARM_REL32:
933 #ifdef USE_REL
934       addend = (bfd_get_32 (input_bfd, hit_data) & howto->src_mask);
935 #endif
936       value -= (input_section->output_section->vma
937                 + input_section->output_offset);
938       value += addend;
939
940       bfd_put_32 (input_bfd, value, hit_data);
941       return bfd_reloc_ok;
942
943     case R_ARM_ABS8:
944 #ifdef USE_REL
945      addend = (bfd_get_32 (input_bfd, hit_data) & howto->src_mask);
946 #endif
947       value += addend;
948       if ((long) value > 0x7f || (long) value < -0x80)
949         return bfd_reloc_overflow;
950
951       bfd_put_8 (input_bfd, value, hit_data);
952       return bfd_reloc_ok;
953
954     case R_ARM_ABS16:
955 #ifdef USE_REL
956       addend = (bfd_get_32 (input_bfd, hit_data) & howto->src_mask);
957 #endif
958       value += addend;
959
960       if ((long) value > 0x7fff || (long) value < -0x8000)
961         return bfd_reloc_overflow;
962
963       bfd_put_16 (input_bfd, value, hit_data);
964       return bfd_reloc_ok;
965
966     case R_ARM_ABS12:
967       /* Support ldr and str instruction for the arm */
968       /* Also thumb b (unconditional branch) */
969 #ifdef USE_REL
970       addend = (bfd_get_32 (input_bfd, hit_data) & howto->src_mask);
971 #endif
972       value += addend;
973
974       if ((long) value > 0x7ff || (long) value < -0x800)
975         return bfd_reloc_overflow;
976
977       value |= (bfd_get_32 (input_bfd, hit_data) & 0xfffff000);
978       bfd_put_32 (input_bfd, value, hit_data);
979       return bfd_reloc_ok;
980
981     case R_ARM_THM_ABS5:
982       /* Support ldr and str instructions for the thumb. */
983       value += addend;
984
985       if ((long) value > 0x1f || (long) value < -0x10)
986         return bfd_reloc_overflow;
987
988       value |= bfd_get_16 (input_bfd, hit_data) & 0xf82f;
989       bfd_put_16 (input_bfd, value, hit_data);
990       return bfd_reloc_ok;
991
992
993     case R_ARM_THM_PC22:
994       /* thumb BL (branch long instruction). */
995       {
996         bfd_vma relocation;
997         boolean overflow = false;
998         bfd_vma insn = bfd_get_32 (input_bfd, hit_data);
999         bfd_vma src_mask = 0x007FFFFE;
1000         bfd_signed_vma reloc_signed_max = (1 << (howto->bitsize - 1)) - 1;
1001         bfd_signed_vma reloc_signed_min = ~reloc_signed_max;
1002         bfd_vma check;
1003         bfd_signed_vma signed_check;
1004         bfd_vma add;
1005         bfd_signed_vma signed_add;
1006
1007         /* If it's not a call to thumb, assume call to arm */
1008         if (sym_flags != STT_ARM_TFUNC)
1009           {
1010             if (elf32_thumb_to_arm_stub
1011                 (info, sym_name, input_bfd, output_bfd, input_section,
1012                  hit_data, sym_sec, offset, addend, value))
1013               return bfd_reloc_ok;
1014             else
1015               return bfd_reloc_dangerous;
1016           }
1017
1018         relocation = value + addend;
1019         relocation -= (input_section->output_section->vma + input_section->output_offset);
1020         relocation -= offset;
1021
1022         check = relocation >> howto->rightshift;
1023
1024         /* If this is a signed value, the rightshift just dropped
1025            leading 1 bits (assuming twos complement).  */
1026         if ((bfd_signed_vma) relocation >= 0)
1027           signed_check = check;
1028         else
1029           signed_check = (check | ((bfd_vma) - 1 & ~((bfd_vma) - 1 >> howto->rightshift)));
1030
1031         /* Get the value from the object file.  */
1032         if (bfd_big_endian (input_bfd))
1033           add = (((insn) & 0x07ff0000) >> 4) | (((insn) & 0x7ff) << 1);
1034         else
1035           add = ((((insn) & 0x7ff) << 12) | (((insn) & 0x07ff0000) >> 15));
1036
1037         /* Get the value from the object file with an appropriate sign.
1038            The expression involving howto->src_mask isolates the upper
1039            bit of src_mask.  If that bit is set in the value we are
1040            adding, it is negative, and we subtract out that number times
1041            two.  If src_mask includes the highest possible bit, then we
1042            can not get the upper bit, but that does not matter since
1043            signed_add needs no adjustment to become negative in that case.  */
1044
1045         signed_add = add;
1046
1047         if ((add & (((~src_mask) >> 1) & src_mask)) != 0)
1048           signed_add -= (((~src_mask) >> 1) & src_mask) << 1;
1049
1050         /* Add the value from the object file, shifted so that it is a
1051            straight number.  */
1052         /* howto->bitpos == 0 */
1053
1054         signed_check += signed_add;
1055         relocation += signed_add;
1056
1057         /* Assumes two's complement.  */
1058         if (signed_check > reloc_signed_max
1059             || signed_check < reloc_signed_min)
1060           overflow = true;
1061
1062         /* Put RELOCATION into the correct bits:  */
1063
1064         if (bfd_big_endian (input_bfd))
1065           relocation = (((relocation & 0xffe) >> 1) | ((relocation << 4) & 0x07ff0000));
1066         else
1067           relocation = (((relocation & 0xffe) << 15) | ((relocation >> 12) & 0x7ff));
1068
1069         /* Add RELOCATION to the correct bits of X:  */
1070         insn = ((insn & ~howto->dst_mask) | relocation);
1071
1072         /* Put the relocated value back in the object file:  */
1073         bfd_put_32 (input_bfd, insn, hit_data);
1074
1075         return (overflow ? bfd_reloc_overflow : bfd_reloc_ok);
1076       }
1077       break;
1078
1079     case R_ARM_GNU_VTINHERIT:
1080     case R_ARM_GNU_VTENTRY:
1081       return bfd_reloc_ok;
1082
1083     case R_ARM_SBREL32:
1084       return bfd_reloc_notsupported;
1085
1086     case R_ARM_AMP_VCALL9:
1087       return bfd_reloc_notsupported;
1088
1089     case R_ARM_RSBREL32:
1090       return bfd_reloc_notsupported;
1091
1092     case R_ARM_THM_RPC22:
1093       return bfd_reloc_notsupported;
1094
1095     case R_ARM_RREL32:
1096       return bfd_reloc_notsupported;
1097
1098     case R_ARM_RABS32:
1099       return bfd_reloc_notsupported;
1100
1101     case R_ARM_RPC24:
1102       return bfd_reloc_notsupported;
1103
1104     case R_ARM_RBASE:
1105       return bfd_reloc_notsupported;
1106
1107     default:
1108       return bfd_reloc_notsupported;
1109     }
1110 }
1111
1112
1113 /* Relocate an ARM ELF section.  */
1114 static boolean
1115 elf32_arm_relocate_section (output_bfd, info, input_bfd, input_section,
1116                             contents, relocs, local_syms, local_sections)
1117      bfd *output_bfd;
1118      struct bfd_link_info *info;
1119      bfd *input_bfd;
1120      asection *input_section;
1121      bfd_byte *contents;
1122      Elf_Internal_Rela *relocs;
1123      Elf_Internal_Sym *local_syms;
1124      asection **local_sections;
1125 {
1126   Elf_Internal_Shdr *symtab_hdr;
1127   struct elf_link_hash_entry **sym_hashes;
1128   Elf_Internal_Rela *rel, *relend;
1129   const char *name;
1130
1131   symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
1132   sym_hashes = elf_sym_hashes (input_bfd);
1133
1134   rel = relocs;
1135   relend = relocs + input_section->reloc_count;
1136   for (; rel < relend; rel++)
1137     {
1138       int r_type;
1139       reloc_howto_type *howto;
1140       unsigned long r_symndx;
1141       Elf_Internal_Sym *sym;
1142       asection *sec;
1143       struct elf_link_hash_entry *h;
1144       bfd_vma relocation;
1145       bfd_reloc_status_type r;
1146
1147       r_symndx = ELF32_R_SYM (rel->r_info);
1148       r_type = ELF32_R_TYPE (rel->r_info);
1149
1150       if (r_type == R_ARM_GNU_VTENTRY
1151           || r_type == R_ARM_GNU_VTINHERIT )
1152         continue;
1153
1154       howto = elf32_arm_howto_table + r_type;
1155
1156       if (info->relocateable)
1157         {
1158           /* This is a relocateable link.  We don't have to change
1159              anything, unless the reloc is against a section symbol,
1160              in which case we have to adjust according to where the
1161              section symbol winds up in the output section.  */
1162           if (r_symndx < symtab_hdr->sh_info)
1163             {
1164               sym = local_syms + r_symndx;
1165               if (ELF_ST_TYPE (sym->st_info) == STT_SECTION)
1166                 {
1167                   sec = local_sections[r_symndx];
1168                   rel->r_addend += sec->output_offset + sym->st_value;
1169                 }
1170             }
1171
1172           continue;
1173         }
1174
1175       /* This is a final link.  */
1176       h = NULL;
1177       sym = NULL;
1178       sec = NULL;
1179       if (r_symndx < symtab_hdr->sh_info)
1180         {
1181           sym = local_syms + r_symndx;
1182           sec = local_sections[r_symndx];
1183           relocation = (sec->output_section->vma
1184                         + sec->output_offset
1185                         + sym->st_value);
1186         }
1187       else
1188         {
1189           h = sym_hashes[r_symndx - symtab_hdr->sh_info];
1190           while (h->root.type == bfd_link_hash_indirect
1191                  || h->root.type == bfd_link_hash_warning)
1192             h = (struct elf_link_hash_entry *) h->root.u.i.link;
1193           if (h->root.type == bfd_link_hash_defined
1194               || h->root.type == bfd_link_hash_defweak)
1195             {
1196               sec = h->root.u.def.section;
1197               relocation = (h->root.u.def.value
1198                             + sec->output_section->vma
1199                             + sec->output_offset);
1200             }
1201           else if (h->root.type == bfd_link_hash_undefweak)
1202             relocation = 0;
1203           else
1204             {
1205               if (!((*info->callbacks->undefined_symbol)
1206                     (info, h->root.root.string, input_bfd,
1207                      input_section, rel->r_offset)))
1208                 return false;
1209               relocation = 0;
1210             }
1211         }
1212
1213       if (h != NULL)
1214         name = h->root.root.string;
1215       else
1216         {
1217           name = (bfd_elf_string_from_elf_section
1218                   (input_bfd, symtab_hdr->sh_link, sym->st_name));
1219           if (name == NULL || *name == '\0')
1220             name = bfd_section_name (input_bfd, sec);
1221         }
1222       
1223       r = elf32_arm_final_link_relocate (howto, input_bfd, output_bfd,
1224                                          input_section,
1225                                          contents, rel->r_offset,
1226                                          relocation, rel->r_addend,
1227                                          info, sec, name,
1228                                          (h ? ELF_ST_TYPE (h->type) :
1229                                           ELF_ST_TYPE (sym->st_info)));
1230
1231       if (r != bfd_reloc_ok)
1232         {
1233           const char * msg = (const char *) 0;
1234
1235           switch (r)
1236             {
1237             case bfd_reloc_overflow:
1238               if (!((*info->callbacks->reloc_overflow)
1239                     (info, name, howto->name, (bfd_vma) 0,
1240                      input_bfd, input_section, rel->r_offset)))
1241                 return false;
1242               break;
1243
1244             case bfd_reloc_undefined:
1245               if (!((*info->callbacks->undefined_symbol)
1246                     (info, name, input_bfd, input_section,
1247                      rel->r_offset)))
1248                 return false;
1249               break;
1250
1251             case bfd_reloc_outofrange:
1252               msg = _ ("internal error: out of range error");
1253               goto common_error;
1254
1255             case bfd_reloc_notsupported:
1256               msg = _ ("internal error: unsupported relocation error");
1257               goto common_error;
1258
1259             case bfd_reloc_dangerous:
1260               msg = _ ("internal error: dangerous error");
1261               goto common_error;
1262
1263             default:
1264               msg = _ ("internal error: unknown error");
1265               /* fall through */
1266
1267             common_error:
1268               if (!((*info->callbacks->warning)
1269                     (info, msg, name, input_bfd, input_section,
1270                      rel->r_offset)))
1271                 return false;
1272               break;
1273             }
1274         }
1275     }
1276
1277   return true;
1278 }
1279
1280 /* Function to keep ARM specific flags in the ELF header. */
1281 static boolean
1282 elf32_arm_set_private_flags (abfd, flags)
1283      bfd *abfd;
1284      flagword flags;
1285 {
1286   if (elf_flags_init (abfd)
1287       && elf_elfheader (abfd)->e_flags != flags)
1288     {
1289       if (flags & EF_INTERWORK)
1290         _bfd_error_handler (_ ("\
1291 Warning: Not setting interwork flag of %s since it has already been specified as non-interworking"),
1292                             bfd_get_filename (abfd));
1293       else
1294         _bfd_error_handler (_ ("\
1295 Warning: Clearing the interwork flag of %s due to outside request"),
1296                             bfd_get_filename (abfd));
1297     }
1298   else
1299     {
1300       elf_elfheader (abfd)->e_flags = flags;
1301       elf_flags_init (abfd) = true;
1302     }
1303
1304   return true;
1305 }
1306
1307 /* Copy backend specific data from one object module to another */
1308 static boolean
1309 elf32_arm_copy_private_bfd_data (ibfd, obfd)
1310      bfd *ibfd;
1311      bfd *obfd;
1312 {
1313   flagword in_flags;
1314   flagword out_flags;
1315
1316   if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour
1317       || bfd_get_flavour (obfd) != bfd_target_elf_flavour)
1318     return true;
1319
1320   in_flags = elf_elfheader (ibfd)->e_flags;
1321   out_flags = elf_elfheader (obfd)->e_flags;
1322
1323   if (elf_flags_init (obfd) && in_flags != out_flags)
1324     {
1325       /* Cannot mix PIC and non-PIC code.  */
1326       if ((in_flags & EF_PIC) != (out_flags & EF_PIC))
1327         return false;
1328
1329       /* Cannot mix APCS26 and APCS32 code.  */
1330       if ((in_flags & EF_APCS_26) != (out_flags & EF_APCS_26))
1331         return false;
1332
1333       /* Cannot mix float APCS and non-float APCS code.  */
1334       if ((in_flags & EF_APCS_FLOAT) != (out_flags & EF_APCS_FLOAT))
1335         return false;
1336
1337       /* If the src and dest have different interworking flags
1338          then turn off the interworking bit.  */
1339       if ((in_flags & EF_INTERWORK) != (out_flags & EF_INTERWORK))
1340         {
1341           if (out_flags & EF_INTERWORK)
1342             _bfd_error_handler (_ ("\
1343 Warning: Clearing the interwork flag in %s because non-interworking code in %s has been linked with it"),
1344                           bfd_get_filename (obfd), bfd_get_filename (ibfd));
1345
1346           in_flags &= ~EF_INTERWORK;
1347         }
1348     }
1349
1350   elf_elfheader (obfd)->e_flags = in_flags;
1351   elf_flags_init (obfd) = true;
1352
1353   return true;
1354 }
1355
1356 /* Merge backend specific data from an object file to the output
1357    object file when linking.  */
1358 static boolean
1359 elf32_arm_merge_private_bfd_data (ibfd, obfd)
1360      bfd *ibfd;
1361      bfd *obfd;
1362 {
1363   flagword out_flags;
1364   flagword in_flags;
1365
1366   if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour
1367       || bfd_get_flavour (obfd) != bfd_target_elf_flavour)
1368     return true;
1369
1370   /* The input BFD must have had its flags initialised.  */
1371   /* The following seems bogus to me -- The flags are initialized in
1372      the assembler but I don't think an elf_flags_init field is
1373      written into the object */
1374   /* BFD_ASSERT (elf_flags_init (ibfd)); */
1375
1376   in_flags = elf_elfheader (ibfd)->e_flags;
1377   out_flags = elf_elfheader (obfd)->e_flags;
1378
1379   if (!elf_flags_init (obfd))
1380     {
1381       /* If the input is the default architecture then do not
1382          bother setting the flags for the output architecture,
1383          instead allow future merges to do this.  If no future
1384          merges ever set these flags then they will retain their
1385          unitialised values, which surprise surprise, correspond
1386          to the default values.  */
1387       if (bfd_get_arch_info (ibfd)->the_default)
1388         return true;
1389
1390       elf_flags_init (obfd) = true;
1391       elf_elfheader (obfd)->e_flags = in_flags;
1392
1393       if (bfd_get_arch (obfd) == bfd_get_arch (ibfd)
1394           && bfd_get_arch_info (obfd)->the_default)
1395         return bfd_set_arch_mach (obfd, bfd_get_arch (ibfd), bfd_get_mach (ibfd));
1396
1397       return true;
1398     }
1399
1400   /* Check flag compatibility.  */
1401   if (in_flags == out_flags)
1402     return true;
1403
1404   /* Complain about various flag mismatches.  */
1405
1406   if ((in_flags & EF_APCS_26) != (out_flags & EF_APCS_26))
1407     _bfd_error_handler (_ ("\
1408 Error: %s compiled for APCS-%d, whereas %s is compiled for APCS-%d"),
1409                         bfd_get_filename (ibfd),
1410                         in_flags & EF_APCS_26 ? 26 : 32,
1411                         bfd_get_filename (obfd),
1412                         out_flags & EF_APCS_26 ? 26 : 32);
1413
1414   if ((in_flags & EF_APCS_FLOAT) != (out_flags & EF_APCS_FLOAT))
1415     _bfd_error_handler (_ ("\
1416 Error: %s passes floats in %s registers, whereas %s passes them in %s registers"),
1417                         bfd_get_filename (ibfd),
1418                      in_flags & EF_APCS_FLOAT ? _ ("float") : _ ("integer"),
1419                         bfd_get_filename (obfd),
1420                       out_flags & EF_APCS_26 ? _ ("float") : _ ("integer"));
1421
1422   if ((in_flags & EF_PIC) != (out_flags & EF_PIC))
1423     _bfd_error_handler (_ ("\
1424 Error: %s is compiled as position %s code, whereas %s is not"),
1425                         bfd_get_filename (ibfd),
1426                     in_flags & EF_PIC ? _ ("independent") : _ ("dependent"),
1427                         bfd_get_filename (obfd));
1428
1429   /* Interworking mismatch is only a warning. */
1430   if ((in_flags & EF_INTERWORK) != (out_flags & EF_INTERWORK))
1431     {
1432       _bfd_error_handler (_ ("\
1433 Warning: %s %s interworking, whereas %s %s"),
1434                           bfd_get_filename (ibfd),
1435           in_flags & EF_INTERWORK ? _ ("supports") : _ ("does not support"),
1436                           bfd_get_filename (obfd),
1437                     out_flags & EF_INTERWORK ? _ ("does not") : _ ("does"));
1438       return true;
1439     }
1440
1441   return false;
1442 }
1443
1444 /* Display the flags field */
1445 static boolean
1446 elf32_arm_print_private_bfd_data (abfd, ptr)
1447      bfd *abfd;
1448      PTR ptr;
1449 {
1450   FILE *file = (FILE *) ptr;
1451
1452   BFD_ASSERT (abfd != NULL && ptr != NULL);
1453
1454   /* Print normal ELF private data.  */
1455   _bfd_elf_print_private_bfd_data (abfd, ptr);
1456
1457   /* Ignore init flag - it may not be set, despite the flags field containing valid data.  */
1458
1459   /* xgettext:c-format */
1460   fprintf (file, _ ("private flags = %lx:"), elf_elfheader (abfd)->e_flags);
1461
1462   if (elf_elfheader (abfd)->e_flags & EF_INTERWORK)
1463     fprintf (file, _ (" [interworking enabled]"));
1464   else
1465     fprintf (file, _ (" [interworking not enabled]"));
1466
1467   if (elf_elfheader (abfd)->e_flags & EF_APCS_26)
1468     fprintf (file, _ (" [APCS-26]"));
1469   else
1470     fprintf (file, _ (" [APCS-32]"));
1471
1472   if (elf_elfheader (abfd)->e_flags & EF_APCS_FLOAT)
1473     fprintf (file, _ (" [floats passed in float registers]"));
1474   else
1475     fprintf (file, _ (" [floats passed in integer registers]"));
1476
1477   if (elf_elfheader (abfd)->e_flags & EF_PIC)
1478     fprintf (file, _ (" [position independent]"));
1479   else
1480     fprintf (file, _ (" [absolute position]"));
1481
1482   fputc ('\n', file);
1483
1484   return true;
1485 }
1486
1487 static int
1488 elf32_arm_get_symbol_type (elf_sym, type)
1489      Elf_Internal_Sym * elf_sym;
1490      int type;
1491 {
1492   if (ELF_ST_TYPE (elf_sym->st_info) == STT_ARM_TFUNC)
1493     return ELF_ST_TYPE (elf_sym->st_info);
1494   else
1495     return type;
1496 }
1497     
1498 static asection *
1499 elf32_arm_gc_mark_hook (abfd, info, rel, h, sym)
1500        bfd *abfd;
1501        struct bfd_link_info *info;
1502        Elf_Internal_Rela *rel;
1503        struct elf_link_hash_entry *h;
1504        Elf_Internal_Sym *sym;
1505 {
1506   if (h != NULL)
1507     {
1508       switch (ELF32_R_TYPE (rel->r_info))
1509       {
1510       case R_ARM_GNU_VTINHERIT:
1511       case R_ARM_GNU_VTENTRY:
1512         break;
1513
1514       default:
1515         switch (h->root.type)
1516           {
1517           case bfd_link_hash_defined:
1518           case bfd_link_hash_defweak:
1519             return h->root.u.def.section;
1520
1521           case bfd_link_hash_common:
1522             return h->root.u.c.p->section;
1523           }
1524        }
1525      }
1526    else
1527      {
1528        if (!(elf_bad_symtab (abfd)
1529            && ELF_ST_BIND (sym->st_info) != STB_LOCAL)
1530          && ! ((sym->st_shndx <= 0 || sym->st_shndx >= SHN_LORESERVE)
1531                 && sym->st_shndx != SHN_COMMON))
1532           {
1533             return bfd_section_from_elf_index (abfd, sym->st_shndx);
1534           }
1535       }
1536   return NULL;
1537 }
1538
1539 static boolean
1540 elf32_arm_gc_sweep_hook (abfd, info, sec, relocs)
1541      bfd *abfd;
1542      struct bfd_link_info *info;
1543      asection *sec;
1544      const Elf_Internal_Rela *relocs;
1545 {
1546   /* we don't use got and plt entries for armelf */
1547   return true;
1548 }
1549
1550 /* Look through the relocs for a section during the first phase.
1551    Since we don't do .gots or .plts, we just need to consider the
1552    virtual table relocs for gc.  */
1553  
1554 static boolean
1555 elf32_arm_check_relocs (abfd, info, sec, relocs)
1556      bfd *abfd;
1557      struct bfd_link_info *info;
1558      asection *sec;
1559      const Elf_Internal_Rela *relocs;
1560 {
1561   Elf_Internal_Shdr *symtab_hdr;
1562   struct elf_link_hash_entry **sym_hashes, **sym_hashes_end;
1563   const Elf_Internal_Rela *rel;
1564   const Elf_Internal_Rela *rel_end;
1565  
1566   if (info->relocateable)
1567     return true;
1568  
1569   symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
1570   sym_hashes = elf_sym_hashes (abfd);
1571   sym_hashes_end = sym_hashes + symtab_hdr->sh_size/sizeof(Elf32_External_Sym);
1572   if (!elf_bad_symtab (abfd))
1573     sym_hashes_end -= symtab_hdr->sh_info;
1574  
1575   rel_end = relocs + sec->reloc_count;
1576   for (rel = relocs; rel < rel_end; rel++)
1577     {
1578       struct elf_link_hash_entry *h;
1579       unsigned long r_symndx;
1580  
1581       r_symndx = ELF32_R_SYM (rel->r_info);
1582       if (r_symndx < symtab_hdr->sh_info)
1583         h = NULL;
1584       else
1585         h = sym_hashes[r_symndx - symtab_hdr->sh_info];
1586  
1587       switch (ELF32_R_TYPE (rel->r_info))
1588         {
1589         /* This relocation describes the C++ object vtable hierarchy.
1590            Reconstruct it for later use during GC.  */
1591         case R_ARM_GNU_VTINHERIT:
1592           if (!_bfd_elf32_gc_record_vtinherit (abfd, sec, h, rel->r_offset))
1593             return false;
1594           break;
1595  
1596         /* This relocation describes which C++ vtable entries are actually
1597            used.  Record for later use during GC.  */
1598         case R_ARM_GNU_VTENTRY:
1599           if (!_bfd_elf32_gc_record_vtentry (abfd, sec, h, rel->r_addend))
1600             return false;
1601           break;
1602         }
1603     }
1604  
1605   return true;
1606 }
1607
1608        
1609 /* Find the nearest line to a particular section and offset, for error
1610    reporting.   This code is a duplicate of the code in elf.c, except
1611    that it also accepts STT_ARM_TFUNC as a symbol that names a function. */
1612
1613 boolean
1614 elf32_arm_find_nearest_line
1615   (abfd, section, symbols, offset, filename_ptr, functionname_ptr, line_ptr)
1616      bfd *          abfd;
1617      asection *     section;
1618      asymbol **     symbols;
1619      bfd_vma        offset;
1620      CONST char **  filename_ptr;
1621      CONST char **  functionname_ptr;
1622      unsigned int * line_ptr;
1623 {
1624   boolean      found;
1625   const char * filename;
1626   asymbol *    func;
1627   bfd_vma      low_func;
1628   asymbol **   p;
1629
1630   if (_bfd_dwarf2_find_nearest_line (abfd, section, symbols, offset,
1631                                      filename_ptr, functionname_ptr, 
1632                                      line_ptr))
1633     return true;
1634
1635   if (! _bfd_stab_section_find_nearest_line (abfd, symbols, section, offset,
1636                                              &found, filename_ptr,
1637                                              functionname_ptr, line_ptr,
1638                                              &elf_tdata (abfd)->line_info))
1639     return false;
1640   
1641   if (found)
1642     return true;
1643
1644   if (symbols == NULL)
1645     return false;
1646
1647   filename = NULL;
1648   func = NULL;
1649   low_func = 0;
1650
1651   for (p = symbols; *p != NULL; p++)
1652     {
1653       elf_symbol_type *q;
1654
1655       q = (elf_symbol_type *) *p;
1656
1657       if (bfd_get_section (&q->symbol) != section)
1658         continue;
1659
1660       switch (ELF_ST_TYPE (q->internal_elf_sym.st_info))
1661         {
1662         default:
1663           break;
1664         case STT_FILE:
1665           filename = bfd_asymbol_name (&q->symbol);
1666           break;
1667         case STT_NOTYPE:
1668         case STT_FUNC:
1669         case STT_ARM_TFUNC:
1670           if (q->symbol.section == section
1671               && q->symbol.value >= low_func
1672               && q->symbol.value <= offset)
1673             {
1674               func = (asymbol *) q;
1675               low_func = q->symbol.value;
1676             }
1677           break;
1678         }
1679     }
1680
1681   if (func == NULL)
1682     return false;
1683
1684   *filename_ptr = filename;
1685   *functionname_ptr = bfd_asymbol_name (func);
1686   *line_ptr = 0;
1687   
1688   return true;
1689 }
1690
1691 #define ELF_ARCH                        bfd_arch_arm
1692 #define ELF_MACHINE_CODE                EM_ARM
1693
1694 #define bfd_elf32_bfd_reloc_type_lookup         elf32_arm_reloc_type_lookup
1695 #define elf_backend_relocate_section            elf32_arm_relocate_section
1696 #define bfd_elf32_bfd_copy_private_bfd_data     elf32_arm_copy_private_bfd_data
1697 #define bfd_elf32_bfd_merge_private_bfd_data    elf32_arm_merge_private_bfd_data
1698 #define bfd_elf32_bfd_set_private_flags         elf32_arm_set_private_flags
1699 #define bfd_elf32_bfd_print_private_bfd_data    elf32_arm_print_private_bfd_data
1700 #define bfd_elf32_bfd_link_hash_table_create    elf32_arm_link_hash_table_create
1701 #define bfd_elf32_find_nearest_line             elf32_arm_find_nearest_line
1702 #define elf_backend_get_symbol_type             elf32_arm_get_symbol_type
1703 #define elf_backend_gc_mark_hook                elf32_arm_gc_mark_hook
1704 #define elf_backend_gc_sweep_hook               elf32_arm_gc_sweep_hook
1705 #define elf_backend_check_relocs                elf32_arm_check_relocs
1706
1707 #define elf_backend_can_gc_sections 1
1708
1709 #include "elf32-target.h"