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
- modifies assignAddress() to track the original section/value of each symbol and return a symbol whose section/value has changed.
- 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 because there was no comment.
linkerscript/addr-zero.test tests this.