[lld] [ELF] OUTPUT_FORMAT: support "binary" and ignore extra OUTPUT_FORMAT commands (PR #98837)
Fangrui Song via llvm-commits
llvm-commits at lists.llvm.org
Sun Jul 14 14:26:09 PDT 2024
https://github.com/MaskRay created https://github.com/llvm/llvm-project/pull/98837
This patch improves GNU ld compatibility.
Close #87891: Support `OUTPUT_FORMAT(binary)`, which is like
--oformat=binary. --oformat=binary takes precedence over an ELF
`OUTPUT_FORMAT`.
In addition, if more than one OUTPUT_FORMAT command is specified, only
check the first one.
>From 31c2dbfe857aa69e6f80a7bfac880e1fc97dcd38 Mon Sep 17 00:00:00 2001
From: Fangrui Song <i at maskray.me>
Date: Sun, 14 Jul 2024 14:25:59 -0700
Subject: [PATCH] =?UTF-8?q?[=F0=9D=98=80=F0=9D=97=BD=F0=9D=97=BF]=20initia?=
=?UTF-8?q?l=20version?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Created using spr 1.3.5-bogner
---
lld/ELF/ScriptParser.cpp | 22 +++++++++++++++-------
lld/test/ELF/invalid-linkerscript.test | 4 ++++
lld/test/ELF/oformat-binary.s | 17 +++++++++++++++--
3 files changed, 34 insertions(+), 9 deletions(-)
diff --git a/lld/ELF/ScriptParser.cpp b/lld/ELF/ScriptParser.cpp
index 41bd9a95053f7..649e2d0e29c22 100644
--- a/lld/ELF/ScriptParser.cpp
+++ b/lld/ELF/ScriptParser.cpp
@@ -461,20 +461,28 @@ static std::pair<ELFKind, uint16_t> parseBfdName(StringRef s) {
void ScriptParser::readOutputFormat() {
expect("(");
- StringRef s;
- config->bfdname = unquote(next());
+ StringRef s = unquote(next());
if (!consume(")")) {
expect(",");
- s = unquote(next());
+ StringRef tmp = unquote(next());
if (config->optEB)
- config->bfdname = s;
+ s = tmp;
expect(",");
- s = unquote(next());
+ tmp = unquote(next());
if (config->optEL)
- config->bfdname = s;
+ s = tmp;
consume(")");
}
- s = config->bfdname;
+ // If more than one OUTPUT_FORMAT is specified, only the first is checked.
+ if (!config->bfdname.empty())
+ return;
+ config->bfdname = s;
+
+ if (s == "binary") {
+ config->oFormatBinary = true;
+ return;
+ }
+
if (s.consume_back("-freebsd"))
config->osabi = ELFOSABI_FREEBSD;
diff --git a/lld/test/ELF/invalid-linkerscript.test b/lld/test/ELF/invalid-linkerscript.test
index c8770bd6aa720..4cbedf639cb1a 100644
--- a/lld/test/ELF/invalid-linkerscript.test
+++ b/lld/test/ELF/invalid-linkerscript.test
@@ -58,3 +58,7 @@
# RUN: not ld.lld %t9 no-such-file 2>&1 | FileCheck -check-prefix=ERR9 %s
# ERR9: , expected, but got y
# ERR9: cannot open no-such-file:
+
+# RUN: echo 'OUTPUT_FORMAT("")' > %t10
+# RUN: not ld.lld %t10 2>&1 | FileCheck -check-prefix=ERR10 %s
+# ERR10: error: {{.*}}:1: unknown output format name:
diff --git a/lld/test/ELF/oformat-binary.s b/lld/test/ELF/oformat-binary.s
index 38af6805140fc..a3780a68b24e1 100644
--- a/lld/test/ELF/oformat-binary.s
+++ b/lld/test/ELF/oformat-binary.s
@@ -6,8 +6,17 @@
# CHECK: 0000000 90 11 22
# CHECK-NEXT: 0000003
-## Check case when linkerscript is used.
-# RUN: echo "SECTIONS { . = 0x1000; }" > %t.script
+## OUTPUT_FORMAT(binary) selects the binary format as well.
+# RUN: echo "OUTPUT_FORMAT(binary)" > %t.script
+# RUN: ld.lld -o %t2.out -T %t.script %t
+# RUN: od -t x1 -v %t2.out | FileCheck %s
+## More OUTPUT_FORMAT commands are ignored.
+# RUN: echo "OUTPUT_FORMAT("binary")OUTPUT_FORMAT(elf64-x86-64)" > %t.script
+# RUN: ld.lld -o %t2.out -T %t.script %t
+# RUN: od -t x1 -v %t2.out | FileCheck %s
+
+## --oformat=binary overrides an ELF OUTPUT_FORMAT.
+# RUN: echo "OUTPUT_FORMAT(elf64-x86-64) SECTIONS { . = 0x1000; }" > %t.script
# RUN: ld.lld -o %t2.out --script %t.script %t --oformat binary
# RUN: od -t x1 -v %t2.out | FileCheck %s
@@ -45,6 +54,10 @@
# RUN: | FileCheck %s --check-prefix ERR
# ERR: unknown --oformat value: foo
+# RUN: echo "OUTPUT_FORMAT(binary-freebsd)" > %t.script
+# RUN: not ld.lld -T %t.script %t -o /dev/null 2>&1 | FileCheck %s --check-prefix=ERR2
+# ERR2: error: {{.*}}.script:1: unknown output format name: binary-freebsd
+
# RUN: ld.lld -o /dev/null %t --oformat elf
# RUN: ld.lld -o /dev/null %t --oformat=elf-foo
More information about the llvm-commits
mailing list