ReactOS 0.4.16-dev-92-g0c2cdca
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
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
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
57struct 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
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,
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 */
129static 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;
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 */
169static 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
191static 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 */
226static 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
239static 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 */
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 */
270static 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 */
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
308static 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 {
326 struct
327 {
332 } u;
333};
334
335static 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{
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
359static 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 */
406static 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
590static 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 */
620static 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 {
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 */
749static 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
812static 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 */
823static 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 */
906static 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;
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 */
981static 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
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
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 }
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));
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
1261 {
1262 WCHAR* ptr;
1263 ptr = HeapAlloc(GetProcessHeap(), 0, (lstrlenW(filename) + 1) * sizeof(WCHAR));
1264 if (ptr)
1265 {
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 */
1286static 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",
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{
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 */
1334static 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 {
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 */
1454static BOOL elf_enum_modules_internal(const struct process* pcs,
1455 const WCHAR* main_name,
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
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
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 */
1661static 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
1739static 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}
unsigned short UINT16
signed int INT32
unsigned long long UINT64
unsigned char UINT8
unsigned int UINT32
signed long long INT64
int strcmp(const char *String1, const char *String2)
Definition: utclib.c:469
int memcmp(void *Buffer1, void *Buffer2, ACPI_SIZE Count)
Definition: utclib.c:112
#define isdigit(c)
Definition: acclib.h:68
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
static BOOL heap_free(void *mem)
Definition: appwiz.h:76
#define WINE_DEFAULT_DEBUG_CHANNEL(t)
Definition: precomp.h:23
void user(int argc, const char *argv[])
Definition: cmds.c:1350
#define ARRAY_SIZE(A)
Definition: main.h:20
#define FIXME(fmt,...)
Definition: precomp.h:53
#define WARN(fmt,...)
Definition: precomp.h:61
#define ERR(fmt,...)
Definition: precomp.h:57
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
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 hash_table_init(struct pool *pool, struct hash_table *ht, unsigned num_buckets) DECLSPEC_HIDDEN
Definition: storage.c:334
BOOL search_dll_path(const struct process *process, const WCHAR *name, BOOL(*match)(void *, HANDLE, const WCHAR *), void *param) DECLSPEC_HIDDEN
Definition: path.c:697
const char * file_nameA(const char *str) DECLSPEC_HIDDEN
Definition: path.c:37
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
void * pool_alloc(struct pool *a, size_t len) DECLSPEC_HIDDEN
Definition: storage.c:89
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
WCHAR * get_dos_file_name(const WCHAR *filename) DECLSPEC_HIDDEN
Definition: path.c:671
static BOOL read_process_memory(const struct process *process, UINT64 addr, void *buf, size_t size)
void pool_init(struct pool *a, size_t arena_size) DECLSPEC_HIDDEN
Definition: storage.c:43
void pool_destroy(struct pool *a) DECLSPEC_HIDDEN
Definition: storage.c:50
unsigned source_new(struct module *module, const char *basedir, const char *source) DECLSPEC_HIDDEN
Definition: source.c:66
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
@ DFI_ELF
void hash_table_iter_init(const struct hash_table *ht, struct hash_table_iter *hti, const char *name) DECLSPEC_HIDDEN
Definition: storage.c:405
WCHAR * get_wine_loader_name(struct process *pcs) DECLSPEC_HIDDEN
Definition: module.c:150
BOOL(* enum_modules_cb)(const WCHAR *, ULONG_PTR addr, void *user)
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
struct module * module_is_already_loaded(const struct process *pcs, const WCHAR *imgname) DECLSPEC_HIDDEN
Definition: module.c:303
void * hash_table_iter_up(struct hash_table_iter *hti) DECLSPEC_HIDDEN
Definition: storage.c:422
BOOL symt_get_address(const struct symt *type, ULONG64 *addr) DECLSPEC_HIDDEN
Definition: type.c:119
struct symt_compiland * symt_new_compiland(struct module *module, ULONG_PTR address, unsigned src_idx) DECLSPEC_HIDDEN
Definition: symbol.c:207
const char * source_get(const struct module *module, unsigned idx) DECLSPEC_HIDDEN
Definition: source.c:130
@ loc_absolute
BOOL search_unix_path(const WCHAR *name, const WCHAR *path, BOOL(*match)(void *, HANDLE, const WCHAR *), void *param) DECLSPEC_HIDDEN
Definition: path.c:782
BOOL module_remove(struct process *pcs, struct module *module) DECLSPEC_HIDDEN
Definition: module.c:889
void hash_table_add(struct hash_table *ht, struct hash_table_elt *elt) DECLSPEC_HIDDEN
Definition: storage.c:378
void module_set_module(struct module *module, const WCHAR *name) DECLSPEC_HIDDEN
Definition: module.c:142
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
@ DMT_ELF
struct symt_ht * symt_find_nearest(struct module *module, DWORD_PTR addr) DECLSPEC_HIDDEN
Definition: symbol.c:903
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
static cab_ULONG checksum(const cab_UBYTE *data, cab_UWORD bytes, cab_ULONG csum)
Definition: fdi.c:353
#define CloseHandle
Definition: compat.h:739
#define CP_UNIXCP
Definition: compat.h:79
#define ReadProcessMemory(a, b, c, d, e)
Definition: compat.h:758
#define GetProcessHeap()
Definition: compat.h:736
#define PAGE_READONLY
Definition: compat.h:138
#define FILE_BEGIN
Definition: compat.h:761
#define MAX_SYM_NAME
Definition: compat.h:975
#define SYMOPT_NO_PUBLICS
Definition: compat.h:993
@ SymDeferred
Definition: compat.h:1061
@ SymExport
Definition: compat.h:1060
#define UnmapViewOfFile
Definition: compat.h:746
#define OPEN_EXISTING
Definition: compat.h:775
#define ReadFile(a, b, c, d, e)
Definition: compat.h:742
#define INVALID_HANDLE_VALUE
Definition: compat.h:731
#define HeapAlloc
Definition: compat.h:733
THUNK_ORDINAL
Definition: compat.h:2215
@ THUNK_ORDINAL_NOTYPE
Definition: compat.h:2216
@ THUNK_ORDINAL_LOAD
Definition: compat.h:2220
#define CreateFileMappingW(a, b, c, d, e, f)
Definition: compat.h:744
#define SYMOPT_PUBLICS_ONLY
Definition: compat.h:992
static __inline const char * wine_dbgstr_longlong(ULONGLONG ll)
Definition: compat.h:49
#define GetCurrentProcess()
Definition: compat.h:759
#define GENERIC_READ
Definition: compat.h:135
struct _SYMBOL_INFO SYMBOL_INFO
@ SymTagFunction
Definition: compat.h:1586
@ SymTagData
Definition: compat.h:1588
#define MAX_PATH
Definition: compat.h:34
#define HeapFree(x, y, z)
Definition: compat.h:735
#define SYMOPT_DEFERRED_LOADS
Definition: compat.h:989
#define CreateFileW
Definition: compat.h:741
#define FILE_MAP_READ
Definition: compat.h:776
@ DataIsGlobal
Definition: compat.h:1654
@ DataIsFileStatic
Definition: compat.h:1653
#define lstrcpyW
Definition: compat.h:749
#define MapViewOfFile
Definition: compat.h:745
#define MultiByteToWideChar
Definition: compat.h:110
#define FILE_SHARE_READ
Definition: compat.h:136
#define lstrlenW
Definition: compat.h:750
DWORD calc_crc32(HANDLE handle)
Definition: dbghelp.c:874
unsigned dbghelp_options
Definition: dbghelp.c:73
SYSTEM_INFO sysinfo
Definition: dbghelp.c:76
const WCHAR * process_getenv(const struct process *process, const WCHAR *name)
Definition: dbghelp.c:335
const WCHAR S_ElfW[]
Definition: module.c:40
const WCHAR S_WineLoaderW[]
Definition: module.c:42
BOOL WINAPI SetFilePointerEx(HANDLE hFile, LARGE_INTEGER liDistanceToMove, PLARGE_INTEGER lpNewFilePointer, DWORD dwMoveMethod)
Definition: fileinfo.c:177
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
static UINT load_file(MSIRECORD *row, LPVOID param)
Definition: action.c:1031
#define assert(x)
Definition: debug.h:53
static BOOL elf_is_local_symbol(unsigned int info)
Definition: elf_module.c:812
#define ELF_PT_LOAD
Definition: elf_module.c:118
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
BOOL elf_read_wine_loader_dbg_info(struct process *pcs, ULONG_PTR addr)
Definition: elf_module.c:1753
#define ELF_SHT_DYNSYM
Definition: elf_module.c:103
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
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
static DWORD_PTR elf_get_map_rva(const struct image_section_map *ism)
Definition: elf_module.c:258
static const char * elf_map_section(struct image_section_map *ism)
Definition: elf_module.c:129
static BOOL elf_synchronize_module_list(struct process *pcs)
Definition: elf_module.c:1700
static unsigned elf_get_map_size(const struct image_section_map *ism)
Definition: elf_module.c:270
BOOL elf_map_handle(HANDLE handle, struct image_file_map *fmap)
Definition: elf_module.c:582
static BOOL elf_map_file(struct elf_map_file_data *emfd, struct image_file_map *fmap)
Definition: elf_module.c:406
static const struct image_file_map_ops elf_file_map_ops
Definition: elf_module.c:298
static struct module * elf_load_module(struct process *pcs, const WCHAR *name, ULONG_PTR addr)
Definition: elf_module.c:1661
static void elf_end_find(struct image_file_map *fmap)
Definition: elf_module.c:239
static void elf_unmap_section(struct image_section_map *ism)
Definition: elf_module.c:226
#define ELF_INFO_MODULE
Definition: elf_module.c:34
static BOOL elf_enum_modules(struct process *process, enum_modules_cb cb, void *user)
Definition: elf_module.c:1580
static void elf_module_remove(struct process *pcs, struct module_format *modfmt)
Definition: elf_module.c:590
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 ELF_INFO_NAME
Definition: elf_module.c:35
static BOOL elf_find_section(struct image_file_map *_fmap, const char *name, struct image_section_map *ism)
Definition: elf_module.c:169
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
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
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 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 ELF_SHT_DYNAMIC
Definition: elf_module.c:98
static BOOL elf_search_auxv(const struct process *pcs, unsigned type, ULONG_PTR *val)
Definition: elf_module.c:1334
#define ELF_SHT_SYMTAB
Definition: elf_module.c:94
#define ELF_STT_FUNC
Definition: elf_module.c:114
#define ELF_STT_FILE
Definition: elf_module.c:116
#define ELF_STT_NOTYPE
Definition: elf_module.c:112
static BOOL elf_load_file_cb(void *param, HANDLE handle, const WCHAR *filename)
Definition: elf_module.c:1323
#define ELF_SHT_NOBITS
Definition: elf_module.c:100
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
int elf_is_in_thunk_area(ULONG_PTR addr, const struct elf_thunk_area *thunks)
Definition: elf_module.c:602
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
static int elf_new_public_symbols(struct module *module, const struct hash_table *symtab)
Definition: elf_module.c:981
#define ELF_STT_OBJECT
Definition: elf_module.c:113
static BOOL elf_load_debug_info(struct process *process, struct module *module)
Definition: elf_module.c:1089
static void elf_finish_stabs_info(struct module *module, const struct hash_table *symtab)
Definition: elf_module.c:823
static void elf_unmap_file(struct image_file_map *fmap)
Definition: elf_module.c:282
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
#define ELF_INFO_DEBUG_HEADER
Definition: elf_module.c:33
static const struct loader_ops elf_loader_ops
Definition: elf_module.c:1739
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
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
#define ELF_AT_SYSINFO_EHDR
Definition: elf_module.c:122
static void elf_reset_file_map(struct image_file_map *fmap)
Definition: elf_module.c:308
static BOOL elf_map_shdr(struct elf_map_file_data *emfd, struct image_file_map *fmap, unsigned int i)
Definition: elf_module.c:359
#define ELF_DT_DEBUG
Definition: elf_module.c:120
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 int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
LARGE_INTEGER li
Definition: fxtimerapi.cpp:235
GLuint GLuint GLsizei GLenum type
Definition: gl.h:1545
GLsizeiptr size
Definition: glext.h:5919
GLdouble n
Definition: glext.h:7729
GLuint address
Definition: glext.h:9393
GLuint buffer
Definition: glext.h:5915
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
GLenum const GLvoid * addr
Definition: glext.h:9621
GLuint GLfloat * val
Definition: glext.h:7180
GLenum GLenum GLenum GLenum mapping
Definition: glext.h:9031
GLfloat GLfloat p
Definition: glext.h:8902
GLfloat param
Definition: glext.h:5796
GLenum GLsizei len
Definition: glext.h:6722
GLuint64EXT * result
Definition: glext.h:11304
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
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
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
#define IMAGE_NO_MAP
Definition: image_private.h:24
static void image_unmap_section(struct image_section_map *ism)
static BOOL image_find_section(struct image_file_map *fmap, const char *name, struct image_section_map *ism)
static const char * image_map_section(struct image_section_map *ism)
BOOL image_check_alternate(struct image_file_map *fmap, const struct module *module) DECLSPEC_HIDDEN
Definition: module.c:701
static void image_unmap_file(struct image_file_map *fmap)
static unsigned image_get_map_size(const struct image_section_map *ism)
_CONST_RETURN wchar_t *__cdecl wcsstr(_In_z_ const wchar_t *_Str, _In_z_ const wchar_t *_SubStr)
REFIID LPVOID DWORD_PTR dw
Definition: atlbase.h:40
const char * filename
Definition: ioapi.h:137
#define debugstr_w
Definition: kernel32.h:32
int load_addr
Definition: mkisofs.c:104
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
#define for
Definition: utility.h:88
unsigned __int64 ULONG64
Definition: imports.h:198
static PVOID ptr
Definition: dispmode.c:27
static HMODULE MODULEINFO DWORD cb
Definition: module.c:33
static UINT_PTR page_mask
Definition: virtual.c:49
static LPCWSTR file_name
Definition: protocol.c:147
#define min(a, b)
Definition: monoChain.cc:55
#define BOOL
Definition: nt_native.h:43
#define L(x)
Definition: ntvdm.h:50
const WCHAR * str
_Check_return_ _CRTIMP int __cdecl wcscmp(_In_z_ const wchar_t *_Str1, _In_z_ const wchar_t *_Str2)
#define TRACE(s)
Definition: solgame.cpp:4
WCHAR ModuleName[32]
Definition: compat.h:1076
WCHAR LoadedImageName[256]
Definition: compat.h:1078
SYM_TYPE SymType
Definition: compat.h:1075
DWORD dwPageSize
Definition: winbase.h:1173
DWORD dwAllocationGranularity
Definition: winbase.h:1179
enum_modules_cb cb
Definition: elf_module.c:1562
unsigned flags
Definition: elf_module.c:41
struct module * module
Definition: elf_module.c:43
const WCHAR * module_name
Definition: elf_module.c:44
DWORD_PTR dbg_hdr_addr
Definition: elf_module.c:42
struct process * process
Definition: elf_module.c:1317
struct elf_info * elf_info
Definition: elf_module.c:1320
const WCHAR * name
Definition: elf_module.c:1599
struct elf_info elf_info
Definition: elf_module.c:1598
BOOL ret
Definition: elf_module.c:1600
struct process * pcs
Definition: elf_module.c:1597
enum elf_map_file_data::@379 kind
union elf_map_file_data::@380 u
struct elf_map_file_data::@380::@381 file
const WCHAR * filename
Definition: elf_module.c:324
struct elf_map_file_data::@380::@382 process
unsigned short elf_loader
Definition: elf_module.c:87
struct image_file_map file_map
Definition: elf_module.c:88
ULONG_PTR elf_addr
Definition: elf_module.c:85
unsigned short elf_mark
Definition: elf_module.c:86
UINT32 st_size
Definition: elf_module.c:51
UINT32 st_name
Definition: elf_module.c:49
UINT32 st_value
Definition: elf_module.c:50
UINT16 st_shndx
Definition: elf_module.c:54
UINT8 st_info
Definition: elf_module.c:52
UINT8 st_other
Definition: elf_module.c:53
UINT32 st_name
Definition: elf_module.c:59
UINT8 st_other
Definition: elf_module.c:61
UINT64 st_value
Definition: elf_module.c:63
UINT64 st_size
Definition: elf_module.c:64
UINT8 st_info
Definition: elf_module.c:60
UINT16 st_shndx
Definition: elf_module.c:62
ULONG_PTR rva_end
Definition: elf_module.c:80
ULONG_PTR rva_start
Definition: elf_module.c:79
const char * symname
Definition: elf_module.c:77
THUNK_ORDINAL ordinal
Definition: elf_module.c:78
struct image_file_map::@383::elf_file_map elf
enum module_type modtype
union image_file_map::@383 u
unsigned addr_size
struct image_file_map * alternate
const struct image_file_map_ops * ops
struct image_file_map * fmap
ULONG_PTR offset
unsigned reg
unsigned kind
struct module * module
void(* loc_compute)(struct process *pcs, const struct module_format *modfmt, const struct symt_function *func, struct location *loc)
union module_format::@372 u
struct elf_module_info * elf_info
void(* remove)(struct process *pcs, struct module_format *modfmt)
DWORD64 reloc_delta
unsigned short is_virtual
IMAGEHLP_MODULEW64 module
int sortlist_valid
struct module_format * format_info[DFI_LAST]
struct hash_table ht_symbols
struct module * next
enum module_type type
Definition: name.c:39
const struct loader_ops * loader
HANDLE handle
struct module * lmodules
ULONG_PTR dbg_hdr_addr
struct hash_table_elt hash_elt
struct hash_table_elt hash_elt
struct symt symt
struct symt symt
struct hash_table_elt ht_elt
Definition: elf_module.c:69
unsigned used
Definition: elf_module.c:72
struct symt_compiland * compiland
Definition: elf_module.c:71
struct elf_sym sym
Definition: elf_module.c:70
BOOL WINAPI SymFromName(HANDLE hProcess, PCSTR Name, PSYMBOL_INFO Symbol)
Definition: symbol.c:1392
uint32_t DWORD_PTR
Definition: typedefs.h:65
ULONG_PTR SIZE_T
Definition: typedefs.h:80
uint32_t ULONG_PTR
Definition: typedefs.h:65
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:260
LONGLONG QuadPart
Definition: typedefs.h:114
int ret
DWORD WINAPI GetLastError(void)
Definition: except.c:1042
ActualNumberDriverObjects * sizeof(PDRIVER_OBJECT)) PDRIVER_OBJECT *DriverObjectList
__wchar_t WCHAR
Definition: xmlstorage.h:180
unsigned char BYTE
Definition: xxhash.c:193