From aa3bbad0c7bd1f054a9375ba4c23f394a60677be Mon Sep 17 00:00:00 2001 From: Max Wash Date: Fri, 4 Jul 2025 15:28:20 +0100 Subject: [PATCH] image: add executable metadata to tag table entries --- src/bin.h | 32 +++++++++++++++++++++++++ src/image.c | 67 +++++++++++++++++++++++++++++++++++++++++++++++++---- 2 files changed, 95 insertions(+), 4 deletions(-) diff --git a/src/bin.h b/src/bin.h index f8a1979..ed99538 100644 --- a/src/bin.h +++ b/src/bin.h @@ -52,6 +52,12 @@ enum ec3_tag_flags { EC3_TAG_F_NONE = 0x00000000u, }; +enum ec3_executable_format { + EC3_EXEC_NONE = 0x0000u, + EC3_EXEC_ELF = 0x0001u, + EC3_EXEC_OTHER = 0x1000u, +}; + enum ec3_vnode_mode { EC3_V_REG = 0x0001u, EC3_V_DIR = 0x0002u, @@ -126,6 +132,27 @@ PACK(struct ec3_cluster_group { uint8_t g_padding[20]; }); +struct ec3_executable { + b_i16 exe_format; + b_i16 exe_reserved; + + union { + struct { + b_i32 elf_data_offset; + b_i32 elf_data_filesz, elf_data_memsz; + + b_i32 elf_text_offset; + b_i32 elf_text_filesz, elf_text_memsz; + + b_i32 elf_data_align, elf_text_align; + + b_i64 elf_data_vaddr; + b_i64 elf_text_vaddr; + b_i64 elf_entry; + } exe_elf; + }; +}; + struct ec3_tag_table_entry { b_i32 tag_type; b_i32 tag_flags; @@ -133,6 +160,11 @@ struct ec3_tag_table_entry { b_i32 tag_reserved1; b_i64 tag_ident; b_i64 tag_length; + + union { + struct ec3_executable tag_exe; + char tag_reserved2[96]; + }; }; /* Extents serve two purposes: diff --git a/src/image.c b/src/image.c index 5e00b89..ad7dcb5 100644 --- a/src/image.c +++ b/src/image.c @@ -47,6 +47,43 @@ static enum ec3_status decode_header( return EC3_SUCCESS; } +static void decode_tag_executable_info( + const struct ec3_executable *in, + struct ec3_tag_executable_info *out) +{ + out->exe_format = b_i16_btoh(in->exe_format); + + switch (out->exe_format) { + case EC3_EXEC_ELF: + out->exe_elf.elf_data_offset + = b_i32_btoh(in->exe_elf.elf_data_offset); + out->exe_elf.elf_data_filesz + = b_i32_btoh(in->exe_elf.elf_data_filesz); + out->exe_elf.elf_data_memsz + = b_i32_btoh(in->exe_elf.elf_data_memsz); + out->exe_elf.elf_data_align + = b_i32_btoh(in->exe_elf.elf_data_align); + + out->exe_elf.elf_text_offset + = b_i32_btoh(in->exe_elf.elf_text_offset); + out->exe_elf.elf_text_filesz + = b_i32_btoh(in->exe_elf.elf_text_filesz); + out->exe_elf.elf_text_memsz + = b_i32_btoh(in->exe_elf.elf_text_memsz); + out->exe_elf.elf_text_align + = b_i32_btoh(in->exe_elf.elf_text_align); + + out->exe_elf.elf_data_vaddr + = b_i64_btoh(in->exe_elf.elf_data_vaddr); + out->exe_elf.elf_text_vaddr + = b_i64_btoh(in->exe_elf.elf_text_vaddr); + out->exe_elf.elf_entry = b_i64_btoh(in->exe_elf.elf_entry); + break; + default: + break; + } +} + static void decode_tag( const struct ec3_tag_table_entry *in, struct ec3_tag_info *out) @@ -56,6 +93,10 @@ static void decode_tag( out->tag_checksum = b_i32_btoh(in->tag_checksum); out->tag_ident = b_i64_btoh(in->tag_ident); out->tag_total_length = b_i64_btoh(in->tag_length); + + if (out->tag_type) { + decode_tag_executable_info(&in->tag_exe, &out->tag_exe); + } } static void decode_extent( @@ -179,6 +220,12 @@ static enum ec3_status create_ioctx(struct ec3_image_ioctx **out) return EC3_SUCCESS; } +static struct ec3_tag_info *image_ioctx_get_tag_info( + struct ec3_image_ioctx *image) +{ + return b_buffer_ptr(image->io_tag_table); +} + static enum ec3_status open_image_ro( b_path *image_path, enum ec3_image_ioctx_mode mode, @@ -430,7 +477,7 @@ enum ec3_status ec3_image_ioctx_close(struct ec3_image_ioctx *image) return status; } - const struct ec3_tag_info *tags = ec3_image_ioctx_get_tag_info(image); + struct ec3_tag_info *tags = image_ioctx_get_tag_info(image); size_t nr_tags = image->io_header.img_nr_tags; /* first set of tags to write are those that haven't been opened, @@ -461,7 +508,7 @@ enum ec3_status ec3_image_ioctx_close(struct ec3_image_ioctx *image) * read into memory, encoded, and written to the dest image */ for (size_t i = 0; i < nr_tags; i++) { - const struct ec3_tag_info *tag = &tags[i]; + struct ec3_tag_info *tag = &tags[i]; struct ec3_tag_ioctx *tag_io = get_opened_tag( &image->io_opened_tags, @@ -478,6 +525,12 @@ enum ec3_status ec3_image_ioctx_close(struct ec3_image_ioctx *image) continue; } + if (tag->tag_type == EC3_TAG_EXEC) { + memcpy(&tag->tag_exe, + &tag_io->io_tag_info.tag_exe, + sizeof tag->tag_exe); + } + status = shadow_image_write_tag(image, tag, tag_io, &shadow); if (status != EC3_SUCCESS) { shadow_image_cancel(&shadow); @@ -494,7 +547,7 @@ enum ec3_status ec3_image_ioctx_close(struct ec3_image_ioctx *image) * the tag's cluster table with that of the dest image */ for (size_t i = 0; i < nr_tags; i++) { - const struct ec3_tag_info *tag = &tags[i]; + struct ec3_tag_info *tag = &tags[i]; struct ec3_tag_ioctx *tag_io = get_opened_tag( &image->io_opened_tags, @@ -511,6 +564,12 @@ enum ec3_status ec3_image_ioctx_close(struct ec3_image_ioctx *image) continue; } + if (tag->tag_type == EC3_TAG_EXEC) { + memcpy(&tag->tag_exe, + &tag_io->io_tag_info.tag_exe, + sizeof tag->tag_exe); + } + status = shadow_image_write_tag(image, tag, tag_io, &shadow); if (status != EC3_SUCCESS) { shadow_image_cancel(&shadow); @@ -586,7 +645,7 @@ static const struct ec3_tag_info *get_tag_info_by_id( const struct ec3_tag_info *ec3_image_ioctx_get_tag_info( struct ec3_image_ioctx *image) { - return b_buffer_ptr(image->io_tag_table); + return image_ioctx_get_tag_info(image); } const struct ec3_tag_info *ec3_image_ioctx_get_tag_info_by_id(