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:
www.*x86*-*64*.org/documentation/*abi*.pdf
"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
DW_CFA_nop
DW_CFA_nop
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
DW_CFA_nop
DW_CFA_nop
DW_CFA_nop
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
http://www.freelists.org/post/luajit/Stack-unwinding-problem-on-Solaris-x64,1