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;
780 int debug_sect, debug_str_sect, debug_abbrev_sect, debug_line_sect;
782 struct thunk_area thunks[] =
784 {"__wine_spec_import_thunks", THUNK_ORDINAL_NOTYPE, 0, 0}, /* inter DLL calls */
785 {"__wine_spec_delayed_import_loaders", THUNK_ORDINAL_LOAD, 0, 0}, /* delayed inter DLL calls */
786 {"__wine_spec_delayed_import_thunks", THUNK_ORDINAL_LOAD, 0, 0}, /* delayed inter DLL calls */
787 {"__wine_delay_load", THUNK_ORDINAL_LOAD, 0, 0}, /* delayed inter DLL calls */
788 {"__wine_spec_thunk_text_16", -16, 0, 0}, /* 16 => 32 thunks */
789 {"__wine_spec_thunk_text_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 = -1;
810 debug_sect = debug_str_sect = debug_abbrev_sect = debug_line_sect = -1;
813 for (i = 0; i < fmap->elfhdr.e_shnum; i++)
815 if (strcmp(shstrtab + fmap->sect[i].shdr.sh_name, ".stab") == 0)
817 if (strcmp(shstrtab + fmap->sect[i].shdr.sh_name, ".stabstr") == 0)
819 if (strcmp(shstrtab + fmap->sect[i].shdr.sh_name, ".debug_info") == 0)
821 if (strcmp(shstrtab + fmap->sect[i].shdr.sh_name, ".debug_str") == 0)
823 if (strcmp(shstrtab + fmap->sect[i].shdr.sh_name, ".debug_abbrev") == 0)
824 debug_abbrev_sect = i;
825 if (strcmp(shstrtab + fmap->sect[i].shdr.sh_name, ".debug_line") == 0)
827 if (strcmp(shstrtab + fmap->sect[i].shdr.sh_name, ".gnu_debuglink") == 0)
829 if ((strcmp(shstrtab + fmap->sect[i].shdr.sh_name, ".symtab") == 0) &&
830 (fmap->sect[i].shdr.sh_type == SHT_SYMTAB))
832 if ((strcmp(shstrtab + fmap->sect[i].shdr.sh_name, ".dynsym") == 0) &&
833 (fmap->sect[i].shdr.sh_type == SHT_DYNSYM))
836 elf_unmap_section(fmap, fmap->elfhdr.e_shstrndx);
839 if (symtab_sect == -1)
841 /* if we don't have a symtab but a dynsym, process the dynsym
842 * section instead. It'll contain less (relevant) information,
843 * but it'll be better than nothing
845 if (dynsym_sect == -1) return FALSE;
846 symtab_sect = dynsym_sect;
849 module->module.SymType = SymExport;
851 /* create a hash table for the symtab */
852 elf_hash_symtab(module, pool, ht_symtab, fmap, symtab_sect, thunks);
854 if (!(dbghelp_options & SYMOPT_PUBLICS_ONLY))
856 if (stab_sect != -1 && stabstr_sect != -1)
861 stab = elf_map_section(fmap, stab_sect);
862 stabstr = elf_map_section(fmap, stabstr_sect);
863 if (stab != NO_MAP && stabstr != NO_MAP)
865 /* OK, now just parse all of the stabs. */
866 ret = stabs_parse(module, module->elf_info->elf_addr,
867 stab, fmap->sect[stab_sect].shdr.sh_size,
868 stabstr, fmap->sect[stabstr_sect].shdr.sh_size);
870 elf_unmap_section(fmap, stab_sect);
871 elf_unmap_section(fmap, stabstr_sect);
875 WARN("Couldn't correctly read stabs\n");
878 /* and fill in the missing information for stabs */
879 elf_finish_stabs_info(module, ht_symtab);
881 else if (debug_sect != -1)
883 /* Dwarf 2 debug information */
884 const char* dw2_debug;
885 const char* dw2_debug_abbrev;
886 const char* dw2_debug_str;
888 FIXME("Alpha-support for Dwarf2 information for %s\n", module->module.ModuleName);
890 dw2_debug = elf_map_section(fmap, debug_sect);
891 dw2_debug_abbrev = elf_map_section(fmap, debug_abbrev_sect);
892 dw2_debug_str = elf_map_section(fmap, debug_str_sect);
893 if (dw2_debug != NO_MAP && NO_MAP != dw2_debug_abbrev && dw2_debug_str != NO_MAP)
895 /* OK, now just parse dwarf2 debug infos. */
896 ret = dwarf2_parse(module, module->elf_info->elf_addr,
897 dw2_debug, fmap->sect[debug_sect].shdr.sh_size,
898 dw2_debug_abbrev, fmap->sect[debug_abbrev_sect].shdr.sh_size,
899 dw2_debug_str, fmap->sect[debug_str_sect].shdr.sh_size);
901 elf_unmap_section(fmap, debug_sect);
902 elf_unmap_section(fmap, debug_abbrev_sect);
903 elf_unmap_section(fmap, debug_str_sect);
906 WARN("Couldn't correctly read stabs\n");
910 else if (debuglink_sect != -1)
912 const char* dbg_link;
913 struct elf_file_map fmap_link;
915 dbg_link = elf_map_section(fmap, debuglink_sect);
916 /* The content of a debug link section is:
917 * 1/ a NULL terminated string, containing the file name for the
919 * 2/ padding on 4 byte boundary
920 * 3/ CRC of the linked ELF file
922 if (dbg_link != NO_MAP && elf_map_file(dbg_link, &fmap_link))
924 fmap_link.crc = *(const DWORD*)(dbg_link + ((DWORD_PTR)(strlen(dbg_link) + 4) & ~3));
925 fmap_link.with_crc = 1;
926 ret = elf_load_debug_info_from_map(module, &fmap_link, pool,
929 WARN("Couldn't load debug information from %s\n", dbg_link);
932 WARN("Couldn't load linked debug file for %s\n",
933 module->module.ModuleName);
934 elf_unmap_file(&fmap_link);
937 if (strstr(module->module.ModuleName, "<elf>") ||
938 !strcmp(module->module.ModuleName, "<wine-loader>"))
940 /* add the thunks for native libraries */
941 if (!(dbghelp_options & SYMOPT_PUBLICS_ONLY))
942 elf_new_wine_thunks(module, ht_symtab,
943 sizeof(thunks) / sizeof(thunks[0]), thunks);
945 /* add all the public symbols from symtab */
946 if (elf_new_public_symbols(module, ht_symtab) && !ret) ret = TRUE;
951 /******************************************************************
952 * elf_load_debug_info
954 * Loads ELF debugging information from the module image file.
956 BOOL elf_load_debug_info(struct module* module, struct elf_file_map* fmap)
960 struct hash_table ht_symtab;
961 struct elf_file_map my_fmap;
963 if (module->type != DMT_ELF || !module->elf_info)
965 ERR("Bad elf module '%s'\n", module->module.LoadedImageName);
969 pool_init(&pool, 65536);
970 hash_table_init(&pool, &ht_symtab, 256);
975 ret = elf_map_file(module->module.LoadedImageName, fmap);
978 ret = elf_load_debug_info_from_map(module, fmap, &pool, &ht_symtab);
981 if (fmap == &my_fmap) elf_unmap_file(fmap);
985 /******************************************************************
986 * elf_fetch_file_info
988 * Gathers some more information for an ELF module from a given file
990 BOOL elf_fetch_file_info(const char* name, DWORD* base,
991 DWORD* size, DWORD* checksum)
993 struct elf_file_map fmap;
994 if (!elf_map_file(name, &fmap)) return FALSE;
995 if (base) *base = fmap.elf_start;
996 *size = fmap.elf_size;
997 *checksum = calc_crc32(&fmap);
998 elf_unmap_file(&fmap);
1002 /******************************************************************
1004 * returns true iff the section tag is valid
1006 static unsigned is_dt_flag_valid(unsigned d_tag)
1009 #define DT_PROCNUM 0
1012 #define DT_EXTRANUM 0
1014 return (d_tag >= 0 && d_tag < DT_NUM + DT_PROCNUM + DT_EXTRANUM)
1015 #if defined(DT_LOOS) && defined(DT_HIOS)
1016 || (d_tag >= DT_LOOS && d_tag < DT_HIOS)
1018 #if defined(DT_LOPROC) && defined(DT_HIPROC)
1019 || (d_tag >= DT_LOPROC && d_tag < DT_HIPROC)
1024 /******************************************************************
1027 * Loads the information for ELF module stored in 'filename'
1028 * the module has been loaded at 'load_offset' address
1030 * -1 if the file cannot be found/opened
1031 * 0 if the file doesn't contain symbolic info (or this info cannot be
1035 static BOOL elf_load_file(struct process* pcs, const char* filename,
1036 unsigned long load_offset, struct elf_info* elf_info)
1039 struct elf_file_map fmap;
1042 TRACE("Processing elf file '%s' at %08lx\n", filename, load_offset);
1044 if (!elf_map_file(filename, &fmap)) goto leave;
1046 /* Next, we need to find a few of the internal ELF headers within
1047 * this thing. We need the main executable header, and the section
1050 if (!fmap.elf_start && !load_offset)
1051 ERR("Relocatable ELF %s, but no load address. Loading at 0x0000000\n",
1053 if (fmap.elf_start && load_offset)
1055 WARN("Non-relocatable ELF %s, but load address of 0x%08lx supplied. "
1056 "Assuming load address is corrupt\n", filename, load_offset);
1060 if (elf_info->flags & ELF_INFO_DEBUG_HEADER)
1062 const char* shstrtab = elf_map_section(&fmap, fmap.elfhdr.e_shstrndx);
1063 if (shstrtab == NO_MAP) goto leave;
1064 for (i = 0; i < fmap.elfhdr.e_shnum; i++)
1066 if (strcmp(shstrtab + fmap.sect[i].shdr.sh_name, ".dynamic") == 0 &&
1067 fmap.sect[i].shdr.sh_type == SHT_DYNAMIC)
1070 char* ptr = (char*)fmap.sect[i].shdr.sh_addr;
1075 if (!ReadProcessMemory(pcs->handle, ptr, &dyn, sizeof(dyn), &len) ||
1076 len != sizeof(dyn) || !is_dt_flag_valid(dyn.d_tag))
1077 dyn.d_tag = DT_NULL;
1079 } while (dyn.d_tag != DT_DEBUG && dyn.d_tag != DT_NULL);
1080 if (dyn.d_tag == DT_NULL) goto leave;
1081 elf_info->dbg_hdr_addr = dyn.d_un.d_ptr;
1084 elf_unmap_section(&fmap, fmap.elfhdr.e_shstrndx);
1087 if (elf_info->flags & ELF_INFO_MODULE)
1089 struct elf_module_info *elf_module_info =
1090 HeapAlloc(GetProcessHeap(), 0, sizeof(struct elf_module_info));
1091 if (!elf_module_info) goto leave;
1092 elf_info->module = module_new(pcs, filename, DMT_ELF,
1093 (load_offset) ? load_offset : fmap.elf_start,
1094 fmap.elf_size, 0, calc_crc32(&fmap));
1095 if (!elf_info->module)
1097 HeapFree(GetProcessHeap(), 0, elf_module_info);
1100 elf_info->module->elf_info = elf_module_info;
1101 elf_info->module->elf_info->elf_addr = load_offset;
1103 if (dbghelp_options & SYMOPT_DEFERRED_LOADS)
1105 elf_info->module->module.SymType = SymDeferred;
1108 else ret = elf_load_debug_info(elf_info->module, &fmap);
1110 elf_info->module->elf_info->elf_mark = 1;
1111 elf_info->module->elf_info->elf_loader = 0;
1114 if (elf_info->flags & ELF_INFO_NAME)
1116 elf_info->module_name = strcpy(HeapAlloc(GetProcessHeap(), 0,
1117 strlen(filename) + 1), filename);
1120 elf_unmap_file(&fmap);
1125 /******************************************************************
1126 * elf_load_file_from_path
1127 * tries to load an ELF file from a set of paths (separated by ':')
1129 static BOOL elf_load_file_from_path(HANDLE hProcess,
1130 const char* filename,
1131 unsigned long load_offset,
1133 struct elf_info* elf_info)
1139 if (!path) return FALSE;
1141 paths = strcpy(HeapAlloc(GetProcessHeap(), 0, strlen(path) + 1), path);
1142 for (s = paths; s && *s; s = (t) ? (t+1) : NULL)
1146 fn = HeapAlloc(GetProcessHeap(), 0, strlen(filename) + 1 + strlen(s) + 1);
1150 strcat(fn, filename);
1151 ret = elf_load_file(hProcess, fn, load_offset, elf_info);
1152 HeapFree(GetProcessHeap(), 0, fn);
1154 s = (t) ? (t+1) : NULL;
1157 HeapFree(GetProcessHeap(), 0, paths);
1161 /******************************************************************
1162 * elf_search_and_load_file
1164 * lookup a file in standard ELF locations, and if found, load it
1166 static BOOL elf_search_and_load_file(struct process* pcs, const char* filename,
1167 unsigned long load_offset,
1168 struct elf_info* elf_info)
1171 struct module* module;
1173 if (filename == NULL || *filename == '\0') return FALSE;
1174 if ((module = module_find_by_name(pcs, filename, DMT_ELF)))
1176 elf_info->module = module;
1177 module->elf_info->elf_mark = 1;
1178 return module->module.SymType;
1181 if (strstr(filename, "libstdc++")) return FALSE; /* We know we can't do it */
1182 ret = elf_load_file(pcs, filename, load_offset, elf_info);
1183 /* if relative pathname, try some absolute base dirs */
1184 if (!ret && !strchr(filename, '/'))
1186 ret = elf_load_file_from_path(pcs, filename, load_offset,
1187 getenv("PATH"), elf_info) ||
1188 elf_load_file_from_path(pcs, filename, load_offset,
1189 getenv("LD_LIBRARY_PATH"), elf_info) ||
1190 elf_load_file_from_path(pcs, filename, load_offset,
1191 getenv("WINEDLLPATH"), elf_info);
1197 /******************************************************************
1198 * elf_enum_modules_internal
1200 * Enumerate ELF modules from a running process
1202 static BOOL elf_enum_modules_internal(const struct process* pcs,
1203 const char* main_name,
1204 elf_enum_modules_cb cb, void* user)
1206 struct r_debug dbg_hdr;
1211 if (!pcs->dbg_hdr_addr ||
1212 !ReadProcessMemory(pcs->handle, (void*)pcs->dbg_hdr_addr,
1213 &dbg_hdr, sizeof(dbg_hdr), NULL))
1216 /* Now walk the linked list. In all known ELF implementations,
1217 * the dynamic loader maintains this linked list for us. In some
1218 * cases the first entry doesn't appear with a name, in other cases it
1221 for (lm_addr = (void*)dbg_hdr.r_map; lm_addr; lm_addr = (void*)lm.l_next)
1223 if (!ReadProcessMemory(pcs->handle, lm_addr, &lm, sizeof(lm), NULL))
1226 if (lm.l_prev != NULL && /* skip first entry, normally debuggee itself */
1227 lm.l_name != NULL &&
1228 ReadProcessMemory(pcs->handle, lm.l_name, bufstr, sizeof(bufstr), NULL))
1230 bufstr[sizeof(bufstr) - 1] = '\0';
1231 if (main_name && !bufstr[0]) strcpy(bufstr, main_name);
1232 if (!cb(bufstr, (unsigned long)lm.l_addr, user)) break;
1240 struct process* pcs;
1241 struct elf_info elf_info;
1244 static BOOL elf_enum_sync_cb(const char* name, unsigned long addr, void* user)
1246 struct elf_sync* es = user;
1248 elf_search_and_load_file(es->pcs, name, addr, &es->elf_info);
1252 /******************************************************************
1253 * elf_synchronize_module_list
1255 * this functions rescans the debuggee module's list and synchronizes it with
1256 * the one from 'pcs', ie:
1257 * - if a module is in debuggee and not in pcs, it's loaded into pcs
1258 * - if a module is in pcs and not in debuggee, it's unloaded from pcs
1260 BOOL elf_synchronize_module_list(struct process* pcs)
1262 struct module* module;
1265 for (module = pcs->lmodules; module; module = module->next)
1267 if (module->type == DMT_ELF) module->elf_info->elf_mark = 0;
1271 es.elf_info.flags = ELF_INFO_MODULE;
1272 if (!elf_enum_modules_internal(pcs, NULL, elf_enum_sync_cb, &es))
1275 module = pcs->lmodules;
1278 if (module->type == DMT_ELF && !module->elf_info->elf_mark &&
1279 !module->elf_info->elf_loader)
1281 module_remove(pcs, module);
1282 /* restart all over */
1283 module = pcs->lmodules;
1285 else module = module->next;
1290 /******************************************************************
1293 * Lookup in a running ELF process the loader, and sets its ELF link
1294 * address (for accessing the list of loaded .so libs) in pcs.
1295 * If flags is ELF_INFO_MODULE, the module for the loader is also
1296 * added as a module into pcs.
1298 static BOOL elf_search_loader(struct process* pcs, struct elf_info* elf_info)
1303 /* All binaries are loaded with WINELOADER (if run from tree) or by the
1304 * main executable (either wine-kthread or wine-pthread)
1305 * FIXME: the heuristic used to know whether we need to load wine-pthread
1306 * or wine-kthread is not 100% safe
1308 if ((ptr = getenv("WINELOADER")))
1309 ret = elf_search_and_load_file(pcs, ptr, 0, elf_info);
1312 ret = elf_search_and_load_file(pcs, "wine-kthread", 0, elf_info) ||
1313 elf_search_and_load_file(pcs, "wine-pthread", 0, elf_info);
1318 /******************************************************************
1319 * elf_read_wine_loader_dbg_info
1321 * Try to find a decent wine executable which could have loaded the debuggee
1323 BOOL elf_read_wine_loader_dbg_info(struct process* pcs)
1325 struct elf_info elf_info;
1327 elf_info.flags = ELF_INFO_DEBUG_HEADER | ELF_INFO_MODULE;
1328 if (!elf_search_loader(pcs, &elf_info)) return FALSE;
1329 elf_info.module->elf_info->elf_loader = 1;
1330 strcpy(elf_info.module->module.ModuleName, "<wine-loader>");
1331 return (pcs->dbg_hdr_addr = elf_info.dbg_hdr_addr) != 0;
1334 /******************************************************************
1337 * Enumerates the ELF loaded modules from a running target (hProc)
1338 * This function doesn't require that someone has called SymInitialize
1339 * on this very process.
1341 BOOL elf_enum_modules(HANDLE hProc, elf_enum_modules_cb cb, void* user)
1344 struct elf_info elf_info;
1347 memset(&pcs, 0, sizeof(pcs));
1349 elf_info.flags = ELF_INFO_DEBUG_HEADER | ELF_INFO_NAME;
1350 if (!elf_search_loader(&pcs, &elf_info)) return FALSE;
1351 pcs.dbg_hdr_addr = elf_info.dbg_hdr_addr;
1352 ret = elf_enum_modules_internal(&pcs, elf_info.module_name, cb, user);
1353 HeapFree(GetProcessHeap(), 0, (char*)elf_info.module_name);
1359 struct process* pcs;
1360 struct elf_info elf_info;
1365 /******************************************************************
1368 * Callback for elf_load_module, used to walk the list of loaded
1371 static BOOL elf_load_cb(const char* name, unsigned long addr, void* user)
1373 struct elf_load* el = user;
1376 /* memcmp is needed for matches when bufstr contains also version information
1377 * el->name: libc.so, name: libc.so.6.0
1379 p = strrchr(name, '/');
1381 if (!memcmp(p, el->name, strlen(el->name)))
1383 elf_search_and_load_file(el->pcs, name, addr, &el->elf_info);
1389 /******************************************************************
1392 * loads an ELF module and stores it in process' module list
1393 * Also, find module real name and load address from
1394 * the real loaded modules list in pcs address space
1396 struct module* elf_load_module(struct process* pcs, const char* name, DWORD addr)
1400 TRACE("(%p %s %08lx)\n", pcs, name, addr);
1402 el.elf_info.flags = ELF_INFO_MODULE;
1405 if (pcs->dbg_hdr_addr) /* we're debugging a life target */
1408 /* do only the lookup from the filename, not the path (as we lookup module
1409 * name in the process' loaded module list)
1411 el.name = strrchr(name, '/');
1412 if (!el.name++) el.name = name;
1415 if (!elf_enum_modules_internal(pcs, NULL, elf_load_cb, &el))
1420 el.ret = elf_search_and_load_file(pcs, name, addr, &el.elf_info);
1422 if (!el.ret) return NULL;
1423 assert(el.elf_info.module);
1424 return el.elf_info.module;
1427 #else /* !__ELF__ */
1429 BOOL elf_synchronize_module_list(struct process* pcs)
1434 BOOL elf_read_wine_loader_dbg_info(struct process* pcs)
1439 struct module* elf_load_module(struct process* pcs, const char* name, DWORD addr)
1444 BOOL elf_load_debug_info(struct module* module, struct elf_file_map* fmap)
1448 #endif /* __ELF__ */