[PATCH][GOLD] Use offsets within output sections during a relocatable link.

Doug Kwan (關振德) dougkwan@google.com
Wed May 26 16:13:00 GMT 2010


Hi,

    This patch fixes a problem that broke some loadable kernel modules
linked with the -r option.  We used output addresses, instead of
offsets relative to starts of output sections when we finalized values
of local symbols in merged sections.  The same problem potentially
affects relaxed sections and is also fixed by this patch.  I am not
sure if I should change the handling of section and TLS symbols so I
leave them alone.

This is tested by running the whole gold testsuite on x86_64 and
building the ARM linux kernel with a loadable module.  The kernel
module worked only with this patch.

-Doug


2010-05-27  Doug Kwan  <dougkwan@google.com>

        * object.cc (Sized_relobj::do_finalize_local_symbols): Use offset
        from start of output section instead of address for a local symbol
        in a merged or relaxed section when doing a relocatable link.
-------------- next part --------------
Index: gold/object.cc
===================================================================
RCS file: /cvs/src/src/gold/object.cc,v
retrieving revision 1.123
diff -u -u -p -r1.123 object.cc
--- gold/object.cc	26 May 2010 15:47:39 -0000	1.123
+++ gold/object.cc	26 May 2010 15:57:55 -0000
@@ -1827,7 +1827,12 @@ Sized_relobj<size, big_endian>::do_final
 		  const Output_section_data* posd =
 		    os->find_relaxed_input_section(this, shndx);
 		  if (posd != NULL)
-		    lv.set_output_value(posd->address());
+		    {
+		      uint64_t relocatable_link_adjustment =
+			relocatable ? os->address() : 0;
+		      lv.set_output_value(posd->address()
+					  - relocatable_link_adjustment);
+		    }
 		  else
 		    lv.set_output_value(os->address());
 		}
@@ -1835,9 +1840,14 @@ Sized_relobj<size, big_endian>::do_final
 		{
 		  // We have to consider the addend to determine the
 		  // value to use in a relocation.  START is the start
-		  // of this input section.
+		  // of this input section.  If we are doing a relocatable
+		  // link, use offset from start output section instead of
+		  // address.
+		  uint64_t adjusted_start =
+		    relocatable ? start - os->address() : start;
 		  Merged_symbol_value<size>* msv =
-		    new Merged_symbol_value<size>(lv.input_value(), start);
+		    new Merged_symbol_value<size>(lv.input_value(),
+						  adjusted_start);
 		  lv.set_merged_symbol_value(msv);
 		}
 	    }


More information about the Binutils mailing list