Hacker News new | past | comments | ask | show | jobs | submit login
Linux/ELF .eh_frame from the bottom up (corsix.org)
105 points by ingve 11 months ago | hide | past | favorite | 11 comments



Wow.

I had to figure all of this out a few years ago and would have really benefitted from the author's clear, precise take.

This is going into the onboarding docs for my team tomorrow morning.


May I ask what sort of work/code your team works on? Sounds wild/interesting.


Just about anyone who works on a profiler for native binaries has to solve this eventually. We had to as well for our eBPF-based profiler: https://www.polarsignals.com/blog/posts/2022/11/29/dwarf-bas...


Distributed tracing x security. It is pretty wild for sure.


> In most cases, if a function modifies a non-volatile register, it'll save it to somewhere on the stack before modifying it. Upon function return, it'll re-load the value from said stack slot

Dumb question: is this a linux specific calling convention thing (I know prologue/epilogue don't mess with random registers, so i'm a bit confused)? Why shouldn't the caller save all the registers it needs instead of relying on the good behavior of the callee?

When I call certain syscalls (Linux/x64), if I have data in certain registers, the kernel does not preserve and restore the data but it garbles it up. Is there documentation/convention somewhere describing which registers are considered volatile by the ABI or do people find out the hard way normally?


> Why shouldn't the caller save all the registers it needs instead of relying on the good behavior of the callee?

You've got to rely on good behavior of the callee in general anyway. Calling conventions are part of the ABI and the caller and callee already need to agree on parameter passing (except for void(void) functions, which usually aren't much fun).

Picking which registers are callee saved and which are caller saved is roughly an optimization problem. Compilers don't have enough information to know what registers the callee (and its callees) actually use, so the caller can't save only the registers it has used that will definitely be trashed. Caller saving registers that the callee doesn't touch wastes code size, stack space, cpu time, and memory/cache bandwidth; same for callee saving registers the caller didn't need to be saved. So somebody puts together a convention that says these registers are super handy and most functions will want to use them --- those will be caller saved if necessesary. The other registers are deemed to be less likely to be used, callees will save them before using, just in case.

Syscalls may often have a different calling convention than library calls, because the needs are different.

There's some docs on syscall ABIs for Linux, but I didn't find one for x86, here's the docs for PPC though: https://www.kernel.org/doc/html/v6.2/powerpc/syscall64-abi.h...


Thank you, that helped me wrap my head around the concept!


On x86-64: r12, r13, r14, r15, rbx, rsp, rbp are callee-saved. See:

https://stackoverflow.com/questions/18024672/what-registers-...

> Why shouldn't the caller save all the registers it needs instead of relying on the good behavior of the callee?

The cost to save a register is non-zero so it's helpful to have some registers the caller doesn't have to preserve and that don't need to be saved by the callee if it won't be using them.

https://stackoverflow.com/questions/65864046/why-make-some-r...


Linux uses the sysv calling convention. I believe these are the official or semi-official documents for x86 64-bit and 32-bit, respectively:

https://gitlab.com/x86-psABIs/x86-64-ABI (Table 3.4 in section 3.2.3 lists which registers may be clobbered and which must be saved) https://gitlab.com/x86-psABIs/i386-ABI

I'd be very surprised if Windows didn't have both caller-save and callee-save registers.


As I have been learning about stack unwinding and how it works, I really feel like this is quite the wizardary that is amazing it all works.


I suppose this is one of many reasons why pretty much everything exposes a C API/ABI for FFIs.




Consider applying for YC's Spring batch! Applications are open till Feb 11.

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: