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