image: add executable metadata to tag table entries

This commit is contained in:
2025-07-04 15:28:20 +01:00
parent d0d7eb05ac
commit aa3bbad0c7
2 changed files with 95 additions and 4 deletions

View File

@@ -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:

View File

@@ -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(