summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xbxgen.c189
1 files changed, 100 insertions, 89 deletions
diff --git a/bxgen.c b/bxgen.c
index b1855e6..3223929 100755
--- a/bxgen.c
+++ b/bxgen.c
@@ -384,6 +384,8 @@ typedef struct {
i64 max_not_found_size;
i64 max_output_size;
+ i64 num_obj_files;
+
u8 * obj_file_buffer;
u8 * dependencies_buffer;
i64 * obj_file_offsets;
@@ -2061,7 +2063,7 @@ void elf_dump(u32 log_level, Buffer_Context b) {
BX_LOG(log_level, "");
}
-void unit_write(Pool *pool, i64 unit, u16 target, i64 io_out, void *io_user_data) {
+i64 unit_write_in_memory(Pool *pool, i64 unit, u16 target) {
BX_CHECK(pool != NULL && pool->entities != NULL, "Invalid arguments",);
BX_CHECK(pool->entities[unit].is_enabled, "Unit does not exist",);
BX_CHECK(pool->entities[unit].unit.entry_point_index != UNDEFINED, "No entry point",);
@@ -2099,93 +2101,16 @@ void unit_write(Pool *pool, i64 unit, u16 target, i64 io_out, void *io_user_data
i64 rwdata_size = 0;
i64 rodata_size = 0;
- // ==============================================================
- //
- // Reading dependencies
-
- i64 num_obj_files = 0;
- i64 obj_files_size = 0;
i64 num_sections = 0;
i64 num_symbols = 0;
i64 not_found_size = 0;
- // Read all dependency files into the memory
- //
-
- Unit *u = &pool->entities[unit].unit;
-
- for (i64 link_index = 0; link_index < u->num_links; ++link_index) {
- i64 id = u->links[link_index];
- if (id == UNDEFINED)
- continue;
- Unit *l = &pool->entities[id].unit;
- BX_CHECK(pool->entities[id].is_enabled, "Internal",);
- BX_CHECK(l->type == UNIT_LIBRARY_STATIC, "Link type not supported",);
- BX_CHECK(l->name_size > 0, "No link name",);
- BX_CHECK(l->name_size <= MAX_NAME_SIZE, "Link name too big",);
-
- i64 f = io_open_read(l->name_size, l->name, io_user_data);
- io_seek(f, 0, IO_SEEK_END, io_user_data);
-
- i64 in_size = io_tell(f, io_user_data);
- BX_CHECK(in_size <= pool->max_obj_file_size, "AR file too big",);
-
- io_seek(f, 0, IO_SEEK_BEGIN, io_user_data);
- i64 n = io_read(f, in_size, pool->obj_file_buffer, io_user_data);
- BX_CHECK(n == in_size, "Read failed",);
-
- io_close(f, io_user_data);
-
- // ========================================================
- //
- // Read AR library
-
- u8 *ar_begin = pool->obj_file_buffer;
- u8 *ar_end = pool->obj_file_buffer + in_size;
-
- BX_CHECK(bx_mem_eq(ar_begin, AR_MAGIC, 8), "Invalid AR file",);
-
- u8 *f_begin = ar_begin + 8;
-
- while (f_begin + 60 < ar_end) {
- u8 *f_id = f_begin;
- u8 *f_size = f_begin + 48;
- u8 *f_end = f_begin + 58;
- u8 *f_data = f_begin + 60;
-
- i64 size = (i64) bx_u64_from_dec_str((c8 *) f_size, (c8 *) f_size + 10);
-
- size = bx_align(size, 2);
-
- BX_CHECK(bx_mem_eq(f_end, "\x60\x0a", 2), "Invalid AR file",);
- BX_CHECK(f_begin + size <= ar_end, "Buffer overflow",);
-
- if (!bx_mem_eq(f_id, AR_SYMBOL_TABLE, 16) &&
- !bx_mem_eq(f_id, AR_STRING_TABLE, 16)) {
- // Read ELF object file
-
- i64 delta_size = bx_align(size, X86_64_ALIGNMENT);
-
- BX_CHECK(obj_files_size + delta_size < pool->max_dependencies_size, "Out of memory",);
- BX_CHECK(num_obj_files + 1 < pool->max_num_obj_files, "Out of memory",);
-
- bx_mem_cpy(pool->dependencies_buffer + obj_files_size, f_data, size);
-
- pool->obj_file_offsets[num_obj_files] = obj_files_size;
- obj_files_size += delta_size;
- pool->obj_file_offsets[++num_obj_files] = obj_files_size;
- }
-
- f_begin = f_data + size;
- }
- }
-
// ==========================================================
//
// Calculate section offsets
- for (i64 elf_index = 0; elf_index < num_obj_files; ++elf_index) {
- Buffer_Context buf = elf_buffer_context(pool, num_obj_files, elf_index);
+ for (i64 elf_index = 0; elf_index < pool->num_obj_files; ++elf_index) {
+ Buffer_Context buf = elf_buffer_context(pool, pool->num_obj_files, elf_index);
elf_checks(buf);
//elf_dump(VERBOSE, buf);
@@ -2230,8 +2155,8 @@ void unit_write(Pool *pool, i64 unit, u16 target, i64 io_out, void *io_user_data
i64 rwdata_address = rwzval_address + rwzval_size;
i64 rodata_address = rwdata_address + rwdata_size;
- for (i64 elf_index = 0, sec_index_global = 0; elf_index < num_obj_files; ++elf_index) {
- Buffer_Context buf = elf_buffer_context(pool, num_obj_files, elf_index);
+ for (i64 elf_index = 0, sec_index_global = 0; elf_index < pool->num_obj_files; ++elf_index) {
+ Buffer_Context buf = elf_buffer_context(pool, pool->num_obj_files, elf_index);
Offset_Num headers = elf_section_headers(buf);
for (i64 sec_index = 1; sec_index < headers.num; ++sec_index, ++sec_index_global) {
@@ -2259,8 +2184,8 @@ void unit_write(Pool *pool, i64 unit, u16 target, i64 io_out, void *io_user_data
//
// Relocate defined symbols
- for (i64 elf_index = 0, sec_index_global = 0; elf_index < num_obj_files; ++elf_index) {
- Buffer_Context buf = elf_buffer_context(pool, num_obj_files, elf_index);
+ for (i64 elf_index = 0, sec_index_global = 0; elf_index < pool->num_obj_files; ++elf_index) {
+ Buffer_Context buf = elf_buffer_context(pool, pool->num_obj_files, elf_index);
Offset_Num headers = elf_section_headers(buf);
Offset_Size strtab = elf_find_section_by_name(buf, SECTION_STRTAB, sizeof SECTION_STRTAB - 1).data;
@@ -2363,8 +2288,8 @@ void unit_write(Pool *pool, i64 unit, u16 target, i64 io_out, void *io_user_data
//
// TODO Apply relocations
- for (i64 elf_index = 0, sec_index_global = 0; elf_index < num_obj_files; ++elf_index) {
- Buffer_Context buf = elf_buffer_context(pool, num_obj_files, elf_index);
+ for (i64 elf_index = 0, sec_index_global = 0; elf_index < pool->num_obj_files; ++elf_index) {
+ Buffer_Context buf = elf_buffer_context(pool, pool->num_obj_files, elf_index);
i64 num_sections = elf_section_headers(buf).num;
Offset_Size strtab = elf_find_section_by_name(buf, SECTION_STRTAB, sizeof SECTION_STRTAB - 1).data;
@@ -2449,7 +2374,7 @@ void unit_write(Pool *pool, i64 unit, u16 target, i64 io_out, void *io_user_data
write_i##BITS(LE, (i##BITS) x_, dst, buf.end); \
} while (0)
- #define TODO_ BX_FAIL("Not implemented",)
+ #define TODO_ BX_FAIL("Not implemented",0)
case R_X86_64_NONE: /* Do nothing */ break;
case R_X86_64_64: ADD_(64, S + A); break;
@@ -2627,8 +2552,8 @@ void unit_write(Pool *pool, i64 unit, u16 target, i64 io_out, void *io_user_data
//
// Write sections into the output buffer
- for (i64 elf_index = 0; elf_index < num_obj_files; ++elf_index) {
- Buffer_Context buf = elf_buffer_context(pool, num_obj_files, elf_index);
+ for (i64 elf_index = 0; elf_index < pool->num_obj_files; ++elf_index) {
+ Buffer_Context buf = elf_buffer_context(pool, pool->num_obj_files, elf_index);
Offset_Num headers = elf_section_headers(buf);
for (i64 sec_index = 1; sec_index < headers.num; ++sec_index, ++num_sections) {
@@ -2645,6 +2570,90 @@ void unit_write(Pool *pool, i64 unit, u16 target, i64 io_out, void *io_user_data
}
// ==============================================================
+
+ return output_size;
+}
+
+void unit_write(Pool *pool, i64 unit, u16 target, i64 io_out, void *io_user_data) {
+ // ==============================================================
+ //
+ // Reading dependencies
+
+ i64 obj_files_size = 0;
+
+ Unit *u = &pool->entities[unit].unit;
+
+ for (i64 link_index = 0; link_index < u->num_links; ++link_index) {
+ i64 id = u->links[link_index];
+ if (id == UNDEFINED)
+ continue;
+ Unit *l = &pool->entities[id].unit;
+ BX_CHECK(pool->entities[id].is_enabled, "Internal",);
+ BX_CHECK(l->type == UNIT_LIBRARY_STATIC, "Link type not supported",);
+ BX_CHECK(l->name_size > 0, "No link name",);
+ BX_CHECK(l->name_size <= MAX_NAME_SIZE, "Link name too big",);
+
+ i64 f = io_open_read(l->name_size, l->name, io_user_data);
+ io_seek(f, 0, IO_SEEK_END, io_user_data);
+
+ i64 in_size = io_tell(f, io_user_data);
+ BX_CHECK(in_size <= pool->max_obj_file_size, "AR file too big",);
+
+ io_seek(f, 0, IO_SEEK_BEGIN, io_user_data);
+ i64 n = io_read(f, in_size, pool->obj_file_buffer, io_user_data);
+ BX_CHECK(n == in_size, "Read failed",);
+
+ io_close(f, io_user_data);
+
+ // ========================================================
+ //
+ // Read AR library
+
+ u8 *ar_begin = pool->obj_file_buffer;
+ u8 *ar_end = pool->obj_file_buffer + in_size;
+
+ BX_CHECK(bx_mem_eq(ar_begin, AR_MAGIC, 8), "Invalid AR file",);
+
+ u8 *f_begin = ar_begin + 8;
+
+ while (f_begin + 60 < ar_end) {
+ u8 *f_id = f_begin;
+ u8 *f_size = f_begin + 48;
+ u8 *f_end = f_begin + 58;
+ u8 *f_data = f_begin + 60;
+
+ i64 size = (i64) bx_u64_from_dec_str((c8 *) f_size, (c8 *) f_size + 10);
+
+ size = bx_align(size, 2);
+
+ BX_CHECK(bx_mem_eq(f_end, "\x60\x0a", 2), "Invalid AR file",);
+ BX_CHECK(f_begin + size <= ar_end, "Buffer overflow",);
+
+ if (!bx_mem_eq(f_id, AR_SYMBOL_TABLE, 16) &&
+ !bx_mem_eq(f_id, AR_STRING_TABLE, 16)) {
+ // Read ELF object file
+
+ i64 delta_size = bx_align(size, X86_64_ALIGNMENT);
+
+ BX_CHECK(obj_files_size + delta_size < pool->max_dependencies_size, "Out of memory",);
+ BX_CHECK(pool->num_obj_files + 1 < pool->max_num_obj_files, "Out of memory",);
+
+ bx_mem_cpy(pool->dependencies_buffer + obj_files_size, f_data, size);
+
+ pool->obj_file_offsets[pool->num_obj_files] = obj_files_size;
+ obj_files_size += delta_size;
+ pool->obj_file_offsets[++pool->num_obj_files] = obj_files_size;
+ }
+
+ f_begin = f_data + size;
+ }
+ }
+
+ // ==============================================================
+
+ i64 output_size = unit_write_in_memory(pool, unit, target);
+
+ // ==============================================================
//
// Write the output buffer into the file
@@ -2654,6 +2663,8 @@ void unit_write(Pool *pool, i64 unit, u16 target, i64 io_out, void *io_user_data
//
// Cleanup
+ pool->num_obj_files = 0;
+
bx_mem_set(pool->obj_file_buffer, 0, pool->max_obj_file_size);
bx_mem_set(pool->dependencies_buffer, 0, pool->max_dependencies_size);
bx_mem_set(pool->obj_file_offsets, 0, pool->max_num_obj_files * sizeof *pool->obj_file_offsets);