diff --git a/bindings/c/Makefile b/bindings/c/Makefile index e69de29..57585fc 100644 --- a/bindings/c/Makefile +++ b/bindings/c/Makefile @@ -0,0 +1,39 @@ +# Either `debug` or `release` +BUILD_MODE ?= debug + +CC := gcc +LIB := ../../target/$(BUILD_MODE)/libipl3checksum.a + +CSTD := -std=c11 +ifeq ($(BUILD_MODE), debug) + CFLAGS ?= -O0 -g3 +else + CFLAGS ?= -Os +endif +IINC := -I include +WARNINGS := -Wall -Wextra -Wshadow -Werror + + +C_BINDINGS_TESTS := $(wildcard tests/test_*.c) +C_BINDINGS_ELFS := $(C_BINDINGS_TESTS:.c=.elf) + +all: $(C_BINDINGS_ELFS) + +clean: + $(RM) -rf $(C_BINDINGS_ELFS) tests/*.elf + +.PHONY: all clean +.DEFAULT_GOAL := all + +CARGO_FLAGS ?= +ifneq ($(BUILD_MODE), debug) + CARGO_FLAGS += --release +endif +$(shell cargo build --lib --features c_bindings $(CARGO_FLAGS)) + + +%.elf: %.c $(LIB) + $(CC) $(CSTD) $(CFLAGS) $(IINC) $(WARNINGS) -o $@ tests/utils.c $< -L ../../target/$(BUILD_MODE) -Wl,-Bstatic -l ipl3checksum -Wl,-Bdynamic + +# Print target for debugging +print-% : ; $(info $* is a $(flavor $*) variable set to [$($*)]) @true diff --git a/bindings/c/include/ipl3checksum/error.h b/bindings/c/include/ipl3checksum/error.h index d680625..4c0723b 100644 --- a/bindings/c/include/ipl3checksum/error.h +++ b/bindings/c/include/ipl3checksum/error.h @@ -2,6 +2,8 @@ #define IPL3CHECKSUM_ERROR_H #pragma once +#include + #ifdef __cplusplus extern "C" { diff --git a/bindings/c/tests/test_checksum.c b/bindings/c/tests/test_checksum.c new file mode 100644 index 0000000..e1f8912 --- /dev/null +++ b/bindings/c/tests/test_checksum.c @@ -0,0 +1,55 @@ +/* SPDX-FileCopyrightText: © 2023 Decompollaborate */ +/* SPDX-License-Identifier: MIT */ + +#include "ipl3checksum.h" + +#include +#include + +#include "utils.h" + +void print_usage(int argc, char *argv[]) { + (void)argc; + + fprintf(stderr, "Usage: %s bin_file cic_kind\n", argv[0]); + fprintf(stderr, "\n"); + fprintf(stderr, "This programs computes the ipl3 checksum of a big endian binary file with a given cic kind\n"); +} + +int main(int argc, char *argv[]) { + int ret = 0; + + if (argc < 2) { + print_usage(argc, argv); + return -1; + } + + const char *bin_path = argv[1]; + const char *cic_kind_name = argv[2]; + + size_t bin_size = 0; + uint8_t *bin = read_binary_file(bin_path, &bin_size); + assert(bin_size > 0); + assert(bin != NULL); + + fprintf(stderr, "CIC kind: '%s'\n", cic_kind_name); + // TODO: Don't hardcode + Ipl3Checksum_CICKind kind = Ipl3Checksum_CICKind_CIC_6102_7101; + + { + uint32_t checksum0; + uint32_t checksum1; + + Ipl3Checksum_Error err = ipl3checksum_calculate_checksum(&checksum0, &checksum1, bin_size, bin, kind); + + if (err.tag == Ipl3Checksum_Error_Okay) { + fprintf(stderr, "Computed checksum: %08X %08X\n", checksum0, checksum1); + } else { + fprintf(stderr, "Error trying to compute the checksum: %s\n", get_ipl3checksum_error_str(err)); + } + } + + free(bin); + + return ret; +} diff --git a/bindings/c/tests/utils.c b/bindings/c/tests/utils.c new file mode 100644 index 0000000..f05a814 --- /dev/null +++ b/bindings/c/tests/utils.c @@ -0,0 +1,57 @@ +/* SPDX-FileCopyrightText: © 2023 Decompollaborate */ +/* SPDX-License-Identifier: MIT */ + +#include "utils.h" + +#include +#include +#include +#include + +uint8_t *read_binary_file(const char *path, size_t *size) { + assert(path != NULL); + assert(size != NULL); + + fprintf(stderr, "Reading file %s\n", path); + + FILE *f = fopen(path, "rb"); + if (f == NULL) { + return NULL; + } + + fseek(f, 0, SEEK_END); + *size = ftell(f); + fseek(f, 0, SEEK_SET); + + uint8_t *data = malloc(*size * sizeof(uint8_t)); + if (data == NULL) { + fclose(f); + return NULL; + } + + size_t count = fread(data, sizeof(uint8_t), *size, f); + if (count != *size) { + free(data); + fclose(f); + return NULL; + } + + fclose(f); + return data; +} + + +const char *const ipl3checksum_error_str[] = { + [Ipl3Checksum_Error_Okay] = "Okay", + [Ipl3Checksum_Error_UnalignedRead] = "UnalignedRead", + [Ipl3Checksum_Error_ByteConversion] = "ByteConversion", + [Ipl3Checksum_Error_OutOfBounds] = "OutOfBounds", + [Ipl3Checksum_Error_NullPointer] = "NullPointer", + [Ipl3Checksum_Error_BufferNotBigEnough] = "BufferNotBigEnough", + [Ipl3Checksum_Error_BufferSizeIsWrong] = "BufferSizeIsWrong", + [Ipl3Checksum_Error_UnableToDetectCIC] = "UnableToDetectCIC", +}; + +const char *get_ipl3checksum_error_str(Ipl3Checksum_Error error) { + return ipl3checksum_error_str[error.tag]; +} diff --git a/bindings/c/tests/utils.h b/bindings/c/tests/utils.h new file mode 100644 index 0000000..3fd36f7 --- /dev/null +++ b/bindings/c/tests/utils.h @@ -0,0 +1,17 @@ +/* SPDX-FileCopyrightText: © 2023 Decompollaborate */ +/* SPDX-License-Identifier: MIT */ + +#ifndef UTILS_H +#define UTILS_H +#pragma once + +#include +#include + +#include "ipl3checksum.h" + +uint8_t *read_binary_file(const char *path, size_t *size); + +const char *get_ipl3checksum_error_str(Ipl3Checksum_Error error); + +#endif