AArch64 and fixed return address register (x30)

Luis Machado luis.machado@arm.com
Fri Jan 6 09:37:58 GMT 2023


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
>>
> 



More information about the Gdb mailing list