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