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
This commit is contained in:
parent
01cc58bfb0
commit
ea8cd00a1d
@ -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(",");
|
||||
|
||||
@ -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)
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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:
|
||||
|
||||
@ -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
|
||||
Loading…
x
Reference in New Issue
Block a user