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]

gold patch committed: Handle odd section symbols with -r


The last case in PR 7091 is about a section symbol for a SHT_REL section
when linking with -r.  Such a case can not be generated by current
versions of gas.  However, they are valid ELF.  gold was crashing trying
to determine the value to use for such a section symbol.  In fact gold
will never emit the section symbol, and it would be bizarre in the
extreme if a relocation entry referenced the symbol.  However, there is
no need to crash.  I committed this patch to fall back to using the
start of the output section as the address for such a section symbol.
This is not really right, but then nothing is really right if anything
actually needs the value of the symbol.

Ian


2009-02-27  Ian Lance Taylor  <iant@google.com>

	PR 7091
	* output.cc (Output_section::find_starting_output_address): Rename
	from starting_output_address; add PADDR parameter; change return
	type.
	* output.h (class Output_section): Declare
	find_starting_output_address instead of starting_output_address.
	* object.cc (Sized_relobj::do_finalize_local_symbols): Handle a
	section symbol for which we can't find a merge section.


Index: object.cc
===================================================================
RCS file: /cvs/src/src/gold/object.cc,v
retrieving revision 1.84
diff -p -u -r1.84 object.cc
--- object.cc	13 Feb 2009 19:04:44 -0000	1.84
+++ object.cc	28 Feb 2009 00:02:32 -0000
@@ -1554,20 +1554,31 @@ Sized_relobj<size, big_endian>::do_final
 	    }
 	  else if (out_offsets[shndx] == invalid_address)
 	    {
+	      uint64_t start;
+
 	      // This is a SHF_MERGE section or one which otherwise
-	      // requires special handling.  We get the output address
-	      // of the start of the merged section.  If this is not a
-	      // section symbol, we can then determine the final
-	      // value.  If it is a section symbol, we can not, as in
-	      // that case we have to consider the addend to determine
-	      // the value to use in a relocation.
+	      // requires special handling.
 	      if (!lv.is_section_symbol())
-		lv.set_output_value(os->output_address(this, shndx,
-                                                       lv.input_value()));
+		{
+		  // This is not a section symbol.  We can determine
+		  // the final value now.
+		  lv.set_output_value(os->output_address(this, shndx,
+							 lv.input_value()));
+		}
+	      else if (!os->find_starting_output_address(this, shndx, &start))
+		{
+		  // This is a section symbol, but apparently not one
+		  // in a merged section.  Just use the start of the
+		  // output section.  This happens with relocatable
+		  // links when the input object has section symbols
+		  // for arbitrary non-merge sections.
+		  lv.set_output_value(os->address());
+		}
 	      else
 		{
-                  section_offset_type start =
-                    os->starting_output_address(this, shndx);
+		  // We have to consider the addend to determine the
+		  // value to use in a relocation.  START is the start
+		  // of this input section.
 		  Merged_symbol_value<size>* msv =
 		    new Merged_symbol_value<size>(lv.input_value(), start);
 		  lv.set_merged_symbol_value(msv);
Index: output.cc
===================================================================
RCS file: /cvs/src/src/gold/output.cc,v
retrieving revision 1.85
diff -p -u -r1.85 output.cc
--- output.cc	15 Jan 2009 02:18:11 -0000	1.85
+++ output.cc	28 Feb 2009 00:02:33 -0000
@@ -1,6 +1,6 @@
 // output.cc -- manage the output file for gold
 
-// Copyright 2006, 2007, 2008 Free Software Foundation, Inc.
+// Copyright 2006, 2007, 2008, 2009 Free Software Foundation, Inc.
 // Written by Ian Lance Taylor <iant@google.com>.
 
 // This file is part of gold.
@@ -2057,12 +2057,13 @@ Output_section::output_address(const Rel
   gold_unreachable();
 }
 
-// Return the output address of the start of the merged section for
+// Find the output address of the start of the merged section for
 // input section SHNDX in object OBJECT.
 
-uint64_t
-Output_section::starting_output_address(const Relobj* object,
-					unsigned int shndx) const
+bool
+Output_section::find_starting_output_address(const Relobj* object,
+					     unsigned int shndx,
+					     uint64_t* paddr) const
 {
   uint64_t addr = this->address() + this->first_input_offset_;
   for (Input_section_list::const_iterator p = this->input_sections_.begin();
@@ -2076,11 +2077,16 @@ Output_section::starting_output_address(
       // Unfortunately we don't know for sure that input offset 0 is
       // mapped at all.
       if (p->is_merge_section_for(object, shndx))
-	return addr;
+	{
+	  *paddr = addr;
+	  return true;
+	}
 
       addr += p->data_size();
     }
-  gold_unreachable();
+
+  // We couldn't find a merge output section for this input section.
+  return false;
 }
 
 // Set the data size of an Output_section.  This is where we handle
Index: output.h
===================================================================
RCS file: /cvs/src/src/gold/output.h,v
retrieving revision 1.76
diff -p -u -r1.76 output.h
--- output.h	29 Sep 2008 21:10:26 -0000	1.76
+++ output.h	28 Feb 2009 00:02:33 -0000
@@ -1,6 +1,6 @@
 // output.h -- manage the output file for gold   -*- C++ -*-
 
-// Copyright 2006, 2007, 2008 Free Software Foundation, Inc.
+// Copyright 2006, 2007, 2008, 2009 Free Software Foundation, Inc.
 // Written by Ian Lance Taylor <iant@google.com>.
 
 // This file is part of gold.
@@ -2260,12 +2260,14 @@ class Output_section : public Output_dat
   output_address(const Relobj* object, unsigned int shndx,
 		 off_t offset) const;
 
-  // Return the output address of the start of the merged section for
-  // input section SHNDX in object OBJECT.  This is not necessarily
-  // the offset corresponding to input offset 0 in the section, since
-  // the section may be mapped arbitrarily.
-  uint64_t
-  starting_output_address(const Relobj* object, unsigned int shndx) const;
+  // Look for the merged section for input section SHNDX in object
+  // OBJECT.  If found, return true, and set *ADDR to the address of
+  // the start of the merged section.  This is not necessary the
+  // output offset corresponding to input offset 0 in the section,
+  // since the section may be mapped arbitrarily.
+  bool
+  find_starting_output_address(const Relobj* object, unsigned int shndx,
+			       uint64_t* addr) const;
 
   // Record that this output section was found in the SECTIONS clause
   // of a linker script.

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