Dynamically loaded plugins for the new pass manager are initialised by
calling llvmGetPassPluginInfo. This is defined as a weak symbol so that
it is continually redefined by each plugin that is loaded. When loading
a plugin from a shared library, the intention is that
llvmGetPassPluginInfo will be resolved to the definition in the most
recent plugin. However, using a global search for this resolution can
fail in situations where multiple plugins are loaded.
Currently:
- If a plugin does not define llvmGetPassPluginInfo, then it will be silently resolved to the previous plugin's definition.
- If loading the same plugin twice with another in between, e.g. plugin A/plugin B/plugin A, then the second load of plugin A will resolve to llvmGetPassPluginInfo in plugin B.
- The previous case can also occur when a dynamic library defines both NPM and legacy plugins; the legacy plugins are loaded first and then with -fplugin=A -fpass-plugin=B -fpass-plugin=A: A will be loaded as a legacy plugin and define llvmGetPassPluginInfo; B will be loaded and redefine it; and finally when A is loaded as an NPM plugin it will be resolved to the definition from B.
Instead of searching globally, restrict the symbol lookup to the library
that is currently being loaded.