PR ld/20125, MMIX weak symbols
authorHans-Peter Nilsson <hp@bitrange.com>
Tue, 25 Jul 2017 02:09:32 +0000 (04:09 +0200)
committerHans-Peter Nilsson <hp@bitrange.com>
Mon, 21 Aug 2017 01:43:35 +0000 (03:43 +0200)
Weak undefineds with PUSHJ relocs were "lost", causing internal
inconsistencies and an abort.

bfd/ChangeLog
bfd/elf64-mmix.c
ld/ChangeLog
ld/testsuite/ld-mmix/pr20125.d [new file with mode: 0644]
ld/testsuite/ld-mmix/pr20125.s [new file with mode: 0644]

index 79dfa1dc145f7323ef63b779d49e58f47d66df08..6badc5db567de4cbcdaa03a86cc798746ea08313 100644 (file)
@@ -1,3 +1,9 @@
+2017-08-21  Hans-Peter Nilsson  <hp@bitrange.com>
+
+       PR ld/20125
+       * elf64-mmix.c (mmix_elf_relax_section): Correct handling of
+       undefined weak symbols.
+
 2017-08-18  Nick Clifton  <nickc@redhat.com>
 
        PR binutils/21962
index 8c8e06dff52693b70ef418aa6f8abbc8dea2c262..8d79d39d8f0266a5540487836ca2563705bcf765 100644 (file)
@@ -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);
index ba576c2a1a46e9baad0f4014650827c70f6c3ef0..a15025608df888e928ed836d3196ace750347832 100644 (file)
@@ -1,3 +1,9 @@
+2017-08-21  Hans-Peter Nilsson  <hp@bitrange.com>
+
+       PR ld/20125
+       * testsuite/ld-mmix/pr20125.d, testsuite/ld-mmix/pr20125.s: New
+       test.
+
 2017-08-20  A. Wilcox  <awilfox@adelielinux.org>
 
        PR ld/21976
diff --git a/ld/testsuite/ld-mmix/pr20125.d b/ld/testsuite/ld-mmix/pr20125.d
new file mode 100644 (file)
index 0000000..7c09c04
--- /dev/null
@@ -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 <Main\+0x14>
+   80008:      f2010004        pushj \$1,80018 <Main\+0x18>
+   8000c:      f6040000        put rJ,\$0
+   80010:      f8010000        pop 1,0
+   80014:      f1fdfffb        jmp 0 <Main-0x80000>
+   80018:      f1fdfffa        jmp 0 <Main-0x80000>
diff --git a/ld/testsuite/ld-mmix/pr20125.s b/ld/testsuite/ld-mmix/pr20125.s
new file mode 100644 (file)
index 0000000..e528d9d
--- /dev/null
@@ -0,0 +1,2 @@
+       .weak bar
+       .include "pr12815-2.s"
This page took 0.033414 seconds and 4 git commands to generate.