Hi Roland,
IIUC your mail is talking about what return_address_register means in DWARF.
But DWARF return_address_register does not need to be guessed by elfutils, it
is always present in CIE, if there is any DWARF FDE/CIE found.
The discussion here was what elfutils ebl_abi_cfi() should return (what is the
"elfutils return_address_register"). That is described in elfutils by:
libebl/libebl.h:
This function can also fill in ABI_INFO->return_address_register with the
DWARF register number that identifies the actual PC in machine state.
If there is no canonical DWARF register number with that meaning, it's
left unchanged (callers usually initialize with (Dwarf_Word) -1).
This value is not used by CFI per se.
This would correspond to your suggested value 15 (PC) for ARM.
But no elfutils code uses that value. I have no idea if systemtap uses it.
Besides that .ARM.exidx assumes return address is in LR plus .debug_frame has
return address set to LR by GCC:
Return address column: 14
I have included an example ARM output at the bottom of this mail.
Existing CIEs do not matter much for the elfutils return_address_register
value, as you wrote below:
On Thu, 29 Aug 2013 22:32:31 +0200, Roland McGrath wrote:
But that's really neither here nor there. It doesn't matter
what the
compiler does for some particular FDEs (or for all that it emits). All that
matters is that the number you choose for a particular CIE is the one that
its FDEs describe correctly for rematerializing the return address
I agree elfutils return_address_register does not matter for CIE as CIE
contains its own value. Then remains the question what is elfutils
return_address_register good for.
My unwinder patchset keeps PC value independently from the DWARF register set
as some archs (ppc/s390) do not have any DWARF register assigned for PC.
Thanks for the pointers, great info.
mov r0, lr
mov lr, #0
bx r0
Now, it would be correct enough to say that return_address_register is r0,
that r0's rule is same-value, and that lr's rule is undefined (or is
register r0, if you like). That is not entirely precise, since it says the
caller's value of r0 was knowable when in fact it's undefined. But as to
the return address and lr, it's perfectly correct and precise. In actual
fact, the compiler would never generate code like that because the hardware
makes it optimal always to use "bx lr" for return (it has a call/return
prediction stack and "bx lr" is specifically recognized as
"return").
So it's not really clear which is "better", because it depends on what
your
goals are.
The goal is IMO to unwind as much inferior code as possible.
You are describing various non-standard ARM code cases. But those should have
their own .ARM.exidx or .debug_frame entry so elfutils return_address_register
does not matter then.
In the example below with -fasynchronous-unwind-tables it does not matter what
elfutils return_address_register is set to. But without
-fasynchronous-unwind-tables the unwind will be successful only if elfutils
return_address_register is set to 14 (when .debug_frame is not available).
Discussing hypothetical unwinder (maybe the systemtap one behaves that way?).
My current pending elfutils unwinder aborts unwind if neither .eh_frame nor
.debug_frame is found as it expects -fasynchronous-unwind-tables is in use.
Thanks,
Jan
000084d4 <main>:
84d4: e52db004 push {fp} ; (str fp, [sp, #-4]!)
84d8: e28db000 add fp, sp, #0
84dc: e3a03000 mov r3, #0
84e0: e1a00003 mov r0, r3
84e4: e24bd000 sub sp, fp, #0
84e8: e49db004 pop {fp} ; (ldr fp, [sp], #4)
84ec: e12fff1e bx lr
000084f0 <__libc_csu_init>:
Unwind table index '.ARM.exidx' at offset 0x568 contains 5 entries:
This entry is present only with -fasynchronous-unwind-tables:
0x84d4 <main>: 0x809b8080
Compact model index: 0
0x9b vsp = r11
0x80 0x80 pop {r11}
Contents of the .debug_frame section:
00000000 0000000c ffffffff CIE
Version: 1
Augmentation: ""
Code alignment factor: 2
Data alignment factor: -4
Return address column: 14
DW_CFA_def_cfa: r13 ofs 0
00000010 00000014 00000000 FDE cie=00000000 pc=000084d4..000084f0
DW_CFA_advance_loc: 4 to 000084d8
DW_CFA_def_cfa_offset: 4
DW_CFA_offset: r11 at cfa-4
DW_CFA_advance_loc: 4 to 000084dc
DW_CFA_def_cfa_register: r11