diff options
Diffstat (limited to 'bfd/elf64-mmix.c')
-rw-r--r-- | bfd/elf64-mmix.c | 43 |
1 files changed, 26 insertions, 17 deletions
diff --git a/bfd/elf64-mmix.c b/bfd/elf64-mmix.c index b4ff5a3..8d79d39 100644 --- a/bfd/elf64-mmix.c +++ b/bfd/elf64-mmix.c @@ -1193,12 +1193,10 @@ mmix_elf_perform_relocation (asection *isec, reloc_howto_type *howto, _bfd_error_handler /* xgettext:c-format */ (_("%B: Internal inconsistency error for value for\n\ - linker-allocated global register: linked: 0x%lx%08lx != relaxed: 0x%lx%08lx\n"), + linker-allocated global register: linked: %#Lx != relaxed: %#Lx"), isec->owner, - (unsigned long) (value >> 32), (unsigned long) value, - (unsigned long) (gregdata->reloc_request[bpo_index].value - >> 32), - (unsigned long) gregdata->reloc_request[bpo_index].value); + value, + gregdata->reloc_request[bpo_index].value); bfd_set_error (bfd_error_bad_value); return bfd_reloc_overflow; } @@ -1740,9 +1738,9 @@ mmix_final_link_relocate (reloc_howto_type *howto, asection *input_section, /* FIXME: Better error message. */ _bfd_error_handler /* xgettext:c-format */ - (_("%B: LOCAL directive: Register $%ld is not a local register." - " First global register is $%ld."), - input_section->owner, (long) srel, (long) first_global); + (_("%B: LOCAL directive: Register $%Ld is not a local register." + " First global register is $%Ld."), + input_section->owner, srel, first_global); return bfd_reloc_overflow; } @@ -2444,10 +2442,10 @@ _bfd_mmix_after_linker_allocation (bfd *abfd ATTRIBUTE_UNUSED, { _bfd_error_handler /* xgettext:c-format */ - (_("Internal inconsistency: remaining %u != max %u.\n\ + (_("Internal inconsistency: remaining %lu != max %lu.\n\ Please report this bug."), - gregdata->n_remaining_bpo_relocs_this_relaxation_round, - gregdata->n_bpo_relocs); + (unsigned long) gregdata->n_remaining_bpo_relocs_this_relaxation_round, + (unsigned long) gregdata->n_bpo_relocs); return FALSE; } @@ -2712,8 +2710,21 @@ mmix_elf_relax_section (bfd *abfd, indx = ELF64_R_SYM (irel->r_info) - symtab_hdr->sh_info; h = elf_sym_hashes (abfd)[indx]; BFD_ASSERT (h != NULL); - if (h->root.type != bfd_link_hash_defined - && h->root.type != bfd_link_hash_defweak) + if (h->root.type == bfd_link_hash_undefweak) + /* FIXME: for R_MMIX_PUSHJ_STUBBABLE, there are alternatives to + the canonical value 0 for an unresolved weak symbol to + consider: as the debug-friendly approach, resolve to "abort" + (or a port-specific function), or as the space-friendly + approach resolve to the next instruction (like some other + ports, notably ARM and AArch64). These alternatives require + matching code in mmix_elf_perform_relocation or its caller. */ + symval = 0; + else if (h->root.type == bfd_link_hash_defined + || h->root.type == bfd_link_hash_defweak) + symval = (h->root.u.def.value + + h->root.u.def.section->output_section->vma + + h->root.u.def.section->output_offset); + else { /* This appears to be a reference to an undefined symbol. Just ignore it--it will be caught by the regular reloc processing. @@ -2727,10 +2738,6 @@ mmix_elf_relax_section (bfd *abfd, } continue; } - - symval = (h->root.u.def.value - + h->root.u.def.section->output_section->vma - + h->root.u.def.section->output_offset); } if (ELF64_R_TYPE (irel->r_info) == (int) R_MMIX_PUSHJ_STUBBABLE) @@ -2868,6 +2875,8 @@ mmix_elf_relax_section (bfd *abfd, } } + BFD_ASSERT(pjsno == mmix_elf_section_data (sec)->pjs.n_pushj_relocs); + if (internal_relocs != NULL && elf_section_data (sec)->relocs != internal_relocs) free (internal_relocs); |