~ubuntu-branches/ubuntu/maverick/tvtime/maverick

« back to all changes in this revision

Viewing changes to src/wine/elfdll.c

  • Committer: Bazaar Package Importer
  • Author(s): Simon Law
  • Date: 2004-01-13 18:00:36 UTC
  • Revision ID: james.westby@ubuntu.com-20040113180036-h996q67t476jymsu
Tags: upstream-0.9.12
ImportĀ upstreamĀ versionĀ 0.9.12

Show diffs side-by-side

added added

removed removed

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