Signed-off-by: Zebediah Figura zfigura@codeweavers.com --- dlls/dbghelp/dbghelp_private.h | 2 +- dlls/dbghelp/macho_module.c | 66 +++++++++++++++++++++--------------------- dlls/dbghelp/module.c | 2 +- 3 files changed, 35 insertions(+), 35 deletions(-)
diff --git a/dlls/dbghelp/dbghelp_private.h b/dlls/dbghelp/dbghelp_private.h index 935e766..0963f1e 100644 --- a/dlls/dbghelp/dbghelp_private.h +++ b/dlls/dbghelp/dbghelp_private.h @@ -591,7 +591,7 @@ extern int elf_is_in_thunk_area(unsigned long addr, const struct elf_th /* macho_module.c */ extern BOOL macho_enum_modules(HANDLE hProc, enum_modules_cb, void*) DECLSPEC_HIDDEN; extern BOOL macho_fetch_file_info(HANDLE process, const WCHAR* name, unsigned long load_addr, DWORD_PTR* base, DWORD* size, DWORD* checksum) DECLSPEC_HIDDEN; -extern BOOL macho_load_debug_info(struct module* module) DECLSPEC_HIDDEN; +extern BOOL macho_load_debug_info(struct process *pcs, struct module* module) DECLSPEC_HIDDEN; extern struct module* macho_load_module(struct process* pcs, const WCHAR* name, unsigned long) DECLSPEC_HIDDEN; extern BOOL macho_read_wine_loader_dbg_info(struct process* pcs) DECLSPEC_HIDDEN; diff --git a/dlls/dbghelp/macho_module.c b/dlls/dbghelp/macho_module.c index 7c40801..ee35af5 100644 --- a/dlls/dbghelp/macho_module.c +++ b/dlls/dbghelp/macho_module.c @@ -91,17 +91,9 @@ WINE_DEFAULT_DEBUG_CHANNEL(dbghelp_macho); #ifdef _WIN64 typedef struct segment_command_64 macho_segment_command; typedef struct nlist_64 macho_nlist; - -#define TARGET_CPU_TYPE CPU_TYPE_X86_64 -#define TARGET_MH_MAGIC MH_MAGIC_64 -#define TARGET_SEGMENT_COMMAND LC_SEGMENT_64 #else typedef struct segment_command macho_segment_command; typedef struct nlist macho_nlist; - -#define TARGET_CPU_TYPE CPU_TYPE_X86 -#define TARGET_MH_MAGIC MH_MAGIC -#define TARGET_SEGMENT_COMMAND LC_SEGMENT #endif
@@ -610,7 +602,8 @@ static inline void reset_file_map(struct image_file_map* ifm) * * Maps a Mach-O file into memory (and checks it's a real Mach-O file) */ -static BOOL macho_map_file(const WCHAR* filenameW, BOOL split_segs, struct image_file_map* ifm) +static BOOL macho_map_file(struct process *pcs, const WCHAR *filenameW, + BOOL split_segs, struct image_file_map* ifm) { struct macho_file_map* fmap = &ifm->u.macho; struct fat_header fat_header; @@ -620,17 +613,16 @@ static BOOL macho_map_file(const WCHAR* filenameW, BOOL split_segs, struct image unsigned len; struct section_info info; BOOL ret = FALSE; + cpu_type_t target_cpu = (pcs->is_64bit) ? CPU_TYPE_X86_64 : CPU_TYPE_X86; + uint32_t target_magic = (pcs->is_64bit) ? MH_MAGIC_64 : MH_MAGIC; + uint32_t target_cmd = (pcs->is_64bit) ? LC_SEGMENT_64 : LC_SEGMENT;
TRACE("(%s, %p)\n", debugstr_w(filenameW), fmap);
reset_file_map(ifm);
ifm->modtype = DMT_MACHO; -#ifdef _WIN64 - ifm->addr_size = 64; -#else - ifm->addr_size = 32; -#endif + ifm->addr_size = (pcs->is_64bit) ? 64 : 32;
len = WideCharToMultiByte(CP_UNIXCP, 0, filenameW, -1, NULL, 0, NULL, NULL); if (!(filename = HeapAlloc(GetProcessHeap(), 0, len))) @@ -670,14 +662,14 @@ static BOOL macho_map_file(const WCHAR* filenameW, BOOL split_segs, struct image struct fat_arch fat_arch; if (read(fmap->fd, &fat_arch, sizeof(fat_arch)) != sizeof(fat_arch)) goto done; - if (swap_ulong_be_to_host(fat_arch.cputype) == TARGET_CPU_TYPE) + if (swap_ulong_be_to_host(fat_arch.cputype) == target_cpu) { fmap->arch_offset = swap_ulong_be_to_host(fat_arch.offset); break; } } if (i >= narch) goto done; - TRACE("... found target arch (%d)\n", TARGET_CPU_TYPE); + TRACE("... found target arch (%d)\n", target_cpu); } else { @@ -691,8 +683,8 @@ static BOOL macho_map_file(const WCHAR* filenameW, BOOL split_segs, struct image goto done; TRACE("... got possible Mach header\n"); /* and check for a Mach-O header */ - if (fmap->mach_header.magic != TARGET_MH_MAGIC || - fmap->mach_header.cputype != TARGET_CPU_TYPE) goto done; + if (fmap->mach_header.magic != target_magic || + fmap->mach_header.cputype != target_cpu) goto done; /* Make sure the file type is one of the ones we expect. */ switch (fmap->mach_header.filetype) { @@ -708,7 +700,7 @@ static BOOL macho_map_file(const WCHAR* filenameW, BOOL split_segs, struct image TRACE("... verified Mach header\n");
fmap->num_sections = 0; - if (macho_enum_load_commands(fmap, TARGET_SEGMENT_COMMAND, macho_count_sections, NULL) < 0) + if (macho_enum_load_commands(fmap, target_cmd, macho_count_sections, NULL) < 0) goto done; TRACE("%d sections\n", fmap->num_sections);
@@ -721,7 +713,7 @@ static BOOL macho_map_file(const WCHAR* filenameW, BOOL split_segs, struct image
info.split_segs = split_segs; info.section_index = 0; - if (macho_enum_load_commands(fmap, TARGET_SEGMENT_COMMAND, macho_load_section_info, &info) < 0) + if (macho_enum_load_commands(fmap, target_cmd, macho_load_section_info, &info) < 0) { fmap->num_sections = 0; goto done; @@ -1072,11 +1064,11 @@ static void macho_finish_stabs(struct module* module, struct hash_table* ht_symt * TRUE. If it can't be mapped or its UUID doesn't match, return * FALSE. */ -static BOOL try_dsym(const WCHAR* path, struct macho_file_map* fmap) +static BOOL try_dsym(struct process *pcs, const WCHAR* path, struct macho_file_map* fmap) { struct image_file_map dsym_ifm;
- if (macho_map_file(path, FALSE, &dsym_ifm)) + if (macho_map_file(pcs, path, FALSE, &dsym_ifm)) { char uuid_string[UUID_STRING_LEN];
@@ -1110,7 +1102,7 @@ static BOOL try_dsym(const WCHAR* path, struct macho_file_map* fmap) * "dsymutil --flat". Finally, use Spotlight to search for a * .dSYM bundle with the same UUID as the module file. */ -static void find_and_map_dsym(struct module* module) +static void find_and_map_dsym(struct process *pcs, struct module* module) { static const WCHAR dot_dsym[] = {'.','d','S','Y','M',0}; static const WCHAR dsym_subpath[] = {'/','C','o','n','t','e','n','t','s','/','R','e','s','o','u','r','c','e','s','/','D','W','A','R','F','/',0}; @@ -1142,12 +1134,12 @@ static void find_and_map_dsym(struct module* module) strcatW(path, dsym_subpath); strcatW(path, p);
- if (try_dsym(path, fmap)) + if (try_dsym(pcs, path, fmap)) goto found;
strcpyW(path + strlenW(module->module.LoadedImageName), dot_dwarf);
- if (try_dsym(path, fmap)) + if (try_dsym(pcs, path, fmap)) goto found;
format_uuid(fmap->uuid->uuid, uuid_string); @@ -1175,7 +1167,7 @@ static void find_and_map_dsym(struct module* module) strcatW(path, p); CFRelease(item_path);
- if (try_dsym(path, fmap)) + if (try_dsym(pcs, path, fmap)) goto found; } } @@ -1201,9 +1193,13 @@ static BOOL image_uses_split_segs(HANDLE process, unsigned long load_addr)
if (process && load_addr) { + struct process *pcs = process_find_by_handle(process); + cpu_type_t target_cpu = (pcs->is_64bit) ? CPU_TYPE_X86_64 : CPU_TYPE_X86; + uint32_t target_magic = (pcs->is_64bit) ? MH_MAGIC_64 : MH_MAGIC; macho_mach_header header; + if (ReadProcessMemory(process, (void*)load_addr, &header, sizeof(header), NULL) && - header.magic == TARGET_MH_MAGIC && header.cputype == TARGET_CPU_TYPE && + header.magic == target_magic && header.cputype == target_cpu && header.flags & MACHO_DYLD_IN_SHARED_CACHE) { split_segs = TRUE; @@ -1218,7 +1214,7 @@ static BOOL image_uses_split_segs(HANDLE process, unsigned long load_addr) * * Loads Mach-O debugging information from the module image file. */ -BOOL macho_load_debug_info(struct module* module) +BOOL macho_load_debug_info(struct process *pcs, struct module* module) { BOOL ret = FALSE; struct macho_debug_info mdi; @@ -1239,7 +1235,7 @@ BOOL macho_load_debug_info(struct module* module)
if (!(dbghelp_options & SYMOPT_PUBLICS_ONLY)) { - find_and_map_dsym(module); + find_and_map_dsym(pcs, module);
if (dwarf2_parse(module, module->reloc_delta, NULL /* FIXME: some thunks to deal with ? */, &module->format_info[DFI_MACHO]->u.macho_info->file_map)) @@ -1281,12 +1277,16 @@ BOOL macho_fetch_file_info(HANDLE process, const WCHAR* name, unsigned long load DWORD* size, DWORD* checksum) { struct image_file_map fmap; + struct process *pcs; BOOL split_segs;
TRACE("(%s, %p, %p, %p)\n", debugstr_w(name), base, size, checksum);
+ pcs = process_find_by_handle(process); + if (!pcs) return FALSE; + split_segs = image_uses_split_segs(process, load_addr); - if (!macho_map_file(name, split_segs, &fmap)) return FALSE; + if (!macho_map_file(pcs, name, split_segs, &fmap)) return FALSE; if (base) *base = fmap.u.macho.segs_start; *size = fmap.u.macho.segs_size; *checksum = calc_crc32(fmap.u.macho.fd); @@ -1375,7 +1375,7 @@ static BOOL macho_load_file(struct process* pcs, const WCHAR* filename, load_addr, macho_info, macho_info->flags);
split_segs = image_uses_split_segs(pcs->handle, load_addr); - if (!macho_map_file(filename, split_segs, &fmap)) return FALSE; + if (!macho_map_file(pcs, filename, split_segs, &fmap)) return FALSE;
/* Find the dynamic loader's table of images loaded into the process. */ @@ -1415,7 +1415,7 @@ static BOOL macho_load_file(struct process* pcs, const WCHAR* filename, reset_file_map(&fmap); if (dbghelp_options & SYMOPT_DEFERRED_LOADS) macho_info->module->module.SymType = SymDeferred; - else if (!macho_load_debug_info(macho_info->module)) + else if (!macho_load_debug_info(pcs, macho_info->module)) ret = FALSE;
macho_info->module->format_info[DFI_MACHO]->u.macho_info->in_use = 1; @@ -1930,7 +1930,7 @@ struct module* macho_load_module(struct process* pcs, const WCHAR* name, unsign return NULL; }
-BOOL macho_load_debug_info(struct module* module) +BOOL macho_load_debug_info(struct process *pcs, struct module* module) { return FALSE; } diff --git a/dlls/dbghelp/module.c b/dlls/dbghelp/module.c index 3659873..040bf9b 100644 --- a/dlls/dbghelp/module.c +++ b/dlls/dbghelp/module.c @@ -397,7 +397,7 @@ BOOL module_get_debug(struct module_pair* pair) &idslW64); break; case DMT_MACHO: - ret = macho_load_debug_info(pair->effective); + ret = macho_load_debug_info(pair->pcs, pair->effective); break; default: ret = FALSE;
It is identical to the 64-bit header, except for the "reserved" field.
Signed-off-by: Zebediah Figura zfigura@codeweavers.com --- dlls/dbghelp/image_private.h | 4 +--- dlls/dbghelp/macho_module.c | 2 +- 2 files changed, 2 insertions(+), 4 deletions(-)
diff --git a/dlls/dbghelp/image_private.h b/dlls/dbghelp/image_private.h index b12cacb..60cdd35 100644 --- a/dlls/dbghelp/image_private.h +++ b/dlls/dbghelp/image_private.h @@ -46,10 +46,8 @@ #include <mach-o/loader.h>
#ifdef _WIN64 -typedef struct mach_header_64 macho_mach_header; typedef struct section_64 macho_section; #else -typedef struct mach_header macho_mach_header; typedef struct section macho_section; #endif #endif @@ -96,7 +94,7 @@ struct image_file_map struct image_file_map* dsym; /* the debug symbols file associated with this one */
#ifdef HAVE_MACH_O_LOADER_H - macho_mach_header mach_header; + struct mach_header mach_header; const struct load_command* load_commands; const struct uuid_command* uuid;
diff --git a/dlls/dbghelp/macho_module.c b/dlls/dbghelp/macho_module.c index ee35af5..679c203 100644 --- a/dlls/dbghelp/macho_module.c +++ b/dlls/dbghelp/macho_module.c @@ -1196,7 +1196,7 @@ static BOOL image_uses_split_segs(HANDLE process, unsigned long load_addr) struct process *pcs = process_find_by_handle(process); cpu_type_t target_cpu = (pcs->is_64bit) ? CPU_TYPE_X86_64 : CPU_TYPE_X86; uint32_t target_magic = (pcs->is_64bit) ? MH_MAGIC_64 : MH_MAGIC; - macho_mach_header header; + struct mach_header header;
if (ReadProcessMemory(process, (void*)load_addr, &header, sizeof(header), NULL) && header.magic == target_magic && header.cputype == target_cpu &&
Signed-off-by: Zebediah Figura zfigura@codeweavers.com --- dlls/dbghelp/macho_module.c | 38 ++++++++++++++++++++++---------------- 1 file changed, 22 insertions(+), 16 deletions(-)
diff --git a/dlls/dbghelp/macho_module.c b/dlls/dbghelp/macho_module.c index 679c203..50fcca4 100644 --- a/dlls/dbghelp/macho_module.c +++ b/dlls/dbghelp/macho_module.c @@ -467,10 +467,11 @@ static const struct load_command* macho_next_load_command(const struct load_comm * callback. If >=0, that's the count of load commands successfully * processed. */ -static int macho_enum_load_commands(struct macho_file_map* fmap, unsigned cmd, - int (*cb)(struct macho_file_map*, const struct load_command*, void*), +static int macho_enum_load_commands(struct image_file_map *ifm, unsigned cmd, + int (*cb)(struct image_file_map*, const struct load_command*, void*), void* user) { + struct macho_file_map* fmap = &ifm->u.macho; const struct load_command* lc; int i; int count = 0; @@ -488,7 +489,7 @@ static int macho_enum_load_commands(struct macho_file_map* fmap, unsigned cmd, if (cmd && cmd != lc->cmd) continue; count++;
- result = cb(fmap, lc, user); + result = cb(ifm, lc, user); TRACE("load_command[%d] (%p), cmd %u; callback => %d\n", i, lc, lc->cmd, result); if (result) return (result < 0) ? result : count; } @@ -503,13 +504,14 @@ static int macho_enum_load_commands(struct macho_file_map* fmap, unsigned cmd, * significant sections in a Mach-O file. All commands are * expected to be of LC_SEGMENT[_64] type. */ -static int macho_count_sections(struct macho_file_map* fmap, const struct load_command* lc, void* user) +static int macho_count_sections(struct image_file_map* ifm, const struct load_command* lc, void* user) { const macho_segment_command* sc = (const macho_segment_command*)lc;
- TRACE("(%p/%d, %p, %p) segment %s\n", fmap, fmap->fd, lc, user, debugstr_an(sc->segname, sizeof(sc->segname))); + TRACE("(%p/%d, %p, %p) segment %s\n", ifm, ifm->u.macho.fd, lc, user, + debugstr_an(sc->segname, sizeof(sc->segname)));
- fmap->num_sections += sc->nsects; + ifm->u.macho.num_sections += sc->nsects; return 0; }
@@ -520,8 +522,9 @@ static int macho_count_sections(struct macho_file_map* fmap, const struct load_c * range covered by the segments of a Mach-O file and builds the * section map. All commands are expected to be of LC_SEGMENT[_64] type. */ -static int macho_load_section_info(struct macho_file_map* fmap, const struct load_command* lc, void* user) +static int macho_load_section_info(struct image_file_map* ifm, const struct load_command* lc, void* user) { + struct macho_file_map* fmap = &ifm->u.macho; const macho_segment_command* sc = (const macho_segment_command*)lc; struct section_info* info = user; BOOL ignore; @@ -576,9 +579,9 @@ static int macho_load_section_info(struct macho_file_map* fmap, const struct loa * Callback for macho_enum_load_commands. Records the UUID load * command of a Mach-O file. */ -static int find_uuid(struct macho_file_map* fmap, const struct load_command* lc, void* user) +static int find_uuid(struct image_file_map* ifm, const struct load_command* lc, void* user) { - fmap->uuid = (const struct uuid_command*)lc; + ifm->u.macho.uuid = (const struct uuid_command*)lc; return 1; }
@@ -700,7 +703,7 @@ static BOOL macho_map_file(struct process *pcs, const WCHAR *filenameW, TRACE("... verified Mach header\n");
fmap->num_sections = 0; - if (macho_enum_load_commands(fmap, target_cmd, macho_count_sections, NULL) < 0) + if (macho_enum_load_commands(ifm, target_cmd, macho_count_sections, NULL) < 0) goto done; TRACE("%d sections\n", fmap->num_sections);
@@ -713,7 +716,7 @@ static BOOL macho_map_file(struct process *pcs, const WCHAR *filenameW,
info.split_segs = split_segs; info.section_index = 0; - if (macho_enum_load_commands(fmap, target_cmd, macho_load_section_info, &info) < 0) + if (macho_enum_load_commands(ifm, target_cmd, macho_load_section_info, &info) < 0) { fmap->num_sections = 0; goto done; @@ -723,7 +726,7 @@ static BOOL macho_map_file(struct process *pcs, const WCHAR *filenameW, TRACE("segs_start: 0x%08lx, segs_size: 0x%08lx\n", (unsigned long)fmap->segs_start, (unsigned long)fmap->segs_size);
- if (macho_enum_load_commands(fmap, LC_UUID, find_uuid, NULL) < 0) + if (macho_enum_load_commands(ifm, LC_UUID, find_uuid, NULL) < 0) goto done; if (fmap->uuid) { @@ -857,9 +860,10 @@ static void macho_stabs_def_cb(struct module* module, unsigned long load_offset, * Callback for macho_enum_load_commands. Processes the LC_SYMTAB * load commands from the Mach-O file. */ -static int macho_parse_symtab(struct macho_file_map* fmap, +static int macho_parse_symtab(struct image_file_map* ifm, const struct load_command* lc, void* user) { + struct macho_file_map* fmap = &ifm->u.macho; const struct symtab_command* sc = (const struct symtab_command*)lc; struct macho_debug_info* mdi = user; const macho_nlist* stab; @@ -1219,6 +1223,7 @@ BOOL macho_load_debug_info(struct process *pcs, struct module* module) BOOL ret = FALSE; struct macho_debug_info mdi; int result; + struct image_file_map *ifm; struct macho_file_map *fmap;
if (module->type != DMT_MACHO || !module->format_info[DFI_MACHO]->u.macho_info) @@ -1227,7 +1232,8 @@ BOOL macho_load_debug_info(struct process *pcs, struct module* module) return FALSE; }
- fmap = &module->format_info[DFI_MACHO]->u.macho_info->file_map.u.macho; + ifm = &module->format_info[DFI_MACHO]->u.macho_info->file_map; + fmap = &ifm->u.macho;
TRACE("(%p, %p/%d)\n", module, fmap, fmap->fd);
@@ -1246,7 +1252,7 @@ BOOL macho_load_debug_info(struct process *pcs, struct module* module) mdi.module = module; pool_init(&mdi.pool, 65536); hash_table_init(&mdi.pool, &mdi.ht_symtab, 256); - result = macho_enum_load_commands(fmap, LC_SYMTAB, macho_parse_symtab, &mdi); + result = macho_enum_load_commands(ifm, LC_SYMTAB, macho_parse_symtab, &mdi); if (result > 0) ret = TRUE; else if (result < 0) @@ -1255,7 +1261,7 @@ BOOL macho_load_debug_info(struct process *pcs, struct module* module) if (!(dbghelp_options & SYMOPT_PUBLICS_ONLY) && fmap->dsym) { mdi.fmap = &fmap->dsym->u.macho; - result = macho_enum_load_commands(mdi.fmap, LC_SYMTAB, macho_parse_symtab, &mdi); + result = macho_enum_load_commands(fmap->dsym, LC_SYMTAB, macho_parse_symtab, &mdi); if (result > 0) ret = TRUE; else if (result < 0)
Signed-off-by: Zebediah Figura zfigura@codeweavers.com --- dlls/dbghelp/macho_module.c | 68 +++++++++++++++++++++++++++++++++------------ 1 file changed, 50 insertions(+), 18 deletions(-)
diff --git a/dlls/dbghelp/macho_module.c b/dlls/dbghelp/macho_module.c index 50fcca4..52ea739 100644 --- a/dlls/dbghelp/macho_module.c +++ b/dlls/dbghelp/macho_module.c @@ -89,10 +89,8 @@ WINE_DEFAULT_DEBUG_CHANNEL(dbghelp_macho);
#ifdef _WIN64 -typedef struct segment_command_64 macho_segment_command; typedef struct nlist_64 macho_nlist; #else -typedef struct segment_command macho_segment_command; typedef struct nlist macho_nlist; #endif
@@ -506,12 +504,26 @@ static int macho_enum_load_commands(struct image_file_map *ifm, unsigned cmd, */ static int macho_count_sections(struct image_file_map* ifm, const struct load_command* lc, void* user) { - const macho_segment_command* sc = (const macho_segment_command*)lc; + char segname[16]; + uint32_t nsects; + + if (ifm->addr_size == 32) + { + const struct segment_command *sc = (const struct segment_command *)lc; + memcpy(segname, sc->segname, sizeof(segname)); + nsects = sc->nsects; + } + else + { + const struct segment_command_64 *sc = (const struct segment_command_64 *)lc; + memcpy(segname, sc->segname, sizeof(segname)); + nsects = sc->nsects; + }
TRACE("(%p/%d, %p, %p) segment %s\n", ifm, ifm->u.macho.fd, lc, user, - debugstr_an(sc->segname, sizeof(sc->segname))); + debugstr_an(segname, sizeof(segname)));
- ifm->u.macho.num_sections += sc->nsects; + ifm->u.macho.num_sections += nsects; return 0; }
@@ -525,44 +537,64 @@ static int macho_count_sections(struct image_file_map* ifm, const struct load_co static int macho_load_section_info(struct image_file_map* ifm, const struct load_command* lc, void* user) { struct macho_file_map* fmap = &ifm->u.macho; - const macho_segment_command* sc = (const macho_segment_command*)lc; struct section_info* info = user; BOOL ignore; const macho_section* section; int i; unsigned long tmp, page_mask = sysconf( _SC_PAGESIZE ) - 1; + uint64_t vmaddr, vmsize; + char segname[16]; + uint32_t nsects; + + if (ifm->addr_size == 32) + { + const struct segment_command *sc = (const struct segment_command *)lc; + vmaddr = sc->vmaddr; + vmsize = sc->vmsize; + memcpy(segname, sc->segname, sizeof(segname)); + nsects = sc->nsects; + section = (const macho_section*)(sc + 1); + } + else + { + const struct segment_command_64 *sc = (const struct segment_command_64 *)lc; + vmaddr = sc->vmaddr; + vmsize = sc->vmsize; + memcpy(segname, sc->segname, sizeof(segname)); + nsects = sc->nsects; + section = (const macho_section*)(sc + 1); + }
TRACE("(%p/%d, %p, %p) before: 0x%08lx - 0x%08lx\n", fmap, fmap->fd, lc, user, (unsigned long)fmap->segs_start, (unsigned long)fmap->segs_size); - TRACE("Segment command vm: 0x%08lx - 0x%08lx\n", (unsigned long)sc->vmaddr, - (unsigned long)(sc->vmaddr + sc->vmsize)); + TRACE("Segment command vm: 0x%08lx - 0x%08lx\n", (unsigned long)vmaddr, + (unsigned long)(vmaddr + vmsize));
/* Images in the dyld shared cache have their segments mapped non-contiguously. We don't know how to properly locate any of the segments other than __TEXT, so ignore them. */ - ignore = (info->split_segs && strcmp(sc->segname, SEG_TEXT)); + ignore = (info->split_segs && strcmp(segname, SEG_TEXT));
- if (!strncmp(sc->segname, "WINE_", 5)) - TRACE("Ignoring special Wine segment %s\n", debugstr_an(sc->segname, sizeof(sc->segname))); - else if (!strncmp(sc->segname, "__PAGEZERO", 10)) + if (!strncmp(segname, "WINE_", 5)) + TRACE("Ignoring special Wine segment %s\n", debugstr_an(segname, sizeof(segname))); + else if (!strncmp(segname, "__PAGEZERO", 10)) TRACE("Ignoring __PAGEZERO segment\n"); else if (ignore) - TRACE("Ignoring %s segment because image has split segments\n", sc->segname); + TRACE("Ignoring %s segment because image has split segments\n", segname); else { /* If this segment starts before previously-known earliest, record new earliest. */ - if (sc->vmaddr < fmap->segs_start) - fmap->segs_start = sc->vmaddr; + if (vmaddr < fmap->segs_start) + fmap->segs_start = vmaddr;
/* If this segment extends beyond previously-known furthest, record new furthest. */ - tmp = (sc->vmaddr + sc->vmsize + page_mask) & ~page_mask; + tmp = (vmaddr + vmsize + page_mask) & ~page_mask; if (fmap->segs_size < tmp) fmap->segs_size = tmp;
TRACE("after: 0x%08lx - 0x%08lx\n", (unsigned long)fmap->segs_start, (unsigned long)fmap->segs_size); }
- section = (const macho_section*)(sc + 1); - for (i = 0; i < sc->nsects; i++) + for (i = 0; i < nsects; i++) { fmap->sect[info->section_index].section = §ion[i]; fmap->sect[info->section_index].mapped = IMAGE_NO_MAP;
Signed-off-by: Zebediah Figura zfigura@codeweavers.com --- dlls/dbghelp/image_private.h | 8 +------- dlls/dbghelp/macho_module.c | 43 +++++++++++++++++++++++++++++-------------- 2 files changed, 30 insertions(+), 21 deletions(-)
diff --git a/dlls/dbghelp/image_private.h b/dlls/dbghelp/image_private.h index 60cdd35..9990850 100644 --- a/dlls/dbghelp/image_private.h +++ b/dlls/dbghelp/image_private.h @@ -44,12 +44,6 @@ #endif #ifdef HAVE_MACH_O_LOADER_H #include <mach-o/loader.h> - -#ifdef _WIN64 -typedef struct section_64 macho_section; -#else -typedef struct section macho_section; -#endif #endif
#define IMAGE_NO_MAP ((void*)-1) @@ -105,7 +99,7 @@ struct image_file_map int num_sections; struct { - const macho_section* section; + struct section_64 section; const char* mapped; unsigned int ignored : 1; }* sect; diff --git a/dlls/dbghelp/macho_module.c b/dlls/dbghelp/macho_module.c index 52ea739..b8f5967 100644 --- a/dlls/dbghelp/macho_module.c +++ b/dlls/dbghelp/macho_module.c @@ -328,7 +328,7 @@ BOOL macho_find_section(struct image_file_map* ifm, const char* segname, const c { struct macho_file_map* fmap; unsigned i; - char tmp[sizeof(fmap->sect[0].section->sectname)]; + char tmp[sizeof(fmap->sect[0].section.sectname)];
/* Other parts of dbghelp use section names like ".eh_frame". Mach-O uses names like "__eh_frame". Convert those. */ @@ -345,8 +345,8 @@ BOOL macho_find_section(struct image_file_map* ifm, const char* segname, const c for (i = 0; i < fmap->num_sections; i++) { if (!fmap->sect[i].ignored && - strcmp(fmap->sect[i].section->sectname, sectname) == 0 && - (!segname || strcmp(fmap->sect[i].section->segname, segname) == 0)) + strcmp(fmap->sect[i].section.sectname, sectname) == 0 && + (!segname || strcmp(fmap->sect[i].section.segname, segname) == 0)) { ism->fmap = ifm; ism->sidx = i; @@ -372,7 +372,7 @@ const char* macho_map_section(struct image_section_map* ism) if (ism->sidx < 0 || ism->sidx >= ism->fmap->u.macho.num_sections || fmap->sect[ism->sidx].ignored) return IMAGE_NO_MAP;
- return macho_map_range(fmap, fmap->sect[ism->sidx].section->offset, fmap->sect[ism->sidx].section->size, + return macho_map_range(fmap, fmap->sect[ism->sidx].section.offset, fmap->sect[ism->sidx].section.size, &fmap->sect[ism->sidx].mapped); }
@@ -385,8 +385,8 @@ void macho_unmap_section(struct image_section_map* ism)
if (ism->sidx >= 0 && ism->sidx < fmap->num_sections && fmap->sect[ism->sidx].mapped != IMAGE_NO_MAP) { - macho_unmap_range(&fmap->sect[ism->sidx].mapped, NULL, fmap, fmap->sect[ism->sidx].section->offset, - fmap->sect[ism->sidx].section->size); + macho_unmap_range(&fmap->sect[ism->sidx].mapped, NULL, fmap, fmap->sect[ism->sidx].section.offset, + fmap->sect[ism->sidx].section.size); } }
@@ -398,7 +398,7 @@ DWORD_PTR macho_get_map_rva(const struct image_section_map* ism) if (ism->sidx < 0 || ism->sidx >= ism->fmap->u.macho.num_sections || ism->fmap->u.macho.sect[ism->sidx].ignored) return 0; - return ism->fmap->u.macho.sect[ism->sidx].section->addr - ism->fmap->u.macho.segs_start; + return ism->fmap->u.macho.sect[ism->sidx].section.addr - ism->fmap->u.macho.segs_start; }
/****************************************************************** @@ -409,7 +409,7 @@ unsigned macho_get_map_size(const struct image_section_map* ism) if (ism->sidx < 0 || ism->sidx >= ism->fmap->u.macho.num_sections || ism->fmap->u.macho.sect[ism->sidx].ignored) return 0; - return ism->fmap->u.macho.sect[ism->sidx].section->size; + return ism->fmap->u.macho.sect[ism->sidx].section.size; }
/****************************************************************** @@ -539,12 +539,12 @@ static int macho_load_section_info(struct image_file_map* ifm, const struct load struct macho_file_map* fmap = &ifm->u.macho; struct section_info* info = user; BOOL ignore; - const macho_section* section; int i; unsigned long tmp, page_mask = sysconf( _SC_PAGESIZE ) - 1; uint64_t vmaddr, vmsize; char segname[16]; uint32_t nsects; + const void *sections;
if (ifm->addr_size == 32) { @@ -553,7 +553,7 @@ static int macho_load_section_info(struct image_file_map* ifm, const struct load vmsize = sc->vmsize; memcpy(segname, sc->segname, sizeof(segname)); nsects = sc->nsects; - section = (const macho_section*)(sc + 1); + sections = (const void *)(sc + 1); } else { @@ -562,7 +562,7 @@ static int macho_load_section_info(struct image_file_map* ifm, const struct load vmsize = sc->vmsize; memcpy(segname, sc->segname, sizeof(segname)); nsects = sc->nsects; - section = (const macho_section*)(sc + 1); + sections = (const void *)(sc + 1); }
TRACE("(%p/%d, %p, %p) before: 0x%08lx - 0x%08lx\n", fmap, fmap->fd, lc, user, @@ -596,7 +596,22 @@ static int macho_load_section_info(struct image_file_map* ifm, const struct load
for (i = 0; i < nsects; i++) { - fmap->sect[info->section_index].section = §ion[i]; + if (ifm->addr_size == 32) + { + const struct section *section = &((const struct section *)sections)[i]; + memcpy(fmap->sect[info->section_index].section.sectname, section->sectname, sizeof(section->sectname)); + memcpy(fmap->sect[info->section_index].section.segname, section->segname, sizeof(section->segname)); + fmap->sect[info->section_index].section.addr = section->addr; + fmap->sect[info->section_index].section.size = section->size; + fmap->sect[info->section_index].section.offset = section->offset; + fmap->sect[info->section_index].section.align = section->align; + fmap->sect[info->section_index].section.reloff = section->reloff; + fmap->sect[info->section_index].section.nreloc = section->nreloc; + fmap->sect[info->section_index].section.flags = section->flags; + } + else + fmap->sect[info->section_index].section = ((const struct section_64 *)sections)[i]; + fmap->sect[info->section_index].mapped = IMAGE_NO_MAP; fmap->sect[info->section_index].ignored = ignore; info->section_index++; @@ -831,8 +846,8 @@ static BOOL macho_sect_is_code(struct macho_file_map* fmap, unsigned char sectid sectidx--; /* convert from 1-based to 0-based */ if (sectidx >= fmap->num_sections || fmap->sect[sectidx].ignored) return FALSE;
- ret = (!(fmap->sect[sectidx].section->flags & SECTION_TYPE) && - (fmap->sect[sectidx].section->flags & (S_ATTR_PURE_INSTRUCTIONS|S_ATTR_SOME_INSTRUCTIONS))); + ret = (!(fmap->sect[sectidx].section.flags & SECTION_TYPE) && + (fmap->sect[sectidx].section.flags & (S_ATTR_PURE_INSTRUCTIONS|S_ATTR_SOME_INSTRUCTIONS))); TRACE("-> %d\n", ret); return ret; }
Signed-off-by: Zebediah Figura zfigura@codeweavers.com --- dlls/dbghelp/dbghelp_private.h | 2 +- dlls/dbghelp/macho_module.c | 16 +++------ dlls/dbghelp/stabs.c | 73 ++++++++++++++++++++++++------------------ 3 files changed, 47 insertions(+), 44 deletions(-)
diff --git a/dlls/dbghelp/dbghelp_private.h b/dlls/dbghelp/dbghelp_private.h index 0963f1e..76f5d00 100644 --- a/dlls/dbghelp/dbghelp_private.h +++ b/dlls/dbghelp/dbghelp_private.h @@ -676,7 +676,7 @@ typedef void (*stabs_def_cb)(struct module* module, unsigned long load_offset, BOOL is_public, BOOL is_global, unsigned char other, struct symt_compiland* compiland, void* user); extern BOOL stabs_parse(struct module* module, unsigned long load_offset, - const void* stabs, int stablen, + const char* stabs, int stablen, const char* strs, int strtablen, stabs_def_cb callback, void* user) DECLSPEC_HIDDEN;
diff --git a/dlls/dbghelp/macho_module.c b/dlls/dbghelp/macho_module.c index b8f5967..52c8e69 100644 --- a/dlls/dbghelp/macho_module.c +++ b/dlls/dbghelp/macho_module.c @@ -88,13 +88,6 @@ struct dyld_all_image_infos { WINE_DEFAULT_DEBUG_CHANNEL(dbghelp_macho);
-#ifdef _WIN64 -typedef struct nlist_64 macho_nlist; -#else -typedef struct nlist macho_nlist; -#endif - - /* Bitmask for Mach-O image header flags indicating that the image is in dyld's shared cached. That implies that its segments are mapped non-contiguously. This value isn't defined anywhere in headers. It's used in dyld and in @@ -913,24 +906,25 @@ static int macho_parse_symtab(struct image_file_map* ifm, struct macho_file_map* fmap = &ifm->u.macho; const struct symtab_command* sc = (const struct symtab_command*)lc; struct macho_debug_info* mdi = user; - const macho_nlist* stab; const char* stabstr; int ret = 0; + size_t stabsize = (ifm->addr_size == 32) ? sizeof(struct nlist) : sizeof(struct nlist_64); + const char *stab;
TRACE("(%p/%d, %p, %p) %u syms at 0x%08x, strings 0x%08x - 0x%08x\n", fmap, fmap->fd, lc, user, sc->nsyms, sc->symoff, sc->stroff, sc->stroff + sc->strsize);
- if (!macho_map_ranges(fmap, sc->symoff, sc->nsyms * sizeof(macho_nlist), + if (!macho_map_ranges(fmap, sc->symoff, sc->nsyms * stabsize, sc->stroff, sc->strsize, (const void**)&stab, (const void**)&stabstr)) return 0;
if (!stabs_parse(mdi->module, mdi->module->format_info[DFI_MACHO]->u.macho_info->load_addr - fmap->segs_start, - stab, sc->nsyms * sizeof(macho_nlist), + stab, sc->nsyms * stabsize, stabstr, sc->strsize, macho_stabs_def_cb, mdi)) ret = -1;
- macho_unmap_ranges(fmap, sc->symoff, sc->nsyms * sizeof(macho_nlist), + macho_unmap_ranges(fmap, sc->symoff, sc->nsyms * stabsize, sc->stroff, sc->strsize, (const void**)&stab, (const void**)&stabstr);
return ret; diff --git a/dlls/dbghelp/stabs.c b/dlls/dbghelp/stabs.c index 177c6bc..846a935 100644 --- a/dlls/dbghelp/stabs.c +++ b/dlls/dbghelp/stabs.c @@ -41,6 +41,7 @@ #include <sys/mman.h> #endif #include <limits.h> +#include <stdint.h> #include <stdlib.h> #include <string.h> #ifdef HAVE_UNISTD_H @@ -111,11 +112,7 @@ struct stab_nlist unsigned char n_type; char n_other; short n_desc; -#if defined(__APPLE__) && defined(_WIN64) - unsigned long n_value; -#else unsigned n_value; -#endif };
static void stab_strcpy(char* dest, int sz, const char* source) @@ -1265,7 +1262,7 @@ static inline void stabbuf_append(char **buf, unsigned *buf_size, const char *st }
BOOL stabs_parse(struct module* module, unsigned long load_offset, - const void* pv_stab_ptr, int stablen, + const char* pv_stab_ptr, int stablen, const char* strs, int strtablen, stabs_def_cb callback, void* user) { @@ -1278,7 +1275,7 @@ BOOL stabs_parse(struct module* module, unsigned long load_offset, const char* ptr; char* stabbuff; unsigned int stabbufflen; - const struct stab_nlist* stab_ptr = pv_stab_ptr; + const struct stab_nlist* stab_ptr; const char* strs_end; int strtabinc; char symname[4096]; @@ -1290,8 +1287,14 @@ BOOL stabs_parse(struct module* module, unsigned long load_offset, BOOL ret = TRUE; struct location loc; unsigned char type; + size_t stabsize = sizeof(struct stab_nlist); + uint64_t n_value;
- nstab = stablen / sizeof(struct stab_nlist); +#ifdef __APPLE__ + if (module->process->is_64bit) + stabsize = sizeof(struct nlist_64); +#endif + nstab = stablen / stabsize; strs_end = strs + strtablen;
memset(stabs_basic, 0, sizeof(stabs_basic)); @@ -1307,8 +1310,14 @@ BOOL stabs_parse(struct module* module, unsigned long load_offset,
strtabinc = 0; stabbuff[0] = '\0'; - for (i = 0; i < nstab; i++, stab_ptr++) + for (i = 0; i < nstab; i++) { + stab_ptr = (struct stab_nlist *)(pv_stab_ptr + i * stabsize); + n_value = stab_ptr->n_value; +#ifdef __APPLE__ + if (module->process->is_64bit) + n_value = ((struct nlist_64 *)stab_ptr)->n_value; +#endif ptr = strs + stab_ptr->n_strx; if ((ptr > strs_end) || (ptr + strlen(ptr) > strs_end)) { @@ -1382,7 +1391,7 @@ BOOL stabs_parse(struct module* module, unsigned long load_offset, stab_strcpy(symname, sizeof(symname), ptr); loc.kind = loc_absolute; loc.reg = 0; - loc.offset = load_offset + stab_ptr->n_value; + loc.offset = load_offset + n_value; symt_new_global_variable(module, compiland, symname, TRUE /* FIXME */, loc, 0, stabs_parse_type(ptr)); break; @@ -1392,7 +1401,7 @@ BOOL stabs_parse(struct module* module, unsigned long load_offset, stab_strcpy(symname, sizeof(symname), ptr); loc.kind = loc_absolute; loc.reg = 0; - loc.offset = load_offset + stab_ptr->n_value; + loc.offset = load_offset + n_value; symt_new_global_variable(module, compiland, symname, TRUE /* FIXME */, loc, 0, stabs_parse_type(ptr)); break; @@ -1400,14 +1409,14 @@ BOOL stabs_parse(struct module* module, unsigned long load_offset, if (curr_func) { block = symt_open_func_block(module, curr_func, block, - stab_ptr->n_value, 0); + n_value, 0); pending_flush(&pending_block, module, curr_func, block); } break; case N_RBRAC: if (curr_func) block = symt_close_func_block(module, curr_func, block, - stab_ptr->n_value); + n_value); break; case N_PSYM: /* These are function parameters. */ @@ -1417,9 +1426,9 @@ BOOL stabs_parse(struct module* module, unsigned long load_offset, stab_strcpy(symname, sizeof(symname), ptr); loc.kind = loc_regrel; loc.reg = dbghelp_current_cpu->frame_regno; - loc.offset = stab_ptr->n_value; + loc.offset = n_value; symt_add_func_local(module, curr_func, - (int)stab_ptr->n_value >= 0 ? DataIsParam : DataIsLocal, + (int)n_value >= 0 ? DataIsParam : DataIsLocal, &loc, NULL, param_type, symname); symt_add_function_signature_parameter(module, (struct symt_function_signature*)curr_func->type, @@ -1433,7 +1442,7 @@ BOOL stabs_parse(struct module* module, unsigned long load_offset, loc.kind = loc_register; loc.offset = 0;
- switch (stab_ptr->n_value) + switch (n_value) { case 0: loc.reg = CV_REG_EAX; break; case 1: loc.reg = CV_REG_ECX; break; @@ -1451,7 +1460,7 @@ BOOL stabs_parse(struct module* module, unsigned long load_offset, case 16: case 17: case 18: - case 19: loc.reg = CV_REG_ST0 + stab_ptr->n_value - 12; break; + case 19: loc.reg = CV_REG_ST0 + n_value - 12; break; case 21: case 22: case 23: @@ -1459,7 +1468,7 @@ BOOL stabs_parse(struct module* module, unsigned long load_offset, case 25: case 26: case 27: - case 28: loc.reg = CV_REG_XMM0 + stab_ptr->n_value - 21; break; + case 28: loc.reg = CV_REG_XMM0 + n_value - 21; break; case 29: case 30: case 31: @@ -1467,9 +1476,9 @@ BOOL stabs_parse(struct module* module, unsigned long load_offset, case 33: case 34: case 35: - case 36: loc.reg = CV_REG_MM0 + stab_ptr->n_value - 29; break; + case 36: loc.reg = CV_REG_MM0 + n_value - 29; break; default: - FIXME("Unknown register value (%lu)\n", (unsigned long)stab_ptr->n_value); + FIXME("Unknown register value (%lu)\n", (unsigned long)n_value); loc.reg = CV_REG_NONE; break; } @@ -1492,7 +1501,7 @@ BOOL stabs_parse(struct module* module, unsigned long load_offset, /* These are local variables */ loc.kind = loc_regrel; loc.reg = dbghelp_current_cpu->frame_regno; - loc.offset = stab_ptr->n_value; + loc.offset = n_value; if (curr_func != NULL) pending_add_var(&pending_block, ptr, DataIsLocal, &loc); break; case N_SLINE: @@ -1503,14 +1512,14 @@ BOOL stabs_parse(struct module* module, unsigned long load_offset, assert(source_idx >= 0); if (curr_func != NULL) { - unsigned long offset = stab_ptr->n_value; + unsigned long offset = n_value; if (module->type == DMT_MACHO) offset -= curr_func->address - load_offset; symt_add_func_line(module, curr_func, source_idx, stab_ptr->n_desc, offset); } else pending_add_line(&pending_func, source_idx, stab_ptr->n_desc, - stab_ptr->n_value, load_offset); + n_value, load_offset); break; case N_FUN: /* @@ -1537,13 +1546,13 @@ BOOL stabs_parse(struct module* module, unsigned long load_offset, * and offset of last function */ stabs_finalize_function(module, curr_func, - stab_ptr->n_value ? - (load_offset + stab_ptr->n_value - curr_func->address) : 0); + n_value ? + (load_offset + n_value - curr_func->address) : 0); } func_type = symt_new_function_signature(module, stabs_parse_type(ptr), -1); curr_func = symt_new_function(module, compiland, symname, - load_offset + stab_ptr->n_value, 0, + load_offset + n_value, 0, &func_type->symt); pending_flush(&pending_func, module, curr_func, NULL); } @@ -1552,7 +1561,7 @@ BOOL stabs_parse(struct module* module, unsigned long load_offset, /* some versions of GCC to use a N_FUN "" to mark the end of a function * and n_value contains the size of the func */ - stabs_finalize_function(module, curr_func, stab_ptr->n_value); + stabs_finalize_function(module, curr_func, n_value); curr_func = NULL; } break; @@ -1594,7 +1603,7 @@ BOOL stabs_parse(struct module* module, unsigned long load_offset, break; case N_UNDF: strs += strtabinc; - strtabinc = stab_ptr->n_value; + strtabinc = n_value; /* I'm not sure this is needed, so trace it before we obsolete it */ if (curr_func) { @@ -1607,7 +1616,7 @@ BOOL stabs_parse(struct module* module, unsigned long load_offset, /* Ignore this. We don't care what it points to. */ break; case N_BINCL: - stabs_add_include(stabs_new_include(ptr, stab_ptr->n_value)); + stabs_add_include(stabs_new_include(ptr, n_value)); assert(incl_stk < (int)(sizeof(incl) / sizeof(incl[0])) - 1); incl[++incl_stk] = source_idx; source_idx = source_new(module, NULL, ptr); @@ -1617,9 +1626,9 @@ BOOL stabs_parse(struct module* module, unsigned long load_offset, source_idx = incl[incl_stk--]; break; case N_EXCL: - if (stabs_add_include(stabs_find_include(ptr, stab_ptr->n_value)) < 0) + if (stabs_add_include(stabs_find_include(ptr, n_value)) < 0) { - ERR("Excluded header not found (%s,%ld)\n", ptr, (unsigned long)stab_ptr->n_value); + ERR("Excluded header not found (%s,%ld)\n", ptr, (unsigned long)n_value); module_reset_debug_info(module); ret = FALSE; goto done; @@ -1656,7 +1665,7 @@ BOOL stabs_parse(struct module* module, unsigned long load_offset, if (*ptr == '_') ptr++; stab_strcpy(symname, sizeof(symname), ptr);
- callback(module, load_offset, symname, stab_ptr->n_value, + callback(module, load_offset, symname, n_value, is_public, is_global, stab_ptr->n_other, compiland, user); } break; @@ -1666,7 +1675,7 @@ BOOL stabs_parse(struct module* module, unsigned long load_offset, } stabbuff[0] = '\0'; TRACE("0x%02x %lx %s\n", - stab_ptr->n_type, (unsigned long)stab_ptr->n_value, debugstr_a(strs + stab_ptr->n_strx)); + stab_ptr->n_type, (unsigned long)n_value, debugstr_a(strs + stab_ptr->n_strx)); } module->module.SymType = SymDia; module->module.CVSig = 'S' | ('T' << 8) | ('A' << 16) | ('B' << 24);