asm: implement object file reader

This commit is contained in:
2025-05-12 15:51:03 +01:00
parent 2e4d1e53f3
commit 8d9ae5f36a
3 changed files with 245 additions and 0 deletions

View File

@@ -0,0 +1,46 @@
#ifndef IVY_ASM_READER_H_
#define IVY_ASM_READER_H_
#include <ivy/misc.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
struct ivy_asm_object_info {
uint32_t obj_magic;
size_t obj_table_offset;
size_t obj_nr_sections;
};
struct ivy_asm_section_info {
uint32_t s_type;
size_t s_offset;
size_t s_length;
};
struct ivy_asm_reader;
struct ivy_asm_section_reader;
IVY_API enum ivy_status ivy_asm_reader_open(FILE *in, struct ivy_asm_reader **out);
IVY_API enum ivy_status ivy_asm_reader_close(struct ivy_asm_reader *reader);
IVY_API const struct ivy_asm_object_info *ivy_asm_reader_get_info(
struct ivy_asm_reader *reader);
IVY_API const struct ivy_asm_section_info *ivy_asm_reader_get_sections(
struct ivy_asm_reader *reader);
IVY_API enum ivy_status ivy_asm_reader_open_section(
struct ivy_asm_reader *reader, size_t index,
struct ivy_asm_section_reader **out);
IVY_API const struct ivy_asm_section_info *ivy_asm_section_reader_get_info(
struct ivy_asm_section_reader *reader);
IVY_API enum ivy_status ivy_asm_section_reader_close(
struct ivy_asm_section_reader *reader);
IVY_API enum ivy_status ivy_asm_section_reader_read(
struct ivy_asm_section_reader *reader, size_t offset, size_t count,
void *p, size_t *nr_read);
IVY_API bool ivy_asm_section_type_to_string(uint32_t in, char out[5]);
#endif

181
asm/reader.c Normal file
View File

@@ -0,0 +1,181 @@
#include "reader.h"
#include <ctype.h>
#include <ivy/asm/bin.h>
#include <ivy/asm/reader.h>
#include <ivy/status.h>
#include <stdlib.h>
#include <string.h>
static enum ivy_status decode_header(
const struct ivy_bin_header *hdr, struct ivy_asm_object_info *out)
{
out->obj_magic = b_i32_btoh(hdr->h_magic);
out->obj_nr_sections = b_i16_btoh(hdr->h_table_len);
out->obj_table_offset = b_i64_btoh(hdr->h_table_offset);
return IVY_OK;
}
static enum ivy_status decode_table_entry(
const struct ivy_bin_table_entry *entry, struct ivy_asm_section_info *out)
{
out->s_type = b_i32_btoh(entry->e_type);
out->s_offset = b_i64_btoh(entry->e_offset);
out->s_length = b_i32_btoh(entry->e_size);
return IVY_OK;
}
enum ivy_status ivy_asm_reader_open(FILE *in, struct ivy_asm_reader **out)
{
struct ivy_asm_reader *reader = malloc(sizeof *reader);
if (!reader) {
return IVY_ERR_NO_MEMORY;
}
memset(reader, 0x0, sizeof *reader);
reader->r_fp = in;
fseek(in, 0, SEEK_SET);
struct ivy_bin_header hdr;
size_t r = fread(&hdr, sizeof hdr, 1, in);
if (r != 1) {
free(reader);
return IVY_ERR_IO_FAILURE;
}
enum ivy_status status = decode_header(&hdr, &reader->r_info);
if (status != IVY_OK) {
free(reader);
return status;
}
if (reader->r_info.obj_magic != IVY_BIN_MAGIC) {
free(reader);
return IVY_ERR_BAD_FORMAT;
}
fseek(in, reader->r_info.obj_table_offset, SEEK_SET);
size_t nr_sections = reader->r_info.obj_nr_sections;
struct ivy_bin_table_entry *table = calloc(nr_sections, sizeof *table);
if (!table) {
free(reader);
return IVY_ERR_NO_MEMORY;
}
r = fread(table, sizeof *table, nr_sections, in);
if (r != nr_sections) {
free(table);
free(reader);
return IVY_ERR_IO_FAILURE;
}
struct ivy_asm_section_info *sections
= calloc(nr_sections, sizeof *sections);
for (size_t i = 0; i < nr_sections; i++) {
status = decode_table_entry(&table[i], &sections[i]);
if (status != IVY_OK) {
free(table);
free(sections);
free(reader);
return status;
}
}
free(table);
reader->r_sections = sections;
*out = reader;
return IVY_OK;
}
enum ivy_status ivy_asm_reader_close(struct ivy_asm_reader *reader)
{
free(reader);
return IVY_OK;
}
const struct ivy_asm_object_info *ivy_asm_reader_get_info(
struct ivy_asm_reader *reader)
{
return &reader->r_info;
}
const struct ivy_asm_section_info *ivy_asm_reader_get_sections(
struct ivy_asm_reader *reader)
{
return reader->r_sections;
}
enum ivy_status ivy_asm_reader_open_section(
struct ivy_asm_reader *reader, size_t index,
struct ivy_asm_section_reader **out)
{
if (index >= reader->r_info.obj_nr_sections) {
return IVY_ERR_NO_ENTRY;
}
struct ivy_asm_section_reader *sect = malloc(sizeof *sect);
if (!sect) {
return IVY_ERR_NO_MEMORY;
}
memset(sect, 0x0, sizeof *sect);
sect->r_parent = reader;
sect->r_info = &reader->r_sections[index];
*out = sect;
return IVY_OK;
}
const struct ivy_asm_section_info *ivy_asm_section_reader_get_info(
struct ivy_asm_section_reader *reader)
{
return reader->r_info;
}
enum ivy_status ivy_asm_section_reader_close(struct ivy_asm_section_reader *reader)
{
free(reader);
return IVY_OK;
}
enum ivy_status ivy_asm_section_reader_read(
struct ivy_asm_section_reader *reader, size_t offset, size_t count,
void *p, size_t *nr_read)
{
size_t object_offset = reader->r_info->s_offset + offset;
FILE *fp = reader->r_parent->r_fp;
fseek(fp, object_offset, SEEK_SET);
size_t r = fread(p, 1, count, fp);
*nr_read = r;
return ferror(fp) ? IVY_ERR_IO_FAILURE : IVY_OK;
}
bool ivy_asm_section_type_to_string(uint32_t in, char out[5])
{
b_i32 v = b_i32_htob(in);
for (size_t i = 0; i < sizeof in; i++) {
char c = v.i_bytes[i];
if (!isgraph(c)) {
return false;
}
out[i] = c;
}
out[4] = 0;
return true;
}

18
asm/reader.h Normal file
View File

@@ -0,0 +1,18 @@
#ifndef _ASM_READER_H_
#define _ASM_READER_H_
#include <ivy/asm/reader.h>
#include <stdio.h>
struct ivy_asm_reader {
FILE *r_fp;
struct ivy_asm_object_info r_info;
struct ivy_asm_section_info *r_sections;
};
struct ivy_asm_section_reader {
struct ivy_asm_reader *r_parent;
const struct ivy_asm_section_info *r_info;
};
#endif