Permalink
Browse files

Add in a slightly less bad, but still no better, hack to find libc fu…

…nctions on windows. Instead of looking up modules by string name, which are guaranteed to change because 'why the heck not?', we can use an undocumented trick to find the HMODULE owner for a particular function pointer. See in-code comments and TT #2150 for more details.
  • Loading branch information...
1 parent a3d4738 commit bd1c96d8c2a3ed263f90ffbd8883a36881c8dbcc @Whiteknight Whiteknight committed Jul 20, 2011
Showing with 33 additions and 5 deletions.
  1. +33 −5 src/platform/win32/dl.c
@@ -76,28 +76,56 @@ you would write something similar to:
Foo_ptr = Parrot_dlsym(lib, "Foo");
}
+=item C<void* find_hmodule_from_func(void *func)>
+
+Attempt a lookup of an owning HMODULE with nothing but the address of an
+exported function pointer from that HMODULE. This relies on a trick where the
+HMODULE value is the pointer to the base address of allocated memory for that
+module. This relationship appears to hold for almost all non-ancient 32- and
+64-bit versions of windows. There is no guarantee that this relationship will
+hold on future versions of windows. Passing tests, expecially t/pmc/nci.t and
+t/library/nciutils.t are a good indicator that this code is working as
+expected
+
+IF NCI-RELATED THINGS START BREAKING WHEN YOU UPDATE WINDOWS, THIS IS A VERY
+GOOD PLACE TO LOOK FOR THE CAUSE OF THE FAILURES.
+
+Visit TT #2150 to register a complaint.
+
=cut
*/
+static void*
+find_hmodule_from_func(void * func)
+{
+ MEMORY_BASIC_INFORMATION mbi;
+ if (VirtualQuery(func, &mbi, sizeof(mbi)))
+ return mbi.AllocationBase;
+ return NULL;
+}
+
void *
Parrot_dlsym(void *handle, const char *symbol)
{
- /* This is a horrible hack. We shouldn't be hard-coding library names
- in the lookup list, and we should have better semantics to fall back
- on. See TT #2150 for more insults about this code. */
+ /* This is a hack, but it appears to work well enough and should be
+ compatible for most versions of windows. It's not pretty, however, and
+ it would be awesome if we could find a better, documented way to
+ perform module lookups.
+ See TT #2150 for more insults about this code. */
if (handle == NULL) {
void * proc = NULL;
- handle = (void*)GetModuleHandle("libparrot");
+ handle = find_hmodule_from_func(Parrot_dlsym);
proc = (void *)GetProcAddress((HINSTANCE)handle, symbol);
if (proc)
return proc;
- handle = (void*)GetModuleHandle("msvcrt");
+ handle = find_hmodule_from_func(atoi);
return (void *)GetProcAddress((HINSTANCE)handle, symbol);
}
return (void *)GetProcAddress((HINSTANCE)handle, symbol);
}
+
/*
=item C<int Parrot_dlclose(void *handle)>

0 comments on commit bd1c96d

Please sign in to comment.