File indexing completed on 2023-11-10 23:34:04
a0b2b1d0f… Alex*0001
0002
0003
0799c1a78… Alex*0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
360a3f914… Jona*0018
a0b2b1d0f… Alex*0019
0020
181cf8b63… Alex*0021 #include "config.h"
0022
28d7d5ba9… Alex*0023 #include <fcntl.h>
4826900a3… Alex*0024 #include <pthread.h>
fedc41174… Alex*0025 #include <stdio.h>
2989895f7… Alex*0026 #include <stdlib.h>
28d7d5ba9… Alex*0027 #include <string.h>
0028 #include <sys/types.h>
0029 #include <sys/stat.h>
0030 #include <unistd.h>
0031 #include <dlfcn.h>
f5e51cfc5… Damj*0032 #include <limits.h>
0033 #ifdef HAVE_SYS_SYSCTL_H
0034 # include <sys/sysctl.h>
0035 #endif
181cf8b63… Alex*0036
b1abca8a5… Alex*0037 #include "main.h"
0038
526522caa… Alex*0039 extern char **environ;
0040
b1abca8a5… Alex*0041
4502eb56b… Alex*0042 const __attribute((visibility("default"))) struct wine_preload_info *wine_main_preload_info = NULL;
181cf8b63… Alex*0043
526522caa… Alex*0044
0045 static char *realpath_dirname( const char *name )
0046 {
0047 char *p, *fullpath = realpath( name, NULL );
0048
0049 if (fullpath)
0050 {
0051 p = strrchr( fullpath, '/' );
0052 if (p == fullpath) p++;
0053 if (p) *p = 0;
0054 }
0055 return fullpath;
0056 }
0057
0058
0059 static char *remove_tail( const char *str, const char *tail )
0060 {
0061 size_t len = strlen( str );
0062 size_t tail_len = strlen( tail );
0063 char *ret;
0064
0065 if (len < tail_len) return NULL;
0066 if (strcmp( str + len - tail_len, tail )) return NULL;
0067 ret = malloc( len - tail_len + 1 );
0068 memcpy( ret, str, len - tail_len );
0069 ret[len - tail_len] = 0;
0070 return ret;
0071 }
0072
0073
0074 static char *build_path( const char *dir, const char *name )
0075 {
0076 size_t len = strlen( dir );
0077 char *ret = malloc( len + strlen( name ) + 2 );
0078
0079 memcpy( ret, dir, len );
0080 if (len && ret[len - 1] != '/') ret[len++] = '/';
0081 strcpy( ret + len, name );
0082 return ret;
0083 }
0084
0085 static const char *get_self_exe( char *argv0 )
0086 {
0087 #if defined(__linux__) || defined(__FreeBSD_kernel__) || defined(__NetBSD__)
0088 return "/proc/self/exe";
0089 #elif defined (__FreeBSD__) || defined(__DragonFly__)
f5e51cfc5… Damj*0090 static int pathname[] = { CTL_KERN, KERN_PROC, KERN_PROC_PATHNAME, -1 };
0091 size_t path_size = PATH_MAX;
0092 char *path = malloc( path_size );
699067ae1… Gera*0093 if (path && !sysctl( pathname, sizeof(pathname)/sizeof(pathname[0]), path, &path_size, NULL, 0 ))
f5e51cfc5… Damj*0094 return path;
0095 free( path );
0096 #endif
0097
526522caa… Alex*0098 if (!strchr( argv0, '/' ))
0099 {
0100 char *p, *path = getenv( "PATH" );
0101
0102 if (!path || !(path = strdup(path))) return NULL;
0103 for (p = strtok( path, ":" ); p; p = strtok( NULL, ":" ))
0104 {
0105 char *name = build_path( p, argv0 );
a75596c94… Mart*0106 if (!access( name, X_OK ))
0107 {
0108 free( path );
0109 return name;
0110 }
526522caa… Alex*0111 free( name );
0112 }
0113 free( path );
a75596c94… Mart*0114 return NULL;
526522caa… Alex*0115 }
0116 return argv0;
0117 }
0118
0119 static void *try_dlopen( const char *dir, const char *name )
0120 {
0121 char *path = build_path( dir, name );
0122 void *handle = dlopen( path, RTLD_NOW );
0123 free( path );
0124 return handle;
0125 }
0126
0127 static void *load_ntdll( char *argv0 )
0128 {
2801d6341… Alex*0129 #ifdef __i386__
0130 #define SO_DIR "i386-unix/"
0131 #elif defined(__x86_64__)
0132 #define SO_DIR "x86_64-unix/"
0133 #elif defined(__arm__)
0134 #define SO_DIR "arm-unix/"
0135 #elif defined(__aarch64__)
0136 #define SO_DIR "aarch64-unix/"
0137 #else
0138 #define SO_DIR ""
0139 #endif
526522caa… Alex*0140 const char *self = get_self_exe( argv0 );
0141 char *path, *p;
0142 void *handle = NULL;
0143
0144 if (self && ((path = realpath_dirname( self ))))
0145 {
0146 if ((p = remove_tail( path, "/loader" )))
0147 {
0148 handle = try_dlopen( p, "dlls/ntdll/ntdll.so" );
0149 free( p );
0150 }
2801d6341… Alex*0151 else handle = try_dlopen( path, BIN_TO_DLLDIR "/" SO_DIR "ntdll.so" );
526522caa… Alex*0152 free( path );
0153 }
0154
0155 if (!handle && (path = getenv( "WINEDLLPATH" )))
0156 {
0157 path = strdup( path );
0158 for (p = strtok( path, ":" ); p; p = strtok( NULL, ":" ))
0159 {
2801d6341… Alex*0160 handle = try_dlopen( p, SO_DIR "ntdll.so" );
0161 if (!handle) handle = try_dlopen( p, "ntdll.so" );
526522caa… Alex*0162 if (handle) break;
0163 }
0164 free( path );
0165 }
0166
2801d6341… Alex*0167 if (!handle && !self) handle = try_dlopen( DLLDIR, SO_DIR "ntdll.so" );
526522caa… Alex*0168
0169 return handle;
0170 }
0171
0172
a0b2b1d0f… Alex*0173
0174
0175
0176 int main( int argc, char *argv[] )
0177 {
526522caa… Alex*0178 void *handle;
b1abca8a5… Alex*0179
50134cce8… Alex*0180 if ((handle = load_ntdll( argv[0] )))
0181 {
0182 void (*init_func)(int, char **, char **) = dlsym( handle, "__wine_main" );
0183 if (init_func) init_func( argc, argv, environ );
0184 fprintf( stderr, "wine: __wine_main function not found in ntdll.so\n" );
0185 exit(1);
0186 }
0187
4826900a3… Alex*0188 fprintf( stderr, "wine: could not load ntdll.so: %s\n", dlerror() );
0189 pthread_detach( pthread_self() );
fedc41174… Alex*0190 exit(1);
a0b2b1d0f… Alex*0191 }