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