diff --git a/.gitignore b/.gitignore index 00a46fd..f088d26 100644 --- a/.gitignore +++ b/.gitignore @@ -6,6 +6,9 @@ tmp/ # Clangd .cache/ -# Us +# Copied dependencies +src/sc/ + +# Build artifacts **/build **/compile_commands.json diff --git a/CMakeLists.txt b/CMakeLists.txt index e7687ea..6c29b00 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -14,29 +14,10 @@ if(UNIX AND NOT APPLE) endif() # Common compile options + +# Hide everything by default to keep libraries smaller. add_compile_options("-fvisibility=hidden") -# Handle 3rd party dependencies -# ############################# - -set(COPY_SCRIPT ${CMAKE_CURRENT_SOURCE_DIR}/scripts/copy_dependencies.sh) - -execute_process( - COMMAND bash ${COPY_SCRIPT} - WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} - RESULT_VARIABLE SCRIPT_RESULT - OUTPUT_VARIABLE SCRIPT_OUTPUT - ERROR_VARIABLE SCRIPT_ERROR -) - -# Check if the script executed successfully -if(NOT SCRIPT_RESULT EQUAL 0) - message(WARNING "Script execution failed: ${SCRIPT_ERROR}") -else() - message(STATUS "Running script ${COPY_SCRIPT}:\n${SCRIPT_OUTPUT}") -endif() - - # hiload library # ############## @@ -45,15 +26,15 @@ add_library(hiload SHARED src/symbols.c src/files.c src/memory.c - src/logger/logger.c - src/moduler/moduler.c - src/moduler/elf.c - src/string/string.c + src/logger.c + src/moduler.c + src/hielf.c + src/histring.c src/filewatcher/filewatcher.c src/filewatcher/filewatch.c # dependencies - src/logger/sc_log.c + 3rd/sc/logger/sc_log.c ) # TODO: Get -Wpadded back by refactoring sc_array or just surround # all type sc_array declarations with the ignore pragma @@ -90,16 +71,19 @@ install(EXPORT hiloadTargets export(TARGETS hiload FILE hiloadConfig.cmake) -# auditor libraries +# Auditor libraries # ############### +# TODO: Move auditor to its own project, possibly even out of this repo. +# It has only been a side product + add_library(auditor-x86_64 SHARED - src/auditor/auditor-x86_64.c + solib-auditors/auditor-x86_64.c ) target_compile_options(auditor-x86_64 PRIVATE - $<$:-Wall -Wextra> - $<$:-Weverything> + $<$:-Wall -Wextra -Wpedantic> + $<$:-Wall -Wextra -Wpedantic> ) target_compile_options(auditor-x86_64 PRIVATE -Wno-unused-parameter) diff --git a/scripts/copy_dependencies.sh b/scripts/copy_dependencies.sh deleted file mode 100644 index c167f76..0000000 --- a/scripts/copy_dependencies.sh +++ /dev/null @@ -1,7 +0,0 @@ -#!/usr/bin/env bash - -cp --verbose "3rd/sc/array/sc_array.h" "src/array/" -cp --verbose "3rd/sc/logger/sc_log.c" "src/logger/" -cp --verbose "3rd/sc/logger/sc_log.h" "src/logger/" - -exit 0 diff --git a/src/auditor/auditor-x86_64.c b/solib-auditors/auditor-x86_64.c similarity index 100% rename from src/auditor/auditor-x86_64.c rename to solib-auditors/auditor-x86_64.c diff --git a/src/array/sc_array.h b/src/array/sc_array.h deleted file mode 100644 index cefca91..0000000 --- a/src/array/sc_array.h +++ /dev/null @@ -1,224 +0,0 @@ -/* - * BSD-3-Clause - * - * Copyright 2021 Ozan Tezcan - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. Neither the name of the copyright holder nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, - * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef SC_ARRAY_H -#define SC_ARRAY_H - -#include -#include -#include -#include -#include -#include - -#define SC_ARRAY_VERSION "2.0.0" - -#ifdef SC_HAVE_CONFIG_H -#include "config.h" -#else -#define sc_array_realloc realloc -#define sc_array_free free -#endif - -#ifndef SC_ARRAY_MAX -#define SC_ARRAY_MAX SIZE_MAX -#endif - -#define sc_array_def(T, name) \ - struct sc_array_##name { \ - bool oom; \ - size_t cap; \ - size_t size; \ - /* NOLINTNEXTLINE */ \ - T *elems; \ - } -/** - * Init array - * @param a array - */ -#define sc_array_init(a) \ - do { \ - memset((a), 0, sizeof(*(a))); \ - } while (0) - -/** - * Destroy array - * @param a array - */ -#define sc_array_term(a) \ - do { \ - sc_array_free((a)->elems); \ - sc_array_init(a); \ - } while (0) - -/** - * Add elem to array, call sc_array_oom(v) to see if 'add' failed because of out - * of memory. - * - * @param a array - * @param k elem - */ -#define sc_array_add(a, k) \ - do { \ - const size_t _max = SC_ARRAY_MAX / sizeof(*(a)->elems); \ - size_t _cap; \ - void *_p; \ - \ - if ((a)->cap == (a)->size) { \ - if ((a)->cap > _max / 2) { \ - (a)->oom = true; \ - break; \ - } \ - _cap = (a)->cap == 0 ? 8 : (a)->cap * 2; \ - _p = sc_array_realloc((a)->elems, \ - _cap * sizeof(*((a)->elems))); \ - if (_p == NULL) { \ - (a)->oom = true; \ - break; \ - } \ - (a)->cap = _cap; \ - (a)->elems = _p; \ - } \ - (a)->oom = false; \ - (a)->elems[(a)->size++] = k; \ - } while (0) - -/** - * Deletes items from the array without deallocating underlying memory - * @param a array - */ -#define sc_array_clear(a) \ - do { \ - (a)->size = 0; \ - (a)->oom = false; \ - } while (0) - -/** - * @param a array - * @return true if last add operation failed, false otherwise. - */ -#define sc_array_oom(a) ((a)->oom) - -/** - * Get element at index i, if 'i' is out of range, result is undefined. - * - * @param a array - * @param i index - * @return element at index 'i' - */ -#define sc_array_at(a, i) ((a)->elems[i]) - -/** - * @param a array - * @return element count - */ -#define sc_array_size(a) ((a)->size) - -/** - * @param a array - * @param i element index, If 'i' is out of the range, result is undefined. - */ -#define sc_array_del(a, i) \ - do { \ - size_t idx = (i); \ - assert(idx < (a)->size); \ - \ - const size_t _cnt = (a)->size - (idx) - 1; \ - if (_cnt > 0) { \ - memmove(&((a)->elems[idx]), &((a)->elems[idx + 1]), \ - _cnt * sizeof(*((a)->elems))); \ - } \ - (a)->size--; \ - } while (0) - -/** - * Deletes the element at index i, replaces last element with the deleted - * element unless deleted element is the last element. This is faster than - * moving elements but elements will no longer be in the 'add order' - * - * arr[a,b,c,d,e,f] -> sc_array_del_unordered(arr, 2) - > arr[a,b,f,d,e] - * - * @param a array - * @param i index. If 'i' is out of the range, result is undefined. - */ -#define sc_array_del_unordered(a, i) \ - do { \ - size_t idx = (i); \ - assert(idx < (a)->size); \ - (a)->elems[idx] = (a)->elems[(--(a)->size)]; \ - } while (0) - -/** - * Deletes the last element. If current size is zero, result is undefined. - * @param a array - */ -#define sc_array_del_last(a) \ - do { \ - assert((a)->size != 0); \ - (a)->size--; \ - } while (0) - -/** - * Sorts the array using qsort() - * @param a array - * @param cmp comparator, check qsort() documentation for details - */ -#define sc_array_sort(a, cmp) \ - (qsort((a)->elems, (a)->size, sizeof(*(a)->elems), cmp)) - -/** - * Returns last element. If array is empty, result is undefined. - * @param a array - */ -#define sc_array_last(a) (a)->elems[(a)->size - 1] - -/** - * @param a array - * @param elem elem - */ -#define sc_array_foreach(a, elem) \ - for (size_t _k = 1, _i = 0; _k && _i != (a)->size; _k = !_k, _i++) \ - for ((elem) = (a)->elems[_i]; _k; _k = !_k) - -// (type, name) -sc_array_def(int, int); -sc_array_def(unsigned int, uint); -sc_array_def(long, long); -sc_array_def(long long, ll); -sc_array_def(unsigned long, ulong); -sc_array_def(unsigned long long, ull); -sc_array_def(uint32_t, 32); -sc_array_def(uint64_t, 64); -sc_array_def(double, double); -sc_array_def(const char *, str); -sc_array_def(void *, ptr); - -#endif diff --git a/src/common.h b/src/common.h index e70b536..c41fac6 100644 --- a/src/common.h +++ b/src/common.h @@ -1,7 +1,7 @@ #ifndef COMMON_H_ #define COMMON_H_ -#include "logger/logger.h" +#include "logger.h" #include "types.h" static inline u32 has_mask(u32 flags, u32 mask) { return flags & mask; } diff --git a/src/files.c b/src/files.c index 21dc924..484262f 100644 --- a/src/files.c +++ b/src/files.c @@ -1,7 +1,7 @@ #include "files.h" -#include "logger/logger.h" -#include "string/string.h" +#include "logger.h" +#include "histring.h" #include "types.h" #include diff --git a/src/files.h b/src/files.h index 590e8a0..6c48099 100644 --- a/src/files.h +++ b/src/files.h @@ -1,5 +1,4 @@ -#ifndef FILES_H_ -#define FILES_H_ +#pragma once #include "types.h" @@ -38,5 +37,3 @@ HiResult file_copy(const char *filename, const char *dest); FileType file_type(const char *path); const char *file_name_from_path(const char *path); - -#endif // FILES_H_ diff --git a/src/filewatcher/filewatch.h b/src/filewatcher/filewatch.h index ff15b1c..519e3aa 100644 --- a/src/filewatcher/filewatch.h +++ b/src/filewatcher/filewatch.h @@ -1,7 +1,7 @@ #ifndef FILEWATCH_H_ #define FILEWATCH_H_ -#include "array/array.h" +#include "vector.h" #include "types.h" typedef struct FileWatcherContext FileWatcherContext; diff --git a/src/filewatcher/filewatch_context.h b/src/filewatcher/filewatch_context.h index a56eb61..954d83c 100644 --- a/src/filewatcher/filewatch_context.h +++ b/src/filewatcher/filewatch_context.h @@ -1,7 +1,7 @@ #ifndef FILEWATCH_CONTEXT_H_ #define FILEWATCH_CONTEXT_H_ -#include "array/array.h" +#include "vector.h" #include "filewatcher/filewatch.h" #include "types.h" diff --git a/src/filewatcher/filewatcher.c b/src/filewatcher/filewatcher.c index 79f5e3a..e48be24 100644 --- a/src/filewatcher/filewatcher.c +++ b/src/filewatcher/filewatcher.c @@ -1,5 +1,14 @@ #include "filewatcher.h" +#include "filewatch.h" +#include "filewatch_context.h" +#include "filewatch_type.h" + +#include "vector.h" +#include "common.h" +#include "logger.h" +#include "types.h" + #include #include #include @@ -10,15 +19,6 @@ #include #include -#include "array/array.h" -#include "array/sc_array.h" -#include "common.h" -#include "filewatch.h" -#include "filewatch_context.h" -#include "filewatch_type.h" -#include "logger/logger.h" -#include "types.h" - sc_array_def(FileEvent, fwevent); typedef struct sc_array_fwevent VectorFileEvent; diff --git a/src/filewatcher/filewatcher.h b/src/filewatcher/filewatcher.h index 59bee82..0375636 100644 --- a/src/filewatcher/filewatcher.h +++ b/src/filewatcher/filewatcher.h @@ -23,7 +23,7 @@ typedef struct { /** Path of the file this event is about. Do not free. */ const char *pathname; - /** Might not be only those given to @a file_watcher_add. */ + /** Might contain types not explicitly given to @a file_watcher_add. */ FileWatchType type; } FileEvent; diff --git a/src/moduler/elf.c b/src/hielf.c similarity index 99% rename from src/moduler/elf.c rename to src/hielf.c index 8c9cc26..95259a5 100644 --- a/src/moduler/elf.c +++ b/src/hielf.c @@ -1,6 +1,6 @@ -#include "elf.h" +#include "hielf.h" -#include "logger/logger.h" +#include "logger.h" #include "types.h" #include diff --git a/src/moduler/elf.h b/src/hielf.h similarity index 80% rename from src/moduler/elf.h rename to src/hielf.h index eb24be9..729eef3 100644 --- a/src/moduler/elf.h +++ b/src/hielf.h @@ -1,7 +1,6 @@ #ifndef ELF_H_ #define ELF_H_ -// TODO: Move these into .c file after API has found its form #include #include #include diff --git a/src/hiload.c b/src/hiload.c index 6f99f5e..fdbf1af 100644 --- a/src/hiload.c +++ b/src/hiload.c @@ -1,13 +1,13 @@ #include "hiload/hiload.h" -#include "array/array.h" +#include "vector.h" #include "common.h" #include "filewatcher/filewatch_context.h" #include "filewatcher/filewatcher.h" -#include "logger/logger.h" +#include "logger.h" #include "memory.h" -#include "moduler/moduler.h" -#include "string/string.h" +#include "moduler.h" +#include "string.h" #include "symbols.h" #include diff --git a/src/string/string.c b/src/histring.c similarity index 100% rename from src/string/string.c rename to src/histring.c diff --git a/src/string/string.h b/src/histring.h similarity index 89% rename from src/string/string.h rename to src/histring.h index 114952e..4068055 100644 --- a/src/string/string.h +++ b/src/histring.h @@ -6,10 +6,10 @@ /** * Concatenate two strings into a buffer. * - * If resulting string would be longer than @a buflen - 1, the resulting string - * in - * @a buf is unchanged. + * If resulting string would be longer than @a buflen - 1, @a buf remains unchanged. * + * @param bufsize Size of the destination buffer @a buf + * @param buf The destination buffer * @param first Null terminated character string * @param second Null terminated character string */ diff --git a/src/logger/logger.c b/src/logger.c similarity index 100% rename from src/logger/logger.c rename to src/logger.c diff --git a/src/logger/logger.h b/src/logger.h similarity index 96% rename from src/logger/logger.h rename to src/logger.h index 78baf12..786d81b 100644 --- a/src/logger/logger.h +++ b/src/logger.h @@ -1,8 +1,7 @@ #ifndef LOGGER_H_ #define LOGGER_H_ -#include "logger/sc_log.h" - +#include "../3rd/sc/logger/sc_log.h" void log_set_verbose(bool value); bool log_get_verbose(); diff --git a/src/logger/sc_log.c b/src/logger/sc_log.c deleted file mode 100644 index bd5da24..0000000 --- a/src/logger/sc_log.c +++ /dev/null @@ -1,451 +0,0 @@ -/* - * BSD-3-Clause - * - * Copyright 2021 Ozan Tezcan - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. Neither the name of the copyright holder nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, - * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef _XOPEN_SOURCE -#define _XOPEN_SOURCE 700 -#endif - -#include "sc_log.h" - -#include -#include -#include - -// clang-format off -#ifndef thread_local - #if __STDC_VERSION__ >= 201112 && !defined __STDC_NO_THREADS__ - #define thread_local _Thread_local - #elif defined _WIN32 && (defined _MSC_VER || defined __ICL || \ - defined __DMC__ || defined __BORLANDC__) - #define thread_local __declspec(thread) - #elif defined __GNUC__ || defined __SUNPRO_C || defined __xlC__ - #define thread_local __thread - #else - #error "Cannot define thread_local" - #endif -#endif - -#if __STDC_VERSION__ >= 201112 && !defined __STDC_NO_ATOMIC__ - #define SC_ATOMIC - #include - - #define sc_atomic _Atomic - #define sc_atomic_store(var, val) \ - (atomic_store_explicit(var, val, memory_order_relaxed)) - #define sc_atomic_load(var) \ - (atomic_load_explicit(var, memory_order_relaxed)) -#else - #define sc_atomic - #define sc_atomic_store(var, val) ((*(var)) = (val)) - #define sc_atomic_load(var) (*(var)) -#endif -// clang-format on - -thread_local char sc_name[32] = "Thread"; - -#if defined(_WIN32) || defined(_WIN64) - -#ifdef _MSC_VER -#pragma warning(disable : 4996) -#endif - -#define strcasecmp _stricmp -#define localtime_r(a, b) (localtime_s(b, a) == 0 ? b : NULL) -#include - -struct sc_log_mutex { - CRITICAL_SECTION mtx; -}; - -int sc_log_mutex_init(struct sc_log_mutex *mtx) -{ - InitializeCriticalSection(&mtx->mtx); - return 0; -} - -int sc_log_mutex_term(struct sc_log_mutex *mtx) -{ - DeleteCriticalSection(&mtx->mtx); - return 0; -} - -void sc_log_mutex_lock(struct sc_log_mutex *mtx) -{ - EnterCriticalSection(&mtx->mtx); -} - -void sc_log_mutex_unlock(struct sc_log_mutex *mtx) -{ - LeaveCriticalSection(&mtx->mtx); -} - -#else - -#include - -struct sc_log_mutex { - pthread_mutex_t mtx; -}; - -int sc_log_mutex_init(struct sc_log_mutex *mtx) -{ - int rc; - - pthread_mutexattr_t attr; - pthread_mutex_t mut = PTHREAD_MUTEX_INITIALIZER; - - mtx->mtx = mut; - - rc = pthread_mutexattr_init(&attr); - if (rc != 0) { - return rc; - } - - pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_NORMAL); - rc = pthread_mutex_init(&mtx->mtx, &attr); - pthread_mutexattr_destroy(&attr); - - return rc; -} - -void sc_log_mutex_term(struct sc_log_mutex *mtx) -{ - pthread_mutex_destroy(&mtx->mtx); -} - -void sc_log_mutex_lock(struct sc_log_mutex *mtx) -{ - pthread_mutex_lock(&mtx->mtx); -} - -void sc_log_mutex_unlock(struct sc_log_mutex *mtx) -{ - pthread_mutex_unlock(&mtx->mtx); -} - -#endif - -struct sc_log { - FILE *fp; - char current_file[256]; - char prev_file[256]; - size_t file_size; - - struct sc_log_mutex mtx; - sc_atomic enum sc_log_level level; - bool init; - bool to_stdout; - - void *arg; - int (*cb)(void *, enum sc_log_level, const char *, va_list); -}; - -struct sc_log sc_log; - -int sc_log_init(void) -{ - int rc; - - sc_log = (struct sc_log){0}; - - sc_atomic_store(&sc_log.level, SC_LOG_INFO); - sc_log.to_stdout = true; - - rc = sc_log_mutex_init(&sc_log.mtx); - if (rc != 0) { - errno = rc; - } - - sc_log.init = true; - - return rc; -} - -int sc_log_term(void) -{ - int rc = 0; - - if (!sc_log.init) { - return -1; - } - - if (sc_log.fp) { - rc = fclose(sc_log.fp); - if (rc != 0) { - rc = -1; - } - } - - sc_log_mutex_term(&sc_log.mtx); - sc_log = (struct sc_log){0}; - - return rc; -} - -void sc_log_set_thread_name(const char *name) -{ - strncpy(sc_name, name, sizeof(sc_name) - 1); -} - -static int sc_strcasecmp(const char *a, const char *b) -{ - int n; - - for (;; a++, b++) { - if (*a == 0 && *b == 0) { - return 0; - } - - n = tolower(*a) - tolower(*b); - if (n != 0) { - return n; - } - } -} - -int sc_log_set_level(const char *str) -{ - size_t count = sizeof(sc_log_levels) / sizeof(sc_log_levels[0]); - - for (size_t i = 0; i < count; i++) { - if (sc_strcasecmp(str, sc_log_levels[i].str) == 0) { -#ifdef SC_ATOMIC - sc_atomic_store(&sc_log.level, sc_log_levels[i].id); -#else - sc_log_mutex_lock(&sc_log.mtx); - sc_log.level = sc_log_levels[i].id; - sc_log_mutex_unlock(&sc_log.mtx); -#endif - return 0; - } - } - - return -1; -} - -void sc_log_set_stdout(bool enable) -{ - sc_log_mutex_lock(&sc_log.mtx); - sc_log.to_stdout = enable; - sc_log_mutex_unlock(&sc_log.mtx); -} - -int sc_log_set_file(const char *prev, const char *current) -{ - int rc = 0, saved_errno = 0; - long size; - FILE *fp = NULL; - - sc_log_mutex_lock(&sc_log.mtx); - - if (sc_log.fp != NULL) { - fclose(sc_log.fp); - sc_log.fp = NULL; - } - - sc_log.prev_file[0] = '\0'; - sc_log.current_file[0] = '\0'; - - if (prev == NULL || current == NULL) { - goto out; - } - - if (strlen(prev) >= sizeof(sc_log.prev_file) - 1 || - strlen(current) >= sizeof(sc_log.current_file) - 1) { - goto error; - } - - memcpy(sc_log.prev_file, prev, strlen(prev) + 1); - memcpy(sc_log.current_file, current, strlen(current) + 1); - - fp = fopen(sc_log.current_file, "a+"); - if (fp == NULL) { - goto error; - } - - if (fprintf(fp, "\n") < 0) { - goto error; - } - - size = ftell(fp); - if (size < 0) { - goto error; - } - - sc_log.file_size = (size_t) size; - sc_log.fp = fp; - - goto out; - -error: - rc = -1; - saved_errno = errno; - - if (fp != NULL) { - fclose(fp); - } -out: - sc_log_mutex_unlock(&sc_log.mtx); - errno = saved_errno; - - return rc; -} - -void sc_log_set_callback(void *arg, int (*cb)(void *, enum sc_log_level, - const char *, va_list)) -{ - sc_log_mutex_lock(&sc_log.mtx); - sc_log.arg = arg; - sc_log.cb = cb; - sc_log_mutex_unlock(&sc_log.mtx); -} - -static int sc_log_print_header(FILE *fp, enum sc_log_level level) -{ - int rc; - time_t t; - struct tm result, *tm; - - t = time(NULL); - tm = localtime_r(&t, &result); - - if (tm == NULL) { - return -1; - } - - rc = fprintf(fp, "[%d-%02d-%02d %02d:%02d:%02d][%-5s][%s] ", - tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday, - tm->tm_hour, tm->tm_min, tm->tm_sec, - sc_log_levels[level].str, sc_name); - if (rc < 0) { - return -1; - } - - return 0; -} - -static int sc_log_stdout(enum sc_log_level level, const char *fmt, va_list va) -{ - int rc; - FILE *dest = level == SC_LOG_ERROR ? stderr : stdout; - - rc = sc_log_print_header(dest, level); - if (rc < 0) { - return -1; - } - - rc = vfprintf(dest, fmt, va); - if (rc < 0) { - return -1; - } - - return 0; -} - -static int sc_log_file(enum sc_log_level level, const char *fmt, va_list va) -{ - int rc, size; - - rc = sc_log_print_header(sc_log.fp, level); - if (rc < 0) { - return -1; - } - - size = vfprintf(sc_log.fp, fmt, va); - if (size < 0) { - return -1; - } - - sc_log.file_size += size; - - if (sc_log.file_size > (size_t) SC_LOG_FILE_SIZE) { - fclose(sc_log.fp); - (void) rename(sc_log.current_file, sc_log.prev_file); - - sc_log.fp = fopen(sc_log.current_file, "w+"); - if (sc_log.fp == NULL) { - return -1; - } - - sc_log.file_size = 0; - } - - return rc; -} - -int sc_log_log(enum sc_log_level level, const char *fmt, ...) -{ - int rc = 0; - va_list va; - - // Use relaxed atomics to avoid locking cost, e.g., DEBUG logs when - // level=INFO will get away without any synchronization on most - // platforms. -#ifdef SC_ATOMIC - enum sc_log_level curr; - - curr = sc_atomic_load(&sc_log.level); - if (level < curr) { - return 0; - } -#endif - - sc_log_mutex_lock(&sc_log.mtx); - -#ifndef SC_ATOMIC - if (level < sc_log.level) { - sc_log_mutex_unlock(&sc_log.mtx); - return 0; - } -#endif - - if (sc_log.to_stdout) { - va_start(va, fmt); - rc |= sc_log_stdout(level, fmt, va); - va_end(va); - } - - if (sc_log.fp != NULL) { - va_start(va, fmt); - rc |= sc_log_file(level, fmt, va); - va_end(va); - } - - if (sc_log.cb) { - va_start(va, fmt); - rc |= sc_log.cb(sc_log.arg, level, fmt, va); - va_end(va); - } - - sc_log_mutex_unlock(&sc_log.mtx); - - return rc; -} diff --git a/src/logger/sc_log.h b/src/logger/sc_log.h deleted file mode 100644 index ec59cb0..0000000 --- a/src/logger/sc_log.h +++ /dev/null @@ -1,146 +0,0 @@ -/* - * BSD-3-Clause - * - * Copyright 2021 Ozan Tezcan - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. Neither the name of the copyright holder nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, - * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef SC_LOG_H -#define SC_LOG_H - -#include -#include -#include -#include -#include - -#define SC_LOG_VERSION "2.0.0" - -enum sc_log_level -{ - SC_LOG_DEBUG, - SC_LOG_INFO, - SC_LOG_WARN, - SC_LOG_ERROR, - SC_LOG_OFF, -}; - -// clang-format off -static const struct sc_log_level_pair -{ - const enum sc_log_level id; - const char *str; -} sc_log_levels[] = { - {SC_LOG_DEBUG, "DEBUG"}, - {SC_LOG_INFO, "INFO" }, - {SC_LOG_WARN, "WARN" }, - {SC_LOG_ERROR, "ERROR"}, - {SC_LOG_OFF, "OFF" }, -}; -// clang-format on - -// Internal function -int sc_log_log(enum sc_log_level level, const char *fmt, ...); - -// Max file size to rotate, should not be more than 4 GB. -#define SC_LOG_FILE_SIZE (2 * 1024 * 1024) - -// Define SC_LOG_PRINT_FILE_NAME to print file name and line no in the log line. -#ifdef SC_LOG_PRINT_FILE_NAME -#define sc_log_ap(fmt, ...) \ - "(%s:%d) " fmt, strrchr("/" __FILE__, '/') + 1, __LINE__, __VA_ARGS__ -#else -#define sc_log_ap(fmt, ...) fmt, __VA_ARGS__ -#endif - -/** - * sc_log_init() call once in your application before using log functions. - * sc_log_term() call once to clean up, you must not use logger after this call. - * These functions are not thread-safe, should be called from a single thread. - * - * @return '0' on success, negative value on error, errno will be set. - */ -int sc_log_init(void); -int sc_log_term(void); - -/** - * Set thread name. - * - * Call once from each thread if you want to set thread name. - * @param name Thread name - */ -void sc_log_set_thread_name(const char *name); - -/** - * Set log level. - * - * @param level One of "DEBUG", "INFO", "WARN", "ERROR", "OFF" - * @return '0' on success, negative value on invalid level string - */ -int sc_log_set_level(const char *level); - -/** - * Enable stdout logging. - * - * @param enable 'true' to enable, 'false' to disable logging to stdout. - */ -void sc_log_set_stdout(bool enable); - -/** - * Enable file logging. - * - * Log files will be rotated to prevent generating very big files. Once current - * log file reaches 'SC_LOG_FILE_SIZE' (see definition above), it will be - * renamed as `prev` and the latest logs will always be in the 'current' file. - * - * e.g., sc_log_set_file("/tmp/log.0.txt", "/tmp/log-latest.txt"); - * - * To disable logging into file: sc_log_set_file(NULL, NULL); - * - * @param prev file path for previous log file, 'NULL' to disable - * @param current file path for latest log file, 'NULL' to disable - * @return 0 on success, -1 on error, errno will be set. - */ -int sc_log_set_file(const char *prev, const char *current); - -/** - * Enabled logging to callback. - * - * @param arg user arg to callback. - * @param cb log callback. - */ -void sc_log_set_callback(void *arg, - int (*cb)(void *arg, enum sc_log_level level, - const char *fmt, va_list va)); - -// e.g., sc_log_error("Errno: %d, reason: %s", errno, strerror(errno)); -#define sc_log_debug(...) (sc_log_log(SC_LOG_DEBUG, sc_log_ap(__VA_ARGS__, ""))) -#define sc_log_info(...) (sc_log_log(SC_LOG_INFO, sc_log_ap(__VA_ARGS__, ""))) -#define sc_log_warn(...) (sc_log_log(SC_LOG_WARN, sc_log_ap(__VA_ARGS__, ""))) -#define sc_log_error(...) (sc_log_log(SC_LOG_ERROR, sc_log_ap(__VA_ARGS__, ""))) - -#endif diff --git a/src/memory.c b/src/memory.c index 0b20310..6cdc12d 100644 --- a/src/memory.c +++ b/src/memory.c @@ -1,8 +1,7 @@ #include "memory.h" -#include "array/sc_array.h" #include "files.h" -#include "logger/logger.h" +#include "logger.h" #include "types.h" static inline int ptr_in_range(uptr ptr, uptr start, uptr end) { diff --git a/src/memory.h b/src/memory.h index 18af806..382bb2e 100644 --- a/src/memory.h +++ b/src/memory.h @@ -1,7 +1,6 @@ -#ifndef MEMORY_H_ -#define MEMORY_H_ +#pragma once -#include "array/array.h" +#include "vector.h" #include "types.h" #include @@ -48,5 +47,3 @@ HiResult memory_find_pointer(uptr ptr, MemoryRegionSpan memory_get_module_span(const VectorMemoryRegion *const regions, const char module_name[static 1]); - -#endif // MEMORY_H_ diff --git a/src/moduler/moduler.c b/src/moduler.c similarity index 94% rename from src/moduler/moduler.c rename to src/moduler.c index 5777c05..1a1b144 100644 --- a/src/moduler/moduler.c +++ b/src/moduler.c @@ -2,10 +2,10 @@ #include "common.h" #include "files.h" -#include "logger/logger.h" +#include "hielf.h" +#include "histring.h" +#include "logger.h" #include "memory.h" -#include "moduler/elf.h" -#include "string/string.h" #include "symbols.h" #include "types.h" @@ -34,8 +34,8 @@ static void *adjust_if_relative(void *ptr, void *module_base) { } static HiResult gather_patchable_symbols(struct sc_array_sym *symbols, - const char *module_name, - void *module_base) { + const char *module_name, + void *module_base) { sc_array_clear(symbols); HiResult ret = HI_FAIL; @@ -135,7 +135,8 @@ static HiResult gather_patchable_symbols(struct sc_array_sym *symbols, } void *sym_addr = (void *)((uintptr_t)module_base + sym.st_value); - SymbolBind binding = symbol_bind_from_efibind(GELF_ST_BIND(sym.st_info)); + SymbolBind binding = + symbol_bind_from_efibind(GELF_ST_BIND(sym.st_info)); SymbolType type = symbol_type_from_efitype(GELF_ST_TYPE(sym.st_info)); size_t size = sym.st_size; @@ -146,10 +147,10 @@ static HiResult gather_patchable_symbols(struct sc_array_sym *symbols, (binding == HI_SYMBOL_BIND_LOCAL && type == HI_SYMBOL_TYPE_OBJECT)) { Symbol hisym = {.name = strdup(name), - .size = size, - .binding = binding, - .type = type, - .address = sym_addr}; + .size = size, + .binding = binding, + .type = type, + .address = sym_addr}; sc_array_add(symbols, hisym); } @@ -167,7 +168,7 @@ cleanup: } static HiResult moduler_apply_module_patch(VectorSymbol *psymbols, - MemoryRegionSpan module_memory) { + MemoryRegionSpan module_memory) { void *module_base = (void *)module_memory.region_start; size_t module_size = module_memory.region_end - module_memory.region_start; @@ -273,7 +274,8 @@ PatchData moduler_create_patch(ModuleData *module) { } char file_append[32]; - if (strftime(file_append, sizeof(file_append), ".%Y%m%d%H%M%S.patch", t) == 0) { + if (strftime(file_append, sizeof(file_append), ".%Y%m%d%H%M%S.patch", t) == + 0) { log_error("Failed to create patch filename.\n"); return (PatchData){0}; } @@ -282,7 +284,6 @@ PatchData moduler_create_patch(ModuleData *module) { size_t written = hi_str_concat_buf(sizeof(filename), filename, module->name, file_append); - if (written == 0) { log_error("Failed to concat %s and %s\n", module->name, ".patch"); return (PatchData){0}; @@ -295,7 +296,7 @@ PatchData moduler_create_patch(ModuleData *module) { } HiResult moduler_reload(VectorModuleData *modules, ModuleData *module, - struct sc_array_memreg *memregs) { + struct sc_array_memreg *memregs) { // Return OK because this isn't an error case. We just don't do it yet // because we only handle reloading a complete solib. Can't do that with @@ -383,7 +384,7 @@ HiResult moduler_reload(VectorModuleData *modules, ModuleData *module, module->info = hi_modinfo_clear(module->info, HI_MODULE_STATE_DIRTY); } - free((char*)patch.filename); + free((char *)patch.filename); symbol_term_symbols(&patch_symbols); dlclose(module->dlhandle); diff --git a/src/moduler/moduler.h b/src/moduler.h similarity index 97% rename from src/moduler/moduler.h rename to src/moduler.h index dbe2f16..caf837a 100644 --- a/src/moduler/moduler.h +++ b/src/moduler.h @@ -1,7 +1,7 @@ #ifndef MODULER_H_ #define MODULER_H_ -#include "array/array.h" +#include "vector.h" #include "memory.h" #include "symbols.h" #include "types.h" diff --git a/src/symbols.c b/src/symbols.c index c709a4d..cb5bd9b 100644 --- a/src/symbols.c +++ b/src/symbols.c @@ -1,5 +1,6 @@ #include "symbols.h" -#include "array/sc_array.h" + +#include "vector.h" #include #include diff --git a/src/symbols.h b/src/symbols.h index e71fd54..f70ea9f 100644 --- a/src/symbols.h +++ b/src/symbols.h @@ -1,8 +1,6 @@ -#ifndef SYMBOLS_H_ -#define SYMBOLS_H_ +#pragma once -#include "array/array.h" -#include "array/sc_array.h" +#include "vector.h" #include "types.h" typedef enum { @@ -21,7 +19,8 @@ typedef enum { HI_SYMBOL_TYPE_TLS, } SymbolType; -typedef struct Symbol { +typedef struct Symbol Symbol; +struct Symbol { const char *name; SymbolBind binding; SymbolType type; @@ -29,7 +28,7 @@ typedef struct Symbol { void *address; void **got_entry; void *orig_address; -} Symbol; +}; sc_array_def(Symbol, sym); typedef struct sc_array_sym VectorSymbol; @@ -56,4 +55,3 @@ Symbol *symbol_find(VectorSymbol *symbols, Symbol *symbol); SymbolBind symbol_bind_from_efibind(u32 efi_bind); SymbolType symbol_type_from_efitype(u32 efi_type); -#endif // SYMBOLS_H_ diff --git a/src/array/array.h b/src/vector.h similarity index 71% rename from src/array/array.h rename to src/vector.h index e40d0ab..70c1b17 100644 --- a/src/array/array.h +++ b/src/vector.h @@ -1,12 +1,9 @@ -#ifndef ARRAY_H_ -#define ARRAY_H_ +#pragma once -#include "array/sc_array.h" +#include "../3rd/sc/array/sc_array.h" typedef struct sc_array_32 VectorU32; typedef struct sc_array_64 VectorU64; typedef struct sc_array_double VectorDouble; typedef struct sc_array_str VectorStr; typedef struct sc_array_ptr VectorPtr; - -#endif // ARRAY_H_