From: Hans-Peter Nilsson Date: Wed, 15 Oct 2014 01:10:25 +0000 (+0200) Subject: Allow unquoted = as the first character in ldscript input_list names X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=eeed9cc785ca447868967e5c84dae63e9ca8e6c2;p=binutils-gdb.git Allow unquoted = as the first character in ldscript input_list names * ldlex.l (INPUTLIST): New start condition. (comment pattern, ",", "(", ")", "AS_NEEDED") ({FILENAMECHAR1}{FILENAMECHAR}*, "-l"{FILENAMECHAR}+) (quoted string pattern, whitespace pattern): Add INPUTLIST to valid start conditions. ("="{FILENAMECHAR1}{FILENAMECHAR}*): New NAME rule. (ldlex_inputlist): New start-condition-setter function. * ldgram.y (input_list1): Rename from input_list. All recursive use changed. (input_list): New wrapper rule for input_list1, setting INPUTLIST lexer state for the duration of parsing input_list1. All this to say INPUT(=/path/to/file) and not be forced to use INPUT("=/path/to/file") whenever there's a need to force a sysroot- prefix. Still, IMHO it seems better to make use of a previously invalid syntax and not only change the meaning of quoted =-prefixed paths (though arguably that's not very useful before this patchset). This got a little bit hairier than I'd expected: I had to add a new lexer state (aka. start condition) to avoid a first "=" being lexed as the token "=", despite that not making sense in constructs expecting file-names in the first place. (The grammar doesn't allow for expressions in any part of those lists.) I guess I *could* have made it work using that token anyway, but I didn't like the idea that you would be able to separate the "=" from the rest of the file-name with whitespace. --- diff --git a/ld/ChangeLog b/ld/ChangeLog index 49a0a669280..6a91a25942c 100644 --- a/ld/ChangeLog +++ b/ld/ChangeLog @@ -1,5 +1,16 @@ 2014-10-15 Hans-Peter Nilsson + * ldlex.l (INPUTLIST): New start condition. + (comment pattern, ",", "(", ")", "AS_NEEDED") + ({FILENAMECHAR1}{FILENAMECHAR}*, "-l"{FILENAMECHAR}+) + (quoted string pattern, whitespace pattern): Add INPUTLIST to + valid start conditions. + ("="{FILENAMECHAR1}{FILENAMECHAR}*): New NAME rule. + (ldlex_inputlist): New start-condition-setter function. + * ldgram.y (input_list1): Rename from input_list. All recursive + use changed. + (input_list): New wrapper rule for input_list1, setting + INPUTLIST lexer state for the duration of parsing input_list1. * ldlang.c (lang_add_input_file): If the first character in the filename is '=', prepend the sysroot and force the context of that input file to non-sysroot. diff --git a/ld/ldgram.y b/ld/ldgram.y index 4875fa7eb79..e76a0a3079f 100644 --- a/ld/ldgram.y +++ b/ld/ldgram.y @@ -365,38 +365,43 @@ ifile_p1: ; input_list: + { ldlex_inputlist(); } + input_list1 + { ldlex_popstate(); } + +input_list1: NAME { lang_add_input_file($1,lang_input_file_is_search_file_enum, (char *)NULL); } - | input_list ',' NAME + | input_list1 ',' NAME { lang_add_input_file($3,lang_input_file_is_search_file_enum, (char *)NULL); } - | input_list NAME + | input_list1 NAME { lang_add_input_file($2,lang_input_file_is_search_file_enum, (char *)NULL); } | LNAME { lang_add_input_file($1,lang_input_file_is_l_enum, (char *)NULL); } - | input_list ',' LNAME + | input_list1 ',' LNAME { lang_add_input_file($3,lang_input_file_is_l_enum, (char *)NULL); } - | input_list LNAME + | input_list1 LNAME { lang_add_input_file($2,lang_input_file_is_l_enum, (char *)NULL); } | AS_NEEDED '(' { $$ = input_flags.add_DT_NEEDED_for_regular; input_flags.add_DT_NEEDED_for_regular = TRUE; } - input_list ')' + input_list1 ')' { input_flags.add_DT_NEEDED_for_regular = $3; } - | input_list ',' AS_NEEDED '(' + | input_list1 ',' AS_NEEDED '(' { $$ = input_flags.add_DT_NEEDED_for_regular; input_flags.add_DT_NEEDED_for_regular = TRUE; } - input_list ')' + input_list1 ')' { input_flags.add_DT_NEEDED_for_regular = $5; } - | input_list AS_NEEDED '(' + | input_list1 AS_NEEDED '(' { $$ = input_flags.add_DT_NEEDED_for_regular; input_flags.add_DT_NEEDED_for_regular = TRUE; } - input_list ')' + input_list1 ')' { input_flags.add_DT_NEEDED_for_regular = $4; } ; diff --git a/ld/ldlex.h b/ld/ldlex.h index 63f4c816023..56cd12162af 100644 --- a/ld/ldlex.h +++ b/ld/ldlex.h @@ -161,6 +161,7 @@ extern int yylex (void); extern void lex_push_file (FILE *, const char *, unsigned int); extern void lex_redirect (const char *, const char *, unsigned int); extern void ldlex_script (void); +extern void ldlex_inputlist (void); extern void ldlex_mri_script (void); extern void ldlex_version_script (void); extern void ldlex_version_file (void); diff --git a/ld/ldlex.l b/ld/ldlex.l index 234867c2ad0..d1621289d6e 100644 --- a/ld/ldlex.l +++ b/ld/ldlex.l @@ -77,6 +77,7 @@ static void lex_warn_invalid (char *where, char *what); /* STATES EXPRESSION definitely in an expression SCRIPT definitely in a script + INPUTLIST definitely in a script, a filename-list BOTH either EXPRESSION or SCRIPT DEFSYMEXP in an argument to -defsym MRI in an MRI script @@ -109,6 +110,7 @@ V_TAG [.$_a-zA-Z][._a-zA-Z0-9]* V_IDENTIFIER [*?.$_a-zA-Z\[\]\-\!\^\\]([*?.$_a-zA-Z0-9\[\]\-\!\^\\]|::)* %s SCRIPT +%s INPUTLIST %s EXPRESSION %s BOTH %s DEFSYMEXP @@ -134,7 +136,7 @@ V_IDENTIFIER [*?.$_a-zA-Z\[\]\-\!\^\\]([*?.$_a-zA-Z0-9\[\]\-\!\^\\]|::)* } } -"/*" { comment (); } +"/*" { comment (); } "-" { RTOKEN('-');} @@ -221,7 +223,7 @@ V_IDENTIFIER [*?.$_a-zA-Z\[\]\-\!\^\\]([*?.$_a-zA-Z0-9\[\]\-\!\^\\]|::)* "|=" { RTOKEN(OREQ);} "&&" { RTOKEN(ANDAND);} ">" { RTOKEN('>');} -"," { RTOKEN(',');} +"," { RTOKEN(',');} "&" { RTOKEN('&');} "|" { RTOKEN('|');} "~" { RTOKEN('~');} @@ -236,8 +238,8 @@ V_IDENTIFIER [*?.$_a-zA-Z\[\]\-\!\^\\]([*?.$_a-zA-Z0-9\[\]\-\!\^\\]|::)* "=" { RTOKEN('=');} "}" { RTOKEN('}') ; } "{" { RTOKEN('{'); } -")" { RTOKEN(')');} -"(" { RTOKEN('(');} +")" { RTOKEN(')');} +"(" { RTOKEN('(');} ":" { RTOKEN(':'); } ";" { RTOKEN(';');} "MEMORY" { RTOKEN(MEMORY);} @@ -272,7 +274,7 @@ V_IDENTIFIER [*?.$_a-zA-Z\[\]\-\!\^\\]([*?.$_a-zA-Z0-9\[\]\-\!\^\\]|::)* "OUTPUT" { RTOKEN(OUTPUT);} "INPUT" { RTOKEN(INPUT);} "GROUP" { RTOKEN(GROUP);} -"AS_NEEDED" { RTOKEN(AS_NEEDED);} +"AS_NEEDED" { RTOKEN(AS_NEEDED);} "DEFINED" { RTOKEN(DEFINED);} "CREATE_OBJECT_SYMBOLS" { RTOKEN(CREATE_OBJECT_SYMBOLS);} "CONSTRUCTORS" { RTOKEN( CONSTRUCTORS);} @@ -373,11 +375,16 @@ V_IDENTIFIER [*?.$_a-zA-Z\[\]\-\!\^\\]([*?.$_a-zA-Z0-9\[\]\-\!\^\\]|::)* } -{FILENAMECHAR1}{FILENAMECHAR}* { +{FILENAMECHAR1}{FILENAMECHAR}* { yylval.name = xstrdup (yytext); return NAME; } -"-l"{FILENAMECHAR}+ { +"="{FILENAMECHAR1}{FILENAMECHAR}* { +/* Filename to be prefixed by --sysroot or when non-sysrooted, nothing. */ + yylval.name = xstrdup (yytext); + return NAME; + } +"-l"{FILENAMECHAR}+ { yylval.name = xstrdup (yytext + 2); return LNAME; } @@ -406,7 +413,7 @@ V_IDENTIFIER [*?.$_a-zA-Z\[\]\-\!\^\\]([*?.$_a-zA-Z0-9\[\]\-\!\^\\]|::)* } } -"\""[^\"]*"\"" { +"\""[^\"]*"\"" { /* No matter the state, quotes give what's inside */ yylval.name = xstrdup (yytext + 1); @@ -447,7 +454,7 @@ V_IDENTIFIER [*?.$_a-zA-Z\[\]\-\!\^\\]([*?.$_a-zA-Z0-9\[\]\-\!\^\\]|::)* #.* { /* Eat up comments */ } -[ \t\r]+ { /* Eat up whitespace */ } +[ \t\r]+ { /* Eat up whitespace */ } <> { include_stack_ptr--; @@ -565,6 +572,13 @@ ldlex_script (void) BEGIN (SCRIPT); } +void +ldlex_inputlist (void) +{ + *(state_stack_p)++ = yy_start; + BEGIN (INPUTLIST); +} + void ldlex_mri_script (void) {