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,
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);
# 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
# 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 { \
.section .neq, "a"
.quad 0
+
+.section .maxpagesize, "a"
+.quad 0
+
+.section .commonpagesize, "a"
+.quad 0
+
+.section .datasegmentalign, "a"
+.quad 0