Implementing syscalls for libc

If you try to use C-library functions such as malloc() or printf(), link fails with these since they depends on these system calls.

/home/sokoide/cross/rpi/arm-unknown-eabi/arm-unknown-eabi/lib//libc.a(lib_a-sbrkr.o): In function `_sbrk_r':
sbrkr.c:(.text+0x18): undefined reference to `_sbrk'
/home/sokoide/cross/rpi/arm-unknown-eabi/arm-unknown-eabi/lib//libc.a(lib_a-writer.o): In function `_write_r':
writer.c:(.text+0x20): undefined reference to `_write'
/home/sokoide/cross/rpi/arm-unknown-eabi/arm-unknown-eabi/lib//libc.a(lib_a-closer.o): In function `_close_r':
closer.c:(.text+0x18): undefined reference to `_close'
/home/sokoide/cross/rpi/arm-unknown-eabi/arm-unknown-eabi/lib//libc.a(lib_a-fstatr.o): In function `_fstat_r':
fstatr.c:(.text+0x1c): undefined reference to `_fstat'
/home/sokoide/cross/rpi/arm-unknown-eabi/arm-unknown-eabi/lib//libc.a(lib_a-isattyr.o): In function `_isatty_r':
isattyr.c:(.text+0x18): undefined reference to `_isatty'
/home/sokoide/cross/rpi/arm-unknown-eabi/arm-unknown-eabi/lib//libc.a(lib_a-lseekr.o): In function `_lseek_r':
lseekr.c:(.text+0x20): undefined reference to `_lseek'
/home/sokoide/cross/rpi/arm-unknown-eabi/arm-unknown-eabi/lib//libc.a(lib_a-readr.o): In function `_read_r':
readr.c:(.text+0x20): undefined reference to `_read'

We can’t use OS’s syscalls obviously since there is no OS. The book suggested to implement it by reffering to ~/cross/src/ct-ng_rpi/.build/src/newlib-1.20.0/newlib/libc/sys/arm/syscalls.c.

I implemented a stub and wrote _write as below. Since there is no stdout yet, I only copied it in memory and confirmed it in gdb + arm sim.

_write in syscalls.c:

int _write(int file, char *ptr, int len) {
  // TODO:
  for (int i = 0; i < len; i++) {
    _write_memory(ptr[i]);
  }
  return len;
}

_writememory in startup.s: only to confirm it's called with a right character

_write_memory:
  bx  lr

confirmation: tried to confirm with arm sim on gdb, and got this. It looks it's not implemented in arm sim.

(gdb) target sim
Connected to the simulator.
(gdb) load hoge.elf
Loading section .text, size 0x8cf0 vma 0x8000
Loading section .rodata, size 0xa48 vma 0x10cf0
Loading section .rodata.str1.4, size 0xc vma 0x11738
Loading section .rodata.str1.1, size 0x4b vma 0x11744
Loading section .ARM.exidx, size 0x8 vma 0x11790
Start address 0x8000
Transfer rate: 310456 bits in <1 sec.
(gdb) file hoge.elf
Reading symbols from hoge.elf...done.
(gdb) b _write_memory
Breakpoint 1 at 0x8020
(gdb) start
Temporary breakpoint 2 at 0x808c
Starting program: /media/psf/Dropbox/workspace/arm/rpi-baremetal/002/hoge.elf 

Temporary breakpoint 2, 0x0000808c in main ()
(gdb) c
Continuing.
Unhandled v6 thumb insn: 4601
[Inferior 1 (process 42000) exited with code 0215]

Uploaded above at https://github.com/sokoide/rpi-baremetal -> 002_libcstub.

Leave a Reply

Your email address will not be published. Required fields are marked *