x86_64 unwinder in libgcc_s

Dmitri Shubin sbn@tbricks.com
Thu Aug 16 08:10:00 GMT 2012

On 14.08.2012 17:58, Ian Lance Taylor wrote:
> unwinder is right and libgcc_s one is wrong.
> I think the definition of _Unwind_GetCFA is ambiguous.  It says "the
> value of %rsp at the call site in the previous frame."  GCC is
> returning the value of %rsp at the point of the call to throw.
> Solaris is returning the value of %rsp at the call to foo.  I don't
> know which is correct.  _Unwind_GetCFA is not part of the C++
> exception handling ABI; I'm not sure where it came from.
_Unwind_GetCFA() is defined in x86_64 psABI: 
"6.2 Unwind Library Interface"

In my example foo_personality() is set as personality routine for foo() 
so I assume the former is called with _Unwind_Context created for foo()
I.e. foo()'s stack frame is 'current' and from this pov the value of 
'previous frame' is unambiguous -- it's main()'s frame.

BTW dwarf unwinding instructions generated by GCC use CFA-relative 
addresses to locate registers saved on stack frame:

$ cat a.c
void foo()
$ /opt/csw/bin/gcc -m64 -c a.c
$ gobjdump -dr a.o

a.o:     file format elf64-x86-64-sol2

Disassembly of section .text:

0000000000000000 <foo>:
    0:   55                      push   %rbp
    1:   48 89 e5                mov    %rsp,%rbp
    4:   5d                      pop    %rbp
    5:   c3                      retq
$ gobjdump -Wf a.o

a.o:     file format elf64-x86-64-sol2

Contents of the .eh_frame section:

00000000 00000014 00000000 CIE
   Version:               1
   Augmentation:          "zR"
   Code alignment factor: 1
   Data alignment factor: -8
   Return address column: 16
   Augmentation data:     1b

   DW_CFA_def_cfa: r7 (rsp) ofs 8
   DW_CFA_offset: r16 (rip) at cfa-8

00000018 0000001c 0000001c FDE cie=00000000 pc=00000000..00000006
   DW_CFA_advance_loc: 1 to 00000001
   DW_CFA_def_cfa_offset: 16
   DW_CFA_offset: r6 (rbp) at cfa-16
   DW_CFA_advance_loc: 3 to 00000004
   DW_CFA_def_cfa_register: r6 (rbp)
   DW_CFA_advance_loc: 1 to 00000005
   DW_CFA_def_cfa: r7 (rsp) ofs 8

Here CIE specifies that right before executing first instruction of 
foo() CFA is RSP+8 and return address is stored at offset -8 from CFA.

> Why do you want the CFA?  Perhaps you can use _Unwind_GetGR or other
> functions that are part of the C++ exception interface?

It's not me, it's author of LuaJIT who use CFA to get some state 
information from stack frame.
Here is his reply to my question about unwinding problem on Solaris x64

More information about the Gcc mailing list