This is the mail archive of the gcc-bugs@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

linkonce sections, DWARF2 EH, and the ppc failures


Hi Ben, Richard,

I've tracked down what's happening in those powerpc-eabi libstdc++-v3
`regressions', or at least the first of them, element_access.

In the code

try {
  cref cref4 = str01.at(csz01);
  VERIFY( false ); // Should not get here, as exception thrown.
}
catch(std::out_of_range& fail) {
  VERIFY( true );
}
...

The `at' method, aka `_ZNKSs2atEj', is coming from the executable, in
a linkonce section, but the EH data that is used is coming from
string-inst.o, because the code for specifying the offsets is:

        .4byte  .LFB70   # FDE initial location
        .4byte  .LFE70-.LFB70    # FDE address range

and the assembler turns this into a section-relative reloc like

000004cc R_PPC_ADDR32      .gnu.linkonce.t._ZNKSs2atEj

which is IMHO not an unreasonable thing to do.  The linker then
combines all the linkonce sections, and decides to resolve this symbol
to the start of the linkonce section in the _output_ file.

Unfortunately, the two compiled procedures differ because the
testsuite is compiled with -O0 and string-inst.o is compiled with -O2,
so the unwinder loses its mind and aborts.

IMHO, the linker behaviour here is wrong.  The reloc refers to the
start of the `.gnu.linkonce.t._ZNKSs2atEj' section in the input file.
If that section is not going into the output file, the linker should
behave as if that symbol was undefined.

Unfortunately, this doesn't solve my problem, because what I really
want is to have the reloc resolved to (say) zero.

So, how about this?

-- 
- Geoffrey Keating <geoffk@geoffk.org>

===File ~/patches/cygnus/ld-staticehbug.patch===============
2001-06-17  Geoffrey Keating  <geoffk@redhat.com>

	* elflink.h (elf_link_input_bfd): Set the value of the section
	symbol of a discarded linkonce section to 0.

Index: elflink.h
===================================================================
RCS file: /cvs/src/src/bfd/elflink.h,v
retrieving revision 1.95
diff -p -u -p -r1.95 elflink.h
--- elflink.h	2001/06/12 17:44:37	1.95
+++ elflink.h	2001/06/18 03:33:12
@@ -5666,22 +5666,23 @@ elf_link_input_bfd (finfo, input_bfd)
 	      isec->symbol->value = isym->st_value;
 	    }
 
-	  /* If this is a discarded link-once section symbol, update
-	     it's value to that of the kept section symbol.  The
-	     linker will keep the first of any matching link-once
-	     sections, so we should have already seen it's section
-	     symbol.  I trust no-one will have the bright idea of
-	     re-ordering the bfd list...  */
+	  /* If this is a discarded link-once section symbol, set its
+	     value to 0.  We should really undefine it, and
+	     complain if anything in the final link tries to use it,
+	     but DWARF-based exception handling might have an entry
+	     in .eh_frame to describe a routine in the linkonce section,
+	     and it turns out to be hard to remove the .eh_frame entry too.  
+	     FIXME.  */
 	  if (isec != NULL
 	      && (bfd_get_section_flags (input_bfd, isec) & SEC_LINK_ONCE) != 0
 	      && (ksec = isec->kept_section) != NULL)
 	    {
-	      isym->st_value = ksec->symbol->value;
+	      isym->st_value = 0;
 
 	      /* That put the value right, but the section info is all
 		 wrong.  I hope this works.  */
-	      isec->output_offset = ksec->output_offset;
-	      isec->output_section = ksec->output_section;
+	      isec->output_offset = 0;
+	      isec->output_section = bfd_abs_section_ptr;
 	    }
 
 	  /* We never output section symbols.  Instead, we use the
============================================================


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]