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