Mercurial > mplayer.hg
annotate loader/elfdll.c @ 25778:15c5da485a77
Remove a broken and useless hack to avoid a memcpy
author | reimar |
---|---|
date | Sat, 19 Jan 2008 16:49:01 +0000 |
parents | dfeedb0580f0 |
children | b70f5ac9c001 |
rev | line source |
---|---|
1 | 1 /* |
2 * Elf-dll loader functions | |
3 * | |
4 * Copyright 1999 Bertho A. Stultiens | |
15166
f5537cc95b02
Mark modified imported files as such to comply with GPL ¡ø2a.
diego
parents:
7386
diff
changeset
|
5 * |
18783 | 6 * Modified for use with MPlayer, detailed changelog at |
7 * http://svn.mplayerhq.hu/mplayer/trunk/ | |
15166
f5537cc95b02
Mark modified imported files as such to comply with GPL ¡ø2a.
diego
parents:
7386
diff
changeset
|
8 * $Id$ |
f5537cc95b02
Mark modified imported files as such to comply with GPL ¡ø2a.
diego
parents:
7386
diff
changeset
|
9 * |
1 | 10 */ |
7386 | 11 #include "config.h" |
1 | 12 |
13 #ifdef HAVE_LIBDL | |
14 | |
7386 | 15 #include "wine/windef.h" |
16 #include "wine/module.h" | |
17 #include "wine/heap.h" | |
18 #include "wine/elfdll.h" | |
19 #include "wine/debugtools.h" | |
20 #include "wine/winerror.h" | |
25773 | 21 #include "debug.h" |
1 | 22 |
23 //DEFAULT_DEBUG_CHANNEL(elfdll) | |
24 | |
2139 | 25 #include <stdio.h> |
26 #include <stdlib.h> | |
27 #include <string.h> | |
28 #include <ctype.h> | |
1 | 29 #include <dlfcn.h> |
30 | |
31 | |
32 //WINE_MODREF *local_wm=NULL; | |
33 extern modref_list* local_wm; | |
34 | |
35 | |
36 /*------------------ HACKS -----------------*/ | |
37 extern DWORD fixup_imports(WINE_MODREF *wm); | |
38 extern void dump_exports(HMODULE hModule); | |
39 /*---------------- END HACKS ---------------*/ | |
40 | |
41 //char *extra_ld_library_path = "/usr/lib/win32"; | |
42 extern char* def_path; | |
43 | |
44 struct elfdll_image | |
45 { | |
46 HMODULE pe_module_start; | |
47 DWORD pe_module_size; | |
48 }; | |
49 | |
50 | |
51 /**************************************************************************** | |
52 * ELFDLL_dlopen | |
53 * | |
54 * Wrapper for dlopen to search the EXTRA_LD_LIBRARY_PATH from wine.conf | |
55 * manually because libdl.so caches the environment and does not accept our | |
56 * changes. | |
57 */ | |
58 void *ELFDLL_dlopen(const char *libname, int flags) | |
59 { | |
60 char buffer[256]; | |
61 int namelen; | |
62 void *handle; | |
63 char *ldpath; | |
64 | |
65 /* First try the default path search of dlopen() */ | |
66 handle = dlopen(libname, flags); | |
67 if(handle) | |
68 return handle; | |
69 | |
70 /* Now try to construct searches through our extra search-path */ | |
71 namelen = strlen(libname); | |
72 ldpath = def_path; | |
73 while(ldpath && *ldpath) | |
74 { | |
75 int len; | |
76 char *cptr; | |
77 char *from; | |
78 | |
79 from = ldpath; | |
80 cptr = strchr(ldpath, ':'); | |
81 if(!cptr) | |
82 { | |
83 len = strlen(ldpath); | |
84 ldpath = NULL; | |
85 } | |
86 else | |
87 { | |
88 len = cptr - ldpath; | |
89 ldpath = cptr + 1; | |
90 } | |
91 | |
92 if(len + namelen + 1 >= sizeof(buffer)) | |
93 { | |
94 ERR("Buffer overflow! Check EXTRA_LD_LIBRARY_PATH or increase buffer size.\n"); | |
95 return NULL; | |
96 } | |
97 | |
98 strncpy(buffer, from, len); | |
99 if(len) | |
100 { | |
101 buffer[len] = '/'; | |
102 strcpy(buffer + len + 1, libname); | |
103 } | |
104 else | |
105 strcpy(buffer + len, libname); | |
106 | |
107 TRACE("Trying dlopen('%s', %d)\n", buffer, flags); | |
108 | |
109 handle = dlopen(buffer, flags); | |
110 if(handle) | |
111 return handle; | |
112 } | |
113 return NULL; | |
114 } | |
115 | |
116 | |
117 /**************************************************************************** | |
118 * get_sobasename (internal) | |
119 * | |
120 */ | |
121 static LPSTR get_sobasename(LPCSTR path, LPSTR name) | |
122 { | |
123 char *cptr; | |
124 | |
125 /* Strip the path from the library name */ | |
126 if((cptr = strrchr(path, '/'))) | |
127 { | |
128 char *cp = strrchr(cptr+1, '\\'); | |
129 if(cp && cp > cptr) | |
130 cptr = cp; | |
131 } | |
132 else | |
133 cptr = strrchr(path, '\\'); | |
134 | |
135 if(!cptr) | |
136 cptr = (char *)path; /* No '/' nor '\\' in path */ | |
137 else | |
138 cptr++; | |
139 | |
140 strcpy(name, cptr); | |
141 cptr = strrchr(name, '.'); | |
142 if(cptr) | |
143 *cptr = '\0'; /* Strip extension */ | |
144 | |
145 /* Convert to lower case. | |
146 * This must be done manually because it is not sure that | |
147 * other modules are accessible. | |
148 */ | |
149 for(cptr = name; *cptr; cptr++) | |
150 *cptr = tolower(*cptr); | |
151 | |
152 return name; | |
153 } | |
154 | |
155 | |
156 /**************************************************************************** | |
157 * ELFDLL_CreateModref (internal) | |
158 * | |
159 * INPUT | |
160 * hModule - the header from the elf-dll's data-segment | |
161 * path - requested path from original call | |
162 * | |
163 * OUTPUT | |
164 * A WINE_MODREF pointer to the new object | |
165 * | |
166 * BUGS | |
167 * - Does not handle errors due to dependencies correctly | |
168 * - path can be wrong | |
169 */ | |
170 #define RVA(base, va) (((DWORD)base) + ((DWORD)va)) | |
171 | |
172 static WINE_MODREF *ELFDLL_CreateModref(HMODULE hModule, LPCSTR path) | |
173 { | |
174 // IMAGE_NT_HEADERS *nt = PE_HEADER(hModule); | |
24388 | 175 // IMAGE_DATA_DIRECTORY *dir; |
176 // IMAGE_IMPORT_DESCRIPTOR *pe_import = NULL; | |
1 | 177 WINE_MODREF *wm; |
24388 | 178 // int len; |
1 | 179 HANDLE procheap = GetProcessHeap(); |
180 | |
181 wm = (WINE_MODREF *)HeapAlloc(procheap, HEAP_ZERO_MEMORY, sizeof(*wm)); | |
182 if(!wm) | |
183 return NULL; | |
184 | |
185 wm->module = hModule; | |
186 wm->type = MODULE32_ELF; /* FIXME */ | |
187 | |
188 // dir = nt->OptionalHeader.DataDirectory+IMAGE_DIRECTORY_ENTRY_EXPORT; | |
189 // if(dir->Size) | |
190 // wm->binfmt.pe.pe_export = (PIMAGE_EXPORT_DIRECTORY)RVA(hModule, dir->VirtualAddress); | |
191 | |
192 // dir = nt->OptionalHeader.DataDirectory+IMAGE_DIRECTORY_ENTRY_IMPORT; | |
193 // if(dir->Size) | |
194 // pe_import = wm->binfmt.pe.pe_import = (PIMAGE_IMPORT_DESCRIPTOR)RVA(hModule, dir->VirtualAddress); | |
195 | |
196 // dir = nt->OptionalHeader.DataDirectory+IMAGE_DIRECTORY_ENTRY_RESOURCE; | |
197 // if(dir->Size) | |
198 // wm->binfmt.pe.pe_resource = (PIMAGE_RESOURCE_DIRECTORY)RVA(hModule, dir->VirtualAddress); | |
199 | |
200 | |
7386 | 201 wm->filename = (char*) malloc(strlen(path)+1); |
1 | 202 strcpy(wm->filename, path); |
203 wm->modname = strrchr( wm->filename, '\\' ); | |
204 if (!wm->modname) wm->modname = wm->filename; | |
205 else wm->modname++; | |
206 /* | |
207 len = GetShortPathNameA( wm->filename, NULL, 0 ); | |
208 wm->short_filename = (char *)HeapAlloc( procheap, 0, len+1 ); | |
209 GetShortPathNameA( wm->filename, wm->short_filename, len+1 ); | |
210 wm->short_modname = strrchr( wm->short_filename, '\\' ); | |
211 if (!wm->short_modname) wm->short_modname = wm->short_filename; | |
212 else wm->short_modname++; | |
213 */ | |
214 /* Link MODREF into process list */ | |
215 | |
216 // EnterCriticalSection( &PROCESS_Current()->crit_section ); | |
217 | |
218 if(local_wm) | |
219 { | |
7386 | 220 local_wm->next = (modref_list*) malloc(sizeof(modref_list)); |
1 | 221 local_wm->next->prev=local_wm; |
222 local_wm->next->next=NULL; | |
223 local_wm->next->wm=wm; | |
224 local_wm=local_wm->next; | |
225 } | |
226 else | |
227 { | |
7386 | 228 local_wm = (modref_list*) malloc(sizeof(modref_list)); |
1 | 229 local_wm->next=local_wm->prev=NULL; |
230 local_wm->wm=wm; | |
231 } | |
232 | |
233 // LeaveCriticalSection( &PROCESS_Current()->crit_section ); | |
234 return wm; | |
235 } | |
236 | |
237 /**************************************************************************** | |
238 * ELFDLL_LoadLibraryExA (internal) | |
239 * | |
240 * Implementation of elf-dll loading for PE modules | |
241 */ | |
242 WINE_MODREF *ELFDLL_LoadLibraryExA(LPCSTR path, DWORD flags) | |
243 { | |
244 LPVOID dlhandle; | |
24388 | 245 // struct elfdll_image *image; |
1 | 246 char name[129]; |
247 char soname[129]; | |
248 WINE_MODREF *wm; | |
249 | |
250 get_sobasename(path, name); | |
251 strcpy(soname, name); | |
252 strcat(soname, ".so"); | |
253 | |
254 /* Try to open the elf-dll */ | |
255 dlhandle = ELFDLL_dlopen(soname, RTLD_LAZY); | |
256 if(!dlhandle) | |
257 { | |
258 WARN("Could not load %s (%s)\n", soname, dlerror()); | |
259 SetLastError( ERROR_FILE_NOT_FOUND ); | |
260 return NULL; | |
261 } | |
262 | |
263 /* Get the 'dllname_elfdll_image' variable */ | |
264 /* strcpy(soname, name); | |
265 strcat(soname, "_elfdll_image"); | |
266 image = (struct elfdll_image *)dlsym(dlhandle, soname); | |
267 if(!image) | |
268 { | |
269 ERR("Could not get elfdll image descriptor %s (%s)\n", soname, dlerror()); | |
270 dlclose(dlhandle); | |
271 SetLastError( ERROR_BAD_FORMAT ); | |
272 return NULL; | |
273 } | |
274 | |
275 */ | |
276 wm = ELFDLL_CreateModref((int)dlhandle, path); | |
277 if(!wm) | |
278 { | |
279 ERR("Could not create WINE_MODREF for %s\n", path); | |
280 dlclose(dlhandle); | |
281 SetLastError( ERROR_OUTOFMEMORY ); | |
282 return NULL; | |
283 } | |
284 | |
285 return wm; | |
286 } | |
287 | |
288 | |
289 /**************************************************************************** | |
290 * ELFDLL_UnloadLibrary (internal) | |
291 * | |
292 * Unload an elf-dll completely from memory and deallocate the modref | |
293 */ | |
294 void ELFDLL_UnloadLibrary(WINE_MODREF *wm) | |
295 { | |
296 } | |
297 | |
298 #endif /*HAVE_LIBDL*/ |