From ef38fd8a0b29ff3e53add753ef8fe3bd6c242542 Mon Sep 17 00:00:00 2001 From: Sriraman Tallam Date: Fri, 23 Apr 2010 18:49:23 +0000 Subject: [PATCH] 2010-04-23 Sriraman Tallam * gc.h (gc_process_relocs): Pass information on relocs pointing to sections that are not ordinary to icf. * icf.cc (get_section_contents): Handle relocation pointing to section with no object or shndx information. * testsuite/Makefile.am: Remove icf_virtual_function_folding_test.sh * testsuite/Makefile.in: Regenerate. * testsuite/icf_virtual_function_folding_test.cc: Remove printf. * testsuite/icf_virtual_function_folding_test.sh: Delete file. --- gold/ChangeLog | 11 +++++ gold/gc.h | 44 ++++++++++++------- gold/icf.cc | 24 +++++++++- gold/testsuite/Makefile.am | 1 - gold/testsuite/Makefile.in | 1 - .../icf_virtual_function_folding_test.cc | 4 -- .../icf_virtual_function_folding_test.sh | 35 --------------- 7 files changed, 60 insertions(+), 60 deletions(-) delete mode 100755 gold/testsuite/icf_virtual_function_folding_test.sh diff --git a/gold/ChangeLog b/gold/ChangeLog index 54e775dd0dc..153828cb7b0 100644 --- a/gold/ChangeLog +++ b/gold/ChangeLog @@ -1,3 +1,14 @@ +2010-04-23 Sriraman Tallam + + * gc.h (gc_process_relocs): Pass information on relocs pointing to + sections that are not ordinary to icf. + * icf.cc (get_section_contents): Handle relocation pointing to section + with no object or shndx information. + * testsuite/Makefile.am: Remove icf_virtual_function_folding_test.sh + * testsuite/Makefile.in: Regenerate. + * testsuite/icf_virtual_function_folding_test.cc: Remove printf. + * testsuite/icf_virtual_function_folding_test.sh: Delete file. + 2010-04-22 Ian Lance Taylor * expression.cc (Expression::Expression_eval_info): Add diff --git a/gold/gc.h b/gold/gc.h index b79bd77e666..77ac6dad9e5 100644 --- a/gold/gc.h +++ b/gold/gc.h @@ -228,14 +228,14 @@ gc_process_relocs( unsigned int shndx = lsym.get_st_shndx(); bool is_ordinary; shndx = src_obj->adjust_sym_shndx(r_sym, shndx, &is_ordinary); - if (!is_ordinary) - continue; dst_obj = src_obj; dst_indx = shndx; - Section_id dst_id(dst_obj, dst_indx); if (is_icf_tracked) { - (*secvec).push_back(dst_id); + if (is_ordinary) + (*secvec).push_back(Section_id(dst_obj, dst_indx)); + else + (*secvec).push_back(Section_id(NULL, 0)); (*symvec).push_back(NULL); long long symvalue = static_cast(lsym.get_st_value()); (*addendvec).push_back(std::make_pair(symvalue, @@ -247,7 +247,8 @@ gc_process_relocs( // When doing safe folding, check to see if this relocation is that // of a function pointer being taken. - if (check_section_for_function_pointers + if (is_ordinary + && check_section_for_function_pointers && lsym.get_st_type() != elfcpp::STT_OBJECT && scan.local_reloc_may_be_function_pointer(symtab, NULL, NULL, src_obj, src_indx, @@ -256,7 +257,7 @@ gc_process_relocs( symtab->icf()->set_section_has_function_pointers( src_obj, lsym.get_st_shndx()); - if (shndx == src_indx) + if (!is_ordinary || shndx == src_indx) continue; } else @@ -265,16 +266,20 @@ gc_process_relocs( gold_assert(gsym != NULL); if (gsym->is_forwarder()) gsym = symtab->resolve_forwards(gsym); - if (gsym->source() != Symbol::FROM_OBJECT) - continue; - bool is_ordinary; - dst_obj = gsym->object(); - dst_indx = gsym->shndx(&is_ordinary); - Section_id dst_id(dst_obj, dst_indx); + + dst_obj = NULL; + dst_indx = 0; + bool is_ordinary = false; + if (gsym->source() == Symbol::FROM_OBJECT) + { + dst_obj = gsym->object(); + dst_indx = gsym->shndx(&is_ordinary); + } // When doing safe folding, check to see if this relocation is that // of a function pointer being taken. - if (check_section_for_function_pointers + if (gsym->source() == Symbol::FROM_OBJECT + && check_section_for_function_pointers && gsym->type() != elfcpp::STT_OBJECT && (!is_ordinary || scan.global_reloc_may_be_function_pointer( @@ -282,9 +287,6 @@ gc_process_relocs( r_type, gsym))) symtab->icf()->set_section_has_function_pointers(dst_obj, dst_indx); - if (!is_ordinary) - continue; - // If the symbol name matches '__start_XXX' then the section with // the C identifier like name 'XXX' should not be garbage collected. // A similar treatment to symbols with the name '__stop_XXX'. @@ -300,7 +302,10 @@ gc_process_relocs( } if (is_icf_tracked) { - (*secvec).push_back(dst_id); + if (is_ordinary && gsym->source() == Symbol::FROM_OBJECT) + (*secvec).push_back(Section_id(dst_obj, dst_indx)); + else + (*secvec).push_back(Section_id(NULL, 0)); (*symvec).push_back(gsym); Sized_symbol* sized_gsym = static_cast* >(gsym); @@ -312,6 +317,11 @@ gc_process_relocs( convert_to_section_size_type(reloc.get_r_offset()); (*offsetvec).push_back(reloc_offset); } + + if (gsym->source() != Symbol::FROM_OBJECT) + continue; + if (!is_ordinary) + continue; } if (parameters->options().gc_sections()) { diff --git a/gold/icf.cc b/gold/icf.cc index 5040a6e0c14..47b6c60a326 100644 --- a/gold/icf.cc +++ b/gold/icf.cc @@ -263,8 +263,11 @@ get_section_contents(bool first_iteration, { Icf::Sections_reachable_info v = (it_reloc_info_list->second).section_info; + // Stores the information of the symbol pointed to by the reloc. Icf::Symbol_info s = (it_reloc_info_list->second).symbol_info; + // Stores the addend and the symbol value. Icf::Addend_info a = (it_reloc_info_list->second).addend_info; + // Stores the offset of the reloc. Icf::Offset_info o = (it_reloc_info_list->second).offset_info; Icf::Sections_reachable_info::iterator it_v = v.begin(); Icf::Symbol_info::iterator it_s = s.begin(); @@ -285,6 +288,24 @@ get_section_contents(bool first_iteration, static_cast((*it_a).first), static_cast((*it_a).second), static_cast(*it_o)); + + // If the symbol pointed to by the reloc is not in an ordinary + // section or if the symbol type is not FROM_OBJECT, then the + // object is NULL. + if (it_v->first == NULL) + { + if (first_iteration) + { + // If the symbol name is available, use it. + if ((*it_s) != NULL) + buffer.append((*it_s)->name()); + // Append the addend. + buffer.append(addend_str); + buffer.append("@"); + } + continue; + } + Section_id reloc_secn(it_v->first, it_v->second); // If this reloc turns back and points to the same section, @@ -406,8 +427,7 @@ get_section_contents(bool first_iteration, else if ((*it_s) != NULL) { // If symbol name is available use that. - const char *sym_name = (*it_s)->name(); - buffer.append(sym_name); + buffer.append((*it_s)->name()); // Append the addend. buffer.append(addend_str); buffer.append("@"); diff --git a/gold/testsuite/Makefile.am b/gold/testsuite/Makefile.am index 7c48074f431..e77a3ed546e 100644 --- a/gold/testsuite/Makefile.am +++ b/gold/testsuite/Makefile.am @@ -193,7 +193,6 @@ icf_safe_so_test_1.stdout: icf_safe_so_test icf_safe_so_test_2.stdout: icf_safe_so_test $(TEST_READELF) -h icf_safe_so_test > icf_safe_so_test_2.stdout -check_SCRIPTS += icf_virtual_function_folding_test.sh check_PROGRAMS += icf_virtual_function_folding_test MOSTLYCLEANFILES += icf_virtual_function_folding_test icf_virtual_function_folding_test.o: icf_virtual_function_folding_test.cc diff --git a/gold/testsuite/Makefile.in b/gold/testsuite/Makefile.in index 6c8860d0203..7b51717a3b3 100644 --- a/gold/testsuite/Makefile.in +++ b/gold/testsuite/Makefile.in @@ -62,7 +62,6 @@ check_PROGRAMS = object_unittest$(EXEEXT) binary_unittest$(EXEEXT) \ @GCC_TRUE@@NATIVE_LINKER_TRUE@ icf_keep_unique_test.sh \ @GCC_TRUE@@NATIVE_LINKER_TRUE@ icf_safe_test.sh \ @GCC_TRUE@@NATIVE_LINKER_TRUE@ icf_safe_so_test.sh \ -@GCC_TRUE@@NATIVE_LINKER_TRUE@ icf_virtual_function_folding_test.sh \ @GCC_TRUE@@NATIVE_LINKER_TRUE@ icf_preemptible_functions_test.sh \ @GCC_TRUE@@NATIVE_LINKER_TRUE@ icf_string_merge_test.sh \ @GCC_TRUE@@NATIVE_LINKER_TRUE@ two_file_shared.sh weak_plt.sh \ diff --git a/gold/testsuite/icf_virtual_function_folding_test.cc b/gold/testsuite/icf_virtual_function_folding_test.cc index 80f96ef5294..1ba3e734682 100644 --- a/gold/testsuite/icf_virtual_function_folding_test.cc +++ b/gold/testsuite/icf_virtual_function_folding_test.cc @@ -25,11 +25,8 @@ // for the virtual call fn1 entry in the vtable. This test makes sure // the call to Foo::fn1 works correctly after the folding. -#include - int fn2(void *) { - printf("fn1==fn2\n"); return 0xA; } @@ -54,7 +51,6 @@ class Foo : public Bar int Foo::fn1() { - printf("fn1==fn2\n"); return 0xA; } diff --git a/gold/testsuite/icf_virtual_function_folding_test.sh b/gold/testsuite/icf_virtual_function_folding_test.sh deleted file mode 100755 index 31c83395e07..00000000000 --- a/gold/testsuite/icf_virtual_function_folding_test.sh +++ /dev/null @@ -1,35 +0,0 @@ -#!/bin/sh - -# icf_virtual_function_folding_test.sh -- test --icf - -# Copyright 2010 Free Software Foundation, Inc. -# Written by Sriraman Tallam . - -# 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. - -check() -{ - ./icf_virtual_function_folding_test | grep $1 > /dev/null 2>&1 - if [ $? -gt 0 ] - then - echo "Program output incorrect after folding." $2 - exit 1 - fi -} - -check "fn1==fn2" -- 2.30.2