dbghelp: Minor cleanup.
[wine/kumbayo.git] / dlls / dbghelp / elf_module.c
blob30b7a3c01021bde68590d95b8c7bc3e9ad951793
1 /*
2 * File elf.c - processing of ELF files
4 * Copyright (C) 1996, Eric Youngdale.
5 * 1999-2007 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
22 #include "config.h"
23 #include "wine/port.h"
25 #if defined(__svr4__) || defined(__sun)
26 #define __ELF__ 1
27 /* large files are not supported by libelf */
28 #undef _FILE_OFFSET_BITS
29 #define _FILE_OFFSET_BITS 32
30 #endif
32 #include <assert.h>
33 #include <stdio.h>
34 #include <stdlib.h>
35 #ifdef HAVE_SYS_STAT_H
36 # include <sys/stat.h>
37 #endif
38 #include <fcntl.h>
39 #ifdef HAVE_SYS_MMAN_H
40 #include <sys/mman.h>
41 #endif
42 #ifdef HAVE_UNISTD_H
43 # include <unistd.h>
44 #endif
45 #ifndef PATH_MAX
46 #define PATH_MAX MAX_PATH
47 #endif
49 #include "dbghelp_private.h"
51 #ifdef HAVE_ELF_H
52 # include <elf.h>
53 #endif
54 #ifdef HAVE_SYS_ELF32_H
55 # include <sys/elf32.h>
56 #endif
57 #ifdef HAVE_SYS_EXEC_ELF_H
58 # include <sys/exec_elf.h>
59 #endif
60 #if !defined(DT_NUM)
61 # if defined(DT_COUNT)
62 # define DT_NUM DT_COUNT
63 # else
64 /* this seems to be a satisfactory value on Solaris, which doesn't support this AFAICT */
65 # define DT_NUM 24
66 # endif
67 #endif
68 #ifdef HAVE_LINK_H
69 # include <link.h>
70 #endif
71 #ifdef HAVE_SYS_LINK_H
72 # include <sys/link.h>
73 #endif
75 #include "wine/library.h"
76 #include "wine/debug.h"
78 struct elf_module_info
80 unsigned long elf_addr;
81 unsigned short elf_mark : 1,
82 elf_loader : 1;
85 #ifdef __ELF__
87 #define ELF_INFO_DEBUG_HEADER 0x0001
88 #define ELF_INFO_MODULE 0x0002
89 #define ELF_INFO_NAME 0x0004
91 WINE_DEFAULT_DEBUG_CHANNEL(dbghelp);
93 struct elf_info
95 unsigned flags; /* IN one (or several) of the ELF_INFO constants */
96 unsigned long dbg_hdr_addr; /* OUT address of debug header (if ELF_INFO_DEBUG_HEADER is set) */
97 struct module* module; /* OUT loaded module (if ELF_INFO_MODULE is set) */
98 const WCHAR* module_name; /* OUT found module name (if ELF_INFO_NAME is set) */
101 /* structure holding information while handling an ELF image
102 * allows one by one section mapping for memory savings
104 struct elf_file_map
106 Elf32_Ehdr elfhdr;
107 size_t elf_size;
108 size_t elf_start;
109 struct
111 Elf32_Shdr shdr;
112 const char* mapped;
113 }* sect;
114 int fd;
115 const char* shstrtab;
116 struct elf_file_map* alternate; /* another ELF file (linked to this one) */
119 struct elf_section_map
121 struct elf_file_map* fmap;
122 long sidx;
125 struct symtab_elt
127 struct hash_table_elt ht_elt;
128 const Elf32_Sym* symp;
129 struct symt_compiland* compiland;
130 unsigned used;
133 struct elf_thunk_area
135 const char* symname;
136 THUNK_ORDINAL ordinal;
137 unsigned long rva_start;
138 unsigned long rva_end;
141 /******************************************************************
142 * elf_map_section
144 * Maps a single section into memory from an ELF file
146 static const char* elf_map_section(struct elf_section_map* esm)
148 unsigned pgsz = getpagesize();
149 unsigned ofst, size;
151 if (esm->sidx < 0 || esm->sidx >= esm->fmap->elfhdr.e_shnum ||
152 esm->fmap->sect[esm->sidx].shdr.sh_type == SHT_NOBITS)
153 return ELF_NO_MAP;
155 /* align required information on page size (we assume pagesize is a power of 2) */
156 ofst = esm->fmap->sect[esm->sidx].shdr.sh_offset & ~(pgsz - 1);
157 size = ((esm->fmap->sect[esm->sidx].shdr.sh_offset +
158 esm->fmap->sect[esm->sidx].shdr.sh_size + pgsz - 1) & ~(pgsz - 1)) - ofst;
159 esm->fmap->sect[esm->sidx].mapped = mmap(NULL, size, PROT_READ, MAP_PRIVATE,
160 esm->fmap->fd, ofst);
161 if (esm->fmap->sect[esm->sidx].mapped == ELF_NO_MAP) return ELF_NO_MAP;
162 return esm->fmap->sect[esm->sidx].mapped + (esm->fmap->sect[esm->sidx].shdr.sh_offset & (pgsz - 1));
165 /******************************************************************
166 * elf_find_section
168 * Finds a section by name (and type) into memory from an ELF file
169 * or its alternate if any
171 static BOOL elf_find_section(struct elf_file_map* fmap, const char* name,
172 unsigned sht, struct elf_section_map* esm)
174 unsigned i;
176 while (fmap)
178 if (fmap->shstrtab == ELF_NO_MAP)
180 struct elf_section_map hdr_esm = {fmap, fmap->elfhdr.e_shstrndx};
181 if ((fmap->shstrtab = elf_map_section(&hdr_esm)) == ELF_NO_MAP) break;
183 for (i = 0; i < fmap->elfhdr.e_shnum; i++)
185 if (strcmp(fmap->shstrtab + fmap->sect[i].shdr.sh_name, name) == 0 &&
186 (sht == SHT_NULL || sht == fmap->sect[i].shdr.sh_type))
188 esm->fmap = fmap;
189 esm->sidx = i;
190 return TRUE;
193 fmap = fmap->alternate;
195 esm->fmap = NULL;
196 esm->sidx = -1;
197 return FALSE;
200 /******************************************************************
201 * elf_unmap_section
203 * Unmaps a single section from memory
205 static void elf_unmap_section(struct elf_section_map* esm)
207 if (esm->sidx >= 0 && esm->sidx < esm->fmap->elfhdr.e_shnum && esm->fmap->sect[esm->sidx].mapped != ELF_NO_MAP)
209 unsigned pgsz = getpagesize();
210 unsigned ofst, size;
212 ofst = esm->fmap->sect[esm->sidx].shdr.sh_offset & ~(pgsz - 1);
213 size = ((esm->fmap->sect[esm->sidx].shdr.sh_offset +
214 esm->fmap->sect[esm->sidx].shdr.sh_size + pgsz - 1) & ~(pgsz - 1)) - ofst;
215 if (munmap((char*)esm->fmap->sect[esm->sidx].mapped, size) < 0)
216 WARN("Couldn't unmap the section\n");
217 esm->fmap->sect[esm->sidx].mapped = ELF_NO_MAP;
221 static void elf_end_find(struct elf_file_map* fmap)
223 struct elf_section_map esm;
225 while (fmap)
227 esm.fmap = fmap;
228 esm.sidx = fmap->elfhdr.e_shstrndx;
229 elf_unmap_section(&esm);
230 fmap->shstrtab = ELF_NO_MAP;
231 fmap = fmap->alternate;
235 /******************************************************************
236 * elf_get_map_size
238 * Get the size of an ELF section
240 static inline unsigned elf_get_map_size(struct elf_section_map* esm)
242 if (esm->sidx < 0 || esm->sidx >= esm->fmap->elfhdr.e_shnum)
243 return 0;
244 return esm->fmap->sect[esm->sidx].shdr.sh_size;
247 /******************************************************************
248 * elf_map_file
250 * Maps an ELF file into memory (and checks it's a real ELF file)
252 static BOOL elf_map_file(const WCHAR* filenameW, struct elf_file_map* fmap)
254 static const BYTE elf_signature[4] = { ELFMAG0, ELFMAG1, ELFMAG2, ELFMAG3 };
255 struct stat statbuf;
256 int i;
257 Elf32_Phdr phdr;
258 unsigned tmp, page_mask = getpagesize() - 1;
259 char* filename;
260 unsigned len;
261 BOOL ret = FALSE;
263 len = WideCharToMultiByte(CP_UNIXCP, 0, filenameW, -1, NULL, 0, NULL, NULL);
264 if (!(filename = HeapAlloc(GetProcessHeap(), 0, len))) return FALSE;
265 WideCharToMultiByte(CP_UNIXCP, 0, filenameW, -1, filename, len, NULL, NULL);
267 fmap->fd = -1;
268 fmap->shstrtab = ELF_NO_MAP;
269 fmap->alternate = NULL;
271 /* check that the file exists, and that the module hasn't been loaded yet */
272 if (stat(filename, &statbuf) == -1 || S_ISDIR(statbuf.st_mode)) goto done;
274 /* Now open the file, so that we can mmap() it. */
275 if ((fmap->fd = open(filename, O_RDONLY)) == -1) goto done;
277 if (read(fmap->fd, &fmap->elfhdr, sizeof(fmap->elfhdr)) != sizeof(fmap->elfhdr))
278 goto done;
279 /* and check for an ELF header */
280 if (memcmp(fmap->elfhdr.e_ident,
281 elf_signature, sizeof(elf_signature))) goto done;
283 fmap->sect = HeapAlloc(GetProcessHeap(), 0,
284 fmap->elfhdr.e_shnum * sizeof(fmap->sect[0]));
285 if (!fmap->sect) goto done;
287 lseek(fmap->fd, fmap->elfhdr.e_shoff, SEEK_SET);
288 for (i = 0; i < fmap->elfhdr.e_shnum; i++)
290 read(fmap->fd, &fmap->sect[i].shdr, sizeof(fmap->sect[i].shdr));
291 fmap->sect[i].mapped = ELF_NO_MAP;
294 /* grab size of module once loaded in memory */
295 lseek(fmap->fd, fmap->elfhdr.e_phoff, SEEK_SET);
296 fmap->elf_size = 0;
297 fmap->elf_start = ~0L;
298 for (i = 0; i < fmap->elfhdr.e_phnum; i++)
300 if (read(fmap->fd, &phdr, sizeof(phdr)) == sizeof(phdr) &&
301 phdr.p_type == PT_LOAD)
303 tmp = (phdr.p_vaddr + phdr.p_memsz + page_mask) & ~page_mask;
304 if (fmap->elf_size < tmp) fmap->elf_size = tmp;
305 if (phdr.p_vaddr < fmap->elf_start) fmap->elf_start = phdr.p_vaddr;
308 /* if non relocatable ELF, then remove fixed address from computation
309 * otherwise, all addresses are zero based and start has no effect
311 fmap->elf_size -= fmap->elf_start;
312 ret = TRUE;
313 done:
314 HeapFree(GetProcessHeap(), 0, filename);
315 return ret;
318 /******************************************************************
319 * elf_unmap_file
321 * Unmaps an ELF file from memory (previously mapped with elf_map_file)
323 static void elf_unmap_file(struct elf_file_map* fmap)
325 while (fmap)
327 if (fmap->fd != -1)
329 struct elf_section_map esm;
330 esm.fmap = fmap;
331 for (esm.sidx = 0; esm.sidx < fmap->elfhdr.e_shnum; esm.sidx++)
333 elf_unmap_section(&esm);
335 HeapFree(GetProcessHeap(), 0, fmap->sect);
336 close(fmap->fd);
338 fmap = fmap->alternate;
342 /******************************************************************
343 * elf_is_in_thunk_area
345 * Check whether an address lies within one of the thunk area we
346 * know of.
348 int elf_is_in_thunk_area(unsigned long addr,
349 const struct elf_thunk_area* thunks)
351 unsigned i;
353 for (i = 0; thunks[i].symname; i++)
355 if (addr >= thunks[i].rva_start && addr < thunks[i].rva_end)
356 return i;
358 return -1;
361 /******************************************************************
362 * elf_hash_symtab
364 * creating an internal hash table to ease use ELF symtab information lookup
366 static void elf_hash_symtab(struct module* module, struct pool* pool,
367 struct hash_table* ht_symtab, struct elf_file_map* fmap,
368 struct elf_thunk_area* thunks)
370 int i, j, nsym;
371 const char* strp;
372 const char* symname;
373 struct symt_compiland* compiland = NULL;
374 const char* ptr;
375 const Elf32_Sym* symp;
376 struct symtab_elt* ste;
377 struct elf_section_map esm, esm_str;
379 if (!elf_find_section(fmap, ".symtab", SHT_SYMTAB, &esm) &&
380 !elf_find_section(fmap, ".dynsym", SHT_DYNSYM, &esm)) return;
381 if ((symp = (const Elf32_Sym*)elf_map_section(&esm)) == ELF_NO_MAP) return;
382 esm_str.fmap = fmap;
383 esm_str.sidx = fmap->sect[esm.sidx].shdr.sh_link;
384 if ((strp = elf_map_section(&esm_str)) == ELF_NO_MAP) return;
386 nsym = elf_get_map_size(&esm) / sizeof(*symp);
388 for (j = 0; thunks[j].symname; j++)
389 thunks[j].rva_start = thunks[j].rva_end = 0;
391 for (i = 0; i < nsym; i++, symp++)
393 /* Ignore certain types of entries which really aren't of that much
394 * interest.
396 if ((ELF32_ST_TYPE(symp->st_info) != STT_NOTYPE &&
397 ELF32_ST_TYPE(symp->st_info) != STT_FILE &&
398 ELF32_ST_TYPE(symp->st_info) != STT_OBJECT &&
399 ELF32_ST_TYPE(symp->st_info) != STT_FUNC) ||
400 symp->st_shndx == SHN_UNDEF)
402 continue;
405 symname = strp + symp->st_name;
407 /* handle some specific symtab (that we'll throw away when done) */
408 switch (ELF32_ST_TYPE(symp->st_info))
410 case STT_FILE:
411 if (symname)
412 compiland = symt_new_compiland(module, symp->st_value,
413 source_new(module, NULL, symname));
414 else
415 compiland = NULL;
416 continue;
417 case STT_NOTYPE:
418 /* we are only interested in wine markers inserted by winebuild */
419 for (j = 0; thunks[j].symname; j++)
421 if (!strcmp(symname, thunks[j].symname))
423 thunks[j].rva_start = symp->st_value;
424 thunks[j].rva_end = symp->st_value + symp->st_size;
425 break;
428 continue;
431 /* FIXME: we don't need to handle them (GCC internals)
432 * Moreover, they screw up our symbol lookup :-/
434 if (symname[0] == '.' && symname[1] == 'L' && isdigit(symname[2]))
435 continue;
437 ste = pool_alloc(pool, sizeof(*ste));
438 ste->ht_elt.name = symname;
439 /* GCC emits, in some cases, a .<digit>+ suffix.
440 * This is used for static variable inside functions, so
441 * that we can have several such variables with same name in
442 * the same compilation unit
443 * We simply ignore that suffix when present (we also get rid
444 * of it in stabs parsing)
446 ptr = symname + strlen(symname) - 1;
447 if (isdigit(*ptr))
449 while (isdigit(*ptr) && ptr >= symname) ptr--;
450 if (ptr > symname && *ptr == '.')
452 char* n = pool_alloc(pool, ptr - symname + 1);
453 memcpy(n, symname, ptr - symname + 1);
454 n[ptr - symname] = '\0';
455 ste->ht_elt.name = n;
458 ste->symp = symp;
459 ste->compiland = compiland;
460 ste->used = 0;
461 hash_table_add(ht_symtab, &ste->ht_elt);
463 /* as we added in the ht_symtab pointers to the symbols themselves,
464 * we cannot unmap yet the sections, it will be done when we're over
465 * with this ELF file
469 /******************************************************************
470 * elf_lookup_symtab
472 * lookup a symbol by name in our internal hash table for the symtab
474 static const Elf32_Sym* elf_lookup_symtab(const struct module* module,
475 const struct hash_table* ht_symtab,
476 const char* name, struct symt* compiland)
478 struct symtab_elt* weak_result = NULL; /* without compiland name */
479 struct symtab_elt* result = NULL;
480 struct hash_table_iter hti;
481 struct symtab_elt* ste;
482 const char* compiland_name;
483 const char* compiland_basename;
484 const char* base;
486 /* we need weak match up (at least) when symbols of same name,
487 * defined several times in different compilation units,
488 * are merged in a single one (hence a different filename for c.u.)
490 if (compiland)
492 compiland_name = source_get(module,
493 ((struct symt_compiland*)compiland)->source);
494 compiland_basename = strrchr(compiland_name, '/');
495 if (!compiland_basename++) compiland_basename = compiland_name;
497 else compiland_name = compiland_basename = NULL;
499 hash_table_iter_init(ht_symtab, &hti, name);
500 while ((ste = hash_table_iter_up(&hti)))
502 if (ste->used || strcmp(ste->ht_elt.name, name)) continue;
504 weak_result = ste;
505 if ((ste->compiland && !compiland_name) || (!ste->compiland && compiland_name))
506 continue;
507 if (ste->compiland && compiland_name)
509 const char* filename = source_get(module, ste->compiland->source);
510 if (strcmp(filename, compiland_name))
512 base = strrchr(filename, '/');
513 if (!base++) base = filename;
514 if (strcmp(base, compiland_basename)) continue;
517 if (result)
519 FIXME("Already found symbol %s (%s) in symtab %s @%08x and %s @%08x\n",
520 name, compiland_name,
521 source_get(module, result->compiland->source), (unsigned int)result->symp->st_value,
522 source_get(module, ste->compiland->source), (unsigned int)ste->symp->st_value);
524 else
526 result = ste;
527 ste->used = 1;
530 if (!result && !(result = weak_result))
532 FIXME("Couldn't find symbol %s!%s in symtab\n",
533 debugstr_w(module->module.ModuleName), name);
534 return NULL;
536 return result->symp;
539 /******************************************************************
540 * elf_finish_stabs_info
542 * - get any relevant information (address & size) from the bits we got from the
543 * stabs debugging information
545 static void elf_finish_stabs_info(struct module* module, struct hash_table* symtab)
547 struct hash_table_iter hti;
548 void* ptr;
549 struct symt_ht* sym;
550 const Elf32_Sym* symp;
552 hash_table_iter_init(&module->ht_symbols, &hti, NULL);
553 while ((ptr = hash_table_iter_up(&hti)))
555 sym = GET_ENTRY(ptr, struct symt_ht, hash_elt);
556 switch (sym->symt.tag)
558 case SymTagFunction:
559 if (((struct symt_function*)sym)->address != module->elf_info->elf_addr &&
560 ((struct symt_function*)sym)->size)
562 break;
564 symp = elf_lookup_symtab(module, symtab, sym->hash_elt.name,
565 ((struct symt_function*)sym)->container);
566 if (symp)
568 if (((struct symt_function*)sym)->address != module->elf_info->elf_addr &&
569 ((struct symt_function*)sym)->address != module->elf_info->elf_addr + symp->st_value)
570 FIXME("Changing address for %p/%s!%s from %08lx to %08lx\n",
571 sym, debugstr_w(module->module.ModuleName), sym->hash_elt.name,
572 ((struct symt_function*)sym)->address, module->elf_info->elf_addr + symp->st_value);
573 if (((struct symt_function*)sym)->size && ((struct symt_function*)sym)->size != symp->st_size)
574 FIXME("Changing size for %p/%s!%s from %08lx to %08x\n",
575 sym, debugstr_w(module->module.ModuleName), sym->hash_elt.name,
576 ((struct symt_function*)sym)->size, (unsigned int)symp->st_size);
578 ((struct symt_function*)sym)->address = module->elf_info->elf_addr +
579 symp->st_value;
580 ((struct symt_function*)sym)->size = symp->st_size;
581 } else
582 FIXME("Couldn't find %s!%s\n",
583 debugstr_w(module->module.ModuleName), sym->hash_elt.name);
584 break;
585 case SymTagData:
586 switch (((struct symt_data*)sym)->kind)
588 case DataIsGlobal:
589 case DataIsFileStatic:
590 if (((struct symt_data*)sym)->u.var.offset != module->elf_info->elf_addr)
591 break;
592 symp = elf_lookup_symtab(module, symtab, sym->hash_elt.name,
593 ((struct symt_data*)sym)->container);
594 if (symp)
596 if (((struct symt_data*)sym)->u.var.offset != module->elf_info->elf_addr &&
597 ((struct symt_data*)sym)->u.var.offset != module->elf_info->elf_addr + symp->st_value)
598 FIXME("Changing address for %p/%s!%s from %08lx to %08lx\n",
599 sym, debugstr_w(module->module.ModuleName), sym->hash_elt.name,
600 ((struct symt_function*)sym)->address, module->elf_info->elf_addr + symp->st_value);
601 ((struct symt_data*)sym)->u.var.offset = module->elf_info->elf_addr +
602 symp->st_value;
603 ((struct symt_data*)sym)->kind = (ELF32_ST_BIND(symp->st_info) == STB_LOCAL) ?
604 DataIsFileStatic : DataIsGlobal;
605 } else
606 FIXME("Couldn't find %s!%s\n",
607 debugstr_w(module->module.ModuleName), sym->hash_elt.name);
608 break;
609 default:;
611 break;
612 default:
613 FIXME("Unsupported tag %u\n", sym->symt.tag);
614 break;
617 /* since we may have changed some addresses & sizes, mark the module to be resorted */
618 module->sortlist_valid = FALSE;
621 /******************************************************************
622 * elf_load_wine_thunks
624 * creating the thunk objects for a wine native DLL
626 static int elf_new_wine_thunks(struct module* module, struct hash_table* ht_symtab,
627 const struct elf_thunk_area* thunks)
629 int j;
630 struct hash_table_iter hti;
631 struct symtab_elt* ste;
632 DWORD addr;
633 struct symt_ht* symt;
635 hash_table_iter_init(ht_symtab, &hti, NULL);
636 while ((ste = hash_table_iter_up(&hti)))
638 if (ste->used) continue;
640 addr = module->elf_info->elf_addr + ste->symp->st_value;
642 j = elf_is_in_thunk_area(ste->symp->st_value, thunks);
643 if (j >= 0) /* thunk found */
645 symt_new_thunk(module, ste->compiland, ste->ht_elt.name, thunks[j].ordinal,
646 addr, ste->symp->st_size);
648 else
650 ULONG64 ref_addr;
652 symt = symt_find_nearest(module, addr);
653 if (symt)
654 symt_get_info(&symt->symt, TI_GET_ADDRESS, &ref_addr);
655 if (!symt || addr != ref_addr)
657 /* creating public symbols for all the ELF symbols which haven't been
658 * used yet (ie we have no debug information on them)
659 * That's the case, for example, of the .spec.c files
661 switch (ELF32_ST_TYPE(ste->symp->st_info))
663 case STT_FUNC:
664 symt_new_function(module, ste->compiland, ste->ht_elt.name,
665 addr, ste->symp->st_size, NULL);
666 break;
667 case STT_OBJECT:
668 symt_new_global_variable(module, ste->compiland, ste->ht_elt.name,
669 ELF32_ST_BIND(ste->symp->st_info) == STB_LOCAL,
670 addr, ste->symp->st_size, NULL);
671 break;
672 default:
673 FIXME("Shouldn't happen\n");
674 break;
676 /* FIXME: this is a hack !!!
677 * we are adding new symbols, but as we're parsing a symbol table
678 * (hopefully without duplicate symbols) we delay rebuilding the sorted
679 * module table until we're done with the symbol table
680 * Otherwise, as we intertwine symbols's add and lookup, performance
681 * is rather bad
683 module->sortlist_valid = TRUE;
685 else if (strcmp(ste->ht_elt.name, symt->hash_elt.name))
687 ULONG64 xaddr = 0, xsize = 0;
688 DWORD kind = -1;
690 symt_get_info(&symt->symt, TI_GET_ADDRESS, &xaddr);
691 symt_get_info(&symt->symt, TI_GET_LENGTH, &xsize);
692 symt_get_info(&symt->symt, TI_GET_DATAKIND, &kind);
694 /* If none of symbols has a correct size, we consider they are both markers
695 * Hence, we can silence this warning
696 * Also, we check that we don't have two symbols, one local, the other
697 * global which is legal
699 if ((xsize || ste->symp->st_size) &&
700 (kind == (ELF32_ST_BIND(ste->symp->st_info) == STB_LOCAL) ? DataIsFileStatic : DataIsGlobal))
701 FIXME("Duplicate in %s: %s<%08x-%08x> %s<%s-%s>\n",
702 debugstr_w(module->module.ModuleName),
703 ste->ht_elt.name, addr, (unsigned int)ste->symp->st_size,
704 symt->hash_elt.name,
705 wine_dbgstr_longlong(xaddr), wine_dbgstr_longlong(xsize));
709 /* see comment above */
710 module->sortlist_valid = FALSE;
711 return TRUE;
714 /******************************************************************
715 * elf_new_public_symbols
717 * Creates a set of public symbols from an ELF symtab
719 static int elf_new_public_symbols(struct module* module, struct hash_table* symtab)
721 struct hash_table_iter hti;
722 struct symtab_elt* ste;
724 if (dbghelp_options & SYMOPT_NO_PUBLICS) return TRUE;
726 /* FIXME: we're missing the ELF entry point here */
728 hash_table_iter_init(symtab, &hti, NULL);
729 while ((ste = hash_table_iter_up(&hti)))
731 symt_new_public(module, ste->compiland, ste->ht_elt.name,
732 module->elf_info->elf_addr + ste->symp->st_value,
733 ste->symp->st_size, TRUE /* FIXME */,
734 ELF32_ST_TYPE(ste->symp->st_info) == STT_FUNC);
736 return TRUE;
739 /* Copyright (C) 1986 Gary S. Brown. Modified by Robert Shearman. You may use
740 the following calc_crc32 code or tables extracted from it, as desired without
741 restriction. */
743 /**********************************************************************\
744 |* Demonstration program to compute the 32-bit CRC used as the frame *|
745 |* check sequence in ADCCP (ANSI X3.66, also known as FIPS PUB 71 *|
746 |* and FED-STD-1003, the U.S. versions of CCITT's X.25 link-level *|
747 |* protocol). The 32-bit FCS was added via the Federal Register, *|
748 |* 1 June 1982, p.23798. I presume but don't know for certain that *|
749 |* this polynomial is or will be included in CCITT V.41, which *|
750 |* defines the 16-bit CRC (often called CRC-CCITT) polynomial. FIPS *|
751 |* PUB 78 says that the 32-bit FCS reduces otherwise undetected *|
752 |* errors by a factor of 10^-5 over 16-bit FCS. *|
753 \**********************************************************************/
755 /* First, the polynomial itself and its table of feedback terms. The */
756 /* polynomial is */
757 /* 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 */
758 /* Note that we take it "backwards" and put the highest-order term in */
759 /* the lowest-order bit. The X^32 term is "implied"; the LSB is the */
760 /* X^31 term, etc. The X^0 term (usually shown as "+1") results in */
761 /* the MSB being 1. */
763 /* Note that the usual hardware shift register implementation, which */
764 /* is what we're using (we're merely optimizing it by doing eight-bit */
765 /* chunks at a time) shifts bits into the lowest-order term. In our */
766 /* implementation, that means shifting towards the right. Why do we */
767 /* do it this way? Because the calculated CRC must be transmitted in */
768 /* order from highest-order term to lowest-order term. UARTs transmit */
769 /* characters in order from LSB to MSB. By storing the CRC this way, */
770 /* we hand it to the UART in the order low-byte to high-byte; the UART */
771 /* sends each low-bit to hight-bit; and the result is transmission bit */
772 /* by bit from highest- to lowest-order term without requiring any bit */
773 /* shuffling on our part. Reception works similarly. */
775 /* The feedback terms table consists of 256, 32-bit entries. Notes: */
776 /* */
777 /* 1. The table can be generated at runtime if desired; code to do so */
778 /* is shown later. It might not be obvious, but the feedback */
779 /* terms simply represent the results of eight shift/xor opera- */
780 /* tions for all combinations of data and CRC register values. */
781 /* */
782 /* 2. The CRC accumulation logic is the same for all CRC polynomials, */
783 /* be they sixteen or thirty-two bits wide. You simply choose the */
784 /* appropriate table. Alternatively, because the table can be */
785 /* generated at runtime, you can start by generating the table for */
786 /* the polynomial in question and use exactly the same "updcrc", */
787 /* if your application needn't simultaneously handle two CRC */
788 /* polynomials. (Note, however, that XMODEM is strange.) */
789 /* */
790 /* 3. For 16-bit CRCs, the table entries need be only 16 bits wide; */
791 /* of course, 32-bit entries work OK if the high 16 bits are zero. */
792 /* */
793 /* 4. The values must be right-shifted by eight bits by the "updcrc" */
794 /* logic; the shift must be unsigned (bring in zeroes). On some */
795 /* hardware you could probably optimize the shift in assembler by */
796 /* using byte-swap instructions. */
799 static DWORD calc_crc32(struct elf_file_map* fmap)
801 #define UPDC32(octet,crc) (crc_32_tab[((crc) ^ (octet)) & 0xff] ^ ((crc) >> 8))
802 static const DWORD crc_32_tab[] =
803 { /* CRC polynomial 0xedb88320 */
804 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f,
805 0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988,
806 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, 0x1db71064, 0x6ab020f2,
807 0xf3b97148, 0x84be41de, 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7,
808 0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9,
809 0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172,
810 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, 0x35b5a8fa, 0x42b2986c,
811 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59,
812 0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423,
813 0xcfba9599, 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924,
814 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190, 0x01db7106,
815 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433,
816 0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d,
817 0x91646c97, 0xe6635c01, 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e,
818 0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950,
819 0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65,
820 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, 0x4adfa541, 0x3dd895d7,
821 0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0,
822 0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa,
823 0xbe0b1010, 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
824 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, 0x2eb40d81,
825 0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a,
826 0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683, 0xe3630b12, 0x94643b84,
827 0x0d6d6a3e, 0x7a6a5aa8, 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1,
828 0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb,
829 0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc,
830 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, 0xd6d6a3e8, 0xa1d1937e,
831 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b,
832 0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55,
833 0x316e8eef, 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,
834 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe, 0xb2bd0b28,
835 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d,
836 0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, 0x9c0906a9, 0xeb0e363f,
837 0x72076785, 0x05005713, 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38,
838 0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242,
839 0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777,
840 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, 0x8f659eff, 0xf862ae69,
841 0x616bffd3, 0x166ccf45, 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2,
842 0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc,
843 0x40df0b66, 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
844 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, 0xcdd70693,
845 0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94,
846 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d
848 int i, r;
849 unsigned char buffer[256];
850 DWORD crc = ~0;
852 lseek(fmap->fd, 0, SEEK_SET);
853 while ((r = read(fmap->fd, buffer, sizeof(buffer))) > 0)
855 for (i = 0; i < r; i++) crc = UPDC32(buffer[i], crc);
857 return ~crc;
858 #undef UPDC32
861 static BOOL elf_check_debug_link(const WCHAR* file, struct elf_file_map* fmap, DWORD crc)
863 BOOL ret;
864 if (!elf_map_file(file, fmap)) return FALSE;
865 if (!(ret = crc == calc_crc32(fmap)))
867 WARN("Bad CRC for file %s (got %08x while expecting %08x)\n",
868 debugstr_w(file), calc_crc32(fmap), crc);
869 elf_unmap_file(fmap);
871 return ret;
874 /******************************************************************
875 * elf_locate_debug_link
877 * Locate a filename from a .gnu_debuglink section, using the same
878 * strategy as gdb:
879 * "If the full name of the directory containing the executable is
880 * execdir, and the executable has a debug link that specifies the
881 * name debugfile, then GDB will automatically search for the
882 * debugging information file in three places:
883 * - the directory containing the executable file (that is, it
884 * will look for a file named `execdir/debugfile',
885 * - a subdirectory of that directory named `.debug' (that is, the
886 * file `execdir/.debug/debugfile', and
887 * - a subdirectory of the global debug file directory that includes
888 * the executable's full path, and the name from the link (that is,
889 * the file `globaldebugdir/execdir/debugfile', where globaldebugdir
890 * is the global debug file directory, and execdir has been turned
891 * into a relative path)." (from GDB manual)
893 static BOOL elf_locate_debug_link(struct elf_file_map* fmap, const char* filename,
894 const WCHAR* loaded_file, DWORD crc)
896 static const WCHAR globalDebugDirW[] = {'/','u','s','r','/','l','i','b','/','d','e','b','u','g','/'};
897 static const WCHAR dotDebugW[] = {'.','d','e','b','u','g','/'};
898 const size_t globalDebugDirLen = sizeof(globalDebugDirW) / sizeof(WCHAR);
899 size_t filename_len;
900 WCHAR* p = NULL;
901 WCHAR* slash;
902 struct elf_file_map* fmap_link = NULL;
904 fmap_link = HeapAlloc(GetProcessHeap(), 0, sizeof(*fmap_link));
905 if (!fmap_link) return FALSE;
907 filename_len = MultiByteToWideChar(CP_UNIXCP, 0, filename, -1, NULL, 0);
908 p = HeapAlloc(GetProcessHeap(), 0,
909 (globalDebugDirLen + strlenW(loaded_file) + 6 + 1 + filename_len + 1) * sizeof(WCHAR));
910 if (!p) goto found;
912 /* we prebuild the string with "execdir" */
913 strcpyW(p, loaded_file);
914 slash = strrchrW(p, '/');
915 if (slash == NULL) slash = p; else slash++;
917 /* testing execdir/filename */
918 MultiByteToWideChar(CP_UNIXCP, 0, filename, -1, slash, filename_len);
919 if (elf_check_debug_link(p, fmap_link, crc)) goto found;
921 /* testing execdir/.debug/filename */
922 memcpy(slash, dotDebugW, sizeof(dotDebugW));
923 MultiByteToWideChar(CP_UNIXCP, 0, filename, -1, slash + sizeof(dotDebugW) / sizeof(WCHAR), filename_len);
924 if (elf_check_debug_link(p, fmap_link, crc)) goto found;
926 /* testing globaldebugdir/execdir/filename */
927 memmove(p + globalDebugDirLen, p, (slash - p) * sizeof(WCHAR));
928 memcpy(p, globalDebugDirW, globalDebugDirLen * sizeof(WCHAR));
929 slash += globalDebugDirLen;
930 MultiByteToWideChar(CP_UNIXCP, 0, filename, -1, slash, filename_len);
931 if (elf_check_debug_link(p, fmap_link, crc)) goto found;
933 /* finally testing filename */
934 if (elf_check_debug_link(slash, fmap_link, crc)) goto found;
937 WARN("Couldn't locate or map %s\n", filename);
938 HeapFree(GetProcessHeap(), 0, p);
939 HeapFree(GetProcessHeap(), 0, fmap_link);
940 return FALSE;
942 found:
943 TRACE("Located debug information file %s at %s\n", filename, debugstr_w(p));
944 HeapFree(GetProcessHeap(), 0, p);
945 fmap->alternate = fmap_link;
946 return TRUE;
949 /******************************************************************
950 * elf_debuglink_parse
952 * Parses a .gnu_debuglink section and loads the debug info from
953 * the external file specified there.
955 static BOOL elf_debuglink_parse(struct elf_file_map* fmap, struct module* module,
956 const BYTE* debuglink)
958 /* The content of a debug link section is:
959 * 1/ a NULL terminated string, containing the file name for the
960 * debug info
961 * 2/ padding on 4 byte boundary
962 * 3/ CRC of the linked ELF file
964 const char* dbg_link = (const char*)debuglink;
965 DWORD crc;
967 crc = *(const DWORD*)(dbg_link + ((DWORD_PTR)(strlen(dbg_link) + 4) & ~3));
968 return elf_locate_debug_link(fmap, dbg_link, module->module.LoadedImageName, crc);
971 /******************************************************************
972 * elf_load_debug_info_from_map
974 * Loads the symbolic information from ELF module which mapping is described
975 * in fmap
976 * the module has been loaded at 'load_offset' address, so symbols' address
977 * relocation is performed.
978 * CRC is checked if fmap->with_crc is TRUE
979 * returns
980 * 0 if the file doesn't contain symbolic info (or this info cannot be
981 * read or parsed)
982 * 1 on success
984 static BOOL elf_load_debug_info_from_map(struct module* module,
985 struct elf_file_map* fmap,
986 struct pool* pool,
987 struct hash_table* ht_symtab)
989 BOOL ret = FALSE, lret;
990 struct elf_thunk_area thunks[] =
992 {"__wine_spec_import_thunks", THUNK_ORDINAL_NOTYPE, 0, 0}, /* inter DLL calls */
993 {"__wine_spec_delayed_import_loaders", THUNK_ORDINAL_LOAD, 0, 0}, /* delayed inter DLL calls */
994 {"__wine_spec_delayed_import_thunks", THUNK_ORDINAL_LOAD, 0, 0}, /* delayed inter DLL calls */
995 {"__wine_delay_load", THUNK_ORDINAL_LOAD, 0, 0}, /* delayed inter DLL calls */
996 {"__wine_spec_thunk_text_16", -16, 0, 0}, /* 16 => 32 thunks */
997 {"__wine_spec_thunk_text_32", -32, 0, 0}, /* 32 => 16 thunks */
998 {NULL, 0, 0, 0}
1001 module->module.SymType = SymExport;
1003 /* create a hash table for the symtab */
1004 elf_hash_symtab(module, pool, ht_symtab, fmap, thunks);
1006 if (!(dbghelp_options & SYMOPT_PUBLICS_ONLY))
1008 struct elf_section_map stab_sect, stabstr_sect;
1009 struct elf_section_map debug_sect, debug_str_sect, debug_abbrev_sect,
1010 debug_line_sect, debug_loclist_sect;
1011 struct elf_section_map debuglink_sect;
1013 /* if present, add the .gnu_debuglink file as an alternate to current one */
1014 if (elf_find_section(fmap, ".gnu_debuglink", SHT_NULL, &debuglink_sect))
1016 const BYTE* dbg_link;
1018 dbg_link = (const BYTE*)elf_map_section(&debuglink_sect);
1019 if (dbg_link != ELF_NO_MAP)
1021 lret = elf_debuglink_parse(fmap, module, dbg_link);
1022 if (!lret)
1023 WARN("Couldn't load linked debug file for %s\n",
1024 debugstr_w(module->module.ModuleName));
1025 ret = ret || lret;
1027 elf_unmap_section(&debuglink_sect);
1029 if (elf_find_section(fmap, ".stab", SHT_NULL, &stab_sect) &&
1030 elf_find_section(fmap, ".stabstr", SHT_NULL, &stabstr_sect))
1032 const char* stab;
1033 const char* stabstr;
1035 stab = elf_map_section(&stab_sect);
1036 stabstr = elf_map_section(&stabstr_sect);
1037 if (stab != ELF_NO_MAP && stabstr != ELF_NO_MAP)
1039 /* OK, now just parse all of the stabs. */
1040 lret = stabs_parse(module, module->elf_info->elf_addr,
1041 stab, elf_get_map_size(&stab_sect),
1042 stabstr, elf_get_map_size(&stabstr_sect));
1043 if (lret)
1044 /* and fill in the missing information for stabs */
1045 elf_finish_stabs_info(module, ht_symtab);
1046 else
1047 WARN("Couldn't correctly read stabs\n");
1048 ret = ret || lret;
1050 else lret = FALSE;
1051 elf_unmap_section(&stab_sect);
1052 elf_unmap_section(&stabstr_sect);
1054 if (elf_find_section(fmap, ".debug_info", SHT_NULL, &debug_sect))
1056 /* Dwarf 2 debug information */
1057 const BYTE* dw2_debug;
1058 const BYTE* dw2_debug_abbrev;
1059 const BYTE* dw2_debug_str;
1060 const BYTE* dw2_debug_line;
1061 const BYTE* dw2_debug_loclist;
1063 /* debug info might have a different base address than .so file
1064 * when elf file is prelinked after splitting off debug info
1065 * adjust symbol base addresses accordingly
1067 unsigned long load_offset = module->elf_info->elf_addr +
1068 fmap->elf_start - debug_sect.fmap->elf_start;
1070 TRACE("Loading Dwarf2 information for %s\n", debugstr_w(module->module.ModuleName));
1072 elf_find_section(fmap, ".debug_str", SHT_NULL, &debug_str_sect);
1073 elf_find_section(fmap, ".debug_abbrev", SHT_NULL, &debug_abbrev_sect);
1074 elf_find_section(fmap, ".debug_line", SHT_NULL, &debug_line_sect);
1075 elf_find_section(fmap, ".debug_loc", SHT_NULL, &debug_loclist_sect);
1077 dw2_debug = (const BYTE*)elf_map_section(&debug_sect);
1078 dw2_debug_abbrev = (const BYTE*)elf_map_section(&debug_abbrev_sect);
1079 dw2_debug_str = (const BYTE*)elf_map_section(&debug_str_sect);
1080 dw2_debug_line = (const BYTE*)elf_map_section(&debug_line_sect);
1081 dw2_debug_loclist = (const BYTE*)elf_map_section(&debug_loclist_sect);
1082 if (dw2_debug != ELF_NO_MAP && dw2_debug_abbrev != ELF_NO_MAP && dw2_debug_str != ELF_NO_MAP)
1084 /* OK, now just parse dwarf2 debug infos. */
1085 lret = dwarf2_parse(module, load_offset, thunks,
1086 dw2_debug, elf_get_map_size(&debug_sect),
1087 dw2_debug_abbrev, elf_get_map_size(&debug_abbrev_sect),
1088 dw2_debug_str, elf_get_map_size(&debug_str_sect),
1089 dw2_debug_line, elf_get_map_size(&debug_line_sect),
1090 dw2_debug_loclist, elf_get_map_size(&debug_loclist_sect));
1092 if (!lret)
1093 WARN("Couldn't correctly read dwarf2\n");
1094 ret = ret || lret;
1096 elf_unmap_section(&debug_sect);
1097 elf_unmap_section(&debug_abbrev_sect);
1098 elf_unmap_section(&debug_str_sect);
1099 elf_unmap_section(&debug_line_sect);
1100 elf_unmap_section(&debug_loclist_sect);
1103 if (strstrW(module->module.ModuleName, S_ElfW) ||
1104 !strcmpW(module->module.ModuleName, S_WineLoaderW))
1106 /* add the thunks for native libraries */
1107 if (!(dbghelp_options & SYMOPT_PUBLICS_ONLY))
1108 elf_new_wine_thunks(module, ht_symtab, thunks);
1110 /* add all the public symbols from symtab */
1111 if (elf_new_public_symbols(module, ht_symtab) && !ret) ret = TRUE;
1113 return ret;
1116 /******************************************************************
1117 * elf_load_debug_info
1119 * Loads ELF debugging information from the module image file.
1121 BOOL elf_load_debug_info(struct module* module, struct elf_file_map* fmap)
1123 BOOL ret = TRUE;
1124 struct pool pool;
1125 struct hash_table ht_symtab;
1126 struct elf_file_map my_fmap;
1128 if (module->type != DMT_ELF || !module->elf_info)
1130 ERR("Bad elf module '%s'\n", debugstr_w(module->module.LoadedImageName));
1131 return FALSE;
1134 pool_init(&pool, 65536);
1135 hash_table_init(&pool, &ht_symtab, 256);
1137 if (!fmap)
1139 fmap = &my_fmap;
1140 ret = elf_map_file(module->module.LoadedImageName, fmap);
1142 if (ret)
1143 ret = elf_load_debug_info_from_map(module, fmap, &pool, &ht_symtab);
1145 pool_destroy(&pool);
1146 if (fmap == &my_fmap) elf_unmap_file(fmap);
1147 return ret;
1150 /******************************************************************
1151 * elf_fetch_file_info
1153 * Gathers some more information for an ELF module from a given file
1155 BOOL elf_fetch_file_info(const WCHAR* name, DWORD* base,
1156 DWORD* size, DWORD* checksum)
1158 struct elf_file_map fmap;
1160 if (!elf_map_file(name, &fmap)) return FALSE;
1161 if (base) *base = fmap.elf_start;
1162 *size = fmap.elf_size;
1163 *checksum = calc_crc32(&fmap);
1164 elf_unmap_file(&fmap);
1165 return TRUE;
1168 /******************************************************************
1169 * elf_load_file
1171 * Loads the information for ELF module stored in 'filename'
1172 * the module has been loaded at 'load_offset' address
1173 * returns
1174 * -1 if the file cannot be found/opened
1175 * 0 if the file doesn't contain symbolic info (or this info cannot be
1176 * read or parsed)
1177 * 1 on success
1179 static BOOL elf_load_file(struct process* pcs, const WCHAR* filename,
1180 unsigned long load_offset, struct elf_info* elf_info)
1182 BOOL ret = FALSE;
1183 struct elf_file_map fmap;
1185 TRACE("Processing elf file '%s' at %08lx\n", debugstr_w(filename), load_offset);
1187 if (!elf_map_file(filename, &fmap)) goto leave;
1189 /* Next, we need to find a few of the internal ELF headers within
1190 * this thing. We need the main executable header, and the section
1191 * table.
1193 if (!fmap.elf_start && !load_offset)
1194 ERR("Relocatable ELF %s, but no load address. Loading at 0x0000000\n",
1195 debugstr_w(filename));
1196 if (fmap.elf_start && load_offset)
1198 WARN("Non-relocatable ELF %s, but load address of 0x%08lx supplied. "
1199 "Assuming load address is corrupt\n", debugstr_w(filename), load_offset);
1200 load_offset = 0;
1203 if (elf_info->flags & ELF_INFO_DEBUG_HEADER)
1205 struct elf_section_map esm;
1207 if (elf_find_section(&fmap, ".dynamic", SHT_DYNAMIC, &esm))
1209 Elf32_Dyn dyn;
1210 char* ptr = (char*)fmap.sect[esm.sidx].shdr.sh_addr;
1211 unsigned long len;
1215 if (!ReadProcessMemory(pcs->handle, ptr, &dyn, sizeof(dyn), &len) ||
1216 len != sizeof(dyn))
1217 goto leave;
1218 if (dyn.d_tag == DT_DEBUG)
1220 elf_info->dbg_hdr_addr = dyn.d_un.d_ptr;
1221 break;
1223 ptr += sizeof(dyn);
1224 } while (dyn.d_tag != DT_NULL);
1225 if (dyn.d_tag == DT_NULL) goto leave;
1227 elf_end_find(&fmap);
1230 if (elf_info->flags & ELF_INFO_MODULE)
1232 struct elf_module_info *elf_module_info =
1233 HeapAlloc(GetProcessHeap(), 0, sizeof(struct elf_module_info));
1234 if (!elf_module_info) goto leave;
1235 elf_info->module = module_new(pcs, filename, DMT_ELF, FALSE,
1236 (load_offset) ? load_offset : fmap.elf_start,
1237 fmap.elf_size, 0, calc_crc32(&fmap));
1238 if (!elf_info->module)
1240 HeapFree(GetProcessHeap(), 0, elf_module_info);
1241 goto leave;
1243 elf_info->module->elf_info = elf_module_info;
1244 elf_info->module->elf_info->elf_addr = load_offset;
1246 if (dbghelp_options & SYMOPT_DEFERRED_LOADS)
1248 elf_info->module->module.SymType = SymDeferred;
1249 ret = TRUE;
1251 else ret = elf_load_debug_info(elf_info->module, &fmap);
1253 elf_info->module->elf_info->elf_mark = 1;
1254 elf_info->module->elf_info->elf_loader = 0;
1255 } else ret = TRUE;
1257 if (elf_info->flags & ELF_INFO_NAME)
1259 WCHAR* ptr;
1260 ptr = HeapAlloc(GetProcessHeap(), 0, (lstrlenW(filename) + 1) * sizeof(WCHAR));
1261 if (ptr)
1263 strcpyW(ptr, filename);
1264 elf_info->module_name = ptr;
1266 else ret = FALSE;
1268 leave:
1269 elf_unmap_file(&fmap);
1271 return ret;
1274 /******************************************************************
1275 * elf_load_file_from_path
1276 * tries to load an ELF file from a set of paths (separated by ':')
1278 static BOOL elf_load_file_from_path(HANDLE hProcess,
1279 const WCHAR* filename,
1280 unsigned long load_offset,
1281 const char* path,
1282 struct elf_info* elf_info)
1284 BOOL ret = FALSE;
1285 WCHAR *s, *t, *fn;
1286 WCHAR* pathW = NULL;
1287 unsigned len;
1289 if (!path) return FALSE;
1291 len = MultiByteToWideChar(CP_UNIXCP, 0, path, -1, NULL, 0);
1292 pathW = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
1293 if (!pathW) return FALSE;
1294 MultiByteToWideChar(CP_UNIXCP, 0, path, -1, pathW, len);
1296 for (s = pathW; s && *s; s = (t) ? (t+1) : NULL)
1298 t = strchrW(s, ':');
1299 if (t) *t = '\0';
1300 fn = HeapAlloc(GetProcessHeap(), 0, (lstrlenW(filename) + 1 + lstrlenW(s) + 1) * sizeof(WCHAR));
1301 if (!fn) break;
1302 strcpyW(fn, s);
1303 strcatW(fn, S_SlashW);
1304 strcatW(fn, filename);
1305 ret = elf_load_file(hProcess, fn, load_offset, elf_info);
1306 HeapFree(GetProcessHeap(), 0, fn);
1307 if (ret) break;
1308 s = (t) ? (t+1) : NULL;
1311 HeapFree(GetProcessHeap(), 0, pathW);
1312 return ret;
1315 /******************************************************************
1316 * elf_load_file_from_dll_path
1318 * Tries to load an ELF file from the dll path
1320 static BOOL elf_load_file_from_dll_path(HANDLE hProcess,
1321 const WCHAR* filename,
1322 unsigned long load_offset,
1323 struct elf_info* elf_info)
1325 BOOL ret = FALSE;
1326 unsigned int index = 0;
1327 const char *path;
1329 while (!ret && (path = wine_dll_enum_load_path( index++ )))
1331 WCHAR *name;
1332 unsigned len;
1334 len = MultiByteToWideChar(CP_UNIXCP, 0, path, -1, NULL, 0);
1336 name = HeapAlloc( GetProcessHeap(), 0,
1337 (len + lstrlenW(filename) + 2) * sizeof(WCHAR) );
1339 if (!name) break;
1340 MultiByteToWideChar(CP_UNIXCP, 0, path, -1, name, len);
1341 strcatW( name, S_SlashW );
1342 strcatW( name, filename );
1343 ret = elf_load_file(hProcess, name, load_offset, elf_info);
1344 HeapFree( GetProcessHeap(), 0, name );
1346 return ret;
1349 /******************************************************************
1350 * elf_search_and_load_file
1352 * lookup a file in standard ELF locations, and if found, load it
1354 static BOOL elf_search_and_load_file(struct process* pcs, const WCHAR* filename,
1355 unsigned long load_offset,
1356 struct elf_info* elf_info)
1358 BOOL ret = FALSE;
1359 struct module* module;
1360 static WCHAR S_libstdcPPW[] = {'l','i','b','s','t','d','c','+','+','\0'};
1362 if (filename == NULL || *filename == '\0') return FALSE;
1363 if ((module = module_is_already_loaded(pcs, filename)))
1365 elf_info->module = module;
1366 module->elf_info->elf_mark = 1;
1367 return module->module.SymType;
1370 if (strstrW(filename, S_libstdcPPW)) return FALSE; /* We know we can't do it */
1371 ret = elf_load_file(pcs, filename, load_offset, elf_info);
1372 /* if relative pathname, try some absolute base dirs */
1373 if (!ret && !strchrW(filename, '/'))
1375 ret = elf_load_file_from_path(pcs, filename, load_offset,
1376 getenv("PATH"), elf_info) ||
1377 elf_load_file_from_path(pcs, filename, load_offset,
1378 getenv("LD_LIBRARY_PATH"), elf_info);
1379 if (!ret) ret = elf_load_file_from_dll_path(pcs, filename, load_offset, elf_info);
1382 return ret;
1385 /******************************************************************
1386 * elf_enum_modules_internal
1388 * Enumerate ELF modules from a running process
1390 static BOOL elf_enum_modules_internal(const struct process* pcs,
1391 const WCHAR* main_name,
1392 elf_enum_modules_cb cb, void* user)
1394 struct r_debug dbg_hdr;
1395 void* lm_addr;
1396 struct link_map lm;
1397 char bufstr[256];
1398 WCHAR bufstrW[MAX_PATH];
1400 if (!pcs->dbg_hdr_addr ||
1401 !ReadProcessMemory(pcs->handle, (void*)pcs->dbg_hdr_addr,
1402 &dbg_hdr, sizeof(dbg_hdr), NULL))
1403 return FALSE;
1405 /* Now walk the linked list. In all known ELF implementations,
1406 * the dynamic loader maintains this linked list for us. In some
1407 * cases the first entry doesn't appear with a name, in other cases it
1408 * does.
1410 for (lm_addr = (void*)dbg_hdr.r_map; lm_addr; lm_addr = (void*)lm.l_next)
1412 if (!ReadProcessMemory(pcs->handle, lm_addr, &lm, sizeof(lm), NULL))
1413 return FALSE;
1415 if (lm.l_prev != NULL && /* skip first entry, normally debuggee itself */
1416 lm.l_name != NULL &&
1417 ReadProcessMemory(pcs->handle, lm.l_name, bufstr, sizeof(bufstr), NULL))
1419 bufstr[sizeof(bufstr) - 1] = '\0';
1420 MultiByteToWideChar(CP_UNIXCP, 0, bufstr, -1, bufstrW, sizeof(bufstrW) / sizeof(WCHAR));
1421 if (main_name && !bufstrW[0]) strcpyW(bufstrW, main_name);
1422 if (!cb(bufstrW, (unsigned long)lm.l_addr, user)) break;
1425 return TRUE;
1428 struct elf_sync
1430 struct process* pcs;
1431 struct elf_info elf_info;
1434 static BOOL elf_enum_sync_cb(const WCHAR* name, unsigned long addr, void* user)
1436 struct elf_sync* es = user;
1438 elf_search_and_load_file(es->pcs, name, addr, &es->elf_info);
1439 return TRUE;
1442 /******************************************************************
1443 * elf_synchronize_module_list
1445 * this functions rescans the debuggee module's list and synchronizes it with
1446 * the one from 'pcs', ie:
1447 * - if a module is in debuggee and not in pcs, it's loaded into pcs
1448 * - if a module is in pcs and not in debuggee, it's unloaded from pcs
1450 BOOL elf_synchronize_module_list(struct process* pcs)
1452 struct module* module;
1453 struct elf_sync es;
1455 for (module = pcs->lmodules; module; module = module->next)
1457 if (module->type == DMT_ELF && !module->is_virtual)
1458 module->elf_info->elf_mark = 0;
1461 es.pcs = pcs;
1462 es.elf_info.flags = ELF_INFO_MODULE;
1463 if (!elf_enum_modules_internal(pcs, NULL, elf_enum_sync_cb, &es))
1464 return FALSE;
1466 module = pcs->lmodules;
1467 while (module)
1469 if (module->type == DMT_ELF && !module->is_virtual &&
1470 !module->elf_info->elf_mark && !module->elf_info->elf_loader)
1472 module_remove(pcs, module);
1473 /* restart all over */
1474 module = pcs->lmodules;
1476 else module = module->next;
1478 return TRUE;
1481 /******************************************************************
1482 * elf_search_loader
1484 * Lookup in a running ELF process the loader, and sets its ELF link
1485 * address (for accessing the list of loaded .so libs) in pcs.
1486 * If flags is ELF_INFO_MODULE, the module for the loader is also
1487 * added as a module into pcs.
1489 static BOOL elf_search_loader(struct process* pcs, struct elf_info* elf_info)
1491 BOOL ret;
1492 const char* ptr;
1494 /* All binaries are loaded with WINELOADER (if run from tree) or by the
1495 * main executable (either wine-kthread or wine-pthread)
1496 * FIXME: the heuristic used to know whether we need to load wine-pthread
1497 * or wine-kthread is not 100% safe
1499 if ((ptr = getenv("WINELOADER")))
1501 WCHAR tmp[MAX_PATH];
1502 MultiByteToWideChar(CP_ACP, 0, ptr, -1, tmp, sizeof(tmp) / sizeof(WCHAR));
1503 ret = elf_search_and_load_file(pcs, tmp, 0, elf_info);
1505 else
1507 ret = elf_search_and_load_file(pcs, S_WineKThreadW, 0, elf_info) ||
1508 elf_search_and_load_file(pcs, S_WinePThreadW, 0, elf_info);
1510 return ret;
1513 /******************************************************************
1514 * elf_read_wine_loader_dbg_info
1516 * Try to find a decent wine executable which could have loaded the debuggee
1518 BOOL elf_read_wine_loader_dbg_info(struct process* pcs)
1520 struct elf_info elf_info;
1522 elf_info.flags = ELF_INFO_DEBUG_HEADER | ELF_INFO_MODULE;
1523 if (!elf_search_loader(pcs, &elf_info)) return FALSE;
1524 elf_info.module->elf_info->elf_loader = 1;
1525 module_set_module(elf_info.module, S_WineLoaderW);
1526 return (pcs->dbg_hdr_addr = elf_info.dbg_hdr_addr) != 0;
1529 /******************************************************************
1530 * elf_enum_modules
1532 * Enumerates the ELF loaded modules from a running target (hProc)
1533 * This function doesn't require that someone has called SymInitialize
1534 * on this very process.
1536 BOOL elf_enum_modules(HANDLE hProc, elf_enum_modules_cb cb, void* user)
1538 struct process pcs;
1539 struct elf_info elf_info;
1540 BOOL ret;
1542 memset(&pcs, 0, sizeof(pcs));
1543 pcs.handle = hProc;
1544 elf_info.flags = ELF_INFO_DEBUG_HEADER | ELF_INFO_NAME;
1545 if (!elf_search_loader(&pcs, &elf_info)) return FALSE;
1546 pcs.dbg_hdr_addr = elf_info.dbg_hdr_addr;
1547 ret = elf_enum_modules_internal(&pcs, elf_info.module_name, cb, user);
1548 HeapFree(GetProcessHeap(), 0, (char*)elf_info.module_name);
1549 return ret;
1552 struct elf_load
1554 struct process* pcs;
1555 struct elf_info elf_info;
1556 const WCHAR* name;
1557 BOOL ret;
1560 /******************************************************************
1561 * elf_load_cb
1563 * Callback for elf_load_module, used to walk the list of loaded
1564 * modules.
1566 static BOOL elf_load_cb(const WCHAR* name, unsigned long addr, void* user)
1568 struct elf_load* el = user;
1569 const WCHAR* p;
1571 /* memcmp is needed for matches when bufstr contains also version information
1572 * el->name: libc.so, name: libc.so.6.0
1574 p = strrchrW(name, '/');
1575 if (!p++) p = name;
1576 if (!memcmp(p, el->name, lstrlenW(el->name) * sizeof(WCHAR)))
1578 el->ret = elf_search_and_load_file(el->pcs, name, addr, &el->elf_info);
1579 return FALSE;
1581 return TRUE;
1584 /******************************************************************
1585 * elf_load_module
1587 * loads an ELF module and stores it in process' module list
1588 * Also, find module real name and load address from
1589 * the real loaded modules list in pcs address space
1591 struct module* elf_load_module(struct process* pcs, const WCHAR* name, unsigned long addr)
1593 struct elf_load el;
1595 TRACE("(%p %s %08lx)\n", pcs, debugstr_w(name), addr);
1597 el.elf_info.flags = ELF_INFO_MODULE;
1598 el.ret = FALSE;
1600 if (pcs->dbg_hdr_addr) /* we're debugging a life target */
1602 el.pcs = pcs;
1603 /* do only the lookup from the filename, not the path (as we lookup module
1604 * name in the process' loaded module list)
1606 el.name = strrchrW(name, '/');
1607 if (!el.name++) el.name = name;
1608 el.ret = FALSE;
1610 if (!elf_enum_modules_internal(pcs, NULL, elf_load_cb, &el))
1611 return NULL;
1613 else if (addr)
1615 el.name = name;
1616 el.ret = elf_search_and_load_file(pcs, el.name, addr, &el.elf_info);
1618 if (!el.ret) return NULL;
1619 assert(el.elf_info.module);
1620 return el.elf_info.module;
1623 #else /* !__ELF__ */
1625 BOOL elf_synchronize_module_list(struct process* pcs)
1627 return FALSE;
1630 BOOL elf_fetch_file_info(const WCHAR* name, DWORD* base,
1631 DWORD* size, DWORD* checksum)
1633 return FALSE;
1636 BOOL elf_read_wine_loader_dbg_info(struct process* pcs)
1638 return FALSE;
1641 BOOL elf_enum_modules(HANDLE hProc, elf_enum_modules_cb cb, void* user)
1643 return FALSE;
1646 struct module* elf_load_module(struct process* pcs, const WCHAR* name, unsigned long addr)
1648 return NULL;
1651 BOOL elf_load_debug_info(struct module* module, struct elf_file_map* fmap)
1653 return FALSE;
1656 int elf_is_in_thunk_area(unsigned long addr,
1657 const struct elf_thunk_area* thunks)
1659 return -1;
1661 #endif /* __ELF__ */