ReactOS  0.4.14-dev-317-g96040ec
elf_module.c
Go to the documentation of this file.
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 
46 #include "dbghelp_private.h"
47 #include "winternl.h"
48 
49 #include "image_private.h"
50 
51 #include "wine/library.h"
52 #include "wine/debug.h"
53 
54 #ifdef __ELF__
55 
56 #define ELF_INFO_DEBUG_HEADER 0x0001
57 #define ELF_INFO_MODULE 0x0002
58 #define ELF_INFO_NAME 0x0004
59 
60 #ifndef NT_GNU_BUILD_ID
61 #define NT_GNU_BUILD_ID 3
62 #endif
63 
64 #ifndef HAVE_STRUCT_R_DEBUG
65 struct r_debug
66 {
67  int r_version;
68  struct link_map *r_map;
69  ElfW(Addr) r_brk;
70  enum
71  {
72  RT_CONSISTENT,
73  RT_ADD,
74  RT_DELETE
75  } r_state;
76  ElfW(Addr) r_ldbase;
77 };
78 #endif /* HAVE_STRUCT_R_DEBUG */
79 
80 #ifndef HAVE_STRUCT_LINK_MAP
81 struct link_map
82 {
83  ElfW(Addr) l_addr;
84  char *l_name;
85  ElfW(Dyn) *l_ld;
86  struct link_map *l_next, *l_prev;
87 };
88 #endif /* HAVE_STRUCT_LINK_MAP */
89 
91 
92 struct elf_info
93 {
94  unsigned flags; /* IN one (or several) of the ELF_INFO constants */
95  DWORD_PTR dbg_hdr_addr; /* OUT address of debug header (if ELF_INFO_DEBUG_HEADER is set) */
96  struct module* module; /* OUT loaded module (if ELF_INFO_MODULE is set) */
97  const WCHAR* module_name; /* OUT found module name (if ELF_INFO_NAME is set) */
98 };
99 
100 struct symtab_elt
101 {
102  struct hash_table_elt ht_elt;
103  const Elf_Sym* symp;
104  struct symt_compiland* compiland;
105  unsigned used;
106 };
107 
108 struct elf_thunk_area
109 {
110  const char* symname;
111  THUNK_ORDINAL ordinal;
112  unsigned long rva_start;
113  unsigned long rva_end;
114 };
115 
116 struct elf_module_info
117 {
118  unsigned long elf_addr;
119  unsigned short elf_mark : 1,
120  elf_loader : 1;
121  struct image_file_map file_map;
122 };
123 
124 /******************************************************************
125  * elf_map_section
126  *
127  * Maps a single section into memory from an ELF file
128  */
129 const char* elf_map_section(struct image_section_map* ism)
130 {
131  struct elf_file_map* fmap = &ism->fmap->u.elf;
132  size_t ofst, size, pgsz = sysconf( _SC_PAGESIZE );
133 
134  assert(ism->fmap->modtype == DMT_ELF);
135  if (ism->sidx < 0 || ism->sidx >= ism->fmap->u.elf.elfhdr.e_shnum ||
136  fmap->sect[ism->sidx].shdr.sh_type == SHT_NOBITS)
137  return IMAGE_NO_MAP;
138 
139  if (fmap->target_copy)
140  {
141  return fmap->target_copy + fmap->sect[ism->sidx].shdr.sh_offset;
142  }
143  /* align required information on page size (we assume pagesize is a power of 2) */
144  ofst = fmap->sect[ism->sidx].shdr.sh_offset & ~(pgsz - 1);
145  size = ((fmap->sect[ism->sidx].shdr.sh_offset +
146  fmap->sect[ism->sidx].shdr.sh_size + pgsz - 1) & ~(pgsz - 1)) - ofst;
147  fmap->sect[ism->sidx].mapped = mmap(NULL, size, PROT_READ, MAP_PRIVATE,
148  fmap->fd, ofst);
149  if (fmap->sect[ism->sidx].mapped == IMAGE_NO_MAP) return IMAGE_NO_MAP;
150  return fmap->sect[ism->sidx].mapped + (fmap->sect[ism->sidx].shdr.sh_offset & (pgsz - 1));
151 }
152 
153 /******************************************************************
154  * elf_find_section
155  *
156  * Finds a section by name (and type) into memory from an ELF file
157  * or its alternate if any
158  */
159 BOOL elf_find_section(struct image_file_map* _fmap, const char* name,
160  unsigned sht, struct image_section_map* ism)
161 {
162  struct elf_file_map* fmap;
163  unsigned i;
164 
165  while (_fmap)
166  {
167  fmap = &_fmap->u.elf;
168  if (fmap->shstrtab == IMAGE_NO_MAP)
169  {
170  struct image_section_map hdr_ism = {_fmap, fmap->elfhdr.e_shstrndx};
171  if ((fmap->shstrtab = elf_map_section(&hdr_ism)) == IMAGE_NO_MAP) break;
172  }
173  for (i = 0; i < fmap->elfhdr.e_shnum; i++)
174  {
175  if (strcmp(fmap->shstrtab + fmap->sect[i].shdr.sh_name, name) == 0 &&
176  (sht == SHT_NULL || sht == fmap->sect[i].shdr.sh_type))
177  {
178  ism->fmap = _fmap;
179  ism->sidx = i;
180  return TRUE;
181  }
182  }
183  _fmap = fmap->alternate;
184  }
185  ism->fmap = NULL;
186  ism->sidx = -1;
187  return FALSE;
188 }
189 
190 /******************************************************************
191  * elf_unmap_section
192  *
193  * Unmaps a single section from memory
194  */
195 void elf_unmap_section(struct image_section_map* ism)
196 {
197  struct elf_file_map* fmap = &ism->fmap->u.elf;
198 
199  if (ism->sidx >= 0 && ism->sidx < fmap->elfhdr.e_shnum && !fmap->target_copy &&
200  fmap->sect[ism->sidx].mapped != IMAGE_NO_MAP)
201  {
202  size_t pgsz = sysconf( _SC_PAGESIZE );
203  size_t ofst = fmap->sect[ism->sidx].shdr.sh_offset & ~(pgsz - 1);
204  size_t size = ((fmap->sect[ism->sidx].shdr.sh_offset +
205  fmap->sect[ism->sidx].shdr.sh_size + pgsz - 1) & ~(pgsz - 1)) - ofst;
206  if (munmap((char*)fmap->sect[ism->sidx].mapped, size) < 0)
207  WARN("Couldn't unmap the section\n");
208  fmap->sect[ism->sidx].mapped = IMAGE_NO_MAP;
209  }
210 }
211 
212 static void elf_end_find(struct image_file_map* fmap)
213 {
214  struct image_section_map ism;
215 
216  while (fmap)
217  {
218  ism.fmap = fmap;
219  ism.sidx = fmap->u.elf.elfhdr.e_shstrndx;
220  elf_unmap_section(&ism);
221  fmap->u.elf.shstrtab = IMAGE_NO_MAP;
222  fmap = fmap->u.elf.alternate;
223  }
224 }
225 
226 /******************************************************************
227  * elf_get_map_rva
228  *
229  * Get the RVA of an ELF section
230  */
232 {
233  if (ism->sidx < 0 || ism->sidx >= ism->fmap->u.elf.elfhdr.e_shnum)
234  return 0;
235  return ism->fmap->u.elf.sect[ism->sidx].shdr.sh_addr - ism->fmap->u.elf.elf_start;
236 }
237 
238 /******************************************************************
239  * elf_get_map_size
240  *
241  * Get the size of an ELF section
242  */
243 unsigned elf_get_map_size(const struct image_section_map* ism)
244 {
245  if (ism->sidx < 0 || ism->sidx >= ism->fmap->u.elf.elfhdr.e_shnum)
246  return 0;
247  return ism->fmap->u.elf.sect[ism->sidx].shdr.sh_size;
248 }
249 
250 static inline void elf_reset_file_map(struct image_file_map* fmap)
251 {
252  fmap->u.elf.fd = -1;
253  fmap->u.elf.shstrtab = IMAGE_NO_MAP;
254  fmap->u.elf.alternate = NULL;
255  fmap->u.elf.target_copy = NULL;
256 }
257 
258 struct elf_map_file_data
259 {
260  enum {from_file, from_process} kind;
261  union
262  {
263  struct
264  {
265  const WCHAR* filename;
266  } file;
267  struct
268  {
269  HANDLE handle;
270  void* load_addr;
271  } process;
272  } u;
273 };
274 
275 static BOOL elf_map_file_read(struct image_file_map* fmap, struct elf_map_file_data* emfd,
276  void* buf, size_t len, off_t off)
277 {
278  SIZE_T dw;
279 
280  switch (emfd->kind)
281  {
282  case from_file:
283  return pread(fmap->u.elf.fd, buf, len, off) == len;
284  case from_process:
285  return ReadProcessMemory(emfd->u.process.handle,
286  (void*)((unsigned long)emfd->u.process.load_addr + (unsigned long)off),
287  buf, len, &dw) && dw == len;
288  default:
289  assert(0);
290  return FALSE;
291  }
292 }
293 
294 /******************************************************************
295  * elf_map_file
296  *
297  * Maps an ELF file into memory (and checks it's a real ELF file)
298  */
299 static BOOL elf_map_file(struct elf_map_file_data* emfd, struct image_file_map* fmap)
300 {
301  static const BYTE elf_signature[4] = { ELFMAG0, ELFMAG1, ELFMAG2, ELFMAG3 };
302  struct stat statbuf;
303  unsigned int i;
304  Elf_Phdr phdr;
305  size_t tmp, page_mask = sysconf( _SC_PAGESIZE ) - 1;
306  char* filename;
307  unsigned len;
308  BOOL ret = FALSE;
309 
310  switch (emfd->kind)
311  {
312  case from_file:
313  len = WideCharToMultiByte(CP_UNIXCP, 0, emfd->u.file.filename, -1, NULL, 0, NULL, NULL);
314  if (!(filename = HeapAlloc(GetProcessHeap(), 0, len))) return FALSE;
315  WideCharToMultiByte(CP_UNIXCP, 0, emfd->u.file.filename, -1, filename, len, NULL, NULL);
316  break;
317  case from_process:
318  filename = NULL;
319  break;
320  default: assert(0);
321  return FALSE;
322  }
323 
324  elf_reset_file_map(fmap);
325 
326  fmap->modtype = DMT_ELF;
327  fmap->u.elf.fd = -1;
328  fmap->u.elf.target_copy = NULL;
329 
330  switch (emfd->kind)
331  {
332  case from_file:
333  /* check that the file exists, and that the module hasn't been loaded yet */
334  if (stat(filename, &statbuf) == -1 || S_ISDIR(statbuf.st_mode)) goto done;
335 
336  /* Now open the file, so that we can mmap() it. */
337  if ((fmap->u.elf.fd = open(filename, O_RDONLY)) == -1) goto done;
338  break;
339  case from_process:
340  break;
341  }
342  if (!elf_map_file_read(fmap, emfd, &fmap->u.elf.elfhdr, sizeof(fmap->u.elf.elfhdr), 0))
343  goto done;
344 
345  /* and check for an ELF header */
346  if (memcmp(fmap->u.elf.elfhdr.e_ident,
347  elf_signature, sizeof(elf_signature))) goto done;
348  /* and check 32 vs 64 size according to current machine */
349 #ifdef _WIN64
350  if (fmap->u.elf.elfhdr.e_ident[EI_CLASS] != ELFCLASS64) goto done;
351 #else
352  if (fmap->u.elf.elfhdr.e_ident[EI_CLASS] != ELFCLASS32) goto done;
353 #endif
354  fmap->addr_size = fmap->u.elf.elfhdr.e_ident[EI_CLASS] == ELFCLASS64 ? 64 : 32;
355  fmap->u.elf.sect = HeapAlloc(GetProcessHeap(), 0,
356  fmap->u.elf.elfhdr.e_shnum * sizeof(fmap->u.elf.sect[0]));
357  if (!fmap->u.elf.sect) goto done;
358 
359  for (i = 0; i < fmap->u.elf.elfhdr.e_shnum; i++)
360  {
361  if (!elf_map_file_read(fmap, emfd, &fmap->u.elf.sect[i].shdr, sizeof(fmap->u.elf.sect[i].shdr),
362  fmap->u.elf.elfhdr.e_shoff + i * sizeof(fmap->u.elf.sect[i].shdr)))
363  {
364  HeapFree(GetProcessHeap(), 0, fmap->u.elf.sect);
365  fmap->u.elf.sect = NULL;
366  goto done;
367  }
368  fmap->u.elf.sect[i].mapped = IMAGE_NO_MAP;
369  }
370 
371  /* grab size of module once loaded in memory */
372  fmap->u.elf.elf_size = 0;
373  fmap->u.elf.elf_start = ~0L;
374  for (i = 0; i < fmap->u.elf.elfhdr.e_phnum; i++)
375  {
376  if (elf_map_file_read(fmap, emfd, &phdr, sizeof(phdr),
377  fmap->u.elf.elfhdr.e_phoff + i * sizeof(phdr)) &&
378  phdr.p_type == PT_LOAD)
379  {
380  tmp = (phdr.p_vaddr + phdr.p_memsz + page_mask) & ~page_mask;
381  if (fmap->u.elf.elf_size < tmp) fmap->u.elf.elf_size = tmp;
382  if (phdr.p_vaddr < fmap->u.elf.elf_start) fmap->u.elf.elf_start = phdr.p_vaddr;
383  }
384  }
385  /* if non relocatable ELF, then remove fixed address from computation
386  * otherwise, all addresses are zero based and start has no effect
387  */
388  fmap->u.elf.elf_size -= fmap->u.elf.elf_start;
389 
390  switch (emfd->kind)
391  {
392  case from_file: break;
393  case from_process:
394  if (!(fmap->u.elf.target_copy = HeapAlloc(GetProcessHeap(), 0, fmap->u.elf.elf_size)))
395  {
396  HeapFree(GetProcessHeap(), 0, fmap->u.elf.sect);
397  goto done;
398  }
399  if (!ReadProcessMemory(emfd->u.process.handle, emfd->u.process.load_addr, fmap->u.elf.target_copy,
400  fmap->u.elf.elf_size, NULL))
401  {
402  HeapFree(GetProcessHeap(), 0, fmap->u.elf.target_copy);
403  HeapFree(GetProcessHeap(), 0, fmap->u.elf.sect);
404  goto done;
405  }
406  break;
407  }
408  ret = TRUE;
409 done:
411  return ret;
412 }
413 
414 /******************************************************************
415  * elf_unmap_file
416  *
417  * Unmaps an ELF file from memory (previously mapped with elf_map_file)
418  */
419 static void elf_unmap_file(struct image_file_map* fmap)
420 {
421  while (fmap)
422  {
423  if (fmap->u.elf.fd != -1)
424  {
425  struct image_section_map ism;
426  ism.fmap = fmap;
427  for (ism.sidx = 0; ism.sidx < fmap->u.elf.elfhdr.e_shnum; ism.sidx++)
428  {
429  elf_unmap_section(&ism);
430  }
431  HeapFree(GetProcessHeap(), 0, fmap->u.elf.sect);
432  close(fmap->u.elf.fd);
433  }
434  HeapFree(GetProcessHeap(), 0, fmap->u.elf.target_copy);
435  fmap = fmap->u.elf.alternate;
436  }
437 }
438 
439 static void elf_module_remove(struct process* pcs, struct module_format* modfmt)
440 {
441  elf_unmap_file(&modfmt->u.elf_info->file_map);
442  HeapFree(GetProcessHeap(), 0, modfmt);
443 }
444 
445 /******************************************************************
446  * elf_is_in_thunk_area
447  *
448  * Check whether an address lies within one of the thunk area we
449  * know of.
450  */
451 int elf_is_in_thunk_area(unsigned long addr,
452  const struct elf_thunk_area* thunks)
453 {
454  unsigned i;
455 
456  if (thunks) for (i = 0; thunks[i].symname; i++)
457  {
458  if (addr >= thunks[i].rva_start && addr < thunks[i].rva_end)
459  return i;
460  }
461  return -1;
462 }
463 
464 /******************************************************************
465  * elf_hash_symtab
466  *
467  * creating an internal hash table to ease use ELF symtab information lookup
468  */
469 static void elf_hash_symtab(struct module* module, struct pool* pool,
470  struct hash_table* ht_symtab, struct image_file_map* fmap,
471  struct elf_thunk_area* thunks)
472 {
473  int i, j, nsym;
474  const char* strp;
475  const char* symname;
476  struct symt_compiland* compiland = NULL;
477  const char* ptr;
478  const Elf_Sym* symp;
479  struct symtab_elt* ste;
480  struct image_section_map ism, ism_str;
481 
482  if (!elf_find_section(fmap, ".symtab", SHT_SYMTAB, &ism) &&
483  !elf_find_section(fmap, ".dynsym", SHT_DYNSYM, &ism)) return;
484  if ((symp = (const Elf_Sym*)image_map_section(&ism)) == IMAGE_NO_MAP) return;
485  ism_str.fmap = ism.fmap;
486  ism_str.sidx = fmap->u.elf.sect[ism.sidx].shdr.sh_link;
487  if ((strp = image_map_section(&ism_str)) == IMAGE_NO_MAP)
488  {
489  image_unmap_section(&ism);
490  return;
491  }
492 
493  nsym = image_get_map_size(&ism) / sizeof(*symp);
494 
495  for (j = 0; thunks[j].symname; j++)
496  thunks[j].rva_start = thunks[j].rva_end = 0;
497 
498  for (i = 0; i < nsym; i++, symp++)
499  {
500  /* Ignore certain types of entries which really aren't of that much
501  * interest.
502  */
503  if ((ELF32_ST_TYPE(symp->st_info) != STT_NOTYPE &&
504  ELF32_ST_TYPE(symp->st_info) != STT_FILE &&
505  ELF32_ST_TYPE(symp->st_info) != STT_OBJECT &&
506  ELF32_ST_TYPE(symp->st_info) != STT_FUNC) ||
507  symp->st_shndx == SHN_UNDEF)
508  {
509  continue;
510  }
511 
512  symname = strp + symp->st_name;
513 
514  /* handle some specific symtab (that we'll throw away when done) */
515  switch (ELF32_ST_TYPE(symp->st_info))
516  {
517  case STT_FILE:
518  if (symname)
519  compiland = symt_new_compiland(module, symp->st_value,
520  source_new(module, NULL, symname));
521  else
522  compiland = NULL;
523  continue;
524  case STT_NOTYPE:
525  /* we are only interested in wine markers inserted by winebuild */
526  for (j = 0; thunks[j].symname; j++)
527  {
528  if (!strcmp(symname, thunks[j].symname))
529  {
530  thunks[j].rva_start = symp->st_value;
531  thunks[j].rva_end = symp->st_value + symp->st_size;
532  break;
533  }
534  }
535  continue;
536  }
537 
538  /* FIXME: we don't need to handle them (GCC internals)
539  * Moreover, they screw up our symbol lookup :-/
540  */
541  if (symname[0] == '.' && symname[1] == 'L' && isdigit(symname[2]))
542  continue;
543 
544  ste = pool_alloc(pool, sizeof(*ste));
545  ste->ht_elt.name = symname;
546  /* GCC emits, in some cases, a .<digit>+ suffix.
547  * This is used for static variable inside functions, so
548  * that we can have several such variables with same name in
549  * the same compilation unit
550  * We simply ignore that suffix when present (we also get rid
551  * of it in stabs parsing)
552  */
553  ptr = symname + strlen(symname) - 1;
554  if (isdigit(*ptr))
555  {
556  while (isdigit(*ptr) && ptr >= symname) ptr--;
557  if (ptr > symname && *ptr == '.')
558  {
559  char* n = pool_alloc(pool, ptr - symname + 1);
560  memcpy(n, symname, ptr - symname + 1);
561  n[ptr - symname] = '\0';
562  ste->ht_elt.name = n;
563  }
564  }
565  ste->symp = symp;
566  ste->compiland = compiland;
567  ste->used = 0;
568  hash_table_add(ht_symtab, &ste->ht_elt);
569  }
570  /* as we added in the ht_symtab pointers to the symbols themselves,
571  * we cannot unmap yet the sections, it will be done when we're over
572  * with this ELF file
573  */
574 }
575 
576 /******************************************************************
577  * elf_lookup_symtab
578  *
579  * lookup a symbol by name in our internal hash table for the symtab
580  */
581 static const Elf_Sym* elf_lookup_symtab(const struct module* module,
582  const struct hash_table* ht_symtab,
583  const char* name, const struct symt* compiland)
584 {
585  struct symtab_elt* weak_result = NULL; /* without compiland name */
586  struct symtab_elt* result = NULL;
587  struct hash_table_iter hti;
588  struct symtab_elt* ste;
589  const char* compiland_name;
590  const char* compiland_basename;
591  const char* base;
592 
593  /* we need weak match up (at least) when symbols of same name,
594  * defined several times in different compilation units,
595  * are merged in a single one (hence a different filename for c.u.)
596  */
597  if (compiland)
598  {
599  compiland_name = source_get(module,
600  ((const struct symt_compiland*)compiland)->source);
601  compiland_basename = strrchr(compiland_name, '/');
602  if (!compiland_basename++) compiland_basename = compiland_name;
603  }
604  else compiland_name = compiland_basename = NULL;
605 
606  hash_table_iter_init(ht_symtab, &hti, name);
607  while ((ste = hash_table_iter_up(&hti)))
608  {
609  if (ste->used || strcmp(ste->ht_elt.name, name)) continue;
610 
611  weak_result = ste;
612  if ((ste->compiland && !compiland_name) || (!ste->compiland && compiland_name))
613  continue;
614  if (ste->compiland && compiland_name)
615  {
616  const char* filename = source_get(module, ste->compiland->source);
617  if (strcmp(filename, compiland_name))
618  {
619  base = strrchr(filename, '/');
620  if (!base++) base = filename;
621  if (strcmp(base, compiland_basename)) continue;
622  }
623  }
624  if (result)
625  {
626  FIXME("Already found symbol %s (%s) in symtab %s @%08x and %s @%08x\n",
627  name, compiland_name,
628  source_get(module, result->compiland->source), (unsigned int)result->symp->st_value,
629  source_get(module, ste->compiland->source), (unsigned int)ste->symp->st_value);
630  }
631  else
632  {
633  result = ste;
634  ste->used = 1;
635  }
636  }
637  if (!result && !(result = weak_result))
638  {
639  FIXME("Couldn't find symbol %s!%s in symtab\n",
641  return NULL;
642  }
643  return result->symp;
644 }
645 
646 /******************************************************************
647  * elf_finish_stabs_info
648  *
649  * - get any relevant information (address & size) from the bits we got from the
650  * stabs debugging information
651  */
652 static void elf_finish_stabs_info(struct module* module, const struct hash_table* symtab)
653 {
654  struct hash_table_iter hti;
655  void* ptr;
656  struct symt_ht* sym;
657  const Elf_Sym* symp;
658  struct elf_module_info* elf_info = module->format_info[DFI_ELF]->u.elf_info;
659 
661  while ((ptr = hash_table_iter_up(&hti)))
662  {
663  sym = CONTAINING_RECORD(ptr, struct symt_ht, hash_elt);
664  switch (sym->symt.tag)
665  {
666  case SymTagFunction:
667  if (((struct symt_function*)sym)->address != elf_info->elf_addr &&
668  ((struct symt_function*)sym)->size)
669  {
670  break;
671  }
672  symp = elf_lookup_symtab(module, symtab, sym->hash_elt.name,
673  ((struct symt_function*)sym)->container);
674  if (symp)
675  {
676  if (((struct symt_function*)sym)->address != elf_info->elf_addr &&
677  ((struct symt_function*)sym)->address != elf_info->elf_addr + symp->st_value)
678  FIXME("Changing address for %p/%s!%s from %08lx to %08lx\n",
679  sym, debugstr_w(module->module.ModuleName), sym->hash_elt.name,
680  ((struct symt_function*)sym)->address, elf_info->elf_addr + symp->st_value);
681  if (((struct symt_function*)sym)->size && ((struct symt_function*)sym)->size != symp->st_size)
682  FIXME("Changing size for %p/%s!%s from %08lx to %08x\n",
683  sym, debugstr_w(module->module.ModuleName), sym->hash_elt.name,
684  ((struct symt_function*)sym)->size, (unsigned int)symp->st_size);
685 
686  ((struct symt_function*)sym)->address = elf_info->elf_addr + symp->st_value;
687  ((struct symt_function*)sym)->size = symp->st_size;
688  } else
689  FIXME("Couldn't find %s!%s\n",
691  break;
692  case SymTagData:
693  switch (((struct symt_data*)sym)->kind)
694  {
695  case DataIsGlobal:
696  case DataIsFileStatic:
697  if (((struct symt_data*)sym)->u.var.kind != loc_absolute ||
698  ((struct symt_data*)sym)->u.var.offset != elf_info->elf_addr)
699  break;
700  symp = elf_lookup_symtab(module, symtab, sym->hash_elt.name,
701  ((struct symt_data*)sym)->container);
702  if (symp)
703  {
704  if (((struct symt_data*)sym)->u.var.offset != elf_info->elf_addr &&
705  ((struct symt_data*)sym)->u.var.offset != elf_info->elf_addr + symp->st_value)
706  FIXME("Changing address for %p/%s!%s from %08lx to %08lx\n",
707  sym, debugstr_w(module->module.ModuleName), sym->hash_elt.name,
708  ((struct symt_function*)sym)->address, elf_info->elf_addr + symp->st_value);
709  ((struct symt_data*)sym)->u.var.offset = elf_info->elf_addr + symp->st_value;
710  ((struct symt_data*)sym)->kind = (ELF32_ST_BIND(symp->st_info) == STB_LOCAL) ?
712  } else
713  FIXME("Couldn't find %s!%s\n",
715  break;
716  default:;
717  }
718  break;
719  default:
720  FIXME("Unsupported tag %u\n", sym->symt.tag);
721  break;
722  }
723  }
724  /* since we may have changed some addresses & sizes, mark the module to be resorted */
726 }
727 
728 /******************************************************************
729  * elf_load_wine_thunks
730  *
731  * creating the thunk objects for a wine native DLL
732  */
733 static int elf_new_wine_thunks(struct module* module, const struct hash_table* ht_symtab,
734  const struct elf_thunk_area* thunks)
735 {
736  int j;
737  struct hash_table_iter hti;
738  struct symtab_elt* ste;
739  DWORD_PTR addr;
740  struct symt_ht* symt;
741 
742  hash_table_iter_init(ht_symtab, &hti, NULL);
743  while ((ste = hash_table_iter_up(&hti)))
744  {
745  if (ste->used) continue;
746 
747  addr = module->reloc_delta + ste->symp->st_value;
748 
749  j = elf_is_in_thunk_area(ste->symp->st_value, thunks);
750  if (j >= 0) /* thunk found */
751  {
752  symt_new_thunk(module, ste->compiland, ste->ht_elt.name, thunks[j].ordinal,
753  addr, ste->symp->st_size);
754  }
755  else
756  {
757  ULONG64 ref_addr;
758  struct location loc;
759 
761  if (symt && !symt_get_address(&symt->symt, &ref_addr))
762  ref_addr = addr;
763  if (!symt || addr != ref_addr)
764  {
765  /* creating public symbols for all the ELF symbols which haven't been
766  * used yet (ie we have no debug information on them)
767  * That's the case, for example, of the .spec.c files
768  */
769  switch (ELF32_ST_TYPE(ste->symp->st_info))
770  {
771  case STT_FUNC:
772  symt_new_function(module, ste->compiland, ste->ht_elt.name,
773  addr, ste->symp->st_size, NULL);
774  break;
775  case STT_OBJECT:
776  loc.kind = loc_absolute;
777  loc.reg = 0;
778  loc.offset = addr;
779  symt_new_global_variable(module, ste->compiland, ste->ht_elt.name,
780  ELF32_ST_BIND(ste->symp->st_info) == STB_LOCAL,
781  loc, ste->symp->st_size, NULL);
782  break;
783  default:
784  FIXME("Shouldn't happen\n");
785  break;
786  }
787  /* FIXME: this is a hack !!!
788  * we are adding new symbols, but as we're parsing a symbol table
789  * (hopefully without duplicate symbols) we delay rebuilding the sorted
790  * module table until we're done with the symbol table
791  * Otherwise, as we intertwine symbols' add and lookup, performance
792  * is rather bad
793  */
795  }
796  }
797  }
798  /* see comment above */
800  return TRUE;
801 }
802 
803 /******************************************************************
804  * elf_new_public_symbols
805  *
806  * Creates a set of public symbols from an ELF symtab
807  */
808 static int elf_new_public_symbols(struct module* module, const struct hash_table* symtab)
809 {
810  struct hash_table_iter hti;
811  struct symtab_elt* ste;
812 
813  if (dbghelp_options & SYMOPT_NO_PUBLICS) return TRUE;
814 
815  /* FIXME: we're missing the ELF entry point here */
816 
817  hash_table_iter_init(symtab, &hti, NULL);
818  while ((ste = hash_table_iter_up(&hti)))
819  {
820  symt_new_public(module, ste->compiland, ste->ht_elt.name,
821  module->reloc_delta + ste->symp->st_value,
822  ste->symp->st_size);
823  }
824  return TRUE;
825 }
826 
827 static BOOL elf_check_debug_link(const WCHAR* file, struct image_file_map* fmap, DWORD crc)
828 {
829  BOOL ret;
830  struct elf_map_file_data emfd;
831 
832  emfd.kind = from_file;
833  emfd.u.file.filename = file;
834  if (!elf_map_file(&emfd, fmap)) return FALSE;
835  if (!(ret = crc == calc_crc32(fmap->u.elf.fd)))
836  {
837  WARN("Bad CRC for file %s (got %08x while expecting %08x)\n",
838  debugstr_w(file), calc_crc32(fmap->u.elf.fd), crc);
839  elf_unmap_file(fmap);
840  }
841  return ret;
842 }
843 
844 /******************************************************************
845  * elf_locate_debug_link
846  *
847  * Locate a filename from a .gnu_debuglink section, using the same
848  * strategy as gdb:
849  * "If the full name of the directory containing the executable is
850  * execdir, and the executable has a debug link that specifies the
851  * name debugfile, then GDB will automatically search for the
852  * debugging information file in three places:
853  * - the directory containing the executable file (that is, it
854  * will look for a file named `execdir/debugfile',
855  * - a subdirectory of that directory named `.debug' (that is, the
856  * file `execdir/.debug/debugfile', and
857  * - a subdirectory of the global debug file directory that includes
858  * the executable's full path, and the name from the link (that is,
859  * the file `globaldebugdir/execdir/debugfile', where globaldebugdir
860  * is the global debug file directory, and execdir has been turned
861  * into a relative path)." (from GDB manual)
862  */
863 static BOOL elf_locate_debug_link(struct image_file_map* fmap, const char* filename,
864  const WCHAR* loaded_file, DWORD crc)
865 {
866  static const WCHAR globalDebugDirW[] = {'/','u','s','r','/','l','i','b','/','d','e','b','u','g','/'};
867  static const WCHAR dotDebugW[] = {'.','d','e','b','u','g','/'};
868  const size_t globalDebugDirLen = sizeof(globalDebugDirW) / sizeof(WCHAR);
869  size_t filename_len;
870  WCHAR* p = NULL;
871  WCHAR* slash;
872  struct image_file_map* fmap_link = NULL;
873 
874  fmap_link = HeapAlloc(GetProcessHeap(), 0, sizeof(*fmap_link));
875  if (!fmap_link) return FALSE;
876 
877  filename_len = MultiByteToWideChar(CP_UNIXCP, 0, filename, -1, NULL, 0);
878  p = HeapAlloc(GetProcessHeap(), 0,
879  (globalDebugDirLen + strlenW(loaded_file) + 6 + 1 + filename_len + 1) * sizeof(WCHAR));
880  if (!p) goto found;
881 
882  /* we prebuild the string with "execdir" */
883  strcpyW(p, loaded_file);
884  slash = strrchrW(p, '/');
885  if (slash == NULL) slash = p; else slash++;
886 
887  /* testing execdir/filename */
888  MultiByteToWideChar(CP_UNIXCP, 0, filename, -1, slash, filename_len);
889  if (elf_check_debug_link(p, fmap_link, crc)) goto found;
890 
891  /* testing execdir/.debug/filename */
892  memcpy(slash, dotDebugW, sizeof(dotDebugW));
893  MultiByteToWideChar(CP_UNIXCP, 0, filename, -1, slash + sizeof(dotDebugW) / sizeof(WCHAR), filename_len);
894  if (elf_check_debug_link(p, fmap_link, crc)) goto found;
895 
896  /* testing globaldebugdir/execdir/filename */
897  memmove(p + globalDebugDirLen, p, (slash - p) * sizeof(WCHAR));
898  memcpy(p, globalDebugDirW, globalDebugDirLen * sizeof(WCHAR));
899  slash += globalDebugDirLen;
900  MultiByteToWideChar(CP_UNIXCP, 0, filename, -1, slash, filename_len);
901  if (elf_check_debug_link(p, fmap_link, crc)) goto found;
902 
903  /* finally testing filename */
904  if (elf_check_debug_link(slash, fmap_link, crc)) goto found;
905 
906 
907  WARN("Couldn't locate or map %s\n", filename);
908  HeapFree(GetProcessHeap(), 0, p);
909  HeapFree(GetProcessHeap(), 0, fmap_link);
910  return FALSE;
911 
912 found:
913  TRACE("Located debug information file %s at %s\n", filename, debugstr_w(p));
914  HeapFree(GetProcessHeap(), 0, p);
915  fmap->u.elf.alternate = fmap_link;
916  return TRUE;
917 }
918 
919 /******************************************************************
920  * elf_locate_build_id_target
921  *
922  * Try to find the .so file containing the debug info out of the build-id note information
923  */
924 static BOOL elf_locate_build_id_target(struct image_file_map* fmap, const BYTE* id, unsigned idlen)
925 {
926  static const WCHAR globalDebugDirW[] = {'/','u','s','r','/','l','i','b','/','d','e','b','u','g','/'};
927  static const WCHAR buildidW[] = {'.','b','u','i','l','d','-','i','d','/'};
928  static const WCHAR dotDebug0W[] = {'.','d','e','b','u','g',0};
929  struct image_file_map* fmap_link = NULL;
930  WCHAR* p;
931  WCHAR* z;
932  const BYTE* idend = id + idlen;
933  struct elf_map_file_data emfd;
934 
935  fmap_link = HeapAlloc(GetProcessHeap(), 0, sizeof(*fmap_link));
936  if (!fmap_link) return FALSE;
937 
938  p = HeapAlloc(GetProcessHeap(), 0,
939  sizeof(globalDebugDirW) + sizeof(buildidW) +
940  (idlen * 2 + 1) * sizeof(WCHAR) + sizeof(dotDebug0W));
941  z = p;
942  memcpy(z, globalDebugDirW, sizeof(globalDebugDirW));
943  z += sizeof(globalDebugDirW) / sizeof(WCHAR);
944  memcpy(z, buildidW, sizeof(buildidW));
945  z += sizeof(buildidW) / sizeof(WCHAR);
946 
947  if (id < idend)
948  {
949  *z++ = "0123456789abcdef"[*id >> 4 ];
950  *z++ = "0123456789abcdef"[*id & 0x0F];
951  id++;
952  }
953  if (id < idend)
954  *z++ = '/';
955  while (id < idend)
956  {
957  *z++ = "0123456789abcdef"[*id >> 4 ];
958  *z++ = "0123456789abcdef"[*id & 0x0F];
959  id++;
960  }
961  memcpy(z, dotDebug0W, sizeof(dotDebug0W));
962  TRACE("checking %s\n", wine_dbgstr_w(p));
963 
964  emfd.kind = from_file;
965  emfd.u.file.filename = p;
966  if (elf_map_file(&emfd, fmap_link))
967  {
968  struct image_section_map buildid_sect;
969  if (elf_find_section(fmap_link, ".note.gnu.build-id", SHT_NULL, &buildid_sect))
970  {
971  const uint32_t* note;
972 
973  note = (const uint32_t*)image_map_section(&buildid_sect);
974  if (note != IMAGE_NO_MAP)
975  {
976  /* the usual ELF note structure: name-size desc-size type <name> <desc> */
977  if (note[2] == NT_GNU_BUILD_ID)
978  {
979  if (note[1] == idlen &&
980  !memcmp(note + 3 + ((note[0] + 3) >> 2), idend - idlen, idlen))
981  {
982  TRACE("Located debug information file at %s\n", debugstr_w(p));
983  HeapFree(GetProcessHeap(), 0, p);
984  fmap->u.elf.alternate = fmap_link;
985  return TRUE;
986  }
987  WARN("mismatch in buildid information for %s\n", wine_dbgstr_w(p));
988  }
989  }
990  image_unmap_section(&buildid_sect);
991  }
992  elf_unmap_file(fmap_link);
993  }
994 
995  TRACE("not found\n");
996  HeapFree(GetProcessHeap(), 0, p);
997  HeapFree(GetProcessHeap(), 0, fmap_link);
998  return FALSE;
999 }
1000 
1001 /******************************************************************
1002  * elf_check_alternate
1003  *
1004  * Load alternate files for a given ELF file, looking at either .note.gnu_build-id
1005  * or .gnu_debuglink sections.
1006  */
1007 static BOOL elf_check_alternate(struct image_file_map* fmap, const struct module* module)
1008 {
1009  BOOL ret = FALSE;
1010  BOOL found = FALSE;
1011  struct image_section_map buildid_sect, debuglink_sect;
1012 
1013  /* if present, add the .gnu_debuglink file as an alternate to current one */
1014  if (elf_find_section(fmap, ".note.gnu.build-id", SHT_NULL, &buildid_sect))
1015  {
1016  const uint32_t* note;
1017 
1018  found = TRUE;
1019  note = (const uint32_t*)image_map_section(&buildid_sect);
1020  if (note != IMAGE_NO_MAP)
1021  {
1022  /* the usual ELF note structure: name-size desc-size type <name> <desc> */
1023  if (note[2] == NT_GNU_BUILD_ID)
1024  {
1025  ret = elf_locate_build_id_target(fmap, (const BYTE*)(note + 3 + ((note[0] + 3) >> 2)), note[1]);
1026  }
1027  }
1028  image_unmap_section(&buildid_sect);
1029  }
1030  /* if present, add the .gnu_debuglink file as an alternate to current one */
1031  if (!ret && elf_find_section(fmap, ".gnu_debuglink", SHT_NULL, &debuglink_sect))
1032  {
1033  const char* dbg_link;
1034 
1035  found = TRUE;
1036  dbg_link = (const char*)image_map_section(&debuglink_sect);
1037  if (dbg_link != IMAGE_NO_MAP)
1038  {
1039  /* The content of a debug link section is:
1040  * 1/ a NULL terminated string, containing the file name for the
1041  * debug info
1042  * 2/ padding on 4 byte boundary
1043  * 3/ CRC of the linked ELF file
1044  */
1045  DWORD crc = *(const DWORD*)(dbg_link + ((DWORD_PTR)(strlen(dbg_link) + 4) & ~3));
1046  ret = elf_locate_debug_link(fmap, dbg_link, module->module.LoadedImageName, crc);
1047  if (!ret)
1048  WARN("Couldn't load linked debug file for %s\n",
1050  }
1051  image_unmap_section(&debuglink_sect);
1052  }
1053  return found ? ret : TRUE;
1054 }
1055 
1056 /******************************************************************
1057  * elf_load_debug_info_from_map
1058  *
1059  * Loads the symbolic information from ELF module which mapping is described
1060  * in fmap
1061  * the module has been loaded at 'load_offset' address, so symbols' address
1062  * relocation is performed.
1063  * CRC is checked if fmap->with_crc is TRUE
1064  * returns
1065  * 0 if the file doesn't contain symbolic info (or this info cannot be
1066  * read or parsed)
1067  * 1 on success
1068  */
1069 static BOOL elf_load_debug_info_from_map(struct module* module,
1070  struct image_file_map* fmap,
1071  struct pool* pool,
1072  struct hash_table* ht_symtab)
1073 {
1074  BOOL ret = FALSE, lret;
1075  struct elf_thunk_area thunks[] =
1076  {
1077  {"__wine_spec_import_thunks", THUNK_ORDINAL_NOTYPE, 0, 0}, /* inter DLL calls */
1078  {"__wine_spec_delayed_import_loaders", THUNK_ORDINAL_LOAD, 0, 0}, /* delayed inter DLL calls */
1079  {"__wine_spec_delayed_import_thunks", THUNK_ORDINAL_LOAD, 0, 0}, /* delayed inter DLL calls */
1080  {"__wine_delay_load", THUNK_ORDINAL_LOAD, 0, 0}, /* delayed inter DLL calls */
1081  {"__wine_spec_thunk_text_16", -16, 0, 0}, /* 16 => 32 thunks */
1082  {"__wine_spec_thunk_text_32", -32, 0, 0}, /* 32 => 16 thunks */
1083  {NULL, 0, 0, 0}
1084  };
1085 
1087 
1088  /* create a hash table for the symtab */
1089  elf_hash_symtab(module, pool, ht_symtab, fmap, thunks);
1090 
1092  {
1093  struct image_section_map stab_sect, stabstr_sect;
1094 
1095  /* check if we need an alternate file (from debuglink or build-id) */
1096  ret = elf_check_alternate(fmap, module);
1097 
1098  if (elf_find_section(fmap, ".stab", SHT_NULL, &stab_sect) &&
1099  elf_find_section(fmap, ".stabstr", SHT_NULL, &stabstr_sect))
1100  {
1101  const char* stab;
1102  const char* stabstr;
1103 
1104  stab = image_map_section(&stab_sect);
1105  stabstr = image_map_section(&stabstr_sect);
1106  if (stab != IMAGE_NO_MAP && stabstr != IMAGE_NO_MAP)
1107  {
1108  /* OK, now just parse all of the stabs. */
1109  lret = stabs_parse(module, module->format_info[DFI_ELF]->u.elf_info->elf_addr,
1110  stab, image_get_map_size(&stab_sect),
1111  stabstr, image_get_map_size(&stabstr_sect),
1112  NULL, NULL);
1113  if (lret)
1114  /* and fill in the missing information for stabs */
1115  elf_finish_stabs_info(module, ht_symtab);
1116  else
1117  WARN("Couldn't correctly read stabs\n");
1118  ret = ret || lret;
1119  }
1120  image_unmap_section(&stab_sect);
1121  image_unmap_section(&stabstr_sect);
1122  }
1123  lret = dwarf2_parse(module, module->reloc_delta, thunks, fmap);
1124  ret = ret || lret;
1125  }
1128  {
1129  /* add the thunks for native libraries */
1131  elf_new_wine_thunks(module, ht_symtab, thunks);
1132  }
1133  /* add all the public symbols from symtab */
1134  if (elf_new_public_symbols(module, ht_symtab) && !ret) ret = TRUE;
1135 
1136  return ret;
1137 }
1138 
1139 /******************************************************************
1140  * elf_load_debug_info
1141  *
1142  * Loads ELF debugging information from the module image file.
1143  */
1145 {
1146  BOOL ret = TRUE;
1147  struct pool pool;
1148  struct hash_table ht_symtab;
1149  struct module_format* modfmt;
1150 
1151  if (module->type != DMT_ELF || !(modfmt = module->format_info[DFI_ELF]) || !modfmt->u.elf_info)
1152  {
1153  ERR("Bad elf module '%s'\n", debugstr_w(module->module.LoadedImageName));
1154  return FALSE;
1155  }
1156 
1157  pool_init(&pool, 65536);
1158  hash_table_init(&pool, &ht_symtab, 256);
1159 
1160  ret = elf_load_debug_info_from_map(module, &modfmt->u.elf_info->file_map, &pool, &ht_symtab);
1161 
1162  pool_destroy(&pool);
1163  return ret;
1164 }
1165 
1166 /******************************************************************
1167  * elf_fetch_file_info
1168  *
1169  * Gathers some more information for an ELF module from a given file
1170  */
1172  DWORD* size, DWORD* checksum)
1173 {
1174  struct image_file_map fmap;
1175 
1176  struct elf_map_file_data emfd;
1177 
1178  emfd.kind = from_file;
1179  emfd.u.file.filename = name;
1180  if (!elf_map_file(&emfd, &fmap)) return FALSE;
1181  if (base) *base = fmap.u.elf.elf_start;
1182  *size = fmap.u.elf.elf_size;
1183  *checksum = calc_crc32(fmap.u.elf.fd);
1184  elf_unmap_file(&fmap);
1185  return TRUE;
1186 }
1187 
1188 static BOOL elf_load_file_from_fmap(struct process* pcs, const WCHAR* filename,
1189  struct image_file_map* fmap, unsigned long load_offset,
1190  unsigned long dyn_addr, struct elf_info* elf_info)
1191 {
1192  BOOL ret = FALSE;
1193 
1194  if (elf_info->flags & ELF_INFO_DEBUG_HEADER)
1195  {
1196  struct image_section_map ism;
1197 
1198  if (elf_find_section(fmap, ".dynamic", SHT_DYNAMIC, &ism))
1199  {
1200  Elf_Dyn dyn;
1201  char* ptr = (char*)fmap->u.elf.sect[ism.sidx].shdr.sh_addr;
1202  unsigned long len;
1203 
1204  if (load_offset) ptr += load_offset - fmap->u.elf.elf_start;
1205 
1206  do
1207  {
1208  if (!ReadProcessMemory(pcs->handle, ptr, &dyn, sizeof(dyn), &len) ||
1209  len != sizeof(dyn))
1210  return ret;
1211  if (dyn.d_tag == DT_DEBUG)
1212  {
1213  elf_info->dbg_hdr_addr = dyn.d_un.d_ptr;
1214  if (load_offset == 0 && dyn_addr == 0) /* likely the case */
1215  /* Assume this module (the Wine loader) has been loaded at its preferred address */
1216  dyn_addr = ism.fmap->u.elf.sect[ism.sidx].shdr.sh_addr;
1217  break;
1218  }
1219  ptr += sizeof(dyn);
1220  } while (dyn.d_tag != DT_NULL);
1221  if (dyn.d_tag == DT_NULL) return ret;
1222  }
1223  elf_end_find(fmap);
1224  }
1225 
1226  if (elf_info->flags & ELF_INFO_MODULE)
1227  {
1228  struct elf_module_info *elf_module_info;
1229  struct module_format* modfmt;
1230  struct image_section_map ism;
1231  unsigned long modbase = load_offset;
1232 
1233  if (elf_find_section(fmap, ".dynamic", SHT_DYNAMIC, &ism))
1234  {
1235  unsigned long rva_dyn = elf_get_map_rva(&ism);
1236 
1237  TRACE("For module %s, got ELF (start=%lx dyn=%lx), link_map (start=%lx dyn=%lx)\n",
1238  debugstr_w(filename), (unsigned long)fmap->u.elf.elf_start, rva_dyn,
1239  load_offset, dyn_addr);
1240  if (dyn_addr && load_offset + rva_dyn != dyn_addr)
1241  {
1242  WARN("\thave to relocate: %lx\n", dyn_addr - rva_dyn);
1243  modbase = dyn_addr - rva_dyn;
1244  }
1245  } else WARN("For module %s, no .dynamic section\n", debugstr_w(filename));
1246  elf_end_find(fmap);
1247 
1248  modfmt = HeapAlloc(GetProcessHeap(), 0,
1249  sizeof(struct module_format) + sizeof(struct elf_module_info));
1250  if (!modfmt) return FALSE;
1251  elf_info->module = module_new(pcs, filename, DMT_ELF, FALSE, modbase,
1252  fmap->u.elf.elf_size, 0, calc_crc32(fmap->u.elf.fd));
1253  if (!elf_info->module)
1254  {
1255  HeapFree(GetProcessHeap(), 0, modfmt);
1256  return FALSE;
1257  }
1258  elf_info->module->reloc_delta = elf_info->module->module.BaseOfImage - fmap->u.elf.elf_start;
1259  elf_module_info = (void*)(modfmt + 1);
1260  elf_info->module->format_info[DFI_ELF] = modfmt;
1261  modfmt->module = elf_info->module;
1262  modfmt->remove = elf_module_remove;
1263  modfmt->loc_compute = NULL;
1264  modfmt->u.elf_info = elf_module_info;
1265 
1266  elf_module_info->elf_addr = load_offset;
1267 
1268  elf_module_info->file_map = *fmap;
1269  elf_reset_file_map(fmap);
1271  {
1272  elf_info->module->module.SymType = SymDeferred;
1273  ret = TRUE;
1274  }
1275  else ret = elf_load_debug_info(elf_info->module);
1276 
1277  elf_module_info->elf_mark = 1;
1278  elf_module_info->elf_loader = 0;
1279  } else ret = TRUE;
1280 
1281  if (elf_info->flags & ELF_INFO_NAME)
1282  {
1283  WCHAR* ptr;
1284  ptr = HeapAlloc(GetProcessHeap(), 0, (lstrlenW(filename) + 1) * sizeof(WCHAR));
1285  if (ptr)
1286  {
1287  strcpyW(ptr, filename);
1288  elf_info->module_name = ptr;
1289  }
1290  else ret = FALSE;
1291  }
1292 
1293  return ret;
1294 }
1295 
1296 /******************************************************************
1297  * elf_load_file
1298  *
1299  * Loads the information for ELF module stored in 'filename'
1300  * the module has been loaded at 'load_offset' address
1301  * returns
1302  * -1 if the file cannot be found/opened
1303  * 0 if the file doesn't contain symbolic info (or this info cannot be
1304  * read or parsed)
1305  * 1 on success
1306  */
1307 static BOOL elf_load_file(struct process* pcs, const WCHAR* filename,
1308  unsigned long load_offset, unsigned long dyn_addr,
1309  struct elf_info* elf_info)
1310 {
1311  BOOL ret = FALSE;
1312  struct image_file_map fmap;
1313  struct elf_map_file_data emfd;
1314 
1315  TRACE("Processing elf file '%s' at %08lx\n", debugstr_w(filename), load_offset);
1316 
1317  emfd.kind = from_file;
1318  emfd.u.file.filename = filename;
1319  if (!elf_map_file(&emfd, &fmap)) return ret;
1320 
1321  /* Next, we need to find a few of the internal ELF headers within
1322  * this thing. We need the main executable header, and the section
1323  * table.
1324  */
1325  if (!fmap.u.elf.elf_start && !load_offset)
1326  ERR("Relocatable ELF %s, but no load address. Loading at 0x0000000\n",
1327  debugstr_w(filename));
1328 
1329  ret = elf_load_file_from_fmap(pcs, filename, &fmap, load_offset, dyn_addr, elf_info);
1330 
1331  elf_unmap_file(&fmap);
1332 
1333  return ret;
1334 }
1335 
1336 /******************************************************************
1337  * elf_load_file_from_path
1338  * tries to load an ELF file from a set of paths (separated by ':')
1339  */
1340 static BOOL elf_load_file_from_path(HANDLE hProcess,
1341  const WCHAR* filename,
1342  unsigned long load_offset,
1343  unsigned long dyn_addr,
1344  const char* path,
1345  struct elf_info* elf_info)
1346 {
1347  BOOL ret = FALSE;
1348  WCHAR *s, *t, *fn;
1349  WCHAR* pathW = NULL;
1350  unsigned len;
1351 
1352  if (!path) return FALSE;
1353 
1354  len = MultiByteToWideChar(CP_UNIXCP, 0, path, -1, NULL, 0);
1355  pathW = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
1356  if (!pathW) return FALSE;
1357  MultiByteToWideChar(CP_UNIXCP, 0, path, -1, pathW, len);
1358 
1359  for (s = pathW; s && *s; s = (t) ? (t+1) : NULL)
1360  {
1361  t = strchrW(s, ':');
1362  if (t) *t = '\0';
1363  fn = HeapAlloc(GetProcessHeap(), 0, (lstrlenW(filename) + 1 + lstrlenW(s) + 1) * sizeof(WCHAR));
1364  if (!fn) break;
1365  strcpyW(fn, s);
1366  strcatW(fn, S_SlashW);
1367  strcatW(fn, filename);
1368  ret = elf_load_file(hProcess, fn, load_offset, dyn_addr, elf_info);
1369  HeapFree(GetProcessHeap(), 0, fn);
1370  if (ret) break;
1371  }
1372 
1373  HeapFree(GetProcessHeap(), 0, pathW);
1374  return ret;
1375 }
1376 
1377 /******************************************************************
1378  * elf_load_file_from_dll_path
1379  *
1380  * Tries to load an ELF file from the dll path
1381  */
1382 static BOOL elf_load_file_from_dll_path(HANDLE hProcess,
1383  const WCHAR* filename,
1384  unsigned long load_offset,
1385  unsigned long dyn_addr,
1386  struct elf_info* elf_info)
1387 {
1388  BOOL ret = FALSE;
1389  unsigned int index = 0;
1390  const char *path;
1391 
1392  while (!ret && (path = wine_dll_enum_load_path( index++ )))
1393  {
1394  WCHAR *name;
1395  unsigned len;
1396 
1397  len = MultiByteToWideChar(CP_UNIXCP, 0, path, -1, NULL, 0);
1398 
1399  name = HeapAlloc( GetProcessHeap(), 0,
1400  (len + lstrlenW(filename) + 2) * sizeof(WCHAR) );
1401 
1402  if (!name) break;
1404  strcatW( name, S_SlashW );
1405  strcatW( name, filename );
1406  ret = elf_load_file(hProcess, name, load_offset, dyn_addr, elf_info);
1407  HeapFree( GetProcessHeap(), 0, name );
1408  }
1409  return ret;
1410 }
1411 
1412 #ifdef AT_SYSINFO_EHDR
1413 /******************************************************************
1414  * elf_search_auxv
1415  *
1416  * locate some a value from the debuggee auxiliary vector
1417  */
1418 static BOOL elf_search_auxv(const struct process* pcs, unsigned type, unsigned long* val)
1419 {
1420  char buffer[sizeof(SYMBOL_INFO) + MAX_SYM_NAME];
1422  void* addr;
1423  void* str;
1424  void* str_max;
1425  Elf_auxv_t auxv;
1426 
1427  si->SizeOfStruct = sizeof(*si);
1428  si->MaxNameLen = MAX_SYM_NAME;
1429  if (!SymFromName(pcs->handle, "libwine.so.1!__wine_main_environ", si) ||
1430  !(addr = (void*)(DWORD_PTR)si->Address) ||
1431  !ReadProcessMemory(pcs->handle, addr, &addr, sizeof(addr), NULL) ||
1432  !addr)
1433  {
1434  FIXME("can't find symbol in module\n");
1435  return FALSE;
1436  }
1437  /* walk through envp[] */
1438  /* envp[] strings are located after the auxiliary vector, so protect the walk */
1439  str_max = (void*)(DWORD_PTR)~0L;
1440  while (ReadProcessMemory(pcs->handle, addr, &str, sizeof(str), NULL) &&
1441  (addr = (void*)((DWORD_PTR)addr + sizeof(str))) != NULL && str != NULL)
1442  str_max = min(str_max, str);
1443 
1444  /* Walk through the end of envp[] array.
1445  * Actually, there can be several NULLs at the end of envp[]. This happens when an env variable is
1446  * deleted, the last entry is replaced by an extra NULL.
1447  */
1448  while (addr < str_max && ReadProcessMemory(pcs->handle, addr, &str, sizeof(str), NULL) && str == NULL)
1449  addr = (void*)((DWORD_PTR)addr + sizeof(str));
1450 
1451  while (ReadProcessMemory(pcs->handle, addr, &auxv, sizeof(auxv), NULL) && auxv.a_type != AT_NULL)
1452  {
1453  if (auxv.a_type == type)
1454  {
1455  *val = auxv.a_un.a_val;
1456  return TRUE;
1457  }
1458  addr = (void*)((DWORD_PTR)addr + sizeof(auxv));
1459  }
1460 
1461  return FALSE;
1462 }
1463 #endif
1464 
1465 /******************************************************************
1466  * elf_search_and_load_file
1467  *
1468  * lookup a file in standard ELF locations, and if found, load it
1469  */
1470 static BOOL elf_search_and_load_file(struct process* pcs, const WCHAR* filename,
1471  unsigned long load_offset, unsigned long dyn_addr,
1472  struct elf_info* elf_info)
1473 {
1474  BOOL ret = FALSE;
1475  struct module* module;
1476  static const WCHAR S_libstdcPPW[] = {'l','i','b','s','t','d','c','+','+','\0'};
1477 
1478  if (filename == NULL || *filename == '\0') return FALSE;
1480  {
1481  elf_info->module = module;
1482  elf_info->module->format_info[DFI_ELF]->u.elf_info->elf_mark = 1;
1483  return module->module.SymType;
1484  }
1485 
1486  if (strstrW(filename, S_libstdcPPW)) return FALSE; /* We know we can't do it */
1487  ret = elf_load_file(pcs, filename, load_offset, dyn_addr, elf_info);
1488  /* if relative pathname, try some absolute base dirs */
1489  if (!ret && !strchrW(filename, '/'))
1490  {
1491  ret = elf_load_file_from_path(pcs, filename, load_offset, dyn_addr,
1492  getenv("PATH"), elf_info);
1493  if (!ret) ret = elf_load_file_from_path(pcs, filename, load_offset, dyn_addr,
1494  getenv("LD_LIBRARY_PATH"), elf_info);
1495  if (!ret) ret = elf_load_file_from_path(pcs, filename, load_offset, dyn_addr,
1496  BINDIR, elf_info);
1497  if (!ret) ret = elf_load_file_from_dll_path(pcs, filename,
1498  load_offset, dyn_addr, elf_info);
1499  }
1500 
1501  return ret;
1502 }
1503 
1504 typedef BOOL (*enum_elf_modules_cb)(const WCHAR*, unsigned long load_addr,
1505  unsigned long dyn_addr, BOOL is_system, void* user);
1506 
1507 /******************************************************************
1508  * elf_enum_modules_internal
1509  *
1510  * Enumerate ELF modules from a running process
1511  */
1512 static BOOL elf_enum_modules_internal(const struct process* pcs,
1513  const WCHAR* main_name,
1514  enum_elf_modules_cb cb, void* user)
1515 {
1516  struct r_debug dbg_hdr;
1517  void* lm_addr;
1518  struct link_map lm;
1519  char bufstr[256];
1520  WCHAR bufstrW[MAX_PATH];
1521 
1522  if (!pcs->dbg_hdr_addr ||
1523  !ReadProcessMemory(pcs->handle, (void*)pcs->dbg_hdr_addr,
1524  &dbg_hdr, sizeof(dbg_hdr), NULL))
1525  return FALSE;
1526 
1527  /* Now walk the linked list. In all known ELF implementations,
1528  * the dynamic loader maintains this linked list for us. In some
1529  * cases the first entry doesn't appear with a name, in other cases it
1530  * does.
1531  */
1532  for (lm_addr = (void*)dbg_hdr.r_map; lm_addr; lm_addr = (void*)lm.l_next)
1533  {
1534  if (!ReadProcessMemory(pcs->handle, lm_addr, &lm, sizeof(lm), NULL))
1535  return FALSE;
1536 
1537  if (lm.l_prev != NULL && /* skip first entry, normally debuggee itself */
1538  lm.l_name != NULL &&
1539  ReadProcessMemory(pcs->handle, lm.l_name, bufstr, sizeof(bufstr), NULL))
1540  {
1541  bufstr[sizeof(bufstr) - 1] = '\0';
1542  MultiByteToWideChar(CP_UNIXCP, 0, bufstr, -1, bufstrW, sizeof(bufstrW) / sizeof(WCHAR));
1543  if (main_name && !bufstrW[0]) strcpyW(bufstrW, main_name);
1544  if (!cb(bufstrW, (unsigned long)lm.l_addr, (unsigned long)lm.l_ld, FALSE, user)) break;
1545  }
1546  }
1547 
1548 #ifdef AT_SYSINFO_EHDR
1549  if (!lm_addr)
1550  {
1551  unsigned long ehdr_addr;
1552 
1553  if (elf_search_auxv(pcs, AT_SYSINFO_EHDR, &ehdr_addr))
1554  {
1555  static const WCHAR vdsoW[] = {'[','v','d','s','o',']','.','s','o',0};
1556  cb(vdsoW, ehdr_addr, 0, TRUE, user);
1557  }
1558  }
1559 #endif
1560  return TRUE;
1561 }
1562 
1563 /******************************************************************
1564  * elf_search_loader
1565  *
1566  * Lookup in a running ELF process the loader, and sets its ELF link
1567  * address (for accessing the list of loaded .so libs) in pcs.
1568  * If flags is ELF_INFO_MODULE, the module for the loader is also
1569  * added as a module into pcs.
1570  */
1571 static BOOL elf_search_loader(struct process* pcs, struct elf_info* elf_info)
1572 {
1574  ULONG_PTR base = 0;
1575 
1577  ReadProcessMemory( pcs->handle, &pbi.PebBaseAddress->Reserved[0], &base, sizeof(base), NULL );
1578 
1579  return elf_search_and_load_file(pcs, get_wine_loader_name(), base, 0, elf_info);
1580 }
1581 
1582 /******************************************************************
1583  * elf_read_wine_loader_dbg_info
1584  *
1585  * Try to find a decent wine executable which could have loaded the debuggee
1586  */
1588 {
1589  struct elf_info elf_info;
1590 
1591  elf_info.flags = ELF_INFO_DEBUG_HEADER | ELF_INFO_MODULE;
1592  if (!elf_search_loader(pcs, &elf_info)) return FALSE;
1593  elf_info.module->format_info[DFI_ELF]->u.elf_info->elf_loader = 1;
1594  module_set_module(elf_info.module, S_WineLoaderW);
1595  return (pcs->dbg_hdr_addr = elf_info.dbg_hdr_addr) != 0;
1596 }
1597 
1598 struct elf_enum_user
1599 {
1601  void* user;
1602 };
1603 
1604 static BOOL elf_enum_modules_translate(const WCHAR* name, unsigned long load_addr,
1605  unsigned long dyn_addr, BOOL is_system, void* user)
1606 {
1607  struct elf_enum_user* eeu = user;
1608  return eeu->cb(name, load_addr, eeu->user);
1609 }
1610 
1611 /******************************************************************
1612  * elf_enum_modules
1613  *
1614  * Enumerates the ELF loaded modules from a running target (hProc)
1615  * This function doesn't require that someone has called SymInitialize
1616  * on this very process.
1617  */
1619 {
1620  struct process pcs;
1621  struct elf_info elf_info;
1622  BOOL ret;
1623  struct elf_enum_user eeu;
1624 
1625  memset(&pcs, 0, sizeof(pcs));
1626  pcs.handle = hProc;
1627  elf_info.flags = ELF_INFO_DEBUG_HEADER | ELF_INFO_NAME;
1628  if (!elf_search_loader(&pcs, &elf_info)) return FALSE;
1629  pcs.dbg_hdr_addr = elf_info.dbg_hdr_addr;
1630  eeu.cb = cb;
1631  eeu.user = user;
1632  ret = elf_enum_modules_internal(&pcs, elf_info.module_name, elf_enum_modules_translate, &eeu);
1633  HeapFree(GetProcessHeap(), 0, (char*)elf_info.module_name);
1634  return ret;
1635 }
1636 
1637 struct elf_load
1638 {
1639  struct process* pcs;
1640  struct elf_info elf_info;
1641  const WCHAR* name;
1642  BOOL ret;
1643 };
1644 
1645 /******************************************************************
1646  * elf_load_cb
1647  *
1648  * Callback for elf_load_module, used to walk the list of loaded
1649  * modules.
1650  */
1651 static BOOL elf_load_cb(const WCHAR* name, unsigned long load_addr,
1652  unsigned long dyn_addr, BOOL is_system, void* user)
1653 {
1654  struct elf_load* el = user;
1655  BOOL ret = TRUE;
1656  const WCHAR* p;
1657 
1658  if (is_system) /* virtual ELF module, created by system. handle it from memory */
1659  {
1660  struct module* module;
1661  struct elf_map_file_data emfd;
1662  struct image_file_map fmap;
1663 
1664  if ((module = module_is_already_loaded(el->pcs, name)))
1665  {
1666  el->elf_info.module = module;
1667  el->elf_info.module->format_info[DFI_ELF]->u.elf_info->elf_mark = 1;
1668  return module->module.SymType;
1669  }
1670 
1671  emfd.kind = from_process;
1672  emfd.u.process.handle = el->pcs->handle;
1673  emfd.u.process.load_addr = (void*)load_addr;
1674 
1675  if (elf_map_file(&emfd, &fmap))
1676  el->ret = elf_load_file_from_fmap(el->pcs, name, &fmap, load_addr, 0, &el->elf_info);
1677  return TRUE;
1678  }
1679  if (el->name)
1680  {
1681  /* memcmp is needed for matches when bufstr contains also version information
1682  * el->name: libc.so, name: libc.so.6.0
1683  */
1684  p = strrchrW(name, '/');
1685  if (!p++) p = name;
1686  }
1687 
1688  if (!el->name || !memcmp(p, el->name, lstrlenW(el->name) * sizeof(WCHAR)))
1689  {
1690  el->ret = elf_search_and_load_file(el->pcs, name, load_addr, dyn_addr, &el->elf_info);
1691  if (el->name) ret = FALSE;
1692  }
1693 
1694  return ret;
1695 }
1696 
1697 /******************************************************************
1698  * elf_load_module
1699  *
1700  * loads an ELF module and stores it in process' module list
1701  * Also, find module real name and load address from
1702  * the real loaded modules list in pcs address space
1703  */
1704 struct module* elf_load_module(struct process* pcs, const WCHAR* name, unsigned long addr)
1705 {
1706  struct elf_load el;
1707 
1708  TRACE("(%p %s %08lx)\n", pcs, debugstr_w(name), addr);
1709 
1710  el.elf_info.flags = ELF_INFO_MODULE;
1711  el.ret = FALSE;
1712 
1713  if (pcs->dbg_hdr_addr) /* we're debugging a life target */
1714  {
1715  el.pcs = pcs;
1716  /* do only the lookup from the filename, not the path (as we lookup module
1717  * name in the process' loaded module list)
1718  */
1719  el.name = strrchrW(name, '/');
1720  if (!el.name++) el.name = name;
1721  el.ret = FALSE;
1722 
1723  if (!elf_enum_modules_internal(pcs, NULL, elf_load_cb, &el))
1724  return NULL;
1725  }
1726  else if (addr)
1727  {
1728  el.name = name;
1729  el.ret = elf_search_and_load_file(pcs, el.name, addr, 0, &el.elf_info);
1730  }
1731  if (!el.ret) return NULL;
1732  assert(el.elf_info.module);
1733  return el.elf_info.module;
1734 }
1735 
1736 /******************************************************************
1737  * elf_synchronize_module_list
1738  *
1739  * this function rescans the debuggee module's list and synchronizes it with
1740  * the one from 'pcs', i.e.:
1741  * - if a module is in debuggee and not in pcs, it's loaded into pcs
1742  * - if a module is in pcs and not in debuggee, it's unloaded from pcs
1743  */
1745 {
1746  struct module* module;
1747  struct elf_load el;
1748 
1749  for (module = pcs->lmodules; module; module = module->next)
1750  {
1751  if (module->type == DMT_ELF && !module->is_virtual)
1752  module->format_info[DFI_ELF]->u.elf_info->elf_mark = 0;
1753  }
1754 
1755  el.pcs = pcs;
1756  el.elf_info.flags = ELF_INFO_MODULE;
1757  el.ret = FALSE;
1758  el.name = NULL; /* fetch all modules */
1759 
1760  if (!elf_enum_modules_internal(pcs, NULL, elf_load_cb, &el))
1761  return FALSE;
1762 
1763  module = pcs->lmodules;
1764  while (module)
1765  {
1766  if (module->type == DMT_ELF && !module->is_virtual)
1767  {
1768  struct elf_module_info* elf_info = module->format_info[DFI_ELF]->u.elf_info;
1769 
1770  if (!elf_info->elf_mark && !elf_info->elf_loader)
1771  {
1772  module_remove(pcs, module);
1773  /* restart all over */
1774  module = pcs->lmodules;
1775  continue;
1776  }
1777  }
1778  module = module->next;
1779  }
1780  return TRUE;
1781 }
1782 
1783 #else /* !__ELF__ */
1784 
1785 BOOL elf_find_section(struct image_file_map* fmap, const char* name,
1786  unsigned sht, struct image_section_map* ism)
1787 {
1788  return FALSE;
1789 }
1790 
1791 const char* elf_map_section(struct image_section_map* ism)
1792 {
1793  return NULL;
1794 }
1795 
1797 {}
1798 
1799 unsigned elf_get_map_size(const struct image_section_map* ism)
1800 {
1801  return 0;
1802 }
1803 
1805 {
1806  return 0;
1807 }
1808 
1810 {
1811  return FALSE;
1812 }
1813 
1815  DWORD* size, DWORD* checksum)
1816 {
1817  return FALSE;
1818 }
1819 
1821 {
1822  return FALSE;
1823 }
1824 
1826 {
1827  return FALSE;
1828 }
1829 
1830 struct module* elf_load_module(struct process* pcs, const WCHAR* name, unsigned long addr)
1831 {
1832  return NULL;
1833 }
1834 
1836 {
1837  return FALSE;
1838 }
1839 
1840 int elf_is_in_thunk_area(unsigned long addr,
1841  const struct elf_thunk_area* thunks)
1842 {
1843  return -1;
1844 }
1845 #endif /* __ELF__ */
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble * u
Definition: glfuncs.h:240
void(* remove)(struct process *pcs, struct module_format *modfmt)
BOOL elf_enum_modules(HANDLE hProc, enum_modules_cb cb, void *user)
Definition: elf_module.c:1825
BOOL symt_get_address(const struct symt *type, ULONG64 *addr) DECLSPEC_HIDDEN
Definition: type.c:120
unsigned addr_size
Definition: image_private.h:90
void module_set_module(struct module *module, const WCHAR *name) DECLSPEC_HIDDEN
Definition: module.c:103
enum module_type modtype
Definition: image_private.h:89
struct module * module_new(struct process *pcs, const WCHAR *name, enum module_type type, BOOL virtual, DWORD64 addr, DWORD64 size, unsigned long stamp, unsigned long checksum) DECLSPEC_HIDDEN
Definition: module.c:163
#define memmove(s1, s2, n)
Definition: mkisofs.h:881
namespace GUID const ADDRINFOEXW ADDRINFOEXW struct timeval OVERLAPPED LPLOOKUPSERVICE_COMPLETION_ROUTINE HANDLE * handle
Definition: sock.c:82
#define TRUE
Definition: types.h:120
HMODULE module
Definition: main.cpp:47
BOOL elf_synchronize_module_list(struct process *pcs)
Definition: elf_module.c:1809
#define SHT_NOBITS
Definition: common.h:254
int memcmp(void *Buffer1, void *Buffer2, ACPI_SIZE Count)
Definition: utclib.c:112
WINE_UNICODE_INLINE unsigned int strlenW(const WCHAR *str)
Definition: unicode.h:212
#define WideCharToMultiByte
Definition: compat.h:101
WCHAR ModuleName[32]
Definition: compat.h:725
#define SHT_NULL
Definition: image_private.h:80
static LPCWSTR LPCWSTR module_name
Definition: db.cpp:168
#define open
Definition: acwin.h:95
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
static GLenum _GLUfuncptr fn
Definition: wgl_font.c:159
GLsizei const GLchar ** path
Definition: glext.h:7234
WINE_UNICODE_INLINE WCHAR * strchrW(const WCHAR *str, WCHAR ch)
Definition: unicode.h:248
char * wine_dbgstr_w(const wchar_t *wstr)
Definition: atltest.h:87
struct hash_table ht_symbols
ssize_t pread(int fd, void *buf, size_t count, off_t offset)
__kernel_off_t off_t
Definition: linux.h:201
#define WARN(fmt,...)
Definition: debug.h:111
NTSTATUS NTAPI NtQueryInformationProcess(IN HANDLE ProcessHandle, IN PROCESSINFOCLASS ProcessInformationClass, OUT PVOID ProcessInformation, IN ULONG ProcessInformationLength, OUT PULONG ReturnLength OPTIONAL)
Definition: query.c:59
struct image_file_map * fmap
const char * elf_map_section(struct image_section_map *ism)
Definition: elf_module.c:1791
#define DT_NULL
Definition: common.h:296
GLdouble n
Definition: glext.h:7729
#define STT_NOTYPE
Definition: common.h:380
GLdouble GLdouble t
Definition: gl.h:2047
#define STT_OBJECT
Definition: common.h:381
static HANDLE process
Definition: process.c:76
void elf_unmap_section(struct image_section_map *ism)
Definition: elf_module.c:1796
GLuint GLuint GLsizei GLenum type
Definition: gl.h:1545
#define assert(x)
Definition: debug.h:53
const WCHAR S_SlashW[]
Definition: module.c:43
GLuint buffer
Definition: glext.h:5915
_In_ BOOL _In_ HANDLE hProcess
Definition: mapping.h:70
#define ReadProcessMemory(a, b, c, d, e)
Definition: compat.h:415
DWORD calc_crc32(int fd)
Definition: crc32.c:89
const char * source_get(const struct module *module, unsigned idx) DECLSPEC_HIDDEN
Definition: source.c:131
_Check_return_ _CRTIMP _CONST_RETURN char *__cdecl strrchr(_In_z_ const char *_Str, _In_ int _Ch)
struct symt_compiland * symt_new_compiland(struct module *module, unsigned long address, unsigned src_idx) DECLSPEC_HIDDEN
Definition: symbol.c:209
const char * filename
Definition: ioapi.h:135
#define SHT_SYMTAB
Definition: common.h:248
#define lstrlenW
Definition: compat.h:407
#define BOOL
Definition: nt_native.h:43
int load_addr
Definition: mkisofs.c:104
BOOL(* enum_modules_cb)(const WCHAR *, unsigned long addr, void *user)
DWORD_PTR elf_get_map_rva(const struct image_section_map *ism)
Definition: elf_module.c:1804
#define AT_NULL
Definition: tdiinfo.h:50
#define SYMOPT_DEFERRED_LOADS
Definition: compat.h:638
enum module_type type
uint32_t ULONG_PTR
Definition: typedefs.h:63
#define IMAGE_NO_MAP
Definition: image_private.h:59
#define ELFCLASS64
Definition: common.h:81
void * pool_alloc(struct pool *a, size_t len) DECLSPEC_HIDDEN
Definition: storage.c:90
WCHAR LoadedImageName[256]
Definition: compat.h:727
BOOL elf_find_section(struct image_file_map *fmap, const char *name, unsigned sht, struct image_section_map *ism)
Definition: elf_module.c:1785
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
#define ELFMAG0
Definition: common.h:67
#define ELFMAG1
Definition: common.h:68
struct module * lmodules
unsigned int BOOL
Definition: ntddk_ex.h:94
GLuint base
Definition: 3dtext.c:35
#define DT_DEBUG
Definition: common.h:319
int sortlist_valid
BOOL elf_load_debug_info(struct module *module)
Definition: elf_module.c:1835
#define debugstr_w
Definition: kernel32.h:32
struct symt_public * symt_new_public(struct module *module, struct symt_compiland *parent, const char *typename, BOOL is_function, unsigned long address, unsigned size) DECLSPEC_HIDDEN
Definition: symbol.c:226
#define FIXME(fmt,...)
Definition: debug.h:110
static PVOID ptr
Definition: dispmode.c:27
BOOL stabs_parse(struct module *module, unsigned long load_offset, const void *stabs, int stablen, const char *strs, int strtablen, stabs_def_cb callback, void *user) DECLSPEC_HIDDEN
Definition: stabs.c:1275
unsigned elf_get_map_size(const struct image_section_map *ism)
Definition: elf_module.c:1799
void hash_table_iter_init(const struct hash_table *ht, struct hash_table_iter *hti, const char *name) DECLSPEC_HIDDEN
Definition: storage.c:406
GLdouble GLdouble z
Definition: glext.h:5874
const WCHAR * str
int note(char *format,...)
Definition: util.c:12
#define strstrW(d, s)
Definition: unicode.h:32
smooth NULL
Definition: ftsmooth.c:416
struct symt symt
_Inout_ PERBANDINFO * pbi
Definition: winddi.h:3917
union image_file_map::@372 u
GLuint index
Definition: glext.h:6031
#define isdigit(c)
Definition: acclib.h:68
PFLT_MESSAGE_WAITER_QUEUE CONTAINING_RECORD(Csq, DEVICE_EXTENSION, IrpQueue)) -> WaiterQ.mLock) _IRQL_raises_(DISPATCH_LEVEL) VOID NTAPI FltpAcquireMessageWaiterLock(_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
Definition: Messaging.c:560
GLuint GLfloat * val
Definition: glext.h:7180
struct module * module_is_already_loaded(const struct process *pcs, const WCHAR *imgname) DECLSPEC_HIDDEN
Definition: module.c:268
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint GLint GLint j
Definition: glfuncs.h:250
struct symt_data * symt_new_global_variable(struct module *module, struct symt_compiland *parent, const char *name, unsigned is_static, struct location loc, unsigned long size, struct symt *type) DECLSPEC_HIDDEN
Definition: symbol.c:258
c used
Definition: write.c:2877
#define TRACE(s)
Definition: solgame.cpp:4
struct elf_module_info * elf_info
GLsizeiptr size
Definition: glext.h:5919
DWORD64 reloc_delta
#define GetProcessHeap()
Definition: compat.h:395
#define EI_CLASS
Definition: common.h:57
PVOID WINAPI HeapAlloc(HANDLE, DWORD, SIZE_T)
BOOL elf_read_wine_loader_dbg_info(struct process *pcs)
Definition: elf_module.c:1820
#define CP_UNIXCP
Definition: compat.h:69
if(!(yy_init))
Definition: macro.lex.yy.c:714
void(* loc_compute)(struct process *pcs, const struct module_format *modfmt, const struct symt_function *func, struct location *loc)
struct image_file_map::@372::elf_file_map elf
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define ELFMAG2
Definition: common.h:69
const WCHAR S_ElfW[]
Definition: module.c:37
#define S_ISDIR(mode)
Definition: various.h:18
#define STB_LOCAL
Definition: common.h:373
#define STT_FUNC
Definition: common.h:382
#define MAX_PATH
Definition: compat.h:26
const char file[]
Definition: icontest.c:11
#define PT_LOAD
Definition: common.h:275
struct _SYMBOL_INFO SYMBOL_INFO
#define ELFCLASS32
Definition: common.h:80
#define MAX_SYM_NAME
Definition: compat.h:624
unsigned dbghelp_options
Definition: dbghelp.c:72
unsigned long DWORD
Definition: ntddk_ex.h:95
GLuint address
Definition: glext.h:9393
#define SHT_DYNSYM
Definition: common.h:257
REFIID LPVOID DWORD dw
Definition: atlbase.h:40
void hash_table_add(struct hash_table *ht, struct hash_table_elt *elt) DECLSPEC_HIDDEN
Definition: storage.c:379
struct symt symt
static unsigned image_get_map_size(const struct image_section_map *ism)
GLbitfield flags
Definition: glext.h:7161
struct module * elf_load_module(struct process *pcs, const WCHAR *name, unsigned long addr)
Definition: elf_module.c:1830
unsigned __int64 ULONG64
Definition: imports.h:198
int ret
void pool_init(struct pool *a, size_t arena_size) DECLSPEC_HIDDEN
Definition: storage.c:44
SYM_TYPE SymType
Definition: compat.h:724
#define SHN_UNDEF
Definition: common.h:237
GLenum const GLvoid * addr
Definition: glext.h:9621
static const WCHAR L[]
Definition: oid.c:1250
unsigned long dbg_hdr_addr
const WCHAR * get_wine_loader_name(void) DECLSPEC_HIDDEN
Definition: module.c:110
static void image_unmap_section(struct image_section_map *ism)
Definition: stat.h:55
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
GLenum GLsizei len
Definition: glext.h:6722
unsigned char BYTE
Definition: mem.h:68
GLdouble s
Definition: gl.h:2039
void * hash_table_iter_up(struct hash_table_iter *hti) DECLSPEC_HIDDEN
Definition: storage.c:423
static cab_ULONG checksum(const cab_UBYTE *data, cab_UWORD bytes, cab_ULONG csum)
Definition: fdi.c:353
#define close
Definition: acwin.h:98
uint32_t DWORD_PTR
Definition: typedefs.h:63
static const char * image_map_section(struct image_section_map *ism)
static UINT_PTR page_mask
Definition: virtual.c:49
WINE_UNICODE_INLINE WCHAR * strrchrW(const WCHAR *str, WCHAR ch)
Definition: unicode.h:254
#define ERR(fmt,...)
Definition: debug.h:109
ULONG_PTR SIZE_T
Definition: typedefs.h:78
int elf_is_in_thunk_area(unsigned long addr, const struct elf_thunk_area *thunks)
Definition: elf_module.c:1840
_CRTIMP int __cdecl stat(const char *_Filename, struct stat *_Stat)
Definition: stat.h:345
WINE_UNICODE_INLINE WCHAR * strcpyW(WCHAR *dst, const WCHAR *src)
Definition: unicode.h:219
_Check_return_ char *__cdecl getenv(_In_z_ const char *_VarName)
#define ELF32_ST_TYPE(info)
Definition: elf32.h:149
void pool_destroy(struct pool *a) DECLSPEC_HIDDEN
Definition: storage.c:51
struct symt_function * symt_new_function(struct module *module, struct symt_compiland *parent, const char *name, unsigned long addr, unsigned long size, struct symt *type) DECLSPEC_HIDDEN
Definition: symbol.c:295
const WCHAR S_WineLoaderW[]
Definition: module.c:38
unsigned short is_virtual
Definition: services.c:325
BOOL elf_fetch_file_info(const WCHAR *name, DWORD_PTR *base, DWORD *size, DWORD *checksum)
Definition: elf_module.c:1814
WINE_UNICODE_INLINE WCHAR * strcatW(WCHAR *dst, const WCHAR *src)
Definition: unicode.h:242
#define min(a, b)
Definition: monoChain.cc:55
BOOL module_remove(struct process *pcs, struct module *module) DECLSPEC_HIDDEN
Definition: module.c:684
struct hash_table_elt hash_elt
BOOL dwarf2_parse(struct module *module, unsigned long load_offset, const struct elf_thunk_area *thunks, struct image_file_map *fmap) DECLSPEC_HIDDEN
Definition: dwarf.c:3522
UINT32 uint32_t
Definition: types.h:75
struct module * module
#define MultiByteToWideChar
Definition: compat.h:100
#define ELF32_ST_BIND(info)
Definition: elf32.h:148
void hash_table_init(struct pool *pool, struct hash_table *ht, unsigned num_buckets) DECLSPEC_HIDDEN
Definition: storage.c:335
static HMODULE MODULEINFO DWORD cb
Definition: module.c:32
unsigned source_new(struct module *module, const char *basedir, const char *source) DECLSPEC_HIDDEN
Definition: source.c:67
#define STT_FILE
Definition: common.h:384
Definition: name.c:36
WINE_UNICODE_INLINE int strcmpW(const WCHAR *str1, const WCHAR *str2)
Definition: unicode.h:229
#define SYMOPT_PUBLICS_ONLY
Definition: compat.h:641
HANDLE handle
int strcmp(const char *String1, const char *String2)
Definition: utclib.c:469
BOOL WINAPI SymFromName(HANDLE hProcess, PCSTR Name, PSYMBOL_INFO Symbol)
Definition: symbol.c:1400
union module_format::@365 u
#define ELFMAG3
Definition: common.h:70
#define SYMOPT_NO_PUBLICS
Definition: compat.h:642
struct symt_thunk * symt_new_thunk(struct module *module, struct symt_compiland *parent, const char *name, THUNK_ORDINAL ord, unsigned long addr, unsigned long size) DECLSPEC_HIDDEN
Definition: symbol.c:498
GLfloat GLfloat p
Definition: glext.h:8902
GLuint64EXT * result
Definition: glext.h:11304
#define memset(x, y, z)
Definition: compat.h:39
#define SHT_DYNAMIC
Definition: common.h:252
#define WINE_DEFAULT_DEBUG_CHANNEL(t)
Definition: precomp.h:23
struct module_format * format_info[DFI_LAST]
IMAGEHLP_MODULEW64 module
void user(int argc, const char *argv[])
Definition: cmds.c:1350
struct module * next
#define HeapFree(x, y, z)
Definition: compat.h:394
struct hash_table_elt hash_elt
THUNK_ORDINAL
Definition: compat.h:1855
struct symt_ht * symt_find_nearest(struct module *module, DWORD_PTR addr) DECLSPEC_HIDDEN
Definition: symbol.c:905
#define O_RDONLY
Definition: acwin.h:108
off
Definition: i386-dis.c:3909
Definition: fci.c:126
GLuint const GLchar * name
Definition: glext.h:6031