what is the use-case for dlmopen vs dlopen? - dll

android has the concept of a linker namespace.
https://source.android.com/devices/architecture/vndk/linker-namespace
what exactly is a linker namespace in layman terms ?
when would we want to use dlmopen vs dlopen ?
what use case is dlmopen trying to solve that dlopen does not solve ?
The project I work on makes use of dlXXX API for loading shared libraries at runtime and we want to ensure that the symbols loaded from the shared library are completely isolated. Does dlmopen address this issue ?

from dlopen's man page :
The dlmopen() function differs from dlopen() primarily in that it ac‐
cepts an additional argument, lmid, that specifies the link-map list
(also referred to as a namespace) in which the shared object should be
loaded. (By comparison, dlopen() adds the dynamically loaded shared
object to the same namespace as the shared object from which the
dlopen() call is made.) The Lmid_t type is an opaque handle that
refers to a namespace.
The lmid argument is either the ID of an existing namespace (which can
be obtained using the dlinfo(3) RTLD_DI_LMID request) or one of the
following special values:
LM_ID_BASE
Load the shared object in the initial namespace (i.e., the ap‐
plication's namespace).
LM_ID_NEWLM
Create a new namespace and load the shared object in that name‐
space. The object must have been correctly linked to reference
all of the other shared objects that it requires, since the new
NOTES
dlmopen() and namespaces
A link-map list defines an isolated namespace for the resolution of
symbols by the dynamic linker. Within a namespace, dependent shared
objects are implicitly loaded according to the usual rules, and symbol
references are likewise resolved according to the usual rules, but such
resolution is confined to the definitions provided by the objects that
have been (explicitly and implicitly) loaded into the namespace.
The dlmopen() function permits object-load isolation—the ability to
load a shared object in a new namespace without exposing the rest of
the application to the symbols made available by the new object. Note
that the use of the RTLD_LOCAL flag is not sufficient for this purpose,
since it prevents a shared object's symbols from being available to any
other shared object. In some cases, we may want to make the symbols
provided by a dynamically loaded shared object available to (a subset
of) other shared objects without exposing those symbols to the entire
application. This can be achieved by using a separate namespace and
the RTLD_GLOBAL flag.
The dlmopen() function also can be used to provide better isolation
than the RTLD_LOCAL flag. In particular, shared objects loaded with
RTLD_LOCAL may be promoted to RTLD_GLOBAL if they are dependencies of
another shared object loaded with RTLD_GLOBAL. Thus, RTLD_LOCAL is in‐
sufficient to isolate a loaded shared object except in the (uncommon)
case where one has explicit control over all shared object dependen‐
cies.
Possible uses of dlmopen() are plugins where the author of the plugin-
loading framework can't trust the plugin authors and does not wish any
undefined symbols from the plugin framework to be resolved to plugin
symbols. Another use is to load the same object more than once. With‐
out the use of dlmopen(), this would require the creation of distinct
copies of the shared object file. Using dlmopen(), this can be
achieved by loading the same shared object file into different name‐
spaces.
The glibc implementation supports a maximum of 16 namespaces.
So yes, it can be used to isolate a loaded lib !

Related

Can't create private classes with same name in different modules

Official docs on visibility modifiers in Kotlin say that package-level elements marked private are be visible only in the module in which they are declared.
So class A declared in Module1.kt isn't visible in Module2.kt. But if I try to add to Module2.kt it's own class A I get the Redeclaration: A error.
Since I can't access in Module2.kt to Module1's A class, why isn't the name A free to use?
"A module is a set of Kotlin files compiled together" (Visibility Modifiers - Kotlin Programming Language).
In your example, Module1.kt and Module2.kt are separate source files and despite their names they are not necessarily part of separate modules:
If they are compiled together then they are part of the same module.
If they are compiled separately from one another then they will be part of different modules and each can define their own private class A.
Keep in mind that visibility is different from identity. Even if a class is not visible elsewhere it doesn't mean that it does not exist. Loading multiple class declarations with the same fully-qualified name can (and likely will) cause issues at run-time.

Is all of a static library included in a final product after linking?

Suppose I create an iOS application. I include a static library. I create an object of a class that is defined and implemented in static library. This object doesn't use other classes defined in the library. Will all of the static library be present in the application I build? The idea is that much of the static library contains unused code and wouldn't need to be present.
I believe there a flags that help determine the behavior -- if someone can spell out how this works, I sure would appreciate it.
A static library is an archive of object files. If you link against a static library libfoo.a then
the linker by default will link into your final executable all and only those object files in libfoo.a
that are required to provide definitions for the public symbols that are referenced by the program.
More specifically, if the linker finds the library requested (via the option -lfoo) at a given
point in the commandline sequence of object files and libraries to be linked, then it will
extract from the archive and link into the executable each object file in the archive that provides
a definition for any symbol that remains undefined up to that point in the linkage.
In so doing, definitions of unused public symbols may be redundantly linked into
your program, but only if they are found in an object file (whether free-standing or a member of
a library) that is not completely redundant.
If you do not want to tolerate even those potential redundancies, then a combination of
compiler and linker options can eliminate them: see this answer

Is there a conventional URI scheme for referencing code in a library?

Is there a standard or conventional URI scheme, like file: or http: for referencing objects in a dynamic library?
For example, if I were to represent a function in a library in the form of a unique string that can be used to look up that function (by whatever reflective means), how might I do that?
Specifically I'm developing this in Objective-C, and I assume different languages/platforms will have different representations (I know .NET has its own), but I'm curious about this in a more general sense.
No, the name of the symbol is derived from its name in your code. In windows you will assuming C or C++
HMODULE module=LoadLibrary( [path to your dll] );
//If the exported name is foo.
Function foo=(Function)GetProcAddress(module,"foo");
//Call function
foo();
FreeLibrary(module);
The exported name is compiler-dependent.
Acually such a naming scheme is quite useless. In C++ you can use something like (Note that you will have one FunctionCaller per function prototype)
FunctionCaller("your-dll.dll/foo")();
Where the constructor of FunctionCaller loads the library, calls foo and frees the library. However it is not good because:
it may happen that the return value points to a resource inside the library and then will become useless
loading libraries and perform function look-up is slow relative to calling the function found
What you do is
Load the library
Load functions that you will need
Use your functions
Free the library
Here you would need to refer to more than one symbol at a time which would require a more complex scheme than uri.
EDIT: If you want to the convenience of calling functions like that you could have a surviving FunctionCaller object that keeps all loaded modules and contains a map from function name to address for each loaded library.

What are Modules when creating COM objects with Embarcadero C++ Buider

I am creating a COM library with Embarcadero C++ Builder. The designer for the ridl file gives several things you can add to the ridl. I think I understand all of them except for creating new "Modules". I can't find good information for it in the documentation.
What is a "Module" and what would it be used for in COM?
You say you can't find 'good information' in the documentation; what have you found? The RAD Studio help has a section specifically explaining modules, which says:
A module defines a group of functions,
typically a set of DLL entry points.
You define a module by
Specifying a DLL that it represents on the attributes page.
Adding methods and constants using the toolbar or the object list pane
context menu. For each method or
constant, you must then define its
attributes by selecting the it in the
object list pane and setting the
values on the Attributes page.
For module methods, you must assign a
name and DLL entry point using the
attributes page. Declare the
function's parameters and return type
using the parameters page.
For module constants, use the
Attributes page to specify a name,
type, and value.
Note: The Type Library Editor does not generate any declarations or
implementation related to a module.
The specified DLL must be created as a
separate project.
It seems it's specifying methods that exist in an external DLL to whatever module (EXE or DLL) the type library is built into. Exactly what that's used for... is a good question.
The module attribute is described in this MSDN Library page. It permits declaring entrypoints in a DLL. That has little to do with COM, it is just a capability of a type library. You'll find few language development environments that can use them. I think VB6 was one of them. Ymmv.

How to update a C++ dll without needing to relink the exe with the lib file?

First off , I'm referring to a Windows environment and VC++ compiler.
What I want to be able to do is rebuild a Vc++ dll and maintain compatability with an exe that has already been linked to the lib without having to rebuild the exe or load the dll dynamically using LoadLibrary. In other words, is there a way to add classes and methods to a dll(but not remove any) and ensure the existing entrypoints remain the same?
If you export the functions from using a DEF file and manually specify the ordinals, you should be able to accomplish this.
Reference
http://msdn.microsoft.com/en-us/library/d91k01sh(VS.80).aspx
It depends on how your EXE used the classes from the DLL. Adding new classes should not affect existing entrypoints. Aside from that, however, any the following will affect object size and/or layout, and as such will be a client-breaking change (note that this is technically VC-specific, but most of these apply to any sane implementation):
Removing fields (even private) from classes
Adding new fields (even private) to classes
Adding new base classes to existing classes
Removing base classes from existing classes
Adding new virtual method before an existing virtual method (adding new virtual methods after existing ones is okay, except for the case described in next point)
Adding a new virtual method in a class that is used as base class by another class in the same DLL which also has virtual methods
Changing type of existing fields
Changing signature of existing methods
Making a virtual method non-virtual, and vice versa
As long as you don't add any exported symbols, the ordinals won't change. If you add exported symbols through the standard dllexport mechanism, then that's going to be difficult to control. If you use the old style .xpf symbol file you might be able to control the ordering of the symbols in the lib (although I don't know this for sure - it might still reorder them however it likes), but it's tricky to do C++ symbols this way.
I think that ordinals are rarely used to resolve DLL imports anymore - I think that you have to use .def files to get the linker to use them. So as long as you don't change names or signatures of the exported functions, the .exe should work just fine.