gimli icon indicating copy to clipboard operation
gimli copied to clipboard

Support GNU extensions to CFI

Open fitzgen opened this issue 8 years ago • 9 comments

http://refspecs.linux-foundation.org/LSB_4.0.0/LSB-Core-generic/LSB-Core-generic/dwarfext.html

DW_CFA_GNU_args_size0x2eThe DW_CFA_GNU_args_size instruction takes an unsigned LEB128 operand representing an argument size. This instruction specifies the total of the size of the arguments which have been pushed onto the stack.
DW_CFA_GNU_negative_offset_extended0x2fThe DW_CFA_def_cfa_sf instruction takes two operands: an unsigned LEB128 value representing a register number and an unsigned LEB128 which represents the magnitude of the offset. This instruction is identical to DW_CFA_offset_extended_sf except that the operand is subtracted to produce the offset. This instructions is obsoleted by DW_CFA_offset_extended_sf.

I think the first one is an assertion?

The second one is obsolete, but we should probably support it for backwards compatibility.

fitzgen avatar Sep 25 '16 13:09 fitzgen

There's also DW_EH_PE_indirect which (AFAICT) means that the resulting pointer is actually an indirect pointer to the resulting pointer. Seems safe. Might not want to support this one.

fitzgen avatar Sep 25 '16 21:09 fitzgen

So I looked up DW_CFA_GNU_args_size since unwind-rs ran into issues with executables using it. LLVM's libunwind (which I base most of my findings on because I find the code much cleaner than GCC's).

I suppose we could add an sp_extra_arg_size field to UnwindTableRow, and unwinders would be expected to reimplement the second step?

roblabla avatar Aug 01 '18 14:08 roblabla

When it needs to set the IP register, it additionally increments the SP register by that value.

To clarify, this function is not used internally right? So this only affects binaries that manually adjust IP in their unwind handlers (which I don't remember encountering so far)?

main-- avatar Aug 01 '18 15:08 main--

this function is used by other functions, like _Unwind_SetIP (used by the rust eh_personality function), _Unwind_FindEnclosingFunction, etc...

roblabla avatar Aug 01 '18 15:08 roblabla

Most binaries adjust ther IP in their unwind handler, that's the whole point of how catch works :P

roblabla avatar Aug 01 '18 15:08 roblabla

Weird, now I'm confused why it worked when I just ignored DW_CFA_GNU_args_size?

main-- avatar Aug 01 '18 15:08 main--

🤷‍♂️

BTW, do you remember which program generates a DW_CFA_GNU_args_size ? I just dwarfdump'd the unwind-rs demo, and it seems to not have any.

roblabla avatar Aug 01 '18 15:08 roblabla

No, sorry.

main-- avatar Aug 01 '18 15:08 main--

Another useful call frame instruction that is a GNU extension is DW_CFA_GNU_window_save - the reason is that it has an alias, DW_CFA_AARCH64_negate_ra_state, which is necessary to support unwinding through functions that use the Pointer Authentication extension to the Arm architecture.

akirilov-arm avatar Dec 07 '21 15:12 akirilov-arm