The register numbering is different between frysk-imports/lib/unwind/RegisterX86.java (ebp=6) and frysk-imports/libunwind/src/x86/unwind_i.h (ebp=5). frysk-imports/lib/unwind/RegisterAMD64.java (rbp=6) and frysk-imports/libunwind/src/x86_64/unwind_i.h (rbp=6) match.
There are at least the following register orderings below. For expression evaluation remapping is done to go from unwind to dwarf. CoredumpAction.java does remapping to go to user.h ordering. Perhaps we need a generic way to do this? dwarf dwarf unw unw user.h user.h 686 68664 686 68664 68664 686 eax %rax eax rax r15 ebx ecx %rbx edx rdx r14 ecx edx %rcx ecx rcx r13 edx ebx %rdx ebx rbx r12 esi esp %rsi esi rsi rbp edi ebp %rdi edi rdi rbx ebp esi %rbp ebp rbp r11 eax edi %rsp esp rsp r10 ds eip %r8 eip r8 r9 es eflags %r15 eflags r9 r8 fs cs %rip trapno r10 rax gs ss %eflags st0 r11 rcx orig_eax ds %cs st1 r12 rdx eip es %ss st2 or13 rsi cs fs %ds rdi eflags gs %es esp
The players: -> .debug_info This contains location expressions (and location lists) that describe how to find the value of a variable. They use ISA's DWARF 2 ABI register numbers when needing to refer to a value in a register of a given frame. -> .debug_frame This contains unwind information that makes it possible to re-construct the value of registers (at least most) for a given frame. The frame, with the re-constructed register values, is then used by location expressions. Again the registers are (ignoring gcc bugs :-) numbered using the ISA's DWARF 2 ABI register numbering. -> libunwind Libunwind, has its own idea of how to number registers that doesn't correspond to DWARF 2. Internally, libunwind maps to/from DWARF 2 register numbers, and assumes its call-backs do similar mapping onto ISA registers. For 32on64, libunwind _should_ be using 32-bit register numbers? -> frysk.proc.Task.registers The "hardware" or "raw" registers. These are the registers as defined by the ISA and it is the ISA that specifies how to layout the register buffer. -> ptrace or core The interface for hardware registers. These provide a mechanism for supplying the ISA registers to each task. -- From the point-of-view of .debug_info, the code needs to ensure that it is consistently mapping its DWARF 2 ABI register numbers to that of libunwind. That is, uses an ABI method to project the dwarf 2 number onto the libunwind number. libunwind then uses its internal register numbers to do magic, and using callbacks to request corresponding ISA registers. Importantly, 32on64 libunwind should talk pure i368. The task then takes the ISA register and projects it onto the underlying ptrace or core layout.
commit 36cbe1fc173c54cd2936407a54ab7a45fd0612a9 Author: Nurdin Premji <npremji@redhat.com> Date: Wed Aug 1 18:50:15 2007 +0000 frysk-core frysk/debuginfo/CL * DebugInfoEvaluator.java (AccessMemory.getBufferAddr): Use DwarfRegisterMapsFactory. (AccessRegisters.getRegister): Added. (getReg): Use getRegister. (getByte): Use Frame.getRegisterValue instead of Frame.getRegister. (getDouble): Ditto. (getFloat): Ditto. (getInt): Ditto. (getLong): Ditto. (getShort): Ditto. * DwarfRegisterMapFactory.java: Added.