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.
There is readelf -u in binutils and see https://wiki.linaro.org/KenWerner/Sandbox/libunwind#unwinding_on_ARM (actual spec in http://infocenter.arm.com/help/topic/com.arm.doc.ihi0038a/IHI0038A_ehabi.pdf ). And you can look at .debug_frame tables.
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