1
0
Fork 0
mirror of https://github.com/tailix/libkernaux.git synced 2025-02-24 15:55:41 -05:00

Rewrite guards

This commit is contained in:
Alex Kotov 2021-12-20 07:22:43 +05:00
parent f49849a501
commit 18a6da53f6
Signed by: kotovalexarian
GPG key ID: 553C0EBBEB5D5F08
8 changed files with 56 additions and 34 deletions

View file

@ -14,7 +14,7 @@ jobs:
cc: ['gcc', 'clang', 'tcc'] cc: ['gcc', 'clang', 'tcc']
opt: ['', '-O0', '-O3'] opt: ['', '-O0', '-O3']
assert: ['--enable-assert', '--disable-assert'] assert: ['--enable-assert', '--disable-assert']
null_guard: ['--enable-null-guard', '--disable-null-guard'] guard: ['--enable-guard', '--disable-guard']
werror: werror:
- cflag: '-Werror' - cflag: '-Werror'
mb2: '--without-multiboot2' mb2: '--without-multiboot2'
@ -27,7 +27,7 @@ jobs:
- name: autogen - name: autogen
run: ./autogen.sh run: ./autogen.sh
- name: configure - name: configure
run: ./configure ${{matrix.assert}} ${{matrix.null_guard}} ${{matrix.werror.mb2}} CC='${{matrix.cc}}' CFLAGS='${{matrix.opt}} ${{matrix.werror.cflag}}' run: ./configure ${{matrix.assert}} ${{matrix.guard}} ${{matrix.werror.mb2}} CC='${{matrix.cc}}' CFLAGS='${{matrix.opt}} ${{matrix.werror.cflag}}'
- name: make - name: make
run: make run: make
- name: check - name: check

2
.gitignore vendored
View file

@ -34,7 +34,7 @@
/tests/test*.log /tests/test*.log
/tests/test*.trs /tests/test*.trs
/examples/assert_return /examples/assert_guards
/examples/assert_simple /examples/assert_simple
/examples/cmdline /examples/cmdline
/examples/pfa /examples/pfa

View file

@ -10,7 +10,7 @@ AM_CFLAGS = \
lib_LIBRARIES = libkernaux.a lib_LIBRARIES = libkernaux.a
TESTS = \ TESTS = \
examples/assert_return \ examples/assert_guards \
examples/assert_simple \ examples/assert_simple \
examples/printf \ examples/printf \
examples/printf_va \ examples/printf_va \
@ -78,9 +78,9 @@ TESTS += \
tests/test_units_human tests/test_units_human
endif endif
examples_assert_return_SOURCES = \ examples_assert_guards_SOURCES = \
$(libkernaux_a_SOURCES) \ $(libkernaux_a_SOURCES) \
examples/assert_return.c examples/assert_guards.c
examples_assert_simple_SOURCES = \ examples_assert_simple_SOURCES = \
$(libkernaux_a_SOURCES) \ $(libkernaux_a_SOURCES) \

View file

@ -32,7 +32,7 @@ API
* Runtime environment * Runtime environment
* [Assertions](/include/kernaux/assert.h) * [Assertions](/include/kernaux/assert.h)
* [Simple](/examples/assert_simple.c) * [Simple](/examples/assert_simple.c)
* [With return](/examples/assert_return.c) * [Guards](/examples/assert_guards.c)
* [Architecture-specific helpers](/include/kernaux/arch/) * [Architecture-specific helpers](/include/kernaux/arch/)
* Device drivers (for debugging only) * Device drivers (for debugging only)
* [Serial console](/include/kernaux/console.h) * [Serial console](/include/kernaux/console.h)
@ -72,14 +72,16 @@ are some non-default options:
* `--enable-assert` - use value of extern variable `kernaux_assert_cb` as a * `--enable-assert` - use value of extern variable `kernaux_assert_cb` as a
callback function for internal assertions. You still can use assertions in callback function for internal assertions. You still can use assertions in
your own application (kernel) even if this option was not enabled. your own application (kernel) even if this option was not enabled.
* `--enable-null-guard` - safely return from functions which require non-null * `--enable-guard` - safely return from functions even when assertions are
pointers as arguments. NULL-guard works with assertions, so this option disabled. This option doesn't have effect if your assetion function was set
doesn't have effect if your assetion function was set and ends execution of and ends execution of application (kernel). However it prevents crashes and
application (kernel). However it prevents crashes because of NULL pointer undefined behabior in other cases. You can also separately enable or disable
dereference in other cases. guards:
* `--(enable|disable)-guard-cond`
* `--(enable|disable)-guard-null`
* `--with-libc` - provides the replacement for some standard C functions. Useful * `--with-libc` - provides the replacement for some standard C functions. Useful
in freestanding environment, where no libc is present. You can also separately in freestanding environment, where no libc is present. You can also separately
enable or disable components: include or exclude components:
* `--with[out]-libc-memset` * `--with[out]-libc-memset`
* `--with[out]-libc-strcpy` * `--with[out]-libc-strcpy`
* `--with[out]-libc-strlen` * `--with[out]-libc-strlen`
@ -100,7 +102,7 @@ environment.
``` ```
./autogen.sh ./autogen.sh
./configure --enable-assert --enable-null-guard ./configure --enable-assert --enable-guard
make make
``` ```

View file

@ -14,7 +14,9 @@ AC_CANONICAL_HOST
dnl Features (disabled by default) dnl Features (disabled by default)
AC_ARG_ENABLE([assert], AS_HELP_STRING([--enable-assert], [enable runtime assertions])) AC_ARG_ENABLE([assert], AS_HELP_STRING([--enable-assert], [enable runtime assertions]))
AC_ARG_ENABLE([null-guard], AS_HELP_STRING([--enable-null-guard], [enable NULL-guard])) AC_ARG_ENABLE([guard], AS_HELP_STRING([--enable-guard], [enable argument guards]))
AC_ARG_ENABLE([guard-cond], AS_HELP_STRING([--enable-guard-cond], [enable condition guard]))
AC_ARG_ENABLE([guard-null], AS_HELP_STRING([--enable-guard-null], [enable NULL-guard]))
dnl Packages (enabled by default) dnl Packages (enabled by default)
AC_ARG_WITH( [cmdline], AS_HELP_STRING([--without-cmdline], [without command line parser])) AC_ARG_WITH( [cmdline], AS_HELP_STRING([--without-cmdline], [without command line parser]))
@ -32,6 +34,13 @@ AC_ARG_WITH( [libc-strlen], AS_HELP_STRING([--with-libc-strlen], [with strlen
AC_DEFUN([do_enable_guard],
[
if test -z "$enable_guard_cond"; then enable_guard_cond=yes; fi
if test -z "$enable_guard_null"; then enable_guard_null=yes; fi
])
AS_IF([test "$enable_guard" = yes], do_enable_guard)
AC_DEFUN([do_with_libc], AC_DEFUN([do_with_libc],
[ [
if test -z "$with_libc_memset"; then with_libc_memset=yes; fi if test -z "$with_libc_memset"; then with_libc_memset=yes; fi
@ -48,7 +57,8 @@ AM_CONDITIONAL([ARCH_X86_64], [test "$host_cpu" = x86_64])
dnl Features (disabled by default) dnl Features (disabled by default)
AM_CONDITIONAL([ENABLE_ASSERT], [test "$enable_assert" = yes]) AM_CONDITIONAL([ENABLE_ASSERT], [test "$enable_assert" = yes])
AM_CONDITIONAL([ENABLE_NULL_GUARD], [test "$enable_null_guard" = yes]) AM_CONDITIONAL([ENABLE_GUARD_COND], [test "$enable_guard_cond" = yes])
AM_CONDITIONAL([ENABLE_GUARD_NULL], [test "$enable_guard_null" = yes])
dnl Packages (enabled by default) dnl Packages (enabled by default)
AM_CONDITIONAL([WITH_CMDLINE], [test "$with_cmdline" != no]) AM_CONDITIONAL([WITH_CMDLINE], [test "$with_cmdline" != no])
@ -59,7 +69,6 @@ AM_CONDITIONAL([WITH_PFA], [test "$with_pfa" != no])
AM_CONDITIONAL([WITH_UNITS], [test "$with_units" != no]) AM_CONDITIONAL([WITH_UNITS], [test "$with_units" != no])
dnl Packages (disabled by default) dnl Packages (disabled by default)
AM_CONDITIONAL([WITH_LIBC], [test "$with_libc" = yes])
AM_CONDITIONAL([WITH_LIBC_MEMSET], [test "$with_libc_memset" = yes]) AM_CONDITIONAL([WITH_LIBC_MEMSET], [test "$with_libc_memset" = yes])
AM_CONDITIONAL([WITH_LIBC_STRCPY], [test "$with_libc_strcpy" = yes]) AM_CONDITIONAL([WITH_LIBC_STRCPY], [test "$with_libc_strcpy" = yes])
AM_CONDITIONAL([WITH_LIBC_STRLEN], [test "$with_libc_strlen" = yes]) AM_CONDITIONAL([WITH_LIBC_STRLEN], [test "$with_libc_strlen" = yes])
@ -72,7 +81,8 @@ AS_IF([test "$host_cpu" = x86_64], [AC_DEFINE([ARCH_X86_64],
dnl Features (disabled by default) dnl Features (disabled by default)
AS_IF([test "$enable_assert" = yes], [AC_DEFINE([KERNAUX_ENABLE_ASSERT], [1], [enabled runtime assertions])]) AS_IF([test "$enable_assert" = yes], [AC_DEFINE([KERNAUX_ENABLE_ASSERT], [1], [enabled runtime assertions])])
AS_IF([test "$enable_null_guard" = yes], [AC_DEFINE([KERNAUX_ENABLE_NULL_GUARD], [1], [enabled NULL-guard])]) AS_IF([test "$enable_guard_cond" = yes], [AC_DEFINE([KERNAUX_ENABLE_GUARD_COND], [1], [enabled condition guard])])
AS_IF([test "$enable_guard_null" = yes], [AC_DEFINE([KERNAUX_ENABLE_GUARD_NULL], [1], [enabled NULL-guard])])
dnl Packages (enabled by default) dnl Packages (enabled by default)
AS_IF([test "$with_cmdline" != no], [AC_DEFINE([WITH_CMDLINE], [1], [with command line parser])]) AS_IF([test "$with_cmdline" != no], [AC_DEFINE([WITH_CMDLINE], [1], [with command line parser])])
@ -83,7 +93,6 @@ AS_IF([test "$with_pfa" != no], [AC_DEFINE([WITH_PFA],
AS_IF([test "$with_units", != no], [AC_DEFINE([WITH_UNITS], [1], [with measurement units utils])]) AS_IF([test "$with_units", != no], [AC_DEFINE([WITH_UNITS], [1], [with measurement units utils])])
dnl Packages (disabled by default) dnl Packages (disabled by default)
AS_IF([test "$with_libc" = yes], [AC_DEFINE([WITH_LIBC], [1], [with libc replacement])])
AS_IF([test "$with_libc_memset" = yes], [AC_DEFINE([WITH_LIBC_MEMSET], [1], [with memset replacement])]) AS_IF([test "$with_libc_memset" = yes], [AC_DEFINE([WITH_LIBC_MEMSET], [1], [with memset replacement])])
AS_IF([test "$with_libc_strcpy" = yes], [AC_DEFINE([WITH_LIBC_STRCPY], [1], [with strcpy replacement])]) AS_IF([test "$with_libc_strcpy" = yes], [AC_DEFINE([WITH_LIBC_STRCPY], [1], [with strcpy replacement])])
AS_IF([test "$with_libc_strlen" = yes], [AC_DEFINE([WITH_LIBC_STRLEN], [1], [with strlen replacement])]) AS_IF([test "$with_libc_strlen" = yes], [AC_DEFINE([WITH_LIBC_STRLEN], [1], [with strlen replacement])])

View file

@ -1,5 +1,5 @@
#define KERNAUX_ENABLE_ASSERT #define KERNAUX_ENABLE_ASSERT
#define KERNAUX_ENABLE_NULL_GUARD #define KERNAUX_ENABLE_GUARD
#include <kernaux/assert.h> #include <kernaux/assert.h>
#include <assert.h> #include <assert.h>

View file

@ -12,14 +12,17 @@ extern "C" {
#define KERNAUX_ASSERT(cond) ((void)sizeof((cond))) #define KERNAUX_ASSERT(cond) ((void)sizeof((cond)))
#endif #endif
#define KERNAUX_ASSERT_RETURN(cond) \ #if defined(KERNAUX_ENABLE_GUARD) || defined(KERNAUX_ENABLE_GUARD_COND)
{ KERNAUX_ASSERT(cond); if (!(cond)) return; } #define KERNAUX_ASSERT_RETURN(cond) { KERNAUX_ASSERT(cond); if (!(cond)) return; }
#define KERNAUX_ASSERT_RETVAL(cond, val) \ #define KERNAUX_ASSERT_RETVAL(cond, val) { KERNAUX_ASSERT(cond); if (!(cond)) return (val); }
{ KERNAUX_ASSERT(cond); if (!(cond)) return (val); } #else
#define KERNAUX_ASSERT_RETURN(cond) { KERNAUX_ASSERT(cond); }
#define KERNAUX_ASSERT_RETVAL(cond, val) { KERNAUX_ASSERT(cond); }
#endif
#ifdef KERNAUX_ENABLE_NULL_GUARD #if defined(KERNAUX_ENABLE_GUARD) || defined(KERNAUX_ENABLE_GUARD_NULL)
#define KERNAUX_NOTNULL_RETURN(cond) { KERNAUX_ASSERT_RETURN(cond); } #define KERNAUX_NOTNULL_RETURN(cond) { KERNAUX_ASSERT(cond); if (!(cond)) return; }
#define KERNAUX_NOTNULL_RETVAL(cond, val) { KERNAUX_ASSERT_RETVAL(cond, val); } #define KERNAUX_NOTNULL_RETVAL(cond, val) { KERNAUX_ASSERT(cond); if (!(cond)) return (val); }
#else #else
#define KERNAUX_NOTNULL_RETURN(cond) { KERNAUX_ASSERT(cond); } #define KERNAUX_NOTNULL_RETURN(cond) { KERNAUX_ASSERT(cond); }
#define KERNAUX_NOTNULL_RETVAL(cond, val) { KERNAUX_ASSERT(cond); } #define KERNAUX_NOTNULL_RETVAL(cond, val) { KERNAUX_ASSERT(cond); }

View file

@ -30,7 +30,7 @@ int main()
kernaux_assert_cb = NULL; kernaux_assert_cb = NULL;
test(); test();
#if defined(KERNAUX_ENABLE_ASSERT) || defined(KERNAUX_ENABLE_NULL_GUARD) #if defined(KERNAUX_ENABLE_ASSERT) || defined(KERNAUX_ENABLE_GUARD_COND) || defined(KERNAUX_ENABLE_GUARD_NULL)
#ifdef KERNAUX_ENABLE_ASSERT #ifdef KERNAUX_ENABLE_ASSERT
kernaux_assert_cb = assert_cb; kernaux_assert_cb = assert_cb;
#endif #endif
@ -46,45 +46,53 @@ void test()
struct KernAux_PFA pfa; struct KernAux_PFA pfa;
KernAux_PFA_initialize(&pfa); KernAux_PFA_initialize(&pfa);
#ifdef KERNAUX_ENABLE_NULL_GUARD #ifdef KERNAUX_ENABLE_GUARD_NULL
KernAux_PFA_initialize(NULL); KernAux_PFA_initialize(NULL);
if (kernaux_assert_cb) assert(count == ++acc); if (kernaux_assert_cb) assert(count == ++acc);
#endif #endif
#ifdef KERNAUX_ENABLE_NULL_GUARD #ifdef KERNAUX_ENABLE_GUARD_NULL
assert(!KernAux_PFA_is_available(NULL, KERNAUX_PFA_PAGE_SIZE)); assert(!KernAux_PFA_is_available(NULL, KERNAUX_PFA_PAGE_SIZE));
if (kernaux_assert_cb) assert(count == ++acc); if (kernaux_assert_cb) assert(count == ++acc);
#endif #endif
#ifdef KERNAUX_ENABLE_GUARD_COND
assert(!KernAux_PFA_is_available(&pfa, 123)); assert(!KernAux_PFA_is_available(&pfa, 123));
if (kernaux_assert_cb) assert(count == ++acc); if (kernaux_assert_cb) assert(count == ++acc);
#endif
#ifdef KERNAUX_ENABLE_NULL_GUARD #ifdef KERNAUX_ENABLE_GUARD_NULL
KernAux_PFA_mark_available(NULL, 0, KERNAUX_PFA_PAGE_SIZE); KernAux_PFA_mark_available(NULL, 0, KERNAUX_PFA_PAGE_SIZE);
if (kernaux_assert_cb) assert(count == ++acc); if (kernaux_assert_cb) assert(count == ++acc);
#endif #endif
#ifdef KERNAUX_ENABLE_GUARD_COND
KernAux_PFA_mark_available(&pfa, KERNAUX_PFA_PAGE_SIZE, 0); KernAux_PFA_mark_available(&pfa, KERNAUX_PFA_PAGE_SIZE, 0);
if (kernaux_assert_cb) assert(count == ++acc); if (kernaux_assert_cb) assert(count == ++acc);
#endif
#ifdef KERNAUX_ENABLE_NULL_GUARD #ifdef KERNAUX_ENABLE_GUARD_NULL
KernAux_PFA_mark_unavailable(NULL, 0, KERNAUX_PFA_PAGE_SIZE); KernAux_PFA_mark_unavailable(NULL, 0, KERNAUX_PFA_PAGE_SIZE);
if (kernaux_assert_cb) assert(count == ++acc); if (kernaux_assert_cb) assert(count == ++acc);
#endif #endif
#ifdef KERNAUX_ENABLE_GUARD_COND
KernAux_PFA_mark_unavailable(&pfa, KERNAUX_PFA_PAGE_SIZE, 0); KernAux_PFA_mark_unavailable(&pfa, KERNAUX_PFA_PAGE_SIZE, 0);
if (kernaux_assert_cb) assert(count == ++acc); if (kernaux_assert_cb) assert(count == ++acc);
#endif
#ifdef KERNAUX_ENABLE_NULL_GUARD #ifdef KERNAUX_ENABLE_GUARD_NULL
assert(KernAux_PFA_alloc_pages(NULL, KERNAUX_PFA_PAGE_SIZE) == 0); assert(KernAux_PFA_alloc_pages(NULL, KERNAUX_PFA_PAGE_SIZE) == 0);
if (kernaux_assert_cb) assert(count == ++acc); if (kernaux_assert_cb) assert(count == ++acc);
#endif #endif
#ifdef KERNAUX_ENABLE_NULL_GUARD #ifdef KERNAUX_ENABLE_GUARD_NULL
KernAux_PFA_free_pages(NULL, KERNAUX_PFA_PAGE_SIZE, KERNAUX_PFA_PAGE_SIZE); KernAux_PFA_free_pages(NULL, KERNAUX_PFA_PAGE_SIZE, KERNAUX_PFA_PAGE_SIZE);
if (kernaux_assert_cb) assert(count == ++acc); if (kernaux_assert_cb) assert(count == ++acc);
#endif #endif
#ifdef KERNAUX_ENABLE_GUARD_COND
KernAux_PFA_free_pages(&pfa, 123, KERNAUX_PFA_PAGE_SIZE); KernAux_PFA_free_pages(&pfa, 123, KERNAUX_PFA_PAGE_SIZE);
if (kernaux_assert_cb) assert(count == ++acc); if (kernaux_assert_cb) assert(count == ++acc);
#endif
} }