[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Xen-devel] [PATCH v6 1/4] xen: introduce SYMBOL



>>> On 07.02.19 at 12:48, <ian.jackson@xxxxxxxxxx> wrote:
> Stefano Stabellini writes ("Re: [Xen-devel] [PATCH v6 1/4] xen: introduce 
> SYMBOL"):
>> I am OK with this approach. Maybe not the best IMO, but good enough. It
>> should also satisfy the MISRAC guys, as they wrote "ideally cast to
>> uintptr_t only once": here we wouldn't be casting only once, but at
>> least we would do it inside a single well-defined macro.
> 
> Right.  I think it meets the goals of MISRA-C, probably better than
> most other approaches.
> 
> FAOD, I think you should expect people to declare the linker symbols
> either as I suggested:
> 
>      extern const struct wombat _wombats_start[];
>      extern const struct abstract_symbol _wombats_end[];
> 
> (or along the lines of Jan's suggestion, but frankly I think that is
> going to be too hard to sort out now.)

Hmm, not overly difficult (and a macro just because there are no
templates in C):

#define WHATEVER(type, name, pfx) \
\
struct abstract_ ## name { \
    type _; \
}; \
\
extern const type pfx ## _start[]; \
extern const struct abstract_ ## name pfx ## _end[]; \
\
static inline _Bool name ## _lt(type const s1[], \
                                const struct abstract_ ## name s2[]) \
{ \
    return (unsigned long)s1 < (unsigned long)s2; \
} \
\
static inline long name ## _diff(type const s1[], \
                                 const struct abstract_ ## name s2[]) \
{ \
    return ((unsigned long)s2 - (unsigned long)s1) / sizeof(*s1); \
}

WHATEVER(unsigned char, uchar, )
WHATEVER(const struct scheduler *, scheduler, schedulers)

/* Example usage */

unsigned long image_size(void)
{
    return uchar_diff(_start, _end);
}

void iterate_schedulers(void (*func)(const struct scheduler *))
{
    const struct scheduler *const *s;

    for ( s = schedulers_start; scheduler_lt(s, schedulers_end); ++s )
        func(*s);
}

I've intentionally used unsigned long and _Bool such that the
example would compile completely standalone. This isn't mean to
be that way in whatever would go into the hypervisor of course.

As you can see type safety gets achieved without any
comparisons at all, hence not even raising the UB-ness question.
As you can further see passing around pointers to the
abstract_* structures is working quite okay, which is what I
was after when talking about the type safety aspect.

Whether the extern array declarations would be part of the
macro is to be determined. On one hand doing so tightly couples
start and end symbols, i.e. they can't be used in non-matching
pairs. Otoh this then requires to declare and use different
"name"s when multiple start/end pairs share their base types.
An option might be to have two macros, one without the decls
and the other having the decls and invoking the first.

And I think you can guess that I've used WHATEVER as a name
because I couldn't really figure a good one (and I also wasn't
overly happy with various names I had seen so far).

Jan



_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxxx
https://lists.xenproject.org/mailman/listinfo/xen-devel

 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.