aboutsummaryrefslogtreecommitdiff
path: root/gold/script.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/script.cc
parente0bb29a5842200725829ebdb21dfa1f3c692b223 (diff)
downloadfsf-binutils-gdb-c82fbeee5970971ab2988ab7fda3439719df09ab.zip
fsf-binutils-gdb-c82fbeee5970971ab2988ab7fda3439719df09ab.tar.gz
fsf-binutils-gdb-c82fbeee5970971ab2988ab7fda3439719df09ab.tar.bz2
* 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/script.cc')
-rw-r--r--gold/script.cc59
1 files changed, 47 insertions, 12 deletions
diff --git a/gold/script.cc b/gold/script.cc
index 53fcf66..9deb726 100644
--- a/gold/script.cc
+++ b/gold/script.cc
@@ -184,7 +184,9 @@ class Lex
// Reading an expression in a linker script.
EXPRESSION,
// Reading a version script.
- VERSION_SCRIPT
+ VERSION_SCRIPT,
+ // Reading a --dynamic-list file.
+ DYNAMIC_LIST
};
Lex(const char* input_string, size_t input_length, int parsing_token)
@@ -393,8 +395,9 @@ Lex::can_start_name(char c, char c2)
case '~':
return this->mode_ == LINKER_SCRIPT && can_continue_name(&c2);
- case '*': case '[':
+ case '*': case '[':
return (this->mode_ == VERSION_SCRIPT
+ || this->mode_ == DYNAMIC_LIST
|| (this->mode_ == LINKER_SCRIPT
&& can_continue_name(&c2)));
@@ -429,6 +432,7 @@ Lex::can_continue_name(const char* c)
case '5': case '6': case '7': case '8': case '9':
return c + 1;
+ // TODO(csilvers): why not allow ~ in names for version-scripts?
case '/': case '\\': case '~':
case '=': case '+':
case ',':
@@ -437,19 +441,22 @@ Lex::can_continue_name(const char* c)
return NULL;
case '[': case ']': case '*': case '?': case '-':
- if (this->mode_ == LINKER_SCRIPT || this->mode_ == VERSION_SCRIPT)
+ if (this->mode_ == LINKER_SCRIPT || this->mode_ == VERSION_SCRIPT
+ || this->mode_ == DYNAMIC_LIST)
return c + 1;
return NULL;
+ // TODO(csilvers): why allow this? ^ is meaningless in version scripts.
case '^':
- if (this->mode_ == VERSION_SCRIPT)
+ if (this->mode_ == VERSION_SCRIPT || this->mode_ == DYNAMIC_LIST)
return c + 1;
return NULL;
case ':':
if (this->mode_ == LINKER_SCRIPT)
return c + 1;
- else if (this->mode_ == VERSION_SCRIPT && (c[1] == ':'))
+ else if ((this->mode_ == VERSION_SCRIPT || this->mode_ == DYNAMIC_LIST)
+ && (c[1] == ':'))
{
// A name can have '::' in it, as that's a c++ namespace
// separator. But a single colon is not part of a name.
@@ -1161,7 +1168,7 @@ class Parser_closure
command_line_(command_line), script_options_(script_options),
version_script_info_(script_options->version_script_info()),
lex_(lex), lineno_(0), charpos_(0), lex_mode_stack_(), inputs_(NULL)
- {
+ {
// We start out processing C symbols in the default lex mode.
language_stack_.push_back("");
lex_mode_stack_.push_back(lex->mode());
@@ -1373,6 +1380,7 @@ read_input_script(Workqueue* workqueue, const General_options& options,
static bool
read_script_file(const char* filename, Command_line* cmdline,
+ Script_options* script_options,
int first_token, Lex::Mode lex_mode)
{
// TODO: if filename is a relative filename, search for it manually
@@ -1404,7 +1412,7 @@ read_script_file(const char* filename, Command_line* cmdline,
false,
input_file.is_in_sysroot(),
cmdline,
- &cmdline->script_options(),
+ script_options,
&lex);
if (yyparse(&closure) != 0)
{
@@ -1425,21 +1433,32 @@ read_script_file(const char* filename, Command_line* cmdline,
bool
read_commandline_script(const char* filename, Command_line* cmdline)
{
- return read_script_file(filename, cmdline,
+ return read_script_file(filename, cmdline, &cmdline->script_options(),
PARSING_LINKER_SCRIPT, Lex::LINKER_SCRIPT);
}
-// FILE was found as an argument to --version-script. Read it as a
-// version script, and store its contents in
+// FILENAME was found as an argument to --version-script. Read it as
+// a version script, and store its contents in
// cmdline->script_options()->version_script_info().
bool
read_version_script(const char* filename, Command_line* cmdline)
{
- return read_script_file(filename, cmdline,
+ return read_script_file(filename, cmdline, &cmdline->script_options(),
PARSING_VERSION_SCRIPT, Lex::VERSION_SCRIPT);
}
+// FILENAME was found as an argument to --dynamic-list. Read it as a
+// list of symbols, and store its contents in DYNAMIC_LIST.
+
+bool
+read_dynamic_list(const char* filename, Command_line* cmdline,
+ Script_options* dynamic_list)
+{
+ return read_script_file(filename, cmdline, dynamic_list,
+ PARSING_DYNAMIC_LIST, Lex::DYNAMIC_LIST);
+}
+
// Implement the --defsym option on the command line. Return true if
// all is well.
@@ -1622,6 +1641,19 @@ version_script_keywords(&version_script_keyword_parsecodes[0],
(sizeof(version_script_keyword_parsecodes)
/ sizeof(version_script_keyword_parsecodes[0])));
+static const Keyword_to_parsecode::Keyword_parsecode
+dynamic_list_keyword_parsecodes[] =
+{
+ { "extern", EXTERN },
+};
+
+static const Keyword_to_parsecode
+dynamic_list_keywords(&dynamic_list_keyword_parsecodes[0],
+ (sizeof(dynamic_list_keyword_parsecodes)
+ / sizeof(dynamic_list_keyword_parsecodes[0])));
+
+
+
// Comparison function passed to bsearch.
extern "C"
@@ -1963,6 +1995,9 @@ yylex(YYSTYPE* lvalp, void* closurev)
case Lex::VERSION_SCRIPT:
parsecode = version_script_keywords.keyword_to_parsecode(str, len);
break;
+ case Lex::DYNAMIC_LIST:
+ parsecode = dynamic_list_keywords.keyword_to_parsecode(str, len);
+ break;
default:
break;
}
@@ -2339,7 +2374,7 @@ script_start_output_section(void* closurev, const char* name, size_t namelen,
// Finish processing entries for an output section.
extern "C" void
-script_finish_output_section(void* closurev,
+script_finish_output_section(void* closurev,
const struct Parser_output_section_trailer* trail)
{
Parser_closure* closure = static_cast<Parser_closure*>(closurev);