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