* Re: AArch64 and fixed return address register (x30)
[not found] ` <d394976c-451b-cfd6-a8dc-3ad715221024@gmail.com>
@ 2023-01-06 9:37 ` Luis Machado
0 siblings, 0 replies; 3+ messages in thread
From: Luis Machado @ 2023-01-06 9:37 UTC (permalink / raw)
To: Sylwester Garncarek, gdb
Hi Sylwester,
On 1/6/23 07:08, Sylwester Garncarek wrote:
> Hi Luis,
>
> Thank you for pointing me to this commit. I cloned recent sources and I built GDB (before I was using GDB 12.1 sources). The stack looks good now when I can explicitly set the PC.
>
Great. Thanks for checking and for all the useful info. There might be a genuine bug here indeed. Or rather a limitation of the way things were implemented.
Let me take a look at this first, and I'll get back to you. We might need to open a bug to track this.
Regards,
Luis
> The issue with return address is solved, but now another problem came out. As part of interrupt/exception handling, the RTOS switches stacks. I modified the test source code to show how such task switching works (I'm not restoring the SP later as test_func4 ends up in a dead loop anyway). I'm using x29 register to hold the old stack pointer and I let unwinder know where it can find it:
>
> mov x29, sp
> mov sp, #0x0e000000 //switch stack to 0x0e200000 (also secure RAM in QEMU)
> add sp, sp, #0x200000
> .cfi_def_cfa x29, 16
>
> This is nothing special and I was expecting it to work, however the stack is not complete (please see the screenshot from GDB). I also tested it with Lauterbach's Trace32 ARM Simulator, and stack is being correctly unwinded (also on attached screenshot). To make sure that return address to "test_func()" function is actually taken from the old stack, I destroyed that return address in memory and stack indeed got corrupted, which confirms, that Trace32 correctly understands this stack switching so CFI directives must be correct.
>
> I attached the modified test source code, linker script for QEMU virt target (CortexA53) and Makefile to build it.
>
> The launch command for QEMU is:
>
> qemu-system-aarch64.exe -M virt ^
> -cpu cortex-a53 ^
> -m 3G ^
> -bios gdb-test.bin ^
> -S ^
> -gdb tcp:192.168.2.100:3117 ^
> --machine virtualization=on,secure=true,gic-version=3 ^
> -smp 1
>
> Maybe someone knows how GDB deals with cfi_def_cfa directives and could help here.
>
>
> BTW: The test source (gdb\testsuite\gdb.arch\aarch64-unwind-pc.S) is not correct, because following three lines:
>
> .cfi_def_cfa sp, 16
> .cfi_offset x29, 0
> .cfi_offset x30, 8
>
> should look like this:
>
> .cfi_def_cfa sp, 16
> .cfi_offset x29, -16 <------
> .cfi_offset x30, -8 <-------
>
> The offset in .cfi_offset directive should be relative to sp+16, not just sp.
>
>
> Thanks,
> Sylwester
>
>
>> Hi,
>>
>> On 1/3/23 00:50, Sylwester Garncarek via Gdb wrote:
>>> Hi All,
>>>
>>> I've been working on adding CFI directives to assembler sources (GNU Asm) of an RTOS and I noticed that GDB seems to ignore .cfi_return_column directive. I checked GDB sources and indeed for AArch64 architecture the return address is fixed to x30 register. Normally this is not a problem, but for exception/interrupt the return address is in ELR_mode register. Because GDB is fixed to x30, there is no way to get a valid call stack. Are there any plans to make the return address register adjustable according to the info provided in DWARF data?
>>
>> It used to be the case that gdb only restored the PC from x30. A recent (ish) patch (1fe8486103e482bcd6cd74fdbf79a7d2ab9b111f) adjusted gdb so the PC can be explicitly set.
>>
>> You can check how the test does it, and replicate the CFI (gdb.arch/aarch64-unwind-pc.S). From what I recall, gdb was taught about the existence of a formal PC column, which is documented in the aadwarf64 spec [1].
>>
>> Hopefully that will be useful for your use case.
>>
>> [1] https://github.com/ARM-software/abi-aa/blob/2022Q1/aadwarf64/aadwarf64.rst#dwarf-register-names
>>
>>>
>>> Thanks,
>>> Sylwester
>>
>
^ permalink raw reply [flat|nested] 3+ messages in thread