Skip to content

Commit

Permalink
[ELF] Use late evaluation for ALIGN in expression
Browse files Browse the repository at this point in the history
While the following expression is handled fine:

  PROVIDE_HIDDEN(newsym = oldsym + address);

The following expression triggers an error because the expression
is evaluated as absolute:

  PROVIDE_HIDDEN(newsym = ALIGN(oldsym, CONSTANT(MAXPAGESIZE)) + address);

To avoid this error, we use late evaluation for ALIGN by making the
alignment an attribute of the expression itself.

Differential Revision: https://reviews.llvm.org/D33629

llvm-svn: 304185
  • Loading branch information
petrhosek committed May 30, 2017
1 parent 0570841 commit 3c6de1a
Showing 5 changed files with 21 additions and 5 deletions.
7 changes: 4 additions & 3 deletions lld/ELF/LinkerScript.cpp
Original file line number Diff line number Diff line change
@@ -52,11 +52,12 @@ LinkerScript *elf::Script;
uint64_t ExprValue::getValue() const {
if (Sec) {
if (Sec->getOutputSection())
return Sec->getOffset(Val) + Sec->getOutputSection()->Addr;
return alignTo(Sec->getOffset(Val) + Sec->getOutputSection()->Addr,
Alignment);
error("unable to evaluate expression: input section " + Sec->Name +
" has no output section assigned");
}
return Val;
return alignTo(Val, Alignment);
}

uint64_t ExprValue::getSecAddr() const {
@@ -143,7 +144,7 @@ void LinkerScript::assignSymbol(SymbolAssignment *Cmd, bool InSec) {
} else {
Sym->Section = V.Sec;
if (Sym->Section->Flags & SHF_ALLOC)
Sym->Value = V.Val;
Sym->Value = alignTo(V.Val, V.Alignment);
else
Sym->Value = V.getValue();
}
5 changes: 5 additions & 0 deletions lld/ELF/LinkerScript.h
Original file line number Diff line number Diff line change
@@ -41,7 +41,12 @@ struct ExprValue {
SectionBase *Sec;
uint64_t Val;
bool ForceAbsolute;
uint64_t Alignment = 1;

ExprValue(SectionBase *Sec, bool ForceAbsolute, uint64_t Val,
uint64_t Alignment)
: Sec(Sec), Val(Val), ForceAbsolute(ForceAbsolute), Alignment(Alignment) {
}
ExprValue(SectionBase *Sec, bool ForceAbsolute, uint64_t Val)
: Sec(Sec), Val(Val), ForceAbsolute(ForceAbsolute) {}
ExprValue(SectionBase *Sec, uint64_t Val) : ExprValue(Sec, false, Val) {}
6 changes: 5 additions & 1 deletion lld/ELF/ScriptParser.cpp
Original file line number Diff line number Diff line change
@@ -859,7 +859,11 @@ Expr ScriptParser::readPrimary() {
expect(",");
Expr E2 = readExpr();
expect(")");
return [=] { return alignTo(E().getValue(), E2().getValue()); };
return [=] {
ExprValue V = E();
V.Alignment = E2().getValue();
return V;
};
}
if (Tok == "ALIGNOF") {
StringRef Name = readParenLiteral();
2 changes: 1 addition & 1 deletion lld/test/ELF/linkerscript/align.s
Original file line number Diff line number Diff line change
@@ -64,7 +64,7 @@
# SYMBOLS-NEXT: 0000000000010000 *ABS* 00000000 __code_base__
# SYMBOLS-NEXT: 0000000000001000 *ABS* 00000000 VAR
# SYMBOLS-NEXT: 0000000000011000 .bbb 00000000 __start_bbb
# SYMBOLS-NEXT: 0000000000012000 *ABS* 00000000 __end_bbb
# SYMBOLS-NEXT: 0000000000012000 .bbb 00000000 __end_bbb

.global _start
_start:
6 changes: 6 additions & 0 deletions lld/test/ELF/linkerscript/symbol-reserved.s
Original file line number Diff line number Diff line change
@@ -11,6 +11,12 @@

# SHARED: 0000000000000005 .dynsym 00000000 .hidden newsym

# RUN: echo "PROVIDE_HIDDEN(newsym = ALIGN(__ehdr_start, CONSTANT(MAXPAGESIZE)) + 5);" > %t.script
# RUN: ld.lld -o %t1 %t.script %t
# RUN: llvm-objdump -t %t1 | FileCheck --check-prefix=ALIGNED %s

# ALIGNED: 0000000000200005 .text 00000000 .hidden newsym

.global _start
_start:
lea newsym(%rip),%rax

0 comments on commit 3c6de1a

Please sign in to comment.