diff options
author | Mitya Selivanov <automainint@guattari.tech> | 2024-07-17 23:13:53 +0200 |
---|---|---|
committer | Mitya Selivanov <automainint@guattari.tech> | 2024-07-17 23:13:53 +0200 |
commit | 7acb2d636540c7b52d67643f60bf366b3fa0a308 (patch) | |
tree | e3a26cc82caba33b21c7784adb85a269eb426365 | |
parent | 640bf3fb685c174466bf453b3ad0dc1e9e3a6855 (diff) | |
download | bxgen-7acb2d636540c7b52d67643f60bf366b3fa0a308.zip |
Print relocations
-rwxr-xr-x | bxgen.c | 205 |
1 files changed, 139 insertions, 66 deletions
@@ -103,6 +103,10 @@ exit $? # */ #define LOG_LEVEL 4 #endif +#ifndef LOG_BLOCKING +#define LOG_BLOCKING 1 +#endif + // ================================================================ // // Basic declarations @@ -1309,16 +1313,16 @@ typedef struct { } Symbol_Entry; typedef struct { - Offset_Size name; - u64 dst; - u32 type; + Symbol_Entry symbol; + u64 dst; + u32 type_; } Rel_Entry; typedef struct { - Offset_Size name; - u64 dst; - u32 type; - i64 addent; + Symbol_Entry symbol; + u64 dst; + u32 type_; + i64 addent; } Rela_Entry; // ================================================================ @@ -1483,35 +1487,51 @@ Section_Header elf_find_section_by_name( return elf_section(b, elf_find_section_index_by_name(b, name, name_size)); } -u16 elf_find_related_section_index( +c8 *elf_name_from_offset( Buffer_Context b, - u16 section_index + Offset_Size name ) { - Offset_Size name = elf_section(b, section_index).name; - c8 *begin = (c8 *) b.begin + name.offset; - c8 *end = begin + name.size; - - BX_CHECK(end <= (c8 *) b.end, "Buffer overflow", 0); - BX_CHECK(end <= (c8 *) b.begin + b.elf.offset + b.elf.size, "Buffer overflow", 0); - - if (*begin == '.') - ++begin; - while (begin < end && *begin != '.') - ++begin; - - BX_CHECK(begin < end, "Not found", 0); + if (name.size == 0) + return ""; - u32 size = (u32) (end - begin); - Offset_Size check_name = elf_section(b, section_index - 1).name; + c8 *begin = (c8 *) (b.begin + name.offset); + i64 len = bx_str_len(begin, (c8 *) b.end); - BX_CHECK(b.begin + check_name.offset + size <= b.end, "Buffer overflow", 0); - BX_CHECK(b.begin + check_name.offset + size <= b.begin + b.elf.offset + b.elf.size, "Buffer overflow", 0); + BX_CHECK((i64) name.size == len, "Buffer overflow", ""); + return begin; +} - if (check_name.size == size && - bx_mem_eq(b.begin + check_name.offset, begin, size)) - return section_index - 1; +Offset_Size elf_find_related_data( + Buffer_Context b, + u16 section_index +) { + Offset_Size src_name = elf_section(b, section_index).name; + Section_Header dst = elf_section(b, section_index - 1); + + if (src_name.size > dst.name.size && + bx_mem_eq( + elf_name_from_offset(b, src_name) + (src_name.size - dst.name.size), + elf_name_from_offset(b, dst.name), + dst.name.size)) + return dst.data; + + u64 num_sections = elf_section_headers(b).num; + + for (u16 i = 0; i < num_sections; ++i) { + if (i == section_index || i + 1 == section_index) + continue; + dst = elf_section(b, i); + if (src_name.size > dst.name.size && + bx_mem_eq( + elf_name_from_offset(b, src_name) + (src_name.size - dst.name.size), + elf_name_from_offset(b, dst.name), + dst.name.size)) { + BX_LOG(WARNING, "Unexpected sections order"); + return dst.data; + } + } - return elf_find_section_index_by_name(b, begin, (u32) (end - begin)); + BX_FAIL("Not found", (Offset_Size) {0}); } Symbol_Entry elf_symbol( @@ -1567,26 +1587,27 @@ Rel_Entry elf_rel( Buffer_Context b, Offset_Size symbol_table, Offset_Size string_table, - u16 section_index, + Offset_Size relocations, + Offset_Size dst, u16 rel_index ) { - Offset_Size data = elf_section(b, section_index).data; - u8 * begin = b.begin + data.offset + rel_index * ELF_REL_ENTRY_SIZE; - u8 * end = begin + ELF_REL_ENTRY_SIZE; + 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}); u64 rel_offset = read_u64(LE, begin, end); u32 rel_type = read_u32(LE, begin + 8, end); u32 rel_sym = read_u32(LE, begin + 12, end); - Symbol_Entry sym = elf_symbol(b, symbol_table, string_table, rel_sym); + BX_CHECK(rel_offset < dst.size, "Buffer overflow", (Rel_Entry) {0}); return (Rel_Entry) { - .name = sym.name, - .dst = data.offset + rel_offset, - .type = rel_type, + .symbol = elf_symbol(b, symbol_table, string_table, rel_sym), + .dst = dst.offset + rel_offset, + .type_ = rel_type, }; } @@ -1594,27 +1615,28 @@ Rela_Entry elf_rela( Buffer_Context b, Offset_Size symbol_table, Offset_Size string_table, - u16 section_index, + Offset_Size relocations, + Offset_Size dst, u16 rela_index ) { - Offset_Size data = elf_section(b, section_index).data; - u8 * begin = b.begin + data.offset + rela_index * ELF_RELA_ENTRY_SIZE; - u8 * end = begin + ELF_RELA_ENTRY_SIZE; + u8 *begin = b.begin + relocations.offset + rela_index * ELF_RELA_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}); u64 rela_offset = read_u64(LE, begin, end); u32 rela_type = read_u32(LE, begin + 8, end); u32 rela_sym = read_u32(LE, begin + 12, end); i64 rela_addent = read_i64(LE, begin + 16, end); - Symbol_Entry sym = elf_symbol(b, symbol_table, string_table, rela_sym); + BX_CHECK(rela_offset < dst.size, "Buffer overflow", (Rel_Entry) {0}); return (Rela_Entry) { - .name = sym.name, - .dst = data.offset + rela_offset, - .type = rela_type, + .symbol = elf_symbol(b, symbol_table, string_table, rela_sym), + .dst = dst.offset + rela_offset, + .type_ = rela_type, .addent = rela_addent, }; } @@ -1641,21 +1663,8 @@ Symbol_Entry elf_find_symbol_by_name( BX_FAIL("Not found", (Symbol_Entry) {0}); } -c8 *elf_name_from_offset( - Buffer_Context b, - Offset_Size name -) { - if (name.size == 0) - return ""; - - c8 *begin = (c8 *) (b.begin + name.offset); - i64 len = bx_str_len(begin, (c8 *) b.end); - - BX_CHECK((i64) name.size == len, "Buffer overflow", ""); - return begin; -} - -#include <stdio.h> // TEMP +#include <stdio.h> // TEMP +#include <stdlib.h> // TEMP 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",); @@ -1866,7 +1875,9 @@ void unit_write(Pool *pool, i64 unit, u16 target, i64 io_out, void *io_user_data }, }; - Offset_Num section_headers = elf_section_headers(buf); + Offset_Num section_headers = elf_section_headers(buf); + Offset_Size symbol_names = {0}; + Offset_Size symbols = {0}; for (u16 sec_index = 0; sec_index < section_headers.num; ++sec_index) { Section_Header section = elf_section(buf, sec_index); @@ -1924,8 +1935,14 @@ void unit_write(Pool *pool, i64 unit, u16 target, i64 io_out, void *io_user_data printf("\n"); switch (section.type_) { - case SEC_SYMBOLS: { - Offset_Size symbol_names = elf_find_section_by_name(buf, SECTION_STRTAB, sizeof SECTION_STRTAB - 1).data; + case SEC_SYMBOLS: + if (symbols.offset == 0) + symbols = section.data; + + if (symbol_names.offset == 0) + symbol_names = elf_find_section_by_name(buf, SECTION_STRTAB, sizeof SECTION_STRTAB - 1).data; + + printf("\n"); for (u32 sym_index = 0; sym_index < section.num_entries; ++sym_index) { Symbol_Entry sym = elf_symbol(buf, section.data, symbol_names, (u16) sym_index); @@ -1970,13 +1987,60 @@ void unit_write(Pool *pool, i64 unit, u16 target, i64 io_out, void *io_user_data } printf("\x1b[37m"); printf("\n"); - } - } break; + } + + printf("\n"); + break; case SEC_RELA: { + if (symbol_names.offset == 0) + symbol_names = elf_find_section_by_name(buf, SECTION_STRTAB, sizeof SECTION_STRTAB - 1).data; + if (symbols.offset == 0) + symbols = elf_find_section_by_name(buf, SECTION_SYMTAB, sizeof SECTION_SYMTAB - 1).data; + + Offset_Size dst = elf_find_related_data(buf, sec_index); + + printf("\n"); + + for (u32 rela_index = 0; rela_index < section.num_entries; ++rela_index) { + Rela_Entry rela = elf_rela(buf, symbols, symbol_names, section.data, dst, rela_index); + + printf( + " %-4d %08llx %-+5lld <= %08llx \"%s\"\n", + rela.type_, + rela.dst, + rela.addent, + rela.symbol.value.offset, + elf_name_from_offset(buf, rela.symbol.name) + ); + } + + printf("\n"); } break; case SEC_REL: { + if (symbol_names.offset == 0) + symbol_names = elf_find_section_by_name(buf, SECTION_STRTAB, sizeof SECTION_STRTAB - 1).data; + if (symbols.offset == 0) + symbols = elf_find_section_by_name(buf, SECTION_SYMTAB, sizeof SECTION_SYMTAB - 1).data; + + Offset_Size dst = elf_find_related_data(buf, sec_index); + + printf("\n"); + + for (u32 rel_index = 0; rel_index < section.num_entries; ++rel_index) { + Rel_Entry rel = elf_rel(buf, symbols, symbol_names, section.data, dst, rel_index); + + printf( + " %-4d %08llx <= %08llx \"%s\"\n", + rel.type_, + rel.dst, + rel.symbol.value.offset, + elf_name_from_offset(buf, rel.symbol.name) + ); + } + + printf("\n"); } break; default:; @@ -2047,6 +2111,11 @@ void io_chmod_exe(i64 f, void *user_data) { #include <sys/stat.h> #endif +void wait_any_input(void) { + while (getc(stdin) != '\n'); + fflush(stdin); +} + void bx_log(i32 log_level, u32 line, c8 *file, c8 *format, ...) { if (file == NULL || format == NULL) return; @@ -2073,6 +2142,8 @@ void bx_log(i32 log_level, u32 line, c8 *file, c8 *format, ...) { message, len, "................................................................", file, line); + if (LOG_BLOCKING) + wait_any_input(); break; case WARNING: @@ -2082,6 +2153,8 @@ void bx_log(i32 log_level, u32 line, c8 *file, c8 *format, ...) { message, len, "................................................................", file, line); + if (LOG_BLOCKING) + wait_any_input(); break; case INFO: |