llvm-project/lld/test/ELF/linkerscript/symbol-assign-not-converge....

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

21 lines
510 B
Plaintext
Raw Normal View History

[ELF] Make LinkerScript::assignAddresses iterative PR42990. For `SECTIONS { b = a; . = 0xff00 + (a >> 8); a = .; }`, we currently set st_value(a)=0xff00 while st_value(b)=0xffff. The following call tree demonstrates the problem: ``` link<ELF64LE>(Args); Script->declareSymbols(); // insert a and b as absolute Defined Writer<ELFT>().run(); Script->processSectionCommands(); addSymbol(cmd); // a and b are re-inserted. LinkerScript::getSymbolValue // is lazily called by subsequent evaluation finalizeSections(); forEachRelSec(scanRelocations<ELFT>); processRelocAux // another problem PR42506, not affected by this patch finalizeAddressDependentContent(); // loop executed once script->assignAddresses(); // a = 0, b = 0xff00 script->assignAddresses(); // a = 0xff00, _end = 0xffff ``` We need another assignAddresses() to finalize the value of `a`. This patch 1) modifies assignAddress() to track the original section/value of each symbol and return a symbol whose section/value has changed. 2) moves the post-finalizeSections assignAddress() inside the loop of finalizeAddressDependentContent() and makes it iterative. Symbol assignment may not converge so we make a few attempts before bailing out. Note, assignAddresses() must be called at least twice. The penultimate call finalized section addresses while the last finalized symbol values. It is somewhat obscure and there was no comment. linkerscript/addr-zero.test tests this. Reviewed By: ruiu Differential Revision: https://reviews.llvm.org/D66279 llvm-svn: 369889
2019-08-26 18:23:31 +08:00
# REQUIRES: aarch64, x86
# RUN: llvm-mc -filetype=obj -triple=x86_64 /dev/null -o %t.o
# RUN: not ld.lld %t.o -T %s -o /dev/null 2>&1 | FileCheck %s
## AArch64 needs thunks and has different address finalization process, so test
## it as well.
# RUN: llvm-mc -filetype=obj -triple=aarch64 /dev/null -o %t.o
# RUN: not ld.lld %t.o -T %s -o /dev/null 2>&1 | FileCheck %s
# CHECK: error: assignment to symbol a does not converge
SECTIONS {
. = 0x1000;
a = b;
b = c;
c = d;
d = e;
e = f;
f = .;
}