Ticket #2249: elf_module.c

File elf_module.c, 61.3 KB (added by kaoutsis, 16 years ago)
Line 
1/*
2 * File elf.c - processing of ELF files
3 *
4 * Copyright (C) 1996, Eric Youngdale.
5 * 1999-2007 Eric Pouech
6 *
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
11 *
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
20 */
21
22#include "config.h"
23#include "wine/port.h"
24
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
31
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
48
49#include "dbghelp_private.h"
50
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
74
75#include "wine/library.h"
76#include "wine/debug.h"
77
78struct elf_module_info
79{
80 unsigned long elf_addr;
81 unsigned short elf_mark : 1,
82 elf_loader : 1;
83};
84
85#ifdef __ELF__
86
87#define ELF_INFO_DEBUG_HEADER 0x0001
88#define ELF_INFO_MODULE 0x0002
89#define ELF_INFO_NAME 0x0004
90
91WINE_DEFAULT_DEBUG_CHANNEL(dbghelp);
92
93struct elf_info
94{
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) */
99};
100
101/* structure holding information while handling an ELF image
102 * allows one by one section mapping for memory savings
103 */
104struct elf_file_map
105{
106 Elf32_Ehdr elfhdr;
107 size_t elf_size;
108 size_t elf_start;
109 struct
110 {
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) */
117};
118
119struct elf_section_map
120{
121 struct elf_file_map* fmap;
122 long sidx;
123};
124
125struct symtab_elt
126{
127 struct hash_table_elt ht_elt;
128 const Elf32_Sym* symp;
129 struct symt_compiland* compiland;
130 unsigned used;
131};
132
133struct elf_thunk_area
134{
135 const char* symname;
136 THUNK_ORDINAL ordinal;
137 unsigned long rva_start;
138 unsigned long rva_end;
139};
140
141/******************************************************************
142 * elf_map_section
143 *
144 * Maps a single section into memory from an ELF file
145 */
146static const char* elf_map_section(struct elf_section_map* esm)
147{
148 unsigned pgsz = getpagesize();
149 unsigned ofst, size;
150
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;
154
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));
163}
164
165/******************************************************************
166 * elf_find_section
167 *
168 * Finds a section by name (and type) into memory from an ELF file
169 * or its alternate if any
170 */
171static BOOL elf_find_section(struct elf_file_map* fmap, const char* name,
172 unsigned sht, struct elf_section_map* esm)
173{
174 unsigned i;
175
176 while (fmap)
177 {
178 if (fmap->shstrtab == ELF_NO_MAP)
179 {
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;
182 }
183 for (i = 0; i < fmap->elfhdr.e_shnum; i++)
184 {
185 if (strcmp(fmap->shstrtab + fmap->sect[i].shdr.sh_name, name) == 0 &&
186 (sht == SHT_NULL || sht == fmap->sect[i].shdr.sh_type))
187 {
188 esm->fmap = fmap;
189 esm->sidx = i;
190 return TRUE;
191 }
192 }
193 fmap = fmap->alternate;
194 }
195 esm->fmap = NULL;
196 esm->sidx = -1;
197 return FALSE;
198}
199
200/******************************************************************
201 * elf_unmap_section
202 *
203 * Unmaps a single section from memory
204 */
205static void elf_unmap_section(struct elf_section_map* esm)
206{
207 if (esm->sidx >= 0 && esm->sidx < esm->fmap->elfhdr.e_shnum && esm->fmap->sect[esm->sidx].mapped != ELF_NO_MAP)
208 {
209 unsigned pgsz = getpagesize();
210 unsigned ofst, size;
211
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;
218 }
219}
220
221static void elf_end_find(struct elf_file_map* fmap)
222{
223 struct elf_section_map esm;
224
225 while (fmap)
226 {
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;
232 }
233}
234
235/******************************************************************
236 * elf_get_map_size
237 *
238 * Get the size of an ELF section
239 */
240static inline unsigned elf_get_map_size(struct elf_section_map* esm)
241{
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;
245}
246
247/******************************************************************
248 * elf_map_file
249 *
250 * Maps an ELF file into memory (and checks it's a real ELF file)
251 */
252static BOOL elf_map_file(const WCHAR* filenameW, struct elf_file_map* fmap)
253{
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;
262
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);
266
267 fmap->fd = -1;
268 fmap->shstrtab = ELF_NO_MAP;
269 fmap->alternate = NULL;
270
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;
273
274 /* Now open the file, so that we can mmap() it. */
275 if ((fmap->fd = open(filename, O_RDONLY)) == -1) goto done;
276
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;
282
283 fmap->sect = HeapAlloc(GetProcessHeap(), 0,
284 fmap->elfhdr.e_shnum * sizeof(fmap->sect[0]));
285 if (!fmap->sect) goto done;
286
287 lseek(fmap->fd, fmap->elfhdr.e_shoff, SEEK_SET);
288 for (i = 0; i < fmap->elfhdr.e_shnum; i++)
289 {
290 read(fmap->fd, &fmap->sect[i].shdr, sizeof(fmap->sect[i].shdr));
291 fmap->sect[i].mapped = ELF_NO_MAP;
292 }
293
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++)
299 {
300 if (read(fmap->fd, &phdr, sizeof(phdr)) == sizeof(phdr) &&
301 phdr.p_type == PT_LOAD)
302 {
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;
306 }
307 }
308 /* if non relocatable ELF, then remove fixed address from computation
309 * otherwise, all addresses are zero based and start has no effect
310 */
311 fmap->elf_size -= fmap->elf_start;
312 ret = TRUE;
313done:
314 HeapFree(GetProcessHeap(), 0, filename);
315 return ret;
316}
317
318/******************************************************************
319 * elf_unmap_file
320 *
321 * Unmaps an ELF file from memory (previously mapped with elf_map_file)
322 */
323static void elf_unmap_file(struct elf_file_map* fmap)
324{
325 while (fmap)
326 {
327 if (fmap->fd != -1)
328 {
329 struct elf_section_map esm;
330 esm.fmap = fmap;
331 for (esm.sidx = 0; esm.sidx < fmap->elfhdr.e_shnum; esm.sidx++)
332 {
333 elf_unmap_section(&esm);
334 }
335 HeapFree(GetProcessHeap(), 0, fmap->sect);
336 close(fmap->fd);
337 }
338 fmap = fmap->alternate;
339 }
340}
341
342/******************************************************************
343 * elf_is_in_thunk_area
344 *
345 * Check whether an address lies within one of the thunk area we
346 * know of.
347 */
348int elf_is_in_thunk_area(unsigned long addr,
349 const struct elf_thunk_area* thunks)
350{
351 unsigned i;
352
353 for (i = 0; thunks[i].symname; i++)
354 {
355 if (addr >= thunks[i].rva_start && addr < thunks[i].rva_end)
356 return i;
357 }
358 return -1;
359}
360
361/******************************************************************
362 * elf_hash_symtab
363 *
364 * creating an internal hash table to ease use ELF symtab information lookup
365 */
366static 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)
369{
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;
378
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;
385
386 nsym = elf_get_map_size(&esm) / sizeof(*symp);
387
388 for (j = 0; thunks[j].symname; j++)
389 thunks[j].rva_start = thunks[j].rva_end = 0;
390
391 for (i = 0; i < nsym; i++, symp++)
392 {
393 /* Ignore certain types of entries which really aren't of that much
394 * interest.
395 */
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)
401 {
402 continue;
403 }
404
405 symname = strp + symp->st_name;
406
407 /* handle some specific symtab (that we'll throw away when done) */
408 switch (ELF32_ST_TYPE(symp->st_info))
409 {
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++)
420 {
421 if (!strcmp(symname, thunks[j].symname))
422 {
423 thunks[j].rva_start = symp->st_value;
424 thunks[j].rva_end = symp->st_value + symp->st_size;
425 break;
426 }
427 }
428 continue;
429 }
430
431 /* FIXME: we don't need to handle them (GCC internals)
432 * Moreover, they screw up our symbol lookup :-/
433 */
434 if (symname[0] == '.' && symname[1] == 'L' && isdigit(symname[2]))
435 continue;
436
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)
445 */
446 ptr = symname + strlen(symname) - 1;
447 if (isdigit(*ptr))
448 {
449 while (isdigit(*ptr) && ptr >= symname) ptr--;
450 if (ptr > symname && *ptr == '.')
451 {
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;
456 }
457 }
458 ste->symp = symp;
459 ste->compiland = compiland;
460 ste->used = 0;
461 hash_table_add(ht_symtab, &ste->ht_elt);
462 }
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
466 */
467}
468
469/******************************************************************
470 * elf_lookup_symtab
471 *
472 * lookup a symbol by name in our internal hash table for the symtab
473 */
474static const Elf32_Sym* elf_lookup_symtab(const struct module* module,
475 const struct hash_table* ht_symtab,
476 const char* name, struct symt* compiland)
477{
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;
485
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.)
489 */
490 if (compiland)
491 {
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;
496 }
497 else compiland_name = compiland_basename = NULL;
498
499 hash_table_iter_init(ht_symtab, &hti, name);
500 while ((ste = hash_table_iter_up(&hti)))
501 {
502 if (ste->used || strcmp(ste->ht_elt.name, name)) continue;
503
504 weak_result = ste;
505 if ((ste->compiland && !compiland_name) || (!ste->compiland && compiland_name))
506 continue;
507 if (ste->compiland && compiland_name)
508 {
509 const char* filename = source_get(module, ste->compiland->source);
510 if (strcmp(filename, compiland_name))
511 {
512 base = strrchr(filename, '/');
513 if (!base++) base = filename;
514 if (strcmp(base, compiland_basename)) continue;
515 }
516 }
517 if (result)
518 {
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);
523 }
524 else
525 {
526 result = ste;
527 ste->used = 1;
528 }
529 }
530 if (!result && !(result = weak_result))
531 {
532 FIXME("Couldn't find symbol %s!%s in symtab\n",
533 debugstr_w(module->module.ModuleName), name);
534 return NULL;
535 }
536 return result->symp;
537}
538
539/******************************************************************
540 * elf_finish_stabs_info
541 *
542 * - get any relevant information (address & size) from the bits we got from the
543 * stabs debugging information
544 */
545static void elf_finish_stabs_info(struct module* module, struct hash_table* symtab)
546{
547 struct hash_table_iter hti;
548 void* ptr;
549 struct symt_ht* sym;
550 const Elf32_Sym* symp;
551
552 hash_table_iter_init(&module->ht_symbols, &hti, NULL);
553 while ((ptr = hash_table_iter_up(&hti)))
554 {
555 sym = GET_ENTRY(ptr, struct symt_ht, hash_elt);
556 switch (sym->symt.tag)
557 {
558 case SymTagFunction:
559 if (((struct symt_function*)sym)->address != module->elf_info->elf_addr &&
560 ((struct symt_function*)sym)->size)
561 {
562 break;
563 }
564 symp = elf_lookup_symtab(module, symtab, sym->hash_elt.name,
565 ((struct symt_function*)sym)->container);
566 if (symp)
567 {
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);
577
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)
587 {
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)
595 {
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:;
610 }
611 break;
612 default:
613 FIXME("Unsupported tag %u\n", sym->symt.tag);
614 break;
615 }
616 }
617 /* since we may have changed some addresses & sizes, mark the module to be resorted */
618 module->sortlist_valid = FALSE;
619}
620
621/******************************************************************
622 * elf_load_wine_thunks
623 *
624 * creating the thunk objects for a wine native DLL
625 */
626static int elf_new_wine_thunks(struct module* module, struct hash_table* ht_symtab,
627 const struct elf_thunk_area* thunks)
628{
629 int j;
630 struct hash_table_iter hti;
631 struct symtab_elt* ste;
632 DWORD addr;
633 struct symt_ht* symt;
634
635 hash_table_iter_init(ht_symtab, &hti, NULL);
636 while ((ste = hash_table_iter_up(&hti)))
637 {
638 if (ste->used) continue;
639
640 addr = module->elf_info->elf_addr + ste->symp->st_value;
641
642 j = elf_is_in_thunk_area(ste->symp->st_value, thunks);
643 if (j >= 0) /* thunk found */
644 {
645 symt_new_thunk(module, ste->compiland, ste->ht_elt.name, thunks[j].ordinal,
646 addr, ste->symp->st_size);
647 }
648 else
649 {
650 ULONG64 ref_addr;
651
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)
656 {
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
660 */
661 switch (ELF32_ST_TYPE(ste->symp->st_info))
662 {
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;
675 }
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
682 */
683 module->sortlist_valid = TRUE;
684 }
685 else if (strcmp(ste->ht_elt.name, symt->hash_elt.name))
686 {
687 ULONG64 xaddr = 0, xsize = 0;
688 DWORD kind = -1;
689
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);
693
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
698 */
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));
706 }
707 }
708 }
709 /* see comment above */
710 module->sortlist_valid = FALSE;
711 return TRUE;
712}
713
714/******************************************************************
715 * elf_new_public_symbols
716 *
717 * Creates a set of public symbols from an ELF symtab
718 */
719static int elf_new_public_symbols(struct module* module, struct hash_table* symtab)
720{
721 struct hash_table_iter hti;
722 struct symtab_elt* ste;
723
724 if (dbghelp_options & SYMOPT_NO_PUBLICS) return TRUE;
725
726 /* FIXME: we're missing the ELF entry point here */
727
728 hash_table_iter_init(symtab, &hti, NULL);
729 while ((ste = hash_table_iter_up(&hti)))
730 {
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);
735 }
736 return TRUE;
737}
738
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. */
742
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\**********************************************************************/
754
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. */
762
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. */
774
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. */
797
798
799static DWORD calc_crc32(struct elf_file_map* fmap)
800{
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
847 };
848 int i, r;
849 unsigned char buffer[256];
850 DWORD crc = ~0;
851
852 lseek(fmap->fd, 0, SEEK_SET);
853 while ((r = read(fmap->fd, buffer, sizeof(buffer))) > 0)
854 {
855 for (i = 0; i < r; i++) crc = UPDC32(buffer[i], crc);
856 }
857 return ~crc;
858#undef UPDC32
859}
860
861static BOOL elf_check_debug_link(const WCHAR* file, struct elf_file_map* fmap, DWORD crc)
862{
863 BOOL ret;
864 if (!elf_map_file(file, fmap)) return FALSE;
865 if (!(ret = crc == calc_crc32(fmap)))
866 {
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);
870 }
871 return ret;
872}
873
874/******************************************************************
875 * elf_locate_debug_link
876 *
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)
892 */
893static BOOL elf_locate_debug_link(struct elf_file_map* fmap, const char* filename,
894 const WCHAR* loaded_file, DWORD crc)
895{
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;
903
904 fmap_link = HeapAlloc(GetProcessHeap(), 0, sizeof(*fmap_link));
905 if (!fmap_link) return FALSE;
906
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;
911
912 /* we prebuild the string with "execdir" */
913 strcpyW(p, loaded_file);
914 slash = strrchrW(p, '/');
915 if (slash == NULL) slash = p; else slash++;
916
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;
920
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;
925
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;
932
933 /* finally testing filename */
934 if (elf_check_debug_link(slash, fmap_link, crc)) goto found;
935
936
937 WARN("Couldn't locate or map %s\n", filename);
938 HeapFree(GetProcessHeap(), 0, p);
939 HeapFree(GetProcessHeap(), 0, fmap_link);
940 return FALSE;
941
942found:
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;
947}
948
949/******************************************************************
950 * elf_debuglink_parse
951 *
952 * Parses a .gnu_debuglink section and loads the debug info from
953 * the external file specified there.
954 */
955static BOOL elf_debuglink_parse(struct elf_file_map* fmap, struct module* module,
956 const BYTE* debuglink)
957{
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
963 */
964 const char* dbg_link = (const char*)debuglink;
965 DWORD crc;
966
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);
969}
970
971/******************************************************************
972 * elf_load_debug_info_from_map
973 *
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
983 */
984static 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)
988{
989 BOOL ret = FALSE, lret;
990 struct elf_thunk_area thunks[] =
991 {
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}
999 };
1000
1001 module->module.SymType = SymExport;
1002
1003 /* create a hash table for the symtab */
1004 elf_hash_symtab(module, pool, ht_symtab, fmap, thunks);
1005
1006 if (!(dbghelp_options & SYMOPT_PUBLICS_ONLY))
1007 {
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;
1012
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))
1015 {
1016 const BYTE* dbg_link;
1017
1018 dbg_link = (const BYTE*)elf_map_section(&debuglink_sect);
1019 if (dbg_link != ELF_NO_MAP)
1020 {
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;
1026 }
1027 elf_unmap_section(&debuglink_sect);
1028 }
1029 if (elf_find_section(fmap, ".stab", SHT_NULL, &stab_sect) &&
1030 elf_find_section(fmap, ".stabstr", SHT_NULL, &stabstr_sect))
1031 {
1032 const char* stab;
1033 const char* stabstr;
1034
1035 stab = elf_map_section(&stab_sect);
1036 stabstr = elf_map_section(&stabstr_sect);
1037 if (stab != ELF_NO_MAP && stabstr != ELF_NO_MAP)
1038 {
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;
1049 }
1050 else lret = FALSE;
1051 elf_unmap_section(&stab_sect);
1052 elf_unmap_section(&stabstr_sect);
1053 }
1054 if (elf_find_section(fmap, ".debug_info", SHT_NULL, &debug_sect))
1055 {
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;
1062
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
1066 */
1067 unsigned long load_offset = module->elf_info->elf_addr +
1068 fmap->elf_start - debug_sect.fmap->elf_start;
1069
1070 TRACE("Loading Dwarf2 information for %s\n", debugstr_w(module->module.ModuleName));
1071
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);
1076
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)
1083 {
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));
1091
1092 if (!lret)
1093 WARN("Couldn't correctly read dwarf2\n");
1094 ret = ret || lret;
1095 }
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);
1101 }
1102 }
1103 if (strstrW(module->module.ModuleName, S_ElfW) ||
1104 !strcmpW(module->module.ModuleName, S_WineLoaderW))
1105 {
1106 /* add the thunks for native libraries */
1107 if (!(dbghelp_options & SYMOPT_PUBLICS_ONLY))
1108 elf_new_wine_thunks(module, ht_symtab, thunks);
1109 }
1110 /* add all the public symbols from symtab */
1111 if (elf_new_public_symbols(module, ht_symtab) && !ret) ret = TRUE;
1112
1113 return ret;
1114}
1115
1116/******************************************************************
1117 * elf_load_debug_info
1118 *
1119 * Loads ELF debugging information from the module image file.
1120 */
1121BOOL elf_load_debug_info(struct module* module, struct elf_file_map* fmap)
1122{
1123 BOOL ret = TRUE;
1124 struct pool pool;
1125 struct hash_table ht_symtab;
1126 struct elf_file_map my_fmap;
1127
1128 if (module->type != DMT_ELF || !module->elf_info)
1129 {
1130 ERR("Bad elf module '%s'\n", debugstr_w(module->module.LoadedImageName));
1131 return FALSE;
1132 }
1133
1134 pool_init(&pool, 65536);
1135 hash_table_init(&pool, &ht_symtab, 256);
1136
1137 if (!fmap)
1138 {
1139 fmap = &my_fmap;
1140 ret = elf_map_file(module->module.LoadedImageName, fmap);
1141 }
1142 if (ret)
1143 ret = elf_load_debug_info_from_map(module, fmap, &pool, &ht_symtab);
1144
1145 pool_destroy(&pool);
1146 if (fmap == &my_fmap) elf_unmap_file(fmap);
1147 return ret;
1148}
1149
1150/******************************************************************
1151 * elf_fetch_file_info
1152 *
1153 * Gathers some more information for an ELF module from a given file
1154 */
1155BOOL elf_fetch_file_info(const WCHAR* name, DWORD* base,
1156 DWORD* size, DWORD* checksum)
1157{
1158 struct elf_file_map fmap;
1159
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;
1166}
1167
1168/******************************************************************
1169 * elf_load_file
1170 *
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
1178 */
1179static BOOL elf_load_file(struct process* pcs, const WCHAR* filename,
1180 unsigned long load_offset, struct elf_info* elf_info)
1181{
1182 BOOL ret = FALSE;
1183 struct elf_file_map fmap;
1184
1185 TRACE("Processing elf file '%s' at %08lx\n", debugstr_w(filename), load_offset);
1186
1187 if (!elf_map_file(filename, &fmap)) goto leave;
1188
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.
1192 */
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)
1197 {
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;
1201 }
1202
1203 if (elf_info->flags & ELF_INFO_DEBUG_HEADER)
1204 {
1205 struct elf_section_map esm;
1206
1207 if (elf_find_section(&fmap, ".dynamic", SHT_DYNAMIC, &esm))
1208 {
1209 Elf32_Dyn dyn;
1210 char* ptr = (char*)fmap.sect[esm.sidx].shdr.sh_addr;
1211 unsigned long len;
1212
1213 do
1214 {
1215 if (!ReadProcessMemory(pcs->handle, ptr, &dyn, sizeof(dyn), &len) ||
1216 len != sizeof(dyn))
1217 goto leave;
1218 if (dyn.d_tag == DT_DEBUG)
1219 {
1220 elf_info->dbg_hdr_addr = dyn.d_un.d_ptr;
1221 break;
1222 }
1223 ptr += sizeof(dyn);
1224 } while (dyn.d_tag != DT_NULL);
1225 if (dyn.d_tag == DT_NULL) goto leave;
1226 }
1227 elf_end_find(&fmap);
1228 }
1229
1230 if (elf_info->flags & ELF_INFO_MODULE)
1231 {
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)
1239 {
1240 HeapFree(GetProcessHeap(), 0, elf_module_info);
1241 goto leave;
1242 }
1243 elf_info->module->elf_info = elf_module_info;
1244 elf_info->module->elf_info->elf_addr = load_offset;
1245
1246 if (dbghelp_options & SYMOPT_DEFERRED_LOADS)
1247 {
1248 elf_info->module->module.SymType = SymDeferred;
1249 ret = TRUE;
1250 }
1251 else ret = elf_load_debug_info(elf_info->module, &fmap);
1252
1253 elf_info->module->elf_info->elf_mark = 1;
1254 elf_info->module->elf_info->elf_loader = 0;
1255 } else ret = TRUE;
1256
1257 if (elf_info->flags & ELF_INFO_NAME)
1258 {
1259 WCHAR* ptr;
1260 ptr = HeapAlloc(GetProcessHeap(), 0, (lstrlenW(filename) + 1) * sizeof(WCHAR));
1261 if (ptr)
1262 {
1263 strcpyW(ptr, filename);
1264 elf_info->module_name = ptr;
1265 }
1266 else ret = FALSE;
1267 }
1268leave:
1269 elf_unmap_file(&fmap);
1270
1271 return ret;
1272}
1273
1274/******************************************************************
1275 * elf_load_file_from_path
1276 * tries to load an ELF file from a set of paths (separated by ':')
1277 */
1278static 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)
1283{
1284 BOOL ret = FALSE;
1285 WCHAR *s, *t, *fn;
1286 WCHAR* pathW = NULL;
1287 unsigned len;
1288
1289 if (!path) return FALSE;
1290
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);
1295
1296 for (s = pathW; s && *s; s = (t) ? (t+1) : NULL)
1297 {
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;
1309 }
1310
1311 HeapFree(GetProcessHeap(), 0, pathW);
1312 return ret;
1313}
1314
1315/******************************************************************
1316 * elf_load_file_from_dll_path
1317 *
1318 * Tries to load an ELF file from the dll path
1319 */
1320static BOOL elf_load_file_from_dll_path(HANDLE hProcess,
1321 const WCHAR* filename,
1322 unsigned long load_offset,
1323 struct elf_info* elf_info)
1324{
1325 BOOL ret = FALSE;
1326 unsigned int index = 0;
1327 const char *path;
1328
1329 while (!ret && (path = wine_dll_enum_load_path( index++ )))
1330 {
1331 WCHAR *name;
1332 unsigned len;
1333
1334 len = MultiByteToWideChar(CP_UNIXCP, 0, path, -1, NULL, 0);
1335
1336 name = HeapAlloc( GetProcessHeap(), 0,
1337 (len + lstrlenW(filename) + 2) * sizeof(WCHAR) );
1338
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 );
1345 }
1346 return ret;
1347}
1348
1349/******************************************************************
1350 * elf_search_and_load_file
1351 *
1352 * lookup a file in standard ELF locations, and if found, load it
1353 */
1354static BOOL elf_search_and_load_file(struct process* pcs, const WCHAR* filename,
1355 unsigned long load_offset,
1356 struct elf_info* elf_info)
1357{
1358 BOOL ret = FALSE;
1359 struct module* module;
1360 static WCHAR S_libstdcPPW[] = {'l','i','b','s','t','d','c','+','+','\0'};
1361
1362 if (filename == NULL || *filename == '\0') return FALSE;
1363 if ((module = module_is_already_loaded(pcs, filename)))
1364 {
1365 elf_info->module = module;
1366 module->elf_info->elf_mark = 1;
1367 return module->module.SymType;
1368 }
1369
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, '/'))
1374 {
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);
1380 }
1381
1382 return ret;
1383}
1384
1385/******************************************************************
1386 * elf_enum_modules_internal
1387 *
1388 * Enumerate ELF modules from a running process
1389 */
1390static BOOL elf_enum_modules_internal(const struct process* pcs,
1391 const WCHAR* main_name,
1392 elf_enum_modules_cb cb, void* user)
1393{
1394 struct r_debug dbg_hdr;
1395 void* lm_addr;
1396 struct link_map lm;
1397 char bufstr[256];
1398 WCHAR bufstrW[MAX_PATH];
1399
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;
1404
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.
1409 */
1410 for (lm_addr = (void*)dbg_hdr.r_map; lm_addr; lm_addr = (void*)lm.l_next)
1411 {
1412 if (!ReadProcessMemory(pcs->handle, lm_addr, &lm, sizeof(lm), NULL))
1413 return FALSE;
1414
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))
1418 {
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;
1423 }
1424 }
1425 return TRUE;
1426}
1427
1428struct elf_sync
1429{
1430 struct process* pcs;
1431 struct elf_info elf_info;
1432};
1433
1434static BOOL elf_enum_sync_cb(const WCHAR* name, unsigned long addr, void* user)
1435{
1436 struct elf_sync* es = user;
1437
1438 elf_search_and_load_file(es->pcs, name, addr, &es->elf_info);
1439 return TRUE;
1440}
1441
1442/******************************************************************
1443 * elf_synchronize_module_list
1444 *
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
1449 */
1450BOOL elf_synchronize_module_list(struct process* pcs)
1451{
1452 struct module* module;
1453 struct elf_sync es;
1454
1455 for (module = pcs->lmodules; module; module = module->next)
1456 {
1457 if (module->type == DMT_ELF && !module->is_virtual)
1458 module->elf_info->elf_mark = 0;
1459 }
1460
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;
1465
1466 module = pcs->lmodules;
1467 while (module)
1468 {
1469 if (module->type == DMT_ELF && !module->is_virtual &&
1470 !module->elf_info->elf_mark && !module->elf_info->elf_loader)
1471 {
1472 module_remove(pcs, module);
1473 /* restart all over */
1474 module = pcs->lmodules;
1475 }
1476 else module = module->next;
1477 }
1478 return TRUE;
1479}
1480
1481/******************************************************************
1482 * elf_search_loader
1483 *
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.
1488 */
1489static BOOL elf_search_loader(struct process* pcs, struct elf_info* elf_info)
1490{
1491 BOOL ret;
1492 const char* ptr;
1493
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
1498 */
1499 if ((ptr = getenv("WINELOADER")))
1500 {
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);
1504 }
1505 else
1506 {
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);
1509 }
1510 return ret;
1511}
1512
1513/******************************************************************
1514 * elf_read_wine_loader_dbg_info
1515 *
1516 * Try to find a decent wine executable which could have loaded the debuggee
1517 */
1518BOOL elf_read_wine_loader_dbg_info(struct process* pcs)
1519{
1520 struct elf_info elf_info;
1521
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;
1527}
1528
1529/******************************************************************
1530 * elf_enum_modules
1531 *
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.
1535 */
1536BOOL elf_enum_modules(HANDLE hProc, elf_enum_modules_cb cb, void* user)
1537{
1538 struct process pcs;
1539 struct elf_info elf_info;
1540 BOOL ret;
1541
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;
1550}
1551
1552struct elf_load
1553{
1554 struct process* pcs;
1555 struct elf_info elf_info;
1556 const WCHAR* name;
1557 BOOL ret;
1558};
1559
1560/******************************************************************
1561 * elf_load_cb
1562 *
1563 * Callback for elf_load_module, used to walk the list of loaded
1564 * modules.
1565 */
1566static BOOL elf_load_cb(const WCHAR* name, unsigned long addr, void* user)
1567{
1568 struct elf_load* el = user;
1569 const WCHAR* p;
1570
1571 /* memcmp is needed for matches when bufstr contains also version information
1572 * el->name: libc.so, name: libc.so.6.0
1573 */
1574 p = strrchrW(name, '/');
1575 if (!p++) p = name;
1576 if (!memcmp(p, el->name, lstrlenW(el->name) * sizeof(WCHAR)))
1577 {
1578 el->ret = elf_search_and_load_file(el->pcs, name, addr, &el->elf_info);
1579 return FALSE;
1580 }
1581 return TRUE;
1582}
1583
1584/******************************************************************
1585 * elf_load_module
1586 *
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
1590 */
1591struct module* elf_load_module(struct process* pcs, const WCHAR* name, unsigned long addr)
1592{
1593 struct elf_load el;
1594
1595 TRACE("(%p %s %08lx)\n", pcs, debugstr_w(name), addr);
1596
1597 el.elf_info.flags = ELF_INFO_MODULE;
1598 el.ret = FALSE;
1599
1600 if (pcs->dbg_hdr_addr) /* we're debugging a life target */
1601 {
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)
1605 */
1606 el.name = strrchrW(name, '/');
1607 if (!el.name++) el.name = name;
1608 el.ret = FALSE;
1609
1610 if (!elf_enum_modules_internal(pcs, NULL, elf_load_cb, &el))
1611 return NULL;
1612 }
1613 else if (addr)
1614 {
1615 el.name = name;
1616 el.ret = elf_search_and_load_file(pcs, el.name, addr, &el.elf_info);
1617 }
1618 if (!el.ret) return NULL;
1619 assert(el.elf_info.module);
1620 return el.elf_info.module;
1621}
1622
1623#else /* !__ELF__ */
1624
1625BOOL elf_synchronize_module_list(struct process* pcs)
1626{
1627 return FALSE;
1628}
1629
1630BOOL elf_fetch_file_info(const WCHAR* name, DWORD* base,
1631 DWORD* size, DWORD* checksum)
1632{
1633 return FALSE;
1634}
1635
1636BOOL elf_read_wine_loader_dbg_info(struct process* pcs)
1637{
1638 return FALSE;
1639}
1640
1641BOOL elf_enum_modules(HANDLE hProc, elf_enum_modules_cb cb, void* user)
1642{
1643 return FALSE;
1644}
1645
1646struct module* elf_load_module(struct process* pcs, const WCHAR* name, unsigned long addr)
1647{
1648 return NULL;
1649}
1650
1651BOOL elf_load_debug_info(struct module* module, struct elf_file_map* fmap)
1652{
1653 return FALSE;
1654}
1655
1656int elf_is_in_thunk_area(unsigned long addr,
1657 const struct elf_thunk_area* thunks)
1658{
1659 return -1;
1660}
1661#endif /* __ELF__ */