summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMitya Selivanov <automainint@guattari.tech>2024-07-17 23:13:53 +0200
committerMitya Selivanov <automainint@guattari.tech>2024-07-17 23:13:53 +0200
commit7acb2d636540c7b52d67643f60bf366b3fa0a308 (patch)
treee3a26cc82caba33b21c7784adb85a269eb426365
parent640bf3fb685c174466bf453b3ad0dc1e9e3a6855 (diff)
downloadbxgen-7acb2d636540c7b52d67643f60bf366b3fa0a308.zip
Print relocations
-rwxr-xr-xbxgen.c205
1 files changed, 139 insertions, 66 deletions
diff --git a/bxgen.c b/bxgen.c
index 226b1de..06a2f3c 100755
--- a/bxgen.c
+++ b/bxgen.c
@@ -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: