This patch series re-works the function elfNN_c64_resize_sections. The function is called early on in linking to ensure that the range of sections which need to be reachable via the PCC can be precisely bounded by the CHERI capability format. It also handles padding and alignign individual sections if there are any relocations to symbols which will be given a size spanning the entire section (i.e. section start linker defined symbols).
We hit a few problems in this function trying to link glibc, and discovered some more while working on the function. This patch series is a combination of the changes we've applied. I plan to apply it as a series of patches rather than as one large patch to keep the mapping between change and rationale.
Overall, the changes are about two things:
The first is making these padding and alignment adjustments to sections in such a way that they are robust against changes earlier on in the linker script instead of relying on making the adjustments in section-VMA order and having no changes earlier on in the linker script after any adjustment has been made.
The fact that the PCC bounds span multiple sections means that we can't rely on making adjustments in section-VMA order (increasing the alignment of the first section in the PCC bounds will mean a change earlier on than any section in the PCC bounds, while changes on the sections inside these bounds can adjust the alignment needed on the PCC).
The second set of changes are around performing the padding and alignment changes in more valid cases. We notice that data-only PURECAP shared libraries (i.e. objects without C64 code) could still have relocations in them pointing to section-start symbols (though won't need a non-existent PCC bounds to be precise), and we fix a bug that did not account for section starting symbols defined in the section they are supposed to mark.
A summary of the patch series: 1) Add padding by setting "dot" to the *expression* "dot + padding required" rather than the value of "dot + padding required". This means that adjustments to alignment of sections before the one being padded cause changes which get propagated past this section. We also include the padding in the section size, which trades unnecessary zerod data in the final binary against having the precisely bounded size clear in the final binary. 2) Set the alignment of sections to what is needed for precise bounds even if the existing VMA happens to be aligned enough. This means that if earlier sections are adjusted then the linker will ensure this section stays aligned correctly. 3) Ensure that PCC bounds are precise independent of whether there are any section-start symbols requiring specific sections to be precisely bounded. (bugfix). 4) Pad and align sections for data-only executables if they are made from PURECAP objects and need it due to their relocations. 5) Refactor the function based on above changes so that rather than construct a list of adjustments to make and sorting that list before applying the adjustments, we simply make adjustments as we find the requirement (possible because the adjustments are now robust against adjustments on earlier sections). 6) Testsuite updates and new tests. 7) Adjust section padding on a section if there is a section start symbol *in that section* (as well as just before it). I.e. if there is a __data_relro_start symbol in the .data.rel.ro section then we adjust the .data.rel.ro section (rather than checking to see if the next section has the same start address as the end address of the current section and padding the next section if that's the case). This is a little tricky since we don't know the position of a symbol within a section at this point, but like the existing code we handle that lack of knowledge by overfitting and adjusting any section that may be relevent.
The entire patch series has been regression tested on AArch64 bare-metal purecap with no regressions.
Thanks, Matthew
Entire patch series attached to cover letter.