summaryrefslogtreecommitdiff
path: root/gold/symtab.cc
diff options
context:
space:
mode:
authorCraig Silverstein <csilvers@google.com>2008-11-06 07:23:31 +0000
committerCraig Silverstein <csilvers@google.com>2008-11-06 07:23:31 +0000
commitc82fbeee5970971ab2988ab7fda3439719df09ab (patch)
treee3d01b8663155d445595c3a0a9e410e4d82bc3d2 /gold/symtab.cc
parente0bb29a5842200725829ebdb21dfa1f3c692b223 (diff)
downloadbinutils-gdb-c82fbeee5970971ab2988ab7fda3439719df09ab.tar.gz
* options.cc (General_options::parse_dynamic_list): New function.
* options.h (General_options): New flags dynamic_list, dynamic_list_data, dynamic_list_cpp_new, and dynamic_list_cpp_typeinfo. New variable dynamic_list_. (General_options::in_dynamic_list): New function. * script.cc (Lex::Mode): New enum DYNAMIC_LIST. (Lex::can_start_name): Add support for DYNAMIC_LIST mode. (Lex::can_continue_name): Likewise. (yylex): Likewise. (read_script_file): New parameter script_options. (read_dynamic_list): New function. (Script_options::define_dynamic_list): New function. (dynamic_list_keyword_parsecodes): New variable. (dynamic_list_keywords): New variable. * script.h (Script_options::define_dynamic_list): New function prototype. (read_dynamic_list): New function prototype. * symtab.cc (strprefix): New macro. (Symbol::should_add_dynsym_entry): Support dynamic_list, dynamic_list_data, dynamic_list_cpp_new, and dynamic_list_cpp_typeinfo. * yyscript.y (PARSING_DYNAMIC_LIST): New token. (dynamic_list_expr): New rule. (dynamic_list_nodes): Likewise. (dynamic_list_node): Likewise. * testsuite/Makefile.am (dynamic_list): New test. * testsuite/Makefile.in: Regenerated. * testsuite/dynamic_list.t: New file. * testsuite/dynamic_list.sh: New file.
Diffstat (limited to 'gold/symtab.cc')
-rw-r--r--gold/symtab.cc46
1 files changed, 46 insertions, 0 deletions
diff --git a/gold/symtab.cc b/gold/symtab.cc
index c2de3bcad90..90ddfaea077 100644
--- a/gold/symtab.cc
+++ b/gold/symtab.cc
@@ -37,6 +37,7 @@
#include "target.h"
#include "workqueue.h"
#include "symtab.h"
+#include "demangle.h" // needed for --dynamic-list-cpp-new
#include "plugin.h"
namespace gold
@@ -288,6 +289,9 @@ Sized_symbol<size>::allocate_common(Output_data* od, Value_type value)
this->value_ = value;
}
+// The ""'s around str ensure str is a string literal, so sizeof works.
+#define strprefix(var, str) (strncmp(var, str, sizeof("" str "") - 1) == 0)
+
// Return true if this symbol should be added to the dynamic symbol
// table.
@@ -302,6 +306,48 @@ Symbol::should_add_dynsym_entry() const
if (this->is_forced_local())
return false;
+ // If the symbol was forced dynamic in a --dynamic-list file, add it.
+ if (parameters->options().in_dynamic_list(this->name()))
+ return true;
+
+ // If dynamic-list-data was specified, add any STT_OBJECT.
+ if (parameters->options().dynamic_list_data()
+ && !this->is_from_dynobj()
+ && this->type() == elfcpp::STT_OBJECT)
+ return true;
+
+ // If --dynamic-list-cpp-new was specified, add any new/delete symbol.
+ // If --dynamic-list-cpp-typeinfo was specified, add any typeinfo symbols.
+ if ((parameters->options().dynamic_list_cpp_new()
+ || parameters->options().dynamic_list_cpp_typeinfo())
+ && !this->is_from_dynobj())
+ {
+ // TODO(csilvers): We could probably figure out if we're an operator
+ // new/delete or typeinfo without the need to demangle.
+ char* demangled_name = cplus_demangle(this->name(),
+ DMGL_ANSI | DMGL_PARAMS);
+ if (demangled_name == NULL)
+ {
+ // Not a C++ symbol, so it can't satisfy these flags
+ }
+ else if (parameters->options().dynamic_list_cpp_new()
+ && (strprefix(demangled_name, "operator new")
+ || strprefix(demangled_name, "operator delete")))
+ {
+ free(demangled_name);
+ return true;
+ }
+ else if (parameters->options().dynamic_list_cpp_typeinfo()
+ && (strprefix(demangled_name, "typeinfo name for")
+ || strprefix(demangled_name, "typeinfo for")))
+ {
+ free(demangled_name);
+ return true;
+ }
+ else
+ free(demangled_name);
+ }
+
// If exporting all symbols or building a shared library,
// and the symbol is defined in a regular object and is
// externally visible, we need to add it.