summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMitya Selivanov <automainint@guattari.tech>2024-08-01 04:05:24 +0200
committerMitya Selivanov <automainint@guattari.tech>2024-08-01 04:05:24 +0200
commitde0850e7f8e62e4b3873e63aee10d9253b006c5f (patch)
tree3527b122eb03bd6fced3369bf24a08a9b8955576
parent7ee8702456a8f2dc4e04f48879eef42a26dbabe8 (diff)
downloadbxgen-de0850e7f8e62e4b3873e63aee10d9253b006c5f.zip
Link with object files; TODO: GOT
-rwxr-xr-xbxgen.c310
1 files changed, 191 insertions, 119 deletions
diff --git a/bxgen.c b/bxgen.c
index d0805f9..f6d0da8 100755
--- a/bxgen.c
+++ b/bxgen.c
@@ -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.