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 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) */
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 /******************************************************************
127 * Maps a single section into memory from an ELF file
129 static const char* elf_map_section(struct image_section_map
* ism
)
131 struct elf_file_map
* fmap
= &ism
->fmap
->u
.elf
;
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
)
140 if (fmap
->target_copy
)
142 return fmap
->target_copy
+ fmap
->sect
[ism
->sidx
].shdr
.sh_offset
;
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
)))
150 ERR("map creation %p failed %u offset %lu %lu size %lu\n", fmap
->handle
, GetLastError(), ofst
, ofst
% 4096, size
);
153 fmap
->sect
[ism
->sidx
].mapped
= MapViewOfFile(mapping
, FILE_MAP_READ
, 0, ofst
, size
);
154 CloseHandle(mapping
);
155 if (!fmap
->sect
[ism
->sidx
].mapped
)
157 ERR("map %p failed %u offset %lu %lu size %lu\n", fmap
->handle
, GetLastError(), ofst
, ofst
% 4096, size
);
160 return fmap
->sect
[ism
->sidx
].mapped
+ (fmap
->sect
[ism
->sidx
].shdr
.sh_offset
& (sysinfo
.dwAllocationGranularity
- 1));
163 /******************************************************************
166 * Finds a section by name (and type) into memory from an ELF file
167 * or its alternate if any
169 static BOOL
elf_find_section(struct image_file_map
* _fmap
, const char* name
, struct image_section_map
* ism
)
171 struct elf_file_map
* fmap
= &_fmap
->u
.elf
;
174 if (fmap
->shstrtab
== IMAGE_NO_MAP
)
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
;
179 for (i
= 0; i
< fmap
->elfhdr
.e_shnum
; i
++)
181 if (strcmp(fmap
->shstrtab
+ fmap
->sect
[i
].shdr
.sh_name
, name
) == 0)
191 static BOOL
elf_find_section_type(struct image_file_map
* _fmap
, const char* name
, unsigned sht
, struct image_section_map
* ism
)
193 struct elf_file_map
* fmap
;
198 if (_fmap
->modtype
!= DMT_ELF
) break;
199 fmap
= &_fmap
->u
.elf
;
200 if (fmap
->shstrtab
== IMAGE_NO_MAP
)
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;
205 for (i
= 0; i
< fmap
->elfhdr
.e_shnum
; i
++)
207 if (strcmp(fmap
->shstrtab
+ fmap
->sect
[i
].shdr
.sh_name
, name
) == 0 && sht
== fmap
->sect
[i
].shdr
.sh_type
)
214 _fmap
= _fmap
->alternate
;
221 /******************************************************************
224 * Unmaps a single section from memory
226 static void elf_unmap_section(struct image_section_map
* ism
)
228 struct elf_file_map
* fmap
= &ism
->fmap
->u
.elf
;
230 if (ism
->sidx
>= 0 && ism
->sidx
< fmap
->elfhdr
.e_shnum
&& !fmap
->target_copy
&&
231 fmap
->sect
[ism
->sidx
].mapped
)
233 if (!UnmapViewOfFile(fmap
->sect
[ism
->sidx
].mapped
))
234 WARN("Couldn't unmap the section\n");
235 fmap
->sect
[ism
->sidx
].mapped
= NULL
;
239 static void elf_end_find(struct image_file_map
* fmap
)
241 struct image_section_map ism
;
243 while (fmap
&& fmap
->modtype
== DMT_ELF
)
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
;
253 /******************************************************************
256 * Get the RVA of an ELF section
258 static DWORD_PTR
elf_get_map_rva(const struct image_section_map
* ism
)
260 if (ism
->sidx
< 0 || ism
->sidx
>= ism
->fmap
->u
.elf
.elfhdr
.e_shnum
)
262 return ism
->fmap
->u
.elf
.sect
[ism
->sidx
].shdr
.sh_addr
- ism
->fmap
->u
.elf
.elf_start
;
265 /******************************************************************
268 * Get the size of an ELF section
270 static unsigned elf_get_map_size(const struct image_section_map
* ism
)
272 if (ism
->sidx
< 0 || ism
->sidx
>= ism
->fmap
->u
.elf
.elfhdr
.e_shnum
)
274 return ism
->fmap
->u
.elf
.sect
[ism
->sidx
].shdr
.sh_size
;
277 /******************************************************************
280 * Unmaps an ELF file from memory (previously mapped with elf_map_file)
282 static void elf_unmap_file(struct image_file_map
* fmap
)
284 if (fmap
->u
.elf
.handle
!= INVALID_HANDLE_VALUE
)
286 struct image_section_map ism
;
288 for (ism
.sidx
= 0; ism
.sidx
< fmap
->u
.elf
.elfhdr
.e_shnum
; ism
.sidx
++)
290 elf_unmap_section(&ism
);
292 HeapFree(GetProcessHeap(), 0, fmap
->u
.elf
.sect
);
293 CloseHandle(fmap
->u
.elf
.handle
);
295 HeapFree(GetProcessHeap(), 0, fmap
->u
.elf
.target_copy
);
298 static const struct image_file_map_ops elf_file_map_ops
=
308 static inline void elf_reset_file_map(struct image_file_map
* fmap
)
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
;
317 struct elf_map_file_data
319 enum {from_file
, from_process
, from_handle
} kind
;
324 const WCHAR
* filename
;
335 static BOOL
elf_map_file_read(struct image_file_map
* fmap
, struct elf_map_file_data
* emfd
,
336 void* buf
, size_t len
, size_t off
)
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
);
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
;
359 static BOOL
elf_map_shdr(struct elf_map_file_data
* emfd
, struct image_file_map
* fmap
, unsigned int i
)
361 if (fmap
->addr_size
== 32)
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 */
377 if (!elf_map_file_read(fmap
, emfd
, &shdr32
, sizeof(shdr32
),
378 fmap
->u
.elf
.elfhdr
.e_shoff
+ i
* sizeof(shdr32
)))
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
;
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
)))
401 /******************************************************************
404 * Maps an ELF file into memory (and checks it's a real ELF file)
406 static BOOL
elf_map_file(struct elf_map_file_data
* emfd
, struct image_file_map
* fmap
)
409 size_t tmp
, page_mask
= sysinfo
.dwPageSize
- 1;
411 unsigned char e_ident
[ARRAY_SIZE(fmap
->u
.elf
.elfhdr
.e_ident
)];
413 elf_reset_file_map(fmap
);
415 fmap
->modtype
= DMT_ELF
;
416 fmap
->u
.elf
.handle
= INVALID_HANDLE_VALUE
;
417 fmap
->u
.elf
.target_copy
= NULL
;
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
);
425 if (fmap
->u
.elf
.handle
== INVALID_HANDLE_VALUE
) return FALSE
;
428 if (!DuplicateHandle(GetCurrentProcess(), emfd
->u
.handle
, GetCurrentProcess(), &fmap
->u
.elf
.handle
, GENERIC_READ
, FALSE
, 0))
435 if (!elf_map_file_read(fmap
, emfd
, e_ident
, sizeof(e_ident
), 0))
438 /* and check for an ELF header */
439 if (memcmp(e_ident
, "\177ELF", 4))
442 fmap
->addr_size
= e_ident
[4] == 2 /* ELFCLASS64 */ ? 64 : 32;
444 if (fmap
->addr_size
== 32)
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 */
464 if (!elf_map_file_read(fmap
, emfd
, &elfhdr32
, sizeof(elfhdr32
), 0))
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
;
484 if (!elf_map_file_read(fmap
, emfd
, &fmap
->u
.elf
.elfhdr
, sizeof(fmap
->u
.elf
.elfhdr
), 0))
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
;
492 for (i
= 0; i
< fmap
->u
.elf
.elfhdr
.e_shnum
; i
++)
494 if (!elf_map_shdr(emfd
, fmap
, i
))
496 HeapFree(GetProcessHeap(), 0, fmap
->u
.elf
.sect
);
497 fmap
->u
.elf
.sect
= NULL
;
500 fmap
->u
.elf
.sect
[i
].mapped
= NULL
;
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
++)
508 if (fmap
->addr_size
== 32)
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 */
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
)
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
;
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 */
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
)
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
;
555 /* if non relocatable ELF, then remove fixed address from computation
556 * otherwise, all addresses are zero based and start has no effect
558 fmap
->u
.elf
.elf_size
-= fmap
->u
.elf
.elf_start
;
563 case from_file
: break;
565 if (!(fmap
->u
.elf
.target_copy
= HeapAlloc(GetProcessHeap(), 0, fmap
->u
.elf
.elf_size
)))
567 HeapFree(GetProcessHeap(), 0, fmap
->u
.elf
.sect
);
570 if (!ReadProcessMemory(emfd
->u
.process
.handle
, emfd
->u
.process
.load_addr
, fmap
->u
.elf
.target_copy
,
571 fmap
->u
.elf
.elf_size
, NULL
))
573 HeapFree(GetProcessHeap(), 0, fmap
->u
.elf
.target_copy
);
574 HeapFree(GetProcessHeap(), 0, fmap
->u
.elf
.sect
);
582 BOOL
elf_map_handle(HANDLE handle
, struct image_file_map
* fmap
)
584 struct elf_map_file_data emfd
;
585 emfd
.kind
= from_handle
;
586 emfd
.u
.handle
= handle
;
587 return elf_map_file(&emfd
, fmap
);
590 static void elf_module_remove(struct process
* pcs
, struct module_format
* modfmt
)
592 image_unmap_file(&modfmt
->u
.elf_info
->file_map
);
593 HeapFree(GetProcessHeap(), 0, modfmt
);
596 /******************************************************************
597 * elf_is_in_thunk_area
599 * Check whether an address lies within one of the thunk area we
602 int elf_is_in_thunk_area(ULONG_PTR addr
,
603 const struct elf_thunk_area
* thunks
)
607 if (thunks
) for (i
= 0; thunks
[i
].symname
; i
++)
609 if (addr
>= thunks
[i
].rva_start
&& addr
< thunks
[i
].rva_end
)
615 /******************************************************************
618 * creating an internal hash table to ease use ELF symtab information lookup
620 static void elf_hash_symtab(struct module
* module
, struct pool
* pool
,
621 struct hash_table
* ht_symtab
, struct image_file_map
* fmap
,
622 struct elf_thunk_area
* thunks
)
627 struct symt_compiland
* compiland
= NULL
;
629 struct symtab_elt
* ste
;
630 struct image_section_map ism
, ism_str
;
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
)
640 image_unmap_section(&ism
);
644 nsym
= image_get_map_size(&ism
) /
645 (fmap
->addr_size
== 32 ? sizeof(struct elf_sym32
) : sizeof(struct elf_sym
));
647 for (j
= 0; thunks
[j
].symname
; j
++)
648 thunks
[j
].rva_start
= thunks
[j
].rva_end
= 0;
650 for (i
= 0; i
< nsym
; i
++)
655 if (fmap
->addr_size
== 32)
657 struct elf_sym32
*sym32
= &((struct elf_sym32
*)symtab
)[i
];
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
;
667 sym
= ((struct elf_sym
*)symtab
)[i
];
669 type
= sym
.st_info
& 0xf;
671 /* Ignore certain types of entries which really aren't of that much
674 if ((type
!= ELF_STT_NOTYPE
&& type
!= ELF_STT_FILE
&& type
!= ELF_STT_OBJECT
&& type
!= ELF_STT_FUNC
)
680 symname
= strp
+ sym
.st_name
;
682 /* handle some specific symtab (that we'll throw away when done) */
687 compiland
= symt_new_compiland(module
, sym
.st_value
,
688 source_new(module
, NULL
, symname
));
693 /* we are only interested in wine markers inserted by winebuild */
694 for (j
= 0; thunks
[j
].symname
; j
++)
696 if (!strcmp(symname
, thunks
[j
].symname
))
698 thunks
[j
].rva_start
= sym
.st_value
;
699 thunks
[j
].rva_end
= sym
.st_value
+ sym
.st_size
;
706 /* FIXME: we don't need to handle them (GCC internals)
707 * Moreover, they screw up our symbol lookup :-/
709 if (symname
[0] == '.' && symname
[1] == 'L' && isdigit(symname
[2]))
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)
721 ptr
= symname
+ strlen(symname
) - 1;
724 while (isdigit(*ptr
) && ptr
>= symname
) ptr
--;
725 if (ptr
> symname
&& *ptr
== '.')
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
;
734 ste
->compiland
= compiland
;
736 hash_table_add(ht_symtab
, &ste
->ht_elt
);
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
744 /******************************************************************
747 * lookup a symbol by name in our internal hash table for the symtab
749 static const struct elf_sym
*elf_lookup_symtab(const struct module
* module
,
750 const struct hash_table
* ht_symtab
,
751 const char* name
, const struct symt
* compiland
)
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
;
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.)
767 compiland_name
= source_get(module
,
768 ((const struct symt_compiland
*)compiland
)->source
);
769 compiland_basename
= file_nameA(compiland_name
);
771 else compiland_name
= compiland_basename
= NULL
;
773 hash_table_iter_init(ht_symtab
, &hti
, name
);
774 while ((ste
= hash_table_iter_up(&hti
)))
776 if (ste
->used
|| strcmp(ste
->ht_elt
.name
, name
)) continue;
779 if ((ste
->compiland
&& !compiland_name
) || (!ste
->compiland
&& compiland_name
))
781 if (ste
->compiland
&& compiland_name
)
783 const char* filename
= source_get(module
, ste
->compiland
->source
);
784 if (strcmp(filename
, compiland_name
))
786 base
= file_nameA(filename
);
787 if (strcmp(base
, compiland_basename
)) continue;
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
);
803 if (!result
&& !(result
= weak_result
))
805 FIXME("Couldn't find symbol %s!%s in symtab\n",
806 debugstr_w(module
->module
.ModuleName
), name
);
812 static BOOL
elf_is_local_symbol(unsigned int info
)
817 /******************************************************************
818 * elf_finish_stabs_info
820 * - get any relevant information (address & size) from the bits we got from the
821 * stabs debugging information
823 static void elf_finish_stabs_info(struct module
* module
, const struct hash_table
* symtab
)
825 struct hash_table_iter hti
;
828 const struct elf_sym
* symp
;
829 struct elf_module_info
* elf_info
= module
->format_info
[DFI_ELF
]->u
.elf_info
;
831 hash_table_iter_init(&module
->ht_symbols
, &hti
, NULL
);
832 while ((ptr
= hash_table_iter_up(&hti
)))
834 sym
= CONTAINING_RECORD(ptr
, struct symt_ht
, hash_elt
);
835 switch (sym
->symt
.tag
)
838 if (((struct symt_function
*)sym
)->address
!= elf_info
->elf_addr
&&
839 ((struct symt_function
*)sym
)->size
)
843 symp
= elf_lookup_symtab(module
, symtab
, sym
->hash_elt
.name
,
844 ((struct symt_function
*)sym
)->container
);
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
);
858 ((struct symt_function
*)sym
)->address
= elf_info
->elf_addr
+ symp
->st_value
;
859 ((struct symt_function
*)sym
)->size
= symp
->st_size
;
861 FIXME("Couldn't find %s!%s\n",
862 debugstr_w(module
->module
.ModuleName
), sym
->hash_elt
.name
);
865 switch (((struct symt_data
*)sym
)->kind
)
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
)
872 symp
= elf_lookup_symtab(module
, symtab
, sym
->hash_elt
.name
,
873 ((struct symt_data
*)sym
)->container
);
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
) ?
884 DataIsFileStatic
: DataIsGlobal
;
886 FIXME("Couldn't find %s!%s\n",
887 debugstr_w(module
->module
.ModuleName
), sym
->hash_elt
.name
);
893 FIXME("Unsupported tag %u\n", sym
->symt
.tag
);
897 /* since we may have changed some addresses & sizes, mark the module to be resorted */
898 module
->sortlist_valid
= FALSE
;
901 /******************************************************************
902 * elf_load_wine_thunks
904 * creating the thunk objects for a wine native DLL
906 static int elf_new_wine_thunks(struct module
* module
, const struct hash_table
* ht_symtab
,
907 const struct elf_thunk_area
* thunks
)
910 struct hash_table_iter hti
;
911 struct symtab_elt
* ste
;
913 struct symt_ht
* symt
;
915 hash_table_iter_init(ht_symtab
, &hti
, NULL
);
916 while ((ste
= hash_table_iter_up(&hti
)))
918 if (ste
->used
) continue;
920 addr
= module
->reloc_delta
+ ste
->sym
.st_value
;
922 j
= elf_is_in_thunk_area(ste
->sym
.st_value
, thunks
);
923 if (j
>= 0) /* thunk found */
925 symt_new_thunk(module
, ste
->compiland
, ste
->ht_elt
.name
, thunks
[j
].ordinal
,
926 addr
, ste
->sym
.st_size
);
933 symt
= symt_find_nearest(module
, addr
);
934 if (symt
&& !symt_get_address(&symt
->symt
, &ref_addr
))
936 if (!symt
|| addr
!= ref_addr
)
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
942 switch (ste
->sym
.st_info
& 0xf)
945 symt_new_function(module
, ste
->compiland
, ste
->ht_elt
.name
,
946 addr
, ste
->sym
.st_size
, NULL
);
949 loc
.kind
= loc_absolute
;
952 symt_new_global_variable(module
, ste
->compiland
, ste
->ht_elt
.name
,
953 elf_is_local_symbol(ste
->sym
.st_info
),
954 loc
, ste
->sym
.st_size
, NULL
);
957 FIXME("Shouldn't happen\n");
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
967 module
->sortlist_valid
= TRUE
;
971 /* see comment above */
972 module
->sortlist_valid
= FALSE
;
976 /******************************************************************
977 * elf_new_public_symbols
979 * Creates a set of public symbols from an ELF symtab
981 static int elf_new_public_symbols(struct module
* module
, const struct hash_table
* symtab
)
983 struct hash_table_iter hti
;
984 struct symtab_elt
* ste
;
986 if (dbghelp_options
& SYMOPT_NO_PUBLICS
) return TRUE
;
988 /* FIXME: we're missing the ELF entry point here */
990 hash_table_iter_init(symtab
, &hti
, NULL
);
991 while ((ste
= hash_table_iter_up(&hti
)))
993 symt_new_public(module
, ste
->compiland
, ste
->ht_elt
.name
,
995 module
->reloc_delta
+ ste
->sym
.st_value
,
1001 /******************************************************************
1002 * elf_load_debug_info_from_map
1004 * Loads the symbolic information from ELF module which mapping is described
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
1010 * 0 if the file doesn't contain symbolic info (or this info cannot be
1014 static BOOL
elf_load_debug_info_from_map(struct module
* module
,
1015 struct image_file_map
* fmap
,
1017 struct hash_table
* ht_symtab
)
1019 BOOL ret
= FALSE
, lret
;
1020 struct elf_thunk_area thunks
[] =
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 */
1031 module
->module
.SymType
= SymExport
;
1033 /* create a hash table for the symtab */
1034 elf_hash_symtab(module
, pool
, ht_symtab
, fmap
, thunks
);
1036 if (!(dbghelp_options
& SYMOPT_PUBLICS_ONLY
))
1038 struct image_section_map stab_sect
, stabstr_sect
;
1040 /* check if we need an alternate file (from debuglink or build-id) */
1041 ret
= image_check_alternate(fmap
, module
);
1043 if (image_find_section(fmap
, ".stab", &stab_sect
) &&
1044 image_find_section(fmap
, ".stabstr", &stabstr_sect
))
1047 const char* stabstr
;
1049 stab
= image_map_section(&stab_sect
);
1050 stabstr
= image_map_section(&stabstr_sect
);
1051 if (stab
!= IMAGE_NO_MAP
&& stabstr
!= IMAGE_NO_MAP
)
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
),
1059 /* and fill in the missing information for stabs */
1060 elf_finish_stabs_info(module
, ht_symtab
);
1062 WARN("Couldn't correctly read stabs\n");
1065 image_unmap_section(&stab_sect
);
1066 image_unmap_section(&stabstr_sect
);
1068 lret
= dwarf2_parse(module
, module
->reloc_delta
, thunks
, fmap
);
1071 if (wcsstr(module
->module
.ModuleName
, S_ElfW
) ||
1072 !wcscmp(module
->module
.ModuleName
, S_WineLoaderW
))
1074 /* add the thunks for native libraries */
1075 if (!(dbghelp_options
& SYMOPT_PUBLICS_ONLY
))
1076 elf_new_wine_thunks(module
, ht_symtab
, thunks
);
1078 /* add all the public symbols from symtab */
1079 if (elf_new_public_symbols(module
, ht_symtab
) && !ret
) ret
= TRUE
;
1084 /******************************************************************
1085 * elf_load_debug_info
1087 * Loads ELF debugging information from the module image file.
1089 static BOOL
elf_load_debug_info(struct process
* process
, struct module
* module
)
1093 struct hash_table ht_symtab
;
1094 struct module_format
* modfmt
;
1096 if (module
->type
!= DMT_ELF
|| !(modfmt
= module
->format_info
[DFI_ELF
]) || !modfmt
->u
.elf_info
)
1098 ERR("Bad elf module '%s'\n", debugstr_w(module
->module
.LoadedImageName
));
1102 pool_init(&pool
, 65536);
1103 hash_table_init(&pool
, &ht_symtab
, 256);
1105 ret
= elf_load_debug_info_from_map(module
, &modfmt
->u
.elf_info
->file_map
, &pool
, &ht_symtab
);
1107 pool_destroy(&pool
);
1111 /******************************************************************
1112 * elf_fetch_file_info
1114 * Gathers some more information for an ELF module from a given file
1116 static BOOL
elf_fetch_file_info(struct process
* process
, const WCHAR
* name
, ULONG_PTR load_addr
, DWORD_PTR
* base
, DWORD
* size
, DWORD
* checksum
)
1118 struct image_file_map fmap
;
1120 struct elf_map_file_data emfd
;
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
);
1132 static BOOL
elf_load_file_from_fmap(struct process
* pcs
, const WCHAR
* filename
,
1133 struct image_file_map
* fmap
, ULONG_PTR load_offset
,
1134 ULONG_PTR dyn_addr
, struct elf_info
* elf_info
)
1138 if (elf_info
->flags
& ELF_INFO_DEBUG_HEADER
)
1140 struct image_section_map ism
;
1142 if (elf_find_section_type(fmap
, ".dynamic", ELF_SHT_DYNAMIC
, &ism
))
1144 char* ptr
= (char*)(ULONG_PTR
)fmap
->u
.elf
.sect
[ism
.sidx
].shdr
.sh_addr
;
1147 if (load_offset
) ptr
+= load_offset
- fmap
->u
.elf
.elf_start
;
1149 if (fmap
->addr_size
== 32)
1153 INT32 d_tag
; /* Dynamic entry type */
1154 UINT32 d_val
; /* Integer or address value */
1159 if (!ReadProcessMemory(pcs
->handle
, ptr
, &dyn
, sizeof(dyn
), &len
) ||
1162 if (dyn
.d_tag
== ELF_DT_DEBUG
)
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
;
1172 } while (dyn
.d_tag
);
1173 if (!dyn
.d_tag
) return ret
;
1179 INT64 d_tag
; /* Dynamic entry type */
1180 UINT64 d_val
; /* Integer or address value */
1185 if (!ReadProcessMemory(pcs
->handle
, ptr
, &dyn
, sizeof(dyn
), &len
) ||
1188 if (dyn
.d_tag
== ELF_DT_DEBUG
)
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
;
1198 } while (dyn
.d_tag
);
1199 if (!dyn
.d_tag
) return ret
;
1205 if (elf_info
->flags
& ELF_INFO_MODULE
)
1207 struct elf_module_info
*elf_module_info
;
1208 struct module_format
* modfmt
;
1209 struct image_section_map ism
;
1210 ULONG_PTR modbase
= load_offset
;
1212 if (elf_find_section_type(fmap
, ".dynamic", ELF_SHT_DYNAMIC
, &ism
))
1214 ULONG_PTR rva_dyn
= elf_get_map_rva(&ism
);
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
)
1221 WARN("\thave to relocate: %lx\n", dyn_addr
- rva_dyn
);
1222 modbase
= dyn_addr
- rva_dyn
;
1224 } else WARN("For module %s, no .dynamic section\n", debugstr_w(filename
));
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
)
1234 HeapFree(GetProcessHeap(), 0, modfmt
);
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
;
1245 elf_module_info
->elf_addr
= load_offset
;
1247 elf_module_info
->file_map
= *fmap
;
1248 elf_reset_file_map(fmap
);
1249 if (dbghelp_options
& SYMOPT_DEFERRED_LOADS
)
1251 elf_info
->module
->module
.SymType
= SymDeferred
;
1254 else ret
= elf_load_debug_info(pcs
, elf_info
->module
);
1256 elf_module_info
->elf_mark
= 1;
1257 elf_module_info
->elf_loader
= 0;
1260 if (elf_info
->flags
& ELF_INFO_NAME
)
1263 ptr
= HeapAlloc(GetProcessHeap(), 0, (lstrlenW(filename
) + 1) * sizeof(WCHAR
));
1266 lstrcpyW(ptr
, filename
);
1267 elf_info
->module_name
= ptr
;
1275 /******************************************************************
1278 * Loads the information for ELF module stored in 'filename'
1279 * the module has been loaded at 'load_offset' address
1281 * -1 if the file cannot be found/opened
1282 * 0 if the file doesn't contain symbolic info (or this info cannot be
1286 static BOOL
elf_load_file(struct process
* pcs
, const WCHAR
* filename
,
1287 ULONG_PTR load_offset
, ULONG_PTR dyn_addr
,
1288 struct elf_info
* elf_info
)
1291 struct image_file_map fmap
;
1292 struct elf_map_file_data emfd
;
1294 TRACE("Processing elf file '%s' at %08lx\n", debugstr_w(filename
), load_offset
);
1296 emfd
.kind
= from_file
;
1297 emfd
.u
.file
.filename
= filename
;
1298 if (!elf_map_file(&emfd
, &fmap
)) return ret
;
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
1304 if (!fmap
.u
.elf
.elf_start
&& !load_offset
)
1305 ERR("Relocatable ELF %s, but no load address. Loading at 0x0000000\n",
1306 debugstr_w(filename
));
1308 ret
= elf_load_file_from_fmap(pcs
, filename
, &fmap
, load_offset
, dyn_addr
, elf_info
);
1310 image_unmap_file(&fmap
);
1315 struct elf_load_file_params
1317 struct process
*process
;
1318 ULONG_PTR load_offset
;
1320 struct elf_info
*elf_info
;
1323 static BOOL
elf_load_file_cb(void *param
, HANDLE handle
, const WCHAR
*filename
)
1325 struct elf_load_file_params
*load_file
= param
;
1326 return elf_load_file(load_file
->process
, filename
, load_file
->load_offset
, load_file
->dyn_addr
, load_file
->elf_info
);
1329 /******************************************************************
1332 * locate some a value from the debuggee auxiliary vector
1334 static BOOL
elf_search_auxv(const struct process
* pcs
, unsigned type
, ULONG_PTR
* val
)
1336 char buffer
[sizeof(SYMBOL_INFO
) + MAX_SYM_NAME
];
1337 SYMBOL_INFO
*si
= (SYMBOL_INFO
*)buffer
;
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
) ||
1349 FIXME("can't find symbol in module\n");
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
);
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.
1363 while (addr
< str_max
&& ReadProcessMemory(pcs
->handle
, addr
, &str
, sizeof(str
), NULL
) && str
== NULL
)
1364 addr
= (void*)((DWORD_PTR
)addr
+ sizeof(str
));
1374 while (ReadProcessMemory(pcs
->handle
, addr
, &auxv
, sizeof(auxv
), NULL
) && auxv
.a_type
)
1376 if (auxv
.a_type
== type
)
1381 addr
+= sizeof(auxv
);
1392 while (ReadProcessMemory(pcs
->handle
, addr
, &auxv
, sizeof(auxv
), NULL
) && auxv
.a_type
)
1394 if (auxv
.a_type
== type
)
1399 addr
+= sizeof(auxv
);
1406 /******************************************************************
1407 * elf_search_and_load_file
1409 * lookup a file in standard ELF locations, and if found, load it
1411 static BOOL
elf_search_and_load_file(struct process
* pcs
, const WCHAR
* filename
,
1412 ULONG_PTR load_offset
, ULONG_PTR dyn_addr
,
1413 struct elf_info
* elf_info
)
1416 struct module
* module
;
1417 static const WCHAR S_libstdcPPW
[] = {'l','i','b','s','t','d','c','+','+','\0'};
1419 if (filename
== NULL
|| *filename
== '\0') return FALSE
;
1420 if ((module
= module_is_already_loaded(pcs
, filename
)))
1422 elf_info
->module
= module
;
1423 elf_info
->module
->format_info
[DFI_ELF
]->u
.elf_info
->elf_mark
= 1;
1424 return module
->module
.SymType
;
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
))
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
;
1438 ret
= search_unix_path(filename
, process_getenv(pcs
, L
"LD_LIBRARY_PATH"), elf_load_file_cb
, &load_elf
)
1439 || search_dll_path(pcs
, filename
, elf_load_file_cb
, &load_elf
);
1445 typedef BOOL (*enum_elf_modules_cb
)(const WCHAR
*, ULONG_PTR load_addr
,
1446 ULONG_PTR dyn_addr
, BOOL is_system
, void* user
);
1448 /******************************************************************
1449 * elf_enum_modules_internal
1451 * Enumerate ELF modules from a running process
1453 static BOOL
elf_enum_modules_internal(const struct process
* pcs
,
1454 const WCHAR
* main_name
,
1455 enum_elf_modules_cb cb
, void* user
)
1457 WCHAR bufstrW
[MAX_PATH
];
1476 UINT64 l_next
, l_prev
;
1479 if (!pcs
->dbg_hdr_addr
|| !read_process_memory(pcs
, pcs
->dbg_hdr_addr
, &dbg_hdr
, sizeof(dbg_hdr
)))
1482 /* Now walk the linked list. In all known ELF implementations,
1483 * the dynamic loader maintains this linked list for us. In some
1484 * cases the first entry doesn't appear with a name, in other cases it
1487 for (lm_addr
= dbg_hdr
.r_map
; lm_addr
; lm_addr
= lm
.l_next
)
1489 if (!read_process_memory(pcs
, lm_addr
, &lm
, sizeof(lm
)))
1492 if (lm
.l_prev
&& /* skip first entry, normally debuggee itself */
1493 lm
.l_name
&& read_process_memory(pcs
, lm
.l_name
, bufstr
, sizeof(bufstr
)))
1495 bufstr
[sizeof(bufstr
) - 1] = '\0';
1496 MultiByteToWideChar(CP_UNIXCP
, 0, bufstr
, -1, bufstrW
, ARRAY_SIZE(bufstrW
));
1497 if (main_name
&& !bufstrW
[0]) lstrcpyW(bufstrW
, main_name
);
1498 if (!cb(bufstrW
, (ULONG_PTR
)lm
.l_addr
, (ULONG_PTR
)lm
.l_ld
, FALSE
, user
))
1518 UINT32 l_next
, l_prev
;
1521 if (!pcs
->dbg_hdr_addr
|| !read_process_memory(pcs
, pcs
->dbg_hdr_addr
, &dbg_hdr
, sizeof(dbg_hdr
)))
1524 /* Now walk the linked list. In all known ELF implementations,
1525 * the dynamic loader maintains this linked list for us. In some
1526 * cases the first entry doesn't appear with a name, in other cases it
1529 for (lm_addr
= dbg_hdr
.r_map
; lm_addr
; lm_addr
= lm
.l_next
)
1531 if (!read_process_memory(pcs
, lm_addr
, &lm
, sizeof(lm
)))
1534 if (lm
.l_prev
&& /* skip first entry, normally debuggee itself */
1535 lm
.l_name
&& read_process_memory(pcs
, lm
.l_name
, bufstr
, sizeof(bufstr
)))
1537 bufstr
[sizeof(bufstr
) - 1] = '\0';
1538 MultiByteToWideChar(CP_UNIXCP
, 0, bufstr
, -1, bufstrW
, ARRAY_SIZE(bufstrW
));
1539 if (main_name
&& !bufstrW
[0]) lstrcpyW(bufstrW
, main_name
);
1540 if (!cb(bufstrW
, (ULONG_PTR
)lm
.l_addr
, (ULONG_PTR
)lm
.l_ld
, FALSE
, user
))
1548 ULONG_PTR ehdr_addr
;
1550 if (elf_search_auxv(pcs
, ELF_AT_SYSINFO_EHDR
, &ehdr_addr
))
1552 static const WCHAR vdsoW
[] = {'[','v','d','s','o',']','.','s','o',0};
1553 cb(vdsoW
, ehdr_addr
, 0, TRUE
, user
);
1559 struct elf_enum_user
1565 static BOOL
elf_enum_modules_translate(const WCHAR
* name
, ULONG_PTR load_addr
,
1566 ULONG_PTR dyn_addr
, BOOL is_system
, void* user
)
1568 struct elf_enum_user
* eeu
= user
;
1569 return eeu
->cb(name
, load_addr
, eeu
->user
);
1572 /******************************************************************
1575 * Enumerates the ELF loaded modules from a running target (hProc)
1576 * This function doesn't require that someone has called SymInitialize
1577 * on this very process.
1579 static BOOL
elf_enum_modules(struct process
* process
, enum_modules_cb cb
, void* user
)
1581 struct elf_info elf_info
;
1583 struct elf_enum_user eeu
;
1585 elf_info
.flags
= ELF_INFO_DEBUG_HEADER
| ELF_INFO_NAME
;
1586 elf_info
.module_name
= NULL
;
1589 ret
= elf_enum_modules_internal(process
, elf_info
.module_name
, elf_enum_modules_translate
, &eeu
);
1590 HeapFree(GetProcessHeap(), 0, (char*)elf_info
.module_name
);
1596 struct process
* pcs
;
1597 struct elf_info elf_info
;
1602 /******************************************************************
1605 * Callback for elf_load_module, used to walk the list of loaded
1608 static BOOL
elf_load_cb(const WCHAR
* name
, ULONG_PTR load_addr
,
1609 ULONG_PTR dyn_addr
, BOOL is_system
, void* user
)
1611 struct elf_load
* el
= user
;
1615 if (is_system
) /* virtual ELF module, created by system. handle it from memory */
1617 struct module
* module
;
1618 struct elf_map_file_data emfd
;
1619 struct image_file_map fmap
;
1621 if ((module
= module_is_already_loaded(el
->pcs
, name
)))
1623 el
->elf_info
.module
= module
;
1624 el
->elf_info
.module
->format_info
[DFI_ELF
]->u
.elf_info
->elf_mark
= 1;
1625 return module
->module
.SymType
;
1628 emfd
.kind
= from_process
;
1629 emfd
.u
.process
.handle
= el
->pcs
->handle
;
1630 emfd
.u
.process
.load_addr
= (void*)load_addr
;
1632 if (elf_map_file(&emfd
, &fmap
))
1633 el
->ret
= elf_load_file_from_fmap(el
->pcs
, name
, &fmap
, load_addr
, 0, &el
->elf_info
);
1638 /* memcmp is needed for matches when bufstr contains also version information
1639 * el->name: libc.so, name: libc.so.6.0
1641 p
= file_name(name
);
1644 if (!el
->name
|| !memcmp(p
, el
->name
, lstrlenW(el
->name
) * sizeof(WCHAR
)))
1646 el
->ret
= elf_search_and_load_file(el
->pcs
, name
, load_addr
, dyn_addr
, &el
->elf_info
);
1647 if (el
->name
) ret
= FALSE
;
1653 /******************************************************************
1656 * loads an ELF module and stores it in process' module list
1657 * Also, find module real name and load address from
1658 * the real loaded modules list in pcs address space
1660 static struct module
* elf_load_module(struct process
* pcs
, const WCHAR
* name
, ULONG_PTR addr
)
1664 TRACE("(%p %s %08lx)\n", pcs
, debugstr_w(name
), addr
);
1666 el
.elf_info
.flags
= ELF_INFO_MODULE
;
1669 if (pcs
->dbg_hdr_addr
) /* we're debugging a life target */
1672 /* do only the lookup from the filename, not the path (as we lookup module
1673 * name in the process' loaded module list)
1675 el
.name
= file_name(name
);
1678 if (!elf_enum_modules_internal(pcs
, NULL
, elf_load_cb
, &el
))
1684 el
.ret
= elf_search_and_load_file(pcs
, el
.name
, addr
, 0, &el
.elf_info
);
1686 if (!el
.ret
) return NULL
;
1687 assert(el
.elf_info
.module
);
1688 return el
.elf_info
.module
;
1691 /******************************************************************
1692 * elf_synchronize_module_list
1694 * this function rescans the debuggee module's list and synchronizes it with
1695 * the one from 'pcs', i.e.:
1696 * - if a module is in debuggee and not in pcs, it's loaded into pcs
1697 * - if a module is in pcs and not in debuggee, it's unloaded from pcs
1699 static BOOL
elf_synchronize_module_list(struct process
* pcs
)
1701 struct module
* module
;
1704 for (module
= pcs
->lmodules
; module
; module
= module
->next
)
1706 if (module
->type
== DMT_ELF
&& !module
->is_virtual
)
1707 module
->format_info
[DFI_ELF
]->u
.elf_info
->elf_mark
= 0;
1711 el
.elf_info
.flags
= ELF_INFO_MODULE
;
1713 el
.name
= NULL
; /* fetch all modules */
1715 if (!elf_enum_modules_internal(pcs
, NULL
, elf_load_cb
, &el
))
1718 module
= pcs
->lmodules
;
1721 if (module
->type
== DMT_ELF
&& !module
->is_virtual
)
1723 struct elf_module_info
* elf_info
= module
->format_info
[DFI_ELF
]->u
.elf_info
;
1725 if (!elf_info
->elf_mark
&& !elf_info
->elf_loader
)
1727 module_remove(pcs
, module
);
1728 /* restart all over */
1729 module
= pcs
->lmodules
;
1733 module
= module
->next
;
1738 static const struct loader_ops elf_loader_ops
=
1740 elf_synchronize_module_list
,
1742 elf_load_debug_info
,
1744 elf_fetch_file_info
,
1747 /******************************************************************
1748 * elf_read_wine_loader_dbg_info
1750 * Try to find a decent wine executable which could have loaded the debuggee
1752 BOOL
elf_read_wine_loader_dbg_info(struct process
* pcs
, ULONG_PTR addr
)
1754 struct elf_info elf_info
;
1757 elf_info
.flags
= ELF_INFO_DEBUG_HEADER
| ELF_INFO_MODULE
;
1758 ret
= elf_search_and_load_file(pcs
, get_wine_loader_name(pcs
), addr
, 0, &elf_info
);
1759 if (!ret
|| !elf_info
.dbg_hdr_addr
) return FALSE
;
1761 TRACE("Found ELF debug header %#lx\n", elf_info
.dbg_hdr_addr
);
1762 elf_info
.module
->format_info
[DFI_ELF
]->u
.elf_info
->elf_loader
= 1;
1763 module_set_module(elf_info
.module
, S_WineLoaderW
);
1764 pcs
->dbg_hdr_addr
= elf_info
.dbg_hdr_addr
;
1765 pcs
->loader
= &elf_loader_ops
;