This is a hotfix that prevents double-loading of certain bap core
libraries (e.g., bap-knowledge, bap-core-theory, bap-main, etc) when
using the baptop executable or bap.top library. It is not 100%
bulletproof against all double-loads but the problem only affects the
toplevel environment and builds that use opam-repository and oasis,
which we will eventually sunset after a full move to the dune build
system.
Problem Description
-------------------
The BAP plugin system is designed to be self-contained so that all
dependencies could be loaded directly from the plugins. This let us
deploy BAP in a standalone form, i.e., on systems that lack OCaml
installation. This feature, of course, leads to bloated plugins. To
partially alleviate this issue, we defined a set of compilation units
that are presumed to be present in the executable that loads bap
plugins. This set includes the transitive closure of three packages
`bap`, `core-kernel`, and `ppx_bap`. So that any compilation unit on
which one of these packages depends will not be packed into a plugin,
since it is expected to be linked into the host exectuable.
This worked perfectly under assumption that all plugins depend on bap
or, at least, that the bap library is installed when a plugin is
built. This assumption stopped to be true after BinaryAnalysisPlatform#1419 when we started
to use plugins that do not depend on bap. Since bap is not installed
when such a plugin is built (which is only possible when building each
package independently from the opam-repository) we can no longer build
the transitive closure of bap dependencies that includes
bap-core-theory, bap-knowledge, etc, therefore we store them in the
plugin. When this plugin is loaded from a toplevel, we can't prevent
units that comprise these packages from loading since in the toplevel
mode they have been loaded to the host executable with the `require`
directive and there's no mechanism in the toplevel system that allows
us to know what units were loaded (dynlink doesn't work in
toplevel). In the end, it leads to double-loading of bap-knowledge,
and if some of the previously loaded plugins already used
bap-knowledge, the information that they have stored in it will be
erased.