2 * File elf.c - processing of ELF files
4 * Copyright (C) 1996, Eric Youngdale.
5 * 1999-2007 Eric Pouech
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
26 #include "dbghelp_private.h"
27 #include "image_private.h"
30 #include "wine/debug.h"
31 #include "wine/heap.h"
33 #define ELF_INFO_DEBUG_HEADER 0x0001
34 #define ELF_INFO_MODULE 0x0002
35 #define ELF_INFO_NAME 0x0004
37 WINE_DEFAULT_DEBUG_CHANNEL(dbghelp
);
41 unsigned flags
; /* IN one (or several) of the ELF_INFO constants */
42 DWORD64 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) */
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 */
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 */
69 struct hash_table_elt ht_elt
;
71 struct symt_compiland
* compiland
;
78 THUNK_ORDINAL ordinal
;
83 struct elf_module_info
86 unsigned short elf_mark
: 1,
88 struct image_file_map file_map
;
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. */
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 */
118 #define ELF_PT_LOAD 1 /* Loadable program segment */
120 #define ELF_DT_DEBUG 21 /* For debugging; unspecified */
122 #define ELF_AT_SYSINFO_EHDR 33
124 static DWORD
elf_get_machine(unsigned mach
)
129 FIXME("No mapping yet for ELF e_machine %u\n", mach
);
131 case /*EM_NONE*/ 0: return IMAGE_FILE_MACHINE_UNKNOWN
;
132 case /*EM_386*/ 3: return IMAGE_FILE_MACHINE_I386
;
133 case /*EM_ARM*/ 40: return IMAGE_FILE_MACHINE_ARMNT
;
134 case /*EM_X86_64*/ 62: return IMAGE_FILE_MACHINE_AMD64
;
135 case /*EM_AARCH64*/ 183: return IMAGE_FILE_MACHINE_ARM64
;
139 /******************************************************************
142 * Maps a single section into memory from an ELF file
144 static const char* elf_map_section(struct image_section_map
* ism
)
146 struct elf_file_map
* fmap
= &ism
->fmap
->u
.elf
;
150 assert(ism
->fmap
->modtype
== DMT_ELF
);
151 if (ism
->sidx
< 0 || ism
->sidx
>= ism
->fmap
->u
.elf
.elfhdr
.e_shnum
||
152 fmap
->sect
[ism
->sidx
].shdr
.sh_type
== ELF_SHT_NOBITS
)
155 if (fmap
->target_copy
)
157 return fmap
->target_copy
+ fmap
->sect
[ism
->sidx
].shdr
.sh_offset
;
160 /* align required information on allocation granularity */
161 ofst
= fmap
->sect
[ism
->sidx
].shdr
.sh_offset
& ~(sysinfo
.dwAllocationGranularity
- 1);
162 size
= fmap
->sect
[ism
->sidx
].shdr
.sh_offset
+ fmap
->sect
[ism
->sidx
].shdr
.sh_size
- ofst
;
163 if (!(mapping
= CreateFileMappingW(fmap
->handle
, NULL
, PAGE_READONLY
, 0, ofst
+ size
, NULL
)))
165 ERR("map creation %p failed %lu offset %Iu %Iu size %Iu\n", fmap
->handle
, GetLastError(), ofst
, ofst
% 4096, size
);
168 fmap
->sect
[ism
->sidx
].mapped
= MapViewOfFile(mapping
, FILE_MAP_READ
, 0, ofst
, size
);
169 CloseHandle(mapping
);
170 if (!fmap
->sect
[ism
->sidx
].mapped
)
172 ERR("map %p failed %lu offset %Iu %Iu size %Iu\n", fmap
->handle
, GetLastError(), ofst
, ofst
% 4096, size
);
175 return fmap
->sect
[ism
->sidx
].mapped
+ (fmap
->sect
[ism
->sidx
].shdr
.sh_offset
& (sysinfo
.dwAllocationGranularity
- 1));
178 /******************************************************************
181 * Finds a section by name (and type) into memory from an ELF file
182 * or its alternate if any
184 static BOOL
elf_find_section(struct image_file_map
* _fmap
, const char* name
, struct image_section_map
* ism
)
186 struct elf_file_map
* fmap
= &_fmap
->u
.elf
;
189 if (fmap
->shstrtab
== IMAGE_NO_MAP
)
191 struct image_section_map hdr_ism
= {_fmap
, fmap
->elfhdr
.e_shstrndx
};
192 if ((fmap
->shstrtab
= elf_map_section(&hdr_ism
)) == IMAGE_NO_MAP
) return FALSE
;
194 for (i
= 0; i
< fmap
->elfhdr
.e_shnum
; i
++)
196 if (strcmp(fmap
->shstrtab
+ fmap
->sect
[i
].shdr
.sh_name
, name
) == 0)
206 static BOOL
elf_find_section_type(struct image_file_map
* _fmap
, const char* name
, unsigned sht
, struct image_section_map
* ism
)
208 struct elf_file_map
* fmap
;
213 if (_fmap
->modtype
!= DMT_ELF
) break;
214 fmap
= &_fmap
->u
.elf
;
215 if (fmap
->shstrtab
== IMAGE_NO_MAP
)
217 struct image_section_map hdr_ism
= {_fmap
, fmap
->elfhdr
.e_shstrndx
};
218 if ((fmap
->shstrtab
= elf_map_section(&hdr_ism
)) == IMAGE_NO_MAP
) break;
220 for (i
= 0; i
< fmap
->elfhdr
.e_shnum
; i
++)
222 if (strcmp(fmap
->shstrtab
+ fmap
->sect
[i
].shdr
.sh_name
, name
) == 0 && sht
== fmap
->sect
[i
].shdr
.sh_type
)
229 _fmap
= _fmap
->alternate
;
236 /******************************************************************
239 * Unmaps a single section from memory
241 static void elf_unmap_section(struct image_section_map
* ism
)
243 struct elf_file_map
* fmap
= &ism
->fmap
->u
.elf
;
245 if (ism
->sidx
>= 0 && ism
->sidx
< fmap
->elfhdr
.e_shnum
&& !fmap
->target_copy
&&
246 fmap
->sect
[ism
->sidx
].mapped
)
248 if (!UnmapViewOfFile(fmap
->sect
[ism
->sidx
].mapped
))
249 WARN("Couldn't unmap the section\n");
250 fmap
->sect
[ism
->sidx
].mapped
= NULL
;
254 static void elf_end_find(struct image_file_map
* fmap
)
256 struct image_section_map ism
;
258 while (fmap
&& fmap
->modtype
== DMT_ELF
)
261 ism
.sidx
= fmap
->u
.elf
.elfhdr
.e_shstrndx
;
262 elf_unmap_section(&ism
);
263 fmap
->u
.elf
.shstrtab
= IMAGE_NO_MAP
;
264 fmap
= fmap
->alternate
;
268 /******************************************************************
271 * Get the RVA of an ELF section
273 static DWORD_PTR
elf_get_map_rva(const struct image_section_map
* ism
)
275 if (ism
->sidx
< 0 || ism
->sidx
>= ism
->fmap
->u
.elf
.elfhdr
.e_shnum
)
277 return ism
->fmap
->u
.elf
.sect
[ism
->sidx
].shdr
.sh_addr
- ism
->fmap
->u
.elf
.elf_start
;
280 /******************************************************************
283 * Get the size of an ELF section
285 static unsigned elf_get_map_size(const struct image_section_map
* ism
)
287 if (ism
->sidx
< 0 || ism
->sidx
>= ism
->fmap
->u
.elf
.elfhdr
.e_shnum
)
289 return ism
->fmap
->u
.elf
.sect
[ism
->sidx
].shdr
.sh_size
;
292 /******************************************************************
295 * Unmaps an ELF file from memory (previously mapped with elf_map_file)
297 static void elf_unmap_file(struct image_file_map
* fmap
)
299 if (fmap
->u
.elf
.handle
!= INVALID_HANDLE_VALUE
)
301 struct image_section_map ism
;
303 for (ism
.sidx
= 0; ism
.sidx
< fmap
->u
.elf
.elfhdr
.e_shnum
; ism
.sidx
++)
305 elf_unmap_section(&ism
);
307 HeapFree(GetProcessHeap(), 0, fmap
->u
.elf
.sect
);
308 CloseHandle(fmap
->u
.elf
.handle
);
310 HeapFree(GetProcessHeap(), 0, fmap
->u
.elf
.target_copy
);
313 static const struct image_file_map_ops elf_file_map_ops
=
323 static inline void elf_reset_file_map(struct image_file_map
* fmap
)
325 fmap
->ops
= &elf_file_map_ops
;
326 fmap
->alternate
= NULL
;
327 fmap
->u
.elf
.handle
= INVALID_HANDLE_VALUE
;
328 fmap
->u
.elf
.shstrtab
= IMAGE_NO_MAP
;
329 fmap
->u
.elf
.target_copy
= NULL
;
332 struct elf_map_file_data
334 enum {from_file
, from_process
, from_handle
} kind
;
339 const WCHAR
* filename
;
350 static BOOL
elf_map_file_read(struct image_file_map
* fmap
, struct elf_map_file_data
* emfd
,
351 void* buf
, size_t len
, size_t off
)
362 if (!SetFilePointerEx(fmap
->u
.elf
.handle
, li
, NULL
, FILE_BEGIN
)) return FALSE
;
363 return ReadFile(fmap
->u
.elf
.handle
, buf
, len
, &bytes_read
, NULL
);
365 return ReadProcessMemory(emfd
->u
.process
.handle
,
366 (void*)((ULONG_PTR
)emfd
->u
.process
.load_addr
+ (ULONG_PTR
)off
),
367 buf
, len
, &dw
) && dw
== len
;
374 static BOOL
elf_map_shdr(struct elf_map_file_data
* emfd
, struct image_file_map
* fmap
, unsigned int i
)
376 if (fmap
->addr_size
== 32)
380 UINT32 sh_name
; /* Section name (string tbl index) */
381 UINT32 sh_type
; /* Section type */
382 UINT32 sh_flags
; /* Section flags */
383 UINT32 sh_addr
; /* Section virtual addr at execution */
384 UINT32 sh_offset
; /* Section file offset */
385 UINT32 sh_size
; /* Section size in bytes */
386 UINT32 sh_link
; /* Link to another section */
387 UINT32 sh_info
; /* Additional section information */
388 UINT32 sh_addralign
; /* Section alignment */
389 UINT32 sh_entsize
; /* Entry size if section holds table */
392 if (!elf_map_file_read(fmap
, emfd
, &shdr32
, sizeof(shdr32
),
393 fmap
->u
.elf
.elfhdr
.e_shoff
+ i
* sizeof(shdr32
)))
396 fmap
->u
.elf
.sect
[i
].shdr
.sh_name
= shdr32
.sh_name
;
397 fmap
->u
.elf
.sect
[i
].shdr
.sh_type
= shdr32
.sh_type
;
398 fmap
->u
.elf
.sect
[i
].shdr
.sh_flags
= shdr32
.sh_flags
;
399 fmap
->u
.elf
.sect
[i
].shdr
.sh_addr
= shdr32
.sh_addr
;
400 fmap
->u
.elf
.sect
[i
].shdr
.sh_offset
= shdr32
.sh_offset
;
401 fmap
->u
.elf
.sect
[i
].shdr
.sh_size
= shdr32
.sh_size
;
402 fmap
->u
.elf
.sect
[i
].shdr
.sh_link
= shdr32
.sh_link
;
403 fmap
->u
.elf
.sect
[i
].shdr
.sh_info
= shdr32
.sh_info
;
404 fmap
->u
.elf
.sect
[i
].shdr
.sh_addralign
= shdr32
.sh_addralign
;
405 fmap
->u
.elf
.sect
[i
].shdr
.sh_entsize
= shdr32
.sh_entsize
;
409 if (!elf_map_file_read(fmap
, emfd
, &fmap
->u
.elf
.sect
[i
].shdr
, sizeof(fmap
->u
.elf
.sect
[i
].shdr
),
410 fmap
->u
.elf
.elfhdr
.e_shoff
+ i
* sizeof(fmap
->u
.elf
.sect
[i
].shdr
)))
416 /******************************************************************
419 * Maps an ELF file into memory (and checks it's a real ELF file)
421 static BOOL
elf_map_file(struct elf_map_file_data
* emfd
, struct image_file_map
* fmap
)
424 size_t tmp
, page_mask
= sysinfo
.dwPageSize
- 1;
426 unsigned char e_ident
[ARRAY_SIZE(fmap
->u
.elf
.elfhdr
.e_ident
)];
428 elf_reset_file_map(fmap
);
430 fmap
->modtype
= DMT_ELF
;
431 fmap
->u
.elf
.handle
= INVALID_HANDLE_VALUE
;
432 fmap
->u
.elf
.target_copy
= NULL
;
437 if (!(dos_path
= get_dos_file_name(emfd
->u
.file
.filename
))) return FALSE
;
438 fmap
->u
.elf
.handle
= CreateFileW(dos_path
, GENERIC_READ
, FILE_SHARE_READ
, NULL
, OPEN_EXISTING
, 0, NULL
);
440 if (fmap
->u
.elf
.handle
== INVALID_HANDLE_VALUE
) return FALSE
;
443 if (!DuplicateHandle(GetCurrentProcess(), emfd
->u
.handle
, GetCurrentProcess(), &fmap
->u
.elf
.handle
, GENERIC_READ
, FALSE
, 0))
450 if (!elf_map_file_read(fmap
, emfd
, e_ident
, sizeof(e_ident
), 0))
453 /* and check for an ELF header */
454 if (memcmp(e_ident
, "\177ELF", 4))
457 fmap
->addr_size
= e_ident
[4] == 2 /* ELFCLASS64 */ ? 64 : 32;
459 if (fmap
->addr_size
== 32)
463 UINT8 e_ident
[16]; /* Magic number and other info */
464 UINT16 e_type
; /* Object file type */
465 UINT16 e_machine
; /* Architecture */
466 UINT32 e_version
; /* Object file version */
467 UINT32 e_entry
; /* Entry point virtual address */
468 UINT32 e_phoff
; /* Program header table file offset */
469 UINT32 e_shoff
; /* Section header table file offset */
470 UINT32 e_flags
; /* Processor-specific flags */
471 UINT16 e_ehsize
; /* ELF header size in bytes */
472 UINT16 e_phentsize
; /* Program header table entry size */
473 UINT16 e_phnum
; /* Program header table entry count */
474 UINT16 e_shentsize
; /* Section header table entry size */
475 UINT16 e_shnum
; /* Section header table entry count */
476 UINT16 e_shstrndx
; /* Section header string table index */
479 if (!elf_map_file_read(fmap
, emfd
, &elfhdr32
, sizeof(elfhdr32
), 0))
482 memcpy(fmap
->u
.elf
.elfhdr
.e_ident
, elfhdr32
.e_ident
, sizeof(e_ident
));
483 fmap
->u
.elf
.elfhdr
.e_type
= elfhdr32
.e_type
;
484 fmap
->u
.elf
.elfhdr
.e_machine
= elfhdr32
.e_machine
;
485 fmap
->u
.elf
.elfhdr
.e_version
= elfhdr32
.e_version
;
486 fmap
->u
.elf
.elfhdr
.e_entry
= elfhdr32
.e_entry
;
487 fmap
->u
.elf
.elfhdr
.e_phoff
= elfhdr32
.e_phoff
;
488 fmap
->u
.elf
.elfhdr
.e_shoff
= elfhdr32
.e_shoff
;
489 fmap
->u
.elf
.elfhdr
.e_flags
= elfhdr32
.e_flags
;
490 fmap
->u
.elf
.elfhdr
.e_ehsize
= elfhdr32
.e_ehsize
;
491 fmap
->u
.elf
.elfhdr
.e_phentsize
= elfhdr32
.e_phentsize
;
492 fmap
->u
.elf
.elfhdr
.e_phnum
= elfhdr32
.e_phnum
;
493 fmap
->u
.elf
.elfhdr
.e_shentsize
= elfhdr32
.e_shentsize
;
494 fmap
->u
.elf
.elfhdr
.e_shnum
= elfhdr32
.e_shnum
;
495 fmap
->u
.elf
.elfhdr
.e_shstrndx
= elfhdr32
.e_shstrndx
;
499 if (!elf_map_file_read(fmap
, emfd
, &fmap
->u
.elf
.elfhdr
, sizeof(fmap
->u
.elf
.elfhdr
), 0))
503 fmap
->u
.elf
.sect
= HeapAlloc(GetProcessHeap(), 0,
504 fmap
->u
.elf
.elfhdr
.e_shnum
* sizeof(fmap
->u
.elf
.sect
[0]));
505 if (!fmap
->u
.elf
.sect
) return FALSE
;
507 for (i
= 0; i
< fmap
->u
.elf
.elfhdr
.e_shnum
; i
++)
509 if (!elf_map_shdr(emfd
, fmap
, i
))
511 HeapFree(GetProcessHeap(), 0, fmap
->u
.elf
.sect
);
512 fmap
->u
.elf
.sect
= NULL
;
515 fmap
->u
.elf
.sect
[i
].mapped
= NULL
;
518 /* grab size of module once loaded in memory */
519 fmap
->u
.elf
.elf_size
= 0;
520 fmap
->u
.elf
.elf_start
= ~0L;
521 for (i
= 0; i
< fmap
->u
.elf
.elfhdr
.e_phnum
; i
++)
523 if (fmap
->addr_size
== 32)
527 UINT32 p_type
; /* Segment type */
528 UINT32 p_offset
; /* Segment file offset */
529 UINT32 p_vaddr
; /* Segment virtual address */
530 UINT32 p_paddr
; /* Segment physical address */
531 UINT32 p_filesz
; /* Segment size in file */
532 UINT32 p_memsz
; /* Segment size in memory */
533 UINT32 p_flags
; /* Segment flags */
534 UINT32 p_align
; /* Segment alignment */
537 if (elf_map_file_read(fmap
, emfd
, &phdr
, sizeof(phdr
),
538 fmap
->u
.elf
.elfhdr
.e_phoff
+ i
* sizeof(phdr
)) &&
539 phdr
.p_type
== ELF_PT_LOAD
)
541 tmp
= (phdr
.p_vaddr
+ phdr
.p_memsz
+ page_mask
) & ~page_mask
;
542 if (fmap
->u
.elf
.elf_size
< tmp
) fmap
->u
.elf
.elf_size
= tmp
;
543 if (phdr
.p_vaddr
< fmap
->u
.elf
.elf_start
) fmap
->u
.elf
.elf_start
= phdr
.p_vaddr
;
550 UINT32 p_type
; /* Segment type */
551 UINT32 p_flags
; /* Segment flags */
552 UINT64 p_offset
; /* Segment file offset */
553 UINT64 p_vaddr
; /* Segment virtual address */
554 UINT64 p_paddr
; /* Segment physical address */
555 UINT64 p_filesz
; /* Segment size in file */
556 UINT64 p_memsz
; /* Segment size in memory */
557 UINT64 p_align
; /* Segment alignment */
560 if (elf_map_file_read(fmap
, emfd
, &phdr
, sizeof(phdr
),
561 fmap
->u
.elf
.elfhdr
.e_phoff
+ i
* sizeof(phdr
)) &&
562 phdr
.p_type
== ELF_PT_LOAD
)
564 tmp
= (phdr
.p_vaddr
+ phdr
.p_memsz
+ page_mask
) & ~page_mask
;
565 if (fmap
->u
.elf
.elf_size
< tmp
) fmap
->u
.elf
.elf_size
= tmp
;
566 if (phdr
.p_vaddr
< fmap
->u
.elf
.elf_start
) fmap
->u
.elf
.elf_start
= phdr
.p_vaddr
;
570 /* if non relocatable ELF, then remove fixed address from computation
571 * otherwise, all addresses are zero based and start has no effect
573 fmap
->u
.elf
.elf_size
-= fmap
->u
.elf
.elf_start
;
578 case from_file
: break;
580 if (!(fmap
->u
.elf
.target_copy
= HeapAlloc(GetProcessHeap(), 0, fmap
->u
.elf
.elf_size
)))
582 HeapFree(GetProcessHeap(), 0, fmap
->u
.elf
.sect
);
585 if (!ReadProcessMemory(emfd
->u
.process
.handle
, emfd
->u
.process
.load_addr
, fmap
->u
.elf
.target_copy
,
586 fmap
->u
.elf
.elf_size
, NULL
))
588 HeapFree(GetProcessHeap(), 0, fmap
->u
.elf
.target_copy
);
589 HeapFree(GetProcessHeap(), 0, fmap
->u
.elf
.sect
);
597 BOOL
elf_map_handle(HANDLE handle
, struct image_file_map
* fmap
)
599 struct elf_map_file_data emfd
;
600 emfd
.kind
= from_handle
;
601 emfd
.u
.handle
= handle
;
602 return elf_map_file(&emfd
, fmap
);
605 static void elf_module_remove(struct process
* pcs
, struct module_format
* modfmt
)
607 image_unmap_file(&modfmt
->u
.elf_info
->file_map
);
608 HeapFree(GetProcessHeap(), 0, modfmt
);
611 /******************************************************************
612 * elf_is_in_thunk_area
614 * Check whether an address lies within one of the thunk area we
617 int elf_is_in_thunk_area(ULONG_PTR addr
,
618 const struct elf_thunk_area
* thunks
)
622 if (thunks
) for (i
= 0; thunks
[i
].symname
; i
++)
624 if (addr
>= thunks
[i
].rva_start
&& addr
< thunks
[i
].rva_end
)
630 /******************************************************************
633 * creating an internal hash table to ease use ELF symtab information lookup
635 static void elf_hash_symtab(struct module
* module
, struct pool
* pool
,
636 struct hash_table
* ht_symtab
, struct image_file_map
* fmap
,
637 struct elf_thunk_area
* thunks
)
642 struct symt_compiland
* compiland
= NULL
;
644 struct symtab_elt
* ste
;
645 struct image_section_map ism
, ism_str
;
648 if (!elf_find_section_type(fmap
, ".symtab", ELF_SHT_SYMTAB
, &ism
) &&
649 !elf_find_section_type(fmap
, ".dynsym", ELF_SHT_DYNSYM
, &ism
)) return;
650 if ((symtab
= image_map_section(&ism
)) == IMAGE_NO_MAP
) return;
651 ism_str
.fmap
= ism
.fmap
;
652 ism_str
.sidx
= fmap
->u
.elf
.sect
[ism
.sidx
].shdr
.sh_link
;
653 if ((strp
= image_map_section(&ism_str
)) == IMAGE_NO_MAP
)
655 image_unmap_section(&ism
);
659 nsym
= image_get_map_size(&ism
) /
660 (fmap
->addr_size
== 32 ? sizeof(struct elf_sym32
) : sizeof(struct elf_sym
));
662 for (j
= 0; thunks
[j
].symname
; j
++)
663 thunks
[j
].rva_start
= thunks
[j
].rva_end
= 0;
665 for (i
= 0; i
< nsym
; i
++)
670 if (fmap
->addr_size
== 32)
672 struct elf_sym32
*sym32
= &((struct elf_sym32
*)symtab
)[i
];
674 sym
.st_name
= sym32
->st_name
;
675 sym
.st_value
= sym32
->st_value
;
676 sym
.st_size
= sym32
->st_size
;
677 sym
.st_info
= sym32
->st_info
;
678 sym
.st_other
= sym32
->st_other
;
679 sym
.st_shndx
= sym32
->st_shndx
;
682 sym
= ((struct elf_sym
*)symtab
)[i
];
684 type
= sym
.st_info
& 0xf;
686 /* Ignore certain types of entries which really aren't of that much
689 if ((type
!= ELF_STT_NOTYPE
&& type
!= ELF_STT_FILE
&& type
!= ELF_STT_OBJECT
&& type
!= ELF_STT_FUNC
)
695 symname
= strp
+ sym
.st_name
;
697 /* handle some specific symtab (that we'll throw away when done) */
702 compiland
= symt_new_compiland(module
, source_new(module
, NULL
, symname
));
707 /* we are only interested in wine markers inserted by winebuild */
708 for (j
= 0; thunks
[j
].symname
; j
++)
710 if (!strcmp(symname
, thunks
[j
].symname
))
712 thunks
[j
].rva_start
= sym
.st_value
;
713 thunks
[j
].rva_end
= sym
.st_value
+ sym
.st_size
;
720 /* FIXME: we don't need to handle them (GCC internals)
721 * Moreover, they screw up our symbol lookup :-/
723 if (symname
[0] == '.' && symname
[1] == 'L' && isdigit(symname
[2]))
726 ste
= pool_alloc(pool
, sizeof(*ste
));
727 ste
->ht_elt
.name
= symname
;
728 /* GCC emits, in some cases, a .<digit>+ suffix.
729 * This is used for static variable inside functions, so
730 * that we can have several such variables with same name in
731 * the same compilation unit
732 * We simply ignore that suffix when present (we also get rid
733 * of it in stabs parsing)
735 ptr
= symname
+ strlen(symname
) - 1;
738 while (isdigit(*ptr
) && ptr
>= symname
) ptr
--;
739 if (ptr
> symname
&& *ptr
== '.')
741 char* n
= pool_alloc(pool
, ptr
- symname
+ 1);
742 memcpy(n
, symname
, ptr
- symname
+ 1);
743 n
[ptr
- symname
] = '\0';
744 ste
->ht_elt
.name
= n
;
748 ste
->compiland
= compiland
;
750 hash_table_add(ht_symtab
, &ste
->ht_elt
);
752 /* as we added in the ht_symtab pointers to the symbols themselves,
753 * we cannot unmap yet the sections, it will be done when we're over
758 /******************************************************************
761 * lookup a symbol by name in our internal hash table for the symtab
763 static const struct elf_sym
*elf_lookup_symtab(const struct module
* module
,
764 const struct hash_table
* ht_symtab
,
765 const char* name
, const struct symt
* compiland
)
767 struct symtab_elt
* weak_result
= NULL
; /* without compiland name */
768 struct symtab_elt
* result
= NULL
;
769 struct hash_table_iter hti
;
770 struct symtab_elt
* ste
;
771 const char* compiland_name
;
772 const char* compiland_basename
;
775 /* we need weak match up (at least) when symbols of same name,
776 * defined several times in different compilation units,
777 * are merged in a single one (hence a different filename for c.u.)
781 compiland_name
= source_get(module
,
782 ((const struct symt_compiland
*)compiland
)->source
);
783 compiland_basename
= file_nameA(compiland_name
);
785 else compiland_name
= compiland_basename
= NULL
;
787 hash_table_iter_init(ht_symtab
, &hti
, name
);
788 while ((ste
= hash_table_iter_up(&hti
)))
790 if (ste
->used
|| strcmp(ste
->ht_elt
.name
, name
)) continue;
793 if ((ste
->compiland
&& !compiland_name
) || (!ste
->compiland
&& compiland_name
))
795 if (ste
->compiland
&& compiland_name
)
797 const char* filename
= source_get(module
, ste
->compiland
->source
);
798 if (strcmp(filename
, compiland_name
))
800 base
= file_nameA(filename
);
801 if (strcmp(base
, compiland_basename
)) continue;
806 FIXME("Already found symbol %s (%s) in symtab %s @%08x and %s @%08x\n",
807 name
, compiland_name
,
808 source_get(module
, result
->compiland
->source
), (unsigned int)result
->sym
.st_value
,
809 source_get(module
, ste
->compiland
->source
), (unsigned int)ste
->sym
.st_value
);
817 if (!result
&& !(result
= weak_result
))
819 FIXME("Couldn't find symbol %s!%s in symtab\n",
820 debugstr_w(module
->modulename
), name
);
826 static BOOL
elf_is_local_symbol(unsigned int info
)
831 /******************************************************************
832 * elf_finish_stabs_info
834 * - get any relevant information (address & size) from the bits we got from the
835 * stabs debugging information
837 static void elf_finish_stabs_info(struct module
* module
, const struct hash_table
* symtab
)
839 struct hash_table_iter hti
;
842 const struct elf_sym
* symp
;
843 struct elf_module_info
* elf_info
= module
->format_info
[DFI_ELF
]->u
.elf_info
;
846 hash_table_iter_init(&module
->ht_symbols
, &hti
, NULL
);
847 while ((ptr
= hash_table_iter_up(&hti
)))
849 sym
= CONTAINING_RECORD(ptr
, struct symt_ht
, hash_elt
);
850 switch (sym
->symt
.tag
)
853 size
= addr_range_size(&((struct symt_function
*)sym
)->ranges
[0]);
854 if (((struct symt_function
*)sym
)->ranges
[0].low
!= elf_info
->elf_addr
&& size
)
858 symp
= elf_lookup_symtab(module
, symtab
, sym
->hash_elt
.name
,
859 ((struct symt_function
*)sym
)->container
);
862 if (((struct symt_function
*)sym
)->ranges
[0].low
!= elf_info
->elf_addr
&&
863 ((struct symt_function
*)sym
)->ranges
[0].low
!= elf_info
->elf_addr
+ symp
->st_value
)
864 FIXME("Changing address for %p/%s!%s from %I64x to %I64x\n",
865 sym
, debugstr_w(module
->modulename
), sym
->hash_elt
.name
,
866 ((struct symt_function
*)sym
)->ranges
[0].low
,
867 elf_info
->elf_addr
+ symp
->st_value
);
868 if (size
&& size
!= symp
->st_size
)
869 FIXME("Changing size for %p/%s!%s from %I64x to %I64x\n",
870 sym
, debugstr_w(module
->modulename
), sym
->hash_elt
.name
,
871 size
, symp
->st_size
);
873 ((struct symt_function
*)sym
)->ranges
[0].low
= elf_info
->elf_addr
+ symp
->st_value
;
874 ((struct symt_function
*)sym
)->ranges
[0].high
= elf_info
->elf_addr
+ symp
->st_value
+ symp
->st_size
;
876 FIXME("Couldn't find %s!%s\n",
877 debugstr_w(module
->modulename
), sym
->hash_elt
.name
);
880 switch (((struct symt_data
*)sym
)->kind
)
883 case DataIsFileStatic
:
884 if (((struct symt_data
*)sym
)->u
.var
.kind
!= loc_absolute
||
885 ((struct symt_data
*)sym
)->u
.var
.offset
!= elf_info
->elf_addr
)
887 symp
= elf_lookup_symtab(module
, symtab
, sym
->hash_elt
.name
,
888 ((struct symt_data
*)sym
)->container
);
891 if (((struct symt_data
*)sym
)->u
.var
.offset
!= elf_info
->elf_addr
&&
892 ((struct symt_data
*)sym
)->u
.var
.offset
!= elf_info
->elf_addr
+ symp
->st_value
)
893 FIXME("Changing address for %p/%s!%s from %I64x to %I64x\n",
894 sym
, debugstr_w(module
->modulename
), sym
->hash_elt
.name
,
895 ((struct symt_function
*)sym
)->ranges
[0].low
,
896 elf_info
->elf_addr
+ symp
->st_value
);
897 ((struct symt_data
*)sym
)->u
.var
.offset
= elf_info
->elf_addr
+ symp
->st_value
;
898 ((struct symt_data
*)sym
)->kind
= elf_is_local_symbol(symp
->st_info
) ?
899 DataIsFileStatic
: DataIsGlobal
;
901 FIXME("Couldn't find %s!%s\n",
902 debugstr_w(module
->modulename
), sym
->hash_elt
.name
);
908 FIXME("Unsupported tag %u\n", sym
->symt
.tag
);
912 /* since we may have changed some addresses & sizes, mark the module to be resorted */
913 module
->sortlist_valid
= FALSE
;
916 /******************************************************************
917 * elf_load_wine_thunks
919 * creating the thunk objects for a wine native DLL
921 static int elf_new_wine_thunks(struct module
* module
, const struct hash_table
* ht_symtab
,
922 const struct elf_thunk_area
* thunks
)
925 struct hash_table_iter hti
;
926 struct symtab_elt
* ste
;
928 struct symt_ht
* symt
;
930 hash_table_iter_init(ht_symtab
, &hti
, NULL
);
931 while ((ste
= hash_table_iter_up(&hti
)))
933 if (ste
->used
) continue;
935 addr
= module
->reloc_delta
+ ste
->sym
.st_value
;
937 j
= elf_is_in_thunk_area(ste
->sym
.st_value
, thunks
);
938 if (j
>= 0) /* thunk found */
940 symt_new_thunk(module
, ste
->compiland
, ste
->ht_elt
.name
, thunks
[j
].ordinal
,
941 addr
, ste
->sym
.st_size
);
948 symt
= symt_find_nearest(module
, addr
);
949 if (symt
&& !symt_get_address(&symt
->symt
, &ref_addr
))
951 if (!symt
|| addr
!= ref_addr
)
953 /* creating public symbols for all the ELF symbols which haven't been
954 * used yet (ie we have no debug information on them)
955 * That's the case, for example, of the .spec.c files
957 switch (ste
->sym
.st_info
& 0xf)
960 symt_new_function(module
, ste
->compiland
, ste
->ht_elt
.name
,
961 addr
, ste
->sym
.st_size
, NULL
);
964 loc
.kind
= loc_absolute
;
967 symt_new_global_variable(module
, ste
->compiland
, ste
->ht_elt
.name
,
968 elf_is_local_symbol(ste
->sym
.st_info
),
969 loc
, ste
->sym
.st_size
, NULL
);
972 FIXME("Shouldn't happen\n");
975 /* FIXME: this is a hack !!!
976 * we are adding new symbols, but as we're parsing a symbol table
977 * (hopefully without duplicate symbols) we delay rebuilding the sorted
978 * module table until we're done with the symbol table
979 * Otherwise, as we intertwine symbols' add and lookup, performance
982 module
->sortlist_valid
= TRUE
;
986 /* see comment above */
987 module
->sortlist_valid
= FALSE
;
991 /******************************************************************
992 * elf_new_public_symbols
994 * Creates a set of public symbols from an ELF symtab
996 static int elf_new_public_symbols(struct module
* module
, const struct hash_table
* symtab
)
998 struct hash_table_iter hti
;
999 struct symtab_elt
* ste
;
1001 if (dbghelp_options
& SYMOPT_NO_PUBLICS
) return TRUE
;
1003 /* FIXME: we're missing the ELF entry point here */
1005 hash_table_iter_init(symtab
, &hti
, NULL
);
1006 while ((ste
= hash_table_iter_up(&hti
)))
1008 symt_new_public(module
, ste
->compiland
, ste
->ht_elt
.name
,
1010 module
->reloc_delta
+ ste
->sym
.st_value
,
1016 /******************************************************************
1017 * elf_load_debug_info_from_map
1019 * Loads the symbolic information from ELF module which mapping is described
1021 * the module has been loaded at 'load_offset' address, so symbols' address
1022 * relocation is performed.
1023 * CRC is checked if fmap->with_crc is TRUE
1025 * 0 if the file doesn't contain symbolic info (or this info cannot be
1029 static BOOL
elf_load_debug_info_from_map(struct module
* module
,
1030 struct image_file_map
* fmap
,
1032 struct hash_table
* ht_symtab
)
1034 BOOL ret
= FALSE
, lret
;
1035 struct elf_thunk_area thunks
[] =
1037 {"__wine_spec_import_thunks", THUNK_ORDINAL_NOTYPE
, 0, 0}, /* inter DLL calls */
1038 {"__wine_spec_delayed_import_loaders", THUNK_ORDINAL_LOAD
, 0, 0}, /* delayed inter DLL calls */
1039 {"__wine_spec_delayed_import_thunks", THUNK_ORDINAL_LOAD
, 0, 0}, /* delayed inter DLL calls */
1040 {"__wine_delay_load", THUNK_ORDINAL_LOAD
, 0, 0}, /* delayed inter DLL calls */
1041 {"__wine_spec_thunk_text_16", -16, 0, 0}, /* 16 => 32 thunks */
1042 {"__wine_spec_thunk_text_32", -32, 0, 0}, /* 32 => 16 thunks */
1046 module
->module
.SymType
= SymExport
;
1048 /* create a hash table for the symtab */
1049 elf_hash_symtab(module
, pool
, ht_symtab
, fmap
, thunks
);
1051 if (!(dbghelp_options
& SYMOPT_PUBLICS_ONLY
))
1053 struct image_section_map stab_sect
, stabstr_sect
;
1055 /* check if we need an alternate file (from debuglink or build-id) */
1056 ret
= image_check_alternate(fmap
, module
);
1058 if (image_find_section(fmap
, ".stab", &stab_sect
) &&
1059 image_find_section(fmap
, ".stabstr", &stabstr_sect
))
1062 const char* stabstr
;
1064 stab
= image_map_section(&stab_sect
);
1065 stabstr
= image_map_section(&stabstr_sect
);
1066 if (stab
!= IMAGE_NO_MAP
&& stabstr
!= IMAGE_NO_MAP
)
1068 /* OK, now just parse all of the stabs. */
1069 lret
= stabs_parse(module
, module
->format_info
[DFI_ELF
]->u
.elf_info
->elf_addr
,
1070 stab
, image_get_map_size(&stab_sect
) / sizeof(struct stab_nlist
), sizeof(struct stab_nlist
),
1071 stabstr
, image_get_map_size(&stabstr_sect
),
1074 /* and fill in the missing information for stabs */
1075 elf_finish_stabs_info(module
, ht_symtab
);
1077 WARN("Couldn't correctly read stabs\n");
1080 image_unmap_section(&stab_sect
);
1081 image_unmap_section(&stabstr_sect
);
1083 lret
= dwarf2_parse(module
, module
->reloc_delta
, thunks
, fmap
);
1086 if (wcsstr(module
->modulename
, S_ElfW
) || !wcscmp(module
->modulename
, S_WineLoaderW
))
1088 /* add the thunks for native libraries */
1089 if (!(dbghelp_options
& SYMOPT_PUBLICS_ONLY
))
1090 elf_new_wine_thunks(module
, ht_symtab
, thunks
);
1092 /* add all the public symbols from symtab */
1093 if (elf_new_public_symbols(module
, ht_symtab
) && !ret
) ret
= TRUE
;
1098 /******************************************************************
1099 * elf_load_debug_info
1101 * Loads ELF debugging information from the module image file.
1103 static BOOL
elf_load_debug_info(struct process
* process
, struct module
* module
)
1107 struct hash_table ht_symtab
;
1108 struct module_format
* modfmt
;
1110 if (module
->type
!= DMT_ELF
|| !(modfmt
= module
->format_info
[DFI_ELF
]) || !modfmt
->u
.elf_info
)
1112 ERR("Bad elf module '%s'\n", debugstr_w(module
->module
.LoadedImageName
));
1116 pool_init(&pool
, 65536);
1117 hash_table_init(&pool
, &ht_symtab
, 256);
1119 ret
= elf_load_debug_info_from_map(module
, &modfmt
->u
.elf_info
->file_map
, &pool
, &ht_symtab
);
1121 pool_destroy(&pool
);
1125 /******************************************************************
1126 * elf_fetch_file_info
1128 * Gathers some more information for an ELF module from a given file
1130 static BOOL
elf_fetch_file_info(struct process
* process
, const WCHAR
* name
, ULONG_PTR load_addr
, DWORD_PTR
* base
, DWORD
* size
, DWORD
* checksum
)
1132 struct image_file_map fmap
;
1134 struct elf_map_file_data emfd
;
1136 emfd
.kind
= from_file
;
1137 emfd
.u
.file
.filename
= name
;
1138 if (!elf_map_file(&emfd
, &fmap
)) return FALSE
;
1139 if (base
) *base
= fmap
.u
.elf
.elf_start
;
1140 *size
= fmap
.u
.elf
.elf_size
;
1141 *checksum
= calc_crc32(fmap
.u
.elf
.handle
);
1142 image_unmap_file(&fmap
);
1146 static BOOL
elf_load_file_from_fmap(struct process
* pcs
, const WCHAR
* filename
,
1147 struct image_file_map
* fmap
, ULONG_PTR load_offset
,
1148 ULONG_PTR dyn_addr
, struct elf_info
* elf_info
)
1152 if (elf_info
->flags
& ELF_INFO_DEBUG_HEADER
)
1154 struct image_section_map ism
;
1156 if (elf_find_section_type(fmap
, ".dynamic", ELF_SHT_DYNAMIC
, &ism
))
1158 char* ptr
= (char*)(ULONG_PTR
)fmap
->u
.elf
.sect
[ism
.sidx
].shdr
.sh_addr
;
1161 if (load_offset
) ptr
+= load_offset
- fmap
->u
.elf
.elf_start
;
1163 if (fmap
->addr_size
== 32)
1167 INT32 d_tag
; /* Dynamic entry type */
1168 UINT32 d_val
; /* Integer or address value */
1173 if (!ReadProcessMemory(pcs
->handle
, ptr
, &dyn
, sizeof(dyn
), &len
) ||
1176 if (dyn
.d_tag
== ELF_DT_DEBUG
)
1178 elf_info
->dbg_hdr_addr
= dyn
.d_val
;
1179 if (load_offset
== 0 && dyn_addr
== 0) /* likely the case */
1180 /* Assume this module (the Wine loader) has been
1181 * loaded at its preferred address */
1182 dyn_addr
= ism
.fmap
->u
.elf
.sect
[ism
.sidx
].shdr
.sh_addr
;
1186 } while (dyn
.d_tag
);
1187 if (!dyn
.d_tag
) return ret
;
1193 INT64 d_tag
; /* Dynamic entry type */
1194 UINT64 d_val
; /* Integer or address value */
1199 if (!ReadProcessMemory(pcs
->handle
, ptr
, &dyn
, sizeof(dyn
), &len
) ||
1202 if (dyn
.d_tag
== ELF_DT_DEBUG
)
1204 elf_info
->dbg_hdr_addr
= dyn
.d_val
;
1205 if (load_offset
== 0 && dyn_addr
== 0) /* likely the case */
1206 /* Assume this module (the Wine loader) has been
1207 * loaded at its preferred address */
1208 dyn_addr
= ism
.fmap
->u
.elf
.sect
[ism
.sidx
].shdr
.sh_addr
;
1212 } while (dyn
.d_tag
);
1213 if (!dyn
.d_tag
) return ret
;
1219 if (elf_info
->flags
& ELF_INFO_MODULE
)
1221 struct elf_module_info
*elf_module_info
;
1222 struct module_format
* modfmt
;
1223 struct image_section_map ism
;
1224 ULONG_PTR modbase
= load_offset
;
1226 if (elf_find_section_type(fmap
, ".dynamic", ELF_SHT_DYNAMIC
, &ism
))
1228 ULONG_PTR rva_dyn
= elf_get_map_rva(&ism
);
1230 TRACE("For module %s, got ELF (start=%Ix dyn=%Ix), link_map (start=%Ix dyn=%Ix)\n",
1231 debugstr_w(filename
), (ULONG_PTR
)fmap
->u
.elf
.elf_start
, rva_dyn
,
1232 load_offset
, dyn_addr
);
1233 if (dyn_addr
&& load_offset
+ rva_dyn
!= dyn_addr
)
1235 WARN("\thave to relocate: %Ix\n", dyn_addr
- rva_dyn
);
1236 modbase
= dyn_addr
- rva_dyn
;
1238 } else WARN("For module %s, no .dynamic section\n", debugstr_w(filename
));
1241 modfmt
= HeapAlloc(GetProcessHeap(), 0,
1242 sizeof(struct module_format
) + sizeof(struct elf_module_info
));
1243 if (!modfmt
) return FALSE
;
1244 elf_info
->module
= module_new(pcs
, filename
, DMT_ELF
, FALSE
, modbase
,
1245 fmap
->u
.elf
.elf_size
, 0, calc_crc32(fmap
->u
.elf
.handle
),
1246 elf_get_machine(fmap
->u
.elf
.elfhdr
.e_machine
));
1247 if (!elf_info
->module
)
1249 HeapFree(GetProcessHeap(), 0, modfmt
);
1252 elf_info
->module
->reloc_delta
= elf_info
->module
->module
.BaseOfImage
- fmap
->u
.elf
.elf_start
;
1253 elf_module_info
= (void*)(modfmt
+ 1);
1254 elf_info
->module
->format_info
[DFI_ELF
] = modfmt
;
1255 modfmt
->module
= elf_info
->module
;
1256 modfmt
->remove
= elf_module_remove
;
1257 modfmt
->loc_compute
= NULL
;
1258 modfmt
->u
.elf_info
= elf_module_info
;
1260 elf_module_info
->elf_addr
= load_offset
;
1262 elf_module_info
->file_map
= *fmap
;
1263 elf_reset_file_map(fmap
);
1265 elf_module_info
->elf_mark
= 1;
1266 elf_module_info
->elf_loader
= 0;
1270 if (elf_info
->flags
& ELF_INFO_NAME
)
1273 ptr
= HeapAlloc(GetProcessHeap(), 0, (lstrlenW(filename
) + 1) * sizeof(WCHAR
));
1276 lstrcpyW(ptr
, filename
);
1277 elf_info
->module_name
= ptr
;
1285 /******************************************************************
1288 * Loads the information for ELF module stored in 'filename'
1289 * the module has been loaded at 'load_offset' address
1291 * -1 if the file cannot be found/opened
1292 * 0 if the file doesn't contain symbolic info (or this info cannot be
1296 static BOOL
elf_load_file(struct process
* pcs
, const WCHAR
* filename
,
1297 ULONG_PTR load_offset
, ULONG_PTR dyn_addr
,
1298 struct elf_info
* elf_info
)
1301 struct image_file_map fmap
;
1302 struct elf_map_file_data emfd
;
1304 TRACE("Processing elf file '%s' at %08Ix\n", debugstr_w(filename
), load_offset
);
1306 emfd
.kind
= from_file
;
1307 emfd
.u
.file
.filename
= filename
;
1308 if (!elf_map_file(&emfd
, &fmap
)) return ret
;
1310 /* Next, we need to find a few of the internal ELF headers within
1311 * this thing. We need the main executable header, and the section
1314 if (!fmap
.u
.elf
.elf_start
&& !load_offset
)
1315 ERR("Relocatable ELF %s, but no load address. Loading at 0x0000000\n",
1316 debugstr_w(filename
));
1318 ret
= elf_load_file_from_fmap(pcs
, filename
, &fmap
, load_offset
, dyn_addr
, elf_info
);
1320 image_unmap_file(&fmap
);
1325 struct elf_load_file_params
1327 struct process
*process
;
1328 ULONG_PTR load_offset
;
1330 struct elf_info
*elf_info
;
1333 static BOOL
elf_load_file_cb(void *param
, HANDLE handle
, const WCHAR
*filename
)
1335 struct elf_load_file_params
*load_file
= param
;
1336 return elf_load_file(load_file
->process
, filename
, load_file
->load_offset
, load_file
->dyn_addr
, load_file
->elf_info
);
1339 /******************************************************************
1342 * Locate a value from the debuggee auxiliary vector
1344 static BOOL
elf_search_auxv(const struct process
* pcs
, unsigned type
, ULONG_PTR
* val
)
1346 char buffer
[sizeof(SYMBOL_INFO
) + MAX_SYM_NAME
];
1347 SYMBOL_INFO
*si
= (SYMBOL_INFO
*)buffer
;
1348 const unsigned ptr_size
= pcs
->is_system_64bit
? 8 : 4;
1354 si
->SizeOfStruct
= sizeof(*si
);
1355 si
->MaxNameLen
= MAX_SYM_NAME
;
1356 if (!SymFromName(pcs
->handle
, "ntdll.so!main_envp", si
) ||
1358 !read_process_integral_value(pcs
, si
->Address
, &envp
, ptr_size
) ||
1361 FIXME("can't find symbol in module\n");
1364 /* walk through envp[] */
1365 /* envp[] strings are located after the auxiliary vector, so protect the walk */
1366 str_max
= ~(UINT64
)0u;
1370 if (!read_process_integral_value(pcs
, addr
, &str
, ptr_size
) || (addr
+= ptr_size
) <= ptr_size
)
1373 /* It can be some env vars have been changed, pointing to a different location */
1375 str_max
= min(str_max
, str
);
1378 /* Walk through the end of envp[] array.
1379 * Actually, there can be several NULLs at the end of envp[]. This happens when an env variable is
1380 * deleted, the last entry is replaced by an extra NULL.
1382 for (; addr
< str_max
; addr
+= ptr_size
)
1384 if (!read_process_integral_value(pcs
, addr
, &str
, ptr_size
)) return FALSE
;
1388 if (pcs
->is_system_64bit
)
1396 while (read_process_memory(pcs
, addr
, &auxv
, sizeof(auxv
)) && auxv
.a_type
)
1398 if (auxv
.a_type
== type
)
1403 addr
+= sizeof(auxv
);
1414 while (read_process_memory(pcs
, addr
, &auxv
, sizeof(auxv
)) && auxv
.a_type
)
1416 if (auxv
.a_type
== type
)
1421 addr
+= sizeof(auxv
);
1428 /******************************************************************
1429 * elf_search_and_load_file
1431 * lookup a file in standard ELF locations, and if found, load it
1433 static BOOL
elf_search_and_load_file(struct process
* pcs
, const WCHAR
* filename
,
1434 ULONG_PTR load_offset
, ULONG_PTR dyn_addr
,
1435 struct elf_info
* elf_info
)
1438 struct module
* module
;
1440 if (filename
== NULL
|| *filename
== '\0') return FALSE
;
1441 if ((module
= module_is_already_loaded(pcs
, filename
)))
1443 elf_info
->module
= module
;
1444 elf_info
->module
->format_info
[DFI_ELF
]->u
.elf_info
->elf_mark
= 1;
1445 return module
->module
.SymType
;
1448 if (wcsstr(filename
, L
"libstdc++")) return FALSE
; /* We know we can't do it */
1449 ret
= elf_load_file(pcs
, filename
, load_offset
, dyn_addr
, elf_info
);
1450 /* if relative pathname, try some absolute base dirs */
1451 if (!ret
&& filename
== file_name(filename
))
1453 struct elf_load_file_params load_elf
;
1454 load_elf
.process
= pcs
;
1455 load_elf
.load_offset
= load_offset
;
1456 load_elf
.dyn_addr
= dyn_addr
;
1457 load_elf
.elf_info
= elf_info
;
1459 ret
= search_unix_path(filename
, process_getenv(pcs
, L
"LD_LIBRARY_PATH"), elf_load_file_cb
, &load_elf
)
1460 || search_dll_path(pcs
, filename
, IMAGE_FILE_MACHINE_UNKNOWN
, elf_load_file_cb
, &load_elf
);
1466 typedef BOOL (*enum_elf_modules_cb
)(const WCHAR
*, ULONG_PTR load_addr
,
1467 ULONG_PTR dyn_addr
, BOOL is_system
, void* user
);
1469 /******************************************************************
1470 * elf_enum_modules_internal
1472 * Enumerate ELF modules from a running process
1474 static BOOL
elf_enum_modules_internal(const struct process
* pcs
,
1475 const WCHAR
* main_name
,
1476 enum_elf_modules_cb cb
, void* user
)
1478 WCHAR bufstrW
[MAX_PATH
];
1482 if (pcs
->is_system_64bit
)
1497 UINT64 l_next
, l_prev
;
1500 if (!pcs
->dbg_hdr_addr
|| !read_process_memory(pcs
, pcs
->dbg_hdr_addr
, &dbg_hdr
, sizeof(dbg_hdr
)))
1503 /* Now walk the linked list. In all known ELF implementations,
1504 * the dynamic loader maintains this linked list for us. In some
1505 * cases the first entry doesn't appear with a name, in other cases it
1508 for (lm_addr
= dbg_hdr
.r_map
; lm_addr
; lm_addr
= lm
.l_next
)
1510 if (!read_process_memory(pcs
, lm_addr
, &lm
, sizeof(lm
)))
1513 if (lm
.l_prev
&& /* skip first entry, normally debuggee itself */
1514 lm
.l_name
&& read_process_memory(pcs
, lm
.l_name
, bufstr
, sizeof(bufstr
)))
1516 bufstr
[sizeof(bufstr
) - 1] = '\0';
1517 MultiByteToWideChar(CP_UNIXCP
, 0, bufstr
, -1, bufstrW
, ARRAY_SIZE(bufstrW
));
1518 if (main_name
&& !bufstrW
[0]) lstrcpyW(bufstrW
, main_name
);
1519 if (!cb(bufstrW
, (ULONG_PTR
)lm
.l_addr
, (ULONG_PTR
)lm
.l_ld
, FALSE
, user
))
1539 UINT32 l_next
, l_prev
;
1542 if (!pcs
->dbg_hdr_addr
|| !read_process_memory(pcs
, pcs
->dbg_hdr_addr
, &dbg_hdr
, sizeof(dbg_hdr
)))
1545 /* Now walk the linked list. In all known ELF implementations,
1546 * the dynamic loader maintains this linked list for us. In some
1547 * cases the first entry doesn't appear with a name, in other cases it
1550 for (lm_addr
= dbg_hdr
.r_map
; lm_addr
; lm_addr
= lm
.l_next
)
1552 if (!read_process_memory(pcs
, lm_addr
, &lm
, sizeof(lm
)))
1555 if (lm
.l_prev
&& /* skip first entry, normally debuggee itself */
1556 lm
.l_name
&& read_process_memory(pcs
, lm
.l_name
, bufstr
, sizeof(bufstr
)))
1558 bufstr
[sizeof(bufstr
) - 1] = '\0';
1559 MultiByteToWideChar(CP_UNIXCP
, 0, bufstr
, -1, bufstrW
, ARRAY_SIZE(bufstrW
));
1560 if (main_name
&& !bufstrW
[0]) lstrcpyW(bufstrW
, main_name
);
1561 if (!cb(bufstrW
, (ULONG_PTR
)lm
.l_addr
, (ULONG_PTR
)lm
.l_ld
, FALSE
, user
))
1569 ULONG_PTR ehdr_addr
;
1571 if (elf_search_auxv(pcs
, ELF_AT_SYSINFO_EHDR
, &ehdr_addr
))
1572 cb(L
"[vdso].so", ehdr_addr
, 0, TRUE
, user
);
1577 struct elf_enum_user
1583 static BOOL
elf_enum_modules_translate(const WCHAR
* name
, ULONG_PTR load_addr
,
1584 ULONG_PTR dyn_addr
, BOOL is_system
, void* user
)
1586 struct elf_enum_user
* eeu
= user
;
1587 return eeu
->cb(name
, load_addr
, eeu
->user
);
1590 /******************************************************************
1593 * Enumerates the ELF loaded modules from a running target (hProc)
1594 * This function doesn't require that someone has called SymInitialize
1595 * on this very process.
1597 static BOOL
elf_enum_modules(struct process
* process
, enum_modules_cb cb
, void* user
)
1599 struct elf_info elf_info
;
1601 struct elf_enum_user eeu
;
1603 elf_info
.flags
= ELF_INFO_DEBUG_HEADER
| ELF_INFO_NAME
;
1604 elf_info
.module_name
= NULL
;
1607 ret
= elf_enum_modules_internal(process
, elf_info
.module_name
, elf_enum_modules_translate
, &eeu
);
1608 HeapFree(GetProcessHeap(), 0, (char*)elf_info
.module_name
);
1614 struct process
* pcs
;
1615 struct elf_info elf_info
;
1620 /******************************************************************
1623 * Callback for elf_load_module, used to walk the list of loaded
1626 static BOOL
elf_load_cb(const WCHAR
* name
, ULONG_PTR load_addr
,
1627 ULONG_PTR dyn_addr
, BOOL is_system
, void* user
)
1629 struct elf_load
* el
= user
;
1633 if (is_system
) /* virtual ELF module, created by system. handle it from memory */
1635 struct module
* module
;
1636 struct elf_map_file_data emfd
;
1637 struct image_file_map fmap
;
1639 if ((module
= module_is_already_loaded(el
->pcs
, name
)))
1641 el
->elf_info
.module
= module
;
1642 el
->elf_info
.module
->format_info
[DFI_ELF
]->u
.elf_info
->elf_mark
= 1;
1643 return module
->module
.SymType
;
1646 emfd
.kind
= from_process
;
1647 emfd
.u
.process
.handle
= el
->pcs
->handle
;
1648 emfd
.u
.process
.load_addr
= (void*)load_addr
;
1650 if (elf_map_file(&emfd
, &fmap
))
1651 el
->ret
= elf_load_file_from_fmap(el
->pcs
, name
, &fmap
, load_addr
, 0, &el
->elf_info
);
1656 /* memcmp is needed for matches when bufstr contains also version information
1657 * el->name: libc.so, name: libc.so.6.0
1659 p
= file_name(name
);
1662 if (!el
->name
|| !memcmp(p
, el
->name
, lstrlenW(el
->name
) * sizeof(WCHAR
)))
1664 el
->ret
= elf_search_and_load_file(el
->pcs
, name
, load_addr
, dyn_addr
, &el
->elf_info
);
1665 if (el
->name
) ret
= FALSE
;
1671 /******************************************************************
1674 * loads an ELF module and stores it in process' module list
1675 * Also, find module real name and load address from
1676 * the real loaded modules list in pcs address space
1678 static struct module
* elf_load_module(struct process
* pcs
, const WCHAR
* name
, ULONG_PTR addr
)
1682 TRACE("(%p %s %08Ix)\n", pcs
, debugstr_w(name
), addr
);
1684 el
.elf_info
.flags
= ELF_INFO_MODULE
;
1687 if (pcs
->dbg_hdr_addr
) /* we're debugging a life target */
1690 /* do only the lookup from the filename, not the path (as we lookup module
1691 * name in the process' loaded module list)
1693 el
.name
= file_name(name
);
1696 if (!elf_enum_modules_internal(pcs
, NULL
, elf_load_cb
, &el
))
1702 el
.ret
= elf_search_and_load_file(pcs
, el
.name
, addr
, 0, &el
.elf_info
);
1704 if (!el
.ret
) return NULL
;
1705 assert(el
.elf_info
.module
);
1706 return el
.elf_info
.module
;
1709 /******************************************************************
1710 * elf_synchronize_module_list
1712 * this function rescans the debuggee module's list and synchronizes it with
1713 * the one from 'pcs', i.e.:
1714 * - if a module is in debuggee and not in pcs, it's loaded into pcs
1715 * - if a module is in pcs and not in debuggee, it's unloaded from pcs
1717 static BOOL
elf_synchronize_module_list(struct process
* pcs
)
1719 struct module
* module
;
1722 for (module
= pcs
->lmodules
; module
; module
= module
->next
)
1724 if (module
->type
== DMT_ELF
&& !module
->is_virtual
)
1725 module
->format_info
[DFI_ELF
]->u
.elf_info
->elf_mark
= 0;
1729 el
.elf_info
.flags
= ELF_INFO_MODULE
;
1731 el
.name
= NULL
; /* fetch all modules */
1733 if (!elf_enum_modules_internal(pcs
, NULL
, elf_load_cb
, &el
))
1736 module
= pcs
->lmodules
;
1739 if (module
->type
== DMT_ELF
&& !module
->is_virtual
)
1741 struct elf_module_info
* elf_info
= module
->format_info
[DFI_ELF
]->u
.elf_info
;
1743 if (!elf_info
->elf_mark
&& !elf_info
->elf_loader
)
1745 module_remove(pcs
, module
);
1746 /* restart all over */
1747 module
= pcs
->lmodules
;
1751 module
= module
->next
;
1756 static const struct loader_ops elf_loader_ops
=
1758 elf_synchronize_module_list
,
1760 elf_load_debug_info
,
1762 elf_fetch_file_info
,
1765 /******************************************************************
1766 * elf_read_wine_loader_dbg_info
1768 * Try to find a decent wine executable which could have loaded the debuggee
1770 BOOL
elf_read_wine_loader_dbg_info(struct process
* pcs
, ULONG_PTR addr
)
1772 struct elf_info elf_info
;
1776 elf_info
.flags
= ELF_INFO_DEBUG_HEADER
| ELF_INFO_MODULE
;
1777 loader
= get_wine_loader_name(pcs
);
1780 ret
= elf_search_and_load_file(pcs
, loader
, addr
, 0, &elf_info
);
1781 HeapFree(GetProcessHeap(), 0, loader
);
1783 if (!ret
|| !elf_info
.dbg_hdr_addr
) return FALSE
;
1784 if (elf_info
.dbg_hdr_addr
!= (ULONG_PTR
)elf_info
.dbg_hdr_addr
)
1786 ERR("Unable to access ELF libraries (outside 32bit limit)\n");
1787 module_remove(pcs
, elf_info
.module
);
1788 pcs
->loader
= &empty_loader_ops
;
1791 TRACE("Found ELF debug header %#I64x\n", elf_info
.dbg_hdr_addr
);
1792 elf_info
.module
->format_info
[DFI_ELF
]->u
.elf_info
->elf_loader
= 1;
1793 module_set_module(elf_info
.module
, S_WineLoaderW
);
1794 pcs
->dbg_hdr_addr
= elf_info
.dbg_hdr_addr
;
1795 pcs
->loader
= &elf_loader_ops
;