From afc06bb8287c9a5c81be4810fd0384e952dd19ea Mon Sep 17 00:00:00 2001 From: Ian Lance Taylor Date: Tue, 24 Mar 2009 19:08:37 +0000 Subject: * yyscript.y (file_cmd): Recognize EXTERN. (extern_name_list, extern_name_list_body): New nonterminals. * script.cc (script_add_extern): Define. * script-c.h (script_add_extern): Declare. --- gold/ChangeLog | 7 +++++++ gold/script-c.h | 6 ++++++ gold/script.cc | 13 +++++++++++++ gold/yyscript.y | 22 +++++++++++++++++++++- 4 files changed, 47 insertions(+), 1 deletion(-) diff --git a/gold/ChangeLog b/gold/ChangeLog index d380aa1..b51509a 100644 --- a/gold/ChangeLog +++ b/gold/ChangeLog @@ -1,3 +1,10 @@ +2009-03-24 Ian Lance Taylor + + * yyscript.y (file_cmd): Recognize EXTERN. + (extern_name_list, extern_name_list_body): New nonterminals. + * script.cc (script_add_extern): Define. + * script-c.h (script_add_extern): Declare. + 2009-03-24 Rafael Avila de Espindola * object.cc (is_elf_object): Define. diff --git a/gold/script-c.h b/gold/script-c.h index 13c789a..3da634f 100644 --- a/gold/script-c.h +++ b/gold/script-c.h @@ -211,6 +211,12 @@ yylex(YYSTYPE*, void* closure); extern void yyerror(void* closure, const char*); +/* Called by the bison parser to add an external symbol (a symbol in + an EXTERN declaration) to the link. */ + +extern void +script_add_extern(void* closure, const char*, size_t); + /* Called by the bison parser to add a file to the link. */ extern void diff --git a/gold/script.cc b/gold/script.cc index 44e43f7..30b4e3c 100644 --- a/gold/script.cc +++ b/gold/script.cc @@ -2119,6 +2119,19 @@ yyerror(void* closurev, const char* message) closure->charpos(), message); } +// Called by the bison parser to add an external symbol to the link. + +extern "C" void +script_add_extern(void* closurev, const char* name, size_t length) +{ + // We treat exactly like -u NAME. FIXME: If it seems useful, we + // could handle this after the command line has been read, by adding + // entries to the symbol table directly. + std::string arg("--undefined="); + arg.append(name, length); + script_parse_option(closurev, arg.c_str(), arg.size()); +} + // Called by the bison parser to add a file to the link. extern "C" void diff --git a/gold/yyscript.y b/gold/yyscript.y index b018005..34b8b55 100644 --- a/gold/yyscript.y +++ b/gold/yyscript.y @@ -234,7 +234,8 @@ linker_script: /* A command which may appear at top level of a linker script. */ file_cmd: - FORCE_COMMON_ALLOCATION + EXTERN '(' extern_name_list ')' + | FORCE_COMMON_ALLOCATION { script_set_common_allocation(closure, 1); } | GROUP { script_start_group(closure); } @@ -282,6 +283,25 @@ ignore_cmd: OUTPUT_ARCH '(' string ')' ; +/* A list of external undefined symbols. We put the lexer into + expression mode so that commas separate names; this is what the GNU + linker does. */ + +extern_name_list: + { script_push_lex_into_expression_mode(closure); } + extern_name_list_body + { script_pop_lex_mode(closure); } + ; + +extern_name_list_body: + string + { script_add_extern(closure, $1.value, $1.length); } + | extern_name_list_body string + { script_add_extern(closure, $2.value, $2.length); } + | extern_name_list_body ',' string + { script_add_extern(closure, $3.value, $3.length); } + ; + /* A list of input file names. */ input_list: input_list_element -- cgit v1.1