aboutsummaryrefslogtreecommitdiff
path: root/test.c
diff options
context:
space:
mode:
authorPali Rohár <pali.rohar@gmail.com>2019-01-29 22:57:04 +0100
committerPali Rohár <pali.rohar@gmail.com>2019-02-14 09:25:21 +0100
commit63d7bda42322bb0916e30bc547123a8330a4dcc2 (patch)
tree71d0ea65a3c604982b20445384392fbdbce6d136 /test.c
parent29c46a54ffa31513be1a2cdcd9e8a55938d6e549 (diff)
downloaddlfcn-win32-63d7bda42322bb0916e30bc547123a8330a4dcc2.tar.gz
dlfcn-win32-63d7bda42322bb0916e30bc547123a8330a4dcc2.tar.bz2
dlfcn-win32-63d7bda42322bb0916e30bc547123a8330a4dcc2.zip
Implement support for dlsym() with RTLD_DEFAULT and RTLD_NEXT
dlsym() with RTLD_DEFAULT handle behaves in same way like with global handle returned by dlopen() with NULL file name. dlsym() with RTLD_NEXT handle search for next loaded module which provides specified symbol. "Next" means module which in EnumProcessModules() result after the module which called dlsym(). To get caller function of dlsym() use _ReturnAddress() intrinsic. To get module where is caller function use the fact that HMODULE is the same value as the module's base address. When compiling under gcc, defines _ReturnAddress() macro via gcc's builtin as it does not provide MSC's specific _ReturnAddress() intrinsic. Added tests demonstrate that both RTLD_DEFAULT and RTLD_NEXT are working as expected.
Diffstat (limited to 'test.c')
-rw-r--r--test.c60
1 files changed, 60 insertions, 0 deletions
diff --git a/test.c b/test.c
index 10c655e..814aca1 100644
--- a/test.c
+++ b/test.c
@@ -73,10 +73,13 @@
73int main() 73int main()
74{ 74{
75 void *global; 75 void *global;
76 void *library2;
76 void *library; 77 void *library;
77 char *error; 78 char *error;
78 int (*function)( void ); 79 int (*function)( void );
80 int (*function2_from_library2)( void );
79 size_t (*fwrite_local) ( const void *, size_t, size_t, FILE * ); 81 size_t (*fwrite_local) ( const void *, size_t, size_t, FILE * );
82 size_t (*fputs_default) ( const char *, FILE * );
80 int (*nonexistentfunction)( void ); 83 int (*nonexistentfunction)( void );
81 int ret; 84 int ret;
82 HMODULE library3; 85 HMODULE library3;
@@ -90,6 +93,16 @@ int main()
90 _CrtSetReportFile(_CRT_ASSERT, _CRTDBG_FILE_STDOUT); 93 _CrtSetReportFile(_CRT_ASSERT, _CRTDBG_FILE_STDOUT);
91#endif 94#endif
92 95
96 library2 = dlopen( "testdll2.dll", RTLD_GLOBAL );
97 if( !library2 )
98 {
99 error = dlerror( );
100 printf( "ERROR\tCould not open library2 globally: %s\n", error ? error : "" );
101 RETURN_ERROR;
102 }
103 else
104 printf( "SUCCESS\tOpened library2 globally: %p\n", library2 );
105
93 library = dlopen( "testdll.dll", RTLD_GLOBAL ); 106 library = dlopen( "testdll.dll", RTLD_GLOBAL );
94 if( !library ) 107 if( !library )
95 { 108 {
@@ -127,6 +140,22 @@ int main()
127 fwrite_local(hello_world,sizeof(char),strlen(hello_world),stderr); 140 fwrite_local(hello_world,sizeof(char),strlen(hello_world),stderr);
128 fflush(stderr); 141 fflush(stderr);
129 142
143 fputs_default = dlsym(RTLD_DEFAULT, "fputs");
144 if (!fputs_default)
145 {
146 error = dlerror();
147 printf("ERROR\tCould not get symbol from default handle: %s\n",
148 error ? error : "");
149 CLOSE_LIB;
150 CLOSE_GLOBAL;
151 RETURN_ERROR;
152 }
153 else
154 printf("SUCCESS\tGot symbol from default handle: %p\n", fputs_default);
155 char * hello_world_fputs = "Hello world from default fputs!\n";
156 fputs_default(hello_world_fputs, stderr);
157 fflush(stderr);
158
130 function = dlsym( library, "function" ); 159 function = dlsym( library, "function" );
131 if( !function ) 160 if( !function )
132 { 161 {
@@ -142,6 +171,27 @@ int main()
142 171
143 RUNFUNC; 172 RUNFUNC;
144 173
174 function2_from_library2 = dlsym( library2, "function2" );
175 if( !function2_from_library2 )
176 {
177 error = dlerror( );
178 printf( "ERROR\tCould not get symbol from library2 handle: %s\n",
179 error ? error : "" );
180 CLOSE_LIB;
181 CLOSE_GLOBAL;
182 RETURN_ERROR;
183 }
184 else
185 printf( "SUCCESS\tGot symbol from library2 handle: %p\n", function2_from_library2 );
186
187 ret = function2_from_library2 ();
188 if( ret != 2 )
189 {
190 CLOSE_LIB;
191 CLOSE_GLOBAL;
192 RETURN_ERROR;
193 }
194
145 nonexistentfunction = dlsym( library, "nonexistentfunction" ); 195 nonexistentfunction = dlsym( library, "nonexistentfunction" );
146 if( nonexistentfunction ) 196 if( nonexistentfunction )
147 { 197 {
@@ -197,6 +247,16 @@ int main()
197 else 247 else
198 printf( "SUCCESS\tClosed library.\n" ); 248 printf( "SUCCESS\tClosed library.\n" );
199 249
250 ret = dlclose( library2 );
251 if( ret )
252 {
253 error = dlerror( );
254 printf( "ERROR\tCould not close library2: %s\n", error ? error : "" );
255 RETURN_ERROR;
256 }
257 else
258 printf( "SUCCESS\tClosed library2.\n" );
259
200 library = dlopen( "testdll.dll", RTLD_LOCAL ); 260 library = dlopen( "testdll.dll", RTLD_LOCAL );
201 if( !library ) 261 if( !library )
202 { 262 {