ReactOS  0.4.15-dev-1206-g731eddf
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 <assert.h>
23 #include <stdio.h>
24 #include <stdlib.h>
25 
26 #include "dbghelp_private.h"
27 #include "image_private.h"
28 #include "winternl.h"
29 
30 #include "wine/debug.h"
31 #include "wine/heap.h"
32 
33 #define ELF_INFO_DEBUG_HEADER 0x0001
34 #define ELF_INFO_MODULE 0x0002
35 #define ELF_INFO_NAME 0x0004
36 
38 
39 struct elf_info
40 {
41  unsigned flags; /* IN one (or several) of the ELF_INFO constants */
42  DWORD_PTR dbg_hdr_addr; /* OUT address of debug header (if ELF_INFO_DEBUG_HEADER is set) */
43  struct module* module; /* OUT loaded module (if ELF_INFO_MODULE is set) */
44  const WCHAR* module_name; /* OUT found module name (if ELF_INFO_NAME is set) */
45 };
46 
47 struct elf_sym32
48 {
49  UINT32 st_name; /* Symbol name (string tbl index) */
50  UINT32 st_value; /* Symbol value */
51  UINT32 st_size; /* Symbol size */
52  UINT8 st_info; /* Symbol type and binding */
53  UINT8 st_other; /* Symbol visibility */
54  UINT16 st_shndx; /* Section index */
55 };
56 
57 struct elf_sym
58 {
59  UINT32 st_name; /* Symbol name (string tbl index) */
60  UINT8 st_info; /* Symbol type and binding */
61  UINT8 st_other; /* Symbol visibility */
62  UINT16 st_shndx; /* Section index */
63  UINT64 st_value; /* Symbol value */
64  UINT64 st_size; /* Symbol size */
65 };
66 
67 struct symtab_elt
68 {
70  struct elf_sym sym;
72  unsigned used;
73 };
74 
76 {
77  const char* symname;
81 };
82 
84 {
86  unsigned short elf_mark : 1,
87  elf_loader : 1;
89 };
90 
91 /* Legal values for sh_type (section type). */
92 #define ELF_SHT_NULL 0 /* Section header table entry unused */
93 #define ELF_SHT_PROGBITS 1 /* Program data */
94 #define ELF_SHT_SYMTAB 2 /* Symbol table */
95 #define ELF_SHT_STRTAB 3 /* String table */
96 #define ELF_SHT_RELA 4 /* Relocation entries with addends */
97 #define ELF_SHT_HASH 5 /* Symbol hash table */
98 #define ELF_SHT_DYNAMIC 6 /* Dynamic linking information */
99 #define ELF_SHT_NOTE 7 /* Notes */
100 #define ELF_SHT_NOBITS 8 /* Program space with no data (bss) */
101 #define ELF_SHT_REL 9 /* Relocation entries, no addends */
102 #define ELF_SHT_SHLIB 10 /* Reserved */
103 #define ELF_SHT_DYNSYM 11 /* Dynamic linker symbol table */
104 #define ELF_SHT_INIT_ARRAY 14 /* Array of constructors */
105 #define ELF_SHT_FINI_ARRAY 15 /* Array of destructors */
106 #define ELF_SHT_PREINIT_ARRAY 16 /* Array of pre-constructors */
107 #define ELF_SHT_GROUP 17 /* Section group */
108 #define ELF_SHT_SYMTAB_SHNDX 18 /* Extended section indices */
109 #define ELF_SHT_NUM 19 /* Number of defined types. */
110 
111 /* Legal values for ST_TYPE subfield of st_info (symbol type). */
112 #define ELF_STT_NOTYPE 0 /* Symbol type is unspecified */
113 #define ELF_STT_OBJECT 1 /* Symbol is a data object */
114 #define ELF_STT_FUNC 2 /* Symbol is a code object */
115 #define ELF_STT_SECTION 3 /* Symbol associated with a section */
116 #define ELF_STT_FILE 4 /* Symbol's name is file name */
117 
118 #define ELF_PT_LOAD 1 /* Loadable program segment */
119 
120 #define ELF_DT_DEBUG 21 /* For debugging; unspecified */
121 
122 #define ELF_AT_SYSINFO_EHDR 33
123 
124 /******************************************************************
125  * elf_map_section
126  *
127  * Maps a single section into memory from an ELF file
128  */
129 static 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;
133  HANDLE mapping;
134 
135  assert(ism->fmap->modtype == DMT_ELF);
136  if (ism->sidx < 0 || ism->sidx >= ism->fmap->u.elf.elfhdr.e_shnum ||
137  fmap->sect[ism->sidx].shdr.sh_type == ELF_SHT_NOBITS)
138  return IMAGE_NO_MAP;
139 
140  if (fmap->target_copy)
141  {
142  return fmap->target_copy + fmap->sect[ism->sidx].shdr.sh_offset;
143  }
144 
145  /* align required information on allocation granularity */
146  ofst = fmap->sect[ism->sidx].shdr.sh_offset & ~(sysinfo.dwAllocationGranularity - 1);
147  size = fmap->sect[ism->sidx].shdr.sh_offset + fmap->sect[ism->sidx].shdr.sh_size - ofst;
148  if (!(mapping = CreateFileMappingW(fmap->handle, NULL, PAGE_READONLY, 0, ofst + size, NULL)))
149  {
150  ERR("map creation %p failed %u offset %lu %lu size %lu\n", fmap->handle, GetLastError(), ofst, ofst % 4096, size);
151  return IMAGE_NO_MAP;
152  }
153  fmap->sect[ism->sidx].mapped = MapViewOfFile(mapping, FILE_MAP_READ, 0, ofst, size);
155  if (!fmap->sect[ism->sidx].mapped)
156  {
157  ERR("map %p failed %u offset %lu %lu size %lu\n", fmap->handle, GetLastError(), ofst, ofst % 4096, size);
158  return IMAGE_NO_MAP;
159  }
160  return fmap->sect[ism->sidx].mapped + (fmap->sect[ism->sidx].shdr.sh_offset & (sysinfo.dwAllocationGranularity - 1));
161 }
162 
163 /******************************************************************
164  * elf_find_section
165  *
166  * Finds a section by name (and type) into memory from an ELF file
167  * or its alternate if any
168  */
169 static BOOL elf_find_section(struct image_file_map* _fmap, const char* name, struct image_section_map* ism)
170 {
171  struct elf_file_map* fmap = &_fmap->u.elf;
172  unsigned i;
173 
174  if (fmap->shstrtab == IMAGE_NO_MAP)
175  {
176  struct image_section_map hdr_ism = {_fmap, fmap->elfhdr.e_shstrndx};
177  if ((fmap->shstrtab = elf_map_section(&hdr_ism)) == IMAGE_NO_MAP) return FALSE;
178  }
179  for (i = 0; i < fmap->elfhdr.e_shnum; i++)
180  {
181  if (strcmp(fmap->shstrtab + fmap->sect[i].shdr.sh_name, name) == 0)
182  {
183  ism->fmap = _fmap;
184  ism->sidx = i;
185  return TRUE;
186  }
187  }
188  return FALSE;
189 }
190 
191 static BOOL elf_find_section_type(struct image_file_map* _fmap, const char* name, unsigned sht, struct image_section_map* ism)
192 {
193  struct elf_file_map* fmap;
194  unsigned i;
195 
196  while (_fmap)
197  {
198  if (_fmap->modtype != DMT_ELF) break;
199  fmap = &_fmap->u.elf;
200  if (fmap->shstrtab == IMAGE_NO_MAP)
201  {
202  struct image_section_map hdr_ism = {_fmap, fmap->elfhdr.e_shstrndx};
203  if ((fmap->shstrtab = elf_map_section(&hdr_ism)) == IMAGE_NO_MAP) break;
204  }
205  for (i = 0; i < fmap->elfhdr.e_shnum; i++)
206  {
207  if (strcmp(fmap->shstrtab + fmap->sect[i].shdr.sh_name, name) == 0 && sht == fmap->sect[i].shdr.sh_type)
208  {
209  ism->fmap = _fmap;
210  ism->sidx = i;
211  return TRUE;
212  }
213  }
214  _fmap = _fmap->alternate;
215  }
216  ism->fmap = NULL;
217  ism->sidx = -1;
218  return FALSE;
219 }
220 
221 /******************************************************************
222  * elf_unmap_section
223  *
224  * Unmaps a single section from memory
225  */
226 static void elf_unmap_section(struct image_section_map* ism)
227 {
228  struct elf_file_map* fmap = &ism->fmap->u.elf;
229 
230  if (ism->sidx >= 0 && ism->sidx < fmap->elfhdr.e_shnum && !fmap->target_copy &&
231  fmap->sect[ism->sidx].mapped)
232  {
233  if (!UnmapViewOfFile(fmap->sect[ism->sidx].mapped))
234  WARN("Couldn't unmap the section\n");
235  fmap->sect[ism->sidx].mapped = NULL;
236  }
237 }
238 
239 static void elf_end_find(struct image_file_map* fmap)
240 {
241  struct image_section_map ism;
242 
243  while (fmap && fmap->modtype == DMT_ELF)
244  {
245  ism.fmap = fmap;
246  ism.sidx = fmap->u.elf.elfhdr.e_shstrndx;
247  elf_unmap_section(&ism);
248  fmap->u.elf.shstrtab = IMAGE_NO_MAP;
249  fmap = fmap->alternate;
250  }
251 }
252 
253 /******************************************************************
254  * elf_get_map_rva
255  *
256  * Get the RVA of an ELF section
257  */
258 static DWORD_PTR elf_get_map_rva(const struct image_section_map* ism)
259 {
260  if (ism->sidx < 0 || ism->sidx >= ism->fmap->u.elf.elfhdr.e_shnum)
261  return 0;
262  return ism->fmap->u.elf.sect[ism->sidx].shdr.sh_addr - ism->fmap->u.elf.elf_start;
263 }
264 
265 /******************************************************************
266  * elf_get_map_size
267  *
268  * Get the size of an ELF section
269  */
270 static unsigned elf_get_map_size(const struct image_section_map* ism)
271 {
272  if (ism->sidx < 0 || ism->sidx >= ism->fmap->u.elf.elfhdr.e_shnum)
273  return 0;
274  return ism->fmap->u.elf.sect[ism->sidx].shdr.sh_size;
275 }
276 
277 /******************************************************************
278  * elf_unmap_file
279  *
280  * Unmaps an ELF file from memory (previously mapped with elf_map_file)
281  */
282 static void elf_unmap_file(struct image_file_map* fmap)
283 {
284  if (fmap->u.elf.handle != INVALID_HANDLE_VALUE)
285  {
286  struct image_section_map ism;
287  ism.fmap = fmap;
288  for (ism.sidx = 0; ism.sidx < fmap->u.elf.elfhdr.e_shnum; ism.sidx++)
289  {
290  elf_unmap_section(&ism);
291  }
292  HeapFree(GetProcessHeap(), 0, fmap->u.elf.sect);
293  CloseHandle(fmap->u.elf.handle);
294  }
295  HeapFree(GetProcessHeap(), 0, fmap->u.elf.target_copy);
296 }
297 
299 {
306 };
307 
308 static inline void elf_reset_file_map(struct image_file_map* fmap)
309 {
310  fmap->ops = &elf_file_map_ops;
311  fmap->alternate = NULL;
312  fmap->u.elf.handle = INVALID_HANDLE_VALUE;
313  fmap->u.elf.shstrtab = IMAGE_NO_MAP;
314  fmap->u.elf.target_copy = NULL;
315 }
316 
318 {
320  union
321  {
322  struct
323  {
324  const WCHAR* filename;
325  } file;
326  struct
327  {
329  void* load_addr;
330  } process;
331  HANDLE handle;
332  } u;
333 };
334 
335 static BOOL elf_map_file_read(struct image_file_map* fmap, struct elf_map_file_data* emfd,
336  void* buf, size_t len, size_t off)
337 {
338  LARGE_INTEGER li;
339  DWORD bytes_read;
340  SIZE_T dw;
341 
342  switch (emfd->kind)
343  {
344  case from_file:
345  case from_handle:
346  li.QuadPart = off;
347  if (!SetFilePointerEx(fmap->u.elf.handle, li, NULL, FILE_BEGIN)) return FALSE;
348  return ReadFile(fmap->u.elf.handle, buf, len, &bytes_read, NULL);
349  case from_process:
350  return ReadProcessMemory(emfd->u.process.handle,
351  (void*)((ULONG_PTR)emfd->u.process.load_addr + (ULONG_PTR)off),
352  buf, len, &dw) && dw == len;
353  default:
354  assert(0);
355  return FALSE;
356  }
357 }
358 
359 static BOOL elf_map_shdr(struct elf_map_file_data* emfd, struct image_file_map* fmap, unsigned int i)
360 {
361  if (fmap->addr_size == 32)
362  {
363  struct
364  {
365  UINT32 sh_name; /* Section name (string tbl index) */
366  UINT32 sh_type; /* Section type */
367  UINT32 sh_flags; /* Section flags */
368  UINT32 sh_addr; /* Section virtual addr at execution */
369  UINT32 sh_offset; /* Section file offset */
370  UINT32 sh_size; /* Section size in bytes */
371  UINT32 sh_link; /* Link to another section */
372  UINT32 sh_info; /* Additional section information */
373  UINT32 sh_addralign; /* Section alignment */
374  UINT32 sh_entsize; /* Entry size if section holds table */
375  } shdr32;
376 
377  if (!elf_map_file_read(fmap, emfd, &shdr32, sizeof(shdr32),
378  fmap->u.elf.elfhdr.e_shoff + i * sizeof(shdr32)))
379  return FALSE;
380 
381  fmap->u.elf.sect[i].shdr.sh_name = shdr32.sh_name;
382  fmap->u.elf.sect[i].shdr.sh_type = shdr32.sh_type;
383  fmap->u.elf.sect[i].shdr.sh_flags = shdr32.sh_flags;
384  fmap->u.elf.sect[i].shdr.sh_addr = shdr32.sh_addr;
385  fmap->u.elf.sect[i].shdr.sh_offset = shdr32.sh_offset;
386  fmap->u.elf.sect[i].shdr.sh_size = shdr32.sh_size;
387  fmap->u.elf.sect[i].shdr.sh_link = shdr32.sh_link;
388  fmap->u.elf.sect[i].shdr.sh_info = shdr32.sh_info;
389  fmap->u.elf.sect[i].shdr.sh_addralign = shdr32.sh_addralign;
390  fmap->u.elf.sect[i].shdr.sh_entsize = shdr32.sh_entsize;
391  }
392  else
393  {
394  if (!elf_map_file_read(fmap, emfd, &fmap->u.elf.sect[i].shdr, sizeof(fmap->u.elf.sect[i].shdr),
395  fmap->u.elf.elfhdr.e_shoff + i * sizeof(fmap->u.elf.sect[i].shdr)))
396  return FALSE;
397  }
398  return TRUE;
399 }
400 
401 /******************************************************************
402  * elf_map_file
403  *
404  * Maps an ELF file into memory (and checks it's a real ELF file)
405  */
406 static BOOL elf_map_file(struct elf_map_file_data* emfd, struct image_file_map* fmap)
407 {
408  unsigned int i;
409  size_t tmp, page_mask = sysinfo.dwPageSize - 1;
410  WCHAR *dos_path;
411  unsigned char e_ident[ARRAY_SIZE(fmap->u.elf.elfhdr.e_ident)];
412 
413  elf_reset_file_map(fmap);
414 
415  fmap->modtype = DMT_ELF;
416  fmap->u.elf.handle = INVALID_HANDLE_VALUE;
417  fmap->u.elf.target_copy = NULL;
418 
419  switch (emfd->kind)
420  {
421  case from_file:
422  if (!(dos_path = get_dos_file_name(emfd->u.file.filename))) return FALSE;
423  fmap->u.elf.handle = CreateFileW(dos_path, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);
424  heap_free(dos_path);
425  if (fmap->u.elf.handle == INVALID_HANDLE_VALUE) return FALSE;
426  break;
427  case from_handle:
428  if (!DuplicateHandle(GetCurrentProcess(), emfd->u.handle, GetCurrentProcess(), &fmap->u.elf.handle, GENERIC_READ, FALSE, 0))
429  return FALSE;
430  break;
431  case from_process:
432  break;
433  }
434 
435  if (!elf_map_file_read(fmap, emfd, e_ident, sizeof(e_ident), 0))
436  return FALSE;
437 
438  /* and check for an ELF header */
439  if (memcmp(e_ident, "\177ELF", 4))
440  return FALSE;
441 
442  fmap->addr_size = e_ident[4] == 2 /* ELFCLASS64 */ ? 64 : 32;
443 
444  if (fmap->addr_size == 32)
445  {
446  struct
447  {
448  UINT8 e_ident[16]; /* Magic number and other info */
449  UINT16 e_type; /* Object file type */
450  UINT16 e_machine; /* Architecture */
451  UINT32 e_version; /* Object file version */
452  UINT32 e_entry; /* Entry point virtual address */
453  UINT32 e_phoff; /* Program header table file offset */
454  UINT32 e_shoff; /* Section header table file offset */
455  UINT32 e_flags; /* Processor-specific flags */
456  UINT16 e_ehsize; /* ELF header size in bytes */
457  UINT16 e_phentsize; /* Program header table entry size */
458  UINT16 e_phnum; /* Program header table entry count */
459  UINT16 e_shentsize; /* Section header table entry size */
460  UINT16 e_shnum; /* Section header table entry count */
461  UINT16 e_shstrndx; /* Section header string table index */
462  } elfhdr32;
463 
464  if (!elf_map_file_read(fmap, emfd, &elfhdr32, sizeof(elfhdr32), 0))
465  return FALSE;
466 
467  memcpy(fmap->u.elf.elfhdr.e_ident, elfhdr32.e_ident, sizeof(e_ident));
468  fmap->u.elf.elfhdr.e_type = elfhdr32.e_type;
469  fmap->u.elf.elfhdr.e_machine = elfhdr32.e_machine;
470  fmap->u.elf.elfhdr.e_version = elfhdr32.e_version;
471  fmap->u.elf.elfhdr.e_entry = elfhdr32.e_entry;
472  fmap->u.elf.elfhdr.e_phoff = elfhdr32.e_phoff;
473  fmap->u.elf.elfhdr.e_shoff = elfhdr32.e_shoff;
474  fmap->u.elf.elfhdr.e_flags = elfhdr32.e_flags;
475  fmap->u.elf.elfhdr.e_ehsize = elfhdr32.e_ehsize;
476  fmap->u.elf.elfhdr.e_phentsize = elfhdr32.e_phentsize;
477  fmap->u.elf.elfhdr.e_phnum = elfhdr32.e_phnum;
478  fmap->u.elf.elfhdr.e_shentsize = elfhdr32.e_shentsize;
479  fmap->u.elf.elfhdr.e_shnum = elfhdr32.e_shnum;
480  fmap->u.elf.elfhdr.e_shstrndx = elfhdr32.e_shstrndx;
481  }
482  else
483  {
484  if (!elf_map_file_read(fmap, emfd, &fmap->u.elf.elfhdr, sizeof(fmap->u.elf.elfhdr), 0))
485  return FALSE;
486  }
487 
488  fmap->u.elf.sect = HeapAlloc(GetProcessHeap(), 0,
489  fmap->u.elf.elfhdr.e_shnum * sizeof(fmap->u.elf.sect[0]));
490  if (!fmap->u.elf.sect) return FALSE;
491 
492  for (i = 0; i < fmap->u.elf.elfhdr.e_shnum; i++)
493  {
494  if (!elf_map_shdr(emfd, fmap, i))
495  {
496  HeapFree(GetProcessHeap(), 0, fmap->u.elf.sect);
497  fmap->u.elf.sect = NULL;
498  return FALSE;
499  }
500  fmap->u.elf.sect[i].mapped = NULL;
501  }
502 
503  /* grab size of module once loaded in memory */
504  fmap->u.elf.elf_size = 0;
505  fmap->u.elf.elf_start = ~0L;
506  for (i = 0; i < fmap->u.elf.elfhdr.e_phnum; i++)
507  {
508  if (fmap->addr_size == 32)
509  {
510  struct
511  {
512  UINT32 p_type; /* Segment type */
513  UINT32 p_offset; /* Segment file offset */
514  UINT32 p_vaddr; /* Segment virtual address */
515  UINT32 p_paddr; /* Segment physical address */
516  UINT32 p_filesz; /* Segment size in file */
517  UINT32 p_memsz; /* Segment size in memory */
518  UINT32 p_flags; /* Segment flags */
519  UINT32 p_align; /* Segment alignment */
520  } phdr;
521 
522  if (elf_map_file_read(fmap, emfd, &phdr, sizeof(phdr),
523  fmap->u.elf.elfhdr.e_phoff + i * sizeof(phdr)) &&
524  phdr.p_type == ELF_PT_LOAD)
525  {
526  tmp = (phdr.p_vaddr + phdr.p_memsz + page_mask) & ~page_mask;
527  if (fmap->u.elf.elf_size < tmp) fmap->u.elf.elf_size = tmp;
528  if (phdr.p_vaddr < fmap->u.elf.elf_start) fmap->u.elf.elf_start = phdr.p_vaddr;
529  }
530  }
531  else
532  {
533  struct
534  {
535  UINT32 p_type; /* Segment type */
536  UINT32 p_flags; /* Segment flags */
537  UINT64 p_offset; /* Segment file offset */
538  UINT64 p_vaddr; /* Segment virtual address */
539  UINT64 p_paddr; /* Segment physical address */
540  UINT64 p_filesz; /* Segment size in file */
541  UINT64 p_memsz; /* Segment size in memory */
542  UINT64 p_align; /* Segment alignment */
543  } phdr;
544 
545  if (elf_map_file_read(fmap, emfd, &phdr, sizeof(phdr),
546  fmap->u.elf.elfhdr.e_phoff + i * sizeof(phdr)) &&
547  phdr.p_type == ELF_PT_LOAD)
548  {
549  tmp = (phdr.p_vaddr + phdr.p_memsz + page_mask) & ~page_mask;
550  if (fmap->u.elf.elf_size < tmp) fmap->u.elf.elf_size = tmp;
551  if (phdr.p_vaddr < fmap->u.elf.elf_start) fmap->u.elf.elf_start = phdr.p_vaddr;
552  }
553  }
554  }
555  /* if non relocatable ELF, then remove fixed address from computation
556  * otherwise, all addresses are zero based and start has no effect
557  */
558  fmap->u.elf.elf_size -= fmap->u.elf.elf_start;
559 
560  switch (emfd->kind)
561  {
562  case from_handle:
563  case from_file: break;
564  case from_process:
565  if (!(fmap->u.elf.target_copy = HeapAlloc(GetProcessHeap(), 0, fmap->u.elf.elf_size)))
566  {
567  HeapFree(GetProcessHeap(), 0, fmap->u.elf.sect);
568  return FALSE;
569  }
570  if (!ReadProcessMemory(emfd->u.process.handle, emfd->u.process.load_addr, fmap->u.elf.target_copy,
571  fmap->u.elf.elf_size, NULL))
572  {
573  HeapFree(GetProcessHeap(), 0, fmap->u.elf.target_copy);
574  HeapFree(GetProcessHeap(), 0, fmap->u.elf.sect);
575  return FALSE;
576  }
577  break;
578  }
579  return TRUE;
580 }
581 
583 {
584  struct elf_map_file_data emfd;
585  emfd.kind = from_handle;
586  emfd.u.handle = handle;
587  return elf_map_file(&emfd, fmap);
588 }
589 
590 static void elf_module_remove(struct process* pcs, struct module_format* modfmt)
591 {
592  image_unmap_file(&modfmt->u.elf_info->file_map);
593  HeapFree(GetProcessHeap(), 0, modfmt);
594 }
595 
596 /******************************************************************
597  * elf_is_in_thunk_area
598  *
599  * Check whether an address lies within one of the thunk area we
600  * know of.
601  */
603  const struct elf_thunk_area* thunks)
604 {
605  unsigned i;
606 
607  if (thunks) for (i = 0; thunks[i].symname; i++)
608  {
609  if (addr >= thunks[i].rva_start && addr < thunks[i].rva_end)
610  return i;
611  }
612  return -1;
613 }
614 
615 /******************************************************************
616  * elf_hash_symtab
617  *
618  * creating an internal hash table to ease use ELF symtab information lookup
619  */
620 static void elf_hash_symtab(struct module* module, struct pool* pool,
621  struct hash_table* ht_symtab, struct image_file_map* fmap,
622  struct elf_thunk_area* thunks)
623 {
624  int i, j, nsym;
625  const char* strp;
626  const char* symname;
627  struct symt_compiland* compiland = NULL;
628  const char* ptr;
629  struct symtab_elt* ste;
630  struct image_section_map ism, ism_str;
631  const char *symtab;
632 
633  if (!elf_find_section_type(fmap, ".symtab", ELF_SHT_SYMTAB, &ism) &&
634  !elf_find_section_type(fmap, ".dynsym", ELF_SHT_DYNSYM, &ism)) return;
635  if ((symtab = image_map_section(&ism)) == IMAGE_NO_MAP) return;
636  ism_str.fmap = ism.fmap;
637  ism_str.sidx = fmap->u.elf.sect[ism.sidx].shdr.sh_link;
638  if ((strp = image_map_section(&ism_str)) == IMAGE_NO_MAP)
639  {
640  image_unmap_section(&ism);
641  return;
642  }
643 
644  nsym = image_get_map_size(&ism) /
645  (fmap->addr_size == 32 ? sizeof(struct elf_sym32) : sizeof(struct elf_sym));
646 
647  for (j = 0; thunks[j].symname; j++)
648  thunks[j].rva_start = thunks[j].rva_end = 0;
649 
650  for (i = 0; i < nsym; i++)
651  {
652  struct elf_sym sym;
653  unsigned int type;
654 
655  if (fmap->addr_size == 32)
656  {
657  struct elf_sym32 *sym32 = &((struct elf_sym32 *)symtab)[i];
658 
659  sym.st_name = sym32->st_name;
660  sym.st_value = sym32->st_value;
661  sym.st_size = sym32->st_size;
662  sym.st_info = sym32->st_info;
663  sym.st_other = sym32->st_other;
664  sym.st_shndx = sym32->st_shndx;
665  }
666  else
667  sym = ((struct elf_sym *)symtab)[i];
668 
669  type = sym.st_info & 0xf;
670 
671  /* Ignore certain types of entries which really aren't of that much
672  * interest.
673  */
675  || !sym.st_shndx)
676  {
677  continue;
678  }
679 
680  symname = strp + sym.st_name;
681 
682  /* handle some specific symtab (that we'll throw away when done) */
683  switch (type)
684  {
685  case ELF_STT_FILE:
686  if (symname)
687  compiland = symt_new_compiland(module, sym.st_value,
688  source_new(module, NULL, symname));
689  else
690  compiland = NULL;
691  continue;
692  case ELF_STT_NOTYPE:
693  /* we are only interested in wine markers inserted by winebuild */
694  for (j = 0; thunks[j].symname; j++)
695  {
696  if (!strcmp(symname, thunks[j].symname))
697  {
698  thunks[j].rva_start = sym.st_value;
699  thunks[j].rva_end = sym.st_value + sym.st_size;
700  break;
701  }
702  }
703  continue;
704  }
705 
706  /* FIXME: we don't need to handle them (GCC internals)
707  * Moreover, they screw up our symbol lookup :-/
708  */
709  if (symname[0] == '.' && symname[1] == 'L' && isdigit(symname[2]))
710  continue;
711 
712  ste = pool_alloc(pool, sizeof(*ste));
713  ste->ht_elt.name = symname;
714  /* GCC emits, in some cases, a .<digit>+ suffix.
715  * This is used for static variable inside functions, so
716  * that we can have several such variables with same name in
717  * the same compilation unit
718  * We simply ignore that suffix when present (we also get rid
719  * of it in stabs parsing)
720  */
721  ptr = symname + strlen(symname) - 1;
722  if (isdigit(*ptr))
723  {
724  while (isdigit(*ptr) && ptr >= symname) ptr--;
725  if (ptr > symname && *ptr == '.')
726  {
727  char* n = pool_alloc(pool, ptr - symname + 1);
728  memcpy(n, symname, ptr - symname + 1);
729  n[ptr - symname] = '\0';
730  ste->ht_elt.name = n;
731  }
732  }
733  ste->sym = sym;
734  ste->compiland = compiland;
735  ste->used = 0;
736  hash_table_add(ht_symtab, &ste->ht_elt);
737  }
738  /* as we added in the ht_symtab pointers to the symbols themselves,
739  * we cannot unmap yet the sections, it will be done when we're over
740  * with this ELF file
741  */
742 }
743 
744 /******************************************************************
745  * elf_lookup_symtab
746  *
747  * lookup a symbol by name in our internal hash table for the symtab
748  */
749 static const struct elf_sym *elf_lookup_symtab(const struct module* module,
750  const struct hash_table* ht_symtab,
751  const char* name, const struct symt* compiland)
752 {
753  struct symtab_elt* weak_result = NULL; /* without compiland name */
754  struct symtab_elt* result = NULL;
755  struct hash_table_iter hti;
756  struct symtab_elt* ste;
757  const char* compiland_name;
758  const char* compiland_basename;
759  const char* base;
760 
761  /* we need weak match up (at least) when symbols of same name,
762  * defined several times in different compilation units,
763  * are merged in a single one (hence a different filename for c.u.)
764  */
765  if (compiland)
766  {
767  compiland_name = source_get(module,
768  ((const struct symt_compiland*)compiland)->source);
769  compiland_basename = file_nameA(compiland_name);
770  }
771  else compiland_name = compiland_basename = NULL;
772 
773  hash_table_iter_init(ht_symtab, &hti, name);
774  while ((ste = hash_table_iter_up(&hti)))
775  {
776  if (ste->used || strcmp(ste->ht_elt.name, name)) continue;
777 
778  weak_result = ste;
779  if ((ste->compiland && !compiland_name) || (!ste->compiland && compiland_name))
780  continue;
781  if (ste->compiland && compiland_name)
782  {
783  const char* filename = source_get(module, ste->compiland->source);
784  if (strcmp(filename, compiland_name))
785  {
787  if (strcmp(base, compiland_basename)) continue;
788  }
789  }
790  if (result)
791  {
792  FIXME("Already found symbol %s (%s) in symtab %s @%08x and %s @%08x\n",
793  name, compiland_name,
794  source_get(module, result->compiland->source), (unsigned int)result->sym.st_value,
795  source_get(module, ste->compiland->source), (unsigned int)ste->sym.st_value);
796  }
797  else
798  {
799  result = ste;
800  ste->used = 1;
801  }
802  }
803  if (!result && !(result = weak_result))
804  {
805  FIXME("Couldn't find symbol %s!%s in symtab\n",
807  return NULL;
808  }
809  return &result->sym;
810 }
811 
812 static BOOL elf_is_local_symbol(unsigned int info)
813 {
814  return !(info >> 4);
815 }
816 
817 /******************************************************************
818  * elf_finish_stabs_info
819  *
820  * - get any relevant information (address & size) from the bits we got from the
821  * stabs debugging information
822  */
823 static void elf_finish_stabs_info(struct module* module, const struct hash_table* symtab)
824 {
825  struct hash_table_iter hti;
826  void* ptr;
827  struct symt_ht* sym;
828  const struct elf_sym* symp;
829  struct elf_module_info* elf_info = module->format_info[DFI_ELF]->u.elf_info;
830 
832  while ((ptr = hash_table_iter_up(&hti)))
833  {
834  sym = CONTAINING_RECORD(ptr, struct symt_ht, hash_elt);
835  switch (sym->symt.tag)
836  {
837  case SymTagFunction:
838  if (((struct symt_function*)sym)->address != elf_info->elf_addr &&
839  ((struct symt_function*)sym)->size)
840  {
841  break;
842  }
843  symp = elf_lookup_symtab(module, symtab, sym->hash_elt.name,
844  ((struct symt_function*)sym)->container);
845  if (symp)
846  {
847  if (((struct symt_function*)sym)->address != elf_info->elf_addr &&
848  ((struct symt_function*)sym)->address != elf_info->elf_addr + symp->st_value)
849  FIXME("Changing address for %p/%s!%s from %08lx to %s\n",
850  sym, debugstr_w(module->module.ModuleName), sym->hash_elt.name,
851  ((struct symt_function*)sym)->address,
852  wine_dbgstr_longlong(elf_info->elf_addr + symp->st_value));
853  if (((struct symt_function*)sym)->size && ((struct symt_function*)sym)->size != symp->st_size)
854  FIXME("Changing size for %p/%s!%s from %08lx to %08x\n",
855  sym, debugstr_w(module->module.ModuleName), sym->hash_elt.name,
856  ((struct symt_function*)sym)->size, (unsigned int)symp->st_size);
857 
858  ((struct symt_function*)sym)->address = elf_info->elf_addr + symp->st_value;
859  ((struct symt_function*)sym)->size = symp->st_size;
860  } else
861  FIXME("Couldn't find %s!%s\n",
863  break;
864  case SymTagData:
865  switch (((struct symt_data*)sym)->kind)
866  {
867  case DataIsGlobal:
868  case DataIsFileStatic:
869  if (((struct symt_data*)sym)->u.var.kind != loc_absolute ||
870  ((struct symt_data*)sym)->u.var.offset != elf_info->elf_addr)
871  break;
872  symp = elf_lookup_symtab(module, symtab, sym->hash_elt.name,
873  ((struct symt_data*)sym)->container);
874  if (symp)
875  {
876  if (((struct symt_data*)sym)->u.var.offset != elf_info->elf_addr &&
877  ((struct symt_data*)sym)->u.var.offset != elf_info->elf_addr + symp->st_value)
878  FIXME("Changing address for %p/%s!%s from %08lx to %s\n",
879  sym, debugstr_w(module->module.ModuleName), sym->hash_elt.name,
880  ((struct symt_function*)sym)->address,
881  wine_dbgstr_longlong(elf_info->elf_addr + symp->st_value));
882  ((struct symt_data*)sym)->u.var.offset = elf_info->elf_addr + symp->st_value;
883  ((struct symt_data*)sym)->kind = elf_is_local_symbol(symp->st_info) ?
885  } else
886  FIXME("Couldn't find %s!%s\n",
888  break;
889  default:;
890  }
891  break;
892  default:
893  FIXME("Unsupported tag %u\n", sym->symt.tag);
894  break;
895  }
896  }
897  /* since we may have changed some addresses & sizes, mark the module to be resorted */
899 }
900 
901 /******************************************************************
902  * elf_load_wine_thunks
903  *
904  * creating the thunk objects for a wine native DLL
905  */
906 static int elf_new_wine_thunks(struct module* module, const struct hash_table* ht_symtab,
907  const struct elf_thunk_area* thunks)
908 {
909  int j;
910  struct hash_table_iter hti;
911  struct symtab_elt* ste;
912  DWORD_PTR addr;
913  struct symt_ht* symt;
914 
915  hash_table_iter_init(ht_symtab, &hti, NULL);
916  while ((ste = hash_table_iter_up(&hti)))
917  {
918  if (ste->used) continue;
919 
920  addr = module->reloc_delta + ste->sym.st_value;
921 
922  j = elf_is_in_thunk_area(ste->sym.st_value, thunks);
923  if (j >= 0) /* thunk found */
924  {
925  symt_new_thunk(module, ste->compiland, ste->ht_elt.name, thunks[j].ordinal,
926  addr, ste->sym.st_size);
927  }
928  else
929  {
930  ULONG64 ref_addr;
931  struct location loc;
932 
934  if (symt && !symt_get_address(&symt->symt, &ref_addr))
935  ref_addr = addr;
936  if (!symt || addr != ref_addr)
937  {
938  /* creating public symbols for all the ELF symbols which haven't been
939  * used yet (ie we have no debug information on them)
940  * That's the case, for example, of the .spec.c files
941  */
942  switch (ste->sym.st_info & 0xf)
943  {
944  case ELF_STT_FUNC:
945  symt_new_function(module, ste->compiland, ste->ht_elt.name,
946  addr, ste->sym.st_size, NULL);
947  break;
948  case ELF_STT_OBJECT:
949  loc.kind = loc_absolute;
950  loc.reg = 0;
951  loc.offset = addr;
953  elf_is_local_symbol(ste->sym.st_info),
954  loc, ste->sym.st_size, NULL);
955  break;
956  default:
957  FIXME("Shouldn't happen\n");
958  break;
959  }
960  /* FIXME: this is a hack !!!
961  * we are adding new symbols, but as we're parsing a symbol table
962  * (hopefully without duplicate symbols) we delay rebuilding the sorted
963  * module table until we're done with the symbol table
964  * Otherwise, as we intertwine symbols' add and lookup, performance
965  * is rather bad
966  */
968  }
969  }
970  }
971  /* see comment above */
973  return TRUE;
974 }
975 
976 /******************************************************************
977  * elf_new_public_symbols
978  *
979  * Creates a set of public symbols from an ELF symtab
980  */
981 static int elf_new_public_symbols(struct module* module, const struct hash_table* symtab)
982 {
983  struct hash_table_iter hti;
984  struct symtab_elt* ste;
985 
986  if (dbghelp_options & SYMOPT_NO_PUBLICS) return TRUE;
987 
988  /* FIXME: we're missing the ELF entry point here */
989 
990  hash_table_iter_init(symtab, &hti, NULL);
991  while ((ste = hash_table_iter_up(&hti)))
992  {
993  symt_new_public(module, ste->compiland, ste->ht_elt.name,
994  FALSE,
995  module->reloc_delta + ste->sym.st_value,
996  ste->sym.st_size);
997  }
998  return TRUE;
999 }
1000 
1001 /******************************************************************
1002  * elf_load_debug_info_from_map
1003  *
1004  * Loads the symbolic information from ELF module which mapping is described
1005  * in fmap
1006  * the module has been loaded at 'load_offset' address, so symbols' address
1007  * relocation is performed.
1008  * CRC is checked if fmap->with_crc is TRUE
1009  * returns
1010  * 0 if the file doesn't contain symbolic info (or this info cannot be
1011  * read or parsed)
1012  * 1 on success
1013  */
1015  struct image_file_map* fmap,
1016  struct pool* pool,
1017  struct hash_table* ht_symtab)
1018 {
1019  BOOL ret = FALSE, lret;
1020  struct elf_thunk_area thunks[] =
1021  {
1022  {"__wine_spec_import_thunks", THUNK_ORDINAL_NOTYPE, 0, 0}, /* inter DLL calls */
1023  {"__wine_spec_delayed_import_loaders", THUNK_ORDINAL_LOAD, 0, 0}, /* delayed inter DLL calls */
1024  {"__wine_spec_delayed_import_thunks", THUNK_ORDINAL_LOAD, 0, 0}, /* delayed inter DLL calls */
1025  {"__wine_delay_load", THUNK_ORDINAL_LOAD, 0, 0}, /* delayed inter DLL calls */
1026  {"__wine_spec_thunk_text_16", -16, 0, 0}, /* 16 => 32 thunks */
1027  {"__wine_spec_thunk_text_32", -32, 0, 0}, /* 32 => 16 thunks */
1028  {NULL, 0, 0, 0}
1029  };
1030 
1032 
1033  /* create a hash table for the symtab */
1034  elf_hash_symtab(module, pool, ht_symtab, fmap, thunks);
1035 
1037  {
1038  struct image_section_map stab_sect, stabstr_sect;
1039 
1040  /* check if we need an alternate file (from debuglink or build-id) */
1042 
1043  if (image_find_section(fmap, ".stab", &stab_sect) &&
1044  image_find_section(fmap, ".stabstr", &stabstr_sect))
1045  {
1046  const char* stab;
1047  const char* stabstr;
1048 
1049  stab = image_map_section(&stab_sect);
1050  stabstr = image_map_section(&stabstr_sect);
1051  if (stab != IMAGE_NO_MAP && stabstr != IMAGE_NO_MAP)
1052  {
1053  /* OK, now just parse all of the stabs. */
1054  lret = stabs_parse(module, module->format_info[DFI_ELF]->u.elf_info->elf_addr,
1055  stab, image_get_map_size(&stab_sect) / sizeof(struct stab_nlist), sizeof(struct stab_nlist),
1056  stabstr, image_get_map_size(&stabstr_sect),
1057  NULL, NULL);
1058  if (lret)
1059  /* and fill in the missing information for stabs */
1060  elf_finish_stabs_info(module, ht_symtab);
1061  else
1062  WARN("Couldn't correctly read stabs\n");
1063  ret = ret || lret;
1064  }
1065  image_unmap_section(&stab_sect);
1066  image_unmap_section(&stabstr_sect);
1067  }
1068  lret = dwarf2_parse(module, module->reloc_delta, thunks, fmap);
1069  ret = ret || lret;
1070  }
1073  {
1074  /* add the thunks for native libraries */
1076  elf_new_wine_thunks(module, ht_symtab, thunks);
1077  }
1078  /* add all the public symbols from symtab */
1079  if (elf_new_public_symbols(module, ht_symtab) && !ret) ret = TRUE;
1080 
1081  return ret;
1082 }
1083 
1084 /******************************************************************
1085  * elf_load_debug_info
1086  *
1087  * Loads ELF debugging information from the module image file.
1088  */
1090 {
1091  BOOL ret = TRUE;
1092  struct pool pool;
1093  struct hash_table ht_symtab;
1094  struct module_format* modfmt;
1095 
1096  if (module->type != DMT_ELF || !(modfmt = module->format_info[DFI_ELF]) || !modfmt->u.elf_info)
1097  {
1098  ERR("Bad elf module '%s'\n", debugstr_w(module->module.LoadedImageName));
1099  return FALSE;
1100  }
1101 
1102  pool_init(&pool, 65536);
1103  hash_table_init(&pool, &ht_symtab, 256);
1104 
1105  ret = elf_load_debug_info_from_map(module, &modfmt->u.elf_info->file_map, &pool, &ht_symtab);
1106 
1107  pool_destroy(&pool);
1108  return ret;
1109 }
1110 
1111 /******************************************************************
1112  * elf_fetch_file_info
1113  *
1114  * Gathers some more information for an ELF module from a given file
1115  */
1117 {
1118  struct image_file_map fmap;
1119 
1120  struct elf_map_file_data emfd;
1121 
1122  emfd.kind = from_file;
1123  emfd.u.file.filename = name;
1124  if (!elf_map_file(&emfd, &fmap)) return FALSE;
1125  if (base) *base = fmap.u.elf.elf_start;
1126  *size = fmap.u.elf.elf_size;
1127  *checksum = calc_crc32(fmap.u.elf.handle);
1128  image_unmap_file(&fmap);
1129  return TRUE;
1130 }
1131 
1133  struct image_file_map* fmap, ULONG_PTR load_offset,
1134  ULONG_PTR dyn_addr, struct elf_info* elf_info)
1135 {
1136  BOOL ret = FALSE;
1137 
1139  {
1140  struct image_section_map ism;
1141 
1142  if (elf_find_section_type(fmap, ".dynamic", ELF_SHT_DYNAMIC, &ism))
1143  {
1144  char* ptr = (char*)(ULONG_PTR)fmap->u.elf.sect[ism.sidx].shdr.sh_addr;
1145  ULONG_PTR len;
1146 
1147  if (load_offset) ptr += load_offset - fmap->u.elf.elf_start;
1148 
1149  if (fmap->addr_size == 32)
1150  {
1151  struct
1152  {
1153  INT32 d_tag; /* Dynamic entry type */
1154  UINT32 d_val; /* Integer or address value */
1155  } dyn;
1156 
1157  do
1158  {
1159  if (!ReadProcessMemory(pcs->handle, ptr, &dyn, sizeof(dyn), &len) ||
1160  len != sizeof(dyn))
1161  return ret;
1162  if (dyn.d_tag == ELF_DT_DEBUG)
1163  {
1164  elf_info->dbg_hdr_addr = dyn.d_val;
1165  if (load_offset == 0 && dyn_addr == 0) /* likely the case */
1166  /* Assume this module (the Wine loader) has been
1167  * loaded at its preferred address */
1168  dyn_addr = ism.fmap->u.elf.sect[ism.sidx].shdr.sh_addr;
1169  break;
1170  }
1171  ptr += sizeof(dyn);
1172  } while (dyn.d_tag);
1173  if (!dyn.d_tag) return ret;
1174  }
1175  else
1176  {
1177  struct
1178  {
1179  INT64 d_tag; /* Dynamic entry type */
1180  UINT64 d_val; /* Integer or address value */
1181  } dyn;
1182 
1183  do
1184  {
1185  if (!ReadProcessMemory(pcs->handle, ptr, &dyn, sizeof(dyn), &len) ||
1186  len != sizeof(dyn))
1187  return ret;
1188  if (dyn.d_tag == ELF_DT_DEBUG)
1189  {
1190  elf_info->dbg_hdr_addr = dyn.d_val;
1191  if (load_offset == 0 && dyn_addr == 0) /* likely the case */
1192  /* Assume this module (the Wine loader) has been
1193  * loaded at its preferred address */
1194  dyn_addr = ism.fmap->u.elf.sect[ism.sidx].shdr.sh_addr;
1195  break;
1196  }
1197  ptr += sizeof(dyn);
1198  } while (dyn.d_tag);
1199  if (!dyn.d_tag) return ret;
1200  }
1201  }
1202  elf_end_find(fmap);
1203  }
1204 
1206  {
1208  struct module_format* modfmt;
1209  struct image_section_map ism;
1210  ULONG_PTR modbase = load_offset;
1211 
1212  if (elf_find_section_type(fmap, ".dynamic", ELF_SHT_DYNAMIC, &ism))
1213  {
1214  ULONG_PTR rva_dyn = elf_get_map_rva(&ism);
1215 
1216  TRACE("For module %s, got ELF (start=%lx dyn=%lx), link_map (start=%lx dyn=%lx)\n",
1217  debugstr_w(filename), (ULONG_PTR)fmap->u.elf.elf_start, rva_dyn,
1218  load_offset, dyn_addr);
1219  if (dyn_addr && load_offset + rva_dyn != dyn_addr)
1220  {
1221  WARN("\thave to relocate: %lx\n", dyn_addr - rva_dyn);
1222  modbase = dyn_addr - rva_dyn;
1223  }
1224  } else WARN("For module %s, no .dynamic section\n", debugstr_w(filename));
1225  elf_end_find(fmap);
1226 
1227  modfmt = HeapAlloc(GetProcessHeap(), 0,
1228  sizeof(struct module_format) + sizeof(struct elf_module_info));
1229  if (!modfmt) return FALSE;
1230  elf_info->module = module_new(pcs, filename, DMT_ELF, FALSE, modbase,
1231  fmap->u.elf.elf_size, 0, calc_crc32(fmap->u.elf.handle));
1232  if (!elf_info->module)
1233  {
1234  HeapFree(GetProcessHeap(), 0, modfmt);
1235  return FALSE;
1236  }
1237  elf_info->module->reloc_delta = elf_info->module->module.BaseOfImage - fmap->u.elf.elf_start;
1238  elf_module_info = (void*)(modfmt + 1);
1239  elf_info->module->format_info[DFI_ELF] = modfmt;
1240  modfmt->module = elf_info->module;
1241  modfmt->remove = elf_module_remove;
1242  modfmt->loc_compute = NULL;
1243  modfmt->u.elf_info = elf_module_info;
1244 
1245  elf_module_info->elf_addr = load_offset;
1246 
1250  {
1251  elf_info->module->module.SymType = SymDeferred;
1252  ret = TRUE;
1253  }
1254  else ret = elf_load_debug_info(pcs, elf_info->module);
1255 
1258  } else ret = TRUE;
1259 
1260  if (elf_info->flags & ELF_INFO_NAME)
1261  {
1262  WCHAR* ptr;
1263  ptr = HeapAlloc(GetProcessHeap(), 0, (lstrlenW(filename) + 1) * sizeof(WCHAR));
1264  if (ptr)
1265  {
1266  lstrcpyW(ptr, filename);
1268  }
1269  else ret = FALSE;
1270  }
1271 
1272  return ret;
1273 }
1274 
1275 /******************************************************************
1276  * elf_load_file
1277  *
1278  * Loads the information for ELF module stored in 'filename'
1279  * the module has been loaded at 'load_offset' address
1280  * returns
1281  * -1 if the file cannot be found/opened
1282  * 0 if the file doesn't contain symbolic info (or this info cannot be
1283  * read or parsed)
1284  * 1 on success
1285  */
1286 static BOOL elf_load_file(struct process* pcs, const WCHAR* filename,
1287  ULONG_PTR load_offset, ULONG_PTR dyn_addr,
1288  struct elf_info* elf_info)
1289 {
1290  BOOL ret = FALSE;
1291  struct image_file_map fmap;
1292  struct elf_map_file_data emfd;
1293 
1294  TRACE("Processing elf file '%s' at %08lx\n", debugstr_w(filename), load_offset);
1295 
1296  emfd.kind = from_file;
1297  emfd.u.file.filename = filename;
1298  if (!elf_map_file(&emfd, &fmap)) return ret;
1299 
1300  /* Next, we need to find a few of the internal ELF headers within
1301  * this thing. We need the main executable header, and the section
1302  * table.
1303  */
1304  if (!fmap.u.elf.elf_start && !load_offset)
1305  ERR("Relocatable ELF %s, but no load address. Loading at 0x0000000\n",
1306  debugstr_w(filename));
1307 
1308  ret = elf_load_file_from_fmap(pcs, filename, &fmap, load_offset, dyn_addr, elf_info);
1309 
1310  image_unmap_file(&fmap);
1311 
1312  return ret;
1313 }
1314 
1316 {
1317  struct process *process;
1321 };
1322 
1324 {
1326  return elf_load_file(load_file->process, filename, load_file->load_offset, load_file->dyn_addr, load_file->elf_info);
1327 }
1328 
1329 /******************************************************************
1330  * elf_search_auxv
1331  *
1332  * locate some a value from the debuggee auxiliary vector
1333  */
1334 static BOOL elf_search_auxv(const struct process* pcs, unsigned type, ULONG_PTR* val)
1335 {
1336  char buffer[sizeof(SYMBOL_INFO) + MAX_SYM_NAME];
1338  BYTE* addr;
1339  BYTE* str;
1340  BYTE* str_max;
1341 
1342  si->SizeOfStruct = sizeof(*si);
1343  si->MaxNameLen = MAX_SYM_NAME;
1344  if (!SymFromName(pcs->handle, "libwine.so.1!__wine_main_environ", si) ||
1345  !(addr = (void*)(DWORD_PTR)si->Address) ||
1346  !ReadProcessMemory(pcs->handle, addr, &addr, sizeof(addr), NULL) ||
1347  !addr)
1348  {
1349  FIXME("can't find symbol in module\n");
1350  return FALSE;
1351  }
1352  /* walk through envp[] */
1353  /* envp[] strings are located after the auxiliary vector, so protect the walk */
1354  str_max = (void*)(DWORD_PTR)~0L;
1355  while (ReadProcessMemory(pcs->handle, addr, &str, sizeof(str), NULL) &&
1356  (addr = (void*)((DWORD_PTR)addr + sizeof(str))) != NULL && str != NULL)
1357  str_max = min(str_max, str);
1358 
1359  /* Walk through the end of envp[] array.
1360  * Actually, there can be several NULLs at the end of envp[]. This happens when an env variable is
1361  * deleted, the last entry is replaced by an extra NULL.
1362  */
1363  while (addr < str_max && ReadProcessMemory(pcs->handle, addr, &str, sizeof(str), NULL) && str == NULL)
1364  addr = (void*)((DWORD_PTR)addr + sizeof(str));
1365 
1366  if (pcs->is_64bit)
1367  {
1368  struct
1369  {
1370  UINT64 a_type;
1371  UINT64 a_val;
1372  } auxv;
1373 
1374  while (ReadProcessMemory(pcs->handle, addr, &auxv, sizeof(auxv), NULL) && auxv.a_type)
1375  {
1376  if (auxv.a_type == type)
1377  {
1378  *val = auxv.a_val;
1379  return TRUE;
1380  }
1381  addr += sizeof(auxv);
1382  }
1383  }
1384  else
1385  {
1386  struct
1387  {
1388  UINT32 a_type;
1389  UINT32 a_val;
1390  } auxv;
1391 
1392  while (ReadProcessMemory(pcs->handle, addr, &auxv, sizeof(auxv), NULL) && auxv.a_type)
1393  {
1394  if (auxv.a_type == type)
1395  {
1396  *val = auxv.a_val;
1397  return TRUE;
1398  }
1399  addr += sizeof(auxv);
1400  }
1401  }
1402 
1403  return FALSE;
1404 }
1405 
1406 /******************************************************************
1407  * elf_search_and_load_file
1408  *
1409  * lookup a file in standard ELF locations, and if found, load it
1410  */
1413  struct elf_info* elf_info)
1414 {
1415  BOOL ret = FALSE;
1416  struct module* module;
1417  static const WCHAR S_libstdcPPW[] = {'l','i','b','s','t','d','c','+','+','\0'};
1418 
1419  if (filename == NULL || *filename == '\0') return FALSE;
1421  {
1422  elf_info->module = module;
1423  elf_info->module->format_info[DFI_ELF]->u.elf_info->elf_mark = 1;
1424  return module->module.SymType;
1425  }
1426 
1427  if (wcsstr(filename, S_libstdcPPW)) return FALSE; /* We know we can't do it */
1428  ret = elf_load_file(pcs, filename, load_offset, dyn_addr, elf_info);
1429  /* if relative pathname, try some absolute base dirs */
1430  if (!ret && filename == file_name(filename))
1431  {
1432  struct elf_load_file_params load_elf;
1433  load_elf.process = pcs;
1434  load_elf.load_offset = load_offset;
1435  load_elf.dyn_addr = dyn_addr;
1436  load_elf.elf_info = elf_info;
1437 
1438  ret = search_unix_path(filename, process_getenv(pcs, L"LD_LIBRARY_PATH"), elf_load_file_cb, &load_elf)
1439  || search_unix_path(filename, BINDIR, elf_load_file_cb, &load_elf)
1440  || search_dll_path(pcs, filename, elf_load_file_cb, &load_elf);
1441  }
1442 
1443  return ret;
1444 }
1445 
1447  ULONG_PTR dyn_addr, BOOL is_system, void* user);
1448 
1449 /******************************************************************
1450  * elf_enum_modules_internal
1451  *
1452  * Enumerate ELF modules from a running process
1453  */
1454 static BOOL elf_enum_modules_internal(const struct process* pcs,
1455  const WCHAR* main_name,
1456  enum_elf_modules_cb cb, void* user)
1457 {
1458  WCHAR bufstrW[MAX_PATH];
1459  char bufstr[256];
1460  ULONG_PTR lm_addr;
1461 
1462  if (pcs->is_64bit)
1463  {
1464  struct
1465  {
1466  UINT32 r_version;
1467  UINT64 r_map;
1468  UINT64 r_brk;
1469  UINT32 r_state;
1470  UINT64 r_ldbase;
1471  } dbg_hdr;
1472  struct
1473  {
1474  UINT64 l_addr;
1475  UINT64 l_name;
1476  UINT64 l_ld;
1477  UINT64 l_next, l_prev;
1478  } lm;
1479 
1480  if (!pcs->dbg_hdr_addr || !read_process_memory(pcs, pcs->dbg_hdr_addr, &dbg_hdr, sizeof(dbg_hdr)))
1481  return FALSE;
1482 
1483  /* Now walk the linked list. In all known ELF implementations,
1484  * the dynamic loader maintains this linked list for us. In some
1485  * cases the first entry doesn't appear with a name, in other cases it
1486  * does.
1487  */
1488  for (lm_addr = dbg_hdr.r_map; lm_addr; lm_addr = lm.l_next)
1489  {
1490  if (!read_process_memory(pcs, lm_addr, &lm, sizeof(lm)))
1491  return FALSE;
1492 
1493  if (lm.l_prev && /* skip first entry, normally debuggee itself */
1494  lm.l_name && read_process_memory(pcs, lm.l_name, bufstr, sizeof(bufstr)))
1495  {
1496  bufstr[sizeof(bufstr) - 1] = '\0';
1497  MultiByteToWideChar(CP_UNIXCP, 0, bufstr, -1, bufstrW, ARRAY_SIZE(bufstrW));
1498  if (main_name && !bufstrW[0]) lstrcpyW(bufstrW, main_name);
1499  if (!cb(bufstrW, (ULONG_PTR)lm.l_addr, (ULONG_PTR)lm.l_ld, FALSE, user))
1500  break;
1501  }
1502  }
1503  }
1504  else
1505  {
1506  struct
1507  {
1508  UINT32 r_version;
1509  UINT32 r_map;
1510  UINT32 r_brk;
1511  UINT32 r_state;
1512  UINT32 r_ldbase;
1513  } dbg_hdr;
1514  struct
1515  {
1516  UINT32 l_addr;
1517  UINT32 l_name;
1518  UINT32 l_ld;
1519  UINT32 l_next, l_prev;
1520  } lm;
1521 
1522  if (!pcs->dbg_hdr_addr || !read_process_memory(pcs, pcs->dbg_hdr_addr, &dbg_hdr, sizeof(dbg_hdr)))
1523  return FALSE;
1524 
1525  /* Now walk the linked list. In all known ELF implementations,
1526  * the dynamic loader maintains this linked list for us. In some
1527  * cases the first entry doesn't appear with a name, in other cases it
1528  * does.
1529  */
1530  for (lm_addr = dbg_hdr.r_map; lm_addr; lm_addr = lm.l_next)
1531  {
1532  if (!read_process_memory(pcs, lm_addr, &lm, sizeof(lm)))
1533  return FALSE;
1534 
1535  if (lm.l_prev && /* skip first entry, normally debuggee itself */
1536  lm.l_name && read_process_memory(pcs, lm.l_name, bufstr, sizeof(bufstr)))
1537  {
1538  bufstr[sizeof(bufstr) - 1] = '\0';
1539  MultiByteToWideChar(CP_UNIXCP, 0, bufstr, -1, bufstrW, ARRAY_SIZE(bufstrW));
1540  if (main_name && !bufstrW[0]) lstrcpyW(bufstrW, main_name);
1541  if (!cb(bufstrW, (ULONG_PTR)lm.l_addr, (ULONG_PTR)lm.l_ld, FALSE, user))
1542  break;
1543  }
1544  }
1545  }
1546 
1547  if (!lm_addr)
1548  {
1549  ULONG_PTR ehdr_addr;
1550 
1551  if (elf_search_auxv(pcs, ELF_AT_SYSINFO_EHDR, &ehdr_addr))
1552  {
1553  static const WCHAR vdsoW[] = {'[','v','d','s','o',']','.','s','o',0};
1554  cb(vdsoW, ehdr_addr, 0, TRUE, user);
1555  }
1556  }
1557  return TRUE;
1558 }
1559 
1561 {
1563  void* user;
1564 };
1565 
1567  ULONG_PTR dyn_addr, BOOL is_system, void* user)
1568 {
1569  struct elf_enum_user* eeu = user;
1570  return eeu->cb(name, load_addr, eeu->user);
1571 }
1572 
1573 /******************************************************************
1574  * elf_enum_modules
1575  *
1576  * Enumerates the ELF loaded modules from a running target (hProc)
1577  * This function doesn't require that someone has called SymInitialize
1578  * on this very process.
1579  */
1581 {
1582  struct elf_info elf_info;
1583  BOOL ret;
1584  struct elf_enum_user eeu;
1585 
1588  eeu.cb = cb;
1589  eeu.user = user;
1592  return ret;
1593 }
1594 
1595 struct elf_load
1596 {
1597  struct process* pcs;
1599  const WCHAR* name;
1601 };
1602 
1603 /******************************************************************
1604  * elf_load_cb
1605  *
1606  * Callback for elf_load_module, used to walk the list of loaded
1607  * modules.
1608  */
1610  ULONG_PTR dyn_addr, BOOL is_system, void* user)
1611 {
1612  struct elf_load* el = user;
1613  BOOL ret = TRUE;
1614  const WCHAR* p;
1615 
1616  if (is_system) /* virtual ELF module, created by system. handle it from memory */
1617  {
1618  struct module* module;
1619  struct elf_map_file_data emfd;
1620  struct image_file_map fmap;
1621 
1622  if ((module = module_is_already_loaded(el->pcs, name)))
1623  {
1624  el->elf_info.module = module;
1625  el->elf_info.module->format_info[DFI_ELF]->u.elf_info->elf_mark = 1;
1626  return module->module.SymType;
1627  }
1628 
1629  emfd.kind = from_process;
1630  emfd.u.process.handle = el->pcs->handle;
1631  emfd.u.process.load_addr = (void*)load_addr;
1632 
1633  if (elf_map_file(&emfd, &fmap))
1634  el->ret = elf_load_file_from_fmap(el->pcs, name, &fmap, load_addr, 0, &el->elf_info);
1635  return TRUE;
1636  }
1637  if (el->name)
1638  {
1639  /* memcmp is needed for matches when bufstr contains also version information
1640  * el->name: libc.so, name: libc.so.6.0
1641  */
1642  p = file_name(name);
1643  }
1644 
1645  if (!el->name || !memcmp(p, el->name, lstrlenW(el->name) * sizeof(WCHAR)))
1646  {
1647  el->ret = elf_search_and_load_file(el->pcs, name, load_addr, dyn_addr, &el->elf_info);
1648  if (el->name) ret = FALSE;
1649  }
1650 
1651  return ret;
1652 }
1653 
1654 /******************************************************************
1655  * elf_load_module
1656  *
1657  * loads an ELF module and stores it in process' module list
1658  * Also, find module real name and load address from
1659  * the real loaded modules list in pcs address space
1660  */
1661 static struct module* elf_load_module(struct process* pcs, const WCHAR* name, ULONG_PTR addr)
1662 {
1663  struct elf_load el;
1664 
1665  TRACE("(%p %s %08lx)\n", pcs, debugstr_w(name), addr);
1666 
1667  el.elf_info.flags = ELF_INFO_MODULE;
1668  el.ret = FALSE;
1669 
1670  if (pcs->dbg_hdr_addr) /* we're debugging a life target */
1671  {
1672  el.pcs = pcs;
1673  /* do only the lookup from the filename, not the path (as we lookup module
1674  * name in the process' loaded module list)
1675  */
1676  el.name = file_name(name);
1677  el.ret = FALSE;
1678 
1680  return NULL;
1681  }
1682  else if (addr)
1683  {
1684  el.name = name;
1685  el.ret = elf_search_and_load_file(pcs, el.name, addr, 0, &el.elf_info);
1686  }
1687  if (!el.ret) return NULL;
1688  assert(el.elf_info.module);
1689  return el.elf_info.module;
1690 }
1691 
1692 /******************************************************************
1693  * elf_synchronize_module_list
1694  *
1695  * this function rescans the debuggee module's list and synchronizes it with
1696  * the one from 'pcs', i.e.:
1697  * - if a module is in debuggee and not in pcs, it's loaded into pcs
1698  * - if a module is in pcs and not in debuggee, it's unloaded from pcs
1699  */
1701 {
1702  struct module* module;
1703  struct elf_load el;
1704 
1705  for (module = pcs->lmodules; module; module = module->next)
1706  {
1707  if (module->type == DMT_ELF && !module->is_virtual)
1708  module->format_info[DFI_ELF]->u.elf_info->elf_mark = 0;
1709  }
1710 
1711  el.pcs = pcs;
1712  el.elf_info.flags = ELF_INFO_MODULE;
1713  el.ret = FALSE;
1714  el.name = NULL; /* fetch all modules */
1715 
1717  return FALSE;
1718 
1719  module = pcs->lmodules;
1720  while (module)
1721  {
1722  if (module->type == DMT_ELF && !module->is_virtual)
1723  {
1724  struct elf_module_info* elf_info = module->format_info[DFI_ELF]->u.elf_info;
1725 
1726  if (!elf_info->elf_mark && !elf_info->elf_loader)
1727  {
1728  module_remove(pcs, module);
1729  /* restart all over */
1730  module = pcs->lmodules;
1731  continue;
1732  }
1733  }
1734  module = module->next;
1735  }
1736  return TRUE;
1737 }
1738 
1739 static const struct loader_ops elf_loader_ops =
1740 {
1746 };
1747 
1748 /******************************************************************
1749  * elf_read_wine_loader_dbg_info
1750  *
1751  * Try to find a decent wine executable which could have loaded the debuggee
1752  */
1754 {
1755  struct elf_info elf_info;
1756  WCHAR *loader;
1757  BOOL ret;
1758 
1760  loader = get_wine_loader_name(pcs);
1761  ret = elf_search_and_load_file(pcs, loader, addr, 0, &elf_info);
1762  heap_free(loader);
1763  if (!ret || !elf_info.dbg_hdr_addr) return FALSE;
1764 
1765  TRACE("Found ELF debug header %#lx\n", elf_info.dbg_hdr_addr);
1766  elf_info.module->format_info[DFI_ELF]->u.elf_info->elf_loader = 1;
1769  pcs->loader = &elf_loader_ops;
1770  return TRUE;
1771 }
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)
const char * symname
Definition: elf_module.c:77
BOOL symt_get_address(const struct symt *type, ULONG64 *addr) DECLSPEC_HIDDEN
Definition: type.c:119
BOOL WINAPI SetFilePointerEx(HANDLE hFile, LARGE_INTEGER liDistanceToMove, PLARGE_INTEGER lpNewFilePointer, DWORD dwMoveMethod)
Definition: fileinfo.c:177
unsigned addr_size
struct symt_function * symt_new_function(struct module *module, struct symt_compiland *parent, const char *name, ULONG_PTR addr, ULONG_PTR size, struct symt *type) DECLSPEC_HIDDEN
Definition: symbol.c:293
void module_set_module(struct module *module, const WCHAR *name) DECLSPEC_HIDDEN
Definition: module.c:142
enum elf_map_file_data::@372 kind
enum module_type modtype
union image_file_map::@376 u
namespace GUID const ADDRINFOEXW ADDRINFOEXW struct timeval OVERLAPPED LPLOOKUPSERVICE_COMPLETION_ROUTINE HANDLE * handle
Definition: sock.c:82
DWORD_PTR dbg_hdr_addr
Definition: elf_module.c:42
static int elf_new_public_symbols(struct module *module, const struct hash_table *symtab)
Definition: elf_module.c:981
#define CloseHandle
Definition: compat.h:598
HMODULE module
Definition: main.cpp:47
struct process * process
Definition: elf_module.c:1317
int memcmp(void *Buffer1, void *Buffer2, ACPI_SIZE Count)
Definition: utclib.c:112
#define MapViewOfFile
Definition: compat.h:604
WCHAR ModuleName[32]
Definition: compat.h:935
ActualNumberDriverObjects * sizeof(PDRIVER_OBJECT)) PDRIVER_OBJECT *DriverObjectList
DWORD dwAllocationGranularity
Definition: winbase.h:1145
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
#define TRUE
Definition: types.h:120
_CONST_RETURN wchar_t *__cdecl wcsstr(_In_z_ const wchar_t *_Str, _In_z_ const wchar_t *_SubStr)
#define ELF_PT_LOAD
Definition: elf_module.c:118
static BOOL elf_fetch_file_info(struct process *process, const WCHAR *name, ULONG_PTR load_addr, DWORD_PTR *base, DWORD *size, DWORD *checksum)
Definition: elf_module.c:1116
int elf_is_in_thunk_area(ULONG_PTR addr, const struct elf_thunk_area *thunks)
Definition: elf_module.c:602
struct hash_table ht_symbols
BOOL image_check_alternate(struct image_file_map *fmap, const struct module *module) DECLSPEC_HIDDEN
Definition: module.c:697
#define WARN(fmt,...)
Definition: debug.h:112
ULONG_PTR rva_start
Definition: elf_module.c:79
struct hash_table_elt ht_elt
Definition: elf_module.c:69
struct image_file_map * fmap
BOOL search_dll_path(const struct process *process, const WCHAR *name, BOOL(*match)(void *, HANDLE, const WCHAR *), void *param) DECLSPEC_HIDDEN
Definition: path.c:695
GLdouble n
Definition: glext.h:7729
GLuint GLuint GLsizei GLenum type
Definition: gl.h:1545
#define INVALID_HANDLE_VALUE
Definition: compat.h:590
#define assert(x)
Definition: debug.h:53
DWORD WINAPI GetLastError(VOID)
Definition: except.c:1044
static void elf_unmap_file(struct image_file_map *fmap)
Definition: elf_module.c:282
BOOL ret
Definition: elf_module.c:1600
GLuint buffer
Definition: glext.h:5915
const WCHAR * filename
Definition: elf_module.c:324
#define ReadProcessMemory(a, b, c, d, e)
Definition: compat.h:617
static BOOL elf_load_file_cb(void *param, HANDLE handle, const WCHAR *filename)
Definition: elf_module.c:1323
const char * source_get(const struct module *module, unsigned idx) DECLSPEC_HIDDEN
Definition: source.c:130
struct elf_sym sym
Definition: elf_module.c:70
#define ELF_DT_DEBUG
Definition: elf_module.c:120
#define FILE_BEGIN
Definition: compat.h:620
#define ELF_SHT_DYNAMIC
Definition: elf_module.c:98
const char * filename
Definition: ioapi.h:135
#define lstrlenW
Definition: compat.h:609
#define BOOL
Definition: nt_native.h:43
int load_addr
Definition: mkisofs.c:104
UINT16 st_shndx
Definition: elf_module.c:62
#define FILE_SHARE_READ
Definition: compat.h:136
#define SYMOPT_DEFERRED_LOADS
Definition: compat.h:848
enum module_type type
#define ELF_SHT_NOBITS
Definition: elf_module.c:100
uint32_t ULONG_PTR
Definition: typedefs.h:65
#define IMAGE_NO_MAP
Definition: image_private.h:24
static BOOL elf_is_local_symbol(unsigned int info)
Definition: elf_module.c:812
ULONG_PTR elf_addr
Definition: elf_module.c:85
static int elf_new_wine_thunks(struct module *module, const struct hash_table *ht_symtab, const struct elf_thunk_area *thunks)
Definition: elf_module.c:906
#define ELF_INFO_DEBUG_HEADER
Definition: elf_module.c:33
void * pool_alloc(struct pool *a, size_t len) DECLSPEC_HIDDEN
Definition: storage.c:89
static unsigned elf_get_map_size(const struct image_section_map *ism)
Definition: elf_module.c:270
UINT8 st_other
Definition: elf_module.c:53
WCHAR LoadedImageName[256]
Definition: compat.h:937
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
union elf_map_file_data::@373 u
static void elf_hash_symtab(struct module *module, struct pool *pool, struct hash_table *ht_symtab, struct image_file_map *fmap, struct elf_thunk_area *thunks)
Definition: elf_module.c:620
static BOOL elf_load_file_from_fmap(struct process *pcs, const WCHAR *filename, struct image_file_map *fmap, ULONG_PTR load_offset, ULONG_PTR dyn_addr, struct elf_info *elf_info)
Definition: elf_module.c:1132
#define FALSE
Definition: types.h:117
struct module * lmodules
unsigned int UINT32
static BOOL elf_load_cb(const WCHAR *name, ULONG_PTR load_addr, ULONG_PTR dyn_addr, BOOL is_system, void *user)
Definition: elf_module.c:1609
ULONG_PTR dbg_hdr_addr
unsigned short elf_mark
Definition: elf_module.c:86
unsigned int BOOL
Definition: ntddk_ex.h:94
GLuint base
Definition: 3dtext.c:35
static BOOL elf_load_debug_info(struct process *process, struct module *module)
Definition: elf_module.c:1089
int sortlist_valid
static BOOL elf_load_file(struct process *pcs, const WCHAR *filename, ULONG_PTR load_offset, ULONG_PTR dyn_addr, struct elf_info *elf_info)
Definition: elf_module.c:1286
const char * file_nameA(const char *str) DECLSPEC_HIDDEN
Definition: path.c:37
#define debugstr_w
Definition: kernel32.h:32
#define FIXME(fmt,...)
Definition: debug.h:111
static PVOID ptr
Definition: dispmode.c:27
REFIID LPVOID DWORD_PTR dw
Definition: atlbase.h:40
#define ELF_STT_NOTYPE
Definition: elf_module.c:112
void hash_table_iter_init(const struct hash_table *ht, struct hash_table_iter *hti, const char *name) DECLSPEC_HIDDEN
Definition: storage.c:405
static const struct image_file_map_ops elf_file_map_ops
Definition: elf_module.c:298
const WCHAR * str
static BOOL elf_enum_modules(struct process *process, enum_modules_cb cb, void *user)
Definition: elf_module.c:1580
UINT16 st_shndx
Definition: elf_module.c:54
smooth NULL
Definition: ftsmooth.c:416
struct symt symt
UINT32 st_name
Definition: elf_module.c:59
unsigned flags
Definition: elf_module.c:41
ULONG_PTR offset
#define FILE_MAP_READ
Definition: compat.h:635
static void elf_unmap_section(struct image_section_map *ism)
Definition: elf_module.c:226
struct elf_map_file_data::@373::@374 file
#define isdigit(c)
Definition: acclib.h:68
static BOOL elf_enum_modules_internal(const struct process *pcs, const WCHAR *main_name, enum_elf_modules_cb cb, void *user)
Definition: elf_module.c:1454
#define OPEN_EXISTING
Definition: compat.h:634
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
UINT32 st_value
Definition: elf_module.c:50
GLuint GLfloat * val
Definition: glext.h:7180
static BOOL elf_map_file(struct elf_map_file_data *emfd, struct image_file_map *fmap)
Definition: elf_module.c:406
struct module * module_is_already_loaded(const struct process *pcs, const WCHAR *imgname) DECLSPEC_HIDDEN
Definition: module.c:303
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
static BOOL elf_find_section(struct image_file_map *_fmap, const char *name, struct image_section_map *ism)
Definition: elf_module.c:169
THUNK_ORDINAL ordinal
Definition: elf_module.c:78
#define TRACE(s)
Definition: solgame.cpp:4
const WCHAR * process_getenv(const struct process *process, const WCHAR *name)
Definition: dbghelp.c:285
struct image_file_map * alternate
struct elf_module_info * elf_info
GLsizeiptr size
Definition: glext.h:5919
DWORD64 reloc_delta
#define GetProcessHeap()
Definition: compat.h:595
PVOID WINAPI HeapAlloc(HANDLE, DWORD, SIZE_T)
#define CP_UNIXCP
Definition: compat.h:79
static const char * elf_map_section(struct image_section_map *ism)
Definition: elf_module.c:129
void(* loc_compute)(struct process *pcs, const struct module_format *modfmt, const struct symt_function *func, struct location *loc)
__wchar_t WCHAR
Definition: xmlstorage.h:180
BOOL dwarf2_parse(struct module *module, ULONG_PTR load_offset, const struct elf_thunk_area *thunks, struct image_file_map *fmap) DECLSPEC_HIDDEN
Definition: dwarf.c:3509
const struct loader_ops * loader
#define CreateFileMappingW(a, b, c, d, e, f)
Definition: compat.h:603
const WCHAR S_ElfW[]
Definition: module.c:40
BOOL elf_map_handle(HANDLE handle, struct image_file_map *fmap)
Definition: elf_module.c:582
struct symt_thunk * symt_new_thunk(struct module *module, struct symt_compiland *parent, const char *name, THUNK_ORDINAL ord, ULONG_PTR addr, ULONG_PTR size) DECLSPEC_HIDDEN
Definition: symbol.c:496
SYSTEM_INFO sysinfo
Definition: dbghelp.c:76
GLfloat param
Definition: glext.h:5796
#define MAX_PATH
Definition: compat.h:34
const WCHAR * name
Definition: elf_module.c:1599
struct _SYMBOL_INFO SYMBOL_INFO
#define ELF_STT_OBJECT
Definition: elf_module.c:113
#define MAX_SYM_NAME
Definition: compat.h:834
#define for
Definition: utility.h:88
unsigned long DWORD
Definition: ntddk_ex.h:95
GLenum GLenum GLenum GLenum mapping
Definition: glext.h:9031
GLuint address
Definition: glext.h:9393
BOOL search_unix_path(const WCHAR *name, const WCHAR *path, BOOL(*match)(void *, HANDLE, const WCHAR *), void *param) DECLSPEC_HIDDEN
Definition: path.c:780
void hash_table_add(struct hash_table *ht, struct hash_table_elt *elt) DECLSPEC_HIDDEN
Definition: storage.c:378
enum_modules_cb cb
Definition: elf_module.c:1562
struct symt symt
BOOL(* enum_elf_modules_cb)(const WCHAR *, ULONG_PTR load_addr, ULONG_PTR dyn_addr, BOOL is_system, void *user)
Definition: elf_module.c:1446
static unsigned image_get_map_size(const struct image_section_map *ism)
struct image_file_map file_map
Definition: elf_module.c:88
static void image_unmap_file(struct image_file_map *fmap)
UINT8 st_other
Definition: elf_module.c:61
unsigned __int64 ULONG64
Definition: imports.h:198
unsigned reg
int ret
void pool_init(struct pool *a, size_t arena_size) DECLSPEC_HIDDEN
Definition: storage.c:43
SYM_TYPE SymType
Definition: compat.h:934
static BOOL elf_search_and_load_file(struct process *pcs, const WCHAR *filename, ULONG_PTR load_offset, ULONG_PTR dyn_addr, struct elf_info *elf_info)
Definition: elf_module.c:1411
GLenum const GLvoid * addr
Definition: glext.h:9621
static const WCHAR L[]
Definition: oid.c:1250
static UINT load_file(MSIRECORD *row, LPVOID param)
Definition: action.c:1202
#define ELF_SHT_SYMTAB
Definition: elf_module.c:94
static void image_unmap_section(struct image_section_map *ism)
signed long long INT64
struct symt_public * symt_new_public(struct module *module, struct symt_compiland *parent, const char *typename, BOOL is_function, ULONG_PTR address, unsigned size) DECLSPEC_HIDDEN
Definition: symbol.c:224
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
GLenum GLsizei len
Definition: glext.h:6722
#define GetCurrentProcess()
Definition: compat.h:618
#define ELF_STT_FILE
Definition: elf_module.c:116
void * hash_table_iter_up(struct hash_table_iter *hti) DECLSPEC_HIDDEN
Definition: storage.c:422
#define GENERIC_READ
Definition: compat.h:135
static cab_ULONG checksum(const cab_UBYTE *data, cab_UWORD bytes, cab_ULONG csum)
Definition: fdi.c:353
static BOOL image_find_section(struct image_file_map *fmap, const char *name, struct image_section_map *ism)
static BOOL elf_enum_modules_translate(const WCHAR *name, ULONG_PTR load_addr, ULONG_PTR dyn_addr, BOOL is_system, void *user)
Definition: elf_module.c:1566
UINT64 st_value
Definition: elf_module.c:63
uint32_t DWORD_PTR
Definition: typedefs.h:65
static const char * image_map_section(struct image_section_map *ism)
unsigned char BYTE
Definition: xxhash.c:193
struct image_file_map::@376::elf_file_map elf
struct elf_map_file_data::@373::@375 process
UINT32 st_size
Definition: elf_module.c:51
static UINT_PTR page_mask
Definition: virtual.c:49
WCHAR * get_wine_loader_name(struct process *pcs) DECLSPEC_HIDDEN
Definition: module.c:150
struct elf_info * elf_info
Definition: elf_module.c:1320
static BOOL elf_search_auxv(const struct process *pcs, unsigned type, ULONG_PTR *val)
Definition: elf_module.c:1334
const struct image_file_map_ops * ops
#define ERR(fmt,...)
Definition: debug.h:110
unsigned kind
static BOOL elf_map_file_read(struct image_file_map *fmap, struct elf_map_file_data *emfd, void *buf, size_t len, size_t off)
Definition: elf_module.c:335
ULONG_PTR SIZE_T
Definition: typedefs.h:80
_Check_return_ _CRTIMP int __cdecl wcscmp(_In_z_ const wchar_t *_Str1, _In_z_ const wchar_t *_Str2)
ULONG_PTR rva_end
Definition: elf_module.c:80
DWORD dwPageSize
Definition: winbase.h:1139
static void elf_module_remove(struct process *pcs, struct module_format *modfmt)
Definition: elf_module.c:590
#define ELF_INFO_NAME
Definition: elf_module.c:35
struct process * pcs
Definition: elf_module.c:1597
void pool_destroy(struct pool *a) DECLSPEC_HIDDEN
Definition: storage.c:50
#define lstrcpyW
Definition: compat.h:608
static BOOL elf_load_debug_info_from_map(struct module *module, struct image_file_map *fmap, struct pool *pool, struct hash_table *ht_symtab)
Definition: elf_module.c:1014
#define ARRAY_SIZE(a)
Definition: main.h:24
const WCHAR S_WineLoaderW[]
Definition: module.c:42
unsigned short is_virtual
#define ELF_INFO_MODULE
Definition: elf_module.c:34
struct module * module
Definition: elf_module.c:43
#define ReadFile(a, b, c, d, e)
Definition: compat.h:601
DWORD calc_crc32(HANDLE handle)
Definition: dbghelp.c:848
static const struct elf_sym * elf_lookup_symtab(const struct module *module, const struct hash_table *ht_symtab, const char *name, const struct symt *compiland)
Definition: elf_module.c:749
unsigned short UINT16
#define min(a, b)
Definition: monoChain.cc:55
unsigned dbghelp_options
Definition: dbghelp.c:73
static BOOL elf_synchronize_module_list(struct process *pcs)
Definition: elf_module.c:1700
#define PAGE_READONLY
Definition: compat.h:138
BOOL module_remove(struct process *pcs, struct module *module) DECLSPEC_HIDDEN
Definition: module.c:885
struct hash_table_elt hash_elt
struct module * module
#define MultiByteToWideChar
Definition: compat.h:110
#define ELF_AT_SYSINFO_EHDR
Definition: elf_module.c:122
unsigned short elf_loader
Definition: elf_module.c:86
static LPCWSTR file_name
Definition: protocol.c:147
void hash_table_init(struct pool *pool, struct hash_table *ht, unsigned num_buckets) DECLSPEC_HIDDEN
Definition: storage.c:334
#define CreateFileW
Definition: compat.h:600
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:66
Definition: name.c:38
BOOL stabs_parse(struct module *module, ULONG_PTR load_offset, const char *stabs, size_t nstab, size_t stabsize, const char *strs, int strtablen, stabs_def_cb callback, void *user) DECLSPEC_HIDDEN
Definition: stabs.c:1241
static const struct loader_ops elf_loader_ops
Definition: elf_module.c:1739
struct symt_data * symt_new_global_variable(struct module *module, struct symt_compiland *parent, const char *name, unsigned is_static, struct location loc, ULONG_PTR size, struct symt *type) DECLSPEC_HIDDEN
Definition: symbol.c:256
#define SYMOPT_PUBLICS_ONLY
Definition: compat.h:851
WINE_DEFAULT_DEBUG_CHANNEL(dbghelp)
UINT64 st_size
Definition: elf_module.c:64
unsigned used
Definition: elf_module.c:72
HANDLE handle
static void elf_reset_file_map(struct image_file_map *fmap)
Definition: elf_module.c:308
static __inline const char * wine_dbgstr_longlong(ULONGLONG ll)
Definition: compat.h:49
int strcmp(const char *String1, const char *String2)
Definition: utclib.c:469
UINT8 st_info
Definition: elf_module.c:52
signed int INT32
BOOL WINAPI SymFromName(HANDLE hProcess, PCSTR Name, PSYMBOL_INFO Symbol)
Definition: symbol.c:1392
static void elf_end_find(struct image_file_map *fmap)
Definition: elf_module.c:239
struct module * module_new(struct process *pcs, const WCHAR *name, enum module_type type, BOOL virtual, DWORD64 addr, DWORD64 size, ULONG_PTR stamp, ULONG_PTR checksum) DECLSPEC_HIDDEN
Definition: module.c:198
static BOOL elf_map_shdr(struct elf_map_file_data *emfd, struct image_file_map *fmap, unsigned int i)
Definition: elf_module.c:359
WCHAR * get_dos_file_name(const WCHAR *filename) DECLSPEC_HIDDEN
Definition: path.c:671
union module_format::@365 u
static struct module * elf_load_module(struct process *pcs, const WCHAR *name, ULONG_PTR addr)
Definition: elf_module.c:1661
#define SYMOPT_NO_PUBLICS
Definition: compat.h:852
unsigned long long UINT64
GLfloat GLfloat p
Definition: glext.h:8902
struct elf_info elf_info
Definition: elf_module.c:1598
#define UnmapViewOfFile
Definition: compat.h:605
static DWORD_PTR elf_get_map_rva(const struct image_section_map *ism)
Definition: elf_module.c:258
unsigned char UINT8
#define ELF_STT_FUNC
Definition: elf_module.c:114
GLuint64EXT * result
Definition: glext.h:11304
static BOOL elf_find_section_type(struct image_file_map *_fmap, const char *name, unsigned sht, struct image_section_map *ism)
Definition: elf_module.c:191
struct module_format * format_info[DFI_LAST]
IMAGEHLP_MODULEW64 module
#define ELF_SHT_DYNSYM
Definition: elf_module.c:103
static BOOL read_process_memory(const struct process *process, UINT64 addr, void *buf, size_t size)
BOOL elf_read_wine_loader_dbg_info(struct process *pcs, ULONG_PTR addr)
Definition: elf_module.c:1753
void user(int argc, const char *argv[])
Definition: cmds.c:1350
struct module * next
#define HeapFree(x, y, z)
Definition: compat.h:594
BOOL WINAPI DuplicateHandle(IN HANDLE hSourceProcessHandle, IN HANDLE hSourceHandle, IN HANDLE hTargetProcessHandle, OUT LPHANDLE lpTargetHandle, IN DWORD dwDesiredAccess, IN BOOL bInheritHandle, IN DWORD dwOptions)
Definition: handle.c:149
struct hash_table_elt hash_elt
const WCHAR * module_name
Definition: elf_module.c:44
struct symt_compiland * compiland
Definition: elf_module.c:71
struct symt_compiland * symt_new_compiland(struct module *module, ULONG_PTR address, unsigned src_idx) DECLSPEC_HIDDEN
Definition: symbol.c:207
LONGLONG QuadPart
Definition: typedefs.h:114
UINT32 st_name
Definition: elf_module.c:49
THUNK_ORDINAL
Definition: compat.h:2073
struct symt_ht * symt_find_nearest(struct module *module, DWORD_PTR addr) DECLSPEC_HIDDEN
Definition: symbol.c:903
static BOOL heap_free(void *mem)
Definition: appwiz.h:75
UINT8 st_info
Definition: elf_module.c:60
BOOL(* enum_modules_cb)(const WCHAR *, ULONG_PTR addr, void *user)
off
Definition: i386-dis.c:3909
static void elf_finish_stabs_info(struct module *module, const struct hash_table *symtab)
Definition: elf_module.c:823
GLuint const GLchar * name
Definition: glext.h:6031