0

Follow-up to this question. I'm writing my own (very basic) standard library (compiling with the -nostdlib gcc option). It seems that the base of almost everything is write, read, creat, open, close, etc.

It's my understanding that glibc simply uses stubs, SYSCALL_INTERNAL macros, etc. to provide those functions. I'm not using glibc and I don't want to get very complicated.

My question. How can I call Unix low-level functions such as write and read without glibc?

Community
  • 1
  • 1
MD XF
  • 7,860
  • 7
  • 40
  • 71
  • 1
    All Linux system calls are implemented via `syscall()`. You may either use it directly or look into its source code. Somewhat helpful question: http://stackoverflow.com/questions/10149621/where-can-i-find-system-call-source-code – DYZ Mar 07 '17 at 02:26

1 Answers1

2

You can make system calls directly from assembly language, for example, for Linux x86_64:

main.c:

long mywrite(int, const void *, unsigned long);

int main(void)
{
    char buffer[] = "Hello, world!\n";
    mywrite(1, buffer, 14);
    return 0;
}

write.S:

.global mywrite

.text

mywrite:
        push    %rbp
        mov     %rsp, %rbp
        mov     $1, %rax
        syscall
        leave
        ret

with output:

paul@thoth:~/src/sandbox/syscall$ gcc -o sc main.c write.S
paul@thoth:~/src/sandbox/syscall$ ./sc
Hello, world!
paul@thoth:~/src/sandbox/syscall$ 

Obviously this implementation doesn't set errno or anything like that, but that's unrelated to actually making the system calls. It'll be easier to implement a single syscall() function in assembly, and then have regular C functions to call it.

Crowman
  • 25,242
  • 5
  • 48
  • 56