Home | History | Annotate | Line # | Download | only in bfd
elf32-m68hc1x.c revision 1.1.1.5
      1      1.1  christos /* Motorola 68HC11/HC12-specific support for 32-bit ELF
      2  1.1.1.5  christos    Copyright (C) 1999-2020 Free Software Foundation, Inc.
      3      1.1  christos    Contributed by Stephane Carrez (stcarrez (at) nerim.fr)
      4      1.1  christos 
      5      1.1  christos    This file is part of BFD, the Binary File Descriptor library.
      6      1.1  christos 
      7      1.1  christos    This program is free software; you can redistribute it and/or modify
      8      1.1  christos    it under the terms of the GNU General Public License as published by
      9      1.1  christos    the Free Software Foundation; either version 3 of the License, or
     10      1.1  christos    (at your option) any later version.
     11      1.1  christos 
     12      1.1  christos    This program is distributed in the hope that it will be useful,
     13      1.1  christos    but WITHOUT ANY WARRANTY; without even the implied warranty of
     14      1.1  christos    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     15      1.1  christos    GNU General Public License for more details.
     16      1.1  christos 
     17      1.1  christos    You should have received a copy of the GNU General Public License
     18      1.1  christos    along with this program; if not, write to the Free Software
     19      1.1  christos    Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
     20      1.1  christos    MA 02110-1301, USA.  */
     21      1.1  christos 
     22      1.1  christos #include "sysdep.h"
     23      1.1  christos #include "alloca-conf.h"
     24      1.1  christos #include "bfd.h"
     25      1.1  christos #include "bfdlink.h"
     26      1.1  christos #include "libbfd.h"
     27      1.1  christos #include "elf-bfd.h"
     28      1.1  christos #include "elf32-m68hc1x.h"
     29      1.1  christos #include "elf/m68hc11.h"
     30      1.1  christos #include "opcode/m68hc11.h"
     31  1.1.1.3  christos #include "libiberty.h"
     32      1.1  christos 
     33      1.1  christos #define m68hc12_stub_hash_lookup(table, string, create, copy) \
     34      1.1  christos   ((struct elf32_m68hc11_stub_hash_entry *) \
     35      1.1  christos    bfd_hash_lookup ((table), (string), (create), (copy)))
     36      1.1  christos 
     37      1.1  christos static struct elf32_m68hc11_stub_hash_entry* m68hc12_add_stub
     38      1.1  christos   (const char *stub_name,
     39      1.1  christos    asection *section,
     40      1.1  christos    struct m68hc11_elf_link_hash_table *htab);
     41      1.1  christos 
     42      1.1  christos static struct bfd_hash_entry *stub_hash_newfunc
     43      1.1  christos   (struct bfd_hash_entry *, struct bfd_hash_table *, const char *);
     44      1.1  christos 
     45      1.1  christos static void m68hc11_elf_set_symbol (bfd* abfd, struct bfd_link_info *info,
     46  1.1.1.4  christos 				    const char* name, bfd_vma value,
     47  1.1.1.4  christos 				    asection* sec);
     48      1.1  christos 
     49      1.1  christos static bfd_boolean m68hc11_elf_export_one_stub
     50      1.1  christos   (struct bfd_hash_entry *gen_entry, void *in_arg);
     51      1.1  christos 
     52      1.1  christos static void scan_sections_for_abi (bfd*, asection*, void *);
     53      1.1  christos 
     54      1.1  christos struct m68hc11_scan_param
     55      1.1  christos {
     56      1.1  christos    struct m68hc11_page_info* pinfo;
     57      1.1  christos    bfd_boolean use_memory_banks;
     58      1.1  christos };
     59      1.1  christos 
     60      1.1  christos 
     61  1.1.1.2  christos /* Destroy a 68HC11/68HC12 ELF linker hash table.  */
     62  1.1.1.2  christos 
     63  1.1.1.2  christos static void
     64  1.1.1.2  christos m68hc11_elf_bfd_link_hash_table_free (bfd *obfd)
     65  1.1.1.2  christos {
     66  1.1.1.2  christos   struct m68hc11_elf_link_hash_table *ret
     67  1.1.1.2  christos     = (struct m68hc11_elf_link_hash_table *) obfd->link.hash;
     68  1.1.1.2  christos 
     69  1.1.1.2  christos   bfd_hash_table_free (ret->stub_hash_table);
     70  1.1.1.2  christos   free (ret->stub_hash_table);
     71  1.1.1.2  christos   _bfd_elf_link_hash_table_free (obfd);
     72  1.1.1.2  christos }
     73  1.1.1.2  christos 
     74      1.1  christos /* Create a 68HC11/68HC12 ELF linker hash table.  */
     75      1.1  christos 
     76      1.1  christos struct m68hc11_elf_link_hash_table*
     77      1.1  christos m68hc11_elf_hash_table_create (bfd *abfd)
     78      1.1  christos {
     79      1.1  christos   struct m68hc11_elf_link_hash_table *ret;
     80      1.1  christos   bfd_size_type amt = sizeof (struct m68hc11_elf_link_hash_table);
     81      1.1  christos 
     82  1.1.1.2  christos   ret = (struct m68hc11_elf_link_hash_table *) bfd_zmalloc (amt);
     83      1.1  christos   if (ret == (struct m68hc11_elf_link_hash_table *) NULL)
     84      1.1  christos     return NULL;
     85      1.1  christos 
     86      1.1  christos   if (!_bfd_elf_link_hash_table_init (&ret->root, abfd,
     87      1.1  christos 				      _bfd_elf_link_hash_newfunc,
     88      1.1  christos 				      sizeof (struct elf_link_hash_entry),
     89      1.1  christos 				      M68HC11_ELF_DATA))
     90      1.1  christos     {
     91      1.1  christos       free (ret);
     92      1.1  christos       return NULL;
     93      1.1  christos     }
     94      1.1  christos 
     95      1.1  christos   /* Init the stub hash table too.  */
     96      1.1  christos   amt = sizeof (struct bfd_hash_table);
     97      1.1  christos   ret->stub_hash_table = (struct bfd_hash_table*) bfd_malloc (amt);
     98      1.1  christos   if (ret->stub_hash_table == NULL)
     99      1.1  christos     {
    100  1.1.1.2  christos       _bfd_elf_link_hash_table_free (abfd);
    101      1.1  christos       return NULL;
    102      1.1  christos     }
    103      1.1  christos   if (!bfd_hash_table_init (ret->stub_hash_table, stub_hash_newfunc,
    104      1.1  christos 			    sizeof (struct elf32_m68hc11_stub_hash_entry)))
    105  1.1.1.2  christos     {
    106  1.1.1.2  christos       free (ret->stub_hash_table);
    107  1.1.1.2  christos       _bfd_elf_link_hash_table_free (abfd);
    108  1.1.1.2  christos       return NULL;
    109  1.1.1.2  christos     }
    110  1.1.1.2  christos   ret->root.root.hash_table_free = m68hc11_elf_bfd_link_hash_table_free;
    111      1.1  christos 
    112      1.1  christos   return ret;
    113      1.1  christos }
    114      1.1  christos 
    115      1.1  christos /* Assorted hash table functions.  */
    116      1.1  christos 
    117      1.1  christos /* Initialize an entry in the stub hash table.  */
    118      1.1  christos 
    119      1.1  christos static struct bfd_hash_entry *
    120      1.1  christos stub_hash_newfunc (struct bfd_hash_entry *entry, struct bfd_hash_table *table,
    121  1.1.1.4  christos 		   const char *string)
    122      1.1  christos {
    123      1.1  christos   /* Allocate the structure if it has not already been allocated by a
    124      1.1  christos      subclass.  */
    125      1.1  christos   if (entry == NULL)
    126      1.1  christos     {
    127      1.1  christos       entry = bfd_hash_allocate (table,
    128      1.1  christos 				 sizeof (struct elf32_m68hc11_stub_hash_entry));
    129      1.1  christos       if (entry == NULL)
    130      1.1  christos 	return entry;
    131      1.1  christos     }
    132      1.1  christos 
    133      1.1  christos   /* Call the allocation method of the superclass.  */
    134      1.1  christos   entry = bfd_hash_newfunc (entry, table, string);
    135      1.1  christos   if (entry != NULL)
    136      1.1  christos     {
    137      1.1  christos       struct elf32_m68hc11_stub_hash_entry *eh;
    138      1.1  christos 
    139      1.1  christos       /* Initialize the local fields.  */
    140      1.1  christos       eh = (struct elf32_m68hc11_stub_hash_entry *) entry;
    141      1.1  christos       eh->stub_sec = NULL;
    142      1.1  christos       eh->stub_offset = 0;
    143      1.1  christos       eh->target_value = 0;
    144      1.1  christos       eh->target_section = NULL;
    145      1.1  christos     }
    146      1.1  christos 
    147      1.1  christos   return entry;
    148      1.1  christos }
    149      1.1  christos 
    150      1.1  christos /* Add a new stub entry to the stub hash.  Not all fields of the new
    151      1.1  christos    stub entry are initialised.  */
    152      1.1  christos 
    153      1.1  christos static struct elf32_m68hc11_stub_hash_entry *
    154      1.1  christos m68hc12_add_stub (const char *stub_name, asection *section,
    155  1.1.1.4  christos 		  struct m68hc11_elf_link_hash_table *htab)
    156      1.1  christos {
    157      1.1  christos   struct elf32_m68hc11_stub_hash_entry *stub_entry;
    158      1.1  christos 
    159      1.1  christos   /* Enter this entry into the linker stub hash table.  */
    160      1.1  christos   stub_entry = m68hc12_stub_hash_lookup (htab->stub_hash_table, stub_name,
    161  1.1.1.4  christos 					 TRUE, FALSE);
    162      1.1  christos   if (stub_entry == NULL)
    163      1.1  christos     {
    164  1.1.1.4  christos       /* xgettext:c-format */
    165  1.1.1.4  christos       _bfd_error_handler (_("%pB: cannot create stub entry %s"),
    166  1.1.1.4  christos 			  section->owner, stub_name);
    167      1.1  christos       return NULL;
    168      1.1  christos     }
    169      1.1  christos 
    170      1.1  christos   if (htab->stub_section == 0)
    171      1.1  christos     {
    172      1.1  christos       htab->stub_section = (*htab->add_stub_section) (".tramp",
    173  1.1.1.4  christos 						      htab->tramp_section);
    174      1.1  christos     }
    175      1.1  christos 
    176      1.1  christos   stub_entry->stub_sec = htab->stub_section;
    177      1.1  christos   stub_entry->stub_offset = 0;
    178      1.1  christos   return stub_entry;
    179      1.1  christos }
    180      1.1  christos 
    181      1.1  christos /* Hook called by the linker routine which adds symbols from an object
    182      1.1  christos    file.  We use it for identify far symbols and force a loading of
    183      1.1  christos    the trampoline handler.  */
    184      1.1  christos 
    185      1.1  christos bfd_boolean
    186      1.1  christos elf32_m68hc11_add_symbol_hook (bfd *abfd, struct bfd_link_info *info,
    187  1.1.1.4  christos 			       Elf_Internal_Sym *sym,
    188  1.1.1.4  christos 			       const char **namep ATTRIBUTE_UNUSED,
    189  1.1.1.4  christos 			       flagword *flagsp ATTRIBUTE_UNUSED,
    190  1.1.1.4  christos 			       asection **secp ATTRIBUTE_UNUSED,
    191  1.1.1.4  christos 			       bfd_vma *valp ATTRIBUTE_UNUSED)
    192      1.1  christos {
    193      1.1  christos   if (sym->st_other & STO_M68HC12_FAR)
    194      1.1  christos     {
    195      1.1  christos       struct elf_link_hash_entry *h;
    196      1.1  christos 
    197      1.1  christos       h = (struct elf_link_hash_entry *)
    198      1.1  christos 	bfd_link_hash_lookup (info->hash, "__far_trampoline",
    199  1.1.1.4  christos 			      FALSE, FALSE, FALSE);
    200      1.1  christos       if (h == NULL)
    201  1.1.1.4  christos 	{
    202  1.1.1.4  christos 	  struct bfd_link_hash_entry* entry = NULL;
    203      1.1  christos 
    204  1.1.1.4  christos 	  _bfd_generic_link_add_one_symbol (info, abfd,
    205  1.1.1.4  christos 					    "__far_trampoline",
    206  1.1.1.4  christos 					    BSF_GLOBAL,
    207  1.1.1.4  christos 					    bfd_und_section_ptr,
    208  1.1.1.4  christos 					    (bfd_vma) 0, (const char*) NULL,
    209  1.1.1.4  christos 					    FALSE, FALSE, &entry);
    210  1.1.1.4  christos 	}
    211      1.1  christos 
    212      1.1  christos     }
    213      1.1  christos   return TRUE;
    214      1.1  christos }
    215      1.1  christos 
    216      1.1  christos /* Merge non-visibility st_other attributes, STO_M68HC12_FAR and
    217      1.1  christos    STO_M68HC12_INTERRUPT.  */
    218      1.1  christos 
    219      1.1  christos void
    220      1.1  christos elf32_m68hc11_merge_symbol_attribute (struct elf_link_hash_entry *h,
    221      1.1  christos 				      const Elf_Internal_Sym *isym,
    222      1.1  christos 				      bfd_boolean definition,
    223      1.1  christos 				      bfd_boolean dynamic ATTRIBUTE_UNUSED)
    224      1.1  christos {
    225      1.1  christos   if (definition)
    226      1.1  christos     h->other = ((isym->st_other & ~ELF_ST_VISIBILITY (-1))
    227      1.1  christos 		| ELF_ST_VISIBILITY (h->other));
    228      1.1  christos }
    229      1.1  christos 
    230      1.1  christos /* External entry points for sizing and building linker stubs.  */
    231      1.1  christos 
    232      1.1  christos /* Set up various things so that we can make a list of input sections
    233      1.1  christos    for each output section included in the link.  Returns -1 on error,
    234      1.1  christos    0 when no stubs will be needed, and 1 on success.  */
    235      1.1  christos 
    236      1.1  christos int
    237      1.1  christos elf32_m68hc11_setup_section_lists (bfd *output_bfd, struct bfd_link_info *info)
    238      1.1  christos {
    239      1.1  christos   bfd *input_bfd;
    240      1.1  christos   unsigned int bfd_count;
    241  1.1.1.2  christos   unsigned int top_id, top_index;
    242      1.1  christos   asection *section;
    243      1.1  christos   asection **input_list, **list;
    244      1.1  christos   bfd_size_type amt;
    245      1.1  christos   asection *text_section;
    246      1.1  christos   struct m68hc11_elf_link_hash_table *htab;
    247      1.1  christos 
    248      1.1  christos   htab = m68hc11_elf_hash_table (info);
    249      1.1  christos   if (htab == NULL)
    250      1.1  christos     return -1;
    251      1.1  christos 
    252      1.1  christos   if (bfd_get_flavour (info->output_bfd) != bfd_target_elf_flavour)
    253      1.1  christos     return 0;
    254      1.1  christos 
    255      1.1  christos   /* Count the number of input BFDs and find the top input section id.
    256      1.1  christos      Also search for an existing ".tramp" section so that we know
    257      1.1  christos      where generated trampolines must go.  Default to ".text" if we
    258      1.1  christos      can't find it.  */
    259      1.1  christos   htab->tramp_section = 0;
    260      1.1  christos   text_section = 0;
    261      1.1  christos   for (input_bfd = info->input_bfds, bfd_count = 0, top_id = 0;
    262      1.1  christos        input_bfd != NULL;
    263  1.1.1.2  christos        input_bfd = input_bfd->link.next)
    264      1.1  christos     {
    265      1.1  christos       bfd_count += 1;
    266      1.1  christos       for (section = input_bfd->sections;
    267      1.1  christos 	   section != NULL;
    268      1.1  christos 	   section = section->next)
    269      1.1  christos 	{
    270  1.1.1.5  christos 	  const char *name = bfd_section_name (section);
    271      1.1  christos 
    272  1.1.1.4  christos 	  if (!strcmp (name, ".tramp"))
    273  1.1.1.4  christos 	    htab->tramp_section = section;
    274      1.1  christos 
    275  1.1.1.4  christos 	  if (!strcmp (name, ".text"))
    276  1.1.1.4  christos 	    text_section = section;
    277      1.1  christos 
    278      1.1  christos 	  if (top_id < section->id)
    279      1.1  christos 	    top_id = section->id;
    280      1.1  christos 	}
    281      1.1  christos     }
    282      1.1  christos   htab->bfd_count = bfd_count;
    283      1.1  christos   if (htab->tramp_section == 0)
    284      1.1  christos     htab->tramp_section = text_section;
    285      1.1  christos 
    286      1.1  christos   /* We can't use output_bfd->section_count here to find the top output
    287      1.1  christos      section index as some sections may have been removed, and
    288      1.1  christos      strip_excluded_output_sections doesn't renumber the indices.  */
    289      1.1  christos   for (section = output_bfd->sections, top_index = 0;
    290      1.1  christos        section != NULL;
    291      1.1  christos        section = section->next)
    292      1.1  christos     {
    293      1.1  christos       if (top_index < section->index)
    294      1.1  christos 	top_index = section->index;
    295      1.1  christos     }
    296      1.1  christos 
    297      1.1  christos   htab->top_index = top_index;
    298      1.1  christos   amt = sizeof (asection *) * (top_index + 1);
    299      1.1  christos   input_list = (asection **) bfd_malloc (amt);
    300      1.1  christos   htab->input_list = input_list;
    301      1.1  christos   if (input_list == NULL)
    302      1.1  christos     return -1;
    303      1.1  christos 
    304      1.1  christos   /* For sections we aren't interested in, mark their entries with a
    305      1.1  christos      value we can check later.  */
    306      1.1  christos   list = input_list + top_index;
    307      1.1  christos   do
    308      1.1  christos     *list = bfd_abs_section_ptr;
    309      1.1  christos   while (list-- != input_list);
    310      1.1  christos 
    311      1.1  christos   for (section = output_bfd->sections;
    312      1.1  christos        section != NULL;
    313      1.1  christos        section = section->next)
    314      1.1  christos     {
    315      1.1  christos       if ((section->flags & SEC_CODE) != 0)
    316      1.1  christos 	input_list[section->index] = NULL;
    317      1.1  christos     }
    318      1.1  christos 
    319      1.1  christos   return 1;
    320      1.1  christos }
    321      1.1  christos 
    322      1.1  christos /* Determine and set the size of the stub section for a final link.
    323      1.1  christos 
    324      1.1  christos    The basic idea here is to examine all the relocations looking for
    325      1.1  christos    PC-relative calls to a target that is unreachable with a "bl"
    326      1.1  christos    instruction.  */
    327      1.1  christos 
    328      1.1  christos bfd_boolean
    329      1.1  christos elf32_m68hc11_size_stubs (bfd *output_bfd, bfd *stub_bfd,
    330  1.1.1.4  christos 			  struct bfd_link_info *info,
    331  1.1.1.4  christos 			  asection * (*add_stub_section) (const char*, asection*))
    332      1.1  christos {
    333      1.1  christos   bfd *input_bfd;
    334      1.1  christos   asection *section;
    335      1.1  christos   Elf_Internal_Sym *local_syms, **all_local_syms;
    336      1.1  christos   unsigned int bfd_indx, bfd_count;
    337      1.1  christos   bfd_size_type amt;
    338      1.1  christos   asection *stub_sec;
    339      1.1  christos   struct m68hc11_elf_link_hash_table *htab = m68hc11_elf_hash_table (info);
    340      1.1  christos 
    341      1.1  christos   if (htab == NULL)
    342      1.1  christos     return FALSE;
    343      1.1  christos 
    344      1.1  christos   /* Stash our params away.  */
    345      1.1  christos   htab->stub_bfd = stub_bfd;
    346      1.1  christos   htab->add_stub_section = add_stub_section;
    347      1.1  christos 
    348      1.1  christos   /* Count the number of input BFDs and find the top input section id.  */
    349      1.1  christos   for (input_bfd = info->input_bfds, bfd_count = 0;
    350      1.1  christos        input_bfd != NULL;
    351  1.1.1.2  christos        input_bfd = input_bfd->link.next)
    352      1.1  christos     bfd_count += 1;
    353      1.1  christos 
    354      1.1  christos   /* We want to read in symbol extension records only once.  To do this
    355      1.1  christos      we need to read in the local symbols in parallel and save them for
    356      1.1  christos      later use; so hold pointers to the local symbols in an array.  */
    357      1.1  christos   amt = sizeof (Elf_Internal_Sym *) * bfd_count;
    358      1.1  christos   all_local_syms = (Elf_Internal_Sym **) bfd_zmalloc (amt);
    359      1.1  christos   if (all_local_syms == NULL)
    360      1.1  christos     return FALSE;
    361      1.1  christos 
    362      1.1  christos   /* Walk over all the input BFDs, swapping in local symbols.  */
    363      1.1  christos   for (input_bfd = info->input_bfds, bfd_indx = 0;
    364      1.1  christos        input_bfd != NULL;
    365  1.1.1.2  christos        input_bfd = input_bfd->link.next, bfd_indx++)
    366      1.1  christos     {
    367      1.1  christos       Elf_Internal_Shdr *symtab_hdr;
    368      1.1  christos 
    369      1.1  christos       /* We'll need the symbol table in a second.  */
    370      1.1  christos       symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
    371      1.1  christos       if (symtab_hdr->sh_info == 0)
    372      1.1  christos 	continue;
    373      1.1  christos 
    374      1.1  christos       /* We need an array of the local symbols attached to the input bfd.  */
    375      1.1  christos       local_syms = (Elf_Internal_Sym *) symtab_hdr->contents;
    376      1.1  christos       if (local_syms == NULL)
    377      1.1  christos 	{
    378      1.1  christos 	  local_syms = bfd_elf_get_elf_syms (input_bfd, symtab_hdr,
    379      1.1  christos 					     symtab_hdr->sh_info, 0,
    380      1.1  christos 					     NULL, NULL, NULL);
    381      1.1  christos 	  /* Cache them for elf_link_input_bfd.  */
    382      1.1  christos 	  symtab_hdr->contents = (unsigned char *) local_syms;
    383      1.1  christos 	}
    384      1.1  christos       if (local_syms == NULL)
    385  1.1.1.4  christos 	{
    386  1.1.1.4  christos 	  free (all_local_syms);
    387      1.1  christos 	  return FALSE;
    388  1.1.1.4  christos 	}
    389      1.1  christos 
    390      1.1  christos       all_local_syms[bfd_indx] = local_syms;
    391      1.1  christos     }
    392      1.1  christos 
    393      1.1  christos   for (input_bfd = info->input_bfds, bfd_indx = 0;
    394      1.1  christos        input_bfd != NULL;
    395  1.1.1.2  christos        input_bfd = input_bfd->link.next, bfd_indx++)
    396      1.1  christos     {
    397      1.1  christos       Elf_Internal_Shdr *symtab_hdr;
    398      1.1  christos       struct elf_link_hash_entry ** sym_hashes;
    399      1.1  christos 
    400      1.1  christos       sym_hashes = elf_sym_hashes (input_bfd);
    401      1.1  christos 
    402      1.1  christos       /* We'll need the symbol table in a second.  */
    403      1.1  christos       symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
    404      1.1  christos       if (symtab_hdr->sh_info == 0)
    405  1.1.1.4  christos 	continue;
    406      1.1  christos 
    407      1.1  christos       local_syms = all_local_syms[bfd_indx];
    408      1.1  christos 
    409      1.1  christos       /* Walk over each section attached to the input bfd.  */
    410      1.1  christos       for (section = input_bfd->sections;
    411  1.1.1.4  christos 	   section != NULL;
    412  1.1.1.4  christos 	   section = section->next)
    413  1.1.1.4  christos 	{
    414  1.1.1.4  christos 	  Elf_Internal_Rela *internal_relocs, *irelaend, *irela;
    415  1.1.1.4  christos 
    416  1.1.1.4  christos 	  /* If there aren't any relocs, then there's nothing more
    417  1.1.1.4  christos 	     to do.  */
    418  1.1.1.4  christos 	  if ((section->flags & SEC_RELOC) == 0
    419  1.1.1.4  christos 	      || section->reloc_count == 0)
    420  1.1.1.4  christos 	    continue;
    421  1.1.1.4  christos 
    422  1.1.1.4  christos 	  /* If this section is a link-once section that will be
    423  1.1.1.4  christos 	     discarded, then don't create any stubs.  */
    424  1.1.1.4  christos 	  if (section->output_section == NULL
    425  1.1.1.4  christos 	      || section->output_section->owner != output_bfd)
    426  1.1.1.4  christos 	    continue;
    427  1.1.1.4  christos 
    428  1.1.1.4  christos 	  /* Get the relocs.  */
    429  1.1.1.4  christos 	  internal_relocs
    430  1.1.1.4  christos 	    = _bfd_elf_link_read_relocs (input_bfd, section, NULL,
    431      1.1  christos 					 (Elf_Internal_Rela *) NULL,
    432      1.1  christos 					 info->keep_memory);
    433  1.1.1.4  christos 	  if (internal_relocs == NULL)
    434  1.1.1.4  christos 	    goto error_ret_free_local;
    435      1.1  christos 
    436  1.1.1.4  christos 	  /* Now examine each relocation.  */
    437  1.1.1.4  christos 	  irela = internal_relocs;
    438  1.1.1.4  christos 	  irelaend = irela + section->reloc_count;
    439  1.1.1.4  christos 	  for (; irela < irelaend; irela++)
    440  1.1.1.4  christos 	    {
    441  1.1.1.4  christos 	      unsigned int r_type, r_indx;
    442  1.1.1.4  christos 	      struct elf32_m68hc11_stub_hash_entry *stub_entry;
    443  1.1.1.4  christos 	      asection *sym_sec;
    444  1.1.1.4  christos 	      bfd_vma sym_value;
    445  1.1.1.4  christos 	      struct elf_link_hash_entry *hash;
    446  1.1.1.4  christos 	      const char *stub_name;
    447  1.1.1.4  christos 	      Elf_Internal_Sym *sym;
    448  1.1.1.4  christos 
    449  1.1.1.4  christos 	      r_type = ELF32_R_TYPE (irela->r_info);
    450  1.1.1.4  christos 
    451  1.1.1.4  christos 	      /* Only look at 16-bit relocs.  */
    452  1.1.1.4  christos 	      if (r_type != (unsigned int) R_M68HC11_16)
    453  1.1.1.4  christos 		continue;
    454  1.1.1.4  christos 
    455  1.1.1.4  christos 	      /* Now determine the call target, its name, value,
    456  1.1.1.4  christos 		 section.  */
    457  1.1.1.4  christos 	      r_indx = ELF32_R_SYM (irela->r_info);
    458  1.1.1.4  christos 	      if (r_indx < symtab_hdr->sh_info)
    459  1.1.1.4  christos 		{
    460  1.1.1.4  christos 		  /* It's a local symbol.  */
    461  1.1.1.4  christos 		  Elf_Internal_Shdr *hdr;
    462  1.1.1.4  christos 		  bfd_boolean is_far;
    463  1.1.1.4  christos 
    464  1.1.1.4  christos 		  sym = local_syms + r_indx;
    465  1.1.1.4  christos 		  is_far = (sym && (sym->st_other & STO_M68HC12_FAR));
    466  1.1.1.4  christos 		  if (!is_far)
    467  1.1.1.4  christos 		    continue;
    468      1.1  christos 
    469      1.1  christos 		  if (sym->st_shndx >= elf_numsections (input_bfd))
    470      1.1  christos 		    sym_sec = NULL;
    471      1.1  christos 		  else
    472      1.1  christos 		    {
    473      1.1  christos 		      hdr = elf_elfsections (input_bfd)[sym->st_shndx];
    474      1.1  christos 		      sym_sec = hdr->bfd_section;
    475      1.1  christos 		    }
    476  1.1.1.4  christos 		  stub_name = (bfd_elf_string_from_elf_section
    477  1.1.1.4  christos 			       (input_bfd, symtab_hdr->sh_link,
    478  1.1.1.4  christos 				sym->st_name));
    479  1.1.1.4  christos 		  sym_value = sym->st_value;
    480  1.1.1.4  christos 		  hash = NULL;
    481  1.1.1.4  christos 		}
    482  1.1.1.4  christos 	      else
    483  1.1.1.4  christos 		{
    484  1.1.1.4  christos 		  /* It's an external symbol.  */
    485  1.1.1.4  christos 		  int e_indx;
    486  1.1.1.4  christos 
    487  1.1.1.4  christos 		  e_indx = r_indx - symtab_hdr->sh_info;
    488  1.1.1.4  christos 		  hash = (struct elf_link_hash_entry *)
    489  1.1.1.4  christos 		    (sym_hashes[e_indx]);
    490  1.1.1.4  christos 
    491  1.1.1.4  christos 		  while (hash->root.type == bfd_link_hash_indirect
    492  1.1.1.4  christos 			 || hash->root.type == bfd_link_hash_warning)
    493  1.1.1.4  christos 		    hash = ((struct elf_link_hash_entry *)
    494  1.1.1.4  christos 			    hash->root.u.i.link);
    495  1.1.1.4  christos 
    496  1.1.1.4  christos 		  if (hash->root.type == bfd_link_hash_defined
    497  1.1.1.4  christos 		      || hash->root.type == bfd_link_hash_defweak
    498  1.1.1.4  christos 		      || hash->root.type == bfd_link_hash_new)
    499  1.1.1.4  christos 		    {
    500  1.1.1.4  christos 		      if (!(hash->other & STO_M68HC12_FAR))
    501  1.1.1.4  christos 			continue;
    502  1.1.1.4  christos 		    }
    503  1.1.1.4  christos 		  else if (hash->root.type == bfd_link_hash_undefweak)
    504  1.1.1.4  christos 		    {
    505  1.1.1.4  christos 		      continue;
    506  1.1.1.4  christos 		    }
    507  1.1.1.4  christos 		  else if (hash->root.type == bfd_link_hash_undefined)
    508  1.1.1.4  christos 		    {
    509  1.1.1.4  christos 		      continue;
    510  1.1.1.4  christos 		    }
    511  1.1.1.4  christos 		  else
    512  1.1.1.4  christos 		    {
    513  1.1.1.4  christos 		      bfd_set_error (bfd_error_bad_value);
    514  1.1.1.4  christos 		      goto error_ret_free_internal;
    515  1.1.1.4  christos 		    }
    516  1.1.1.4  christos 		  sym_sec = hash->root.u.def.section;
    517  1.1.1.4  christos 		  sym_value = hash->root.u.def.value;
    518  1.1.1.4  christos 		  stub_name = hash->root.root.string;
    519  1.1.1.4  christos 		}
    520  1.1.1.4  christos 
    521  1.1.1.4  christos 	      if (!stub_name)
    522  1.1.1.4  christos 		goto error_ret_free_internal;
    523  1.1.1.4  christos 
    524  1.1.1.4  christos 	      stub_entry = m68hc12_stub_hash_lookup
    525  1.1.1.4  christos 		(htab->stub_hash_table,
    526  1.1.1.4  christos 		 stub_name,
    527  1.1.1.4  christos 		 FALSE, FALSE);
    528  1.1.1.4  christos 	      if (stub_entry == NULL)
    529  1.1.1.4  christos 		{
    530  1.1.1.4  christos 		  if (add_stub_section == 0)
    531  1.1.1.4  christos 		    continue;
    532  1.1.1.4  christos 
    533  1.1.1.4  christos 		  stub_entry = m68hc12_add_stub (stub_name, section, htab);
    534  1.1.1.4  christos 		  if (stub_entry == NULL)
    535  1.1.1.4  christos 		    {
    536  1.1.1.4  christos 		    error_ret_free_internal:
    537  1.1.1.4  christos 		      if (elf_section_data (section)->relocs == NULL)
    538  1.1.1.4  christos 			free (internal_relocs);
    539  1.1.1.4  christos 		      goto error_ret_free_local;
    540  1.1.1.4  christos 		    }
    541  1.1.1.4  christos 		}
    542  1.1.1.4  christos 
    543  1.1.1.4  christos 	      stub_entry->target_value = sym_value;
    544  1.1.1.4  christos 	      stub_entry->target_section = sym_sec;
    545  1.1.1.4  christos 	    }
    546  1.1.1.4  christos 
    547  1.1.1.4  christos 	  /* We're done with the internal relocs, free them.  */
    548  1.1.1.4  christos 	  if (elf_section_data (section)->relocs == NULL)
    549  1.1.1.4  christos 	    free (internal_relocs);
    550  1.1.1.4  christos 	}
    551      1.1  christos     }
    552      1.1  christos 
    553      1.1  christos   if (add_stub_section)
    554      1.1  christos     {
    555      1.1  christos       /* OK, we've added some stubs.  Find out the new size of the
    556  1.1.1.4  christos 	 stub sections.  */
    557      1.1  christos       for (stub_sec = htab->stub_bfd->sections;
    558  1.1.1.4  christos 	   stub_sec != NULL;
    559  1.1.1.4  christos 	   stub_sec = stub_sec->next)
    560  1.1.1.4  christos 	{
    561  1.1.1.4  christos 	  stub_sec->size = 0;
    562  1.1.1.4  christos 	}
    563      1.1  christos 
    564      1.1  christos       bfd_hash_traverse (htab->stub_hash_table, htab->size_one_stub, htab);
    565      1.1  christos     }
    566      1.1  christos   free (all_local_syms);
    567      1.1  christos   return TRUE;
    568      1.1  christos 
    569      1.1  christos  error_ret_free_local:
    570      1.1  christos   free (all_local_syms);
    571      1.1  christos   return FALSE;
    572      1.1  christos }
    573      1.1  christos 
    574      1.1  christos /* Export the trampoline addresses in the symbol table.  */
    575      1.1  christos static bfd_boolean
    576      1.1  christos m68hc11_elf_export_one_stub (struct bfd_hash_entry *gen_entry, void *in_arg)
    577      1.1  christos {
    578      1.1  christos   struct bfd_link_info *info;
    579      1.1  christos   struct m68hc11_elf_link_hash_table *htab;
    580      1.1  christos   struct elf32_m68hc11_stub_hash_entry *stub_entry;
    581      1.1  christos   char* name;
    582      1.1  christos   bfd_boolean result;
    583      1.1  christos 
    584      1.1  christos   info = (struct bfd_link_info *) in_arg;
    585      1.1  christos   htab = m68hc11_elf_hash_table (info);
    586      1.1  christos   if (htab == NULL)
    587      1.1  christos     return FALSE;
    588      1.1  christos 
    589      1.1  christos   /* Massage our args to the form they really have.  */
    590      1.1  christos   stub_entry = (struct elf32_m68hc11_stub_hash_entry *) gen_entry;
    591      1.1  christos 
    592      1.1  christos   /* Generate the trampoline according to HC11 or HC12.  */
    593      1.1  christos   result = (* htab->build_one_stub) (gen_entry, in_arg);
    594      1.1  christos 
    595      1.1  christos   /* Make a printable name that does not conflict with the real function.  */
    596  1.1.1.3  christos   name = concat ("tramp.", stub_entry->root.string, NULL);
    597      1.1  christos 
    598      1.1  christos   /* Export the symbol for debugging/disassembling.  */
    599      1.1  christos   m68hc11_elf_set_symbol (htab->stub_bfd, info, name,
    600  1.1.1.4  christos 			  stub_entry->stub_offset,
    601  1.1.1.4  christos 			  stub_entry->stub_sec);
    602  1.1.1.3  christos   free (name);
    603      1.1  christos   return result;
    604      1.1  christos }
    605      1.1  christos 
    606      1.1  christos /* Export a symbol or set its value and section.  */
    607      1.1  christos static void
    608      1.1  christos m68hc11_elf_set_symbol (bfd *abfd, struct bfd_link_info *info,
    609  1.1.1.4  christos 			const char *name, bfd_vma value, asection *sec)
    610      1.1  christos {
    611      1.1  christos   struct elf_link_hash_entry *h;
    612      1.1  christos 
    613      1.1  christos   h = (struct elf_link_hash_entry *)
    614      1.1  christos     bfd_link_hash_lookup (info->hash, name, FALSE, FALSE, FALSE);
    615      1.1  christos   if (h == NULL)
    616      1.1  christos     {
    617      1.1  christos       _bfd_generic_link_add_one_symbol (info, abfd,
    618  1.1.1.4  christos 					name,
    619  1.1.1.4  christos 					BSF_GLOBAL,
    620  1.1.1.4  christos 					sec,
    621  1.1.1.4  christos 					value,
    622  1.1.1.4  christos 					(const char*) NULL,
    623  1.1.1.4  christos 					TRUE, FALSE, NULL);
    624      1.1  christos     }
    625      1.1  christos   else
    626      1.1  christos     {
    627      1.1  christos       h->root.type = bfd_link_hash_defined;
    628      1.1  christos       h->root.u.def.value = value;
    629      1.1  christos       h->root.u.def.section = sec;
    630      1.1  christos     }
    631      1.1  christos }
    632      1.1  christos 
    633      1.1  christos 
    634      1.1  christos /* Build all the stubs associated with the current output file.  The
    635      1.1  christos    stubs are kept in a hash table attached to the main linker hash
    636      1.1  christos    table.  This function is called via m68hc12elf_finish in the
    637      1.1  christos    linker.  */
    638      1.1  christos 
    639      1.1  christos bfd_boolean
    640      1.1  christos elf32_m68hc11_build_stubs (bfd *abfd, struct bfd_link_info *info)
    641      1.1  christos {
    642      1.1  christos   asection *stub_sec;
    643      1.1  christos   struct bfd_hash_table *table;
    644      1.1  christos   struct m68hc11_elf_link_hash_table *htab;
    645      1.1  christos   struct m68hc11_scan_param param;
    646      1.1  christos 
    647      1.1  christos   m68hc11_elf_get_bank_parameters (info);
    648      1.1  christos   htab = m68hc11_elf_hash_table (info);
    649      1.1  christos   if (htab == NULL)
    650      1.1  christos     return FALSE;
    651      1.1  christos 
    652      1.1  christos   for (stub_sec = htab->stub_bfd->sections;
    653      1.1  christos        stub_sec != NULL;
    654      1.1  christos        stub_sec = stub_sec->next)
    655      1.1  christos     {
    656      1.1  christos       bfd_size_type size;
    657      1.1  christos 
    658      1.1  christos       /* Allocate memory to hold the linker stubs.  */
    659      1.1  christos       size = stub_sec->size;
    660      1.1  christos       stub_sec->contents = (unsigned char *) bfd_zalloc (htab->stub_bfd, size);
    661      1.1  christos       if (stub_sec->contents == NULL && size != 0)
    662      1.1  christos 	return FALSE;
    663      1.1  christos       stub_sec->size = 0;
    664      1.1  christos     }
    665      1.1  christos 
    666      1.1  christos   /* Build the stubs as directed by the stub hash table.  */
    667      1.1  christos   table = htab->stub_hash_table;
    668      1.1  christos   bfd_hash_traverse (table, m68hc11_elf_export_one_stub, info);
    669  1.1.1.2  christos 
    670      1.1  christos   /* Scan the output sections to see if we use the memory banks.
    671      1.1  christos      If so, export the symbols that define how the memory banks
    672      1.1  christos      are mapped.  This is used by gdb and the simulator to obtain
    673      1.1  christos      the information.  It can be used by programs to burn the eprom
    674      1.1  christos      at the good addresses.  */
    675      1.1  christos   param.use_memory_banks = FALSE;
    676      1.1  christos   param.pinfo = &htab->pinfo;
    677      1.1  christos   bfd_map_over_sections (abfd, scan_sections_for_abi, &param);
    678      1.1  christos   if (param.use_memory_banks)
    679      1.1  christos     {
    680      1.1  christos       m68hc11_elf_set_symbol (abfd, info, BFD_M68HC11_BANK_START_NAME,
    681  1.1.1.4  christos 			      htab->pinfo.bank_physical,
    682  1.1.1.4  christos 			      bfd_abs_section_ptr);
    683      1.1  christos       m68hc11_elf_set_symbol (abfd, info, BFD_M68HC11_BANK_VIRTUAL_NAME,
    684  1.1.1.4  christos 			      htab->pinfo.bank_virtual,
    685  1.1.1.4  christos 			      bfd_abs_section_ptr);
    686      1.1  christos       m68hc11_elf_set_symbol (abfd, info, BFD_M68HC11_BANK_SIZE_NAME,
    687  1.1.1.4  christos 			      htab->pinfo.bank_size,
    688  1.1.1.4  christos 			      bfd_abs_section_ptr);
    689      1.1  christos     }
    690      1.1  christos 
    691      1.1  christos   return TRUE;
    692      1.1  christos }
    693      1.1  christos 
    694      1.1  christos void
    695      1.1  christos m68hc11_elf_get_bank_parameters (struct bfd_link_info *info)
    696      1.1  christos {
    697      1.1  christos   unsigned i;
    698      1.1  christos   struct m68hc11_page_info *pinfo;
    699      1.1  christos   struct bfd_link_hash_entry *h;
    700      1.1  christos   struct m68hc11_elf_link_hash_table *htab;
    701      1.1  christos 
    702      1.1  christos   htab = m68hc11_elf_hash_table (info);
    703      1.1  christos   if (htab == NULL)
    704      1.1  christos     return;
    705      1.1  christos 
    706      1.1  christos   pinfo = & htab->pinfo;
    707      1.1  christos   if (pinfo->bank_param_initialized)
    708      1.1  christos     return;
    709      1.1  christos 
    710      1.1  christos   pinfo->bank_virtual = M68HC12_BANK_VIRT;
    711      1.1  christos   pinfo->bank_mask = M68HC12_BANK_MASK;
    712      1.1  christos   pinfo->bank_physical = M68HC12_BANK_BASE;
    713      1.1  christos   pinfo->bank_shift = M68HC12_BANK_SHIFT;
    714      1.1  christos   pinfo->bank_size = 1 << M68HC12_BANK_SHIFT;
    715      1.1  christos 
    716      1.1  christos   h = bfd_link_hash_lookup (info->hash, BFD_M68HC11_BANK_START_NAME,
    717  1.1.1.4  christos 			    FALSE, FALSE, TRUE);
    718      1.1  christos   if (h != (struct bfd_link_hash_entry*) NULL
    719      1.1  christos       && h->type == bfd_link_hash_defined)
    720      1.1  christos     pinfo->bank_physical = (h->u.def.value
    721  1.1.1.4  christos 			    + h->u.def.section->output_section->vma
    722  1.1.1.4  christos 			    + h->u.def.section->output_offset);
    723      1.1  christos 
    724      1.1  christos   h = bfd_link_hash_lookup (info->hash, BFD_M68HC11_BANK_VIRTUAL_NAME,
    725  1.1.1.4  christos 			    FALSE, FALSE, TRUE);
    726      1.1  christos   if (h != (struct bfd_link_hash_entry*) NULL
    727      1.1  christos       && h->type == bfd_link_hash_defined)
    728      1.1  christos     pinfo->bank_virtual = (h->u.def.value
    729  1.1.1.4  christos 			   + h->u.def.section->output_section->vma
    730  1.1.1.4  christos 			   + h->u.def.section->output_offset);
    731      1.1  christos 
    732      1.1  christos   h = bfd_link_hash_lookup (info->hash, BFD_M68HC11_BANK_SIZE_NAME,
    733  1.1.1.4  christos 			    FALSE, FALSE, TRUE);
    734      1.1  christos   if (h != (struct bfd_link_hash_entry*) NULL
    735      1.1  christos       && h->type == bfd_link_hash_defined)
    736      1.1  christos     pinfo->bank_size = (h->u.def.value
    737  1.1.1.4  christos 			+ h->u.def.section->output_section->vma
    738  1.1.1.4  christos 			+ h->u.def.section->output_offset);
    739      1.1  christos 
    740      1.1  christos   pinfo->bank_shift = 0;
    741      1.1  christos   for (i = pinfo->bank_size; i != 0; i >>= 1)
    742      1.1  christos     pinfo->bank_shift++;
    743      1.1  christos   pinfo->bank_shift--;
    744      1.1  christos   pinfo->bank_mask = (1 << pinfo->bank_shift) - 1;
    745      1.1  christos   pinfo->bank_physical_end = pinfo->bank_physical + pinfo->bank_size;
    746      1.1  christos   pinfo->bank_param_initialized = 1;
    747      1.1  christos 
    748      1.1  christos   h = bfd_link_hash_lookup (info->hash, "__far_trampoline", FALSE,
    749  1.1.1.4  christos 			    FALSE, TRUE);
    750      1.1  christos   if (h != (struct bfd_link_hash_entry*) NULL
    751      1.1  christos       && h->type == bfd_link_hash_defined)
    752      1.1  christos     pinfo->trampoline_addr = (h->u.def.value
    753  1.1.1.4  christos 			      + h->u.def.section->output_section->vma
    754  1.1.1.4  christos 			      + h->u.def.section->output_offset);
    755      1.1  christos }
    756      1.1  christos 
    757      1.1  christos /* Return 1 if the address is in banked memory.
    758      1.1  christos    This can be applied to a virtual address and to a physical address.  */
    759      1.1  christos int
    760      1.1  christos m68hc11_addr_is_banked (struct m68hc11_page_info *pinfo, bfd_vma addr)
    761      1.1  christos {
    762      1.1  christos   if (addr >= pinfo->bank_virtual)
    763      1.1  christos     return 1;
    764      1.1  christos 
    765      1.1  christos   if (addr >= pinfo->bank_physical && addr <= pinfo->bank_physical_end)
    766      1.1  christos     return 1;
    767      1.1  christos 
    768      1.1  christos   return 0;
    769      1.1  christos }
    770      1.1  christos 
    771      1.1  christos /* Return the physical address seen by the processor, taking
    772      1.1  christos    into account banked memory.  */
    773      1.1  christos bfd_vma
    774      1.1  christos m68hc11_phys_addr (struct m68hc11_page_info *pinfo, bfd_vma addr)
    775      1.1  christos {
    776      1.1  christos   if (addr < pinfo->bank_virtual)
    777      1.1  christos     return addr;
    778      1.1  christos 
    779      1.1  christos   /* Map the address to the memory bank.  */
    780      1.1  christos   addr -= pinfo->bank_virtual;
    781      1.1  christos   addr &= pinfo->bank_mask;
    782      1.1  christos   addr += pinfo->bank_physical;
    783      1.1  christos   return addr;
    784      1.1  christos }
    785      1.1  christos 
    786      1.1  christos /* Return the page number corresponding to an address in banked memory.  */
    787      1.1  christos bfd_vma
    788      1.1  christos m68hc11_phys_page (struct m68hc11_page_info *pinfo, bfd_vma addr)
    789      1.1  christos {
    790      1.1  christos   if (addr < pinfo->bank_virtual)
    791      1.1  christos     return 0;
    792      1.1  christos 
    793      1.1  christos   /* Map the address to the memory bank.  */
    794      1.1  christos   addr -= pinfo->bank_virtual;
    795      1.1  christos   addr >>= pinfo->bank_shift;
    796      1.1  christos   addr &= 0x0ff;
    797      1.1  christos   return addr;
    798      1.1  christos }
    799      1.1  christos 
    800      1.1  christos /* This function is used for relocs which are only used for relaxing,
    801      1.1  christos    which the linker should otherwise ignore.  */
    802      1.1  christos 
    803      1.1  christos bfd_reloc_status_type
    804      1.1  christos m68hc11_elf_ignore_reloc (bfd *abfd ATTRIBUTE_UNUSED,
    805  1.1.1.4  christos 			  arelent *reloc_entry,
    806  1.1.1.4  christos 			  asymbol *symbol ATTRIBUTE_UNUSED,
    807  1.1.1.4  christos 			  void *data ATTRIBUTE_UNUSED,
    808  1.1.1.4  christos 			  asection *input_section,
    809  1.1.1.4  christos 			  bfd *output_bfd,
    810  1.1.1.4  christos 			  char **error_message ATTRIBUTE_UNUSED)
    811      1.1  christos {
    812      1.1  christos   if (output_bfd != NULL)
    813      1.1  christos     reloc_entry->address += input_section->output_offset;
    814      1.1  christos   return bfd_reloc_ok;
    815      1.1  christos }
    816      1.1  christos 
    817      1.1  christos bfd_reloc_status_type
    818      1.1  christos m68hc11_elf_special_reloc (bfd *abfd ATTRIBUTE_UNUSED,
    819  1.1.1.4  christos 			   arelent *reloc_entry,
    820  1.1.1.4  christos 			   asymbol *symbol,
    821  1.1.1.4  christos 			   void *data ATTRIBUTE_UNUSED,
    822  1.1.1.4  christos 			   asection *input_section,
    823  1.1.1.4  christos 			   bfd *output_bfd,
    824  1.1.1.4  christos 			   char **error_message ATTRIBUTE_UNUSED)
    825      1.1  christos {
    826      1.1  christos   if (output_bfd != (bfd *) NULL
    827      1.1  christos       && (symbol->flags & BSF_SECTION_SYM) == 0
    828      1.1  christos       && (! reloc_entry->howto->partial_inplace
    829      1.1  christos 	  || reloc_entry->addend == 0))
    830      1.1  christos     {
    831      1.1  christos       reloc_entry->address += input_section->output_offset;
    832      1.1  christos       return bfd_reloc_ok;
    833      1.1  christos     }
    834      1.1  christos 
    835      1.1  christos   if (output_bfd != NULL)
    836      1.1  christos     return bfd_reloc_continue;
    837      1.1  christos 
    838      1.1  christos   if (reloc_entry->address > bfd_get_section_limit (abfd, input_section))
    839      1.1  christos     return bfd_reloc_outofrange;
    840      1.1  christos 
    841      1.1  christos   abort();
    842      1.1  christos }
    843      1.1  christos 
    844      1.1  christos /* Look through the relocs for a section during the first phase.
    845      1.1  christos    Since we don't do .gots or .plts, we just need to consider the
    846      1.1  christos    virtual table relocs for gc.  */
    847      1.1  christos 
    848      1.1  christos bfd_boolean
    849      1.1  christos elf32_m68hc11_check_relocs (bfd *abfd, struct bfd_link_info *info,
    850  1.1.1.4  christos 			    asection *sec, const Elf_Internal_Rela *relocs)
    851      1.1  christos {
    852  1.1.1.4  christos   Elf_Internal_Shdr *		symtab_hdr;
    853      1.1  christos   struct elf_link_hash_entry ** sym_hashes;
    854  1.1.1.4  christos   const Elf_Internal_Rela *	rel;
    855  1.1.1.4  christos   const Elf_Internal_Rela *	rel_end;
    856      1.1  christos 
    857  1.1.1.2  christos   if (bfd_link_relocatable (info))
    858      1.1  christos     return TRUE;
    859      1.1  christos 
    860      1.1  christos   symtab_hdr = & elf_tdata (abfd)->symtab_hdr;
    861      1.1  christos   sym_hashes = elf_sym_hashes (abfd);
    862      1.1  christos   rel_end = relocs + sec->reloc_count;
    863      1.1  christos 
    864      1.1  christos   for (rel = relocs; rel < rel_end; rel++)
    865      1.1  christos     {
    866      1.1  christos       struct elf_link_hash_entry * h;
    867      1.1  christos       unsigned long r_symndx;
    868      1.1  christos 
    869      1.1  christos       r_symndx = ELF32_R_SYM (rel->r_info);
    870      1.1  christos 
    871      1.1  christos       if (r_symndx < symtab_hdr->sh_info)
    872  1.1.1.4  christos 	h = NULL;
    873      1.1  christos       else
    874      1.1  christos 	{
    875      1.1  christos 	  h = sym_hashes [r_symndx - symtab_hdr->sh_info];
    876      1.1  christos 	  while (h->root.type == bfd_link_hash_indirect
    877      1.1  christos 		 || h->root.type == bfd_link_hash_warning)
    878      1.1  christos 	    h = (struct elf_link_hash_entry *) h->root.u.i.link;
    879      1.1  christos 	}
    880      1.1  christos 
    881      1.1  christos       switch (ELF32_R_TYPE (rel->r_info))
    882  1.1.1.4  christos 	{
    883  1.1.1.4  christos 	/* This relocation describes the C++ object vtable hierarchy.
    884  1.1.1.4  christos 	   Reconstruct it for later use during GC.  */
    885  1.1.1.4  christos 	case R_M68HC11_GNU_VTINHERIT:
    886  1.1.1.4  christos 	  if (!bfd_elf_gc_record_vtinherit (abfd, sec, h, rel->r_offset))
    887  1.1.1.4  christos 	    return FALSE;
    888  1.1.1.4  christos 	  break;
    889  1.1.1.4  christos 
    890  1.1.1.4  christos 	/* This relocation describes which C++ vtable entries are actually
    891  1.1.1.4  christos 	   used.  Record for later use during GC.  */
    892  1.1.1.4  christos 	case R_M68HC11_GNU_VTENTRY:
    893  1.1.1.5  christos 	  if (!bfd_elf_gc_record_vtentry (abfd, sec, h, rel->r_addend))
    894  1.1.1.4  christos 	    return FALSE;
    895  1.1.1.4  christos 	  break;
    896  1.1.1.4  christos 	}
    897      1.1  christos     }
    898      1.1  christos 
    899      1.1  christos   return TRUE;
    900      1.1  christos }
    901      1.1  christos 
    902  1.1.1.5  christos static bfd_boolean ATTRIBUTE_PRINTF (6, 7)
    903  1.1.1.5  christos reloc_warning (struct bfd_link_info *info, const char *name, bfd *input_bfd,
    904  1.1.1.5  christos 	       asection *input_section, const Elf_Internal_Rela *rel,
    905  1.1.1.5  christos 	       const char *fmt, ...)
    906  1.1.1.5  christos {
    907  1.1.1.5  christos   va_list ap;
    908  1.1.1.5  christos   char *buf;
    909  1.1.1.5  christos   int ret;
    910  1.1.1.5  christos 
    911  1.1.1.5  christos   va_start (ap, fmt);
    912  1.1.1.5  christos   ret = vasprintf (&buf, fmt, ap);
    913  1.1.1.5  christos   va_end (ap);
    914  1.1.1.5  christos   if (ret < 0)
    915  1.1.1.5  christos     {
    916  1.1.1.5  christos       bfd_set_error (bfd_error_no_memory);
    917  1.1.1.5  christos       return FALSE;
    918  1.1.1.5  christos     }
    919  1.1.1.5  christos   info->callbacks->warning (info, buf, name, input_bfd, input_section,
    920  1.1.1.5  christos 			    rel->r_offset);
    921  1.1.1.5  christos   free (buf);
    922  1.1.1.5  christos   return TRUE;
    923  1.1.1.5  christos }
    924  1.1.1.5  christos 
    925      1.1  christos /* Relocate a 68hc11/68hc12 ELF section.  */
    926      1.1  christos bfd_boolean
    927      1.1  christos elf32_m68hc11_relocate_section (bfd *output_bfd ATTRIBUTE_UNUSED,
    928  1.1.1.4  christos 				struct bfd_link_info *info,
    929  1.1.1.4  christos 				bfd *input_bfd, asection *input_section,
    930  1.1.1.4  christos 				bfd_byte *contents, Elf_Internal_Rela *relocs,
    931  1.1.1.4  christos 				Elf_Internal_Sym *local_syms,
    932  1.1.1.4  christos 				asection **local_sections)
    933      1.1  christos {
    934      1.1  christos   Elf_Internal_Shdr *symtab_hdr;
    935      1.1  christos   struct elf_link_hash_entry **sym_hashes;
    936      1.1  christos   Elf_Internal_Rela *rel, *relend;
    937      1.1  christos   const char *name = NULL;
    938      1.1  christos   struct m68hc11_page_info *pinfo;
    939      1.1  christos   const struct elf_backend_data * const ebd = get_elf_backend_data (input_bfd);
    940      1.1  christos   struct m68hc11_elf_link_hash_table *htab;
    941      1.1  christos   unsigned long e_flags;
    942      1.1  christos 
    943      1.1  christos   symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
    944      1.1  christos   sym_hashes = elf_sym_hashes (input_bfd);
    945      1.1  christos   e_flags = elf_elfheader (input_bfd)->e_flags;
    946      1.1  christos 
    947      1.1  christos   htab = m68hc11_elf_hash_table (info);
    948      1.1  christos   if (htab == NULL)
    949      1.1  christos     return FALSE;
    950      1.1  christos 
    951      1.1  christos   /* Get memory bank parameters.  */
    952      1.1  christos   m68hc11_elf_get_bank_parameters (info);
    953      1.1  christos 
    954      1.1  christos   pinfo = & htab->pinfo;
    955      1.1  christos   rel = relocs;
    956      1.1  christos   relend = relocs + input_section->reloc_count;
    957      1.1  christos 
    958      1.1  christos   for (; rel < relend; rel++)
    959      1.1  christos     {
    960      1.1  christos       int r_type;
    961      1.1  christos       arelent arel;
    962      1.1  christos       reloc_howto_type *howto;
    963      1.1  christos       unsigned long r_symndx;
    964      1.1  christos       Elf_Internal_Sym *sym;
    965      1.1  christos       asection *sec;
    966      1.1  christos       bfd_vma relocation = 0;
    967      1.1  christos       bfd_reloc_status_type r = bfd_reloc_undefined;
    968      1.1  christos       bfd_vma phys_page;
    969      1.1  christos       bfd_vma phys_addr;
    970      1.1  christos       bfd_vma insn_addr;
    971      1.1  christos       bfd_vma insn_page;
    972      1.1  christos       bfd_boolean is_far = FALSE;
    973      1.1  christos       bfd_boolean is_xgate_symbol = FALSE;
    974      1.1  christos       bfd_boolean is_section_symbol = FALSE;
    975      1.1  christos       struct elf_link_hash_entry *h;
    976      1.1  christos       bfd_vma val;
    977  1.1.1.5  christos       const char *msg;
    978      1.1  christos 
    979      1.1  christos       r_symndx = ELF32_R_SYM (rel->r_info);
    980      1.1  christos       r_type = ELF32_R_TYPE (rel->r_info);
    981      1.1  christos 
    982      1.1  christos       if (r_type == R_M68HC11_GNU_VTENTRY
    983  1.1.1.4  christos 	  || r_type == R_M68HC11_GNU_VTINHERIT)
    984  1.1.1.4  christos 	continue;
    985      1.1  christos 
    986  1.1.1.4  christos       if (! (*ebd->elf_info_to_howto_rel) (input_bfd, &arel, rel))
    987  1.1.1.4  christos 	continue;
    988      1.1  christos       howto = arel.howto;
    989      1.1  christos 
    990      1.1  christos       h = NULL;
    991      1.1  christos       sym = NULL;
    992      1.1  christos       sec = NULL;
    993      1.1  christos       if (r_symndx < symtab_hdr->sh_info)
    994      1.1  christos 	{
    995      1.1  christos 	  sym = local_syms + r_symndx;
    996      1.1  christos 	  sec = local_sections[r_symndx];
    997      1.1  christos 	  relocation = (sec->output_section->vma
    998      1.1  christos 			+ sec->output_offset
    999      1.1  christos 			+ sym->st_value);
   1000      1.1  christos 	  is_far = (sym && (sym->st_other & STO_M68HC12_FAR));
   1001      1.1  christos 	  is_xgate_symbol = (sym && (sym->st_target_internal));
   1002      1.1  christos 	  is_section_symbol = ELF_ST_TYPE (sym->st_info) & STT_SECTION;
   1003      1.1  christos 	}
   1004      1.1  christos       else
   1005      1.1  christos 	{
   1006  1.1.1.2  christos 	  bfd_boolean unresolved_reloc, warned, ignored;
   1007      1.1  christos 
   1008      1.1  christos 	  RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel,
   1009      1.1  christos 				   r_symndx, symtab_hdr, sym_hashes,
   1010      1.1  christos 				   h, sec, relocation, unresolved_reloc,
   1011  1.1.1.2  christos 				   warned, ignored);
   1012      1.1  christos 
   1013      1.1  christos 	  is_far = (h && (h->other & STO_M68HC12_FAR));
   1014      1.1  christos 	  is_xgate_symbol = (h && (h->target_internal));
   1015      1.1  christos 	}
   1016      1.1  christos 
   1017      1.1  christos       if (sec != NULL && discarded_section (sec))
   1018      1.1  christos 	RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section,
   1019      1.1  christos 					 rel, 1, relend, howto, 0, contents);
   1020      1.1  christos 
   1021  1.1.1.2  christos       if (bfd_link_relocatable (info))
   1022      1.1  christos 	{
   1023      1.1  christos 	  /* This is a relocatable link.  We don't have to change
   1024      1.1  christos 	     anything, unless the reloc is against a section symbol,
   1025      1.1  christos 	     in which case we have to adjust according to where the
   1026      1.1  christos 	     section symbol winds up in the output section.  */
   1027      1.1  christos 	  if (sym != NULL && ELF_ST_TYPE (sym->st_info) == STT_SECTION)
   1028      1.1  christos 	    rel->r_addend += sec->output_offset;
   1029      1.1  christos 	  continue;
   1030      1.1  christos 	}
   1031      1.1  christos 
   1032      1.1  christos       if (h != NULL)
   1033      1.1  christos 	name = h->root.root.string;
   1034      1.1  christos       else
   1035      1.1  christos 	{
   1036      1.1  christos 	  name = (bfd_elf_string_from_elf_section
   1037      1.1  christos 		  (input_bfd, symtab_hdr->sh_link, sym->st_name));
   1038      1.1  christos 	  if (name == NULL || *name == '\0')
   1039  1.1.1.5  christos 	    name = bfd_section_name (sec);
   1040      1.1  christos 	}
   1041      1.1  christos 
   1042      1.1  christos       if (is_far && ELF32_R_TYPE (rel->r_info) == R_M68HC11_16)
   1043      1.1  christos 	{
   1044      1.1  christos 	  struct elf32_m68hc11_stub_hash_entry* stub;
   1045      1.1  christos 
   1046      1.1  christos 	  stub = m68hc12_stub_hash_lookup (htab->stub_hash_table,
   1047      1.1  christos 					   name, FALSE, FALSE);
   1048      1.1  christos 	  if (stub)
   1049      1.1  christos 	    {
   1050      1.1  christos 	      relocation = stub->stub_offset
   1051      1.1  christos 		+ stub->stub_sec->output_section->vma
   1052      1.1  christos 		+ stub->stub_sec->output_offset;
   1053      1.1  christos 	      is_far = FALSE;
   1054      1.1  christos 	    }
   1055      1.1  christos 	}
   1056      1.1  christos 
   1057      1.1  christos       /* Do the memory bank mapping.  */
   1058      1.1  christos       phys_addr = m68hc11_phys_addr (pinfo, relocation + rel->r_addend);
   1059      1.1  christos       phys_page = m68hc11_phys_page (pinfo, relocation + rel->r_addend);
   1060      1.1  christos       switch (r_type)
   1061  1.1.1.4  christos 	{
   1062  1.1.1.4  christos 	case R_M68HC12_LO8XG:
   1063  1.1.1.4  christos 	  /* This relocation is specific to XGATE IMM16 calls and will precede
   1064      1.1  christos 	     a HI8. tc-m68hc11 only generates them in pairs.
   1065      1.1  christos 	     Leave the relocation to the HI8XG step.  */
   1066  1.1.1.4  christos 	  r = bfd_reloc_ok;
   1067  1.1.1.4  christos 	  r_type = R_M68HC11_NONE;
   1068  1.1.1.4  christos 	  break;
   1069  1.1.1.4  christos 
   1070  1.1.1.4  christos 	case R_M68HC12_HI8XG:
   1071  1.1.1.4  christos 	  /* This relocation is specific to XGATE IMM16 calls and must follow
   1072  1.1.1.4  christos 	     a LO8XG. Does not actually check that it was a LO8XG.
   1073      1.1  christos 	     Adjusts high and low bytes.  */
   1074  1.1.1.4  christos 	  relocation = phys_addr;
   1075  1.1.1.4  christos 	  if ((e_flags & E_M68HC11_XGATE_RAMOFFSET)
   1076      1.1  christos 	      && (relocation >= 0x2000))
   1077      1.1  christos 	    relocation += 0xc000; /* HARDCODED RAM offset for XGATE.  */
   1078      1.1  christos 
   1079  1.1.1.4  christos 	  /* Fetch 16 bit value including low byte in previous insn.  */
   1080  1.1.1.4  christos 	  val = (bfd_get_8 (input_bfd, (bfd_byte*) contents + rel->r_offset) << 8)
   1081      1.1  christos 	    | bfd_get_8 (input_bfd, (bfd_byte*) contents + rel->r_offset - 2);
   1082      1.1  christos 
   1083  1.1.1.4  christos 	  /* Add on value to preserve carry, then write zero to high byte.  */
   1084  1.1.1.4  christos 	  relocation += val;
   1085      1.1  christos 
   1086  1.1.1.4  christos 	  /* Write out top byte.  */
   1087  1.1.1.4  christos 	  bfd_put_8 (input_bfd, (relocation >> 8) & 0xff,
   1088      1.1  christos 		     (bfd_byte*) contents + rel->r_offset);
   1089      1.1  christos 
   1090  1.1.1.4  christos 	  /* Write out low byte to previous instruction.  */
   1091  1.1.1.4  christos 	  bfd_put_8 (input_bfd, relocation & 0xff,
   1092      1.1  christos 		     (bfd_byte*) contents + rel->r_offset - 2);
   1093      1.1  christos 
   1094  1.1.1.4  christos 	  /* Mark as relocation completed.  */
   1095  1.1.1.4  christos 	  r = bfd_reloc_ok;
   1096  1.1.1.4  christos 	  r_type = R_M68HC11_NONE;
   1097  1.1.1.4  christos 	  break;
   1098  1.1.1.4  christos 
   1099  1.1.1.4  christos 	/* The HI8 and LO8 relocs are generated by %hi(expr) %lo(expr)
   1100  1.1.1.4  christos 	   assembler directives. %hi does not support carry.  */
   1101  1.1.1.4  christos 	case R_M68HC11_HI8:
   1102  1.1.1.4  christos 	case R_M68HC11_LO8:
   1103  1.1.1.4  christos 	  relocation = phys_addr;
   1104  1.1.1.4  christos 	  break;
   1105  1.1.1.4  christos 
   1106  1.1.1.4  christos 	case R_M68HC11_24:
   1107  1.1.1.4  christos 	  /* Reloc used by 68HC12 call instruction.  */
   1108  1.1.1.4  christos 	  bfd_put_16 (input_bfd, phys_addr,
   1109  1.1.1.4  christos 		      (bfd_byte*) contents + rel->r_offset);
   1110  1.1.1.4  christos 	  bfd_put_8 (input_bfd, phys_page,
   1111  1.1.1.4  christos 		     (bfd_byte*) contents + rel->r_offset + 2);
   1112  1.1.1.4  christos 	  r = bfd_reloc_ok;
   1113  1.1.1.4  christos 	  r_type = R_M68HC11_NONE;
   1114  1.1.1.4  christos 	  break;
   1115  1.1.1.4  christos 
   1116  1.1.1.4  christos 	case R_M68HC11_NONE:
   1117  1.1.1.4  christos 	  r = bfd_reloc_ok;
   1118  1.1.1.4  christos 	  break;
   1119  1.1.1.4  christos 
   1120  1.1.1.4  christos 	case R_M68HC11_LO16:
   1121  1.1.1.4  christos 	  /* Reloc generated by %addr(expr) gas to obtain the
   1122  1.1.1.4  christos 	     address as mapped in the memory bank window.  */
   1123  1.1.1.4  christos 	  relocation = phys_addr;
   1124  1.1.1.4  christos 	  break;
   1125  1.1.1.4  christos 
   1126  1.1.1.4  christos 	case R_M68HC11_PAGE:
   1127  1.1.1.4  christos 	  /* Reloc generated by %page(expr) gas to obtain the
   1128  1.1.1.4  christos 	     page number associated with the address.  */
   1129  1.1.1.4  christos 	  relocation = phys_page;
   1130  1.1.1.4  christos 	  break;
   1131  1.1.1.4  christos 
   1132  1.1.1.4  christos 	case R_M68HC11_16:
   1133  1.1.1.4  christos 	  if (is_far)
   1134  1.1.1.4  christos 	    {
   1135  1.1.1.5  christos 	      if (!reloc_warning (info, name, input_bfd, input_section, rel,
   1136  1.1.1.5  christos 				  _("reference to the far symbol `%s' using a "
   1137  1.1.1.5  christos 				    "wrong relocation may result in incorrect "
   1138  1.1.1.5  christos 				    "execution"), name))
   1139  1.1.1.5  christos 		return FALSE;
   1140  1.1.1.4  christos 	    }
   1141      1.1  christos 
   1142  1.1.1.4  christos 	  /* Get virtual address of instruction having the relocation.  */
   1143  1.1.1.4  christos 	  insn_addr = input_section->output_section->vma
   1144  1.1.1.4  christos 	    + input_section->output_offset
   1145  1.1.1.4  christos 	    + rel->r_offset;
   1146      1.1  christos 
   1147  1.1.1.4  christos 	  insn_page = m68hc11_phys_page (pinfo, insn_addr);
   1148      1.1  christos 
   1149  1.1.1.4  christos 	 /* If we are linking an S12 instruction against an XGATE symbol, we
   1150  1.1.1.4  christos 	    need to change the offset of the symbol value so that it's correct
   1151      1.1  christos 	    from the S12's perspective.  */
   1152  1.1.1.4  christos 	  if (is_xgate_symbol)
   1153      1.1  christos 	    {
   1154      1.1  christos 	      /* The ram in the global space is mapped to 0x2000 in the 16-bit
   1155      1.1  christos 		 address space for S12 and 0xE000 in the 16-bit address space
   1156      1.1  christos 		 for XGATE.  */
   1157      1.1  christos 	      if (relocation >= 0xE000)
   1158      1.1  christos 		{
   1159      1.1  christos 		  /* We offset the address by the difference
   1160      1.1  christos 		     between these two mappings.  */
   1161      1.1  christos 		  relocation -= 0xC000;
   1162      1.1  christos 		  break;
   1163      1.1  christos 		}
   1164      1.1  christos 	      else
   1165      1.1  christos 		{
   1166  1.1.1.5  christos 		  if (!reloc_warning (info, name, input_bfd, input_section, rel,
   1167  1.1.1.5  christos 				      _("XGATE address (%lx) is not within "
   1168  1.1.1.5  christos 					"shared RAM(0xE000-0xFFFF), therefore "
   1169  1.1.1.5  christos 					"you must manually offset the address, "
   1170  1.1.1.5  christos 					"and possibly manage the page, in your "
   1171  1.1.1.5  christos 					"code."), (long) phys_addr))
   1172  1.1.1.5  christos 		    return FALSE;
   1173      1.1  christos 		  break;
   1174      1.1  christos 		}
   1175      1.1  christos 	    }
   1176      1.1  christos 
   1177  1.1.1.4  christos 	  if (m68hc11_addr_is_banked (pinfo, relocation + rel->r_addend)
   1178  1.1.1.4  christos 	      && m68hc11_addr_is_banked (pinfo, insn_addr)
   1179  1.1.1.5  christos 	      && phys_page != insn_page
   1180  1.1.1.5  christos 	      && !(e_flags & E_M68HC11_NO_BANK_WARNING))
   1181  1.1.1.4  christos 	    {
   1182  1.1.1.5  christos 	      if (!reloc_warning (info, name, input_bfd, input_section, rel,
   1183  1.1.1.5  christos 				  _("banked address [%lx:%04lx] (%lx) is not "
   1184  1.1.1.5  christos 				    "in the same bank as current banked "
   1185  1.1.1.5  christos 				    "address [%lx:%04lx] (%lx)"),
   1186  1.1.1.5  christos 				  (long) phys_page, (long) phys_addr,
   1187  1.1.1.5  christos 				  (long) (relocation + rel->r_addend),
   1188  1.1.1.5  christos 				  (long) insn_page,
   1189  1.1.1.5  christos 				  (long) m68hc11_phys_addr (pinfo, insn_addr),
   1190  1.1.1.5  christos 				  (long) insn_addr))
   1191  1.1.1.5  christos 		return FALSE;
   1192  1.1.1.4  christos 	      break;
   1193  1.1.1.4  christos 	    }
   1194      1.1  christos 
   1195  1.1.1.4  christos 	  if (phys_page != 0 && insn_page == 0)
   1196  1.1.1.4  christos 	    {
   1197  1.1.1.5  christos 	      if (!reloc_warning (info, name, input_bfd, input_section, rel,
   1198  1.1.1.5  christos 				  _("reference to a banked address [%lx:%04lx] "
   1199  1.1.1.5  christos 				    "in the normal address space at %04lx"),
   1200  1.1.1.5  christos 				  (long) phys_page, (long) phys_addr,
   1201  1.1.1.5  christos 				  (long) insn_addr))
   1202  1.1.1.5  christos 		return FALSE;
   1203  1.1.1.4  christos 	      relocation = phys_addr;
   1204  1.1.1.4  christos 	      break;
   1205  1.1.1.4  christos 	    }
   1206  1.1.1.4  christos 
   1207  1.1.1.4  christos 	  /* If this is a banked address use the phys_addr so that
   1208  1.1.1.4  christos 	     we stay in the banked window.  */
   1209  1.1.1.4  christos 	  if (m68hc11_addr_is_banked (pinfo, relocation + rel->r_addend))
   1210  1.1.1.4  christos 	    relocation = phys_addr;
   1211  1.1.1.4  christos 	  break;
   1212  1.1.1.4  christos 	}
   1213      1.1  christos 
   1214      1.1  christos       /* If we are linking an XGATE instruction against an S12 symbol, we
   1215  1.1.1.4  christos 	 need to change the offset of the symbol value so that it's correct
   1216      1.1  christos 	 from the XGATE's perspective.  */
   1217      1.1  christos       if (!strcmp (howto->name, "R_XGATE_IMM8_LO")
   1218  1.1.1.4  christos 	  || !strcmp (howto->name, "R_XGATE_IMM8_HI"))
   1219  1.1.1.4  christos 	{
   1220  1.1.1.4  christos 	  /* We can only offset S12 addresses that lie within the non-paged
   1221  1.1.1.4  christos 	     area of RAM.  */
   1222  1.1.1.4  christos 	  if (!is_xgate_symbol && !is_section_symbol)
   1223  1.1.1.4  christos 	    {
   1224  1.1.1.4  christos 	      /* The ram in the global space is mapped to 0x2000 and stops at
   1225  1.1.1.4  christos 		 0x4000 in the 16-bit address space for S12 and 0xE000 in the
   1226  1.1.1.4  christos 		 16-bit address space for XGATE.  */
   1227  1.1.1.4  christos 	      if (relocation >= 0x2000 && relocation < 0x4000)
   1228  1.1.1.4  christos 		 /* We offset the address by the difference
   1229  1.1.1.4  christos 		   between these two mappings.  */
   1230  1.1.1.4  christos 		relocation += 0xC000;
   1231  1.1.1.4  christos 	      else
   1232  1.1.1.4  christos 		{
   1233  1.1.1.5  christos 		  if (!reloc_warning (info, name, input_bfd, input_section, rel,
   1234  1.1.1.5  christos 				      _("S12 address (%lx) is not within "
   1235  1.1.1.5  christos 					"shared RAM(0x2000-0x4000), therefore "
   1236  1.1.1.5  christos 					"you must manually offset the address "
   1237  1.1.1.5  christos 					"in your code"), (long) phys_addr))
   1238  1.1.1.5  christos 		    return FALSE;
   1239  1.1.1.4  christos 		  break;
   1240  1.1.1.4  christos 		}
   1241  1.1.1.4  christos 	    }
   1242  1.1.1.4  christos 	}
   1243      1.1  christos 
   1244      1.1  christos       if (r_type != R_M68HC11_NONE)
   1245  1.1.1.4  christos 	{
   1246  1.1.1.4  christos 	  if ((r_type == R_M68HC12_PCREL_9) || (r_type == R_M68HC12_PCREL_10))
   1247  1.1.1.4  christos 	    r = _bfd_final_link_relocate (howto, input_bfd, input_section,
   1248  1.1.1.4  christos 				      contents, rel->r_offset,
   1249  1.1.1.4  christos 				      relocation - 2, rel->r_addend);
   1250  1.1.1.4  christos 	  else
   1251  1.1.1.4  christos 	    r = _bfd_final_link_relocate (howto, input_bfd, input_section,
   1252  1.1.1.4  christos 					  contents, rel->r_offset,
   1253  1.1.1.4  christos 					  relocation, rel->r_addend);
   1254  1.1.1.4  christos 	}
   1255      1.1  christos 
   1256      1.1  christos       if (r != bfd_reloc_ok)
   1257      1.1  christos 	{
   1258      1.1  christos 	  switch (r)
   1259      1.1  christos 	    {
   1260      1.1  christos 	    case bfd_reloc_overflow:
   1261  1.1.1.3  christos 	      (*info->callbacks->reloc_overflow)
   1262  1.1.1.3  christos 		(info, NULL, name, howto->name, (bfd_vma) 0,
   1263  1.1.1.3  christos 		 input_bfd, input_section, rel->r_offset);
   1264      1.1  christos 	      break;
   1265      1.1  christos 
   1266      1.1  christos 	    case bfd_reloc_undefined:
   1267  1.1.1.3  christos 	      (*info->callbacks->undefined_symbol)
   1268  1.1.1.3  christos 		(info, name, input_bfd, input_section, rel->r_offset, TRUE);
   1269      1.1  christos 	      break;
   1270      1.1  christos 
   1271      1.1  christos 	    case bfd_reloc_outofrange:
   1272      1.1  christos 	      msg = _ ("internal error: out of range error");
   1273      1.1  christos 	      goto common_error;
   1274      1.1  christos 
   1275      1.1  christos 	    case bfd_reloc_notsupported:
   1276      1.1  christos 	      msg = _ ("internal error: unsupported relocation error");
   1277      1.1  christos 	      goto common_error;
   1278      1.1  christos 
   1279      1.1  christos 	    case bfd_reloc_dangerous:
   1280      1.1  christos 	      msg = _ ("internal error: dangerous error");
   1281      1.1  christos 	      goto common_error;
   1282      1.1  christos 
   1283      1.1  christos 	    default:
   1284      1.1  christos 	      msg = _ ("internal error: unknown error");
   1285      1.1  christos 	      /* fall through */
   1286      1.1  christos 
   1287      1.1  christos 	    common_error:
   1288  1.1.1.3  christos 	      (*info->callbacks->warning) (info, msg, name, input_bfd,
   1289  1.1.1.3  christos 					   input_section, rel->r_offset);
   1290      1.1  christos 	      break;
   1291      1.1  christos 	    }
   1292      1.1  christos 	}
   1293      1.1  christos     }
   1294      1.1  christos 
   1295      1.1  christos   return TRUE;
   1296      1.1  christos }
   1297      1.1  christos 
   1298      1.1  christos 
   1299      1.1  christos 
   1300      1.1  christos /* Set and control ELF flags in ELF header.  */
   1302      1.1  christos 
   1303      1.1  christos bfd_boolean
   1304      1.1  christos _bfd_m68hc11_elf_set_private_flags (bfd *abfd, flagword flags)
   1305      1.1  christos {
   1306      1.1  christos   BFD_ASSERT (!elf_flags_init (abfd)
   1307      1.1  christos 	      || elf_elfheader (abfd)->e_flags == flags);
   1308      1.1  christos 
   1309      1.1  christos   elf_elfheader (abfd)->e_flags = flags;
   1310      1.1  christos   elf_flags_init (abfd) = TRUE;
   1311      1.1  christos   return TRUE;
   1312      1.1  christos }
   1313      1.1  christos 
   1314      1.1  christos /* Merge backend specific data from an object file to the output
   1315      1.1  christos    object file when linking.  */
   1316      1.1  christos 
   1317  1.1.1.4  christos bfd_boolean
   1318      1.1  christos _bfd_m68hc11_elf_merge_private_bfd_data (bfd *ibfd, struct bfd_link_info *info)
   1319  1.1.1.4  christos {
   1320      1.1  christos   bfd *obfd = info->output_bfd;
   1321      1.1  christos   flagword old_flags;
   1322      1.1  christos   flagword new_flags;
   1323      1.1  christos   bfd_boolean ok = TRUE;
   1324      1.1  christos 
   1325  1.1.1.4  christos   /* Check if we have the same endianness */
   1326      1.1  christos   if (!_bfd_generic_verify_endian_match (ibfd, info))
   1327      1.1  christos     return FALSE;
   1328      1.1  christos 
   1329      1.1  christos   if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour
   1330      1.1  christos       || bfd_get_flavour (obfd) != bfd_target_elf_flavour)
   1331      1.1  christos     return TRUE;
   1332      1.1  christos 
   1333      1.1  christos   new_flags = elf_elfheader (ibfd)->e_flags;
   1334      1.1  christos   elf_elfheader (obfd)->e_flags |= new_flags & EF_M68HC11_ABI;
   1335      1.1  christos   old_flags = elf_elfheader (obfd)->e_flags;
   1336      1.1  christos 
   1337      1.1  christos   if (! elf_flags_init (obfd))
   1338      1.1  christos     {
   1339      1.1  christos       elf_flags_init (obfd) = TRUE;
   1340      1.1  christos       elf_elfheader (obfd)->e_flags = new_flags;
   1341      1.1  christos       elf_elfheader (obfd)->e_ident[EI_CLASS]
   1342      1.1  christos 	= elf_elfheader (ibfd)->e_ident[EI_CLASS];
   1343      1.1  christos 
   1344      1.1  christos       if (bfd_get_arch (obfd) == bfd_get_arch (ibfd)
   1345      1.1  christos 	  && bfd_get_arch_info (obfd)->the_default)
   1346      1.1  christos 	{
   1347      1.1  christos 	  if (! bfd_set_arch_mach (obfd, bfd_get_arch (ibfd),
   1348      1.1  christos 				   bfd_get_mach (ibfd)))
   1349      1.1  christos 	    return FALSE;
   1350      1.1  christos 	}
   1351      1.1  christos 
   1352      1.1  christos       return TRUE;
   1353      1.1  christos     }
   1354      1.1  christos 
   1355      1.1  christos   /* Check ABI compatibility.  */
   1356      1.1  christos   if ((new_flags & E_M68HC11_I32) != (old_flags & E_M68HC11_I32))
   1357  1.1.1.4  christos     {
   1358  1.1.1.4  christos       _bfd_error_handler
   1359  1.1.1.4  christos 	(_("%pB: linking files compiled for 16-bit integers (-mshort) "
   1360      1.1  christos 	   "and others for 32-bit integers"), ibfd);
   1361      1.1  christos       ok = FALSE;
   1362      1.1  christos     }
   1363      1.1  christos   if ((new_flags & E_M68HC11_F64) != (old_flags & E_M68HC11_F64))
   1364  1.1.1.4  christos     {
   1365  1.1.1.4  christos       _bfd_error_handler
   1366  1.1.1.4  christos 	(_("%pB: linking files compiled for 32-bit double (-fshort-double) "
   1367      1.1  christos 	   "and others for 64-bit double"), ibfd);
   1368      1.1  christos       ok = FALSE;
   1369      1.1  christos     }
   1370      1.1  christos 
   1371      1.1  christos   /* Processor compatibility.  */
   1372      1.1  christos   if (!EF_M68HC11_CAN_MERGE_MACH (new_flags, old_flags))
   1373  1.1.1.4  christos     {
   1374  1.1.1.4  christos       _bfd_error_handler
   1375  1.1.1.4  christos 	(_("%pB: linking files compiled for HCS12 with "
   1376      1.1  christos 	   "others compiled for HC12"), ibfd);
   1377      1.1  christos       ok = FALSE;
   1378      1.1  christos     }
   1379  1.1.1.4  christos   new_flags = ((new_flags & ~EF_M68HC11_MACH_MASK)
   1380      1.1  christos 	       | (EF_M68HC11_MERGE_MACH (new_flags, old_flags)));
   1381      1.1  christos 
   1382      1.1  christos   elf_elfheader (obfd)->e_flags = new_flags;
   1383      1.1  christos 
   1384      1.1  christos   new_flags &= ~(EF_M68HC11_ABI | EF_M68HC11_MACH_MASK);
   1385      1.1  christos   old_flags &= ~(EF_M68HC11_ABI | EF_M68HC11_MACH_MASK);
   1386      1.1  christos 
   1387      1.1  christos   /* Warn about any other mismatches */
   1388      1.1  christos   if (new_flags != old_flags)
   1389  1.1.1.4  christos     {
   1390  1.1.1.4  christos       _bfd_error_handler
   1391  1.1.1.4  christos 	/* xgettext:c-format */
   1392  1.1.1.4  christos 	(_("%pB: uses different e_flags (%#x) fields than previous modules (%#x)"),
   1393      1.1  christos 	 ibfd, new_flags, old_flags);
   1394      1.1  christos       ok = FALSE;
   1395      1.1  christos     }
   1396      1.1  christos 
   1397      1.1  christos   if (! ok)
   1398      1.1  christos     {
   1399      1.1  christos       bfd_set_error (bfd_error_bad_value);
   1400      1.1  christos       return FALSE;
   1401      1.1  christos     }
   1402      1.1  christos 
   1403      1.1  christos   return TRUE;
   1404      1.1  christos }
   1405      1.1  christos 
   1406      1.1  christos bfd_boolean
   1407      1.1  christos _bfd_m68hc11_elf_print_private_bfd_data (bfd *abfd, void *ptr)
   1408      1.1  christos {
   1409      1.1  christos   FILE *file = (FILE *) ptr;
   1410      1.1  christos 
   1411      1.1  christos   BFD_ASSERT (abfd != NULL && ptr != NULL);
   1412      1.1  christos 
   1413      1.1  christos   /* Print normal ELF private data.  */
   1414      1.1  christos   _bfd_elf_print_private_bfd_data (abfd, ptr);
   1415      1.1  christos 
   1416      1.1  christos   /* xgettext:c-format */
   1417      1.1  christos   fprintf (file, _("private flags = %lx:"), elf_elfheader (abfd)->e_flags);
   1418      1.1  christos 
   1419      1.1  christos   if (elf_elfheader (abfd)->e_flags & E_M68HC11_I32)
   1420      1.1  christos     fprintf (file, _("[abi=32-bit int, "));
   1421      1.1  christos   else
   1422      1.1  christos     fprintf (file, _("[abi=16-bit int, "));
   1423      1.1  christos 
   1424      1.1  christos   if (elf_elfheader (abfd)->e_flags & E_M68HC11_F64)
   1425      1.1  christos     fprintf (file, _("64-bit double, "));
   1426      1.1  christos   else
   1427      1.1  christos     fprintf (file, _("32-bit double, "));
   1428      1.1  christos 
   1429      1.1  christos   if (strcmp (bfd_get_target (abfd), "elf32-m68hc11") == 0)
   1430      1.1  christos     fprintf (file, _("cpu=HC11]"));
   1431      1.1  christos   else if (elf_elfheader (abfd)->e_flags & EF_M68HCS12_MACH)
   1432      1.1  christos     fprintf (file, _("cpu=HCS12]"));
   1433  1.1.1.2  christos   else
   1434      1.1  christos     fprintf (file, _("cpu=HC12]"));
   1435      1.1  christos 
   1436      1.1  christos   if (elf_elfheader (abfd)->e_flags & E_M68HC12_BANKS)
   1437      1.1  christos     fprintf (file, _(" [memory=bank-model]"));
   1438      1.1  christos   else
   1439      1.1  christos     fprintf (file, _(" [memory=flat]"));
   1440      1.1  christos 
   1441      1.1  christos   if (elf_elfheader (abfd)->e_flags & E_M68HC11_XGATE_RAMOFFSET)
   1442      1.1  christos     fprintf (file, _(" [XGATE RAM offsetting]"));
   1443      1.1  christos 
   1444      1.1  christos   fputc ('\n', file);
   1445      1.1  christos 
   1446      1.1  christos   return TRUE;
   1447      1.1  christos }
   1448      1.1  christos 
   1449  1.1.1.4  christos static void scan_sections_for_abi (bfd *abfd ATTRIBUTE_UNUSED,
   1450      1.1  christos 				   asection *asect, void *arg)
   1451      1.1  christos {
   1452      1.1  christos   struct m68hc11_scan_param* p = (struct m68hc11_scan_param*) arg;
   1453      1.1  christos 
   1454      1.1  christos   if (asect->vma >= p->pinfo->bank_virtual)
   1455      1.1  christos     p->use_memory_banks = TRUE;
   1456  1.1.1.2  christos }
   1457      1.1  christos 
   1458      1.1  christos /* Tweak the OSABI field of the elf header.  */
   1459  1.1.1.5  christos 
   1460  1.1.1.5  christos bfd_boolean
   1461      1.1  christos elf32_m68hc11_init_file_header (bfd *abfd, struct bfd_link_info *link_info)
   1462      1.1  christos {
   1463      1.1  christos   struct m68hc11_scan_param param;
   1464      1.1  christos   struct m68hc11_elf_link_hash_table *htab;
   1465  1.1.1.5  christos 
   1466  1.1.1.5  christos   if (!_bfd_elf_init_file_header (abfd, link_info))
   1467  1.1.1.5  christos     return FALSE;
   1468      1.1  christos 
   1469  1.1.1.5  christos   if (link_info == NULL)
   1470      1.1  christos     return TRUE;
   1471      1.1  christos 
   1472      1.1  christos   htab = m68hc11_elf_hash_table (link_info);
   1473  1.1.1.5  christos   if (htab == NULL)
   1474      1.1  christos     return TRUE;
   1475      1.1  christos 
   1476      1.1  christos   m68hc11_elf_get_bank_parameters (link_info);
   1477      1.1  christos 
   1478      1.1  christos   param.use_memory_banks = FALSE;
   1479      1.1  christos   param.pinfo = & htab->pinfo;
   1480      1.1  christos 
   1481      1.1  christos   bfd_map_over_sections (abfd, scan_sections_for_abi, &param);
   1482      1.1  christos 
   1483      1.1  christos   if (param.use_memory_banks)
   1484      1.1  christos     {
   1485      1.1  christos       Elf_Internal_Ehdr * i_ehdrp;
   1486      1.1  christos 
   1487      1.1  christos       i_ehdrp = elf_elfheader (abfd);
   1488      1.1  christos       i_ehdrp->e_flags |= E_M68HC12_BANKS;
   1489  1.1.1.5  christos     }
   1490      1.1  christos   return TRUE;
   1491                    }
   1492