2023 10 04 13 30 [linux] 純粹使用syscall.不依賴libc.

原本是要研究如何讓static link程式能不能dlopen一個shared library來使用.
但是gcc -static main.c 就會吐以下的Warnings.
usr/bin/ld: /tmp/cc9fDIEm.o: in function `main':
main.c:(.text+0x50): warning: Using 'dlopen' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking
還是可以compile出來,只是dlopen進來的shared library不能再用到其他的library.
要不然還是會找不到.
所以才參考了glibc source codes.
寫出以下直接call syscall的程式.

#include <stdio.h>
#include <unistd.h>
#include <sys/syscall.h>


#define TYPEFY(X, name) __typeof__ (ARGIFY (X)) name
#define TYPEFY1(X) __typeof__ ((X) - (X))
#define ARGIFY(X) ((TYPEFY1 (X)) (X))

# define REGISTERS_CLOBBERED_BY_SYSCALL "cc", "r11", "cx"

#define my_syscall3(number, arg1, arg2, arg3)                   \
({                                                                      \
    unsigned long int resultvar;                                        \
    TYPEFY (arg3, __arg3) = ARGIFY (arg3);                              \
    TYPEFY (arg2, __arg2) = ARGIFY (arg2);                              \
    TYPEFY (arg1, __arg1) = ARGIFY (arg1);                              \
    register TYPEFY (arg3, _a3) asm ("rdx") = __arg3;                   \
    register TYPEFY (arg2, _a2) asm ("rsi") = __arg2;                   \
    register TYPEFY (arg1, _a1) asm ("rdi") = __arg1;                   \
    asm volatile (                                                      \
    "syscall\n\t"                                                       \
    : "=a" (resultvar)                                                  \
    : "0" (number), "r" (_a1), "r" (_a2), "r" (_a3)                     \
    : "memory", REGISTERS_CLOBBERED_BY_SYSCALL);                        \
    (long int) resultvar;                                               \
})


void foo() {
  my_syscall3(SYS_write, STDOUT_FILENO, "my syscall foo\n", 15);
  printf("call foo\n");
}