forked from OSchip/llvm-project
[ELF] - Linkerscript: implemented += operator.
Sometimes += is used to move the location counter. Example from the wild is: .dbg_excpt _DBG_EXCPT_ADDR (NOLOAD) : { . += (DEFINED (_DEBUGGER) ? 0x8 : 0x0); https://github.com/chipKIT32/pic32-Arduino-USB-Bootloader-original/blob/master/boot-linkerscript.ld Patch implements it and opens way for others type of assignments (-= *= etc), though I think only += is actual to support. Differential revision: https://reviews.llvm.org/D22916 llvm-svn: 277035
This commit is contained in:
parent
ad10c3d8d4
commit
30835ea47a
|
@ -643,7 +643,7 @@ void ScriptParser::readSections() {
|
|||
expect("{");
|
||||
while (!Error && !skip("}")) {
|
||||
StringRef Tok = next();
|
||||
if (peek() == "=") {
|
||||
if (peek() == "=" || peek() == "+=") {
|
||||
readAssignment(Tok);
|
||||
expect(";");
|
||||
} else if (Tok == "PROVIDE") {
|
||||
|
@ -777,19 +777,10 @@ void ScriptParser::readProvide(bool Hidden) {
|
|||
expect(";");
|
||||
}
|
||||
|
||||
SymbolAssignment *ScriptParser::readAssignment(StringRef Name) {
|
||||
expect("=");
|
||||
Expr E = readExpr();
|
||||
auto *Cmd = new SymbolAssignment(Name, E);
|
||||
Opt.Commands.emplace_back(Cmd);
|
||||
return Cmd;
|
||||
}
|
||||
static uint64_t getSymbolValue(StringRef S, uint64_t Dot) {
|
||||
if (S == ".")
|
||||
return Dot;
|
||||
|
||||
// This is an operator-precedence parser to parse a linker
|
||||
// script expression.
|
||||
Expr ScriptParser::readExpr() { return readExpr1(readPrimary(), 0); }
|
||||
|
||||
static uint64_t getSymbolValue(StringRef S) {
|
||||
switch (Config->EKind) {
|
||||
case ELF32LEKind:
|
||||
if (SymbolBody *B = Symtab<ELF32LE>::X->find(S))
|
||||
|
@ -814,6 +805,21 @@ static uint64_t getSymbolValue(StringRef S) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
SymbolAssignment *ScriptParser::readAssignment(StringRef Name) {
|
||||
StringRef Op = next();
|
||||
assert(Op == "=" || Op == "+=");
|
||||
Expr E = readExpr();
|
||||
if (Op == "+=")
|
||||
E = [=](uint64_t Dot) { return getSymbolValue(Name, Dot) + E(Dot); };
|
||||
auto *Cmd = new SymbolAssignment(Name, E);
|
||||
Opt.Commands.emplace_back(Cmd);
|
||||
return Cmd;
|
||||
}
|
||||
|
||||
// This is an operator-precedence parser to parse a linker
|
||||
// script expression.
|
||||
Expr ScriptParser::readExpr() { return readExpr1(readPrimary(), 0); }
|
||||
|
||||
// This is a part of the operator-precedence parser. This function
|
||||
// assumes that the remaining token stream starts with an operator.
|
||||
Expr ScriptParser::readExpr1(Expr Lhs, int MinPrec) {
|
||||
|
@ -853,9 +859,6 @@ uint64_t static getConstant(StringRef S) {
|
|||
Expr ScriptParser::readPrimary() {
|
||||
StringRef Tok = next();
|
||||
|
||||
if (Tok == ".")
|
||||
return [](uint64_t Dot) { return Dot; };
|
||||
|
||||
if (Tok == "(") {
|
||||
Expr E = readExpr();
|
||||
expect(")");
|
||||
|
@ -914,9 +917,9 @@ Expr ScriptParser::readPrimary() {
|
|||
// Parse a symbol name or a number literal.
|
||||
uint64_t V = 0;
|
||||
if (Tok.getAsInteger(0, V)) {
|
||||
if (!isValidCIdentifier(Tok))
|
||||
if (Tok != "." && !isValidCIdentifier(Tok))
|
||||
setError("malformed number: " + Tok);
|
||||
return [=](uint64_t Dot) { return getSymbolValue(Tok); };
|
||||
return [=](uint64_t Dot) { return getSymbolValue(Tok, Dot); };
|
||||
}
|
||||
return [=](uint64_t Dot) { return V; };
|
||||
}
|
||||
|
|
|
@ -37,6 +37,9 @@
|
|||
# RUN: . = DATA_SEGMENT_ALIGN (CONSTANT (MAXPAGESIZE), CONSTANT (COMMONPAGESIZE)); \
|
||||
# RUN: .datasegmentalign : { *(.datasegmentalign) } \
|
||||
# RUN: . = DATA_SEGMENT_END (.); \
|
||||
# RUN: . = 0x27000; \
|
||||
# RUN: . += 0x1000; \
|
||||
# RUN: .plusassign : { *(.plusassign) } \
|
||||
# RUN: }" > %t.script
|
||||
# RUN: ld.lld %t --script %t.script -o %t2
|
||||
# RUN: llvm-readobj -s %t2 | FileCheck %s
|
||||
|
@ -296,6 +299,21 @@
|
|||
# CHECK-NEXT: AddressAlignment:
|
||||
# CHECK-NEXT: EntrySize:
|
||||
# CHECK-NEXT: }
|
||||
# CHECK-NEXT: Section {
|
||||
# CHECK-NEXT: Index:
|
||||
# CHECK-NEXT: Name: .plusassign
|
||||
# CHECK-NEXT: Type: SHT_PROGBITS
|
||||
# CHECK-NEXT: Flags [
|
||||
# CHECK-NEXT: SHF_ALLOC
|
||||
# CHECK-NEXT: ]
|
||||
# CHECK-NEXT: Address: 0x28000
|
||||
# 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 { \
|
||||
|
@ -399,3 +417,6 @@ nop
|
|||
|
||||
.section .datasegmentalign, "a"
|
||||
.quad 0
|
||||
|
||||
.section .plusassign, "a"
|
||||
.quad 0
|
||||
|
|
Loading…
Reference in New Issue