3 ms·
This would be a portable C (i.e. non x86-64, but still Linux) with just 2 syscalls: $ cat a.c #define _GNU_SOURCE #include <unistd.h> #include <sys/sys
by jagrsw 7y ago
This would be a portable C (i.e. non x86-64, but still Linux) with just 2 syscalls:
$ cat a.c
#define _GNU_SOURCE
#include <unistd.h>
#include <sys/syscall.h>
void _start(void) {
syscall(__NR_write, 1, "Hello world!\n", 13);
syscall(__NR_exit_group, 1);
}
$ gcc -nostartfiles a.c -o a -static
$ ls -l a
-rwxr-xr-x 1 user user 9584 jan 5 00:07 a
$ strip -s a; ls -l a
-rwxr-xr-x 1 user user 9000 jan 5 00:10 a
$ strace ./a
execve("./a", ["./a"], 0x7ffd4d4f8250 /* 67 vars */) = 0
write(1, "Hello world!\n", 13) = 13
exit_group(1) = ?
+++ exited with 1 +++
I'm not actually sure why syscall() is inlined and glibc code is not included here while compiling with -static, but well, it works. Maybe it's because syscall() is a macro, or maybe it's some kind of ld code minimization (removing unused/unreachable code) trick which seems to be common in modern static linkers (ld, gold, lld).
- sandov 7y ago> portable > #define _GNU_SOURCE If it's portable, what's the point of defining _GNU_SOURCE? Honest question.
- saagarjha 7y agoI’m not sure why they aren’t using the SYS_* constants either.
- jagrsw 7y agoYup, it'd make it (also using SYS_exit instead of SYS_exit_group) compilable under various *BSD OSes. Doesn't work for some reason under NetBSD due to some linking problem producing invalid binary for the platform. $ gcc -nostartfiles a.c -o a -Wl,--entry=_start -static $ ./a -bash: ./a: cannot execute binary file: Exec format error $ file a a: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), statically linked, not stripped\ But the final binary is impressively small, and it seem to contain all relevant code (body of _start and syscall funcs) $ strip -s a; ls -l a -rwxr-xr-x 1 user users 2688 Jan 5 07:53 a Works under FreeBSD though: $ clang -nostartfiles a.c -o a -static $ ./a Hello world! $ strip -s a; ls -l a -rwxr-xr-x 1 user user 9216 Jan 5 07:59 a
- deleted 7y ago[deleted]
- jagrsw 7y agoIt's 'portable' as originally stated, across various Linux CPU archs. _GNU_SOURCE is requested by man 2 syscall. Interestingly it mentions it appeared in 4BSD, so possibly it might work (maybe with some changes) under other Unixy platforms.