[Pdbg] [PATCH 1/4] libpdbg: Validate hardware units at build time
Alistair Popple
alistair at popple.id.au
Fri Mar 16 13:47:35 AEDT 2018
On Wednesday, 7 March 2018 4:35:24 PM AEDT Cyril Bur wrote:
> I'll send this to the list otherwise I'll forget.
>
> Al and I decided to send our Core HTM patches and get them merged
> first, I'll rebase this series onto those.
Thanks for the reminder :-)
> I don't expect any other changes in v2 unless someone wants to jump in.
>
>
> On Tue, 2018-02-27 at 19:23 +1100, Cyril Bur wrote:
> > Hardware unit structs such as struct htm contain a struct pdbg_target
> > which can be passed around to create an abstraction. Currently there is
> > a bit of extra runtime code used to guard against developers not
> > declaring the struct pdbg_target member as the first member. If we can
> > enforce this at build time then a some runtime can be removed.
> >
> > This patch enforces that the struct pdbg_target member of hardware
> > units is always the first member at build time.
> >
> > The only caveat is that compiling with -O0 will result in a false
> > negative - the build succeeding when it should not. We should be using
> > litterally any other optimisation level so that isn't really a problem.
> >
> > Signed-off-by: Cyril Bur <cyrilbur at gmail.com>
> > ---
> > Makefile.am | 2 +-
> > libpdbg/target.c | 10 ++++------
> > libpdbg/target.h | 16 ++++++++++++----
> > 3 files changed, 17 insertions(+), 11 deletions(-)
> >
> > diff --git a/Makefile.am b/Makefile.am
> > index 4156b21..099a035 100644
> > --- a/Makefile.am
> > +++ b/Makefile.am
> > @@ -8,7 +8,7 @@ include libfdt/Makefile.libfdt
> > bin_PROGRAMS = pdbg
> >
> > ACLOCAL_AMFLAGS = -Im4
> > -AM_CFLAGS = -I$(top_srcdir)/ccan/array_size -Wall -Werror
> > +AM_CFLAGS = -I$(top_srcdir)/ccan/array_size -Wall -Werror -O2
> >
> > pdbg_SOURCES = \
> > src/main.c src/cfam.c src/scom.c src/reg.c src/mem.c src/thread.c \
> > diff --git a/libpdbg/target.c b/libpdbg/target.c
> > index 1eb85bb..07159d2 100644
> > --- a/libpdbg/target.c
> > +++ b/libpdbg/target.c
> > @@ -254,7 +254,7 @@ struct hw_unit_info *find_compatible_target(const char *compat)
> > struct pdbg_target *target;
> >
> > for (p = &__start_hw_units; p < (struct hw_unit_info **) &__stop_hw_units; p++) {
> > - target = (*p)->hw_unit + (*p)->struct_target_offset;
> > + target = (*p)->hw_unit;
> > if (!strcmp(target->compatible, compat))
> > return *p;
> > }
> > @@ -268,7 +268,6 @@ void pdbg_targets_init(void *fdt)
> > const struct dt_property *p;
> > struct pdbg_target_class *target_class;
> > struct hw_unit_info *hw_unit_info;
> > - void *new_hw_unit;
> > struct pdbg_target *new_target;
> > uint32_t index;
> >
> > @@ -283,10 +282,9 @@ void pdbg_targets_init(void *fdt)
> > hw_unit_info = find_compatible_target(p->prop);
> > if (hw_unit_info) {
> > /* We need to allocate a new target */
> > - new_hw_unit = malloc(hw_unit_info->size);
> > - assert(new_hw_unit);
> > - memcpy(new_hw_unit, hw_unit_info->hw_unit, hw_unit_info->size);
> > - new_target = new_hw_unit + hw_unit_info->struct_target_offset;
> > + new_target = malloc(hw_unit_info->size);
> > + assert(new_target);
> > + memcpy(new_target, hw_unit_info->hw_unit, hw_unit_info->size);
> > new_target->dn = dn;
> > dn->target = new_target;
> > index = dt_prop_get_u32_def(dn, "index", -1);
> > diff --git a/libpdbg/target.h b/libpdbg/target.h
> > index 0a618e2..2bc7dba 100644
> > --- a/libpdbg/target.h
> > +++ b/libpdbg/target.h
> > @@ -18,6 +18,7 @@
> >
> > #include <stdint.h>
> > #include <ccan/list/list.h>
> > +#include <ccan/str/str.h>
> > #include <ccan/container_of/container_of.h>
> > #include "compiler.h"
> > #include "device.h"
> > @@ -60,16 +61,23 @@ extern struct list_head empty_list;
> > struct hw_unit_info {
> > void *hw_unit;
> > size_t size;
> > - size_t struct_target_offset;
> > };
> >
> > /* We can't pack the structs themselves directly into a special
> > * section because there doesn't seem to be any standard way of doing
> > * that due to alignment rules. So instead we pack pointers into a
> > - * special section. */
> > + * special section.
> > + *
> > + * If this macro fails to compile for you, you've probably not
> > + * declared the struct pdbg_target as the first member of the
> > + * container struct. Not doing so will break other assumptions.
> > + * */
> > #define DECLARE_HW_UNIT(name) \
> > - const struct hw_unit_info __used name ##_hw_unit = \
> > - { .hw_unit = &name, .size = sizeof(name), .struct_target_offset = container_off(typeof(name), target) }; \
> > + static inline void name ##_hw_unit_check(void) { \
> > + ((void)sizeof(char[1 - 2 * (container_off(typeof(name), target) != 0)])); \
> > + } \
> > + const struct hw_unit_info __used name ##_hw_unit = \
> > + { .hw_unit = &name, .size = sizeof(name) }; \
> > const struct hw_unit_info __used __section("hw_units") *name ##_hw_unit_p = &name ##_hw_unit
> >
> > struct htm {
>
More information about the Pdbg
mailing list