This is an archive of the discontinued LLVM Phabricator instance.

[libcxxabi] Align unwindHeader on a double-word boundary
ClosedPublic

Authored by ahatanak on May 9 2017, 11:34 PM.

Details

Summary

r276215 made a change to annotate _Unwind_Exception with "attribute((aligned))" so that exception objects are double-word aligned. This fix hasn't been incorporated to unwind.h on Darwin yet and, since it is an ABI breaking change, I'm not sure it will ever happen in the future.

Instead of annotating struct _Unwind_Exception with the attribute, this patch annotates field unwindHeader of __cxa_exception. This fixes the test case (exception_object_alignment.sh.cpp) that used to crash because of the under-aligned object.

rdar://problem/25364625

Diff Detail

Event Timeline

ahatanak created this revision.May 9 2017, 11:34 PM
mehdi_amini edited edge metadata.May 10 2017, 10:26 AM

Something still isn't clear to me: the issue IIUC is not with the unwindHeader itself, but with the misaligned thrown object that is allocated right after the __cxa_exception itself. Isn't it?

Then are you aligning the unwindHeader field and by side-effect the size of the __cxa_exception structure becomes aligned and then the thrown object will be as well?

Something still isn't clear to me: the issue IIUC is not with the unwindHeader itself, but with the misaligned thrown object that is allocated right after the __cxa_exception itself. Isn't it?

Then are you aligning the unwindHeader field and by side-effect the size of the __cxa_exception structure becomes aligned and then the thrown object will be as well?

Yes, that's correct.

If field unwindHeader is annotated with the aligned attribute, both the field and struct cxa_exception are aligned. As a result, the exception object that follows cxa_exception is aligned too.

If we annotate struct cxa_exception with the attribute instead of annotating the field, the test case segfaults. It seems that this approach doesn't work because several places in cxa_exception.cpp assume the exception object immediately follows field unwindHeader (there are should be no paddings at the end of cxa_exception).

mehdi_amini accepted this revision.May 10 2017, 5:13 PM

If field unwindHeader is annotated with the aligned attribute, both the field and struct cxa_exception are aligned. As a result, the exception object that follows cxa_exception is aligned too.

If we annotate struct cxa_exception with the attribute instead of annotating the field, the test case segfaults. It seems that this approach doesn't work because several places in cxa_exception.cpp assume the exception object immediately follows field unwindHeader (there are should be no paddings at the end of cxa_exception).

OK, then LGTM but add all these informations as a comment for unwindHeader field.

This revision is now accepted and ready to land.May 10 2017, 5:13 PM
This revision was automatically updated to reflect the committed changes.
sberg added a subscriber: sberg.Jun 20 2017, 5:04 AM

In LibreOffice we unfortunately have some dirty code that synthesizes exception throwing, calling __cxa_allocate_exception, __cxa_throw (passing in our own exception destructor function), and then, when the exception destructor function gets called, assumes we can map from the passed pointer to the __cxa_exception header preceding it (to get at its exceptionType member). That code was thus broken by this change. I have a dirty hack around that (checking whether the __cxa_exception exceptionDestructor member has the expected value; if not, adjust: Hack to dynamically adapt to __cxa_exceptiom in LLVM 5.0 libcxxabi) and two questions:

  • Is there any estimation when this change will show up in macOS's libcxxabi? That would give me an idea which LibreOffice versions I would need to backport my fix to.
  • Does anybody happen to have a good idea how to do my hacky fix in a cleaner way?