From: Rui Ueyama Date: Mon, 22 Oct 2018 20:50:01 +0000 (+0000) Subject: Add OUTPUT_FORMAT linker script directive support. X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=ea8cd00a1d1ae8ba47d749ca7bd2c9281e4b1847;p=platform%2Fupstream%2Fllvm.git 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 --- diff --git a/lld/ELF/ScriptParser.cpp b/lld/ELF/ScriptParser.cpp index d548689..112eec0 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 readBfdName(); void readSort(); Expr readAssert(); Expr readConstant(); @@ -382,10 +383,34 @@ void ScriptParser::readOutputArch() { skip(); } +std::pair 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 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 98f78b8..2228cff 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 94b9b51..311cd77 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 f9fb847..e635ae4 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 7d4402a..0000000 --- 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