From df12fdb8d4cdf11d9f72a068923a5b0097e36bdb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20M=C3=BCller?= Date: Wed, 28 May 2014 19:50:51 +0200 Subject: [PATCH] loader: Add commandline option --check-libs. --- include/wine/library.h | 2 + libs/wine/config.c | 124 +++++++++++++++++++++++++++++++++++++++++ libs/wine/loader.c | 36 ++++++++++++ libs/wine/wine.map | 2 + loader/main.c | 50 ++++++++++++++++- 5 files changed, 213 insertions(+), 1 deletion(-) diff --git a/include/wine/library.h b/include/wine/library.h index 511bf4722a0..557cec20cf8 100644 --- a/include/wine/library.h +++ b/include/wine/library.h @@ -44,6 +44,7 @@ extern "C" { extern const char *wine_get_build_dir(void); extern const char *wine_get_config_dir(void); extern const char *wine_get_data_dir(void); +extern const char **wine_get_libs(void); extern const char *wine_get_server_dir(void); extern const char *wine_get_user_name(void); extern const char *wine_get_version(void); @@ -56,6 +57,7 @@ extern void wine_exec_wine_binary( const char *name, char **argv, const char *en typedef void (*load_dll_callback_t)( void *, const char * ); +extern int wine_dladdr( void *addr, void *info, char *error, size_t errorsize ); extern void *wine_dlopen( const char *filename, int flag, char *error, size_t errorsize ); extern void *wine_dlsym( void *handle, const char *symbol, char *error, size_t errorsize ); extern int wine_dlclose( void *handle, char *error, size_t errorsize ); diff --git a/libs/wine/config.c b/libs/wine/config.c index 5b66c063db6..e0988513e14 100644 --- a/libs/wine/config.c +++ b/libs/wine/config.c @@ -470,6 +470,130 @@ const char *wine_get_build_dir(void) return build_dir; } +const char *wine_libs[] = { +#ifdef SONAME_LIBCAIRO + SONAME_LIBCAIRO, +#endif +#ifdef SONAME_LIBCAPI20 + SONAME_LIBCAPI20, +#endif +#ifdef SONAME_LIBCUPS + SONAME_LIBCUPS, +#endif +#ifdef SONAME_LIBCURSES + SONAME_LIBCURSES, +#endif +#ifdef SONAME_LIBDBUS_1 + SONAME_LIBDBUS_1, +#endif +#ifdef SONAME_LIBFONTCONFIG + SONAME_LIBFONTCONFIG, +#endif +#ifdef SONAME_LIBFREETYPE + SONAME_LIBFREETYPE, +#endif +#ifdef SONAME_LIBGL + SONAME_LIBGL, +#endif +#ifdef SONAME_LIBGNUTLS + SONAME_LIBGNUTLS, +#endif +#ifdef SONAME_LIBGOBJECT_2_0 + SONAME_LIBGOBJECT_2_0, +#endif +#ifdef SONAME_LIBGSM + SONAME_LIBGSM, +#endif +#ifdef SONAME_LIBGTK_3 + SONAME_LIBGTK_3, +#endif +#ifdef SONAME_LIBHAL + SONAME_LIBHAL, +#endif +#ifdef SONAME_LIBJPEG + SONAME_LIBJPEG, +#endif +#ifdef SONAME_LIBNCURSES + SONAME_LIBNCURSES, +#endif +#ifdef SONAME_LIBNETAPI + SONAME_LIBNETAPI, +#endif +#ifdef SONAME_LIBODBC + SONAME_LIBODBC, +#endif +#ifdef SONAME_LIBOSMESA + SONAME_LIBOSMESA, +#endif +#ifdef SONAME_LIBPCAP + SONAME_LIBPCAP, +#endif +#ifdef SONAME_LIBPNG + SONAME_LIBPNG, +#endif +#ifdef SONAME_LIBSANE + SONAME_LIBSANE, +#endif +#ifdef SONAME_LIBTIFF + SONAME_LIBTIFF, +#endif +#ifdef SONAME_LIBTXC_DXTN + SONAME_LIBTXC_DXTN, +#endif +#ifdef SONAME_LIBV4L1 + SONAME_LIBV4L1, +#endif +#ifdef SONAME_LIBVA + SONAME_LIBVA, +#endif +#ifdef SONAME_LIBVA_DRM + SONAME_LIBVA_DRM, +#endif +#ifdef SONAME_LIBVA_X11 + SONAME_LIBVA_X11, +#endif +#ifdef SONAME_LIBX11 + SONAME_LIBX11, +#endif +#ifdef SONAME_LIBX11_XCB + SONAME_LIBX11_XCB, +#endif +#ifdef SONAME_LIBXCOMPOSITE + SONAME_LIBXCOMPOSITE, +#endif +#ifdef SONAME_LIBXCURSOR + SONAME_LIBXCURSOR, +#endif +#ifdef SONAME_LIBXEXT + SONAME_LIBXEXT, +#endif +#ifdef SONAME_LIBXI + SONAME_LIBXI, +#endif +#ifdef SONAME_LIBXINERAMA + SONAME_LIBXINERAMA, +#endif +#ifdef SONAME_LIBXRANDR + SONAME_LIBXRANDR, +#endif +#ifdef SONAME_LIBXRENDER + SONAME_LIBXRENDER, +#endif +#ifdef SONAME_LIBXSLT + SONAME_LIBXSLT, +#endif +#ifdef SONAME_LIBXXF86VM + SONAME_LIBXXF86VM, +#endif + NULL +}; + +/* return the list of shared libs used by wine */ +const char **wine_get_libs(void) +{ + return &wine_libs[0]; +} + /* return the full name of the server directory (the one containing the socket) */ const char *wine_get_server_dir(void) { diff --git a/libs/wine/loader.c b/libs/wine/loader.c index 2a569f5b739..5f10c3f9d3e 100644 --- a/libs/wine/loader.c +++ b/libs/wine/loader.c @@ -1072,6 +1072,42 @@ void *wine_dlopen( const char *filename, int flag, char *error, size_t errorsize return ret; } +/*********************************************************************** + * wine_dladdr + */ +int wine_dladdr( void *addr, void *info, char *error, size_t errorsize ) +{ +#ifdef HAVE_DLADDR + int ret; + const char *s; + dlerror(); dlerror(); + ret = dladdr( addr, (Dl_info *)info ); + s = dlerror(); + if (error && errorsize) + { + if (s) + { + size_t len = strlen(s); + if (len >= errorsize) len = errorsize - 1; + memcpy( error, s, len ); + error[len] = 0; + } + else error[0] = 0; + } + dlerror(); + return ret; +#else + if (error) + { + static const char msg[] = "dladdr interface not detected by configure"; + size_t len = min( errorsize, sizeof(msg) ); + memcpy( error, msg, len ); + error[len - 1] = 0; + } + return 0; +#endif +} + /*********************************************************************** * wine_dlsym */ diff --git a/libs/wine/wine.map b/libs/wine/wine.map index ca46979f5b9..22a4e73b05b 100644 --- a/libs/wine/wine.map +++ b/libs/wine/wine.map @@ -9,6 +9,7 @@ WINE_1.0 wine_anon_mmap; wine_casemap_lower; wine_casemap_upper; + wine_dladdr; wine_dlclose; wine_dll_enum_load_path; wine_dll_set_callback; @@ -24,6 +25,7 @@ WINE_1.0 wine_get_es; wine_get_fs; wine_get_gs; + wine_get_libs; wine_get_server_dir; wine_get_ss; wine_get_user_name; diff --git a/loader/main.c b/loader/main.c index d97d6b28bf8..49dc996e354 100644 --- a/loader/main.c +++ b/loader/main.c @@ -36,6 +36,12 @@ #ifdef HAVE_UNISTD_H # include #endif +#ifdef HAVE_DLADDR +# include +#endif +#ifdef HAVE_LINK_H +# include +#endif #include "wine/library.h" #include "main.h" @@ -54,7 +60,8 @@ static void check_command_line( int argc, char *argv[] ) "Usage: wine PROGRAM [ARGUMENTS...] Run the specified program\n" " wine --help Display this help and exit\n" " wine --version Output version information and exit\n" - " wine --patches Output patch information and exit"; + " wine --patches Output patch information and exit\n" + " wine --check-libs Checks if shared libs are installed"; if (argc <= 1) { @@ -110,6 +117,47 @@ static void check_command_line( int argc, char *argv[] ) exit(0); } + if (!strcmp( argv[1], "--check-libs" )) + { + void* lib_handle; + int ret = 0; + const char **wine_libs = wine_get_libs(); + + for(; *wine_libs; wine_libs++) + { + lib_handle = wine_dlopen( *wine_libs, RTLD_NOW, NULL, 0 ); + if (lib_handle) + { + #ifdef HAVE_DLADDR + Dl_info libinfo; + void* symbol; + + #ifdef HAVE_LINK_H + struct link_map *lm = (struct link_map *)lib_handle; + symbol = (void *)lm->l_addr; + #else + symbol = wine_dlsym( lib_handle, "_init", NULL, 0 ); + #endif + if (symbol && wine_dladdr( symbol, &libinfo, NULL, 0 )) + { + printf( "%s: %s\n", *wine_libs, libinfo.dli_fname ); + } + else + #endif + { + printf( "%s: found\n", *wine_libs ); + } + wine_dlclose( lib_handle, NULL, 0 ); + } + else + { + printf( "%s: missing\n", *wine_libs ); + ret = 1; + } + } + + exit(ret); + } } -- 2.25.1