ReactOS 0.4.16-dev-340-g0540c21
dbghelp_private.h File Reference
#include <stdarg.h>
#include "windef.h"
#include "winbase.h"
#include "winver.h"
#include "dbghelp.h"
#include "objbase.h"
#include "oaidl.h"
#include "winnls.h"
#include "wine/list.h"
#include "wine/rbtree.h"
#include "cvconst.h"
Include dependency graph for dbghelp_private.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Classes

struct  pool
 
class  vector< _Tp, >
 
struct  sparse_array
 
struct  hash_table_elt
 
struct  hash_table_bucket
 
struct  hash_table
 
struct  hash_table_iter
 
struct  location
 
struct  symt
 
struct  symt_ht
 
struct  symt_block
 
struct  symt_compiland
 
struct  symt_data
 
struct  symt_function
 
struct  symt_hierarchy_point
 
struct  symt_public
 
struct  symt_thunk
 
struct  symt_array
 
struct  symt_basic
 
struct  symt_enum
 
struct  symt_function_signature
 
struct  symt_function_arg_type
 
struct  symt_pointer
 
struct  symt_typedef
 
struct  symt_udt
 
struct  module_format
 
struct  module
 
struct  loader_ops
 
struct  process
 
struct  line_info
 
struct  module_pair
 
struct  pdb_lookup
 
struct  cpu_stack_walk
 
struct  dump_memory
 
struct  dump_memory64
 
struct  dump_module
 
struct  dump_thread
 
struct  dump_context
 
union  ctx
 
struct  cpu
 
struct  _PEB32
 
struct  pdb_cmd_pair
 

Typedefs

typedef BOOL(* enum_modules_cb) (const WCHAR *, ULONG_PTR addr, void *user)
 
typedef struct _PEB32 PEB32
 
typedef void(* stabs_def_cb) (struct module *module, ULONG_PTR load_offset, const char *name, ULONG_PTR offset, BOOL is_public, BOOL is_global, unsigned char other, struct symt_compiland *compiland, void *user)
 

Enumerations

enum  location_kind {
  loc_error , loc_unavailable , loc_absolute , loc_register ,
  loc_regrel , loc_tlsrel , loc_user
}
 
enum  location_error {
  loc_err_internal = -1 , loc_err_too_complex = -2 , loc_err_out_of_scope = -3 , loc_err_cant_read = -4 ,
  loc_err_no_location = -5
}
 
enum  module_type {
  DMT_UNKNOWN , DMT_ELF , DMT_PE , DMT_MACHO ,
  DMT_PDB , DMT_DBG
}
 
enum  format_info {
  DFI_ELF , DFI_PE , DFI_MACHO , DFI_DWARF ,
  DFI_PDB , DFI_LAST
}
 
enum  pdb_kind { PDB_JG , PDB_DS }
 
enum  cpu_addr { cpu_addr_pc , cpu_addr_stack , cpu_addr_frame }
 

Functions

void pool_init (struct pool *a, size_t arena_size) DECLSPEC_HIDDEN
 
void pool_destroy (struct pool *a) DECLSPEC_HIDDEN
 
voidpool_alloc (struct pool *a, size_t len) DECLSPEC_HIDDEN
 
charpool_strdup (struct pool *a, const char *str) DECLSPEC_HIDDEN
 
void vector_init (struct vector *v, unsigned elt_sz, unsigned bucket_sz) DECLSPEC_HIDDEN
 
unsigned vector_length (const struct vector *v) DECLSPEC_HIDDEN
 
voidvector_at (const struct vector *v, unsigned pos) DECLSPEC_HIDDEN
 
voidvector_add (struct vector *v, struct pool *pool) DECLSPEC_HIDDEN
 
void sparse_array_init (struct sparse_array *sa, unsigned elt_sz, unsigned bucket_sz) DECLSPEC_HIDDEN
 
voidsparse_array_find (const struct sparse_array *sa, ULONG_PTR idx) DECLSPEC_HIDDEN
 
voidsparse_array_add (struct sparse_array *sa, ULONG_PTR key, struct pool *pool) DECLSPEC_HIDDEN
 
unsigned sparse_array_length (const struct sparse_array *sa) DECLSPEC_HIDDEN
 
void hash_table_init (struct pool *pool, struct hash_table *ht, unsigned num_buckets) DECLSPEC_HIDDEN
 
void hash_table_destroy (struct hash_table *ht) DECLSPEC_HIDDEN
 
void hash_table_add (struct hash_table *ht, struct hash_table_elt *elt) DECLSPEC_HIDDEN
 
void hash_table_iter_init (const struct hash_table *ht, struct hash_table_iter *hti, const char *name) DECLSPEC_HIDDEN
 
voidhash_table_iter_up (struct hash_table_iter *hti) DECLSPEC_HIDDEN
 
static BOOL read_process_memory (const struct process *process, UINT64 addr, void *buf, size_t size)
 
struct processprocess_find_by_handle (HANDLE hProcess) DECLSPEC_HIDDEN
 
BOOL validate_addr64 (DWORD64 addr) DECLSPEC_HIDDEN
 
BOOL pcs_callback (const struct process *pcs, ULONG action, void *data) DECLSPEC_HIDDEN
 
voidfetch_buffer (struct process *pcs, unsigned size) DECLSPEC_HIDDEN
 
const charwine_dbgstr_addr (const ADDRESS64 *addr) DECLSPEC_HIDDEN
 
struct cpucpu_find (DWORD) DECLSPEC_HIDDEN
 
const WCHARprocess_getenv (const struct process *process, const WCHAR *name)
 
DWORD calc_crc32 (HANDLE handle) DECLSPEC_HIDDEN
 
BOOL elf_read_wine_loader_dbg_info (struct process *pcs, ULONG_PTR addr) DECLSPEC_HIDDEN
 
int elf_is_in_thunk_area (ULONG_PTR addr, const struct elf_thunk_area *thunks) DECLSPEC_HIDDEN
 
BOOL macho_read_wine_loader_dbg_info (struct process *pcs, ULONG_PTR addr) DECLSPEC_HIDDEN
 
void minidump_add_memory_block (struct dump_context *dc, ULONG64 base, ULONG size, ULONG rva) DECLSPEC_HIDDEN
 
struct modulemodule_find_by_addr (const struct process *pcs, DWORD64 addr, enum module_type type) DECLSPEC_HIDDEN
 
struct modulemodule_find_by_nameW (const struct process *pcs, const WCHAR *name) DECLSPEC_HIDDEN
 
struct modulemodule_find_by_nameA (const struct process *pcs, const char *name) DECLSPEC_HIDDEN
 
struct modulemodule_is_already_loaded (const struct process *pcs, const WCHAR *imgname) DECLSPEC_HIDDEN
 
BOOL module_get_debug (struct module_pair *) DECLSPEC_HIDDEN
 
struct modulemodule_new (struct process *pcs, const WCHAR *name, enum module_type type, BOOL virtual, DWORD64 addr, DWORD64 size, ULONG_PTR stamp, ULONG_PTR checksum) DECLSPEC_HIDDEN
 
struct modulemodule_get_containee (const struct process *pcs, const struct module *inner) DECLSPEC_HIDDEN
 
void module_reset_debug_info (struct module *module) DECLSPEC_HIDDEN
 
BOOL module_remove (struct process *pcs, struct module *module) DECLSPEC_HIDDEN
 
void module_set_module (struct module *module, const WCHAR *name) DECLSPEC_HIDDEN
 
WCHARget_wine_loader_name (struct process *pcs) DECLSPEC_HIDDEN
 
BOOL pe_load_debug_directory (const struct process *pcs, struct module *module, const BYTE *mapping, const IMAGE_SECTION_HEADER *sectp, DWORD nsect, const IMAGE_DEBUG_DIRECTORY *dbg, int nDbg) DECLSPEC_HIDDEN
 
BOOL pdb_fetch_file_info (const struct pdb_lookup *pdb_lookup, unsigned *matched) DECLSPEC_HIDDEN
 
BOOL pdb_virtual_unwind (struct cpu_stack_walk *csw, DWORD_PTR ip, union ctx *context, struct pdb_cmd_pair *cpair) DECLSPEC_HIDDEN
 
BOOL path_find_symbol_file (const struct process *pcs, const struct module *module, PCSTR full_path, enum module_type type, const GUID *guid, DWORD dw1, DWORD dw2, WCHAR *buffer, BOOL *is_unmatched) DECLSPEC_HIDDEN
 
WCHARget_dos_file_name (const WCHAR *filename) DECLSPEC_HIDDEN
 
BOOL search_dll_path (const struct process *process, const WCHAR *name, BOOL(*match)(void *, HANDLE, const WCHAR *), void *param) DECLSPEC_HIDDEN
 
BOOL search_unix_path (const WCHAR *name, const WCHAR *path, BOOL(*match)(void *, HANDLE, const WCHAR *), void *param) DECLSPEC_HIDDEN
 
const WCHARfile_name (const WCHAR *str) DECLSPEC_HIDDEN
 
const charfile_nameA (const char *str) DECLSPEC_HIDDEN
 
BOOL pe_load_nt_header (HANDLE hProc, DWORD64 base, IMAGE_NT_HEADERS *nth) DECLSPEC_HIDDEN
 
struct modulepe_load_native_module (struct process *pcs, const WCHAR *name, HANDLE hFile, DWORD64 base, DWORD size) DECLSPEC_HIDDEN
 
struct modulepe_load_builtin_module (struct process *pcs, const WCHAR *name, DWORD64 base, DWORD64 size) DECLSPEC_HIDDEN
 
BOOL pe_load_debug_info (const struct process *pcs, struct module *module) DECLSPEC_HIDDEN
 
const charpe_map_directory (struct module *module, int dirno, DWORD *size) DECLSPEC_HIDDEN
 
unsigned source_new (struct module *module, const char *basedir, const char *source) DECLSPEC_HIDDEN
 
const charsource_get (const struct module *module, unsigned idx) DECLSPEC_HIDDEN
 
int source_rb_compare (const void *key, const struct wine_rb_entry *entry) DECLSPEC_HIDDEN
 
BOOL stabs_parse (struct module *module, ULONG_PTR load_offset, const char *stabs, size_t nstab, size_t stabsize, const char *strs, int strtablen, stabs_def_cb callback, void *user) DECLSPEC_HIDDEN
 
BOOL dwarf2_parse (struct module *module, ULONG_PTR load_offset, const struct elf_thunk_area *thunks, struct image_file_map *fmap) DECLSPEC_HIDDEN
 
BOOL dwarf2_virtual_unwind (struct cpu_stack_walk *csw, DWORD_PTR ip, union ctx *ctx, DWORD64 *cfa) DECLSPEC_HIDDEN
 
BOOL rsym_parse (struct module *module, unsigned long load_offset, const void *rsym, int rsymlen) DECLSPEC_HIDDEN
 
BOOL sw_read_mem (struct cpu_stack_walk *csw, DWORD64 addr, void *ptr, DWORD sz) DECLSPEC_HIDDEN
 
DWORD64 sw_xlat_addr (struct cpu_stack_walk *csw, ADDRESS64 *addr) DECLSPEC_HIDDEN
 
voidsw_table_access (struct cpu_stack_walk *csw, DWORD64 addr) DECLSPEC_HIDDEN
 
DWORD64 sw_module_base (struct cpu_stack_walk *csw, DWORD64 addr) DECLSPEC_HIDDEN
 
const charsymt_get_name (const struct symt *sym) DECLSPEC_HIDDEN
 
WCHARsymt_get_nameW (const struct symt *sym) DECLSPEC_HIDDEN
 
BOOL symt_get_address (const struct symt *type, ULONG64 *addr) DECLSPEC_HIDDEN
 
int __cdecl symt_cmp_addr (const void *p1, const void *p2) DECLSPEC_HIDDEN
 
void copy_symbolW (SYMBOL_INFOW *siw, const SYMBOL_INFO *si) DECLSPEC_HIDDEN
 
struct symt_htsymt_find_nearest (struct module *module, DWORD_PTR addr) DECLSPEC_HIDDEN
 
struct symt_compilandsymt_new_compiland (struct module *module, ULONG_PTR address, unsigned src_idx) DECLSPEC_HIDDEN
 
struct symt_publicsymt_new_public (struct module *module, struct symt_compiland *parent, const char *typename, BOOL is_function, ULONG_PTR address, unsigned size) DECLSPEC_HIDDEN
 
struct symt_datasymt_new_global_variable (struct module *module, struct symt_compiland *parent, const char *name, unsigned is_static, struct location loc, ULONG_PTR size, struct symt *type) DECLSPEC_HIDDEN
 
struct symt_functionsymt_new_function (struct module *module, struct symt_compiland *parent, const char *name, ULONG_PTR addr, ULONG_PTR size, struct symt *type) DECLSPEC_HIDDEN
 
BOOL symt_normalize_function (struct module *module, const struct symt_function *func) DECLSPEC_HIDDEN
 
void symt_add_func_line (struct module *module, struct symt_function *func, unsigned source_idx, int line_num, ULONG_PTR offset) DECLSPEC_HIDDEN
 
struct symt_datasymt_add_func_local (struct module *module, struct symt_function *func, enum DataKind dt, const struct location *loc, struct symt_block *block, struct symt *type, const char *name) DECLSPEC_HIDDEN
 
struct symt_blocksymt_open_func_block (struct module *module, struct symt_function *func, struct symt_block *block, unsigned pc, unsigned len) DECLSPEC_HIDDEN
 
struct symt_blocksymt_close_func_block (struct module *module, const struct symt_function *func, struct symt_block *block, unsigned pc) DECLSPEC_HIDDEN
 
struct symt_hierarchy_pointsymt_add_function_point (struct module *module, struct symt_function *func, enum SymTagEnum point, const struct location *loc, const char *name) DECLSPEC_HIDDEN
 
BOOL symt_fill_func_line_info (const struct module *module, const struct symt_function *func, DWORD64 addr, IMAGEHLP_LINE64 *line) DECLSPEC_HIDDEN
 
BOOL symt_get_func_line_next (const struct module *module, PIMAGEHLP_LINE64 line) DECLSPEC_HIDDEN
 
struct symt_thunksymt_new_thunk (struct module *module, struct symt_compiland *parent, const char *name, THUNK_ORDINAL ord, ULONG_PTR addr, ULONG_PTR size) DECLSPEC_HIDDEN
 
struct symt_datasymt_new_constant (struct module *module, struct symt_compiland *parent, const char *name, struct symt *type, const VARIANT *v) DECLSPEC_HIDDEN
 
struct symt_hierarchy_pointsymt_new_label (struct module *module, struct symt_compiland *compiland, const char *name, ULONG_PTR address) DECLSPEC_HIDDEN
 
struct symtsymt_index2ptr (struct module *module, DWORD id) DECLSPEC_HIDDEN
 
DWORD symt_ptr2index (struct module *module, const struct symt *sym) DECLSPEC_HIDDEN
 
void symt_init_basic (struct module *module) DECLSPEC_HIDDEN
 
BOOL symt_get_info (struct module *module, const struct symt *type, IMAGEHLP_SYMBOL_TYPE_INFO req, void *pInfo) DECLSPEC_HIDDEN
 
struct symt_basicsymt_new_basic (struct module *module, enum BasicType, const char *typename, unsigned size) DECLSPEC_HIDDEN
 
struct symt_udtsymt_new_udt (struct module *module, const char *typename, unsigned size, enum UdtKind kind) DECLSPEC_HIDDEN
 
BOOL symt_set_udt_size (struct module *module, struct symt_udt *type, unsigned size) DECLSPEC_HIDDEN
 
BOOL symt_add_udt_element (struct module *module, struct symt_udt *udt_type, const char *name, struct symt *elt_type, unsigned offset, unsigned size) DECLSPEC_HIDDEN
 
struct symt_enumsymt_new_enum (struct module *module, const char *typename, struct symt *basetype) DECLSPEC_HIDDEN
 
BOOL symt_add_enum_element (struct module *module, struct symt_enum *enum_type, const char *name, int value) DECLSPEC_HIDDEN
 
struct symt_arraysymt_new_array (struct module *module, int min, int max, struct symt *base, struct symt *index) DECLSPEC_HIDDEN
 
struct symt_function_signaturesymt_new_function_signature (struct module *module, struct symt *ret_type, enum CV_call_e call_conv) DECLSPEC_HIDDEN
 
BOOL symt_add_function_signature_parameter (struct module *module, struct symt_function_signature *sig, struct symt *param) DECLSPEC_HIDDEN
 
struct symt_pointersymt_new_pointer (struct module *module, struct symt *ref_type, ULONG_PTR size) DECLSPEC_HIDDEN
 
struct symt_typedefsymt_new_typedef (struct module *module, struct symt *ref, const char *name) DECLSPEC_HIDDEN
 

Variables

unsigned dbghelp_options DECLSPEC_HIDDEN
 

Typedef Documentation

◆ enum_modules_cb

typedef BOOL(* enum_modules_cb) (const WCHAR *, ULONG_PTR addr, void *user)

Definition at line 416 of file dbghelp_private.h.

◆ PEB32

typedef struct _PEB32 PEB32

◆ stabs_def_cb

typedef void(* stabs_def_cb) (struct module *module, ULONG_PTR load_offset, const char *name, ULONG_PTR offset, BOOL is_public, BOOL is_global, unsigned char other, struct symt_compiland *compiland, void *user)

Definition at line 732 of file dbghelp_private.h.

Enumeration Type Documentation

◆ cpu_addr

Enumerator
cpu_addr_pc 
cpu_addr_stack 
cpu_addr_frame 

Definition at line 576 of file dbghelp_private.h.

@ cpu_addr_frame
@ cpu_addr_pc
@ cpu_addr_stack

◆ format_info

Enumerator
DFI_ELF 
DFI_PE 
DFI_MACHO 
DFI_DWARF 
DFI_PDB 
DFI_LAST 

Definition at line 339 of file dbghelp_private.h.

340{
341 DFI_ELF,
342 DFI_PE,
343 DFI_MACHO,
344 DFI_DWARF,
345 DFI_PDB,
347};
@ DFI_ELF
@ DFI_PE
@ DFI_DWARF
@ DFI_LAST
@ DFI_MACHO
@ DFI_PDB

◆ location_error

Enumerator
loc_err_internal 
loc_err_too_complex 
loc_err_out_of_scope 
loc_err_cant_read 
loc_err_no_location 

Definition at line 144 of file dbghelp_private.h.

144 {loc_err_internal = -1, /* internal while computing */
145 loc_err_too_complex = -2, /* couldn't compute location (even at runtime) */
146 loc_err_out_of_scope = -3, /* variable isn't available at current address */
147 loc_err_cant_read = -4, /* couldn't read memory at given address */
148 loc_err_no_location = -5, /* likely optimized away (by compiler) */
149};
@ loc_err_cant_read
@ loc_err_no_location
@ loc_err_too_complex
@ loc_err_internal
@ loc_err_out_of_scope

◆ location_kind

Enumerator
loc_error 
loc_unavailable 
loc_absolute 
loc_register 
loc_regrel 
loc_tlsrel 
loc_user 

Definition at line 134 of file dbghelp_private.h.

134 {loc_error, /* reg is the error code */
135 loc_unavailable, /* location is not available */
136 loc_absolute, /* offset is the location */
137 loc_register, /* reg is the location */
138 loc_regrel, /* [reg+offset] is the location */
139 loc_tlsrel, /* offset is the address of the TLS index */
140 loc_user, /* value is debug information dependent,
141 reg & offset can be used ad libidem */
142};
@ loc_unavailable
@ loc_regrel
@ loc_register
@ loc_user
@ loc_error
@ loc_absolute
@ loc_tlsrel

◆ module_type

Enumerator
DMT_UNKNOWN 
DMT_ELF 
DMT_PE 
DMT_MACHO 
DMT_PDB 
DMT_DBG 

Definition at line 323 of file dbghelp_private.h.

324{
325 DMT_UNKNOWN, /* for lookup, not actually used for a module */
326 DMT_ELF, /* a real ELF shared module */
327 DMT_PE, /* a native or builtin PE module */
328 DMT_MACHO, /* a real Mach-O shared module */
329 DMT_PDB, /* .PDB file */
330 DMT_DBG, /* .DBG file */
331};
@ DMT_UNKNOWN
@ DMT_DBG
@ DMT_PE
@ DMT_MACHO
@ DMT_PDB
@ DMT_ELF

◆ pdb_kind

Enumerator
PDB_JG 
PDB_DS 

Definition at line 476 of file dbghelp_private.h.

476{PDB_JG, PDB_DS};
@ PDB_DS
@ PDB_JG

Function Documentation

◆ calc_crc32()

DWORD calc_crc32 ( HANDLE  handle)

Definition at line 874 of file dbghelp.c.

875{
876 BYTE buffer[8192];
877 DWORD crc = 0;
878 DWORD len;
879
881 while (ReadFile(handle, buffer, sizeof(buffer), &len, NULL) && len)
882 crc = RtlComputeCrc32(crc, buffer, len);
883 return crc;
884}
#define NULL
Definition: types.h:112
#define FILE_BEGIN
Definition: compat.h:761
#define RtlComputeCrc32
Definition: compat.h:810
#define ReadFile(a, b, c, d, e)
Definition: compat.h:742
#define SetFilePointer
Definition: compat.h:743
unsigned long DWORD
Definition: ntddk_ex.h:95
GLuint buffer
Definition: glext.h:5915
GLenum GLsizei len
Definition: glext.h:6722
unsigned char BYTE
Definition: xxhash.c:193

Referenced by elf_fetch_file_info(), elf_load_file_from_fmap(), image_check_debug_link(), macho_fetch_file_info(), and macho_load_file().

◆ copy_symbolW()

void copy_symbolW ( SYMBOL_INFOW siw,
const SYMBOL_INFO si 
)

Definition at line 1029 of file symbol.c.

1030{
1031 siw->SizeOfStruct = si->SizeOfStruct;
1032 siw->TypeIndex = si->TypeIndex;
1033 siw->Reserved[0] = si->Reserved[0];
1034 siw->Reserved[1] = si->Reserved[1];
1035 siw->Index = si->Index;
1036 siw->Size = si->Size;
1037 siw->ModBase = si->ModBase;
1038 siw->Flags = si->Flags;
1039 siw->Value = si->Value;
1040 siw->Address = si->Address;
1041 siw->Register = si->Register;
1042 siw->Scope = si->Scope;
1043 siw->Tag = si->Tag;
1044 siw->NameLen = si->NameLen;
1045 siw->MaxNameLen = si->MaxNameLen;
1046 MultiByteToWideChar(CP_ACP, 0, si->Name, -1, siw->Name, siw->MaxNameLen);
1047}
#define CP_ACP
Definition: compat.h:109
#define MultiByteToWideChar
Definition: compat.h:110
ULONG Scope
Definition: compat.h:1368
ULONG64 Address
Definition: compat.h:1366
ULONG Size
Definition: compat.h:1362
ULONG TypeIndex
Definition: compat.h:1359
ULONG Register
Definition: compat.h:1367
ULONG Flags
Definition: compat.h:1364
ULONG NameLen
Definition: compat.h:1370
ULONG64 Value
Definition: compat.h:1365
WCHAR Name[1]
Definition: compat.h:1372
ULONG64 ModBase
Definition: compat.h:1363
ULONG SizeOfStruct
Definition: compat.h:1358
ULONG Tag
Definition: compat.h:1369
ULONG64 Reserved[2]
Definition: compat.h:1360
ULONG Index
Definition: compat.h:1361
ULONG MaxNameLen
Definition: compat.h:1371
ULONG64 ModBase
Definition: compat.h:1043
ULONG TypeIndex
Definition: compat.h:1039
ULONG SizeOfStruct
Definition: compat.h:1038
ULONG Tag
Definition: compat.h:1049
ULONG NameLen
Definition: compat.h:1050
ULONG64 Value
Definition: compat.h:1045
ULONG Scope
Definition: compat.h:1048
CHAR Name[1]
Definition: compat.h:1052
ULONG64 Address
Definition: compat.h:1046
ULONG Register
Definition: compat.h:1047
ULONG64 Reserved[2]
Definition: compat.h:1040
ULONG Flags
Definition: compat.h:1044
ULONG Index
Definition: compat.h:1041
ULONG MaxNameLen
Definition: compat.h:1051
ULONG Size
Definition: compat.h:1042

Referenced by enum_types_AtoW(), sym_enumW(), and SymFromAddrW().

◆ cpu_find()

struct cpu * cpu_find ( DWORD  machine)

Definition at line 183 of file dbghelp.c.

184{
185 struct cpu** cpu;
186
187 for (cpu = dbghelp_cpus ; *cpu; cpu++)
188 {
189 if (cpu[0]->machine == machine) return cpu[0];
190 }
191 return NULL;
192}
static struct cpu * dbghelp_cpus[]
Definition: dbghelp.c:164
static const char machine[]
Definition: profile.c:104

Referenced by StackWalk(), and StackWalk64().

◆ dwarf2_parse()

BOOL dwarf2_parse ( struct module module,
ULONG_PTR  load_offset,
const struct elf_thunk_area thunks,
struct image_file_map fmap 
)

Definition at line 3509 of file dwarf.c.

3512{
3515 struct image_section_map debug_sect, debug_str_sect, debug_abbrev_sect,
3516 debug_line_sect, debug_ranges_sect, eh_frame_sect;
3517 BOOL ret = TRUE;
3518 struct module_format* dwarf2_modfmt;
3519
3520 if (!dwarf2_init_section(&eh_frame, fmap, ".eh_frame", NULL, &eh_frame_sect))
3521 /* lld produces .eh_fram to avoid generating a long name */
3522 dwarf2_init_section(&eh_frame, fmap, ".eh_fram", NULL, &eh_frame_sect);
3523 dwarf2_init_section(&section[section_debug], fmap, ".debug_info", ".zdebug_info", &debug_sect);
3524 dwarf2_init_section(&section[section_abbrev], fmap, ".debug_abbrev", ".zdebug_abbrev", &debug_abbrev_sect);
3525 dwarf2_init_section(&section[section_string], fmap, ".debug_str", ".zdebug_str", &debug_str_sect);
3526 dwarf2_init_section(&section[section_line], fmap, ".debug_line", ".zdebug_line", &debug_line_sect);
3527 dwarf2_init_section(&section[section_ranges], fmap, ".debug_ranges", ".zdebug_ranges", &debug_ranges_sect);
3528
3529 /* to do anything useful we need either .eh_frame or .debug_info */
3530 if ((!eh_frame.address || eh_frame.address == IMAGE_NO_MAP) &&
3531 (!section[section_debug].address || section[section_debug].address == IMAGE_NO_MAP))
3532 {
3533 ret = FALSE;
3534 goto leave;
3535 }
3536
3537 if (fmap->modtype == DMT_ELF && debug_sect.fmap)
3538 {
3539 /* debug info might have a different base address than .so file
3540 * when elf file is prelinked after splitting off debug info
3541 * adjust symbol base addresses accordingly
3542 */
3543 load_offset += fmap->u.elf.elf_start - debug_sect.fmap->u.elf.elf_start;
3544 }
3545
3546 TRACE("Loading Dwarf2 information for %s\n", debugstr_w(module->module.ModuleName));
3547
3548 mod_ctx.data = section[section_debug].address;
3549 mod_ctx.end_data = mod_ctx.data + section[section_debug].size;
3550 mod_ctx.word_size = 0; /* will be correctly set later on */
3551
3552 dwarf2_modfmt = HeapAlloc(GetProcessHeap(), 0,
3553 sizeof(*dwarf2_modfmt) + sizeof(*dwarf2_modfmt->u.dwarf2_info));
3554 if (!dwarf2_modfmt)
3555 {
3556 ret = FALSE;
3557 goto leave;
3558 }
3559 dwarf2_modfmt->module = module;
3560 dwarf2_modfmt->remove = dwarf2_module_remove;
3561 dwarf2_modfmt->loc_compute = dwarf2_location_compute;
3562 dwarf2_modfmt->u.dwarf2_info = (struct dwarf2_module_info_s*)(dwarf2_modfmt + 1);
3563 dwarf2_modfmt->u.dwarf2_info->word_size = 0; /* will be correctly set later on */
3564 dwarf2_modfmt->module->format_info[DFI_DWARF] = dwarf2_modfmt;
3565
3566 /* As we'll need later some sections' content, we won't unmap these
3567 * sections upon existing this function
3568 */
3569 dwarf2_init_section(&dwarf2_modfmt->u.dwarf2_info->debug_loc, fmap, ".debug_loc", ".zdebug_loc", NULL);
3570 dwarf2_init_section(&dwarf2_modfmt->u.dwarf2_info->debug_frame, fmap, ".debug_frame", ".zdebug_frame", NULL);
3571 dwarf2_modfmt->u.dwarf2_info->eh_frame = eh_frame;
3572
3573 while (mod_ctx.data < mod_ctx.end_data)
3574 {
3575 dwarf2_parse_compilation_unit(section, dwarf2_modfmt->module, thunks, &mod_ctx, load_offset);
3576 }
3577 dwarf2_modfmt->module->module.SymType = SymDia;
3578 dwarf2_modfmt->module->module.CVSig = 'D' | ('W' << 8) | ('A' << 16) | ('R' << 24);
3579 /* FIXME: we could have a finer grain here */
3580 dwarf2_modfmt->module->module.GlobalSymbols = TRUE;
3581 dwarf2_modfmt->module->module.TypeInfo = TRUE;
3582 dwarf2_modfmt->module->module.SourceIndexed = TRUE;
3583 dwarf2_modfmt->module->module.Publics = TRUE;
3584
3585 /* set the word_size for eh_frame parsing */
3586 dwarf2_modfmt->u.dwarf2_info->word_size = fmap->addr_size / 8;
3587
3588leave:
3594
3595 image_unmap_section(&debug_sect);
3596 image_unmap_section(&debug_abbrev_sect);
3597 image_unmap_section(&debug_str_sect);
3598 image_unmap_section(&debug_line_sect);
3599 image_unmap_section(&debug_ranges_sect);
3600 if (!ret) image_unmap_section(&eh_frame_sect);
3601
3602 return ret;
3603}
#define leave
Definition: btrfs_drv.h:138
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define GetProcessHeap()
Definition: compat.h:736
@ SymDia
Definition: compat.h:1063
#define HeapAlloc
Definition: compat.h:733
static BOOL dwarf2_parse_compilation_unit(const dwarf2_section_t *sections, struct module *module, const struct elf_thunk_area *thunks, dwarf2_traverse_context_t *mod_ctx, ULONG_PTR load_offset)
Definition: dwarf.c:2371
static void dwarf2_fini_section(dwarf2_section_t *section)
Definition: dwarf.c:3496
@ section_line
Definition: dwarf.c:164
@ section_max
Definition: dwarf.c:164
@ section_string
Definition: dwarf.c:164
@ section_abbrev
Definition: dwarf.c:164
@ section_debug
Definition: dwarf.c:164
@ section_ranges
Definition: dwarf.c:164
static BOOL dwarf2_init_section(dwarf2_section_t *section, struct image_file_map *fmap, const char *sectname, const char *zsectname, struct image_section_map *ism)
Definition: dwarf.c:3467
static void dwarf2_location_compute(struct process *pcs, const struct module_format *modfmt, const struct symt_function *func, struct location *loc)
Definition: dwarf.c:3324
static void dwarf2_module_remove(struct process *pcs, struct module_format *modfmt)
Definition: dwarf.c:3502
unsigned int BOOL
Definition: ntddk_ex.h:94
#define IMAGE_NO_MAP
Definition: image_private.h:24
static void image_unmap_section(struct image_section_map *ism)
#define debugstr_w
Definition: kernel32.h:32
#define TRACE(s)
Definition: solgame.cpp:4
WCHAR ModuleName[32]
Definition: compat.h:1076
dwarf2_section_t eh_frame
Definition: dwarf.c:201
const unsigned char * address
Definition: dwarf.c:159
unsigned char word_size
Definition: dwarf.c:170
const unsigned char * end_data
Definition: dwarf.c:169
const unsigned char * data
Definition: dwarf.c:168
enum module_type modtype
union image_file_map::@384 u
struct image_file_map::@384::elf_file_map elf
unsigned addr_size
struct module * module
struct dwarf2_module_info_s * dwarf2_info
void(* loc_compute)(struct process *pcs, const struct module_format *modfmt, const struct symt_function *func, struct location *loc)
union module_format::@373 u
void(* remove)(struct process *pcs, struct module_format *modfmt)
IMAGEHLP_MODULEW64 module
Definition: parser.c:56
int ret

Referenced by elf_load_debug_info_from_map(), macho_load_debug_info(), and pe_load_dwarf().

◆ dwarf2_virtual_unwind()

BOOL dwarf2_virtual_unwind ( struct cpu_stack_walk csw,
DWORD_PTR  ip,
union ctx ctx,
DWORD64 cfa 
)

Definition at line 3258 of file dwarf.c.

3260{
3261 struct module_pair pair;
3262 struct frame_info info;
3263 dwarf2_traverse_context_t cie_ctx, fde_ctx;
3264 struct module_format* modfmt;
3265 const unsigned char* end;
3266 DWORD_PTR delta;
3267
3268 if (!(pair.pcs = process_find_by_handle(csw->hProcess)) ||
3269 !(pair.requested = module_find_by_addr(pair.pcs, ip, DMT_UNKNOWN)) ||
3271 return FALSE;
3272 modfmt = pair.effective->format_info[DFI_DWARF];
3273 if (!modfmt) return FALSE;
3274 memset(&info, 0, sizeof(info));
3275 fde_ctx.data = modfmt->u.dwarf2_info->eh_frame.address;
3276 fde_ctx.end_data = fde_ctx.data + modfmt->u.dwarf2_info->eh_frame.size;
3277 fde_ctx.word_size = modfmt->u.dwarf2_info->word_size;
3278 /* let offsets relative to the eh_frame sections be correctly computed, as we'll map
3279 * in this process the IMAGE section at a different address as the one expected by
3280 * the image
3281 */
3282 delta = pair.effective->module.BaseOfImage + modfmt->u.dwarf2_info->eh_frame.rva -
3283 (DWORD_PTR)modfmt->u.dwarf2_info->eh_frame.address;
3284 if (!dwarf2_get_cie(ip, pair.effective, delta, &fde_ctx, &cie_ctx, &info, TRUE))
3285 {
3286 fde_ctx.data = modfmt->u.dwarf2_info->debug_frame.address;
3287 fde_ctx.end_data = fde_ctx.data + modfmt->u.dwarf2_info->debug_frame.size;
3288 fde_ctx.word_size = modfmt->u.dwarf2_info->word_size;
3289 delta = pair.effective->reloc_delta;
3290 if (!dwarf2_get_cie(ip, pair.effective, delta, &fde_ctx, &cie_ctx, &info, FALSE))
3291 {
3292 TRACE("Couldn't find information for %lx\n", ip);
3293 return FALSE;
3294 }
3295 }
3296
3297 TRACE("function %lx/%lx code_align %lu data_align %ld retaddr %s\n",
3298 ip, info.ip, info.code_align, info.data_align,
3299 csw->cpu->fetch_regname(csw->cpu->map_dwarf_register(info.retaddr_reg, pair.effective, TRUE)));
3300
3301 /* if at very beginning of function, return and use default unwinder */
3302 if (ip == info.ip) return FALSE;
3303 execute_cfa_instructions(pair.effective, &cie_ctx, ip, &info);
3304
3305 if (info.aug_z_format) /* get length of augmentation data */
3306 {
3308 end = fde_ctx.data + len;
3309 }
3310 else end = NULL;
3311 dwarf2_parse_augmentation_ptr(&fde_ctx, info.lsda_encoding); /* handler_data */
3312 if (end) fde_ctx.data = end;
3313
3314 execute_cfa_instructions(pair.effective, &fde_ctx, ip, &info);
3315
3316 /* if there is no information about retaddr, use default unwinder */
3317 if (info.state.rules[info.retaddr_reg] == RULE_UNSET) return FALSE;
3318
3319 apply_frame_state(pair.effective, csw, context, &info.state, cfa);
3320
3321 return TRUE;
3322}
struct module * module_find_by_addr(const struct process *pcs, DWORD64 addr, enum module_type type) DECLSPEC_HIDDEN
Definition: module.c:420
BOOL module_get_debug(struct module_pair *) DECLSPEC_HIDDEN
Definition: module.c:374
struct process * process_find_by_handle(HANDLE hProcess)
Definition: dbghelp.c:99
@ RULE_UNSET
Definition: dwarf.c:2558
static BOOL dwarf2_get_cie(ULONG_PTR addr, struct module *module, DWORD_PTR delta, dwarf2_traverse_context_t *fde_ctx, dwarf2_traverse_context_t *cie_ctx, struct frame_info *info, BOOL in_eh_frame)
Definition: dwarf.c:2715
static ULONG_PTR dwarf2_parse_augmentation_ptr(dwarf2_traverse_context_t *ctx, unsigned char encoding)
Definition: dwarf.c:2595
static void apply_frame_state(const struct module *module, struct cpu_stack_walk *csw, union ctx *context, struct frame_state *state, DWORD64 *cfa)
Definition: dwarf.c:3201
static ULONG_PTR dwarf2_leb128_as_unsigned(dwarf2_traverse_context_t *ctx)
Definition: dwarf.c:276
static void execute_cfa_instructions(struct module *module, dwarf2_traverse_context_t *ctx, ULONG_PTR last_ip, struct frame_info *info)
Definition: dwarf.c:2792
GLuint GLuint end
Definition: gl.h:1545
if(dx< 0)
Definition: linetemp.h:194
#define memset(x, y, z)
Definition: compat.h:39
Definition: http.c:7252
struct cpu * cpu
Definition: dhcpd.h:62
Definition: _pair.h:47
#define DWORD_PTR
Definition: treelist.c:76
uint32_t DWORD_PTR
Definition: typedefs.h:65
uint32_t ULONG_PTR
Definition: typedefs.h:65

Referenced by fetch_next_frame32().

◆ elf_is_in_thunk_area()

int elf_is_in_thunk_area ( ULONG_PTR  addr,
const struct elf_thunk_area thunks 
)

Definition at line 602 of file elf_module.c.

604{
605 unsigned i;
606
607 if (thunks) for (i = 0; thunks[i].symname; i++)
608 {
609 if (addr >= thunks[i].rva_start && addr < thunks[i].rva_end)
610 return i;
611 }
612 return -1;
613}
GLenum const GLvoid * addr
Definition: glext.h:9621
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
const char * symname
Definition: elf_module.c:77

Referenced by dwarf2_parse_subprogram(), and elf_new_wine_thunks().

◆ elf_read_wine_loader_dbg_info()

BOOL elf_read_wine_loader_dbg_info ( struct process pcs,
ULONG_PTR  addr 
)

Definition at line 1753 of file elf_module.c.

1754{
1755 struct elf_info elf_info;
1756 WCHAR *loader;
1757 BOOL ret;
1758
1760 loader = get_wine_loader_name(pcs);
1761 ret = elf_search_and_load_file(pcs, loader, addr, 0, &elf_info);
1762 heap_free(loader);
1763 if (!ret || !elf_info.dbg_hdr_addr) return FALSE;
1764
1765 TRACE("Found ELF debug header %#lx\n", elf_info.dbg_hdr_addr);
1766 elf_info.module->format_info[DFI_ELF]->u.elf_info->elf_loader = 1;
1769 pcs->loader = &elf_loader_ops;
1770 return TRUE;
1771}
static BOOL heap_free(void *mem)
Definition: appwiz.h:76
WCHAR * get_wine_loader_name(struct process *pcs) DECLSPEC_HIDDEN
Definition: module.c:150
void module_set_module(struct module *module, const WCHAR *name) DECLSPEC_HIDDEN
Definition: module.c:142
const WCHAR S_WineLoaderW[]
Definition: module.c:42
static BOOL elf_search_and_load_file(struct process *pcs, const WCHAR *filename, ULONG_PTR load_offset, ULONG_PTR dyn_addr, struct elf_info *elf_info)
Definition: elf_module.c:1411
#define ELF_INFO_MODULE
Definition: elf_module.c:34
#define ELF_INFO_DEBUG_HEADER
Definition: elf_module.c:33
static const struct loader_ops elf_loader_ops
Definition: elf_module.c:1739
unsigned flags
Definition: elf_module.c:41
struct module * module
Definition: elf_module.c:43
DWORD_PTR dbg_hdr_addr
Definition: elf_module.c:42
const struct loader_ops * loader
ULONG_PTR dbg_hdr_addr
__wchar_t WCHAR
Definition: xmlstorage.h:180

Referenced by check_live_target().

◆ fetch_buffer()

void * fetch_buffer ( struct process pcs,
unsigned  size 
)

Definition at line 128 of file dbghelp.c.

129{
130 if (size > pcs->buffer_size)
131 {
132 if (pcs->buffer)
133 pcs->buffer = HeapReAlloc(GetProcessHeap(), 0, pcs->buffer, size);
134 else
135 pcs->buffer = HeapAlloc(GetProcessHeap(), 0, size);
136 pcs->buffer_size = (pcs->buffer) ? size : 0;
137 }
138 return pcs->buffer;
139}
#define HeapReAlloc
Definition: compat.h:734
GLsizeiptr size
Definition: glext.h:5919
void * buffer
unsigned buffer_size

Referenced by copy_line_W64_from_64(), and symt_fill_func_line_info().

◆ file_name()

const WCHAR * file_name ( const WCHAR str)

Definition at line 45 of file path.c.

46{
47 const WCHAR* p;
48
49 for (p = str + lstrlenW(str) - 1; p >= str && !is_sep(*p); p--);
50 return p + 1;
51}
#define lstrlenW
Definition: compat.h:750
static BOOL is_sep(WCHAR ch)
Definition: path.c:35
GLfloat GLfloat p
Definition: glext.h:8902
const WCHAR * str

◆ file_nameA()

const char * file_nameA ( const char str)

Definition at line 37 of file path.c.

38{
39 const char* p;
40
41 for (p = str + strlen(str) - 1; p >= str && !is_sepA(*p); p--);
42 return p + 1;
43}
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
static BOOL is_sepA(char ch)
Definition: path.c:34

Referenced by elf_lookup_symtab(), FindDebugInfoFile(), is_wine_loader(), and test_query_process_image_file_name().

◆ get_dos_file_name()

WCHAR * get_dos_file_name ( const WCHAR filename)

Definition at line 671 of file path.c.

672{
673 WCHAR *dos_path;
674 size_t len;
675
676#ifndef __REACTOS__
677 if (*filename == '/')
678 {
679 char *unix_path;
681 unix_path = heap_alloc(len * sizeof(WCHAR));
682 WideCharToMultiByte(CP_UNIXCP, 0, filename, -1, unix_path, len, NULL, NULL);
683 dos_path = wine_get_dos_file_name(unix_path);
684 heap_free(unix_path);
685 }
686 else
687#endif
688 {
690 dos_path = heap_alloc((len + 1) * sizeof(WCHAR));
691 memcpy(dos_path, filename, (len + 1) * sizeof(WCHAR));
692 }
693 return dos_path;
694}
static void * heap_alloc(size_t len)
Definition: appwiz.h:66
#define CP_UNIXCP
Definition: compat.h:79
#define wine_get_dos_file_name(__x)
Definition: compat.h:61
#define WideCharToMultiByte
Definition: compat.h:111
const char * filename
Definition: ioapi.h:137
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878

Referenced by elf_map_file(), image_check_debug_link(), and macho_map_file().

◆ get_wine_loader_name()

WCHAR * get_wine_loader_name ( struct process pcs)

Definition at line 150 of file module.c.

151{
152 static const WCHAR wineW[] = {'w','i','n','e',0};
153 static const WCHAR suffixW[] = {'6','4',0};
154 WCHAR *buffer, *p;
155 const char *env;
156
157 /* All binaries are loaded with WINELOADER (if run from tree) or by the
158 * main executable
159 */
160 if ((env = getenv("WINELOADER")))
161 {
162 DWORD len = 2 + MultiByteToWideChar( CP_UNIXCP, 0, env, -1, NULL, 0 );
163 buffer = heap_alloc( len * sizeof(WCHAR) );
165 }
166 else
167 {
168 buffer = heap_alloc( sizeof(wineW) + 2 * sizeof(WCHAR) );
170 }
171
172 p = buffer + lstrlenW( buffer ) - lstrlenW( suffixW );
173 if (p > buffer && !wcscmp( p, suffixW ))
174 *p = 0;
175
176 if (pcs->is_64bit)
177 lstrcatW(buffer, suffixW);
178
179 TRACE( "returning %s\n", debugstr_w(buffer) );
180 return buffer;
181}
static LPCWSTR LPCWSTR LPCWSTR env
Definition: db.cpp:170
#define lstrcpyW
Definition: compat.h:749
_Check_return_ char *__cdecl getenv(_In_z_ const char *_VarName)
static WCHAR wineW[]
Definition: localmon.c:128
LPWSTR WINAPI lstrcatW(LPWSTR lpString1, LPCWSTR lpString2)
Definition: lstring.c:274
_Check_return_ _CRTIMP int __cdecl wcscmp(_In_z_ const wchar_t *_Str1, _In_z_ const wchar_t *_Str2)

Referenced by elf_read_wine_loader_dbg_info(), and macho_search_loader().

◆ hash_table_add()

void hash_table_add ( struct hash_table ht,
struct hash_table_elt elt 
)

Definition at line 378 of file storage.c.

379{
380 unsigned hash = hash_table_hash(elt->name, ht->num_buckets);
381
382 if (!ht->buckets)
383 {
384 ht->buckets = pool_alloc(ht->pool, ht->num_buckets * sizeof(struct hash_table_bucket));
385 assert(ht->buckets);
386 memset(ht->buckets, 0, ht->num_buckets * sizeof(struct hash_table_bucket));
387 }
388
389 /* in some cases, we need to get back the symbols of same name in the order
390 * in which they've been inserted. So insert new elements at the end of the list.
391 */
392 if (!ht->buckets[hash].first)
393 {
394 ht->buckets[hash].first = elt;
395 }
396 else
397 {
398 ht->buckets[hash].last->next = elt;
399 }
400 ht->buckets[hash].last = elt;
401 elt->next = NULL;
402 ht->num_elts++;
403}
static unsigned hash_table_hash(const char *name, unsigned num_buckets)
Definition: storage.c:319
void * pool_alloc(struct pool *pool, size_t len)
Definition: storage.c:89
#define assert(x)
Definition: debug.h:53
static const struct newhuff ht[]
Definition: huffman.h:296
struct hash_table_elt * next
const char * name
Definition: _hash_fun.h:40

Referenced by elf_hash_symtab(), macho_stabs_def_cb(), pev_set_value(), symt_add_module_ht(), symt_new_basic(), symt_new_typedef(), symt_new_udt(), and symt_ptr2index().

◆ hash_table_destroy()

void hash_table_destroy ( struct hash_table ht)

Definition at line 342 of file storage.c.

343{
344#if defined(USE_STATS)
345 int i;
346 unsigned len;
347 unsigned min = 0xffffffff, max = 0, sq = 0;
348 struct hash_table_elt* elt;
349 double mean, variance;
350
351 for (i = 0; i < ht->num_buckets; i++)
352 {
353 for (len = 0, elt = ht->buckets[i]; elt; elt = elt->next) len++;
354 if (len < min) min = len;
355 if (len > max) max = len;
356 sq += len * len;
357 }
358 mean = (double)ht->num_elts / ht->num_buckets;
359 variance = (double)sq / ht->num_buckets - mean * mean;
360 FIXME("STATS: elts[num:%-4u size:%u mean:%f] buckets[min:%-4u variance:%+f max:%-4u]\n",
361 ht->num_elts, ht->num_buckets, mean, min, variance, max);
362
363 for (i = 0; i < ht->num_buckets; i++)
364 {
365 for (len = 0, elt = ht->buckets[i]; elt; elt = elt->next) len++;
366 if (len == max)
367 {
368 FIXME("Longest bucket:\n");
369 for (elt = ht->buckets[i]; elt; elt = elt->next)
370 FIXME("\t%s\n", elt->name);
371 break;
372 }
373
374 }
375#endif
376}
#define FIXME(fmt,...)
Definition: precomp.h:53
static const char mbstate_t *static wchar_t const char mbstate_t *static const wchar_t int *static double
Definition: string.c:80
#define min(a, b)
Definition: monoChain.cc:55
#define max(a, b)
Definition: svc.c:63

Referenced by module_remove(), and module_reset_debug_info().

◆ hash_table_init()

void hash_table_init ( struct pool pool,
struct hash_table ht,
unsigned  num_buckets 
)

Definition at line 334 of file storage.c.

335{
336 ht->num_elts = 0;
337 ht->num_buckets = num_buckets;
338 ht->pool = pool;
339 ht->buckets = NULL;
340}

Referenced by elf_load_debug_info(), macho_load_debug_info(), module_new(), and pev_init().

◆ hash_table_iter_init()

void hash_table_iter_init ( const struct hash_table ht,
struct hash_table_iter hti,
const char name 
)

Definition at line 405 of file storage.c.

407{
408 hti->ht = ht;
409 if (name)
410 {
411 hti->last = hash_table_hash(name, ht->num_buckets);
412 hti->index = hti->last - 1;
413 }
414 else
415 {
416 hti->last = ht->num_buckets - 1;
417 hti->index = -1;
418 }
419 hti->element = NULL;
420}
struct hash_table_elt * element
const struct hash_table * ht
Definition: name.c:39

Referenced by codeview_add_type_struct(), elf_finish_stabs_info(), elf_lookup_symtab(), elf_new_public_symbols(), elf_new_wine_thunks(), find_name(), macho_finish_stabs(), pe_locate_with_coff_symbol_table(), pev_get_val(), pev_set_value(), SymEnumLines(), symt_enum_module(), symt_find_type_by_name(), and symt_ptr2index().

◆ hash_table_iter_up()

void * hash_table_iter_up ( struct hash_table_iter hti)

Definition at line 422 of file storage.c.

423{
424 if (!hti->ht->buckets) return NULL;
425
426 if (hti->element) hti->element = hti->element->next;
427 while (!hti->element && hti->index < hti->last)
428 hti->element = hti->ht->buckets[++hti->index].first;
429 return hti->element;
430}

Referenced by codeview_add_type_struct(), elf_finish_stabs_info(), elf_lookup_symtab(), elf_new_public_symbols(), elf_new_wine_thunks(), find_name(), macho_finish_stabs(), pe_locate_with_coff_symbol_table(), pev_get_val(), pev_set_value(), SymEnumLines(), symt_enum_module(), symt_find_type_by_name(), and symt_ptr2index().

◆ macho_read_wine_loader_dbg_info()

BOOL macho_read_wine_loader_dbg_info ( struct process pcs,
ULONG_PTR  addr 
)

Definition at line 1911 of file macho_module.c.

1912{
1913 struct macho_info macho_info;
1914
1915 TRACE("(%p/%p)\n", pcs, pcs->handle);
1916 pcs->dbg_hdr_addr = addr;
1918 if (!macho_search_loader(pcs, &macho_info)) return FALSE;
1919 macho_info.module->format_info[DFI_MACHO]->u.macho_info->is_loader = 1;
1921 pcs->loader = &macho_loader_ops;
1922 TRACE("Found macho debug header %#lx\n", pcs->dbg_hdr_addr);
1923 return TRUE;
1924}
static BOOL macho_search_loader(struct process *pcs, struct macho_info *macho_info)
static const struct loader_ops macho_loader_ops
#define MACHO_INFO_MODULE
Definition: macho_module.c:189
struct module * module
Definition: macho_module.c:195
unsigned flags
Definition: macho_module.c:194
HANDLE handle

Referenced by check_live_target().

◆ minidump_add_memory_block()

void minidump_add_memory_block ( struct dump_context dc,
ULONG64  base,
ULONG  size,
ULONG  rva 
)

Definition at line 355 of file minidump.c.

356{
357 if (!dc->mem)
358 {
359 dc->alloc_mem = 32;
360 dc->mem = HeapAlloc(GetProcessHeap(), 0, dc->alloc_mem * sizeof(*dc->mem));
361 }
362 else if (dc->num_mem >= dc->alloc_mem)
363 {
364 dc->alloc_mem *= 2;
365 dc->mem = HeapReAlloc(GetProcessHeap(), 0, dc->mem,
366 dc->alloc_mem * sizeof(*dc->mem));
367 }
368 if (dc->mem)
369 {
370 dc->mem[dc->num_mem].base = base;
371 dc->mem[dc->num_mem].size = size;
372 dc->mem[dc->num_mem].rva = rva;
373 dc->num_mem++;
374 }
375 else dc->num_mem = dc->alloc_mem = 0;
376}
static const WCHAR dc[]

Referenced by arm64_fetch_minidump_thread(), arm_fetch_minidump_thread(), dump_threads(), i386_fetch_minidump_thread(), x86_64_fetch_minidump_module(), and x86_64_fetch_minidump_thread().

◆ module_find_by_addr()

struct module * module_find_by_addr ( const struct process pcs,
DWORD64  addr,
enum module_type  type 
)

Definition at line 420 of file module.c.

422{
423 struct module* module;
424
425 if (type == DMT_UNKNOWN)
426 {
427 if ((module = module_find_by_addr(pcs, addr, DMT_PE)) ||
430 return module;
431 }
432 else
433 {
434 for (module = pcs->lmodules; module; module = module->next)
435 {
436 if (type == module->type && addr >= module->module.BaseOfImage &&
437 addr < module->module.BaseOfImage + module->module.ImageSize)
438 return module;
439 }
440 }
442 return module;
443}
#define ERROR_MOD_NOT_FOUND
Definition: compat.h:104
#define SetLastError(x)
Definition: compat.h:752
struct module * module_find_by_addr(const struct process *pcs, DWORD64 addr, enum module_type type)
Definition: module.c:420
GLuint GLuint GLsizei GLenum type
Definition: gl.h:1545
DWORD64 BaseOfImage
Definition: compat.h:1070
struct module * next
enum module_type type
struct module * lmodules

Referenced by dwarf2_virtual_unwind(), module_find_by_addr(), pdb_virtual_unwind(), sym_enum(), SymAddSymbolW(), SymEnumLines(), SymEnumSourceFilesW(), SymEnumTypes(), SymFromAddr(), SymFunctionTableAccess64(), SymGetLineFromAddr64(), SymGetLineNext64(), SymGetLinePrev64(), SymGetModuleBase64(), SymGetModuleInfoW64(), SymGetTypeFromName(), SymGetTypeInfo(), symt_enum_locals(), SymUnloadModule(), SymUnloadModule64(), and x86_64_fetch_minidump_module().

◆ module_find_by_nameA()

struct module * module_find_by_nameA ( const struct process pcs,
const char name 
)

Definition at line 291 of file module.c.

292{
293 WCHAR wname[MAX_PATH];
294
295 MultiByteToWideChar(CP_ACP, 0, name, -1, wname, ARRAY_SIZE(wname));
296 return module_find_by_nameW(pcs, wname);
297}
#define ARRAY_SIZE(A)
Definition: main.h:20
#define MAX_PATH
Definition: compat.h:34
struct module * module_find_by_nameW(const struct process *pcs, const WCHAR *name)
Definition: module.c:279

Referenced by SymFromName().

◆ module_find_by_nameW()

struct module * module_find_by_nameW ( const struct process pcs,
const WCHAR name 
)

Definition at line 279 of file module.c.

280{
281 struct module* module;
282
283 for (module = pcs->lmodules; module; module = module->next)
284 {
285 if (!wcsicmp(name, module->module.ModuleName)) return module;
286 }
288 return NULL;
289}
#define ERROR_INVALID_NAME
Definition: compat.h:103
#define wcsicmp
Definition: compat.h:15

Referenced by module_find_by_nameA(), and SymEnumSourceFilesW().

◆ module_get_containee()

struct module * module_get_containee ( const struct process pcs,
const struct module inner 
)

Definition at line 349 of file module.c.

350{
351 struct module* module;
352
353 for (module = pcs->lmodules; module; module = module->next)
354 {
355 if (module != outer &&
357 outer->module.BaseOfImage + outer->module.ImageSize >=
359 return module;
360 }
361 return NULL;
362}

Referenced by sym_enum(), and SymFromName().

◆ module_get_debug()

BOOL module_get_debug ( struct module_pair pair)

Definition at line 374 of file module.c.

375{
377
378 if (!pair->requested) return FALSE;
379 /* for a PE builtin, always get info from container */
380 if (!(pair->effective = module_get_container(pair->pcs, pair->requested)))
381 pair->effective = pair->requested;
382 /* if deferred, force loading */
383 if (pair->effective->module.SymType == SymDeferred)
384 {
385 BOOL ret;
386
387 if (pair->effective->is_virtual) ret = FALSE;
388 else if (pair->effective->type == DMT_PE)
389 {
390 idslW64.SizeOfStruct = sizeof(idslW64);
391 idslW64.BaseOfImage = pair->effective->module.BaseOfImage;
392 idslW64.CheckSum = pair->effective->module.CheckSum;
393 idslW64.TimeDateStamp = pair->effective->module.TimeDateStamp;
394 memcpy(idslW64.FileName, pair->effective->module.ImageName,
395 sizeof(pair->effective->module.ImageName));
396 idslW64.Reparse = FALSE;
397 idslW64.hFile = INVALID_HANDLE_VALUE;
398
400 ret = pe_load_debug_info(pair->pcs, pair->effective);
401 pcs_callback(pair->pcs,
403 &idslW64);
404 }
405 else ret = pair->pcs->loader->load_debug_info(pair->pcs, pair->effective);
406
407 if (!ret) pair->effective->module.SymType = SymNone;
408 assert(pair->effective->module.SymType != SymDeferred);
409 pair->effective->module.NumSyms = pair->effective->ht_symbols.num_elts;
410 }
411 return pair->effective->module.SymType != SymNone;
412}
BOOL pe_load_debug_info(const struct process *pcs, struct module *module) DECLSPEC_HIDDEN
Definition: pe_module.c:751
@ SymNone
Definition: compat.h:1056
@ SymDeferred
Definition: compat.h:1061
#define INVALID_HANDLE_VALUE
Definition: compat.h:731
#define CBA_DEFERRED_SYMBOL_LOAD_COMPLETE
Definition: compat.h:977
#define CBA_DEFERRED_SYMBOL_LOAD_FAILURE
Definition: compat.h:978
#define CBA_DEFERRED_SYMBOL_LOAD_START
Definition: compat.h:976
BOOL pcs_callback(const struct process *pcs, ULONG action, void *data)
Definition: dbghelp.c:731
static struct module * module_get_container(const struct process *pcs, const struct module *inner)
Definition: module.c:329
WCHAR FileName[MAX_PATH+1]
Definition: compat.h:1167

Referenced by dwarf2_virtual_unwind(), find_name(), pdb_virtual_unwind(), sym_enum(), SymAddSymbolW(), SymEnumLines(), SymEnumSourceFilesW(), SymEnumTypes(), SymFromAddr(), SymGetLineFromAddr64(), SymGetLineNext64(), SymGetLinePrev64(), SymGetTypeFromName(), SymGetTypeInfo(), and symt_enum_locals().

◆ module_is_already_loaded()

struct module * module_is_already_loaded ( const struct process pcs,
const WCHAR imgname 
)

Definition at line 303 of file module.c.

304{
305 struct module* module;
306 const WCHAR* filename;
307
308 /* first compare the loaded image name... */
309 for (module = pcs->lmodules; module; module = module->next)
310 {
312 return module;
313 }
314 /* then compare the standard filenames (without the path) ... */
316 for (module = pcs->lmodules; module; module = module->next)
317 {
319 return module;
320 }
322 return NULL;
323}
static const WCHAR * get_filename(const WCHAR *name, const WCHAR *endptr)
Definition: module.c:70
WCHAR LoadedImageName[256]
Definition: compat.h:1078

Referenced by elf_load_cb(), elf_search_and_load_file(), macho_search_and_load_file(), and SymLoadModuleExW().

◆ module_new()

struct module * module_new ( struct process pcs,
const WCHAR name,
enum module_type  type,
BOOL  virtual,
DWORD64  addr,
DWORD64  size,
ULONG_PTR  stamp,
ULONG_PTR  checksum 
)

Definition at line 198 of file module.c.

202{
203 struct module* module;
204 unsigned i;
205
206 assert(type == DMT_ELF || type == DMT_PE || type == DMT_MACHO);
208 return NULL;
209
210 module->next = pcs->lmodules;
211 pcs->lmodules = module;
212
213 TRACE("=> %s %s-%s %s\n",
214 get_module_type(type, virtual),
215 wine_dbgstr_longlong(mod_addr), wine_dbgstr_longlong(mod_addr + size),
217
218 pool_init(&module->pool, 65536);
219
220 module->process = pcs;
222 module->module.BaseOfImage = mod_addr;
225 module->module.ImageName[0] = '\0';
228 module->module.NumSyms = 0;
229 module->module.TimeDateStamp = stamp;
231
233 module->module.CVSig = 0;
235 module->module.PdbSig = 0;
237 module->module.PdbAge = 0;
245
246 module->reloc_delta = 0;
247 module->type = type;
248 module->is_virtual = virtual;
249 for (i = 0; i < DFI_LAST; i++) module->format_info[i] = NULL;
251 module->sorttab_size = 0;
253 module->num_sorttab = 0;
254 module->num_symbols = 0;
255
256 vector_init(&module->vsymt, sizeof(struct symt*), 128);
257 /* FIXME: this seems a bit too high (on a per module basis)
258 * need some statistics about this
259 */
262#ifdef __x86_64__
263 hash_table_init(&module->pool, &module->ht_symaddr, 4096);
264#endif
265 vector_init(&module->vtypes, sizeof(struct symt*), 32);
266
267 module->sources_used = 0;
269 module->sources = 0;
271
272 return module;
273}
void hash_table_init(struct pool *pool, struct hash_table *ht, unsigned num_buckets) DECLSPEC_HIDDEN
Definition: storage.c:334
void vector_init(struct vector *v, unsigned elt_sz, unsigned bucket_sz) DECLSPEC_HIDDEN
Definition: storage.c:133
int source_rb_compare(const void *key, const struct wine_rb_entry *entry) DECLSPEC_HIDDEN
Definition: source.c:40
void pool_init(struct pool *a, size_t arena_size) DECLSPEC_HIDDEN
Definition: storage.c:43
static cab_ULONG checksum(const cab_UBYTE *data, cab_UWORD bytes, cab_ULONG csum)
Definition: fdi.c:353
static __inline const char * wine_dbgstr_longlong(ULONGLONG ll)
Definition: compat.h:49
#define HEAP_ZERO_MEMORY
Definition: compat.h:134
#define lstrcpynW
Definition: compat.h:738
void module_set_module(struct module *module, const WCHAR *name)
Definition: module.c:142
static const char * get_module_type(enum module_type type, BOOL virtual)
Definition: module.c:184
static void wine_rb_init(struct wine_rb_tree *tree, wine_rb_compare_func_t compare)
Definition: rbtree.h:179
WCHAR CVData[MAX_PATH *3]
Definition: compat.h:1081
WCHAR LoadedPdbName[256]
Definition: compat.h:1079
WCHAR ImageName[256]
Definition: compat.h:1077
SYM_TYPE SymType
Definition: compat.h:1075
unsigned num_sorttab
DWORD64 reloc_delta
unsigned num_symbols
unsigned short is_virtual
struct symt_ht ** addr_sorttab
struct wine_rb_tree sources_offsets_tree
int sortlist_valid
struct process * process
struct hash_table ht_types
unsigned sorttab_size
unsigned sources_used
char * sources
struct module_format * format_info[DFI_LAST]
unsigned sources_alloc
struct vector vsymt
struct hash_table ht_symbols
struct pool pool
struct vector vtypes

Referenced by elf_load_file_from_fmap(), macho_load_file(), pe_load_builtin_module(), pe_load_native_module(), and SymLoadModuleExW().

◆ module_remove()

BOOL module_remove ( struct process pcs,
struct module module 
)

Definition at line 889 of file module.c.

890{
891 struct module_format*modfmt;
892 struct module** p;
893 unsigned i;
894
896
897 for (i = 0; i < DFI_LAST; i++)
898 {
899 if ((modfmt = module->format_info[i]) && modfmt->remove)
900 modfmt->remove(pcs, module->format_info[i]);
901 }
908 /* native dbghelp doesn't invoke registered callback(,CBA_SYMBOLS_UNLOADED,) here
909 * so do we
910 */
911 for (p = &pcs->lmodules; *p; p = &(*p)->next)
912 {
913 if (*p == module)
914 {
915 *p = module->next;
917 return TRUE;
918 }
919 }
920 FIXME("This shouldn't happen\n");
921 return FALSE;
922}
void pool_destroy(struct pool *a) DECLSPEC_HIDDEN
Definition: storage.c:50
void hash_table_destroy(struct hash_table *ht) DECLSPEC_HIDDEN
Definition: storage.c:342
#define HeapFree(x, y, z)
Definition: compat.h:735
WCHAR * real_path

Referenced by elf_synchronize_module_list(), macho_synchronize_module_list(), SymCleanup(), SymUnloadModule(), and SymUnloadModule64().

◆ module_reset_debug_info()

void module_reset_debug_info ( struct module module)

Definition at line 1328 of file module.c.

1329{
1331 module->sorttab_size = 0;
1335 module->ht_symbols.num_buckets = 0;
1336 module->ht_symbols.buckets = NULL;
1338 module->ht_types.num_buckets = 0;
1339 module->ht_types.buckets = NULL;
1340 module->vtypes.num_elts = 0;
1343 module->sources = NULL;
1344}

Referenced by stabs_parse().

◆ module_set_module()

void module_set_module ( struct module module,
const WCHAR name 
)

Definition at line 142 of file module.c.

143{
146}
static void module_fill_module(const WCHAR *in, WCHAR *out, size_t size)
Definition: module.c:118
WCHAR modulename[64]

Referenced by elf_read_wine_loader_dbg_info(), macho_read_wine_loader_dbg_info(), module_new(), and SymLoadModuleExW().

◆ path_find_symbol_file()

BOOL path_find_symbol_file ( const struct process pcs,
const struct module module,
PCSTR  full_path,
enum module_type  type,
const GUID guid,
DWORD  dw1,
DWORD  dw2,
WCHAR buffer,
BOOL is_unmatched 
)

Definition at line 596 of file path.c.

599{
600 struct module_find mf;
601 WCHAR full_pathW[MAX_PATH];
602 WCHAR* ptr;
603 const WCHAR* filename;
604 WCHAR* searchPath = pcs->search_path;
605
606 TRACE("(pcs = %p, full_path = %s, guid = %s, dw1 = 0x%08x, dw2 = 0x%08x, buffer = %p)\n",
607 pcs, debugstr_a(full_path), debugstr_guid(guid), dw1, dw2, buffer);
608
609 mf.guid = guid;
610 mf.dw1 = dw1;
611 mf.dw2 = dw2;
612 mf.matched = 0;
613
614 MultiByteToWideChar(CP_ACP, 0, full_path, -1, full_pathW, MAX_PATH);
615 filename = file_name(full_pathW);
616 mf.kind = type;
617 *is_unmatched = FALSE;
618
619 /* first check full path to file */
620 if (module_find_cb(full_pathW, &mf))
621 {
622 lstrcpyW( buffer, full_pathW );
623 return TRUE;
624 }
625
626 /* FIXME: Use Environment-Variables (see MS docs)
627 _NT_SYMBOL_PATH and _NT_ALT_SYMBOL_PATH
628 FIXME: Implement "Standard Path Elements" (Path) ... (see MS docs)
629 do a search for (every?) path-element like this ...
630 <path>
631 <path>\dll
632 <path>\symbols\dll
633 (dll may be exe, or sys depending on the file extension) */
634
635 /* 2. check module-path */
637 if (do_searchW(filename, buffer, FALSE, module_find_cb, &mf)) return TRUE;
638 if (module->real_path)
639 {
641 if (do_searchW(filename, buffer, FALSE, module_find_cb, &mf)) return TRUE;
642 }
643
644 while (searchPath)
645 {
646 ptr = wcschr(searchPath, ';');
647 if (ptr)
648 {
649 memcpy(buffer, searchPath, (ptr - searchPath) * sizeof(WCHAR));
650 buffer[ptr - searchPath] = '\0';
651 searchPath = ptr + 1;
652 }
653 else
654 {
655 lstrcpyW(buffer, searchPath);
656 searchPath = NULL;
657 }
658 /* return first fully matched file */
659 if (do_searchW(filename, buffer, FALSE, module_find_cb, &mf)) return TRUE;
660 }
661 /* if no fully matching file is found, return the best matching file if any */
662 if ((dbghelp_options & SYMOPT_LOAD_ANYTHING) && mf.matched)
663 {
664 lstrcpyW( buffer, mf.filename );
665 *is_unmatched = TRUE;
666 return TRUE;
667 }
668 return FALSE;
669}
#define wcschr
Definition: compat.h:17
#define SYMOPT_LOAD_ANYTHING
Definition: compat.h:991
unsigned dbghelp_options
Definition: dbghelp.c:73
static BOOL CALLBACK module_find_cb(PCWSTR buffer, PVOID user)
Definition: path.c:473
static BOOL do_searchW(PCWSTR file, PWSTR buffer, BOOL recurse, PENUMDIRTREE_CALLBACKW cb, PVOID user)
Definition: path.c:221
static void file_pathW(const WCHAR *src, WCHAR *dst)
Definition: path.c:53
#define debugstr_guid
Definition: kernel32.h:35
#define debugstr_a
Definition: kernel32.h:31
const GUID * guid
static PVOID ptr
Definition: dispmode.c:27
static LPCWSTR file_name
Definition: protocol.c:147
DWORD dw1
Definition: path.c:462
DWORD dw2
Definition: path.c:463
WCHAR * search_path

Referenced by map_pdb_file(), and pe_load_dbg_file().

◆ pcs_callback()

BOOL pcs_callback ( const struct process pcs,
ULONG  action,
void data 
)

Definition at line 731 of file dbghelp.c.

732{
734
735 TRACE("%p %u %p\n", pcs, action, data);
736
737 if (!pcs->reg_cb) return FALSE;
738 if (!pcs->reg_is_unicode)
739 {
741
742 switch (action)
743 {
744 case CBA_DEBUG_INFO:
746 case CBA_SET_OPTIONS:
748 break;
753 idslW = data;
754 idsl.SizeOfStruct = sizeof(idsl);
755 idsl.BaseOfImage = idslW->BaseOfImage;
756 idsl.CheckSum = idslW->CheckSum;
757 idsl.TimeDateStamp = idslW->TimeDateStamp;
758 WideCharToMultiByte(CP_ACP, 0, idslW->FileName, -1,
759 idsl.FileName, sizeof(idsl.FileName), NULL, NULL);
760 idsl.Reparse = idslW->Reparse;
761 data = &idsl;
762 break;
764 case CBA_EVENT:
765 case CBA_READ_MEMORY:
766 default:
767 FIXME("No mapping for action %u\n", action);
768 return FALSE;
769 }
770 }
771 return pcs->reg_cb(pcs->handle, action, (ULONG64)(DWORD_PTR)data, pcs->reg_user);
772}
#define CBA_DUPLICATE_SYMBOL
Definition: compat.h:980
#define CBA_SYMBOLS_UNLOADED
Definition: compat.h:979
#define CBA_SET_OPTIONS
Definition: compat.h:983
#define CBA_DEFERRED_SYMBOL_LOAD_CANCEL
Definition: compat.h:982
#define CBA_DEBUG_INFO
Definition: compat.h:986
#define CBA_READ_MEMORY
Definition: compat.h:981
#define CBA_DEFERRED_SYMBOL_LOAD_PARTIAL
Definition: compat.h:985
#define CBA_EVENT
Definition: compat.h:984
const WCHAR * action
Definition: action.c:7509
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
unsigned __int64 ULONG64
Definition: imports.h:198
PSYMBOL_REGISTERED_CALLBACK64 reg_cb
BOOL reg_is_unicode
DWORD64 reg_user

Referenced by module_get_debug(), and SymSetOptions().

◆ pdb_fetch_file_info()

BOOL pdb_fetch_file_info ( const struct pdb_lookup pdb_lookup,
unsigned matched 
)

Definition at line 2913 of file msc.c.

2914{
2915 HANDLE hFile, hMap = NULL;
2916 char* image = NULL;
2917 BOOL ret;
2918 struct pdb_file_info pdb_file;
2919
2923 ((image = MapViewOfFile(hMap, FILE_MAP_READ, 0, 0, 0)) == NULL))
2924 {
2925 WARN("Unable to open .PDB file: %s\n", pdb_lookup->filename);
2926 ret = FALSE;
2927 }
2928 else
2929 {
2930 ret = pdb_init(pdb_lookup, &pdb_file, image, matched);
2931 pdb_free_file(&pdb_file);
2932 }
2933
2935 if (hMap) CloseHandle(hMap);
2937
2938 return ret;
2939}
#define WARN(fmt,...)
Definition: precomp.h:61
#define CloseHandle
Definition: compat.h:739
#define PAGE_READONLY
Definition: compat.h:138
#define UnmapViewOfFile
Definition: compat.h:746
#define OPEN_EXISTING
Definition: compat.h:775
#define CreateFileMappingW(a, b, c, d, e, f)
Definition: compat.h:744
#define CreateFileA(a, b, c, d, e, f, g)
Definition: compat.h:740
#define GENERIC_READ
Definition: compat.h:135
#define FILE_MAP_READ
Definition: compat.h:776
#define FILE_ATTRIBUTE_NORMAL
Definition: compat.h:137
#define MapViewOfFile
Definition: compat.h:745
#define FILE_SHARE_READ
Definition: compat.h:136
static void pdb_free_file(struct pdb_file_info *pdb_file)
Definition: msc.c:2269
static BOOL pdb_init(const struct pdb_lookup *pdb_lookup, struct pdb_file_info *pdb_file, const char *image, unsigned *matched)
Definition: msc.c:2539
_In_ HANDLE hFile
Definition: mswsock.h:90
HANDLE hMap
Definition: msc.c:64
const char * filename

Referenced by module_find_cb().

◆ pdb_virtual_unwind()

BOOL pdb_virtual_unwind ( struct cpu_stack_walk csw,
DWORD_PTR  ip,
union ctx context,
struct pdb_cmd_pair cpair 
)

Definition at line 3200 of file msc.c.

3202{
3203 struct module_pair pair;
3204 struct pdb_module_info* pdb_info;
3205 PDB_FPO_DATA* fpoext;
3206 unsigned i, size, strsize;
3207 char* strbase;
3208 BOOL ret = TRUE;
3209
3210 if (!(pair.pcs = process_find_by_handle(csw->hProcess)) ||
3211 !(pair.requested = module_find_by_addr(pair.pcs, ip, DMT_UNKNOWN)) ||
3213 return FALSE;
3214 if (!pair.effective->format_info[DFI_PDB]) return FALSE;
3215 pdb_info = pair.effective->format_info[DFI_PDB]->u.pdb_info;
3216 TRACE("searching %lx => %lx\n", ip, ip - (DWORD_PTR)pair.effective->module.BaseOfImage);
3217 ip -= (DWORD_PTR)pair.effective->module.BaseOfImage;
3218
3219 strbase = pdb_read_strings(&pdb_info->pdb_files[0]);
3220 if (!strbase) return FALSE;
3221 strsize = *(const DWORD*)(strbase + 8);
3222 fpoext = pdb_read_file(&pdb_info->pdb_files[0], pdb_info->pdb_files[0].fpoext_stream);
3223 size = pdb_get_file_size(&pdb_info->pdb_files[0], pdb_info->pdb_files[0].fpoext_stream);
3224 if (fpoext && (size % sizeof(*fpoext)) == 0)
3225 {
3226 size /= sizeof(*fpoext);
3227 for (i = 0; i < size; i++)
3228 {
3229 if (fpoext[i].start <= ip && ip < fpoext[i].start + fpoext[i].func_size)
3230 {
3231 TRACE("\t%08x %08x %8x %8x %4x %4x %4x %08x %s\n",
3232 fpoext[i].start, fpoext[i].func_size, fpoext[i].locals_size,
3233 fpoext[i].params_size, fpoext[i].maxstack_size, fpoext[i].prolog_size,
3234 fpoext[i].savedregs_size, fpoext[i].flags,
3235 fpoext[i].str_offset < strsize ?
3236 wine_dbgstr_a(strbase + 12 + fpoext[i].str_offset) : "<out of bounds>");
3237 if (fpoext[i].str_offset < strsize)
3238 ret = pdb_parse_cmd_string(csw, &fpoext[i], strbase + 12 + fpoext[i].str_offset, cpair);
3239 else
3240 ret = FALSE;
3241 break;
3242 }
3243 }
3244 }
3245 else ret = FALSE;
3246 pdb_free(fpoext);
3247 pdb_free(strbase);
3248
3249 return ret;
3250}
GLuint start
Definition: gl.h:1545
GLbitfield flags
Definition: glext.h:7161
static void * pdb_read_file(const struct pdb_file_info *pdb_file, DWORD file_nr)
Definition: msc.c:2239
static BOOL pdb_parse_cmd_string(struct cpu_stack_walk *csw, PDB_FPO_DATA *fpoext, const char *cmd, struct pdb_cmd_pair *cpair)
Definition: msc.c:3147
static void pdb_free(void *buffer)
Definition: msc.c:2264
static void * pdb_read_strings(const struct pdb_file_info *pdb_file)
Definition: msc.c:2337
static unsigned pdb_get_file_size(const struct pdb_file_info *pdb_file, DWORD file_nr)
Definition: msc.c:2254
const char int int int static __inline const char * wine_dbgstr_a(const char *s)
Definition: debug.h:187
struct pdb_file_info pdb_files[CV_MAX_MODULES]
Definition: msc.c:88

Referenced by fetch_next_frame32().

◆ pe_load_builtin_module()

struct module * pe_load_builtin_module ( struct process pcs,
const WCHAR name,
DWORD64  base,
DWORD64  size 
)

Definition at line 896 of file pe_module.c.

898{
899 struct module* module = NULL;
900
901 if (base && pcs->dbg_hdr_addr)
902 {
904
905 if (pe_load_nt_header(pcs->handle, base, &nth))
906 {
911 }
912 }
913 return module;
914}
struct module * module_new(struct process *pcs, const WCHAR *name, enum module_type type, BOOL virtual, DWORD64 addr, DWORD64 size, ULONG_PTR stamp, ULONG_PTR checksum) DECLSPEC_HIDDEN
Definition: module.c:198
BOOL pe_load_nt_header(HANDLE hProc, DWORD64 base, IMAGE_NT_HEADERS *nth)
Definition: pe_module.c:881
IMAGE_OPTIONAL_HEADER32 OptionalHeader
Definition: ntddk_ex.h:184
IMAGE_FILE_HEADER FileHeader
Definition: ntddk_ex.h:183

Referenced by SymLoadModuleExW().

◆ pe_load_debug_directory()

BOOL pe_load_debug_directory ( const struct process pcs,
struct module module,
const BYTE mapping,
const IMAGE_SECTION_HEADER sectp,
DWORD  nsect,
const IMAGE_DEBUG_DIRECTORY dbg,
int  nDbg 
)

Definition at line 3391 of file msc.c.

3395{
3396 BOOL ret;
3397 int i;
3398 struct msc_debug_info msc_dbg;
3399
3400 msc_dbg.module = module;
3401 msc_dbg.nsect = nsect;
3402 msc_dbg.sectp = sectp;
3403 msc_dbg.nomap = 0;
3404 msc_dbg.omapp = NULL;
3405
3406 __TRY
3407 {
3408 ret = FALSE;
3409
3410 /* First, watch out for OMAP data */
3411 for (i = 0; i < nDbg; i++)
3412 {
3414 {
3415 msc_dbg.nomap = dbg[i].SizeOfData / sizeof(OMAP_DATA);
3416 msc_dbg.omapp = (const OMAP_DATA*)(mapping + dbg[i].PointerToRawData);
3417 break;
3418 }
3419 }
3420
3421 /* Now, try to parse CodeView debug info */
3422 for (i = 0; i < nDbg; i++)
3423 {
3424 if (dbg[i].Type == IMAGE_DEBUG_TYPE_CODEVIEW)
3425 {
3426 msc_dbg.root = mapping + dbg[i].PointerToRawData;
3427 if ((ret = codeview_process_info(pcs, &msc_dbg))) goto done;
3428 }
3429 }
3430
3431 /* If not found, try to parse COFF debug info */
3432 for (i = 0; i < nDbg; i++)
3433 {
3434 if (dbg[i].Type == IMAGE_DEBUG_TYPE_COFF)
3435 {
3436 msc_dbg.root = mapping + dbg[i].PointerToRawData;
3437 if ((ret = coff_process_info(&msc_dbg))) goto done;
3438 }
3439 }
3440 done:
3441 /* FIXME: this should be supported... this is the debug information for
3442 * functions compiled without a frame pointer (FPO = frame pointer omission)
3443 * the associated data helps finding out the relevant information
3444 */
3445 for (i = 0; i < nDbg; i++)
3446 if (dbg[i].Type == IMAGE_DEBUG_TYPE_FPO)
3447 FIXME("This guy has FPO information\n");
3448#if 0
3449
3450#define FRAME_FPO 0
3451#define FRAME_TRAP 1
3452#define FRAME_TSS 2
3453
3454typedef struct _FPO_DATA
3455{
3456 DWORD ulOffStart; /* offset 1st byte of function code */
3457 DWORD cbProcSize; /* # bytes in function */
3458 DWORD cdwLocals; /* # bytes in locals/4 */
3459 WORD cdwParams; /* # bytes in params/4 */
3460
3461 WORD cbProlog : 8; /* # bytes in prolog */
3462 WORD cbRegs : 3; /* # regs saved */
3463 WORD fHasSEH : 1; /* TRUE if SEH in func */
3464 WORD fUseBP : 1; /* TRUE if EBP has been allocated */
3465 WORD reserved : 1; /* reserved for future use */
3466 WORD cbFrame : 2; /* frame type */
3467} FPO_DATA;
3468#endif
3469
3470 }
3472 {
3473 ERR("Got a page fault while loading symbols\n");
3474 ret = FALSE;
3475 }
3476 __ENDTRY
3477 return ret;
3478}
Type
Definition: Type.h:7
#define ERR(fmt,...)
Definition: precomp.h:57
DECLSPEC_HIDDEN BOOL coff_process_info(const struct msc_debug_info *msc_dbg)
Definition: coff.c:148
#define IMAGE_DEBUG_TYPE_OMAP_FROM_SRC
Definition: compat.h:148
#define __TRY
Definition: compat.h:80
#define IMAGE_DEBUG_TYPE_FPO
Definition: compat.h:143
#define IMAGE_DEBUG_TYPE_CODEVIEW
Definition: compat.h:142
#define __ENDTRY
Definition: compat.h:82
#define __EXCEPT_PAGE_FAULT
Definition: compat.h:81
#define IMAGE_DEBUG_TYPE_COFF
Definition: compat.h:141
unsigned short WORD
Definition: ntddk_ex.h:93
GLenum GLenum GLenum GLenum mapping
Definition: glext.h:9031
static BOOL codeview_process_info(const struct process *pcs, const struct msc_debug_info *msc_dbg)
Definition: msc.c:3262
DWORD ulOffStart
Definition: winnt_old.h:3607
WORD cbFrame
Definition: winnt_old.h:3616
WORD cdwParams
Definition: winnt_old.h:3610
WORD fUseBP
Definition: winnt_old.h:3614
WORD fHasSEH
Definition: winnt_old.h:3613
WORD reserved
Definition: winnt_old.h:3615
WORD cbRegs
Definition: winnt_old.h:3612
WORD cbProlog
Definition: winnt_old.h:3611
DWORD cdwLocals
Definition: winnt_old.h:3609
DWORD cbProcSize
Definition: winnt_old.h:3608
const IMAGE_SECTION_HEADER * sectp
Definition: mscvpdb.h:2136
struct module * module
Definition: mscvpdb.h:2134
struct _FPO_DATA FPO_DATA

Referenced by pe_load_dbg_file(), and pe_load_msc_debug_info().

◆ pe_load_debug_info()

BOOL pe_load_debug_info ( const struct process pcs,
struct module module 
)

Definition at line 751 of file pe_module.c.

752{
753 BOOL ret = FALSE;
754
756 {
758 ret = pe_load_stabs(pcs, module) || ret;
760 #ifndef DBGHELP_STATIC_LIB
763 #endif
764
765 ret = ret || pe_load_coff_symbol_table(module); /* FIXME */
766 /* if we still have no debug info (we could only get SymExport at this
767 * point), then do the SymExport except if we have an ELF container,
768 * in which case we'll rely on the export's on the ELF side
769 */
770 }
771 /* FIXME shouldn't we check that? if (!module_get_debug(pcs, module)) */
773 ret = TRUE;
774
775 return ret;
776}
#define SYMOPT_PUBLICS_ONLY
Definition: compat.h:992
BOOL image_check_alternate(struct image_file_map *fmap, const struct module *module) DECLSPEC_HIDDEN
Definition: module.c:701
static BOOL pe_load_coff_symbol_table(struct module *module)
Definition: pe_module.c:420
static BOOL pe_load_dwarf(struct module *module)
Definition: pe_module.c:525
static BOOL pe_load_rsym(struct module *module)
Definition: pe_module.c:545
static BOOL pe_load_export_debug_info(const struct process *pcs, struct module *module)
Definition: pe_module.c:666
static BOOL pe_load_msc_debug_info(const struct process *pcs, struct module *module)
Definition: pe_module.c:618
static BOOL pe_load_stabs(const struct process *pcs, struct module *module)
Definition: pe_module.c:489

Referenced by module_get_debug(), and pe_load_native_module().

◆ pe_load_native_module()

struct module * pe_load_native_module ( struct process pcs,
const WCHAR name,
HANDLE  hFile,
DWORD64  base,
DWORD  size 
)

Definition at line 803 of file pe_module.c.

805{
806 struct module* module = NULL;
807 BOOL opened = FALSE;
808 struct module_format* modfmt;
809 WCHAR loaded_name[MAX_PATH];
810
811 loaded_name[0] = '\0';
812 if (!hFile)
813 {
814 assert(name);
815
816 if ((hFile = FindExecutableImageExW(name, pcs->search_path, loaded_name, NULL, NULL)) == NULL)
817 return NULL;
818 opened = TRUE;
819 }
820 else if (name) lstrcpyW(loaded_name, name);
822 FIXME("Trouble ahead (no module name passed in deferred mode)\n");
823 if (!(modfmt = HeapAlloc(GetProcessHeap(), 0, sizeof(struct module_format) + sizeof(struct pe_module_info))))
824 return NULL;
825 modfmt->u.pe_info = (struct pe_module_info*)(modfmt + 1);
826 if (pe_map_file(hFile, &modfmt->u.pe_info->fmap, DMT_PE))
827 {
828#ifndef __REACTOS__
829 struct builtin_search builtin = { NULL };
830 if (modfmt->u.pe_info->fmap.u.pe.builtin && search_dll_path(pcs, loaded_name, search_builtin_pe, &builtin))
831 {
832 TRACE("reloaded %s from %s\n", debugstr_w(loaded_name), debugstr_w(builtin.path));
833 image_unmap_file(&modfmt->u.pe_info->fmap);
834 modfmt->u.pe_info->fmap = builtin.fmap;
835 }
836#endif
837 if (!base) base = modfmt->u.pe_info->fmap.u.pe.ntheader.OptionalHeader.ImageBase;
838 if (!size) size = modfmt->u.pe_info->fmap.u.pe.ntheader.OptionalHeader.SizeOfImage;
839
840 module = module_new(pcs, loaded_name, DMT_PE, FALSE, base, size,
841 modfmt->u.pe_info->fmap.u.pe.ntheader.FileHeader.TimeDateStamp,
842 modfmt->u.pe_info->fmap.u.pe.ntheader.OptionalHeader.CheckSum);
843 if (module)
844 {
845#ifdef __REACTOS__
847#else
848 module->real_path = builtin.path;
849#endif
850 modfmt->module = module;
851 modfmt->remove = pe_module_remove;
852 modfmt->loc_compute = NULL;
853
854 module->format_info[DFI_PE] = modfmt;
857 else
859 module->reloc_delta = base - modfmt->u.pe_info->fmap.u.pe.ntheader.OptionalHeader.ImageBase;
860 }
861 else
862 {
863 ERR("could not load the module '%s'\n", debugstr_w(loaded_name));
864#ifndef __REACTOS__
865 heap_free(builtin.path);
866#endif
867 image_unmap_file(&modfmt->u.pe_info->fmap);
868 }
869 }
870 if (!module) HeapFree(GetProcessHeap(), 0, modfmt);
871
872 if (opened) CloseHandle(hFile);
873
874 return module;
875}
BOOL search_dll_path(const struct process *process, const WCHAR *name, BOOL(*match)(void *, HANDLE, const WCHAR *), void *param) DECLSPEC_HIDDEN
Definition: path.c:697
#define FindExecutableImageExW
Definition: compat.h:1141
#define SYMOPT_DEFERRED_LOADS
Definition: compat.h:989
static void image_unmap_file(struct image_file_map *fmap)
BOOL pe_map_file(HANDLE file, struct image_file_map *fmap, enum module_type mt)
Definition: pe_module.c:245
BOOL pe_load_debug_info(const struct process *pcs, struct module *module)
Definition: pe_module.c:751
static void pe_module_remove(struct process *pcs, struct module_format *modfmt)
Definition: pe_module.c:345
static BOOL search_builtin_pe(void *param, HANDLE handle, const WCHAR *path)
Definition: pe_module.c:785
WCHAR * path
Definition: pe_module.c:781
struct image_file_map fmap
Definition: pe_module.c:782
struct pe_module_info * pe_info

Referenced by SymLoadModuleExW().

◆ pe_load_nt_header()

BOOL pe_load_nt_header ( HANDLE  hProc,
DWORD64  base,
IMAGE_NT_HEADERS nth 
)

Definition at line 881 of file pe_module.c.

882{
884
885 return ReadProcessMemory(hProc, (char*)(DWORD_PTR)base, &dos, sizeof(dos), NULL) &&
887 ReadProcessMemory(hProc, (char*)(DWORD_PTR)(base + dos.e_lfanew),
888 nth, sizeof(*nth), NULL) &&
890}
#define ReadProcessMemory(a, b, c, d, e)
Definition: compat.h:758
IMAGE_DOS_HEADER dos
Definition: module.c:49
#define IMAGE_NT_SIGNATURE
Definition: pedump.c:93
#define IMAGE_DOS_SIGNATURE
Definition: pedump.c:89

Referenced by fetch_pe_module_info_cb(), and pe_load_builtin_module().

◆ pe_map_directory()

const char * pe_map_directory ( struct module module,
int  dirno,
DWORD size 
)

Definition at line 331 of file pe_module.c.

332{
333 IMAGE_NT_HEADERS* nth;
334 void* mapping;
335
336 if (module->type != DMT_PE || !module->format_info[DFI_PE]) return NULL;
338 !(mapping = pe_map_full(&module->format_info[DFI_PE]->u.pe_info->fmap, &nth)))
339 return NULL;
340 if (size) *size = nth->OptionalHeader.DataDirectory[dirno].Size;
341 return RtlImageRvaToVa(nth, mapping,
343}
#define RtlImageRvaToVa
Definition: compat.h:807
#define IMAGE_NUMBEROF_DIRECTORY_ENTRIES
Definition: ntddk_ex.h:135
static void * pe_map_full(struct image_file_map *fmap, IMAGE_NT_HEADERS **nth)
Definition: pe_module.c:50
IMAGE_DATA_DIRECTORY DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES]
Definition: ntddk_ex.h:178

Referenced by x86_64_fetch_minidump_module(), and x86_64_find_runtime_function().

◆ pool_alloc()

void * pool_alloc ( struct pool a,
size_t  len 
)

Definition at line 89 of file storage.c.

90{
91 struct pool_arena* arena;
92 void* ret;
93 size_t size;
94
95 len = (len + 3) & ~3; /* round up size on DWORD boundary */
96
98 {
99 if (arena->end - arena->current >= len)
100 {
101 ret = arena->current;
102 arena->current += len;
103 if (arena->current + 16 >= arena->end)
104 {
105 list_remove( &arena->entry );
106 list_add_tail( &pool->arena_full, &arena->entry );
107 }
108 return ret;
109 }
110 }
111
112 size = max( pool->arena_size, len );
113 arena = HeapAlloc(GetProcessHeap(), 0, size + sizeof(struct pool_arena));
114 if (!arena) return NULL;
115
116 ret = arena + 1;
117 arena->current = (char*)ret + len;
118 arena->end = (char*)ret + size;
119 if (arena->current + 16 >= arena->end)
120 list_add_tail( &pool->arena_full, &arena->entry );
121 else
122 list_add_head( &pool->arena_list, &arena->entry );
123 return ret;
124}
static void list_remove(struct list_entry *entry)
Definition: list.h:90
static void list_add_tail(struct list_entry *head, struct list_entry *entry)
Definition: list.h:83
static void list_add_head(struct list_entry *head, struct list_entry *entry)
Definition: list.h:76
uint32_t entry
Definition: isohybrid.c:63
#define LIST_FOR_EACH_ENTRY(elem, list, type, field)
Definition: list.h:198
struct list entry
Definition: storage.c:38
char * current
Definition: storage.c:39
char * end
Definition: storage.c:40
struct list arena_list
size_t arena_size
struct list arena_full

Referenced by dwarf2_compute_location_attr(), dwarf2_get_cpp_name(), dwarf2_parse_abbrev_set(), dwarf2_parse_line_numbers(), dwarf2_parse_variable(), dwarf2_read_one_debug_info(), elf_hash_symtab(), hash_table_add(), macho_stabs_def_cb(), pev_set_value(), pool_strdup(), source_new(), symt_add_enum_element(), symt_add_func_local(), symt_add_function_point(), symt_add_function_signature_parameter(), symt_add_udt_element(), symt_new_array(), symt_new_basic(), symt_new_compiland(), symt_new_constant(), symt_new_enum(), symt_new_function(), symt_new_function_signature(), symt_new_global_variable(), symt_new_label(), symt_new_pointer(), symt_new_public(), symt_new_thunk(), symt_new_typedef(), symt_new_udt(), symt_open_func_block(), symt_ptr2index(), and vector_add().

◆ pool_destroy()

void pool_destroy ( struct pool a)

Definition at line 50 of file storage.c.

51{
52 struct pool_arena* arena;
53 struct pool_arena* next;
54
55#ifdef USE_STATS
56 size_t alloc, used, num;
57
58 alloc = used = num = 0;
60 {
61 alloc += arena->end - (char *)arena;
62 used += arena->current - (char*)arena;
63 num++;
64 }
66 {
67 alloc += arena->end - (char *)arena;
68 used += arena->current - (char*)arena;
69 num++;
70 }
71 if (alloc == 0) alloc = 1; /* avoid division by zero */
72 FIXME("STATS: pool %p has allocated %u kbytes, used %u kbytes in %u arenas, non-allocation ratio: %.2f%%\n",
73 pool, (unsigned)(alloc >> 10), (unsigned)(used >> 10), (unsigned)num,
74 100.0 - (float)used / (float)alloc * 100.0);
75#endif
76
78 {
79 list_remove( &arena->entry );
80 HeapFree(GetProcessHeap(), 0, arena);
81 }
83 {
84 list_remove( &arena->entry );
85 HeapFree(GetProcessHeap(), 0, arena);
86 }
87}
static int used
Definition: adh-main.c:39
GLuint GLuint num
Definition: glext.h:9618
static unsigned __int64 next
Definition: rand_nt.c:6
#define alloc
Definition: rosglue.h:13
#define LIST_FOR_EACH_ENTRY_SAFE(cursor, cursor2, list, type, field)
Definition: list.h:204

Referenced by dwarf2_parse_compilation_unit(), elf_load_debug_info(), macho_load_debug_info(), module_remove(), pev_free(), and rsym_parse().

◆ pool_init()

void pool_init ( struct pool a,
size_t  arena_size 
)

Definition at line 43 of file storage.c.

44{
45 list_init( &a->arena_list );
46 list_init( &a->arena_full );
47 a->arena_size = arena_size;
48}
static void list_init(struct list_entry *head)
Definition: list.h:51
GLboolean GLboolean GLboolean GLboolean a
Definition: glext.h:6204

Referenced by dwarf2_parse_compilation_unit(), elf_load_debug_info(), macho_load_debug_info(), module_new(), pev_init(), and rsym_parse().

◆ pool_strdup()

◆ process_find_by_handle()

◆ process_getenv()

const WCHAR * process_getenv ( const struct process process,
const WCHAR name 
)

Definition at line 335 of file dbghelp.c.

336{
337 size_t name_len;
338 const WCHAR *iter;
339
340 if (!process->environment) return NULL;
341 name_len = lstrlenW(name);
342
343 for (iter = process->environment; *iter; iter += lstrlenW(iter) + 1)
344 {
345 if (!wcsnicmp(iter, name, name_len) && iter[name_len] == '=')
346 return iter + name_len + 1;
347 }
348
349 return NULL;
350}
#define wcsnicmp
Definition: compat.h:14
WCHAR * environment

Referenced by elf_search_and_load_file(), macho_search_and_load_file(), and search_dll_path().

◆ read_process_memory()

static BOOL read_process_memory ( const struct process process,
UINT64  addr,
void buf,
size_t  size 
)
inlinestatic

Definition at line 451 of file dbghelp_private.h.

452{
454}
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
unsigned __int3264 UINT_PTR
Definition: mstsclib_h.h:274

Referenced by check_live_target(), dump_memory64_info(), dump_memory_info(), elf_enum_modules_internal(), image_uses_split_segs(), macho_enum_modules_internal(), macho_search_loader(), and x86_64_fetch_minidump_module().

◆ rsym_parse()

BOOL rsym_parse ( struct module module,
unsigned long  load_offset,
const void rsym,
int  rsymlen 
)

Definition at line 79 of file rsym.c.

81{
82 const ROSSYM_HEADER* RosSymHeader;
83 const ROSSYM_ENTRY* First, *Last, *Entry;
84 const CHAR* Strings;
85
86 struct pool pool;
87 struct sparse_array file_table, func_table;
88 rsym_func_entry_t* first_func = NULL;
89
90
91 RosSymHeader = rsym_ptr;
92
93 if (RosSymHeader->SymbolsOffset < sizeof(ROSSYM_HEADER)
94 || RosSymHeader->StringsOffset < RosSymHeader->SymbolsOffset + RosSymHeader->SymbolsLength
95 || rsymlen < RosSymHeader->StringsOffset + RosSymHeader->StringsLength
96 || 0 != (RosSymHeader->SymbolsLength % sizeof(ROSSYM_ENTRY)))
97 {
98 WARN("Invalid ROSSYM_HEADER\n");
99 return FALSE;
100 }
101
102 First = (const ROSSYM_ENTRY *)((const char*)rsym_ptr + RosSymHeader->SymbolsOffset);
103 Last = First + RosSymHeader->SymbolsLength / sizeof(ROSSYM_ENTRY);
104 Strings = (const CHAR*)rsym_ptr + RosSymHeader->StringsOffset;
105
106 pool_init(&pool, 65536);
107 sparse_array_init(&file_table, sizeof(rsym_file_entry_t), 64);
108 sparse_array_init(&func_table, sizeof(rsym_func_entry_t), 128);
109
110 for (Entry = First; Entry != Last; Entry++)
111 {
112 ULONG Address = load_offset + Entry->Address;
113 if (!Entry->FileOffset)
114 {
115 rsym_func_entry_t* func = sparse_array_find(&func_table, Entry->FunctionOffset);
116
117 /* We do not want to define a data point where there is already a function! */
118 if (!func || func->Address != Address)
119 {
120 const char* SymbolName = Strings + Entry->FunctionOffset;
121 if (!is_metadata_sym(SymbolName))
122 {
123 /* TODO: How should we determine the size? */
124 ULONG Size = sizeof(ULONG);
125 if (use_raw_address(SymbolName))
126 Address = Entry->Address;
127
128 symt_new_public(module, NULL, SymbolName, FALSE, Address, Size);
129 }
130 else
131 {
132 /* Maybe use it to fill some metadata? */
133 }
134 }
135 }
136 else
137 {
138 rsym_file_entry_t* file = sparse_array_find(&file_table, Entry->FileOffset);
139 rsym_func_entry_t* func = sparse_array_find(&func_table, Entry->FunctionOffset);
140
141 if (!file)
142 {
143 file = sparse_array_add(&file_table, Entry->FileOffset, &pool);
144 file->File = Strings + Entry->FileOffset;
145 file->Source = source_new(module, NULL, Strings + Entry->FileOffset);
146 }
147
148 if (!func)
149 {
150 func = sparse_array_add(&func_table, Entry->FunctionOffset, &pool);
151 func->func = symt_new_function(module, NULL, Strings + Entry->FunctionOffset,
152 Address, 0, NULL);
153 func->Address = Address;
154 func->next = first_func;
155 first_func = func;
156 }
157
158 /* TODO: What if we have multiple chunks scattered around? */
159 symt_add_func_line(module, func->func, file->Source, Entry->SourceLine, Address - func->Address);
160 }
161 }
162
163 while (first_func)
164 {
165 /* TODO: Size of function? */
166 rsym_finalize_function(module, first_func->func);
167 first_func = first_func->next;
168 }
169
171 module->module.CVSig = 'R' | ('S' << 8) | ('Y' << 16) | ('M' << 24);
177
179
180 return TRUE;
181}
WCHAR First[]
Definition: FormatMessage.c:11
struct symt_function * symt_new_function(struct module *module, struct symt_compiland *parent, const char *name, ULONG_PTR addr, ULONG_PTR size, struct symt *type) DECLSPEC_HIDDEN
Definition: symbol.c:293
void sparse_array_init(struct sparse_array *sa, unsigned elt_sz, unsigned bucket_sz) DECLSPEC_HIDDEN
Definition: storage.c:213
unsigned source_new(struct module *module, const char *basedir, const char *source) DECLSPEC_HIDDEN
Definition: source.c:66
struct symt_public * symt_new_public(struct module *module, struct symt_compiland *parent, const char *typename, BOOL is_function, ULONG_PTR address, unsigned size) DECLSPEC_HIDDEN
Definition: symbol.c:224
void * sparse_array_add(struct sparse_array *sa, ULONG_PTR key, struct pool *pool) DECLSPEC_HIDDEN
Definition: storage.c:281
void * sparse_array_find(const struct sparse_array *sa, ULONG_PTR idx) DECLSPEC_HIDDEN
Definition: storage.c:271
void symt_add_func_line(struct module *module, struct symt_function *func, unsigned source_idx, int line_num, ULONG_PTR offset) DECLSPEC_HIDDEN
Definition: symbol.c:326
static const WCHAR Strings[]
Definition: reg.c:35
static int use_raw_address(const char *name)
Definition: rsym.c:64
static int is_metadata_sym(const char *name)
Definition: rsym.c:58
static void rsym_finalize_function(struct module *module, struct symt_function *func)
Definition: rsym.c:37
GLenum func
Definition: glext.h:6028
static WCHAR Address[46]
Definition: ping.c:68
struct _ROSSYM_ENTRY ROSSYM_ENTRY
base of all file and directory entries
Definition: entries.h:83
Definition: rossym.h:26
unsigned long SymbolsOffset
Definition: rossym.h:20
unsigned long SymbolsLength
Definition: rossym.h:21
unsigned long StringsLength
Definition: rossym.h:23
unsigned long StringsOffset
Definition: rossym.h:22
Definition: fci.c:127
Definition: rsym.c:16
Definition: rsym.c:22
uint32_t ULONG
Definition: typedefs.h:59
_Must_inspect_result_ _In_ WDFDEVICE _In_ PWDF_DEVICE_PROPERTY_DATA _In_ DEVPROPTYPE _In_ ULONG Size
Definition: wdfdevice.h:4533
char CHAR
Definition: xmlstorage.h:175

Referenced by pe_load_rsym().

◆ search_dll_path()

BOOL search_dll_path ( const struct process process,
const WCHAR name,
BOOL(*)(void *, HANDLE, const WCHAR *)  match,
void param 
)

Definition at line 697 of file path.c.

698{
699 const WCHAR *env;
700 size_t len, i;
701 HANDLE file;
702 WCHAR *buf;
703 BOOL ret;
704
706
707 if ((env = process_getenv(process, L"WINEBUILDDIR")))
708 {
709 WCHAR *p, *end;
710 const WCHAR dllsW[] = { '\\','d','l','l','s','\\' };
711 const WCHAR programsW[] = { '\\','p','r','o','g','r','a','m','s','\\' };
712 const WCHAR dot_dllW[] = {'.','d','l','l',0};
713 const WCHAR dot_exeW[] = {'.','e','x','e',0};
714 const WCHAR dot_soW[] = {'.','s','o',0};
715
716
717 len = lstrlenW(env);
718 if (!(buf = heap_alloc((len + 8 + 3 * lstrlenW(name)) * sizeof(WCHAR)))) return FALSE;
719 wcscpy(buf, env);
720 end = buf + len;
721
722 memcpy(end, dllsW, sizeof(dllsW));
723 lstrcpyW(end + ARRAY_SIZE(dllsW), name);
724 if ((p = wcsrchr(end, '.')) && !lstrcmpW(p, dot_soW)) *p = 0;
725 if ((p = wcsrchr(end, '.')) && !lstrcmpW(p, dot_dllW)) *p = 0;
726 p = end + lstrlenW(end);
727 *p++ = '\\';
728 lstrcpyW(p, name);
731 {
732 ret = match(param, file, buf);
734 if (ret) goto found;
735 }
736
737 memcpy(end, programsW, sizeof(programsW));
738 end += ARRAY_SIZE(programsW);
739 lstrcpyW(end, name);
740 if ((p = wcsrchr(end, '.')) && !lstrcmpW(p, dot_soW)) *p = 0;
741 if ((p = wcsrchr(end, '.')) && !lstrcmpW(p, dot_exeW)) *p = 0;
742 p = end + lstrlenW(end);
743 *p++ = '\\';
744 lstrcpyW(p, name);
747 {
748 ret = match(param, file, buf);
750 if (ret) goto found;
751 }
752
753 heap_free(buf);
754 }
755
756 for (i = 0;; i++)
757 {
758 WCHAR env_name[64];
759 swprintf(env_name, ARRAY_SIZE(env_name), L"WINEDLLDIR%u", i);
760 if (!(env = process_getenv(process, env_name))) return FALSE;
761 len = wcslen(env) + wcslen(name) + 2;
762 if (!(buf = heap_alloc(len * sizeof(WCHAR)))) return FALSE;
763 swprintf(buf, len, L"%s\\%s", env, name);
766 {
767 ret = match(param, file, buf);
769 if (ret) goto found;
770 }
771 heap_free(buf);
772 }
773
774 return FALSE;
775
776found:
777 TRACE("found %s\n", debugstr_w(buf));
778 heap_free(buf);
779 return TRUE;
780}
#define wcsrchr
Definition: compat.h:16
#define CreateFileW
Definition: compat.h:741
const WCHAR * process_getenv(const struct process *process, const WCHAR *name)
Definition: dbghelp.c:335
int WINAPI lstrcmpW(LPCWSTR str1, LPCWSTR str2)
Definition: locale.c:4243
#define swprintf
Definition: precomp.h:40
GLfloat param
Definition: glext.h:5796
_CRTIMP size_t __cdecl wcslen(_In_z_ const wchar_t *_Str)
#define L(x)
Definition: ntvdm.h:50
_CRTIMP wchar_t *__cdecl wcscpy(_Out_writes_z_(_String_length_(_Source)+1) wchar_t *_Dest, _In_z_ const wchar_t *_Source)
Definition: match.c:28

Referenced by elf_search_and_load_file(), macho_search_and_load_file(), and pe_load_native_module().

◆ search_unix_path()

BOOL search_unix_path ( const WCHAR name,
const WCHAR path,
BOOL(*)(void *, HANDLE, const WCHAR *)  match,
void param 
)

Definition at line 782 of file path.c.

783{
784 const WCHAR *iter, *next;
785 size_t size, len;
786 WCHAR *dos_path;
787 char *buf;
788 BOOL ret = FALSE;
789
790 if (!path) return FALSE;
792
795 if (!(buf = heap_alloc(size))) return FALSE;
796
797 for (iter = path;; iter = next + 1)
798 {
799 if (!(next = wcschr(iter, ':'))) next = iter + lstrlenW(iter);
800 if (*iter == '/')
801 {
802 len = WideCharToMultiByte(CP_UNIXCP, 0, iter, next - iter, buf, size, NULL, NULL);
803 if (buf[len - 1] != '/') buf[len++] = '/';
805 if ((dos_path = wine_get_dos_file_name(buf)))
806 {
809 {
810 ret = match(param, file, dos_path);
812 if (ret) TRACE("found %s\n", debugstr_w(dos_path));
813 }
814 heap_free(dos_path);
815 if (ret) break;
816 }
817 }
818 if (*next != ':') break;
819 }
820
821 heap_free(buf);
822 return ret;
823}

Referenced by elf_search_and_load_file(), and macho_search_and_load_file().

◆ source_get()

const char * source_get ( const struct module module,
unsigned  idx 
)

◆ source_new()

unsigned source_new ( struct module module,
const char basedir,
const char source 
)

Definition at line 66 of file source.c.

67{
68 unsigned ret = -1;
69 const char* full;
70 char* tmp = NULL;
71
72 if (!name) return ret;
73 if (!base || *name == '/')
74 full = name;
75 else
76 {
77 unsigned bsz = strlen(base);
78
79 tmp = HeapAlloc(GetProcessHeap(), 0, bsz + 1 + strlen(name) + 1);
80 if (!tmp) return ret;
81 full = tmp;
82 strcpy(tmp, base);
83 if (tmp[bsz - 1] != '/') tmp[bsz++] = '/';
84 strcpy(&tmp[bsz], name);
85 }
87 if (!module->sources || (ret = source_find(full)) == (unsigned)-1)
88 {
89 char* new;
90 int len = strlen(full) + 1;
91 struct source_rb* rb;
92
94 {
95 if (!module->sources)
96 {
97 module->sources_alloc = (module->sources_used + len + 1 + 255) & ~255;
99 }
100 else
101 {
103 (module->sources_used + len + 1 + 255) & ~255 );
106 }
107 if (!new) goto done;
108 module->sources = new;
109 }
114 if ((rb = pool_alloc(&module->pool, sizeof(*rb))))
115 {
116 rb->source = ret;
118 }
119 }
120done:
121 HeapFree(GetProcessHeap(), 0, tmp);
122 return ret;
123}
void * pool_alloc(struct pool *a, size_t len) DECLSPEC_HIDDEN
Definition: storage.c:89
static struct module * rb_module
Definition: source.c:33
static unsigned source_find(const char *name)
Definition: source.c:52
static int wine_rb_put(struct wine_rb_tree *tree, const void *key, struct wine_rb_entry *entry)
Definition: rbtree.h:215
unsigned source
Definition: source.c:37
struct wine_rb_entry entry
Definition: source.c:36

Referenced by codeview_snarf(), codeview_snarf_linetab(), codeview_snarf_linetab2(), coff_add_file(), dwarf2_parse_compilation_unit(), dwarf2_parse_line_numbers(), elf_hash_symtab(), pe_load_coff_symbol_table(), rsym_parse(), and stabs_parse().

◆ source_rb_compare()

int source_rb_compare ( const void key,
const struct wine_rb_entry entry 
)

Definition at line 40 of file source.c.

41{
42 const struct source_rb *t = WINE_RB_ENTRY_VALUE(entry, const struct source_rb, entry);
43
44 return strcmp((const char*)key, rb_module->sources + t->source);
45}
int strcmp(const char *String1, const char *String2)
Definition: utclib.c:469
GLdouble GLdouble t
Definition: gl.h:2047
#define WINE_RB_ENTRY_VALUE(element, type, field)
Definition: rbtree.h:31
Definition: copy.c:22

Referenced by module_new().

◆ sparse_array_add()

void * sparse_array_add ( struct sparse_array sa,
ULONG_PTR  key,
struct pool pool 
)

Definition at line 281 of file storage.c.

283{
284 unsigned idx, i;
285 struct key2index* pk2i;
286 struct key2index* to;
287
288 pk2i = sparse_array_lookup(sa, key, &idx);
289 if (pk2i && pk2i->key == key)
290 {
291 FIXME("re-adding an existing key\n");
292 return NULL;
293 }
294 to = vector_add(&sa->key2index, pool);
295 if (pk2i)
296 {
297 /* we need to shift vector's content... */
298 /* let's do it brute force... (FIXME) */
299 assert(sa->key2index.num_elts >= 2);
300 for (i = sa->key2index.num_elts - 1; i > idx; i--)
301 {
302 pk2i = vector_at(&sa->key2index, i - 1);
303 *to = *pk2i;
304 to = pk2i;
305 }
306 }
307
308 to->key = key;
309 to->index = sa->elements.num_elts;
310
311 return vector_add(&sa->elements, pool);
312}
static struct sockaddr_in sa
Definition: adnsresfilter.c:69
void * vector_at(const struct vector *v, unsigned pos)
Definition: storage.c:162
static struct key2index * sparse_array_lookup(const struct sparse_array *sa, ULONG_PTR key, unsigned *idx)
Definition: storage.c:224
void * vector_add(struct vector *v, struct pool *pool)
Definition: storage.c:171
unsigned index
Definition: storage.c:210
ULONG_PTR key
Definition: storage.c:209

Referenced by dwarf2_parse_abbrev_set(), dwarf2_read_one_debug_info(), and rsym_parse().

◆ sparse_array_find()

void * sparse_array_find ( const struct sparse_array sa,
ULONG_PTR  idx 
)

Definition at line 271 of file storage.c.

272{
273 unsigned idx;
274 struct key2index* pk2i;
275
276 if ((pk2i = sparse_array_lookup(sa, key, &idx)) && pk2i->key == key)
277 return vector_at(&sa->elements, pk2i->index);
278 return NULL;
279}

Referenced by dwarf2_abbrev_table_find_entry(), dwarf2_find_attribute(), dwarf2_get_cpp_name(), dwarf2_get_di_children(), dwarf2_lookup_type(), and rsym_parse().

◆ sparse_array_init()

void sparse_array_init ( struct sparse_array sa,
unsigned  elt_sz,
unsigned  bucket_sz 
)

Definition at line 213 of file storage.c.

214{
215 vector_init(&sa->key2index, sizeof(struct key2index), bucket_sz);
216 vector_init(&sa->elements, elt_sz, bucket_sz);
217}
void vector_init(struct vector *v, unsigned esz, unsigned bucket_sz)
Definition: storage.c:133

Referenced by dwarf2_parse_abbrev_set(), dwarf2_parse_compilation_unit(), and rsym_parse().

◆ sparse_array_length()

unsigned sparse_array_length ( const struct sparse_array sa)

Definition at line 314 of file storage.c.

315{
316 return sa->elements.num_elts;
317}

Referenced by dwarf2_parse_abbrev_set().

◆ stabs_parse()

BOOL stabs_parse ( struct module module,
ULONG_PTR  load_offset,
const char stabs,
size_t  nstab,
size_t  stabsize,
const char strs,
int  strtablen,
stabs_def_cb  callback,
void user 
)

Definition at line 1241 of file stabs.c.

1245{
1246 struct symt_function* curr_func = NULL;
1247 struct symt_block* block = NULL;
1248 struct symt_compiland* compiland = NULL;
1249 char* srcpath = NULL;
1250 int i;
1251 const char* ptr;
1252 char* stabbuff;
1253 unsigned int stabbufflen;
1254 const struct stab_nlist* stab_ptr;
1255 const char* strs_end;
1256 int strtabinc;
1257 char symname[4096];
1258 unsigned incl[32];
1259 int incl_stk = -1;
1260 int source_idx = -1;
1261 struct pending_list pending_block;
1262 struct pending_list pending_func;
1263 BOOL ret = TRUE;
1264 struct location loc;
1265 unsigned char type;
1266 uint64_t n_value;
1267
1268 strs_end = strs + strtablen;
1269
1270 memset(stabs_basic, 0, sizeof(stabs_basic));
1271 memset(&pending_block, 0, sizeof(pending_block));
1272 memset(&pending_func, 0, sizeof(pending_func));
1273
1274 /*
1275 * Allocate a buffer into which we can build stab strings for cases
1276 * where the stab is continued over multiple lines.
1277 */
1278 stabbufflen = 65536;
1279 stabbuff = HeapAlloc(GetProcessHeap(), 0, stabbufflen);
1280
1281 strtabinc = 0;
1282 stabbuff[0] = '\0';
1283 for (i = 0; i < nstab; i++)
1284 {
1285 stab_ptr = (struct stab_nlist *)(pv_stab_ptr + i * stabsize);
1286 n_value = stabsize == sizeof(struct macho64_nlist) ? ((struct macho64_nlist *)stab_ptr)->n_value : stab_ptr->n_value;
1287 ptr = strs + stab_ptr->n_strx;
1288 if ((ptr > strs_end) || (ptr + strlen(ptr) > strs_end))
1289 {
1290 WARN("Bad stabs string %p\n", ptr);
1291 continue;
1292 }
1293 if (*ptr != '\0' && (ptr[strlen(ptr) - 1] == '\\'))
1294 {
1295 /*
1296 * Indicates continuation. Append this to the buffer, and go onto the
1297 * next record. Repeat the process until we find a stab without the
1298 * '/' character, as this indicates we have the whole thing.
1299 */
1300 stabbuf_append(&stabbuff, &stabbufflen, ptr);
1301 continue;
1302 }
1303 else if (stabbuff[0] != '\0')
1304 {
1305 stabbuf_append(&stabbuff, &stabbufflen, ptr);
1306 ptr = stabbuff;
1307 }
1308
1309 if (stab_ptr->n_type & N_STAB)
1310 type = stab_ptr->n_type;
1311 else
1312 {
1313 type = (stab_ptr->n_type & N_TYPE);
1314 if (module->type == DMT_MACHO) type &= ~N_PEXT;
1315 }
1316
1317 /* only symbol entries contain a typedef */
1318 switch (type)
1319 {
1320 case N_GSYM:
1321 case N_LCSYM:
1322 case N_STSYM:
1323 case N_RSYM:
1324 case N_LSYM:
1325 case N_ROSYM:
1326 case N_PSYM:
1327 if (strchr(ptr, '=') != NULL)
1328 {
1329 /*
1330 * The stabs aren't in writable memory, so copy it over so we are
1331 * sure we can scribble on it.
1332 */
1333 if (ptr != stabbuff)
1334 {
1335 stabbuff[0] = 0;
1336 stabbuf_append(&stabbuff, &stabbufflen, ptr);
1337 ptr = stabbuff;
1338 }
1339 stab_strcpy(symname, sizeof(symname), ptr);
1340 if (!stabs_parse_typedef(module, ptr, symname))
1341 {
1342 /* skip this definition */
1343 stabbuff[0] = '\0';
1344 continue;
1345 }
1346 }
1347 }
1348
1349 switch (type)
1350 {
1351 case N_GSYM:
1352 /*
1353 * These are useless with ELF. They have no value, and you have to
1354 * read the normal symbol table to get the address. Thus we
1355 * ignore them, and when we process the normal symbol table
1356 * we should do the right thing.
1357 *
1358 * With a.out or mingw, they actually do make some amount of sense.
1359 */
1360 stab_strcpy(symname, sizeof(symname), ptr);
1361 loc.kind = loc_absolute;
1362 loc.reg = 0;
1363 loc.offset = load_offset + n_value;
1364 symt_new_global_variable(module, compiland, symname, TRUE /* FIXME */,
1365 loc, 0, stabs_parse_type(ptr));
1366 break;
1367 case N_LCSYM:
1368 case N_STSYM:
1369 /* These are static symbols and BSS symbols. */
1370 stab_strcpy(symname, sizeof(symname), ptr);
1371 loc.kind = loc_absolute;
1372 loc.reg = 0;
1373 loc.offset = load_offset + n_value;
1374 symt_new_global_variable(module, compiland, symname, TRUE /* FIXME */,
1375 loc, 0, stabs_parse_type(ptr));
1376 break;
1377 case N_LBRAC:
1378 if (curr_func)
1379 {
1380 block = symt_open_func_block(module, curr_func, block,
1381 n_value, 0);
1382 pending_flush(&pending_block, module, curr_func, block);
1383 }
1384 break;
1385 case N_RBRAC:
1386 if (curr_func)
1388 n_value);
1389 break;
1390 case N_PSYM:
1391 /* These are function parameters. */
1392 if (curr_func != NULL)
1393 {
1394 struct symt* param_type = stabs_parse_type(ptr);
1395 stab_strcpy(symname, sizeof(symname), ptr);
1396 loc.kind = loc_regrel;
1397 loc.reg = dbghelp_current_cpu->frame_regno;
1398 loc.offset = n_value;
1399 symt_add_func_local(module, curr_func,
1400 (int)n_value >= 0 ? DataIsParam : DataIsLocal,
1401 &loc, NULL, param_type, symname);
1403 (struct symt_function_signature*)curr_func->type,
1404 param_type);
1405 }
1406 break;
1407 case N_RSYM:
1408 /* These are registers (as local variables) */
1409 if (curr_func != NULL)
1410 {
1411 loc.kind = loc_register;
1412 loc.offset = 0;
1413
1414 switch (n_value)
1415 {
1416 case 0: loc.reg = CV_REG_EAX; break;
1417 case 1: loc.reg = CV_REG_ECX; break;
1418 case 2: loc.reg = CV_REG_EDX; break;
1419 case 3: loc.reg = CV_REG_EBX; break;
1420 case 4: loc.reg = CV_REG_ESP; break;
1421 case 5: loc.reg = CV_REG_EBP; break;
1422 case 6: loc.reg = CV_REG_ESI; break;
1423 case 7: loc.reg = CV_REG_EDI; break;
1424 case 11:
1425 case 12:
1426 case 13:
1427 case 14:
1428 case 15:
1429 case 16:
1430 case 17:
1431 case 18:
1432 case 19: loc.reg = CV_REG_ST0 + n_value - 12; break;
1433 case 21:
1434 case 22:
1435 case 23:
1436 case 24:
1437 case 25:
1438 case 26:
1439 case 27:
1440 case 28: loc.reg = CV_REG_XMM0 + n_value - 21; break;
1441 case 29:
1442 case 30:
1443 case 31:
1444 case 32:
1445 case 33:
1446 case 34:
1447 case 35:
1448 case 36: loc.reg = CV_REG_MM0 + n_value - 29; break;
1449 default:
1450 FIXME("Unknown register value (%lu)\n", (ULONG_PTR)n_value);
1451 loc.reg = CV_REG_NONE;
1452 break;
1453 }
1454 stab_strcpy(symname, sizeof(symname), ptr);
1455 if (ptr[strlen(symname) + 1] == 'P')
1456 {
1457 struct symt* param_type = stabs_parse_type(ptr);
1458 stab_strcpy(symname, sizeof(symname), ptr);
1459 symt_add_func_local(module, curr_func, DataIsParam, &loc,
1460 NULL, param_type, symname);
1462 (struct symt_function_signature*)curr_func->type,
1463 param_type);
1464 }
1465 else
1466 pending_add_var(&pending_block, ptr, DataIsLocal, &loc);
1467 }
1468 break;
1469 case N_LSYM:
1470 /* These are local variables */
1471 loc.kind = loc_regrel;
1472 loc.reg = dbghelp_current_cpu->frame_regno;
1473 loc.offset = n_value;
1474 if (curr_func != NULL) pending_add_var(&pending_block, ptr, DataIsLocal, &loc);
1475 break;
1476 case N_SLINE:
1477 /*
1478 * This is a line number. These are always relative to the start
1479 * of the function (N_FUN), and this makes the lookup easier.
1480 */
1481 assert(source_idx >= 0);
1482 if (curr_func != NULL)
1483 {
1484 ULONG_PTR offset = n_value;
1485 if (module->type == DMT_MACHO)
1486 offset -= curr_func->address - load_offset;
1487 symt_add_func_line(module, curr_func, source_idx,
1488 stab_ptr->n_desc, offset);
1489 }
1490 else pending_add_line(&pending_func, source_idx, stab_ptr->n_desc,
1491 n_value, load_offset);
1492 break;
1493 case N_FUN:
1494 /*
1495 * For now, just declare the various functions. Later
1496 * on, we will add the line number information and the
1497 * local symbols.
1498 */
1499 /*
1500 * Copy the string to a temp buffer so we
1501 * can kill everything after the ':'. We do
1502 * it this way because otherwise we end up dirtying
1503 * all of the pages related to the stabs, and that
1504 * sucks up swap space like crazy.
1505 */
1506 stab_strcpy(symname, sizeof(symname), ptr);
1507 if (*symname)
1508 {
1509 struct symt_function_signature* func_type;
1510
1511 if (curr_func)
1512 {
1513 /* First, clean up the previous function we were working on.
1514 * Assume size of the func is the delta between current offset
1515 * and offset of last function
1516 */
1518 n_value ?
1519 (load_offset + n_value - curr_func->address) : 0);
1520 }
1522 stabs_parse_type(ptr), -1);
1523 curr_func = symt_new_function(module, compiland, symname,
1524 load_offset + n_value, 0,
1525 &func_type->symt);
1526 pending_flush(&pending_func, module, curr_func, NULL);
1527 }
1528 else
1529 {
1530 /* some versions of GCC to use a N_FUN "" to mark the end of a function
1531 * and n_value contains the size of the func
1532 */
1533 stabs_finalize_function(module, curr_func, n_value);
1534 curr_func = NULL;
1535 }
1536 break;
1537 case N_SO:
1538 /*
1539 * This indicates a new source file. Append the records
1540 * together, to build the correct path name.
1541 */
1542 if (*ptr == '\0') /* end of N_SO file */
1543 {
1544 /* Nuke old path. */
1545 HeapFree(GetProcessHeap(), 0, srcpath);
1546 srcpath = NULL;
1547 stabs_finalize_function(module, curr_func, 0);
1548 curr_func = NULL;
1549 source_idx = -1;
1550 incl_stk = -1;
1551 assert(block == NULL);
1552 compiland = NULL;
1553 }
1554 else
1555 {
1556 int len = strlen(ptr);
1557 if (ptr[len-1] != '/')
1558 {
1560 source_idx = source_new(module, srcpath, ptr);
1561 compiland = symt_new_compiland(module, 0 /* FIXME */, source_idx);
1562 }
1563 else
1564 {
1565 srcpath = HeapAlloc(GetProcessHeap(), 0, len + 1);
1566 strcpy(srcpath, ptr);
1567 }
1568 }
1569 break;
1570 case N_SOL:
1571 source_idx = source_new(module, srcpath, ptr);
1572 break;
1573 case N_UNDF:
1574 strs += strtabinc;
1575 strtabinc = n_value;
1576 /* I'm not sure this is needed, so trace it before we obsolete it */
1577 if (curr_func)
1578 {
1579 FIXME("UNDF: curr_func %s\n", curr_func->hash_elt.name);
1580 stabs_finalize_function(module, curr_func, 0); /* FIXME */
1581 curr_func = NULL;
1582 }
1583 break;
1584 case N_OPT:
1585 /* Ignore this. We don't care what it points to. */
1586 break;
1587 case N_BINCL:
1589 assert(incl_stk < (int) ARRAY_SIZE(incl) - 1);
1590 incl[++incl_stk] = source_idx;
1591 source_idx = source_new(module, NULL, ptr);
1592 break;
1593 case N_EINCL:
1594 assert(incl_stk >= 0);
1595 source_idx = incl[incl_stk--];
1596 break;
1597 case N_EXCL:
1598 if (stabs_add_include(stabs_find_include(ptr, n_value)) < 0)
1599 {
1600 ERR("Excluded header not found (%s,%ld)\n", ptr, (ULONG_PTR)n_value);
1602 ret = FALSE;
1603 goto done;
1604 }
1605 break;
1606 case N_MAIN:
1607 /* Always ignore these. GCC doesn't even generate them. */
1608 break;
1609 case N_BNSYM:
1610 case N_ENSYM:
1611 case N_OSO:
1612 case N_INDR:
1613 /* Always ignore these, they seem to be used only on Darwin. */
1614 break;
1615 case N_ABS:
1616 case N_SECT:
1617 /* FIXME: Other definition types (N_TEXT, N_DATA, N_BSS, ...)? */
1618 if (callback)
1619 {
1620 BOOL is_public = (stab_ptr->n_type & N_EXT);
1621 BOOL is_global = is_public;
1622
1623 /* "private extern"; shared among compilation units in a shared
1624 * library, but not accessible from outside the library. */
1625 if (stab_ptr->n_type & N_PEXT)
1626 {
1627 is_public = FALSE;
1628 is_global = TRUE;
1629 }
1630
1631 if (*ptr == '_') ptr++;
1632 stab_strcpy(symname, sizeof(symname), ptr);
1633
1634 callback(module, load_offset, symname, n_value,
1635 is_public, is_global, stab_ptr->n_other, compiland, user);
1636 }
1637 break;
1638 default:
1639 ERR("Unknown stab type 0x%02x\n", type);
1640 break;
1641 }
1642 stabbuff[0] = '\0';
1643 TRACE("0x%02x %lx %s\n",
1644 stab_ptr->n_type, (ULONG_PTR)n_value, debugstr_a(strs + stab_ptr->n_strx));
1645 }
1647 module->module.CVSig = 'S' | ('T' << 8) | ('A' << 16) | ('B' << 24);
1648 /* FIXME: we could have a finer grain here */
1654done:
1655 HeapFree(GetProcessHeap(), 0, stabbuff);
1657 HeapFree(GetProcessHeap(), 0, pending_block.objs);
1658 HeapFree(GetProcessHeap(), 0, pending_func.objs);
1659 HeapFree(GetProcessHeap(), 0, srcpath);
1660
1661 return ret;
1662}
char * strchr(const char *String, int ch)
Definition: utclib.c:501
void user(int argc, const char *argv[])
Definition: cmds.c:1350
struct symt_data * symt_add_func_local(struct module *module, struct symt_function *func, enum DataKind dt, const struct location *loc, struct symt_block *block, struct symt *type, const char *name) DECLSPEC_HIDDEN
Definition: symbol.c:378
struct symt_function_signature * symt_new_function_signature(struct module *module, struct symt *ret_type, enum CV_call_e call_conv) DECLSPEC_HIDDEN
Definition: type.c:377
struct symt_block * symt_close_func_block(struct module *module, const struct symt_function *func, struct symt_block *block, unsigned pc) DECLSPEC_HIDDEN
Definition: symbol.c:440
struct symt_data * symt_new_global_variable(struct module *module, struct symt_compiland *parent, const char *name, unsigned is_static, struct location loc, ULONG_PTR size, struct symt *type) DECLSPEC_HIDDEN
Definition: symbol.c:256
struct symt_block * symt_open_func_block(struct module *module, struct symt_function *func, struct symt_block *block, unsigned pc, unsigned len) DECLSPEC_HIDDEN
Definition: symbol.c:413
void module_reset_debug_info(struct module *module) DECLSPEC_HIDDEN
Definition: module.c:1328
struct symt_compiland * symt_new_compiland(struct module *module, ULONG_PTR address, unsigned src_idx) DECLSPEC_HIDDEN
Definition: symbol.c:207
BOOL symt_add_function_signature_parameter(struct module *module, struct symt_function_signature *sig, struct symt *param) DECLSPEC_HIDDEN
Definition: type.c:394
UINT64 uint64_t
Definition: types.h:77
@ CV_REG_EBX
Definition: compat.h:1699
@ CV_REG_XMM0
Definition: compat.h:1744
@ CV_REG_ESI
Definition: compat.h:1702
@ CV_REG_ECX
Definition: compat.h:1697
@ CV_REG_ST0
Definition: compat.h:1732
@ CV_REG_EBP
Definition: compat.h:1701
@ CV_REG_EAX
Definition: compat.h:1696
@ CV_REG_EDI
Definition: compat.h:1703
@ CV_REG_MM0
Definition: compat.h:1743
@ CV_REG_ESP
Definition: compat.h:1700
@ CV_REG_EDX
Definition: compat.h:1698
@ CV_REG_NONE
Definition: compat.h:1679
@ DataIsLocal
Definition: compat.h:1649
@ DataIsParam
Definition: compat.h:1651
struct cpu * dbghelp_current_cpu
Definition: dbghelp.c:169
GLintptr offset
Definition: glext.h:5920
static IPrintDialogCallback callback
Definition: printdlg.c:326
static void stab_strcpy(char *dest, int sz, const char *source)
Definition: stabs.c:95
static int stabs_find_include(const char *file, ULONG_PTR val)
Definition: stabs.c:174