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 |