On Thu, Jul 13, 2017 at 02:33:57PM +0200, Martin Kletzander wrote:
On Thu, Jul 13, 2017 at 12:25:50PM +0100, Daniel P. Berrange wrote:
> On Thu, Jul 13, 2017 at 01:14:12PM +0200, Martin Kletzander wrote:
> > On Wed, Jul 12, 2017 at 05:06:22PM +0100, Daniel P. Berrange wrote:
> > > Currently any mockable functions are marked with attributes
> > > noinline, noclone and weak. This prevents the compiler from
> > > optimizing away the impl of these functions.
> > >
> > > It has an unfortunate side effect with the libtool convenience
> > > libraries, if executables directly link to them. For example
> > > virlockd, virlogd both link to libvirt_util.la When this is
> > > done, the linker does not consider weak symbols as being
> > > undefined, so it never copies them into the final executable.
> > >
> > > In this new approach, we stop annotating the headers entirely.
> > > Instead we create a weak function alias in the source.
> > >
> > > int fooImpl(void) {
> > > ..the real code..
> > > }
> > >
> > > int foo(void) __attribute__((noinline, noclone, weak,
alias("fooImpl"))
> > >
> > > If any functions in the same file call "foo", this prevents the
> > > optimizer from inlining any part of fooImpl. When linking to the
> > > libtool convenience static library, we also get all the symbols
> > > present. Finally the test suite can just directly define a
> > > 'foo' function in its source, removing the need to use LD_PRELOAD
> > > (though removal of LD_PRELOADS is left for a future patch).
> > >
> >
> > What are you using for tag navigation? With this macro-defined
> > functions I cannot easily jump to them (the main reason why I don't like
> > macros defining functions).
>
> Grep & historic knowledge :-)
>
> > I would very much prefer if
> > ATTRIBUTE_MOCKABLE just took a parameter like this:
> >
> > #define ATTRIBUTE_MOCKABLE(func) __attribute__((noinline, noclone, weak,
alias(#func "Impl"))
> >
> > (written by hand, don't take mu word for it working out of the box) and
> > the original function would be left untouched.
>
> Yeah, that is certainly a valid alternative. I was not entirely happy
> with the results I get here. As long as we don't mind repeating the
> arg list in both places, your approach is more attractive, despite
> the duplication.
>
I think we don't if we do:
#define VIR_MOCKABLE(ret, name) typeof(name ## Impl) name \
__attribute__((noinline, weak, __alias__(#name "Impl")));
or can't this be done for functions? It worked when I tried it now.
I've never tried typeof in this way, so I guess we can experiment.
I have one more idea, though. So that we don't have to
double-type the
actual definition of the Impl function, we can make it static. What if
we make *all* functions static and only add weak aliases to those that
are supposed to be used outside the file? That is after we deal with
the Darwin case, of course.
NB, I orignally marked the funtions as static, but clang complains that
they are unused, despite being referenced from an alias annotation.
Regards,
Daniel
--
|:
https://berrange.com -o-
https://www.flickr.com/photos/dberrange :|
|:
https://libvirt.org -o-
https://fstop138.berrange.com :|
|:
https://entangle-photo.org -o-
https://www.instagram.com/dberrange :|