From 4ffb22ec4040030ea36829c74076f35b3ca0872a Mon Sep 17 00:00:00 2001 From: Alan Modra Date: Sat, 14 Aug 2021 09:32:35 +0930 Subject: [PATCH] ld script fill pattern expression 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 | 22 ++++++++++++++++++++++ ld/testsuite/ld-elf/overlay.t | 8 +++++--- 2 files changed, 27 insertions(+), 3 deletions(-) diff --git a/ld/ldgram.y b/ld/ldgram.y index 1f6c44a073c..a0c881e9a73 100644 --- a/ld/ldgram.y +++ b/ld/ldgram.y @@ -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 diff --git a/ld/testsuite/ld-elf/overlay.t b/ld/testsuite/ld-elf/overlay.t index 2c50a6b1a48..640af9650fb 100644 --- a/ld/testsuite/ld-elf/overlay.t +++ b/ld/testsuite/ld-elf/overlay.t @@ -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") -- 2.30.2