From dd9d3dc6f1a466feb13e19f4c98cd911508f53d4 Mon Sep 17 00:00:00 2001 From: pommicket Date: Fri, 11 Nov 2022 12:15:24 -0500 Subject: readme --- README.md | 55 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ tests/sdl.c | 6 ++++-- tests/tests.rs | 2 +- 3 files changed, 60 insertions(+), 3 deletions(-) create mode 100644 README.md diff --git a/README.md b/README.md new file mode 100644 index 0000000..11f7ae7 --- /dev/null +++ b/README.md @@ -0,0 +1,55 @@ +# tinyld + +a linker for making tiny 32-bit linux executables. + +*Just after* making this, I found out that something similar already existed here: +https://github.com/Shizmob/smol/ -- although smold's executables are giving me segfaults +for some reason. +This linker is worse in terms of output size, but the executables are more standard-compliant +and don't rely on undocumented ELF magic. The difference isn't even that big (in the 10s of bytes) +after compressing with `xz` -- so if you're using [this handy executable unpacker](https://gitlab.com/PoroCYon/vondehi), +you'll get about the same output size. + +## Executable sizes + +Exit using inline assembly (tests/tiny.c): **93 bytes** + +Hello world: **369 bytes** (252 bytes `xz`-compressed) + +Open a window, get a GL context, and call `glClearColor`, `glClear` each frame (tests/sdl.c): **881 bytes** +(532 bytes `xz`-compressed) + +## Installation + +You will need a [rust installation](https://www.rust-lang.org/tools/install). + +``` +cargo install --path . +``` + +## Usage + +`gcc-multilib`/`g++-multilib` are needed for 32-bit headers for C/C++. + +Example: create a file called `hello.c` containing +``` +#include +#include + +void entry(void) { + printf("Hello, world!\n"); + exit(0); +} +``` + +then run `tinyld hello.c -o hello`. You now have an executable called `hello` which prints `Hello, world!`. + +To add libaries, use e.g. `tinyld my_sdl_program.c libSDL2.so`. + +You can use C++, but exceptions probably won't work, and `cout`/`cin` don't seem to work either +(you should be using `printf` anyways if you want a smaller executable). + +Only 32-bit x86 ELF is supported. If you give tinyld a 64-bit executable it will die. +If you're compiling your own object files, you need to add `-fno-pic` otherwise tinyld will die. + +For more information, see `tinyld --help`. diff --git a/tests/sdl.c b/tests/sdl.c index a3c3d8f..31331c0 100644 --- a/tests/sdl.c +++ b/tests/sdl.c @@ -8,8 +8,10 @@ int main(void) { SDL_Init(SDL_INIT_EVERYTHING); SDL_Window *window = SDL_CreateWindow("hi", 0, 0, 1280, 720, SDL_WINDOW_SHOWN|SDL_WINDOW_OPENGL); SDL_GLContext ctx = SDL_GL_CreateContext(window); - PFNGLCLEARPROC glClear = SDL_GL_GetProcAddress("glClear"); - PFNGLCLEARCOLORPROC glClearColor = SDL_GL_GetProcAddress("glClearColor"); + // we save a byte this way since we don't need an extra relocation. + void *(*volatile get_proc_address)() = SDL_GL_GetProcAddress; + PFNGLCLEARPROC glClear = get_proc_address("glClear"); + PFNGLCLEARCOLORPROC glClearColor = get_proc_address("glClearColor"); SDL_GL_SetSwapInterval(1); while (true) { SDL_Event event; diff --git a/tests/tests.rs b/tests/tests.rs index 24e1881..761fe41 100644 --- a/tests/tests.rs +++ b/tests/tests.rs @@ -52,7 +52,7 @@ mod tests { fn tiny_c() { let mut linker = test_linker(); add(&mut linker, "tiny.c", true); - link(&linker, "test.out", "entry"); + link(&linker, "tiny.out", "entry"); let output = run("tiny.out"); assert!(output.stdout.is_empty()); } -- cgit v1.2.3