This is an archive of the discontinued LLVM Phabricator instance.

[ELF] Align file offset for .bss if first section in a PT_LOAD
AbandonedPublic

Authored by jrtc27 on Apr 16 2019, 10:46 AM.

Details

Summary

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.

Event Timeline

jrtc27 created this revision.Apr 16 2019, 10:46 AM
jrtc27 updated this revision to Diff 195420.Apr 16 2019, 11:12 AM

Updated affected tests.

ruiu accepted this revision.Apr 18 2019, 2:10 AM

LGTM

This revision is now accepted and ready to land.Apr 18 2019, 2:10 AM
MaskRay added inline comments.Apr 18 2019, 5:46 AM
lld/ELF/Writer.cpp
2221

when not the first section in a PT_LOAD -> not in a PT_LOAD?

jrtc27 marked 2 inline comments as done.Apr 18 2019, 6:00 AM
jrtc27 added inline comments.
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 ↗(On Diff #195420)

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.

MaskRay added inline comments.Apr 18 2019, 6:01 AM
lld/ELF/Writer.cpp
2224

What happens if you delete if (OS->Type == SHT_NOBITS) return Off; here?

MaskRay added inline comments.Apr 18 2019, 6:15 AM
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.

jrtc27 marked 2 inline comments as done.Apr 18 2019, 8:20 AM
jrtc27 added inline comments.
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.

jrtc27 updated this revision to Diff 195758.Apr 18 2019, 8:52 AM

Also handle .bss where the zeroes are written to the file.

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);
MaskRay added inline comments.Jun 3 2019, 8:19 AM
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.

jrtc27 abandoned this revision.Oct 6 2019, 8:21 AM

Fixed slightly differently by D66658 which landed over a month ago.