Looking for Information on dlltool --add-indirect (-a)

504 views Asked by At

I am looking for more information on the --add-indirect option for dlltool. When do you use this option? What does it do?

Information from binutils help on this option:

-a
--add-indirect

Specifies that when dlltool is creating the exports file it should add a section which allows the exported functions to be referenced without using the import library. Whatever the hell that means!

1

There are 1 answers

0
Alexander Shukaev On BEST ANSWER

First of all, let's make it clear what is exports file. Exports file is needed for creation of DLL. This file is linked with the object files (produced by compiler) that make up the body of the DLL (i.e. functions, classes, etc.) and it handles the interface between the DLL and the outside world. This is a binary file and it can be created by giving the -e option to dlltool when it is creating or reading in *.def file.

The next term that you have to understand is import library. One of the ways to employ DLL by some consumer application is to link this application against the DLL, so that all the exported functionality from DLL is available to the consumer. Such linking to DLLs is usually done by linking to an import library which is essentially an auxiliary static library that contains an import address table (IAT) which is there to allow consumer to reference all the DLL exported functionality. For example, each referenced DLL function contains its own entry in IAT. At runtime, the IAT is filled with appropriate addresses that point directly to corresponding functions in the separately loaded DLL.

Now let's manually create a DLL with dlltool and gcc to give you the feeling what's going on:

gcc -c library.c

produces library.o,

dlltool -e exports.o -l library.dll.a library.o

produces exports file exports.o and import library library.dll.a (.dll.a is conventional suffix for import libraries produced by GCC which emphasizes that the import library is, in fact, static with .a, but is aimed at DLL with .dll),

gcc library.o exports.o -o library.dll

produces library.dll,

gcc consumer.o library.dll.a -o consumer

produces executable consumer.exe which is linked against library.dll.

NOTE: The above is a manual procedure of creating the DLL, and it's discouraged to do that in production because GCC wraps all of that logic in one optimized call:

gcc -shared -o library.dll library.o -Wl,--out-implib,library.dll.a

Back on track, now that we know the basic terminology and purpose, we can easily interpret what is written in help about --add-indirect:

Specifies that when dlltool is creating the exports file it should add a section which allows the exported functions to be referenced without using the import library. Whatever the hell that means!

Let's apply that to the previous example. In this case, exports.o will already contain IAT, and therefore resulting library.dll will also contain that information, so we don't need import library library.dll.a because now we can directly link to library.dll itself:

gcc consumer.o library.dll -o consumer

Whether it's useful or not is quite subjective question to ask. I guess from the point of view of us (programmers/users) it's pretty much useless since DLL creation and linkage shouldn't be done explicitly (i.e. through direct invocation of dlltool) anyway, but should rather be done through GCC front end (as noted above). From the point of view of building development tools such as toolchains (like GCC itself) this might be useful since something similar to the above example may actually be used behind the scenes by GCC itself to perform gcc -shared -o library.dll ... and etc.

Finally, it is generally discouraged to link against DLL directly. Although, it works fine with latest versions of MinGW/MinGW-w64, it has been known to have bugs in the past. Furthermore, if pseudo-relocation is disabled, then direct linkage with DLL might result in certain runtime issues. Also, this is the official way MSVC links consumers against DLLs, i.e. without an import library, MSVC simply can't do the linkage, what could also be the reason why you should prefer to always use import libraries. Remember DLL is not the same as shared object (SO) on Linux: their use cases are the same, but their implementations are based on different technologies.