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: Fix debug info for commons in shared libraries


PR 9918 is about a bug in gold in which it does not generate correct
debugging information for common symbols in shared libraries.  The bug
only occurred for the x86 target (not x86_64).  gold does not scan
relocs for sections with the SHF_ALLOC flag clear.  When i386 gold is
processing relocs, it skips applying relocs which will get a dynamic
reloc.  However, the calculation for whether a reloc would get a dynamic
reloc was flawed, because it did not consider the sections with
SHF_ALLOC clear which had been skipped.

I committed this patch to fix the problem, along with a test case.

Ian


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

	PR 9918
	* target-reloc.h (relocate_section): Pass output_section to
	relocate.
	* i386.cc (Target_i386::should_apply_static_reloc): Add
	output_section parameter.  Change all callers.
	(Target_i386::Relocate::relocate): Add output_section parameter.
	* x86_64.cc (Target_x86_64::Relocate::relocate): Likewise.
	* sparc.cc (Target_sparc::Relocate::relocate): Likewise.
	* powerpc.cc (Target_powerpc::Relocate::relocate): Likewise.
	* testsuite/two_file_shared.sh: New script.
	* testsuite/Makefile.am (check_SCRIPTS): Add two_file_shared.sh.
	(check_DATA): Add two_file_shared.dbg.
	(two_file_shared.dbg): New target.
	* testsuite/Makefile.in: Rebuild.


Index: i386.cc
===================================================================
RCS file: /cvs/src/src/gold/i386.cc,v
retrieving revision 1.84
diff -p -u -r1.84 i386.cc
--- i386.cc	30 Jan 2009 00:21:46 -0000	1.84
+++ i386.cc	4 Mar 2009 06:42:45 -0000
@@ -214,13 +214,14 @@ class Target_i386 : public Sized_target<
     inline bool
     should_apply_static_reloc(const Sized_symbol<32>* gsym,
                               int ref_flags,
-                              bool is_32bit);
+                              bool is_32bit,
+			      Output_section* output_section);
 
     // Do a relocation.  Return false if the caller should not issue
     // any warnings about this relocation.
     inline bool
-    relocate(const Relocate_info<32, false>*, Target_i386*, size_t relnum,
-	     const elfcpp::Rel<32, false>&,
+    relocate(const Relocate_info<32, false>*, Target_i386*, Output_section*,
+	     size_t relnum, const elfcpp::Rel<32, false>&,
 	     unsigned int r_type, const Sized_symbol<32>*,
 	     const Symbol_value<32>*,
 	     unsigned char*, elfcpp::Elf_types<32>::Elf_Addr,
@@ -1595,8 +1596,15 @@ Target_i386::do_finalize_sections(Layout
 inline bool
 Target_i386::Relocate::should_apply_static_reloc(const Sized_symbol<32>* gsym,
                                                  int ref_flags,
-                                                 bool is_32bit)
+                                                 bool is_32bit,
+						 Output_section* output_section)
 {
+  // If the output section is not allocated, then we didn't call
+  // scan_relocs, we didn't create a dynamic reloc, and we must apply
+  // the reloc here.
+  if ((output_section->flags() & elfcpp::SHF_ALLOC) == 0)
+    return true;
+
   // For local symbols, we will have created a non-RELATIVE dynamic
   // relocation only if (a) the output is position independent,
   // (b) the relocation is absolute (not pc- or segment-relative), and
@@ -1622,6 +1630,7 @@ Target_i386::Relocate::should_apply_stat
 inline bool
 Target_i386::Relocate::relocate(const Relocate_info<32, false>* relinfo,
 				Target_i386* target,
+				Output_section *output_section,
 				size_t relnum,
 				const elfcpp::Rel<32, false>& rel,
 				unsigned int r_type,
@@ -1697,7 +1706,8 @@ Target_i386::Relocate::relocate(const Re
       break;
 
     case elfcpp::R_386_32:
-      if (should_apply_static_reloc(gsym, Symbol::ABSOLUTE_REF, true))
+      if (should_apply_static_reloc(gsym, Symbol::ABSOLUTE_REF, true,
+				    output_section))
         Relocate_functions<32, false>::rel32(view, object, psymval);
       break;
 
@@ -1706,13 +1716,14 @@ Target_i386::Relocate::relocate(const Re
         int ref_flags = Symbol::NON_PIC_REF;
         if (gsym != NULL && gsym->type() == elfcpp::STT_FUNC)
           ref_flags |= Symbol::FUNCTION_CALL;
-        if (should_apply_static_reloc(gsym, ref_flags, true))
+        if (should_apply_static_reloc(gsym, ref_flags, true, output_section))
           Relocate_functions<32, false>::pcrel32(view, object, psymval, address);
       }
       break;
 
     case elfcpp::R_386_16:
-      if (should_apply_static_reloc(gsym, Symbol::ABSOLUTE_REF, false))
+      if (should_apply_static_reloc(gsym, Symbol::ABSOLUTE_REF, false,
+				    output_section))
         Relocate_functions<32, false>::rel16(view, object, psymval);
       break;
 
@@ -1721,13 +1732,14 @@ Target_i386::Relocate::relocate(const Re
         int ref_flags = Symbol::NON_PIC_REF;
         if (gsym != NULL && gsym->type() == elfcpp::STT_FUNC)
           ref_flags |= Symbol::FUNCTION_CALL;
-        if (should_apply_static_reloc(gsym, ref_flags, false))
+        if (should_apply_static_reloc(gsym, ref_flags, false, output_section))
           Relocate_functions<32, false>::pcrel16(view, object, psymval, address);
       }
       break;
 
     case elfcpp::R_386_8:
-      if (should_apply_static_reloc(gsym, Symbol::ABSOLUTE_REF, false))
+      if (should_apply_static_reloc(gsym, Symbol::ABSOLUTE_REF, false,
+				    output_section))
         Relocate_functions<32, false>::rel8(view, object, psymval);
       break;
 
@@ -1736,7 +1748,8 @@ Target_i386::Relocate::relocate(const Re
         int ref_flags = Symbol::NON_PIC_REF;
         if (gsym != NULL && gsym->type() == elfcpp::STT_FUNC)
           ref_flags |= Symbol::FUNCTION_CALL;
-        if (should_apply_static_reloc(gsym, ref_flags, false))
+        if (should_apply_static_reloc(gsym, ref_flags, false,
+				      output_section))
           Relocate_functions<32, false>::pcrel8(view, object, psymval, address);
       }
       break;
Index: powerpc.cc
===================================================================
RCS file: /cvs/src/src/gold/powerpc.cc,v
retrieving revision 1.9
diff -p -u -r1.9 powerpc.cc
--- powerpc.cc	28 Jan 2009 02:25:33 -0000	1.9
+++ powerpc.cc	4 Mar 2009 06:42:45 -0000
@@ -214,7 +214,8 @@ class Target_powerpc : public Sized_targ
     // any warnings about this relocation.
     inline bool
     relocate(const Relocate_info<size, big_endian>*, Target_powerpc*,
-	     size_t relnum, const elfcpp::Rela<size, big_endian>&,
+	     Output_section*, size_t relnum,
+	     const elfcpp::Rela<size, big_endian>&,
 	     unsigned int r_type, const Sized_symbol<size>*,
 	     const Symbol_value<size>*,
 	     unsigned char*,
@@ -1578,6 +1579,7 @@ inline bool
 Target_powerpc<size, big_endian>::Relocate::relocate(
 			const Relocate_info<size, big_endian>* relinfo,
 			Target_powerpc* target,
+			Output_section*,
 			size_t relnum,
 			const elfcpp::Rela<size, big_endian>& rela,
 			unsigned int r_type,
Index: reloc.cc
===================================================================
RCS file: /cvs/src/src/gold/reloc.cc,v
retrieving revision 1.41
diff -p -u -r1.41 reloc.cc
--- reloc.cc	28 Jan 2009 02:25:33 -0000	1.41
+++ reloc.cc	4 Mar 2009 06:42:45 -0000
@@ -279,7 +279,9 @@ Sized_relobj<size, big_endian>::do_read_
       // PLT sections.  Relocations for sections which are not
       // allocated (typically debugging sections) should not add new
       // GOT and PLT entries.  So we skip them unless this is a
-      // relocatable link or we need to emit relocations.
+      // relocatable link or we need to emit relocations.  FIXME: What
+      // should we do if a linker script maps a section with SHF_ALLOC
+      // clear to a section with SHF_ALLOC set?
       typename This::Shdr secshdr(pshdrs + shndx * This::shdr_size);
       bool is_section_allocated = ((secshdr.get_sh_flags() & elfcpp::SHF_ALLOC)
 				   != 0);
Index: sparc.cc
===================================================================
RCS file: /cvs/src/src/gold/sparc.cc,v
retrieving revision 1.12
diff -p -u -r1.12 sparc.cc
--- sparc.cc	28 Jan 2009 02:25:33 -0000	1.12
+++ sparc.cc	4 Mar 2009 06:42:46 -0000
@@ -232,7 +232,8 @@ class Target_sparc : public Sized_target
     // any warnings about this relocation.
     inline bool
     relocate(const Relocate_info<size, big_endian>*, Target_sparc*,
-	     size_t relnum, const elfcpp::Rela<size, big_endian>&,
+	     Output_section*, size_t relnum,
+	     const elfcpp::Rela<size, big_endian>&,
 	     unsigned int r_type, const Sized_symbol<size>*,
 	     const Symbol_value<size>*,
 	     unsigned char*,
@@ -2356,6 +2357,7 @@ inline bool
 Target_sparc<size, big_endian>::Relocate::relocate(
 			const Relocate_info<size, big_endian>* relinfo,
 			Target_sparc* target,
+			Output_section*,
 			size_t relnum,
 			const elfcpp::Rela<size, big_endian>& rela,
 			unsigned int r_type,
Index: target-reloc.h
===================================================================
RCS file: /cvs/src/src/gold/target-reloc.h,v
retrieving revision 1.32
diff -p -u -r1.32 target-reloc.h
--- target-reloc.h	6 Feb 2009 19:20:09 -0000	1.32
+++ target-reloc.h	4 Mar 2009 06:42:46 -0000
@@ -268,8 +268,9 @@ relocate_section(
 	  psymval = &symval;
 	}
 
-      if (!relocate.relocate(relinfo, target, i, reloc, r_type, sym, psymval,
-			     view + offset, view_address + offset, view_size))
+      if (!relocate.relocate(relinfo, target, output_section, i, reloc,
+			     r_type, sym, psymval, view + offset,
+			     view_address + offset, view_size))
 	continue;
 
       if (offset < 0 || static_cast<section_size_type>(offset) >= view_size)
Index: x86_64.cc
===================================================================
RCS file: /cvs/src/src/gold/x86_64.cc,v
retrieving revision 1.78
diff -p -u -r1.78 x86_64.cc
--- x86_64.cc	30 Jan 2009 00:21:46 -0000	1.78
+++ x86_64.cc	4 Mar 2009 06:42:46 -0000
@@ -227,8 +227,8 @@ class Target_x86_64 : public Sized_targe
     // Do a relocation.  Return false if the caller should not issue
     // any warnings about this relocation.
     inline bool
-    relocate(const Relocate_info<64, false>*, Target_x86_64*, size_t relnum,
-	     const elfcpp::Rela<64, false>&,
+    relocate(const Relocate_info<64, false>*, Target_x86_64*, Output_section*,
+	     size_t relnum, const elfcpp::Rela<64, false>&,
 	     unsigned int r_type, const Sized_symbol<64>*,
 	     const Symbol_value<64>*,
 	     unsigned char*, elfcpp::Elf_types<64>::Elf_Addr,
@@ -1692,6 +1692,7 @@ Target_x86_64::do_finalize_sections(Layo
 inline bool
 Target_x86_64::Relocate::relocate(const Relocate_info<64, false>* relinfo,
                                   Target_x86_64* target,
+				  Output_section*,
                                   size_t relnum,
                                   const elfcpp::Rela<64, false>& rela,
                                   unsigned int r_type,
Index: testsuite/Makefile.am
===================================================================
RCS file: /cvs/src/src/gold/testsuite/Makefile.am,v
retrieving revision 1.85
diff -p -u -r1.85 Makefile.am
--- testsuite/Makefile.am	27 Feb 2009 19:57:46 -0000	1.85
+++ testsuite/Makefile.am	4 Mar 2009 06:42:46 -0000
@@ -226,6 +226,11 @@ two_file_relocatable_test_LDADD = two_fi
 two_file_relocatable.o: gcctestdir/ld two_file_test_1.o two_file_test_1b.o two_file_test_2.o
 	gcctestdir/ld -r -o $@ two_file_test_1.o two_file_test_1b.o two_file_test_2.o
 
+check_SCRIPTS += two_file_shared.sh
+check_DATA += two_file_shared.dbg
+two_file_shared.dbg: two_file_shared.so
+	$(TEST_READELF) -w $< >$@ 2>/dev/null
+
 # The nonpic tests will fail on platforms which can not put non-PIC
 # code into shared libraries, so we just don't run them in that case.
 if FN_PTRS_IN_SO_WITHOUT_PIC
Index: testsuite/two_file_shared.sh
===================================================================
RCS file: testsuite/two_file_shared.sh
diff -N testsuite/two_file_shared.sh
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ testsuite/two_file_shared.sh	4 Mar 2009 06:42:47 -0000
@@ -0,0 +1,30 @@
+#!/bin/sh
+
+# two_file_shared.sh -- check that debug info gets symbol addresses
+
+# Copyright 2009 Free Software Foundation, Inc.
+# Written by Ian Lance Taylor <iant@google.com>.
+
+# This file is part of gold.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+# MA 02110-1301, USA.
+
+addrs=`grep DW_OP_addr two_file_shared.dbg | fgrep '(DW_OP_addr: 0)'`
+if test -n "$addrs"; then
+  echo "Found variables with address zero"
+  echo $addrs
+  exit 1
+fi

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