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 <stdbool.h>
#include <linklist-lib/singly-linked-list.h>
#include <patchelfcrc/crc-datatypes.h>
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);
/**
* @brief Write CRCs to output section. This will have no effect, if file is opened read onyl
* @param ep Elf patch object
* @param[in] section Section name to place CRCs in
* @param[in] section_name_list The list of sections the data belongs to
* @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);
int elf_patch_write_crcs_to_section(elfpatch_handle_t *ep, const char *output_sec_name,
const struct crc_import_data *crc_data, bool use_vma,
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_ */

View File

@ -1,29 +1,13 @@
#ifndef _ELFPATCHCRC_XML_H_
#define _ELFPATCHCRC_XML_H_
#include <stdint.h>
#include <linklist-lib/singly-linked-list.h>
#include <patchelfcrc/crc.h>
#include <patchelfcrc/elfpatch.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 */
};
#include <patchelfcrc/crc-datatypes.h>
void xml_init(void);
int xml_write_crcs_to_file(const char *path, const uint32_t *crcs, SlList *section_names,
const struct crc_settings *crc_params, elfpatch_handle_t *ep);
int xml_write_crcs_to_file(const char *path, const struct crc_import_data *crc_data);
/**
* @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 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
* @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
*/
void xml_print_xsd(void);
struct crc_import_data *xml_crc_import_alloc(void);
#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;
}
static size_t calculate_needed_space_for_crcs(elfpatch_handle_t *ep,
enum crc_format format,
static size_t calculate_needed_space_for_crcs(enum crc_format format,
uint8_t source_elf_bits,
bool check_start_magic, bool check_end_magic,
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:
/* Calculate space for CRCs including sentinel struct at the end */
needed_space = (crc_count + 1) *
(ep->class == ELFCLASS32
(source_elf_bits == 32
? sizeof(struct crc_out_struct_32bit)
: sizeof(struct crc_out_struct_64bit));
break;
@ -599,8 +599,8 @@ static size_t calculate_needed_space_for_crcs(elfpatch_handle_t *ep,
/* Add existing magic numbers to required space */
if (check_start_magic) {
needed_space += 4u;
/* Account for paading after 32 bit magic value in case of structure usage on 64 bit systems */
if (ep->class == ELFCLASS64 && format == FORMAT_STRUCT)
/* Account for padding after 32 bit magic value in case of structure usage on 64 bit systems */
if (source_elf_bits == 64 && format == FORMAT_STRUCT)
needed_space += 4u;
}
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,
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)
int elf_patch_write_crcs_to_section(elfpatch_handle_t *ep, const char *output_sec_name,
const struct crc_import_data *crc_data, bool use_vma,
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;
uint8_t crc_size_bits;
struct elf_section *output_section;
struct elf_section *input_section;
Elf_Data *output_sec_data;
const SlList *iter;
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 *sec_bytes;
size_t idx;
struct crc_entry *crc_entry;
struct crc_out_struct_32bit crc_32bit;
struct crc_out_struct_64bit crc_64bit;
uint64_t in_sec_addr, in_sec_len;
ret_val_if_ep_err(ep, -1000);
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) {
print_err("Unsupported CRC size: %u", (unsigned int)crc_size_bits);
return -1;
}
/* All pointer parameters are required */
if (!section || !section_name_list || !crcs)
if (!output_sec_name || !crc_data)
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) {
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;
}
@ -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);
sec_bytes = (uint8_t *)output_sec_data->d_buf;
if (!sec_bytes) {
print_err("Output section '%s' does not contain loadable data. It has to be allocated in the ELF file\n",
section);
print_err("Output section '%s' does not contain loadable data. It has to be allocated in the ELF file.\n",
output_sec_name);
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 */
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) {
/* No CRCs to patch... */
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;
}
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);
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 (check_start_magic)
sec_bytes += 4u;
for (iter = section_name_list, idx = 0; iter; iter = sl_list_next(iter), idx++) {
print_debug("Write CRC 0x%08x (%u bytes) for section %s\n", crcs[idx],
(unsigned int)crc_size_bytes,
iter->data);
write_crc_to_byte_array(sec_bytes, crcs[idx], crc_size_bytes, little_endian);
for (iter = crc_data->crc_entries, idx = 0; iter; iter = sl_list_next(iter), 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,
crc_entry->name);
write_crc_to_byte_array(sec_bytes, crc_entry->crc, crc_size_bytes, little_endian);
sec_bytes += crc_size_bytes;
}
} else if (format == FORMAT_STRUCT) {
if (check_start_magic)
sec_bytes += 4u;
if (check_start_magic && ep->class == ELFCLASS64)
if (check_start_magic && crc_data->elf_bits == 64)
sec_bytes += 4u;
for (iter = section_name_list, idx = 0; iter; iter = sl_list_next(iter), idx++) {
input_section = find_section_in_list(ep->sections, (const char *)iter->data);
if (!input_section) {
print_err("Internal error. Please report this. %s:%d ", __FILE__, __LINE__);
ret = -2;
goto ret_err;
}
print_debug("Write CRC 0x%08x (%u bytes) for section %s.\n", crcs[idx],
for (iter = crc_data->crc_entries, idx = 0; iter; iter = sl_list_next(iter), idx++) {
crc_entry = (struct crc_entry *)iter->data;
in_sec_addr = use_vma ? crc_entry->vma : crc_entry->lma;
in_sec_len = crc_entry->size;
print_debug("Write CRC 0x%08x (%u bytes) for section %s.\n", crc_entry->crc,
(unsigned int)crc_size_bytes,
iter->data);
crc_entry->name);
print_debug("Corresponding input section at 0x%"PRIx64", length: %"PRIu64"\n",
(uint64_t)input_section->section_header.sh_addr,
(uint64_t)input_section->section_header.sh_size);
if (ep->class == ELFCLASS32) {
crc_32bit.crc = crcs[idx];
crc_32bit.length = (uint32_t)input_section->section_header.sh_size;
crc_32bit.start_address = (uint32_t)input_section->section_header.sh_addr;
in_sec_addr,
in_sec_len);
if (crc_data->elf_bits == 32) {
crc_32bit.crc = crc_entry->crc;
crc_32bit.length = (uint32_t)in_sec_len;
crc_32bit.start_address = (uint32_t)in_sec_addr;
memcpy(sec_bytes, &crc_32bit, sizeof(crc_32bit));
sec_bytes += sizeof(crc_32bit);
} else {
/* 64 bit case */
crc_64bit.crc = crcs[idx];
crc_64bit.crc = crc_entry->crc;
crc_64bit._unused_dummy = 0ul;
crc_64bit.length = (uint64_t)input_section->section_header.sh_size;
crc_64bit.start_address = (uint64_t)input_section->section_header.sh_addr;
crc_64bit.length = in_sec_len;
crc_64bit.start_address = in_sec_addr;
memcpy(sec_bytes, &crc_64bit, 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.start_address = 0ull;
if (ep->class == ELFCLASS32) {
if (crc_data->elf_bits == 32) {
memcpy(sec_bytes, &crc_32bit, sizeof(crc_32bit));
} else {
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 list List of section names to patch
* @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 0 if successful
* @return CRC data
*/
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;
const char *sec_name;
int ret = 0;
struct crc_import_data *ret = NULL;
struct crc_entry *entry;
struct crc_calc _crc;
struct crc_calc * const crc = &_crc;
unsigned int idx;
uint64_t vma, lma, len;
/* Construct the 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++) {
crc_reset(crc);
sec_name = (const char *)iter->data;
if (elf_patch_compute_crc_over_section(ep, sec_name, crc, opts->granularity, opts->little_endian)) {
print_err("Error during CRC calculation. Exiting.\n");
ret = -1;
xml_crc_import_free(ret);
ret = NULL;
break;
}
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);
@ -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
* @param[in] list List of section names
* @param[in] crcs Array of CRCs.
* @param[in] crc_data CRC data structure containing the CRCs.
* @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;
unsigned int idx;
const char *sec_name;
ft_table_t *table;
const struct crc_entry *entry;
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_write_ln(table, "Section", "CRC");
for (iter = list, idx = 0; iter; iter = sl_list_next(iter), idx++) {
sec_name = (const char *)iter->data;
ft_printf_ln(table, "%s|0x%x", sec_name, crcs[idx]);
for (iter = crc_data->crc_entries; iter; iter = sl_list_next(iter)) {
entry = (const struct crc_entry *)iter->data;
ft_printf_ln(table, "%s|0x%x", entry->name, entry->crc);
}
print_debug("Calculated CRCs:\n%s\n", ft_to_string(table));
ft_destroy_table(table);
@ -401,8 +417,7 @@ int main(int argc, char **argv)
struct command_line_options cmd_opts;
elfpatch_handle_t *ep;
int ret = 0;
uint32_t *crcs = NULL;
struct xml_crc_import *import_data = NULL;
struct crc_import_data *crc_data = NULL;
xml_init();
@ -457,40 +472,41 @@ int main(int argc, char **argv)
goto free_cmds;
}
/* Check if all sections are present */
if (check_all_sections_present(ep, cmd_opts.section_list)) {
ret = -2;
goto ret_close_elf;
}
if (!cmd_opts.import_xml) {
/* Check if all sections are present */
if (check_all_sections_present(ep, cmd_opts.section_list)) {
ret = -2;
goto ret_close_elf;
}
/* Compute CRCs over sections */
crcs = (uint32_t *)malloc(sl_list_length(cmd_opts.section_list) * sizeof(uint32_t));
if (compute_crcs(ep, cmd_opts.section_list, &cmd_opts, crcs)) {
goto ret_close_elf;
}
/* Compute CRCs over sections */
crc_data = compute_crcs(ep, cmd_opts.section_list, &cmd_opts);
if (!crc_data) {
goto ret_close_elf;
}
if (reporting_get_verbosity()) {
print_crcs(cmd_opts.section_list, crcs);
if (reporting_get_verbosity()) {
print_crcs(crc_data);
}
} else {
crc_data = xml_import_from_file(cmd_opts.import_xml);
}
if (cmd_opts.output_section) {
if (elf_patch_write_crcs_to_section(ep, cmd_opts.output_section, cmd_opts.section_list,
crcs, crc_len_from_poly(cmd_opts.crc.polynomial),
cmd_opts.start_magic, cmd_opts.end_magic,
cmd_opts.has_start_magic, cmd_opts.has_end_magic,
cmd_opts.format, cmd_opts.little_endian)) {
/* Construct data */
if (elf_patch_write_crcs_to_section(ep, cmd_opts.output_section, crc_data, cmd_opts.use_vma,
cmd_opts.start_magic, cmd_opts.end_magic, cmd_opts.has_end_magic,
cmd_opts.has_end_magic, cmd_opts.format, cmd_opts.little_endian)) {
ret = -1;
}
}
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");
ret = -3;
}
/* Fix this: */
import_data = xml_import_from_file(cmd_opts.export_xml);
}
ret_close_elf:
@ -500,10 +516,8 @@ free_cmds:
free_cmd_args(&cmd_opts);
/* Free CRCs if necessary */
if (crcs)
free(crcs);
if (import_data)
xml_crc_import_free(import_data);
if (crc_data)
xml_crc_import_free(crc_data);
return ret;
}

View File

@ -22,18 +22,15 @@ void xml_init(void)
LIBXML_TEST_VERSION;
}
int xml_write_crcs_to_file(const char *path, const uint32_t *crcs, SlList *section_name_list,
const struct crc_settings *crc_params, elfpatch_handle_t *ep)
int xml_write_crcs_to_file(const char *path, const struct crc_import_data *crc_data)
{
int ret = 0;
int bitsize;
xmlTextWriter *writer;
SlList *name_iter;
const char *section_name;
SlList *entry_iter;
const struct crc_entry *entry;
size_t index;
uint64_t vma, len, lma;
if (!path || !crcs || !section_name_list || !crc_params || !ep) {
if (!path || !crc_data) {
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);
xmlTextWriterStartElement(writer, BAD_CAST "settings");
xmlTextWriterWriteFormatElement(writer, BAD_CAST "poly", "0x%" PRIx64, crc_params->polynomial);
xmlTextWriterWriteFormatElement(writer, BAD_CAST "start", "0x%" PRIx32, crc_params->start_value);
if (crc_params->rev) {
xmlTextWriterWriteFormatElement(writer, BAD_CAST "poly", "0x%" PRIx64, crc_data->crc_config.polynomial);
xmlTextWriterWriteFormatElement(writer, BAD_CAST "start", "0x%" PRIx32, crc_data->crc_config.start_value);
if (crc_data->crc_config.rev) {
xmlTextWriterStartElement(writer, BAD_CAST "rev");
xmlTextWriterEndElement(writer);
}
xmlTextWriterWriteFormatElement(writer, BAD_CAST "xor", "0x%" PRIx32, crc_params->xor);
bitsize = elf_patch_get_bits(ep);
if (bitsize < 0) {
xmlTextWriterWriteFormatElement(writer, BAD_CAST "xor", "0x%" PRIx32, crc_data->crc_config.xor);
if (crc_data->elf_bits < 0) {
print_err("Cannot determine ELF class. Generated XML will be faulty.\n");
ret |= -1;
}
xmlTextWriterWriteFormatElement(writer, BAD_CAST "elfclass", "%d", bitsize);
xmlTextWriterWriteFormatElement(writer, BAD_CAST "elfclass", "%d", crc_data->elf_bits);
xmlTextWriterEndElement(writer); /* End settings */
xmlTextWriterStartElement(writer, BAD_CAST "sections");
/* Output all section CRCs */
for (name_iter = section_name_list, index = 0u; name_iter; name_iter = sl_list_next(name_iter), index++) {
section_name = (const char *)name_iter->data;
for (entry_iter = crc_data->crc_entries, index = 0u; entry_iter; entry_iter = sl_list_next(entry_iter), index++) {
entry = (const struct crc_entry *)entry_iter->data;
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);
if (elf_patch_get_section_address(ep, section_name, &vma, &lma, &len)) {
print_err("Could not retrieve section addresses / length of section '%s'. XML output will be faulty.\n",
section_name);
ret |= -1;
}
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]);
xmlTextWriterWriteFormatAttribute(writer, BAD_CAST "vma", "0x%" PRIx64, entry->vma);
xmlTextWriterWriteFormatAttribute(writer, BAD_CAST "lma", "0x%" PRIx64, entry->lma);
xmlTextWriterWriteFormatAttribute(writer, BAD_CAST "size", "0x%" PRIx64, entry->size);
xmlTextWriterWriteFormatRaw(writer, "0x%" PRIx32, entry->crc);
xmlTextWriterEndElement(writer); /* End crc */
}
xmlTextWriterEndElement(writer); /* End sections */
@ -98,13 +89,13 @@ ret_none:
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)
ret->xml_crc_entries = NULL;
ret->crc_entries = NULL;
else
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 xml_crc_entry *crc;
struct crc_import_data *ret = NULL;
struct crc_entry *crc;
xmlDocPtr doc;
xmlNodePtr root_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++) {
current_node = xpath_obj->nodesetval->nodeTab[i];
crc = (struct xml_crc_entry *)malloc(sizeof(struct xml_crc_entry));
ret->xml_crc_entries = sl_list_append(ret->xml_crc_entries, crc);
crc = (struct crc_entry *)malloc(sizeof(struct crc_entry));
ret->crc_entries = sl_list_append(ret->crc_entries, crc);
get_uint64_from_node_attribute(current_node, "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);
crc->crc = tmp_num32;
crc->name = (char *)xmlGetProp(current_node, "name");
crc->name = (char *)xmlGetProp(current_node, BAD_CAST "name");
}
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 (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)
return;
sl_list_free_full(data->xml_crc_entries, free_xml_crc_entry);
data->xml_crc_entries = NULL;
sl_list_free_full(data->crc_entries, free_crc_entry);
data->crc_entries = NULL;
free(data);
}