summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMitya Selivanov <automainint@guattari.tech>2024-06-11 12:58:23 +0200
committerMitya Selivanov <automainint@guattari.tech>2024-06-11 12:58:23 +0200
commit0158fc479e3be59f1e2e8bfea4d0021e135a589e (patch)
tree2a23101b6e7894253206c9561ee4776b45f1dadc
parentb8ab04e26e8d1352e5a6cbd51e640c7d799e2eb3 (diff)
downloadbxgen-0158fc479e3be59f1e2e8bfea4d0021e135a589e.zip
parsing ar library
-rwxr-xr-xbxgen.c193
1 files changed, 184 insertions, 9 deletions
diff --git a/bxgen.c b/bxgen.c
index 1482992..7419611 100755
--- a/bxgen.c
+++ b/bxgen.c
@@ -2,6 +2,7 @@
SRC=${0##*/}
BIN=${SRC%.*}
gcc \
+ -Wno-old-style-declaration \
-Wno-missing-field-initializers -Wno-missing-braces \
-Wall -Wextra -Werror -pedantic \
-O0 -fsanitize=undefined,address,leak -mshstk \
@@ -181,9 +182,14 @@ enum {
IO_OPEN = 0,
IO_CLOSE,
+ IO_SEEK,
IO_READ,
IO_WRITE,
IO_CHMOD_EXE,
+
+ IO_SEEK_CURSOR = 0,
+ IO_SEEK_BEGIN,
+ IO_SEEK_END,
};
// A semantic node is an operation with optional data
@@ -332,6 +338,7 @@ void unit_write(pool_t *pool, i64 unit, u16 target, i64 io_id, void *io_user_dat
i64 io_open(i64 name_size, c8 *name, void *user_data);
void io_close(i64 f, void *user_data);
+i64 io_seek(i64 f, i64 offset, u16 origin, void *user_data);
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);
@@ -705,13 +712,170 @@ void unit_set_entry_point(pool_t *pool, i64 unit, i64 entry_point_proc) {
// Code generation proc
//
+#include <stdio.h> // TEMP
+#include <stdlib.h> // TEMP
+
void unit_write(pool_t *pool, i64 unit, u16 target, i64 io_out, void *io_user_data) {
assert(pool != NULL && pool->entities != NULL);
assert(pool->entities[unit].is_enabled);
assert(pool->entities[unit].unit.entry_point_index != UNDEFINED);
assert(target == (FORMAT_ELF | ARCH_X86_64));
-// unit_t *u =
+ // Read dependencies
+ //
+ {
+ unit_t *u = &pool->entities[unit].unit;
+
+ for (i64 i = 0; i < u->link_count; ++i) {
+ if (u->links[i] == UNDEFINED)
+ continue;
+
+ i64 index = u->links[i];
+ unit_t *l = &pool->entities[index].unit;
+
+ assert(pool->entities[index].is_enabled);
+ assert(l->type == UNIT_LIBRARY_STATIC);
+ assert(l->name_size > 0 && l->name_size <= MAX_NAME_SIZE);
+
+ i64 f = io_open(l->name_size, l->name, io_user_data);
+
+ c8 buf0_[MAX_NAME_SIZE + 1] = { 0 };
+ memcpy(buf0_, l->name, l->name_size);
+ printf("\nReading `%s` library...\n\n", buf0_);
+
+ i64 n = 0;
+
+ // Read AR
+ //
+
+ u8 magic[8];
+
+ n = io_read(f, sizeof magic, magic, io_user_data); if (n == 0) continue;
+
+ assert(magic[0] == '!');
+ assert(magic[1] == '<');
+ assert(magic[2] == 'a');
+ assert(magic[3] == 'r');
+ assert(magic[4] == 'c');
+ assert(magic[5] == 'h');
+ assert(magic[6] == '>');
+ assert(magic[7] == '\n');
+
+ u32 static offsets[10000] = { 0 };
+ i64 file_count = 1;
+
+ for (i64 k = 0;;) {
+ c8 id[17] = { 0 };
+ c8 timestamp[13] = { 0 };
+ c8 owner[7] = { 0 };
+ c8 group[7] = { 0 };
+ c8 mode[9] = { 0 };
+ c8 size[11] = { 0 };
+ c8 end[2] = { 0 };
+
+ n = io_read(f, (sizeof id) - 1, id, io_user_data); if (n == 0) break;
+ n = io_read(f, (sizeof timestamp) - 1, timestamp, io_user_data); if (n == 0) break;
+ n = io_read(f, (sizeof owner) - 1, owner, io_user_data); if (n == 0) break;
+ n = io_read(f, (sizeof group) - 1, group, io_user_data); if (n == 0) break;
+ n = io_read(f, (sizeof mode) - 1, mode, io_user_data); if (n == 0) break;
+ n = io_read(f, (sizeof size) - 1, size, io_user_data); if (n == 0) break;
+ n = io_read(f, sizeof end, end, io_user_data); if (n == 0) break;
+
+ assert(end[0] == '\x60');
+ assert(end[1] == '\x0a');
+
+ if (strcmp(id, "/ ") == 0) {
+ // Symbol table
+ //
+
+ u32 count_be;
+ n = io_read(f, 4, &count_be, io_user_data); if (n == 0) break;
+
+ file_count =
+ (( count_be & 0xffu) << 24) |
+ (((count_be >> 8) & 0xffu) << 16) |
+ (((count_be >> 16) & 0xffu) << 8) |
+ ((count_be >> 24) & 0xffu);
+
+ printf("Symbol table - %lld symbols.\n\n", file_count);
+ assert(file_count <= (i64) (sizeof offsets / sizeof *offsets));
+
+ for (u32 j = 0; j < file_count; ++j) {
+ u32 offset_be;
+ n = io_read(f, 4, &offset_be, io_user_data); if (n == 0) break;
+
+ offsets[j] =
+ (( offset_be & 0xffu) << 24) |
+ (((offset_be >> 8) & 0xffu) << 16) |
+ (((offset_be >> 16) & 0xffu) << 8) |
+ ((offset_be >> 24) & 0xffu);
+ }
+ if (n == 0) break;
+
+ i64 byte_count = 0;
+
+ for (u32 j = 0; j < file_count; ++j) {
+ for (;;) {
+ c8 c;
+ n = io_read(f, 1, &c, io_user_data); if (n == 0) break;
+ ++byte_count;
+ if (c == '\0')
+ break;
+ printf("%c", c);
+ }
+ if (n == 0) break;
+ printf(" ");
+ }
+ if (n == 0) break;
+
+ printf("\n");
+
+ if ((byte_count & 1) == 1) {
+ // align
+ n = io_seek(f, 1, IO_SEEK_CURSOR, io_user_data); if (n == 0) break;
+ }
+ } else if (strcmp(id, "// ") == 0) {
+ // String table
+ //
+ // Skip file
+ //
+
+ i64 byte_count = atoi(size);
+ if ((byte_count & 1) == 1)
+ ++byte_count; // align
+
+ n = io_seek(f, byte_count, IO_SEEK_CURSOR, io_user_data); if (n == 0) break;
+ } else {
+ if (strstr(id, "/") != NULL)
+ *strstr(id, "/") = '\0';
+ if (strstr(size, " ") != NULL)
+ *strstr(size, " ") = '\0';
+ printf("%08x: %-16s - %5s bytes\n", offsets[k], id, size);
+
+ // Skip file
+ //
+
+ i64 byte_count = atoi(size);
+ if ((byte_count & 1) == 1)
+ ++byte_count; // align
+
+ n = io_seek(f, byte_count, IO_SEEK_CURSOR, io_user_data); if (n == 0) break;
+
+ if (++k == file_count)
+ break;
+ }
+ }
+
+ 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;
@@ -736,13 +900,6 @@ void unit_write(pool_t *pool, i64 unit, u16 target, i64 io_out, void *io_user_da
// ELF header
//
- #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 )
-
WRITE_V( 0x7f, 'E', 'L', 'F' ); // magic
WRITE_V( 2 ); // elf64
@@ -805,6 +962,11 @@ void io_close(i64 f, void *user_data) {
io_dispatch(IO_CLOSE, &f, NULL, NULL, user_data);
}
+i64 io_seek(i64 f, i64 offset, u16 origin, void *user_data) {
+ io_dispatch(IO_SEEK, &f, &offset, &origin, user_data);
+ return offset;
+}
+
i64 io_read(i64 f, i64 size, void *data, void *user_data) {
io_dispatch(IO_READ, &f, &size, data, user_data);
return size;
@@ -864,6 +1026,19 @@ void io_dispatch(i16 op, i64 *id, i64 *size, void *data, void *user_data) {
fclose(*f);
break;
+ case IO_SEEK: {
+ assert(*f != NULL);
+ assert(size != NULL);
+ assert(data != NULL);
+
+ u16 *origin = (u16 *) data;
+ assert(*origin == IO_SEEK_CURSOR || *origin == IO_SEEK_BEGIN || *origin == IO_SEEK_END);
+ i32 s = fseek(*f, *size, *origin == IO_SEEK_CURSOR ? SEEK_CUR :
+ *origin == IO_SEEK_BEGIN ? SEEK_SET :
+ SEEK_END);
+ assert(s == 0);
+ } break;
+
case IO_READ:
assert(*f != NULL);
assert(size != NULL);
@@ -994,7 +1169,7 @@ int main(int argc, char **argv) {
printf("node - %d bytes\n", (i32) sizeof(node_t));
printf("proc - %d bytes\n", (i32) sizeof(proc_t));
printf("unit - %d bytes\n", (i32) sizeof(unit_t));
- printf("entity - %d bytes\n", (i32) sizeof(entity_t));
+ printf("entity - %d bytes\n\n", (i32) sizeof(entity_t));
i64 main = p_new("main");
i64 n0 = n_i64(42);