Implement predefined CRCs and add libfort
This commit is contained in:
parent
199b48d963
commit
3040d8a23f
3
.gitmodules
vendored
Normal file
3
.gitmodules
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
[submodule "3rdparty/libfort"]
|
||||
path = 3rdparty/libfort
|
||||
url = https://git.shimatta.de/3rd-party/libfort
|
1
3rdparty/libfort
vendored
Submodule
1
3rdparty/libfort
vendored
Submodule
@ -0,0 +1 @@
|
||||
Subproject commit 41237162a9bd34a30a88069ee4e230584ae8d674
|
@ -8,6 +8,7 @@ pkg_check_modules(ELF REQUIRED libelf)
|
||||
set (CFILES
|
||||
main.c
|
||||
version.c
|
||||
named_crcs.c
|
||||
)
|
||||
|
||||
set(GEN_HEADER_PATH "${CMAKE_CURRENT_BINARY_DIR}/include/generated")
|
||||
|
23
include/patchelfcrc/named_crcs.h
Normal file
23
include/patchelfcrc/named_crcs.h
Normal file
@ -0,0 +1,23 @@
|
||||
#ifndef _NAMED_CRCS_H_
|
||||
#define _NAMED_CRCS_H_
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
struct crc_settings {
|
||||
uint32_t polynomial;
|
||||
uint32_t xor;
|
||||
uint32_t start_value;
|
||||
bool rev;
|
||||
};
|
||||
|
||||
struct named_crc {
|
||||
const char *name;
|
||||
struct crc_settings settings;
|
||||
};
|
||||
|
||||
const struct named_crc *reverse_lookup_named_crc(const struct crc_settings *settings);
|
||||
|
||||
const struct named_crc *lookup_named_crc(const char *name);
|
||||
|
||||
#endif /* _NAMED_CRCS_H_ */
|
112
main.c
112
main.c
@ -2,6 +2,9 @@
|
||||
#include <libelf.h>
|
||||
#include <argp.h>
|
||||
#include <stdbool.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <patchelfcrc/named_crcs.h>
|
||||
#include <patchelfcrc/version.h>
|
||||
|
||||
#define print_err(fmt, ...) fprintf(stderr, (fmt), ## __VA_ARGS__);
|
||||
@ -14,23 +17,63 @@
|
||||
const char *argp_program_bug_address = "<mario.huettel@linux.com>";
|
||||
|
||||
enum granularity {
|
||||
GRANULARITY_BYTE = 1,
|
||||
GRANULARITY_16BIT,
|
||||
GRANULARITY_32BIT,
|
||||
GRANULARITY_BYTE = 8,
|
||||
GRANULARITY_16BIT = 16,
|
||||
GRANULARITY_32BIT = 32,
|
||||
};
|
||||
|
||||
enum crc_format {
|
||||
FORMAT_BARE = 0,
|
||||
FORMAT_STRUCT,
|
||||
};
|
||||
|
||||
#define ARG_KEY_DRY_RUN (1)
|
||||
#define ARG_KEY_START_MAGIC (2)
|
||||
#define ARG_KEY_END_MAGIC (3)
|
||||
|
||||
struct command_line_options {
|
||||
bool little_endian;
|
||||
bool dry_run;
|
||||
bool verbose;
|
||||
enum granularity granularity;
|
||||
enum crc_format format;
|
||||
struct crc_settings crc;
|
||||
bool has_start_magic;
|
||||
uint32_t start_magic;
|
||||
bool has_end_magic;
|
||||
uint32_t end_magic;
|
||||
};
|
||||
|
||||
static error_t parse_opt(int key, char *arg, struct argp_state *state)
|
||||
{
|
||||
struct command_line_options *args = (struct command_line_options *)state->input;
|
||||
switch (key) {
|
||||
case ARG_KEY_DRY_RUN:
|
||||
args->dry_run = true;
|
||||
args->verbose = true;
|
||||
break;
|
||||
case ARG_KEY_START_MAGIC:
|
||||
args->has_start_magic = true;
|
||||
args->start_magic = strtoul(arg, NULL, 0);
|
||||
break;
|
||||
case ARG_KEY_END_MAGIC:
|
||||
args->has_end_magic = true;
|
||||
args->end_magic = strtoul(arg, NULL, 0);
|
||||
break;
|
||||
case 'l':
|
||||
args->little_endian = true;
|
||||
break;
|
||||
case 'v':
|
||||
args->verbose = true;
|
||||
break;
|
||||
case 'g':
|
||||
if (!strcmp(arg, "byte"))
|
||||
args->granularity = GRANULARITY_BYTE;
|
||||
else if (!strcmp(arg, "halfword"))
|
||||
args->granularity = GRANULARITY_16BIT;
|
||||
else if (!strcmp(arg, "word"))
|
||||
args->granularity = GRANULARITY_32BIT;
|
||||
break;
|
||||
default:
|
||||
return ARGP_ERR_UNKNOWN;
|
||||
}
|
||||
@ -41,6 +84,7 @@ static error_t parse_opt(int key, char *arg, struct argp_state *state)
|
||||
|
||||
static int parse_cmdline_options(int *argc, char ***argv, struct command_line_options *cmd_opts)
|
||||
{
|
||||
const int crc_param_group = 1;
|
||||
error_t err;
|
||||
|
||||
if (!argc || !argv)
|
||||
@ -48,6 +92,18 @@ static int parse_cmdline_options(int *argc, char ***argv, struct command_line_op
|
||||
|
||||
static struct argp_option options[] = {
|
||||
{"little-endian", 'l', 0, 0, "Memory image is little endian. Only relevant if granularity is greater than a single byte", 0},
|
||||
{"granularity", 'g', "GRANULARITY", 0, "Granularity to calculate the CRC for", 0},
|
||||
{"poly", 'p', "POLYNOMIAL", 0, "Polynomial to use", crc_param_group},
|
||||
{"start-value", 's', "STARTVALUE", 0, "Start value for CRC calculation", crc_param_group},
|
||||
{"reversed", 'r', 0, 0, "Bit reversed CRC", crc_param_group},
|
||||
{"xor-out", 'x', "XORVAL", 0, "XOR the output with XORVAL. Default 0x0", crc_param_group},
|
||||
{"dry-run", ARG_KEY_DRY_RUN, 0, 0, "Dry run. Caclualate CRCs but do not patch output file. Implicitly activates verbose mode.", 0},
|
||||
{"verbose", 'v', 0, 0, "Verbose output", 0},
|
||||
{"section", 'S', "SEC", 0, "Section to calculate CRC for", 2},
|
||||
{"output-section", 'O', "OUTPUTSEC", 0, "Output section for generated CRCs", 2},
|
||||
{"crc-format", 'F', "FORMAT", 0, "Output Format for CRCs.", 2},
|
||||
{"start-magic", ARG_KEY_START_MAGIC, "STARTMAGIC", 0, "Check output section for start magic (uint32)", 2},
|
||||
{"end-magic", ARG_KEY_END_MAGIC, "STARTMAGIC", 0, "Check output section for start magic (uint32)", 2},
|
||||
/* Sentinel */
|
||||
{NULL, 0, 0, 0, NULL, 0}
|
||||
};
|
||||
@ -65,18 +121,52 @@ static int parse_cmdline_options(int *argc, char ***argv, struct command_line_op
|
||||
return err ? -1 : 0;
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
static void prepare_default_opts(struct command_line_options *opts)
|
||||
{
|
||||
bool verbose = true;
|
||||
struct command_line_options cmd_opts;
|
||||
opts->little_endian = false;
|
||||
opts->verbose = false;
|
||||
opts->granularity = GRANULARITY_BYTE;
|
||||
opts->dry_run = false;
|
||||
opts->crc.xor = 0UL;
|
||||
opts->crc.polynomial = 0x04C11DB7UL;
|
||||
opts->crc.start_value = 0xFFFFFFFFUL;
|
||||
opts->crc.rev = false;
|
||||
opts->format = FORMAT_BARE;
|
||||
opts->has_end_magic = false;
|
||||
opts->has_start_magic = false;
|
||||
}
|
||||
|
||||
cmd_opts.little_endian = false;
|
||||
cmd_opts.granularity = GRANULARITY_BYTE;
|
||||
|
||||
parse_cmdline_options(&argc, &argv, &cmd_opts);
|
||||
static void print_verbose_start_info(const struct command_line_options *cmd_opts)
|
||||
{
|
||||
bool verbose = cmd_opts->verbose;
|
||||
const struct named_crc *predef_crc;
|
||||
|
||||
print_debug("Start CRC patching\n");
|
||||
print_debug("Endianess: %s endian\n", (cmd_opts.little_endian ? "little" : "big"));
|
||||
print_debug("Endianess: %s endian\n", (cmd_opts->little_endian ? "little" : "big"));
|
||||
print_debug("Granularity: %u bits\n", (unsigned int)cmd_opts->granularity);
|
||||
if (cmd_opts->has_start_magic)
|
||||
print_debug("Checking for start magic: 0x%08x\n", (unsigned int)cmd_opts->start_magic);
|
||||
if (cmd_opts->has_end_magic)
|
||||
print_debug("Checking for end magic: 0x%08x\n", (unsigned int)cmd_opts->end_magic);
|
||||
if (cmd_opts->dry_run)
|
||||
print_debug("Dry run mode selected. Will not touch ELF file.\n");
|
||||
predef_crc = reverse_lookup_named_crc(&cmd_opts->crc);
|
||||
if (predef_crc) {
|
||||
print_debug("Predefined CRC detected: %s\n", predef_crc->name);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
bool verbose;
|
||||
struct command_line_options cmd_opts;
|
||||
|
||||
prepare_default_opts(&cmd_opts);
|
||||
parse_cmdline_options(&argc, &argv, &cmd_opts);
|
||||
|
||||
verbose = cmd_opts.verbose || cmd_opts.dry_run;
|
||||
print_verbose_start_info(&cmd_opts);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
88
named_crcs.c
Normal file
88
named_crcs.c
Normal file
@ -0,0 +1,88 @@
|
||||
#include <patchelfcrc/named_crcs.h>
|
||||
#include <stddef.h>
|
||||
#include <string.h>
|
||||
|
||||
#define NAMED_CRC(crc_name, poly, reverse, init, outxor) { \
|
||||
.name = crc_name, \
|
||||
.settings = { \
|
||||
.polynomial = poly, \
|
||||
.xor = outxor, \
|
||||
.start_value = init, \
|
||||
.rev = reverse \
|
||||
}}
|
||||
|
||||
const struct named_crc predefined_crc_table[] = {
|
||||
NAMED_CRC("crc-8", 0x07, false, 0x00, 0x00),
|
||||
NAMED_CRC("crc-8-darc", 0x39, true, 0x00, 0x00),
|
||||
NAMED_CRC("crc-8-i-code", 0x1D, false, 0xFD, 0x00),
|
||||
NAMED_CRC("crc-8-itu", 0x07, false, 0x55, 0x55),
|
||||
NAMED_CRC("crc-8-maxim", 0x31, true, 0x00, 0x00),
|
||||
NAMED_CRC("crc-8-rohc", 0x07, true, 0xFF, 0x00),
|
||||
NAMED_CRC("crc-8-wcdma", 0x9B, true, 0x00, 0x00),
|
||||
NAMED_CRC("crc-16", 0x8005, true, 0x0000, 0x0000),
|
||||
NAMED_CRC("crc-16-buypass", 0x8005, false, 0x0000, 0x0000),
|
||||
NAMED_CRC("crc-16-dds-110", 0x8005, false, 0x800D, 0x0000),
|
||||
NAMED_CRC("crc-16-dect", 0x0589, false, 0x0001, 0x0001),
|
||||
NAMED_CRC("crc-16-dnp", 0x3D65, true, 0xFFFF, 0xFFFF),
|
||||
NAMED_CRC("crc-16-en-13757", 0x3D65, false, 0xFFFF, 0xFFFF),
|
||||
NAMED_CRC("crc-16-genibus", 0x1021, false, 0x0000, 0xFFFF),
|
||||
NAMED_CRC("crc-16-maxim", 0x8005, true, 0xFFFF, 0xFFFF),
|
||||
NAMED_CRC("crc-16-mcrf4xx", 0x1021, true, 0xFFFF, 0x0000),
|
||||
NAMED_CRC("crc-16-riello", 0x1021, true, 0x554D, 0x0000),
|
||||
NAMED_CRC("crc-16-t10-dif", 0x8BB7, false, 0x0000, 0x0000),
|
||||
NAMED_CRC("crc-16-teledisk", 0xA097, false, 0x0000, 0x0000),
|
||||
NAMED_CRC("crc-16-usb", 0x8005, true, 0x0000, 0xFFFF),
|
||||
NAMED_CRC("x-25", 0x1021, true, 0x0000, 0xFFFF),
|
||||
NAMED_CRC("xmodem", 0x1021, false, 0x0000, 0x0000),
|
||||
NAMED_CRC("modbus", 0x8005, true, 0xFFFF, 0x0000),
|
||||
NAMED_CRC("kermit [1]", 0x1021, true, 0x0000, 0x0000),
|
||||
NAMED_CRC("crc-ccitt-false [1]", 0x1021, false, 0xFFFF, 0x0000),
|
||||
NAMED_CRC("crc-aug-ccitt [1]", 0x1021, false, 0x1D0F, 0x0000),
|
||||
NAMED_CRC("crc-24", 0x864CFB, false, 0xB704CE, 0x000000),
|
||||
NAMED_CRC("crc-24-flexray-a", 0x5D6DCB, false, 0xFEDCBA, 0x000000),
|
||||
NAMED_CRC("crc-24-flexray-b", 0x5D6DCB, false, 0xABCDEF, 0x000000),
|
||||
NAMED_CRC("crc-32", 0x04C11DB7, true, 0x00000000, 0xFFFFFFFF),
|
||||
NAMED_CRC("crc-32-bzip2", 0x04C11DB7, false, 0x00000000, 0xFFFFFFFF),
|
||||
NAMED_CRC("crc-32c", 0x1EDC6F41, true, 0x00000000, 0xFFFFFFFF),
|
||||
NAMED_CRC("crc-32d", 0xA833982B, true, 0x00000000, 0xFFFFFFFF),
|
||||
NAMED_CRC("crc-32-mpeg", 0x04C11DB7, false, 0xFFFFFFFF, 0x00000000),
|
||||
NAMED_CRC("posix", 0x04C11DB7, false, 0xFFFFFFFF, 0xFFFFFFFF),
|
||||
NAMED_CRC("crc-32q", 0x814141AB, false, 0x00000000, 0x00000000),
|
||||
NAMED_CRC("jamcrc", 0x04C11DB7, true, 0xFFFFFFFF, 0x00000000),
|
||||
NAMED_CRC("xfer", 0x000000AF, false, 0x00000000, 0x00000000),
|
||||
/* SENTINEL */
|
||||
{.name = NULL, .settings = {0, 0, 0, false}},
|
||||
};
|
||||
|
||||
const struct named_crc *reverse_lookup_named_crc(const struct crc_settings *settings)
|
||||
{
|
||||
const struct named_crc *iter;
|
||||
const struct named_crc *found = NULL;
|
||||
|
||||
for (iter = predefined_crc_table; iter->name; iter++) {
|
||||
if (iter->settings.polynomial == settings->polynomial &&
|
||||
iter->settings.rev == settings->rev &&
|
||||
iter->settings.start_value == settings->start_value &&
|
||||
iter->settings.xor == settings->xor) {
|
||||
found = iter;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return found;
|
||||
}
|
||||
|
||||
const struct named_crc *lookup_named_crc(const char *name)
|
||||
{
|
||||
const struct named_crc *iter;
|
||||
const struct named_crc *found = NULL;
|
||||
|
||||
for (iter = predefined_crc_table; iter->name; iter++) {
|
||||
if (strcmp(iter->name, name)) {
|
||||
found = iter;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return found;
|
||||
}
|
Loading…
Reference in New Issue
Block a user