Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
W
wine-cw
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
wine
wine-cw
Commits
e6758871
Commit
e6758871
authored
Dec 13, 2000
by
James Abbatiello
Committed by
Alexandre Julliard
Dec 13, 2000
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Work around glibc 2.1.x dlopen bug (again).
parent
559f4321
Hide whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
149 additions
and
73 deletions
+149
-73
proxyodbc.c
dlls/odbc32/proxyodbc.c
+11
-12
library.h
include/wine/library.h
+1
-1
port.h
include/wine/port.h
+12
-0
loader.c
library/loader.c
+10
-27
port.c
library/port.c
+98
-0
elf.c
loader/elf.c
+9
-13
module.c
loader/module.c
+1
-1
builtin32.c
relay32/builtin32.c
+7
-19
No files found.
dlls/odbc32/proxyodbc.c
View file @
e6758871
...
...
@@ -11,11 +11,11 @@
#include <stdio.h>
#include <stdlib.h>
#include <dlfcn.h>
#include <string.h>
#include "winbase.h"
#include "debugtools.h"
#include "wine/port.h"
#include "sql.h"
#include "sqltypes.h"
...
...
@@ -164,7 +164,7 @@ MAIN_OdbcInit(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
if
(
gProxyHandle
.
dmHandle
)
{
dlclose
(
gProxyHandle
.
dmHandle
);
wine_dlclose
(
gProxyHandle
.
dmHandle
,
NULL
,
0
);
gProxyHandle
.
dmHandle
=
NULL
;
}
}
...
...
@@ -186,6 +186,7 @@ MAIN_OdbcInit(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
BOOL
ODBC_LoadDriverManager
()
{
char
*
s
=
getenv
(
"LIB_ODBC_DRIVER_MANAGER"
);
char
error
[
256
];
TRACE
(
"
\n
"
);
...
...
@@ -196,13 +197,11 @@ BOOL ODBC_LoadDriverManager()
else
strcpy
(
gProxyHandle
.
dmLibName
,
"libodbc.so"
);
dlerror
();
/* clear dlerror first */
gProxyHandle
.
dmHandle
=
dlopen
(
gProxyHandle
.
dmLibName
,
RTLD_LAZY
);
gProxyHandle
.
dmHandle
=
wine_dlopen
(
gProxyHandle
.
dmLibName
,
RTLD_LAZY
,
error
,
sizeof
(
error
));
if
(
gProxyHandle
.
dmHandle
==
NULL
)
/* fail to load unixODBC driver manager */
{
const
char
*
err
=
dlerror
();
WARN
(
"failed to open library %s: %s
\n
"
,
gProxyHandle
.
dmLibName
,
err
);
WARN
(
"failed to open library %s: %s
\n
"
,
gProxyHandle
.
dmLibName
,
error
);
gProxyHandle
.
dmLibName
[
0
]
=
'\0'
;
gProxyHandle
.
nErrorType
=
ERROR_LIBRARY_NOT_FOUND
;
return
FALSE
;
...
...
@@ -228,18 +227,18 @@ BOOL ODBC_LoadDriverManager()
BOOL
ODBC_LoadDMFunctions
()
{
int
i
;
char
error
[
256
];
if
(
gProxyHandle
.
dmHandle
==
NULL
)
return
FALSE
;
dlerror
();
/* clear dlerror first */
for
(
i
=
0
;
i
<
NUM_SQLFUNC
;
i
++
)
{
gProxyHandle
.
functions
[
i
]
=
template_func
[
i
];
gProxyHandle
.
functions
[
i
].
func
=
dlsym
(
gProxyHandle
.
dmHandle
,
gProxyHandle
.
functions
[
i
].
name
);
gProxyHandle
.
functions
[
i
].
func
=
wine_
dlsym
(
gProxyHandle
.
dmHandle
,
gProxyHandle
.
functions
[
i
].
name
,
error
,
sizeof
(
error
)
);
if
(
dlerror
()
)
if
(
error
[
0
]
)
{
ERR
(
"Failed to load function %s"
,
gProxyHandle
.
functions
[
i
].
name
);
gProxyHandle
.
functions
[
i
].
func
=
SQLDummyFunc
;
...
...
@@ -739,7 +738,7 @@ SQLRETURN WINAPI SQLFreeEnv(SQLHENV EnvironmentHandle)
/*
if (gProxyHandle.dmHandle)
{
dlclose(gProxyHandle.dmHandle
);
wine_dlclose(gProxyHandle.dmHandle,NULL,0
);
gProxyHandle.dmHandle = NULL;
}
*/
...
...
@@ -769,7 +768,7 @@ SQLRETURN WINAPI SQLFreeHandle(SQLSMALLINT HandleType, SQLHANDLE Handle)
{
if
(
gProxyHandle
.
dmHandle
)
{
dlclose
(
gProxyHandle
.
dmHandle
);
wine_dlclose
(
gProxyHandle
.
dmHandle
,
NULL
,
0
);
gProxyHandle
.
dmHandle
=
NULL
;
}
}
...
...
include/wine/library.h
View file @
e6758871
...
...
@@ -15,7 +15,7 @@
typedef
void
(
*
load_dll_callback_t
)(
void
*
,
const
char
*
);
extern
void
wine_dll_set_callback
(
load_dll_callback_t
load
);
extern
void
*
wine_dll_load
(
const
char
*
filename
);
extern
void
*
wine_dll_load
(
const
char
*
filename
,
char
*
error
,
int
errorsize
);
extern
void
*
wine_dll_load_main_exe
(
const
char
*
name
,
int
search_path
);
extern
void
wine_dll_unload
(
void
*
handle
);
...
...
include/wine/port.h
View file @
e6758871
...
...
@@ -130,4 +130,16 @@ int lstat(const char *file_name, struct stat *buf);
#define S_ISLNK(mod) (0)
#endif
/* S_ISLNK */
extern
void
*
wine_dlopen
(
const
char
*
filename
,
int
flag
,
char
*
error
,
int
errorsize
);
extern
void
*
wine_dlsym
(
void
*
handle
,
const
char
*
symbol
,
char
*
error
,
int
errorsize
);
extern
int
wine_dlclose
(
void
*
handle
,
char
*
error
,
int
errorsize
);
#ifdef HAVE_DL_API
#include <dlfcn.h>
#else
#define RTLD_LAZY 0x001
#define RTLD_NOW 0x002
#define RTLD_GLOBAL 0x100
#endif
#endif
/* !defined(__WINE_WINE_PORT_H) */
library/loader.c
View file @
e6758871
...
...
@@ -15,9 +15,6 @@
#ifdef HAVE_SYS_MMAN_H
#include <sys/mman.h>
#endif
#ifdef HAVE_DL_API
#include <dlfcn.h>
#endif
#include "winnt.h"
#include "wine/library.h"
...
...
@@ -79,18 +76,14 @@ static void build_dll_path(void)
/* open a library for a given dll, searching in the dll path
* 'name' must be the Windows dll name (e.g. "kernel32.dll") */
static
void
*
dlopen_dll
(
const
char
*
name
)
static
void
*
dlopen_dll
(
const
char
*
name
,
char
*
error
,
int
errorsize
)
{
#ifdef HAVE_DL_API
int
i
,
namelen
=
strlen
(
name
);
char
*
buffer
,
*
p
,
*
ext
;
void
*
ret
=
NULL
;
if
(
!
init_done
)
build_dll_path
();
/* clear dlerror to avoid glibc bug */
dlerror
();
buffer
=
malloc
(
dll_path_maxlen
+
namelen
+
8
);
/* store the name at the end of the buffer, prefixed by /lib and followed by .so */
...
...
@@ -109,17 +102,14 @@ static void *dlopen_dll( const char *name )
int
len
=
strlen
(
dll_paths
[
i
]);
char
*
p
=
buffer
+
dll_path_maxlen
-
len
;
memcpy
(
p
,
dll_paths
[
i
],
len
);
if
((
ret
=
dlopen
(
p
,
RTLD_NOW
)))
break
;
dlerror
();
/* clear dlerror to avoid glibc bug */
if
((
ret
=
wine_dlopen
(
p
,
RTLD_NOW
,
error
,
errorsize
)))
break
;
}
/* now try the default dlopen search path */
if
(
!
ret
)
ret
=
dlopen
(
buffer
+
dll_path_maxlen
+
1
,
RTLD_NOW
);
if
(
!
ret
)
ret
=
wine_dlopen
(
buffer
+
dll_path_maxlen
+
1
,
RTLD_NOW
,
error
,
errorsize
);
free
(
buffer
);
return
ret
;
#else
return
NULL
;
#endif
}
...
...
@@ -318,7 +308,7 @@ void wine_dll_set_callback( load_dll_callback_t load )
*
* Load a builtin dll.
*/
void
*
wine_dll_load
(
const
char
*
filename
)
void
*
wine_dll_load
(
const
char
*
filename
,
char
*
error
,
int
errorsize
)
{
int
i
;
...
...
@@ -338,7 +328,7 @@ void *wine_dll_load( const char *filename )
return
(
void
*
)
1
;
}
}
return
dlopen_dll
(
filename
);
return
dlopen_dll
(
filename
,
error
,
errorsize
);
}
...
...
@@ -349,9 +339,8 @@ void *wine_dll_load( const char *filename )
*/
void
wine_dll_unload
(
void
*
handle
)
{
#ifdef HAVE_DL_API
if
(
handle
!=
(
void
*
)
1
)
dlclose
(
handle
);
#endif
if
(
handle
!=
(
void
*
)
1
)
wine_dlclose
(
handle
,
NULL
,
0
);
}
...
...
@@ -359,20 +348,17 @@ void wine_dll_unload( void *handle )
* wine_dll_load_main_exe
*
* Try to load the .so for the main exe, optionally searching for it in PATH.
* Note: dlerror() is cleared before returning because of a glibc bug.
*/
void
*
wine_dll_load_main_exe
(
const
char
*
name
,
int
search_path
)
{
void
*
ret
=
NULL
;
#ifdef HAVE_DL_API
const
char
*
path
=
NULL
;
if
(
search_path
)
path
=
getenv
(
"PATH"
);
if
(
!
path
)
{
/* no path, try only the specified name */
dlerror
();
/* clear dlerror to avoid glibc bug */
ret
=
dlopen
(
name
,
RTLD_NOW
);
ret
=
wine_dlopen
(
name
,
RTLD_NOW
,
NULL
,
0
);
}
else
{
...
...
@@ -394,8 +380,7 @@ void *wine_dll_load_main_exe( const char *name, int search_path )
if
((
len
=
p
-
path
)
>
0
)
{
memcpy
(
basename
-
len
,
path
,
len
);
dlerror
();
/* clear dlerror to avoid glibc bug */
if
((
ret
=
dlopen
(
basename
-
len
,
RTLD_NOW
)))
break
;
if
((
ret
=
wine_dlopen
(
basename
-
len
,
RTLD_NOW
,
NULL
,
0
)))
break
;
}
if
(
!*
p
)
break
;
path
=
p
+
1
;
...
...
@@ -403,7 +388,5 @@ void *wine_dll_load_main_exe( const char *name, int search_path )
if
(
tmp
!=
buffer
)
free
(
tmp
);
}
}
if
(
!
ret
)
dlerror
();
/* clear dlerror to avoid glibc bug */
#endif
/* HAVE_DL_API */
return
ret
;
}
library/port.c
View file @
e6758871
...
...
@@ -38,6 +38,9 @@
#ifdef HAVE_LIBUTIL_H
# include <libutil.h>
#endif
#ifdef HAVE_DL_API
# include <dlfcn.h>
#endif
#include "wine/port.h"
...
...
@@ -411,3 +414,98 @@ void *wine_anon_mmap( void *start, size_t size, int prot, int flags )
#endif
return
mmap
(
start
,
size
,
prot
,
flags
,
fdzero
,
0
);
}
/*
* These functions provide wrappers around dlopen() and associated
* functions. They work around a bug in glibc 2.1.x where calling
* a dl*() function after a previous dl*() function has failed
* without a dlerror() call between the two will cause a crash.
* They all take a pointer to a buffer that
* will receive the error description (from dlerror()). This
* parameter may be NULL if the error description is not required.
*/
/***********************************************************************
* wine_dlopen
*/
void
*
wine_dlopen
(
const
char
*
filename
,
int
flag
,
char
*
error
,
int
errorsize
)
{
#ifdef HAVE_DL_API
void
*
ret
;
char
*
s
;
dlerror
();
dlerror
();
ret
=
dlopen
(
filename
,
flag
);
s
=
dlerror
();
if
(
error
)
{
strncpy
(
error
,
s
?
s
:
""
,
errorsize
);
error
[
errorsize
-
1
]
=
'\0'
;
}
dlerror
();
return
ret
;
#else
if
(
error
)
{
strncpy
(
error
,
"dlopen interface not detected by configure"
,
errorsize
);
error
[
errorsize
-
1
]
=
'\0'
;
}
return
NULL
;
#endif
}
/***********************************************************************
* wine_dlsym
*/
void
*
wine_dlsym
(
void
*
handle
,
const
char
*
symbol
,
char
*
error
,
int
errorsize
)
{
#ifdef HAVE_DL_API
void
*
ret
;
char
*
s
;
dlerror
();
dlerror
();
ret
=
dlsym
(
handle
,
symbol
);
s
=
dlerror
();
if
(
error
)
{
strncpy
(
error
,
s
?
s
:
""
,
errorsize
);
error
[
errorsize
-
1
]
=
'\0'
;
}
dlerror
();
return
ret
;
#else
if
(
error
)
{
strncpy
(
error
,
"dlopen interface not detected by configure"
,
errorsize
);
error
[
errorsize
-
1
]
=
'\0'
;
}
return
NULL
;
#endif
}
/***********************************************************************
* wine_dlclose
*/
int
wine_dlclose
(
void
*
handle
,
char
*
error
,
int
errorsize
)
{
#ifdef HAVE_DL_API
int
ret
;
char
*
s
;
dlerror
();
dlerror
();
ret
=
dlclose
(
handle
);
s
=
dlerror
();
if
(
error
)
{
strncpy
(
error
,
s
?
s
:
""
,
errorsize
);
error
[
errorsize
-
1
]
=
'\0'
;
}
dlerror
();
return
ret
;
#else
if
(
error
)
{
strncpy
(
error
,
"dlopen interface not detected by configure"
,
errorsize
);
error
[
errorsize
-
1
]
=
'\0'
;
}
return
1
;
#endif
}
loader/elf.c
View file @
e6758871
...
...
@@ -22,6 +22,7 @@
#include "module.h"
#include "debugtools.h"
#include "winerror.h"
#include "wine/port.h"
DEFAULT_DEBUG_CHANNEL
(
win32
);
...
...
@@ -49,8 +50,6 @@ typedef struct {
sizeof(IMAGE_NT_HEADERS) + \
sizeof(IMAGE_SECTION_HEADER))
#include <dlfcn.h>
static
FARPROC
ELF_FindExportedFunction
(
WINE_MODREF
*
wm
,
LPCSTR
funcName
,
BOOL
snoop
);
static
HMODULE
ELF_CreateDummyModule
(
LPCSTR
libname
,
LPCSTR
modname
)
...
...
@@ -109,6 +108,7 @@ WINE_MODREF *ELF_LoadLibraryExA( LPCSTR libname, DWORD flags)
HMODULE
hmod
;
char
*
modname
,
*
s
,
*
t
,
*
x
;
LPVOID
*
dlhandle
;
char
error
[
256
];
t
=
HeapAlloc
(
GetProcessHeap
(),
HEAP_ZERO_MEMORY
,
strlen
(
libname
)
+
strlen
(
"lib.so"
)
+
1
);
...
...
@@ -152,10 +152,9 @@ WINE_MODREF *ELF_LoadLibraryExA( LPCSTR libname, DWORD flags)
points to the ENTIRE DOS filename of the library
t is returned by HeapAlloc() above and so is also used
with HeapFree() below */
dlerror
();
/* clear dlerror because of glibc bug */
dlhandle
=
dlopen
(
s
,
RTLD_NOW
);
dlhandle
=
wine_dlopen
(
s
,
RTLD_NOW
,
error
,
sizeof
(
error
));
if
(
!
dlhandle
)
{
dlerror
();
/* clear dlerror because of glibc bug */
WARN
(
"failed to load %s: %s
\n
"
,
s
,
error
);
HeapFree
(
GetProcessHeap
(),
0
,
t
);
SetLastError
(
ERROR_FILE_NOT_FOUND
);
return
NULL
;
...
...
@@ -176,22 +175,20 @@ static FARPROC ELF_FindExportedFunction( WINE_MODREF *wm, LPCSTR funcName, BOOL
LPVOID
fun
;
int
i
,
nrofargs
=
0
;
ELF_STDCALL_STUB
*
stub
,
*
first_stub
;
char
error
[
256
];
if
(
!
HIWORD
(
funcName
))
{
ERR
(
"Can't import from UNIX dynamic libs by ordinal, sorry.
\n
"
);
return
(
FARPROC
)
0
;
}
dlerror
();
/* clear dlerror() first */
fun
=
dlsym
(
wm
->
dlhandle
,
funcName
);
fun
=
wine_dlsym
(
wm
->
dlhandle
,
funcName
,
error
,
sizeof
(
error
));
if
(
!
fun
)
{
dlerror
();
/* clear dlerror() to avoid glibc bug */
/* we sometimes have an excess '_' at the beginning of the name */
if
(
funcName
[
0
]
==
'_'
)
{
funcName
++
;
fun
=
dlsym
(
wm
->
dlhandle
,
funcName
);
if
(
!
fun
)
dlerror
();
/* clear dlerror() to avoid glibc bug */
fun
=
wine_dlsym
(
wm
->
dlhandle
,
funcName
,
error
,
sizeof
(
error
));
}
}
if
(
!
fun
)
{
...
...
@@ -205,8 +202,7 @@ static FARPROC ELF_FindExportedFunction( WINE_MODREF *wm, LPCSTR funcName, BOOL
*
t
=
'\0'
;
nrofargs
=
0
;
sscanf
(
t
+
1
,
"%d"
,
&
nrofargs
);
fun
=
dlsym
(
wm
->
dlhandle
,
fn
);
if
(
!
fun
)
dlerror
();
/* clear dlerror() to avoid glibc bug */
fun
=
wine_dlsym
(
wm
->
dlhandle
,
fn
,
error
,
sizeof
(
error
));
HeapFree
(
GetProcessHeap
(),
0
,
fn
);
}
}
...
...
@@ -266,7 +262,7 @@ static FARPROC ELF_FindExportedFunction( WINE_MODREF *wm, LPCSTR funcName, BOOL
fun
=
(
FARPROC
)
stub
;
}
if
(
!
fun
)
{
FIXME
(
"function %s not found: %s
\n
"
,
funcName
,
dlerror
()
);
FIXME
(
"function %s not found: %s
\n
"
,
funcName
,
error
);
return
fun
;
}
fun
=
SNOOP_GetProcAddress
(
wm
->
module
,
funcName
,
stub
-
first_stub
,
fun
);
...
...
loader/module.c
View file @
e6758871
...
...
@@ -1505,7 +1505,7 @@ static void MODULE_FlushModrefs(void)
TRACE
(
" unloading %s
\n
"
,
wm
->
filename
);
/* VirtualFree( (LPVOID)wm->module, 0, MEM_RELEASE ); */
/* FIXME */
/* if (wm->dlhandle)
dlclose( wm->dlhandle
); */
/* FIXME */
/* if (wm->dlhandle)
wine_dlclose( wm->dlhandle, NULL, 0
); */
/* FIXME */
FreeLibrary16
(
wm
->
hDummyMod
);
HeapFree
(
GetProcessHeap
(),
0
,
wm
->
deps
);
HeapFree
(
GetProcessHeap
(),
0
,
wm
->
filename
);
...
...
relay32/builtin32.c
View file @
e6758871
...
...
@@ -10,9 +10,6 @@
#include <string.h>
#include <stdio.h>
#include <ctype.h>
#ifdef HAVE_DL_API
#include <dlfcn.h>
#endif
#include <sys/types.h>
#ifdef HAVE_SYS_MMAN_H
#include <sys/mman.h>
...
...
@@ -40,24 +37,17 @@ static HMODULE main_module;
*/
void
*
BUILTIN32_dlopen
(
const
char
*
name
)
{
#ifdef HAVE_DL_API
void
*
handle
;
char
error
[
256
];
if
(
!
(
handle
=
wine_dll_load
(
name
)))
if
(
!
(
handle
=
wine_dll_load
(
name
,
error
,
sizeof
(
error
)
)))
{
LPSTR
pErr
;
if
((
pErr
=
dlerror
()))
{
if
(
strstr
(
pErr
,
"undefined symbol"
))
/* undef symbol -> ERR() */
ERR
(
"failed to load %s: %s
\n
"
,
name
,
pErr
);
else
/* WARN() for libraries that are supposed to be native */
WARN
(
"failed to load %s: %s
\n
"
,
name
,
pErr
);
}
if
(
strstr
(
error
,
"undefined symbol"
))
/* undef symbol -> ERR() */
ERR
(
"failed to load %s: %s
\n
"
,
name
,
error
);
else
/* WARN() for libraries that are supposed to be native */
WARN
(
"failed to load %s: %s
\n
"
,
name
,
error
);
}
return
handle
;
#else
return
NULL
;
#endif
}
/***********************************************************************
...
...
@@ -65,10 +55,8 @@ void *BUILTIN32_dlopen( const char *name )
*/
int
BUILTIN32_dlclose
(
void
*
handle
)
{
#ifdef HAVE_DL_API
/* FIXME: should unregister descriptors first */
/* return dlclose( handle ); */
#endif
/* wine_dll_unload( handle ); */
return
0
;
}
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment