Re: Restoring pc to a different value than lr on aarch64
Luis Machado via Gdb <[email protected]>
| Newsgroups | gmane.comp.gdb.devel |
|---|---|
| Message-ID | <[email protected]> |
On 5/6/22 13:46, Yichao Yu via Gdb wrote: > On Fri, May 6, 2022 at 8:05 AM Yichao Yu <[email protected]> wrote: >> >> I have a case in my code where I want to restore the value of lr (x30) >> during unwinding, to a different value than the return address of the >> code. However, it seems that for aarch64, >> (aarch64_dwarf2_frame_init_reg among other functions) hardcode x30 and >> pc to be exactly the same value after unwinding. > > Actually I misspoke for that. It seems that sp is probably fine and > the only thing missing causing pc to not work is that > aarch64_dwarf_reg_to_regnum doesn't understand the PC dwarf reg > number. It seems that the only thing needed is to add a > > + if (reg == AARCH64_DWARF_PC) > + return AARCH64_PC_REGNUM; > > to that function. > Yes, GDB always assumes the PC from the previous frame is the LR from the current frame. That is what GCC generates. If a different setup is needed, GDB needs to be taught about it. >> >> According to aadwarf64[1], >> >>> having both LR and PC columns is useful for describing asynchronously created stack frames. A DWARF expression may use this register to restore the context in case of a signal context. >> >> so assume the intention is that if I explicitly unwind the pc in >> addition to lr, it should work. I tried to do that, and also to set >> return address column to 32, as well as trying to mark the frame as >> signal frame but none of them seems to work. Is there any way for gdb >> to honer the explicit unwinding of pc? >> >> Also it seems that the sp is also card coded to be cfa. My code also >> contains explicit saving and restoring of that as well so if that's >> the case (haven't tested yet) it would be a problem too... >> >> Would it be possible to not use this hard-coded logic if the frame >> contains explicit override of the pc value? >> >> Yichao >> >> A bit more about the actual code. This is done as part of runtime >> patching code. The actual restoration of lr is done by returning to a >> runtime allocated stub that restores lr and directly branch back to >> the return location. After returning, all registers values are >> restored back to their previous one. The stack pointer is also >> switched out since we cannot rely on how much stack space the call >> site has available. This seems to work in a similar way as signal handler. GDB needs to be taught where to find the registers so it can properly unwind things. >> >> [1] https://github.com/ARM-software/abi-aa/blob/8a7b266879c60ca1c76e94ebb279b2dac60ed6a5/aadwarf64/aadwarf64.rst#note-9