[lld] 6464dd2 - [ELF] OUTPUT_FORMAT: support "binary" and ignore extra OUTPUT_FORMAT commands

via llvm-commits llvm-commits at lists.llvm.org
Tue Jul 16 10:28:13 PDT 2024


Author: Fangrui Song
Date: 2024-07-16T10:28:09-07:00
New Revision: 6464dd21b50bb5f22a5beae1377fec501b38e764

URL: https://github.com/llvm/llvm-project/commit/6464dd21b50bb5f22a5beae1377fec501b38e764
DIFF: https://github.com/llvm/llvm-project/commit/6464dd21b50bb5f22a5beae1377fec501b38e764.diff

LOG: [ELF] OUTPUT_FORMAT: support "binary" and ignore extra OUTPUT_FORMAT commands

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: https://github.com/llvm/llvm-project/pull/98837

Added: 
    

Modified: 
    lld/ELF/ScriptParser.cpp
    lld/docs/ReleaseNotes.rst
    lld/test/ELF/invalid-linkerscript.test
    lld/test/ELF/oformat-binary.s

Removed: 
    


################################################################################
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/docs/ReleaseNotes.rst b/lld/docs/ReleaseNotes.rst
index c95170c1165b2..05179bfdcb536 100644
--- a/lld/docs/ReleaseNotes.rst
+++ b/lld/docs/ReleaseNotes.rst
@@ -79,6 +79,8 @@ ELF Improvements
 * ``PROVIDE(lhs = rhs) PROVIDE(rhs = ...)``, ``lhs`` is now defined only if ``rhs`` is needed.
   (`#74771 <https://github.com/llvm/llvm-project/issues/74771>`_)
   (`#87530 <https://github.com/llvm/llvm-project/pull/87530>`_)
+* ``OUTPUT_FORMAT(binary)`` is now supported.
+  (`#98837 <https://github.com/llvm/llvm-project/pull/98837>`_)
 * Orphan placement is refined to prefer the last similar section when its rank <= orphan's rank.
   (`#94099 <https://github.com/llvm/llvm-project/pull/94099>`_)
   Non-alloc orphan sections are now placed at the end.

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