[lld] r207141 - [PECOFF] Define implicit symbols for exported ones.
Rui Ueyama
ruiu at google.com
Thu Apr 24 13:12:01 PDT 2014
Author: ruiu
Date: Thu Apr 24 15:12:01 2014
New Revision: 207141
URL: http://llvm.org/viewvc/llvm-project?rev=207141&view=rev
Log:
[PECOFF] Define implicit symbols for exported ones.
This patch is to fix a compatibility issue with MSVC link.exe as to
use of dllexported symbols inside DLL.
A DLL exports two symbols for a function. One is non-decorated one,
and the other is with __imp_ prefix. The former is a function that
you can directly call, and the latter is a pointer to the function.
These dllexported symbols are created by linker for programs that
link against the DLL. So, I naturally believed that __imp_ symbols
become available when you once create a DLL and link against it, but
they don't exist until then. And that's not true.
MSVC link.exe is smart enough to allow users to use __imp_ symbols
locally. That is, if a symbol is specified with /export option, it
implicitly creates a new symbol with __imp_ prefix as a pointer to
the exported symbol. This feature allows the following program to
be linked and run, although _imp__hello is not defined in this code.
#include <stdio.h>
__declspec(dllexport)
void hello(void) { printf("Hello\n"); }
extern void (*_imp__hello)(void);
int main() {
_imp__hello();
return 0;
}
MSVC link.exe prints out the following warning when linking it.
LNK4217: locally defined symbol _hello imported in function _main
Using __imp_ symbols locally is I think not a good coding style. One
should just take an address using "&" operator rather than appending
__imp_ prefix. However, there are programs in the wild that depends
on this link.exe's behavior, so we need this feature.
Modified:
lld/trunk/lib/ReaderWriter/PECOFF/LinkerGeneratedSymbolFile.h
Modified: lld/trunk/lib/ReaderWriter/PECOFF/LinkerGeneratedSymbolFile.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/PECOFF/LinkerGeneratedSymbolFile.h?rev=207141&r1=207140&r2=207141&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/PECOFF/LinkerGeneratedSymbolFile.h (original)
+++ lld/trunk/lib/ReaderWriter/PECOFF/LinkerGeneratedSymbolFile.h Thu Apr 24 15:12:01 2014
@@ -11,10 +11,25 @@
#include "lld/ReaderWriter/PECOFFLinkingContext.h"
#include "lld/ReaderWriter/Simple.h"
+#include "llvm/Support/Allocator.h"
namespace lld {
namespace pecoff {
+/// The defined atom for dllexported symbols with __imp_ prefix.
+class ImpPointerAtom : public COFFLinkerInternalAtom {
+public:
+ ImpPointerAtom(const File &file, StringRef symbolName)
+ : COFFLinkerInternalAtom(file, /*oridnal*/ 0, std::vector<uint8_t>(4),
+ symbolName) {}
+
+ uint64_t ordinal() const override { return 0; }
+ Scope scope() const override { return scopeGlobal; }
+ ContentType contentType() const override { return typeData; }
+ Alignment alignment() const override { return Alignment(4); }
+ ContentPermissions permissions() const override { return permR__; }
+};
+
// A virtual file containing absolute symbol __ImageBase. __ImageBase (or
// ___ImageBase on x86) is a linker-generated symbol whose address is the same
// as the image base address.
@@ -25,10 +40,29 @@ public:
_imageBaseAtom(*this, ctx.decorateSymbol("__ImageBase"),
Atom::scopeGlobal, ctx.getBaseAddress()) {
addAtom(_imageBaseAtom);
+
+ // Create implciit symbols for exported symbols.
+ for (const PECOFFLinkingContext::ExportDesc exp : ctx.getDllExports()) {
+ UndefinedAtom *target = new (_alloc) SimpleUndefinedAtom(*this, exp.name);
+ COFFLinkerInternalAtom *imp = createImpPointerAtom(ctx, exp.name);
+ imp->addReference(std::unique_ptr<COFFReference>(
+ new COFFReference(target, 0, llvm::COFF::IMAGE_REL_I386_DIR32)));
+ addAtom(*target);
+ addAtom(*imp);
+ }
};
private:
+ COFFLinkerInternalAtom *createImpPointerAtom(const PECOFFLinkingContext &ctx,
+ StringRef name) {
+ std::string sym = "_imp_";
+ sym.append(name);
+ sym = ctx.decorateSymbol(sym);
+ return new (_alloc) ImpPointerAtom(*this, ctx.allocate(sym));
+ }
+
COFFAbsoluteAtom _imageBaseAtom;
+ llvm::BumpPtrAllocator _alloc;
};
} // end namespace pecoff
More information about the llvm-commits
mailing list