14 Commits

Author SHA1 Message Date
27580b5f32 Correctly free CRC array 2023-01-04 15:17:35 +01:00
aaa7bdd288 Merge pull request 'Fix #1: Segmentation fault when using NOBITS sections' (#2) from fix-segmentation-fault into master
Reviewed-on: #2
2023-01-04 15:11:48 +01:00
2fca25d4c0 Fix segmentation fault if a NOBITS section is specified for output 2023-01-04 15:07:01 +01:00
e09a07b3d3 Fix segmentation fault if a NOBITS section is specified as a source section 2023-01-04 15:04:06 +01:00
5b86194734 Remove reading of program headers. It is not necessary. 2023-01-04 14:53:25 +01:00
f4f373d65d Readout elf endianess and print error on mismatch 2022-12-17 19:33:13 +01:00
320b0ce650 It is too late. Fix bugs again... 2022-10-25 22:27:56 +02:00
9aa82975b1 Bugifx: Fix CRCs not being written to section 2022-10-25 22:23:39 +02:00
dafd51a376 Bugfix: Fix broken segment table. Manually enforce original layout 2022-10-25 22:02:11 +02:00
baa34c7525 Fix typo in PKGBUILD 2022-10-25 18:21:27 +02:00
c033ec7206 Add man page 2022-10-25 18:17:54 +02:00
7e56af08bf Add first draft of markdown for generation of man page 2022-10-24 21:18:49 +02:00
19a84ef4f2 Move source code to SRC folder and start doxygen 2022-10-24 20:47:38 +02:00
f3f7b1a7ad Comment code and add last missing cmd parameters 2022-10-24 19:47:48 +02:00
16 changed files with 3109 additions and 62 deletions

View File

@@ -8,7 +8,7 @@ arch=('i686' 'x86_64')
url="https://git.shimatta.de/mhu/patchelfcrc"
licence=('GPLv2')
depends=('libelf')
makedepends=('cmake' 'git')
makedepends=('cmake' 'pandoc' 'git')
provides=('patchelfcrc')
source=("${pkgname}-git"::"git+https://git.shimatta.de/mhu/patchelfcrc" "git+https://git.shimatta.de/3rd-party/libfort.git" "git+https://git.shimatta.de/mhu/linklist-lib")
sha1sums=('SKIP' 'SKIP' 'SKIP')
@@ -36,4 +36,5 @@ prepare () {
package () {
install -Dm755 "$srcdir/$pkgname-git/build/patchelfcrc" "$pkgdir/usr/bin/patchelfcrc"
install -Dm644 "$srcdir/$pkgname-git/build/man/patchelfcrc.1.gz" "$pkgdir/usr/share/man/man1/patchelfcrc.1.gz"
}

View File

@@ -2,17 +2,34 @@ cmake_minimum_required(VERSION 3.5)
project(patchelfcrc LANGUAGES C)
if(NOT WIN32)
string(ASCII 27 Esc)
set(ColorReset "${Esc}[m")
set(ColorBold "${Esc}[1m")
set(Red "${Esc}[31m")
set(Green "${Esc}[32m")
set(Yellow "${Esc}[33m")
set(Blue "${Esc}[34m")
set(Magenta "${Esc}[35m")
set(Cyan "${Esc}[36m")
set(White "${Esc}[37m")
set(BoldRed "${Esc}[1;31m")
set(BoldGreen "${Esc}[1;32m")
set(BoldYellow "${Esc}[1;33m")
set(BoldBlue "${Esc}[1;34m")
set(BoldMagenta "${Esc}[1;35m")
set(BoldCyan "${Esc}[1;36m")
set(BoldWhite "${Esc}[1;37m")
endif()
find_package(PkgConfig REQUIRED)
pkg_check_modules(ELF REQUIRED libelf)
set (CFILES
main.c
version.c
named_crcs.c
crc.c
elfpatch.c
reporting.c
)
find_package(Doxygen)
add_subdirectory(man)
aux_source_directory("src" CFILES)
set(GEN_HEADER_PATH "${CMAKE_CURRENT_BINARY_DIR}/include/generated")
@@ -38,4 +55,26 @@ target_include_directories(${PROJECT_NAME} PRIVATE "${CMAKE_CURRENT_BINARY_DIR}/
target_include_directories(${PROJECT_NAME} PRIVATE "include")
add_dependencies(${PROJECT_NAME} version-header)
if (DOXYGEN_FOUND)
set(DOXYFILE_SRC "${CMAKE_CURRENT_SOURCE_DIR}/doxygen/Doxyfile.in")
set(DOXYFILE_DEST "${CMAKE_CURRENT_BINARY_DIR}/Doxyfile")
configure_file(${DOXYFILE_SRC} ${DOXYFILE_DEST} @ONLY)
add_custom_target(doxygen
DEPENDS
doxygen-version-header
COMMAND
${DOXYGEN_EXECUTABLE} ${DOXYFILE_DEST}
WORKING_DIRECTORY
${CMAKE_CURRENT_SOURCE_DIR}
)
add_custom_target(doxygen-version-header
COMMAND
bash ${CMAKE_CURRENT_SOURCE_DIR}/doxygen/gen-version-string.sh "${CMAKE_CURRENT_BINARY_DIR}/doxyversion.in"
WORKING_DIRECTORY
${CMAKE_CURRENT_SOURCE_DIR}
)
else (DOXYGEN_FOUND)
message("${BoldMagenta}Doxygen needs to be installed to generate the doxygen documentation${ColorReset}")
message("${BoldMagenta}doxygen target will not be available${ColorReset}")
endif (DOXYGEN_FOUND)

2666
doxygen/Doxyfile.in Normal file

File diff suppressed because it is too large Load Diff

7
doxygen/gen-version-string.sh Executable file
View File

@@ -0,0 +1,7 @@
#!/bin/bash
if [[ -z $1 ]]; then
exit -1
fi
echo "PROJECT_NUMBER = `git describe --tags --always --dirty`" > $1

View File

@@ -1,16 +1,49 @@
/*
* This file is part of patchelfcrc.
* Copyright (c) 2022 Mario Hüttel.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, version 2 only.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef _CRC_OUTPUT_STRUCT_H_
#define _CRC_OUTPUT_STRUCT_H_
#include <stdint.h>
/**
* @brief Expected size of @ref crc_out_struct_32bit.
* @note If the size of the structure does not match this number, structure padding occured which should not happen.
*/
#define CRC_OUT_STRUCT_SIZE_32BIT 12u
/**
* @brief output structure of CRCs in a 32bit executable
*/
struct crc_out_struct_32bit {
uint32_t start_address; /**< @brief Start address of struct*/
uint32_t length; /**< @brief Length of section in bytes */
uint32_t crc; /**< @brief LSB aligned CRC */
};
/**
* @brief Expected size of @ref crc_out_struct_64bit.
* @note If the size of the structure does not match this number, structure padding occured which should not happen.
*/
#define CRC_OUT_STRUCT_SIZE_64BIT 24u
/**
* @brief output structure of CRCs in a 64bit executable
*/
struct crc_out_struct_64bit {
uint64_t start_address; /**< @brief Start address of struct*/
uint64_t length; /**< @brief Length of section in bytes */
@@ -18,6 +51,9 @@ struct crc_out_struct_64bit {
uint32_t _unused_dummy; /**< @brief Dummy. Do not use, it prevents misalignments */
};
/**
* @brief Trigger compile error if condition is false
*/
#define BUILD_ASSERT(cond) ((void)sizeof(char[1 - 2 * !!(cond)]))
/**

View File

@@ -1,3 +1,25 @@
/*
* This file is part of patchelfcrc.
* Copyright (c) 2022 Mario Hüttel.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, version 2 only.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/**
* @file elfpatch.h
* @brief Header for ELF Patching Class
*/
#ifndef _ELFPATCH_H_
#define _ELFPATCH_H_
@@ -19,7 +41,7 @@ enum crc_format {
FORMAT_STRUCT,
};
elfpatch_handle_t *elf_patch_open(const char *path, bool readonly);
elfpatch_handle_t *elf_patch_open(const char *path, bool readonly, bool expect_little_endian);
/**
* @brief Check if a section is present in file
@@ -28,6 +50,16 @@ elfpatch_handle_t *elf_patch_open(const char *path, bool readonly);
*/
int elf_patch_check_for_section(elfpatch_handle_t *ep, const char *section);
/**
* @brief Compute CRC over a section in an ELF file
* @param ep Elf patch object
* @param section Section name
* @param[out] crc CRC output
* @param granularity CRC calculation granularity
* @param little_endian memory layout is little endian
* @return 0 if successful
* @return negative if error
*/
int elf_patch_compute_crc_over_section(elfpatch_handle_t *ep, const char *section, struct crc_calc *crc,
enum granularity granularity, bool little_endian);

View File

@@ -1,3 +1,21 @@
/*
* This file is part of patchelfcrc.
* Copyright (c) 2022 Mario Hüttel.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, version 2 only.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef _REPORTING_H_
#define _REPORTING_H_

19
man/CMakeLists.txt Normal file
View File

@@ -0,0 +1,19 @@
set (MAN_PAGE_NAME "patchelfcrc.1.gz")
add_custom_target(man-page
ALL
DEPENDS
${CMAKE_CURRENT_BINARY_DIR}/${MAN_PAGE_NAME}
)
add_custom_command(
OUTPUT
${CMAKE_CURRENT_BINARY_DIR}/${MAN_PAGE_NAME}
COMMAND
bash -c "pandoc \"${CMAKE_CURRENT_SOURCE_DIR}/patchelfcrc.1.md\" -s -t man | gzip > \"${CMAKE_CURRENT_BINARY_DIR}/${MAN_PAGE_NAME}\""
VERBATIM
WORKING_DIRECTORY
${CMAKE_CURRENT_BINARY_DIR}
MAIN_DEPENDENCY
${CMAKE_CURRENT_SOURCE_DIR}/patchelfcrc.1.md
)

123
man/patchelfcrc.1.md Normal file
View File

@@ -0,0 +1,123 @@
% patchelfcrc(1) 0.0.2
% Mario Huettel
% October 2022
# NAME
**patchelfcrc** - Patch CRC checksums into ELF files
# SYNOPSYS
**patchelfcrc** [**-lrv?V**] [**-g** *GRANULARITY*] [**-p** *POLYNOMIAL*] [**-s** *STARTVALUE*]
[**-x** *XORVAL*] [**-F** *FORMAT*] [**-O** *OUTPUTSECTION*] [**-S** *SEC*]
[**\--granularity**=*GRANULARITY*] [**\--little-endian**] [**\--dry-run**]
[**\--poly**=*POLYNOMIAL*] [**\--reversed**] [**\--start-value**=*STARTVALUE*]
[**--verbose**] [**\--xor-out**=*XORVAL*] [**\--end-magic**=*MAGIC*]
[**\--crc-format**=*FORMAT*] [**\--list-crcs**] [**\--output-section**=*OUTPUTSECTION*]
[**\--start-magic**=*MAGIC*] [**\--section**=*SECTION*] [**\--help**] [**\--usage**]
[**\--version**] *ELF*
# DESCRIPTION
**patchelfcrc** reads in sections of an *ELF* file and computes CRC checksums over the data. The calculated CRCs are placed in an output section of the *ELFFILE*. The output section must already exist inside the *ELF* file and must be big enough to hold all generated CRC checksums.
**patchelfcrc** supports multiple predefined CRCs as well as custom polynomials.
# OPTIONS
**-h**, **\--help**
: Display help
**\--usage**
: Display usage information
**-p** *POLYNOMIAL*, **\--polynomial**=*POLYNOMIAL*
: Polynomial to use for CRC calculation. For a n bit wide CRC supply a number with n+1 bits and the MSB set. Alternatively, a predifined name can be supplied. See **\--list-crcs** for details. At maximum a 32 bit wide CRC can be calculated. If nothing is given, crc-32-mpeg is used.
**-s** *STARTVALUE*, **\--start-value**=*STARTVALUE*
: Start value to preload CRC register with. This value is XORed with the *XORVAL* (see option **-x**).
**-x** *XORVAL*, **\--xor-value**=*XORVAL*
: XOR Value applied to initial start value (**-s**) and to the final CRC result.
**-r**, **\--reversed**
: Use bitreversed CRC. This is not implemented yet!
**-g** *GRANULARITY*, **\--granularity**=*GRANULARITY*
: CRC calculation granularity. This has no effect if big endian layout is used. For little endian layout, it specifies the sizes of the individual elements the CRC is computed over.
: *GRANULARITY* = [word | halfword | byte]. Defaults to byte.
**-l**, **\--little-endian**
: The memory layout of the *ELFFILE* is in little-endian format.
**-F** *FORMAT*, **\--crc-format**=*FORMAT*
: Output format to place in output section. Options for *FORMAT* are *bare* or *struct*
**--start-magic**=*MAGIC*, **--endmagic**=*MAGIC*
: *MAGIC* numbers (32 bit unsigned) that are expected to be found at the start and the end of the given output section. This serves as safety guard against accidental corruption of the output file. *It is highly recommended to use these options*.
**--help**, **-h**, **-?**
: Print help.
**\--dry-run**
: Dry run. Do all calculations but do not write changes to file. *ELF* file will only be opened readonly. This mode implicitly activates the verbose output
**-v**, **\--verbose**
: Activate verbose output
**-V**, **\--version**
: Print version number
**--usage**
: Print usage hints on command line options.
# EXAMPLES
**patchelfcrc** --list-crcs
| Name | Polynomial | Reversed | Start Value | Output XOR |
|------------------|-------------|----------|-------------|------------|
| crc-8 | 0x107 | no | 0x0 | 0x0 |
| crc-8-darc | 0x139 | yes | 0x0 | 0x0 |
| crc-8-i-code | 0x11d | no | 0xfd | 0x0 |
| crc-8-itu | 0x107 | no | 0x55 | 0x55 |
| crc-8-maxim | 0x131 | yes | 0x0 | 0x0 |
| crc-8-rohc | 0x107 | yes | 0xff | 0x0 |
| crc-8-wcdma | 0x19b | yes | 0x0 | 0x0 |
| crc-16 | 0x18005 | yes | 0x0 | 0x0 |
| crc-16-buypass | 0x18005 | no | 0x0 | 0x0 |
| crc-16-dds-110 | 0x18005 | no | 0x800d | 0x0 |
| crc-16-dect | 0x10589 | no | 0x1 | 0x1 |
| crc-16-dnp | 0x13d65 | yes | 0xffff | 0xffff |
| crc-16-en-13757 | 0x13d65 | no | 0xffff | 0xffff |
| crc-16-genibus | 0x11021 | no | 0x0 | 0xffff |
| crc-16-maxim | 0x18005 | yes | 0xffff | 0xffff |
| crc-16-mcrf4xx | 0x11021 | yes | 0xffff | 0x0 |
| crc-16-riello | 0x11021 | yes | 0x554d | 0x0 |
| crc-16-t10-dif | 0x18bb7 | no | 0x0 | 0x0 |
| crc-16-teledisk | 0x1a097 | no | 0x0 | 0x0 |
| crc-16-usb | 0x18005 | yes | 0x0 | 0xffff |
| x-25 | 0x11021 | yes | 0x0 | 0xffff |
| xmodem | 0x11021 | no | 0x0 | 0x0 |
| modbus | 0x18005 | yes | 0xffff | 0x0 |
| kermit | 0x11021 | yes | 0x0 | 0x0 |
| crc-ccitt-false | 0x11021 | no | 0xffff | 0x0 |
| crc-aug-ccitt | 0x11021 | no | 0x1d0f | 0x0 |
| crc-24 | 0x1864cfb | no | 0xb704ce | 0x0 |
| crc-24-flexray-a | 0x15d6dcb | no | 0xfedcba | 0x0 |
| crc-24-flexray-b | 0x15d6dcb | no | 0xabcdef | 0x0 |
| crc-32 | 0x104c11db7 | yes | 0x0 | 0xffffffff |
| crc-32-bzip2 | 0x104c11db7 | no | 0x0 | 0xffffffff |
| crc-32c | 0x11edc6f41 | yes | 0x0 | 0xffffffff |
| crc-32d | 0x1a833982b | yes | 0x0 | 0xffffffff |
| crc-32-mpeg | 0x104c11db7 | no | 0xffffffff | 0x0 |
| posix | 0x104c11db7 | no | 0xffffffff | 0xffffffff |
| crc-32q | 0x1814141ab | no | 0x0 | 0x0 |
| jamcrc | 0x104c11db7 | yes | 0xffffffff | 0x0 |
| xfer | 0x1000000af | no | 0x0 | 0x0 |
**patchelfcrc** -l -g word --start-magic=0x12345678 --end-magic=0x8754321 -p crc-32-mpeg -f bare -O .outputsection -S .text executable.elf
: Calculate the CRC over *.text* section and place the result in the *.outputsection* section.
The output sections start and end are checked for the given magic numbers in order to assure correct memory layout.
*CRC-32-MPEG* is used as CRC algorothm.
The memory is interpreted as *little endian* and the CRC calculation granularity is a 32 bit *word*.
# BUGS
Currently, reversed CRC algorithms are not implemented.

View File

@@ -1,27 +0,0 @@
#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;
}
bool reporting_get_verbosity(void)
{
return global_verbosity_state;
}

View File

View File

@@ -1,3 +1,21 @@
/*
* This file is part of patchelfcrc.
* Copyright (c) 2022 Mario Hüttel.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, version 2 only.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <patchelfcrc/elfpatch.h>
#include <patchelfcrc/reporting.h>
#include <unistd.h>
@@ -255,14 +273,13 @@ static int elf_patch_update_info(elfpatch_handle_t *ep)
return -1;
}
return 0;
}
elfpatch_handle_t *elf_patch_open(const char *path, bool readonly)
elfpatch_handle_t *elf_patch_open(const char *path, bool readonly, bool expect_little_endian)
{
struct elfpatch *ep;
const char *ident;
/* This is important to guarantee structure packing behavior */
CRC_OUT_CHECK_STRUCT_SIZES;
@@ -287,11 +304,35 @@ elfpatch_handle_t *elf_patch_open(const char *path, bool readonly)
goto close_fd;
}
/* Prevent Libelf from relayouting the sections, which would brick the load segments */
elf_flagelf(ep->elf, ELF_C_SET, ELF_F_LAYOUT);
if (elf_patch_update_info(ep)) {
print_err("File malformatted. Cannot use for CRC patching\n");
goto close_elf;
}
ident = elf_getident(ep->elf, NULL);
if (ident) {
switch (ident[5]) {
case 1:
print_debug("ELF Endianess: little\n");
if (!expect_little_endian) {
print_err("Big endian format expected. File is little endian. Double check settings!\n");
}
break;
case 2:
print_debug("ELF Endianess: big\n");
if (expect_little_endian) {
print_err("Little endian format expected. File is big endian. Double check settings!\n");
}
break;
default:
print_err("Cannot determine endianess of ELF file. EI_DATA is: %d\n", ident[5]);
break;
}
}
return (elfpatch_handle_t *)ep;
close_elf:
if (ep->elf) {
@@ -382,8 +423,16 @@ int elf_patch_compute_crc_over_section(elfpatch_handle_t *ep, const char *sectio
}
print_debug("Section data length: %lu\n", data->d_size);
if (!data->d_size)
if (!data->d_size) {
print_err("Section %s contains no data.\n", section);
return -2;
}
/* NOBIT sections have a length but no data in the file. Abort in this case */
if (!data->d_buf) {
print_err("Section %s does not contain loadable data.\n", section);
return -2;
}
/* If big endian or granularity is byte, simply compute CRC. No reordering is necessary */
if (!little_endian || granularity == GRANULARITY_BYTE) {
@@ -485,6 +534,11 @@ int elf_patch_write_crcs_to_section(elfpatch_handle_t *ep, const char *section,
/* Get data object of 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);
goto ret_err;
}
/* Check the start and end magics */
if (check_start_magic) {
@@ -597,17 +651,11 @@ int elf_patch_write_crcs_to_section(elfpatch_handle_t *ep, const char *section,
}
}
/* Update ELF file */
if (ep->readonly) {
print_debug("DRY RUN: File will not be updated\n");
ret = 0;
} else {
if (elf_update(ep->elf, ELF_C_WRITE) < 0) {
print_err("Error writing ELF file: %s\n", elf_errmsg(-1));
} else {
ret = 0;
}
}
/* Flag section data as invalid to trigger rewrite.
* This is needed due to the forced memory layout
*/
elf_flagdata(output_sec_data, ELF_C_SET, ELF_F_DIRTY);
ret = 0;
ret_err:
return ret;
@@ -617,6 +665,17 @@ void elf_patch_close_and_free(elfpatch_handle_t *ep)
{
ret_if_ep_err(ep);
if (ep->elf) {
/* Update ELF file */
if (ep->readonly) {
print_debug("DRY RUN: File will not be updated\n");
} else {
if (elf_update(ep->elf, ELF_C_WRITE) < 0) {
print_err("Error writing ELF file: %s\n", elf_errmsg(-1));
}
}
}
if (ep->elf)
elf_end(ep->elf);

View File

@@ -53,6 +53,14 @@ struct command_line_options {
const char *output_section;
};
/**
* @brief Parse command line options
* @param key Option key
* @param arg Argument passed
* @param state State of ARGP parser
* @return 0 No error
* @return ARGP_ERR_UNKNOWN in case of an unknown option
*/
static error_t parse_opt(int key, char *arg, struct argp_state *state)
{
struct command_line_options *args = (struct command_line_options *)state->input;
@@ -117,6 +125,15 @@ static error_t parse_opt(int key, char *arg, struct argp_state *state)
case 'O':
args->output_section = arg;
break;
case 'r':
args->crc.rev = true;
break;
case 's':
args->crc.start_value = strtoul(arg, NULL, 0);
break;
case 'x':
args->crc.xor = strtoul(arg, NULL, 0);
break;
case ARGP_KEY_ARG:
if (state->arg_num >= 1)
argp_usage(state);
@@ -315,6 +332,12 @@ static int compute_crcs(elfpatch_handle_t *ep, SlList *list, const struct comman
return ret;
}
/**
* @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.
* @note The array @p crcs must be at least as long as @p list
*/
static void print_crcs(SlList *list, const uint32_t *crcs)
{
SlList *iter;
@@ -341,7 +364,7 @@ int main(int argc, char **argv)
struct command_line_options cmd_opts;
elfpatch_handle_t *ep;
int ret = 0;
uint32_t *crcs;
uint32_t *crcs = NULL;
prepare_default_opts(&cmd_opts);
parse_cmdline_options(&argc, &argv, &cmd_opts);
@@ -350,6 +373,11 @@ int main(int argc, char **argv)
reporting_enable_verbose();
print_verbose_start_info(&cmd_opts);
if (cmd_opts.list) {
list_predefined_crcs();
goto free_cmds;
}
/* Check if file has been supplied */
if (!cmd_opts.elf_path) {
print_err("No ELF file specified. Exiting...\n");
@@ -360,11 +388,6 @@ int main(int argc, char **argv)
print_err("No output section specified. Will continue but not patch file.\n");
}
if (cmd_opts.list) {
list_predefined_crcs();
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");
@@ -375,7 +398,7 @@ int main(int argc, char **argv)
elf_version(EV_CURRENT);
/* Open the ELF file */
ep = elf_patch_open(cmd_opts.elf_path, cmd_opts.dry_run);
ep = elf_patch_open(cmd_opts.elf_path, cmd_opts.dry_run, cmd_opts.little_endian);
if (!ep) {
ret = -2;
goto free_cmds;
@@ -384,12 +407,14 @@ int main(int argc, char **argv)
/* Check if all sections are present */
if (check_all_sections_present(ep, cmd_opts.section_list)) {
ret = -2;
goto free_cmds;
goto ret_close_elf;
}
/* Compute CRCs over sections */
crcs = (uint32_t *)malloc(sl_list_length(cmd_opts.section_list) * sizeof(uint32_t));
compute_crcs(ep, cmd_opts.section_list, &cmd_opts, crcs);
if (compute_crcs(ep, cmd_opts.section_list, &cmd_opts, crcs)) {
goto ret_close_elf;
}
if (reporting_get_verbosity()) {
print_crcs(cmd_opts.section_list, crcs);
@@ -404,11 +429,15 @@ int main(int argc, char **argv)
}
}
ret_close_elf:
elf_patch_close_and_free(ep);
free_cmds:
free_cmd_args(&cmd_opts);
/* Free CRCs if necessary */
if (crcs)
free(crcs);
return ret;
}

45
src/reporting.c Normal file
View File

@@ -0,0 +1,45 @@
/*
* This file is part of patchelfcrc.
* Copyright (c) 2022 Mario Hüttel.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, version 2 only.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#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;
}
bool reporting_get_verbosity(void)
{
return global_verbosity_state;
}