summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMitya Selivanov <automainint@guattari.tech>2024-07-24 18:38:48 +0200
committerMitya Selivanov <automainint@guattari.tech>2024-07-24 18:38:48 +0200
commit6a546e1cda2da728edc72305c009236b1ecf51ef (patch)
treeda526311b56a557202724a76a4f90989cdafdcb2
parentf89a887bd04d060bf03a8d9f76da8686dc79d9d1 (diff)
downloadbxgen-6a546e1cda2da728edc72305c009236b1ecf51ef.zip
Write output into memory
-rwxr-xr-xbxgen.c354
1 files changed, 198 insertions, 156 deletions
diff --git a/bxgen.c b/bxgen.c
index be2b5d0..9acf2d6 100755
--- a/bxgen.c
+++ b/bxgen.c
@@ -56,7 +56,7 @@
#/
#/ Bugs
#/
-#/ - ...
+#/ - Segmentation fault when assembling all sections
#/
#/ Done features
#/
@@ -166,6 +166,7 @@ enum {
MAX_OBJECT_FILE_SIZE = 10 * 1024 * 1024, // 10 MB
MAX_DEPENDENCIES_SIZE = 50 * 1024 * 1024, // 50 MB
MAX_NOT_FOUND_SIZE = 10 * 1024, // 10 KB
+ MAX_OUTPUT_SIZE = 20 * 1024 * 1024, // 20 MB
MAX_PATH_SIZE = 10 * 1024,
MAX_LITERAL_SIZE = 400,
@@ -381,6 +382,7 @@ typedef struct {
i64 max_num_sections;
i64 max_num_symbols;
i64 max_not_found_size;
+ i64 max_output_size;
u8 * obj_file_buffer;
u8 * dependencies_buffer;
@@ -388,6 +390,7 @@ typedef struct {
i64 * section_addresses;
Internal_Symbol_Entry *symbols;
c8 * not_found_buffer;
+ u8 * output_buffer;
} Pool;
// ================================================================
@@ -1873,56 +1876,31 @@ Symbol_Entry elf_symbol(
};
}
-Relx_Entry elf_rel(
+Relx_Entry elf_relx(
Buffer_Context b,
Offset_Size symbol_table,
Offset_Size string_table,
Offset_Size relocations,
- i64 rel_index
+ i64 relx_index,
+ b8 is_rela
) {
- u8 *begin = b.begin + relocations.offset + rel_index * ELF_REL_ENTRY_SIZE;
- u8 *end = begin + ELF_REL_ENTRY_SIZE;
-
- BX_CHECK(end <= b.end, "Buffer overflow", (Rel_Entry) {0});
- BX_CHECK(end <= b.begin + b.elf.offset + b.elf.size, "Buffer overflow", (Rel_Entry) {0});
- BX_CHECK(end <= b.begin + relocations.offset + relocations.size, "Buffer overflow", (Rel_Entry) {0});
-
- i64 rel_offset = read_i64(LE, begin, end);
- u32 rel_type = read_u32(LE, begin + 8, end);
- i64 rel_sym = (i64) read_u32(LE, begin + 12, end);
-
- return (Relx_Entry) {
- .symbol = elf_symbol(b, symbol_table, string_table, rel_sym),
- .offset = rel_offset,
- .type = rel_type,
- .addent = 0,
- };
-}
-
-Relx_Entry elf_rela(
- Buffer_Context b,
- Offset_Size symbol_table,
- Offset_Size string_table,
- Offset_Size relocations,
- i64 rela_index
-) {
- u8 *begin = b.begin + relocations.offset + rela_index * ELF_RELA_ENTRY_SIZE;
+ u8 *begin = b.begin + relocations.offset + relx_index * (is_rela ? ELF_RELA_ENTRY_SIZE : ELF_REL_ENTRY_SIZE);
u8 *end = begin + ELF_RELA_ENTRY_SIZE;
- BX_CHECK(end <= b.end, "Buffer overflow", (Rela_Entry) {0});
- BX_CHECK(end <= b.begin + b.elf.offset + b.elf.size, "Buffer overflow", (Rela_Entry) {0});
- BX_CHECK(end <= b.begin + relocations.offset + relocations.size, "Buffer overflow", (Rela_Entry) {0});
+ BX_CHECK(end <= b.end, "Buffer overflow", (Relx_Entry) {0});
+ BX_CHECK(end <= b.begin + b.elf.offset + b.elf.size, "Buffer overflow", (Relx_Entry) {0});
+ BX_CHECK(end <= b.begin + relocations.offset + relocations.size, "Buffer overflow", (Relx_Entry) {0});
- i64 rela_offset = read_i64(LE, begin, end);
- u32 rela_type = read_u32(LE, begin + 8, end);
- i64 rela_sym = (i64) read_u32(LE, begin + 12, end);
- i64 rela_addent = read_i64(LE, begin + 16, end);
+ i64 relx_offset = read_i64(LE, begin, end);
+ u32 relx_type = read_u32(LE, begin + 8, end);
+ i64 relx_sym = (i64) read_u32(LE, begin + 12, end);
+ i64 relx_addent = is_rela ? read_i64(LE, begin + 16, end) : 0;
return (Relx_Entry) {
- .symbol = elf_symbol(b, symbol_table, string_table, rela_sym),
- .offset = rela_offset,
- .type = rela_type,
- .addent = rela_addent,
+ .symbol = elf_symbol(b, symbol_table, string_table, relx_sym),
+ .offset = relx_offset,
+ .type = relx_type,
+ .addent = relx_addent,
};
}
@@ -2047,11 +2025,12 @@ void elf_dump(u32 log_level, Buffer_Context b) {
BX_LOG(log_level, " - -");
break;
+ case SEC_REL:
case SEC_RELA: {
BX_LOG(log_level, " - -");
- for (i64 rela_index = 0; rela_index < section.num_entries; ++rela_index) {
- Relx_Entry relx = elf_rela(b, symtab, strtab, section.data, rela_index);
+ for (i64 relx_index = 0; relx_index < section.num_entries; ++relx_index) {
+ Relx_Entry relx = elf_relx(b, symtab, strtab, section.data, relx_index, section.type == SEC_RELA);
BX_LOG(
log_level,
@@ -2075,33 +2054,6 @@ void elf_dump(u32 log_level, Buffer_Context b) {
BX_LOG(log_level, " - -");
} break;
- case SEC_REL: {
- BX_LOG(log_level, " - -");
-
- for (i64 rel_index = 0; rel_index < section.num_entries; ++rel_index) {
- Relx_Entry relx = elf_rel(b, symtab, strtab, section.data, rel_index);
-
- BX_LOG(
- log_level,
- " %-16s %08llx <= %s%08llx\x1b[37m%s\x1b[37m \"%s\"",
- REL_NAMES[relx.type],
- relx.offset,
- relx.symbol.bind == BIND_WEAK ? "\x1b[33m" : "\x1b[32m",
- relx.symbol.value.offset + elf_section(b, relx.symbol.section).data.offset,
- relx.symbol.type == SYM_DATA ? " \x1b[34mdata" :
- relx.symbol.type == SYM_COMMON ? " \x1b[32mdata" :
- relx.symbol.type == SYM_TLS ? " \x1b[35mdata" :
- relx.symbol.type == SYM_PROC ? " \x1b[34mproc" :
- relx.symbol.type == SYM_SECTION ? " \x1b[36msect" :
- relx.symbol.type == SYM_SPECIFIC ? " \x1b[34mspec" :
- " \x1b[33mnone",
- elf_name_from_offset(b, relx.symbol.name)
- );
- }
-
- BX_LOG(log_level, " - -");
- } break;
-
default:;
}
}
@@ -2129,21 +2081,21 @@ void unit_write(Pool *pool, i64 unit, u16 target, i64 io_out, void *io_user_data
0x0f, 0x05, // syscall
};
- i64 num_program_headers = 1;
+ u16 num_program_headers = 1;
- i64 data_offset = bx_align(ELF_HEADER_SIZE + ELF_PROGRAM_HEADER_SIZE * num_program_headers, X86_64_ALIGNMENT);
- i64 code_size = bx_align(sizeof code, X86_64_ALIGNMENT);
- i64 entry_offset = 0;
+ i64 program_offset = bx_align(ELF_HEADER_SIZE + ELF_PROGRAM_HEADER_SIZE * num_program_headers, X86_64_ALIGNMENT);
+ i64 code_size = bx_align(sizeof code, X86_64_ALIGNMENT);
+ i64 entry_offset = 0;
- i64 base_address = X86_64_BASE_ADDRESS;
- i64 code_address = base_address + data_offset;
- i64 entry = code_address + entry_offset;
+ i64 base_address = X86_64_BASE_ADDRESS;
+ i64 rotext_address = base_address + program_offset;
+ i64 entry = rotext_address + entry_offset;
Internal_Symbol_Entry sym_printf = {0};
- i64 text_size = code_size;
- i64 data_size = 0;
- i64 bss_size = 0;
+ i64 rotext_size = code_size;
+ i64 rwzval_size = 0;
+ i64 rwdata_size = 0;
i64 rodata_size = 0;
// ==============================================================
@@ -2250,16 +2202,16 @@ void unit_write(Pool *pool, i64 unit, u16 target, i64 io_out, void *io_user_data
continue;
if (section.exec) {
- pool->section_addresses[num_sections] = base_address + data_offset + text_size;
- text_size += bx_align(section.data.size, X86_64_ALIGNMENT);
+ pool->section_addresses[num_sections] = rotext_size;
+ rotext_size += bx_align(section.data.size, X86_64_ALIGNMENT);
} else if (section.write && section.type == SEC_NOBITS) {
- pool->section_addresses[num_sections] = base_address + data_offset + bss_size;
- bss_size += bx_align(section.data.size, X86_64_ALIGNMENT);
+ pool->section_addresses[num_sections] = rwzval_size;
+ rwzval_size += bx_align(section.data.size, X86_64_ALIGNMENT);
} else if (section.write) {
- pool->section_addresses[num_sections] = base_address + data_offset + data_size;
- data_size += bx_align(section.data.size, X86_64_ALIGNMENT);
+ pool->section_addresses[num_sections] = rwdata_size;
+ rwdata_size += bx_align(section.data.size, X86_64_ALIGNMENT);
} else if (section.data.size > 0) {
- pool->section_addresses[num_sections] = base_address + data_offset + rodata_size;
+ pool->section_addresses[num_sections] = rodata_size;
rodata_size += bx_align(section.data.size, X86_64_ALIGNMENT);
} else {
BX_LAX(0, "Unsupported section type");
@@ -2268,6 +2220,35 @@ void unit_write(Pool *pool, i64 unit, u16 target, i64 io_out, void *io_user_data
}
}
+ i64 rwzval_address = rotext_address + rotext_size;
+ 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);
+ Offset_Num headers = elf_section_headers(buf);
+
+ for (i64 sec_index = 1; sec_index < headers.num; ++sec_index, ++sec_index_global) {
+ BX_CHECK(sec_index_global < num_sections, "Buffer overflow",);
+
+ pool->section_addresses[sec_index_global] = 0;
+
+ Section_Header section = elf_section(buf, sec_index);
+
+ if (!section.alloc)
+ continue;
+
+ if (section.exec)
+ pool->section_addresses[sec_index_global] += rotext_address;
+ else if (section.write && section.type == SEC_NOBITS)
+ pool->section_addresses[sec_index_global] += rwzval_address;
+ else if (section.write)
+ pool->section_addresses[sec_index_global] += rwdata_address;
+ else if (section.data.size > 0)
+ pool->section_addresses[sec_index_global] += rodata_address;
+ }
+ }
+
// ==========================================================
//
// Relocate defined symbols
@@ -2276,7 +2257,7 @@ void unit_write(Pool *pool, i64 unit, u16 target, i64 io_out, void *io_user_data
Buffer_Context buf = elf_buffer_context(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;
+ Offset_Size strtab = elf_find_section_by_name(buf, SECTION_STRTAB, sizeof SECTION_STRTAB - 1).data;
for (i64 sec_index = 1; sec_index < headers.num; ++sec_index) {
Section_Header tab = elf_section(buf, sec_index);
@@ -2289,12 +2270,17 @@ void unit_write(Pool *pool, i64 unit, u16 target, i64 io_out, void *io_user_data
if (sym.section == 0) // undefined symbol
continue;
+ if (sym.section == 65522) // common
+ continue;
- i64 sym_section = sec_index_global + sym.section - 1;
-
- BX_CHECK(sym_section < pool->max_num_sections, "Buffer overflow",);
+ i64 sym_section = 0;
+ i64 sym_address = sym.value.offset;
- i64 sym_address = pool->section_addresses[sym_section] + sym.value.offset;
+ if (sym.section != 65521) {
+ sym_section = sec_index_global + sym.section - 1;
+ BX_CHECK(sym_section < num_sections, "Buffer overflow",);
+ sym_address = pool->section_addresses[sym_section] + sym.value.offset;
+ }
BX_CHECK(num_symbols < pool->max_num_symbols, "Too many symbols",);
@@ -2388,9 +2374,7 @@ void unit_write(Pool *pool, i64 unit, u16 target, i64 io_out, void *io_user_data
BX_CHECK(dst_index >= 0 && dst_index < pool->max_num_sections, "Buffer overflow",);
for (i64 entry_index = 0; entry_index < src_sec.num_entries; ++entry_index) {
- Relx_Entry relx = (src_sec.type == SEC_REL) ?
- elf_rel (buf, symtab, strtab, src_sec.data, entry_index) :
- elf_rela(buf, symtab, strtab, src_sec.data, entry_index);
+ Relx_Entry relx = elf_relx(buf, symtab, strtab, src_sec.data, entry_index, src_sec.type == SEC_RELA);
c8 *sym_name = elf_name_from_offset(buf, relx.symbol.name);
@@ -2414,7 +2398,7 @@ void unit_write(Pool *pool, i64 unit, u16 target, i64 io_out, void *io_user_data
sym_name,
sym_name + relx.symbol.name.size
) == NULL) {
- BX_LOG(WARNING, "Symbol not found: %s", sym_name);
+ BX_LOG(WARNING, "Undefined symbol: %s", sym_name);
BX_CHECK(not_found_size + relx.symbol.name.size + 1 <= pool->max_not_found_size, "Out of memory",);
bx_mem_cpy(pool->not_found_buffer + not_found_size, sym_name, relx.symbol.name.size);
not_found_size += relx.symbol.name.size + 1;
@@ -2435,13 +2419,13 @@ void unit_write(Pool *pool, i64 unit, u16 target, i64 io_out, void *io_user_data
i64 B = pool->section_addresses[dst_index];
// Represents the offset into the global offset table at which the relocation entry's symbol will reside during execution.
- i64 G = symbol.address - base_address - data_offset;
+ i64 G = symbol.address - base_address - program_offset;
// Represents the address of the global offset table.
- i64 GOT = base_address + data_offset;
+ i64 GOT = base_address + program_offset;
// Represents the place (section offset or address) of the Procedure Linkage Table entry for a symbol.
- i64 L = base_address + data_offset;
+ i64 L = base_address + program_offset;
// Represents the place (section offset or address) of the storage unit being relocated (computed using r_offset).
i64 P = pool->section_addresses[dst_index] + relx.offset;
@@ -2523,88 +2507,142 @@ void unit_write(Pool *pool, i64 unit, u16 target, i64 io_out, void *io_user_data
// ==============================================================
//
- // TODO Write sections into the output buffer
-
- // ==============================================================
- //
// Writing the ELF executable
//
- // TODO Write into memory.
+
+ //i64 output_size = bx_align(program_offset + rotext_size + rwzval_size + rwdata_size + rodata_size, X86_64_ALIGNMENT);
+ i64 output_size = bx_align(program_offset + code_size, X86_64_ALIGNMENT);
+
+ BX_CHECK(output_size <= pool->max_output_size, "Out of memory",);
BX_LOG(VERBOSE, "Total %lld sections", num_sections);
BX_LOG(VERBOSE, "Total %lld symbols", num_symbols);
BX_LOG(VERBOSE, "Total size");
- BX_LOG(VERBOSE, ".text - %lld bytes", text_size);
- BX_LOG(VERBOSE, ".bss - %lld bytes", bss_size);
- BX_LOG(VERBOSE, ".data - %lld bytes", data_size);
+ BX_LOG(VERBOSE, ".rotext - %lld bytes", rotext_size);
+ BX_LOG(VERBOSE, ".rwzval - %lld bytes", rwzval_size);
+ BX_LOG(VERBOSE, ".rwdata - %lld bytes", rwdata_size);
BX_LOG(VERBOSE, ".rodata - %lld bytes", rodata_size);
- BX_CHECK(sym_printf.name_size != 0, "Symbol not found: printf",);
+ BX_CHECK(sym_printf.name_size != 0, "Undefined symbol: printf",);
BX_LOG(VERBOSE, "Found printf: %08llx", sym_printf.address);
BX_LOG(VERBOSE, "Writing ELF x86_64 executable");
- #define WRITE(x, n) io_write( io_out, n, x, io_user_data )
- #define WRITE_V(...) io_write( io_out, sizeof((u8[]) {__VA_ARGS__}), (u8[]) {__VA_ARGS__}, io_user_data )
- #define WRITE_DUP(x, n) io_write( io_out, n, (u8[n]) { 0 }, io_user_data )
- #define WRITE_2(x) io_write( io_out, 2, &(u16) { x }, io_user_data )
- #define WRITE_4(x) io_write( io_out, 4, &(u32) { x }, io_user_data )
- #define WRITE_8(x) io_write( io_out, 8, &(u64) { x }, io_user_data )
-
// ELF header
//
- WRITE ( ELF_MAGIC, 4 );
-
- WRITE_V( ELF_64 );
- WRITE_V( ELF_2_LE );
- WRITE_V( ELF_VERSION );
- WRITE_V( ELF_SYS_V );
- WRITE_V( ELF_ABI_VERSION );
-
- WRITE_DUP(0, 7); // padding
-
- WRITE_2( ELF_EXECUTABLE );
- WRITE_2( ELF_X86_64 );
- WRITE_4( ELF_VERSION );
- WRITE_8( entry );
- WRITE_8( ELF_HEADER_SIZE );
- WRITE_8( 0 ); // section header offset
- WRITE_4( 0 ); // flags
- WRITE_2( ELF_HEADER_SIZE );
- WRITE_2( ELF_PROGRAM_HEADER_SIZE );
- WRITE_2( 1 ); // num program headers
- WRITE_2( 0 ); // section header size
- WRITE_2( 0 ); // num section headers
- WRITE_2( 0 ); // string table section header index
-
- // Program header
+ u8 *o = pool->output_buffer;
+ u8 *o_end = o + pool->max_output_size;
+
+ bx_mem_cpy(o, ELF_MAGIC, 4);
+
+ write_u8 (LE, ELF_64, o + 4, o_end);
+ write_u8 (LE, ELF_2_LE, o + 5, o_end);
+ write_u8 (LE, ELF_VERSION, o + 6, o_end);
+ write_u8 (LE, ELF_SYS_V, o + 7, o_end);
+ write_u8 (LE, ELF_ABI_VERSION, o + 8, o_end);
+ // 7 bytes - padding
+ write_u16(LE, ELF_EXECUTABLE, o + 16, o_end);
+ write_u16(LE, ELF_X86_64, o + 18, o_end);
+ write_u32(LE, ELF_VERSION, o + 20, o_end);
+ write_i64(LE, entry, o + 24, o_end);
+ write_u64(LE, ELF_HEADER_SIZE, o + 32, o_end); // program header offset
+ // 8 bytes - section header offset o + 40
+ // 4 bytes - flags o + 48
+ write_u16(LE, ELF_HEADER_SIZE, o + 52, o_end);
+ write_u16(LE, ELF_PROGRAM_HEADER_SIZE, o + 54, o_end);
+ write_u16(LE, num_program_headers, o + 56, o_end);
+ // 2 bytes - section header size o + 58
+ // 2 bytes - num section headers o + 60
+ // 2 bytes - string table section o + 62
+ // header index
+
+ // Program headers
//
- WRITE_4( 1 ); // type (PT_LOAD)
- WRITE_4( 5 ); // flags (PF_X | PF_R)
- WRITE_8( data_offset );
- WRITE_8( code_address ); // virtual address
- WRITE_8( code_address ); // phisical address
- WRITE_8( code_size ); // size in file
- WRITE_8( code_size ); // size in memory
- WRITE_8( X86_64_ALIGNMENT );
+ i64 rotext_offset = program_offset;
+ i64 rwzval_offset = rotext_offset + rotext_size;
+ i64 rwdata_offset = rwzval_offset;
+ i64 rodata_offset = rwdata_offset + rwdata_size;
+
+ // .rotext
+ write_u32(LE, 1, o + 64, o_end); // type (PT_LOAD)
+ write_u32(LE, 5, o + 68, o_end); // flags (PF_X | PF_R)
+ write_i64(LE, rotext_offset, o + 72, o_end);
+ write_i64(LE, rotext_address, o + 80, o_end); // virtual address
+ write_i64(LE, rotext_address, o + 88, o_end); // phisical address
+ write_i64(LE, rotext_size, o + 96, o_end); // size in file
+ write_i64(LE, rotext_size, o + 104, o_end); // size in memory
+ write_i64(LE, X86_64_ALIGNMENT, o + 112, o_end);
+
+ /*
+ // .rwzval
+ write_u32(LE, 1, o + 120, o_end); // type (PT_LOAD)
+ write_u32(LE, 6, o + 124, o_end); // flags (PF_R | PF_W)
+ write_i64(LE, rwzval_offset, o + 128, o_end);
+ write_i64(LE, rwzval_address, o + 136, o_end); // virtual address
+ write_i64(LE, rwzval_address, o + 144, o_end); // phisical address
+ write_i64(LE, 0, o + 152, o_end); // size in file
+ write_i64(LE, rwzval_size, o + 160, o_end); // size in memory
+ write_i64(LE, X86_64_ALIGNMENT, o + 168, o_end);
+
+ // .rwdata
+ write_u32(LE, 1, o + 176, o_end); // type (PT_LOAD)
+ write_u32(LE, 6, o + 180, o_end); // flags (PF_R | PF_W)
+ write_i64(LE, rwdata_offset, o + 184, o_end);
+ write_i64(LE, rwdata_address, o + 192, o_end); // virtual address
+ write_i64(LE, rwdata_address, o + 200, o_end); // phisical address
+ write_i64(LE, rwdata_size, o + 208, o_end); // size in file
+ write_i64(LE, rwdata_size, o + 216, o_end); // size in memory
+ write_i64(LE, X86_64_ALIGNMENT, o + 224, o_end);
+
+ // .rodata
+ write_u32(LE, 1, o + 232, o_end); // type (PT_LOAD)
+ write_u32(LE, 4, o + 236, o_end); // flags (PF_R)
+ write_i64(LE, rodata_offset, o + 240, o_end);
+ write_i64(LE, rodata_address, o + 248, o_end); // virtual address
+ write_i64(LE, rodata_address, o + 256, o_end); // phisical address
+ write_i64(LE, rodata_size, o + 264, o_end); // size in file
+ write_i64(LE, rodata_size, o + 272, o_end); // size in memory
+ write_i64(LE, X86_64_ALIGNMENT, o + 280, o_end);
+ */
+
+ //BX_CHECK(rotext_offset >= 288, "Sanity",);
// Code
//
- for (i64 i = data_offset - ELF_HEADER_SIZE - ELF_PROGRAM_HEADER_SIZE; i > 0; --i)
- WRITE_V( 0 );
+ bx_mem_cpy(o + rotext_offset, code, code_size);
+
+ // ==============================================================
+ //
+ // TODO 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);
+ Offset_Num headers = elf_section_headers(buf);
- WRITE( code, code_size );
+ for (i64 sec_index = 1; sec_index < headers.num; ++sec_index, ++num_sections) {
+ Section_Header section = elf_section(buf, sec_index);
+ if (pool->section_addresses[sec_index] == 0 ||
+ !section.alloc ||
+ section.data.size == 0)
+ continue;
+ u8 *p = o + (pool->section_addresses[sec_index] - base_address);
+ BX_CHECK(p >= pool->output_buffer + program_offset, "Buffer overflow",);
+ BX_CHECK(p + section.data.size <= pool->output_buffer + output_size, "Buffer overflow",);
+ bx_mem_cpy(p, buf.begin + section.data.offset, section.data.size);
+ }
+ }
+ */
- #undef WRITE_V
- #undef WRITE_DUP
- #undef WRITE_32
- #undef WRITE_64
+ // ==============================================================
+ //
+ // Write the output buffer into the file
- #undef WRITE
+ io_write(io_out, output_size, pool->output_buffer, io_user_data);
// ==============================================================
//
@@ -2615,6 +2653,8 @@ void unit_write(Pool *pool, i64 unit, u16 target, i64 io_out, void *io_user_data
bx_mem_set(pool->obj_file_offsets, 0, pool->max_num_obj_files * sizeof *pool->obj_file_offsets);
bx_mem_set(pool->section_addresses, 0, pool->max_num_sections * sizeof *pool->section_addresses);
bx_mem_set(pool->symbols, 0, pool->max_num_symbols * sizeof *pool->symbols);
+ bx_mem_set(pool->not_found_buffer, 0, pool->max_not_found_size);
+ bx_mem_set(pool->output_buffer, 0, pool->max_output_size);
}
i64 io_open_read(i64 name_size, c8 *name, void *user_data) {
@@ -2866,6 +2906,7 @@ Pool g_pool = {
.max_num_sections = MAX_NUM_SECTIONS,
.max_num_symbols = MAX_NUM_SYMBOLS,
.max_not_found_size = MAX_NOT_FOUND_SIZE,
+ .max_output_size = MAX_OUTPUT_SIZE,
.obj_file_buffer = (u8[MAX_OBJECT_FILE_SIZE]) {0},
.dependencies_buffer = (u8[MAX_DEPENDENCIES_SIZE]) {0},
@@ -2873,6 +2914,7 @@ Pool g_pool = {
.section_addresses = (i64[MAX_NUM_SECTIONS]) {0},
.symbols = (Internal_Symbol_Entry[MAX_NUM_SYMBOLS]) {0},
.not_found_buffer = (c8[MAX_NOT_FOUND_SIZE]) {0},
+ .output_buffer = (u8[MAX_OUTPUT_SIZE]) {0},
};
// Handy procedures