summaryrefslogtreecommitdiff
path: root/bxgen.c
diff options
context:
space:
mode:
authorMitya Selivanov <automainint@guattari.tech>2024-07-13 22:14:29 +0200
committerMitya Selivanov <automainint@guattari.tech>2024-07-13 22:14:29 +0200
commit9984d86a47d53d331b5bcb674393a2632e9f116e (patch)
tree5dcab9bc78dec5c58598830352f2239a83ec4bd6 /bxgen.c
parent90dfcfd6913b24700b956e9b21661f58b0913e88 (diff)
downloadbxgen-9984d86a47d53d331b5bcb674393a2632e9f116e.zip
Add ELF decoding procs
Diffstat (limited to 'bxgen.c')
-rwxr-xr-xbxgen.c700
1 files changed, 435 insertions, 265 deletions
diff --git a/bxgen.c b/bxgen.c
index a5c590c..f665ca8 100755
--- a/bxgen.c
+++ b/bxgen.c
@@ -397,7 +397,7 @@ i64 io_read(i64 f, i64 size, void *data, void *user_data);
i64 io_write(i64 f, i64 size, void *data, void *user_data);
void io_chmod_exe(i64 f, void *user_data);
-void bx_assert(b8 condition, c8 const *message, u32 line, c8 const *file);
+void bx_assert(b8 condition, c8 *message, u32 line, c8 *file);
void io_dispatch(i16 op, i64 *id, i64 *size, void *data, void *user_data);
#ifndef DISABLE_HELPERS
@@ -448,22 +448,22 @@ i64 bx_align(i64 x, i64 a) {
return x + ((a - (x % a)) % a);
}
-void bx_mem_cpy(void *dst, void const *src, i64 size) {
+void bx_mem_cpy(void *dst, void *src, i64 size) {
BX_ASSERT(dst != NULL);
BX_ASSERT(src != NULL);
BX_ASSERT(size > 0);
for (i64 i = 0; i < size; ++i)
- ((u8 *)dst)[i] = ((u8 const *)src)[i];
+ ((u8 *)dst)[i] = ((u8 *)src)[i];
}
-b8 bx_mem_eq(void const *a, void const *b, i64 size) {
+b8 bx_mem_eq(void *a, void *b, i64 size) {
BX_ASSERT(a != NULL);
BX_ASSERT(b != NULL);
BX_ASSERT(size > 0);
- u8 const *x = (u8 const *) a;
- u8 const *y = (u8 const *) b;
+ u8 *x = (u8 *) a;
+ u8 *y = (u8 *) b;
for (i64 i = 0; i < size; ++i)
if (x[i] != y[i])
@@ -472,9 +472,17 @@ b8 bx_mem_eq(void const *a, void const *b, i64 size) {
return 1;
}
+i64 bx_str_len(c8 *s, c8 *s_max) {
+ for (i64 len = 0; s + len < s_max; ++len)
+ if (s[len] == '\0')
+ return len;
+ BX_ASSERT(0);
+ return 0;
+}
+
b8 bx_str_eq(
- c8 const *a, c8 const *a_end,
- c8 const *b, c8 const *b_end
+ c8 *a, c8 *a_end,
+ c8 *b, c8 *b_end
) {
BX_ASSERT(a != NULL && a_end != NULL);
BX_ASSERT(b != NULL && b_end != NULL);
@@ -817,188 +825,203 @@ void unit_set_entry_point(Pool *pool, i64 unit, i64 entry_point_proc) {
//
// ================================================================
-u16 read_u16(i32 endianness, void const *v) {
+u16 read_u16(i32 endianness, u8 *v, u8 *v_end) {
BX_ASSERT(v != NULL);
+ BX_ASSERT(v + 2 <= v_end);
- u8 const *u = (u8 const *) v;
-
if (endianness == LE)
- return ((u16) u[0]) |
- (((u16) u[1]) << 8);
+ return ((u16) v[0]) |
+ (((u16) v[1]) << 8);
if (endianness == BE)
- return ((u16) u[1]) |
- (((u16) u[0]) << 8);
+ return ((u16) v[1]) |
+ (((u16) v[0]) << 8);
BX_ASSERT(0);
return 0;
}
-u32 read_u32(i32 endianness, void const *v) {
+u32 read_u32(i32 endianness, u8 *v, u8 *v_end) {
BX_ASSERT(v != NULL);
-
- u8 const *u = (u8 const *) v;
+ BX_ASSERT(v + 4 <= v_end);
if (endianness == LE)
- return ((u32) u[0]) |
- (((u32) u[1]) << 8) |
- (((u32) u[2]) << 16) |
- (((u32) u[3]) << 24);
+ return ((u32) v[0]) |
+ (((u32) v[1]) << 8) |
+ (((u32) v[2]) << 16) |
+ (((u32) v[3]) << 24);
if (endianness == BE)
- return ((u32) u[3]) |
- (((u32) u[2]) << 8) |
- (((u32) u[1]) << 16) |
- (((u32) u[0]) << 24);
+ return ((u32) v[3]) |
+ (((u32) v[2]) << 8) |
+ (((u32) v[1]) << 16) |
+ (((u32) v[0]) << 24);
BX_ASSERT(0);
return 0;
}
-u64 read_u64(i32 endianness, void const *v) {
+u64 read_u64(i32 endianness, u8 *v, u8 *v_end) {
BX_ASSERT(v != NULL);
-
- u8 const *u = (u8 const *) v;
+ BX_ASSERT(v + 8 <= v_end);
if (endianness == LE)
- return ((u64) u[0]) |
- (((u64) u[1]) << 8) |
- (((u64) u[2]) << 16) |
- (((u64) u[3]) << 24) |
- (((u64) u[4]) << 32) |
- (((u64) u[5]) << 40) |
- (((u64) u[6]) << 48) |
- (((u64) u[7]) << 56);
+ return ((u64) v[0]) |
+ (((u64) v[1]) << 8) |
+ (((u64) v[2]) << 16) |
+ (((u64) v[3]) << 24) |
+ (((u64) v[4]) << 32) |
+ (((u64) v[5]) << 40) |
+ (((u64) v[6]) << 48) |
+ (((u64) v[7]) << 56);
if (endianness == BE)
- return ((u64) u[7]) |
- (((u64) u[6]) << 8) |
- (((u64) u[5]) << 16) |
- (((u64) u[4]) << 24) |
- (((u64) u[3]) << 32) |
- (((u64) u[2]) << 40) |
- (((u64) u[1]) << 48) |
- (((u64) u[0]) << 56);
+ return ((u64) v[7]) |
+ (((u64) v[6]) << 8) |
+ (((u64) v[5]) << 16) |
+ (((u64) v[4]) << 24) |
+ (((u64) v[3]) << 32) |
+ (((u64) v[2]) << 40) |
+ (((u64) v[1]) << 48) |
+ (((u64) v[0]) << 56);
BX_ASSERT(0);
return 0;
}
-void write_u16(i32 endianness, u16 x, void *v) {
+void write_u16(i32 endianness, u16 x, u8 *v, u8 *v_end) {
BX_ASSERT(v != NULL);
-
- u8 *u = (u8 *) v;
+ BX_ASSERT(v + 2 <= v_end);
if (endianness == LE) {
- u[0] = (u8) ( x & 0xff);
- u[1] = (u8) ((x >> 8) & 0xff);
+ v[0] = (u8) ( x & 0xff);
+ v[1] = (u8) ((x >> 8) & 0xff);
}
if (endianness == BE) {
- u[1] = (u8) ( x & 0xff);
- u[0] = (u8) ((x >> 8) & 0xff);
+ v[1] = (u8) ( x & 0xff);
+ v[0] = (u8) ((x >> 8) & 0xff);
}
BX_ASSERT(0);
}
-void write_u32(i32 endianness, u32 x, void *v) {
+void write_u32(i32 endianness, u32 x, u8 *v, u8 *v_end) {
BX_ASSERT(v != NULL);
-
- u8 *u = (u8 *) v;
+ BX_ASSERT(v + 4 <= v_end);
if (endianness == LE) {
- u[0] = (u8) ( x & 0xff);
- u[1] = (u8) ((x >> 8) & 0xff);
- u[2] = (u8) ((x >> 16) & 0xff);
- u[3] = (u8) ((x >> 24) & 0xff);
+ v[0] = (u8) ( x & 0xff);
+ v[1] = (u8) ((x >> 8) & 0xff);
+ v[2] = (u8) ((x >> 16) & 0xff);
+ v[3] = (u8) ((x >> 24) & 0xff);
}
if (endianness == BE) {
- u[3] = (u8) ( x & 0xff);
- u[2] = (u8) ((x >> 8) & 0xff);
- u[1] = (u8) ((x >> 16) & 0xff);
- u[0] = (u8) ((x >> 24) & 0xff);
+ v[3] = (u8) ( x & 0xff);
+ v[2] = (u8) ((x >> 8) & 0xff);
+ v[1] = (u8) ((x >> 16) & 0xff);
+ v[0] = (u8) ((x >> 24) & 0xff);
}
BX_ASSERT(0);
}
-void write_u64(i32 endianness, u64 x, void *v) {
+void write_u64(i32 endianness, u64 x, u8 *v, u8 *v_end) {
BX_ASSERT(v != NULL);
-
- u8 *u = (u8 *) v;
+ BX_ASSERT(v + 8 <= v_end);
if (endianness == LE) {
- u[0] = (u8) ( x & 0xff);
- u[1] = (u8) ((x >> 8) & 0xff);
- u[2] = (u8) ((x >> 16) & 0xff);
- u[3] = (u8) ((x >> 24) & 0xff);
- u[4] = (u8) ((x >> 32) & 0xff);
- u[5] = (u8) ((x >> 40) & 0xff);
- u[6] = (u8) ((x >> 48) & 0xff);
- u[7] = (u8) ((x >> 56) & 0xff);
+ v[0] = (u8) ( x & 0xff);
+ v[1] = (u8) ((x >> 8) & 0xff);
+ v[2] = (u8) ((x >> 16) & 0xff);
+ v[3] = (u8) ((x >> 24) & 0xff);
+ v[4] = (u8) ((x >> 32) & 0xff);
+ v[5] = (u8) ((x >> 40) & 0xff);
+ v[6] = (u8) ((x >> 48) & 0xff);
+ v[7] = (u8) ((x >> 56) & 0xff);
}
if (endianness == BE) {
- u[7] = (u8) ( x & 0xff);
- u[6] = (u8) ((x >> 8) & 0xff);
- u[5] = (u8) ((x >> 16) & 0xff);
- u[4] = (u8) ((x >> 24) & 0xff);
- u[3] = (u8) ((x >> 32) & 0xff);
- u[2] = (u8) ((x >> 40) & 0xff);
- u[1] = (u8) ((x >> 48) & 0xff);
- u[0] = (u8) ((x >> 56) & 0xff);
+ v[7] = (u8) ( x & 0xff);
+ v[6] = (u8) ((x >> 8) & 0xff);
+ v[5] = (u8) ((x >> 16) & 0xff);
+ v[4] = (u8) ((x >> 24) & 0xff);
+ v[3] = (u8) ((x >> 32) & 0xff);
+ v[2] = (u8) ((x >> 40) & 0xff);
+ v[1] = (u8) ((x >> 48) & 0xff);
+ v[0] = (u8) ((x >> 56) & 0xff);
}
BX_ASSERT(0);
}
-i16 read_i16(i32 endianness, void *v) {
- return (i16) read_u16(endianness, v);
+i16 read_i16(i32 endianness, void *v, void *v_end) {
+ return (i16) read_u16(endianness, v, v_end);
}
-i32 read_i32(i32 endianness, void *v) {
- return (i32) read_u32(endianness, v);
+i32 read_i32(i32 endianness, void *v, void *v_end) {
+ return (i32) read_u32(endianness, v, v_end);
}
-i64 read_i64(i32 endianness, void *v) {
- return (i64) read_u64(endianness, v);
+i64 read_i64(i32 endianness, void *v, void *v_end) {
+ return (i64) read_u64(endianness, v, v_end);
}
-f32 read_f32(i32 endianness, void *v) {
- return *(f32 *) &(u32) { read_u32(endianness, v) };
+f32 read_f32(i32 endianness, void *v, void *v_end) {
+ return *(f32 *) &(u32) { read_u32(endianness, v, v_end) };
}
-f32 read_f64(i32 endianness, void *v) {
- return *(f64 *) &(u64) { read_u64(endianness, v) };
+f32 read_f64(i32 endianness, void *v, void *v_end) {
+ return *(f64 *) &(u64) { read_u64(endianness, v, v_end) };
}
-void write_i16(i32 endianness, i16 x, void *v) {
- write_u16(endianness, (u16) x, v);
+void write_i16(i32 endianness, i16 x, void *v, void *v_end) {
+ write_u16(endianness, (u16) x, v, v_end);
}
-void write_i32(i32 endianness, i32 x, void *v) {
- write_u32(endianness, (u32) x, v);
+void write_i32(i32 endianness, i32 x, void *v, void *v_end) {
+ write_u32(endianness, (u32) x, v, v_end);
}
-void write_i64(i32 endianness, i64 x, void *v) {
- write_u64(endianness, (u64) x, v);
+void write_i64(i32 endianness, i64 x, void *v, void *v_end) {
+ write_u64(endianness, (u64) x, v, v_end);
}
-void write_f32(i32 endianness, f32 x, void *v) {
- write_u32(endianness, *(u32 *) &x, v);
+void write_f32(i32 endianness, f32 x, void *v, void *v_end) {
+ write_u32(endianness, *(u32 *) &x, v, v_end);
}
-void write_f64(i32 endianness, f64 x, void *v) {
- write_u64(endianness, *(u64 *) &x, v);
+void write_f64(i32 endianness, f64 x, void *v, void *v_end) {
+ write_u64(endianness, *(u64 *) &x, v, v_end);
}
// ================================================================
//
// * Code generation and linking
//
+// ----------------------------------------------------------------
+//
+// Docs and helpful materials
+//
+// AR https://man.freebsd.org/cgi/man.cgi?query=ar&sektion=5
+// ELF https://man7.org/linux/man-pages/man5/elf.5.html
+//
+// Relocation types
+// https://intezer.com/blog/malware-analysis/executable-and-linkable-format-101-part-3-relocations/
+// https://docs.oracle.com/cd/E19120-01/open.solaris/819-0690/chapter7-2/index.html
+//
+// https://web.archive.org/web/20150324024617/http://mylinuxbook.com/readelf-command/
+//
+// LLVM impl https://github.com/llvm/llvm-project/blob/main/lld/ELF/Driver.cpp#L2822
+// https://github.com/llvm/llvm-project/blob/main/lld/ELF/Writer.cpp#L304
+// https://github.com/llvm/llvm-project/blob/main/lld/ELF/OutputSections.cpp#L469
+//
+// Online assembler
+// https://defuse.ca/online-x86-assembler.htm
+// https://shell-storm.org/online/Online-Assembler-and-Disassembler/
+//
// ================================================================
#include <stdio.h> // TEMP
@@ -1060,59 +1083,204 @@ typedef struct {
Input_Section_Info input_sections[MAX_INPUT_SECTIONS];
} Binary_Output;
-void unit_write(Pool *pool, i64 unit, u16 target, i64 io_out, void *io_user_data) {
- // Docs
- //
- // AR https://man.freebsd.org/cgi/man.cgi?query=ar&sektion=5
- // ELF https://man7.org/linux/man-pages/man5/elf.5.html
- //
- // Relocation types
- // https://intezer.com/blog/malware-analysis/executable-and-linkable-format-101-part-3-relocations/
- // https://docs.oracle.com/cd/E19120-01/open.solaris/819-0690/chapter7-2/index.html
- //
- // https://web.archive.org/web/20150324024617/http://mylinuxbook.com/readelf-command/
- //
- // LLVM impl https://github.com/llvm/llvm-project/blob/main/lld/ELF/Driver.cpp#L2822
- // https://github.com/llvm/llvm-project/blob/main/lld/ELF/Writer.cpp#L304
- // https://github.com/llvm/llvm-project/blob/main/lld/ELF/OutputSections.cpp#L469
- //
- // Online assembler
- // https://defuse.ca/online-x86-assembler.htm
- // https://shell-storm.org/online/Online-Assembler-and-Disassembler/
+// ================================================================
- BX_ASSERT(pool != NULL && pool->entities != NULL);
- BX_ASSERT(pool->entities[unit].is_enabled);
- BX_ASSERT(pool->entities[unit].unit.entry_point_index != UNDEFINED);
- BX_ASSERT(target == (FORMAT_ELF | ARCH_X86_64));
+typedef struct {
+ u64 offset;
+ u64 size;
+} Offset_Size;
- // ==============================================================
+typedef struct {
+ u64 offset;
+ u16 count;
+} Offset_Count;
+
+typedef struct {
+ Offset_Size name;
+ u32 type;
+ u64 flags;
+ Offset_Size data;
+} Section_Header;
+
+typedef struct {
+ Offset_Size name;
+ u8 info;
+ Offset_Size section;
+ Offset_Size value;
+} Symbol_Entry;
- c8 ELF_MAGIC[4] = "\x7f" "ELF";
+typedef struct {
+ Offset_Size dst;
+ Offset_Size symbol;
+ u32 type;
+} Rel_Entry;
- u8 ELF_64 = 2;
- u8 ELF_2_LE = 1;
- u8 ELF_VERSION = 1;
- u8 ELF_SYS_V = 0;
- u8 ELF_LINUX = 3;
- u8 ELF_ABI_VERSION = 0;
- u16 ELF_RELOCATABLE = 1;
- u16 ELF_EXECUTABLE = 2;
- u16 ELF_X86_64 = 62;
+typedef struct {
+ Offset_Size dst;
+ Offset_Size symbol;
+ u32 type;
+ i64 addent;
+} Rela_Entry;
+
+c8 ELF_MAGIC[4] = "\x7f" "ELF";
+u8 ELF_64 = 2;
+u8 ELF_2_LE = 1;
+u8 ELF_VERSION = 1;
+u8 ELF_SYS_V = 0;
+u8 ELF_LINUX = 3;
+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;
+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";
- u16 ELF_HEADER_SIZE = 64;
- u16 ELF_PROGRAM_HEADER_SIZE = 56;
- u16 ELF_SECTION_HEADER_SIZE = 64;
+// ================================================================
- u64 X86_64_BASE_ADDRESS = 0x400000;
- u64 X86_64_ALIGNMENT = 8;
+u32 ar_find_symbol_offset_by_name(u8 *ar_symbol_table, u8 *ar_end, c8 *name, c8 *name_end) {
+ BX_ASSERT(ar_symbol_table != NULL);
+ BX_ASSERT(name != NULL);
+ BX_ASSERT(name_end > name);
- c8 AR_MAGIC[8] = "!<arch>\n";
+ u32 count = read_u32(BE, ar_symbol_table, ar_end);
- c8 AR_SYMBOL_TABLE[] = "/ ";
- c8 AR_STRING_TABLE[] = "// ";
+ i64 len = name_end - name;
+
+ c8 *s = (c8 *) (ar_symbol_table + 4 * (count + 1));
+ u32 index = 0;
+
+ for (; index < count; ++index) {
+ BX_ASSERT(s + len <= (c8 *) ar_end);
+ if (s[len] == '\0' && bx_mem_eq(s, name, len))
+ return read_u32(BE, ar_symbol_table + 4 * (index + 1), ar_end);
+ while (*s != '\0' && s < (c8 *) ar_end)
+ ++s;
+ BX_ASSERT(s < (c8 *) ar_end);
+ BX_ASSERT(*s == '\0');
+ ++s;
+ }
+
+ BX_ASSERT(0);
+ return 0;
+}
+
+u16 elf_section_names_table_index(
+ u8 *elf_begin,
+ u8 *elf_end
+) {
+ return read_u16(LE, elf_begin + 62, elf_end);
+}
+
+Offset_Count elf_section_headers(
+ u8 *elf_begin,
+ u8 *elf_end
+) {
+ return (Offset_Count) {
+ .offset = read_u64(LE, elf_begin + 40, elf_end),
+ .count = read_u16(LE, elf_begin + 60, elf_end),
+ };
+}
+
+u64 elf_section_header_offset(
+ u8 *elf_begin,
+ u8 *elf_end,
+ u16 index
+) {
+ return elf_section_headers(elf_begin, elf_end).offset + ELF_SECTION_HEADER_SIZE * index;
+}
+
+Offset_Size elf_section_names_data(
+ u8 *elf_begin,
+ u8 *elf_end
+) {
+ u16 string_table_index = elf_section_names_table_index(elf_begin, elf_end);
+
+ u8 *begin = elf_begin + elf_section_header_offset(elf_begin, elf_end, string_table_index);
+
+ return (Offset_Size) {
+ .offset = read_u64(LE, begin + 24, elf_end),
+ .size = read_u64(LE, begin + 32, elf_end),
+ };
+}
+
+Offset_Size elf_name_in_string_table(
+ u8 * elf_begin,
+ u8 * elf_end,
+ Offset_Size string_table,
+ u32 name_offset
+) {
+ u64 offset = string_table.offset + name_offset;
+ c8 *begin = (c8 *) (elf_begin + offset);
+ c8 *end = begin + string_table.size;
+
+ BX_ASSERT(end <= (c8 *) elf_end);
+
+ return (Offset_Size) {
+ .offset = offset,
+ .size = bx_str_len(begin, end),
+ };
+}
+
+u64 elf_find_section_header_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);
+
+ for (u16 i = 0; i < headers.count; ++i) {
+ u8 *begin = elf_begin + headers.offset + i * ELF_SECTION_HEADER_SIZE;
+ u32 name_offset = read_u32(LE, begin, elf_end);
+
+ 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;
+ }
+
+ BX_ASSERT(0);
+ return 0;
+}
+
+Section_Header elf_section_data_by_offset(
+ u8 *elf_begin,
+ u8 *elf_end,
+ u64 offset
+) {
+ Offset_Size names = elf_section_names_data(elf_begin, elf_end);
+ u8 * begin = elf_begin + offset;
+ u32 name_index = read_u32(LE, begin, elf_end);
+
+ return (Section_Header) {
+ .name = elf_name_in_string_table(
+ elf_begin,
+ elf_end,
+ names,
+ name_index
+ ),
+ .type = read_u32(LE, begin + 4, elf_end),
+ .flags = read_u64(LE, begin + 8, elf_end),
+ .data = {
+ .offset = read_u64(LE, begin + 24, elf_end),
+ .size = read_u64(LE, begin + 32, elf_end),
+ },
+ };
+}
+
+void unit_write(Pool *pool, i64 unit, u16 target, i64 io_out, void *io_user_data) {
+ BX_ASSERT(pool != NULL && pool->entities != NULL);
+ BX_ASSERT(pool->entities[unit].is_enabled);
+ BX_ASSERT(pool->entities[unit].unit.entry_point_index != UNDEFINED);
+ BX_ASSERT(target == (FORMAT_ELF | ARCH_X86_64));
- c8 STRTAB[] = ".strtab";
-
// ==============================================================
#define WRITE(x, n) io_write( io_out, n, x, io_user_data )
@@ -1197,143 +1365,145 @@ void unit_write(Pool *pool, i64 unit, u16 target, i64 io_out, void *io_user_data
// Intermediate buffer
//
+ if (0) {
+ u8 static in_buffer[1024 * 1024 * 300]; // 300 MB
+ i64 static ar_offsets[128];
+ i64 ar_count = 0;
- u8 static in_buffer[1024 * 1024 * 300]; // 300 MB
- i64 static ar_offsets[128];
- i64 ar_count = 0;
-
- // Read all dependency files into the memory
- //
- {
- Unit *u = &pool->entities[unit].unit;
-
- for (i64 link_index = 0; link_index < u->link_count; ++link_index) {
- i64 id = u->links[link_index];
- if (id == UNDEFINED)
- continue;
- BX_ASSERT(ar_count + 1 < (i64) (sizeof ar_offsets / sizeof *ar_offsets));
+ // Read all dependency files into the memory
+ //
+ {
+ Unit *u = &pool->entities[unit].unit;
+
+ for (i64 link_index = 0; link_index < u->link_count; ++link_index) {
+ i64 id = u->links[link_index];
+ if (id == UNDEFINED)
+ continue;
+ BX_ASSERT(ar_count + 1 < (i64) (sizeof ar_offsets / sizeof *ar_offsets));
- Unit *l = &pool->entities[id].unit;
- BX_ASSERT(pool->entities[id].is_enabled);
- BX_ASSERT(l->type == UNIT_LIBRARY_STATIC);
- BX_ASSERT(l->name_size > 0 && l->name_size <= MAX_NAME_SIZE);
-
- i64 f = io_open_read(l->name_size, l->name, io_user_data);
- io_seek(f, 0, IO_SEEK_END, io_user_data);
- i64 size = io_tell(f, io_user_data);
- io_seek(f, 0, IO_SEEK_BEGIN, io_user_data);
- if (ar_count == 0)
- ar_offsets[ar_count] = 0;
- ar_offsets[ar_count + 1] = ar_offsets[ar_count] + bx_align(size, 8);
- i64 n = io_read(f, size, in_buffer + ar_offsets[ar_count], io_user_data);
- BX_ASSERT(n == size);
- ++ar_count;
- io_close(f, io_user_data);
+ Unit *l = &pool->entities[id].unit;
+ BX_ASSERT(pool->entities[id].is_enabled);
+ BX_ASSERT(l->type == UNIT_LIBRARY_STATIC);
+ BX_ASSERT(l->name_size > 0 && l->name_size <= MAX_NAME_SIZE);
+
+ i64 f = io_open_read(l->name_size, l->name, io_user_data);
+ io_seek(f, 0, IO_SEEK_END, io_user_data);
+ i64 size = io_tell(f, io_user_data);
+ io_seek(f, 0, IO_SEEK_BEGIN, io_user_data);
+ if (ar_count == 0)
+ ar_offsets[ar_count] = 0;
+ ar_offsets[ar_count + 1] = ar_offsets[ar_count] + bx_align(size, 8);
+ i64 n = io_read(f, size, in_buffer + ar_offsets[ar_count], io_user_data);
+ BX_ASSERT(n == size);
+ ++ar_count;
+ io_close(f, io_user_data);
+ }
}
- }
- for (i64 ar_index = 0; ar_index < ar_count; ++ar_index) {
- // ================================================================
- //
- // Read AR library
+ for (i64 ar_index = 0; ar_index < ar_count; ++ar_index) {
+ // ================================================================
+ //
+ // Read AR library
- u8 *ar_begin = in_buffer + ar_offsets[ar_index];
- u8 *ar_end = in_buffer + ar_offsets[ar_index + 1];
+ u8 *ar_begin = in_buffer + ar_offsets[ar_index];
+ u8 *ar_end = in_buffer + ar_offsets[ar_index + 1];
- u8 *ar_symbol_table = NULL;
- u8 *ar_string_table = NULL;
+ u8 *ar_symbol_table = NULL;
+ u8 *ar_string_table = NULL;
- BX_ASSERT(bx_mem_eq(ar_begin, AR_MAGIC, 8));
+ BX_ASSERT(bx_mem_eq(ar_begin, AR_MAGIC, 8));
- u8 *f_begin = ar_begin + 8;
+ u8 *f_begin = ar_begin + 8;
- while (f_begin + 60 < ar_end) {
- u8 *f_id = f_begin;
- u8 *f_size = f_begin + 48;
- u8 *f_end = f_begin + 58;
- u8 *f_data = f_begin + 60;
+ while (f_begin + 60 < ar_end) {
+ u8 *f_id = f_begin;
+ u8 *f_size = f_begin + 48;
+ u8 *f_end = f_begin + 58;
+ u8 *f_data = f_begin + 60;
- i64 fn_size;
- {
- c8 buf[7] = {0};
- bx_mem_cpy(buf, f_size, 6);
- fn_size = atoi(buf);
- }
+ i64 fn_size;
+ {
+ c8 buf[7] = {0};
+ bx_mem_cpy(buf, f_size, 6);
+ fn_size = atoi(buf);
+ }
- fn_size = bx_align(fn_size, 2);
+ fn_size = bx_align(fn_size, 2);
- BX_ASSERT(bx_mem_eq(f_end, "\x60\x0a", 2));
- BX_ASSERT(f_begin + fn_size <= ar_end);
+ BX_ASSERT(bx_mem_eq(f_end, "\x60\x0a", 2));
+ BX_ASSERT(f_begin + fn_size <= ar_end);
- if (bx_mem_eq(f_id, AR_SYMBOL_TABLE, 16)) {
- // AR symbol table
- //
+ if (bx_mem_eq(f_id, AR_SYMBOL_TABLE, 16)) {
+ // AR symbol table
+ //
- ar_symbol_table = f_data;
+ ar_symbol_table = f_data;
- f_begin = f_data + fn_size;
- } else if (bx_mem_eq(f_id, AR_STRING_TABLE, 16)) {
- // String table
- //
+ f_begin = f_data + fn_size;
+ } else if (bx_mem_eq(f_id, AR_STRING_TABLE, 16)) {
+ // String table
+ //
- ar_string_table = f_data;
+ ar_string_table = f_data;
- f_begin = f_data + fn_size;
- } else {
- // ========================================================
- //
- // Decode ELF object file
+ f_begin = f_data + fn_size;
+ } else {
+ // ========================================================
+ //
+ // Decode ELF object file
- u8 *elf_begin = f_data;
- f_begin += fn_size;
+ u8 *elf_begin = f_data;
+ u8 *elf_end = f_begin + fn_size;
+ f_begin = elf_end;
- u64 section_header_offset;
- u16 section_count;
- u16 string_table_index;
- u16 string_table_offset;
+ u64 section_header_offset;
+ u16 section_count;
+ u16 string_table_index;
+ u16 string_table_offset;
- BX_ASSERT(bx_mem_eq(elf_begin, ELF_MAGIC, 4));
- BX_ASSERT(elf_begin[4] == ELF_64);
- BX_ASSERT(elf_begin[5] == ELF_2_LE);
- BX_ASSERT(elf_begin[6] == ELF_VERSION);
- BX_ASSERT(elf_begin[7] == ELF_SYS_V || elf_begin[7] == ELF_LINUX);
- BX_ASSERT(elf_begin[8] == ELF_ABI_VERSION);
+ BX_ASSERT(bx_mem_eq(elf_begin, ELF_MAGIC, 4));
+ BX_ASSERT(elf_begin[4] == ELF_64);
+ BX_ASSERT(elf_begin[5] == ELF_2_LE);
+ BX_ASSERT(elf_begin[6] == ELF_VERSION);
+ BX_ASSERT(elf_begin[7] == ELF_SYS_V || elf_begin[7] == ELF_LINUX);
+ BX_ASSERT(elf_begin[8] == ELF_ABI_VERSION);
- BX_ASSERT(read_u16(LE, elf_begin + 16) == ELF_RELOCATABLE);
- BX_ASSERT(read_u16(LE, elf_begin + 18) == ELF_X86_64);
- BX_ASSERT(read_u32(LE, elf_begin + 20) == ELF_VERSION);
- BX_ASSERT(read_u64(LE, elf_begin + 24) == 0); // entry
- BX_ASSERT(read_u64(LE, elf_begin + 32) == 0); // program header offset
+ BX_ASSERT(read_u16(LE, elf_begin + 16, elf_end) == ELF_RELOCATABLE);
+ BX_ASSERT(read_u16(LE, elf_begin + 18, elf_end) == ELF_X86_64);
+ BX_ASSERT(read_u32(LE, elf_begin + 20, elf_end) == ELF_VERSION);
+ BX_ASSERT(read_u64(LE, elf_begin + 24, elf_end) == 0); // entry
+ BX_ASSERT(read_u64(LE, elf_begin + 32, elf_end) == 0); // program header offset
- section_header_offset = read_u64(LE, elf_begin + 40);
+ section_header_offset = read_u64(LE, elf_begin + 40, elf_end);
- BX_ASSERT(read_u32(LE, elf_begin + 48) == 0); // flags
- BX_ASSERT(read_u16(LE, elf_begin + 52) == ELF_HEADER_SIZE);
- BX_ASSERT(read_u16(LE, elf_begin + 54) == 0); // program header size
- BX_ASSERT(read_u16(LE, elf_begin + 56) == 0); // program header count
- BX_ASSERT(read_u16(LE, elf_begin + 58) == ELF_SECTION_HEADER_SIZE);
+ BX_ASSERT(read_u32(LE, elf_begin + 48, elf_end) == 0); // flags
+ BX_ASSERT(read_u16(LE, elf_begin + 52, elf_end) == ELF_HEADER_SIZE);
+ BX_ASSERT(read_u16(LE, elf_begin + 54, elf_end) == 0); // program header size
+ BX_ASSERT(read_u16(LE, elf_begin + 56, elf_end) == 0); // program header count
+ BX_ASSERT(read_u16(LE, elf_begin + 58, elf_end) == ELF_SECTION_HEADER_SIZE);
- section_count = read_u16(LE, elf_begin + 60);
- string_table_index = read_u16(LE, elf_begin + 62);
+ section_count = read_u16(LE, elf_begin + 60, elf_end);
+ string_table_index = read_u16(LE, elf_begin + 62, elf_end);
- string_table_offset = read_u64(LE, elf_begin + section_header_offset + string_table_index * ELF_SECTION_HEADER_SIZE + 24);
+ string_table_offset = read_u64(LE, elf_begin + section_header_offset + string_table_index * ELF_SECTION_HEADER_SIZE + 24, elf_end);
- (void) ar_symbol_table;
- (void) ar_string_table;
+ (void) ar_symbol_table;
+ (void) ar_string_table;
- (void) section_header_offset;
- (void) section_count;
- (void) string_table_index;
- (void) string_table_offset;
+ (void) section_header_offset;
+ (void) section_count;
+ (void) string_table_index;
+ (void) string_table_offset;
- f_begin = f_data + fn_size;
+ f_begin = f_data + fn_size;
- // ========================================================
+ // ========================================================
+ }
}
}
- }
- return;
+ return;
+ }
// ==============================================================
@@ -1555,7 +1725,7 @@ void unit_write(Pool *pool, i64 unit, u16 target, i64 io_out, void *io_user_data
u64 strings_offset;
u64 symbol_names_offset;
- u32 symbol_names_size;
+ u64 symbol_names_size;
b8 symbol_names_found = 0;
// ELF header
@@ -1630,7 +1800,7 @@ void unit_write(Pool *pool, i64 unit, u16 target, i64 io_out, void *io_user_data
IO_SEEK_BEGIN, io_user_data);
u32 name;
u64 offset;
- u32 size;
+ u64 size;
READ(name);
io_seek(f, 20, IO_SEEK_CURSOR, io_user_data);
@@ -1734,7 +1904,7 @@ void unit_write(Pool *pool, i64 unit, u16 target, i64 io_out, void *io_user_data
printf(
"%-10s",
type >= 1 && type <= 9 ?
- (c8 const *[]) {
+ (c8 *[]) {
"Program",
"Symbols",
"Strings",
@@ -1850,7 +2020,7 @@ void unit_write(Pool *pool, i64 unit, u16 target, i64 io_out, void *io_user_data
printf("%08llx ", sym_value); // symbol address
printf("%-8s ",
- (sym_info & 0xf) <= 4 ? (c8 const *[]) {
+ (sym_info & 0xf) <= 4 ? (c8 *[]) {
"No type",
"Data",
"Func",
@@ -1888,18 +2058,18 @@ void unit_write(Pool *pool, i64 unit, u16 target, i64 io_out, void *io_user_data
printf("\n");
for (byte_count = size; byte_count > 0;) {
- u64 rela_offset;
- u64 rela_info;
+ u64 rel_offset;
+ u64 rel_info;
- READ(rela_offset); BX_ASSERT(n != 0);
- READ(rela_info); BX_ASSERT(n != 0);
+ READ(rel_offset); BX_ASSERT(n != 0);
+ READ(rel_info); BX_ASSERT(n != 0);
- u32 rela_sym = (u32) (rela_info >> 32);
- u32 rela_type = (u32) (rela_info & 0xffffffff);
+ u32 rel_sym = (u32) (rel_info >> 32);
+ u32 rel_type = (u32) (rel_info & 0xffffffff);
printf(" ");
- printf("%08llx sym %-2d type %-2d", rela_offset, rela_sym, rela_type);
+ printf("%08llx sym %-2d type %-2d", rel_offset, rel_sym, rel_type);
printf("\n");
}
@@ -2104,7 +2274,7 @@ void io_chmod_exe(i64 f, void *user_data) {
// Assert
//
-void bx_assert(b8 condition, c8 const *message, u32 line, c8 const *file) {
+void bx_assert(b8 condition, c8 *message, u32 line, c8 *file) {
if (condition)
return;
@@ -2313,8 +2483,8 @@ int main(int argc, char **argv) {
i64 u = u_new();
u_add(u, main);
u_entry_point(u, main);
- l_static(u, "/lib/x86_64-linux-gnu/libc.a");
- // l_static(u, "libtest.a");
+ // l_static(u, "/lib/x86_64-linux-gnu/libc.a");
+ l_static(u, "libtest.a");
printf("Writing ELF x86_64 executable...\n");
u_elf_x86_64(u, "test_foo");