From c7e737ac9de6c8b20a79f782735c0242610da04e Mon Sep 17 00:00:00 2001 From: sw Date: Thu, 2 Apr 2026 20:07:06 +1100 Subject: [PATCH 1/5] draft: setup draft pr because i want the branch to exist so it syncs hehe --- src/link.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/link.c b/src/link.c index 57ebb7b..c6c452d 100644 --- a/src/link.c +++ b/src/link.c @@ -42,6 +42,7 @@ void stb_global_collision(Hashmap **file_symbols, Hashmap **globals, Objdata *fi // for linking to succeed: // // TODO: +// - [ ] all files are relocatable (eheader->e_type is et_rel) // - [x] same e_machine // - [x] ensure no global bindings are shared between files // undefined external references (every symbol needs to have a corresponding address) From cf2690f00b1b2032bd8e812e764c89cae1e7900d Mon Sep 17 00:00:00 2001 From: sw Date: Thu, 2 Apr 2026 22:59:02 +1100 Subject: [PATCH 2/5] feat: add et_rel check --- src/link.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/link.c b/src/link.c index c6c452d..315e112 100644 --- a/src/link.c +++ b/src/link.c @@ -9,6 +9,10 @@ bool shared_emachine(uint64_t base, uint64_t input) { return base == input; } +bool etype_is_et_rel(Elf_header *header) { + return header->e_type == ET_REL; +} + // checks for stb_global symbol collision between files. // drains the symtab hashmap and inserts into global hashmap // collisions between equal values will crash @@ -62,6 +66,9 @@ void validate_objmeta(Objdata *head, Args args) { if (!shared_emachine(shared_machine, eheader.e_machine)) fatal_error("Different e_machine detected"); + if (!etype_is_et_rel(&eheader)) + fatal_error("File's e_type is not ET_REL"); + // we get a copy of allocated symtab because stb_global calls hashmap_pop // which modifies the hashmap. Hashmap **symtab_dup = grab_symbol_table(eheader, sheader, args, path); From 3eb2bbbfc6620943cbb1228bf02de3bc2474d18c Mon Sep 17 00:00:00 2001 From: sw Date: Fri, 3 Apr 2026 00:07:23 +1100 Subject: [PATCH 3/5] tests: ET_REL tests --- meson.build | 10 +++++++++ tests/ET_REL_FAIL/makefile | 7 ++++++ tests/ET_REL_FAIL/program1.c | 5 +++++ tests/ET_REL_FAIL/program2.c | 5 +++++ tests/ET_REL_FAIL/program3.c | 5 +++++ tests/ET_REL_FAIL/tester.py | 42 ++++++++++++++++++++++++++++++++++++ 6 files changed, 74 insertions(+) create mode 100644 tests/ET_REL_FAIL/makefile create mode 100644 tests/ET_REL_FAIL/program1.c create mode 100644 tests/ET_REL_FAIL/program2.c create mode 100644 tests/ET_REL_FAIL/program3.c create mode 100755 tests/ET_REL_FAIL/tester.py diff --git a/meson.build b/meson.build index 1bb3fe7..5604ac5 100644 --- a/meson.build +++ b/meson.build @@ -38,3 +38,13 @@ test( depends: [bin], workdir: meson.project_source_root() / 'tests/STB_GLOBAL_NOCONFLICT' ) + +test( + 'et_rel_fail', + find_program('python3'), + args : [ + files('tests/ET_REL_FAIL/tester.py'), bin + ], + depends: [bin], + workdir: meson.project_source_root() / 'tests/ET_REL_FAIL' +) diff --git a/tests/ET_REL_FAIL/makefile b/tests/ET_REL_FAIL/makefile new file mode 100644 index 0000000..e62a124 --- /dev/null +++ b/tests/ET_REL_FAIL/makefile @@ -0,0 +1,7 @@ +clean: + rm *.out + +all: + gcc program1.c -o p1.out + gcc program2.c -o p2.out + gcc program3.c -o p3.out diff --git a/tests/ET_REL_FAIL/program1.c b/tests/ET_REL_FAIL/program1.c new file mode 100644 index 0000000..7ef391c --- /dev/null +++ b/tests/ET_REL_FAIL/program1.c @@ -0,0 +1,5 @@ +#include + +int main() { + printf("hi meow\n"); +} diff --git a/tests/ET_REL_FAIL/program2.c b/tests/ET_REL_FAIL/program2.c new file mode 100644 index 0000000..7ef391c --- /dev/null +++ b/tests/ET_REL_FAIL/program2.c @@ -0,0 +1,5 @@ +#include + +int main() { + printf("hi meow\n"); +} diff --git a/tests/ET_REL_FAIL/program3.c b/tests/ET_REL_FAIL/program3.c new file mode 100644 index 0000000..7ef391c --- /dev/null +++ b/tests/ET_REL_FAIL/program3.c @@ -0,0 +1,5 @@ +#include + +int main() { + printf("hi meow\n"); +} diff --git a/tests/ET_REL_FAIL/tester.py b/tests/ET_REL_FAIL/tester.py new file mode 100755 index 0000000..c69cce8 --- /dev/null +++ b/tests/ET_REL_FAIL/tester.py @@ -0,0 +1,42 @@ +#!/bin/python3 + +import subprocess +import os +import sys + +linker_bin = sys.argv[1] + +def test_prom(prom_path: String, bin_path: String, cwd: String): + result = subprocess.run( + [prom_path, bin_path], + capture_output=True, text=True, + cwd=cwd + ) + if result.returncode == 0: + print(f"failed to identify {bin_path} is not ET_REL") + print(result.stdout) + print(result.stderr) + exit(1) + + +def main(): + cwd = os.path.dirname(os.path.abspath(__file__)) + + result = subprocess.run( + ["make", "all", "-C", cwd], + capture_output = True, text = True + ) + + if result.returncode != 0: + print("make failed:", result.stderr) + sys.exit(1) + + # checking prom against binaries + + for i in range(1,4): + test_prom(linker_bin, f"program{i}.out", cwd) + + print("pass") + + +main() From f8ea5391d9e7cd24ba445a50597b18fe22c10adf Mon Sep 17 00:00:00 2001 From: sw Date: Fri, 3 Apr 2026 00:07:38 +1100 Subject: [PATCH 4/5] feat: somehow i havent added *.out files to gitignore --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index dc03131..854de3e 100644 --- a/.gitignore +++ b/.gitignore @@ -2,3 +2,4 @@ build/ .cache/ tags *.o +*.out From 275544a1ff79dbc744c736c50475c722e6dc891c Mon Sep 17 00:00:00 2001 From: sw Date: Fri, 3 Apr 2026 00:09:47 +1100 Subject: [PATCH 5/5] fix: et_rel test forgot syntax for strings --- tests/ET_REL_FAIL/tester.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/ET_REL_FAIL/tester.py b/tests/ET_REL_FAIL/tester.py index c69cce8..a22de22 100755 --- a/tests/ET_REL_FAIL/tester.py +++ b/tests/ET_REL_FAIL/tester.py @@ -6,7 +6,7 @@ linker_bin = sys.argv[1] -def test_prom(prom_path: String, bin_path: String, cwd: String): +def test_prom(prom_path: str, bin_path: str, cwd: str): result = subprocess.run( [prom_path, bin_path], capture_output=True, text=True,