Added more implementation of IDocumentView.
[wine] / dlls / dbghelp / elf_module.c
1 /*
2  * File elf.c - processing of ELF files
3  *
4  * Copyright (C) 1996, Eric Youngdale.
5  *               1999-2004 Eric Pouech
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2.1 of the License, or (at your option) any later version.
11  *
12  * This library is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with this library; if not, write to the Free Software
19  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
20  */
21
22 #include "config.h"
23
24 #include <assert.h>
25 #include <stdio.h>
26 #include <stdlib.h>
27 #include <sys/stat.h>
28 #include <fcntl.h>
29 #ifdef HAVE_SYS_MMAN_H
30 #include <sys/mman.h>
31 #endif
32 #ifdef HAVE_UNISTD_H
33 # include <unistd.h>
34 #endif
35 #ifndef PATH_MAX
36 #define PATH_MAX MAX_PATH
37 #endif
38
39 #include "dbghelp_private.h"
40
41 #if defined(__svr4__) || defined(__sun)
42 #define __ELF__
43 #endif
44
45 #ifdef HAVE_ELF_H
46 # include <elf.h>
47 #endif
48 #ifdef HAVE_SYS_ELF32_H
49 # include <sys/elf32.h>
50 #endif
51 #ifdef HAVE_SYS_EXEC_ELF_H
52 # include <sys/exec_elf.h>
53 #endif
54 #if !defined(DT_NUM)
55 # if defined(DT_COUNT)
56 #  define DT_NUM DT_COUNT
57 # else
58 /* this seems to be a satisfactory value on Solaris, which doesn't support this AFAICT */
59 #  define DT_NUM 24
60 # endif
61 #endif
62 #ifdef HAVE_LINK_H
63 # include <link.h>
64 #endif
65 #ifdef HAVE_SYS_LINK_H
66 # include <sys/link.h>
67 #endif
68
69 #include "wine/debug.h"
70
71 WINE_DEFAULT_DEBUG_CHANNEL(dbghelp);
72
73 struct elf_module_info
74 {
75     unsigned long               elf_addr;
76     unsigned short              elf_mark : 1,
77                                 elf_loader : 1;
78 };
79
80 #ifdef __ELF__
81
82 #define ELF_INFO_DEBUG_HEADER   0x0001
83 #define ELF_INFO_MODULE         0x0002
84 #define ELF_INFO_NAME           0x0004
85
86 struct elf_info
87 {
88     unsigned                    flags;          /* IN  one (or several) of the ELF_INFO constants */
89     unsigned long               dbg_hdr_addr;   /* OUT address of debug header (if ELF_INFO_DEBUG_HEADER is set) */
90     struct module*              module;         /* OUT loaded module (if ELF_INFO_MODULE is set) */
91     const char*                 module_name;    /* OUT found module name (if ELF_INFO_NAME is set) */
92 };
93
94 #define NO_MAP                  ((const void*)0xffffffff)
95 /* structure holding information while handling an ELF image
96  * allows one by one section mapping for memory savings
97  */
98 struct elf_file_map
99 {
100     Elf32_Ehdr                  elfhdr;
101     size_t                      elf_size;
102     size_t                      elf_start;
103     struct
104     {
105         Elf32_Shdr                      shdr;
106         const char*                     mapped;
107     }*                          sect;
108     int                         fd;
109     unsigned                    with_crc;
110     unsigned long               crc;
111 };
112
113 struct symtab_elt
114 {
115     struct hash_table_elt       ht_elt;
116     const Elf32_Sym*            symp;
117     const char*                 filename;
118     unsigned                    used;
119 };
120
121 struct thunk_area
122 {
123     const char*                 symname;
124     THUNK_ORDINAL               ordinal;
125     unsigned long               rva_start;
126     unsigned long               rva_end;
127 };
128
129 /******************************************************************
130  *              elf_map_section
131  *
132  * Maps a single section into memory from an ELF file
133  */
134 static const char* elf_map_section(struct elf_file_map* fmap, int sidx)
135 {
136     unsigned pgsz = getpagesize();
137     unsigned ofst, size;
138
139     if (sidx >= fmap->elfhdr.e_shnum ||
140         fmap->sect[sidx].shdr.sh_type == SHT_NOBITS)
141         return NO_MAP;
142     /* align required information on page size (we assume pagesize is a power of 2) */
143     ofst = fmap->sect[sidx].shdr.sh_offset & ~(pgsz - 1);
144     size = (fmap->sect[sidx].shdr.sh_offset + 
145             fmap->sect[sidx].shdr.sh_size + pgsz - 1) & ~(pgsz - 1);
146     fmap->sect[sidx].mapped = mmap(NULL, size, PROT_READ, MAP_PRIVATE, fmap->fd, ofst);
147     if (fmap->sect[sidx].mapped == NO_MAP) return NO_MAP;
148     return fmap->sect[sidx].mapped + (fmap->sect[sidx].shdr.sh_offset & (pgsz - 1));
149 }
150
151 /******************************************************************
152  *              elf_unmap_section
153  *
154  * Unmaps a single section from memory
155  */
156 static void elf_unmap_section(struct elf_file_map* fmap, int sidx)
157 {
158     if (sidx < fmap->elfhdr.e_shnum && fmap->sect[sidx].mapped != NO_MAP)
159     {
160         munmap((char*)fmap->sect[sidx].mapped, fmap->sect[sidx].shdr.sh_size);
161         fmap->sect[sidx].mapped = NO_MAP;
162     }
163 }
164
165 /******************************************************************
166  *              elf_map_file
167  *
168  * Maps an ELF file into memory (and checks it's a real ELF file)
169  */
170 static BOOL elf_map_file(const char* filename, struct elf_file_map* fmap)
171 {
172     static const BYTE   elf_signature[4] = { ELFMAG0, ELFMAG1, ELFMAG2, ELFMAG3 };
173     struct stat         statbuf;
174     int                 i;
175     Elf32_Phdr          phdr;
176     unsigned            tmp, page_mask = getpagesize() - 1;
177
178
179     fmap->fd = -1;
180     fmap->with_crc = 0;
181
182     /* check that the file exists, and that the module hasn't been loaded yet */
183     if (stat(filename, &statbuf) == -1 || S_ISDIR(statbuf.st_mode)) return FALSE;
184
185     /* Now open the file, so that we can mmap() it. */
186     if ((fmap->fd = open(filename, O_RDONLY)) == -1) return FALSE;
187
188     if (read(fmap->fd, &fmap->elfhdr, sizeof(fmap->elfhdr)) != sizeof(fmap->elfhdr))
189         return FALSE;
190     /* and check for an ELF header */
191     if (memcmp(fmap->elfhdr.e_ident, 
192                elf_signature, sizeof(elf_signature))) return FALSE;
193
194     fmap->sect = HeapAlloc(GetProcessHeap(), 0,
195                            fmap->elfhdr.e_shnum * sizeof(fmap->sect[0]));
196     if (!fmap->sect) return FALSE;
197
198     lseek(fmap->fd, fmap->elfhdr.e_shoff, SEEK_SET);
199     for (i = 0; i < fmap->elfhdr.e_shnum; i++)
200     {
201         read(fmap->fd, &fmap->sect[i].shdr, sizeof(fmap->sect[i].shdr));
202         fmap->sect[i].mapped = NO_MAP;
203     }
204
205     /* grab size of module once loaded in memory */
206     lseek(fmap->fd, fmap->elfhdr.e_phoff, SEEK_SET);
207     fmap->elf_size = 0; 
208     fmap->elf_start = ~0L;
209     for (i = 0; i < fmap->elfhdr.e_phnum; i++)
210     {
211         if (read(fmap->fd, &phdr, sizeof(phdr)) == sizeof(phdr) && 
212             phdr.p_type == PT_LOAD)
213         {
214             tmp = (phdr.p_vaddr + phdr.p_memsz + page_mask) & ~page_mask;
215             if (fmap->elf_size < tmp) fmap->elf_size = tmp;
216             if (phdr.p_vaddr < fmap->elf_start) fmap->elf_start = phdr.p_vaddr;
217         }
218     }
219     /* if non relocatable ELF, then remove fixed address from computation
220      * otherwise, all addresses are zero based and start has no effect
221      */
222     fmap->elf_size -= fmap->elf_start;
223     return TRUE;
224 }
225
226 /******************************************************************
227  *              elf_unmap_file
228  *
229  * Unmaps an ELF file from memory (previously mapped with elf_map_file)
230  */
231 static void elf_unmap_file(struct elf_file_map* fmap)
232 {
233     if (fmap->fd != -1)
234     {
235         int i;
236         for (i = 0; i < fmap->elfhdr.e_shnum; i++)
237         {
238             elf_unmap_section(fmap, i);
239         }
240         HeapFree(GetProcessHeap(), 0, fmap->sect);
241         close(fmap->fd);
242     }
243 }
244
245 /******************************************************************
246  *              elf_hash_symtab
247  *
248  * creating an internal hash table to ease use ELF symtab information lookup
249  */
250 static void elf_hash_symtab(const struct module* module, struct pool* pool, 
251                             struct hash_table* ht_symtab, struct elf_file_map* fmap,
252                             int symtab_idx, struct thunk_area* thunks)
253 {
254     int                         i, j, nsym;
255     const char*                 strp;
256     const char*                 symname;
257     const char*                 filename = NULL;
258     const char*                 ptr;
259     const Elf32_Sym*            symp;
260     struct symtab_elt*          ste;
261
262     symp = (const Elf32_Sym*)elf_map_section(fmap, symtab_idx);
263     strp = elf_map_section(fmap, fmap->sect[symtab_idx].shdr.sh_link);
264     if (symp == NO_MAP || strp == NO_MAP) return;
265
266     nsym = fmap->sect[symtab_idx].shdr.sh_size / sizeof(*symp);
267
268     for (j = 0; thunks[j].symname; j++)
269         thunks[j].rva_start = thunks[j].rva_end = 0;
270
271     for (i = 0; i < nsym; i++, symp++)
272     {
273         /* Ignore certain types of entries which really aren't of that much
274          * interest.
275          */
276         if ((ELF32_ST_TYPE(symp->st_info) != STT_FILE &&
277              ELF32_ST_TYPE(symp->st_info) != STT_OBJECT &&
278              ELF32_ST_TYPE(symp->st_info) != STT_FUNC) ||
279             symp->st_shndx == SHN_UNDEF)
280         {
281             continue;
282         }
283
284         symname = strp + symp->st_name;
285
286         if (ELF32_ST_TYPE(symp->st_info) == STT_FILE)
287         {
288             filename = symname;
289             continue;
290         }
291         for (j = 0; thunks[j].symname; j++)
292         {
293             if (!strcmp(symname, thunks[j].symname))
294             {
295                 thunks[j].rva_start = symp->st_value;
296                 thunks[j].rva_end   = symp->st_value + symp->st_size;
297                 break;
298             }
299         }
300         if (thunks[j].symname) continue;
301
302         /* FIXME: we don't need to handle them (GCC internals)
303          * Moreover, they screw up our symbol lookup :-/
304          */
305         if (symname[0] == '.' && symname[1] == 'L' && isdigit(symname[2]))
306             continue;
307
308         ste = pool_alloc(pool, sizeof(*ste));
309         ste->ht_elt.name = symname;
310         /* GCC emits, in some cases, a .<digit>+ suffix.
311          * This is used for static variable inside functions, so
312          * that we can have several such variables with same name in
313          * the same compilation unit
314          * We simply ignore that suffix when present (we also get rid
315          * of it in stabs parsing)
316          */
317         ptr = symname + strlen(symname) - 1;
318         if (isdigit(*ptr))
319         {
320             while (isdigit(*ptr) && ptr >= symname) ptr--;
321             if (ptr > symname && *ptr == '.')
322             {
323                 char* n = pool_alloc(pool, ptr - symname + 1);
324                 memcpy(n, symname, ptr - symname + 1);
325                 n[ptr - symname] = '\0';
326                 ste->ht_elt.name = n;
327             }
328         }
329         ste->symp        = symp;
330         ste->filename    = filename;
331         ste->used        = 0;
332         hash_table_add(ht_symtab, &ste->ht_elt);
333     }
334     /* as we added in the ht_symtab pointers to the symbols themselves,
335      * we cannot unmap yet the sections, it will be done when we're over
336      * with this ELF file
337      */
338 }
339
340 /******************************************************************
341  *              elf_lookup_symtab
342  *
343  * lookup a symbol by name in our internal hash table for the symtab
344  */
345 static const Elf32_Sym* elf_lookup_symtab(const struct module* module,        
346                                           const struct hash_table* ht_symtab,
347                                           const char* name, struct symt* compiland)
348 {
349     struct symtab_elt*          weak_result = NULL; /* without compiland name */
350     struct symtab_elt*          result = NULL;
351     struct hash_table_iter      hti;
352     struct symtab_elt*          ste;
353     const char*                 compiland_name;
354     const char*                 compiland_basename;
355     const char*                 base;
356
357     /* we need weak match up (at least) when symbols of same name, 
358      * defined several times in different compilation units,
359      * are merged in a single one (hence a different filename for c.u.)
360      */
361     if (compiland)
362     {
363         compiland_name = source_get(module,
364                                     ((struct symt_compiland*)compiland)->source);
365         compiland_basename = strrchr(compiland_name, '/');
366         if (!compiland_basename++) compiland_basename = compiland_name;
367     }
368     else compiland_name = compiland_basename = NULL;
369     
370     hash_table_iter_init(ht_symtab, &hti, name);
371     while ((ste = hash_table_iter_up(&hti)))
372     {
373         if (ste->used || strcmp(ste->ht_elt.name, name)) continue;
374
375         weak_result = ste;
376         if ((ste->filename && !compiland_name) || (!ste->filename && compiland_name))
377             continue;
378         if (ste->filename && compiland_name)
379         {
380             if (strcmp(ste->filename, compiland_name))
381             {
382                 base = strrchr(ste->filename, '/');
383                 if (!base++) base = ste->filename;
384                 if (strcmp(base, compiland_basename)) continue;
385             }
386         }
387         if (result)
388         {
389             FIXME("Already found symbol %s (%s) in symtab %s @%08x and %s @%08x\n", 
390                   name, compiland_name, result->filename, result->symp->st_value,
391                   ste->filename, ste->symp->st_value);
392         }
393         else
394         {
395             result = ste;
396             ste->used = 1;
397         }
398     }
399     if (!result && !(result = weak_result))
400     {
401         FIXME("Couldn't find symbol %s!%s in symtab\n", 
402               module->module.ModuleName, name);
403         return NULL;
404     }
405     return result->symp;
406 }
407
408 /******************************************************************
409  *              elf_finish_stabs_info
410  *
411  * - get any relevant information (address & size) from the bits we got from the
412  *   stabs debugging information
413  */
414 static void elf_finish_stabs_info(struct module* module, struct hash_table* symtab)
415 {
416     struct hash_table_iter      hti;
417     void*                       ptr;
418     struct symt_ht*             sym;
419     const Elf32_Sym*            symp;
420
421     hash_table_iter_init(&module->ht_symbols, &hti, NULL);
422     while ((ptr = hash_table_iter_up(&hti)))
423     {
424         sym = GET_ENTRY(ptr, struct symt_ht, hash_elt);
425         switch (sym->symt.tag)
426         {
427         case SymTagFunction:
428             if (((struct symt_function*)sym)->address != module->elf_info->elf_addr &&
429                 ((struct symt_function*)sym)->size)
430             {
431                 break;
432             }
433             symp = elf_lookup_symtab(module, symtab, sym->hash_elt.name, 
434                                      ((struct symt_function*)sym)->container);
435             if (symp)
436             {
437                 if (((struct symt_function*)sym)->address != module->elf_info->elf_addr &&
438                     ((struct symt_function*)sym)->address != module->elf_info->elf_addr + symp->st_value)
439                     FIXME("Changing address for %p/%s!%s from %08lx to %08lx\n", 
440                           sym, module->module.ModuleName, sym->hash_elt.name, 
441                           ((struct symt_function*)sym)->address, module->elf_info->elf_addr + symp->st_value);
442                 if (((struct symt_function*)sym)->size && ((struct symt_function*)sym)->size != symp->st_size)
443                     FIXME("Changing size for %p/%s!%s from %08lx to %08x\n", 
444                           sym, module->module.ModuleName, sym->hash_elt.name,
445                           ((struct symt_function*)sym)->size, symp->st_size);
446
447                 ((struct symt_function*)sym)->address = module->elf_info->elf_addr +
448                                                         symp->st_value;
449                 ((struct symt_function*)sym)->size    = symp->st_size;
450             } else FIXME("Couldn't find %s!%s\n", module->module.ModuleName, sym->hash_elt.name);
451             break;
452         case SymTagData:
453             switch (((struct symt_data*)sym)->kind)
454             {
455             case DataIsGlobal:
456             case DataIsFileStatic:
457                 if (((struct symt_data*)sym)->u.address != module->elf_info->elf_addr)
458                     break;
459                 symp = elf_lookup_symtab(module, symtab, sym->hash_elt.name, 
460                                          ((struct symt_data*)sym)->container);
461                 if (symp)
462                 {
463                 if (((struct symt_data*)sym)->u.address != module->elf_info->elf_addr &&
464                     ((struct symt_data*)sym)->u.address != module->elf_info->elf_addr + symp->st_value)
465                     FIXME("Changing address for %p/%s!%s from %08lx to %08lx\n", 
466                           sym, module->module.ModuleName, sym->hash_elt.name, 
467                           ((struct symt_function*)sym)->address, module->elf_info->elf_addr + symp->st_value);
468                     ((struct symt_data*)sym)->u.address = module->elf_info->elf_addr +
469                                                           symp->st_value;
470                     ((struct symt_data*)sym)->kind = (ELF32_ST_BIND(symp->st_info) == STB_LOCAL) ?
471                         DataIsFileStatic : DataIsGlobal;
472                 } else FIXME("Couldn't find %s!%s\n", module->module.ModuleName, sym->hash_elt.name);
473                 break;
474             default:;
475             }
476             break;
477         default:
478             FIXME("Unsupported tag %u\n", sym->symt.tag);
479             break;
480         }
481     }
482     /* since we may have changed some addresses & sizes, mark the module to be resorted */
483     module->sortlist_valid = FALSE;
484 }
485
486 /******************************************************************
487  *              elf_load_wine_thunks
488  *
489  * creating the thunk objects for a wine native DLL
490  */
491 static int elf_new_wine_thunks(struct module* module, struct hash_table* ht_symtab,
492                                unsigned num_areas, struct thunk_area* thunks)
493 {
494     int                         j;
495     struct symt_compiland*      compiland = NULL;
496     const char*                 compiland_name = NULL;
497     struct hash_table_iter      hti;
498     struct symtab_elt*          ste;
499     DWORD                       addr;
500     int                         idx;
501
502     hash_table_iter_init(ht_symtab, &hti, NULL);
503     while ((ste = hash_table_iter_up(&hti)))
504     {
505         if (ste->used) continue;
506
507         /* FIXME: this is not a good idea anyway... we are creating several
508          * compiland objects for a same compilation unit
509          * We try to cache the last compiland used, but it's not enough
510          * (we should here only create compilands if they are not yet 
511          *  defined)
512          */
513         if (!compiland_name || compiland_name != ste->filename)
514             compiland = symt_new_compiland(module, 
515                                            compiland_name = ste->filename);
516
517         addr = module->elf_info->elf_addr + ste->symp->st_value;
518
519         for (j = 0; j < num_areas; j++)
520         {
521             if (ste->symp->st_value >= thunks[j].rva_start && 
522                 ste->symp->st_value < thunks[j].rva_end)
523                 break;
524         }
525         if (j < num_areas) /* thunk found */
526         {
527             symt_new_thunk(module, compiland, ste->ht_elt.name, thunks[j].ordinal,
528                            addr, ste->symp->st_size);
529         }
530         else
531         {
532             ULONG64     ref_addr;
533
534             idx = symt_find_nearest(module, addr);
535             if (idx != -1)
536                 symt_get_info(&module->addr_sorttab[idx]->symt, 
537                               TI_GET_ADDRESS, &ref_addr);
538             if (idx == -1 || addr != ref_addr)
539             {
540                 /* creating public symbols for all the ELF symbols which haven't been
541                  * used yet (ie we have no debug information on them)
542                  * That's the case, for example, of the .spec.c files
543                  */
544                 switch (ELF32_ST_TYPE(ste->symp->st_info))
545                 {
546                 case STT_FUNC:
547                     symt_new_function(module, compiland, ste->ht_elt.name,
548                                       addr, ste->symp->st_size, NULL);
549                     break;
550                 case STT_OBJECT:
551                     symt_new_global_variable(module, compiland, ste->ht_elt.name,
552                                              ELF32_ST_BIND(ste->symp->st_info) == STB_LOCAL,
553                                              addr, ste->symp->st_size, NULL);
554                     break;
555                 default:
556                     FIXME("Shouldn't happen\n");
557                     break;
558                 }
559                 /* FIXME: this is a hack !!!
560                  * we are adding new symbols, but as we're parsing a symbol table
561                  * (hopefully without duplicate symbols) we delay rebuilding the sorted
562                  * module table until we're done with the symbol table
563                  * Otherwise, as we intertwine symbols's add and lookup, performance
564                  * is rather bad
565                  */
566                 module->sortlist_valid = TRUE;
567             }
568             else if (strcmp(ste->ht_elt.name, module->addr_sorttab[idx]->hash_elt.name))
569             {
570                 ULONG64 xaddr = 0;
571                 DWORD   xsize = 0, kind = -1;
572
573                 symt_get_info(&module->addr_sorttab[idx]->symt, TI_GET_ADDRESS,  &xaddr);
574                 symt_get_info(&module->addr_sorttab[idx]->symt, TI_GET_LENGTH,   &xsize);
575                 symt_get_info(&module->addr_sorttab[idx]->symt, TI_GET_DATAKIND, &kind);
576
577                 /* If none of symbols has a correct size, we consider they are both markers
578                  * Hence, we can silence this warning
579                  * Also, we check that we don't have two symbols, one local, the other 
580                  * global which is legal
581                  */
582                 if ((xsize || ste->symp->st_size) && 
583                     (kind == (ELF32_ST_BIND(ste->symp->st_info) == STB_LOCAL) ? DataIsFileStatic : DataIsGlobal))
584                     FIXME("Duplicate in %s: %s<%08lx-%08x> %s<%s-%08lx>\n", 
585                           module->module.ModuleName,
586                           ste->ht_elt.name, addr, ste->symp->st_size,
587                           module->addr_sorttab[idx]->hash_elt.name,
588                           wine_dbgstr_longlong(xaddr), xsize);
589             }
590         }
591     }
592     /* see comment above */
593     module->sortlist_valid = FALSE;
594     return TRUE;
595 }
596
597 /******************************************************************
598  *              elf_new_public_symbols
599  *
600  * Creates a set of public symbols from an ELF symtab
601  */
602 static int elf_new_public_symbols(struct module* module, struct hash_table* symtab)
603 {
604     struct symt_compiland*      compiland = NULL;
605     const char*                 compiland_name = NULL;
606     struct hash_table_iter      hti;
607     struct symtab_elt*          ste;
608
609     if (dbghelp_options & SYMOPT_NO_PUBLICS) return TRUE;
610
611     /* FIXME: we're missing the ELF entry point here */
612
613     hash_table_iter_init(symtab, &hti, NULL);
614     while ((ste = hash_table_iter_up(&hti)))
615     {
616         /* FIXME: this is not a good idea anyway... we are creating several
617          * compiland objects for a same compilation unit
618          * We try to cache the last compiland used, but it's not enough
619          * (we should here only create compilands if they are not yet 
620          *  defined)
621          */
622         if (!compiland_name || compiland_name != ste->filename)
623             compiland = symt_new_compiland(module, 
624                                            compiland_name = ste->filename);
625
626         symt_new_public(module, compiland, ste->ht_elt.name,
627                         module->elf_info->elf_addr + ste->symp->st_value,
628                         ste->symp->st_size, TRUE /* FIXME */, 
629                         ELF32_ST_TYPE(ste->symp->st_info) == STT_FUNC);
630     }
631     return TRUE;
632 }
633
634 /* Copyright (C) 1986 Gary S. Brown. Modified by Robert Shearman. You may use
635    the following calc_crc32 code or tables extracted from it, as desired without
636    restriction. */
637
638 /**********************************************************************\
639 |* Demonstration program to compute the 32-bit CRC used as the frame  *|
640 |* check sequence in ADCCP (ANSI X3.66, also known as FIPS PUB 71     *|
641 |* and FED-STD-1003, the U.S. versions of CCITT's X.25 link-level     *|
642 |* protocol).  The 32-bit FCS was added via the Federal Register,     *|
643 |* 1 June 1982, p.23798.  I presume but don't know for certain that   *|
644 |* this polynomial is or will be included in CCITT V.41, which        *|
645 |* defines the 16-bit CRC (often called CRC-CCITT) polynomial.  FIPS  *|
646 |* PUB 78 says that the 32-bit FCS reduces otherwise undetected       *|
647 |* errors by a factor of 10^-5 over 16-bit FCS.                       *|
648 \**********************************************************************/
649
650 /* First, the polynomial itself and its table of feedback terms.  The  */
651 /* polynomial is                                                       */
652 /* X^32+X^26+X^23+X^22+X^16+X^12+X^11+X^10+X^8+X^7+X^5+X^4+X^2+X^1+X^0 */
653 /* Note that we take it "backwards" and put the highest-order term in  */
654 /* the lowest-order bit.  The X^32 term is "implied"; the LSB is the   */
655 /* X^31 term, etc.  The X^0 term (usually shown as "+1") results in    */
656 /* the MSB being 1.                                                    */
657
658 /* Note that the usual hardware shift register implementation, which   */
659 /* is what we're using (we're merely optimizing it by doing eight-bit  */
660 /* chunks at a time) shifts bits into the lowest-order term.  In our   */
661 /* implementation, that means shifting towards the right.  Why do we   */
662 /* do it this way?  Because the calculated CRC must be transmitted in  */
663 /* order from highest-order term to lowest-order term.  UARTs transmit */
664 /* characters in order from LSB to MSB.  By storing the CRC this way,  */
665 /* we hand it to the UART in the order low-byte to high-byte; the UART */
666 /* sends each low-bit to hight-bit; and the result is transmission bit */
667 /* by bit from highest- to lowest-order term without requiring any bit */
668 /* shuffling on our part.  Reception works similarly.                  */
669
670 /* The feedback terms table consists of 256, 32-bit entries.  Notes:   */
671 /*                                                                     */
672 /*  1. The table can be generated at runtime if desired; code to do so */
673 /*     is shown later.  It might not be obvious, but the feedback      */
674 /*     terms simply represent the results of eight shift/xor opera-    */
675 /*     tions for all combinations of data and CRC register values.     */
676 /*                                                                     */
677 /*  2. The CRC accumulation logic is the same for all CRC polynomials, */
678 /*     be they sixteen or thirty-two bits wide.  You simply choose the */
679 /*     appropriate table.  Alternatively, because the table can be     */
680 /*     generated at runtime, you can start by generating the table for */
681 /*     the polynomial in question and use exactly the same "updcrc",   */
682 /*     if your application needn't simultaneously handle two CRC       */
683 /*     polynomials.  (Note, however, that XMODEM is strange.)          */
684 /*                                                                     */
685 /*  3. For 16-bit CRCs, the table entries need be only 16 bits wide;   */
686 /*     of course, 32-bit entries work OK if the high 16 bits are zero. */
687 /*                                                                     */
688 /*  4. The values must be right-shifted by eight bits by the "updcrc"  */
689 /*     logic; the shift must be unsigned (bring in zeroes).  On some   */
690 /*     hardware you could probably optimize the shift in assembler by  */
691 /*     using byte-swap instructions.                                   */
692
693
694 static DWORD calc_crc32(struct elf_file_map* fmap)
695 {
696 #define UPDC32(octet,crc) (crc_32_tab[((crc) ^ (octet)) & 0xff] ^ ((crc) >> 8))
697     static const DWORD crc_32_tab[] =
698     { /* CRC polynomial 0xedb88320 */
699         0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f,
700         0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988,
701         0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, 0x1db71064, 0x6ab020f2,
702         0xf3b97148, 0x84be41de, 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7,
703         0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9,
704         0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172,
705         0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, 0x35b5a8fa, 0x42b2986c,
706         0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59,
707         0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423,
708         0xcfba9599, 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924,
709         0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190, 0x01db7106,
710         0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433,
711         0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d,
712         0x91646c97, 0xe6635c01, 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e,
713         0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950,
714         0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65,
715         0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, 0x4adfa541, 0x3dd895d7,
716         0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0,
717         0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa,
718         0xbe0b1010, 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
719         0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, 0x2eb40d81,
720         0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a,
721         0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683, 0xe3630b12, 0x94643b84,
722         0x0d6d6a3e, 0x7a6a5aa8, 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1,
723         0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb,
724         0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc,
725         0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, 0xd6d6a3e8, 0xa1d1937e,
726         0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b,
727         0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55,
728         0x316e8eef, 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,
729         0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe, 0xb2bd0b28,
730         0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d,
731         0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, 0x9c0906a9, 0xeb0e363f,
732         0x72076785, 0x05005713, 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38,
733         0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242,
734         0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777,
735         0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, 0x8f659eff, 0xf862ae69,
736         0x616bffd3, 0x166ccf45, 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2,
737         0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc,
738         0x40df0b66, 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
739         0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, 0xcdd70693,
740         0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94,
741         0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d
742     };
743     int                 i, r;
744     unsigned char       buffer[256];
745     DWORD               crc = ~0;
746
747     lseek(fmap->fd, 0, SEEK_SET);
748     while ((r = read(fmap->fd, buffer, sizeof(buffer))) > 0)
749     {
750         for (i = 0; i < r; i++) crc = UPDC32(buffer[i], crc);
751     }
752     return ~crc;
753 #undef UPDC32
754 }
755
756 /******************************************************************
757  *              elf_load_debug_info_from_map
758  *
759  * Loads the symbolic information from ELF module which mapping is described
760  * in fmap
761  * the module has been loaded at 'load_offset' address, so symbols' address
762  * relocation is performed.
763  * CRC is checked if fmap->with_crc is TRUE
764  * returns
765  *      0 if the file doesn't contain symbolic info (or this info cannot be
766  *      read or parsed)
767  *      1 on success
768  */
769 static BOOL elf_load_debug_info_from_map(struct module* module, 
770                                          struct elf_file_map* fmap,
771                                          struct pool* pool,
772                                          struct hash_table* ht_symtab)
773 {
774     BOOL                ret = FALSE;
775     const char*         shstrtab;
776     int                 i;
777     int                 symtab_sect, dynsym_sect, stab_sect, stabstr_sect, debug_sect, debuglink_sect;
778     struct thunk_area   thunks[] = 
779     {
780         {"__wine_spec_import_thunks",           THUNK_ORDINAL_NOTYPE, 0, 0},    /* inter DLL calls */
781         {"__wine_spec_delayed_import_loaders",  THUNK_ORDINAL_LOAD,   0, 0},    /* delayed inter DLL calls */
782         {"__wine_spec_delayed_import_thunks",   THUNK_ORDINAL_LOAD,   0, 0},    /* delayed inter DLL calls */
783         {"__wine_delay_load",                   THUNK_ORDINAL_LOAD,   0, 0},    /* delayed inter DLL calls */
784         {"__wine_spec_thunk_text_16",           -16,                  0, 0},    /* 16 => 32 thunks */
785         {"__wine_spec_thunk_data_16",           -16,                  0, 0},    /* 16 => 32 thunks */
786         {"__wine_spec_thunk_text_32",           -32,                  0, 0},    /* 32 => 16 thunks */
787         {"__wine_spec_thunk_data_32",           -32,                  0, 0},    /* 32 => 16 thunks */
788         {NULL,                                  0,                    0, 0}
789     };
790
791     if (fmap->with_crc && (fmap->crc != calc_crc32(fmap)))
792     {
793         ERR("Bad CRC for module %s (got %08lx while expecting %08lx)\n",
794             module->module.ImageName, calc_crc32(fmap), fmap->crc);
795         /* we don't tolerate mis-matched files */
796         return FALSE;
797     }
798
799     /*
800      * Next, we need to find a few of the internal ELF headers within
801      * this thing.  We need the main executable header, and the section
802      * table.
803      */
804     shstrtab = elf_map_section(fmap, fmap->elfhdr.e_shstrndx);
805     if (shstrtab == NO_MAP) return FALSE;
806
807     symtab_sect = dynsym_sect = stab_sect = stabstr_sect =
808         debug_sect = debuglink_sect = -1;
809
810     for (i = 0; i < fmap->elfhdr.e_shnum; i++)
811     {
812         if (strcmp(shstrtab + fmap->sect[i].shdr.sh_name, ".stab") == 0)
813             stab_sect = i;
814         if (strcmp(shstrtab + fmap->sect[i].shdr.sh_name, ".stabstr") == 0)
815             stabstr_sect = i;
816         if (strcmp(shstrtab + fmap->sect[i].shdr.sh_name, ".debug_info") == 0)
817             debug_sect = i;
818         if (strcmp(shstrtab + fmap->sect[i].shdr.sh_name, ".gnu_debuglink") == 0)
819             debuglink_sect = i;
820         if ((strcmp(shstrtab + fmap->sect[i].shdr.sh_name, ".symtab") == 0) &&
821             (fmap->sect[i].shdr.sh_type == SHT_SYMTAB))
822             symtab_sect = i;
823         if ((strcmp(shstrtab + fmap->sect[i].shdr.sh_name, ".dynsym") == 0) &&
824             (fmap->sect[i].shdr.sh_type == SHT_DYNSYM))
825             dynsym_sect = i;
826     }
827     elf_unmap_section(fmap, fmap->elfhdr.e_shstrndx);
828     shstrtab = NULL;
829
830     if (symtab_sect == -1)
831     {
832         /* if we don't have a symtab but a dynsym, process the dynsym
833          * section instead. It'll contain less (relevant) information, 
834          * but it'll be better than nothing
835          */
836         if (dynsym_sect == -1) return FALSE;
837         symtab_sect = dynsym_sect;
838     }
839
840     module->module.SymType = SymExport;
841
842     /* create a hash table for the symtab */
843     elf_hash_symtab(module, pool, ht_symtab, fmap, symtab_sect, thunks);
844
845     if (!(dbghelp_options & SYMOPT_PUBLICS_ONLY))
846     {
847         if (stab_sect != -1 && stabstr_sect != -1)
848         {
849             const char* stab;
850             const char* stabstr;
851
852             stab = elf_map_section(fmap, stab_sect);
853             stabstr = elf_map_section(fmap, stabstr_sect);
854             if (stab != NO_MAP && stabstr != NO_MAP)
855             {
856                 /* OK, now just parse all of the stabs. */
857                 ret = stabs_parse(module, module->elf_info->elf_addr,
858                                   stab, fmap->sect[stab_sect].shdr.sh_size,
859                                   stabstr, fmap->sect[stabstr_sect].shdr.sh_size);
860             }
861             elf_unmap_section(fmap, stab_sect);
862             elf_unmap_section(fmap, stabstr_sect);
863             
864             if (!ret)
865             {
866                 WARN("Couldn't correctly read stabs\n");
867                 return FALSE;
868             }
869             /* and fill in the missing information for stabs */
870             elf_finish_stabs_info(module, ht_symtab);
871         }
872         else if (debug_sect != -1)
873         {
874             /* Dwarf 2 debug information */
875             FIXME("Unsupported Dwarf2 information for %s\n",
876                   module->module.ModuleName);
877         }
878         else if (debuglink_sect != -1)
879         {
880             const char* dbg_link;
881             struct elf_file_map fmap_link;
882
883             dbg_link = elf_map_section(fmap, debuglink_sect);
884             /* The content of a debug link section is:
885              * 1/ a NULL terminated string, containing the file name for the
886              *    debug info
887              * 2/ padding on 4 byte boundary
888              * 3/ CRC of the linked ELF file
889              */
890             if (dbg_link != NO_MAP && elf_map_file(dbg_link, &fmap_link))
891             {
892                 fmap_link.crc = *(const DWORD*)(dbg_link + ((DWORD_PTR)(strlen(dbg_link) + 4) & ~3));
893                 fmap_link.with_crc = 1;
894                 ret = elf_load_debug_info_from_map(module, &fmap_link, pool,
895                                                    ht_symtab);
896                 if (!ret)
897                     WARN("Couldn't load debug information from %s\n", dbg_link);
898             }
899             else
900                 WARN("Couldn't load linked debug file for %s\n",
901                      module->module.ModuleName);
902             elf_unmap_file(&fmap_link);
903         }
904     }
905     if (strstr(module->module.ModuleName, "<elf>") ||
906         !strcmp(module->module.ModuleName, "<wine-loader>"))
907     {
908         /* add the thunks for native libraries */
909         if (!(dbghelp_options & SYMOPT_PUBLICS_ONLY))
910             elf_new_wine_thunks(module, ht_symtab, 
911                                 sizeof(thunks) / sizeof(thunks[0]), thunks);
912     }
913     /* add all the public symbols from symtab */
914     if (elf_new_public_symbols(module, ht_symtab) && !ret) ret = TRUE;
915
916     return ret;
917 }
918
919 /******************************************************************
920  *              elf_load_debug_info
921  *
922  * Loads ELF debugging information from the module image file.
923  */
924 BOOL elf_load_debug_info(struct module* module, struct elf_file_map* fmap)
925 {
926     BOOL                ret = TRUE;
927     struct pool         pool;
928     struct hash_table   ht_symtab;
929     struct elf_file_map my_fmap;
930
931     if (module->type != DMT_ELF || !module->elf_info)
932     {
933         ERR("Bad elf module '%s'\n", module->module.LoadedImageName);
934         return FALSE;
935     }
936
937     pool_init(&pool, 65536);
938     hash_table_init(&pool, &ht_symtab, 256);
939
940     if (!fmap)
941     {
942         fmap = &my_fmap;
943         ret = elf_map_file(module->module.LoadedImageName, fmap);
944     }
945     if (ret)
946         ret = elf_load_debug_info_from_map(module, fmap, &pool, &ht_symtab);
947
948     pool_destroy(&pool);
949     if (fmap == &my_fmap) elf_unmap_file(fmap);
950     return ret;
951 }
952
953 /******************************************************************
954  *              elf_fetch_file_info
955  *
956  * Gathers some more information for an ELF module from a given file
957  */
958 BOOL elf_fetch_file_info(const char* name, DWORD* base,
959                          DWORD* size, DWORD* checksum)
960 {
961     struct elf_file_map fmap;
962     if (!elf_map_file(name, &fmap)) return FALSE;
963     if (base) *base = fmap.elf_start;
964     *size = fmap.elf_size;
965     *checksum = calc_crc32(&fmap);
966     elf_unmap_file(&fmap);
967     return TRUE;
968 }
969
970 /******************************************************************
971  *              is_dt_flag_valid
972  * returns true iff the section tag is valid 
973  */
974 static unsigned is_dt_flag_valid(unsigned d_tag)
975 {
976 #ifndef DT_PROCNUM
977 #define DT_PROCNUM 0
978 #endif
979 #ifndef DT_EXTRANUM
980 #define DT_EXTRANUM 0
981 #endif
982     return (d_tag >= 0 && d_tag < DT_NUM + DT_PROCNUM + DT_EXTRANUM)
983 #if defined(DT_LOOS) && defined(DT_HIOS)
984         || (d_tag >= DT_LOOS && d_tag < DT_HIOS)
985 #endif
986 #if defined(DT_LOPROC) && defined(DT_HIPROC)
987         || (d_tag >= DT_LOPROC && d_tag < DT_HIPROC)
988 #endif
989         ;
990 }
991
992 /******************************************************************
993  *              elf_load_file
994  *
995  * Loads the information for ELF module stored in 'filename'
996  * the module has been loaded at 'load_offset' address
997  * returns
998  *      -1 if the file cannot be found/opened
999  *      0 if the file doesn't contain symbolic info (or this info cannot be
1000  *      read or parsed)
1001  *      1 on success
1002  */
1003 static BOOL elf_load_file(struct process* pcs, const char* filename,
1004                           unsigned long load_offset, struct elf_info* elf_info)
1005 {
1006     BOOL                ret = FALSE;
1007     struct elf_file_map fmap;
1008     int                 i;
1009
1010     TRACE("Processing elf file '%s' at %08lx\n", filename, load_offset);
1011
1012     if (!elf_map_file(filename, &fmap)) goto leave;
1013
1014     /* Next, we need to find a few of the internal ELF headers within
1015      * this thing.  We need the main executable header, and the section
1016      * table.
1017      */
1018     if (!fmap.elf_start && !load_offset)
1019         ERR("Relocatable ELF %s, but no load address. Loading at 0x0000000\n",
1020             filename);
1021     if (fmap.elf_start && load_offset)
1022     {
1023         WARN("Non-relocatable ELF %s, but load address of 0x%08lx supplied. "
1024              "Assuming load address is corrupt\n", filename, load_offset);
1025         load_offset = 0;
1026     }
1027
1028     if (elf_info->flags & ELF_INFO_DEBUG_HEADER)
1029     {
1030         const char* shstrtab = elf_map_section(&fmap, fmap.elfhdr.e_shstrndx);
1031         if (shstrtab == NO_MAP) goto leave;
1032         for (i = 0; i < fmap.elfhdr.e_shnum; i++)
1033         {
1034             if (strcmp(shstrtab + fmap.sect[i].shdr.sh_name, ".dynamic") == 0 &&
1035                 fmap.sect[i].shdr.sh_type == SHT_DYNAMIC)
1036             {
1037                 Elf32_Dyn       dyn;
1038                 char*           ptr = (char*)fmap.sect[i].shdr.sh_addr;
1039                 unsigned long   len;
1040
1041                 do
1042                 {
1043                     if (!ReadProcessMemory(pcs->handle, ptr, &dyn, sizeof(dyn), &len) ||
1044                         len != sizeof(dyn) || !is_dt_flag_valid(dyn.d_tag))
1045                         dyn.d_tag = DT_NULL;
1046                     ptr += sizeof(dyn);
1047                 } while (dyn.d_tag != DT_DEBUG && dyn.d_tag != DT_NULL);
1048                 if (dyn.d_tag == DT_NULL) goto leave;
1049                 elf_info->dbg_hdr_addr = dyn.d_un.d_ptr;
1050             }
1051         }
1052         elf_unmap_section(&fmap, fmap.elfhdr.e_shstrndx);
1053     }
1054
1055     if (elf_info->flags & ELF_INFO_MODULE)
1056     {
1057         struct elf_module_info *elf_module_info = 
1058             HeapAlloc(GetProcessHeap(), 0, sizeof(struct elf_module_info));
1059         if (!elf_module_info) goto leave;
1060         elf_info->module = module_new(pcs, filename, DMT_ELF, 
1061                                       (load_offset) ? load_offset : fmap.elf_start, 
1062                                       fmap.elf_size, 0, calc_crc32(&fmap));
1063         if (!elf_info->module)
1064         {
1065             HeapFree(GetProcessHeap(), 0, elf_module_info);
1066             goto leave;
1067         }
1068         elf_info->module->elf_info = elf_module_info;
1069         elf_info->module->elf_info->elf_addr = load_offset;
1070
1071         if (dbghelp_options & SYMOPT_DEFERRED_LOADS)
1072         {
1073             elf_info->module->module.SymType = SymDeferred;
1074             ret = TRUE;
1075         }
1076         else ret = elf_load_debug_info(elf_info->module, &fmap);
1077
1078         elf_info->module->elf_info->elf_mark = 1;
1079         elf_info->module->elf_info->elf_loader = 0;
1080     } else ret = TRUE;
1081
1082     if (elf_info->flags & ELF_INFO_NAME)
1083     {
1084         elf_info->module_name = strcpy(HeapAlloc(GetProcessHeap(), 0,
1085                                                  strlen(filename) + 1), filename);
1086     }
1087 leave:
1088     elf_unmap_file(&fmap);
1089
1090     return ret;
1091 }
1092
1093 /******************************************************************
1094  *              elf_load_file_from_path
1095  * tries to load an ELF file from a set of paths (separated by ':')
1096  */
1097 static BOOL elf_load_file_from_path(HANDLE hProcess,
1098                                     const char* filename,
1099                                     unsigned long load_offset,
1100                                     const char* path,
1101                                     struct elf_info* elf_info)
1102 {
1103     BOOL                ret = FALSE;
1104     char                *s, *t, *fn;
1105     char*               paths = NULL;
1106
1107     if (!path) return FALSE;
1108
1109     paths = strcpy(HeapAlloc(GetProcessHeap(), 0, strlen(path) + 1), path);
1110     for (s = paths; s && *s; s = (t) ? (t+1) : NULL) 
1111     {
1112         t = strchr(s, ':');
1113         if (t) *t = '\0';
1114         fn = HeapAlloc(GetProcessHeap(), 0, strlen(filename) + 1 + strlen(s) + 1);
1115         if (!fn) break;
1116         strcpy(fn, s);
1117         strcat(fn, "/");
1118         strcat(fn, filename);
1119         ret = elf_load_file(hProcess, fn, load_offset, elf_info);
1120         HeapFree(GetProcessHeap(), 0, fn);
1121         if (ret) break;
1122         s = (t) ? (t+1) : NULL;
1123     }
1124     
1125     HeapFree(GetProcessHeap(), 0, paths);
1126     return ret;
1127 }
1128
1129 /******************************************************************
1130  *              elf_search_and_load_file
1131  *
1132  * lookup a file in standard ELF locations, and if found, load it
1133  */
1134 static BOOL elf_search_and_load_file(struct process* pcs, const char* filename,
1135                                      unsigned long load_offset, 
1136                                      struct elf_info* elf_info)
1137 {
1138     BOOL                ret = FALSE;
1139     struct module*      module;
1140
1141     if (filename == NULL || *filename == '\0') return FALSE;
1142     if ((module = module_find_by_name(pcs, filename, DMT_ELF)))
1143     {
1144         elf_info->module = module;
1145         module->elf_info->elf_mark = 1;
1146         return module->module.SymType;
1147     }
1148
1149     if (strstr(filename, "libstdc++")) return FALSE; /* We know we can't do it */
1150     ret = elf_load_file(pcs, filename, load_offset, elf_info);
1151     /* if relative pathname, try some absolute base dirs */
1152     if (!ret && !strchr(filename, '/'))
1153     {
1154         ret = elf_load_file_from_path(pcs, filename, load_offset, 
1155                                       getenv("PATH"), elf_info) ||
1156             elf_load_file_from_path(pcs, filename, load_offset,
1157                                     getenv("LD_LIBRARY_PATH"), elf_info) ||
1158             elf_load_file_from_path(pcs, filename, load_offset,
1159                                     getenv("WINEDLLPATH"), elf_info);
1160     }
1161     
1162     return ret;
1163 }
1164
1165 /******************************************************************
1166  *              elf_enum_modules_internal
1167  *
1168  * Enumerate ELF modules from a running process
1169  */
1170 static BOOL elf_enum_modules_internal(const struct process* pcs,
1171                                       const char* main_name,
1172                                       elf_enum_modules_cb cb, void* user)
1173 {
1174     struct r_debug      dbg_hdr;
1175     void*               lm_addr;
1176     struct link_map     lm;
1177     char                bufstr[256];
1178
1179     if (!pcs->dbg_hdr_addr ||
1180         !ReadProcessMemory(pcs->handle, (void*)pcs->dbg_hdr_addr, 
1181                            &dbg_hdr, sizeof(dbg_hdr), NULL))
1182         return FALSE;
1183
1184     /* Now walk the linked list.  In all known ELF implementations,
1185      * the dynamic loader maintains this linked list for us.  In some
1186      * cases the first entry doesn't appear with a name, in other cases it
1187      * does.
1188      */
1189     for (lm_addr = (void*)dbg_hdr.r_map; lm_addr; lm_addr = (void*)lm.l_next)
1190     {
1191         if (!ReadProcessMemory(pcs->handle, lm_addr, &lm, sizeof(lm), NULL))
1192             return FALSE;
1193
1194         if (lm.l_prev != NULL && /* skip first entry, normally debuggee itself */
1195             lm.l_name != NULL &&
1196             ReadProcessMemory(pcs->handle, lm.l_name, bufstr, sizeof(bufstr), NULL)) 
1197         {
1198             bufstr[sizeof(bufstr) - 1] = '\0';
1199             if (main_name && !bufstr[0]) strcpy(bufstr, main_name);
1200             if (!cb(bufstr, (unsigned long)lm.l_addr, user)) break;
1201         }
1202     }
1203     return TRUE;
1204 }
1205
1206 struct elf_sync
1207 {
1208     struct process*     pcs;
1209     struct elf_info     elf_info;
1210 };
1211
1212 static BOOL elf_enum_sync_cb(const char* name, unsigned long addr, void* user)
1213 {
1214     struct elf_sync*    es = user;
1215
1216     elf_search_and_load_file(es->pcs, name, addr, &es->elf_info);
1217     return TRUE;
1218 }
1219     
1220 /******************************************************************
1221  *              elf_synchronize_module_list
1222  *
1223  * this functions rescans the debuggee module's list and synchronizes it with
1224  * the one from 'pcs', ie:
1225  * - if a module is in debuggee and not in pcs, it's loaded into pcs
1226  * - if a module is in pcs and not in debuggee, it's unloaded from pcs
1227  */
1228 BOOL    elf_synchronize_module_list(struct process* pcs)
1229 {
1230     struct module*      module;
1231     struct elf_sync     es;
1232
1233     for (module = pcs->lmodules; module; module = module->next)
1234     {
1235         if (module->type == DMT_ELF) module->elf_info->elf_mark = 0;
1236     }
1237
1238     es.pcs = pcs;
1239     es.elf_info.flags = ELF_INFO_MODULE;
1240     if (!elf_enum_modules_internal(pcs, NULL, elf_enum_sync_cb, &es))
1241         return FALSE;
1242
1243     module = pcs->lmodules;
1244     while (module)
1245     {
1246         if (module->type == DMT_ELF && !module->elf_info->elf_mark && 
1247             !module->elf_info->elf_loader)
1248         {
1249             module_remove(pcs, module);
1250             /* restart all over */
1251             module = pcs->lmodules;
1252         }
1253         else module = module->next;
1254     }
1255     return TRUE;
1256 }
1257
1258 /******************************************************************
1259  *              elf_search_loader
1260  *
1261  * Lookup in a running ELF process the loader, and sets its ELF link
1262  * address (for accessing the list of loaded .so libs) in pcs.
1263  * If flags is ELF_INFO_MODULE, the module for the loader is also
1264  * added as a module into pcs.
1265  */
1266 static BOOL elf_search_loader(struct process* pcs, struct elf_info* elf_info)
1267 {
1268     BOOL                ret;
1269     const char*         ptr;
1270
1271     /* All binaries are loaded with WINELOADER (if run from tree) or by the
1272      * main executable (either wine-kthread or wine-pthread)
1273      * FIXME: the heuristic used to know whether we need to load wine-pthread
1274      * or wine-kthread is not 100% safe
1275      */
1276     if ((ptr = getenv("WINELOADER")))
1277         ret = elf_search_and_load_file(pcs, ptr, 0, elf_info);
1278     else 
1279     {
1280         ret = elf_search_and_load_file(pcs, "wine-kthread", 0, elf_info) ||
1281             elf_search_and_load_file(pcs, "wine-pthread", 0, elf_info);
1282     }
1283     return ret;
1284 }
1285
1286 /******************************************************************
1287  *              elf_read_wine_loader_dbg_info
1288  *
1289  * Try to find a decent wine executable which could have loaded the debuggee
1290  */
1291 BOOL elf_read_wine_loader_dbg_info(struct process* pcs)
1292 {
1293     struct elf_info     elf_info;
1294
1295     elf_info.flags = ELF_INFO_DEBUG_HEADER | ELF_INFO_MODULE;
1296     if (!elf_search_loader(pcs, &elf_info)) return FALSE;
1297     elf_info.module->elf_info->elf_loader = 1;
1298     strcpy(elf_info.module->module.ModuleName, "<wine-loader>");
1299     return (pcs->dbg_hdr_addr = elf_info.dbg_hdr_addr) != 0;
1300 }
1301
1302 /******************************************************************
1303  *              elf_enum_modules
1304  *
1305  * Enumerates the ELF loaded modules from a running target (hProc)
1306  * This function doesn't require that someone has called SymInitialize
1307  * on this very process.
1308  */
1309 BOOL elf_enum_modules(HANDLE hProc, elf_enum_modules_cb cb, void* user)
1310 {
1311     struct process      pcs;
1312     struct elf_info     elf_info;
1313     BOOL                ret;
1314
1315     memset(&pcs, 0, sizeof(pcs));
1316     pcs.handle = hProc;
1317     elf_info.flags = ELF_INFO_DEBUG_HEADER | ELF_INFO_NAME;
1318     if (!elf_search_loader(&pcs, &elf_info)) return FALSE;
1319     pcs.dbg_hdr_addr = elf_info.dbg_hdr_addr;
1320     ret = elf_enum_modules_internal(&pcs, elf_info.module_name, cb, user);
1321     HeapFree(GetProcessHeap(), 0, (char*)elf_info.module_name);
1322     return ret;
1323 }
1324
1325 struct elf_load
1326 {
1327     struct process*     pcs;
1328     struct elf_info     elf_info;
1329     const char*         name;
1330     BOOL                ret;
1331 };
1332
1333 /******************************************************************
1334  *              elf_load_cb
1335  *
1336  * Callback for elf_load_module, used to walk the list of loaded
1337  * modules.
1338  */
1339 static BOOL elf_load_cb(const char* name, unsigned long addr, void* user)
1340 {
1341     struct elf_load*    el = user;
1342     const char*         p;
1343
1344     /* memcmp is needed for matches when bufstr contains also version information
1345      * el->name: libc.so, name: libc.so.6.0
1346      */
1347     p = strrchr(name, '/');
1348     if (!p++) p = name;
1349     if (!memcmp(p, el->name, strlen(el->name)))
1350     {
1351         elf_search_and_load_file(el->pcs, name, addr, &el->elf_info);
1352         return FALSE;
1353     }
1354     return TRUE;
1355 }
1356
1357 /******************************************************************
1358  *              elf_load_module
1359  *
1360  * loads an ELF module and stores it in process' module list
1361  * Also, find module real name and load address from
1362  * the real loaded modules list in pcs address space
1363  */
1364 struct module*  elf_load_module(struct process* pcs, const char* name, DWORD addr)
1365 {
1366     struct elf_load     el;
1367
1368     TRACE("(%p %s %08lx)\n", pcs, name, addr);
1369
1370     el.elf_info.flags = ELF_INFO_MODULE;
1371     el.ret = FALSE;
1372
1373     if (pcs->dbg_hdr_addr) /* we're debugging a life target */
1374     {
1375         el.pcs = pcs;
1376         /* do only the lookup from the filename, not the path (as we lookup module
1377          * name in the process' loaded module list)
1378          */
1379         el.name = strrchr(name, '/');
1380         if (!el.name++) el.name = name;
1381         el.ret = FALSE;
1382
1383         if (!elf_enum_modules_internal(pcs, NULL, elf_load_cb, &el))
1384             return NULL;
1385     }
1386     else if (addr)
1387     {
1388         el.ret = elf_search_and_load_file(pcs, name, addr, &el.elf_info);
1389     }
1390     if (!el.ret) return NULL;
1391     assert(el.elf_info.module);
1392     return el.elf_info.module;
1393 }
1394
1395 #else   /* !__ELF__ */
1396
1397 BOOL    elf_synchronize_module_list(struct process* pcs)
1398 {
1399     return FALSE;
1400 }
1401
1402 BOOL elf_read_wine_loader_dbg_info(struct process* pcs)
1403 {
1404     return FALSE;
1405 }
1406
1407 struct module*  elf_load_module(struct process* pcs, const char* name, DWORD addr)
1408 {
1409     return NULL;
1410 }
1411
1412 BOOL elf_load_debug_info(struct module* module)
1413 {
1414     return FALSE;
1415 }
1416 #endif  /* __ELF__ */