This commit was generated by cvs2svn to track changes on a CVS vendor
[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 *, int));
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   /* GNU extension to record C++ vtable hierarchy */
827   HOWTO (R_ARM_GNU_VTINHERIT, /* type */
828          0,                     /* rightshift */
829          2,                     /* size (0 = byte, 1 = short, 2 = long) */
830          0,                     /* bitsize */
831          false,                 /* pc_relative */
832          0,                     /* bitpos */
833          complain_overflow_dont, /* complain_on_overflow */
834          NULL,                  /* special_function */
835          "R_ARM_GNU_VTINHERIT", /* name */
836          false,                 /* partial_inplace */
837          0,                     /* src_mask */
838          0,                     /* dst_mask */
839          false),                /* pcrel_offset */
840
841   /* GNU extension to record C++ vtable member usage */
842   HOWTO (R_ARM_GNU_VTENTRY,     /* type */
843          0,                     /* rightshift */
844          2,                     /* size (0 = byte, 1 = short, 2 = long) */
845          0,                     /* bitsize */
846          false,                 /* pc_relative */
847          0,                     /* bitpos */
848          complain_overflow_dont, /* complain_on_overflow */
849          _bfd_elf_rel_vtable_reloc_fn,  /* special_function */
850          "R_ARM_GNU_VTENTRY",   /* name */
851          false,                 /* partial_inplace */
852          0,                     /* src_mask */
853          0,                     /* dst_mask */
854          false),                /* pcrel_offset */
855  
856
857   HOWTO (R_ARM_RREL32,          /* 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_RREL32",        /* name */
866          false,                 /* partial_inplace */
867          0,                     /* src_mask */
868          0,                     /* dst_mask */
869          false),                /* pcrel_offset */
870
871   HOWTO (R_ARM_RABS32,          /* 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_RABS32",        /* name */
880          false,                 /* partial_inplace */
881          0,                     /* src_mask */
882          0,                     /* dst_mask */
883          false),                /* pcrel_offset */
884
885   HOWTO (R_ARM_RPC24,           /* type */
886          0,                     /* rightshift */
887          0,                     /* size (0 = byte, 1 = short, 2 = long) */
888          0,                     /* bitsize */
889          false,                 /* pc_relative */
890          0,                     /* bitpos */
891          complain_overflow_dont,        /* complain_on_overflow */
892          bfd_elf_generic_reloc, /* special_function */
893          "R_ARM_RPC24",         /* name */
894          false,                 /* partial_inplace */
895          0,                     /* src_mask */
896          0,                     /* dst_mask */
897          false),                /* pcrel_offset */
898
899   HOWTO (R_ARM_RBASE,           /* type */
900          0,                     /* rightshift */
901          0,                     /* size (0 = byte, 1 = short, 2 = long) */
902          0,                     /* bitsize */
903          false,                 /* pc_relative */
904          0,                     /* bitpos */
905          complain_overflow_dont,        /* complain_on_overflow */
906          bfd_elf_generic_reloc, /* special_function */
907          "R_ARM_RBASE",         /* name */
908          false,                 /* partial_inplace */
909          0,                     /* src_mask */
910          0,                     /* dst_mask */
911          false),                /* pcrel_offset */
912
913 };
914 struct elf32_arm_reloc_map
915   {
916     unsigned char bfd_reloc_val;
917     unsigned char elf_reloc_val;
918   };
919
920 static const struct elf32_arm_reloc_map elf32_arm_reloc_map[] =
921 {
922   {BFD_RELOC_NONE, R_ARM_NONE,},
923   {BFD_RELOC_ARM_PCREL_BRANCH, R_ARM_PC24,},
924   {BFD_RELOC_32, R_ARM_ABS32,},
925   {BFD_RELOC_32_PCREL, R_ARM_REL32,},
926   {BFD_RELOC_8, R_ARM_ABS8,},
927   {BFD_RELOC_16, R_ARM_ABS16,},
928   {BFD_RELOC_ARM_OFFSET_IMM, R_ARM_ABS12,},
929   {BFD_RELOC_ARM_THUMB_OFFSET, R_ARM_THM_ABS5,},
930   {BFD_RELOC_THUMB_PCREL_BRANCH23, R_ARM_THM_PC22,},
931   {BFD_RELOC_VTABLE_INHERIT, R_ARM_GNU_VTINHERIT },
932   {BFD_RELOC_VTABLE_ENTRY, R_ARM_GNU_VTENTRY },
933   {BFD_RELOC_NONE, R_ARM_SBREL32,},
934   {BFD_RELOC_NONE, R_ARM_AMP_VCALL9,},
935   {BFD_RELOC_THUMB_PCREL_BRANCH12, R_ARM_THM_PC11,},
936   {BFD_RELOC_THUMB_PCREL_BRANCH9, R_ARM_THM_PC9,}
937 };
938
939 static reloc_howto_type *
940 elf32_arm_reloc_type_lookup (abfd, code)
941      bfd *abfd;
942      bfd_reloc_code_real_type code;
943 {
944   unsigned int i;
945
946   for (i = 0;
947      i < sizeof (elf32_arm_reloc_map) / sizeof (struct elf32_arm_reloc_map);
948        i++)
949     {
950       if (elf32_arm_reloc_map[i].bfd_reloc_val == code)
951         return &elf32_arm_howto_table[elf32_arm_reloc_map[i].elf_reloc_val];
952     }
953
954   return NULL;
955 }
956
957 static void
958 elf32_arm_info_to_howto (abfd, bfd_reloc, elf_reloc)
959      bfd *abfd;
960      arelent *bfd_reloc;
961      Elf32_Internal_Rela *elf_reloc;
962 {
963   unsigned int r_type;
964
965   r_type = ELF32_R_TYPE (elf_reloc->r_info);
966   /* fixme: need range test */
967   /* BFD_ASSERT (r_type < (unsigned int) R_ELF32_ARM_MAX); */
968   bfd_reloc->howto = &elf32_arm_howto_table[r_type];
969 }
970
971 /* The thumb form of a long branch is a bit finicky, because the offset
972    encoding is split over two fields, each in it's own instruction. They
973    can occur in any order. So given a thumb form of long branch, and an 
974    offset, insert the offset into the thumb branch and return finished
975    instruction. 
976
977    It takes two thumb instructions to encode the target address. Each has 
978    11 bits to invest. The upper 11 bits are stored in one (identifed by
979    H-0.. see below), the lower 11 bits are stored in the other (identified 
980    by H-1). 
981
982    Combine together and shifted left by 1 (it's a half word address) and 
983    there you have it.
984
985    Op: 1111 = F,
986    H-0, upper address-0 = 000
987    Op: 1111 = F,
988    H-1, lower address-0 = 800
989
990    They can be ordered either way, but the arm tools I've seen always put 
991    the lower one first. It probably doesn't matter. krk@cygnus.com
992
993    XXX:  Actually the order does matter.  The second instruction (H-1)
994    moves the computed address into the PC, so it must be the second one
995    in the sequence.  The problem, however is that whilst little endian code
996    stores the instructions in HI then LOW order, big endian code does the
997    reverse.  nickc@cygnus.com  */
998
999 #define LOW_HI_ORDER 0xF800F000
1000 #define HI_LOW_ORDER 0xF000F800
1001
1002 static insn32
1003 insert_thumb_branch (br_insn, rel_off)
1004      insn32 br_insn;
1005      int rel_off;
1006 {
1007   unsigned int low_bits;
1008   unsigned int high_bits;
1009
1010
1011   BFD_ASSERT ((rel_off & 1) != 1);
1012
1013   rel_off >>= 1;                /* half word aligned address */
1014   low_bits = rel_off & 0x000007FF;      /* the bottom 11 bits */
1015   high_bits = (rel_off >> 11) & 0x000007FF;     /* the top 11 bits */
1016
1017   if ((br_insn & LOW_HI_ORDER) == LOW_HI_ORDER)
1018     br_insn = LOW_HI_ORDER | (low_bits << 16) | high_bits;
1019   else if ((br_insn & HI_LOW_ORDER) == HI_LOW_ORDER)
1020     br_insn = HI_LOW_ORDER | (high_bits << 16) | low_bits;
1021   else
1022     abort ();                   /* error - not a valid branch instruction form */
1023
1024   /* FIXME: abort is probably not the right call. krk@cygnus.com */
1025
1026   return br_insn;
1027 }
1028
1029 /* Thumb code calling an ARM function */
1030 int
1031 elf32_thumb_to_arm_stub (info, name, input_bfd, output_bfd, input_section,
1032                          hit_data, sym_sec, offset, addend, val)
1033      struct bfd_link_info *info;
1034      char *name;
1035      bfd *input_bfd;
1036      bfd *output_bfd;
1037      asection *input_section;
1038      bfd_byte *hit_data;
1039      asection *sym_sec;
1040      int offset;
1041      int addend;
1042      bfd_vma val;
1043 {
1044   asection *s = 0;
1045   long int my_offset;
1046   unsigned long int tmp;
1047   long int ret_offset;
1048   struct elf_link_hash_entry *myh;
1049   struct elf32_arm_link_hash_table *globals;
1050
1051   myh = find_thumb_glue (info, name, input_bfd);
1052   if (myh == NULL)
1053     return false;
1054
1055   globals = elf32_arm_hash_table (info);
1056
1057   BFD_ASSERT (globals != NULL);
1058   BFD_ASSERT (globals->bfd_of_glue_owner != NULL);
1059
1060   my_offset = myh->root.u.def.value;
1061
1062   s = bfd_get_section_by_name (globals->bfd_of_glue_owner,
1063                                THUMB2ARM_GLUE_SECTION_NAME);
1064
1065   BFD_ASSERT (s != NULL);
1066   BFD_ASSERT (s->contents != NULL);
1067   BFD_ASSERT (s->output_section != NULL);
1068
1069   if ((my_offset & 0x01) == 0x01)
1070     {
1071       if (sym_sec != NULL
1072           && sym_sec->owner != NULL
1073           && !INTERWORK_FLAG (sym_sec->owner))
1074         {
1075           _bfd_error_handler
1076             (_ ("%s(%s): warning: interworking not enabled."),
1077              bfd_get_filename (sym_sec->owner), name);
1078           _bfd_error_handler
1079             (_ ("  first occurrence: %s: thumb call to arm"),
1080              bfd_get_filename (input_bfd));
1081
1082           return false;
1083         }
1084
1085       --my_offset;
1086       myh->root.u.def.value = my_offset;
1087
1088       bfd_put_16 (output_bfd, t2a1_bx_pc_insn,
1089                   s->contents + my_offset);
1090
1091       bfd_put_16 (output_bfd, t2a2_noop_insn,
1092                   s->contents + my_offset + 2);
1093
1094       ret_offset =
1095         ((bfd_signed_vma) val)  /* Address of destination of the stub */
1096         - ((bfd_signed_vma)
1097            (s->output_offset    /* Offset from the start of the current section to the start of the stubs.  */
1098             + my_offset         /* Offset of the start of this stub from the start of the stubs.  */
1099             + s->output_section->vma)   /* Address of the start of the current section.  */
1100            + 4                  /* The branch instruction is 4 bytes into the stub.  */
1101            + 8);                /* ARM branches work from the pc of the instruction + 8.  */
1102
1103       bfd_put_32 (output_bfd,
1104                   t2a3_b_insn | ((ret_offset >> 2) & 0x00FFFFFF),
1105                   s->contents + my_offset + 4);
1106     }
1107
1108   BFD_ASSERT (my_offset <= globals->thumb_glue_size);
1109
1110   /* Now go back and fix up the original BL insn to point
1111      to here.  */
1112   ret_offset =
1113     s->output_offset
1114     + my_offset
1115     - (input_section->output_offset
1116        + offset + addend)
1117     - 4;
1118
1119   tmp = bfd_get_32 (input_bfd, hit_data
1120                     - input_section->vma);
1121
1122   bfd_put_32 (output_bfd,
1123               insert_thumb_branch (tmp, ret_offset),
1124               hit_data - input_section->vma);
1125
1126   return true;
1127 }
1128
1129 /* Arm code calling a Thumb function */
1130 int
1131 elf32_arm_to_thumb_stub (info, name, input_bfd, output_bfd, input_section,
1132                          hit_data, sym_sec, offset, addend, val)
1133
1134      struct bfd_link_info *info;
1135      char *name;
1136      bfd *input_bfd;
1137      bfd *output_bfd;
1138      asection *input_section;
1139      bfd_byte *hit_data;
1140      asection *sym_sec;
1141      int offset;
1142      int addend;
1143      bfd_vma val;
1144 {
1145   unsigned long int tmp;
1146   long int my_offset;
1147   asection *s;
1148   long int ret_offset;
1149   struct elf_link_hash_entry *myh;
1150   struct elf32_arm_link_hash_table *globals;
1151
1152   myh = find_arm_glue (info, name, input_bfd);
1153   if (myh == NULL)
1154     return false;
1155
1156   globals = elf32_arm_hash_table (info);
1157
1158   BFD_ASSERT (globals != NULL);
1159   BFD_ASSERT (globals->bfd_of_glue_owner != NULL);
1160
1161   my_offset = myh->root.u.def.value;
1162   s = bfd_get_section_by_name (globals->bfd_of_glue_owner,
1163                                ARM2THUMB_GLUE_SECTION_NAME);
1164   BFD_ASSERT (s != NULL);
1165   BFD_ASSERT (s->contents != NULL);
1166   BFD_ASSERT (s->output_section != NULL);
1167
1168   if ((my_offset & 0x01) == 0x01)
1169     {
1170       if (sym_sec != NULL
1171           && sym_sec->owner != NULL
1172           && !INTERWORK_FLAG (sym_sec->owner))
1173         {
1174           _bfd_error_handler
1175             (_ ("%s(%s): warning: interworking not enabled."),
1176              bfd_get_filename (sym_sec->owner), name);
1177           _bfd_error_handler
1178             (_ ("  first occurrence: %s: arm call to thumb"),
1179              bfd_get_filename (input_bfd));
1180         }
1181       --my_offset;
1182       myh->root.u.def.value = my_offset;
1183
1184       bfd_put_32 (output_bfd, a2t1_ldr_insn,
1185                   s->contents + my_offset);
1186
1187       bfd_put_32 (output_bfd, a2t2_bx_r12_insn,
1188                   s->contents + my_offset + 4);
1189
1190       /* It's a thumb address.  Add the low order bit.  */
1191       bfd_put_32 (output_bfd, val | a2t3_func_addr_insn,
1192                   s->contents + my_offset + 8);
1193     }
1194
1195   BFD_ASSERT (my_offset <= globals->arm_glue_size);
1196
1197   tmp = bfd_get_32 (input_bfd, hit_data);
1198   tmp = tmp & 0xFF000000;
1199
1200   /* Somehow these are both 4 too far, so subtract 8. */
1201   ret_offset = s->output_offset
1202     + my_offset
1203     + s->output_section->vma
1204     - (input_section->output_offset
1205        + input_section->output_section->vma
1206        + offset + addend)
1207     - 8;
1208
1209   tmp = tmp | ((ret_offset >> 2) & 0x00FFFFFF);
1210
1211   bfd_put_32 (output_bfd, tmp, hit_data
1212               - input_section->vma);
1213
1214
1215   return true;
1216 }
1217
1218 /* Perform a relocation as part of a final link.  */
1219 static bfd_reloc_status_type
1220 elf32_arm_final_link_relocate (howto, input_bfd, output_bfd,
1221                                input_section, contents, offset, value,
1222                                addend, info, sym_sec, sym_name, sym_flags)
1223      reloc_howto_type *howto;
1224      bfd *input_bfd;
1225      bfd *output_bfd;
1226      asection *input_section;
1227      bfd_byte *contents;
1228      bfd_vma offset;
1229      bfd_vma value;
1230      bfd_vma addend;
1231      struct bfd_link_info *info;
1232      asection *sym_sec;
1233      const char *sym_name;
1234      unsigned char sym_flags;
1235 {
1236   unsigned long r_type = howto->type;
1237   bfd_byte *hit_data = contents + offset;
1238
1239   switch (r_type)
1240     {
1241
1242     case R_ARM_NONE:
1243       return bfd_reloc_ok;
1244
1245     case R_ARM_PC24:
1246       /* Arm B/BL instruction */
1247
1248       /* check for arm calling thumb function */
1249       if (sym_flags == STT_ARM_TFUNC)
1250         {
1251           elf32_arm_to_thumb_stub (info, sym_name, input_bfd, output_bfd,
1252                    input_section, hit_data, sym_sec, offset, addend, value);
1253           return bfd_reloc_ok;
1254         }
1255
1256       value = value + addend;
1257       value -= (input_section->output_section->vma
1258                 + input_section->output_offset + 8);
1259       value -= offset;
1260       value = value >> howto->rightshift;
1261
1262       value &= 0xffffff;
1263       value |= (bfd_get_32 (input_bfd, hit_data) & 0xff000000);
1264       bfd_put_32 (input_bfd, value, hit_data);
1265       return bfd_reloc_ok;
1266
1267     case R_ARM_ABS32:
1268       value += addend;
1269       if (sym_flags == STT_ARM_TFUNC)
1270         value |= 1;
1271       bfd_put_32 (input_bfd, value, hit_data);
1272       return bfd_reloc_ok;
1273
1274     case R_ARM_REL32:
1275       value -= (input_section->output_section->vma
1276                 + input_section->output_offset);
1277       value += addend;
1278
1279       bfd_put_32 (input_bfd, value, hit_data);
1280       return bfd_reloc_ok;
1281
1282     case R_ARM_ABS8:
1283       value += addend;
1284
1285       if ((long) value > 0x7f || (long) value < -0x80)
1286         return bfd_reloc_overflow;
1287
1288       bfd_put_8 (input_bfd, value, hit_data);
1289       return bfd_reloc_ok;
1290
1291     case R_ARM_ABS16:
1292       value += addend;
1293
1294       if ((long) value > 0x7fff || (long) value < -0x8000)
1295         return bfd_reloc_overflow;
1296
1297       bfd_put_16 (input_bfd, value, hit_data);
1298       return bfd_reloc_ok;
1299
1300     case R_ARM_ABS12:
1301       /* Support ldr and str instruction for the arm */
1302       /* Also thumb b (unconditional branch) */
1303       value += addend;
1304
1305       if ((long) value > 0x7ff || (long) value < -0x800)
1306         return bfd_reloc_overflow;
1307
1308       value |= (bfd_get_32 (input_bfd, hit_data) & 0xfffff000);
1309       bfd_put_32 (input_bfd, value, hit_data);
1310       return bfd_reloc_ok;
1311
1312     case R_ARM_THM_ABS5:
1313       /* Support ldr and str instructions for the thumb. */
1314       value += addend;
1315
1316       if ((long) value > 0x1f || (long) value < -0x10)
1317         return bfd_reloc_overflow;
1318
1319       value |= bfd_get_16 (input_bfd, hit_data) & 0xf82f;
1320       bfd_put_16 (input_bfd, value, hit_data);
1321       return bfd_reloc_ok;
1322
1323
1324     case R_ARM_THM_PC22:
1325       /* thumb BL (branch long instruction). */
1326       {
1327         bfd_vma relocation;
1328         boolean overflow = false;
1329         bfd_vma insn = bfd_get_32 (input_bfd, hit_data);
1330         bfd_vma src_mask = 0x007FFFFE;
1331         bfd_signed_vma reloc_signed_max = (1 << (howto->bitsize - 1)) - 1;
1332         bfd_signed_vma reloc_signed_min = ~reloc_signed_max;
1333         bfd_vma check;
1334         bfd_signed_vma signed_check;
1335         bfd_vma add;
1336         bfd_signed_vma signed_add;
1337
1338         /* If it's not a call to thumb, assume call to arm */
1339         if (sym_flags != STT_ARM_TFUNC)
1340           {
1341             if (elf32_thumb_to_arm_stub
1342                 (info, sym_name, input_bfd, output_bfd, input_section,
1343                  hit_data, sym_sec, offset, addend, value))
1344               return bfd_reloc_ok;
1345             else
1346               return bfd_reloc_dangerous;
1347           }
1348
1349         relocation = value + addend;
1350         relocation -= (input_section->output_section->vma + input_section->output_offset);
1351         relocation -= offset;
1352
1353         check = relocation >> howto->rightshift;
1354
1355         /* If this is a signed value, the rightshift just dropped
1356            leading 1 bits (assuming twos complement).  */
1357         if ((bfd_signed_vma) relocation >= 0)
1358           signed_check = check;
1359         else
1360           signed_check = (check | ((bfd_vma) - 1 & ~((bfd_vma) - 1 >> howto->rightshift)));
1361
1362         /* Get the value from the object file.  */
1363         if (bfd_big_endian (input_bfd))
1364           add = (((insn) & 0x07ff0000) >> 4) | (((insn) & 0x7ff) << 1);
1365         else
1366           add = ((((insn) & 0x7ff) << 12) | (((insn) & 0x07ff0000) >> 15));
1367
1368         /* Get the value from the object file with an appropriate sign.
1369            The expression involving howto->src_mask isolates the upper
1370            bit of src_mask.  If that bit is set in the value we are
1371            adding, it is negative, and we subtract out that number times
1372            two.  If src_mask includes the highest possible bit, then we
1373            can not get the upper bit, but that does not matter since
1374            signed_add needs no adjustment to become negative in that case.  */
1375
1376         signed_add = add;
1377
1378         if ((add & (((~src_mask) >> 1) & src_mask)) != 0)
1379           signed_add -= (((~src_mask) >> 1) & src_mask) << 1;
1380
1381         /* Add the value from the object file, shifted so that it is a
1382            straight number.  */
1383         /* howto->bitpos == 0 */
1384
1385         signed_check += signed_add;
1386         relocation += signed_add;
1387
1388         /* Assumes two's complement.  */
1389         if (signed_check > reloc_signed_max
1390             || signed_check < reloc_signed_min)
1391           overflow = true;
1392
1393         /* Put RELOCATION into the correct bits:  */
1394
1395         if (bfd_big_endian (input_bfd))
1396           relocation = (((relocation & 0xffe) >> 1) | ((relocation << 4) & 0x07ff0000));
1397         else
1398           relocation = (((relocation & 0xffe) << 15) | ((relocation >> 12) & 0x7ff));
1399
1400         /* Add RELOCATION to the correct bits of X:  */
1401         insn = ((insn & ~howto->dst_mask) | relocation);
1402
1403         /* Put the relocated value back in the object file:  */
1404         bfd_put_32 (input_bfd, insn, hit_data);
1405
1406         return (overflow ? bfd_reloc_overflow : bfd_reloc_ok);
1407       }
1408       break;
1409
1410     case R_ARM_GNU_VTINHERIT:
1411     case R_ARM_GNU_VTENTRY:
1412       return bfd_reloc_ok;
1413
1414     case R_ARM_SBREL32:
1415       return bfd_reloc_notsupported;
1416
1417     case R_ARM_AMP_VCALL9:
1418       return bfd_reloc_notsupported;
1419
1420     case R_ARM_RSBREL32:
1421       return bfd_reloc_notsupported;
1422
1423     case R_ARM_THM_RPC22:
1424       return bfd_reloc_notsupported;
1425
1426     case R_ARM_RREL32:
1427       return bfd_reloc_notsupported;
1428
1429     case R_ARM_RABS32:
1430       return bfd_reloc_notsupported;
1431
1432     case R_ARM_RPC24:
1433       return bfd_reloc_notsupported;
1434
1435     case R_ARM_RBASE:
1436       return bfd_reloc_notsupported;
1437
1438     default:
1439       return bfd_reloc_notsupported;
1440     }
1441 }
1442
1443
1444 /* Relocate an ARM ELF section.  */
1445 static boolean
1446 elf32_arm_relocate_section (output_bfd, info, input_bfd, input_section,
1447                             contents, relocs, local_syms, local_sections)
1448      bfd *output_bfd;
1449      struct bfd_link_info *info;
1450      bfd *input_bfd;
1451      asection *input_section;
1452      bfd_byte *contents;
1453      Elf_Internal_Rela *relocs;
1454      Elf_Internal_Sym *local_syms;
1455      asection **local_sections;
1456 {
1457   Elf_Internal_Shdr *symtab_hdr;
1458   struct elf_link_hash_entry **sym_hashes;
1459   Elf_Internal_Rela *rel, *relend;
1460   const char *name;
1461
1462   symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
1463   sym_hashes = elf_sym_hashes (input_bfd);
1464
1465   rel = relocs;
1466   relend = relocs + input_section->reloc_count;
1467   for (; rel < relend; rel++)
1468     {
1469       int r_type;
1470       reloc_howto_type *howto;
1471       unsigned long r_symndx;
1472       Elf_Internal_Sym *sym;
1473       asection *sec;
1474       struct elf_link_hash_entry *h;
1475       bfd_vma relocation;
1476       bfd_reloc_status_type r;
1477
1478       r_symndx = ELF32_R_SYM (rel->r_info);
1479       r_type = ELF32_R_TYPE (rel->r_info);
1480
1481       if (r_type == R_ARM_GNU_VTENTRY
1482           || r_type == R_ARM_GNU_VTINHERIT )
1483         continue;
1484
1485       howto = elf32_arm_howto_table + r_type;
1486
1487       if (info->relocateable)
1488         {
1489           /* This is a relocateable link.  We don't have to change
1490              anything, unless the reloc is against a section symbol,
1491              in which case we have to adjust according to where the
1492              section symbol winds up in the output section.  */
1493           if (r_symndx < symtab_hdr->sh_info)
1494             {
1495               sym = local_syms + r_symndx;
1496               if (ELF_ST_TYPE (sym->st_info) == STT_SECTION)
1497                 {
1498                   sec = local_sections[r_symndx];
1499                   rel->r_addend += sec->output_offset + sym->st_value;
1500                 }
1501             }
1502
1503           continue;
1504         }
1505
1506       /* This is a final link.  */
1507       h = NULL;
1508       sym = NULL;
1509       sec = NULL;
1510       if (r_symndx < symtab_hdr->sh_info)
1511         {
1512           sym = local_syms + r_symndx;
1513           sec = local_sections[r_symndx];
1514           relocation = (sec->output_section->vma
1515                         + sec->output_offset
1516                         + sym->st_value);
1517         }
1518       else
1519         {
1520           h = sym_hashes[r_symndx - symtab_hdr->sh_info];
1521           while (h->root.type == bfd_link_hash_indirect
1522                  || h->root.type == bfd_link_hash_warning)
1523             h = (struct elf_link_hash_entry *) h->root.u.i.link;
1524           if (h->root.type == bfd_link_hash_defined
1525               || h->root.type == bfd_link_hash_defweak)
1526             {
1527               sec = h->root.u.def.section;
1528               relocation = (h->root.u.def.value
1529                             + sec->output_section->vma
1530                             + sec->output_offset);
1531             }
1532           else if (h->root.type == bfd_link_hash_undefweak)
1533             relocation = 0;
1534           else
1535             {
1536               if (!((*info->callbacks->undefined_symbol)
1537                     (info, h->root.root.string, input_bfd,
1538                      input_section, rel->r_offset)))
1539                 return false;
1540               relocation = 0;
1541             }
1542         }
1543
1544       if (h != NULL)
1545         name = h->root.root.string;
1546       else
1547         {
1548           name = (bfd_elf_string_from_elf_section
1549                   (input_bfd, symtab_hdr->sh_link, sym->st_name));
1550           if (name == NULL || *name == '\0')
1551             name = bfd_section_name (input_bfd, sec);
1552         }
1553       
1554       r = elf32_arm_final_link_relocate (howto, input_bfd, output_bfd,
1555                                          input_section,
1556                                          contents, rel->r_offset,
1557                                          relocation, rel->r_addend,
1558                                          info, sec, name,
1559                                          (h ? ELF_ST_TYPE (h->type) :
1560                                           ELF_ST_TYPE (sym->st_info)));
1561
1562       if (r != bfd_reloc_ok)
1563         {
1564           const char * msg = (const char *) 0;
1565
1566           switch (r)
1567             {
1568             case bfd_reloc_overflow:
1569               if (!((*info->callbacks->reloc_overflow)
1570                     (info, name, howto->name, (bfd_vma) 0,
1571                      input_bfd, input_section, rel->r_offset)))
1572                 return false;
1573               break;
1574
1575             case bfd_reloc_undefined:
1576               if (!((*info->callbacks->undefined_symbol)
1577                     (info, name, input_bfd, input_section,
1578                      rel->r_offset)))
1579                 return false;
1580               break;
1581
1582             case bfd_reloc_outofrange:
1583               msg = _ ("internal error: out of range error");
1584               goto common_error;
1585
1586             case bfd_reloc_notsupported:
1587               msg = _ ("internal error: unsupported relocation error");
1588               goto common_error;
1589
1590             case bfd_reloc_dangerous:
1591               msg = _ ("internal error: dangerous error");
1592               goto common_error;
1593
1594             default:
1595               msg = _ ("internal error: unknown error");
1596               /* fall through */
1597
1598             common_error:
1599               if (!((*info->callbacks->warning)
1600                     (info, msg, name, input_bfd, input_section,
1601                      rel->r_offset)))
1602                 return false;
1603               break;
1604             }
1605         }
1606     }
1607
1608   return true;
1609 }
1610
1611 /* Function to keep ARM specific flags in the ELF header. */
1612 static boolean
1613 elf32_arm_set_private_flags (abfd, flags)
1614      bfd *abfd;
1615      flagword flags;
1616 {
1617   if (elf_flags_init (abfd)
1618       && elf_elfheader (abfd)->e_flags != flags)
1619     {
1620       if (flags & EF_INTERWORK)
1621         _bfd_error_handler (_ ("\
1622 Warning: Not setting interwork flag of %s since it has already been specified as non-interworking"),
1623                             bfd_get_filename (abfd));
1624       else
1625         _bfd_error_handler (_ ("\
1626 Warning: Clearing the interwork flag of %s due to outside request"),
1627                             bfd_get_filename (abfd));
1628     }
1629   else
1630     {
1631       elf_elfheader (abfd)->e_flags = flags;
1632       elf_flags_init (abfd) = true;
1633     }
1634
1635   return true;
1636 }
1637
1638 /* Copy backend specific data from one object module to another */
1639 static boolean
1640 elf32_arm_copy_private_bfd_data (ibfd, obfd)
1641      bfd *ibfd;
1642      bfd *obfd;
1643 {
1644   flagword in_flags;
1645   flagword out_flags;
1646
1647   if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour
1648       || bfd_get_flavour (obfd) != bfd_target_elf_flavour)
1649     return true;
1650
1651   in_flags = elf_elfheader (ibfd)->e_flags;
1652   out_flags = elf_elfheader (obfd)->e_flags;
1653
1654   if (elf_flags_init (obfd) && in_flags != out_flags)
1655     {
1656       /* Cannot mix PIC and non-PIC code.  */
1657       if ((in_flags & EF_PIC) != (out_flags & EF_PIC))
1658         return false;
1659
1660       /* Cannot mix APCS26 and APCS32 code.  */
1661       if ((in_flags & EF_APCS_26) != (out_flags & EF_APCS_26))
1662         return false;
1663
1664       /* Cannot mix float APCS and non-float APCS code.  */
1665       if ((in_flags & EF_APCS_FLOAT) != (out_flags & EF_APCS_FLOAT))
1666         return false;
1667
1668       /* If the src and dest have different interworking flags
1669          then turn off the interworking bit.  */
1670       if ((in_flags & EF_INTERWORK) != (out_flags & EF_INTERWORK))
1671         {
1672           if (out_flags & EF_INTERWORK)
1673             _bfd_error_handler (_ ("\
1674 Warning: Clearing the interwork flag in %s because non-interworking code in %s has been linked with it"),
1675                           bfd_get_filename (obfd), bfd_get_filename (ibfd));
1676
1677           in_flags &= ~EF_INTERWORK;
1678         }
1679     }
1680
1681   elf_elfheader (obfd)->e_flags = in_flags;
1682   elf_flags_init (obfd) = true;
1683
1684   return true;
1685 }
1686
1687 /* Merge backend specific data from an object file to the output
1688    object file when linking.  */
1689 static boolean
1690 elf32_arm_merge_private_bfd_data (ibfd, obfd)
1691      bfd *ibfd;
1692      bfd *obfd;
1693 {
1694   flagword out_flags;
1695   flagword in_flags;
1696
1697   if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour
1698       || bfd_get_flavour (obfd) != bfd_target_elf_flavour)
1699     return true;
1700
1701   /* The input BFD must have had its flags initialised.  */
1702   /* The following seems bogus to me -- The flags are initialized in
1703      the assembler but I don't think an elf_flags_init field is
1704      written into the object */
1705   /* BFD_ASSERT (elf_flags_init (ibfd)); */
1706
1707   in_flags = elf_elfheader (ibfd)->e_flags;
1708   out_flags = elf_elfheader (obfd)->e_flags;
1709
1710   if (!elf_flags_init (obfd))
1711     {
1712       /* If the input is the default architecture then do not
1713          bother setting the flags for the output architecture,
1714          instead allow future merges to do this.  If no future
1715          merges ever set these flags then they will retain their
1716          unitialised values, which surprise surprise, correspond
1717          to the default values.  */
1718       if (bfd_get_arch_info (ibfd)->the_default)
1719         return true;
1720
1721       elf_flags_init (obfd) = true;
1722       elf_elfheader (obfd)->e_flags = in_flags;
1723
1724       if (bfd_get_arch (obfd) == bfd_get_arch (ibfd)
1725           && bfd_get_arch_info (obfd)->the_default)
1726         return bfd_set_arch_mach (obfd, bfd_get_arch (ibfd), bfd_get_mach (ibfd));
1727
1728       return true;
1729     }
1730
1731   /* Check flag compatibility.  */
1732   if (in_flags == out_flags)
1733     return true;
1734
1735   /* Complain about various flag mismatches.  */
1736
1737   if ((in_flags & EF_APCS_26) != (out_flags & EF_APCS_26))
1738     _bfd_error_handler (_ ("\
1739 Error: %s compiled for APCS-%d, whereas %s is compiled for APCS-%d"),
1740                         bfd_get_filename (ibfd),
1741                         in_flags & EF_APCS_26 ? 26 : 32,
1742                         bfd_get_filename (obfd),
1743                         out_flags & EF_APCS_26 ? 26 : 32);
1744
1745   if ((in_flags & EF_APCS_FLOAT) != (out_flags & EF_APCS_FLOAT))
1746     _bfd_error_handler (_ ("\
1747 Error: %s passes floats in %s registers, whereas %s passes them in %s registers"),
1748                         bfd_get_filename (ibfd),
1749                      in_flags & EF_APCS_FLOAT ? _ ("float") : _ ("integer"),
1750                         bfd_get_filename (obfd),
1751                       out_flags & EF_APCS_26 ? _ ("float") : _ ("integer"));
1752
1753   if ((in_flags & EF_PIC) != (out_flags & EF_PIC))
1754     _bfd_error_handler (_ ("\
1755 Error: %s is compiled as position %s code, whereas %s is not"),
1756                         bfd_get_filename (ibfd),
1757                     in_flags & EF_PIC ? _ ("independent") : _ ("dependent"),
1758                         bfd_get_filename (obfd));
1759
1760   /* Interworking mismatch is only a warning. */
1761   if ((in_flags & EF_INTERWORK) != (out_flags & EF_INTERWORK))
1762     {
1763       _bfd_error_handler (_ ("\
1764 Warning: %s %s interworking, whereas %s %s"),
1765                           bfd_get_filename (ibfd),
1766           in_flags & EF_INTERWORK ? _ ("supports") : _ ("does not support"),
1767                           bfd_get_filename (obfd),
1768                     out_flags & EF_INTERWORK ? _ ("does not") : _ ("does"));
1769       return true;
1770     }
1771
1772   return false;
1773 }
1774
1775 /* Display the flags field */
1776 static boolean
1777 elf32_arm_print_private_bfd_data (abfd, ptr)
1778      bfd *abfd;
1779      PTR ptr;
1780 {
1781   FILE *file = (FILE *) ptr;
1782
1783   BFD_ASSERT (abfd != NULL && ptr != NULL);
1784
1785   /* Print normal ELF private data.  */
1786   _bfd_elf_print_private_bfd_data (abfd, ptr);
1787
1788   /* Ignore init flag - it may not be set, despite the flags field containing valid data.  */
1789
1790   /* xgettext:c-format */
1791   fprintf (file, _ ("private flags = %lx:"), elf_elfheader (abfd)->e_flags);
1792
1793   if (elf_elfheader (abfd)->e_flags & EF_INTERWORK)
1794     fprintf (file, _ (" [interworking enabled]"));
1795   else
1796     fprintf (file, _ (" [interworking not enabled]"));
1797
1798   if (elf_elfheader (abfd)->e_flags & EF_APCS_26)
1799     fprintf (file, _ (" [APCS-26]"));
1800   else
1801     fprintf (file, _ (" [APCS-32]"));
1802
1803   if (elf_elfheader (abfd)->e_flags & EF_APCS_FLOAT)
1804     fprintf (file, _ (" [floats passed in float registers]"));
1805   else
1806     fprintf (file, _ (" [floats passed in integer registers]"));
1807
1808   if (elf_elfheader (abfd)->e_flags & EF_PIC)
1809     fprintf (file, _ (" [position independent]"));
1810   else
1811     fprintf (file, _ (" [absolute position]"));
1812
1813   fputc ('\n', file);
1814
1815   return true;
1816 }
1817
1818 static int
1819 elf32_arm_get_symbol_type (elf_sym, type)
1820      Elf_Internal_Sym * elf_sym;
1821      int type;
1822 {
1823   if (ELF_ST_TYPE (elf_sym->st_info) == STT_ARM_TFUNC)
1824     return ELF_ST_TYPE (elf_sym->st_info);
1825   else
1826     return type;
1827 }
1828     
1829 static asection *
1830 elf32_arm_gc_mark_hook (abfd, info, rel, h, sym)
1831        bfd *abfd;
1832        struct bfd_link_info *info;
1833        Elf_Internal_Rela *rel;
1834        struct elf_link_hash_entry *h;
1835        Elf_Internal_Sym *sym;
1836 {
1837   if (h != NULL)
1838     {
1839       switch (ELF32_R_TYPE (rel->r_info))
1840       {
1841       case R_ARM_GNU_VTINHERIT:
1842       case R_ARM_GNU_VTENTRY:
1843         break;
1844
1845       default:
1846         printf("h is %s\n", h->root.root.string);
1847         switch (h->root.type)
1848           {
1849           case bfd_link_hash_defined:
1850           case bfd_link_hash_defweak:
1851             return h->root.u.def.section;
1852
1853           case bfd_link_hash_common:
1854             return h->root.u.c.p->section;
1855           }
1856        }
1857      }
1858    else
1859      {
1860        if (!(elf_bad_symtab (abfd)
1861            && ELF_ST_BIND (sym->st_info) != STB_LOCAL)
1862          && ! ((sym->st_shndx <= 0 || sym->st_shndx >= SHN_LORESERVE)
1863                 && sym->st_shndx != SHN_COMMON))
1864           {
1865             return bfd_section_from_elf_index (abfd, sym->st_shndx);
1866           }
1867       }
1868   return NULL;
1869 }
1870
1871 static boolean
1872 elf32_arm_gc_sweep_hook (abfd, info, sec, relocs)
1873      bfd *abfd;
1874      struct bfd_link_info *info;
1875      asection *sec;
1876      const Elf_Internal_Rela *relocs;
1877 {
1878   /* we don't use got and plt entries for armelf */
1879   return true;
1880 }
1881
1882 /* Look through the relocs for a section during the first phase.
1883    Since we don't do .gots or .plts, we just need to consider the
1884    virtual table relocs for gc.  */
1885  
1886 static boolean
1887 elf32_arm_check_relocs (abfd, info, sec, relocs)
1888      bfd *abfd;
1889      struct bfd_link_info *info;
1890      asection *sec;
1891      const Elf_Internal_Rela *relocs;
1892 {
1893   Elf_Internal_Shdr *symtab_hdr;
1894   struct elf_link_hash_entry **sym_hashes, **sym_hashes_end;
1895   const Elf_Internal_Rela *rel;
1896   const Elf_Internal_Rela *rel_end;
1897  
1898   if (info->relocateable)
1899     return true;
1900  
1901   symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
1902   sym_hashes = elf_sym_hashes (abfd);
1903   sym_hashes_end = sym_hashes + symtab_hdr->sh_size/sizeof(Elf32_External_Sym);
1904   if (!elf_bad_symtab (abfd))
1905     sym_hashes_end -= symtab_hdr->sh_info;
1906  
1907   rel_end = relocs + sec->reloc_count;
1908   for (rel = relocs; rel < rel_end; rel++)
1909     {
1910       struct elf_link_hash_entry *h;
1911       unsigned long r_symndx;
1912  
1913       r_symndx = ELF32_R_SYM (rel->r_info);
1914       if (r_symndx < symtab_hdr->sh_info)
1915         h = NULL;
1916       else
1917         h = sym_hashes[r_symndx - symtab_hdr->sh_info];
1918  
1919       switch (ELF32_R_TYPE (rel->r_info))
1920         {
1921         /* This relocation describes the C++ object vtable hierarchy.
1922            Reconstruct it for later use during GC.  */
1923         case R_ARM_GNU_VTINHERIT:
1924           if (!_bfd_elf32_gc_record_vtinherit (abfd, sec, h, rel->r_offset))
1925             return false;
1926           break;
1927  
1928         /* This relocation describes which C++ vtable entries are actually
1929            used.  Record for later use during GC.  */
1930         case R_ARM_GNU_VTENTRY:
1931           if (!_bfd_elf32_gc_record_vtentry (abfd, sec, h, rel->r_addend))
1932             return false;
1933           break;
1934         }
1935     }
1936  
1937   return true;
1938 }
1939
1940        
1941 /* Find the nearest line to a particular section and offset, for error
1942    reporting.   This code is a duplicate of the code in elf.c, except
1943    that it also accepts STT_ARM_TFUNC as a symbol that names a function. */
1944
1945 boolean
1946 elf32_arm_find_nearest_line
1947   (abfd, section, symbols, offset, filename_ptr, functionname_ptr, line_ptr)
1948      bfd *          abfd;
1949      asection *     section;
1950      asymbol **     symbols;
1951      bfd_vma        offset;
1952      CONST char **  filename_ptr;
1953      CONST char **  functionname_ptr;
1954      unsigned int * line_ptr;
1955 {
1956   boolean      found;
1957   const char * filename;
1958   asymbol *    func;
1959   bfd_vma      low_func;
1960   asymbol **   p;
1961
1962   if (_bfd_dwarf2_find_nearest_line (abfd, section, symbols, offset,
1963                                      filename_ptr, functionname_ptr, 
1964                                      line_ptr))
1965     return true;
1966
1967   if (! _bfd_stab_section_find_nearest_line (abfd, symbols, section, offset,
1968                                              &found, filename_ptr,
1969                                              functionname_ptr, line_ptr,
1970                                              &elf_tdata (abfd)->line_info))
1971     return false;
1972   
1973   if (found)
1974     return true;
1975
1976   if (symbols == NULL)
1977     return false;
1978
1979   filename = NULL;
1980   func = NULL;
1981   low_func = 0;
1982
1983   for (p = symbols; *p != NULL; p++)
1984     {
1985       elf_symbol_type *q;
1986
1987       q = (elf_symbol_type *) *p;
1988
1989       if (bfd_get_section (&q->symbol) != section)
1990         continue;
1991
1992       switch (ELF_ST_TYPE (q->internal_elf_sym.st_info))
1993         {
1994         default:
1995           break;
1996         case STT_FILE:
1997           filename = bfd_asymbol_name (&q->symbol);
1998           break;
1999         case STT_NOTYPE:
2000         case STT_FUNC:
2001         case STT_ARM_TFUNC:
2002           if (q->symbol.section == section
2003               && q->symbol.value >= low_func
2004               && q->symbol.value <= offset)
2005             {
2006               func = (asymbol *) q;
2007               low_func = q->symbol.value;
2008             }
2009           break;
2010         }
2011     }
2012
2013   if (func == NULL)
2014     return false;
2015
2016   *filename_ptr = filename;
2017   *functionname_ptr = bfd_asymbol_name (func);
2018   *line_ptr = 0;
2019   
2020   return true;
2021 }
2022
2023
2024 #define TARGET_LITTLE_SYM               bfd_elf32_littlearm_vec
2025 #define TARGET_LITTLE_NAME              "elf32-littlearm"
2026 #define TARGET_BIG_SYM                  bfd_elf32_bigarm_vec
2027 #define TARGET_BIG_NAME                 "elf32-bigarm"
2028 #define ELF_ARCH                        bfd_arch_arm
2029 #define ELF_MACHINE_CODE                EM_ARM
2030
2031 #define bfd_elf32_bfd_reloc_type_lookup         elf32_arm_reloc_type_lookup
2032 #define elf_info_to_howto                       elf32_arm_info_to_howto
2033 #define elf_info_to_howto_rel                   0
2034 #define elf_backend_relocate_section            elf32_arm_relocate_section
2035 #define bfd_elf32_bfd_copy_private_bfd_data     elf32_arm_copy_private_bfd_data
2036 #define bfd_elf32_bfd_merge_private_bfd_data    elf32_arm_merge_private_bfd_data
2037 #define bfd_elf32_bfd_set_private_flags         elf32_arm_set_private_flags
2038 #define bfd_elf32_bfd_print_private_bfd_data    elf32_arm_print_private_bfd_data
2039 #define bfd_elf32_bfd_link_hash_table_create    elf32_arm_link_hash_table_create
2040 #define bfd_elf32_find_nearest_line             elf32_arm_find_nearest_line
2041 #define elf_backend_get_symbol_type             elf32_arm_get_symbol_type
2042 #define elf_backend_gc_mark_hook                elf32_arm_gc_mark_hook
2043 #define elf_backend_gc_sweep_hook               elf32_arm_gc_sweep_hook
2044 #define elf_backend_check_relocs                elf32_arm_check_relocs
2045
2046 #define elf_backend_can_gc_sections 1
2047 #define elf_symbol_leading_char '_'
2048
2049 #include "elf32-target.h"