summaryrefslogtreecommitdiff
path: root/src/library.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/library.c')
-rw-r--r--src/library.c99
1 files changed, 96 insertions, 3 deletions
diff --git a/src/library.c b/src/library.c
index 6e1eb64..3e60077 100644
--- a/src/library.c
+++ b/src/library.c
@@ -52,8 +52,8 @@ static i64 get_kwargs_i64(pit_runtime *rt, i64 def, pit_value kwargs, char *kw)
static pit_value impl_elf_write_header(pit_runtime *rt, pit_value args) {
pit_value velf = pit_car(rt, args);
pit_value kwargs = pit_cdr(rt, args);
- elf_header h = {0};
struct elf_builder *e = pit_nativedata_get(rt, pit_intern_cstr(rt, "elf"), velf);
+ elf_header h = {0};
if (!e) return PIT_NIL;
builder_ensure_size(e, elf_header_size(&e->ctx));
h.type = get_kwargs_i64(rt, ELF_TYPE_EXEC, kwargs, ":type");
@@ -75,12 +75,12 @@ static pit_value impl_elf_write_section_header(pit_runtime *rt, pit_value args)
pit_value voff = pit_car(rt, pit_cdr(rt, args));
i64 off = pit_as_integer(rt, voff);
pit_value kwargs = pit_cdr(rt, pit_cdr(rt, args));
- elf_section_header h = {0};
struct elf_builder *e = pit_nativedata_get(rt, pit_intern_cstr(rt, "elf"), velf);
+ elf_section_header h = {0};
if (!e) return PIT_NIL;
if (off < 0) { pit_error(rt, "negative offset: %d", off); return PIT_NIL; }
builder_ensure_size(e, off + elf_header_size(&e->ctx));
- h.name_index = (u32) get_kwargs_i64(rt, ELF_SECTION_TYPE_NULL, kwargs, ":name-index");
+ h.name_index = (u32) get_kwargs_i64(rt, 0, kwargs, ":name-index");
h.type = (u32) get_kwargs_i64(rt, ELF_SECTION_TYPE_NULL, kwargs, ":type");
h.flags = (u64) get_kwargs_i64(rt, 0, kwargs, ":flags");
h.addr = (u64) get_kwargs_i64(rt, 0, kwargs, ":addr");
@@ -93,6 +93,47 @@ static pit_value impl_elf_write_section_header(pit_runtime *rt, pit_value args)
elf_write_section_header(&h, &e->ctx, (u64) off);
return PIT_NIL;
}
+static pit_value impl_elf_write_symbol(pit_runtime *rt, pit_value args) {
+ pit_value velf = pit_car(rt, args);
+ pit_value voff = pit_car(rt, pit_cdr(rt, args));
+ i64 off = pit_as_integer(rt, voff);
+ pit_value kwargs = pit_cdr(rt, pit_cdr(rt, args));
+ elf_symbol h = {0};
+ struct elf_builder *e = pit_nativedata_get(rt, pit_intern_cstr(rt, "elf"), velf);
+ if (!e) return PIT_NIL;
+ if (off < 0) { pit_error(rt, "negative offset: %d", off); return PIT_NIL; }
+ builder_ensure_size(e, off + elf_symbol_size(&e->ctx));
+ h.size = (u64) get_kwargs_i64(rt, 0, kwargs, ":size");
+ h.value = (u64) get_kwargs_i64(rt, 0, kwargs, ":value");
+ h.name_index = (u32) get_kwargs_i64(rt, 0, kwargs, ":name_index");
+ h.bind = get_kwargs_i64(rt, ELF_SYMBOL_BINDING_LOCAL, kwargs, ":bind");
+ h.type = get_kwargs_i64(rt, ELF_SYMBOL_TYPE_NOTYPE, kwargs, ":type");
+ h.visibility = get_kwargs_i64(rt, ELF_SYMBOL_VISIBILITY_DEFAULT, kwargs, ":visibility");
+ h.section_header_index = (u16) get_kwargs_i64(rt, 0, kwargs, ":section-header-index");
+ elf_write_symbol(&h, &e->ctx, (u64) off);
+ return PIT_NIL;
+}
+static pit_value impl_elf_write_program_header(pit_runtime *rt, pit_value args) {
+ pit_value velf = pit_car(rt, args);
+ pit_value voff = pit_car(rt, pit_cdr(rt, args));
+ i64 off = pit_as_integer(rt, voff);
+ pit_value kwargs = pit_cdr(rt, pit_cdr(rt, args));
+ elf_program_header h = {0};
+ struct elf_builder *e = pit_nativedata_get(rt, pit_intern_cstr(rt, "elf"), velf);
+ if (!e) return PIT_NIL;
+ if (off < 0) { pit_error(rt, "negative offset: %d", off); return PIT_NIL; }
+ builder_ensure_size(e, off + elf_program_header_size(&e->ctx));
+ h.type = (u32) get_kwargs_i64(rt, ELF_PROGRAM_HEADER_TYPE_NULL, kwargs, ":type");
+ h.offset = (u64) get_kwargs_i64(rt, 0, kwargs, ":offset");
+ h.virtual_addr = (u64) get_kwargs_i64(rt, 0, kwargs, ":virtual-addr");
+ h.physical_addr = (u64) get_kwargs_i64(rt, 0, kwargs, ":physical-addr");
+ h.file_size = (u64) get_kwargs_i64(rt, 0, kwargs, ":file-size");
+ h.mem_size = (u64) get_kwargs_i64(rt, 0, kwargs, ":mem-size");
+ h.flags = (u32) get_kwargs_i64(rt, 0, kwargs, ":flags");
+ h.align = (u64) get_kwargs_i64(rt, 0, kwargs, ":align");
+ elf_write_program_header(&h, &e->ctx, (u64) off);
+ return PIT_NIL;
+}
static pit_value impl_elf_spit(pit_runtime *rt, pit_value args) {
char pathbuf[1024] = {0};
i64 len = 0, actual = 0;
@@ -134,9 +175,61 @@ void rj_install_library(pit_runtime *rt) {
pit_set(rt, pit_intern_cstr(rt, "elf/MACHINE_NONE"), pit_integer_new(rt, 0));
pit_set(rt, pit_intern_cstr(rt, "elf/MACHINE_X86"), pit_integer_new(rt, 3));
pit_set(rt, pit_intern_cstr(rt, "elf/MACHINE_AMD64"), pit_integer_new(rt, 62));
+ pit_set(rt, pit_intern_cstr(rt, "elf/SECTION_TYPE_NULL"), pit_integer_new(rt, 0));
+ pit_set(rt, pit_intern_cstr(rt, "elf/SECTION_TYPE_PROGBITS"), pit_integer_new(rt, 1));
+ pit_set(rt, pit_intern_cstr(rt, "elf/SECTION_TYPE_SYMTAB"), pit_integer_new(rt, 2));
+ pit_set(rt, pit_intern_cstr(rt, "elf/SECTION_TYPE_STRTAB"), pit_integer_new(rt, 3));
+ pit_set(rt, pit_intern_cstr(rt, "elf/SECTION_TYPE_RELA"), pit_integer_new(rt, 4));
+ pit_set(rt, pit_intern_cstr(rt, "elf/SECTION_TYPE_HASH"), pit_integer_new(rt, 5));
+ pit_set(rt, pit_intern_cstr(rt, "elf/SECTION_TYPE_DYNAMIC"), pit_integer_new(rt, 6));
+ pit_set(rt, pit_intern_cstr(rt, "elf/SECTION_TYPE_NOTE"), pit_integer_new(rt, 7));
+ pit_set(rt, pit_intern_cstr(rt, "elf/SECTION_TYPE_NOBITS"), pit_integer_new(rt, 8));
+ pit_set(rt, pit_intern_cstr(rt, "elf/SECTION_TYPE_REL"), pit_integer_new(rt, 9));
+ pit_set(rt, pit_intern_cstr(rt, "elf/SECTION_TYPE_SHLIB"), pit_integer_new(rt, 10));
+ pit_set(rt, pit_intern_cstr(rt, "elf/SECTION_TYPE_DYNSYM"), pit_integer_new(rt, 11));
+ pit_set(rt, pit_intern_cstr(rt, "elf/SECTION_TYPE_INIT_ARRAY"), pit_integer_new(rt, 14));
+ pit_set(rt, pit_intern_cstr(rt, "elf/SECTION_TYPE_FINI_ARRAY"), pit_integer_new(rt, 15));
+ pit_set(rt, pit_intern_cstr(rt, "elf/SECTION_TYPE_PREINIT_ARRAY"), pit_integer_new(rt, 16));
+ pit_set(rt, pit_intern_cstr(rt, "elf/SECTION_TYPE_GROUP"), pit_integer_new(rt, 17));
+ pit_set(rt, pit_intern_cstr(rt, "elf/SECTION_TYPE_SYMTAB_SHNDX"), pit_integer_new(rt, 1));
+ pit_set(rt, pit_intern_cstr(rt, "elf/SECTION_FLAG_WRITE"), pit_integer_new(rt, 0x1));
+ pit_set(rt, pit_intern_cstr(rt, "elf/SECTION_FLAG_ALLOC"), pit_integer_new(rt, 0x2));
+ pit_set(rt, pit_intern_cstr(rt, "elf/SECTION_FLAG_EXECINSTR"), pit_integer_new(rt, 0x4));
+ pit_set(rt, pit_intern_cstr(rt, "elf/SECTION_FLAG_MERGE"), pit_integer_new(rt, 0x10));
+ pit_set(rt, pit_intern_cstr(rt, "elf/SECTION_FLAG_STRINGS"), pit_integer_new(rt, 0x20));
+ pit_set(rt, pit_intern_cstr(rt, "elf/SECTION_FLAG_INFO_LINK"), pit_integer_new(rt, 0x40));
+ pit_set(rt, pit_intern_cstr(rt, "elf/SECTION_FLAG_LINK_ORDER"), pit_integer_new(rt, 0x80));
+ pit_set(rt, pit_intern_cstr(rt, "elf/SECTION_FLAG_OS_NONCOMFORMING"), pit_integer_new(rt, 0x100));
+ pit_set(rt, pit_intern_cstr(rt, "elf/SECTION_FLAG_GROUP"), pit_integer_new(rt, 0x200));
+ pit_set(rt, pit_intern_cstr(rt, "elf/SECTION_FLAG_TLS"), pit_integer_new(rt, 0x400));
+ pit_set(rt, pit_intern_cstr(rt, "elf/SECTION_FLAG_COMPRESSED"), pit_integer_new(rt, 0x80));
+ pit_set(rt, pit_intern_cstr(rt, "elf/SYMBOL_BINDING_LOCAL"), pit_integer_new(rt, 0));
+ pit_set(rt, pit_intern_cstr(rt, "elf/SYMBOL_BINDING_GLOBAL"), pit_integer_new(rt, 1));
+ pit_set(rt, pit_intern_cstr(rt, "elf/SYMBOL_BINDING_WEAK"), pit_integer_new(rt, 2));
+ pit_set(rt, pit_intern_cstr(rt, "elf/SYMBOL_TYPE_NOTYPE"), pit_integer_new(rt, 0));
+ pit_set(rt, pit_intern_cstr(rt, "elf/SYMBOL_TYPE_OBJECT"), pit_integer_new(rt, 1));
+ pit_set(rt, pit_intern_cstr(rt, "elf/SYMBOL_TYPE_FUNC"), pit_integer_new(rt, 2));
+ pit_set(rt, pit_intern_cstr(rt, "elf/SYMBOL_TYPE_SECTION"), pit_integer_new(rt, 3));
+ pit_set(rt, pit_intern_cstr(rt, "elf/SYMBOL_TYPE_FILE"), pit_integer_new(rt, 4));
+ pit_set(rt, pit_intern_cstr(rt, "elf/SYMBOL_TYPE_COMMON"), pit_integer_new(rt, 5));
+ pit_set(rt, pit_intern_cstr(rt, "elf/SYMBOL_TYPE_TLS"), pit_integer_new(rt, 6));
+ pit_set(rt, pit_intern_cstr(rt, "elf/SYMBOL_VISIBILITY_DEFAULT"), pit_integer_new(rt, 0));
+ pit_set(rt, pit_intern_cstr(rt, "elf/SYMBOL_VISIBILITY_INTERNAL"), pit_integer_new(rt, 1));
+ pit_set(rt, pit_intern_cstr(rt, "elf/SYMBOL_VISIBILITY_HIDDEN"), pit_integer_new(rt, 2));
+ pit_set(rt, pit_intern_cstr(rt, "elf/SYMBOL_VISIBILITY_PROTECTED"), pit_integer_new(rt, 3));
+ pit_set(rt, pit_intern_cstr(rt, "elf/PROGRAM_HEADER_TYPE_NULL"), pit_integer_new(rt, 0));
+ pit_set(rt, pit_intern_cstr(rt, "elf/PROGRAM_HEADER_TYPE_LOAD"), pit_integer_new(rt, 1));
+ pit_set(rt, pit_intern_cstr(rt, "elf/PROGRAM_HEADER_TYPE_DYNAMIC"), pit_integer_new(rt, 2));
+ pit_set(rt, pit_intern_cstr(rt, "elf/PROGRAM_HEADER_TYPE_INTERP"), pit_integer_new(rt, 3));
+ pit_set(rt, pit_intern_cstr(rt, "elf/PROGRAM_HEADER_TYPE_NOTE"), pit_integer_new(rt, 4));
+ pit_set(rt, pit_intern_cstr(rt, "elf/PROGRAM_HEADER_TYPE_SHLIB"), pit_integer_new(rt, 5));
+ pit_set(rt, pit_intern_cstr(rt, "elf/PROGRAM_HEADER_TYPE_PHDR"), pit_integer_new(rt, 6));
+ pit_set(rt, pit_intern_cstr(rt, "elf/PROGRAM_HEADER_TYPE_TLS"), pit_integer_new(rt, 7));
pit_fset(rt, pit_intern_cstr(rt, "elf/new!"), pit_nativefunc_new(rt, impl_elf_new));
pit_fset(rt, pit_intern_cstr(rt, "elf/write-header!"), pit_nativefunc_new(rt, impl_elf_write_header));
pit_fset(rt, pit_intern_cstr(rt, "elf/write-section-header!"), pit_nativefunc_new(rt, impl_elf_write_section_header));
+ pit_fset(rt, pit_intern_cstr(rt, "elf/write-symbol!"), pit_nativefunc_new(rt, impl_elf_write_symbol));
+ pit_fset(rt, pit_intern_cstr(rt, "elf/write-program-header!"), pit_nativefunc_new(rt, impl_elf_write_program_header));
pit_fset(rt, pit_intern_cstr(rt, "elf/spit!"), pit_nativefunc_new(rt, impl_elf_spit));
}