[lld] r344952 - Add OUTPUT_FORMAT linker script directive support.

Rui Ueyama via llvm-commits llvm-commits at lists.llvm.org
Mon Oct 22 13:50:01 PDT 2018


Author: ruiu
Date: Mon Oct 22 13:50:01 2018
New Revision: 344952

URL: http://llvm.org/viewvc/llvm-project?rev=344952&view=rev
Log:
Add OUTPUT_FORMAT linker script directive support.

This patch adds a support for OUTPUT_FORMAT linker script directive.
Since I'm not 100% confident with BFD names you can use in the directive
for all architectures, I added only a few in this patch. We can add
other names for other archtiectures later.

We still do not support triple-style OUTPUT_FORMAT directive, namely,
OUTPUT_FORMAT(bfdname, big, little). If you pass -EL (little endian)
or -EB (big endian) to the linker, GNU linkers pick up big or little
as a BFD name, correspondingly, so that you can use a single linker
script for bi-endian processor. I'm not sure if we really need to
support that, so I'll leave it alone for now.

Note that -m takes precedence over OUTPUT_FORAMT, but we always parse
a BFD name given to OUTPUT_FORMAT for error checking. You cannot write
an invalid name in the OUTPUT_FORMAT directive.

Differential Revision: https://reviews.llvm.org/D53495

Removed:
    lld/trunk/test/ELF/linkerscript/output-format.s
Modified:
    lld/trunk/ELF/ScriptParser.cpp
    lld/trunk/test/ELF/emulation.s
    lld/trunk/test/ELF/format-binary.test
    lld/trunk/test/ELF/invalid-linkerscript.test

Modified: lld/trunk/ELF/ScriptParser.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/ScriptParser.cpp?rev=344952&r1=344951&r2=344952&view=diff
==============================================================================
--- lld/trunk/ELF/ScriptParser.cpp (original)
+++ lld/trunk/ELF/ScriptParser.cpp Mon Oct 22 13:50:01 2018
@@ -94,6 +94,7 @@ private:
   SortSectionPolicy readSortKind();
   SymbolAssignment *readProvideHidden(bool Provide, bool Hidden);
   SymbolAssignment *readAssignment(StringRef Tok);
+  std::pair<ELFKind, uint16_t> readBfdName();
   void readSort();
   Expr readAssert();
   Expr readConstant();
@@ -382,10 +383,34 @@ void ScriptParser::readOutputArch() {
     skip();
 }
 
+std::pair<ELFKind, uint16_t> ScriptParser::readBfdName() {
+  StringRef S = next();
+  if (S == "elf32-i386")
+    return {ELF32LEKind, EM_386};
+  if (S == "elf32-iamcu")
+    return {ELF32LEKind, EM_IAMCU};
+  if (S == "elf32-x86-64")
+    return {ELF32LEKind, EM_X86_64};
+  if (S == "elf64-littleaarch64")
+    return {ELF64LEKind, EM_AARCH64};
+  if (S == "elf64-x86-64")
+    return {ELF64LEKind, EM_X86_64};
+
+  setError("unknown output format name: " + S);
+  return {ELFNoneKind, EM_NONE};
+}
+
+// Parse OUTPUT_FORMAT(bfdname) or OUTPUT_FORMAT(bfdname, big, little).
+// Currently we ignore big and little parameters.
 void ScriptParser::readOutputFormat() {
-  // Error checking only for now.
   expect("(");
-  skip();
+
+  std::pair<ELFKind, uint16_t> P = readBfdName();
+  if (Config->EKind == ELFNoneKind) {
+    Config->EKind = P.first;
+    Config->EMachine = P.second;
+  }
+
   if (consume(")"))
     return;
   expect(",");

Modified: lld/trunk/test/ELF/emulation.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/emulation.s?rev=344952&r1=344951&r2=344952&view=diff
==============================================================================
--- lld/trunk/test/ELF/emulation.s (original)
+++ lld/trunk/test/ELF/emulation.s Mon Oct 22 13:50:01 2018
@@ -38,6 +38,10 @@
 # RUN: llvm-readobj -file-headers %t2x64 | FileCheck --check-prefix=X86-64 %s
 # RUN: ld.lld %tx64 -o %t3x64
 # RUN: llvm-readobj -file-headers %t3x64 | FileCheck --check-prefix=X86-64 %s
+# RUN: echo 'OUTPUT_FORMAT(elf64-x86-64)' > %t4x64.script
+# RUN: ld.lld %t4x64.script %tx64 -o %t4x64
+# RUN: ld.lld %tx64 -o %t4x64 %t4x64.script
+# RUN: llvm-readobj -file-headers %t4x64 | FileCheck --check-prefix=X86-64 %s
 # X86-64:      ElfHeader {
 # X86-64-NEXT:   Ident {
 # X86-64-NEXT:     Magic: (7F 45 4C 46)
@@ -69,6 +73,9 @@
 # RUN: llvm-readobj -file-headers %t2x32 | FileCheck --check-prefix=X32 %s
 # RUN: ld.lld %tx32 -o %t3x32
 # RUN: llvm-readobj -file-headers %t3x32 | FileCheck --check-prefix=X32 %s
+# RUN: echo 'OUTPUT_FORMAT(elf32-x86-64)' > %t4x32.script
+# RUN: ld.lld %t4x32.script %tx32 -o %t4x32
+# RUN: llvm-readobj -file-headers %t4x32 | FileCheck --check-prefix=X32 %s
 # X32:      ElfHeader {
 # X32-NEXT:   Ident {
 # X32-NEXT:     Magic: (7F 45 4C 46)
@@ -100,6 +107,9 @@
 # RUN: llvm-readobj -file-headers %t2x86 | FileCheck --check-prefix=X86 %s
 # RUN: ld.lld %tx86 -o %t3x86
 # RUN: llvm-readobj -file-headers %t3x86 | FileCheck --check-prefix=X86 %s
+# RUN: echo 'OUTPUT_FORMAT(elf32-i386)' > %t4x86.script
+# RUN: ld.lld %t4x86.script %tx86 -o %t4x86
+# RUN: llvm-readobj -file-headers %t4x86 | FileCheck --check-prefix=X86 %s
 # X86:      ElfHeader {
 # X86-NEXT:   Ident {
 # X86-NEXT:     Magic: (7F 45 4C 46)
@@ -162,6 +172,9 @@
 # RUN: llvm-readobj -file-headers %t2iamcu | FileCheck --check-prefix=IAMCU %s
 # RUN: ld.lld %tiamcu -o %t3iamcu
 # RUN: llvm-readobj -file-headers %t3iamcu | FileCheck --check-prefix=IAMCU %s
+# RUN: echo 'OUTPUT_FORMAT(elf32-iamcu)' > %t4iamcu.script
+# RUN: ld.lld %t4iamcu.script %tiamcu -o %t4iamcu
+# RUN: llvm-readobj -file-headers %t4iamcu | FileCheck --check-prefix=IAMCU %s
 # IAMCU:      ElfHeader {
 # IAMCU-NEXT:   Ident {
 # IAMCU-NEXT:     Magic: (7F 45 4C 46)
@@ -373,6 +386,9 @@
 # RUN: llvm-readobj -file-headers %t4aarch64 | FileCheck --check-prefix=AARCH64 %s
 # RUN: ld.lld %taarch64 -o %t5aarch64
 # RUN: llvm-readobj -file-headers %t5aarch64 | FileCheck --check-prefix=AARCH64 %s
+# RUN: echo 'OUTPUT_FORMAT(elf64-littleaarch64)' > %t4aarch64.script
+# RUN: ld.lld %t4aarch64.script %taarch64 -o %t4aarch64
+# RUN: llvm-readobj -file-headers %t4aarch64 | FileCheck --check-prefix=AARCH64 %s
 # AARCH64:      ElfHeader {
 # AARCH64-NEXT:   Ident {
 # AARCH64-NEXT:     Magic: (7F 45 4C 46)

Modified: lld/trunk/test/ELF/format-binary.test
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/format-binary.test?rev=344952&r1=344951&r2=344952&view=diff
==============================================================================
--- lld/trunk/test/ELF/format-binary.test (original)
+++ lld/trunk/test/ELF/format-binary.test Mon Oct 22 13:50:01 2018
@@ -55,3 +55,9 @@
 # CHECK-NEXT:     Other: 0
 # CHECK-NEXT:     Section: Absolute
 # CHECK-NEXT:   }
+
+# RUN: echo 'OUTPUT_FORMAT(elf64-x86-64)' > %t.script
+# RUN: ld.lld -b binary %t.binary -T %t.script -o %t.out
+# RUN: llvm-readobj %t.out -sections -section-data -symbols | FileCheck -check-prefix=X86-64 %s
+
+# X86-64: Format: ELF64-x86-64

Modified: lld/trunk/test/ELF/invalid-linkerscript.test
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/invalid-linkerscript.test?rev=344952&r1=344951&r2=344952&view=diff
==============================================================================
--- lld/trunk/test/ELF/invalid-linkerscript.test (original)
+++ lld/trunk/test/ELF/invalid-linkerscript.test Mon Oct 22 13:50:01 2018
@@ -50,5 +50,11 @@
 
 # RUN: echo "OUTPUT_FORMAT(x y z)" > %t8
 # RUN: not ld.lld %t8 no-such-file 2>&1 | FileCheck -check-prefix=ERR8 %s
-# ERR8: , expected, but got y
+# 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: cannot open no-such-file:
+
+# RUN: echo "OUTPUT_FORMAT(elf64-x86-64 y z)" > %t9
+# 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:

Removed: lld/trunk/test/ELF/linkerscript/output-format.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/linkerscript/output-format.s?rev=344951&view=auto
==============================================================================
--- lld/trunk/test/ELF/linkerscript/output-format.s (original)
+++ lld/trunk/test/ELF/linkerscript/output-format.s (removed)
@@ -1,9 +0,0 @@
-# REQUIRES: x86
-# RUN: echo "OUTPUT_FORMAT(x, y, z)" > %t.script
-# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-freebsd %s -o %t1
-# RUN: ld.lld -shared -o %t2 %t1 %t.script
-# RUN: llvm-readobj %t2 > /dev/null
-
-# RUN: echo "OUTPUT_FORMAT(x, y)" > %t.script
-# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-freebsd %s -o %t1
-# RUN: not ld.lld -shared -o %t2 %t1 %t.script




More information about the llvm-commits mailing list