Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support GNU extensions to CFI #130

Open
fitzgen opened this issue Sep 25, 2016 · 9 comments
Open

Support GNU extensions to CFI #130

fitzgen opened this issue Sep 25, 2016 · 9 comments

Comments

@fitzgen
Copy link
Member

fitzgen commented Sep 25, 2016

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
Copy link
Member Author

fitzgen commented Sep 25, 2016

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.

@roblabla
Copy link
Contributor

roblabla commented Aug 1, 2018

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?

@main--
Copy link
Contributor

main-- commented Aug 1, 2018

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)?

@roblabla
Copy link
Contributor

roblabla commented Aug 1, 2018

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

@roblabla
Copy link
Contributor

roblabla commented Aug 1, 2018

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

@main--
Copy link
Contributor

main-- commented Aug 1, 2018

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

@roblabla
Copy link
Contributor

roblabla commented Aug 1, 2018

🤷‍♂️

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.

@main--
Copy link
Contributor

main-- commented Aug 1, 2018

No, sorry.

@akirilov-arm
Copy link

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants