- add test 12 which checks for global constructor problems and works
around it.
This commit is contained in:
parent
c3b2adfd00
commit
570fa2c949
@ -1,4 +1,4 @@
|
||||
SUBDIRS = test1-static test2-dynamic test3-twomodules test4-interdep test5-execsymbols test6-ltdlopen test7-win32dll test8-execlass test9-modclass test10-modvirtual test11-modglobalconstr
|
||||
SUBDIRS = test1-static test2-dynamic test3-twomodules test4-interdep test5-execsymbols test6-ltdlopen test7-win32dll test8-execlass test9-modclass test10-modvirtual test11-modglobalconstr test12-modglobalconstr2
|
||||
|
||||
all: build_libltdl
|
||||
-for i in $(SUBDIRS); do (echo Entering $$i; cd $$i && make all; echo Leaving $$i;); done
|
||||
|
5201
bochs-testing/plugin-test/configure
vendored
5201
bochs-testing/plugin-test/configure
vendored
File diff suppressed because it is too large
Load Diff
@ -53,4 +53,4 @@ AC_SUBST(LDFLAGS)
|
||||
AC_SUBST(LIBS)
|
||||
AC_SUBST(LT_LDFLAGS)
|
||||
|
||||
AC_OUTPUT(config.h Makefile test1-static/Makefile test2-dynamic/Makefile test3-twomodules/Makefile test4-interdep/Makefile test5-execsymbols/Makefile test6-ltdlopen/Makefile test7-win32dll/Makefile test8-execlass/Makefile test9-modclass/Makefile test10-modvirtual/Makefile test11-modglobalconstr/Makefile testscript)
|
||||
AC_OUTPUT(config.h Makefile test1-static/Makefile test2-dynamic/Makefile test3-twomodules/Makefile test4-interdep/Makefile test5-execsymbols/Makefile test6-ltdlopen/Makefile test7-win32dll/Makefile test8-execlass/Makefile test9-modclass/Makefile test10-modvirtual/Makefile test11-modglobalconstr/Makefile test12-modglobalconstr2/Makefile testscript)
|
||||
|
@ -0,0 +1,53 @@
|
||||
top_builddir = ..
|
||||
top_srcdir = @srcdir@/..
|
||||
srcdir = @srcdir@
|
||||
VPATH = @srcdir@
|
||||
|
||||
CXX=@CXX@
|
||||
CXXFLAGS=@CXXFLAGS@ @INCLTDL@
|
||||
LDFLAGS=@LDFLAGS@ @LT_LDFLAGS@
|
||||
LIBS=@LIBS@
|
||||
LTDL_STATIC_LIB=${top_builddir}/libltdl/.libs/libltdlc.al
|
||||
LIBTOOL=@LIBTOOL@
|
||||
RPATH=`pwd`/lib
|
||||
|
||||
# select whether to use libtool or win32-specific target.
|
||||
# This should either be all_libtool or all_win32_dlltool.
|
||||
all: @PLUGIN_MAKEFILE_TARGET@
|
||||
|
||||
########### libtool makefile for all platforms except win32 ###########
|
||||
all_libtool: uselib libmodule1.la libmodule2.la
|
||||
|
||||
uselib: main.lo
|
||||
$(LIBTOOL) $(CXX) -export-dynamic $(LDFLAGS) -o uselib main.lo $(LIBS) @LIBLTDL@
|
||||
|
||||
lib%.la: %.lo
|
||||
$(LIBTOOL) $(CXX) -module $(LDFLAGS) -o $@ $< -rpath ${RPATH}
|
||||
mkdir -p lib bin
|
||||
$(LIBTOOL) cp $@ ${RPATH}
|
||||
|
||||
%.lo: %.cc
|
||||
$(LIBTOOL) $(CXX) $(CXXFLAGS) -c $<
|
||||
#######################################################################
|
||||
|
||||
############# makefile for building plugin DLLs for win32 #############
|
||||
all_win32_dlltool: uselib.exe module1.dll module2.dll
|
||||
|
||||
uselib.exe: main.cc main.h
|
||||
$(CXX) $(CXXFLAGS) -c -DDLL_EXPORT -o main.o ${srcdir}/main.cc
|
||||
dlltool --output-def uselib.def main.o
|
||||
dlltool --dllname uselib.exe --def uselib.def --output-lib uselib.a
|
||||
dlltool --dllname uselib.exe --output-exp uselib.exp --def uselib.def
|
||||
$(CXX) $(CXXFLAGS) -o uselib.exe uselib.exp main.o ${LIBS} ${LTDL_STATIC_LIB}
|
||||
#rm uselib.exp uselib.def
|
||||
|
||||
%.dll: %.o uselib.exe
|
||||
$(CXX) $(CXXFLAGS) -shared -o $@ $< uselib.a
|
||||
|
||||
%.o: %.cc
|
||||
$(CXX) $(CXXFLAGS) -c $<
|
||||
#######################################################################
|
||||
|
||||
include ${top_srcdir}/common-make-defs.txt
|
||||
|
||||
clean: clean-common
|
4
bochs-testing/plugin-test/test12-modglobalconstr2/README
Normal file
4
bochs-testing/plugin-test/test12-modglobalconstr2/README
Normal file
@ -0,0 +1,4 @@
|
||||
test12-modglobalconstr2
|
||||
|
||||
This is kind of a stupid example, but it detects platforms that have
|
||||
problems with their global initializers, and works around it.
|
89
bochs-testing/plugin-test/test12-modglobalconstr2/main.cc
Normal file
89
bochs-testing/plugin-test/test12-modglobalconstr2/main.cc
Normal file
@ -0,0 +1,89 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <assert.h>
|
||||
#define LT_SCOPE extern /* so that ltdl.h does not export anything */
|
||||
#include <ltdl.h>
|
||||
#define MAIN_DLL_EXPORT
|
||||
#include "main.h"
|
||||
#include "modules.h"
|
||||
|
||||
const char *version_string = "uselib-test6-1.0";
|
||||
|
||||
#if 1
|
||||
// This lines forces main.cc to link in the functions associated with
|
||||
// the new operator. If there is no "new" in the whole executable, the
|
||||
// Solaris linker decides not to link in __builtin_new, giving this error
|
||||
// when you try to load a module:
|
||||
// fatal: relocation error: file .libs/libmodule1.so.0:
|
||||
// symbol __builtin_new: referenced symbol not found
|
||||
int *force_builtin_new = new int;
|
||||
#endif
|
||||
|
||||
int register_module (const char *name)
|
||||
{
|
||||
printf ("register_module was called by module '%s'\n", name);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int load_module (const char *fmt, const char *modname)
|
||||
{
|
||||
char buf[512];
|
||||
sprintf (buf, fmt, modname);
|
||||
printf ("loading module from VARIES{%s}\n", buf);
|
||||
lt_dlhandle handle = lt_dlopenext (buf);
|
||||
printf ("handle is VARIES{%p}\n", handle);
|
||||
if (!handle) {
|
||||
printf ("lt_dlopen error: %s\n", lt_dlerror ());
|
||||
return -1;
|
||||
}
|
||||
modload_func func = (modload_func) lt_dlsym (handle, "module_init");
|
||||
printf ("module_init function is at VARIES{%p}\n", func);
|
||||
if (func != NULL) {
|
||||
printf ("Calling module_init\n");
|
||||
DeviceInterface *device = (*func)();
|
||||
if (device) {
|
||||
printf ("%s's device is called '%s'\n", modname, device->getName ());
|
||||
printf ("%s can do '%s'\n", modname, device->getFeatures ());
|
||||
printf ("Calling the device's print method:\n ");
|
||||
device->print (stdout);
|
||||
printf ("\n");
|
||||
} else {
|
||||
printf ("%s has not defined any device\n", modname);
|
||||
}
|
||||
} else {
|
||||
printf ("lt_dlsym error: %s\n", lt_dlerror ());
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int main (int argc, char **argv)
|
||||
{
|
||||
printf ("start\n");
|
||||
if (lt_dlinit () != 0) {
|
||||
printf ("lt_dlinit error: %s\n", lt_dlerror ());
|
||||
return -1;
|
||||
}
|
||||
#ifdef WIN32
|
||||
const char *module_name_format = "%s";
|
||||
#else
|
||||
const char *module_name_format = "lib%s.la";
|
||||
#endif
|
||||
printf ("loading module1\n");
|
||||
// try to load module1
|
||||
if (load_module (module_name_format, "module1") < 0) {
|
||||
printf ("load module1 failed\n");
|
||||
}
|
||||
if (load_module (module_name_format, "module2") < 0) {
|
||||
printf ("load module2 failed\n");
|
||||
}
|
||||
int arg;
|
||||
for (int arg=1; arg < argc; arg++) {
|
||||
if (load_module (module_name_format, argv[arg]) < 0) {
|
||||
printf ("load %s failed\n", argv[arg]);
|
||||
}
|
||||
}
|
||||
|
||||
printf ("stop\n");
|
||||
exit (77);
|
||||
}
|
18
bochs-testing/plugin-test/test12-modglobalconstr2/main.h
Normal file
18
bochs-testing/plugin-test/test12-modglobalconstr2/main.h
Normal file
@ -0,0 +1,18 @@
|
||||
#if defined(WIN32) || defined(__CYGWIN__)
|
||||
# ifdef MAIN_DLL_EXPORT
|
||||
# ifdef DLL_EXPORT
|
||||
# warning I will export DLL symbols for MODULE1
|
||||
# define MAINAPI(type) __declspec(dllexport) type
|
||||
# endif
|
||||
# else
|
||||
# warning I will import DLL symbols for MODULE1
|
||||
# define MAINAPI(type) __declspec(dllimport) type
|
||||
# endif
|
||||
#endif
|
||||
#ifndef MAINAPI
|
||||
# warning No DLL import/export is needed
|
||||
# define MAINAPI(type) type
|
||||
#endif
|
||||
|
||||
MAINAPI(extern const char *) version_string;
|
||||
MAINAPI(extern int) register_module (const char *name);
|
48
bochs-testing/plugin-test/test12-modglobalconstr2/module1.cc
Normal file
48
bochs-testing/plugin-test/test12-modglobalconstr2/module1.cc
Normal file
@ -0,0 +1,48 @@
|
||||
#include <stdio.h>
|
||||
#include "main.h"
|
||||
#include "modules.h"
|
||||
|
||||
class CellPhone : public DeviceInterface {
|
||||
int id;
|
||||
const char *name;
|
||||
const char *features;
|
||||
public:
|
||||
CellPhone(const char* name, const char* features);
|
||||
virtual const char* getName ();
|
||||
virtual const char* getFeatures ();
|
||||
virtual void print(FILE *);
|
||||
};
|
||||
|
||||
class DeviceInterface* module_init ()
|
||||
{
|
||||
printf ("module1 init for main version %s\n", version_string);
|
||||
register_module ("module1");
|
||||
return new CellPhone ("BochsCellPhone", "Caller ID, Video Conferencing");
|
||||
}
|
||||
|
||||
int operate (int a, int b)
|
||||
{
|
||||
return a + b;
|
||||
}
|
||||
|
||||
//////// CellPhone class methods
|
||||
CellPhone::CellPhone(const char* name, const char* features)
|
||||
{
|
||||
this->name = name;
|
||||
this->features = features;
|
||||
}
|
||||
|
||||
const char* CellPhone::getName ()
|
||||
{
|
||||
return name;
|
||||
}
|
||||
|
||||
const char* CellPhone::getFeatures ()
|
||||
{
|
||||
return features;
|
||||
}
|
||||
|
||||
void CellPhone::print (FILE *fp)
|
||||
{
|
||||
fprintf (fp, "[CellPhone name='%s', features='%s']", name, features);
|
||||
}
|
91
bochs-testing/plugin-test/test12-modglobalconstr2/module2.cc
Normal file
91
bochs-testing/plugin-test/test12-modglobalconstr2/module2.cc
Normal file
@ -0,0 +1,91 @@
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
#include "main.h"
|
||||
#include "modules.h"
|
||||
|
||||
class GPS_Receiver : public DeviceInterface {
|
||||
int id;
|
||||
const char *name;
|
||||
char features[1024];
|
||||
const char *vendor;
|
||||
float resolution_meters;
|
||||
public:
|
||||
GPS_Receiver(const char* name, const char* vendor, float res);
|
||||
void addFeature (const char *f);
|
||||
virtual const char* getName ();
|
||||
virtual const char* getFeatures ();
|
||||
virtual void print(FILE *);
|
||||
const char* getVendor ();
|
||||
float getResolutionMeters ();
|
||||
};
|
||||
|
||||
GPS_Receiver *theReceiverPtr = new GPS_Receiver ("BochsStarGPS 4.0", "Bochs Project", 9.5);
|
||||
|
||||
int n_operations = 0;
|
||||
|
||||
class DeviceInterface* module_init ()
|
||||
{
|
||||
printf ("module2 init for main version %s\n", version_string);
|
||||
register_module ("module2");
|
||||
if (theReceiverPtr == NULL) {
|
||||
printf ("VARIES{The global initializer for theReceiverPtr was not called.}\n");
|
||||
printf ("VARIES{Creating the object in module_init.}\n");
|
||||
theReceiverPtr = new GPS_Receiver ("BochsStarGPS 4.0", "Bochs Project", 9.5);
|
||||
} else {
|
||||
printf ("VARIES{The initializer was called, as it should be}\n");
|
||||
printf ("VARIES{No action needed}\n");
|
||||
}
|
||||
theReceiverPtr->addFeature ("High Accuracy");
|
||||
theReceiverPtr->addFeature ("Low Power");
|
||||
theReceiverPtr->addFeature ("Pentium Emulation");
|
||||
return theReceiverPtr;
|
||||
}
|
||||
|
||||
int operate (int a, int b)
|
||||
{
|
||||
return a - b;
|
||||
}
|
||||
|
||||
//////// GPS_Receiver class methods
|
||||
|
||||
GPS_Receiver::GPS_Receiver(const char* name, const char* vendor, float res)
|
||||
{
|
||||
this->name = name;
|
||||
this->features[0] = 0;
|
||||
this->vendor = vendor;
|
||||
this->resolution_meters = res;
|
||||
}
|
||||
|
||||
const char* GPS_Receiver::getName ()
|
||||
{
|
||||
return name;
|
||||
}
|
||||
|
||||
const char* GPS_Receiver::getFeatures ()
|
||||
{
|
||||
if (strlen (features) == 0) return "none";
|
||||
else return features;
|
||||
}
|
||||
|
||||
const char* GPS_Receiver::getVendor ()
|
||||
{
|
||||
return vendor;
|
||||
}
|
||||
|
||||
float GPS_Receiver::getResolutionMeters ()
|
||||
{
|
||||
return resolution_meters;
|
||||
}
|
||||
|
||||
void GPS_Receiver::addFeature (const char *featureName)
|
||||
{
|
||||
if (strlen(features) != 0)
|
||||
strcat (features, ", ");
|
||||
strcat (features, featureName);
|
||||
}
|
||||
|
||||
void GPS_Receiver::print (FILE *fp)
|
||||
{
|
||||
fprintf (fp, "[GPS_Receiver name='%s', vendor='%s', resolution_meters='%.4f', feature_list='%s']", name, vendor, resolution_meters, features);
|
||||
}
|
13
bochs-testing/plugin-test/test12-modglobalconstr2/modules.h
Normal file
13
bochs-testing/plugin-test/test12-modglobalconstr2/modules.h
Normal file
@ -0,0 +1,13 @@
|
||||
extern "C" {
|
||||
// this prevents C++ name mangling
|
||||
class DeviceInterface * module_init ();
|
||||
};
|
||||
|
||||
typedef class DeviceInterface* (*modload_func)(void);
|
||||
|
||||
class DeviceInterface {
|
||||
public:
|
||||
virtual const char* getName () = 0;
|
||||
virtual const char* getFeatures () = 0;
|
||||
virtual void print(FILE *) = 0;
|
||||
};
|
Loading…
x
Reference in New Issue
Block a user