Skip to content

Instantly share code, notes, and snippets.

@oguz-ismail
Last active March 3, 2025 05:17
Show Gist options
  • Save oguz-ismail/dfb8a28c5774c54cca75480f8bb18531 to your computer and use it in GitHub Desktop.
Save oguz-ismail/dfb8a28c5774c54cca75480f8bb18531 to your computer and use it in GitHub Desktop.
#include <fcntl.h>
#include <sys/resource.h>
#include <sys/wait.h>
#include <time.h>
#include <unistd.h>
#ifdef __STATIC__
#include "crt.h"
#endif
static void
print(unsigned long long x, int delim) {
static char buf[24];
char *p = &buf[(sizeof buf)-1];
*p = delim;
do {
*--p = '0' + x%10;
x /= 10;
}
while (x);
write(1, p, (sizeof buf)-(p-buf));
}
int
main(int argc, char **argv) {
int fd;
struct timespec start, end;
struct rusage rusage;
fd = open("/dev/null", O_WRONLY|O_CLOEXEC);
for (;;) {
clock_gettime(CLOCK_MONOTONIC, &start);
switch (fork()) {
case 0:
lseek(0, 0, SEEK_SET);
dup2(fd, 1);
execv(argv[1], &argv[1]);
case -1:
return 1;
default:
wait4(-1, NULL, 0, &rusage);
clock_gettime(CLOCK_MONOTONIC, &end);
#define ns(t) ((t).tv_sec*1000000000 + (t).tv_nsec)
#define us(t) ((t).tv_sec*1000000 + (t).tv_usec)
print((ns(end)-ns(start))/1000, '\t');
print(us(rusage.ru_utime), '\t');
print(us(rusage.ru_stime), '\n');
}
}
}
.globl _start
.section .rodata
0: .asciz "/dev/null"
.data
.skip 23
1: .skip 1
.text
_start:
mov w19, 0xca00
movk w19, 0x3b9a, lsl 16
mov w20, 0x4240
movk w20, 0xf, lsl 16
mov x21, 0xf7cf
movk x21, 0xe353, lsl 16
movk x21, 0x9ba5, lsl 32
movk x21, 0x20c4, lsl 48
mov x22, 0xcccccccccccccccc
movk x22, 0xcccd
mov x23, 10 /* also '\n' */
adrp x24, 1b
add x24, x24, :lo12:1b
mov w25, '\t'
ldr x0, [sp]
add x26, sp, 16 /* argv+1 */
add x27, x26, x0, lsl 3 /* envp */
sub sp, sp, 160
mov w8, 56 /* openat */
mov w0, wzr
adrp x1, 0b
add x1, x1, :lo12:0b
mov w2, 1
movk w2, 8, lsl 16 /* O_WRONLY|O_CLOEXEC */
svc 0
mov w20, w0
parent:
mov w8, 113 /* clock_gettime */
mov w0, 1
add x1, sp, 144
svc 0
mov w8, 220 /* clone */
mov w0, 16657 /* CLONE_VM|CLONE_VFORK|SIGCHLD */
mov w1, wzr
mov w2, wzr
mov w3, wzr
svc 0
cmn x0, 1
b.eq 1f
cbz x0, child
mov w8, 260 /* wait4 */
mov w0, -1
mov x1, xzr
mov w2, wzr
mov x3, sp
svc 0
mov w8, 113
mov w0, 1
add x1, sp, 160
svc 0
ldp q0, q1, [sp, 144]
sub v0.2d, v1.2d, v0.2d
fmov x1, d0
mov x2, v0.d[1]
madd x2, x1, x19, x2
umulh x2, x2, x21
asr x1, x2, 7
add x0, x1, x2, lsr 63
strb w25, [x24]
bl print
ldp x1, x2, [sp]
madd x0, x1, x20, x2
strb w25, [x24]
bl print
ldp x1, x2, [sp, 16]
madd x0, x1, x20, x2
strb w23, [x24]
bl print
b parent
child:
mov w8, 62 /* lseek */
mov w0, wzr
mov w1, wzr
mov w2, wzr
svc 0
mov w8, 24 /* dup3 */
mov w0, w20
mov w1, 1
mov w2, wzr
svc 0
mov w8, 221 /* execve */
ldr x0, [x26]
mov x1, x26
mov x2, x27
svc 0
1: mov w8, 93 /* _exit */
mov w0, 1
svc 0
print:
mov x1, x24
mov w2, 1
0: umulh x3, x0, x22
lsr x3, x3, 3
msub w4, w3, w23, w0
orr w4, w4, '0'
strb w4, [x1, -1]!
add w2, w2, 1
cmp x0, 9
mov x0, x3
b.hi 0b
mov w8, 64
mov w0, 1
svc 0
ret
.globl _start
.section .rodata
0: .asciz "/dev/null"
.data
.skip 23
1: .skip 1
.text
_start:
mov (%rsp), %rax
lea 16(%rsp), %rbx /* argv+1 */
lea (%rbx, %rax, 8), %rbp /* envp */
sub $160, %rsp
mov $2, %eax
mov $0b, %rdi
mov $0x80001, %esi /* O_WRONLY|O_CLOEXEC */
syscall
mov %eax, %r8d
parent:
mov $228, %eax /* clock_gettime */
mov $1, %edi
mov %rsp, %rsi
syscall
mov $58, %eax /* vfork */
syscall
cmp $-1, %eax
je 2f
test %eax, %eax
je child
mov $61, %eax /* wait4 */
mov $-1, %edi
xor %esi, %esi
xor %edx, %edx
xor %ecx, %ecx
lea 32(%rsp), %r10
syscall
mov $228, %eax
mov $1, %edi
lea 16(%rsp), %rsi
syscall
imul $1000000000, (%rsp), %rdx
add 8(%rsp), %rdx
mov $1000, %ecx
imul $1000000000, 16(%rsp), %rax
add 24(%rsp), %rax
sub %rdx, %rax
cqto
idiv %rcx
mov %rax, %rdi
movb $'\t', 1b
call print
imul $1000000, 32(%rsp), %rdi
add 40(%rsp), %rdi
movb $'\t', 1b
call print
imul $1000000, 48(%rsp), %rdi
add 56(%rsp), %rdi
movb $'\n', 1b
call print
jmp parent
child:
mov $8, %eax /* lseek */
xor %edi, %edi
xor %esi, %esi
xor %edx, %edx
syscall
mov $292, %eax /* dup3 */
mov %r8d, %edi
mov $1, %esi
xor %edx, %edx
syscall
mov $59, %eax /* execve */
mov (%rbx), %rdi
lea (%rbx), %rsi
mov %rbp, %rdx
syscall
2: mov $60, %eax /* _exit */
mov $1, %edi
syscall
print:
mov $1b, %rsi
mov $0xcccccccccccccccd, %r9
0: sub $1, %rsi
mov %rdi, %rax
mul %r9
shr $3, %rdx
mov %rdi, %rax
lea (%rdx, %rdx, 4), %rcx
add %rcx, %rcx
sub %rcx, %rax
add $'0', %eax
mov %al, (%rsi)
mov %rdi, %rax
mov %rdx, %rdi
cmp $9, %rax
ja 0b
mov $1, %eax /* write */
mov $1, %edi
mov $1b+1, %rdx
sub %rsi, %rdx
syscall
ret
#include <linux/sched.h>
#include <sys/syscall.h>
#include <unistd.h>
#define clock_gettime(...) \
syscall(SYS_clock_gettime, __VA_ARGS__)
#define dup2(...) \
syscall(SYS_dup3, __VA_ARGS__, 0)
#define execv(pathname, argv) \
syscall(SYS_execve, pathname, argv, environ)
#if __aarch64__
#define fork() \
syscall(SYS_clone, CLONE_VFORK|CLONE_VM|SIGCHLD, 0, 0, 0)
#elif __amd64__
#define fork() syscall(SYS_fork)
#endif
#define lseek(...) \
syscall(SYS_lseek, __VA_ARGS__)
#define open(...) \
syscall(SYS_openat, 0, __VA_ARGS__)
#define wait4(...) \
syscall(SYS_wait4, __VA_ARGS__)
#define write(...) \
syscall(SYS_write, __VA_ARGS__)
char **environ;
__asm__(
"syscall:\n"
#if __aarch64__
" mov x8, x0\n"
" mov x0, x1\n"
" mov x1, x2\n"
" mov x2, x3\n"
" mov x3, x4\n"
" mov x4, x5\n"
" mov x5, x6\n"
" mov x6, x7\n"
" svc 0\n"
" ret\n"
#elif __amd64__
" mov %rdi, %rax\n"
" mov %rsi, %rdi\n"
" mov %rdx, %rsi\n"
" mov %rcx, %rdx\n"
" mov %r8, %r10\n"
" mov %r9, %r8\n"
" mov 8(%rsp), %r9\n"
" syscall\n"
" ret\n"
#endif
);
__asm__(
" .globl _start\n"
"_start:\n"
#if __aarch64__
" ldr x0, [sp]\n"
" add x1, sp, 8\n"
" add x8, x1, x0, lsl 3\n"
" add x8, x8, 8\n"
" adrp x9, environ\n"
" str x8, [x9, :lo12:environ]\n"
" bl main\n"
" mov w8, 93\n"
" svc 0\n"
#elif __amd64__
" mov (%rsp), %edi\n"
" lea 8(%rsp), %rsi\n"
" lea 8(%rsi, %rdi, 8), %rdx\n"
" mov %rdx, environ\n"
" call main\n"
" mov $60, %eax\n"
" syscall\n"
#endif
);
CFLAGS += -O2 -fno-asynchronous-unwind-tables -fno-builtin -fno-pie \
-fno-stack-protector -fno-unwind-tables -fomit-frame-pointer
CPPFLAGS += -D__STATIC__
LDFLAGS += -no-pie -nostdlib -static -z noexecstack -z norelro
bin = _t
objs = _t.o
.c.o:
$(CC) $(CFLAGS) $(CPPFLAGS) -c -o $@ $<
all: $(bin)
$(bin): $(objs)
$(CC) $(LDFLAGS) -o $@ $(objs)
t.c: crt.h
clean:
rm -f $(bin) $(objs)
if ! pathname=$(command -v "$1") ||
! case $pathname in */*) ;; *) false; esac then
echo "$1: bad command"
exit 1
fi
shift
trap 'printf \\33\[\?25h\\n' EXIT
printf '\33[?25l'
stty -echoctl </dev/tty
"${0%/*}/_${0##*/}" "$pathname" "$@" | awk '
BEGIN {
OFS = "\t"
print "real", "user", "sys"
}
{
for (i = 1; i <= NF; i++) {
mean[i] *= (NR-1)/NR
mean[i] += $i/NR
$i = int(mean[i])
}
printf "\33[G\33[K%s", $0
}'
# vim: ft=sh
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment