[lld] r276323 - [ELF] - Basic support of linkerscript commands: DATA_SEGMENT_ALIGN, DATA_SEGMENT_END, CONSTANT

George Rimar via llvm-commits llvm-commits at lists.llvm.org
Thu Jul 21 12:48:00 PDT 2016


Author: grimar
Date: Thu Jul 21 14:48:00 2016
New Revision: 276323

URL: http://llvm.org/viewvc/llvm-project?rev=276323&view=rev
Log:
[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

Modified:
    lld/trunk/ELF/LinkerScript.cpp
    lld/trunk/test/ELF/linkerscript-locationcounter.s

Modified: lld/trunk/ELF/LinkerScript.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/LinkerScript.cpp?rev=276323&r1=276322&r2=276323&view=diff
==============================================================================
--- lld/trunk/ELF/LinkerScript.cpp (original)
+++ lld/trunk/ELF/LinkerScript.cpp Thu Jul 21 14:48:00 2016
@@ -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);

Modified: lld/trunk/test/ELF/linkerscript-locationcounter.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/linkerscript-locationcounter.s?rev=276323&r1=276322&r2=276323&view=diff
==============================================================================
--- lld/trunk/test/ELF/linkerscript-locationcounter.s (original)
+++ lld/trunk/test/ELF/linkerscript-locationcounter.s Thu Jul 21 14:48:00 2016
@@ -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




More information about the llvm-commits mailing list