This is an archive of the discontinued LLVM Phabricator instance.

[lld-macho] Fix bug in CUE folding that resulted in wrong unwind table.
ClosedPublic

Authored by oontvoo on Nov 18 2022, 12:23 PM.

Details

Summary

PR/59070

Diff Detail

Event Timeline

oontvoo created this revision.Nov 18 2022, 12:23 PM
Herald added projects: Restricted Project, Restricted Project. · View Herald TranscriptNov 18 2022, 12:23 PM
Herald added a reviewer: Restricted Project. · View Herald Transcript
oontvoo requested review of this revision.Nov 18 2022, 12:23 PM
Herald added a project: Restricted Project. · View Herald TranscriptNov 18 2022, 12:23 PM

Code change looks good to me!

int3 added a subscriber: int3.Nov 18 2022, 3:43 PM

Thanks for tracking this down!!

lld/MachO/UnwindInfoSection.cpp
182

nit: rm blank line

183

nit 1: I think "largest" is more descriptive than "final" (plus "final" often has temporal-ordering connotations, e.g. InputSection::isFinal). Also maybe unwindAddressBoundary or cuAddressBoundary might be a better name for the variable, for similar reasons?

nit 2: I don't think "this should covered folded entries as well" is a super clear explanation; I thought about how to elaborate on it, but then I think maybe it's better to let the reader figure that out by reading the comments in the implementation. I guess it's okay if you want to keep that line though.

464

"remember" usually means "recall", rather than record/save.

660–661

this is now unused

661

I'm not entirely sure why, but this is what ld64 does

lld/test/MachO/compact-unwind-folding-bug.s
3

just to be clear, 'remove boilerplate' will include removing all the LSDA stuff, yes? we don't need to have a file that repros the actual no-catch bug, just something that checks that the last address of a bunch of folded CUEs is correct

jyknight added inline comments.Nov 18 2022, 3:54 PM
lld/MachO/UnwindInfoSection.cpp
661

Adding 1 does make sense. This value is the start of the "next function", so it's an exclusive bound, and you want the final byte of the function to actually be included in the range.

int3 added inline comments.Nov 18 2022, 4:12 PM
lld/MachO/UnwindInfoSection.cpp
661

That was my initial thought too, but shouldn't adding the length already make it an exclusive bound?

oontvoo marked 5 inline comments as done.Nov 18 2022, 9:18 PM
oontvoo added inline comments.
lld/MachO/UnwindInfoSection.cpp
661

hmm yeah, looks like LD64 does add 1. (here and a couple of lines up in the secondLevelPages loop too).

oontvoo updated this revision to Diff 476657.Nov 18 2022, 9:18 PM

addressed review comments + simplified test.

Thanks!

oontvoo updated this revision to Diff 476878.Nov 21 2022, 6:21 AM

fixed test + off-by-one error

jyknight added inline comments.Nov 21 2022, 8:55 AM
lld/MachO/UnwindInfoSection.cpp
661

@int3: oh, good point! ld64's code is actually making it too large by one byte. I suspect that's by accident, and a mistake which we should not replicate.

int3 accepted this revision.Nov 21 2022, 11:35 AM

Thanks!

lld/MachO/UnwindInfoSection.cpp
183

thanks for changing the comments!

thoughts on the variable rename?

641
661

or possibly to work around a mistake in the runtime unwinder... hard to say without carefully reading its implementation.

@oontvoo I'll leave it up to you whether you want to leave the +1 in. We could certainly omit it and see if it causes any problems in practice.

lld/test/MachO/compact-unwind-folding-bug.s
2

How about

This is a regression test. for verifying that the level-1 index sentinel entry has the correct address value. In particular, we used to emit the wrong value when the last N compact unwind entries were folded together.

I'm also wondering if the test file name can have something more specific than "folding bug"... maybe compact-unwind-tail-folding.s? Because it's not a bug in folding in general, only when the fold happens at the tail entries of the CUE array.

19

(alternatively you could omit it entirely, MC emits stuff into .text by default)

25–28

can we remove more boilerplate? (likewise for the other functions)

57–60

why do we need this?

This revision is now accepted and ready to land.Nov 21 2022, 11:35 AM
oontvoo marked 2 inline comments as done.Nov 21 2022, 12:27 PM
oontvoo added inline comments.
lld/MachO/UnwindInfoSection.cpp
183

changed to cueEndBoundary ?

661

I'll remove the +1 since it seems wrong (ie., if there happens to be stuff after the last entry taht *shouldn't* be in it, then the table would still include it.)

Also speaking of "strange", there seems to be another edge case here. I've added the test case below.

Should we replicate this or not? (my guess is no, but /shrug)

lld/test/MachO/compact-unwind-folding-bug.s
2

How about just compact-unwind-folding.s?
(added two additional test cases, where we behave slightly differently from LD64 ... LMK what you think)

25–28

We probably could - but slightly prefer that these symbols refer to each other (so that they don't look like they're all unused)
(I did remove the push/pop pairs to make the test smaller)

oontvoo updated this revision to Diff 476973.Nov 21 2022, 12:28 PM
oontvoo marked 2 inline comments as done.

updated tests and remove the off-by-one "bug"

int3 added inline comments.Nov 21 2022, 3:41 PM
lld/MachO/UnwindInfoSection.cpp
183

sounds good!

lld/test/MachO/compact-unwind-folding-bug.s
2

sgtm!

lld/test/MachO/compact-unwind-foldings.s
7 ↗(On Diff #476973)
59–60 ↗(On Diff #476973)

this makes sense to me, and I think we can keep our deviation from ld64's behavior here

61 ↗(On Diff #476973)

is this directive necessary?

85–86 ↗(On Diff #476973)

both ld64 and LLD do include an entry (with encoding 0x0) for this, right?

I'm not sure there's a way to *not* include _d here, since if there isn't an entry with 0x0 encoding, then the unwinder just uses the CUE at the most recent preceding address. So I think ld64 is working correctly here

88 ↗(On Diff #476973)

ditto

oontvoo marked 4 inline comments as done.Nov 22 2022, 7:39 AM
oontvoo added inline comments.
lld/test/MachO/compact-unwind-foldings.s
85–86 ↗(On Diff #476973)

right - when _d is in the middle of the range, we can't exclude it.

oontvoo updated this revision to Diff 477191.Nov 22 2022, 7:40 AM
oontvoo marked an inline comment as done.

address review comments + rebase

This revision was landed with ongoing or failed builds.Nov 22 2022, 7:40 AM
This revision was automatically updated to reflect the committed changes.