Is it possible to satisfy a __declspec(dllimport) symbol without a dll? - visual-c++

It's possible to override C runtime functions using the preprocessor (e.g. /Dfree=my_debug_free), however having to match the linkage of the redefined symbol is sometimes undesirable or awkward within the context of a given project.
Is there a way to force the dllimport linkage of a symbol to be satisfied with a symbol coming from a static .lib or a .obj?
Let's assume modifying the calling code directly, or defining away the __declspec keyword itself is out of the question.

Answering my own question with what I've found:
One of the things that the __declspec(dllimport) does is say that the function in question has a prefix __imp_ added to it from the importer's point of view, so manually add the prefixed function, and you satisfy the link.
As far as I understand these __imp_ are the bit that the .lib file corresponding to the .dll would normally provide. If you cut out the linking of the .lib for the .dll you cut that those also, and so have to fill in the __imp_ shaped hole manually yourself.
https://msdn.microsoft.com/en-us/library/aa271769(v=vs.60).aspx has a good overview.
All that said, I've found that using a pre-included file (/FI or -include) that #includes the original (unredefined) definitions first, then redefines them with #defines before entering your code works better than using /D to to redefine them everywhere, even in the original definitions. Doing it that way meas you don't need to worry about the .dll stuff.

Related

problems compiling with gcc and gnu make

The problem arises firstly from the "isfinite" function: (undefined reference to isfinite). From google search I find that I must include "math.h" and write three lines of code, like:
ifdef __linux__
define _finite(v) (__builtin_isfinite(v))
endif
But then, there comes the error: (Make:47 missing endif. Stop).
If I comment out those three lines of code, the error becomes: (<math.h> no such file or directory).
My system is OpenSUSE Leap 15.4; gcc version 7; gnu make version 4.2.1-7.3.2.
I think I have installed all the needed packages. However the errors persist. Any help?
I primarily want to address this part of the question, as the underlying issue has been addressed elsewhere, multiple times:
The problem arises firstly from the "isfinite" function: (undefined reference to isfinite). From google search I find that I must include "math.h" and write three lines of code, like:
ifdef __linux__
define _finite(v) (__builtin_isfinite(v))
endif
I started to write "Google led you astray", but I think it's more likely that you seriously misunderstood what it led you to. And perhaps you happened to choose poor results.
The error message indicates that you put those lines in your makefile, but they are wholly inappropriate for that. Don't put them there.
The lines are C preprocessor directives that have been stripped of their leading # characters. You would use them by restoring the # characters ...
#ifdef __linux__
#define _finite(v) (__builtin_isfinite(v))
#endif
... and putting the resulting lines into one or more of your C source files. BUT DON'T! Those lines are unnecessary and at best unhelpful.
You do need to #include <math.h> in each C source file that contains a call to isfinite(), because that is the header that provides a declaration of the function. Since C99, functions must be declared before they are called (and it was good practice well before then).
Other than that, with GCC and many other traditional-style Unix C compilers, you need to explicitly include the math library in your link when you need any of the functions it provides. That would involve adding -lm to your makefile, at the end of the gcc command that builds the final executable. This is covered in gcc will not properly include math.h, and many other duplicates on this site.

GDB - disable source view in backtrace

Is it possible to DISABLE source code view in backtrace, to display only line numbers and file names?
I mean do NOT include these informations to application, because you can also read from the application file.
I don't want anyone to see my source code.
If it's impossible in GDB, is there any other debugger with such feature?
GDB can only show your source code if it can find your original source files. If people can see your source in the backtrace, then presumably they can also see your entire source base.
Therefore, I suspect you mean that you do not want the compiler to include any of your sources in the application binaries?
In fact, the application binaries only contain the source filenames, line numbers, symbol names (such as function and variable names), and some type information. If you use -g3 then they might also include preprocessor macros, but most people just use -g.
The easiest way to exclude the 'source' information is to not ship binaries with debug information. You can either build it without using -g in the first place, or you can use strip to remove it after the fact.
Not building with debug info will remove all symbol names that are not absolutely necessary (including static functions, and all local variable names), but it will not remove the symbol names for externally visible functions: the linker needs to see those. strip can remove some of those also, I think, although I've never tried. Beware that libraries must have symbol names for externally visible function.
Removing debug info will also remove line-number information, and source file names, so this still isn't quite what you want.
I'd suggest a) refactoring your source code so that isn't embarrassing and/or give away any clues, and b) don't ship with debug info.

Linux, GNU GCC, ld, version scripts and the ELF binary format -- How does it work?

I'm trying to learn more about library versioning in Linux and how to put it all to work. Here's the context:
-- I have two versions of a dynamic library which expose the same set of interfaces, say libsome1.so and libsome2.so.
-- An application is linked against libsome1.so.
-- This application uses libdl.so to dynamically load another module, say libmagic.so.
-- Now libmagic.so is linked against libsome2.so. Obviously, without using linker scripts to hide symbols in libmagic.so, at run-time all calls to interfaces in libsome2.so are resolved to libsome1.so. This can be confirmed by checking the value returned by libVersion() against the value of the macro LIB_VERSION.
-- So I try next to compile and link libmagic.so with a linker script which hides all symbols except 3 which are defined in libmagic.so and are exported by it. This works... Or at least libVersion() and LIB_VERSION values match (and it reports version 2 not 1).
-- However, when some data structures are serialized to disk, I noticed some corruption. In the application's directory if I delete libsome1.so and create a soft link in its place to point to libsome2.so, everything works as expected and the same corruption does not happen.
I can't help but think that this may be caused due to some conflict in the run-time linker's resolution of symbols. I've tried many things, like trying to link libsome2.so so that all symbols are alised to symbol##VER_2 (which I am still confused about because the command nm -CD libsome2.so still lists symbols as symbol and not symbol##VER_2)... Nothing seems to work!!! Help!!!!!!
Edit: I should have mentioned it earlier, but the app in question is Firefox, and libsome1.so is libsqlite3.so shipped with it. I don't quite have the option of recompiling them. Also, using version scripts to hide symbols seems to be the only solution right now. So what really happens when symbols are hidden? Do they become 'local' to the SO? Does rtld have no knowledge of their existence? What happens when an exported function refers to a hidden symbol?
Try compiling both libsome1.so and libsome2.so to add symbol versioning, each with their own version (use the --version-script option to ld). Then link the application and libmagic.so using the new libraries. Then, libsome1.so and libsome2.so should be completely separate.
Problems can still occur if there are unversioned references to symbols. Such references can be satisfied by versioned definitions (so that it is possible to add symbol versioning to a library without breaking binary compatibility). If there are multiple symbols of the same name, it can sometimes be hard to predict which one will be used.
Regarding tools, nm -D does not display any information about symbol versioning. Try objdump -T or readelf -s instead.

Linux, GNU GCC, ld, version scripts and the ELF binary format -- How does it work? [duplicate]

I'm trying to learn more about library versioning in Linux and how to put it all to work. Here's the context:
-- I have two versions of a dynamic library which expose the same set of interfaces, say libsome1.so and libsome2.so.
-- An application is linked against libsome1.so.
-- This application uses libdl.so to dynamically load another module, say libmagic.so.
-- Now libmagic.so is linked against libsome2.so. Obviously, without using linker scripts to hide symbols in libmagic.so, at run-time all calls to interfaces in libsome2.so are resolved to libsome1.so. This can be confirmed by checking the value returned by libVersion() against the value of the macro LIB_VERSION.
-- So I try next to compile and link libmagic.so with a linker script which hides all symbols except 3 which are defined in libmagic.so and are exported by it. This works... Or at least libVersion() and LIB_VERSION values match (and it reports version 2 not 1).
-- However, when some data structures are serialized to disk, I noticed some corruption. In the application's directory if I delete libsome1.so and create a soft link in its place to point to libsome2.so, everything works as expected and the same corruption does not happen.
I can't help but think that this may be caused due to some conflict in the run-time linker's resolution of symbols. I've tried many things, like trying to link libsome2.so so that all symbols are alised to symbol##VER_2 (which I am still confused about because the command nm -CD libsome2.so still lists symbols as symbol and not symbol##VER_2)... Nothing seems to work!!! Help!!!!!!
Edit: I should have mentioned it earlier, but the app in question is Firefox, and libsome1.so is libsqlite3.so shipped with it. I don't quite have the option of recompiling them. Also, using version scripts to hide symbols seems to be the only solution right now. So what really happens when symbols are hidden? Do they become 'local' to the SO? Does rtld have no knowledge of their existence? What happens when an exported function refers to a hidden symbol?
Try compiling both libsome1.so and libsome2.so to add symbol versioning, each with their own version (use the --version-script option to ld). Then link the application and libmagic.so using the new libraries. Then, libsome1.so and libsome2.so should be completely separate.
Problems can still occur if there are unversioned references to symbols. Such references can be satisfied by versioned definitions (so that it is possible to add symbol versioning to a library without breaking binary compatibility). If there are multiple symbols of the same name, it can sometimes be hard to predict which one will be used.
Regarding tools, nm -D does not display any information about symbol versioning. Try objdump -T or readelf -s instead.

How do I disable the generation of an import library?

I'm creating a COM DLL in Visual Studio. The linker generates an import library for the DLL. I don't need the import library.
Is there any way to tell the linker not to generate it?
Nine years later, this may not be useful to the OP, but it may prove useful to others coming by looking for a solution.
LINK.EXE supports the /NOIMPLIB option that prevents creation of an import library, even in the presence of a __declspec(dllexport) routine in the DLL or EXE being linked.
Go to Project Properties, open up the Linker section. The very last option is Command Line. Select that, and there's a place at the bottom to add additional options to the linker. Enter /NOIMPLIB in the edit field, save and apply, and it'll prevent the creation of the .lib file.
-- Edit --
Unfortunately, while it does prevent creation of the .lib file, empirically I've found that the .exp file is still created. I'd file a bug report with MS, but based on past experience with their developer tools team, trying to get something like this fixed will be akin to trying to roll a boulder up hill.
-- Edit -- four years later --
As noted in the comments, VS 2019 finally has this fixed, so that /NOIMPLIB now suppresses the creation of both the .lib and .exp files.
This answer seems to be the solution:
https://stackoverflow.com/a/15214141/660440
"Using a .def file containing your exported functions marked with the PRIVATE keyword will tell the linker to skip placing the symbol in your import library."

Resources