Skip to content

Commit 3853a98

Browse files
MaskRayyuxuanchen1997
authored andcommitted
[ELF] OUTPUT_FORMAT: support "binary" and ignore extra OUTPUT_FORMAT commands
Summary: 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. Pull Request: #98837 Test Plan: Reviewers: Subscribers: Tasks: Tags: Differential Revision: https://phabricator.intern.facebook.com/D60251671
1 parent 15915a2 commit 3853a98

File tree

4 files changed

+36
-9
lines changed

4 files changed

+36
-9
lines changed

lld/ELF/ScriptParser.cpp

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -461,20 +461,28 @@ static std::pair<ELFKind, uint16_t> parseBfdName(StringRef s) {
461461
void ScriptParser::readOutputFormat() {
462462
expect("(");
463463

464-
StringRef s;
465-
config->bfdname = unquote(next());
464+
StringRef s = unquote(next());
466465
if (!consume(")")) {
467466
expect(",");
468-
s = unquote(next());
467+
StringRef tmp = unquote(next());
469468
if (config->optEB)
470-
config->bfdname = s;
469+
s = tmp;
471470
expect(",");
472-
s = unquote(next());
471+
tmp = unquote(next());
473472
if (config->optEL)
474-
config->bfdname = s;
473+
s = tmp;
475474
consume(")");
476475
}
477-
s = config->bfdname;
476+
// If more than one OUTPUT_FORMAT is specified, only the first is checked.
477+
if (!config->bfdname.empty())
478+
return;
479+
config->bfdname = s;
480+
481+
if (s == "binary") {
482+
config->oFormatBinary = true;
483+
return;
484+
}
485+
478486
if (s.consume_back("-freebsd"))
479487
config->osabi = ELFOSABI_FREEBSD;
480488

lld/docs/ReleaseNotes.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,8 @@ ELF Improvements
7979
* ``PROVIDE(lhs = rhs) PROVIDE(rhs = ...)``, ``lhs`` is now defined only if ``rhs`` is needed.
8080
(`#74771 <https://github.com/llvm/llvm-project/issues/74771>`_)
8181
(`#87530 <https://github.com/llvm/llvm-project/pull/87530>`_)
82+
* ``OUTPUT_FORMAT(binary)`` is now supported.
83+
(`#98837 <https://github.com/llvm/llvm-project/pull/98837>`_)
8284
* Orphan placement is refined to prefer the last similar section when its rank <= orphan's rank.
8385
(`#94099 <https://github.com/llvm/llvm-project/pull/94099>`_)
8486
Non-alloc orphan sections are now placed at the end.

lld/test/ELF/invalid-linkerscript.test

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,3 +58,7 @@
5858
# RUN: not ld.lld %t9 no-such-file 2>&1 | FileCheck -check-prefix=ERR9 %s
5959
# ERR9: , expected, but got y
6060
# ERR9: cannot open no-such-file:
61+
62+
# RUN: echo 'OUTPUT_FORMAT("")' > %t10
63+
# RUN: not ld.lld %t10 2>&1 | FileCheck -check-prefix=ERR10 %s
64+
# ERR10: error: {{.*}}:1: unknown output format name:

lld/test/ELF/oformat-binary.s

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,17 @@
66
# CHECK: 0000000 90 11 22
77
# CHECK-NEXT: 0000003
88

9-
## Check case when linkerscript is used.
10-
# RUN: echo "SECTIONS { . = 0x1000; }" > %t.script
9+
## OUTPUT_FORMAT(binary) selects the binary format as well.
10+
# RUN: echo "OUTPUT_FORMAT(binary)" > %t.script
11+
# RUN: ld.lld -o %t2.out -T %t.script %t
12+
# RUN: od -t x1 -v %t2.out | FileCheck %s
13+
## More OUTPUT_FORMAT commands are ignored.
14+
# RUN: echo "OUTPUT_FORMAT("binary")OUTPUT_FORMAT(elf64-x86-64)" > %t.script
15+
# RUN: ld.lld -o %t2.out -T %t.script %t
16+
# RUN: od -t x1 -v %t2.out | FileCheck %s
17+
18+
## --oformat=binary overrides an ELF OUTPUT_FORMAT.
19+
# RUN: echo "OUTPUT_FORMAT(elf64-x86-64) SECTIONS { . = 0x1000; }" > %t.script
1120
# RUN: ld.lld -o %t2.out --script %t.script %t --oformat binary
1221
# RUN: od -t x1 -v %t2.out | FileCheck %s
1322

@@ -45,6 +54,10 @@
4554
# RUN: | FileCheck %s --check-prefix ERR
4655
# ERR: unknown --oformat value: foo
4756

57+
# RUN: echo "OUTPUT_FORMAT(binary-freebsd)" > %t.script
58+
# RUN: not ld.lld -T %t.script %t -o /dev/null 2>&1 | FileCheck %s --check-prefix=ERR2
59+
# ERR2: error: {{.*}}.script:1: unknown output format name: binary-freebsd
60+
4861
# RUN: ld.lld -o /dev/null %t --oformat elf
4962
# RUN: ld.lld -o /dev/null %t --oformat=elf-foo
5063

0 commit comments

Comments
 (0)