Re: Running programs on aarch64 simulator

Joel Sherrill
2020-05-08T16:57:33Z

On Fri, May 8, 2020 at 11:09 AM Simon Marchi <simark@simark.ca> wrote:

> On 2020-05-08 9:44 a.m., Joel Sherrill wrote:
> > Hi
> >
> > Can someone please provide an example of how to compile a program to run
> on
> > the aarch64 simulator in gdb? The simple "aarch64-elf main.c -o main"
> does
> > not link and appears to be missing libgloss type symbols.
> >
> > I asked on newlib but got no response. I'm hoping someone here knows.
> >
> > Thanks.
> >
> > --joel
> > RTEMS
> >
>
> Hi Joel,
>
> If I just compile a "main" function with the bare-metal aarch64 or arm
> compiler, it does indeed
> complain about a missing _exit function:
>
> <snip>/gcc/aarch64-none-elf/9.2.1/../../../../aarch64-none-elf/lib/libg.a(lib_a-exit.o):
> in function `exit':
> <snip>/build/src/newlib-cygwin/newlib/libc/stdlib/exit.c:64: undefined
> reference to `_exit'
>
> I think this is expected, as the runtime requires you to provide some
> implementation for _exit,
> in other words what you want to do when the program has finished. Maybe
> shut down the board,
> reset it, shut down the simulator, that's use case-specific. libgloss
> indeed provides an
> implementation, so I guess you could include that in your program:
>
>
> https://sourceware.org/git/?p=newlib-cygwin.git;a=blob;f=libgloss/aarch64/_exit.c;h=16564bbdaaaa3fa20c68198903432dfbf7f768a7;hb=HEAD
>
> But for the GDB simulator, you can just provide a simple implementation of
> _exit. In my case,
> I just defined it as an empty loop, but maybe there's a way to signal the
> simulator to shut
> down, I don't know.
>

On all the elf/eabi targets I have tried over the years, CPU-elf-gcc
produced an a.out that was linked with the installed libgloss. I randomly
had an sh-elf toolchain laying around and it worked like "sh-elf-gcc m.c"
and then both sh-elf-gdb and sh-elf-run could run it on the gdb simulator.

The aarch64-elf toolchain installs 4 .specs files from libgloss but adding
-specs XXX and trying each with the gdb simulator (via aarch64-elf-run) all
fail.

home/joel/test-gcc/install-master/aarch64-elf/lib/aem-validation.specs
/home/joel/test-gcc/install-master/aarch64-elf/lib/aem-ve.specs
/home/joel/test-gcc/install-master/aarch64-elf/lib/nosys.specs
/home/joel/test-gcc/install-master/aarch64-elf/lib/rdimon.specs

This seems to be an odd case where there is a simulator in the source tree
and there is no clear way to use it. Assuming it works.

Looks like Nick Clifton added it back in 2015. Surely he had a way to run
programs on it. :)

> ---
> void _exit(int status)
> {
> for (;;);
> }
>
> int x = 0;
>
> int main(void)
> {
> for (int i = 0; i < 1000; i++) {
> x++;
> }
> return 0;
> }
> ---
>
> Compiled with:
>
> $ aarch64-none-elf-gcc test.c -g3 -O0 -o test
>
> or
>
> $ arm-none-eabi-gcc test.c -g3 -O0 -o test
>
> With my arm binary, here's how I can run it with the simulator:
>
> $ ./gdb -nx -q --data-directory=data-directory ./test -ex "target sim" -ex
> "load" -ex "b main" -ex "run"
> Reading symbols from ./test...
> Connected to the simulator.
> Loading section .init, size 0x18 lma 0x8000
> Loading section .text, size 0x630 lma 0x8018
> Loading section .fini, size 0x18 lma 0x8648
> Loading section .rodata, size 0x4 lma 0x8660
> Loading section .ARM.exidx, size 0x8 lma 0x8664
> Loading section .eh_frame, size 0x4 lma 0x866c
> Loading section .init_array, size 0x4 lma 0x18670
> Loading section .fini_array, size 0x4 lma 0x18674
> Loading section .data, size 0x430 lma 0x18678
> Start address 0x8128
> Transfer rate: 21824 bits in <1 sec.
> Breakpoint 1 at 0x824c: file test.c, line 10.
> Starting program: /home/smarchi/build/binutils-gdb-target-arm/gdb/test
>
> Breakpoint 1, main () at test.c:10
> 10 for (int i = 0; i < 1000; i++) {
> (gdb) n
> 11 x++;
> (gdb)
> 10 for (int i = 0; i < 1000; i++) {
>
> I tried to build a GDB for the AArch64 target, but it did not include the
> simulator. I then
> did the following change to enable it:
>
> diff --git a/gdb/configure.tgt b/gdb/configure.tgt
> index b3f31af763c..1dcd153f52f 100644
> --- a/gdb/configure.tgt
> +++ b/gdb/configure.tgt
> @@ -114,6 +114,7 @@ case "${targ}" in
> aarch64*-*-elf | aarch64*-*-rtems*)
> # Target: AArch64 embedded system
> gdb_target_obs="aarch64-newlib-tdep.o"
> + gdb_sim=../sim/aarch64/libsim.a
> ;;
>
> This got me a GDB for the AArch64 target with simulator support. However,
> it does not
> run correctly:
>
> $ ./gdb -nx -q --data-directory=data-directory ./test -ex "target sim" -ex
> "load" -ex "b main" -ex "run"
> Reading symbols from ./test...
> Connected to the simulator.
> Loading section .init, size 0x34 lma 0x400000
> Loading section .text, size 0x67c lma 0x400040
> Loading section .fini, size 0x34 lma 0x4006bc
> Loading section .rodata, size 0x58 lma 0x4006f0
> Loading section .eh_frame, size 0x4 lma 0x400748
> Loading section .init_array, size 0x8 lma 0x410750
> Loading section .fini_array, size 0x8 lma 0x410758
> Loading section .data, size 0x758 lma 0x410760
> Start address 0x400168
> Transfer rate: 30016 bits in <1 sec.
> Breakpoint 1 at 0x4001e8: file test.c, line 10.
> Starting program: /home/smarchi/build/binutils-gdb-target-aarch64/gdb/test
> core: 8 byte write to unmapped address 0xfffffff0 at 0x0
>
> Program received signal SIGSEGV, Segmentation fault.
> 0x0000000000000000 in ?? ()
>

That matches what luck I had on master. I suspect that is a mismatch between
the address map of the simulator and whatever the default linker script
does.

>
> I did not push the investigation further.
>

I think Nick may be the key to getting an answer here.

Thanks.

--joel

>
> Simon
>