ld script fill pattern expression
authorAlan Modra <amodra@gmail.com>
Sat, 14 Aug 2021 00:02:35 +0000 (09:32 +0930)
committerAlan Modra <amodra@gmail.com>
Sat, 14 Aug 2021 00:24:48 +0000 (09:54 +0930)
It turns out we do need to backtrack when parsing after all.  The
fill_opt component in the section rule swiches to EXPRESSION and back
to SCRIPT, and to find the end of an expression it is necessary to
look ahead one token.

* ldgram.y (section): Throw away lookahead NAME token.
(overlay_section): Likewise.
* testsuite/ld-elf/overlay.t: Add fill pattern on overlays.
Test fill pattern before stupidly named normal sections too,
and before /DISCARD/.

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

index 1f6c44a073ca69692bca164f81c459579fb6a113..a0c881e9a736344d817bc9dd17d73b4e7990db48 100644 (file)
@@ -1063,6 +1063,18 @@ section: NAME
                        { ldlex_popstate (); }
                memspec_opt memspec_at_opt phdr_opt fill_opt
                        {
+                         /* fill_opt may have switched the lexer into
+                            expression state, and back again, but in
+                            order to find the end of the fill
+                            expression the parser must look ahead one
+                            token.  If it is a NAME, throw it away as
+                            it will have been lexed in the wrong
+                            state.  */
+                         if (yychar == NAME)
+                           {
+                             yyclearin;
+                             ldlex_backup ();
+                           }
                          lang_leave_output_section_statement ($17, $14,
                                                               $16, $15);
                        }
@@ -1079,6 +1091,11 @@ section: NAME
                '}'
                memspec_opt memspec_at_opt phdr_opt fill_opt
                        {
+                         if (yychar == NAME)
+                           {
+                             yyclearin;
+                             ldlex_backup ();
+                           }
                          lang_leave_overlay ($5, (int) $4,
                                              $15, $12, $14, $13);
                        }
@@ -1179,6 +1196,11 @@ overlay_section:
                        { ldlex_popstate (); }
                phdr_opt fill_opt
                        {
+                         if (yychar == NAME)
+                           {
+                             yyclearin;
+                             ldlex_backup ();
+                           }
                          lang_leave_overlay_section ($9, $8);
                        }
                opt_comma
index 2c50a6b1a482c9319a22a9a5645454f5e1cb30c9..640af9650fb609bd383ab2b00e22f37c11422e60 100644 (file)
@@ -6,9 +6,11 @@ SECTIONS
   {
     .text1 {*(.text1)}
     .text2 {*(.text2)}
-    .silly-name1 { *(.silly-name1) }
-    .silly-name2 { *(.silly-name2) }
-  }
+    .silly-name1 { *(.silly-name1) } = 0
+    .silly-name2 { *(.silly-name2) } = 0
+  } = 0
+  .silly-name3 : { *(.silly-name3) } = 0
+  .silly-name4 : { *(.silly-name4) } = 0
   /DISCARD/ : { *(.*) }
   ASSERT(ADDR(.text1)==ADDR(.text2), "overlay error")
   ASSERT(ADDR(.silly-name1)==ADDR(.silly-name2), "silly overlay error")