forked from OSchip/llvm-project
[ELF] Use late evaluation for ALIGN in expression
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
This commit is contained in:
parent
0570841806
commit
3c6de1a66c
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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) {}
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue