Implement ELF file opening
This commit is contained in:
parent
dd9eb898a8
commit
fb5f527f45
@ -10,6 +10,8 @@ set (CFILES
|
|||||||
version.c
|
version.c
|
||||||
named_crcs.c
|
named_crcs.c
|
||||||
crc.c
|
crc.c
|
||||||
|
elfpatch.c
|
||||||
|
reporting.c
|
||||||
)
|
)
|
||||||
|
|
||||||
set(GEN_HEADER_PATH "${CMAKE_CURRENT_BINARY_DIR}/include/generated")
|
set(GEN_HEADER_PATH "${CMAKE_CURRENT_BINARY_DIR}/include/generated")
|
||||||
|
75
elfpatch.c
Normal file
75
elfpatch.c
Normal file
@ -0,0 +1,75 @@
|
|||||||
|
#include <patchelfcrc/elfpatch.h>
|
||||||
|
#include <patchelfcrc/reporting.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
|
||||||
|
#define print_err(fmt, ...) fprintf(stderr, (fmt), ## __VA_ARGS__);
|
||||||
|
|
||||||
|
int elf_patch_open(struct elfpatch *ep, const char *path)
|
||||||
|
{
|
||||||
|
int fd;
|
||||||
|
Elf *elf;
|
||||||
|
|
||||||
|
if (!ep || !path)
|
||||||
|
return -1000;
|
||||||
|
|
||||||
|
memset(ep, 0, sizeof(struct elfpatch));
|
||||||
|
|
||||||
|
fd = open(path, O_RDWR, 0);
|
||||||
|
if (fd < 0) {
|
||||||
|
print_err("Error opening file: %s\n", path);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
elf = elf_begin(fd, ELF_C_RDWR, NULL);
|
||||||
|
if (!elf) {
|
||||||
|
close(fd);
|
||||||
|
print_err("[LIBELF] %s\n", elf_errmsg(-1));
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
ep->fd = fd;
|
||||||
|
ep->elf = elf;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void elf_patch_print_stats(const struct elfpatch *ep)
|
||||||
|
{
|
||||||
|
Elf_Kind ek;
|
||||||
|
const char *type_string = "unrecognized";
|
||||||
|
|
||||||
|
if (!ep || !ep->elf)
|
||||||
|
return;
|
||||||
|
|
||||||
|
ek = elf_kind(ep->elf);
|
||||||
|
|
||||||
|
switch (ek) {
|
||||||
|
case ELF_K_AR:
|
||||||
|
type_string = "archive";
|
||||||
|
break;
|
||||||
|
case ELF_K_ELF:
|
||||||
|
type_string = "elf object";
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
/* Unrecognized is the default. Do nothing */
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
print_debug("ELF File Type: %s\n", type_string);
|
||||||
|
}
|
||||||
|
|
||||||
|
void elf_patch_close(struct elfpatch *ep)
|
||||||
|
{
|
||||||
|
if (!ep)
|
||||||
|
return;
|
||||||
|
if (ep->elf)
|
||||||
|
elf_end(ep->elf);
|
||||||
|
|
||||||
|
if (ep->fd > 0)
|
||||||
|
close(ep->fd);
|
||||||
|
|
||||||
|
ep->elf = NULL;
|
||||||
|
ep->fd = 0;
|
||||||
|
}
|
17
include/patchelfcrc/elfpatch.h
Normal file
17
include/patchelfcrc/elfpatch.h
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
#ifndef _ELFPATCH_H_
|
||||||
|
#define _ELFPATCH_H_
|
||||||
|
|
||||||
|
#include <libelf.h>
|
||||||
|
|
||||||
|
struct elfpatch {
|
||||||
|
int fd;
|
||||||
|
Elf *elf;
|
||||||
|
};
|
||||||
|
|
||||||
|
int elf_patch_open(struct elfpatch *ep, const char *path);
|
||||||
|
|
||||||
|
void elf_patch_print_stats(const struct elfpatch *ep);
|
||||||
|
|
||||||
|
void elf_patch_close(struct elfpatch *ep);
|
||||||
|
|
||||||
|
#endif /* _ELFPATCH_H_ */
|
10
include/patchelfcrc/reporting.h
Normal file
10
include/patchelfcrc/reporting.h
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
#ifndef _REPORTING_H_
|
||||||
|
#define _REPORTING_H_
|
||||||
|
|
||||||
|
#define print_err(fmt, ...) fprintf(stderr, (fmt), ## __VA_ARGS__);
|
||||||
|
|
||||||
|
void print_debug(const char *fmt, ...);
|
||||||
|
|
||||||
|
void reporting_enable_verbose(void);
|
||||||
|
|
||||||
|
#endif /* _REPORTING_H_ */
|
54
main.c
54
main.c
@ -25,13 +25,8 @@
|
|||||||
#include <patchelfcrc/crc.h>
|
#include <patchelfcrc/crc.h>
|
||||||
#include <patchelfcrc/version.h>
|
#include <patchelfcrc/version.h>
|
||||||
#include <linklist-lib/singly-linked-list.h>
|
#include <linklist-lib/singly-linked-list.h>
|
||||||
|
#include <patchelfcrc/reporting.h>
|
||||||
#define print_err(fmt, ...) fprintf(stderr, (fmt), ## __VA_ARGS__);
|
#include <patchelfcrc/elfpatch.h>
|
||||||
#define print_debug(fmt, ...) do { \
|
|
||||||
if (verbose) { \
|
|
||||||
printf("[DBG] "fmt, ## __VA_ARGS__); \
|
|
||||||
} \
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
const char *argp_program_bug_address = "<mario.huettel@linux.com>";
|
const char *argp_program_bug_address = "<mario.huettel@linux.com>";
|
||||||
|
|
||||||
@ -64,6 +59,7 @@ struct command_line_options {
|
|||||||
uint32_t end_magic;
|
uint32_t end_magic;
|
||||||
bool list;
|
bool list;
|
||||||
SlList *section_list;
|
SlList *section_list;
|
||||||
|
const char *elf_path;
|
||||||
};
|
};
|
||||||
|
|
||||||
static error_t parse_opt(int key, char *arg, struct argp_state *state)
|
static error_t parse_opt(int key, char *arg, struct argp_state *state)
|
||||||
@ -117,6 +113,12 @@ static error_t parse_opt(int key, char *arg, struct argp_state *state)
|
|||||||
else if (!strcmp(arg, "word"))
|
else if (!strcmp(arg, "word"))
|
||||||
args->granularity = GRANULARITY_32BIT;
|
args->granularity = GRANULARITY_32BIT;
|
||||||
break;
|
break;
|
||||||
|
case ARGP_KEY_ARG:
|
||||||
|
if (state->arg_num >= 1)
|
||||||
|
argp_usage(state);
|
||||||
|
else
|
||||||
|
args->elf_path = arg;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
return ARGP_ERR_UNKNOWN;
|
return ARGP_ERR_UNKNOWN;
|
||||||
}
|
}
|
||||||
@ -155,7 +157,7 @@ static int parse_cmdline_options(int *argc, char ***argv, struct command_line_op
|
|||||||
static struct argp arg_parser = {
|
static struct argp arg_parser = {
|
||||||
options,
|
options,
|
||||||
parse_opt,
|
parse_opt,
|
||||||
NULL,
|
"ELF",
|
||||||
NULL,
|
NULL,
|
||||||
0, 0, 0
|
0, 0, 0
|
||||||
};
|
};
|
||||||
@ -180,11 +182,11 @@ static void prepare_default_opts(struct command_line_options *opts)
|
|||||||
opts->has_start_magic = false;
|
opts->has_start_magic = false;
|
||||||
opts->list = false;
|
opts->list = false;
|
||||||
opts->section_list = NULL;
|
opts->section_list = NULL;
|
||||||
|
opts->elf_path = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void print_verbose_start_info(const struct command_line_options *cmd_opts)
|
static void print_verbose_start_info(const struct command_line_options *cmd_opts)
|
||||||
{
|
{
|
||||||
bool verbose = cmd_opts->verbose;
|
|
||||||
int i;
|
int i;
|
||||||
SlList *list_iter;
|
SlList *list_iter;
|
||||||
const struct named_crc *predef_crc;
|
const struct named_crc *predef_crc;
|
||||||
@ -209,6 +211,10 @@ static void print_verbose_start_info(const struct command_line_options *cmd_opts
|
|||||||
print_debug("CRC length: %d\n", crc_len_from_poly(cmd_opts->crc.polynomial));
|
print_debug("CRC length: %d\n", crc_len_from_poly(cmd_opts->crc.polynomial));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (cmd_opts->elf_path) {
|
||||||
|
print_debug("ELF file: %s\n", cmd_opts->elf_path);
|
||||||
|
}
|
||||||
|
|
||||||
if (cmd_opts->section_list) {
|
if (cmd_opts->section_list) {
|
||||||
for (list_iter = cmd_opts->section_list, i = 1; list_iter; list_iter = sl_list_next(list_iter), i++) {
|
for (list_iter = cmd_opts->section_list, i = 1; list_iter; list_iter = sl_list_next(list_iter), i++) {
|
||||||
print_debug("Input section [%d]: \"%s\"\n", i, (const char *)list_iter->data);
|
print_debug("Input section [%d]: \"%s\"\n", i, (const char *)list_iter->data);
|
||||||
@ -234,28 +240,46 @@ static void free_cmd_args(struct command_line_options *opts)
|
|||||||
|
|
||||||
int main(int argc, char **argv)
|
int main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
bool verbose;
|
|
||||||
struct crc_calc crc;
|
struct crc_calc crc;
|
||||||
struct command_line_options cmd_opts;
|
struct command_line_options cmd_opts;
|
||||||
|
struct elfpatch ep;
|
||||||
|
|
||||||
prepare_default_opts(&cmd_opts);
|
prepare_default_opts(&cmd_opts);
|
||||||
parse_cmdline_options(&argc, &argv, &cmd_opts);
|
parse_cmdline_options(&argc, &argv, &cmd_opts);
|
||||||
|
|
||||||
verbose = cmd_opts.verbose || cmd_opts.dry_run;
|
if (cmd_opts.verbose || cmd_opts.dry_run)
|
||||||
|
reporting_enable_verbose();
|
||||||
print_verbose_start_info(&cmd_opts);
|
print_verbose_start_info(&cmd_opts);
|
||||||
|
|
||||||
|
/* Check if file has been supplied */
|
||||||
|
if (!cmd_opts.elf_path) {
|
||||||
|
print_err("No ELF file specified. Exiting...\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
if (cmd_opts.list) {
|
if (cmd_opts.list) {
|
||||||
list_predefined_crcs();
|
list_predefined_crcs();
|
||||||
goto free_cmds;
|
goto free_cmds;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Do error printing if using a reversed polynomial. It is not implemented yet! */
|
||||||
|
if (cmd_opts.crc.rev) {
|
||||||
|
print_err("Reversed polynomials are not supported yet\nExiting...\n");
|
||||||
|
goto free_cmds;
|
||||||
|
}
|
||||||
|
|
||||||
/* Build the CRC */
|
/* Build the CRC */
|
||||||
crc_init(&crc, &cmd_opts.crc);
|
crc_init(&crc, &cmd_opts.crc);
|
||||||
|
|
||||||
/* Perform the check test */
|
/* Prepare libelf for use with the latest ELF version */
|
||||||
crc_push_bytes(&crc, "123456789", 9u);
|
elf_version(EV_CURRENT);
|
||||||
crc_finish_calc(&crc);
|
|
||||||
printf("CRC Check value: 0x%08x\n", crc_get_value(&crc));
|
/* Open the ELF file */
|
||||||
|
elf_patch_open(&ep, cmd_opts.elf_path);
|
||||||
|
|
||||||
|
elf_patch_print_stats(&ep);
|
||||||
|
|
||||||
|
elf_patch_close(&ep);
|
||||||
|
|
||||||
crc_destroy(&crc);
|
crc_destroy(&crc);
|
||||||
free_cmds:
|
free_cmds:
|
||||||
|
22
reporting.c
Normal file
22
reporting.c
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
#include <patchelfcrc/reporting.h>
|
||||||
|
#include <stdarg.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
|
||||||
|
static bool global_verbosity_state = false;
|
||||||
|
|
||||||
|
void print_debug(const char *fmt, ...)
|
||||||
|
{
|
||||||
|
va_list va;
|
||||||
|
|
||||||
|
if (global_verbosity_state) {
|
||||||
|
va_start(va, fmt);
|
||||||
|
(void)vprintf(fmt, va);
|
||||||
|
va_end(va);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void reporting_enable_verbose(void)
|
||||||
|
{
|
||||||
|
global_verbosity_state = true;
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user