[Exception Handling] Why does frame unwind label have static alignment 4?
Joseph Faulls
Joseph.Faulls@imgtec.com
Mon Jan 17 17:24:06 GMT 2022
Hello all,
Small disclaimer of being new to EH, but I have come across a problem that seems quite fundamental to EH frame registry. I am targeting riscv64, but I believe the problem to be entirely platform agnostic.
When using EH frame registry, a label is put at the beginning of the frame unwind info to register and deregister frames:
libgcc/crtstuff.c:
> STATIC EH_FRAME_SECTION_CONST char __EH_FRAME_BEGIN__[]
> __attribute__((section(__LIBGCC_EH_FRAME_SECTION_NAME__), aligned(4)))
This is then populated with struct dwarf_fde:
libgcc/unwind-dw2-fde.h:
> struct dwarf_fde
> {
> uword length;
> sword CIE_delta;
> unsigned char pc_begin[];
> } __attribute__ ((packed, aligned (__alignof__ (void *))));
The trouble is that the __EH_FRAME_BEGIN__ has alignment 4, whereas the struct dwarf_fde has alignment of void*. When targeting 64-bit, these values are not the same.
It is this that is causing 4 bytes of padding. This is the disassembly of a simple program targeting riscv64 that throws an exception:
> 22954 000000000000e324 <__EH_FRAME_BEGIN__>:
> e324: 0000 unimp
> e326: 0000 unimp
> e328: 0010 0x10
> e32a: 0000 unimp
> e32c: 0000 unimp
> e32e: 0000 unimp
> e330: 00527a03 0x527a03
It is this that causes __register_frame_info_bases to fall flat on its face:
Libgcc/crtstuff.c in function frame_dummy:
> __register_frame_info (__EH_FRAME_BEGIN__, &object);
libgcc/unwind-dw2-fde.c
> void
> __register_frame_info_bases (const void *begin, struct object *ob,
> void *tbase, void *dbase)
> {
> /* If .eh_frame is empty, don't register at all. */
> if ((const uword *) begin == 0 || *(const uword *) begin == 0)
> return;
> ...
> void
> __register_frame_info (const void *begin, struct object *ob)
> {
> __register_frame_info_bases (begin, ob, 0, 0);
> }
This means no EH frames are ever registered, and so exceptions cannot be handled!
So, why does __EH_FRAME_BEGIN__ have alignment 4 and not of __alignof__ (void *) ? Is this a bug?
Thanks,
Joe
More information about the Gcc
mailing list