If a linker script requests additional alignment for .bss, and it is the
first section in a PT_LOAD, we must ensure to apply this alignment to
the file offset as well, as with other sections, to ensure the file
offset and virtual address are congruent modulo the page size.
Details
- Reviewers
ruiu • espindola MaskRay
Diff Detail
- Repository
- rG LLVM Github Monorepo
- Build Status
Buildable 30635 Build 30634: arc lint + arc unit
Event Timeline
lld/ELF/Writer.cpp | ||
---|---|---|
2221 | when not the first section in a PT_LOAD -> not in a PT_LOAD? |
lld/ELF/Writer.cpp | ||
---|---|---|
2221 | not in a PT_LOAD is encompassed by that, and this means it also covers the case below that has a reference to this comment. | |
lld/test/ELF/basic-ppc64.s | ||
166 | Technically, in this case, we could not align the section in the file, since the entire PT_LOAD it gets put into is empty and thus omitted, but that's complexity for optimising a rare edge-case. |
lld/ELF/Writer.cpp | ||
---|---|---|
2224 | What happens if you delete if (OS->Type == SHT_NOBITS) return Off; here? |
lld/ELF/Writer.cpp | ||
---|---|---|
2224 | I think we probably just need to delete if (OS->Type == SHT_NOBITS) return Off; from the original code. .tss in tls-offset.s is affected but that offset is not significant. |
lld/ELF/Writer.cpp | ||
---|---|---|
2224 | Then you potentially unnecessarily over-align a non-loaded nobits section in the file. It's not wrong, it just deviates more from the current output. | |
2239 | This might actually be wrong; consider .bss being followed (stupidly) by .data in the same segment. In that case, .bss will be filled with zeroes and thus have a non-zero filesz, but we need to make sure its file offset is still the same as its address modulo the page size (ie by using the standard formula below), otherwise it will appear shifted in the segment. I'll see if this is true in practice with another simple test case. |
Sorry I didn't compare the results carefully, but I ran into a similar issue with PPC32 BSS PLT.
Have you tried this diff?
- if (OS->Type == SHT_NOBITS) + if (OS->Type == SHT_NOBITS && !(OS->PtLoad && OS->PtLoad->FirstSec == OS)) return Off; // If the section is not in a PT_LOAD, we just have to align it. if (!OS->PtLoad) return alignTo(Off, OS->Alignment);
lld/test/ELF/linkerscript/bss-middle-align.test | ||
---|---|---|
4 ↗ | (On Diff #195758) | For llvm-readelf, --long-option is now more common (GNU readelf parses -long-option as a list of short options). |
8 ↗ | (On Diff #195758) | I think most other linkerscript tests write this on one line: .text : { *(.text) }. It is concise and more readable in my opinion. |
when not the first section in a PT_LOAD -> not in a PT_LOAD?