aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Duncan <pabs@pablotron.org>2024-07-24 22:39:59 -0400
committerPaul Duncan <pabs@pablotron.org>2024-07-24 22:39:59 -0400
commitb328a92f0e3c648bad7ef47a98f1db75e545789a (patch)
treeed6d37508d13cf3296f8ad57dc7214b0697e979d
downloadalonzo-sucks-arm64-main.tar.bz2
alonzo-sucks-arm64-main.zip
initial commitHEADmain
-rw-r--r--.gitignore3
-rw-r--r--Dockerfile15
-rw-r--r--Makefile15
-rw-r--r--README.md22
-rw-r--r--hi.s31
5 files changed, 86 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..e389069
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,3 @@
+*.sw?
+*.o
+./hi
diff --git a/Dockerfile b/Dockerfile
new file mode 100644
index 0000000..1c6845e
--- /dev/null
+++ b/Dockerfile
@@ -0,0 +1,15 @@
+# build image: latest alpine plus the following packages:
+# - binutils: for as and ld
+# - make: for gnu make
+FROM docker.io/alpine:latest AS build
+COPY . /src
+WORKDIR /src
+RUN apk add binutils make && \
+ make && \
+ wc -c ./hi
+
+# output image which contains a single 384 byte statically-linked arm64
+# binary named "/hi"
+FROM scratch
+COPY --from=build /src/hi /hi
+CMD ["/hi"]
diff --git a/Makefile b/Makefile
new file mode 100644
index 0000000..b5d8aae
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,15 @@
+APP=./hi
+OBJS=hi.o
+
+.PHONY=all
+
+all: $(APP)
+
+$(APP): $(OBJS)
+ ld -s -o $(APP) $(OBJS)
+
+hi.o: hi.s
+ as -o hi.o hi.s
+
+clean:
+ $(RM) $(APP) $(OBJS)
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..4b545d7
--- /dev/null
+++ b/README.md
@@ -0,0 +1,22 @@
+Critical infrastructure.
+
+Compiles to 384 byte statically-linked arm64 linux binary and a ~4k
+container image.
+
+Build, run, and view binary size on an arm64 linux system:
+
+ > make
+ ...
+ > ./hi
+ alonzo sucks!
+ > wc -c ./hi
+ 384 ./hi
+ >
+
+Build container image, then check image size:
+
+ > podman build -t hi:latest .
+ ...
+ > podman images --format '{{.Size}}' hi
+ 3.83 kB
+ >
diff --git a/hi.s b/hi.s
new file mode 100644
index 0000000..90190cb
--- /dev/null
+++ b/hi.s
@@ -0,0 +1,31 @@
+// hi.s: print "alonzo sucks!" to standard output and then exit.
+//
+// uses write() and exit() linux system calls directly to elide libc and
+// assembles to a static, 384 byte arm64 binary.
+
+// entry point
+//
+// uses 32-bit registers (wN) instead of 64-bit registers (xN) to
+// save a few bytes in the assembled binary
+.text
+.global _start
+_start:
+ // write(stdout, msg, len)
+ mov w0, #1 // stdout fd (1)
+ ldr w1, =msg // message
+ mov w2, len // message length
+ mov w8, #64 // write() (64)
+ svc #0 // call write()
+
+ // exit(0)
+ mov w0, #0 // exit code (0)
+ mov w8, #93 // exit() (93)
+ svc #0 // call exit()
+
+// message and message length
+//
+// technically the message belongs in the .rodata section, but sticking
+// it here allows it to be packed after _start and the saves ~60 bytes
+// in the assembled binary
+msg: .ascii "alonzo sucks!\n" // message (14 bytes)
+len = . - msg // message length