PowerPC gold assertion on missing global entry stub

Alan Modra amodra@gmail.com
Tue Apr 28 07:27:00 GMT 2015


On Tue, Apr 28, 2015 at 01:45:10PM +0930, Alan Modra wrote:
> 	* powerpc.cc (Target_powerpc::Relocate::relocate): Don't assert
> 	on missing global entry stub due to bogus debug info.

Completely removing the assert probably wasn't the best idea, so
reinstate it for allocated sections.  Also cope with debug info
potentially referring to a missing plt call stub.

And a tidy.  find_global_entry now returns an Address, so make temps
holding the return value of type Address, and compare against
invalid_address.

	* powerpc.cc (Target_powerpc::do_dynsym_value): Use Address rather
	than unsigned int for find_global_entry result temp.  Compare
	against invalid_address.
	(Target_powerpc::do_plt_address_for_global): Likewise.
	(Target_powerpc::Relocate::relocate): Likewise.  Don't assert
	on plt call stub existence for debug info.  Do assert for plt
	and global entry stub existence if an alloc section.

diff --git a/gold/powerpc.cc b/gold/powerpc.cc
index 3d753b5..9a0bd9d 100644
--- a/gold/powerpc.cc
+++ b/gold/powerpc.cc
@@ -6835,8 +6835,8 @@ Target_powerpc<size, big_endian>::Relocate::relocate(
 	  && !parameters->options().output_is_position_independent()
 	  && !is_branch_reloc(r_type))
 	{
-	  unsigned int off = target->glink_section()->find_global_entry(gsym);
-	  if (off != (unsigned int)-1)
+	  Address off = target->glink_section()->find_global_entry(gsym);
+	  if (off != invalid_address)
 	    {
 	      value = target->glink_section()->global_entry_address() + off;
 	      has_stub_value = true;
@@ -6852,18 +6852,26 @@ Target_powerpc<size, big_endian>::Relocate::relocate(
 	      if (target->stub_tables().size() != 0)
 		stub_table = target->stub_tables()[0];
 	    }
-	  gold_assert(stub_table != NULL);
-	  Address off;
-	  if (gsym != NULL)
-	    off = stub_table->find_plt_call_entry(object, gsym, r_type,
-						  rela.get_r_addend());
-	  else
-	    off = stub_table->find_plt_call_entry(object, r_sym, r_type,
-						  rela.get_r_addend());
-	  gold_assert(off != invalid_address);
-	  value = stub_table->stub_address() + off;
-	  has_stub_value = true;
+	  if (stub_table != NULL)
+	    {
+	      Address off;
+	      if (gsym != NULL)
+		off = stub_table->find_plt_call_entry(object, gsym, r_type,
+						      rela.get_r_addend());
+	      else
+		off = stub_table->find_plt_call_entry(object, r_sym, r_type,
+						      rela.get_r_addend());
+	      if (off != invalid_address)
+		{
+		  value = stub_table->stub_address() + off;
+		  has_stub_value = true;
+		}
+	    }
 	}
+      // We don't care too much about bogus debug references to
+      // non-local functions, but otherwise there had better be a plt
+      // call stub or global entry stub as appropriate.
+      gold_assert(has_stub_value || !(os->flags() & elfcpp::SHF_ALLOC));
     }
 
   if (r_type == elfcpp::R_POWERPC_GOT16
@@ -8232,8 +8240,8 @@ Target_powerpc<size, big_endian>::do_dynsym_value(const Symbol* gsym) const
     }
   else if (this->abiversion() >= 2)
     {
-      unsigned int off = this->glink_section()->find_global_entry(gsym);
-      if (off != (unsigned int)-1)
+      Address off = this->glink_section()->find_global_entry(gsym);
+      if (off != invalid_address)
 	return this->glink_section()->global_entry_address() + off;
     }
   gold_unreachable();
@@ -8282,8 +8290,8 @@ Target_powerpc<size, big_endian>::do_plt_address_for_global(
     }
   else if (this->abiversion() >= 2)
     {
-      unsigned int off = this->glink_section()->find_global_entry(gsym);
-      if (off != (unsigned int)-1)
+      Address off = this->glink_section()->find_global_entry(gsym);
+      if (off != invalid_address)
 	return this->glink_section()->global_entry_address() + off;
     }
   gold_unreachable();

-- 
Alan Modra
Australia Development Lab, IBM



More information about the Binutils mailing list