diff options
author | Mitya Selivanov <automainint@guattari.tech> | 2024-08-01 04:05:24 +0200 |
---|---|---|
committer | Mitya Selivanov <automainint@guattari.tech> | 2024-08-01 04:05:24 +0200 |
commit | de0850e7f8e62e4b3873e63aee10d9253b006c5f (patch) | |
tree | 3527b122eb03bd6fced3369bf24a08a9b8955576 | |
parent | 7ee8702456a8f2dc4e04f48879eef42a26dbabe8 (diff) | |
download | bxgen-de0850e7f8e62e4b3873e63aee10d9253b006c5f.zip |
Link with object files; TODO: GOT
-rwxr-xr-x | bxgen.c | 310 |
1 files changed, 191 insertions, 119 deletions
@@ -457,6 +457,7 @@ typedef struct { i64 max_num_rels; i64 max_code_size; i64 max_ro_data_size; + b8 has_entry; i64 entry_point; i64 num_rels; i64 offset_code; @@ -657,7 +658,7 @@ c8 * l_find(c8 *name); dispatch_log(log_level, __LINE__, __FILE__, __VA_ARGS__); \ } while (0) -i64 bx_align(i64 x, i64 a) { +i64 align(i64 x, i64 a) { CHECK(a > 0, "Invalid arguments", 0); return x + ((a - (x % a)) % a); } @@ -694,7 +695,7 @@ b8 mem_eq(void *a, void *b, i64 size) { return 1; } -i64 bx_str_len(c8 *s, c8 *s_end) { +i64 str_len(c8 *s, c8 *s_end) { CHECK(s < s_end, "Buffer overflow", 0); for (i64 len = 0; s + len < s_end; ++len) @@ -704,7 +705,7 @@ i64 bx_str_len(c8 *s, c8 *s_end) { FAIL("Buffer overflow", 0); } -i64 bx_str_len_or(c8 *s, c8 *s_max, i64 or_val) { +i64 str_len_or(c8 *s, c8 *s_max, i64 or_val) { for (i64 len = 0; s + len < s_max; ++len) if (s[len] == '\0') return len; @@ -749,7 +750,7 @@ c8 *find_str_in_table(c8 *buf, c8 *buf_end, c8 *sub, c8 *sub_end) { CHECK(sub_end != NULL, "Invalid arguments", NULL); while (buf < buf_end) { - i64 len = bx_str_len(buf, buf_end); + i64 len = str_len(buf, buf_end); if (sub_end - sub == len && mem_eq(buf, sub, len)) return buf; buf += len + 1; @@ -2153,7 +2154,9 @@ void emit_unit(Pool *pool, Codegen_Context *codegen, i64 unit, u16 arch) { u32 context = 0; if (i == pool->entities[unit].unit.entry_point_index) { + CHECK(!codegen->has_entry, "Multiple entry points",); codegen->entry_point = codegen->offset_code; + codegen->has_entry = 1; context |= EMIT_ENTRY_PROC; } @@ -2269,7 +2272,7 @@ Offset_Size elf_name_in_string_table( return (Offset_Size) { .offset = string_table.offset + name_offset, - .size = bx_str_len(begin, end), + .size = str_len(begin, end), }; } @@ -2353,7 +2356,7 @@ c8 *elf_name_from_offset( return ""; c8 *begin = (c8 *) (b.begin + name.offset); - i64 len = bx_str_len(begin, (c8 *) b.end); + i64 len = str_len(begin, (c8 *) b.end); CHECK((i64) name.size == len, "Buffer overflow", ""); return begin; @@ -2648,11 +2651,10 @@ i64 unit_write_in_memory( u16 format, u16 arch ) { - CHECK(pool != NULL && pool->entities != NULL, "Invalid arguments",); - CHECK(unit != UNDEFINED && pool->entities[unit].is_enabled, "No unit",); - CHECK(pool->entities[unit].type == ENTITY_UNIT, "Invalid entity", 0); - CHECK(pool->entities[unit].unit.entry_point_index != UNDEFINED, "No entry point",); - CHECK(format == FORMAT_ELF && arch == ARCH_X86_64, "Target not supported",); + CHECK(pool != NULL && pool->entities != NULL, "Invalid arguments",); + CHECK(unit != UNDEFINED && pool->entities[unit].is_enabled, "No unit",); + CHECK(pool->entities[unit].type == ENTITY_UNIT, "Invalid entity", 0); + CHECK(format == FORMAT_ELF && arch == ARCH_X86_64, "Target not supported",); CHECK(linker->obj_file_buffer != NULL, "No object file buffer",); CHECK(linker->dependencies_buffer != NULL, "No dependencies buffer",); CHECK(linker->obj_file_offsets != NULL, "No object file offsets buffer",); @@ -2660,13 +2662,10 @@ i64 unit_write_in_memory( emit_unit(pool, codegen, unit, arch); u16 num_program_headers = 7; - i64 program_offset = bx_align(ELF_HEADER_SIZE + ELF_PROGRAM_HEADER_SIZE * num_program_headers, X86_64_ALIGNMENT); + i64 program_offset = align(ELF_HEADER_SIZE + ELF_PROGRAM_HEADER_SIZE * num_program_headers, X86_64_ALIGNMENT); i64 base_address = X86_64_BASE_ADDRESS; i64 rx_code_address = base_address + program_offset; - i64 entry = rx_code_address + codegen->entry_point; - - LOG(VERBOSE, "Entry point: 0x%llx", entry); i64 rx_code_size = codegen->offset_code; i64 rw_zval_size = 0; @@ -2698,11 +2697,15 @@ i64 unit_write_in_memory( c8 *name = elf_name_from_offset(buf, section.name); - if (section.type == SEC_PROGBITS && section.name.size == sizeof SECTION_GOT - 1 && mem_eq(name, SECTION_GOT, sizeof SECTION_GOT - 1)) { + if (section.type == SEC_PROGBITS && + section.name.size == sizeof SECTION_GOT - 1 && + mem_eq(name, SECTION_GOT, sizeof SECTION_GOT - 1)) { FAIL("Not implemented", 0); } - if (section.type == SEC_PROGBITS && section.name.size == sizeof SECTION_PLT - 1 && mem_eq(name, SECTION_PLT, sizeof SECTION_PLT - 1)) { + if (section.type == SEC_PROGBITS && + section.name.size == sizeof SECTION_PLT - 1 && + mem_eq(name, SECTION_PLT, sizeof SECTION_PLT - 1)) { FAIL("Not implemented", 0); } @@ -2713,11 +2716,15 @@ i64 unit_write_in_memory( FAIL("Not implemented", 0); } - if (section.type == SEC_PROGBITS && section.exec && section.name.size == sizeof SECTION_INIT - 1 && mem_eq(name, SECTION_INIT, sizeof SECTION_INIT - 1)) { + if (section.type == SEC_PROGBITS && section.exec && + section.name.size == sizeof SECTION_INIT - 1 && + mem_eq(name, SECTION_INIT, sizeof SECTION_INIT - 1)) { FAIL("Not implemented", 0); } - if (section.type == SEC_PROGBITS && section.exec && section.name.size == sizeof SECTION_FINI - 1 && mem_eq(name, SECTION_FINI, sizeof SECTION_FINI - 1)) { + if (section.type == SEC_PROGBITS && section.exec && + section.name.size == sizeof SECTION_FINI - 1 && + mem_eq(name, SECTION_FINI, sizeof SECTION_FINI - 1)) { FAIL("Not implemented", 0); } @@ -2726,35 +2733,35 @@ i64 unit_write_in_memory( linker->section_offsets[num_sections_total] = rx_code_size; linker->section_addresses[num_sections_total] = rx_code_size; - rx_code_size += bx_align(section.data.size, X86_64_ALIGNMENT); + rx_code_size += align(section.data.size, X86_64_ALIGNMENT); continue; } if (section.write && section.type == SEC_NOBITS) { linker->section_addresses[num_sections_total] = rw_zval_size; - rw_zval_size += bx_align(section.data.size, X86_64_ALIGNMENT); + rw_zval_size += align(section.data.size, X86_64_ALIGNMENT); continue; } if (section.write) { linker->section_offsets[num_sections_total] = rw_data_size; linker->section_addresses[num_sections_total] = rw_data_size; - rw_data_size += bx_align(section.data.size, X86_64_ALIGNMENT); + rw_data_size += align(section.data.size, X86_64_ALIGNMENT); continue; } linker->section_offsets[num_sections_total] = ro_data_size; linker->section_addresses[num_sections_total] = ro_data_size; - ro_data_size += bx_align(section.data.size, X86_64_ALIGNMENT); + ro_data_size += align(section.data.size, X86_64_ALIGNMENT); } } - rx_code_size = bx_align(rx_code_size, X86_64_PAGE_SIZE); - rw_zval_size = bx_align(rw_zval_size, X86_64_PAGE_SIZE); - rw_data_size = bx_align(rw_data_size, X86_64_PAGE_SIZE); - ro_data_size = bx_align(ro_data_size, X86_64_PAGE_SIZE); - rw_got_size = bx_align(rw_got_size, X86_64_PAGE_SIZE); - rw_dynamic_size = bx_align(rw_dynamic_size, X86_64_PAGE_SIZE); + rx_code_size = align(rx_code_size, X86_64_PAGE_SIZE); + rw_zval_size = align(rw_zval_size, X86_64_PAGE_SIZE); + rw_data_size = align(rw_data_size, X86_64_PAGE_SIZE); + ro_data_size = align(ro_data_size, X86_64_PAGE_SIZE); + rw_got_size = align(rw_got_size, X86_64_PAGE_SIZE); + rw_dynamic_size = align(rw_dynamic_size, X86_64_PAGE_SIZE); i64 rw_zval_address = rx_code_address + rx_code_size; i64 rw_data_address = rw_zval_address + rw_zval_size; @@ -2952,17 +2959,39 @@ i64 unit_write_in_memory( Symbol_Entry symbol = {0}; if (relx.symbol.section == 0) { - for (i64 i = 0; i < num_symbols; ++i) - if (linker->symbols[i].name_size == relx.symbol.name.size && - mem_eq( - linker->symbols[i].name, - sym_name, - relx.symbol.name.size - )) { - symbol = linker->symbols[i]; + b8 found = 0; + + for (i64 i = 0; i < pool->num_entities; ++i) + if (pool->entities[i].is_enabled && + pool->entities[i].type == ENTITY_PROC && + pool->entities[i].proc.name_size == relx.symbol.name.size && + mem_eq(pool->entities[i].proc.name, sym_name, relx.symbol.name.size)) { + CHECK(pool->entities[i].proc.codegen.emit_done, "No proc code",); + + symbol = (Symbol_Entry) { + .address = rx_code_address + pool->entities[i].proc.codegen.offset, + .size = relx.symbol.value.size, + }; + + found = 1; break; } - if (symbol.address == 0 && + + if (!found) + for (i64 i = 0; i < num_symbols; ++i) + if (linker->symbols[i].name_size == relx.symbol.name.size && + mem_eq( + linker->symbols[i].name, + sym_name, + relx.symbol.name.size + )) { + symbol = linker->symbols[i]; + + found = 1; + break; + } + + if (!found && find_str_in_table( linker->not_found_buffer, linker->not_found_buffer + not_found_size, @@ -2970,7 +2999,7 @@ i64 unit_write_in_memory( sym_name + relx.symbol.name.size ) == NULL) { // FIXME - // LOG(WARNING, "Undefined symbol: %s", sym_name); + LOG(WARNING, "Undefined symbol: %s", sym_name); CHECK(not_found_size + relx.symbol.name.size + 1 <= linker->max_not_found_size, "Out of memory",); mem_cpy(linker->not_found_buffer + not_found_size, sym_name, relx.symbol.name.size); not_found_size += relx.symbol.name.size + 1; @@ -3012,16 +3041,6 @@ i64 unit_write_in_memory( // Represents the place (section offset or address) of the Procedure Linkage Table entry for a symbol. i64 L = S; // TODO - // if (S == 0x5a2478 || S + A == 0x5a2478) { - // LOG(VERBOSE, "%s: type %d, S=0x%llx, A=0x%llx, P=0x%llx", sym_name, relx.type, S, A, P); - // LOG(TRACE, ""); - // } - // LOG(VERBOSE, "--"); - - // if (S + A == 0x58fa84) { - // LOG(TRACE, "Symbol: %s, Obj: %lld, Section: %lld, Index: %lld", sym_name, elf_index, relx.symbol.section, relx.symbol._index); - // } - switch (relx.type) { #define SKIP_(x) \ if (relx.symbol.name.size == sizeof(#x) - 1 && \ @@ -3123,7 +3142,7 @@ i64 unit_write_in_memory( case R_X86_64_IRELATIVE: TODO_; break; case R_X86_64_RELATIVE64: TODO_; break; case R_X86_64_GOTPCRELX: TODO_; break; - case R_X86_64_REX_GOTPCRELX: ADD_(32, GOT - P + G - 4); break; // 32, GOT - P + G - 4 + case R_X86_64_REX_GOTPCRELX: TODO_; break; default: FAIL("Unknown relocation type", 0); @@ -3205,7 +3224,7 @@ i64 unit_write_in_memory( // i64 output_size = - bx_align( + align( program_offset + rx_code_size + rw_zval_size @@ -3217,6 +3236,23 @@ i64 unit_write_in_memory( CHECK(output_size <= linker->max_output_size, "Out of memory",); + i64 entry = rx_code_address + codegen->entry_point; + + if (!codegen->has_entry) { + b8 found = 0; + + for (i64 sym_index = 0; sym_index < num_symbols; ++sym_index) if (linker->symbols[sym_index].name_size == 6 && + mem_eq(linker->symbols[sym_index].name, "_start", 6)) { + entry = linker->symbols[sym_index].address; + found = 1; + break; + } + + CHECK(found, "Undefined symbol: _start",); + } + + LOG(VERBOSE, "Entry point: 0x%llx", entry); + LOG(VERBOSE, "Total %lld sections", num_sections_total); LOG(VERBOSE, "Total %lld symbols", num_symbols); @@ -3410,63 +3446,89 @@ void unit_write( continue; Unit *l = &pool->entities[id].unit; CHECK(pool->entities[id].is_enabled, "Internal",); - CHECK(l->type == UNIT_LIBRARY_STATIC, "Link type not supported",); CHECK(l->name_size > 0, "No link name",); 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); + switch (l->type) { + case UNIT_LIBRARY_OBJECT: { + 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); - CHECK(in_size <= linker->max_obj_file_size, "AR file too big",); + i64 in_size = io_tell(f, io_user_data); + CHECK(in_size <= linker->max_obj_file_size, "Object file too big",); + CHECK(obj_files_size + in_size < linker->max_dependencies_size, "Out of memory",); + CHECK(linker->num_obj_files + 1 < linker->max_num_obj_files, "Out of memory",); - io_seek(f, 0, IO_SEEK_BEGIN, io_user_data); - i64 n = io_read(f, in_size, linker->obj_file_buffer, io_user_data); - CHECK(n == in_size, "Read failed",); + io_seek(f, 0, IO_SEEK_BEGIN, io_user_data); + i64 n = io_read(f, in_size, linker->dependencies_buffer + obj_files_size, io_user_data); + CHECK(n == in_size, "Read failed",); - io_close(f, io_user_data); + io_close(f, io_user_data); - // ======================================================== - // - // Read AR library + linker->obj_file_offsets[linker->num_obj_files] = obj_files_size; + obj_files_size += align(in_size, X86_64_ALIGNMENT); + linker->obj_file_offsets[++linker->num_obj_files] = obj_files_size; + } break; - u8 *ar_begin = linker->obj_file_buffer; - u8 *ar_end = linker->obj_file_buffer + in_size; + case UNIT_LIBRARY_STATIC: { + i64 f = io_open_read(l->name_size, l->name, io_user_data); + io_seek(f, 0, IO_SEEK_END, io_user_data); - CHECK(mem_eq(ar_begin, AR_MAGIC, 8), "Invalid AR file",); + i64 in_size = io_tell(f, io_user_data); + CHECK(in_size <= linker->max_obj_file_size, "AR file too big",); - u8 *f_begin = ar_begin + 8; + io_seek(f, 0, IO_SEEK_BEGIN, io_user_data); + i64 n = io_read(f, in_size, linker->obj_file_buffer, io_user_data); + CHECK(n == in_size, "Read failed",); - 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; + io_close(f, io_user_data); - i64 size = (i64) u64_from_dec_str((c8 *) f_size, (c8 *) f_size + 10); + // ======================================================== + // + // Read AR library - size = bx_align(size, 2); + u8 *ar_begin = linker->obj_file_buffer; + u8 *ar_end = linker->obj_file_buffer + in_size; - CHECK(mem_eq(f_end, "\x60\x0a", 2), "Invalid AR file",); - CHECK(f_begin + size <= ar_end, "Buffer overflow",); + CHECK(mem_eq(ar_begin, AR_MAGIC, 8), "Invalid AR file",); - if (!mem_eq(f_id, AR_SYMBOL_TABLE, sizeof AR_SYMBOL_TABLE - 1) && - !mem_eq(f_id, AR_STRING_TABLE, sizeof AR_STRING_TABLE - 1)) { - // Read ELF object file + u8 *f_begin = ar_begin + 8; - i64 delta_size = bx_align(size, X86_64_ALIGNMENT); + 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; - CHECK(obj_files_size + delta_size < linker->max_dependencies_size, "Out of memory",); - CHECK(linker->num_obj_files + 1 < linker->max_num_obj_files, "Out of memory",); + i64 size = (i64) u64_from_dec_str((c8 *) f_size, (c8 *) f_size + 10); - mem_cpy(linker->dependencies_buffer + obj_files_size, f_data, size); + size = align(size, 2); - linker->obj_file_offsets[linker->num_obj_files] = obj_files_size; - obj_files_size += delta_size; - linker->obj_file_offsets[++linker->num_obj_files] = obj_files_size; - } + CHECK(mem_eq(f_end, "\x60\x0a", 2), "Invalid AR file",); + CHECK(f_begin + size <= ar_end, "Buffer overflow",); + + if (!mem_eq(f_id, AR_SYMBOL_TABLE, sizeof AR_SYMBOL_TABLE - 1) && + !mem_eq(f_id, AR_STRING_TABLE, sizeof AR_STRING_TABLE - 1)) { + // Read ELF object file + + i64 delta_size = align(size, X86_64_ALIGNMENT); + + CHECK(obj_files_size + delta_size < linker->max_dependencies_size, "Out of memory",); + CHECK(linker->num_obj_files + 1 < linker->max_num_obj_files, "Out of memory",); + + mem_cpy(linker->dependencies_buffer + obj_files_size, f_data, size); + + linker->obj_file_offsets[linker->num_obj_files] = obj_files_size; + obj_files_size += delta_size; + linker->obj_file_offsets[++linker->num_obj_files] = obj_files_size; + } + + f_begin = f_data + size; + } + } break; - f_begin = f_data + size; + default: + FAIL("Not implemented",); } } @@ -3590,7 +3652,7 @@ void dispatch_log(i32 log_level, u32 line, c8 *file, c8 *format, ...) { va_end(ap); fflush(stdout); - i32 len = 56 - (i32) bx_str_len_or(message, message + 56, 56); + i32 len = 56 - (i32) str_len_or(message, message + 56, 56); switch (log_level) { case ERROR: fprintf(stderr, @@ -3661,6 +3723,8 @@ void dispatch_io(u16 op, i64 *id, i64 *size, void *data, void *user_data) { mem_cpy(buf, data, *size); *f = fopen(buf, op == IO_OPEN_READ ? "rb" : "wb"); + if (*f == NULL) + LOG(ERROR, "Open: %s", buf); CHECK(*f != NULL, "File open failed",); break; @@ -3797,7 +3861,7 @@ i64 n_ptr(i64 proc, u64 address) { } i64 n_str(i64 proc, c8 *value) { - i64 len = bx_str_len(value, value + MAX_LITERAL_SIZE - 1); + i64 len = str_len(value, value + MAX_LITERAL_SIZE - 1); i64 n_data = node_data_array_c8(&g_pool, len + 1, value); i64 n_ref = node_data_reference(&g_pool, n_data); p_add(proc, n_data); @@ -3824,7 +3888,7 @@ i64 n_call(i64 proc, i64 target_proc, i64 num_args, Var *args) { } i64 n_call_by_name(i64 proc, c8 *name, i64 num_args, Var *args) { - i64 n = node_ctrl_call_by_name(&g_pool, bx_str_len(name, name + MAX_NAME_SIZE), name, num_args, args); + i64 n = node_ctrl_call_by_name(&g_pool, str_len(name, name + MAX_NAME_SIZE), name, num_args, args); p_add(proc, n); return n; } @@ -3837,7 +3901,7 @@ i64 n_ret(i64 proc, i64 num_vals, Var *vals) { i64 p_new(i64 unit, c8 *name) { i64 p = proc_init(&g_pool); - i64 len = bx_str_len(name, name + MAX_NAME_SIZE); + i64 len = str_len(name, name + MAX_NAME_SIZE); if (len > 0) proc_set_name(&g_pool, p, len, name); u_add(unit, p); @@ -3867,7 +3931,7 @@ void u_entry_point(i64 unit, i64 proc) { } void u_elf_x86_64(i64 unit, c8 *output_file_name) { - i64 name_len = bx_str_len(output_file_name, output_file_name + MAX_PATH_SIZE); + i64 name_len = str_len(output_file_name, output_file_name + MAX_PATH_SIZE); i64 out = io_open_write(name_len, output_file_name, NULL); unit_write(&g_pool, &g_codegen, &g_linker, unit, FORMAT_ELF, ARCH_X86_64, out, NULL); @@ -3881,15 +3945,17 @@ void l_code(i64 unit, i64 link_unit) { } void l_object(i64 unit, c8 *object_library) { - i64 l = unit_init(&g_pool, UNIT_LIBRARY_OBJECT); - unit_set_name(&g_pool, l, bx_str_len(object_library, object_library + MAX_PATH_SIZE), object_library); + i64 l = unit_init(&g_pool, UNIT_LIBRARY_OBJECT); + c8 *path = l_find(object_library); + i64 len = str_len(path, path + MAX_PATH_SIZE); + unit_set_name(&g_pool, l, len, path); unit_link_add(&g_pool, unit, l); } void l_static(i64 unit, c8 *static_library) { i64 l = unit_init(&g_pool, UNIT_LIBRARY_STATIC); c8 *path = l_find(static_library); - i64 len = bx_str_len(path, path + MAX_PATH_SIZE); + i64 len = str_len(path, path + MAX_PATH_SIZE); unit_set_name(&g_pool, l, len, path); unit_link_add(&g_pool, unit, l); } @@ -3898,7 +3964,10 @@ c8 *l_find(c8 *name) { // Find the full path to a library CHECK(name != NULL, "Invalid argument", ""); - CHECK(bx_str_len(name, name + MAX_PATH_SIZE) < MAX_PATH_SIZE, "Invalid argument", ""); + + i64 len = str_len(name, name + MAX_PATH_SIZE); + + CHECK(len < MAX_PATH_SIZE, "Invalid argument", ""); static c8 buf[MAX_PATH_SIZE]; // FIXME @@ -3913,9 +3982,12 @@ c8 *l_find(c8 *name) { } while (0) TRY_("%s"); - TRY_("lib%s.a"); TRY_("/lib/x86_64-linux-gnu/%s"); + + TRY_("lib%s.a"); + TRY_("%s.o"); TRY_("/lib/x86_64-linux-gnu/lib%s.a"); + TRY_("/lib/x86_64-linux-gnu/%s.o"); #undef TRY_ @@ -3943,8 +4015,7 @@ b8 link_with_libc(void) { i64 u = u_new(); // Add the main proc. - // NOTE We don't need a name for it. - i64 mainproc = p_new(u, ""); + i64 mainproc = p_new(u, "main"); { // Call puts N_CALL_BY_NAME( @@ -3960,25 +4031,25 @@ b8 link_with_libc(void) { ); } - // Add the entry point. - i64 entry = p_new_entry(u); - { - // Initialize libc - N_CALL_BY_NAME( - entry, - "__libc_start_main", - n_ref(entry, mainproc), // main - n_i32(entry, 0), // argc - n_ref(entry, n_ptr(entry, 0)), // argv - n_ptr(entry, 0), // init - n_ptr(entry, 0), // fini - n_ptr(entry, 0), // rtld_fini - n_ptr(entry, 0) // stack_end - ); - - // Return - n_ret(entry, 0, NULL); - } + // // Add the entry point. + // i64 entry = p_new_entry(u); + // { + // // Initialize libc + // N_CALL_BY_NAME( + // entry, + // "__libc_start_main", + // n_ref(entry, mainproc), // main + // n_i32(entry, 0), // argc + // n_ref(entry, n_ptr(entry, 0)), // argv + // n_ptr(entry, 0), // init + // n_ptr(entry, 0), // fini + // n_ptr(entry, 0), // rtld_fini + // n_ptr(entry, 0) // stack_end + // ); + + // // Return + // n_ret(entry, 0, NULL); + // } // ============================================================ // @@ -3986,6 +4057,7 @@ b8 link_with_libc(void) { // Add a static library. l_static(u, "c"); + l_object(u, "crt1"); // l_static(u, "test"); // Write the compilation unit into an executable file. |