| Index: bfd/elf32-m68hc1x.c
|
| diff --git a/bfd/elf32-m68hc1x.c b/bfd/elf32-m68hc1x.c
|
| index d862c9fbe326d0dc895d7ea629342c947d6e3092..f5f68bc41bd10c847e071478ce78a7df5d630bcc 100644
|
| --- a/bfd/elf32-m68hc1x.c
|
| +++ b/bfd/elf32-m68hc1x.c
|
| @@ -67,11 +67,10 @@ m68hc11_elf_hash_table_create (bfd *abfd)
|
| struct m68hc11_elf_link_hash_table *ret;
|
| bfd_size_type amt = sizeof (struct m68hc11_elf_link_hash_table);
|
|
|
| - ret = (struct m68hc11_elf_link_hash_table *) bfd_malloc (amt);
|
| + ret = (struct m68hc11_elf_link_hash_table *) bfd_zmalloc (amt);
|
| if (ret == (struct m68hc11_elf_link_hash_table *) NULL)
|
| return NULL;
|
|
|
| - memset (ret, 0, amt);
|
| if (!_bfd_elf_link_hash_table_init (&ret->root, abfd,
|
| _bfd_elf_link_hash_newfunc,
|
| sizeof (struct elf_link_hash_entry),
|
| @@ -93,11 +92,6 @@ m68hc11_elf_hash_table_create (bfd *abfd)
|
| sizeof (struct elf32_m68hc11_stub_hash_entry)))
|
| return NULL;
|
|
|
| - ret->stub_bfd = NULL;
|
| - ret->stub_section = 0;
|
| - ret->add_stub_section = NULL;
|
| - ret->sym_cache.abfd = NULL;
|
| -
|
| return ret;
|
| }
|
|
|
| @@ -111,7 +105,7 @@ m68hc11_elf_bfd_link_hash_table_free (struct bfd_link_hash_table *hash)
|
|
|
| bfd_hash_table_free (ret->stub_hash_table);
|
| free (ret->stub_hash_table);
|
| - _bfd_generic_link_hash_table_free (hash);
|
| + _bfd_elf_link_hash_table_free (hash);
|
| }
|
|
|
| /* Assorted hash table functions. */
|
| @@ -667,7 +661,7 @@ elf32_m68hc11_build_stubs (bfd *abfd, struct bfd_link_info *info)
|
| /* Build the stubs as directed by the stub hash table. */
|
| table = htab->stub_hash_table;
|
| bfd_hash_traverse (table, m68hc11_elf_export_one_stub, info);
|
| -
|
| +
|
| /* Scan the output sections to see if we use the memory banks.
|
| If so, export the symbols that define how the memory banks
|
| are mapped. This is used by gdb and the simulator to obtain
|
| @@ -877,6 +871,10 @@ elf32_m68hc11_check_relocs (bfd *abfd, struct bfd_link_info *info,
|
| while (h->root.type == bfd_link_hash_indirect
|
| || h->root.type == bfd_link_hash_warning)
|
| h = (struct elf_link_hash_entry *) h->root.u.i.link;
|
| +
|
| + /* PR15323, ref flags aren't set for references in the same
|
| + object. */
|
| + h->root.non_ir_ref = 1;
|
| }
|
|
|
| switch (ELF32_R_TYPE (rel->r_info))
|
| @@ -918,9 +916,11 @@ elf32_m68hc11_relocate_section (bfd *output_bfd ATTRIBUTE_UNUSED,
|
| struct m68hc11_page_info *pinfo;
|
| const struct elf_backend_data * const ebd = get_elf_backend_data (input_bfd);
|
| struct m68hc11_elf_link_hash_table *htab;
|
| + unsigned long e_flags;
|
|
|
| symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
|
| sym_hashes = elf_sym_hashes (input_bfd);
|
| + e_flags = elf_elfheader (input_bfd)->e_flags;
|
|
|
| htab = m68hc11_elf_hash_table (info);
|
| if (htab == NULL)
|
| @@ -948,6 +948,8 @@ elf32_m68hc11_relocate_section (bfd *output_bfd ATTRIBUTE_UNUSED,
|
| bfd_vma insn_addr;
|
| bfd_vma insn_page;
|
| bfd_boolean is_far = FALSE;
|
| + bfd_boolean is_xgate_symbol = FALSE;
|
| + bfd_boolean is_section_symbol = FALSE;
|
| struct elf_link_hash_entry *h;
|
| bfd_vma val;
|
|
|
| @@ -955,7 +957,7 @@ elf32_m68hc11_relocate_section (bfd *output_bfd ATTRIBUTE_UNUSED,
|
| r_type = ELF32_R_TYPE (rel->r_info);
|
|
|
| if (r_type == R_M68HC11_GNU_VTENTRY
|
| - || r_type == R_M68HC11_GNU_VTINHERIT )
|
| + || r_type == R_M68HC11_GNU_VTINHERIT)
|
| continue;
|
|
|
| (*ebd->elf_info_to_howto_rel) (input_bfd, &arel, rel);
|
| @@ -972,17 +974,20 @@ elf32_m68hc11_relocate_section (bfd *output_bfd ATTRIBUTE_UNUSED,
|
| + sec->output_offset
|
| + sym->st_value);
|
| is_far = (sym && (sym->st_other & STO_M68HC12_FAR));
|
| + is_xgate_symbol = (sym && (sym->st_target_internal));
|
| + is_section_symbol = ELF_ST_TYPE (sym->st_info) & STT_SECTION;
|
| }
|
| else
|
| {
|
| - bfd_boolean unresolved_reloc, warned;
|
| + bfd_boolean unresolved_reloc, warned, ignored;
|
|
|
| RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel,
|
| r_symndx, symtab_hdr, sym_hashes,
|
| h, sec, relocation, unresolved_reloc,
|
| - warned);
|
| + warned, ignored);
|
|
|
| is_far = (h && (h->other & STO_M68HC12_FAR));
|
| + is_xgate_symbol = (h && (h->target_internal));
|
| }
|
|
|
| if (sec != NULL && discarded_section (sec))
|
| @@ -1043,7 +1048,7 @@ elf32_m68hc11_relocate_section (bfd *output_bfd ATTRIBUTE_UNUSED,
|
| a LO8XG. Does not actually check that it was a LO8XG.
|
| Adjusts high and low bytes. */
|
| relocation = phys_addr;
|
| - if ((elf_elfheader (input_bfd)->e_flags & E_M68HC11_XGATE_RAMOFFSET)
|
| + if ((e_flags & E_M68HC11_XGATE_RAMOFFSET)
|
| && (relocation >= 0x2000))
|
| relocation += 0xc000; /* HARDCODED RAM offset for XGATE. */
|
|
|
| @@ -1110,7 +1115,7 @@ elf32_m68hc11_relocate_section (bfd *output_bfd ATTRIBUTE_UNUSED,
|
| "relocation may result in incorrect execution");
|
| buf = alloca (strlen (msg) + strlen (name) + 10);
|
| sprintf (buf, msg, name);
|
| -
|
| +
|
| (* info->callbacks->warning)
|
| (info, buf, name, input_bfd, NULL, rel->r_offset);
|
| }
|
| @@ -1122,12 +1127,45 @@ elf32_m68hc11_relocate_section (bfd *output_bfd ATTRIBUTE_UNUSED,
|
|
|
| insn_page = m68hc11_phys_page (pinfo, insn_addr);
|
|
|
| + /* If we are linking an S12 instruction against an XGATE symbol, we
|
| + need to change the offset of the symbol value so that it's correct
|
| + from the S12's perspective. */
|
| + if (is_xgate_symbol)
|
| + {
|
| + /* The ram in the global space is mapped to 0x2000 in the 16-bit
|
| + address space for S12 and 0xE000 in the 16-bit address space
|
| + for XGATE. */
|
| + if (relocation >= 0xE000)
|
| + {
|
| + /* We offset the address by the difference
|
| + between these two mappings. */
|
| + relocation -= 0xC000;
|
| + break;
|
| + }
|
| + else
|
| + {
|
| + const char * msg;
|
| + char * buf;
|
| +
|
| + msg = _("XGATE address (%lx) is not within shared RAM"
|
| + "(0xE000-0xFFFF), therefore you must manually offset "
|
| + "the address, and possibly manage the page, in your "
|
| + "code.");
|
| + buf = alloca (strlen (msg) + 128);
|
| + sprintf (buf, msg, phys_addr);
|
| + if (!((*info->callbacks->warning) (info, buf, name, input_bfd,
|
| + input_section, insn_addr)))
|
| + return FALSE;
|
| + break;
|
| + }
|
| + }
|
| +
|
| if (m68hc11_addr_is_banked (pinfo, relocation + rel->r_addend)
|
| && m68hc11_addr_is_banked (pinfo, insn_addr)
|
| - && phys_page != insn_page)
|
| + && phys_page != insn_page && !(e_flags & E_M68HC11_NO_BANK_WARNING))
|
| {
|
| - const char* msg;
|
| - char* buf;
|
| + const char * msg;
|
| + char * buf;
|
|
|
| msg = _("banked address [%lx:%04lx] (%lx) is not in the same bank "
|
| "as current banked address [%lx:%04lx] (%lx)");
|
| @@ -1143,10 +1181,11 @@ elf32_m68hc11_relocate_section (bfd *output_bfd ATTRIBUTE_UNUSED,
|
| return FALSE;
|
| break;
|
| }
|
| +
|
| if (phys_page != 0 && insn_page == 0)
|
| {
|
| - const char* msg;
|
| - char* buf;
|
| + const char * msg;
|
| + char * buf;
|
|
|
| msg = _("reference to a banked address [%lx:%04lx] in the "
|
| "normal address space at %04lx");
|
| @@ -1169,6 +1208,45 @@ elf32_m68hc11_relocate_section (bfd *output_bfd ATTRIBUTE_UNUSED,
|
| break;
|
| }
|
|
|
| + /* If we are linking an XGATE instruction against an S12 symbol, we
|
| + need to change the offset of the symbol value so that it's correct
|
| + from the XGATE's perspective. */
|
| + if (!strcmp (howto->name, "R_XGATE_IMM8_LO")
|
| + || !strcmp (howto->name, "R_XGATE_IMM8_HI"))
|
| + {
|
| + /* We can only offset S12 addresses that lie within the non-paged
|
| + area of RAM. */
|
| + if (!is_xgate_symbol && !is_section_symbol)
|
| + {
|
| + /* The ram in the global space is mapped to 0x2000 and stops at
|
| + 0x4000 in the 16-bit address space for S12 and 0xE000 in the
|
| + 16-bit address space for XGATE. */
|
| + if (relocation >= 0x2000 && relocation < 0x4000)
|
| + /* We offset the address by the difference
|
| + between these two mappings. */
|
| + relocation += 0xC000;
|
| + else
|
| + {
|
| + const char * msg;
|
| + char * buf;
|
| +
|
| + /* Get virtual address of instruction having the relocation. */
|
| + insn_addr = input_section->output_section->vma
|
| + + input_section->output_offset + rel->r_offset;
|
| +
|
| + msg = _("S12 address (%lx) is not within shared RAM"
|
| + "(0x2000-0x4000), therefore you must manually "
|
| + "offset the address in your code");
|
| + buf = alloca (strlen (msg) + 128);
|
| + sprintf (buf, msg, phys_addr);
|
| + if (!((*info->callbacks->warning) (info, buf, name, input_bfd,
|
| + input_section, insn_addr)))
|
| + return FALSE;
|
| + break;
|
| + }
|
| + }
|
| + }
|
| +
|
| if (r_type != R_M68HC11_NONE)
|
| {
|
| if ((r_type == R_M68HC12_PCREL_9) || (r_type == R_M68HC12_PCREL_10))
|
| @@ -1363,7 +1441,7 @@ _bfd_m68hc11_elf_print_private_bfd_data (bfd *abfd, void *ptr)
|
| else if (elf_elfheader (abfd)->e_flags & EF_M68HCS12_MACH)
|
| fprintf (file, _("cpu=HCS12]"));
|
| else
|
| - fprintf (file, _("cpu=HC12]"));
|
| + fprintf (file, _("cpu=HC12]"));
|
|
|
| if (elf_elfheader (abfd)->e_flags & E_M68HC12_BANKS)
|
| fprintf (file, _(" [memory=bank-model]"));
|
| @@ -1386,7 +1464,7 @@ static void scan_sections_for_abi (bfd *abfd ATTRIBUTE_UNUSED,
|
| if (asect->vma >= p->pinfo->bank_virtual)
|
| p->use_memory_banks = TRUE;
|
| }
|
| -
|
| +
|
| /* Tweak the OSABI field of the elf header. */
|
|
|
| void
|
|
|