summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRui Ueyama <ruiu@google.com>2018-10-22 20:50:01 +0000
committerRui Ueyama <ruiu@google.com>2018-10-22 20:50:01 +0000
commitea8cd00a1d1ae8ba47d749ca7bd2c9281e4b1847 (patch)
tree9a48695cf58deed17a3eccedd09fe099794fc45b
parent01cc58bfb0139bf3a758d01c9985f78144d0c70c (diff)
downloadbcm5719-llvm-ea8cd00a1d1ae8ba47d749ca7bd2c9281e4b1847.tar.gz
bcm5719-llvm-ea8cd00a1d1ae8ba47d749ca7bd2c9281e4b1847.zip
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 llvm-svn: 344952
-rw-r--r--lld/ELF/ScriptParser.cpp29
-rw-r--r--lld/test/ELF/emulation.s16
-rw-r--r--lld/test/ELF/format-binary.test6
-rw-r--r--lld/test/ELF/invalid-linkerscript.test8
-rw-r--r--lld/test/ELF/linkerscript/output-format.s9
5 files changed, 56 insertions, 12 deletions
diff --git a/lld/ELF/ScriptParser.cpp b/lld/ELF/ScriptParser.cpp
index d548689c92f..112eec0cbbc 100644
--- a/lld/ELF/ScriptParser.cpp
+++ b/lld/ELF/ScriptParser.cpp
@@ -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(",");
diff --git a/lld/test/ELF/emulation.s b/lld/test/ELF/emulation.s
index 98f78b8ec1d..2228cff8ffa 100644
--- a/lld/test/ELF/emulation.s
+++ b/lld/test/ELF/emulation.s
@@ -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)
diff --git a/lld/test/ELF/format-binary.test b/lld/test/ELF/format-binary.test
index 94b9b51afe7..311cd773a40 100644
--- a/lld/test/ELF/format-binary.test
+++ b/lld/test/ELF/format-binary.test
@@ -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
diff --git a/lld/test/ELF/invalid-linkerscript.test b/lld/test/ELF/invalid-linkerscript.test
index f9fb8478251..e635ae4f2af 100644
--- a/lld/test/ELF/invalid-linkerscript.test
+++ b/lld/test/ELF/invalid-linkerscript.test
@@ -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:
diff --git a/lld/test/ELF/linkerscript/output-format.s b/lld/test/ELF/linkerscript/output-format.s
deleted file mode 100644
index 7d4402a557a..00000000000
--- a/lld/test/ELF/linkerscript/output-format.s
+++ /dev/null
@@ -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
OpenPOWER on IntegriCloud