This change splits out the finalizing of SyntheticSections size and the overall finalizing. This permits us to move createThunks() to the point where the addresses and sizes will be stable. It involves:
- Separating out the addition of GlobalSymbols to the dynamic symbol table and the static symbol table. The existing symbol table is built to assume that all local symbols are added before globals.
- Added a new member function finalizeAllocSize() to set the SyntheticSections size.
- Call the finalizeAllocSize() prior to createThunks(), which has been moved as late as it can.
I chose the name finalizeAllocSize to emphasize that only SHF_ALLOC sizes need to be finalized. We only need to worry about SyntheticSections that can disrupt thunk creation.
There is an argument that the DynamicSection and GOT sections don't need their size finalized early as they are in RW and well behaved applications will have all their code in RO, and all RO comes before RW. However since it wasn't much more effort to do so I thought it better to be consistent and to remove the possibility of a linker script breaking the assumption that they don't matter.
I initially tried to just move some of the existing finalize() calls before createThunks() but ended up in a somewhat tangled web of ordering dependencies. I think it would be less fragile to explicitly separate out the size finalization.
In the patch I've left the size calculations in the finalize() as asserts to check that createThunks() does not affect the size calculation.
The motivation is to allow addresses to be calculated prior to createThunks so that the information can be used in determining whether calls are within range. By finalizing the size of the SyntheticSections that have the SHF_ALLOC we remove a potential source of errors where range calculations made in createThunks are broken by changes in the sizes of SyntheticSections.
My next step is to allow address assignment prior to, and immediately after createThunks. At present the linker script address assignment is designed to only be run once so we can't just use the existing Script<ELFT>::X->assignAddresses(Phdrs). Any suggestions of how to approach that task would be most welcome as I don't have a lot of experience with that code.