mirror of
https://github.com/darlinghq/darling-gdb.git
synced 2024-11-23 20:19:49 +00:00
* gc.h (Garbage_collection::Cident_section_map): New typedef.
(Garbage_collection::cident_sections): New function. (Garbage_collection::add_cident_section): New function. (Garbage_collection::cident_sections_): New member. (gc_process_relocs): Add references to sections whose names are C identifiers. * gold.h (cident_section_start_prefix): New constant. (cident_section_stop_prefix): New constant. (is_cident): New function. * layout.cc (Layout::define_section_symbols): Replace string constants with the newly defined constants. * object.cc (Sized_relobj::do_layout): Track sections whose names are C identifiers. * testsuite/Makefile.am: Add gc_orphan_section_test. * testsuite/Makefile.in: Regenerate. * testsuite/gc_orphan_section_test.cc: New file. * testsuite/gc_orphan_section_test.sh: New file.
This commit is contained in:
parent
b9674e179b
commit
f1ec9ded5c
@ -1,3 +1,23 @@
|
||||
2010-01-06 Sriraman Tallam <tmsriram@google.com>
|
||||
|
||||
* gc.h (Garbage_collection::Cident_section_map): New typedef.
|
||||
(Garbage_collection::cident_sections): New function.
|
||||
(Garbage_collection::add_cident_section): New function.
|
||||
(Garbage_collection::cident_sections_): New member.
|
||||
(gc_process_relocs): Add references to sections whose names are C
|
||||
identifiers.
|
||||
* gold.h (cident_section_start_prefix): New constant.
|
||||
(cident_section_stop_prefix): New constant.
|
||||
(is_cident): New function.
|
||||
* layout.cc (Layout::define_section_symbols): Replace string constants
|
||||
with the newly defined constants.
|
||||
* object.cc (Sized_relobj::do_layout): Track sections whose names are
|
||||
C identifiers.
|
||||
* testsuite/Makefile.am: Add gc_orphan_section_test.
|
||||
* testsuite/Makefile.in: Regenerate.
|
||||
* testsuite/gc_orphan_section_test.cc: New file.
|
||||
* testsuite/gc_orphan_section_test.sh: New file.
|
||||
|
||||
2010-01-06 Ian Lance Taylor <iant@google.com>
|
||||
|
||||
PR 10980
|
||||
|
46
gold/gc.h
46
gold/gc.h
@ -60,6 +60,10 @@ class Garbage_collection
|
||||
typedef Unordered_set<Section_id, Section_id_hash> Sections_reachable;
|
||||
typedef std::map<Section_id, Sections_reachable> Section_ref;
|
||||
typedef std::queue<Section_id> Worklist_type;
|
||||
// This maps the name of the section which can be represented as a C
|
||||
// identifier (cident) to the list of sections that have that name.
|
||||
// Different object files can have cident sections with the same name.
|
||||
typedef std::map<std::string, Sections_reachable> Cident_section_map;
|
||||
|
||||
Garbage_collection()
|
||||
: is_worklist_ready_(false)
|
||||
@ -94,12 +98,23 @@ class Garbage_collection
|
||||
is_section_garbage(Object* obj, unsigned int shndx)
|
||||
{ return (this->referenced_list().find(Section_id(obj, shndx))
|
||||
== this->referenced_list().end()); }
|
||||
|
||||
Cident_section_map*
|
||||
cident_sections()
|
||||
{ return &cident_sections_; }
|
||||
|
||||
void
|
||||
add_cident_section(std::string section_name,
|
||||
Section_id secn)
|
||||
{ this->cident_sections_[section_name].insert(secn); }
|
||||
|
||||
private:
|
||||
|
||||
Worklist_type work_list_;
|
||||
bool is_worklist_ready_;
|
||||
Section_ref section_reloc_map_;
|
||||
Sections_reachable referenced_list_;
|
||||
Cident_section_map cident_sections_;
|
||||
};
|
||||
|
||||
// Data to pass between successive invocations of do_layout
|
||||
@ -161,6 +176,7 @@ gc_process_relocs(
|
||||
std::vector<Symbol*>* symvec = NULL;
|
||||
std::vector<std::pair<long long, long long> >* addendvec = NULL;
|
||||
bool is_icf_tracked = false;
|
||||
const char* cident_section_name = NULL;
|
||||
|
||||
if (parameters->options().icf_enabled()
|
||||
&& is_section_foldable_candidate(src_obj->section_name(src_indx).c_str()))
|
||||
@ -218,6 +234,19 @@ gc_process_relocs(
|
||||
if (!is_ordinary)
|
||||
continue;
|
||||
Section_id dst_id(dst_obj, dst_indx);
|
||||
// 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'.
|
||||
if (is_prefix_of(cident_section_start_prefix, gsym->name()))
|
||||
{
|
||||
cident_section_name = (gsym->name()
|
||||
+ strlen(cident_section_start_prefix));
|
||||
}
|
||||
else if (is_prefix_of(cident_section_stop_prefix, gsym->name()))
|
||||
{
|
||||
cident_section_name = (gsym->name()
|
||||
+ strlen(cident_section_stop_prefix));
|
||||
}
|
||||
if (is_icf_tracked)
|
||||
{
|
||||
(*secvec).push_back(dst_id);
|
||||
@ -245,6 +274,23 @@ gc_process_relocs(
|
||||
Garbage_collection::Sections_reachable& v(map_it->second);
|
||||
v.insert(dst_id);
|
||||
}
|
||||
if (cident_section_name != NULL)
|
||||
{
|
||||
Garbage_collection::Cident_section_map::iterator ele =
|
||||
symtab->gc()->cident_sections()->find(std::string(cident_section_name));
|
||||
if (ele == symtab->gc()->cident_sections()->end())
|
||||
continue;
|
||||
Garbage_collection::Sections_reachable&
|
||||
v(symtab->gc()->section_reloc_map()[src_id]);
|
||||
Garbage_collection::Sections_reachable& cident_secn(ele->second);
|
||||
for (Garbage_collection::Sections_reachable::iterator it_v
|
||||
= cident_secn.begin();
|
||||
it_v != cident_secn.end();
|
||||
++it_v)
|
||||
{
|
||||
v.insert(*it_v);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return;
|
||||
|
17
gold/gold.h
17
gold/gold.h
@ -1,6 +1,6 @@
|
||||
// gold.h -- general definitions for gold -*- C++ -*-
|
||||
|
||||
// Copyright 2006, 2007, 2008, 2009 Free Software Foundation, Inc.
|
||||
// Copyright 2006, 2007, 2008, 2009, 2010 Free Software Foundation, Inc.
|
||||
// Written by Ian Lance Taylor <iant@google.com>.
|
||||
|
||||
// This file is part of gold.
|
||||
@ -349,6 +349,21 @@ is_prefix_of(const char* prefix, const char* str)
|
||||
return strncmp(prefix, str, strlen(prefix)) == 0;
|
||||
}
|
||||
|
||||
const char* const cident_section_start_prefix = "__start_";
|
||||
const char* const cident_section_stop_prefix = "__stop_";
|
||||
|
||||
// Returns true if the name is a valid C identifier
|
||||
inline bool
|
||||
is_cident(const char* name)
|
||||
{
|
||||
return (name[strspn(name,
|
||||
("0123456789"
|
||||
"ABCDEFGHIJKLMNOPWRSTUVWXYZ"
|
||||
"abcdefghijklmnopqrstuvwxyz"
|
||||
"_"))]
|
||||
== '\0');
|
||||
}
|
||||
|
||||
// We sometimes need to hash strings. Ideally we should use std::tr1::hash or
|
||||
// __gnu_cxx::hash on some systems but there is no guarantee that either
|
||||
// one is available. For portability, we define simple string hash functions.
|
||||
|
@ -1,6 +1,6 @@
|
||||
// layout.cc -- lay out output file sections for gold
|
||||
|
||||
// Copyright 2006, 2007, 2008, 2009 Free Software Foundation, Inc.
|
||||
// Copyright 2006, 2007, 2008, 2009, 2010 Free Software Foundation, Inc.
|
||||
// Written by Ian Lance Taylor <iant@google.com>.
|
||||
|
||||
// This file is part of gold.
|
||||
@ -1232,16 +1232,13 @@ Layout::define_section_symbols(Symbol_table* symtab)
|
||||
++p)
|
||||
{
|
||||
const char* const name = (*p)->name();
|
||||
if (name[strspn(name,
|
||||
("0123456789"
|
||||
"ABCDEFGHIJKLMNOPWRSTUVWXYZ"
|
||||
"abcdefghijklmnopqrstuvwxyz"
|
||||
"_"))]
|
||||
== '\0')
|
||||
if (is_cident(name))
|
||||
{
|
||||
const std::string name_string(name);
|
||||
const std::string start_name("__start_" + name_string);
|
||||
const std::string stop_name("__stop_" + name_string);
|
||||
const std::string start_name(cident_section_start_prefix
|
||||
+ name_string);
|
||||
const std::string stop_name(cident_section_stop_prefix
|
||||
+ name_string);
|
||||
|
||||
symtab->define_in_output_data(start_name.c_str(),
|
||||
NULL, // version
|
||||
|
@ -1180,6 +1180,14 @@ Sized_relobj<size, big_endian>::do_layout(Symbol_table* symtab,
|
||||
{
|
||||
symtab->gc()->worklist().push(Section_id(this, i));
|
||||
}
|
||||
// If the section name XXX can be represented as a C identifier
|
||||
// it cannot be discarded if there are references to
|
||||
// __start_XXX and __stop_XXX symbols. These need to be
|
||||
// specially handled.
|
||||
if (is_cident(name))
|
||||
{
|
||||
symtab->gc()->add_cident_section(name, Section_id(this, i));
|
||||
}
|
||||
}
|
||||
|
||||
// When doing a relocatable link we are going to copy input
|
||||
|
@ -139,6 +139,16 @@ gc_tls_test:gc_tls_test.o gcctestdir/ld
|
||||
gc_tls_test.stdout: gc_tls_test
|
||||
$(TEST_NM) -C gc_tls_test > gc_tls_test.stdout
|
||||
|
||||
check_SCRIPTS += gc_orphan_section_test.sh
|
||||
check_DATA += gc_orphan_section_test.stdout
|
||||
MOSTLYCLEANFILES += gc_orphan_section_test
|
||||
gc_orphan_section_test.o: gc_orphan_section_test.cc
|
||||
$(CXXCOMPILE) -O0 -c -g -o $@ $<
|
||||
gc_orphan_section_test:gc_orphan_section_test.o gcctestdir/ld
|
||||
$(CXXLINK) -Bgcctestdir/ -Wl,--gc-sections gc_orphan_section_test.o
|
||||
gc_orphan_section_test.stdout: gc_orphan_section_test
|
||||
$(TEST_NM) gc_orphan_section_test > gc_orphan_section_test.stdout
|
||||
|
||||
check_SCRIPTS += icf_test.sh
|
||||
check_DATA += icf_test.stdout
|
||||
MOSTLYCLEANFILES += icf_test
|
||||
|
@ -57,6 +57,7 @@ check_PROGRAMS = object_unittest$(EXEEXT) binary_unittest$(EXEEXT) \
|
||||
# and --dynamic-list-cpp-typeinfo
|
||||
@GCC_TRUE@@NATIVE_LINKER_TRUE@am__append_1 = incremental_test.sh \
|
||||
@GCC_TRUE@@NATIVE_LINKER_TRUE@ gc_comdat_test.sh gc_tls_test.sh \
|
||||
@GCC_TRUE@@NATIVE_LINKER_TRUE@ gc_orphan_section_test.sh \
|
||||
@GCC_TRUE@@NATIVE_LINKER_TRUE@ icf_test.sh \
|
||||
@GCC_TRUE@@NATIVE_LINKER_TRUE@ icf_keep_unique_test.sh \
|
||||
@GCC_TRUE@@NATIVE_LINKER_TRUE@ icf_safe_test.sh \
|
||||
@ -82,6 +83,7 @@ check_PROGRAMS = object_unittest$(EXEEXT) binary_unittest$(EXEEXT) \
|
||||
@GCC_TRUE@@NATIVE_LINKER_TRUE@am__append_2 = incremental_test.stdout \
|
||||
@GCC_TRUE@@NATIVE_LINKER_TRUE@ gc_comdat_test.stdout \
|
||||
@GCC_TRUE@@NATIVE_LINKER_TRUE@ gc_tls_test.stdout \
|
||||
@GCC_TRUE@@NATIVE_LINKER_TRUE@ gc_orphan_section_test.stdout \
|
||||
@GCC_TRUE@@NATIVE_LINKER_TRUE@ icf_test.stdout \
|
||||
@GCC_TRUE@@NATIVE_LINKER_TRUE@ icf_keep_unique_test.stdout \
|
||||
@GCC_TRUE@@NATIVE_LINKER_TRUE@ icf_safe_test.stdout \
|
||||
@ -103,7 +105,8 @@ check_PROGRAMS = object_unittest$(EXEEXT) binary_unittest$(EXEEXT) \
|
||||
@GCC_TRUE@@NATIVE_LINKER_TRUE@ dynamic_list.stdout
|
||||
@GCC_TRUE@@NATIVE_LINKER_TRUE@am__append_3 = incremental_test \
|
||||
@GCC_TRUE@@NATIVE_LINKER_TRUE@ gc_comdat_test gc_tls_test \
|
||||
@GCC_TRUE@@NATIVE_LINKER_TRUE@ icf_test icf_keep_unique_test \
|
||||
@GCC_TRUE@@NATIVE_LINKER_TRUE@ gc_orphan_section_test icf_test \
|
||||
@GCC_TRUE@@NATIVE_LINKER_TRUE@ icf_keep_unique_test \
|
||||
@GCC_TRUE@@NATIVE_LINKER_TRUE@ icf_safe_test \
|
||||
@GCC_TRUE@@NATIVE_LINKER_TRUE@ two_file_shared.dbg \
|
||||
@GCC_TRUE@@NATIVE_LINKER_TRUE@ alt/weak_undef_lib.so
|
||||
@ -2582,6 +2585,12 @@ uninstall-am:
|
||||
@GCC_TRUE@@NATIVE_LINKER_TRUE@ $(CXXLINK) -Bgcctestdir/ -Wl,--gc-sections gc_tls_test.o
|
||||
@GCC_TRUE@@NATIVE_LINKER_TRUE@gc_tls_test.stdout: gc_tls_test
|
||||
@GCC_TRUE@@NATIVE_LINKER_TRUE@ $(TEST_NM) -C gc_tls_test > gc_tls_test.stdout
|
||||
@GCC_TRUE@@NATIVE_LINKER_TRUE@gc_orphan_section_test.o: gc_orphan_section_test.cc
|
||||
@GCC_TRUE@@NATIVE_LINKER_TRUE@ $(CXXCOMPILE) -O0 -c -g -o $@ $<
|
||||
@GCC_TRUE@@NATIVE_LINKER_TRUE@gc_orphan_section_test:gc_orphan_section_test.o gcctestdir/ld
|
||||
@GCC_TRUE@@NATIVE_LINKER_TRUE@ $(CXXLINK) -Bgcctestdir/ -Wl,--gc-sections gc_orphan_section_test.o
|
||||
@GCC_TRUE@@NATIVE_LINKER_TRUE@gc_orphan_section_test.stdout: gc_orphan_section_test
|
||||
@GCC_TRUE@@NATIVE_LINKER_TRUE@ $(TEST_NM) gc_orphan_section_test > gc_orphan_section_test.stdout
|
||||
@GCC_TRUE@@NATIVE_LINKER_TRUE@icf_test.o: icf_test.cc
|
||||
@GCC_TRUE@@NATIVE_LINKER_TRUE@ $(CXXCOMPILE) -O0 -c -ffunction-sections -g -o $@ $<
|
||||
@GCC_TRUE@@NATIVE_LINKER_TRUE@icf_test: icf_test.o gcctestdir/ld
|
||||
|
36
gold/testsuite/gc_orphan_section_test.cc
Normal file
36
gold/testsuite/gc_orphan_section_test.cc
Normal file
@ -0,0 +1,36 @@
|
||||
// gc_orphan_section_test.cc -- a test case for gold
|
||||
|
||||
// Copyright 2010 Free Software Foundation, Inc.
|
||||
// Written by Sriraman Tallam <tmsriram@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.
|
||||
|
||||
// The goal of this program is to verify if garbage collection does not
|
||||
// discard orphan sections when references to them through __start_XXX
|
||||
// and __stop_XXX are present. Here section _foo must not be gc'ed but
|
||||
// _boo should be gc'ed.
|
||||
|
||||
extern const int *__start__foo;
|
||||
int foo __attribute__((__section__("_foo"))) = 1;
|
||||
int boo __attribute__((__section__("_boo"))) = 1;
|
||||
|
||||
int main()
|
||||
{
|
||||
return *__start__foo;
|
||||
}
|
||||
|
46
gold/testsuite/gc_orphan_section_test.sh
Executable file
46
gold/testsuite/gc_orphan_section_test.sh
Executable file
@ -0,0 +1,46 @@
|
||||
#!/bin/sh
|
||||
|
||||
# gc_orphan_section_test.sh -- test --gc-sections
|
||||
|
||||
# Copyright 2010 Free Software Foundation, Inc.
|
||||
# Written by Sriraman Tallam <tmsriram@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.
|
||||
|
||||
# The goal of this program is to verify if gc-sections works as expected
|
||||
# with orphan sections.
|
||||
# File gc_orphan_sections_test.cc is in this test. This program checks if
|
||||
# the orphan sections are retained when they are referenced through
|
||||
# __start_XXX and __stop_XXX symbols.
|
||||
|
||||
check()
|
||||
{
|
||||
if grep -q " boo" "$1"
|
||||
then
|
||||
echo "Garbage collection failed to collect boo"
|
||||
exit 1
|
||||
fi
|
||||
grep_foo=`grep -q " foo" $1`
|
||||
if [ $? != 0 ];
|
||||
then
|
||||
echo "Garbage collection should not discard foo"
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
check gc_orphan_section_test.stdout
|
Loading…
Reference in New Issue
Block a user