This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
gold patch committed: Fix debug info for commons in shared libraries
- From: Ian Lance Taylor <iant at google dot com>
- To: binutils at sourceware dot org
- Date: Tue, 03 Mar 2009 22:53:36 -0800
- Subject: 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