2 * File elf.c - processing of ELF files
4 * Copyright (C) 1996, Eric Youngdale.
5 * 1999-2004 Eric Pouech
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.
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.
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
27 #ifdef HAVE_SYS_STAT_H
28 # include <sys/stat.h>
31 #ifdef HAVE_SYS_MMAN_H
38 #define PATH_MAX MAX_PATH
41 #include "dbghelp_private.h"
43 #if defined(__svr4__) || defined(__sun)
50 #ifdef HAVE_SYS_ELF32_H
51 # include <sys/elf32.h>
53 #ifdef HAVE_SYS_EXEC_ELF_H
54 # include <sys/exec_elf.h>
57 # if defined(DT_COUNT)
58 # define DT_NUM DT_COUNT
60 /* this seems to be a satisfactory value on Solaris, which doesn't support this AFAICT */
67 #ifdef HAVE_SYS_LINK_H
68 # include <sys/link.h>
71 #include "wine/debug.h"
73 WINE_DEFAULT_DEBUG_CHANNEL(dbghelp);
75 struct elf_module_info
77 unsigned long elf_addr;
78 unsigned short elf_mark : 1,
84 #define ELF_INFO_DEBUG_HEADER 0x0001
85 #define ELF_INFO_MODULE 0x0002
86 #define ELF_INFO_NAME 0x0004
90 unsigned flags; /* IN one (or several) of the ELF_INFO constants */
91 unsigned long dbg_hdr_addr; /* OUT address of debug header (if ELF_INFO_DEBUG_HEADER is set) */
92 struct module* module; /* OUT loaded module (if ELF_INFO_MODULE is set) */
93 const char* module_name; /* OUT found module name (if ELF_INFO_NAME is set) */
96 #define NO_MAP ((const void*)0xffffffff)
97 /* structure holding information while handling an ELF image
98 * allows one by one section mapping for memory savings
117 struct hash_table_elt ht_elt;
118 const Elf32_Sym* symp;
119 const char* filename;
126 THUNK_ORDINAL ordinal;
127 unsigned long rva_start;
128 unsigned long rva_end;
131 /******************************************************************
134 * Maps a single section into memory from an ELF file
136 static const char* elf_map_section(struct elf_file_map* fmap, int sidx)
138 unsigned pgsz = getpagesize();
141 if (sidx >= fmap->elfhdr.e_shnum ||
142 fmap->sect[sidx].shdr.sh_type == SHT_NOBITS)
144 /* align required information on page size (we assume pagesize is a power of 2) */
145 ofst = fmap->sect[sidx].shdr.sh_offset & ~(pgsz - 1);
146 size = (fmap->sect[sidx].shdr.sh_offset +
147 fmap->sect[sidx].shdr.sh_size + pgsz - 1) & ~(pgsz - 1);
148 fmap->sect[sidx].mapped = mmap(NULL, size, PROT_READ, MAP_PRIVATE, fmap->fd, ofst);
149 if (fmap->sect[sidx].mapped == NO_MAP) return NO_MAP;
150 return fmap->sect[sidx].mapped + (fmap->sect[sidx].shdr.sh_offset & (pgsz - 1));
153 /******************************************************************
156 * Unmaps a single section from memory
158 static void elf_unmap_section(struct elf_file_map* fmap, int sidx)
160 if (sidx < fmap->elfhdr.e_shnum && fmap->sect[sidx].mapped != NO_MAP)
162 munmap((char*)fmap->sect[sidx].mapped, fmap->sect[sidx].shdr.sh_size);
163 fmap->sect[sidx].mapped = NO_MAP;
167 /******************************************************************
170 * Maps an ELF file into memory (and checks it's a real ELF file)
172 static BOOL elf_map_file(const char* filename, struct elf_file_map* fmap)
174 static const BYTE elf_signature[4] = { ELFMAG0, ELFMAG1, ELFMAG2, ELFMAG3 };
178 unsigned tmp, page_mask = getpagesize() - 1;
184 /* check that the file exists, and that the module hasn't been loaded yet */
185 if (stat(filename, &statbuf) == -1 || S_ISDIR(statbuf.st_mode)) return FALSE;
187 /* Now open the file, so that we can mmap() it. */
188 if ((fmap->fd = open(filename, O_RDONLY)) == -1) return FALSE;
190 if (read(fmap->fd, &fmap->elfhdr, sizeof(fmap->elfhdr)) != sizeof(fmap->elfhdr))
192 /* and check for an ELF header */
193 if (memcmp(fmap->elfhdr.e_ident,
194 elf_signature, sizeof(elf_signature))) return FALSE;
196 fmap->sect = HeapAlloc(GetProcessHeap(), 0,
197 fmap->elfhdr.e_shnum * sizeof(fmap->sect[0]));
198 if (!fmap->sect) return FALSE;
200 lseek(fmap->fd, fmap->elfhdr.e_shoff, SEEK_SET);
201 for (i = 0; i < fmap->elfhdr.e_shnum; i++)
203 read(fmap->fd, &fmap->sect[i].shdr, sizeof(fmap->sect[i].shdr));
204 fmap->sect[i].mapped = NO_MAP;
207 /* grab size of module once loaded in memory */
208 lseek(fmap->fd, fmap->elfhdr.e_phoff, SEEK_SET);
210 fmap->elf_start = ~0L;
211 for (i = 0; i < fmap->elfhdr.e_phnum; i++)
213 if (read(fmap->fd, &phdr, sizeof(phdr)) == sizeof(phdr) &&
214 phdr.p_type == PT_LOAD)
216 tmp = (phdr.p_vaddr + phdr.p_memsz + page_mask) & ~page_mask;
217 if (fmap->elf_size < tmp) fmap->elf_size = tmp;
218 if (phdr.p_vaddr < fmap->elf_start) fmap->elf_start = phdr.p_vaddr;
221 /* if non relocatable ELF, then remove fixed address from computation
222 * otherwise, all addresses are zero based and start has no effect
224 fmap->elf_size -= fmap->elf_start;
228 /******************************************************************
231 * Unmaps an ELF file from memory (previously mapped with elf_map_file)
233 static void elf_unmap_file(struct elf_file_map* fmap)
238 for (i = 0; i < fmap->elfhdr.e_shnum; i++)
240 elf_unmap_section(fmap, i);
242 HeapFree(GetProcessHeap(), 0, fmap->sect);
247 /******************************************************************
250 * creating an internal hash table to ease use ELF symtab information lookup
252 static void elf_hash_symtab(const struct module* module, struct pool* pool,
253 struct hash_table* ht_symtab, struct elf_file_map* fmap,
254 int symtab_idx, struct thunk_area* thunks)
259 const char* filename = NULL;
261 const Elf32_Sym* symp;
262 struct symtab_elt* ste;
264 symp = (const Elf32_Sym*)elf_map_section(fmap, symtab_idx);
265 strp = elf_map_section(fmap, fmap->sect[symtab_idx].shdr.sh_link);
266 if (symp == NO_MAP || strp == NO_MAP) return;
268 nsym = fmap->sect[symtab_idx].shdr.sh_size / sizeof(*symp);
270 for (j = 0; thunks[j].symname; j++)
271 thunks[j].rva_start = thunks[j].rva_end = 0;
273 for (i = 0; i < nsym; i++, symp++)
275 /* Ignore certain types of entries which really aren't of that much
278 if ((ELF32_ST_TYPE(symp->st_info) != STT_FILE &&
279 ELF32_ST_TYPE(symp->st_info) != STT_OBJECT &&
280 ELF32_ST_TYPE(symp->st_info) != STT_FUNC) ||
281 symp->st_shndx == SHN_UNDEF)
286 symname = strp + symp->st_name;
288 if (ELF32_ST_TYPE(symp->st_info) == STT_FILE)
293 for (j = 0; thunks[j].symname; j++)
295 if (!strcmp(symname, thunks[j].symname))
297 thunks[j].rva_start = symp->st_value;
298 thunks[j].rva_end = symp->st_value + symp->st_size;
302 if (thunks[j].symname) continue;
304 /* FIXME: we don't need to handle them (GCC internals)
305 * Moreover, they screw up our symbol lookup :-/
307 if (symname[0] == '.' && symname[1] == 'L' && isdigit(symname[2]))
310 ste = pool_alloc(pool, sizeof(*ste));
311 ste->ht_elt.name = symname;
312 /* GCC emits, in some cases, a .<digit>+ suffix.
313 * This is used for static variable inside functions, so
314 * that we can have several such variables with same name in
315 * the same compilation unit
316 * We simply ignore that suffix when present (we also get rid
317 * of it in stabs parsing)
319 ptr = symname + strlen(symname) - 1;
322 while (isdigit(*ptr) && ptr >= symname) ptr--;
323 if (ptr > symname && *ptr == '.')
325 char* n = pool_alloc(pool, ptr - symname + 1);
326 memcpy(n, symname, ptr - symname + 1);
327 n[ptr - symname] = '\0';
328 ste->ht_elt.name = n;
332 ste->filename = filename;
334 hash_table_add(ht_symtab, &ste->ht_elt);
336 /* as we added in the ht_symtab pointers to the symbols themselves,
337 * we cannot unmap yet the sections, it will be done when we're over
342 /******************************************************************
345 * lookup a symbol by name in our internal hash table for the symtab
347 static const Elf32_Sym* elf_lookup_symtab(const struct module* module,
348 const struct hash_table* ht_symtab,
349 const char* name, struct symt* compiland)
351 struct symtab_elt* weak_result = NULL; /* without compiland name */
352 struct symtab_elt* result = NULL;
353 struct hash_table_iter hti;
354 struct symtab_elt* ste;
355 const char* compiland_name;
356 const char* compiland_basename;
359 /* we need weak match up (at least) when symbols of same name,
360 * defined several times in different compilation units,
361 * are merged in a single one (hence a different filename for c.u.)
365 compiland_name = source_get(module,
366 ((struct symt_compiland*)compiland)->source);
367 compiland_basename = strrchr(compiland_name, '/');
368 if (!compiland_basename++) compiland_basename = compiland_name;
370 else compiland_name = compiland_basename = NULL;
372 hash_table_iter_init(ht_symtab, &hti, name);
373 while ((ste = hash_table_iter_up(&hti)))
375 if (ste->used || strcmp(ste->ht_elt.name, name)) continue;
378 if ((ste->filename && !compiland_name) || (!ste->filename && compiland_name))
380 if (ste->filename && compiland_name)
382 if (strcmp(ste->filename, compiland_name))
384 base = strrchr(ste->filename, '/');
385 if (!base++) base = ste->filename;
386 if (strcmp(base, compiland_basename)) continue;
391 FIXME("Already found symbol %s (%s) in symtab %s @%08x and %s @%08x\n",
392 name, compiland_name, result->filename, result->symp->st_value,
393 ste->filename, ste->symp->st_value);
401 if (!result && !(result = weak_result))
403 FIXME("Couldn't find symbol %s!%s in symtab\n",
404 module->module.ModuleName, name);
410 /******************************************************************
411 * elf_finish_stabs_info
413 * - get any relevant information (address & size) from the bits we got from the
414 * stabs debugging information
416 static void elf_finish_stabs_info(struct module* module, struct hash_table* symtab)
418 struct hash_table_iter hti;
421 const Elf32_Sym* symp;
423 hash_table_iter_init(&module->ht_symbols, &hti, NULL);
424 while ((ptr = hash_table_iter_up(&hti)))
426 sym = GET_ENTRY(ptr, struct symt_ht, hash_elt);
427 switch (sym->symt.tag)
430 if (((struct symt_function*)sym)->address != module->elf_info->elf_addr &&
431 ((struct symt_function*)sym)->size)
435 symp = elf_lookup_symtab(module, symtab, sym->hash_elt.name,
436 ((struct symt_function*)sym)->container);
439 if (((struct symt_function*)sym)->address != module->elf_info->elf_addr &&
440 ((struct symt_function*)sym)->address != module->elf_info->elf_addr + symp->st_value)
441 FIXME("Changing address for %p/%s!%s from %08lx to %08lx\n",
442 sym, module->module.ModuleName, sym->hash_elt.name,
443 ((struct symt_function*)sym)->address, module->elf_info->elf_addr + symp->st_value);
444 if (((struct symt_function*)sym)->size && ((struct symt_function*)sym)->size != symp->st_size)
445 FIXME("Changing size for %p/%s!%s from %08lx to %08x\n",
446 sym, module->module.ModuleName, sym->hash_elt.name,
447 ((struct symt_function*)sym)->size, symp->st_size);
449 ((struct symt_function*)sym)->address = module->elf_info->elf_addr +
451 ((struct symt_function*)sym)->size = symp->st_size;
452 } else FIXME("Couldn't find %s!%s\n", module->module.ModuleName, sym->hash_elt.name);
455 switch (((struct symt_data*)sym)->kind)
458 case DataIsFileStatic:
459 if (((struct symt_data*)sym)->u.address != module->elf_info->elf_addr)
461 symp = elf_lookup_symtab(module, symtab, sym->hash_elt.name,
462 ((struct symt_data*)sym)->container);
465 if (((struct symt_data*)sym)->u.address != module->elf_info->elf_addr &&
466 ((struct symt_data*)sym)->u.address != module->elf_info->elf_addr + symp->st_value)
467 FIXME("Changing address for %p/%s!%s from %08lx to %08lx\n",
468 sym, module->module.ModuleName, sym->hash_elt.name,
469 ((struct symt_function*)sym)->address, module->elf_info->elf_addr + symp->st_value);
470 ((struct symt_data*)sym)->u.address = module->elf_info->elf_addr +
472 ((struct symt_data*)sym)->kind = (ELF32_ST_BIND(symp->st_info) == STB_LOCAL) ?
473 DataIsFileStatic : DataIsGlobal;
474 } else FIXME("Couldn't find %s!%s\n", module->module.ModuleName, sym->hash_elt.name);
480 FIXME("Unsupported tag %u\n", sym->symt.tag);
484 /* since we may have changed some addresses & sizes, mark the module to be resorted */
485 module->sortlist_valid = FALSE;
488 /******************************************************************
489 * elf_load_wine_thunks
491 * creating the thunk objects for a wine native DLL
493 static int elf_new_wine_thunks(struct module* module, struct hash_table* ht_symtab,
494 unsigned num_areas, struct thunk_area* thunks)
497 struct symt_compiland* compiland = NULL;
498 const char* compiland_name = NULL;
499 struct hash_table_iter hti;
500 struct symtab_elt* ste;
504 hash_table_iter_init(ht_symtab, &hti, NULL);
505 while ((ste = hash_table_iter_up(&hti)))
507 if (ste->used) continue;
509 /* FIXME: this is not a good idea anyway... we are creating several
510 * compiland objects for a same compilation unit
511 * We try to cache the last compiland used, but it's not enough
512 * (we should here only create compilands if they are not yet
515 if (!compiland_name || compiland_name != ste->filename)
516 compiland = symt_new_compiland(module,
517 compiland_name = ste->filename);
519 addr = module->elf_info->elf_addr + ste->symp->st_value;
521 for (j = 0; j < num_areas; j++)
523 if (ste->symp->st_value >= thunks[j].rva_start &&
524 ste->symp->st_value < thunks[j].rva_end)
527 if (j < num_areas) /* thunk found */
529 symt_new_thunk(module, compiland, ste->ht_elt.name, thunks[j].ordinal,
530 addr, ste->symp->st_size);
536 idx = symt_find_nearest(module, addr);
538 symt_get_info(&module->addr_sorttab[idx]->symt,
539 TI_GET_ADDRESS, &ref_addr);
540 if (idx == -1 || addr != ref_addr)
542 /* creating public symbols for all the ELF symbols which haven't been
543 * used yet (ie we have no debug information on them)
544 * That's the case, for example, of the .spec.c files
546 switch (ELF32_ST_TYPE(ste->symp->st_info))
549 symt_new_function(module, compiland, ste->ht_elt.name,
550 addr, ste->symp->st_size, NULL);
553 symt_new_global_variable(module, compiland, ste->ht_elt.name,
554 ELF32_ST_BIND(ste->symp->st_info) == STB_LOCAL,
555 addr, ste->symp->st_size, NULL);
558 FIXME("Shouldn't happen\n");
561 /* FIXME: this is a hack !!!
562 * we are adding new symbols, but as we're parsing a symbol table
563 * (hopefully without duplicate symbols) we delay rebuilding the sorted
564 * module table until we're done with the symbol table
565 * Otherwise, as we intertwine symbols's add and lookup, performance
568 module->sortlist_valid = TRUE;
570 else if (strcmp(ste->ht_elt.name, module->addr_sorttab[idx]->hash_elt.name))
573 DWORD xsize = 0, kind = -1;
575 symt_get_info(&module->addr_sorttab[idx]->symt, TI_GET_ADDRESS, &xaddr);
576 symt_get_info(&module->addr_sorttab[idx]->symt, TI_GET_LENGTH, &xsize);
577 symt_get_info(&module->addr_sorttab[idx]->symt, TI_GET_DATAKIND, &kind);
579 /* If none of symbols has a correct size, we consider they are both markers
580 * Hence, we can silence this warning
581 * Also, we check that we don't have two symbols, one local, the other
582 * global which is legal
584 if ((xsize || ste->symp->st_size) &&
585 (kind == (ELF32_ST_BIND(ste->symp->st_info) == STB_LOCAL) ? DataIsFileStatic : DataIsGlobal))
586 FIXME("Duplicate in %s: %s<%08lx-%08x> %s<%s-%08lx>\n",
587 module->module.ModuleName,
588 ste->ht_elt.name, addr, ste->symp->st_size,
589 module->addr_sorttab[idx]->hash_elt.name,
590 wine_dbgstr_longlong(xaddr), xsize);
594 /* see comment above */
595 module->sortlist_valid = FALSE;
599 /******************************************************************
600 * elf_new_public_symbols
602 * Creates a set of public symbols from an ELF symtab
604 static int elf_new_public_symbols(struct module* module, struct hash_table* symtab)
606 struct symt_compiland* compiland = NULL;
607 const char* compiland_name = NULL;
608 struct hash_table_iter hti;
609 struct symtab_elt* ste;
611 if (dbghelp_options & SYMOPT_NO_PUBLICS) return TRUE;
613 /* FIXME: we're missing the ELF entry point here */
615 hash_table_iter_init(symtab, &hti, NULL);
616 while ((ste = hash_table_iter_up(&hti)))
618 /* FIXME: this is not a good idea anyway... we are creating several
619 * compiland objects for a same compilation unit
620 * We try to cache the last compiland used, but it's not enough
621 * (we should here only create compilands if they are not yet
624 if (!compiland_name || compiland_name != ste->filename)
625 compiland = symt_new_compiland(module,
626 compiland_name = ste->filename);
628 symt_new_public(module, compiland, ste->ht_elt.name,
629 module->elf_info->elf_addr + ste->symp->st_value,
630 ste->symp->st_size, TRUE /* FIXME */,
631 ELF32_ST_TYPE(ste->symp->st_info) == STT_FUNC);
636 /* Copyright (C) 1986 Gary S. Brown. Modified by Robert Shearman. You may use
637 the following calc_crc32 code or tables extracted from it, as desired without
640 /**********************************************************************\
641 |* Demonstration program to compute the 32-bit CRC used as the frame *|
642 |* check sequence in ADCCP (ANSI X3.66, also known as FIPS PUB 71 *|
643 |* and FED-STD-1003, the U.S. versions of CCITT's X.25 link-level *|
644 |* protocol). The 32-bit FCS was added via the Federal Register, *|
645 |* 1 June 1982, p.23798. I presume but don't know for certain that *|
646 |* this polynomial is or will be included in CCITT V.41, which *|
647 |* defines the 16-bit CRC (often called CRC-CCITT) polynomial. FIPS *|
648 |* PUB 78 says that the 32-bit FCS reduces otherwise undetected *|
649 |* errors by a factor of 10^-5 over 16-bit FCS. *|
650 \**********************************************************************/
652 /* First, the polynomial itself and its table of feedback terms. The */
654 /* 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 */
655 /* Note that we take it "backwards" and put the highest-order term in */
656 /* the lowest-order bit. The X^32 term is "implied"; the LSB is the */
657 /* X^31 term, etc. The X^0 term (usually shown as "+1") results in */
658 /* the MSB being 1. */
660 /* Note that the usual hardware shift register implementation, which */
661 /* is what we're using (we're merely optimizing it by doing eight-bit */
662 /* chunks at a time) shifts bits into the lowest-order term. In our */
663 /* implementation, that means shifting towards the right. Why do we */
664 /* do it this way? Because the calculated CRC must be transmitted in */
665 /* order from highest-order term to lowest-order term. UARTs transmit */
666 /* characters in order from LSB to MSB. By storing the CRC this way, */
667 /* we hand it to the UART in the order low-byte to high-byte; the UART */
668 /* sends each low-bit to hight-bit; and the result is transmission bit */
669 /* by bit from highest- to lowest-order term without requiring any bit */
670 /* shuffling on our part. Reception works similarly. */
672 /* The feedback terms table consists of 256, 32-bit entries. Notes: */
674 /* 1. The table can be generated at runtime if desired; code to do so */
675 /* is shown later. It might not be obvious, but the feedback */
676 /* terms simply represent the results of eight shift/xor opera- */
677 /* tions for all combinations of data and CRC register values. */
679 /* 2. The CRC accumulation logic is the same for all CRC polynomials, */
680 /* be they sixteen or thirty-two bits wide. You simply choose the */
681 /* appropriate table. Alternatively, because the table can be */
682 /* generated at runtime, you can start by generating the table for */
683 /* the polynomial in question and use exactly the same "updcrc", */
684 /* if your application needn't simultaneously handle two CRC */
685 /* polynomials. (Note, however, that XMODEM is strange.) */
687 /* 3. For 16-bit CRCs, the table entries need be only 16 bits wide; */
688 /* of course, 32-bit entries work OK if the high 16 bits are zero. */
690 /* 4. The values must be right-shifted by eight bits by the "updcrc" */
691 /* logic; the shift must be unsigned (bring in zeroes). On some */
692 /* hardware you could probably optimize the shift in assembler by */
693 /* using byte-swap instructions. */
696 static DWORD calc_crc32(struct elf_file_map* fmap)
698 #define UPDC32(octet,crc) (crc_32_tab[((crc) ^ (octet)) & 0xff] ^ ((crc) >> 8))
699 static const DWORD crc_32_tab[] =
700 { /* CRC polynomial 0xedb88320 */
701 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f,
702 0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988,
703 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, 0x1db71064, 0x6ab020f2,
704 0xf3b97148, 0x84be41de, 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7,
705 0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9,
706 0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172,
707 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, 0x35b5a8fa, 0x42b2986c,
708 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59,
709 0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423,
710 0xcfba9599, 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924,
711 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190, 0x01db7106,
712 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433,
713 0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d,
714 0x91646c97, 0xe6635c01, 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e,
715 0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950,
716 0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65,
717 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, 0x4adfa541, 0x3dd895d7,
718 0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0,
719 0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa,
720 0xbe0b1010, 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
721 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, 0x2eb40d81,
722 0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a,
723 0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683, 0xe3630b12, 0x94643b84,
724 0x0d6d6a3e, 0x7a6a5aa8, 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1,
725 0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb,
726 0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc,
727 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, 0xd6d6a3e8, 0xa1d1937e,
728 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b,
729 0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55,
730 0x316e8eef, 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,
731 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe, 0xb2bd0b28,
732 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d,
733 0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, 0x9c0906a9, 0xeb0e363f,
734 0x72076785, 0x05005713, 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38,
735 0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242,
736 0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777,
737 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, 0x8f659eff, 0xf862ae69,
738 0x616bffd3, 0x166ccf45, 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2,
739 0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc,
740 0x40df0b66, 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
741 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, 0xcdd70693,
742 0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94,
743 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d
746 unsigned char buffer[256];
749 lseek(fmap->fd, 0, SEEK_SET);
750 while ((r = read(fmap->fd, buffer, sizeof(buffer))) > 0)
752 for (i = 0; i < r; i++) crc = UPDC32(buffer[i], crc);
758 /******************************************************************
759 * elf_load_debug_info_from_map
761 * Loads the symbolic information from ELF module which mapping is described
763 * the module has been loaded at 'load_offset' address, so symbols' address
764 * relocation is performed.
765 * CRC is checked if fmap->with_crc is TRUE
767 * 0 if the file doesn't contain symbolic info (or this info cannot be
771 static BOOL elf_load_debug_info_from_map(struct module* module,
772 struct elf_file_map* fmap,
774 struct hash_table* ht_symtab)
777 const char* shstrtab;
779 int symtab_sect, dynsym_sect, stab_sect, stabstr_sect, debug_sect, debuglink_sect;
780 struct thunk_area thunks[] =
782 {"__wine_spec_import_thunks", THUNK_ORDINAL_NOTYPE, 0, 0}, /* inter DLL calls */
783 {"__wine_spec_delayed_import_loaders", THUNK_ORDINAL_LOAD, 0, 0}, /* delayed inter DLL calls */
784 {"__wine_spec_delayed_import_thunks", THUNK_ORDINAL_LOAD, 0, 0}, /* delayed inter DLL calls */
785 {"__wine_delay_load", THUNK_ORDINAL_LOAD, 0, 0}, /* delayed inter DLL calls */
786 {"__wine_spec_thunk_text_16", -16, 0, 0}, /* 16 => 32 thunks */
787 {"__wine_spec_thunk_data_16", -16, 0, 0}, /* 16 => 32 thunks */
788 {"__wine_spec_thunk_text_32", -32, 0, 0}, /* 32 => 16 thunks */
789 {"__wine_spec_thunk_data_32", -32, 0, 0}, /* 32 => 16 thunks */
793 if (fmap->with_crc && (fmap->crc != calc_crc32(fmap)))
795 ERR("Bad CRC for module %s (got %08lx while expecting %08lx)\n",
796 module->module.ImageName, calc_crc32(fmap), fmap->crc);
797 /* we don't tolerate mis-matched files */
802 * Next, we need to find a few of the internal ELF headers within
803 * this thing. We need the main executable header, and the section
806 shstrtab = elf_map_section(fmap, fmap->elfhdr.e_shstrndx);
807 if (shstrtab == NO_MAP) return FALSE;
809 symtab_sect = dynsym_sect = stab_sect = stabstr_sect =
810 debug_sect = debuglink_sect = -1;
812 for (i = 0; i < fmap->elfhdr.e_shnum; i++)
814 if (strcmp(shstrtab + fmap->sect[i].shdr.sh_name, ".stab") == 0)
816 if (strcmp(shstrtab + fmap->sect[i].shdr.sh_name, ".stabstr") == 0)
818 if (strcmp(shstrtab + fmap->sect[i].shdr.sh_name, ".debug_info") == 0)
820 if (strcmp(shstrtab + fmap->sect[i].shdr.sh_name, ".gnu_debuglink") == 0)
822 if ((strcmp(shstrtab + fmap->sect[i].shdr.sh_name, ".symtab") == 0) &&
823 (fmap->sect[i].shdr.sh_type == SHT_SYMTAB))
825 if ((strcmp(shstrtab + fmap->sect[i].shdr.sh_name, ".dynsym") == 0) &&
826 (fmap->sect[i].shdr.sh_type == SHT_DYNSYM))
829 elf_unmap_section(fmap, fmap->elfhdr.e_shstrndx);
832 if (symtab_sect == -1)
834 /* if we don't have a symtab but a dynsym, process the dynsym
835 * section instead. It'll contain less (relevant) information,
836 * but it'll be better than nothing
838 if (dynsym_sect == -1) return FALSE;
839 symtab_sect = dynsym_sect;
842 module->module.SymType = SymExport;
844 /* create a hash table for the symtab */
845 elf_hash_symtab(module, pool, ht_symtab, fmap, symtab_sect, thunks);
847 if (!(dbghelp_options & SYMOPT_PUBLICS_ONLY))
849 if (stab_sect != -1 && stabstr_sect != -1)
854 stab = elf_map_section(fmap, stab_sect);
855 stabstr = elf_map_section(fmap, stabstr_sect);
856 if (stab != NO_MAP && stabstr != NO_MAP)
858 /* OK, now just parse all of the stabs. */
859 ret = stabs_parse(module, module->elf_info->elf_addr,
860 stab, fmap->sect[stab_sect].shdr.sh_size,
861 stabstr, fmap->sect[stabstr_sect].shdr.sh_size);
863 elf_unmap_section(fmap, stab_sect);
864 elf_unmap_section(fmap, stabstr_sect);
868 WARN("Couldn't correctly read stabs\n");
871 /* and fill in the missing information for stabs */
872 elf_finish_stabs_info(module, ht_symtab);
874 else if (debug_sect != -1)
876 /* Dwarf 2 debug information */
877 FIXME("Unsupported Dwarf2 information for %s\n",
878 module->module.ModuleName);
880 else if (debuglink_sect != -1)
882 const char* dbg_link;
883 struct elf_file_map fmap_link;
885 dbg_link = elf_map_section(fmap, debuglink_sect);
886 /* The content of a debug link section is:
887 * 1/ a NULL terminated string, containing the file name for the
889 * 2/ padding on 4 byte boundary
890 * 3/ CRC of the linked ELF file
892 if (dbg_link != NO_MAP && elf_map_file(dbg_link, &fmap_link))
894 fmap_link.crc = *(const DWORD*)(dbg_link + ((DWORD_PTR)(strlen(dbg_link) + 4) & ~3));
895 fmap_link.with_crc = 1;
896 ret = elf_load_debug_info_from_map(module, &fmap_link, pool,
899 WARN("Couldn't load debug information from %s\n", dbg_link);
902 WARN("Couldn't load linked debug file for %s\n",
903 module->module.ModuleName);
904 elf_unmap_file(&fmap_link);
907 if (strstr(module->module.ModuleName, "<elf>") ||
908 !strcmp(module->module.ModuleName, "<wine-loader>"))
910 /* add the thunks for native libraries */
911 if (!(dbghelp_options & SYMOPT_PUBLICS_ONLY))
912 elf_new_wine_thunks(module, ht_symtab,
913 sizeof(thunks) / sizeof(thunks[0]), thunks);
915 /* add all the public symbols from symtab */
916 if (elf_new_public_symbols(module, ht_symtab) && !ret) ret = TRUE;
921 /******************************************************************
922 * elf_load_debug_info
924 * Loads ELF debugging information from the module image file.
926 BOOL elf_load_debug_info(struct module* module, struct elf_file_map* fmap)
930 struct hash_table ht_symtab;
931 struct elf_file_map my_fmap;
933 if (module->type != DMT_ELF || !module->elf_info)
935 ERR("Bad elf module '%s'\n", module->module.LoadedImageName);
939 pool_init(&pool, 65536);
940 hash_table_init(&pool, &ht_symtab, 256);
945 ret = elf_map_file(module->module.LoadedImageName, fmap);
948 ret = elf_load_debug_info_from_map(module, fmap, &pool, &ht_symtab);
951 if (fmap == &my_fmap) elf_unmap_file(fmap);
955 /******************************************************************
956 * elf_fetch_file_info
958 * Gathers some more information for an ELF module from a given file
960 BOOL elf_fetch_file_info(const char* name, DWORD* base,
961 DWORD* size, DWORD* checksum)
963 struct elf_file_map fmap;
964 if (!elf_map_file(name, &fmap)) return FALSE;
965 if (base) *base = fmap.elf_start;
966 *size = fmap.elf_size;
967 *checksum = calc_crc32(&fmap);
968 elf_unmap_file(&fmap);
972 /******************************************************************
974 * returns true iff the section tag is valid
976 static unsigned is_dt_flag_valid(unsigned d_tag)
982 #define DT_EXTRANUM 0
984 return (d_tag >= 0 && d_tag < DT_NUM + DT_PROCNUM + DT_EXTRANUM)
985 #if defined(DT_LOOS) && defined(DT_HIOS)
986 || (d_tag >= DT_LOOS && d_tag < DT_HIOS)
988 #if defined(DT_LOPROC) && defined(DT_HIPROC)
989 || (d_tag >= DT_LOPROC && d_tag < DT_HIPROC)
994 /******************************************************************
997 * Loads the information for ELF module stored in 'filename'
998 * the module has been loaded at 'load_offset' address
1000 * -1 if the file cannot be found/opened
1001 * 0 if the file doesn't contain symbolic info (or this info cannot be
1005 static BOOL elf_load_file(struct process* pcs, const char* filename,
1006 unsigned long load_offset, struct elf_info* elf_info)
1009 struct elf_file_map fmap;
1012 TRACE("Processing elf file '%s' at %08lx\n", filename, load_offset);
1014 if (!elf_map_file(filename, &fmap)) goto leave;
1016 /* Next, we need to find a few of the internal ELF headers within
1017 * this thing. We need the main executable header, and the section
1020 if (!fmap.elf_start && !load_offset)
1021 ERR("Relocatable ELF %s, but no load address. Loading at 0x0000000\n",
1023 if (fmap.elf_start && load_offset)
1025 WARN("Non-relocatable ELF %s, but load address of 0x%08lx supplied. "
1026 "Assuming load address is corrupt\n", filename, load_offset);
1030 if (elf_info->flags & ELF_INFO_DEBUG_HEADER)
1032 const char* shstrtab = elf_map_section(&fmap, fmap.elfhdr.e_shstrndx);
1033 if (shstrtab == NO_MAP) goto leave;
1034 for (i = 0; i < fmap.elfhdr.e_shnum; i++)
1036 if (strcmp(shstrtab + fmap.sect[i].shdr.sh_name, ".dynamic") == 0 &&
1037 fmap.sect[i].shdr.sh_type == SHT_DYNAMIC)
1040 char* ptr = (char*)fmap.sect[i].shdr.sh_addr;
1045 if (!ReadProcessMemory(pcs->handle, ptr, &dyn, sizeof(dyn), &len) ||
1046 len != sizeof(dyn) || !is_dt_flag_valid(dyn.d_tag))
1047 dyn.d_tag = DT_NULL;
1049 } while (dyn.d_tag != DT_DEBUG && dyn.d_tag != DT_NULL);
1050 if (dyn.d_tag == DT_NULL) goto leave;
1051 elf_info->dbg_hdr_addr = dyn.d_un.d_ptr;
1054 elf_unmap_section(&fmap, fmap.elfhdr.e_shstrndx);
1057 if (elf_info->flags & ELF_INFO_MODULE)
1059 struct elf_module_info *elf_module_info =
1060 HeapAlloc(GetProcessHeap(), 0, sizeof(struct elf_module_info));
1061 if (!elf_module_info) goto leave;
1062 elf_info->module = module_new(pcs, filename, DMT_ELF,
1063 (load_offset) ? load_offset : fmap.elf_start,
1064 fmap.elf_size, 0, calc_crc32(&fmap));
1065 if (!elf_info->module)
1067 HeapFree(GetProcessHeap(), 0, elf_module_info);
1070 elf_info->module->elf_info = elf_module_info;
1071 elf_info->module->elf_info->elf_addr = load_offset;
1073 if (dbghelp_options & SYMOPT_DEFERRED_LOADS)
1075 elf_info->module->module.SymType = SymDeferred;
1078 else ret = elf_load_debug_info(elf_info->module, &fmap);
1080 elf_info->module->elf_info->elf_mark = 1;
1081 elf_info->module->elf_info->elf_loader = 0;
1084 if (elf_info->flags & ELF_INFO_NAME)
1086 elf_info->module_name = strcpy(HeapAlloc(GetProcessHeap(), 0,
1087 strlen(filename) + 1), filename);
1090 elf_unmap_file(&fmap);
1095 /******************************************************************
1096 * elf_load_file_from_path
1097 * tries to load an ELF file from a set of paths (separated by ':')
1099 static BOOL elf_load_file_from_path(HANDLE hProcess,
1100 const char* filename,
1101 unsigned long load_offset,
1103 struct elf_info* elf_info)
1109 if (!path) return FALSE;
1111 paths = strcpy(HeapAlloc(GetProcessHeap(), 0, strlen(path) + 1), path);
1112 for (s = paths; s && *s; s = (t) ? (t+1) : NULL)
1116 fn = HeapAlloc(GetProcessHeap(), 0, strlen(filename) + 1 + strlen(s) + 1);
1120 strcat(fn, filename);
1121 ret = elf_load_file(hProcess, fn, load_offset, elf_info);
1122 HeapFree(GetProcessHeap(), 0, fn);
1124 s = (t) ? (t+1) : NULL;
1127 HeapFree(GetProcessHeap(), 0, paths);
1131 /******************************************************************
1132 * elf_search_and_load_file
1134 * lookup a file in standard ELF locations, and if found, load it
1136 static BOOL elf_search_and_load_file(struct process* pcs, const char* filename,
1137 unsigned long load_offset,
1138 struct elf_info* elf_info)
1141 struct module* module;
1143 if (filename == NULL || *filename == '\0') return FALSE;
1144 if ((module = module_find_by_name(pcs, filename, DMT_ELF)))
1146 elf_info->module = module;
1147 module->elf_info->elf_mark = 1;
1148 return module->module.SymType;
1151 if (strstr(filename, "libstdc++")) return FALSE; /* We know we can't do it */
1152 ret = elf_load_file(pcs, filename, load_offset, elf_info);
1153 /* if relative pathname, try some absolute base dirs */
1154 if (!ret && !strchr(filename, '/'))
1156 ret = elf_load_file_from_path(pcs, filename, load_offset,
1157 getenv("PATH"), elf_info) ||
1158 elf_load_file_from_path(pcs, filename, load_offset,
1159 getenv("LD_LIBRARY_PATH"), elf_info) ||
1160 elf_load_file_from_path(pcs, filename, load_offset,
1161 getenv("WINEDLLPATH"), elf_info);
1167 /******************************************************************
1168 * elf_enum_modules_internal
1170 * Enumerate ELF modules from a running process
1172 static BOOL elf_enum_modules_internal(const struct process* pcs,
1173 const char* main_name,
1174 elf_enum_modules_cb cb, void* user)
1176 struct r_debug dbg_hdr;
1181 if (!pcs->dbg_hdr_addr ||
1182 !ReadProcessMemory(pcs->handle, (void*)pcs->dbg_hdr_addr,
1183 &dbg_hdr, sizeof(dbg_hdr), NULL))
1186 /* Now walk the linked list. In all known ELF implementations,
1187 * the dynamic loader maintains this linked list for us. In some
1188 * cases the first entry doesn't appear with a name, in other cases it
1191 for (lm_addr = (void*)dbg_hdr.r_map; lm_addr; lm_addr = (void*)lm.l_next)
1193 if (!ReadProcessMemory(pcs->handle, lm_addr, &lm, sizeof(lm), NULL))
1196 if (lm.l_prev != NULL && /* skip first entry, normally debuggee itself */
1197 lm.l_name != NULL &&
1198 ReadProcessMemory(pcs->handle, lm.l_name, bufstr, sizeof(bufstr), NULL))
1200 bufstr[sizeof(bufstr) - 1] = '\0';
1201 if (main_name && !bufstr[0]) strcpy(bufstr, main_name);
1202 if (!cb(bufstr, (unsigned long)lm.l_addr, user)) break;
1210 struct process* pcs;
1211 struct elf_info elf_info;
1214 static BOOL elf_enum_sync_cb(const char* name, unsigned long addr, void* user)
1216 struct elf_sync* es = user;
1218 elf_search_and_load_file(es->pcs, name, addr, &es->elf_info);
1222 /******************************************************************
1223 * elf_synchronize_module_list
1225 * this functions rescans the debuggee module's list and synchronizes it with
1226 * the one from 'pcs', ie:
1227 * - if a module is in debuggee and not in pcs, it's loaded into pcs
1228 * - if a module is in pcs and not in debuggee, it's unloaded from pcs
1230 BOOL elf_synchronize_module_list(struct process* pcs)
1232 struct module* module;
1235 for (module = pcs->lmodules; module; module = module->next)
1237 if (module->type == DMT_ELF) module->elf_info->elf_mark = 0;
1241 es.elf_info.flags = ELF_INFO_MODULE;
1242 if (!elf_enum_modules_internal(pcs, NULL, elf_enum_sync_cb, &es))
1245 module = pcs->lmodules;
1248 if (module->type == DMT_ELF && !module->elf_info->elf_mark &&
1249 !module->elf_info->elf_loader)
1251 module_remove(pcs, module);
1252 /* restart all over */
1253 module = pcs->lmodules;
1255 else module = module->next;
1260 /******************************************************************
1263 * Lookup in a running ELF process the loader, and sets its ELF link
1264 * address (for accessing the list of loaded .so libs) in pcs.
1265 * If flags is ELF_INFO_MODULE, the module for the loader is also
1266 * added as a module into pcs.
1268 static BOOL elf_search_loader(struct process* pcs, struct elf_info* elf_info)
1273 /* All binaries are loaded with WINELOADER (if run from tree) or by the
1274 * main executable (either wine-kthread or wine-pthread)
1275 * FIXME: the heuristic used to know whether we need to load wine-pthread
1276 * or wine-kthread is not 100% safe
1278 if ((ptr = getenv("WINELOADER")))
1279 ret = elf_search_and_load_file(pcs, ptr, 0, elf_info);
1282 ret = elf_search_and_load_file(pcs, "wine-kthread", 0, elf_info) ||
1283 elf_search_and_load_file(pcs, "wine-pthread", 0, elf_info);
1288 /******************************************************************
1289 * elf_read_wine_loader_dbg_info
1291 * Try to find a decent wine executable which could have loaded the debuggee
1293 BOOL elf_read_wine_loader_dbg_info(struct process* pcs)
1295 struct elf_info elf_info;
1297 elf_info.flags = ELF_INFO_DEBUG_HEADER | ELF_INFO_MODULE;
1298 if (!elf_search_loader(pcs, &elf_info)) return FALSE;
1299 elf_info.module->elf_info->elf_loader = 1;
1300 strcpy(elf_info.module->module.ModuleName, "<wine-loader>");
1301 return (pcs->dbg_hdr_addr = elf_info.dbg_hdr_addr) != 0;
1304 /******************************************************************
1307 * Enumerates the ELF loaded modules from a running target (hProc)
1308 * This function doesn't require that someone has called SymInitialize
1309 * on this very process.
1311 BOOL elf_enum_modules(HANDLE hProc, elf_enum_modules_cb cb, void* user)
1314 struct elf_info elf_info;
1317 memset(&pcs, 0, sizeof(pcs));
1319 elf_info.flags = ELF_INFO_DEBUG_HEADER | ELF_INFO_NAME;
1320 if (!elf_search_loader(&pcs, &elf_info)) return FALSE;
1321 pcs.dbg_hdr_addr = elf_info.dbg_hdr_addr;
1322 ret = elf_enum_modules_internal(&pcs, elf_info.module_name, cb, user);
1323 HeapFree(GetProcessHeap(), 0, (char*)elf_info.module_name);
1329 struct process* pcs;
1330 struct elf_info elf_info;
1335 /******************************************************************
1338 * Callback for elf_load_module, used to walk the list of loaded
1341 static BOOL elf_load_cb(const char* name, unsigned long addr, void* user)
1343 struct elf_load* el = user;
1346 /* memcmp is needed for matches when bufstr contains also version information
1347 * el->name: libc.so, name: libc.so.6.0
1349 p = strrchr(name, '/');
1351 if (!memcmp(p, el->name, strlen(el->name)))
1353 elf_search_and_load_file(el->pcs, name, addr, &el->elf_info);
1359 /******************************************************************
1362 * loads an ELF module and stores it in process' module list
1363 * Also, find module real name and load address from
1364 * the real loaded modules list in pcs address space
1366 struct module* elf_load_module(struct process* pcs, const char* name, DWORD addr)
1370 TRACE("(%p %s %08lx)\n", pcs, name, addr);
1372 el.elf_info.flags = ELF_INFO_MODULE;
1375 if (pcs->dbg_hdr_addr) /* we're debugging a life target */
1378 /* do only the lookup from the filename, not the path (as we lookup module
1379 * name in the process' loaded module list)
1381 el.name = strrchr(name, '/');
1382 if (!el.name++) el.name = name;
1385 if (!elf_enum_modules_internal(pcs, NULL, elf_load_cb, &el))
1390 el.ret = elf_search_and_load_file(pcs, name, addr, &el.elf_info);
1392 if (!el.ret) return NULL;
1393 assert(el.elf_info.module);
1394 return el.elf_info.module;
1397 #else /* !__ELF__ */
1399 BOOL elf_synchronize_module_list(struct process* pcs)
1404 BOOL elf_read_wine_loader_dbg_info(struct process* pcs)
1409 struct module* elf_load_module(struct process* pcs, const char* name, DWORD addr)
1414 BOOL elf_load_debug_info(struct module* module, struct elf_file_map* fmap)
1418 #endif /* __ELF__ */