[ELF] - Linkerscript: implemented output section [address] attribute.

Output section description in SECTIONS looks like that:

section [address] [(type)] :
...
{
...
}

Patch implements support of address atribute.

Differential revision: https://reviews.llvm.org/D22689

llvm-svn: 276619
This commit is contained in:
George Rimar 2016-07-25 08:29:46 +00:00
parent ebf866213c
commit 58e5c4dcfe
4 changed files with 133 additions and 1 deletions

View File

@ -194,6 +194,9 @@ void LinkerScript<ELFT>::assignAddresses(
if (Sec->getName() != Cmd->Name)
continue;
if (Cmd->AddrExpr)
Dot = Cmd->AddrExpr(Dot);
if ((Sec->getFlags() & SHF_TLS) && Sec->getType() == SHT_NOBITS) {
uintX_t TVA = Dot + ThreadBssOffset;
TVA = alignTo(TVA, Sec->getAlignment());
@ -648,6 +651,12 @@ static int precedence(StringRef Op) {
void ScriptParser::readOutputSectionDescription(StringRef OutSec) {
OutputSectionCommand *Cmd = new OutputSectionCommand(OutSec);
Opt.Commands.emplace_back(Cmd);
// Read an address expression.
// https://sourceware.org/binutils/docs/ld/Output-Section-Address.html#Output-Section-Address
if (peek() != ":")
Cmd->AddrExpr = readExpr();
expect(":");
// Parse constraints.

View File

@ -72,6 +72,7 @@ struct OutputSectionCommand : BaseCommand {
: BaseCommand(OutputSectionKind), Name(Name) {}
static bool classof(const BaseCommand *C);
StringRef Name;
Expr AddrExpr;
std::vector<std::unique_ptr<BaseCommand>> Commands;
std::vector<StringRef> Phdrs;
std::vector<uint8_t> Filler;

View File

@ -0,0 +1,122 @@
# REQUIRES: x86
# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t
# RUN: echo "SECTIONS { \
# RUN: .aaa 0x2000 : \
# RUN: { \
# RUN: *(.aaa) \
# RUN: } \
# RUN: .bbb 0x1 ? 0x3000 : 0x4000 : \
# RUN: { \
# RUN: *(.bbb) \
# RUN: } \
# RUN: .ccc ALIGN(CONSTANT (MAXPAGESIZE)) + (. & (CONSTANT (MAXPAGESIZE) - 1)) : \
# RUN: { \
# RUN: *(.ccc) \
# RUN: } \
# RUN: .ddd 0x5001 : \
# RUN: { \
# RUN: *(.ddd) \
# RUN: } \
# RUN: }" > %t.script
# RUN: ld.lld %t --script %t.script -o %tout
# RUN: llvm-readobj -s %tout | FileCheck %s
## Check:
## 1) Simple constant as address.
## 2) That something that contains ":" character, like ternary
## operator works as expression.
## 3) That complex expressions work.
## 4) That section alignment still applied to explicitly specified address.
#CHECK:Sections [
#CHECK: Section {
#CHECK: Index: 0
#CHECK: Name:
#CHECK: Type: SHT_NULL
#CHECK: Flags [
#CHECK: ]
#CHECK: Address: 0x0
#CHECK: Offset: 0x0
#CHECK: Size: 0
#CHECK: Link: 0
#CHECK: Info: 0
#CHECK: AddressAlignment: 0
#CHECK: EntrySize: 0
#CHECK: }
#CHECK: Section {
#CHECK: Index: 1
#CHECK: Name: .aaa
#CHECK: Type: SHT_PROGBITS
#CHECK: Flags [
#CHECK: SHF_ALLOC
#CHECK: ]
#CHECK: Address: 0x2000
#CHECK: Offset: 0x1000
#CHECK: Size: 8
#CHECK: Link: 0
#CHECK: Info: 0
#CHECK: AddressAlignment: 1
#CHECK: EntrySize: 0
#CHECK: }
#CHECK: Section {
#CHECK: Index: 2
#CHECK: Name: .bbb
#CHECK: Type: SHT_PROGBITS
#CHECK: Flags [
#CHECK: SHF_ALLOC
#CHECK: ]
#CHECK: Address: 0x3000
#CHECK: Offset: 0x2000
#CHECK: Size: 8
#CHECK: Link: 0
#CHECK: Info: 0
#CHECK: AddressAlignment: 1
#CHECK: EntrySize: 0
#CHECK: }
#CHECK: Section {
#CHECK: Index: 3
#CHECK: Name: .ccc
#CHECK: Type: SHT_PROGBITS
#CHECK: Flags [
#CHECK: SHF_ALLOC
#CHECK: ]
#CHECK: Address: 0x4008
#CHECK: Offset: 0x2008
#CHECK: Size: 8
#CHECK: Link: 0
#CHECK: Info: 0
#CHECK: AddressAlignment: 1
#CHECK: EntrySize: 0
#CHECK: }
#CHECK: Section {
#CHECK: Index: 4
#CHECK: Name: .ddd
#CHECK: Type: SHT_PROGBITS
#CHECK: Flags [
#CHECK: SHF_ALLOC
#CHECK: ]
#CHECK: Address: 0x5010
#CHECK: Offset: 0x2010
#CHECK: Size: 8
#CHECK: Link: 0
#CHECK: Info: 0
#CHECK: AddressAlignment: 16
#CHECK: EntrySize: 0
#CHECK: }
.globl _start
_start:
nop
.section .aaa, "a"
.quad 0
.section .bbb, "a"
.quad 0
.section .ccc, "a"
.quad 0
.section .ddd, "a"
.align 16
.quad 0

View File

@ -61,6 +61,6 @@
# RUN: echo "boom .temp : { *(.temp) } }" >> %t.script
# RUN: not ld.lld -shared %t -o %t1 --script %t.script > %t.log 2>&1
# RUN: FileCheck -check-prefix=ERR7 %s < %t.log
# ERR7: line 4: : expected, but got .temp
# ERR7: line 4: malformed number: .temp
# ERR7-NEXT: boom .temp : { *(.temp) } }
# RUN: grep '^ ^' %t.log