How to compile and run an executable in gem5 syscall emulation mode with se.py?

Minimal working Ubuntu setup

First beware of one thing: a dynamically linked executable first runs the dynamic loader, which means a lot more startup instructions in addition to a static ELF’s pre main stuff. Therefore if you have a small userland test, and this time difference happens to happen across the “5 seconds to 50 seconds” barrier, it could destroy your productivity as you iterate an emulator/testcase patch with that testcase. I have observed for example a C++ hello world debug builds in which DerivO3CPU runs a static executable in 6 seconds, and a dynamic one in 150 seconds!

As of gem5 8162e0da0285d346046151b2a45ceeb1baf63b8f Oct 2018, a C hello world for all of x86, arm and aarch64 just works on both Ubuntu 16.04 and 18.04. x86 was working previously, but that commit finalized some required arm changes to make the glibc int code run before main work properly.

Given that gem5 version and one of those Ubuntu versions, you can run the following C program:

main.c

#include <stdio.h>

int main(int argc, char **argv) {
    size_t i;
    for (i = 0; i < (size_t)argc; ++i)
        printf("%s\n", argv[i]);
    return 0;
}

simply as:

sudo apt-get install gcc
gcc -O0 -ggdb3 -std=c99 -static -o x86.out main.c
build/X86/gem5.opt \
  configs/example/se.py \
  -c x86.out \
  -o 'asdf qwer' \
;

sudo apt-get install gcc-arm-linux-gnueabihf
arm-linux-gnueabihf-gcc -O0 -ggdb3 -std=c99 -static -o arm.out main.c
build/ARM/gem5.opt \
  configs/example/se.py \
  -c arm.out \
  -o 'asdf qwer' \
;

sudo apt-get install gcc-aarch64-linux-gnu
aarch64-linux-gnu-gcc -O0 -ggdb3 -std=c99 -static -o aarch64.out main.c
build/ARM/gem5.opt \
    configs/example/se.py \
    -c aarch64.out \
    -o 'asdf qwer' \
;

and in all cases produces the correct output:

asdf
qwer

-static was required on ARM as mentioned at: How to run a dynamically linked executable syscall emulation mode se.py in gem5? Although it is not required anymore, it still requires less CLI options and is easier to use.

Ubuntu cross compiler installation is also mentioned at: How to compile and run an executable in gem5 syscall emulation mode with se.py?

There are also some gem5 in-tree user examples, some of which with proper cross compilation support, under tests/test-progs.

If anyone finds a setup at a newer gem5 revision or Ubuntu version for which such minimal C program does not execute correctly in one of the previously mentioned arches, please send an email describing your system setup in detail to the mailing list and CC me.

Missing syscalls

Then of course, as you try to run more complex userland programs, you will inevitably meet unimplemented syscalls, as there are many of those.

Please don’t report those as bugs unless they appear on the glibc setup code for a minimal C example, since we already have a list of the missing syscalls on the source code itself.

Rather, don’t be put off, and try a patch!

Many of the syscalls are trivial to implement, see for example 8162e0da0285d346046151b2a45ceeb1baf63b8f.

Also, alternatively, you can just mark syscalls as ignored with ignoreFunc, if you think skipping them won’t affect execution significantly, see e.g.: https://github.com/gem5/gem5/blob/8162e0da0285d346046151b2a45ceeb1baf63b8f/src/arch/arm/linux/process.cc#L161

Only then, if you have tried a patch, but failed, start pinging people on the mailing list and asking for guidance on how to make your patch work.

Related:

Multi-threading

TODO this is a known major pain point. I don’t know what the status is, but I’ve heard it is flaky.

Recent fixes that made ARM work

As things inevitably break again, you might be able to take some inspiration from the following fixes that we have done, and possibly patch the problem yourself:

crosstool-NG

Using crosstool-NG to enable ulibc instead of glibc can sometimes serve as a workaround for glibc init code, since ulibc is more minimal an exercises less code than glibc. It is not ideal, but might work if you really can’t manage to patch gem5. Described at: How to solve “FATAL: kernel too old” when running gem5 in syscall emulation SE mode?

Another possibility is to use the crosscompilers built by Buildroot if you also need to generate full system images from scratch, see this example.

There are also some in-tree scripts to build across compiler under: util/build_cross_gcc but I would just use crosstool-NG which factors out maintenance of cross compilers with other projects.

Leave a Comment