diff options
Diffstat (limited to 'gold/object.cc')
-rw-r--r-- | gold/object.cc | 24 |
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; |