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

Re: Detecting transitive ABI dependencies with libabigail?



"Andrew C. Morrow" <andrew.c.morrow@gmail.com> a écrit:

> Could libabigail be leveraged to answer the following question:
>
> Given a library libprovider.so and a library libuser.so, I'd like to
> know whether the ABI of libuser.so requires knowledge of types,
> functions, or values exported by the ABI of libprovider.so. In other
> words, is it the case that to meaningfully use the ABI of libuser.so
> one must link to libprovider.so?
>
> In particular, I'd like to distinguish the case where libuser.so makes
> use of libprovider.so purely internally, meaning that someone linking
> to libuser.so does not necessarily need to link explicitly to
> libprovider.so, from the case where libuser.so makes use of objects
> from libprovider.so in its ABI, and therefore does induce such a
> transitive dependency on libprovider.so.

If I understand correctly, the case where libuser.so makes use of types
(or functions/variables) from libprovider in its ABI happens when:

    1/ libuser.so "exports" a header file user.h that includes a header
    file provider.h from libprovider.so, and users of libuser.so *have*
    to use artifacts (types, functions or variables) from provider.h for
    a particular feature provided by libuser.so.

So 1/ is the general case.

Let's look at what I see as a possible breakdown of the different
possibilities covered by 1/.

1.a/ libuser.so header file user.h exports a function or variable 'foo'
that is actually declared in provider.h and defined in libprovider.so

 In other words, user.h includes provider.h.  Users of libuser.so can
thus use 'foo' and become dependent on libprovider.so.

As foo is not present (defined) in the binary libuser.so, looking at
that binary won't give us any meaningful information about it.

foo could be used by libuser.so itself, though.  That is, foo could be
seen as an undefined symbol, needed by libuser.so.  But that doesn't
give us much information because it could mean that libuser.so just
needs foo privately.

We thus need to have access to the header files of both libuser.so and
libprovider.so to detect this case.  And we need a way to parse those
header files to to so, I think.

1.b/ libuser.so header file user.h declares a function (or variable)
'bar'.  bar is defined in libuser.so and exported from there.  The
interface of bar then uses a type 'provider_type' that is declared (or
defined) in provider.h.

If 'provided_type' is *used* in a public interface defined in
libprovider.so, then we could detect that provided_type, used by a
public interface of libuser.so is also used by a public interface of
libprovider.so.  We can do that with libabigail, yes, without having to
have access to header files.

[...]

> I'm hoping to build something which can act as a lint tool to evaluate
> whether a given project is using the CMake style
> public/private/interface library dependency annotations correctly.
> Most notably, I'd like to be able to find library dependencies that
> are declared public, but could/should be weakened to private.

I see.  It makes sense.


[...]

> - Is the information provided by running abidw on both libuser.so and
> libprovider.so sufficient to answer this question?

For the 1.a case, I am afraid that we don't have enough information by
just looking at the binaries.  We'd need access to header files and a
way to parse them.  And libabigail doesn't parse header files.  It just
analyzes binaries.

For 1.b, though, I think we could answer the question, yes.

> - How would one approach writing such a tool given the facilities
> already available in libabigail?

For 1.b, I think one could walk the type tree reachable from
functions/variables exported from libuser.so [1] and build the set of
types reachable from those interfaces.

One could lookup those types from libprovider.so to see if anyone of
them is actually "defined" (or even declared) in libprovider.so.  If
there is one, then we have found one of these problematic cases.

I am not sure if I have answered your question completely, or if I am
forgetting something.

In any case, please do not hesitate to ask :-)


[1]: Please note that this type tree walk would be a shallow one,
though.  That is, one should not follow pointers -- but this is a
detail I this point, I guess.


Cheers,

-- 
		Dodji