From 284d826d9f57e3ff47e41f61f3250c8d029baaa3 Mon Sep 17 00:00:00 2001 From: Hans-Peter Nilsson Date: Tue, 25 Jul 2017 04:09:32 +0200 Subject: [PATCH] PR ld/20125, MMIX weak symbols Weak undefineds with PUSHJ relocs were "lost", causing internal inconsistencies and an abort. --- bfd/ChangeLog | 6 ++++++ bfd/elf64-mmix.c | 23 +++++++++++++++++------ ld/ChangeLog | 6 ++++++ ld/testsuite/ld-mmix/pr20125.d | 21 +++++++++++++++++++++ ld/testsuite/ld-mmix/pr20125.s | 2 ++ 5 files changed, 52 insertions(+), 6 deletions(-) create mode 100644 ld/testsuite/ld-mmix/pr20125.d create mode 100644 ld/testsuite/ld-mmix/pr20125.s diff --git a/bfd/ChangeLog b/bfd/ChangeLog index 79dfa1dc145..6badc5db567 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,9 @@ +2017-08-21 Hans-Peter Nilsson + + PR ld/20125 + * elf64-mmix.c (mmix_elf_relax_section): Correct handling of + undefined weak symbols. + 2017-08-18 Nick Clifton PR binutils/21962 diff --git a/bfd/elf64-mmix.c b/bfd/elf64-mmix.c index 8c8e06dff52..8d79d39d8f0 100644 --- a/bfd/elf64-mmix.c +++ b/bfd/elf64-mmix.c @@ -2710,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. @@ -2725,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) @@ -2866,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); diff --git a/ld/ChangeLog b/ld/ChangeLog index ba576c2a1a4..a15025608df 100644 --- a/ld/ChangeLog +++ b/ld/ChangeLog @@ -1,3 +1,9 @@ +2017-08-21 Hans-Peter Nilsson + + PR ld/20125 + * testsuite/ld-mmix/pr20125.d, testsuite/ld-mmix/pr20125.s: New + test. + 2017-08-20 A. Wilcox PR ld/21976 diff --git a/ld/testsuite/ld-mmix/pr20125.d b/ld/testsuite/ld-mmix/pr20125.d new file mode 100644 index 00000000000..7c09c04383e --- /dev/null +++ b/ld/testsuite/ld-mmix/pr20125.d @@ -0,0 +1,21 @@ +#as: -no-predefined-syms -x -I$srcdir/$subdir +#ld: -m mmo --defsym __.MMIX.start..text=0x80000 +#objdump: -dr + +# PUSHJ reloc handling was wrong for weak undefined symbols, causing +# internal inconsistencies, leading to a call to abort. +# Note that we don't keep track of which symbols have pushj-stubs, so +# we get one stub each for the two calls to "foo". + +.*: file format mmo + +Disassembly of section \.text: + +0+80000 <(_start|Main)>: + 80000: fe000004 get \$0,rJ + 80004: f2010004 pushj \$1,80014 + 80008: f2010004 pushj \$1,80018 + 8000c: f6040000 put rJ,\$0 + 80010: f8010000 pop 1,0 + 80014: f1fdfffb jmp 0 + 80018: f1fdfffa jmp 0 diff --git a/ld/testsuite/ld-mmix/pr20125.s b/ld/testsuite/ld-mmix/pr20125.s new file mode 100644 index 00000000000..e528d9d75f7 --- /dev/null +++ b/ld/testsuite/ld-mmix/pr20125.s @@ -0,0 +1,2 @@ + .weak bar + .include "pr12815-2.s" -- 2.30.2