libcxxrt: add padding in __cxa_allocate_* to fix alignment
The addition of the referenceCount to __cxa_allocate_exception put the unwindHeader at offset 0x58 in __cxa_exception, but it requires 16-byte alignment. In order to avoid changing the current __cxa_exception ABI (and thus breaking its consumers), add explicit padding in the allocation routines (and account for it when freeing). This is intended as a lower-risk change for FreeBSD 11. A "more correct" fix should be prepared for upstream and -CURRENT. Reviewed by: dim MFC after: 3 days Sponsored by: The FreeBSD Foundation Differential Revision: https://reviews.freebsd.org/D7271
This commit is contained in:
parent
bb04182c90
commit
3c4fd2463b
@ -572,6 +572,19 @@ static void free_exception(char *e)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef __LP64__
|
||||||
|
/**
|
||||||
|
* There's an ABI bug in __cxa_exception: unwindHeader requires 16-byte
|
||||||
|
* alignment but it was broken by the addition of the referenceCount.
|
||||||
|
* The unwindHeader is at offset 0x58 in __cxa_exception. In order to keep
|
||||||
|
* compatibility with consumers of the broken __cxa_exception, explicitly add
|
||||||
|
* padding on allocation (and account for it on free).
|
||||||
|
*/
|
||||||
|
static const int exception_alignment_padding = 8;
|
||||||
|
#else
|
||||||
|
static const int exception_alignment_padding = 0;
|
||||||
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Allocates an exception structure. Returns a pointer to the space that can
|
* Allocates an exception structure. Returns a pointer to the space that can
|
||||||
* be used to store an object of thrown_size bytes. This function will use an
|
* be used to store an object of thrown_size bytes. This function will use an
|
||||||
@ -580,16 +593,19 @@ static void free_exception(char *e)
|
|||||||
*/
|
*/
|
||||||
extern "C" void *__cxa_allocate_exception(size_t thrown_size)
|
extern "C" void *__cxa_allocate_exception(size_t thrown_size)
|
||||||
{
|
{
|
||||||
size_t size = thrown_size + sizeof(__cxa_exception);
|
size_t size = exception_alignment_padding + sizeof(__cxa_exception) +
|
||||||
|
thrown_size;
|
||||||
char *buffer = alloc_or_die(size);
|
char *buffer = alloc_or_die(size);
|
||||||
return buffer+sizeof(__cxa_exception);
|
return buffer + exception_alignment_padding + sizeof(__cxa_exception);
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C" void *__cxa_allocate_dependent_exception(void)
|
extern "C" void *__cxa_allocate_dependent_exception(void)
|
||||||
{
|
{
|
||||||
size_t size = sizeof(__cxa_dependent_exception);
|
size_t size = exception_alignment_padding +
|
||||||
|
sizeof(__cxa_dependent_exception);
|
||||||
char *buffer = alloc_or_die(size);
|
char *buffer = alloc_or_die(size);
|
||||||
return buffer+sizeof(__cxa_dependent_exception);
|
return buffer + exception_alignment_padding +
|
||||||
|
sizeof(__cxa_dependent_exception);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -617,7 +633,8 @@ extern "C" void __cxa_free_exception(void *thrown_exception)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
free_exception(reinterpret_cast<char*>(ex));
|
free_exception(reinterpret_cast<char*>(ex) -
|
||||||
|
exception_alignment_padding);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void releaseException(__cxa_exception *exception)
|
static void releaseException(__cxa_exception *exception)
|
||||||
@ -644,7 +661,8 @@ void __cxa_free_dependent_exception(void *thrown_exception)
|
|||||||
{
|
{
|
||||||
releaseException(realExceptionFromException(reinterpret_cast<__cxa_exception*>(ex)));
|
releaseException(realExceptionFromException(reinterpret_cast<__cxa_exception*>(ex)));
|
||||||
}
|
}
|
||||||
free_exception(reinterpret_cast<char*>(ex));
|
free_exception(reinterpret_cast<char*>(ex) -
|
||||||
|
exception_alignment_padding);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
Loading…
x
Reference in New Issue
Block a user