This is the mail archive of the binutils@sourceware.org mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

PowerPC64 gold --gc-sections error


This fixes some errors in gold triggered by invalid powerpc64 objects.
See http://sourceware.org/bugzilla/show_bug.cgi?id=15687

2013-06-27  Cary Coutant

	* powerpc.cc (Target_powerpc::symval_for_branch): Don't assert
	on garbage collected .opd section.

2013-06-27  Alan Modra

	* powerpc.cc (Target_powerpc::do_gc_add_reference): Test dst_shndx
	is non-zero.
	(Target_powerpc::do_gc_mark_symbols): Likewise for sym->shndx().
	(Target_powerpc::do_function_location): Likewise for loc->shndx.

Index: gold/powerpc.cc
===================================================================
RCS file: /cvs/src/src/gold/powerpc.cc,v
retrieving revision 1.91
diff -u -p -r1.91 powerpc.cc
--- gold/powerpc.cc	27 Apr 2013 00:53:16 -0000	1.91
+++ gold/powerpc.cc	27 Jun 2013 02:43:20 -0000
@@ -5827,7 +5827,7 @@ Target_powerpc<size, big_endian>::do_gc_
 
   Powerpc_relobj<size, big_endian>* ppc_object
     = static_cast<Powerpc_relobj<size, big_endian>*>(dst_obj);
-  if (dst_shndx == ppc_object->opd_shndx())
+  if (dst_shndx != 0 && dst_shndx == ppc_object->opd_shndx())
     {
       if (ppc_object->opd_valid())
 	{
@@ -5859,7 +5859,7 @@ Target_powerpc<size, big_endian>::do_gc_
 	= static_cast<Powerpc_relobj<size, big_endian>*>(sym->object());
       bool is_ordinary;
       unsigned int shndx = sym->shndx(&is_ordinary);
-      if (is_ordinary && shndx == ppc_object->opd_shndx())
+      if (is_ordinary && shndx != 0 && shndx == ppc_object->opd_shndx())
 	{
 	  Sized_symbol<size>* gsym = symtab->get_sized_symbol<size>(sym);
 	  Address dst_off = gsym->value();
@@ -5882,7 +5882,7 @@ void
 Target_powerpc<size, big_endian>::do_function_location(
     Symbol_location* loc) const
 {
-  if (size == 64)
+  if (size == 64 && loc->shndx != 0)
     {
       if (loc->object->is_dynamic())
 	{
@@ -6183,7 +6183,8 @@ Target_powerpc<size, big_endian>::symval
   if (shndx == 0)
     return value;
   Address opd_addr = symobj->get_output_section_offset(shndx);
-  gold_assert(opd_addr != invalid_address);
+  if (opd_addr == invalid_address)
+    return value;
   opd_addr += symobj->output_section(shndx)->address();
   if (value >= opd_addr && value < opd_addr + symobj->section_size(shndx))
     {

-- 
Alan Modra
Australia Development Lab, IBM


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