diff --git a/build.sh b/build.sh index a2faeb1..b296d8f 100755 --- a/build.sh +++ b/build.sh @@ -1,7 +1,7 @@ #!/bin/bash set -euo pipefail -CFLAGS="-Wall -Wextra -Wpedantic -std=c99 -O3" +CFLAGS="-Wall -Wextra -Wpedantic -std=c99" echo "building mos6502..." cc $CFLAGS -o mos6502 mos6502.c @@ -16,4 +16,16 @@ if command -v pkg-config >/dev/null; then fi else echo "pkg-config not found - skipping chip8..." -fi \ No newline at end of file +fi + +if command -v pkg-config >/dev/null; then + LIBELF_FLAGS=$(pkg-config --cflags --libs libelf 2>/dev/null) + if [ $? -eq 0 ]; then + echo "building riscv64..." + cc $CFLAGS -o riscv64 riscv64.c $LIBELF_FLAGS + else + echo "raylib not found - skipping riscv64..." + fi +else + echo "pkg-config not found - skipping riscv64..." +fi diff --git a/riscv64.c b/riscv64.c new file mode 100644 index 0000000..f02671d --- /dev/null +++ b/riscv64.c @@ -0,0 +1,74 @@ +#include +#include +#include +#include +#include +#include + +typedef struct { + size_t offset; + size_t size; +} Section; + +Section get_code_section(uint8_t *exe_bytes, size_t exe_size) { + Elf *elf = elf_memory((char *)exe_bytes, exe_size); + if (!elf) { + fprintf(stderr, "elf_begin failed: %s\n", elf_errmsg(-1)); + exit(1); + } + + size_t str_table_index; + if (elf_getshdrstrndx(elf, &str_table_index) != 0) { + fprintf(stderr, "elf_getshdrstrndx failed: %s\n", elf_errmsg(-1)); + exit(1); + } + + Elf_Scn *section = NULL; + while ((section = elf_nextscn(elf, section)) != NULL) { + GElf_Shdr header; + if (gelf_getshdr(section, &header) != &header) + continue; + + const char *name = elf_strptr(elf, str_table_index, header.sh_name); + if (name && strcmp(name, ".text") == 0) { + elf_end(elf); + return (Section){.offset = header.sh_offset, .size = header.sh_size}; + } + } + + fprintf(stderr, "Failed to locate .text\n"); + exit(1); +} + +int main(int argc, char *argv[]) { + if (elf_version(EV_CURRENT) == EV_NONE) { + fprintf(stderr, "Failed to initialize libelf: %s\n", elf_errmsg(-1)); + return 1; + } + + const char *path = NULL; + for (int i = 1; i < argc; i++) { + path = argv[i]; + } + + if (path == NULL) { + fprintf(stderr, "Usage: %s \n", argv[0]); + return 1; + } + + FILE *file = fopen(path, "rb"); + if (!file) { + fprintf(stderr, "Failed to open %s\n", path); + return 1; + } + + // probably enough for anything we can handle + uint8_t *exe_bytes = malloc(20 * 1024 * 1024); + size_t exe_size = fread(exe_bytes, 1, 20 * 1024 * 1024, file); + fclose(file); + + Section section = get_code_section(exe_bytes, exe_size); + + printf("Offset: %zu\n", section.offset); + printf("Size: %zu\n", section.size); +}