diff options
Diffstat (limited to 'bxgen.c')
-rwxr-xr-x | bxgen.c | 189 |
1 files changed, 100 insertions, 89 deletions
@@ -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); |