This is the mail archive of the mailing list for the GCC project.

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: x86_64 unwinder in libgcc_s

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

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,1

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]