mirror of
https://gitlab.nic.cz/labs/bird.git
synced 2025-01-18 06:51:54 +00:00
Enforcing certain data structure explicit paddings.
Implicit paddings have undefined values in C. We want the eattr blocks to be comparable by memcmp and eattrs settable directly by structrure literals. This check ensures that all paddings in eattr and bval are explicit and therefore zeroed in all literals.
This commit is contained in:
parent
c1194ab7ed
commit
1d309c4ce6
26
aclocal.m4
vendored
26
aclocal.m4
vendored
@ -1,6 +1,32 @@
|
|||||||
dnl ** Additional Autoconf tests for BIRD configure script
|
dnl ** Additional Autoconf tests for BIRD configure script
|
||||||
dnl ** (c) 1999 Martin Mares <mj@ucw.cz>
|
dnl ** (c) 1999 Martin Mares <mj@ucw.cz>
|
||||||
|
|
||||||
|
AC_DEFUN([BIRD_CHECK_POINTER_ALIGNMENT],
|
||||||
|
[
|
||||||
|
AC_CACHE_CHECK(
|
||||||
|
[how pointers are aligned],
|
||||||
|
[bird_cv_pointer_alignment],
|
||||||
|
AC_COMPILE_IFELSE([
|
||||||
|
AC_LANG_PROGRAM(
|
||||||
|
[
|
||||||
|
_Static_assert(_Alignof(void *) == 8, "bad");
|
||||||
|
], []
|
||||||
|
)
|
||||||
|
],
|
||||||
|
[bird_cv_pointer_alignment=8],
|
||||||
|
AC_COMPILE_IFELSE([
|
||||||
|
AC_LANG_PROGRAM(
|
||||||
|
[
|
||||||
|
_Static_assert(_Alignof(void *) == 4, "bad");
|
||||||
|
], []
|
||||||
|
)
|
||||||
|
],
|
||||||
|
[bird_cv_pointer_alignment=4],
|
||||||
|
[bird_cv_pointer_alignment=unknown]
|
||||||
|
))
|
||||||
|
)
|
||||||
|
])
|
||||||
|
|
||||||
AC_DEFUN([BIRD_CHECK_THREAD_LOCAL],
|
AC_DEFUN([BIRD_CHECK_THREAD_LOCAL],
|
||||||
[
|
[
|
||||||
AC_CACHE_CHECK(
|
AC_CACHE_CHECK(
|
||||||
|
@ -360,6 +360,13 @@ AC_C_BIGENDIAN(
|
|||||||
[AC_MSG_ERROR([Cannot determine CPU endianity.])]
|
[AC_MSG_ERROR([Cannot determine CPU endianity.])]
|
||||||
)
|
)
|
||||||
|
|
||||||
|
BIRD_CHECK_POINTER_ALIGNMENT
|
||||||
|
if test "$bird_cv_pointer_alignment" = "unknown" ; then
|
||||||
|
AC_MSG_ERROR([Couldn't determine pointer alignment])
|
||||||
|
else
|
||||||
|
AC_DEFINE_UNQUOTED([CPU_POINTER_ALIGNMENT], [$bird_cv_pointer_alignment], [Pointer alignment for macro usage])
|
||||||
|
fi
|
||||||
|
|
||||||
BIRD_CHECK_ANDROID_GLOB
|
BIRD_CHECK_ANDROID_GLOB
|
||||||
if test "$bird_cv_lib_glob" = no ; then
|
if test "$bird_cv_lib_glob" = no ; then
|
||||||
AC_MSG_ERROR([glob.h not found.])
|
AC_MSG_ERROR([glob.h not found.])
|
||||||
|
@ -2,6 +2,6 @@ src := a-path.c a-set.c bitmap.c bitops.c blake2s.c blake2b.c checksum.c event.c
|
|||||||
obj := $(src-o-files)
|
obj := $(src-o-files)
|
||||||
$(all-daemon)
|
$(all-daemon)
|
||||||
|
|
||||||
tests_src := a-set_test.c a-path_test.c bitmap_test.c heap_test.c buffer_test.c event_test.c flowspec_test.c bitops_test.c patmatch_test.c fletcher16_test.c slist_test.c checksum_test.c lists_test.c mac_test.c ip_test.c hash_test.c printf_test.c slab_test.c
|
tests_src := a-set_test.c a-path_test.c bitmap_test.c heap_test.c buffer_test.c event_test.c flowspec_test.c bitops_test.c patmatch_test.c fletcher16_test.c slist_test.c checksum_test.c lists_test.c mac_test.c ip_test.c hash_test.c printf_test.c slab_test.c type_test.c
|
||||||
tests_targets := $(tests_targets) $(tests-target-files)
|
tests_targets := $(tests_targets) $(tests-target-files)
|
||||||
tests_objs := $(tests_objs) $(src-o-files)
|
tests_objs := $(tests_objs) $(src-o-files)
|
||||||
|
@ -9,18 +9,30 @@
|
|||||||
#ifndef _BIRD_BIRDLIB_H_
|
#ifndef _BIRD_BIRDLIB_H_
|
||||||
#define _BIRD_BIRDLIB_H_
|
#define _BIRD_BIRDLIB_H_
|
||||||
|
|
||||||
|
#include "sysdep/config.h"
|
||||||
#include "lib/alloca.h"
|
#include "lib/alloca.h"
|
||||||
|
|
||||||
/* Ugly structure offset handling macros */
|
/* Ugly structure offset handling macros */
|
||||||
|
|
||||||
struct align_probe { char x; long int y; };
|
|
||||||
|
|
||||||
#define OFFSETOF(s, i) ((size_t) &((s *)0)->i)
|
#define OFFSETOF(s, i) ((size_t) &((s *)0)->i)
|
||||||
#define SKIP_BACK(s, i, p) ((s *)((char *)p - OFFSETOF(s, i)))
|
#define SKIP_BACK(s, i, p) ((s *)((char *)p - OFFSETOF(s, i)))
|
||||||
#define BIRD_ALIGN(s, a) (((s)+a-1)&~(a-1))
|
#define BIRD_ALIGN(s, a) (((s)+a-1)&~(a-1))
|
||||||
#define CPU_STRUCT_ALIGN (sizeof(struct align_probe))
|
#define CPU_STRUCT_ALIGN (MAX_(_Alignof(void*), _Alignof(u64)))
|
||||||
#define BIRD_CPU_ALIGN(s) BIRD_ALIGN((s), CPU_STRUCT_ALIGN)
|
#define BIRD_CPU_ALIGN(s) BIRD_ALIGN((s), CPU_STRUCT_ALIGN)
|
||||||
|
|
||||||
|
/* Structure item alignment macros */
|
||||||
|
|
||||||
|
#define PADDING_NAME(id) _padding_##id
|
||||||
|
#define PADDING_(id, sz) u8 PADDING_NAME(id)[sz]
|
||||||
|
|
||||||
|
#if CPU_POINTER_ALIGNMENT == 4
|
||||||
|
#define PADDING(id, n32, n64) PADDING_(id, n32)
|
||||||
|
#elif CPU_POINTER_ALIGNMENT == 8
|
||||||
|
#define PADDING(id, n32, n64) PADDING_(id, n64)
|
||||||
|
#else
|
||||||
|
#error "Strange CPU pointer alignment: " CPU_POINTER_ALIGNMENT
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Utility macros */
|
/* Utility macros */
|
||||||
|
|
||||||
#define MIN_(a,b) (((a)<(b))?(a):(b))
|
#define MIN_(a,b) (((a)<(b))?(a):(b))
|
||||||
|
@ -144,6 +144,8 @@ typedef struct eattr {
|
|||||||
byte fresh:1; /* An uncached attribute (e.g. modified in export filter) */
|
byte fresh:1; /* An uncached attribute (e.g. modified in export filter) */
|
||||||
byte undef:1; /* Explicitly undefined */
|
byte undef:1; /* Explicitly undefined */
|
||||||
|
|
||||||
|
PADDING(unused, 0, 4);
|
||||||
|
|
||||||
union bval u;
|
union bval u;
|
||||||
} eattr;
|
} eattr;
|
||||||
|
|
||||||
|
@ -14,8 +14,14 @@
|
|||||||
|
|
||||||
union bval {
|
union bval {
|
||||||
#define BVAL_ITEMS \
|
#define BVAL_ITEMS \
|
||||||
|
struct { \
|
||||||
u32 data; /* Integer type inherited from eattrs */ \
|
u32 data; /* Integer type inherited from eattrs */ \
|
||||||
|
PADDING(data, 0, 4); /* Must be padded on 64-bits */ \
|
||||||
|
}; \
|
||||||
|
struct { \
|
||||||
u32 i; /* Integer type inherited from filters */ \
|
u32 i; /* Integer type inherited from filters */ \
|
||||||
|
PADDING(i, 0, 4); /* Must be padded on 64-bits */ \
|
||||||
|
}; \
|
||||||
const struct adata *ptr; /* Generic attribute data inherited from eattrs */ \
|
const struct adata *ptr; /* Generic attribute data inherited from eattrs */ \
|
||||||
const struct adata *ad; /* Generic attribute data inherited from filters */ \
|
const struct adata *ad; /* Generic attribute data inherited from filters */ \
|
||||||
|
|
||||||
|
78
lib/type_test.c
Normal file
78
lib/type_test.c
Normal file
@ -0,0 +1,78 @@
|
|||||||
|
/*
|
||||||
|
* BIRD Library -- Data Type Alignment Tests
|
||||||
|
*
|
||||||
|
* (c) 2022 Maria Matejka <mq@jmq.cz>
|
||||||
|
*
|
||||||
|
* Can be freely distributed and used under the terms of the GNU GPL.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "test/birdtest.h"
|
||||||
|
#include "lib/type.h"
|
||||||
|
#include "lib/route.h"
|
||||||
|
|
||||||
|
#define CHECK_ONE(val) \
|
||||||
|
for (uint i=0; i<sizeof(val); i++) \
|
||||||
|
bt_assert(((const u8 *) &val)[i] == (u8) ~0);
|
||||||
|
|
||||||
|
#define SET_PADDING(val, name) \
|
||||||
|
for (uint i=0; i<sizeof(val.PADDING_NAME(name)); i++) \
|
||||||
|
val.PADDING_NAME(name)[i] = ~0;
|
||||||
|
|
||||||
|
|
||||||
|
static int
|
||||||
|
t_bval(void)
|
||||||
|
{
|
||||||
|
union bval v;
|
||||||
|
|
||||||
|
memset(&v, 0, sizeof(v));
|
||||||
|
v.data = ~0;
|
||||||
|
SET_PADDING(v, data);
|
||||||
|
CHECK_ONE(v);
|
||||||
|
|
||||||
|
memset(&v, 0, sizeof(v));
|
||||||
|
v.i = ~0;
|
||||||
|
SET_PADDING(v, i);
|
||||||
|
CHECK_ONE(v);
|
||||||
|
|
||||||
|
memset(&v, 0, sizeof(v));
|
||||||
|
v.ptr = (void *) ~0;
|
||||||
|
CHECK_ONE(v);
|
||||||
|
|
||||||
|
memset(&v, 0, sizeof(v));
|
||||||
|
v.ad = (void *) ~0;
|
||||||
|
CHECK_ONE(v);
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
t_eattr(void)
|
||||||
|
{
|
||||||
|
struct eattr e;
|
||||||
|
memset(&e, 0, sizeof(e));
|
||||||
|
|
||||||
|
e.id = ~0;
|
||||||
|
e.flags = ~0;
|
||||||
|
e.type = ~0;
|
||||||
|
e.originated = ~0;
|
||||||
|
e.fresh = ~0;
|
||||||
|
e.undef = ~0;
|
||||||
|
memset(&e.u, ~0, sizeof(e.u)); /* Assumes t_bval passed */
|
||||||
|
|
||||||
|
SET_PADDING(e, unused);
|
||||||
|
|
||||||
|
CHECK_ONE(e);
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int main(int argc, char *argv[])
|
||||||
|
{
|
||||||
|
bt_init(argc, argv);
|
||||||
|
|
||||||
|
bt_test_suite(t_bval, "Structure alignment test: bval");
|
||||||
|
bt_test_suite(t_eattr, "Structure alignment test: eattr");
|
||||||
|
|
||||||
|
return bt_exit_value();
|
||||||
|
}
|
@ -6,7 +6,7 @@ $(call proto-build,dev_build)
|
|||||||
|
|
||||||
$(proto-build-c): $(lastword $(MAKEFILE_LIST))
|
$(proto-build-c): $(lastword $(MAKEFILE_LIST))
|
||||||
$(E)echo GEN $@
|
$(E)echo GEN $@
|
||||||
$(Q)echo "$(patsubst %,void %(void); ,$(PROTO_BUILD)) void protos_build_gen(void) { $(patsubst %, %(); ,$(PROTO_BUILD))}" > $@
|
$(Q)echo "#include \"lib/birdlib.h\"\n$(patsubst %,void %(void);\n,$(PROTO_BUILD)) void protos_build_gen(void) { $(patsubst %, %();\n,$(PROTO_BUILD))}" > $@
|
||||||
|
|
||||||
tests_src :=
|
tests_src :=
|
||||||
tests_targets := $(tests_targets) $(tests-target-files)
|
tests_targets := $(tests_targets) $(tests-target-files)
|
||||||
|
@ -9,7 +9,6 @@
|
|||||||
#ifndef _BIRD_BIRD_H_
|
#ifndef _BIRD_BIRD_H_
|
||||||
#define _BIRD_BIRD_H_
|
#define _BIRD_BIRD_H_
|
||||||
|
|
||||||
#include "sysdep/config.h"
|
|
||||||
#include "lib/birdlib.h"
|
#include "lib/birdlib.h"
|
||||||
#include "lib/ip.h"
|
#include "lib/ip.h"
|
||||||
#include "lib/net.h"
|
#include "lib/net.h"
|
||||||
|
Loading…
Reference in New Issue
Block a user