* yyscript.y (file_cmd): Recognize EXTERN.
authorIan Lance Taylor <ian@airs.com>
Tue, 24 Mar 2009 19:08:37 +0000 (19:08 +0000)
committerIan Lance Taylor <ian@airs.com>
Tue, 24 Mar 2009 19:08:37 +0000 (19:08 +0000)
(extern_name_list, extern_name_list_body): New nonterminals.
* script.cc (script_add_extern): Define.
* script-c.h (script_add_extern): Declare.

gold/ChangeLog
gold/script-c.h
gold/script.cc
gold/yyscript.y

index d380aa1..b51509a 100644 (file)
@@ -1,3 +1,10 @@
+2009-03-24  Ian Lance Taylor  <iant@google.com>
+
+       * 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  <espindola@google.com>
 
        * object.cc (is_elf_object): Define.
index 13c789a..3da634f 100644 (file)
@@ -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
index 44e43f7..30b4e3c 100644 (file)
@@ -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
index b018005..34b8b55 100644 (file)
@@ -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