[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [Xen-devel] [PATCH v10 2/6] xen: introduce DEFINE_SYMBOL
Stefano Stabellini writes ("[PATCH v10 2/6] xen: introduce DEFINE_SYMBOL"): > Introduce a MACRO to be used to declare array variables corresponding to > linker symbols, plus two static inline functions to be used for > comparing and subtracting pointers with the linker symbols. > > Note that the start and end symbols are declared of different types to > help avoid errors and misusing those variables. Firstly, sorry, but a formatting grumble: The \ cause wrap damage on my 80-column terminal even before I quote the email as I am doing now. Right now it looks like this: > +extern const type start_name[]; \ \ > +extern const struct abstract_ ## name end_name[]; \ \ which is just awful. I will remove some spaces from the quoted text so I can review it. I'm not a hypervisor maintainer but I would appreciate it if you could make the whole thing fit in 75 columns or so. > + > +/* > + * Declare start and end array variables in C corresponding to existing > + * linker symbols. > + * > + * Two static inline functions are declared to do comparisons and > + * subtractions between these variables. > + * > + * The end variable is declared with a different type to make sure that > + * the static inline functions cannot be misused. > + */ > +#define DEFINE_SYMBOL(type, name, start_name, end_name) \ > + \ > +struct abstract_ ## name { \ > + type _; \ > +}; \ > + \ > +extern const type start_name[]; \ > +extern const struct abstract_ ## name end_name[]; \ I have thought of a problem with this approach. This goes wrong unless `type' is a struct type. Because the compiler is allowed to assume that end_name has the correct alignment for its type. And in some ABIs, the alignment of a struct containing (say) a char is bigger than that of a char. AIUI in some of the actual use cases the linker-generated symbols may not be struct aligned. I am not aware of a standard C type which could be used instead of this struct. But I think you can use the `packed' attribute to get the right behaviour. The GCC manual says: | Alignment can be decreased by specifying the 'packed' attribute. | See below. Bizarrely, this seems only to be stated, slightly elliptically like this, in the section on the `aligned' attribute; it's not mentioned in `packed'. I suggest we couple this with a compile-time assertion that alignof is the struct is the same as alignof the type. (FTR I think this is a largely theoretical concern because most current ABIs including all of Xen's specify that structs inherit the alignment of the coarsest member.) > +static inline bool name ## _lt(const type s1[], \ > + const struct abstract_ ## name s2[]) \ > +{ \ > + return (uintptr_t)s1 < (uintptr_t)s2; \ > +} \ This seems right to me. > +static inline ptrdiff_t name ## _diff(const type s1[], \ > + const struct abstract_ ## name s2[])\ > +{ \ > + return ((uintptr_t)s2 - (uintptr_t)s1) / sizeof(*s1); \ This is wrong. The conversion to ptrdiff_t (currently done implicitly by return) must come before the division. Otherwise it will give the wrong answer when s1 > s2. Suppose 32-bit, s1=0x00000040 s2=0x00000020 sizeof=0x10, Then s2-s1=0xffffffe0, and unsigned division gives (s2-s1)/sizeof=0x0ffffffe. Converstion to ptrdiff_t does not change the bit pattern. But we wanted 0xffffffe. Signed integer division by a positive divisor is always defined (and always fits) so doing the conversion first is fine. Regards, Ian. _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxxxxxxxxx https://lists.xenproject.org/mailman/listinfo/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |