aboutsummaryrefslogtreecommitdiff
path: root/gold/object.cc
diff options
context:
space:
mode:
authorDoug Kwan <dougkwan@google.com>2009-06-05 21:32:57 +0000
committerDoug Kwan <dougkwan@google.com>2009-06-05 21:32:57 +0000
commitbb04269c747a7aa5acffa2355efd1d7343338faf (patch)
treec0146d3edcbd719434f09eee57c611a592170761 /gold/object.cc
parentda1f277114fc1ed98e71bf2fde32fe82757e9314 (diff)
downloadgdb-bb04269c747a7aa5acffa2355efd1d7343338faf.zip
gdb-bb04269c747a7aa5acffa2355efd1d7343338faf.tar.gz
gdb-bb04269c747a7aa5acffa2355efd1d7343338faf.tar.bz2
2009-06-05 Doug Kwan <dougkwan@google.com>
* Makefile.am (CCFILES): Add target.cc. * Makefile.in: Regenerate. * i386.cc (class Target_i386): Define new virtual method to override do_is_local_label_name in parent. * object.cc (Sized_relobj::do_count_local_symbols): Discard local symbols if --discard-locals or -X is given. * options.h (class General_options): Declare new options '--discard-locals' and '-X' for discarding locals. * target.h (class Target): Define new methods is_local_label_name. Declare new virtual method do_is_local_label_name. * target.cc: New file. * testsuite/Makefile.am (check_PROGRAMS): Add discard_locals_test. (check_SCRIPTS): Add discard_locals_test.sh. (check_DATA): Add discard_local_tests.syms. (discard_locals_test_SOURCES, discard_locals_test_LDFLAGS): Define. (discard_local_tests.syms, discard_locals_test.o): New make rules. * testsuite/Makefile.in: Regenerate. * testsuite/discard_locals_test.c: New file. * testsuite/discard_locals_test.sh: Same.
Diffstat (limited to 'gold/object.cc')
-rw-r--r--gold/object.cc24
1 files changed, 23 insertions, 1 deletions
diff --git a/gold/object.cc b/gold/object.cc
index 77ddce6..88b6028 100644
--- a/gold/object.cc
+++ b/gold/object.cc
@@ -1439,6 +1439,7 @@ Sized_relobj<size, big_endian>::do_count_local_symbols(Stringpool* pool,
unsigned int dyncount = 0;
// Skip the first, dummy, symbol.
psyms += sym_size;
+ bool discard_locals = parameters->options().discard_locals();
for (unsigned int i = 1; i < loccount; ++i, psyms += sym_size)
{
elfcpp::Sym<size, big_endian> sym(psyms);
@@ -1484,8 +1485,29 @@ Sized_relobj<size, big_endian>::do_count_local_symbols(Stringpool* pool,
continue;
}
- // Add the symbol to the symbol table string pool.
+ // If --discard-locals option is used, discard all temporary local
+ // symbols. These symbols start with system-specific local label
+ // prefixes, typically .L for ELF system. We want to be compatible
+ // with GNU ld so here we essentially use the same check in
+ // bfd_is_local_label(). The code is different because we already
+ // know that:
+ //
+ // - the symbol is local and thus cannot have global or weak binding.
+ // - the symbol is not a section symbol.
+ // - the symbol has a name.
+ //
+ // We do not discard a symbol if it needs a dynamic symbol entry.
const char* name = pnames + sym.get_st_name();
+ if (discard_locals
+ && sym.get_st_type() != elfcpp::STT_FILE
+ && !lv.needs_output_dynsym_entry()
+ && parameters->target().is_local_label_name(name))
+ {
+ lv.set_no_output_symtab_entry();
+ continue;
+ }
+
+ // Add the symbol to the symbol table string pool.
pool->add(name, true, NULL);
++count;