summaryrefslogtreecommitdiff
path: root/bxgen.c
diff options
context:
space:
mode:
Diffstat (limited to 'bxgen.c')
-rwxr-xr-xbxgen.c198
1 files changed, 116 insertions, 82 deletions
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 <stdio.h> // TEMP
#include <stdlib.h> // 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] = "!<arch>\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;