From 9aae3ebc862cbdbb4f224ba39a4e77a44e7be8c3 Mon Sep 17 00:00:00 2001 From: Mitya Selivanov Date: Wed, 17 Jul 2024 08:38:28 +0200 Subject: Add elf_symbol proc --- bxgen.c | 198 +++++++++++++++++++++++++++++++++++++--------------------------- 1 file changed, 116 insertions(+), 82 deletions(-) (limited to 'bxgen.c') diff --git a/bxgen.c b/bxgen.c index 4ddbd81..28b1b2f 100755 --- a/bxgen.c +++ b/bxgen.c @@ -294,6 +294,7 @@ typedef struct { i64 index_in_proc; union { u8 lit_bytes[MAX_LITERAL_SIZE]; // byte array literal + // TODO use string table i64 lit_int; // integer literal Ret ret; Call call; @@ -1129,64 +1130,6 @@ void write_f64(i32 bit_order, i32 byte_order, i32 f64_dword_order, f64 x, void * #include // TEMP #include // TEMP -// TODO - -enum { - MAX_SECTION_SIZE = 1024 * 1024 * 10, - MAX_SYMBOL_NAME_SIZE = 1024, - MAX_INPUT_SIZE = 1024 * 1024 * 100, - MAX_SYMBOLS = 1024 * 100, - MAX_RELOCATIONS = 1024 * 100, - MAX_INPUT_SECTIONS = 1024 * 10, -}; - -typedef struct { - i64 address_in_memory; - i64 offset_in_file; - i64 size; - u8 bytes[MAX_SECTION_SIZE]; -} Section; - -typedef struct { - i64 src_section; - i64 src_offset_in_file; - i64 src_size; - i64 name_size; - c8 name[MAX_SYMBOL_NAME_SIZE]; -} Symbol; - -typedef struct { - i64 src_section; - i64 src_offset_in_file; - i64 src_size; - i64 dst_section; - i64 dst_address_in_memory; -} Relocation; - -typedef struct { - i64 object; - i64 section; - i64 offset_in_file; - i64 size; -} Input_Section_Info; - -typedef struct { - Section exec; - Section read_only; - Section read_write; - Section zero_init; - i64 symbols_size; - Symbol symbols[MAX_SYMBOLS]; - i64 relocs_size; - Relocation relocs[MAX_RELOCATIONS]; - i64 input_raw_size; - u8 input_raw[MAX_INPUT_SIZE]; - i64 input_sections_size; - Input_Section_Info input_sections[MAX_INPUT_SECTIONS]; -} Binary_Output; - -// ================================================================ - typedef struct { u64 offset; u64 size; @@ -1207,7 +1150,6 @@ typedef struct { typedef struct { Offset_Size name; u8 info; - Offset_Size section; Offset_Size value; } Symbol_Entry; @@ -1234,15 +1176,28 @@ u8 ELF_ABI_VERSION = 0; u16 ELF_RELOCATABLE = 1; u16 ELF_EXECUTABLE = 2; u16 ELF_X86_64 = 62; + u16 ELF_HEADER_SIZE = 64; u16 ELF_PROGRAM_HEADER_SIZE = 56; u16 ELF_SECTION_HEADER_SIZE = 64; +u16 ELF_SYMBOL_ENTRY_SIZE = 24; +u16 ELF_REL_ENTRY_SIZE = 16; +u16 ELF_RELA_ENTRY_SIZE = 24; + u64 X86_64_BASE_ADDRESS = 0x400000; u64 X86_64_ALIGNMENT = 8; c8 AR_MAGIC[8] = "!\n"; c8 AR_SYMBOL_TABLE[] = "/ "; c8 AR_STRING_TABLE[] = "// "; -c8 STRTAB[] = ".strtab"; + +c8 SECTION_TEXT[] = ".text"; +c8 SECTION_RELA_TEXT[] = ".rela.text"; +c8 SECTION_DATA[] = ".data"; +c8 SECTION_BSS[] = ".bss"; +c8 SECTION_RODATA[] = ".rodata"; +c8 SECTION_SYMTAB[] = ".symtab"; +c8 SECTION_STRTAB[] = ".strtab"; +c8 SECTION_SHSTRTAB[] = ".shstrtab"; // ================================================================ @@ -1329,11 +1284,11 @@ Offset_Size elf_name_in_string_table( }; } -u64 elf_find_section_header_by_name( - u8 * elf_begin, - u8 * elf_end, - c8 * name, - u32 name_size +u16 elf_find_section_index_by_name( + u8 *elf_begin, + u8 *elf_end, + c8 *name, + u32 name_size ) { Offset_Count headers = elf_section_headers(elf_begin, elf_end); Offset_Size names = elf_section_names_data(elf_begin, elf_end); @@ -1344,19 +1299,19 @@ u64 elf_find_section_header_by_name( if (name_offset + name_size <= names.size && bx_mem_eq(elf_begin + names.offset + name_offset, name, name_size)) - return headers.offset + i * ELF_SECTION_HEADER_SIZE; + return i; } BX_FAIL("Not found", -1); } -Section_Header elf_section_data_by_offset( +Section_Header elf_section( u8 *elf_begin, u8 *elf_end, - u64 offset + u16 index ) { Offset_Size names = elf_section_names_data(elf_begin, elf_end); - u8 * begin = elf_begin + offset; + u8 * begin = elf_begin + elf_section_header_offset(elf_begin, elf_end, index); u32 name_index = read_u32(HO_u32, begin, elf_end); return (Section_Header) { @@ -1375,6 +1330,84 @@ Section_Header elf_section_data_by_offset( }; } +Section_Header elf_find_section_by_name( + u8 *elf_begin, + u8 *elf_end, + c8 *name, + u32 name_size +) { + return elf_section(elf_begin, elf_end, elf_find_section_index_by_name(elf_begin, elf_end, name, name_size)); +} + +Symbol_Entry elf_symbol( + u8 * elf_begin, + u8 * elf_end, + Offset_Size string_table, + u16 section_index, + u16 symbol_index +) { + Offset_Size data = elf_section(elf_begin, elf_end, section_index).data; + u8 * begin = elf_begin + data.offset + symbol_index * ELF_SYMBOL_ENTRY_SIZE; + u8 * end = elf_begin + data.offset + data.size; + + BX_CHECK(end <= elf_end, "Buffer overflow", (Symbol_Entry) {0}); + + u32 sym_name = read_u32(HO_u32, begin, end); + u8 sym_info = read_u8 (HO_u8, begin + 4); + u16 sym_shndx = read_u16(HO_u16, begin + 6, end); + u64 sym_value = read_u64(HO_u64, begin + 8, end); + u64 sym_size = read_u64(HO_u64, begin + 16, end); + + Offset_Size dst = elf_section(elf_begin, elf_end, sym_shndx).data; + + BX_CHECK(sym_value + sym_size <= dst.size, "Buffer overflow", (Symbol_Entry) {0}); + + return (Symbol_Entry) { + .name = elf_name_in_string_table(elf_begin, elf_end, string_table, sym_name), + .info = sym_info, + .value = { + .offset = dst.offset + sym_value, + .size = sym_size, + }, + }; +} + +Rel_Entry elf_rel( + u8 * elf_begin, + u8 * elf_end, + Offset_Size string_table, + u16 section_index, + u16 rel_index +) { + (void) elf_begin; + (void) elf_end; + (void) string_table; + (void) section_index; + (void) rel_index; + + return (Rel_Entry) { + 0 + }; +} + +Rela_Entry elf_rela( + u8 * elf_begin, + u8 * elf_end, + Offset_Size string_table, + u16 section_index, + u16 rela_index +) { + (void) elf_begin; + (void) elf_end; + (void) string_table; + (void) section_index; + (void) rela_index; + + return (Rela_Entry) { + 0 + }; +} + void unit_write(Pool *pool, i64 unit, u16 target, i64 io_out, void *io_user_data) { BX_CHECK(pool != NULL && pool->entities != NULL, "Invalid arguments",); BX_CHECK(pool->entities[unit].is_enabled, "Unit does not exist",); @@ -1565,25 +1598,26 @@ void unit_write(Pool *pool, i64 unit, u16 target, i64 io_out, void *io_user_data BX_CHECK(read_u8(HO_u8, elf_begin + 1) == ELF_MAGIC[1], "Invalid ELF file",); BX_CHECK(read_u8(HO_u8, elf_begin + 2) == ELF_MAGIC[2], "Invalid ELF file",); BX_CHECK(read_u8(HO_u8, elf_begin + 3) == ELF_MAGIC[3], "Invalid ELF file",); - BX_CHECK(read_u8(HO_u8, elf_begin + 4) == ELF_64, "Invalid ELF file",); - BX_CHECK(read_u8(HO_u8, elf_begin + 5) == ELF_2_LE, "Invalid ELF file",); - BX_CHECK(read_u8(HO_u8, elf_begin + 6) == ELF_VERSION, "Invalid ELF file",); + BX_CHECK(read_u8(HO_u8, elf_begin + 4) == ELF_64, "Invalid ELF file",); + BX_CHECK(read_u8(HO_u8, elf_begin + 5) == ELF_2_LE, "Invalid ELF file",); + BX_CHECK(read_u8(HO_u8, elf_begin + 6) == ELF_VERSION, "Invalid ELF file",); + u8 osabi = read_u8(HO_u8, elf_begin + 7); - BX_CHECK(osabi == ELF_SYS_V || osabi == ELF_LINUX, "Invalid ELF file",); + BX_CHECK(osabi == ELF_SYS_V || osabi == ELF_LINUX, "Invalid ELF file",); BX_CHECK(read_u8(HO_u8, elf_begin + 8) == ELF_ABI_VERSION, "Invalid ELF file",); BX_CHECK(read_u16(HO_u16, elf_begin + 16, elf_end) == ELF_RELOCATABLE, "Invalid ELF file",); - BX_CHECK(read_u16(HO_u16, elf_begin + 18, elf_end) == ELF_X86_64, "Invalid ELF file",); - BX_CHECK(read_u32(HO_u32, elf_begin + 20, elf_end) == ELF_VERSION, "Invalid ELF file",); - BX_CHECK(read_u64(HO_u64, elf_begin + 24, elf_end) == 0, "Invalid ELF file",); // entry - BX_CHECK(read_u64(HO_u64, elf_begin + 32, elf_end) == 0, "Invalid ELF file",); // program header offset + BX_CHECK(read_u16(HO_u16, elf_begin + 18, elf_end) == ELF_X86_64, "Invalid ELF file",); + BX_CHECK(read_u32(HO_u32, elf_begin + 20, elf_end) == ELF_VERSION, "Invalid ELF file",); + BX_CHECK(read_u64(HO_u64, elf_begin + 24, elf_end) == 0, "Invalid ELF file",); // entry + BX_CHECK(read_u64(HO_u64, elf_begin + 32, elf_end) == 0, "Invalid ELF file",); // program header offset section_header_offset = read_u64(HO_u64, elf_begin + 40, elf_end); - BX_CHECK(read_u32(HO_u32, elf_begin + 48, elf_end) == 0, "Invalid ELF file",); // flags - BX_CHECK(read_u16(HO_u16, elf_begin + 52, elf_end) == ELF_HEADER_SIZE, "Invalid ELF file",); - BX_CHECK(read_u16(HO_u16, elf_begin + 54, elf_end) == 0, "Invalid ELF file",); // program header size - BX_CHECK(read_u16(HO_u16, elf_begin + 56, elf_end) == 0, "Invalid ELF file",); // program header count + BX_CHECK(read_u32(HO_u32, elf_begin + 48, elf_end) == 0, "Invalid ELF file",); // flags + BX_CHECK(read_u16(HO_u16, elf_begin + 52, elf_end) == ELF_HEADER_SIZE, "Invalid ELF file",); + BX_CHECK(read_u16(HO_u16, elf_begin + 54, elf_end) == 0, "Invalid ELF file",); // program header size + BX_CHECK(read_u16(HO_u16, elf_begin + 56, elf_end) == 0, "Invalid ELF file",); // program header count BX_CHECK(read_u16(HO_u16, elf_begin + 58, elf_end) == ELF_SECTION_HEADER_SIZE, "Invalid ELF file",); section_count = read_u16(HO_u16, elf_begin + 60, elf_end); @@ -1921,7 +1955,7 @@ void unit_write(Pool *pool, i64 unit, u16 target, i64 io_out, void *io_user_data c8 buf[8]; n = io_read(f, sizeof buf, buf, io_user_data); if (n == 0) break; - if (!bx_mem_eq(buf, STRTAB, 7)) + if (!bx_mem_eq(buf, SECTION_STRTAB, sizeof SECTION_STRTAB - 1)) continue; symbol_names_offset = offset; -- cgit v1.2.3