LLVM ERROR: Program used external function 'printd' which could not be resolved!

Hi

Buit the Kaleidoscope example under MinGW and everything runs fine except when I try the following example in Chapter 6:

extern printd(x);

printd(123);

where printd is the library function defined in C as

extern “C”

double printd(double X) {

printf("%f\n", X);

return 0;

}

The error message is:

LLVM ERROR: Program used external function ‘printd’ which could not be resolved!

Any help will be much appreciated. Thanks!

LLVM ERROR: Program used external function 'printd' which could not be
resolved!
Any help will be much appreciated. Thanks!

Windows does not support dynamic linking. You will need to resolve
externals by hand.

Why would it not support dynamic linking? What about loadlibrary and
its kin are not sufficient to handle this? Perhaps a work-around can
be developed.

Any help will be much appreciated. Thanks!

Windows does not support dynamic linking. You will need to resolve
externals by hand.

Why would it not support dynamic linking? What about loadlibrary and
its kin are not sufficient to handle this?

Well, you cannot easily export stuff from an executable and this is
the main issue here.
(And you cannot e.g. import stuff from executable into dynamic library
as you can on linux/darwin)

Perhaps a work-around can be developed.

Maybe. Patches are welcome!

Boost has worked around that same issue (which actually causes an
issue in Boost.Serialization because for it to work on Windows it has
to export the entire serialization tree of the user's program, which
can be on the order of *bloody massive* at times, it is fascinating
how it managed to pull this off without causing edits to the user code
though), by defining a specific macro that is clear on non-windows but
is the proper dllexport statement on Windows, could do the same thing
while encapsulating things in a "C" export to keep the names simple
for easy import. If that is really the only issue, I could easily fix
it. I figured it was something more complex...

And yes, you can import stuff from the executable into a dynamic
library in Windows, GetModuleHandle being passed null/0/etc... will
give a module link to the primary running executable, upon which you
can then pull in things it exports with ease. LoadLibrary will link
in a dynamic library if it is not already linked in, then calls
GetModuleHandle on it, then returns what GetModuleHandle returns on
that. GetModuleHandle by itself just looks in the linked in library
list (of which the executable is part of), and returns a handle to it.
GetProcAddress operates on that handle to return a function pointer.

For example, from within the executable itself, if you want to link in
something that is exported from itself, you can do this:

export "C" {
  void printInt(int i) { printf("%i", i); }

  typedef void(*printIntType)(int);
}

int main(void) {
  HMODULE self = GetModuleHandle(0);
  printIntType printIntPtr = (AddFunc)GetProcAddress(self, "printInt");
  (*printIntPtr)(42);
}

And if you want to check for something exported from any currently
loaded module, EnumProcessModules can be used for that to get all
modules loaded into the current process.

So is this really all that is needed to get linking working on
Windows? If so then I can easily do it. Maybe a few pointers to show
me where in LLVM/clang source the equivalent *nix code is so I can
special case it?

s/AddFunc/printIntType
I copied the code from one of my existing projects...

Then the easiest thing to do is just stuff the function pointer in the
global pointer table in your module's JIT, single line of code (which
I do not recall off hand, hence you should be asking the list, I will
forward this to the list as well).

Hi,

That seems really simple… just changing the function pointer. But how to do it for the ‘printd’ function in the Kaleidoscope example?
An example how to do this would be super-great.

Any help will be much appreciated. Thanks!

With updateGlobalMapping from you execution engine ?

Olivier.

2010/10/9 António Saragga Seabra <antseabra@gmail.com>