msc_dbg->module->module.BaseOfImage + base + coff_sym->Value,
0 /* FIXME */,
NULL /* FIXME */)->symt);
- i += naux;
continue;
}
* Ignore these. They don't have anything to do with
* reality.
*/
- i += naux;
continue;
}
#ifdef __arm__
case cpu_addr_pc: addr->Offset = ctx->Pc; return TRUE;
case cpu_addr_stack: addr->Offset = ctx->Sp; return TRUE;
- case cpu_addr_frame: addr->Offset = ctx->Fpscr; return TRUE;
+ case cpu_addr_frame: addr->Offset = ctx->Fp; return TRUE;
#endif
default: addr->Mode = -1;
return FALSE;
/* set frame information */
frame->AddrStack.Offset = context->Sp;
frame->AddrReturn.Offset = context->Lr;
- frame->AddrFrame.Offset = context->Fpscr;
+ frame->AddrFrame.Offset = context->Fp;
frame->AddrPC.Offset = context->Pc;
frame->Far = TRUE;
}
#endif
-static unsigned arm_map_dwarf_register(unsigned regno)
+static unsigned arm_map_dwarf_register(unsigned regno, BOOL eh_frame)
{
if (regno <= 15) return CV_ARM_R0 + regno;
if (regno == 128) return CV_ARM_CPSR;
case CV_ARM_R0 + 8: *size = sizeof(ctx->R8); return &ctx->R8;
case CV_ARM_R0 + 9: *size = sizeof(ctx->R9); return &ctx->R9;
case CV_ARM_R0 + 10: *size = sizeof(ctx->R10); return &ctx->R10;
- case CV_ARM_R0 + 11: *size = sizeof(ctx->Fpscr); return &ctx->Fpscr;
- //case CV_ARM_R0 + 12: *size = sizeof(ctx->Ip); return &ctx->Ip;
+ case CV_ARM_R0 + 11: *size = sizeof(ctx->Fp); return &ctx->Fp;
+ case CV_ARM_R0 + 12: *size = sizeof(ctx->Ip); return &ctx->Ip;
case CV_ARM_SP: *size = sizeof(ctx->Sp); return &ctx->Sp;
case CV_ARM_LR: *size = sizeof(ctx->Lr); return &ctx->Lr;
#ifdef __aarch64__
case cpu_addr_pc: addr->Offset = ctx->Pc; return TRUE;
case cpu_addr_stack: addr->Offset = ctx->Sp; return TRUE;
- case cpu_addr_frame: addr->Offset = ctx->X29; return TRUE;
+ case cpu_addr_frame: addr->Offset = ctx->Fp; return TRUE;
#endif
default: addr->Mode = -1;
return FALSE;
CONTEXT* context, DWORD_PTR curr_pc)
{
DWORD_PTR xframe;
- DWORD_PTR oldReturn = context->X30;
+ DWORD_PTR oldReturn = context->Lr;
if (dwarf2_virtual_unwind(csw, curr_pc, context, &xframe))
{
return TRUE;
}
- if (context->Pc == context->X30) return FALSE;
+ if (context->Pc == context->Lr) return FALSE;
context->Pc = oldReturn;
return TRUE;
/* set frame information */
frame->AddrStack.Offset = context->Sp;
- frame->AddrReturn.Offset = context->X30;
- frame->AddrFrame.Offset = context->X29;
+ frame->AddrReturn.Offset = context->Lr;
+ frame->AddrFrame.Offset = context->Fp;
frame->AddrPC.Offset = context->Pc;
frame->Far = TRUE;
wine_dbgstr_addr(&frame->AddrFrame),
wine_dbgstr_addr(&frame->AddrReturn),
wine_dbgstr_addr(&frame->AddrStack),
- curr_mode == stm_start ? "start" : "ARM",
+ curr_mode == stm_start ? "start" : "ARM64",
wine_dbgstr_longlong(curr_count),
frame->FuncTableEntry);
}
#endif
-static unsigned arm64_map_dwarf_register(unsigned regno)
+static unsigned arm64_map_dwarf_register(unsigned regno, BOOL eh_frame)
{
- if (regno <= 30) return CV_ARM64_X0 + regno;
+ if (regno <= 28) return CV_ARM64_X0 + regno;
+ if (regno == 29) return CV_ARM64_FP;
+ if (regno == 30) return CV_ARM64_LR;
if (regno == 31) return CV_ARM64_SP;
FIXME("Don't know how to map register %d\n", regno);
#ifdef __aarch64__
switch (regno)
{
-
+ case CV_ARM64_PSTATE: *size = sizeof(ctx->Cpsr); return &ctx->Cpsr;
case CV_ARM64_X0 + 0: *size = sizeof(ctx->X0); return &ctx->X0;
case CV_ARM64_X0 + 1: *size = sizeof(ctx->X1); return &ctx->X1;
case CV_ARM64_X0 + 2: *size = sizeof(ctx->X2); return &ctx->X2;
case CV_ARM64_X0 + 26: *size = sizeof(ctx->X26); return &ctx->X26;
case CV_ARM64_X0 + 27: *size = sizeof(ctx->X27); return &ctx->X27;
case CV_ARM64_X0 + 28: *size = sizeof(ctx->X28); return &ctx->X28;
- case CV_ARM64_X0 + 29: *size = sizeof(ctx->X29); return &ctx->X29;
- case CV_ARM64_X0 + 30: *size = sizeof(ctx->X30); return &ctx->X30;
+ case CV_ARM64_FP: *size = sizeof(ctx->Fp); return &ctx->Fp;
+ case CV_ARM64_LR: *size = sizeof(ctx->Lr); return &ctx->Lr;
case CV_ARM64_SP: *size = sizeof(ctx->Sp); return &ctx->Sp;
case CV_ARM64_PC: *size = sizeof(ctx->Pc); return &ctx->Pc;
- case CV_ARM64_PSTATE: *size = sizeof(ctx->PState); return &ctx->PState;
}
#endif
FIXME("Unknown register %x\n", regno);
{
switch (regno)
{
+ case CV_ARM64_PSTATE: return "cpsr";
case CV_ARM64_X0 + 0: return "x0";
case CV_ARM64_X0 + 1: return "x1";
case CV_ARM64_X0 + 2: return "x2";
case CV_ARM64_X0 + 26: return "x26";
case CV_ARM64_X0 + 27: return "x27";
case CV_ARM64_X0 + 28: return "x28";
- case CV_ARM64_X0 + 29: return "x29";
- case CV_ARM64_X0 + 30: return "x30";
+ case CV_ARM64_FP: return "fp";
+ case CV_ARM64_LR: return "lr";
case CV_ARM64_SP: return "sp";
case CV_ARM64_PC: return "pc";
- case CV_ARM64_PSTATE: return "cpsr";
}
FIXME("Unknown register %x\n", regno);
return NULL;
DECLSPEC_HIDDEN struct cpu cpu_arm64 = {
IMAGE_FILE_MACHINE_ARM64,
8,
- CV_ARM64_X0 + 29,
+ CV_ARM64_FP,
arm64_get_addr,
arm64_stack_walk,
NULL,
WINE_DEFAULT_DEBUG_CHANNEL(dbghelp);
-#define STEP_FLAG 0x00000100 /* single step flag */
#define V86_FLAG 0x00020000
#define IS_VM86_MODE(ctx) (ctx->EFlags & V86_FLAG)
}
#endif /* DBGHELP_STATIC_LIB */
-static unsigned i386_map_dwarf_register(unsigned regno)
+static unsigned i386_map_dwarf_register(unsigned regno, BOOL eh_frame)
{
unsigned reg;
case 1: reg = CV_REG_ECX; break;
case 2: reg = CV_REG_EDX; break;
case 3: reg = CV_REG_EBX; break;
- case 4: reg = CV_REG_ESP; break;
- case 5: reg = CV_REG_EBP; break;
+ case 4:
+ case 5:
+#ifdef __APPLE__
+ /* On OS X, DWARF eh_frame uses a different mapping for the registers. It's
+ apparently the mapping as emitted by GCC, at least at some point in its history. */
+ if (eh_frame)
+ reg = (regno == 4) ? CV_REG_EBP : CV_REG_ESP;
+ else
+#endif
+ reg = (regno == 4) ? CV_REG_ESP : CV_REG_EBP;
+ break;
case 6: reg = CV_REG_ESI; break;
case 7: reg = CV_REG_EDI; break;
case 8: reg = CV_REG_EIP; break;
return FALSE;
}
-static unsigned ppc_map_dwarf_register(unsigned regno)
+static unsigned ppc_map_dwarf_register(unsigned regno, BOOL eh_frame)
{
FIXME("not done\n");
return 0;
BYTE CodeOffset;
BYTE UnwindOp : 4;
BYTE OpInfo : 4;
- };
+ } u;
USHORT FrameOffset;
} UNWIND_CODE, *PUNWIND_CODE;
}
}
+#ifdef __x86_64__
+
enum st_mode {stm_start, stm_64bit, stm_done};
/* indexes in Reserved array */
#define curr_count (frame->Reserved[__CurrentCount])
/* #define ??? (frame->Reserved[__]) (unused) */
-#ifdef __x86_64__
union handler_data
{
RUNTIME_FUNCTION chain;
for (i = 0; i < info->CountOfCodes; i++)
{
- TRACE(" 0x%x: ", info->UnwindCode[i].CodeOffset);
- switch (info->UnwindCode[i].UnwindOp)
+ TRACE(" 0x%x: ", info->UnwindCode[i].u.CodeOffset);
+ switch (info->UnwindCode[i].u.UnwindOp)
{
case UWOP_PUSH_NONVOL:
- TRACE("pushq %%%s\n", reg_names[info->UnwindCode[i].OpInfo]);
+ TRACE("pushq %%%s\n", reg_names[info->UnwindCode[i].u.OpInfo]);
break;
case UWOP_ALLOC_LARGE:
- if (info->UnwindCode[i].OpInfo)
+ if (info->UnwindCode[i].u.OpInfo)
{
count = *(DWORD*)&info->UnwindCode[i+1];
i += 2;
TRACE("subq $0x%x,%%rsp\n", count);
break;
case UWOP_ALLOC_SMALL:
- count = (info->UnwindCode[i].OpInfo + 1) * 8;
+ count = (info->UnwindCode[i].u.OpInfo + 1) * 8;
TRACE("subq $0x%x,%%rsp\n", count);
break;
case UWOP_SET_FPREG:
break;
case UWOP_SAVE_NONVOL:
count = *(USHORT*)&info->UnwindCode[i+1] * 8;
- TRACE("movq %%%s,0x%x(%%rsp)\n", reg_names[info->UnwindCode[i].OpInfo], count);
+ TRACE("movq %%%s,0x%x(%%rsp)\n", reg_names[info->UnwindCode[i].u.OpInfo], count);
i++;
break;
case UWOP_SAVE_NONVOL_FAR:
count = *(DWORD*)&info->UnwindCode[i+1];
- TRACE("movq %%%s,0x%x(%%rsp)\n", reg_names[info->UnwindCode[i].OpInfo], count);
+ TRACE("movq %%%s,0x%x(%%rsp)\n", reg_names[info->UnwindCode[i].u.OpInfo], count);
i += 2;
break;
case UWOP_SAVE_XMM128:
count = *(USHORT*)&info->UnwindCode[i+1] * 16;
- TRACE("movaps %%xmm%u,0x%x(%%rsp)\n", info->UnwindCode[i].OpInfo, count);
+ TRACE("movaps %%xmm%u,0x%x(%%rsp)\n", info->UnwindCode[i].u.OpInfo, count);
i++;
break;
case UWOP_SAVE_XMM128_FAR:
count = *(DWORD*)&info->UnwindCode[i+1];
- TRACE("movaps %%xmm%u,0x%x(%%rsp)\n", info->UnwindCode[i].OpInfo, count);
+ TRACE("movaps %%xmm%u,0x%x(%%rsp)\n", info->UnwindCode[i].u.OpInfo, count);
i += 2;
break;
case UWOP_PUSH_MACHFRAME:
- TRACE("PUSH_MACHFRAME %u\n", info->UnwindCode[i].OpInfo);
+ TRACE("PUSH_MACHFRAME %u\n", info->UnwindCode[i].u.OpInfo);
break;
default:
- FIXME("unknown code %u\n", info->UnwindCode[i].UnwindOp);
+ FIXME("unknown code %u\n", info->UnwindCode[i].u.UnwindOp);
break;
}
}
static int get_opcode_size(UNWIND_CODE op)
{
- switch (op.UnwindOp)
+ switch (op.u.UnwindOp)
{
case UWOP_ALLOC_LARGE:
- return 2 + (op.OpInfo != 0);
+ return 2 + (op.u.OpInfo != 0);
case UWOP_SAVE_NONVOL:
case UWOP_SAVE_XMM128:
return 2;
for (i = 0; i < info->CountOfCodes; i += get_opcode_size(info->UnwindCode[i]))
{
- if (prolog_offset < info->UnwindCode[i].CodeOffset) continue; /* skip it */
+ if (prolog_offset < info->UnwindCode[i].u.CodeOffset) continue; /* skip it */
- switch (info->UnwindCode[i].UnwindOp)
+ switch (info->UnwindCode[i].u.UnwindOp)
{
case UWOP_PUSH_NONVOL: /* pushq %reg */
if (!sw_read_mem(csw, context->Rsp, &value, sizeof(DWORD64))) return FALSE;
- set_int_reg(context, info->UnwindCode[i].OpInfo, value);
+ set_int_reg(context, info->UnwindCode[i].u.OpInfo, value);
context->Rsp += sizeof(ULONG64);
break;
case UWOP_ALLOC_LARGE: /* subq $nn,%rsp */
- if (info->UnwindCode[i].OpInfo) context->Rsp += *(DWORD*)&info->UnwindCode[i+1];
+ if (info->UnwindCode[i].u.OpInfo) context->Rsp += *(DWORD*)&info->UnwindCode[i+1];
else context->Rsp += *(USHORT*)&info->UnwindCode[i+1] * 8;
break;
case UWOP_ALLOC_SMALL: /* subq $n,%rsp */
- context->Rsp += (info->UnwindCode[i].OpInfo + 1) * 8;
+ context->Rsp += (info->UnwindCode[i].u.OpInfo + 1) * 8;
break;
case UWOP_SET_FPREG: /* leaq nn(%rsp),%framereg */
context->Rsp = newframe;
case UWOP_SAVE_NONVOL: /* movq %reg,n(%rsp) */
off = newframe + *(USHORT*)&info->UnwindCode[i+1] * 8;
if (!sw_read_mem(csw, off, &value, sizeof(DWORD64))) return FALSE;
- set_int_reg(context, info->UnwindCode[i].OpInfo, value);
+ set_int_reg(context, info->UnwindCode[i].u.OpInfo, value);
break;
case UWOP_SAVE_NONVOL_FAR: /* movq %reg,nn(%rsp) */
off = newframe + *(DWORD*)&info->UnwindCode[i+1];
if (!sw_read_mem(csw, off, &value, sizeof(DWORD64))) return FALSE;
- set_int_reg(context, info->UnwindCode[i].OpInfo, value);
+ set_int_reg(context, info->UnwindCode[i].u.OpInfo, value);
break;
case UWOP_SAVE_XMM128: /* movaps %xmmreg,n(%rsp) */
off = newframe + *(USHORT*)&info->UnwindCode[i+1] * 16;
if (!sw_read_mem(csw, off, &floatvalue, sizeof(M128A))) return FALSE;
- set_float_reg(context, info->UnwindCode[i].OpInfo, floatvalue);
+ set_float_reg(context, info->UnwindCode[i].u.OpInfo, floatvalue);
break;
case UWOP_SAVE_XMM128_FAR: /* movaps %xmmreg,nn(%rsp) */
off = newframe + *(DWORD*)&info->UnwindCode[i+1];
if (!sw_read_mem(csw, off, &floatvalue, sizeof(M128A))) return FALSE;
- set_float_reg(context, info->UnwindCode[i].OpInfo, floatvalue);
+ set_float_reg(context, info->UnwindCode[i].u.OpInfo, floatvalue);
break;
case UWOP_PUSH_MACHFRAME:
- FIXME("PUSH_MACHFRAME %u\n", info->UnwindCode[i].OpInfo);
+ FIXME("PUSH_MACHFRAME %u\n", info->UnwindCode[i].u.OpInfo);
break;
default:
- FIXME("unknown code %u\n", info->UnwindCode[i].UnwindOp);
+ FIXME("unknown code %u\n", info->UnwindCode[i].u.UnwindOp);
break;
}
}
return NULL;
}
-static unsigned x86_64_map_dwarf_register(unsigned regno)
+static unsigned x86_64_map_dwarf_register(unsigned regno, BOOL eh_frame)
{
unsigned reg;
void* (*find_runtime_function)(struct module*, DWORD64 addr);
/* dwarf dedicated information */
- unsigned (*map_dwarf_register)(unsigned regno);
+ unsigned (*map_dwarf_register)(unsigned regno, BOOL eh_frame);
/* context related manipulation */
void* (*fetch_context_reg)(CONTEXT* context, unsigned regno, unsigned* size);
extern int elf_is_in_thunk_area(unsigned long addr, const struct elf_thunk_area* thunks) DECLSPEC_HIDDEN;
/* macho_module.c */
-#define MACHO_NO_MAP ((const void*)-1)
extern BOOL macho_enum_modules(HANDLE hProc, enum_modules_cb, void*) DECLSPEC_HIDDEN;
extern BOOL macho_fetch_file_info(const WCHAR* name, DWORD_PTR* base, DWORD* size, DWORD* checksum) DECLSPEC_HIDDEN;
-struct macho_file_map;
-extern BOOL macho_load_debug_info(struct module* module, struct macho_file_map* fmap) DECLSPEC_HIDDEN;
+extern BOOL macho_load_debug_info(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;
extern BOOL macho_synchronize_module_list(struct process* pcs) DECLSPEC_HIDDEN;
/* minidump.c */
-void minidump_add_memory_block(struct dump_context* dc, ULONG64 base, ULONG size, ULONG rva);
+void minidump_add_memory_block(struct dump_context* dc, ULONG64 base, ULONG size, ULONG rva) DECLSPEC_HIDDEN;
/* module.c */
extern const WCHAR S_ElfW[] DECLSPEC_HIDDEN;
extern BOOL pe_load_debug_info(const struct process* pcs,
struct module* module) DECLSPEC_HIDDEN;
extern const char* pe_map_directory(struct module* module, int dirno, DWORD* size) DECLSPEC_HIDDEN;
-extern void pe_unmap_directoy(struct module* module, int dirno) DECLSPEC_HIDDEN;
/* source.c */
extern unsigned source_new(struct module* module, const char* basedir, const char* source) DECLSPEC_HIDDEN;
-diff -prudN e:\Wine\dlls\dbghelp/cpu_i386.c e:\reactos\dll\win32\dbghelp/cpu_i386.c
---- e:\Wine\dlls\dbghelp/cpu_i386.c 2012-12-09 09:57:02.223180200 +0100
-+++ e:\reactos\dll\win32\dbghelp/cpu_i386.c 2013-07-31 14:07:19.201466300 +0100
-@@ -20,12 +20,17 @@
-
- #include <assert.h>
-
-+#ifndef DBGHELP_STATIC_LIB
- #include "ntstatus.h"
--#define WIN32_NO_STATUS
-+#endif
-+
- #include "dbghelp_private.h"
-+
-+#ifndef DBGHELP_STATIC_LIB
- #include "wine/winbase16.h"
- #include "winternl.h"
- #include "wine/debug.h"
-+#endif
-
- WINE_DEFAULT_DEBUG_CHANNEL(dbghelp);
-
-@@ -34,7 +39,8 @@ WINE_DEFAULT_DEBUG_CHANNEL(dbghelp);
+diff -pudN e:\wine\dlls\dbghelp/cpu_i386.c e:\reactos\dll\win32\dbghelp/cpu_i386.c
+--- e:\wine\dlls\dbghelp/cpu_i386.c 2015-07-14 15:44:34.399098500 +0100
++++ e:\reactos\dll\win32\dbghelp/cpu_i386.c 2015-07-19 09:09:09.912044200 +0100
+@@ -33,7 +30,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(dbghelp);
#define IS_VM86_MODE(ctx) (ctx->EFlags & V86_FLAG)
-#ifdef __i386__
-+
+#if defined(__i386__) && !defined(DBGHELP_STATIC_LIB)
static ADDRESS_MODE get_selector_type(HANDLE hThread, const CONTEXT* ctx, WORD sel)
{
LDT_ENTRY le;
-@@ -73,6 +79,7 @@ static unsigned i386_build_addr(HANDLE h
+@@ -72,6 +69,7 @@ static BOOL i386_build_addr(HANDLE hThre
}
#endif
+#ifndef DBGHELP_STATIC_LIB
- static unsigned i386_get_addr(HANDLE hThread, const CONTEXT* ctx,
- enum cpu_addr ca, ADDRESS64* addr)
+ static BOOL i386_get_addr(HANDLE hThread, const CONTEXT* ctx,
+ enum cpu_addr ca, ADDRESS64* addr)
{
-@@ -86,8 +93,9 @@ static unsigned i386_get_addr(HANDLE hTh
+@@ -85,8 +83,9 @@ static BOOL i386_get_addr(HANDLE hThread
#endif
return FALSE;
}
/* fetch_next_frame32()
*
* modify (at least) context.{eip, esp, ebp} using unwind information
-@@ -110,7 +118,9 @@ static BOOL fetch_next_frame32(struct cp
+@@ -109,7 +108,9 @@ static BOOL fetch_next_frame32(struct cp
cpair[2].name = "$eip"; cpair[2].pvalue = &context->Eip;
cpair[3].name = NULL; cpair[3].pvalue = NULL;
{
/* do a simple unwind using ebp
* we assume a "regular" prologue in the function has been used
-@@ -148,6 +158,7 @@ enum st_mode {stm_start, stm_32bit, stm_
+@@ -147,6 +148,7 @@ enum st_mode {stm_start, stm_32bit, stm_
#define set_curr_mode(m) {frame->Reserved[__CurrentModeCount] &= ~0x0F; frame->Reserved[__CurrentModeCount] |= (m & 0x0F);}
#define inc_curr_count() (frame->Reserved[__CurrentModeCount] += 0x10)
static BOOL i386_stack_walk(struct cpu_stack_walk* csw, LPSTACKFRAME64 frame, CONTEXT* context)
{
STACK32FRAME frame32;
-@@ -513,6 +524,7 @@ done_err:
+@@ -512,6 +514,7 @@ done_err:
set_curr_mode(stm_done);
return FALSE;
}
+#endif /* DBGHELP_STATIC_LIB */
- static unsigned i386_map_dwarf_register(unsigned regno)
+ static unsigned i386_map_dwarf_register(unsigned regno, BOOL eh_frame)
{
-@@ -662,6 +674,7 @@ static const char* i386_fetch_regname(un
+@@ -670,6 +673,7 @@ static const char* i386_fetch_regname(un
return NULL;
}
static BOOL i386_fetch_minidump_thread(struct dump_context* dc, unsigned index, unsigned flags, const CONTEXT* ctx)
{
if (ctx->ContextFlags && (flags & ThreadWriteInstructionWindow))
-@@ -675,6 +688,7 @@ static BOOL i386_fetch_minidump_thread(s
+@@ -683,6 +687,7 @@ static BOOL i386_fetch_minidump_thread(s
return TRUE;
}
static BOOL i386_fetch_minidump_module(struct dump_context* dc, unsigned index, unsigned flags)
{
-@@ -688,12 +702,22 @@ DECLSPEC_HIDDEN struct cpu cpu_i386 = {
+@@ -696,12 +701,22 @@ DECLSPEC_HIDDEN struct cpu cpu_i386 = {
IMAGE_FILE_MACHINE_I386,
4,
CV_REG_EBP,
+ NULL,
+#endif
};
-diff -prudN e:\Wine\dlls\dbghelp/cpu_x86_64.c e:\reactos\dll\win32\dbghelp/cpu_x86_64.c
---- e:\Wine\dlls\dbghelp/cpu_x86_64.c 2012-04-02 20:39:57.749333300 +0100
-+++ e:\reactos\dll\win32\dbghelp/cpu_x86_64.c 2013-06-16 10:06:39.482074000 +0100
-@@ -302,10 +302,10 @@ static BOOL is_inside_epilog(struct cpu_
+diff -pudN e:\wine\dlls\dbghelp/cpu_x86_64.c e:\reactos\dll\win32\dbghelp/cpu_x86_64.c
+--- e:\wine\dlls\dbghelp/cpu_x86_64.c 2015-07-14 15:44:34.403098700 +0100
++++ e:\reactos\dll\win32\dbghelp/cpu_x86_64.c 2015-07-19 08:56:08.508350500 +0100
+@@ -288,10 +280,10 @@ static BOOL is_inside_epilog(struct cpu_
if ((op0 & 0xf8) == 0x48)
{
if (!sw_read_mem(csw, pc + 1, &op1, 1)) return FALSE;
if (op0 == 0x48 && op2 == 0xc4)
{
pc += 7;
-@@ -313,7 +313,6 @@ static BOOL is_inside_epilog(struct cpu_
+@@ -299,7 +291,6 @@ static BOOL is_inside_epilog(struct cpu_
}
return FALSE;
case 0x83: /* add $n,%rsp */
if (op0 == 0x48 && op2 == 0xc4)
{
pc += 4;
-@@ -321,7 +320,6 @@ static BOOL is_inside_epilog(struct cpu_
+@@ -307,7 +298,6 @@ static BOOL is_inside_epilog(struct cpu_
}
return FALSE;
case 0x8d: /* lea n(reg),%rsp */
if (op0 & 0x06) return FALSE; /* rex.RX must be cleared */
if (((op2 >> 3) & 7) != 4) return FALSE; /* dest reg mus be %rsp */
if ((op2 & 7) == 4) return FALSE; /* no SIB byte allowed */
-diff -prudN e:\Wine\dlls\dbghelp/dbghelp.c e:\reactos\dll\win32\dbghelp/dbghelp.c
---- e:\Wine\dlls\dbghelp/dbghelp.c 2013-03-16 11:54:52.395468000 +0100
-+++ e:\reactos\dll\win32\dbghelp/dbghelp.c 2013-07-31 14:07:19.207470800 +0100
-@@ -21,11 +21,14 @@
- #include "config.h"
-
- #include "dbghelp_private.h"
-+#include "wdbgexts.h"
-+
-+#ifndef DBGHELP_STATIC_LIB
- #include "winerror.h"
- #include "psapi.h"
- #include "wine/debug.h"
--#include "wdbgexts.h"
- #include "winnls.h"
-+#endif
-
- WINE_DEFAULT_DEBUG_CHANNEL(dbghelp);
-
-@@ -133,6 +136,7 @@ void* fetch_buffer(struct process* pcs,
+diff -pudN e:\wine\dlls\dbghelp/dbghelp.c e:\reactos\dll\win32\dbghelp/dbghelp.c
+--- e:\wine\dlls\dbghelp/dbghelp.c 2015-02-21 17:13:08.781542200 +0100
++++ e:\reactos\dll\win32\dbghelp/dbghelp.c 2014-04-06 13:39:18.629374300 +0100
+@@ -114,6 +109,7 @@ void* fetch_buffer(struct process* pcs,
return pcs->buffer;
}
const char* wine_dbgstr_addr(const ADDRESS64* addr)
{
if (!addr) return "(null)";
-@@ -150,12 +154,18 @@ const char* wine_dbgstr_addr(const ADDRE
+@@ -131,12 +127,18 @@ const char* wine_dbgstr_addr(const ADDRE
return "unknown";
}
}
&cpu_i386
#elif defined(__x86_64__)
&cpu_x86_64
-@@ -280,8 +290,10 @@ static BOOL check_live_target(struct pro
+@@ -261,8 +263,10 @@ static BOOL check_live_target(struct pro
{
if (!GetProcessId(pcs->handle)) return FALSE;
if (GetEnvironmentVariableA("DBGHELP_NOLIVE", NULL, 0)) return FALSE;
return TRUE;
}
-@@ -370,7 +382,8 @@ BOOL WINAPI SymInitializeW(HANDLE hProce
+@@ -351,7 +355,8 @@ BOOL WINAPI SymInitializeW(HANDLE hProce
pcs->dbg_hdr_addr = 0;
pcs->next = process_first;
process_first = pcs;
if (check_live_target(pcs))
{
if (fInvadeProcess)
-@@ -384,6 +397,7 @@ BOOL WINAPI SymInitializeW(HANDLE hProce
+@@ -365,6 +370,7 @@ BOOL WINAPI SymInitializeW(HANDLE hProce
SetLastError(ERROR_INVALID_PARAMETER);
return FALSE;
}
return TRUE;
}
-
-diff -prudN e:\Wine\dlls\dbghelp/dbghelp_private.h e:\reactos\dll\win32\dbghelp/dbghelp_private.h
---- e:\Wine\dlls\dbghelp/dbghelp_private.h 2012-04-02 20:39:57.749333300 +0100
-+++ e:\reactos\dll\win32\dbghelp/dbghelp_private.h 2013-09-01 11:29:17.911557200 +0100
-@@ -21,19 +21,30 @@
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
- */
-
-+#define WIN32_NO_STATUS
-+#define _INC_WINDOWS
-+#define COM_NO_WINDOWS_H
-+
- #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/unicode.h"
--#include "wine/rbtree.h"
-
--#include "cvconst.h"
-+#ifndef DBGHELP_STATIC_LIB
-+#include <windef.h>
-+#include <winbase.h>
-+#include <winver.h>
-+#include <dbghelp.h>
-+#include <objbase.h>
-+#include <cvconst.h>
-+#include <wine/unicode.h>
-+#else
-+#include <string.h>
-+#include "compat.h"
-+#endif
-+
-+//#include "oaidl.h"
-+//#include "winnls.h"
-+#include <wine/list.h>
-+#include <wine/rbtree.h>
-+
-
- /* #define USE_STATS */
-
-@@ -352,6 +363,13 @@ struct module_format
+diff -pudN e:\wine\dlls\dbghelp/dbghelp_private.h e:\reactos\dll\win32\dbghelp/dbghelp_private.h
+--- e:\wine\dlls\dbghelp/dbghelp_private.h 2015-07-14 15:44:34.411099200 +0100
++++ e:\reactos\dll\win32\dbghelp/dbghelp_private.h 2015-07-19 08:57:09.675849100 +0100
+@@ -352,6 +391,15 @@ struct module_format
} u;
};
++#ifdef __REACTOS__
+struct symt_idx_to_ptr
+{
+ struct hash_table_elt hash_elt;
+ DWORD idx;
+ const struct symt *sym;
+};
++#endif
+
extern const struct wine_rb_functions source_rb_functions DECLSPEC_HIDDEN;
struct module
{
-@@ -376,6 +394,9 @@ struct module
+@@ -376,6 +424,9 @@ struct module
unsigned sorttab_size;
struct symt_ht** addr_sorttab;
struct hash_table ht_symbols;
/* types */
struct hash_table ht_types;
-@@ -671,7 +692,9 @@ extern BOOL dwarf2_virtual_unwin
+@@ -667,7 +718,9 @@ extern BOOL dwarf2_virtual_unwin
CONTEXT* context, ULONG_PTR* cfa) DECLSPEC_HIDDEN;
/* stack.c */
extern DWORD64 sw_xlat_addr(struct cpu_stack_walk* csw, ADDRESS64* addr) DECLSPEC_HIDDEN;
extern void* sw_table_access(struct cpu_stack_walk* csw, DWORD64 addr) DECLSPEC_HIDDEN;
extern DWORD64 sw_module_base(struct cpu_stack_walk* csw, DWORD64 addr) DECLSPEC_HIDDEN;
-
-diff -prudN e:\Wine\dlls\dbghelp/dwarf.c e:\reactos-dwarf\dll\win32\dbghelp/dwarf.c
---- e:\Wine\dlls\dbghelp/dwarf.c 2013-03-02 14:17:59.439371000 +0100
-+++ e:\reactos\dll\win32\dbghelp/dwarf.c 2013-07-31 14:07:19.222482300 +0100
-@@ -22,23 +22,23 @@
-
- #define NONAMELESSUNION
-
--#include "config.h"
-+#include <config.h>
-
--#include <sys/types.h>
--#include <fcntl.h>
-+//#include <sys/types.h>
-+//#include <fcntl.h>
- #ifdef HAVE_SYS_STAT_H
- # include <sys/stat.h>
- #endif
- #ifdef HAVE_SYS_MMAN_H
- #include <sys/mman.h>
- #endif
--#include <limits.h>
--#include <stdlib.h>
--#include <string.h>
-+//#include <limits.h>
-+//#include <stdlib.h>
-+//#include <string.h>
- #ifdef HAVE_UNISTD_H
- # include <unistd.h>
- #endif
--#include <stdio.h>
-+//#include <stdio.h>
- #include <assert.h>
- #include <stdarg.h>
-
-@@ -46,18 +46,20 @@
- #include <zlib.h>
- #endif
-
--#include "windef.h"
--#include "winternl.h"
--#include "winbase.h"
--#include "winuser.h"
--#include "ole2.h"
--#include "oleauto.h"
-+//#include "windef.h"
-+//#include "winbase.h"
-+//#include "winuser.h"
-+//#include "ole2.h"
-+//#include "oleauto.h"
+@@ -788,3 +841,7 @@ extern struct symt_pointer*
+ extern struct symt_typedef*
+ symt_new_typedef(struct module* module, struct symt* ref,
+ const char* name) DECLSPEC_HIDDEN;
+
-+#ifndef DBGHELP_STATIC_LIB
-+#include <winternl.h>
-+#include <wine/debug.h>
-+#endif
-
- #include "dbghelp_private.h"
- #include "image_private.h"
-
--#include "wine/debug.h"
--
- WINE_DEFAULT_DEBUG_CHANNEL(dbghelp_dwarf);
-
- /* FIXME:
-@@ -1888,8 +1890,10 @@ static struct symt* dwarf2_parse_subprog
++#include "image_private.h"
++
++#endif /* _DBGHELP_PRIVATE_H_ */
+diff -pudN e:\wine\dlls\dbghelp/dwarf.c e:\reactos\dll\win32\dbghelp/dwarf.c
+--- e:\wine\dlls\dbghelp/dwarf.c 2015-07-14 15:44:34.417099500 +0100
++++ e:\reactos\dll\win32\dbghelp/dwarf.c 2015-07-19 08:58:24.024101500 +0100
+@@ -1930,8 +1898,10 @@ static struct symt* dwarf2_parse_subprog
* (not the case for stabs), we just drop Wine's thunks here...
* Actual thunks will be created in elf_module from the symbol table
*/
if (!(ret_type = dwarf2_lookup_type(ctx, di)))
{
ret_type = ctx->symt_cache[sc_void];
-diff -prudN e:\Wine\dlls\dbghelp/dwarf.h e:\reactos\dll\win32\dbghelp/dwarf.h
---- e:\Wine\dlls\dbghelp/dwarf.h 2011-09-16 23:22:36.194780200 +0100
-+++ e:\reactos\dll\win32\dbghelp/dwarf.h 2013-07-31 14:07:19.227485700 +0100
-@@ -554,3 +554,15 @@ enum dwarf_call_frame_info
+@@ -2446,7 +2416,17 @@ static BOOL dwarf2_parse_compilation_uni
+ }
+ if (dwarf2_find_attribute(&ctx, di, DW_AT_stmt_list, &stmt_list))
+ {
++#if defined(__REACTOS__) && defined(__clang__)
++ unsigned long stmt_list_val = stmt_list.u.uvalue;
++ if (stmt_list_val > module->module.BaseOfImage)
++ {
++ /* FIXME: Clang is recording this as an address, not an offset */
++ stmt_list_val -= module->module.BaseOfImage + sections[section_line].rva;
++ }
++ if (dwarf2_parse_line_numbers(sections, &ctx, comp_dir.u.string, stmt_list_val))
++#else
+ if (dwarf2_parse_line_numbers(sections, &ctx, comp_dir.u.string, stmt_list.u.uvalue))
++#endif
+ module->module.LineNumbers = TRUE;
+ }
+ ret = TRUE;
+diff -pudN e:\wine\dlls\dbghelp/dwarf.h e:\reactos\dll\win32\dbghelp/dwarf.h
+--- e:\wine\dlls\dbghelp/dwarf.h 2015-02-21 17:13:08.785542200 +0100
++++ e:\reactos\dll\win32\dbghelp/dwarf.h 2014-03-05 11:46:23.713943000 +0100
+@@ -554,3 +556,15 @@ enum dwarf_call_frame_info
#define DW_INL_inlined 0x01
#define DW_INL_declared_not_inlined 0x02
#define DW_INL_declared_inlined 0x03
+ return csw->u.s64.f_read_mem(csw->hProcess, addr, ptr, sz, &bytes_read);
+}
+#endif
-
-diff -prudN e:\Wine\dlls\dbghelp/image_private.h e:\reactos\dll\win32\dbghelp/image_private.h
---- e:\Wine\dlls\dbghelp/image_private.h 2012-04-02 20:39:57.752333500 +0100
-+++ e:\reactos\dll\win32\dbghelp/image_private.h 2013-07-31 14:07:19.195462800 +0100
-@@ -45,7 +45,7 @@
+diff -pudN e:\wine\dlls\dbghelp/image_private.h e:\reactos\dll\win32\dbghelp/image_private.h
+--- e:\wine\dlls\dbghelp/image_private.h 2015-07-14 15:44:34.418099600 +0100
++++ e:\reactos\dll\win32\dbghelp/image_private.h 2015-07-19 09:00:19.387700000 +0100
+@@ -56,7 +58,7 @@ typedef struct section mach
#define IMAGE_NO_MAP ((void*)-1)
#ifdef _WIN64
#define Elf_Ehdr Elf64_Ehdr
-@@ -85,7 +85,7 @@ struct image_file_map
+@@ -96,7 +98,7 @@ struct image_file_map
const char* shstrtab;
struct image_file_map* alternate; /* another ELF file (linked to this one) */
char* target_copy;
Elf_Ehdr elfhdr;
struct
{
-@@ -135,7 +135,9 @@ static inline BOOL image_find_section(st
+@@ -177,8 +179,10 @@ static inline BOOL image_find_section(st
{
switch (fmap->modtype)
{
+#ifndef DBGHELP_STATIC_LIB
- case DMT_ELF: return elf_find_section(fmap, name, SHT_NULL, ism);
+ case DMT_ELF: return elf_find_section(fmap, name, SHT_NULL, ism);
+ case DMT_MACHO: return macho_find_section(fmap, NULL, name, ism);
+#endif
- case DMT_PE: return pe_find_section(fmap, name, ism);
+ case DMT_PE: return pe_find_section(fmap, name, ism);
default: assert(0); return FALSE;
}
-@@ -146,7 +148,9 @@ static inline const char* image_map_sect
+@@ -189,8 +193,10 @@ static inline const char* image_map_sect
if (!ism->fmap) return NULL;
switch (ism->fmap->modtype)
{
+#ifndef DBGHELP_STATIC_LIB
- case DMT_ELF: return elf_map_section(ism);
+ case DMT_ELF: return elf_map_section(ism);
+ case DMT_MACHO: return macho_map_section(ism);
+#endif
- case DMT_PE: return pe_map_section(ism);
+ case DMT_PE: return pe_map_section(ism);
default: assert(0); return NULL;
}
-@@ -157,7 +161,9 @@ static inline void image_unmap_section(s
+@@ -201,8 +207,10 @@ static inline void image_unmap_section(s
if (!ism->fmap) return;
switch (ism->fmap->modtype)
{
+#ifndef DBGHELP_STATIC_LIB
- case DMT_ELF: elf_unmap_section(ism); break;
+ case DMT_ELF: elf_unmap_section(ism); break;
+ case DMT_MACHO: macho_unmap_section(ism); break;
+#endif
- case DMT_PE: pe_unmap_section(ism); break;
+ case DMT_PE: pe_unmap_section(ism); break;
default: assert(0); return;
}
-@@ -168,7 +174,9 @@ static inline DWORD_PTR image_get_map_rv
+@@ -213,8 +221,10 @@ static inline DWORD_PTR image_get_map_rv
if (!ism->fmap) return 0;
switch (ism->fmap->modtype)
{
+#ifndef DBGHELP_STATIC_LIB
- case DMT_ELF: return elf_get_map_rva(ism);
+ case DMT_ELF: return elf_get_map_rva(ism);
+ case DMT_MACHO: return macho_get_map_rva(ism);
+#endif
- case DMT_PE: return pe_get_map_rva(ism);
+ case DMT_PE: return pe_get_map_rva(ism);
default: assert(0); return 0;
}
-@@ -179,7 +187,9 @@ static inline unsigned image_get_map_siz
+@@ -225,8 +235,10 @@ static inline unsigned image_get_map_siz
if (!ism->fmap) return 0;
switch (ism->fmap->modtype)
{
+#ifndef DBGHELP_STATIC_LIB
- case DMT_ELF: return elf_get_map_size(ism);
+ case DMT_ELF: return elf_get_map_size(ism);
+ case DMT_MACHO: return macho_get_map_size(ism);
+#endif
- case DMT_PE: return pe_get_map_size(ism);
+ case DMT_PE: return pe_get_map_size(ism);
default: assert(0); return 0;
}
-
-diff -prudN e:\Wine\dlls\dbghelp/module.c e:\reactos\dll\win32\dbghelp/module.c
---- e:\Wine\dlls\dbghelp/module.c 2012-09-09 19:47:53.367024200 +0100
-+++ e:\reactos\dll\win32\dbghelp/module.c 2013-09-01 11:29:17.840509700 +0100
-@@ -19,16 +19,19 @@
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
- */
-
--#include "config.h"
--#include <stdlib.h>
--#include <stdio.h>
--#include <string.h>
-+#include <config.h>
-+//#include <stdlib.h>
-+//#include <stdio.h>
-+//#include <string.h>
- #include <assert.h>
-
- #include "dbghelp_private.h"
--#include "psapi.h"
--#include "winternl.h"
--#include "wine/debug.h"
-+
-+#ifndef DBGHELP_STATIC_LIB
-+#include <psapi.h>
-+#include <wine/debug.h>
-+#endif
-+//#include "winternl.h"
-
- WINE_DEFAULT_DEBUG_CHANNEL(dbghelp);
-
-@@ -220,6 +223,9 @@ struct module* module_new(struct process
+diff -pudN e:\wine\dlls\dbghelp/module.c e:\reactos\dll\win32\dbghelp/module.c
+--- e:\wine\dlls\dbghelp/module.c 2015-07-14 15:44:34.423099800 +0100
++++ e:\reactos\dll\win32\dbghelp/module.c 2015-07-19 09:04:12.643041400 +0100
+@@ -220,6 +213,9 @@ struct module* module_new(struct process
*/
hash_table_init(&module->pool, &module->ht_symbols, 4096);
hash_table_init(&module->pool, &module->ht_types, 4096);
vector_init(&module->vtypes, sizeof(struct symt*), 32);
module->sources_used = 0;
-@@ -346,9 +352,11 @@ BOOL module_get_debug(struct module_pair
+@@ -346,9 +342,11 @@ BOOL module_get_debug(struct module_pair
if (pair->effective->is_virtual) ret = FALSE;
else switch (pair->effective->type)
{
case DMT_PE:
idslW64.SizeOfStruct = sizeof(idslW64);
idslW64.BaseOfImage = pair->effective->module.BaseOfImage;
-@@ -365,9 +373,11 @@ BOOL module_get_debug(struct module_pair
+@@ -365,9 +363,11 @@ BOOL module_get_debug(struct module_pair
ret ? CBA_DEFERRED_SYMBOL_LOAD_COMPLETE : CBA_DEFERRED_SYMBOL_LOAD_FAILURE,
&idslW64);
break;
+#ifndef DBGHELP_STATIC_LIB
case DMT_MACHO:
- ret = macho_load_debug_info(pair->effective, NULL);
+ ret = macho_load_debug_info(pair->effective);
break;
+#endif
default:
ret = FALSE;
break;
-@@ -506,11 +516,13 @@ enum module_type module_get_type_by_name
+@@ -517,11 +517,13 @@ enum module_type module_get_type_by_name
/******************************************************************
* refresh_module_list
*/
/***********************************************************************
* SymLoadModule (DBGHELP.@)
-@@ -594,7 +606,9 @@ DWORD64 WINAPI SymLoadModuleExW(HANDLE
+@@ -605,7 +607,9 @@ DWORD64 WINAPI SymLoadModuleExW(HANDLE
if (Flags & ~(SLMFLAG_VIRTUAL))
FIXME("Unsupported Flags %08x for %s\n", Flags, debugstr_w(wImageName));
/* this is a Wine extension to the API just to redo the synchronisation */
if (!wImageName && !hFile) return 0;
-@@ -618,6 +632,7 @@ DWORD64 WINAPI SymLoadModuleExW(HANDLE
+@@ -629,6 +633,7 @@ DWORD64 WINAPI SymLoadModuleExW(HANDLE
wImageName)
{
/* and finally an ELF or Mach-O module */
switch (module_get_type_by_name(wImageName))
{
case DMT_ELF:
-@@ -630,6 +645,7 @@ DWORD64 WINAPI SymLoadModuleExW(HANDLE
+@@ -641,6 +646,7 @@ DWORD64 WINAPI SymLoadModuleExW(HANDLE
/* Ignored */
break;
}
}
}
if (!module)
-@@ -819,6 +835,7 @@ BOOL WINAPI SymEnumerateModulesW64(HAND
+@@ -830,6 +836,7 @@ BOOL WINAPI SymEnumerateModulesW64(HAND
return TRUE;
}
/******************************************************************
* EnumerateLoadedModules64 (DBGHELP.@)
*
-@@ -919,6 +936,7 @@ BOOL WINAPI EnumerateLoadedModulesW64(H
+@@ -930,6 +937,7 @@ BOOL WINAPI EnumerateLoadedModulesW64(H
return sz != 0 && i == sz;
}
/******************************************************************
* SymGetModuleInfo (DBGHELP.@)
-@@ -1131,7 +1149,11 @@ BOOL WINAPI SymRefreshModuleList(HANDLE
+@@ -1142,7 +1150,11 @@ BOOL WINAPI SymRefreshModuleList(HANDLE
if (!(pcs = process_find_by_handle(hProcess))) return FALSE;
}
/***********************************************************************
-
-diff -prudN e:\Wine\dlls\dbghelp/pe_module.c e:\reactos\dll\win32\dbghelp/pe_module.c
---- e:\Wine\dlls\dbghelp/pe_module.c 2012-04-02 20:39:57.755333700 +0100
-+++ e:\reactos\dll\win32\dbghelp/pe_module.c 2013-07-31 14:07:19.229487000 +0100
-@@ -31,8 +31,10 @@
-
- #include "dbghelp_private.h"
- #include "image_private.h"
-+#ifndef DBGHELP_STATIC_LIB
- #include "winternl.h"
- #include "wine/debug.h"
-+#endif
-
- WINE_DEFAULT_DEBUG_CHANNEL(dbghelp);
-
-@@ -526,6 +528,7 @@ static BOOL pe_load_dwarf(struct module*
+diff -pudN e:\wine\dlls\dbghelp/pe_module.c e:\reactos\dll\win32\dbghelp/pe_module.c
+--- e:\wine\dlls\dbghelp/pe_module.c 2015-03-21 14:04:47.631809000 +0100
++++ e:\reactos\dll\win32\dbghelp/pe_module.c 2015-07-19 09:04:59.065696600 +0100
+@@ -516,6 +505,7 @@ static BOOL pe_load_dwarf(struct module*
return ret;
}
/******************************************************************
* pe_load_dbg_file
*
-@@ -625,6 +628,7 @@ done:
+@@ -615,6 +605,7 @@ done:
pe_unmap_full(fmap);
return ret;
}
/***********************************************************************
* pe_load_export_debug_info
-@@ -721,7 +725,9 @@ BOOL pe_load_debug_info(const struct pro
+@@ -711,7 +702,9 @@ BOOL pe_load_debug_info(const struct pro
{
ret = pe_load_stabs(pcs, module);
ret = pe_load_dwarf(module) || ret;
ret = ret || pe_load_coff_symbol_table(module); /* FIXME */
/* if we still have no debug info (we could only get SymExport at this
* point), then do the SymExport except if we have an ELF container,
-
-diff -prudN e:\Wine\dlls\dbghelp/source.c e:\reactos\dll\win32\dbghelp/source.c
---- e:\Wine\dlls\dbghelp/source.c 2011-09-16 23:22:36.198780400 +0100
-+++ e:\reactos\dll\win32\dbghelp/source.c 2013-07-31 14:07:19.220481000 +0100
-@@ -18,14 +18,17 @@
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
- *
- */
--#include "config.h"
--#include <stdlib.h>
--#include <stdio.h>
--#include <string.h>
-+#include <config.h>
-+//#include <stdlib.h>
-+//#include <stdio.h>
-+//#include <string.h>
- #include <assert.h>
-
- #include "dbghelp_private.h"
--#include "wine/debug.h"
-+
-+#ifndef DBGHELP_STATIC_LIB
-+#include <wine/debug.h>
-+#endif
-
- WINE_DEFAULT_DEBUG_CHANNEL(dbghelp);
-
-diff -prudN e:\Wine\dlls\dbghelp/stabs.c e:\reactos\dll\win32\dbghelp/stabs.c
---- e:\Wine\dlls\dbghelp/stabs.c 2012-08-13 02:55:03.317206300 +0100
-+++ e:\reactos\dll\win32\dbghelp/stabs.c 2013-07-31 14:07:19.210472800 +0100
-@@ -29,41 +29,47 @@
- * available (hopefully) from http://sources.redhat.com/gdb/onlinedocs
- */
-
--#include "config.h"
--#include "wine/port.h"
-+#include <config.h>
-+//#include "wine/port.h"
-
--#include <sys/types.h>
--#include <fcntl.h>
-+//#include <sys/types.h>
-+//#include <fcntl.h>
- #ifdef HAVE_SYS_STAT_H
- # include <sys/stat.h>
- #endif
- #ifdef HAVE_SYS_MMAN_H
- #include <sys/mman.h>
- #endif
--#include <limits.h>
--#include <stdlib.h>
--#include <string.h>
-+//#include <limits.h>
-+//#include <stdlib.h>
-+//#include <string.h>
- #ifdef HAVE_UNISTD_H
- # include <unistd.h>
- #endif
--#include <stdio.h>
-+//#include <stdio.h>
- #include <assert.h>
--#include <stdarg.h>
-+//#include <stdarg.h>
-
- #ifdef HAVE_MACH_O_NLIST_H
- # include <mach-o/nlist.h>
- #endif
-
--#include "windef.h"
--#include "winbase.h"
--#include "winnls.h"
-+//#include "windef.h"
-+//#include "winbase.h"
-+//#include "winnls.h"
-
- #include "dbghelp_private.h"
-
--#include "wine/debug.h"
-+#ifndef DBGHELP_STATIC_LIB
-+#include <wine/debug.h>
-+#endif
-
- WINE_DEFAULT_DEBUG_CHANNEL(dbghelp_stabs);
-
-+#ifndef DBGHELP_STATIC_LIB
-+#define strtoull _strtoui64
-+#endif
-+
- /* Masks for n_type field */
- #ifndef N_STAB
- #define N_STAB 0xe0
-
-diff -prudN e:\Wine\dlls\dbghelp/storage.c e:\reactos\dll\win32\dbghelp/storage.c
---- e:\Wine\dlls\dbghelp/storage.c 2011-09-16 23:22:36.199780500 +0100
-+++ e:\reactos\dll\win32\dbghelp/storage.c 2013-07-31 14:07:19.203469700 +0100
-@@ -23,7 +23,10 @@
- #include "config.h"
- #include <assert.h>
- #include <stdlib.h>
-+
-+#ifndef DBGHELP_STATIC_LIB
- #include "wine/debug.h"
-+#endif
-
- #include "dbghelp_private.h"
- #ifdef USE_STATS
-
-diff -prudN e:\Wine\dlls\dbghelp/symbol.c e:\reactos-dwarf\dll\win32\dbghelp/symbol.c
---- e:\Wine\dlls\dbghelp/symbol.c 2012-04-02 20:39:57.756333700 +0100
-+++ e:\reactos\dll\win32\dbghelp/symbol.c 2013-09-01 11:31:20.334679400 +0100
-@@ -31,9 +31,12 @@
- #include <sys/types.h>
- #include <assert.h>
-
--#include "wine/debug.h"
- #include "dbghelp_private.h"
-+
-+#ifndef DBGHELP_STATIC_LIB
-+#include "wine/debug.h"
- #include "winnls.h"
-+#endif
-
- WINE_DEFAULT_DEBUG_CHANNEL(dbghelp);
- WINE_DECLARE_DEBUG_CHANNEL(dbghelp_symt);
-@@ -67,18 +70,39 @@ int symt_cmp_addr(const void* p1, const
+diff -pudN e:\wine\dlls\dbghelp/symbol.c e:\reactos\dll\win32\dbghelp/symbol.c
+--- e:\wine\dlls\dbghelp/symbol.c 2015-03-21 14:04:47.632809700 +0100
++++ e:\reactos\dll\win32\dbghelp/symbol.c 2014-09-14 18:44:28.955907600 +0100
+@@ -66,18 +53,39 @@ int symt_cmp_addr(const void* p1, const
DWORD symt_ptr2index(struct module* module, const struct symt* sym)
{
if (c) *c = sym;
return len + 1;
#else
-@@ -88,7 +112,7 @@ DWORD symt_ptr2index(struct
+@@ -87,7 +95,7 @@ DWORD symt_ptr2index(struct
struct symt* symt_index2ptr(struct module* module, DWORD id)
{
if (!id-- || id >= vector_length(&module->vsymt)) return NULL;
return *(struct symt**)vector_at(&module->vsymt, id);
#else
-diff -prudN e:\Wine\dlls\dbghelp/type.c e:\reactos\dll\win32\dbghelp/type.c
---- e:\Wine\dlls\dbghelp/type.c 2012-04-02 20:39:57.756333700 +0100
-+++ e:\reactos\dll\win32\dbghelp/type.c 2013-07-31 14:07:19.197464100 +0100
-@@ -29,10 +29,13 @@
- #include <stdarg.h>
- #include <assert.h>
-
-+#ifndef DBGHELP_STATIC_LIB
- #include "windef.h"
- #include "winbase.h"
- #include "winnls.h"
- #include "wine/debug.h"
-+#endif
-+
- #include "dbghelp_private.h"
-
- WINE_DEFAULT_DEBUG_CHANNEL(dbghelp);
FIXME("What the heck map reg 0x%x\n",regno);
return 0;
}
- return dbghelp_current_cpu->map_dwarf_register(regno);
+ return dbghelp_current_cpu->map_dwarf_register(regno, FALSE);
}
static enum location_error
/* parse the CIE first */
version = dwarf2_parse_byte(ctx);
- if (version != 1)
+ if (version != 1 && version != 3)
{
FIXME("unknown CIE version %u at %p\n", version, ctx->data - 1);
return FALSE;
info->code_align = dwarf2_leb128_as_unsigned(ctx);
info->data_align = dwarf2_leb128_as_signed(ctx);
- info->retaddr_reg = dwarf2_parse_byte(ctx);
+ if (version == 1)
+ info->retaddr_reg = dwarf2_parse_byte(ctx);
+ else
+ info->retaddr_reg = dwarf2_leb128_as_unsigned(ctx);
info->state.cfa_rule = RULE_CFA_OFFSET;
end = NULL;
if (!valid_reg(reg)) break;
TRACE("%lx: DW_CFA_offset %s, %ld\n",
info->ip,
- dbghelp_current_cpu->fetch_regname(dbghelp_current_cpu->map_dwarf_register(reg)),
+ dbghelp_current_cpu->fetch_regname(dbghelp_current_cpu->map_dwarf_register(reg, TRUE)),
offset);
info->state.regs[reg] = offset;
info->state.rules[reg] = RULE_CFA_OFFSET;
if (!valid_reg(reg)) break;
TRACE("%lx: DW_CFA_restore %s\n",
info->ip,
- dbghelp_current_cpu->fetch_regname(dbghelp_current_cpu->map_dwarf_register(reg)));
+ dbghelp_current_cpu->fetch_regname(dbghelp_current_cpu->map_dwarf_register(reg, TRUE)));
info->state.rules[reg] = RULE_UNSET;
break;
}
if (!valid_reg(reg)) break;
TRACE("%lx: DW_CFA_offset_extended %s, %ld\n",
info->ip,
- dbghelp_current_cpu->fetch_regname(dbghelp_current_cpu->map_dwarf_register(reg)),
+ dbghelp_current_cpu->fetch_regname(dbghelp_current_cpu->map_dwarf_register(reg, TRUE)),
offset);
info->state.regs[reg] = offset;
info->state.rules[reg] = RULE_CFA_OFFSET;
if (!valid_reg(reg)) break;
TRACE("%lx: DW_CFA_restore_extended %s\n",
info->ip,
- dbghelp_current_cpu->fetch_regname(dbghelp_current_cpu->map_dwarf_register(reg)));
+ dbghelp_current_cpu->fetch_regname(dbghelp_current_cpu->map_dwarf_register(reg, TRUE)));
info->state.rules[reg] = RULE_UNSET;
break;
}
if (!valid_reg(reg)) break;
TRACE("%lx: DW_CFA_undefined %s\n",
info->ip,
- dbghelp_current_cpu->fetch_regname(dbghelp_current_cpu->map_dwarf_register(reg)));
+ dbghelp_current_cpu->fetch_regname(dbghelp_current_cpu->map_dwarf_register(reg, TRUE)));
info->state.rules[reg] = RULE_UNDEFINED;
break;
}
if (!valid_reg(reg)) break;
TRACE("%lx: DW_CFA_same_value %s\n",
info->ip,
- dbghelp_current_cpu->fetch_regname(dbghelp_current_cpu->map_dwarf_register(reg)));
+ dbghelp_current_cpu->fetch_regname(dbghelp_current_cpu->map_dwarf_register(reg, TRUE)));
info->state.regs[reg] = reg;
info->state.rules[reg] = RULE_SAME;
break;
if (!valid_reg(reg) || !valid_reg(reg2)) break;
TRACE("%lx: DW_CFA_register %s == %s\n",
info->ip,
- dbghelp_current_cpu->fetch_regname(dbghelp_current_cpu->map_dwarf_register(reg)),
- dbghelp_current_cpu->fetch_regname(dbghelp_current_cpu->map_dwarf_register(reg2)));
+ dbghelp_current_cpu->fetch_regname(dbghelp_current_cpu->map_dwarf_register(reg, TRUE)),
+ dbghelp_current_cpu->fetch_regname(dbghelp_current_cpu->map_dwarf_register(reg2, TRUE)));
info->state.regs[reg] = reg2;
info->state.rules[reg] = RULE_OTHER_REG;
break;
if (!valid_reg(reg)) break;
TRACE("%lx: DW_CFA_def_cfa %s, %ld\n",
info->ip,
- dbghelp_current_cpu->fetch_regname(dbghelp_current_cpu->map_dwarf_register(reg)),
+ dbghelp_current_cpu->fetch_regname(dbghelp_current_cpu->map_dwarf_register(reg, TRUE)),
offset);
info->state.cfa_reg = reg;
info->state.cfa_offset = offset;
if (!valid_reg(reg)) break;
TRACE("%lx: DW_CFA_def_cfa_register %s\n",
info->ip,
- dbghelp_current_cpu->fetch_regname(dbghelp_current_cpu->map_dwarf_register(reg)));
+ dbghelp_current_cpu->fetch_regname(dbghelp_current_cpu->map_dwarf_register(reg, TRUE)));
info->state.cfa_reg = reg;
info->state.cfa_rule = RULE_CFA_OFFSET;
break;
if (!valid_reg(reg)) break;
TRACE("%lx: DW_CFA_%sexpression %s %lx-%lx\n",
info->ip, (op == DW_CFA_expression) ? "" : "val_",
- dbghelp_current_cpu->fetch_regname(dbghelp_current_cpu->map_dwarf_register(reg)),
+ dbghelp_current_cpu->fetch_regname(dbghelp_current_cpu->map_dwarf_register(reg, TRUE)),
expr, expr + len);
info->state.regs[reg] = expr;
info->state.rules[reg] = (op == DW_CFA_expression) ? RULE_EXPRESSION : RULE_VAL_EXPRESSION;
/* retrieve a context register from its dwarf number */
static ULONG_PTR get_context_reg(CONTEXT *context, ULONG_PTR dw_reg)
{
- unsigned regno = dbghelp_current_cpu->map_dwarf_register(dw_reg), sz;
+ unsigned regno = dbghelp_current_cpu->map_dwarf_register(dw_reg, TRUE), sz;
ULONG_PTR* ptr = dbghelp_current_cpu->fetch_context_reg(context, regno, &sz);
if (sz != sizeof(ULONG_PTR))
static void set_context_reg(struct cpu_stack_walk* csw, CONTEXT *context, ULONG_PTR dw_reg,
ULONG_PTR val, BOOL isdebuggee)
{
- unsigned regno = dbghelp_current_cpu->map_dwarf_register(dw_reg), sz;
+ unsigned regno = dbghelp_current_cpu->map_dwarf_register(dw_reg, TRUE), sz;
ULONG_PTR* ptr = dbghelp_current_cpu->fetch_context_reg(context, regno, &sz);
if (isdebuggee)
/* copy a register from one context to another using dwarf number */
static void copy_context_reg(CONTEXT *dstcontext, ULONG_PTR dwregdst, CONTEXT* srccontext, ULONG_PTR dwregsrc)
{
- unsigned regdstno = dbghelp_current_cpu->map_dwarf_register(dwregdst), szdst;
- unsigned regsrcno = dbghelp_current_cpu->map_dwarf_register(dwregsrc), szsrc;
+ unsigned regdstno = dbghelp_current_cpu->map_dwarf_register(dwregdst, TRUE), szdst;
+ unsigned regsrcno = dbghelp_current_cpu->map_dwarf_register(dwregsrc, TRUE), szsrc;
ULONG_PTR* ptrdst = dbghelp_current_cpu->fetch_context_reg(dstcontext, regdstno, &szdst);
ULONG_PTR* ptrsrc = dbghelp_current_cpu->fetch_context_reg(srccontext, regsrcno, &szsrc);
TRACE("function %lx/%lx code_align %lu data_align %ld retaddr %s\n",
ip, info.ip, info.code_align, info.data_align,
- dbghelp_current_cpu->fetch_regname(dbghelp_current_cpu->map_dwarf_register(info.retaddr_reg)));
+ dbghelp_current_cpu->fetch_regname(dbghelp_current_cpu->map_dwarf_register(info.retaddr_reg, TRUE)));
/* if at very beginning of function, return and use default unwinder */
if (ip == info.ip) return FALSE;
if (end) fde_ctx.data = end;
execute_cfa_instructions(&fde_ctx, ip, &info);
+
+ /* if there is no information about retaddr, use default unwinder */
+ if (info.state.rules[info.retaddr_reg] == RULE_UNSET) return FALSE;
+
apply_frame_state(pair.effective, csw, context, &info.state, cfa);
return TRUE;
#ifdef HAVE_SYS_LINK_H
# include <sys/link.h>
#endif
+#ifdef HAVE_MACH_O_LOADER_H
+#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
#define IMAGE_NO_MAP ((void*)-1)
}* sect;
#endif
} elf;
+ struct macho_file_map
+ {
+ size_t segs_size;
+ size_t segs_start;
+ int fd;
+ struct image_file_map* dsym; /* the debug symbols file associated with this one */
+
+#ifdef HAVE_MACH_O_LOADER_H
+ macho_mach_header mach_header;
+ const struct load_command* load_commands;
+ const struct uuid_command* uuid;
+
+ /* The offset in the file which is this architecture. mach_header was
+ * read from arch_offset. */
+ unsigned arch_offset;
+
+ int num_sections;
+ struct
+ {
+ const macho_section* section;
+ const char* mapped;
+ }* sect;
+#endif
+ } macho;
struct pe_file_map
{
HANDLE hMap;
extern DWORD_PTR elf_get_map_rva(const struct image_section_map* ism) DECLSPEC_HIDDEN;
extern unsigned elf_get_map_size(const struct image_section_map* ism) DECLSPEC_HIDDEN;
+extern BOOL macho_find_section(struct image_file_map* ifm, const char* segname,
+ const char* sectname, struct image_section_map* ism) DECLSPEC_HIDDEN;
+extern const char* macho_map_section(struct image_section_map* ism) DECLSPEC_HIDDEN;
+extern void macho_unmap_section(struct image_section_map* ism) DECLSPEC_HIDDEN;
+extern DWORD_PTR macho_get_map_rva(const struct image_section_map* ism) DECLSPEC_HIDDEN;
+extern unsigned macho_get_map_size(const struct image_section_map* ism) DECLSPEC_HIDDEN;
+
extern BOOL pe_find_section(struct image_file_map* fmap, const char* name,
struct image_section_map* ism) DECLSPEC_HIDDEN;
extern const char* pe_map_section(struct image_section_map* psm) DECLSPEC_HIDDEN;
switch (fmap->modtype)
{
#ifndef DBGHELP_STATIC_LIB
- case DMT_ELF: return elf_find_section(fmap, name, SHT_NULL, ism);
+ case DMT_ELF: return elf_find_section(fmap, name, SHT_NULL, ism);
+ case DMT_MACHO: return macho_find_section(fmap, NULL, name, ism);
#endif
- case DMT_PE: return pe_find_section(fmap, name, ism);
+ case DMT_PE: return pe_find_section(fmap, name, ism);
default: assert(0); return FALSE;
}
}
switch (ism->fmap->modtype)
{
#ifndef DBGHELP_STATIC_LIB
- case DMT_ELF: return elf_map_section(ism);
+ case DMT_ELF: return elf_map_section(ism);
+ case DMT_MACHO: return macho_map_section(ism);
#endif
- case DMT_PE: return pe_map_section(ism);
+ case DMT_PE: return pe_map_section(ism);
default: assert(0); return NULL;
}
}
switch (ism->fmap->modtype)
{
#ifndef DBGHELP_STATIC_LIB
- case DMT_ELF: elf_unmap_section(ism); break;
+ case DMT_ELF: elf_unmap_section(ism); break;
+ case DMT_MACHO: macho_unmap_section(ism); break;
#endif
- case DMT_PE: pe_unmap_section(ism); break;
+ case DMT_PE: pe_unmap_section(ism); break;
default: assert(0); return;
}
}
switch (ism->fmap->modtype)
{
#ifndef DBGHELP_STATIC_LIB
- case DMT_ELF: return elf_get_map_rva(ism);
+ case DMT_ELF: return elf_get_map_rva(ism);
+ case DMT_MACHO: return macho_get_map_rva(ism);
#endif
- case DMT_PE: return pe_get_map_rva(ism);
+ case DMT_PE: return pe_get_map_rva(ism);
default: assert(0); return 0;
}
}
switch (ism->fmap->modtype)
{
#ifndef DBGHELP_STATIC_LIB
- case DMT_ELF: return elf_get_map_size(ism);
+ case DMT_ELF: return elf_get_map_size(ism);
+ case DMT_MACHO: return macho_get_map_size(ism);
#endif
- case DMT_PE: return pe_get_map_size(ism);
+ case DMT_PE: return pe_get_map_size(ism);
default: assert(0); return 0;
}
}
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
+
+
+#define UUID_STRING_LEN 37 /* 16 bytes at 2 hex digits apiece, 4 dashes, and the null terminator */
+
+
struct macho_module_info
{
+ struct image_file_map file_map;
unsigned long load_addr;
unsigned short in_use : 1,
is_loader : 1;
const WCHAR* module_name; /* OUT found module name (if MACHO_INFO_NAME is set) */
};
-/* structure holding information while handling a Mach-O image */
-#define BITS_PER_ULONG (sizeof(ULONG) * 8)
-#define ULONGS_FOR_BITS(nbits) (((nbits) + BITS_PER_ULONG - 1) / BITS_PER_ULONG)
-struct macho_file_map
-{
- /* A copy of the Mach-O header for an individual architecture. */
- struct mach_header mach_header;
-
- /* The mapped load commands. */
- const struct load_command* load_commands;
-
- /* The portion of the file which is this architecture. mach_header was
- * read from arch_offset. */
- unsigned arch_offset;
- unsigned arch_size;
-
- /* The range of address space covered by all segments. */
- size_t segs_start;
- size_t segs_size;
-
- /* Map of which sections contain code. Sections are accessed using 1-based
- * index. Bit 0 of this bitset indicates if the bitset has been initialized. */
- RTL_BITMAP sect_is_code;
- ULONG sect_is_code_buff[ULONGS_FOR_BITS(MAX_SECT + 1)];
-
- /* The file. */
- int fd;
-};
+static void macho_unmap_file(struct image_file_map* fmap);
-static void macho_unmap_file(struct macho_file_map* fmap);
+static char* format_uuid(const uint8_t uuid[16], char out[UUID_STRING_LEN])
+{
+ sprintf(out, "%02X%02X%02X%02X-%02X%02X-%02X%02X-%02X%02X-%02X%02X%02X%02X%02X%02X",
+ uuid[0], uuid[1], uuid[2], uuid[3], uuid[4], uuid[5], uuid[6], uuid[7],
+ uuid[8], uuid[9], uuid[10], uuid[11], uuid[12], uuid[13], uuid[14], uuid[15]);
+ return out;
+}
/******************************************************************
* macho_calc_range
* that encompasses it. For a fat binary, the architecture will
* itself be offset within the file, so take that into account.
*/
-static void macho_calc_range(const struct macho_file_map* fmap, unsigned offset,
- unsigned len, unsigned* out_aligned_offset,
- unsigned* out_aligned_end, unsigned* out_aligned_len,
- unsigned* out_misalign)
+static void macho_calc_range(const struct macho_file_map* fmap, unsigned long offset,
+ unsigned long len, unsigned long* out_aligned_offset,
+ unsigned long* out_aligned_end, unsigned long* out_aligned_len,
+ unsigned long* out_misalign)
{
- unsigned pagemask = sysconf( _SC_PAGESIZE ) - 1;
- unsigned file_offset, misalign;
+ unsigned long pagemask = sysconf( _SC_PAGESIZE ) - 1;
+ unsigned long file_offset, misalign;
file_offset = fmap->arch_offset + offset;
misalign = file_offset & pagemask;
*
* Maps a range (offset, length in bytes) from a Mach-O file into memory
*/
-static const char* macho_map_range(const struct macho_file_map* fmap, unsigned offset, unsigned len)
+static const char* macho_map_range(const struct macho_file_map* fmap, unsigned long offset, unsigned long len,
+ const char** base)
{
- unsigned misalign, aligned_offset, aligned_map_end, map_size;
- const void* aligned_ptr;
+ unsigned long misalign, aligned_offset, aligned_map_end, map_size;
+ const void* aligned_ptr;
- TRACE("(%p/%d, 0x%08x, 0x%08x)\n", fmap, fmap->fd, offset, len);
+ TRACE("(%p/%d, 0x%08lx, 0x%08lx)\n", fmap, fmap->fd, offset, len);
macho_calc_range(fmap, offset, len, &aligned_offset, &aligned_map_end,
&map_size, &misalign);
aligned_ptr = mmap(NULL, map_size, PROT_READ, MAP_PRIVATE, fmap->fd, aligned_offset);
- TRACE("Mapped (0x%08x - 0x%08x) to %p\n", aligned_offset, aligned_map_end, aligned_ptr);
+ TRACE("Mapped (0x%08lx - 0x%08lx) to %p\n", aligned_offset, aligned_map_end, aligned_ptr);
- if (aligned_ptr == MAP_FAILED) return MACHO_NO_MAP;
+ if (aligned_ptr == MAP_FAILED) return IMAGE_NO_MAP;
+ if (base)
+ *base = aligned_ptr;
return (const char*)aligned_ptr + misalign;
}
*
* Unmaps a range (offset, length in bytes) of a Mach-O file from memory
*/
-static void macho_unmap_range(const void** mapped, const struct macho_file_map* fmap,
- unsigned offset, unsigned len)
+static void macho_unmap_range(const char** base, const void** mapped, const struct macho_file_map* fmap,
+ unsigned long offset, unsigned long len)
{
- TRACE("(%p, %p/%d, 0x%08x, 0x%08x)\n", mapped, fmap, fmap->fd, offset, len);
+ TRACE("(%p, %p, %p/%d, 0x%08lx, 0x%08lx)\n", base, mapped, fmap, fmap->fd, offset, len);
- if (mapped && *mapped != MACHO_NO_MAP)
+ if ((mapped && *mapped != IMAGE_NO_MAP) || (base && *base != IMAGE_NO_MAP))
{
- unsigned misalign, aligned_offset, aligned_map_end, map_size;
- void* aligned_ptr;
+ unsigned long misalign, aligned_offset, aligned_map_end, map_size;
+ void* aligned_ptr;
macho_calc_range(fmap, offset, len, &aligned_offset, &aligned_map_end,
&map_size, &misalign);
- aligned_ptr = (char*)*mapped - misalign;
+ if (mapped)
+ aligned_ptr = (char*)*mapped - misalign;
+ else
+ aligned_ptr = (void*)*base;
if (munmap(aligned_ptr, map_size) < 0)
WARN("Couldn't unmap the range\n");
- TRACE("Unmapped (0x%08x - 0x%08x) from %p - %p\n", aligned_offset, aligned_map_end, aligned_ptr, (char*)aligned_ptr + map_size);
- *mapped = MACHO_NO_MAP;
+ TRACE("Unmapped (0x%08lx - 0x%08lx) from %p - %p\n", aligned_offset, aligned_map_end, aligned_ptr, (char*)aligned_ptr + map_size);
+ if (mapped)
+ *mapped = IMAGE_NO_MAP;
+ if (base)
+ *base = IMAGE_NO_MAP;
}
}
* the munmap doesn't fragment the mapping.
*/
static BOOL macho_map_ranges(const struct macho_file_map* fmap,
- unsigned offset1, unsigned len1,
- unsigned offset2, unsigned len2,
+ unsigned long offset1, unsigned long len1,
+ unsigned long offset2, unsigned long len2,
const void** mapped1, const void** mapped2)
{
- unsigned aligned_offset1, aligned_map_end1;
- unsigned aligned_offset2, aligned_map_end2;
+ unsigned long aligned_offset1, aligned_map_end1;
+ unsigned long aligned_offset2, aligned_map_end2;
- TRACE("(%p/%d, 0x%08x, 0x%08x, 0x%08x, 0x%08x, %p, %p)\n", fmap, fmap->fd,
+ TRACE("(%p/%d, 0x%08lx, 0x%08lx, 0x%08lx, 0x%08lx, %p, %p)\n", fmap, fmap->fd,
offset1, len1, offset2, len2, mapped1, mapped2);
macho_calc_range(fmap, offset1, len1, &aligned_offset1, &aligned_map_end1, NULL, NULL);
if (aligned_map_end1 < aligned_offset2 || aligned_map_end2 < aligned_offset1)
{
- *mapped1 = macho_map_range(fmap, offset1, len1);
- if (*mapped1 != MACHO_NO_MAP)
+ *mapped1 = macho_map_range(fmap, offset1, len1, NULL);
+ if (*mapped1 != IMAGE_NO_MAP)
{
- *mapped2 = macho_map_range(fmap, offset2, len2);
- if (*mapped2 == MACHO_NO_MAP)
- macho_unmap_range(mapped1, fmap, offset1, len1);
+ *mapped2 = macho_map_range(fmap, offset2, len2, NULL);
+ if (*mapped2 == IMAGE_NO_MAP)
+ macho_unmap_range(NULL, mapped1, fmap, offset1, len1);
}
}
else
{
if (offset1 < offset2)
{
- *mapped1 = macho_map_range(fmap, offset1, offset2 + len2 - offset1);
- if (*mapped1 != MACHO_NO_MAP)
+ *mapped1 = macho_map_range(fmap, offset1, offset2 + len2 - offset1, NULL);
+ if (*mapped1 != IMAGE_NO_MAP)
*mapped2 = (const char*)*mapped1 + offset2 - offset1;
}
else
{
- *mapped2 = macho_map_range(fmap, offset2, offset1 + len1 - offset2);
- if (*mapped2 != MACHO_NO_MAP)
+ *mapped2 = macho_map_range(fmap, offset2, offset1 + len1 - offset2, NULL);
+ if (*mapped2 != IMAGE_NO_MAP)
*mapped1 = (const char*)*mapped2 + offset1 - offset2;
}
}
TRACE(" => %p, %p\n", *mapped1, *mapped2);
- return (*mapped1 != MACHO_NO_MAP) && (*mapped2 != MACHO_NO_MAP);
+ return (*mapped1 != IMAGE_NO_MAP) && (*mapped2 != IMAGE_NO_MAP);
}
/******************************************************************
* macho_map_ranges.
*/
static void macho_unmap_ranges(const struct macho_file_map* fmap,
- unsigned offset1, unsigned len1,
- unsigned offset2, unsigned len2,
+ unsigned long offset1, unsigned long len1,
+ unsigned long offset2, unsigned long len2,
const void** mapped1, const void** mapped2)
{
- unsigned aligned_offset1, aligned_map_end1;
- unsigned aligned_offset2, aligned_map_end2;
+ unsigned long aligned_offset1, aligned_map_end1;
+ unsigned long aligned_offset2, aligned_map_end2;
- TRACE("(%p/%d, 0x%08x, 0x%08x, 0x%08x, 0x%08x, %p/%p, %p/%p)\n", fmap, fmap->fd,
+ TRACE("(%p/%d, 0x%08lx, 0x%08lx, 0x%08lx, 0x%08lx, %p/%p, %p/%p)\n", fmap, fmap->fd,
offset1, len1, offset2, len2, mapped1, *mapped1, mapped2, *mapped2);
macho_calc_range(fmap, offset1, len1, &aligned_offset1, &aligned_map_end1, NULL, NULL);
if (aligned_map_end1 < aligned_offset2 || aligned_map_end2 < aligned_offset1)
{
- macho_unmap_range(mapped1, fmap, offset1, len1);
- macho_unmap_range(mapped2, fmap, offset2, len2);
+ macho_unmap_range(NULL, mapped1, fmap, offset1, len1);
+ macho_unmap_range(NULL, mapped2, fmap, offset2, len2);
}
else
{
if (offset1 < offset2)
{
- macho_unmap_range(mapped1, fmap, offset1, offset2 + len2 - offset1);
- *mapped2 = MACHO_NO_MAP;
+ macho_unmap_range(NULL, mapped1, fmap, offset1, offset2 + len2 - offset1);
+ *mapped2 = IMAGE_NO_MAP;
}
else
{
- macho_unmap_range(mapped2, fmap, offset2, offset1 + len1 - offset2);
- *mapped1 = MACHO_NO_MAP;
+ macho_unmap_range(NULL, mapped2, fmap, offset2, offset1 + len1 - offset2);
+ *mapped1 = IMAGE_NO_MAP;
+ }
+ }
+}
+
+/******************************************************************
+ * macho_find_section
+ */
+BOOL macho_find_section(struct image_file_map* ifm, const char* segname, const char* sectname, struct image_section_map* ism)
+{
+ struct macho_file_map* fmap;
+ unsigned i;
+ 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. */
+ if (sectname[0] == '.')
+ {
+ lstrcpynA(tmp, "__", sizeof(tmp));
+ lstrcpynA(tmp + 2, sectname + 1, sizeof(tmp) - 2);
+ sectname = tmp;
+ }
+
+ while (ifm)
+ {
+ fmap = &ifm->u.macho;
+ for (i = 0; i < fmap->num_sections; i++)
+ {
+ if (strcmp(fmap->sect[i].section->sectname, sectname) == 0 &&
+ (!segname || strcmp(fmap->sect[i].section->sectname, segname) == 0))
+ {
+ ism->fmap = ifm;
+ ism->sidx = i;
+ return TRUE;
+ }
}
+ ifm = fmap->dsym;
+ }
+
+ ism->fmap = NULL;
+ ism->sidx = -1;
+ return FALSE;
+}
+
+/******************************************************************
+ * macho_map_section
+ */
+const char* macho_map_section(struct image_section_map* ism)
+{
+ struct macho_file_map* fmap = &ism->fmap->u.macho;
+
+ assert(ism->fmap->modtype == DMT_MACHO);
+ if (ism->sidx < 0 || ism->sidx >= ism->fmap->u.macho.num_sections)
+ return IMAGE_NO_MAP;
+
+ return macho_map_range(fmap, fmap->sect[ism->sidx].section->offset, fmap->sect[ism->sidx].section->size,
+ &fmap->sect[ism->sidx].mapped);
+}
+
+/******************************************************************
+ * macho_unmap_section
+ */
+void macho_unmap_section(struct image_section_map* ism)
+{
+ struct macho_file_map* fmap = &ism->fmap->u.macho;
+
+ 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_get_map_rva
+ */
+DWORD_PTR macho_get_map_rva(const struct image_section_map* ism)
+{
+ if (ism->sidx < 0 || ism->sidx >= ism->fmap->u.macho.num_sections)
+ return 0;
+ return ism->fmap->u.macho.sect[ism->sidx].section->addr - ism->fmap->u.macho.segs_start;
+}
+
+/******************************************************************
+ * macho_get_map_size
+ */
+unsigned macho_get_map_size(const struct image_section_map* ism)
+{
+ if (ism->sidx < 0 || ism->sidx >= ism->fmap->u.macho.num_sections)
+ return 0;
+ return ism->fmap->u.macho.sect[ism->sidx].section->size;
+}
+
/******************************************************************
* macho_map_load_commands
*
*/
static const struct load_command* macho_map_load_commands(struct macho_file_map* fmap)
{
- if (fmap->load_commands == MACHO_NO_MAP)
+ if (fmap->load_commands == IMAGE_NO_MAP)
{
fmap->load_commands = (const struct load_command*) macho_map_range(
- fmap, sizeof(fmap->mach_header), fmap->mach_header.sizeofcmds);
+ fmap, sizeof(fmap->mach_header), fmap->mach_header.sizeofcmds, NULL);
TRACE("Mapped load commands: %p\n", fmap->load_commands);
}
*/
static void macho_unmap_load_commands(struct macho_file_map* fmap)
{
- if (fmap->load_commands != MACHO_NO_MAP)
+ if (fmap->load_commands != IMAGE_NO_MAP)
{
TRACE("Unmapping load commands: %p\n", fmap->load_commands);
- macho_unmap_range((const void**)&fmap->load_commands, fmap,
+ macho_unmap_range(NULL, (const void**)&fmap->load_commands, fmap,
sizeof(fmap->mach_header), fmap->mach_header.sizeofcmds);
}
}
TRACE("(%p/%d, %u, %p, %p)\n", fmap, fmap->fd, cmd, cb, user);
- if ((lc = macho_map_load_commands(fmap)) == MACHO_NO_MAP) return -1;
+ if ((lc = macho_map_load_commands(fmap)) == IMAGE_NO_MAP) return -1;
TRACE("%d total commands\n", fmap->mach_header.ncmds);
}
/******************************************************************
- * macho_accum_segs_range
+ * macho_count_sections
+ *
+ * Callback for macho_enum_load_commands. Counts the number of
+ * 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)
+{
+ 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)));
+
+ fmap->num_sections += sc->nsects;
+ return 0;
+}
+
+/******************************************************************
+ * macho_load_section_info
*
* Callback for macho_enum_load_commands. Accumulates the address
- * range covered by the segments of a Mach-O file. All commands
- * are expected to be of LC_SEGMENT type.
+ * 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_accum_segs_range(struct macho_file_map* fmap,
- const struct load_command* lc, void* user)
+static int macho_load_section_info(struct macho_file_map* fmap, const struct load_command* lc, void* user)
{
- const struct segment_command* sc = (const struct segment_command*)lc;
- unsigned tmp, page_mask = sysconf( _SC_PAGESIZE ) - 1;
+ const macho_segment_command* sc = (const macho_segment_command*)lc;
+ int* section_index = (int*)user;
+ const macho_section* section;
+ int i;
+ unsigned long tmp, page_mask = sysconf( _SC_PAGESIZE ) - 1;
- TRACE("(%p/%d, %p, %p) before: 0x%08x - 0x%08x\n", fmap, fmap->fd, lc, user,
- (unsigned)fmap->segs_start, (unsigned)fmap->segs_size);
- TRACE("Segment command vm: 0x%08x - 0x%08x\n", (unsigned)sc->vmaddr,
- (unsigned)sc->vmaddr + sc->vmsize);
+ 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));
if (!strncmp(sc->segname, "WINE_", 5))
- {
TRACE("Ignoring special Wine segment %s\n", debugstr_an(sc->segname, sizeof(sc->segname)));
- return 0;
+ else if (!strncmp(sc->segname, "__PAGEZERO", 10))
+ TRACE("Ignoring __PAGEZERO segment\n");
+ else
+ {
+ /* If this segment starts before previously-known earliest, record new earliest. */
+ if (sc->vmaddr < fmap->segs_start)
+ fmap->segs_start = sc->vmaddr;
+
+ /* If this segment extends beyond previously-known furthest, record new furthest. */
+ tmp = (sc->vmaddr + sc->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);
}
- if (!strncmp(sc->segname, "__PAGEZERO", 10))
+
+ section = (const macho_section*)(sc + 1);
+ for (i = 0; i < sc->nsects; i++)
{
- TRACE("Ignoring __PAGEZERO segment\n");
- return 0;
+ fmap->sect[*section_index].section = §ion[i];
+ fmap->sect[*section_index].mapped = IMAGE_NO_MAP;
+ (*section_index)++;
}
- /* If this segment starts before previously-known earliest, record
- * new earliest. */
- if (sc->vmaddr < fmap->segs_start)
- fmap->segs_start = sc->vmaddr;
+ return 0;
+}
- /* If this segment extends beyond previously-known furthest, record
- * new furthest. */
- tmp = (sc->vmaddr + sc->vmsize + page_mask) & ~page_mask;
- if (fmap->segs_size < tmp) fmap->segs_size = tmp;
+/******************************************************************
+ * find_uuid
+ *
+ * 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)
+{
+ fmap->uuid = (const struct uuid_command*)lc;
+ return 1;
+}
- TRACE("after: 0x%08x - 0x%08x\n", (unsigned)fmap->segs_start, (unsigned)fmap->segs_size);
+/******************************************************************
+ * reset_file_map
+ */
+static inline void reset_file_map(struct image_file_map* ifm)
+{
+ struct macho_file_map* fmap = &ifm->u.macho;
- return 0;
+ fmap->fd = -1;
+ fmap->dsym = NULL;
+ fmap->load_commands = IMAGE_NO_MAP;
+ fmap->uuid = NULL;
+ fmap->num_sections = 0;
+ fmap->sect = NULL;
}
/******************************************************************
*
* Maps a Mach-O file into memory (and checks it's a real Mach-O file)
*/
-static BOOL macho_map_file(const WCHAR* filenameW, struct macho_file_map* fmap)
+static BOOL macho_map_file(const WCHAR* filenameW, struct image_file_map* ifm)
{
+ struct macho_file_map* fmap = &ifm->u.macho;
struct fat_header fat_header;
struct stat statbuf;
int i;
TRACE("(%s, %p)\n", debugstr_w(filenameW), fmap);
- fmap->fd = -1;
- fmap->load_commands = MACHO_NO_MAP;
- RtlInitializeBitMap(&fmap->sect_is_code, fmap->sect_is_code_buff, MAX_SECT + 1);
+ reset_file_map(ifm);
+
+ ifm->modtype = DMT_MACHO;
+#ifdef _WIN64
+ ifm->addr_size = 64;
+#else
+ ifm->addr_size = 32;
+#endif
len = WideCharToMultiByte(CP_UNIXCP, 0, filenameW, -1, NULL, 0, NULL, NULL);
if (!(filename = HeapAlloc(GetProcessHeap(), 0, len)))
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) == CPU_TYPE_X86)
+ if (swap_ulong_be_to_host(fat_arch.cputype) == TARGET_CPU_TYPE)
{
fmap->arch_offset = swap_ulong_be_to_host(fat_arch.offset);
- fmap->arch_size = swap_ulong_be_to_host(fat_arch.size);
break;
}
}
if (i >= narch) goto done;
- TRACE("... found x86 arch\n");
+ TRACE("... found target arch (%d)\n", TARGET_CPU_TYPE);
}
else
{
fmap->arch_offset = 0;
- fmap->arch_size = statbuf.st_size;
TRACE("... not a fat header\n");
}
goto done;
TRACE("... got possible Mach header\n");
/* and check for a Mach-O header */
- if (fmap->mach_header.magic != MH_MAGIC ||
- fmap->mach_header.cputype != CPU_TYPE_X86) goto done;
+ if (fmap->mach_header.magic != TARGET_MH_MAGIC ||
+ fmap->mach_header.cputype != TARGET_CPU_TYPE) goto done;
/* Make sure the file type is one of the ones we expect. */
switch (fmap->mach_header.filetype)
{
case MH_DYLIB:
case MH_DYLINKER:
case MH_BUNDLE:
+ case MH_DSYM:
break;
default:
goto done;
}
- TRACE("... verified Mach x86 header\n");
+ TRACE("... verified Mach header\n");
+
+ fmap->num_sections = 0;
+ if (macho_enum_load_commands(fmap, TARGET_SEGMENT_COMMAND, macho_count_sections, NULL) < 0)
+ goto done;
+ TRACE("%d sections\n", fmap->num_sections);
+
+ fmap->sect = HeapAlloc(GetProcessHeap(), 0, fmap->num_sections * sizeof(fmap->sect[0]));
+ if (!fmap->sect)
+ goto done;
fmap->segs_size = 0;
fmap->segs_start = ~0L;
- if (macho_enum_load_commands(fmap, LC_SEGMENT, macho_accum_segs_range, NULL) < 0)
+ i = 0;
+ if (macho_enum_load_commands(fmap, TARGET_SEGMENT_COMMAND, macho_load_section_info, &i) < 0)
+ {
+ fmap->num_sections = 0;
goto done;
+ }
fmap->segs_size -= fmap->segs_start;
- TRACE("segs_start: 0x%08x, segs_size: 0x%08x\n", (unsigned)fmap->segs_start,
- (unsigned)fmap->segs_size);
+ 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)
+ goto done;
+ if (fmap->uuid)
+ {
+ char uuid_string[UUID_STRING_LEN];
+ TRACE("UUID %s\n", format_uuid(fmap->uuid->uuid, uuid_string));
+ }
+ else
+ TRACE("no UUID found\n");
ret = TRUE;
done:
if (!ret)
- macho_unmap_file(fmap);
+ macho_unmap_file(ifm);
HeapFree(GetProcessHeap(), 0, filename);
return ret;
}
*
* Unmaps a Mach-O file from memory (previously mapped with macho_map_file)
*/
-static void macho_unmap_file(struct macho_file_map* fmap)
+static void macho_unmap_file(struct image_file_map* ifm)
{
- TRACE("(%p/%d)\n", fmap, fmap->fd);
- if (fmap->fd != -1)
+ struct image_file_map* cursor;
+
+ TRACE("(%p/%d)\n", ifm, ifm->u.macho.fd);
+
+ cursor = ifm;
+ while (cursor)
{
- macho_unmap_load_commands(fmap);
- close(fmap->fd);
- fmap->fd = -1;
- }
-}
+ struct image_file_map* next;
-/******************************************************************
- * macho_fill_sect_is_code
- *
- * Callback for macho_enum_load_commands. Determines which segments
- * of a Mach-O file contain code. All commands are expected to be
- * of LC_SEGMENT type.
- */
-static int macho_fill_sect_is_code(struct macho_file_map* fmap,
- const struct load_command* lc, void* user)
-{
- const struct segment_command* sc = (const struct segment_command*)lc;
- const struct section* sections;
- int* cursect = user;
- int i;
+ if (ifm->u.macho.fd != -1)
+ {
+ struct image_section_map ism;
- TRACE("(%p/%d, %p, %p/%d) scanning %u sections\n", fmap, fmap->fd, lc,
- cursect, *cursect, sc->nsects);
+ ism.fmap = ifm;
+ for (ism.sidx = 0; ism.sidx < ifm->u.macho.num_sections; ism.sidx++)
+ macho_unmap_section(&ism);
- sections = (const struct section*)(sc + 1);
- for (i = 0; i < sc->nsects; i++)
- {
- if (*cursect > MAX_SECT) return -1;
- (*cursect)++;
+ HeapFree(GetProcessHeap(), 0, ifm->u.macho.sect);
+ macho_unmap_load_commands(&ifm->u.macho);
+ close(ifm->u.macho.fd);
+ ifm->u.macho.fd = -1;
+ }
- if (!(sections[i].flags & SECTION_TYPE) &&
- (sections[i].flags & (S_ATTR_PURE_INSTRUCTIONS|S_ATTR_SOME_INSTRUCTIONS)))
- RtlSetBits(&fmap->sect_is_code, *cursect, 1);
- else
- RtlClearBits(&fmap->sect_is_code, *cursect, 1);
- TRACE("Section %d (%d of this segment) is%s code\n", *cursect, i,
- (RtlAreBitsSet(&fmap->sect_is_code, *cursect, 1) ? "" : " not"));
+ next = cursor->u.macho.dsym;
+ if (cursor != ifm)
+ HeapFree(GetProcessHeap(), 0, cursor);
+ cursor = next;
}
-
- return 0;
}
/******************************************************************
*/
static BOOL macho_sect_is_code(struct macho_file_map* fmap, unsigned char sectidx)
{
+ BOOL ret;
+
TRACE("(%p/%d, %u)\n", fmap, fmap->fd, sectidx);
- if (!RtlAreBitsSet(&fmap->sect_is_code, 0, 1))
- {
- int cursect = 0;
- if (macho_enum_load_commands(fmap, LC_SEGMENT, macho_fill_sect_is_code, &cursect) < 0)
- WARN("Couldn't load sect_is_code map\n");
- RtlSetBits(&fmap->sect_is_code, 0, 1);
- }
+ if (!sectidx) return FALSE;
- return RtlAreBitsSet(&fmap->sect_is_code, sectidx, 1);
+ sectidx--; /* convert from 1-based to 0-based */
+ if (sectidx >= fmap->num_sections) return FALSE;
+
+ 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;
}
struct symtab_elt
{
const struct symtab_command* sc = (const struct symtab_command*)lc;
struct macho_debug_info* mdi = user;
- const struct nlist* stab;
+ const macho_nlist* stab;
const char* stabstr;
int ret = 0;
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(struct nlist),
+ if (!macho_map_ranges(fmap, sc->symoff, sc->nsyms * sizeof(macho_nlist),
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(struct nlist),
+ stab, sc->nsyms * sizeof(macho_nlist),
stabstr, sc->strsize, macho_stabs_def_cb, mdi))
ret = -1;
- macho_unmap_ranges(fmap, sc->symoff, sc->nsyms * sizeof(struct nlist),
+ macho_unmap_ranges(fmap, sc->symoff, sc->nsyms * sizeof(macho_nlist),
sc->stroff, sc->strsize, (const void**)&stab, (const void**)&stabstr);
return ret;
}
/******************************************************************
- * macho_load_debug_info_from_map
+ * try_dsym
*
- * Loads the symbolic information from a Mach-O module.
- * Returns
- * FALSE if the file doesn't contain symbolic info (or this info
- * cannot be read or parsed)
- * TRUE on success
+ * Try to load a debug symbol file from the given path and check
+ * if its UUID matches the UUID of an already-mapped file. If so,
+ * stash the file map in the "dsym" field of the file and return
+ * TRUE. If it can't be mapped or its UUID doesn't match, return
+ * FALSE.
*/
-static BOOL macho_load_debug_info_from_map(struct module* module,
- struct macho_file_map* fmap)
+static BOOL try_dsym(const WCHAR* path, struct macho_file_map* fmap)
{
- BOOL ret = FALSE;
- struct macho_debug_info mdi;
- int result;
+ struct image_file_map dsym_ifm;
- TRACE("(%p, %p/%d)\n", module, fmap, fmap->fd);
+ if (macho_map_file(path, &dsym_ifm))
+ {
+ char uuid_string[UUID_STRING_LEN];
- module->module.SymType = SymExport;
+ if (dsym_ifm.u.macho.uuid && !memcmp(dsym_ifm.u.macho.uuid->uuid, fmap->uuid->uuid, sizeof(fmap->uuid->uuid)))
+ {
+ TRACE("found matching debug symbol file at %s\n", debugstr_w(path));
+ fmap->dsym = HeapAlloc(GetProcessHeap(), 0, sizeof(dsym_ifm));
+ *fmap->dsym = dsym_ifm;
+ return TRUE;
+ }
- mdi.fmap = fmap;
- 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);
- if (result > 0)
- ret = TRUE;
- else if (result < 0)
- WARN("Couldn't correctly read stabs\n");
+ TRACE("candidate debug symbol file at %s has wrong UUID %s; ignoring\n", debugstr_w(path),
+ format_uuid(dsym_ifm.u.macho.uuid->uuid, uuid_string));
- macho_finish_stabs(module, &mdi.ht_symtab);
+ macho_unmap_file(&dsym_ifm);
+ }
+ else
+ TRACE("couldn't map file at %s\n", debugstr_w(path));
- pool_destroy(&mdi.pool);
- return ret;
+ return FALSE;
+}
+
+/******************************************************************
+ * find_and_map_dsym
+ *
+ * Search for a debugging symbols file associated with a module and
+ * map it. First look for a .dSYM bundle next to the module file
+ * (e.g. <path>.dSYM/Contents/Resources/DWARF/<basename of path>)
+ * as produced by dsymutil. Next, look for a .dwarf file next to
+ * the module file (e.g. <path>.dwarf) as produced by
+ * "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 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};
+ static const WCHAR dot_dwarf[] = {'.','d','w','a','r','f',0};
+ struct macho_file_map* fmap = &module->format_info[DFI_MACHO]->u.macho_info->file_map.u.macho;
+ const WCHAR* p;
+ size_t len;
+ WCHAR* path = NULL;
+ char uuid_string[UUID_STRING_LEN];
+ CFStringRef uuid_cfstring;
+ CFStringRef query_string;
+ MDQueryRef query = NULL;
+
+ /* Without a UUID, we can't verify that any debug info file we find corresponds
+ to this file. Better to have no debug info than incorrect debug info. */
+ if (!fmap->uuid)
+ return;
+
+ if ((p = strrchrW(module->module.LoadedImageName, '/')))
+ p++;
+ else
+ p = module->module.LoadedImageName;
+ len = strlenW(module->module.LoadedImageName) + strlenW(dot_dsym) + strlenW(dsym_subpath) + strlenW(p) + 1;
+ path = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
+ if (!path)
+ return;
+ strcpyW(path, module->module.LoadedImageName);
+ strcatW(path, dot_dsym);
+ strcatW(path, dsym_subpath);
+ strcatW(path, p);
+
+ if (try_dsym(path, fmap))
+ goto found;
+
+ strcpyW(path + strlenW(module->module.LoadedImageName), dot_dwarf);
+
+ if (try_dsym(path, fmap))
+ goto found;
+
+ format_uuid(fmap->uuid->uuid, uuid_string);
+ uuid_cfstring = CFStringCreateWithCString(NULL, uuid_string, kCFStringEncodingASCII);
+ query_string = CFStringCreateWithFormat(NULL, NULL, CFSTR("com_apple_xcode_dsym_uuids == \"%@\""), uuid_cfstring);
+ CFRelease(uuid_cfstring);
+ query = MDQueryCreate(NULL, query_string, NULL, NULL);
+ CFRelease(query_string);
+ MDQuerySetMaxCount(query, 1);
+ if (MDQueryExecute(query, kMDQuerySynchronous) && MDQueryGetResultCount(query) >= 1)
+ {
+ MDItemRef item = (MDItemRef)MDQueryGetResultAtIndex(query, 0);
+ CFStringRef item_path = MDItemCopyAttribute(item, kMDItemPath);
+ if (item_path)
+ {
+ CFIndex item_path_len = CFStringGetLength(item_path);
+ if (item_path_len + strlenW(dsym_subpath) + strlenW(p) >= len)
+ {
+ HeapFree(GetProcessHeap(), 0, path);
+ len = item_path_len + strlenW(dsym_subpath) + strlenW(p) + 1;
+ path = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
+ }
+ CFStringGetCharacters(item_path, CFRangeMake(0, item_path_len), (UniChar*)path);
+ strcpyW(path + item_path_len, dsym_subpath);
+ strcatW(path, p);
+ CFRelease(item_path);
+
+ if (try_dsym(path, fmap))
+ goto found;
+ }
+ }
+
+found:
+ HeapFree(GetProcessHeap(), 0, path);
+ if (query) CFRelease(query);
}
/******************************************************************
*
* Loads Mach-O debugging information from the module image file.
*/
-BOOL macho_load_debug_info(struct module* module, struct macho_file_map* fmap)
+BOOL macho_load_debug_info(struct module* module)
{
- BOOL ret = TRUE;
- struct macho_file_map my_fmap;
-
- TRACE("(%p, %p/%d)\n", module, fmap, fmap ? fmap->fd : -1);
+ BOOL ret = FALSE;
+ struct macho_debug_info mdi;
+ int result;
+ struct macho_file_map *fmap;
if (module->type != DMT_MACHO || !module->format_info[DFI_MACHO]->u.macho_info)
{
return FALSE;
}
- if (!fmap)
+ fmap = &module->format_info[DFI_MACHO]->u.macho_info->file_map.u.macho;
+
+ TRACE("(%p, %p/%d)\n", module, fmap, fmap->fd);
+
+ module->module.SymType = SymExport;
+
+ if (!(dbghelp_options & SYMOPT_PUBLICS_ONLY))
+ {
+ find_and_map_dsym(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))
+ ret = TRUE;
+ }
+
+ mdi.fmap = fmap;
+ 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);
+ if (result > 0)
+ ret = TRUE;
+ else if (result < 0)
+ WARN("Couldn't correctly read stabs\n");
+
+ if (!(dbghelp_options & SYMOPT_PUBLICS_ONLY) && fmap->dsym)
{
- fmap = &my_fmap;
- ret = macho_map_file(module->module.LoadedImageName, fmap);
+ mdi.fmap = &fmap->dsym->u.macho;
+ result = macho_enum_load_commands(mdi.fmap, LC_SYMTAB, macho_parse_symtab, &mdi);
+ if (result > 0)
+ ret = TRUE;
+ else if (result < 0)
+ WARN("Couldn't correctly read stabs\n");
}
- if (ret)
- ret = macho_load_debug_info_from_map(module, fmap);
- if (fmap == &my_fmap) macho_unmap_file(fmap);
+ macho_finish_stabs(module, &mdi.ht_symtab);
+
+ pool_destroy(&mdi.pool);
return ret;
}
BOOL macho_fetch_file_info(const WCHAR* name, DWORD_PTR* base,
DWORD* size, DWORD* checksum)
{
- struct macho_file_map fmap;
+ struct image_file_map fmap;
TRACE("(%s, %p, %p, %p)\n", debugstr_w(name), base, size, checksum);
if (!macho_map_file(name, &fmap)) return FALSE;
- if (base) *base = fmap.segs_start;
- *size = fmap.segs_size;
- *checksum = calc_crc32(fmap.fd);
+ if (base) *base = fmap.u.macho.segs_start;
+ *size = fmap.u.macho.segs_size;
+ *checksum = calc_crc32(fmap.u.macho.fd);
macho_unmap_file(&fmap);
return TRUE;
}
+/******************************************************************
+ * macho_module_remove
+ */
+static void macho_module_remove(struct process* pcs, struct module_format* modfmt)
+{
+ macho_unmap_file(&modfmt->u.macho_info->file_map);
+ HeapFree(GetProcessHeap(), 0, modfmt);
+}
+
/******************************************************************
* macho_load_file
*
unsigned long load_addr, struct macho_info* macho_info)
{
BOOL ret = TRUE;
- struct macho_file_map fmap;
+ struct image_file_map fmap;
TRACE("(%p/%p, %s, 0x%08lx, %p/0x%08x)\n", pcs, pcs->handle, debugstr_w(filename),
load_addr, macho_info, macho_info->flags);
if (ReadProcessMemory(pcs->handle, &pbi.PebBaseAddress->Reserved[0],
&dyld_image_info, sizeof(dyld_image_info), NULL))
{
- TRACE("got dyld_image_info 0x%08x from PEB %p MacDyldImageInfo %p\n",
- dyld_image_info, pbi.PebBaseAddress, &pbi.PebBaseAddress->Reserved);
+ TRACE("got dyld_image_info 0x%08lx from PEB %p MacDyldImageInfo %p\n",
+ (unsigned long)dyld_image_info, pbi.PebBaseAddress, &pbi.PebBaseAddress->Reserved);
macho_info->dbg_hdr_addr = dyld_image_info;
ret = TRUE;
}
HeapAlloc(GetProcessHeap(), 0, sizeof(struct module_format) + sizeof(struct macho_module_info));
if (!modfmt) goto leave;
if (!load_addr)
- load_addr = fmap.segs_start;
+ load_addr = fmap.u.macho.segs_start;
macho_info->module = module_new(pcs, filename, DMT_MACHO, FALSE, load_addr,
- fmap.segs_size, 0, calc_crc32(fmap.fd));
+ fmap.u.macho.segs_size, 0, calc_crc32(fmap.u.macho.fd));
if (!macho_info->module)
{
HeapFree(GetProcessHeap(), 0, modfmt);
goto leave;
}
+ macho_info->module->reloc_delta = macho_info->module->module.BaseOfImage - fmap.u.macho.segs_start;
macho_module_info = (void*)(modfmt + 1);
macho_info->module->format_info[DFI_MACHO] = modfmt;
modfmt->module = macho_info->module;
- modfmt->remove = NULL;
+ modfmt->remove = macho_module_remove;
modfmt->loc_compute = NULL;
modfmt->u.macho_info = macho_module_info;
macho_module_info->load_addr = load_addr;
+ macho_module_info->file_map = fmap;
+ 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, &fmap))
+ else if (!macho_load_debug_info(macho_info->module))
ret = FALSE;
macho_info->module->format_info[DFI_MACHO]->u.macho_info->in_use = 1;
#else /* HAVE_MACH_O_LOADER_H */
+BOOL macho_find_section(struct image_file_map* ifm, const char* segname, const char* sectname, struct image_section_map* ism)
+{
+ return FALSE;
+}
+
+const char* macho_map_section(struct image_section_map* ism)
+{
+ return NULL;
+}
+
+void macho_unmap_section(struct image_section_map* ism)
+{
+}
+
+DWORD_PTR macho_get_map_rva(const struct image_section_map* ism)
+{
+ return 0;
+}
+
+unsigned macho_get_map_size(const struct image_section_map* ism)
+{
+ return 0;
+}
+
BOOL macho_synchronize_module_list(struct process* pcs)
{
return FALSE;
return NULL;
}
-BOOL macho_load_debug_info(struct module* module, struct macho_file_map* fmap)
+BOOL macho_load_debug_info(struct module* module)
{
return FALSE;
}
break;
#ifndef DBGHELP_STATIC_LIB
case DMT_MACHO:
- ret = macho_load_debug_info(pair->effective, NULL);
+ ret = macho_load_debug_info(pair->effective);
break;
#endif
default:
WINE_DEFAULT_DEBUG_CHANNEL(dbghelp_msc);
-#define MAX_PATHNAME_LEN 1024
-
struct pdb_stream_name
{
const char* name;
case 0x1142:
case 0x1143:
case 0x1144:
+ case 0x114c:
+ case 0x114d:
+ case 0x114e:
+ case 0x1145:
+ case 0x115a:
+ case 0x1153:
TRACE("Unsupported symbol id %x\n", sym->generic.id);
break;
nth->OptionalHeader.DataDirectory[dirno].VirtualAddress, NULL);
}
-/******************************************************************
- * pe_unmap_directory
- *
- * Unmaps a directory content
- */
-void pe_unmap_directory(struct image_file_map* fmap, int dirno)
-{
- pe_unmap_full(fmap);
-}
-
static void pe_module_remove(struct process* pcs, struct module_format* modfmt)
{
pe_unmap_file(&modfmt->u.pe_info->fmap);
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)
case 35:
case 36: loc.reg = CV_REG_MM0 + stab_ptr->n_value - 29; break;
default:
- FIXME("Unknown register value (%u)\n", stab_ptr->n_value);
+ FIXME("Unknown register value (%lu)\n", (unsigned long)stab_ptr->n_value);
loc.reg = CV_REG_NONE;
break;
}
case N_EXCL:
if (stabs_add_include(stabs_find_include(ptr, stab_ptr->n_value)) < 0)
{
- ERR("Excluded header not found (%s,%d)\n", ptr, stab_ptr->n_value);
+ ERR("Excluded header not found (%s,%ld)\n", ptr, (unsigned long)stab_ptr->n_value);
module_reset_debug_info(module);
ret = FALSE;
goto done;
break;
}
stabbuff[0] = '\0';
- TRACE("0x%02x %x %s\n",
- stab_ptr->n_type, stab_ptr->n_value, debugstr_a(strs + stab_ptr->n_strx));
+ TRACE("0x%02x %lx %s\n",
+ stab_ptr->n_type, (unsigned long)stab_ptr->n_value, debugstr_a(strs + stab_ptr->n_strx));
}
module->module.SymType = SymDia;
module->module.CVSig = 'S' | ('T' << 8) | ('A' << 16) | ('B' << 24);
reactos/dll/win32/cryptdll # Synced to WineStaging-1.7.37
reactos/dll/win32/cryptnet # Synced to WineStaging-1.7.37
reactos/dll/win32/cryptui # Synced to WineStaging-1.7.37
-reactos/dll/win32/dbghelp # Synced to WineStaging-1.7.37
+reactos/dll/win32/dbghelp # Synced to WineStaging-1.7.47
reactos/dll/win32/dciman32 # Synced to WineStaging-1.7.37
reactos/dll/win32/dwmapi # Synced to WineStaging-1.7.37
reactos/dll/win32/faultrep # Synced to WineStaging-1.7.37