Re: ld script expression parsing
authorAlan Modra <amodra@gmail.com>
Thu, 22 Jul 2021 12:11:15 +0000 (21:41 +0930)
committerAlan Modra <amodra@gmail.com>
Sat, 24 Jul 2021 08:05:59 +0000 (17:35 +0930)
Commit 40726f16a8d7 broke references to sections within ADDR(), and
overlays with weird section names.

* ldgram.y (paren_script_name): New rule.
(exp): Use it for ALIGNOF, SIZEOF, ADDR, and LOADADDR.  Similarly
ensure script mode parsing for section name in SEGMENT_START.
(overlay_section): Delete unnecessary ldlex_script call.  Backup
on a lookahead NAME parsed in expression mode.
* testsuite/ld-elf/overlay.s: Add more sections.
* testsuite/ld-elf/overlay.t: Test '-' in section names.

ld/ldgram.y
ld/testsuite/ld-elf/overlay.s
ld/testsuite/ld-elf/overlay.t

index 31e0071c6fc92ad4988b3b913fad6e1e241871ed..2f9de59321a01383efe7e8680f66d71e2a12e31d 100644 (file)
@@ -96,8 +96,7 @@ static int error_index;
 %type <wildcard_list> section_name_list
 %type <flag_info_list> sect_flag_list
 %type <flag_info> sect_flags
-%type <name> memspec_opt casesymlist
-%type <name> memspec_at_opt
+%type <name> memspec_opt memspec_at_opt paren_script_name casesymlist
 %type <cname> wildcard_name
 %type <wildcard> section_name_spec filename_spec wildcard_maybe_exclude
 %token <bigint> INT
@@ -906,6 +905,10 @@ nocrossref_list:
                }
        ;
 
+paren_script_name:
+               { ldlex_script (); } '(' NAME  { ldlex_popstate (); } ')'
+                       { $$ = $3; }
+
 mustbe_exp:             { ldlex_expression (); }
                exp
                         { ldlex_popstate (); $$=$2;}
@@ -970,14 +973,14 @@ exp       :
        |       SIZEOF_HEADERS
                        { $$ = exp_nameop (SIZEOF_HEADERS,0); }
 
-       |       ALIGNOF '(' NAME ')'
-                       { $$ = exp_nameop (ALIGNOF,$3); }
-       |       SIZEOF '(' NAME ')'
-                       { $$ = exp_nameop (SIZEOF,$3); }
-       |       ADDR '(' NAME ')'
-                       { $$ = exp_nameop (ADDR,$3); }
-       |       LOADADDR '(' NAME ')'
-                       { $$ = exp_nameop (LOADADDR,$3); }
+       |       ALIGNOF paren_script_name
+                       { $$ = exp_nameop (ALIGNOF, $2); }
+       |       SIZEOF  paren_script_name
+                       { $$ = exp_nameop (SIZEOF, $2); }
+       |       ADDR    paren_script_name
+                       { $$ = exp_nameop (ADDR, $2); }
+       |       LOADADDR paren_script_name
+                       { $$ = exp_nameop (LOADADDR, $2); }
        |       CONSTANT '(' NAME ')'
                        { $$ = exp_nameop (CONSTANT,$3); }
        |       ABSOLUTE '(' exp ')'
@@ -992,15 +995,16 @@ exp       :
                        { $$ = exp_binop (DATA_SEGMENT_RELRO_END, $5, $3); }
        |       DATA_SEGMENT_END '(' exp ')'
                        { $$ = exp_unop (DATA_SEGMENT_END, $3); }
-       |       SEGMENT_START '(' NAME ',' exp ')'
+       |       SEGMENT_START { ldlex_script (); } '(' NAME
+                       { ldlex_popstate (); } ',' exp ')'
                        { /* The operands to the expression node are
                             placed in the opposite order from the way
                             in which they appear in the script as
                             that allows us to reuse more code in
                             fold_binary.  */
                          $$ = exp_binop (SEGMENT_START,
-                                         $5,
-                                         exp_nameop (NAME, $3)); }
+                                         $7,
+                                         exp_nameop (NAME, $4)); }
        |       BLOCK '(' exp ')'
                        { $$ = exp_unop (ALIGN_K,$3); }
        |       NAME
@@ -1186,13 +1190,17 @@ overlay_section:
        |       overlay_section
                NAME
                        {
-                         ldlex_script ();
                          lang_enter_overlay_section ($2);
                        }
                '{' statement_list_opt '}'
-                       { ldlex_popstate (); ldlex_expression (); }
+                       { ldlex_expression (); }
                phdr_opt fill_opt
                        {
+                         if (yychar == NAME)
+                           {
+                             yyclearin;
+                             ldlex_backup ();
+                           }
                          ldlex_popstate ();
                          lang_leave_overlay_section ($9, $8);
                        }
index f153044e31b6639e431444fa55adb4a21e4d8bc9..20d8f4154dc59d9664e74abe70f18967f1c6ca8c 100644 (file)
@@ -2,5 +2,9 @@
        .space 0x10
        .section .text2,"ax",%progbits
        .space 0x20
+       .section .silly-name1,"ax",%progbits
+       .space 0x10
+       .section .silly-name2,"ax",%progbits
+       .space 0x20
        .text
        .space 0x30
index dd374bb68b8211e885724207675f6b11077accc5..2c50a6b1a482c9319a22a9a5645454f5e1cb30c9 100644 (file)
@@ -6,6 +6,10 @@ SECTIONS
   {
     .text1 {*(.text1)}
     .text2 {*(.text2)}
-  } 
+    .silly-name1 { *(.silly-name1) }
+    .silly-name2 { *(.silly-name2) }
+  }
   /DISCARD/ : { *(.*) }
+  ASSERT(ADDR(.text1)==ADDR(.text2), "overlay error")
+  ASSERT(ADDR(.silly-name1)==ADDR(.silly-name2), "silly overlay error")
 }