#include "reader.h" #include #include #include #include #include #include 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], §ions[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; }