Finish import/export functionality
This commit is contained in:
parent
aa15e1a541
commit
c41214fc75
20
include/patchelfcrc/crc-datatypes.h
Normal file
20
include/patchelfcrc/crc-datatypes.h
Normal 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_ */
|
@ -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_ */
|
||||||
|
@ -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_ */
|
||||||
|
@ -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;
|
||||||
(unsigned int)crc_size_bytes,
|
print_debug("Write CRC 0x%08x (%u bytes) for section %s\n", crc_entry->crc,
|
||||||
iter->data);
|
(unsigned int)crc_size_bytes,
|
||||||
write_crc_to_byte_array(sec_bytes, crcs[idx], crc_size_bytes, little_endian);
|
crc_entry->name);
|
||||||
|
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));
|
||||||
|
96
src/main.c
96
src/main.c
@ -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,40 +472,41 @@ int main(int argc, char **argv)
|
|||||||
goto free_cmds;
|
goto free_cmds;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check if all sections are present */
|
if (!cmd_opts.import_xml) {
|
||||||
if (check_all_sections_present(ep, cmd_opts.section_list)) {
|
/* Check if all sections are present */
|
||||||
ret = -2;
|
if (check_all_sections_present(ep, cmd_opts.section_list)) {
|
||||||
goto ret_close_elf;
|
ret = -2;
|
||||||
}
|
goto ret_close_elf;
|
||||||
|
}
|
||||||
|
|
||||||
/* 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;
|
||||||
}
|
}
|
||||||
|
73
src/xml.c
73
src/xml.c
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user