I have this simple C code:
#include "uart.h"
#include <string.h>
char x[32];
__attribute__((noinline))
void foo(void)
{
strcpy(x, "xxxxxxxxxxxxxxxxxxxxxxxx");
}
int main(void)
{
uart_puts("xxx\n");
foo();
uart_puts("yyy\n");
}
compiled as:
$ aarch64-none-elf-gcc t78.c -mcpu=cortex-a57 -Wall -Wextra -g -O2 -c -std=c11 \
&& aarch64-none-elf-ld -T linker.ld t78.o boot.o uart.o -o kernel.elf
and executed as:
$ qemu-system-aarch64.exe -machine virt -cpu cortex-a57 -nographic -kernel kernel.elf
prints:
xxx
Why yyy
is not printed?
By reducing the issue I've found that:
- for
strcpy
GCC generated a code other than "call strcpy" (see below) ldr q1, [x0]
causesyyy
to not be printed.
Here is the generated code of foo
:
foo:
.LFB0:
.file 1 "t78.c"
.loc 1 6 1 view -0
.cfi_startproc
.loc 1 7 5 view .LVU1
adrp x0, .LC0
add x0, x0, :lo12:.LC0
adrp x1, .LANCHOR0
add x2, x1, :lo12:.LANCHOR0
ldr q1, [x0] <<== root cause
ldr q0, [x0, 9]
str q1, [x1, #:lo12:.LANCHOR0]
str q0, [x2, 9]
.loc 1 8 1 is_stmt 0 view .LVU2
ret
If I put ret
before ldr q1, [x0]
the yyy
is printed (ax expected).
The question: why ldr q1, [x0]
causes yyy
to not be printed?
Tool versions:
$ aarch64-none-elf-gcc --version
aarch64-none-elf-gcc.exe (Arm GNU Toolchain 12.2.Rel1 (Build arm-12.24)) 12.2.1 20221205
$ qemu-system-aarch64 --version
QEMU emulator version 7.2.0 (v7.2.0-11948-ge6523b71fc-dirty)