[lld] 28045ce - [ELF] Support (TYPE=<value>) beside output section address
Fangrui Song via llvm-commits
llvm-commits at lists.llvm.org
Sat Jul 20 14:13:06 PDT 2024
Author: Fangrui Song
Date: 2024-07-20T14:13:02-07:00
New Revision: 28045ceab08d41a8a42d93ebc445e8fe906f884c
URL: https://github.com/llvm/llvm-project/commit/28045ceab08d41a8a42d93ebc445e8fe906f884c
DIFF: https://github.com/llvm/llvm-project/commit/28045ceab08d41a8a42d93ebc445e8fe906f884c.diff
LOG: [ELF] Support (TYPE=<value>) beside output section address
Support `preinit_array . (TYPE=SHT_PREINIT_ARRAY) : { QUAD(16) }`
Follow-up to https://reviews.llvm.org/D118840
peek2() could be eliminated by a future change.
Added:
Modified:
lld/ELF/ScriptParser.cpp
lld/test/ELF/linkerscript/custom-section-type.s
Removed:
################################################################################
diff --git a/lld/ELF/ScriptParser.cpp b/lld/ELF/ScriptParser.cpp
index 47a94c29ea496..92f4bb41cd68f 100644
--- a/lld/ELF/ScriptParser.cpp
+++ b/lld/ELF/ScriptParser.cpp
@@ -92,7 +92,7 @@ class ScriptParser final : ScriptLexer {
SymbolAssignment *readSymbolAssignment(StringRef name);
ByteCommand *readByteCommand(StringRef tok);
std::array<uint8_t, 4> readFill();
- bool readSectionDirective(OutputSection *cmd, StringRef tok1, StringRef tok2);
+ bool readSectionDirective(OutputSection *cmd, StringRef tok2);
void readSectionAddressType(OutputSection *cmd);
OutputDesc *readOverlaySectionDescription();
OutputDesc *readOutputSectionDescription(StringRef outSec);
@@ -875,9 +875,7 @@ constexpr std::pair<const char *, unsigned> typeMap[] = {
// "(TYPE=<value>)".
// Tok1 and Tok2 are next 2 tokens peeked. See comment for
// readSectionAddressType below.
-bool ScriptParser::readSectionDirective(OutputSection *cmd, StringRef tok1, StringRef tok2) {
- if (tok1 != "(")
- return false;
+bool ScriptParser::readSectionDirective(OutputSection *cmd, StringRef tok2) {
if (tok2 != "NOLOAD" && tok2 != "COPY" && tok2 != "INFO" &&
tok2 != "OVERLAY" && tok2 != "TYPE")
return false;
@@ -921,16 +919,20 @@ bool ScriptParser::readSectionDirective(OutputSection *cmd, StringRef tok1, Stri
// https://sourceware.org/binutils/docs/ld/Output-Section-Address.html
// https://sourceware.org/binutils/docs/ld/Output-Section-Type.html
void ScriptParser::readSectionAddressType(OutputSection *cmd) {
- // Temporarily set inExpr to support TYPE=<value> without spaces.
- bool saved = std::exchange(inExpr, true);
- bool isDirective = readSectionDirective(cmd, peek(), peek2());
- inExpr = saved;
- if (isDirective)
- return;
-
+ if (peek() == "(") {
+ // Temporarily set inExpr to support TYPE=<value> without spaces.
+ SaveAndRestore saved(inExpr, true);
+ if (readSectionDirective(cmd, peek2()))
+ return;
+ }
cmd->addrExpr = readExpr();
- if (peek() == "(" && !readSectionDirective(cmd, "(", peek2()))
- setError("unknown section directive: " + peek2());
+
+ if (peek() == "(") {
+ SaveAndRestore saved(inExpr, true);
+ StringRef tok2 = peek2();
+ if (!readSectionDirective(cmd, tok2))
+ setError("unknown section directive: " + tok2);
+ }
}
static Expr checkAlignment(Expr e, std::string &loc) {
diff --git a/lld/test/ELF/linkerscript/custom-section-type.s b/lld/test/ELF/linkerscript/custom-section-type.s
index 8ca0a4db325bd..2add3a52f8117 100644
--- a/lld/test/ELF/linkerscript/custom-section-type.s
+++ b/lld/test/ELF/linkerscript/custom-section-type.s
@@ -67,7 +67,7 @@ SECTIONS {
nobits ( TYPE=SHT_NOBITS) : { BYTE(8) }
init_array (TYPE=SHT_INIT_ARRAY ) : { QUAD(myinit) }
fini_array (TYPE=SHT_FINI_ARRAY) : { QUAD(15) }
- preinit_array (TYPE=SHT_PREINIT_ARRAY) : { QUAD(16) }
+ preinit_array . (TYPE=SHT_PREINIT_ARRAY) : { QUAD(16) }
group (TYPE=17) : { LONG(17) }
expr (TYPE=0x41+1) : { BYTE(0x42) *(expr) }
}
More information about the llvm-commits
mailing list