This is an archive of the discontinued LLVM Phabricator instance.

[lld-macho] Ensure __bss sections we output have file offset of zero
ClosedPublic

Authored by int3 on May 29 2020, 9:47 PM.

Details

Summary

llvm-mc emits __bss sections with an offset of zero, but we weren't expecting
that in our input, so we were copying non-zero data from the start of the file and
putting it in __bss, with obviously undesirable runtime results. (It appears that
the kernel will copy those nonzero bytes as long as the offset is nonzero, regardless
of whether S_ZERO_FILL is set.)

I debated on whether to make a special ZeroFillSection -- separate from a
regular InputSection -- but it seemed like too much work for now. But I'm happy
to refactor if anyone feels strongly about having it as a separate class.

Depends on D80857.

Diff Detail

Event Timeline

int3 created this revision.May 29 2020, 9:47 PM
Herald added a project: Restricted Project. · View Herald TranscriptMay 29 2020, 9:47 PM
int3 edited the summary of this revision. (Show Details)May 29 2020, 9:51 PM

I'm not sure it's strictly necessary, but it's what ld64 does.

If no tool enforces this, then maybe this is unnecessary? I believe the ELF counterpart is SHT_NOBITS. sh_offset of a SHT_NOBITS section is ignored, but for aesthetic reasons and practical reasons (monotonic property), linkers reuses the previous section's offset.

BTW, llvm-readobj -S for ELF is so verbose that I stopped using it and switched to llvm-readelf -S for most new tests. If you find Mach-O output verbose, maybe it is time to add a compact style.

int3 added a comment.Jun 2 2020, 3:52 PM

If no tool enforces this, then maybe this is unnecessary?

If we don't have an offset of zero, then it appears that whatever bytes at that non-zero offset get copied into __bss. Unlike __PAGEZERO, which is a segment, there's no way to say that a section has a non-zero vmsize but a zero filesize: there's just a single size field. So I guess I should've said it's necessary if we don't want to actually allocate disk space for the zero bytes in our binary.

int3 edited the summary of this revision. (Show Details)Jun 2 2020, 3:53 PM
smeenai accepted this revision.Jun 9 2020, 7:46 PM

I'm okay with your isZeroFill solution. Making a separate class seems like overkill for now, considering the check is needed in a grand total of three places (four if you count the resulting conditional in InputSection::writeTo, but still). A separate class might be cleaner from a Software Engineering™ perspective, but I think you'd still end up with two checks in that case (one to make a ZeroFillSection instead of an InputSection, and one for the writer fileOff logic), so it doesn't seem worth the extra complexity.

This revision is now accepted and ready to land.Jun 9 2020, 7:46 PM
int3 updated this revision to Diff 270645.Jun 14 2020, 6:20 PM

fix ubsan

int3 updated this revision to Diff 270925.Jun 15 2020, 5:26 PM

update SAN fix

This revision was automatically updated to reflect the committed changes.