Finish import/export functionality

This commit is contained in:
Mario Hüttel 2023-01-06 18:43:47 +01:00
parent aa15e1a541
commit c41214fc75
6 changed files with 165 additions and 157 deletions

View File

@ -0,0 +1,20 @@
#ifndef _ELFPATCHCRC_DATATYPES_H_
#define _ELFPATCHCRC_DATATYPES_H_
#include <stdint.h>
struct crc_entry {
char *name;
uint64_t vma;
uint64_t lma;
uint64_t size;
uint32_t crc;
};
struct crc_import_data {
int elf_bits;
struct crc_settings crc_config;
SlList *crc_entries; /**< @brief linked list of @ref crc_entry structs */
};
#endif /* _ELFPATCHCRC_DATATYPES_H_ */

View File

@ -27,6 +27,7 @@
#include <patchelfcrc/crc.h> #include <patchelfcrc/crc.h>
#include <stdbool.h> #include <stdbool.h>
#include <linklist-lib/singly-linked-list.h> #include <linklist-lib/singly-linked-list.h>
#include <patchelfcrc/crc-datatypes.h>
typedef struct elfpatch elfpatch_handle_t; typedef struct elfpatch elfpatch_handle_t;
@ -87,17 +88,9 @@ int elf_patch_compute_crc_over_section(elfpatch_handle_t *ep, const char *sectio
void elf_patch_close_and_free(elfpatch_handle_t *ep); void elf_patch_close_and_free(elfpatch_handle_t *ep);
/** int elf_patch_write_crcs_to_section(elfpatch_handle_t *ep, const char *output_sec_name,
* @brief Write CRCs to output section. This will have no effect, if file is opened read onyl const struct crc_import_data *crc_data, bool use_vma,
* @param ep Elf patch object uint32_t start_magic, uint32_t end_magic,
* @param[in] section Section name to place CRCs in bool check_start_magic, bool check_end_magic,
* @param[in] section_name_list The list of sections the data belongs to enum crc_format format, bool little_endian);
* @param[in] crcs CRCs. Must be of the same lenght as the \p section_name_list
* @return 0 Success
* @return -1000 Parameter error
* @return -1 internal error
*/
int elf_patch_write_crcs_to_section(elfpatch_handle_t *ep, const char *section, const SlList *section_name_list,
const uint32_t *crcs, uint8_t crc_size_bits, uint32_t start_magic, uint32_t end_magic,
bool check_start_magic, bool check_end_magic, enum crc_format format, bool little_endian);
#endif /* _ELFPATCH_H_ */ #endif /* _ELFPATCH_H_ */

View File

@ -1,29 +1,13 @@
#ifndef _ELFPATCHCRC_XML_H_ #ifndef _ELFPATCHCRC_XML_H_
#define _ELFPATCHCRC_XML_H_ #define _ELFPATCHCRC_XML_H_
#include <stdint.h>
#include <linklist-lib/singly-linked-list.h> #include <linklist-lib/singly-linked-list.h>
#include <patchelfcrc/crc.h> #include <patchelfcrc/crc.h>
#include <patchelfcrc/elfpatch.h> #include <patchelfcrc/crc-datatypes.h>
struct xml_crc_entry {
char *name;
uint64_t vma;
uint64_t lma;
uint64_t size;
uint32_t crc;
};
struct xml_crc_import {
int elf_bits;
struct crc_settings crc_config;
SlList *xml_crc_entries; /**< @brief linked list of @ref xml_crc_entry structs */
};
void xml_init(void); void xml_init(void);
int xml_write_crcs_to_file(const char *path, const uint32_t *crcs, SlList *section_names, int xml_write_crcs_to_file(const char *path, const struct crc_import_data *crc_data);
const struct crc_settings *crc_params, elfpatch_handle_t *ep);
/** /**
* @brief xml_import_from_file Import from file * @brief xml_import_from_file Import from file
@ -31,17 +15,19 @@ int xml_write_crcs_to_file(const char *path, const uint32_t *crcs, SlList *secti
* @return Returns a newly allocated struct. Must be freed with @ref xml_crc_import_free * @return Returns a newly allocated struct. Must be freed with @ref xml_crc_import_free
* @return NULL in case of error * @return NULL in case of error
*/ */
struct xml_crc_import *xml_import_from_file(const char *path); struct crc_import_data *xml_import_from_file(const char *path);
/** /**
* @brief Fully free supplied import data * @brief Fully free supplied import data
* @param data Data to free * @param data Data to free
*/ */
void xml_crc_import_free(struct xml_crc_import *data); void xml_crc_import_free(struct crc_import_data *data);
/** /**
* @brief Print XML XSD file to stdout * @brief Print XML XSD file to stdout
*/ */
void xml_print_xsd(void); void xml_print_xsd(void);
struct crc_import_data *xml_crc_import_alloc(void);
#endif /* _ELFPATCHCRC_XML_H_ */ #endif /* _ELFPATCHCRC_XML_H_ */

View File

@ -574,8 +574,8 @@ int elf_patch_compute_crc_over_section(elfpatch_handle_t *ep, const char *sectio
return 0; return 0;
} }
static size_t calculate_needed_space_for_crcs(elfpatch_handle_t *ep, static size_t calculate_needed_space_for_crcs(enum crc_format format,
enum crc_format format, uint8_t source_elf_bits,
bool check_start_magic, bool check_end_magic, bool check_start_magic, bool check_end_magic,
uint8_t crc_size_bytes, size_t crc_count) uint8_t crc_size_bytes, size_t crc_count)
{ {
@ -588,7 +588,7 @@ static size_t calculate_needed_space_for_crcs(elfpatch_handle_t *ep,
case FORMAT_STRUCT: case FORMAT_STRUCT:
/* Calculate space for CRCs including sentinel struct at the end */ /* Calculate space for CRCs including sentinel struct at the end */
needed_space = (crc_count + 1) * needed_space = (crc_count + 1) *
(ep->class == ELFCLASS32 (source_elf_bits == 32
? sizeof(struct crc_out_struct_32bit) ? sizeof(struct crc_out_struct_32bit)
: sizeof(struct crc_out_struct_64bit)); : sizeof(struct crc_out_struct_64bit));
break; break;
@ -599,8 +599,8 @@ static size_t calculate_needed_space_for_crcs(elfpatch_handle_t *ep,
/* Add existing magic numbers to required space */ /* Add existing magic numbers to required space */
if (check_start_magic) { if (check_start_magic) {
needed_space += 4u; needed_space += 4u;
/* Account for paading after 32 bit magic value in case of structure usage on 64 bit systems */ /* Account for padding after 32 bit magic value in case of structure usage on 64 bit systems */
if (ep->class == ELFCLASS64 && format == FORMAT_STRUCT) if (source_elf_bits == 64 && format == FORMAT_STRUCT)
needed_space += 4u; needed_space += 4u;
} }
if (check_end_magic) if (check_end_magic)
@ -629,13 +629,15 @@ static void get_section_load_addr(const struct elf_section *sec, uint64_t *lma)
} }
int elf_patch_write_crcs_to_section(elfpatch_handle_t *ep, const char *section, const SlList *section_name_list, int elf_patch_write_crcs_to_section(elfpatch_handle_t *ep, const char *output_sec_name,
const uint32_t *crcs, uint8_t crc_size_bits, uint32_t start_magic, uint32_t end_magic, const struct crc_import_data *crc_data, bool use_vma,
bool check_start_magic, bool check_end_magic, enum crc_format format, bool little_endian) uint32_t start_magic, uint32_t end_magic,
bool check_start_magic, bool check_end_magic,
enum crc_format format, bool little_endian)
{ {
int ret = -1; int ret = -1;
uint8_t crc_size_bits;
struct elf_section *output_section; struct elf_section *output_section;
struct elf_section *input_section;
Elf_Data *output_sec_data; Elf_Data *output_sec_data;
const SlList *iter; const SlList *iter;
size_t needed_space; size_t needed_space;
@ -643,25 +645,29 @@ int elf_patch_write_crcs_to_section(elfpatch_handle_t *ep, const char *section,
uint8_t crc_size_bytes; uint8_t crc_size_bytes;
uint8_t *sec_bytes; uint8_t *sec_bytes;
size_t idx; size_t idx;
struct crc_entry *crc_entry;
struct crc_out_struct_32bit crc_32bit; struct crc_out_struct_32bit crc_32bit;
struct crc_out_struct_64bit crc_64bit; struct crc_out_struct_64bit crc_64bit;
uint64_t in_sec_addr, in_sec_len;
ret_val_if_ep_err(ep, -1000); ret_val_if_ep_err(ep, -1000);
print_debug("== Patch output file ==\n"); print_debug("== Patch output file ==\n");
crc_size_bits = crc_len_from_poly(crc_data->crc_config.polynomial);
if (crc_size_bits < 1u || crc_size_bits > 32u) { if (crc_size_bits < 1u || crc_size_bits > 32u) {
print_err("Unsupported CRC size: %u", (unsigned int)crc_size_bits); print_err("Unsupported CRC size: %u", (unsigned int)crc_size_bits);
return -1; return -1;
} }
/* All pointer parameters are required */ /* All pointer parameters are required */
if (!section || !section_name_list || !crcs) if (!output_sec_name || !crc_data)
return -1000; return -1000;
output_section = find_section_in_list(ep->sections, section); output_section = find_section_in_list(ep->sections, output_sec_name);
if (!output_section) { if (!output_section) {
print_err("Cannot find output section '%s' to place CRCs. Exiting.\n", section); print_err("Cannot find output section '%s' to place CRCs. Exiting.\n", output_sec_name);
goto ret_err; goto ret_err;
} }
@ -669,8 +675,8 @@ int elf_patch_write_crcs_to_section(elfpatch_handle_t *ep, const char *section,
output_sec_data = elf_getdata(output_section->scn, NULL); output_sec_data = elf_getdata(output_section->scn, NULL);
sec_bytes = (uint8_t *)output_sec_data->d_buf; sec_bytes = (uint8_t *)output_sec_data->d_buf;
if (!sec_bytes) { if (!sec_bytes) {
print_err("Output section '%s' does not contain loadable data. It has to be allocated in the ELF file\n", print_err("Output section '%s' does not contain loadable data. It has to be allocated in the ELF file.\n",
section); output_sec_name);
goto ret_err; goto ret_err;
} }
@ -695,17 +701,17 @@ int elf_patch_write_crcs_to_section(elfpatch_handle_t *ep, const char *section,
/* Calculate Bytes needed for CRC */ /* Calculate Bytes needed for CRC */
crc_size_bytes = (crc_size_bits + 7u) / 8u; crc_size_bytes = (crc_size_bits + 7u) / 8u;
crc_count = sl_list_length(section_name_list); crc_count = sl_list_length(crc_data->crc_entries);
if (crc_count < 1) { if (crc_count < 1) {
/* No CRCs to patch... */ /* No CRCs to patch... */
ret = -1; ret = -1;
print_err("No CRCs to patch. This is probably an internal error.\n"); print_err("No CRCs to patch.\n");
goto ret_err; goto ret_err;
} }
print_debug("Single CRC requires %u bytes.\n", (unsigned int)crc_size_bytes); print_debug("Single CRC requires %u bytes.\n", (unsigned int)crc_size_bytes);
needed_space = calculate_needed_space_for_crcs(ep, format, check_start_magic, check_end_magic, crc_size_bytes, needed_space = calculate_needed_space_for_crcs(format, crc_data->elf_bits, check_start_magic, check_end_magic, crc_size_bytes,
crc_count); crc_count);
print_debug("Required space for %zu CRCs%s: %zu (available: %zu)\n", print_debug("Required space for %zu CRCs%s: %zu (available: %zu)\n",
@ -726,44 +732,42 @@ int elf_patch_write_crcs_to_section(elfpatch_handle_t *ep, const char *section,
if (format == FORMAT_BARE) { if (format == FORMAT_BARE) {
if (check_start_magic) if (check_start_magic)
sec_bytes += 4u; sec_bytes += 4u;
for (iter = section_name_list, idx = 0; iter; iter = sl_list_next(iter), idx++) { for (iter = crc_data->crc_entries, idx = 0; iter; iter = sl_list_next(iter), idx++) {
print_debug("Write CRC 0x%08x (%u bytes) for section %s\n", crcs[idx], crc_entry = (struct crc_entry *)iter->data;
print_debug("Write CRC 0x%08x (%u bytes) for section %s\n", crc_entry->crc,
(unsigned int)crc_size_bytes, (unsigned int)crc_size_bytes,
iter->data); crc_entry->name);
write_crc_to_byte_array(sec_bytes, crcs[idx], crc_size_bytes, little_endian); write_crc_to_byte_array(sec_bytes, crc_entry->crc, crc_size_bytes, little_endian);
sec_bytes += crc_size_bytes; sec_bytes += crc_size_bytes;
} }
} else if (format == FORMAT_STRUCT) { } else if (format == FORMAT_STRUCT) {
if (check_start_magic) if (check_start_magic)
sec_bytes += 4u; sec_bytes += 4u;
if (check_start_magic && ep->class == ELFCLASS64) if (check_start_magic && crc_data->elf_bits == 64)
sec_bytes += 4u; sec_bytes += 4u;
for (iter = section_name_list, idx = 0; iter; iter = sl_list_next(iter), idx++) { for (iter = crc_data->crc_entries, idx = 0; iter; iter = sl_list_next(iter), idx++) {
input_section = find_section_in_list(ep->sections, (const char *)iter->data); crc_entry = (struct crc_entry *)iter->data;
if (!input_section) { in_sec_addr = use_vma ? crc_entry->vma : crc_entry->lma;
print_err("Internal error. Please report this. %s:%d ", __FILE__, __LINE__); in_sec_len = crc_entry->size;
ret = -2; print_debug("Write CRC 0x%08x (%u bytes) for section %s.\n", crc_entry->crc,
goto ret_err;
}
print_debug("Write CRC 0x%08x (%u bytes) for section %s.\n", crcs[idx],
(unsigned int)crc_size_bytes, (unsigned int)crc_size_bytes,
iter->data); crc_entry->name);
print_debug("Corresponding input section at 0x%"PRIx64", length: %"PRIu64"\n", print_debug("Corresponding input section at 0x%"PRIx64", length: %"PRIu64"\n",
(uint64_t)input_section->section_header.sh_addr, in_sec_addr,
(uint64_t)input_section->section_header.sh_size); in_sec_len);
if (ep->class == ELFCLASS32) { if (crc_data->elf_bits == 32) {
crc_32bit.crc = crcs[idx]; crc_32bit.crc = crc_entry->crc;
crc_32bit.length = (uint32_t)input_section->section_header.sh_size; crc_32bit.length = (uint32_t)in_sec_len;
crc_32bit.start_address = (uint32_t)input_section->section_header.sh_addr; crc_32bit.start_address = (uint32_t)in_sec_addr;
memcpy(sec_bytes, &crc_32bit, sizeof(crc_32bit)); memcpy(sec_bytes, &crc_32bit, sizeof(crc_32bit));
sec_bytes += sizeof(crc_32bit); sec_bytes += sizeof(crc_32bit);
} else { } else {
/* 64 bit case */ /* 64 bit case */
crc_64bit.crc = crcs[idx]; crc_64bit.crc = crc_entry->crc;
crc_64bit._unused_dummy = 0ul; crc_64bit._unused_dummy = 0ul;
crc_64bit.length = (uint64_t)input_section->section_header.sh_size; crc_64bit.length = in_sec_len;
crc_64bit.start_address = (uint64_t)input_section->section_header.sh_addr; crc_64bit.start_address = in_sec_addr;
memcpy(sec_bytes, &crc_64bit, sizeof(crc_64bit)); memcpy(sec_bytes, &crc_64bit, sizeof(crc_64bit));
sec_bytes += sizeof(crc_64bit); sec_bytes += sizeof(crc_64bit);
} }
@ -778,7 +782,7 @@ int elf_patch_write_crcs_to_section(elfpatch_handle_t *ep, const char *section,
crc_64bit.length = 0ull; crc_64bit.length = 0ull;
crc_64bit.start_address = 0ull; crc_64bit.start_address = 0ull;
if (ep->class == ELFCLASS32) { if (crc_data->elf_bits == 32) {
memcpy(sec_bytes, &crc_32bit, sizeof(crc_32bit)); memcpy(sec_bytes, &crc_32bit, sizeof(crc_32bit));
} else { } else {
memcpy(sec_bytes, &crc_64bit, sizeof(crc_64bit)); memcpy(sec_bytes, &crc_64bit, sizeof(crc_64bit));

View File

@ -338,31 +338,49 @@ static int check_all_sections_present(elfpatch_handle_t *ep, SlList *list)
* @param ep Elf patch * @param ep Elf patch
* @param list List of section names to patch * @param list List of section names to patch
* @param opts Command line options. Used for CRC generation * @param opts Command line options. Used for CRC generation
* @param[out] crcs Array of output CRCs. Must be large enough to hold all elements * @return CRC data
* @return 0 if successful
*/ */
static int compute_crcs(elfpatch_handle_t *ep, SlList *list, const struct command_line_options *opts, uint32_t *crcs) static struct crc_import_data *compute_crcs(elfpatch_handle_t *ep, SlList *list, const struct command_line_options *opts)
{ {
SlList *iter; SlList *iter;
const char *sec_name; const char *sec_name;
int ret = 0; struct crc_import_data *ret = NULL;
struct crc_entry *entry;
struct crc_calc _crc; struct crc_calc _crc;
struct crc_calc * const crc = &_crc; struct crc_calc * const crc = &_crc;
unsigned int idx; unsigned int idx;
uint64_t vma, lma, len;
/* Construct the CRC */ /* Construct the CRC */
crc_init(crc, &opts->crc); crc_init(crc, &opts->crc);
ret = xml_crc_import_alloc();
ret->elf_bits = elf_patch_get_bits(ep);
memcpy(&ret->crc_config, &opts->crc, sizeof(struct crc_settings));
for (iter = list, idx = 0; iter; iter = sl_list_next(iter), idx++) { for (iter = list, idx = 0; iter; iter = sl_list_next(iter), idx++) {
crc_reset(crc); crc_reset(crc);
sec_name = (const char *)iter->data; sec_name = (const char *)iter->data;
if (elf_patch_compute_crc_over_section(ep, sec_name, crc, opts->granularity, opts->little_endian)) { if (elf_patch_compute_crc_over_section(ep, sec_name, crc, opts->granularity, opts->little_endian)) {
print_err("Error during CRC calculation. Exiting.\n"); print_err("Error during CRC calculation. Exiting.\n");
ret = -1; xml_crc_import_free(ret);
ret = NULL;
break; break;
} }
crc_finish_calc(crc); crc_finish_calc(crc);
crcs[idx] = crc_get_value(crc); if (elf_patch_get_section_address(ep, sec_name, &vma, &lma, &len)) {
print_err("Cannot retrieve section addresses. Internal error. Exiting.\n");
xml_crc_import_free(ret);
ret = NULL;
break;
}
entry = (struct crc_entry *)malloc(sizeof(struct crc_entry));
entry->name = strdup(sec_name);
entry->crc = crc_get_value(crc);
entry->lma = lma;
entry->size = len;
entry->vma = vma;
ret->crc_entries = sl_list_append(ret->crc_entries, entry);
} }
crc_destroy(crc); crc_destroy(crc);
@ -371,16 +389,14 @@ static int compute_crcs(elfpatch_handle_t *ep, SlList *list, const struct comman
/** /**
* @brief Debug-print the CRCs of sections in form of a table * @brief Debug-print the CRCs of sections in form of a table
* @param[in] list List of section names * @param[in] crc_data CRC data structure containing the CRCs.
* @param[in] crcs Array of CRCs.
* @note The array @p crcs must be at least as long as @p list * @note The array @p crcs must be at least as long as @p list
*/ */
static void print_crcs(SlList *list, const uint32_t *crcs) static void print_crcs(const struct crc_import_data *crc_data)
{ {
SlList *iter; SlList *iter;
unsigned int idx;
const char *sec_name;
ft_table_t *table; ft_table_t *table;
const struct crc_entry *entry;
table = ft_create_table(); table = ft_create_table();
@ -388,9 +404,9 @@ static void print_crcs(SlList *list, const uint32_t *crcs)
ft_set_cell_prop(table, 0, FT_ANY_COLUMN, FT_CPROP_ROW_TYPE, FT_ROW_HEADER); ft_set_cell_prop(table, 0, FT_ANY_COLUMN, FT_CPROP_ROW_TYPE, FT_ROW_HEADER);
ft_write_ln(table, "Section", "CRC"); ft_write_ln(table, "Section", "CRC");
for (iter = list, idx = 0; iter; iter = sl_list_next(iter), idx++) { for (iter = crc_data->crc_entries; iter; iter = sl_list_next(iter)) {
sec_name = (const char *)iter->data; entry = (const struct crc_entry *)iter->data;
ft_printf_ln(table, "%s|0x%x", sec_name, crcs[idx]); ft_printf_ln(table, "%s|0x%x", entry->name, entry->crc);
} }
print_debug("Calculated CRCs:\n%s\n", ft_to_string(table)); print_debug("Calculated CRCs:\n%s\n", ft_to_string(table));
ft_destroy_table(table); ft_destroy_table(table);
@ -401,8 +417,7 @@ int main(int argc, char **argv)
struct command_line_options cmd_opts; struct command_line_options cmd_opts;
elfpatch_handle_t *ep; elfpatch_handle_t *ep;
int ret = 0; int ret = 0;
uint32_t *crcs = NULL; struct crc_import_data *crc_data = NULL;
struct xml_crc_import *import_data = NULL;
xml_init(); xml_init();
@ -457,6 +472,7 @@ int main(int argc, char **argv)
goto free_cmds; goto free_cmds;
} }
if (!cmd_opts.import_xml) {
/* Check if all sections are present */ /* Check if all sections are present */
if (check_all_sections_present(ep, cmd_opts.section_list)) { if (check_all_sections_present(ep, cmd_opts.section_list)) {
ret = -2; ret = -2;
@ -464,33 +480,33 @@ int main(int argc, char **argv)
} }
/* Compute CRCs over sections */ /* Compute CRCs over sections */
crcs = (uint32_t *)malloc(sl_list_length(cmd_opts.section_list) * sizeof(uint32_t)); crc_data = compute_crcs(ep, cmd_opts.section_list, &cmd_opts);
if (compute_crcs(ep, cmd_opts.section_list, &cmd_opts, crcs)) { if (!crc_data) {
goto ret_close_elf; goto ret_close_elf;
} }
if (reporting_get_verbosity()) { if (reporting_get_verbosity()) {
print_crcs(cmd_opts.section_list, crcs); print_crcs(crc_data);
}
} else {
crc_data = xml_import_from_file(cmd_opts.import_xml);
} }
if (cmd_opts.output_section) { if (cmd_opts.output_section) {
if (elf_patch_write_crcs_to_section(ep, cmd_opts.output_section, cmd_opts.section_list, /* Construct data */
crcs, crc_len_from_poly(cmd_opts.crc.polynomial),
cmd_opts.start_magic, cmd_opts.end_magic, if (elf_patch_write_crcs_to_section(ep, cmd_opts.output_section, crc_data, cmd_opts.use_vma,
cmd_opts.has_start_magic, cmd_opts.has_end_magic, cmd_opts.start_magic, cmd_opts.end_magic, cmd_opts.has_end_magic,
cmd_opts.format, cmd_opts.little_endian)) { cmd_opts.has_end_magic, cmd_opts.format, cmd_opts.little_endian)) {
ret = -1; ret = -1;
} }
} }
if (cmd_opts.export_xml) { if (cmd_opts.export_xml) {
if (xml_write_crcs_to_file(cmd_opts.export_xml, crcs, cmd_opts.section_list, &cmd_opts.crc, ep)) { if (xml_write_crcs_to_file(cmd_opts.export_xml, crc_data)) {
print_err("Error during XML generation\n"); print_err("Error during XML generation\n");
ret = -3; ret = -3;
} }
/* Fix this: */
import_data = xml_import_from_file(cmd_opts.export_xml);
} }
ret_close_elf: ret_close_elf:
@ -500,10 +516,8 @@ free_cmds:
free_cmd_args(&cmd_opts); free_cmd_args(&cmd_opts);
/* Free CRCs if necessary */ /* Free CRCs if necessary */
if (crcs) if (crc_data)
free(crcs); xml_crc_import_free(crc_data);
if (import_data)
xml_crc_import_free(import_data);
return ret; return ret;
} }

View File

@ -22,18 +22,15 @@ void xml_init(void)
LIBXML_TEST_VERSION; LIBXML_TEST_VERSION;
} }
int xml_write_crcs_to_file(const char *path, const uint32_t *crcs, SlList *section_name_list, int xml_write_crcs_to_file(const char *path, const struct crc_import_data *crc_data)
const struct crc_settings *crc_params, elfpatch_handle_t *ep)
{ {
int ret = 0; int ret = 0;
int bitsize;
xmlTextWriter *writer; xmlTextWriter *writer;
SlList *name_iter; SlList *entry_iter;
const char *section_name; const struct crc_entry *entry;
size_t index; size_t index;
uint64_t vma, len, lma;
if (!path || !crcs || !section_name_list || !crc_params || !ep) { if (!path || !crc_data) {
return -1000; return -1000;
} }
@ -53,38 +50,32 @@ int xml_write_crcs_to_file(const char *path, const uint32_t *crcs, SlList *secti
xmlTextWriterWriteFormatAttribute(writer, BAD_CAST "version", "%s", version_string); xmlTextWriterWriteFormatAttribute(writer, BAD_CAST "version", "%s", version_string);
xmlTextWriterStartElement(writer, BAD_CAST "settings"); xmlTextWriterStartElement(writer, BAD_CAST "settings");
xmlTextWriterWriteFormatElement(writer, BAD_CAST "poly", "0x%" PRIx64, crc_params->polynomial); xmlTextWriterWriteFormatElement(writer, BAD_CAST "poly", "0x%" PRIx64, crc_data->crc_config.polynomial);
xmlTextWriterWriteFormatElement(writer, BAD_CAST "start", "0x%" PRIx32, crc_params->start_value); xmlTextWriterWriteFormatElement(writer, BAD_CAST "start", "0x%" PRIx32, crc_data->crc_config.start_value);
if (crc_params->rev) { if (crc_data->crc_config.rev) {
xmlTextWriterStartElement(writer, BAD_CAST "rev"); xmlTextWriterStartElement(writer, BAD_CAST "rev");
xmlTextWriterEndElement(writer); xmlTextWriterEndElement(writer);
} }
xmlTextWriterWriteFormatElement(writer, BAD_CAST "xor", "0x%" PRIx32, crc_params->xor); xmlTextWriterWriteFormatElement(writer, BAD_CAST "xor", "0x%" PRIx32, crc_data->crc_config.xor);
bitsize = elf_patch_get_bits(ep); if (crc_data->elf_bits < 0) {
if (bitsize < 0) {
print_err("Cannot determine ELF class. Generated XML will be faulty.\n"); print_err("Cannot determine ELF class. Generated XML will be faulty.\n");
ret |= -1; ret |= -1;
} }
xmlTextWriterWriteFormatElement(writer, BAD_CAST "elfclass", "%d", bitsize); xmlTextWriterWriteFormatElement(writer, BAD_CAST "elfclass", "%d", crc_data->elf_bits);
xmlTextWriterEndElement(writer); /* End settings */ xmlTextWriterEndElement(writer); /* End settings */
xmlTextWriterStartElement(writer, BAD_CAST "sections"); xmlTextWriterStartElement(writer, BAD_CAST "sections");
/* Output all section CRCs */ /* Output all section CRCs */
for (name_iter = section_name_list, index = 0u; name_iter; name_iter = sl_list_next(name_iter), index++) { for (entry_iter = crc_data->crc_entries, index = 0u; entry_iter; entry_iter = sl_list_next(entry_iter), index++) {
section_name = (const char *)name_iter->data; entry = (const struct crc_entry *)entry_iter->data;
xmlTextWriterStartElement(writer, BAD_CAST "crc"); xmlTextWriterStartElement(writer, BAD_CAST "crc");
xmlTextWriterWriteFormatAttribute(writer, BAD_CAST "name", "%s", section_name); xmlTextWriterWriteFormatAttribute(writer, BAD_CAST "name", "%s", entry->name);
xmlTextWriterWriteFormatAttribute(writer, BAD_CAST "index", "%zu", index); xmlTextWriterWriteFormatAttribute(writer, BAD_CAST "index", "%zu", index);
if (elf_patch_get_section_address(ep, section_name, &vma, &lma, &len)) { xmlTextWriterWriteFormatAttribute(writer, BAD_CAST "vma", "0x%" PRIx64, entry->vma);
print_err("Could not retrieve section addresses / length of section '%s'. XML output will be faulty.\n", xmlTextWriterWriteFormatAttribute(writer, BAD_CAST "lma", "0x%" PRIx64, entry->lma);
section_name); xmlTextWriterWriteFormatAttribute(writer, BAD_CAST "size", "0x%" PRIx64, entry->size);
ret |= -1; xmlTextWriterWriteFormatRaw(writer, "0x%" PRIx32, entry->crc);
}
xmlTextWriterWriteFormatAttribute(writer, BAD_CAST "vma", "0x%" PRIx64, vma);
xmlTextWriterWriteFormatAttribute(writer, BAD_CAST "lma", "0x%" PRIx64, lma);
xmlTextWriterWriteFormatAttribute(writer, BAD_CAST "size", "0x%" PRIx64, len);
xmlTextWriterWriteFormatRaw(writer, "0x%" PRIx32, crcs[index]);
xmlTextWriterEndElement(writer); /* End crc */ xmlTextWriterEndElement(writer); /* End crc */
} }
xmlTextWriterEndElement(writer); /* End sections */ xmlTextWriterEndElement(writer); /* End sections */
@ -98,13 +89,13 @@ ret_none:
return ret; return ret;
} }
static struct xml_crc_import *xml_crc_import_alloc(void) struct crc_import_data *xml_crc_import_alloc(void)
{ {
struct xml_crc_import *ret = NULL; struct crc_import_data *ret = NULL;
ret = (struct xml_crc_import *)malloc(sizeof(struct xml_crc_import)); ret = (struct crc_import_data *)malloc(sizeof(struct crc_import_data));
if (ret) if (ret)
ret->xml_crc_entries = NULL; ret->crc_entries = NULL;
else else
print_err("Error. Out of memory. This should never happen\n"); print_err("Error. Out of memory. This should never happen\n");
@ -346,10 +337,10 @@ static int get_uint32_from_node_content(xmlNodePtr node, uint32_t *output)
} }
struct xml_crc_import *xml_import_from_file(const char *path) struct crc_import_data *xml_import_from_file(const char *path)
{ {
struct xml_crc_import *ret = NULL; struct crc_import_data *ret = NULL;
struct xml_crc_entry *crc; struct crc_entry *crc;
xmlDocPtr doc; xmlDocPtr doc;
xmlNodePtr root_node; xmlNodePtr root_node;
xmlNodePtr current_node; xmlNodePtr current_node;
@ -434,8 +425,8 @@ struct xml_crc_import *xml_import_from_file(const char *path)
for (i = 0; i < xpath_obj->nodesetval->nodeNr; i++) { for (i = 0; i < xpath_obj->nodesetval->nodeNr; i++) {
current_node = xpath_obj->nodesetval->nodeTab[i]; current_node = xpath_obj->nodesetval->nodeTab[i];
crc = (struct xml_crc_entry *)malloc(sizeof(struct xml_crc_entry)); crc = (struct crc_entry *)malloc(sizeof(struct crc_entry));
ret->xml_crc_entries = sl_list_append(ret->xml_crc_entries, crc); ret->crc_entries = sl_list_append(ret->crc_entries, crc);
get_uint64_from_node_attribute(current_node, "vma", &tmp_num64); get_uint64_from_node_attribute(current_node, "vma", &tmp_num64);
crc->vma = tmp_num64; crc->vma = tmp_num64;
@ -446,7 +437,7 @@ struct xml_crc_import *xml_import_from_file(const char *path)
get_uint32_from_node_content(current_node, &tmp_num32); get_uint32_from_node_content(current_node, &tmp_num32);
crc->crc = tmp_num32; crc->crc = tmp_num32;
crc->name = (char *)xmlGetProp(current_node, "name"); crc->name = (char *)xmlGetProp(current_node, BAD_CAST "name");
} }
ret_close_doc: ret_close_doc:
@ -467,9 +458,9 @@ ret_none:
} }
static void free_xml_crc_entry(void *entry) static void free_crc_entry(void *entry)
{ {
struct xml_crc_entry *e = (struct xml_crc_entry *)entry; struct crc_entry *e = (struct crc_entry *)entry;
if (entry) { if (entry) {
if (e->name) if (e->name)
@ -478,13 +469,13 @@ static void free_xml_crc_entry(void *entry)
} }
} }
void xml_crc_import_free(struct xml_crc_import *data) void xml_crc_import_free(struct crc_import_data *data)
{ {
if (!data) if (!data)
return; return;
sl_list_free_full(data->xml_crc_entries, free_xml_crc_entry); sl_list_free_full(data->crc_entries, free_crc_entry);
data->xml_crc_entries = NULL; data->crc_entries = NULL;
free(data); free(data);
} }