Port-vax archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

Re: ld assertion failures building NetBSD-VAX with GCC 4.5



I have a patch to binutils that fixes the ld assertion failure with
GCC 4.5. I haven't tested the generated code yet, but I will do that
tonight.

The cause was that "__clz_tab" and "__popcount_tab" are defined in
libgcc.a with the hidden attribute in GCC 4.5 but not in GCC 4.1. The
hidden attribute is not defined in the code but is added to the
symbols in the .o files with some special rules in
external/gpl3/gcc/lib/libgcc/libgcc/Makefile.

The bug is that elf_vax_instantiate_got_entries() in elf32-vax.c
doesn't allocate space in the .got and .rela.got sections for the
hidden symbols because it only does so if the visibility is set to
default. For the two hidden symbols, this isn't the case. There's a
section of code in elf_vax_relocate_section() immediately after I was
seeing the assertion failure that has special handling that applies to
these cases:

            dyn = elf_hash_table (info)->dynamic_sections_created;
            if (! WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, info->shared, h)
                || (info->shared
                    && SYMBOL_REFERENCES_LOCAL (info, h)))
              {
                /* The symbol was forced to be local
                   because of a version file..  We must initialize
                   this entry in the global offset table.  Since
                   the offset must always be a multiple of 4, we
                   use the least significant bit to record whether
                   we have initialized it already.

                   When doing a dynamic link, we create a .rela.got
                   relocation entry to initialize the value.  This
                   is done in the finish_dynamic_symbol routine.  */

I modified the check in elf_vax_instantiate_got_entries() to also
reserve space when WILL_CALL_FINISH_DYNAMIC_SYMBOL() returns false,
which only happens for the two hidden symbols in the entire NetBSD
build. The assertion failures happened when an executable like "vi" or
"less" referenced either __clz_tab or __popcount_tab, which got pulled
in from libgcc.a and then the GOT table was one entry too small
because a slot was reserved but the size wasn't incremented. Here's my
patch, which also updates a few comments to note that there are 3, not
2, reserved entries in the GOT.

--- external/gpl3/binutils/dist/bfd/elf32-vax.c 3 Sep 2012 18:59:23
-0000 1.5.2.2
+++ external/gpl3/binutils/dist/bfd/elf32-vax.c 13 Mar 2013 00:38:28 -0000
@@ -1337,8 +1337,7 @@
       dyn = elf_hash_table (info)->dynamic_sections_created;
       /* Allocate space in the .got and .rela.got sections.  */
       if (ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
-  && (info->shared
-      || WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, 0, h)))
+  || !WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, 0, h))
  {
   sgot->size += 4;
   srelgot->size += sizeof (Elf32_External_Rela);
@@ -1572,7 +1571,7 @@

   /* Get the offset into the .got table of the entry that
      corresponds to this function.  Each .got entry is 4 bytes.
-     The first two are reserved.  */
+     The first three are reserved.  */
   got_offset = (plt_index + 3) * 4;

   /* We want the relocation to point into the .got.plt instead
@@ -1839,7 +1838,7 @@

       /* Get the offset into the .got table of the entry that
  corresponds to this function.  Each .got entry is 4 bytes.
- The first two are reserved.  */
+ The first three are reserved.  */
       got_offset = (plt_index + 3) * 4;

       /* Fill in the entry in the procedure linkage table.  */


Hopefully the whitespace didn't get borked when I pasted that.

Regards,
Jake


Home | Main Index | Thread Index | Old Index