Skip to content

Commit

Permalink
Merge d02a9d9 into 1d6fcd4
Browse files Browse the repository at this point in the history
  • Loading branch information
mdavidsaver committed Apr 1, 2020
2 parents 1d6fcd4 + d02a9d9 commit 276ac71
Show file tree
Hide file tree
Showing 8 changed files with 144 additions and 10 deletions.
4 changes: 2 additions & 2 deletions .travis.yml
Expand Up @@ -31,11 +31,11 @@ matrix:
compiler: gcc
env: CMPLR=clang STATIC=YES
- sudo: false
dist: trusty
dist: bionic
compiler: gcc
env: WINE=32 TEST=NO STATIC=YES
- sudo: false
dist: trusty
dist: bionic
compiler: gcc
env: WINE=32 TEST=NO STATIC=NO
- sudo: false
Expand Down
2 changes: 1 addition & 1 deletion configure/os/CONFIG.linux-x86.win32-x86-mingw
Expand Up @@ -21,4 +21,4 @@ LOADABLE_SHRLIB_LDFLAGS = -shared \
GNU_LDLIBS_YES =

# Link with system libraries
OP_SYS_LDLIBS = -lws2_32 -ladvapi32 -luser32 -lkernel32 -lwinmm -ldbghelp
OP_SYS_LDLIBS = -lpsapi -lws2_32 -ladvapi32 -luser32 -lkernel32 -lwinmm -ldbghelp
2 changes: 1 addition & 1 deletion configure/os/CONFIG.win32-x86-mingw.win32-x86-mingw
Expand Up @@ -32,4 +32,4 @@ LOADABLE_SHRLIB_LDFLAGS = -shared \
GNU_LDLIBS_YES =

# Link with system libraries
OP_SYS_LDLIBS = -lws2_32 -ladvapi32 -luser32 -lkernel32 -lwinmm -ldbghelp
OP_SYS_LDLIBS = -lpsapi -lws2_32 -ladvapi32 -luser32 -lkernel32 -lwinmm -ldbghelp
2 changes: 1 addition & 1 deletion configure/os/CONFIG.win32-x86.win32-x86
Expand Up @@ -135,7 +135,7 @@ OBJ_CXXFLAG = -Fo
STATIC_CXXFLAGS_YES= -MT$(VISC_CFLAGS_DEBUG) $(BUILD_DLL_CFLAGS)
STATIC_CXXFLAGS_NO= -MD$(VISC_CFLAGS_DEBUG) $(BUILD_DLL_CFLAGS) -DEPICS_CALL_DLL

STATIC_LDLIBS_YES=ws2_32.lib advapi32.lib user32.lib kernel32.lib winmm.lib dbghelp.lib
STATIC_LDLIBS_YES=psapi.lib ws2_32.lib advapi32.lib user32.lib kernel32.lib winmm.lib dbghelp.lib
STATIC_LDLIBS_NO=
STATIC_LDFLAGS=
RANLIB=
Expand Down
35 changes: 31 additions & 4 deletions modules/libcom/src/osi/os/WIN32/osdFindSymbol.c
Expand Up @@ -5,13 +5,22 @@
\*************************************************************************/
/* osi/os/WIN32/osdFindSymbol.c */


#include <windows.h>
#include <psapi.h>

#define epicsExportSharedSymbols
#include "epicsFindSymbol.h"

static int epicsLoadErrorCode = 0;
#ifdef _MSC_VER
# define STORE static __declspec( thread )
#elif __GNUC__
# define STORE static __thread
#else
# define STORE static
#endif

STORE
int epicsLoadErrorCode = 0;

epicsShareFunc void * epicsLoadLibrary(const char *name)
{
Expand All @@ -28,7 +37,7 @@ epicsShareFunc void * epicsLoadLibrary(const char *name)

epicsShareFunc const char *epicsLoadError(void)
{
static char buffer[100];
STORE char buffer[100];

FormatMessage(
FORMAT_MESSAGE_FROM_SYSTEM,
Expand All @@ -42,5 +51,23 @@ epicsShareFunc const char *epicsLoadError(void)

epicsShareFunc void * epicsShareAPI epicsFindSymbol(const char *name)
{
return GetProcAddress(0, name);
HMODULE dlls[128];
DWORD ndlls=0u, i;
void* ret = NULL;

/* As a handle returned by LoadLibrary() isn't available to us,
* try all loaded modules in arbitrary order.
*/
if(EnumProcessModules(GetCurrentProcess(), dlls, sizeof(dlls), &ndlls)) {
for(i=0; !ret && i<ndlls; i++) {
ret = GetProcAddress(dlls[i], name);
}
}
if(!ret) {
/* only capturing the last error code,
* but what else to do?
*/
epicsLoadErrorCode = GetLastError();
}
return ret;
}
8 changes: 7 additions & 1 deletion modules/libcom/src/osi/os/posix/osdFindSymbol.c
Expand Up @@ -11,6 +11,12 @@
#define epicsExportSharedSymbols
#include "epicsFindSymbol.h"

/* non-POSIX extension available on Linux (glibc at least) and OSX.
*/
#ifndef RTLD_DEFAULT
# define RTLD_DEFAULT 0
#endif

epicsShareFunc void * epicsLoadLibrary(const char *name)
{
return dlopen(name, RTLD_LAZY | RTLD_GLOBAL);
Expand All @@ -23,5 +29,5 @@ epicsShareFunc const char *epicsLoadError(void)

epicsShareFunc void * epicsShareAPI epicsFindSymbol(const char *name)
{
return dlsym(0, name);
return dlsym(RTLD_DEFAULT, name);
}
10 changes: 10 additions & 0 deletions modules/libcom/test/Makefile
Expand Up @@ -260,6 +260,16 @@ iocshTest_SRCS += iocshTest.cpp
TESTS += iocshTest
TESTFILES += $(wildcard ../iocshTest*.cmd)

TESTPROD_HOST += epicsLoadTest
epicsLoadTest_SRCS += epicsLoadTest.cpp
# test linked against static libCom?
epicsLoadTest_CPPFLAGS_STATIC_YES = -DLINKING_STATIC
epicsLoadTest_CPPFLAGS += $(epicsLoadTest_CPPFLAGS_STATIC_$(STATIC_BUILD))
# are dynamic libraries built?
epicsLoadTest_CPPFLAGS_SHARED_YES = -DBUILDING_SHARED_LIBRARIES
epicsLoadTest_CPPFLAGS += $(epicsLoadTest_CPPFLAGS_SHARED_$(SHARED_LIBRARIES))
TESTS += epicsLoadTest

# The testHarness runs all the test programs in a known working order.
testHarness_SRCS += epicsRunLibComTests.c

Expand Down
91 changes: 91 additions & 0 deletions modules/libcom/test/epicsLoadTest.cpp
@@ -0,0 +1,91 @@
/*************************************************************************\
* Copyright (c) 2020 Michael Davidsaver
* EPICS BASE is distributed subject to a Software License Agreement found
* in file LICENSE that is included with this distribution.
\*************************************************************************/

#include <sstream>

#include <stdlib.h>

#include "epicsUnitTest.h"
#include "testMain.h"

#include "envDefs.h"
#include "epicsFindSymbol.h"
#include "epicsThread.h"

namespace {

// lookup a symbol from libCom
// which this executable is linked against (maybe statically)
// Doesn't work for static builds on windows
void loadCom()
{
testDiag("Lookup symbol from Com");

#if defined (_WIN32) && defined(LINKING_STATIC)
testTodoBegin("windows static build");
#endif

void* ptr = epicsFindSymbol("epicsThreadGetCPUs");
testOk(ptr==(void*)&epicsThreadGetCPUs,
"%p == %p (epicsThreadGetCPUs) : %s",
ptr, (void*)&epicsThreadGetCPUs,
epicsLoadError());

testTodoEnd();
}

void loadCA()
{
testDiag("Load and lookup symbol from libca");

std::string libname;
{
std::ostringstream strm;
// running in eg. modules/libcom/test/O.linux-x86_64-debug
#ifdef _WIN32
strm<<"..\\..\\..\\..\\bin\\"<<envGetConfigParamPtr(&EPICS_BUILD_TARGET_ARCH)<<"\\ca.dll";
#else
strm<<"../../../../lib/"<<envGetConfigParamPtr(&EPICS_BUILD_TARGET_ARCH)<<"/";
# ifdef __APPLE__
strm<<"libca.dylib";
# else
strm<<"libca.so";
# endif
#endif
libname = strm.str();
}
testDiag("Loading %s", libname.c_str());

void *ptr = epicsLoadLibrary(libname.c_str());
testOk(!!ptr, "Loaded %p : %s", ptr, epicsLoadError());

ptr = epicsFindSymbol("ca_context_create");
testOk(!!ptr, "ca_context_create %p : %s", ptr, epicsLoadError());
}

} // namespace

MAIN(epicsLoadTest)
{
testPlan(3);

// reference to ensure linkage when linking statically,
// and actually use the result to make extra doubly sure that
// this call isn't optimized out by eg. an LTO pass.
testDiag("# of CPUs %d", epicsThreadGetCPUs());

#if defined(__rtems__) || defined(vxWorks)
testSkip(3, "Target does not implement epicsFindSymbol()");
#else
loadCom();
# if defined(BUILDING_SHARED_LIBRARIES)
loadCA();
# else
testSkip(2, "Shared libraries not built");
# endif
#endif
return testDone();
}

0 comments on commit 276ac71

Please sign in to comment.