[lld] eea34aa - [ELF] Inspect -EL & -EB for OUTPUT_FORMAT(default, big, little)
Fangrui Song via llvm-commits
llvm-commits at lists.llvm.org
Mon Feb 8 10:35:05 PST 2021
Author: Fangrui Song
Date: 2021-02-08T10:34:57-08:00
New Revision: eea34aae2e74e9b6fbdd5b95f479bc7f397bf387
URL: https://github.com/llvm/llvm-project/commit/eea34aae2e74e9b6fbdd5b95f479bc7f397bf387
DIFF: https://github.com/llvm/llvm-project/commit/eea34aae2e74e9b6fbdd5b95f479bc7f397bf387.diff
LOG: [ELF] Inspect -EL & -EB for OUTPUT_FORMAT(default, big, little)
Choose big if -EB is specified, little if -EL is specified, or default if neither is specified.
The new behavior matches GNU ld.
Fixes: https://github.com/ClangBuiltLinux/linux/issues/1025
Differential Revision: https://reviews.llvm.org/D96214
Added:
Modified:
lld/ELF/Config.h
lld/ELF/Driver.cpp
lld/ELF/Options.td
lld/ELF/ScriptParser.cpp
lld/docs/ld.lld.1
lld/test/ELF/emulation-aarch64.s
lld/test/ELF/invalid-linkerscript.test
Removed:
################################################################################
diff --git a/lld/ELF/Config.h b/lld/ELF/Config.h
index 7881dfe82c87..f80c6fbe4d5e 100644
--- a/lld/ELF/Config.h
+++ b/lld/ELF/Config.h
@@ -187,6 +187,8 @@ struct Configuration {
bool nostdlib;
bool oFormatBinary;
bool omagic;
+ bool optEB = false;
+ bool optEL = false;
bool optimizeBBJumps;
bool optRemarksWithHotness;
bool picThunk;
diff --git a/lld/ELF/Driver.cpp b/lld/ELF/Driver.cpp
index 09c2c17de9b2..fe722ebd4891 100644
--- a/lld/ELF/Driver.cpp
+++ b/lld/ELF/Driver.cpp
@@ -1125,6 +1125,13 @@ static void readConfigs(opt::InputArgList &args) {
config->zWxneeded = hasZOption(args, "wxneeded");
setUnresolvedSymbolPolicy(args);
+ if (opt::Arg *arg = args.getLastArg(OPT_eb, OPT_el)) {
+ if (arg->getOption().matches(OPT_eb))
+ config->optEB = true;
+ else
+ config->optEL = true;
+ }
+
for (opt::Arg *arg : args.filtered(OPT_z)) {
std::pair<StringRef, StringRef> option =
StringRef(arg->getValue()).split('=');
diff --git a/lld/ELF/Options.td b/lld/ELF/Options.td
index 65ef3e824f50..e1eccdbada33 100644
--- a/lld/ELF/Options.td
+++ b/lld/ELF/Options.td
@@ -159,6 +159,9 @@ defm dynamic_list : Eq<"dynamic-list",
"shared object. Implies -Bsymbolic but does not set DF_SYMBOLIC">,
MetaVarName<"<file>">;
+def eb: F<"EB">, HelpText<"Select the big-endian format in OUTPUT_FORMAT">;
+def el: F<"EL">, HelpText<"Select the little-endian format in OUTPUT_FORMAT">;
+
defm eh_frame_hdr: B<"eh-frame-hdr",
"Request creation of .eh_frame_hdr section and PT_GNU_EH_FRAME segment header",
"Do not create .eh_frame_hdr section">;
@@ -687,8 +690,6 @@ def: F<"stats">;
def: F<"warn-execstack">;
def: F<"warn-once">;
def: F<"warn-shared-textrel">;
-def: F<"EB">;
-def: F<"EL">;
def: JoinedOrSeparate<["-"], "G">;
def: F<"Qy">;
diff --git a/lld/ELF/ScriptParser.cpp b/lld/ELF/ScriptParser.cpp
index 3af63830f9c0..4b15a71f029b 100644
--- a/lld/ELF/ScriptParser.cpp
+++ b/lld/ELF/ScriptParser.cpp
@@ -431,13 +431,26 @@ static std::pair<ELFKind, uint16_t> parseBfdName(StringRef s) {
.Default({ELFNoneKind, EM_NONE});
}
-// Parse OUTPUT_FORMAT(bfdname) or OUTPUT_FORMAT(bfdname, big, little).
-// Currently we ignore big and little parameters.
+// Parse OUTPUT_FORMAT(bfdname) or OUTPUT_FORMAT(default, big, little). Choose
+// big if -EB is specified, little if -EL is specified, or default if neither is
+// specified.
void ScriptParser::readOutputFormat() {
expect("(");
+ StringRef s;
config->bfdname = unquote(next());
- StringRef s = config->bfdname;
+ if (!consume(")")) {
+ expect(",");
+ s = unquote(next());
+ if (config->optEB)
+ config->bfdname = s;
+ expect(",");
+ s = unquote(next());
+ if (config->optEL)
+ config->bfdname = s;
+ consume(")");
+ }
+ s = config->bfdname;
if (s.consume_back("-freebsd"))
config->osabi = ELFOSABI_FREEBSD;
@@ -448,14 +461,6 @@ void ScriptParser::readOutputFormat() {
config->mipsN32Abi = true;
if (config->emachine == EM_MSP430)
config->osabi = ELFOSABI_STANDALONE;
-
- if (consume(")"))
- return;
- expect(",");
- skip();
- expect(",");
- skip();
- expect(")");
}
void ScriptParser::readPhdrs() {
diff --git a/lld/docs/ld.lld.1 b/lld/docs/ld.lld.1
index 79a684def275..cd9052e678cc 100644
--- a/lld/docs/ld.lld.1
+++ b/lld/docs/ld.lld.1
@@ -161,6 +161,10 @@ Read a list of dynamic symbols from
(shared object) References to matched non-local STV_DEFAULT symbols shouldn't be bound to definitions within the shared object. Implies
.Cm -Bsymbolic
but does not set DF_SYMBOLIC
+.It Fl -EB
+Select the big-endian format in the OUTPUT_FORMAT command.
+.It Fl -EL
+Select the little-endian format in the OUTPUT_FORMAT command.
.It Fl -eh-frame-hdr
Request creation of
.Li .eh_frame_hdr
diff --git a/lld/test/ELF/emulation-aarch64.s b/lld/test/ELF/emulation-aarch64.s
index e5ba733a5b8f..2d26a1e8e64e 100644
--- a/lld/test/ELF/emulation-aarch64.s
+++ b/lld/test/ELF/emulation-aarch64.s
@@ -23,6 +23,20 @@
# RUN: ld.lld %t.script %t.be.o -o %t3.be
# RUN: llvm-readobj --file-headers %t3.be | FileCheck --check-prefixes=AARCH64,BE %s
+## Test OUTPUT_FORMAT(default, big, little).
+# RUN: echo 'OUTPUT_FORMAT("elf64-littleaarch64", "elf64-bigaarch64", "elf64-littleaarch64")' > %t.script
+# RUN: ld.lld -EL -T %t.script %t.o -o %t4.le
+# RUN: llvm-readobj --file-headers %t4.le | FileCheck --check-prefixes=AARCH64,LE %s
+# RUN: not ld.lld -EB -T %t.script %t.o -o /dev/null 2>&1 | FileCheck --check-prefix=ERR_BE %s
+
+# RUN: not ld.lld -T %t.script %t.be.o -o /dev/null 2>&1 | FileCheck --check-prefix=ERR_LE %s
+# RUN: not ld.lld -EL -T %t.script %t.be.o -o /dev/null 2>&1 | FileCheck --check-prefix=ERR_LE %s
+# RUN: ld.lld -EB -T %t.script %t.be.o -o %t4.be
+# RUN: llvm-readobj --file-headers %t4.be | FileCheck --check-prefixes=AARCH64,BE %s
+
+# ERR_LE: error: {{.*}}.o is incompatible with elf64-littleaarch64
+# ERR_BE: error: {{.*}}.o is incompatible with elf64-bigaarch64
+
# AARCH64: ElfHeader {
# AARCH64-NEXT: Ident {
# AARCH64-NEXT: Magic: (7F 45 4C 46)
diff --git a/lld/test/ELF/invalid-linkerscript.test b/lld/test/ELF/invalid-linkerscript.test
index e635ae4f2af9..c8770bd6aa72 100644
--- a/lld/test/ELF/invalid-linkerscript.test
+++ b/lld/test/ELF/invalid-linkerscript.test
@@ -51,7 +51,7 @@
# RUN: echo "OUTPUT_FORMAT(x y z)" > %t8
# RUN: not ld.lld %t8 no-such-file 2>&1 | FileCheck -check-prefix=ERR8 %s
# RUN: not ld.lld -m elf_amd64 %t8 no-such-file 2>&1 | FileCheck -check-prefix=ERR8 %s
-# ERR8: unknown output format name: x
+# ERR8: , expected, but got y
# ERR8: cannot open no-such-file:
# RUN: echo "OUTPUT_FORMAT(elf64-x86-64 y z)" > %t9
More information about the llvm-commits
mailing list