summaryrefslogtreecommitdiff
path: root/bxgen.c
diff options
context:
space:
mode:
authorMitya Selivanov <automainint@guattari.tech>2024-07-09 18:34:39 +0200
committerMitya Selivanov <automainint@guattari.tech>2024-07-09 18:34:39 +0200
commit1210a16c7fb6764b5eb3697d17b14c06f44d0ef6 (patch)
tree0623076fc5e7ead5d156f697915336f7d44e2042 /bxgen.c
parent96ca3d3d4c263229ea16ef99579974f485de6bf8 (diff)
downloadbxgen-1210a16c7fb6764b5eb3697d17b14c06f44d0ef6.zip
Refactor; Update comments
Diffstat (limited to 'bxgen.c')
-rwxr-xr-xbxgen.c215
1 files changed, 110 insertions, 105 deletions
diff --git a/bxgen.c b/bxgen.c
index 6987216..c123f70 100755
--- a/bxgen.c
+++ b/bxgen.c
@@ -720,8 +720,12 @@ void unit_set_entry_point(Pool *pool, i64 unit, i64 entry_point_proc) {
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
+ // AR https://man.freebsd.org/cgi/man.cgi?query=ar&sektion=5
+ // ELF https://man7.org/linux/man-pages/man5/elf.5.html
+ //
+ // 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
//
assert(pool != NULL && pool->entities != NULL);
@@ -739,6 +743,90 @@ void unit_write(Pool *pool, i64 unit, u16 target, i64 io_out, void *io_user_data
u8 elf_abi_ver = 0; // ABI version
u16 elf_machine = 62; // x86_64
+ #define WRITE(x, n) io_write( io_out, n, x, io_user_data )
+ #define WRITE_V(...) io_write( io_out, sizeof((u8[]) {__VA_ARGS__}), (u8[]) {__VA_ARGS__}, io_user_data )
+ #define WRITE_DUP(x, n) io_write( io_out, n, (u8[n]) { 0 }, io_user_data )
+ #define WRITE_2(x) io_write( io_out, 2, &(u16) { x }, io_user_data )
+ #define WRITE_4(x) io_write( io_out, 4, &(u32) { x }, io_user_data )
+ #define WRITE_8(x) io_write( io_out, 8, &(u64) { x }, io_user_data )
+
+ u16 ehs = 64;
+ u16 shs = 0;
+ u16 phs = 56;
+ u64 align = 8;
+
+ u8 code[16] = {
+ 0xb8, // mov rax
+ 0x3c, 0, 0, 0, // 60 // exit
+ 0x48, 0x31, 0xff, // xor rdx, rdx // rdx = 0
+ 0x0f, 0x05, // syscall
+ };
+
+ u64 code_offset = ehs + phs;
+ u64 code_size = sizeof code;
+ u64 entry_offset = 0;
+
+ u64 base_address = 0x400000; // x86_64 base address
+ u64 code_address = base_address + code_offset;
+ u64 entry = code_address + entry_offset;
+
+ assert((code_offset % align) == 0);
+ assert((code_size % align) == 0);
+
+ // ELF header
+ //
+
+ WRITE_V( 0x7f, 'E', 'L', 'F' ); // magic
+
+ WRITE_V( elf_class );
+ WRITE_V( elf_data );
+ WRITE_V( elf_ver );
+ WRITE_V( elf_abi );
+ WRITE_V( elf_abi_ver );
+
+ WRITE_DUP(0, 7); // padding
+
+ WRITE_2( 2 ); // executable
+ WRITE_2( elf_machine );
+ WRITE_4( 1 ); // current version
+ WRITE_8( entry ); // entry point address
+ WRITE_8( ehs ); // program header offset
+ WRITE_8( 0 ); // section header offset
+ WRITE_4( 0 ); // flags
+ WRITE_2( ehs ); // ELF header size
+ WRITE_2( phs ); // program header size
+ WRITE_2( 1 ); // program header count
+ WRITE_2( shs ); // section header size
+ WRITE_2( 0 ); // section header count
+ WRITE_2( 0 ); // string table section header index
+
+ // Program header
+ //
+
+ WRITE_4( 1 ); // type (PT_LOAD)
+ WRITE_4( 5 ); // flags (PF_X | PF_R)
+ WRITE_8( code_offset ); // offset
+ WRITE_8( code_address ); // vaddr
+ WRITE_8( code_address ); // paddr
+ WRITE_8( code_size ); // filesz
+ WRITE_8( code_size ); // memsz
+ WRITE_8( 8 ); // align
+
+ // Code
+ //
+
+ for (i64 i = code_offset - ehs - phs; i > 0; --i)
+ WRITE_V( 0 );
+
+ WRITE( code, code_size );
+
+ #undef WRITE_V
+ #undef WRITE_DUP
+ #undef WRITE_32
+ #undef WRITE_64
+
+ #undef WRITE
+
// Read dependencies
//
{
@@ -1065,25 +1153,23 @@ void unit_write(Pool *pool, i64 unit, u16 target, i64 io_out, void *io_user_data
current_offset = prev_offset;
}
- printf("%-18s", type >= 1 && type <= 17 ? (c8 const *[]) {
- "Program data",
- "Symbols",
- "String table",
- "Rel width addends",
- "Dynamic",
- "Note",
- "Zero",
- "Rel",
- "",
- "",
- "",
- "",
- "",
- "",
- "",
- "",
- "Group",
- }[type - 1] : "");
+ printf(
+ "%-18s",
+ type >= 1 && type <= 8 ?
+ (c8 const *[]) {
+ "Program data",
+ "Symbols",
+ "String table",
+ "Rel width addends",
+ "Dynamic",
+ "Note",
+ "No data",
+ "Rel",
+ }[type - 1] :
+ type == 17 ?
+ "Group" :
+ ""
+ );
if ((flags & 1) == 1)
printf(" Writable");
@@ -1092,6 +1178,9 @@ void unit_write(Pool *pool, i64 unit, u16 target, i64 io_out, void *io_user_data
if ((flags & 4) == 4)
printf(" Executable");
+ // NOTE
+ // Only alloc sections should be written to the output binary.
+
printf("\n");
}
@@ -1121,90 +1210,6 @@ void unit_write(Pool *pool, i64 unit, u16 target, i64 io_out, void *io_user_data
io_close(f, io_user_data);
}
}
-
- #define WRITE(x, n) io_write( io_out, n, x, io_user_data )
- #define WRITE_V(...) io_write( io_out, sizeof((u8[]) {__VA_ARGS__}), (u8[]) {__VA_ARGS__}, io_user_data )
- #define WRITE_DUP(x, n) io_write( io_out, n, (u8[n]) { 0 }, io_user_data )
- #define WRITE_2(x) io_write( io_out, 2, &(u16) { x }, io_user_data )
- #define WRITE_4(x) io_write( io_out, 4, &(u32) { x }, io_user_data )
- #define WRITE_8(x) io_write( io_out, 8, &(u64) { x }, io_user_data )
-
- u16 ehs = 64;
- u16 shs = 0;
- u16 phs = 56;
- u64 align = 8;
-
- u8 code[16] = {
- 0xb8, // mov rax
- 0x3c, 0, 0, 0, // 60 // exit
- 0x48, 0x31, 0xff, // xor rdx, rdx // rdx = 0
- 0x0f, 0x05, // syscall
- };
-
- u64 code_offset = ehs + phs;
- u64 code_size = sizeof code;
- u64 entry_offset = 0;
-
- u64 base_address = 0x400000; // x86_64 base address
- u64 code_address = base_address + code_offset;
- u64 entry = code_address + entry_offset;
-
- assert((code_offset % align) == 0);
- assert((code_size % align) == 0);
-
- // ELF header
- //
-
- WRITE_V( 0x7f, 'E', 'L', 'F' ); // magic
-
- WRITE_V( elf_class );
- WRITE_V( elf_data );
- WRITE_V( elf_ver );
- WRITE_V( elf_abi );
- WRITE_V( elf_abi_ver );
-
- WRITE_DUP(0, 7); // padding
-
- WRITE_2( 2 ); // executable
- WRITE_2( elf_machine );
- WRITE_4( 1 ); // current version
- WRITE_8( entry ); // entry point address
- WRITE_8( ehs ); // program header offset
- WRITE_8( 0 ); // section header offset
- WRITE_4( 0 ); // flags
- WRITE_2( ehs ); // ELF header size
- WRITE_2( phs ); // program header size
- WRITE_2( 1 ); // program header count
- WRITE_2( shs ); // section header size
- WRITE_2( 0 ); // section header count
- WRITE_2( 0 ); // string table section header index
-
- // Program header
- //
-
- WRITE_4( 1 ); // type (PT_LOAD)
- WRITE_4( 5 ); // flags (PF_X | PF_R)
- WRITE_8( code_offset ); // offset
- WRITE_8( code_address ); // vaddr
- WRITE_8( code_address ); // paddr
- WRITE_8( code_size ); // filesz
- WRITE_8( code_size ); // memsz
- WRITE_8( 8 ); // align
-
- // Code
- //
-
- for (i64 i = code_offset - ehs - phs; i > 0; --i)
- WRITE_V( 0 );
-
- WRITE( code, code_size );
-
- #undef WRITE_V
- #undef WRITE_DUP
- #undef WRITE_32
- #undef WRITE_64
-
- #undef WRITE
}
i64 io_open_read(i64 name_size, c8 *name, void *user_data) {