@emard 'small' is relative. The cross compiler has >0.5MB of executable; that includes 4 backends (spare, mips, x86 and riscv32) but it will be >0.3MB for sure. Runtime memory use may be double that.
@lawrie @emard I did look a bit more at the toolchain. Compiler, assembler, archiver all appear to work fine. The utils appear to have roots in the ECO32 project: https://github.com/hgeisse/eco32
The riscv32 linker/loader seems to be a custom job. I managed to build a full libc.lib and could link a "hello world" program to an a.out file. That file is ~30KB, as it drags in much of stdio and of the floating point library routines.
As there is no OS, the C library just has stubs for some of the sys calls (https://github.com/michg/riscv32_lcc/blob/master/lcc/bin/libs/stdlib/syscall.c), with I/O hardcoded to a UART.
All in all, the compiler seems fine, but getting it to run on SaxonSoc is not a slam dunk.
make CC=cross-compiler all.
root@buildroot:~# lcc -Wo-lccdir=/riscv32_lcc/lcc/bin -target=riscv32 hello.c Assembling module '/tmp/lcc1441.s'... Reading module '/tmp/lcc1442.o'... Usage: /riscv32_lcc/lcc/bin/../../binutils/bin/ld [-h] do not write object header [-o objfile] set output file name [-m mapfile] produce map file [-rc addr] relocate code segment [-rd addr] relocate data segment [-rb addr] relocate bss segment file object file name [files...] additional object files
root@buildroot:~# dof -a hello.o Header size of code : 48 bytes size of data : 16 bytes size of bss : 0 bytes size of code relocs : 48 bytes size of data relocs : 0 bytes size of symbol table : 48 bytes size of string space : 12 bytes Code Segment 00000000: 13 01 01 FD 23 26 81 02 13 04 01 02 23 2C 11 00 ....#&......#,.. 00000010: 17 06 00 00 13 06 06 00 EF 00 00 00 13 05 00 00 ................ 00000020: 83 20 81 01 03 24 C1 02 13 01 01 03 67 80 00 00 . ...$......g... Data Segment 00000000: 48 65 6C 6C 6F 20 77 6F 72 6C 64 21 0A 00 00 00 Hello world!.... Code Relocation Records 0: offset = 0x00000018 Error: illegal relocation method
Ok. The linker/loader was not integrated with the lcc front end. I've posted a revised unix.c file here: https://gitlab.com/pnru/ulx3s-misc/-/blob/master/tmp/linux.c
This has the default path set to /riscv32_lcc/lcc/bin and adds some forgotten / separators.
It also adapts the options given to ld to something it actually understands. It now tells the linker to look for the library c.lib in the directory "/riscv32_lcc/lcc/bin/../../lib". I.e. that lib needs to be here: /riscv32_lcc/lib/c.lib
ar -r c.lib stdlib/*.o,
ar -r c.lib stdio/*.oetc. with the last one using
ar -rsv c.lib string/*.oto also generate the ranlib index.
There are some quirks in
ld that need fixing (it now leaves a lot of debris when linking stuff from the C library and that debris then messes up subsequent runs). That is not too hard.
Then the C library needs real code in the system call stubs. That is not hard, but I do not know how riskv Linux wants its system calls - presumably the arguments need to go into certain registers and then there has to be a software interrupt or trap of some kind, but I'm blank on specifics. Maybe @Dolu1990 knows.
Is it very difficult to build your linux kernel with support for a.out? Or just a tweak and a compile?
ld -l /riscv32_lcc/lib/c.lib hello.o
root@buildroot:~# ld -l /riscv32_lcc/lib/c.lib hello.o Reading module 'hello.o'... Using Library:/riscv32_lcc/lib/c.lib [ 700.670829] ld: unhandled signal 11 code 0x1 at 0x00e46c30 in libc-2.29.so[3569a000+149000] [ 700.676835] CPU: 2 PID: 124 Comm: ld Tainted: G W 5.0.9 #1 [ 700.682157] sepc: 35711650 ra : 00012a34 sp : 9fe46bb0 [ 700.686248] gp : 0001bd14 tp : 35577de0 t0 : 0001e010 [ 700.690075] t1 : 00010c9c t2 : 00000000 s0 : 9fe46bf0 [ 700.693304] s1 : 9fe46c08 a0 : 00e46c31 a1 : 000249a0 [ 700.698437] a2 : 9fe46c08 a3 : 00000000 a4 : 00000000 [ 700.703855] a5 : 000249a0 a6 : fefefeff a7 : 0000003f [ 700.709083] s2 : 000da247 s3 : 00000000 s4 : 000e1454 [ 700.714653] s5 : 35577e08 s6 : 00000008 s7 : 00000002 [ 700.720056] s8 : 00000014 s9 : 35577e08 s10: 000c08e8 [ 700.725350] s11: 000e49b5 t3 : 3571164c t4 : 0005f1c4 [ 700.730665] t5 : 00000000 t6 : 00000000 [ 700.735003] sstatus: 00000020 sbadaddr: 00e46c30 scause: 0000000d Segmentation fault
root@buildroot:~# lcc -v -Wo-lccdir=/riscv32_lcc/lcc/bin -target=riscv32 hello.c lcc $Id$ /riscv32_lcc/lcc/bin/ucpp -DLANGUAGE_C -D_LANGUAGE_C -DUNIX -D_UNIX -Dunix -zI -D__LCC__ -I/riscv32_lcc/lcc/bin/include hello.c -o /tmp/lcc1340.i /riscv32_lcc/lcc/bin/rcc -target=riscv32 -v -target=riscv32 /tmp/lcc1340.i /tmp/lcc1341.s /riscv32_lcc/lcc/bin/rcc $Name$($Id$) /riscv32_lcc/lcc/bin/../../binutils/bin/as -o /tmp/lcc1342.o /tmp/lcc1341.s Assembling module '/tmp/lcc1341.s'... /riscv32_lcc/lcc/bin/../../binutils/bin/ld -o a.out -l /riscv32_lcc/lcc/bin/../../lib/c.lib -L/riscv32_lcc/lcc/bin Usage: /riscv32_lcc/lcc/bin/../../binutils/bin/ld [-h] do not write object header [-o objfile] set output file name [-m mapfile] produce map file [-rc addr] relocate code segment [-rd addr] relocate data segment [-rb addr] relocate bss segment file object file name [files...] additional object files rm /tmp/lcc1342.o /tmp/lcc1340.i /tmp/lcc1341.s
-Wo-lccdir=/riscv32_lcc/lcc/bin -target=riscv32either anymore. That is now the default. I forgot to remove this line: