[ELF] - Basic support of linkerscript commands: DATA_SEGMENT_ALIGN, DATA_SEGMENT_END, CONSTANT
It is called basic because: CONSTANT expression can refer to COMMONPAGESIZE and MAXPAGESIZE. This sizes are usually different and used for possible optimization of memory consumption. More details are here: https://sourceware.org/ml/binutils/2002-02/msg00265.html We currently do not support this optimization, so both CONSTANT(MAXPAGESIZE) and CONSTANT(COMMONPAGESIZE) just return Target->PageSize value. DATA_SEGMENT_ALIGN and DATA_SEGMENT_END are used as a part of opt. The latter one is just ignored now. According to documentation DATA_SEGMENT_ALIGN has 2 possible calculation, but since we do not support mentioned opt - it is always calculated now as (ALIGN(MAXPAGESIZE) + (. & (MAXPAGESIZE - 1))). In general this should work for now until we deside to support this opt. Differential revision: https://reviews.llvm.org/D19663 llvm-svn: 276323
This commit is contained in:
parent
629e0aa5be
commit
92e93fb4ba
|
@ -105,6 +105,13 @@ uint64_t ExprParser::run() {
|
|||
return V;
|
||||
}
|
||||
|
||||
uint64_t static getConstantValue(StringRef C) {
|
||||
if (C == "COMMONPAGESIZE" || C == "MAXPAGESIZE")
|
||||
return Target->PageSize;
|
||||
error("unknown constant: " + C);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// This is a part of the operator-precedence parser to evaluate
|
||||
// arithmetic expressions in SECTIONS command. This function evaluates an
|
||||
// integer literal, a parenthesized expression, the ALIGN function,
|
||||
|
@ -124,6 +131,34 @@ uint64_t ExprParser::parsePrimary() {
|
|||
expect(")");
|
||||
return alignTo(Dot, V);
|
||||
}
|
||||
if (Tok == "CONSTANT") {
|
||||
expect("(");
|
||||
uint64_t V = getConstantValue(next());
|
||||
expect(")");
|
||||
return V;
|
||||
}
|
||||
// Documentations says there are two ways to compute
|
||||
// the value of DATA_SEGMENT_ALIGN command, depending on whether the second
|
||||
// uses fewer COMMONPAGESIZE sized pages for the data segment(area between the
|
||||
// result of this expression and `DATA_SEGMENT_END') than the first or not.
|
||||
// That is possible optimization, that we do not support, so we compute that
|
||||
// function always as (ALIGN(MAXPAGESIZE) + (. & (MAXPAGESIZE - 1))) now.
|
||||
if (Tok == "DATA_SEGMENT_ALIGN") {
|
||||
expect("(");
|
||||
uint64_t L = parseExpr();
|
||||
expect(",");
|
||||
parseExpr();
|
||||
expect(")");
|
||||
return alignTo(Dot, L) + (Dot & (L - 1));
|
||||
}
|
||||
// Since we do not support the optimization from comment above,
|
||||
// we can just ignore that command.
|
||||
if (Tok == "DATA_SEGMENT_END") {
|
||||
expect("(");
|
||||
expect(".");
|
||||
expect(")");
|
||||
return Dot;
|
||||
}
|
||||
uint64_t V = 0;
|
||||
if (Tok.getAsInteger(0, V))
|
||||
setError("malformed number: " + Tok);
|
||||
|
|
|
@ -30,6 +30,13 @@
|
|||
# RUN: .eq : { *(.eq) } \
|
||||
# RUN: . = 0x2 != 0x1 ? 0x23000 : 0x999999; \
|
||||
# RUN: .neq : { *(.neq) } \
|
||||
# RUN: . = CONSTANT (MAXPAGESIZE) * 0x24; \
|
||||
# RUN: .maxpagesize : { *(.maxpagesize) } \
|
||||
# RUN: . = CONSTANT (COMMONPAGESIZE) * 0x25; \
|
||||
# RUN: .commonpagesize : { *(.commonpagesize) } \
|
||||
# RUN: . = DATA_SEGMENT_ALIGN (CONSTANT (MAXPAGESIZE), CONSTANT (COMMONPAGESIZE)); \
|
||||
# RUN: .datasegmentalign : { *(.datasegmentalign) } \
|
||||
# RUN: . = DATA_SEGMENT_END (.); \
|
||||
# RUN: }" > %t.script
|
||||
# RUN: ld.lld %t --script %t.script -o %t2
|
||||
# RUN: llvm-readobj -s %t2 | FileCheck %s
|
||||
|
@ -244,6 +251,51 @@
|
|||
# CHECK-NEXT: AddressAlignment:
|
||||
# CHECK-NEXT: EntrySize:
|
||||
# CHECK-NEXT: }
|
||||
# CHECK-NEXT: Section {
|
||||
# CHECK-NEXT: Index:
|
||||
# CHECK-NEXT: Name: .maxpagesize
|
||||
# CHECK-NEXT: Type: SHT_PROGBITS
|
||||
# CHECK-NEXT: Flags [
|
||||
# CHECK-NEXT: SHF_ALLOC
|
||||
# CHECK-NEXT: ]
|
||||
# CHECK-NEXT: Address: 0x24000
|
||||
# CHECK-NEXT: Offset:
|
||||
# CHECK-NEXT: Size:
|
||||
# CHECK-NEXT: Link:
|
||||
# CHECK-NEXT: Info:
|
||||
# CHECK-NEXT: AddressAlignment:
|
||||
# CHECK-NEXT: EntrySize: 0
|
||||
# CHECK-NEXT: }
|
||||
# CHECK-NEXT: Section {
|
||||
# CHECK-NEXT: Index:
|
||||
# CHECK-NEXT: Name: .commonpagesize
|
||||
# CHECK-NEXT: Type: SHT_PROGBITS
|
||||
# CHECK-NEXT: Flags [
|
||||
# CHECK-NEXT: SHF_ALLOC
|
||||
# CHECK-NEXT: ]
|
||||
# CHECK-NEXT: Address: 0x25000
|
||||
# CHECK-NEXT: Offset:
|
||||
# CHECK-NEXT: Size:
|
||||
# CHECK-NEXT: Link:
|
||||
# CHECK-NEXT: Info:
|
||||
# CHECK-NEXT: AddressAlignment:
|
||||
# CHECK-NEXT: EntrySize:
|
||||
# CHECK-NEXT: }
|
||||
# CHECK-NEXT: Section {
|
||||
# CHECK-NEXT: Index:
|
||||
# CHECK-NEXT: Name: .datasegmentalign
|
||||
# CHECK-NEXT: Type: SHT_PROGBITS
|
||||
# CHECK-NEXT: Flags [
|
||||
# CHECK-NEXT: SHF_ALLOC
|
||||
# CHECK-NEXT: ]
|
||||
# CHECK-NEXT: Address: 0x26008
|
||||
# CHECK-NEXT: Offset:
|
||||
# CHECK-NEXT: Size:
|
||||
# CHECK-NEXT: Link:
|
||||
# CHECK-NEXT: Info:
|
||||
# CHECK-NEXT: AddressAlignment:
|
||||
# CHECK-NEXT: EntrySize:
|
||||
# CHECK-NEXT: }
|
||||
|
||||
## Mailformed number error.
|
||||
# RUN: echo "SECTIONS { \
|
||||
|
@ -338,3 +390,12 @@ nop
|
|||
|
||||
.section .neq, "a"
|
||||
.quad 0
|
||||
|
||||
.section .maxpagesize, "a"
|
||||
.quad 0
|
||||
|
||||
.section .commonpagesize, "a"
|
||||
.quad 0
|
||||
|
||||
.section .datasegmentalign, "a"
|
||||
.quad 0
|
||||
|
|
Loading…
Reference in New Issue