[DBGHELP] Sync with Wine Staging 1.7.47. CORE-9924
authorAmine Khaldi <amine.khaldi@reactos.org>
Wed, 22 Jul 2015 19:50:35 +0000 (19:50 +0000)
committerAmine Khaldi <amine.khaldi@reactos.org>
Wed, 22 Jul 2015 19:50:35 +0000 (19:50 +0000)
svn path=/trunk/; revision=68561

16 files changed:
reactos/dll/win32/dbghelp/coff.c
reactos/dll/win32/dbghelp/cpu_arm.c
reactos/dll/win32/dbghelp/cpu_arm64.c
reactos/dll/win32/dbghelp/cpu_i386.c
reactos/dll/win32/dbghelp/cpu_ppc.c
reactos/dll/win32/dbghelp/cpu_x86_64.c
reactos/dll/win32/dbghelp/dbghelp_private.h
reactos/dll/win32/dbghelp/dbghelp_ros.diff
reactos/dll/win32/dbghelp/dwarf.c
reactos/dll/win32/dbghelp/image_private.h
reactos/dll/win32/dbghelp/macho_module.c
reactos/dll/win32/dbghelp/module.c
reactos/dll/win32/dbghelp/msc.c
reactos/dll/win32/dbghelp/pe_module.c
reactos/dll/win32/dbghelp/stabs.c
reactos/media/doc/README.WINE

index 6ab0b67..a9d983e 100644 (file)
@@ -277,7 +277,6 @@ DECLSPEC_HIDDEN BOOL coff_process_info(const struct msc_debug_info* msc_dbg)
                                                msc_dbg->module->module.BaseOfImage + base + coff_sym->Value,
                                                0 /* FIXME */,
                                                NULL /* FIXME */)->symt);
-            i += naux;
             continue;
        }
 
@@ -358,7 +357,6 @@ DECLSPEC_HIDDEN BOOL coff_process_info(const struct msc_debug_info* msc_dbg)
              * Ignore these.  They don't have anything to do with
              * reality.
              */
-            i += naux;
             continue;
        }
 
index f58cf02..53fa7ee 100644 (file)
@@ -33,7 +33,7 @@ static BOOL arm_get_addr(HANDLE hThread, const CONTEXT* ctx,
 #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;
@@ -116,7 +116,7 @@ static BOOL arm_stack_walk(struct cpu_stack_walk* csw, LPSTACKFRAME64 frame, CON
     /* 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;
@@ -144,7 +144,7 @@ static BOOL arm_stack_walk(struct cpu_stack_walk* csw, LPSTACKFRAME64 frame, CON
 }
 #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;
@@ -169,8 +169,8 @@ static void* arm_fetch_context_reg(CONTEXT* ctx, unsigned regno, unsigned* size)
     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;
index 8a8511a..68cff95 100644 (file)
@@ -33,7 +33,7 @@ static BOOL arm64_get_addr(HANDLE hThread, const CONTEXT* ctx,
 #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;
@@ -61,7 +61,7 @@ static BOOL fetch_next_frame(struct cpu_stack_walk* csw,
                                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))
     {
@@ -70,7 +70,7 @@ static BOOL fetch_next_frame(struct cpu_stack_walk* csw,
         return TRUE;
     }
 
-    if (context->Pc == context->X30) return FALSE;
+    if (context->Pc == context->Lr) return FALSE;
     context->Pc = oldReturn;
 
     return TRUE;
@@ -115,8 +115,8 @@ static BOOL arm64_stack_walk(struct cpu_stack_walk* csw, LPSTACKFRAME64 frame, C
 
     /* 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;
@@ -128,7 +128,7 @@ static BOOL arm64_stack_walk(struct cpu_stack_walk* csw, LPSTACKFRAME64 frame, C
           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);
 
@@ -144,9 +144,11 @@ static BOOL arm64_stack_walk(struct cpu_stack_walk* csw, LPSTACKFRAME64 frame, C
 }
 #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);
@@ -158,7 +160,7 @@ static void* arm64_fetch_context_reg(CONTEXT* ctx, unsigned regno, unsigned* siz
 #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;
@@ -188,12 +190,11 @@ static void* arm64_fetch_context_reg(CONTEXT* ctx, unsigned regno, unsigned* siz
     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);
@@ -204,6 +205,7 @@ static const char* arm64_fetch_regname(unsigned 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";
@@ -233,12 +235,11 @@ static const char* arm64_fetch_regname(unsigned regno)
     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;
@@ -269,7 +270,7 @@ static BOOL arm64_fetch_minidump_module(struct dump_context* dc, unsigned index,
 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,
index 5916d21..64f8baa 100644 (file)
@@ -26,7 +26,6 @@
 
 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)
@@ -517,7 +516,7 @@ done_err:
 }
 #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;
 
@@ -527,8 +526,17 @@ static unsigned i386_map_dwarf_register(unsigned regno)
     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;
index 7090847..6c38245 100644 (file)
@@ -48,7 +48,7 @@ static BOOL ppc_stack_walk(struct cpu_stack_walk* csw, LPSTACKFRAME64 frame, CON
     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;
index 26b5c21..5beb6df 100644 (file)
@@ -45,7 +45,7 @@ typedef union _UNWIND_CODE
         BYTE CodeOffset;
         BYTE UnwindOp : 4;
         BYTE OpInfo   : 4;
-    };
+    } u;
     USHORT FrameOffset;
 } UNWIND_CODE, *PUNWIND_CODE;
 
@@ -84,6 +84,8 @@ static BOOL x86_64_get_addr(HANDLE hThread, const CONTEXT* ctx,
     }
 }
 
+#ifdef __x86_64__
+
 enum st_mode {stm_start, stm_64bit, stm_done};
 
 /* indexes in Reserved array */
@@ -95,7 +97,6 @@ enum st_mode {stm_start, stm_64bit, stm_done};
 #define curr_count  (frame->Reserved[__CurrentCount])
 /* #define ??? (frame->Reserved[__]) (unused) */
 
-#ifdef __x86_64__
 union handler_data
 {
     RUNTIME_FUNCTION chain;
@@ -149,14 +150,14 @@ static void dump_unwind_info(struct cpu_stack_walk* csw, ULONG64 base, RUNTIME_F
 
         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;
@@ -169,7 +170,7 @@ static void dump_unwind_info(struct cpu_stack_walk* csw, ULONG64 base, RUNTIME_F
                 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:
@@ -178,29 +179,29 @@ static void dump_unwind_info(struct cpu_stack_walk* csw, ULONG64 base, RUNTIME_F
                 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;
             }
         }
@@ -252,10 +253,10 @@ static void set_float_reg(CONTEXT *context, int reg, M128A val)
 
 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;
@@ -504,21 +505,21 @@ static BOOL interpret_function_table_entry(struct cpu_stack_walk* csw,
 
         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;
@@ -526,28 +527,28 @@ static BOOL interpret_function_table_entry(struct cpu_stack_walk* csw,
             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;
             }
         }
@@ -711,7 +712,7 @@ static void*    x86_64_find_runtime_function(struct module* module, DWORD64 addr
     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;
 
index b7ab2b1..cf6c783 100644 (file)
@@ -581,7 +581,7 @@ struct cpu
     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);
@@ -620,18 +620,16 @@ struct elf_thunk_area;
 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;
@@ -697,7 +695,6 @@ extern struct module*
 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;
index b9095cd..b1cc199 100644 (file)
@@ -1,44 +1,24 @@
-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;
  }
@@ -49,7 +29,7 @@ diff -prudN e:\Wine\dlls\dbghelp/cpu_i386.c e:\reactos\dll\win32\dbghelp/cpu_i38
  /* 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;
  
@@ -59,7 +39,7 @@ diff -prudN e:\Wine\dlls\dbghelp/cpu_i386.c e:\reactos\dll\win32\dbghelp/cpu_i38
      {
          /* 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)
  
@@ -67,15 +47,15 @@ diff -prudN e:\Wine\dlls\dbghelp/cpu_i386.c e:\reactos\dll\win32\dbghelp/cpu_i38
  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;
  }
  
@@ -83,7 +63,7 @@ diff -prudN e:\Wine\dlls\dbghelp/cpu_i386.c e:\reactos\dll\win32\dbghelp/cpu_i38
  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;
  }
@@ -91,7 +71,7 @@ diff -prudN e:\Wine\dlls\dbghelp/cpu_i386.c e:\reactos\dll\win32\dbghelp/cpu_i38
  
  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,
@@ -114,10 +94,10 @@ diff -prudN e:\Wine\dlls\dbghelp/cpu_i386.c e:\reactos\dll\win32\dbghelp/cpu_i38
 +    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;
@@ -129,7 +109,7 @@ diff -prudN e:\Wine\dlls\dbghelp/cpu_x86_64.c e:\reactos\dll\win32\dbghelp/cpu_x
              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 */
@@ -137,7 +117,7 @@ diff -prudN e:\Wine\dlls\dbghelp/cpu_x86_64.c e:\reactos\dll\win32\dbghelp/cpu_x
              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 */
@@ -145,26 +125,10 @@ diff -prudN e:\Wine\dlls\dbghelp/cpu_x86_64.c e:\reactos\dll\win32\dbghelp/cpu_x
              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;
  }
  
@@ -172,7 +136,7 @@ diff -prudN e:\Wine\dlls\dbghelp/dbghelp.c e:\reactos\dll\win32\dbghelp/dbghelp.
  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";
      }
  }
@@ -192,7 +156,7 @@ diff -prudN e:\Wine\dlls\dbghelp/dbghelp.c e:\reactos\dll\win32\dbghelp/dbghelp.
      &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;
@@ -203,7 +167,7 @@ diff -prudN e:\Wine\dlls\dbghelp/dbghelp.c e:\reactos\dll\win32\dbghelp/dbghelp.
      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;
@@ -213,7 +177,7 @@ diff -prudN e:\Wine\dlls\dbghelp/dbghelp.c e:\reactos\dll\win32\dbghelp/dbghelp.
      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;
      }
@@ -221,67 +185,26 @@ diff -prudN e:\Wine\dlls\dbghelp/dbghelp.c e:\reactos\dll\win32\dbghelp/dbghelp.
  
      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;
@@ -291,7 +214,7 @@ diff -prudN e:\Wine\dlls\dbghelp/dbghelp_private.h e:\reactos\dll\win32\dbghelp/
  
      /* 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 */
@@ -301,71 +224,18 @@ diff -prudN e:\Wine\dlls\dbghelp/dbghelp_private.h e:\reactos\dll\win32\dbghelp/
  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
       */
@@ -376,10 +246,28 @@ diff -prudN e:\Wine\dlls\dbghelp/dwarf.c e:\reactos-dwarf\dll\win32\dbghelp/dwar
      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
@@ -395,11 +283,10 @@ diff -prudN e:\Wine\dlls\dbghelp/dwarf.h e:\reactos\dll\win32\dbghelp/dwarf.h
 +        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)
  
@@ -408,7 +295,7 @@ diff -prudN e:\Wine\dlls\dbghelp/image_private.h e:\reactos\dll\win32\dbghelp/im
  
  #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;
@@ -417,88 +304,65 @@ diff -prudN e:\Wine\dlls\dbghelp/image_private.h e:\reactos\dll\win32\dbghelp/im
              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);
@@ -508,7 +372,7 @@ diff -prudN e:\Wine\dlls\dbghelp/module.c e:\reactos\dll\win32\dbghelp/module.c
      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)
          {
@@ -520,19 +384,19 @@ diff -prudN e:\Wine\dlls\dbghelp/module.c e:\reactos\dll\win32\dbghelp/module.c
          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
   */
@@ -546,7 +410,7 @@ diff -prudN e:\Wine\dlls\dbghelp/module.c e:\reactos\dll\win32\dbghelp/module.c
  
  /***********************************************************************
   *                    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));
  
@@ -556,7 +420,7 @@ diff -prudN e:\Wine\dlls\dbghelp/module.c e:\reactos\dll\win32\dbghelp/module.c
  
      /* 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 */
@@ -564,7 +428,7 @@ diff -prudN e:\Wine\dlls\dbghelp/module.c e:\reactos\dll\win32\dbghelp/module.c
              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;
              }
@@ -572,7 +436,7 @@ diff -prudN e:\Wine\dlls\dbghelp/module.c e:\reactos\dll\win32\dbghelp/module.c
          }
      }
      if (!module)
-@@ -819,6 +835,7 @@ BOOL  WINAPI SymEnumerateModulesW64(HAND
+@@ -830,6 +836,7 @@ BOOL  WINAPI SymEnumerateModulesW64(HAND
      return TRUE;
  }
  
@@ -580,7 +444,7 @@ diff -prudN e:\Wine\dlls\dbghelp/module.c e:\reactos\dll\win32\dbghelp/module.c
  /******************************************************************
   *            EnumerateLoadedModules64 (DBGHELP.@)
   *
-@@ -919,6 +936,7 @@ BOOL  WINAPI EnumerateLoadedModulesW64(H
+@@ -930,6 +937,7 @@ BOOL  WINAPI EnumerateLoadedModulesW64(H
  
      return sz != 0 && i == sz;
  }
@@ -588,7 +452,7 @@ diff -prudN e:\Wine\dlls\dbghelp/module.c e:\reactos\dll\win32\dbghelp/module.c
  
  /******************************************************************
   *            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;
  
@@ -600,22 +464,10 @@ diff -prudN e:\Wine\dlls\dbghelp/module.c e:\reactos\dll\win32\dbghelp/module.c
  }
  
  /***********************************************************************
-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;
  }
  
@@ -623,7 +475,7 @@ diff -prudN e:\Wine\dlls\dbghelp/pe_module.c e:\reactos\dll\win32\dbghelp/pe_mod
  /******************************************************************
   *            pe_load_dbg_file
   *
-@@ -625,6 +628,7 @@ done:
+@@ -615,6 +605,7 @@ done:
      pe_unmap_full(fmap);
      return ret;
  }
@@ -631,7 +483,7 @@ diff -prudN e:\Wine\dlls\dbghelp/pe_module.c e:\reactos\dll\win32\dbghelp/pe_mod
  
  /***********************************************************************
   *                    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;
@@ -641,131 +493,10 @@ diff -prudN e:\Wine\dlls\dbghelp/pe_module.c e:\reactos\dll\win32\dbghelp/pe_mod
          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)
  {
@@ -812,7 +543,7 @@ diff -prudN e:\Wine\dlls\dbghelp/symbol.c e:\reactos-dwarf\dll\win32\dbghelp/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)
  {
@@ -821,20 +552,3 @@ diff -prudN e:\Wine\dlls\dbghelp/symbol.c e:\reactos-dwarf\dll\win32\dbghelp/sym
      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);
index 8a92557..eceabc1 100644 (file)
@@ -617,7 +617,7 @@ static unsigned dwarf2_map_register(int regno)
         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
@@ -2609,7 +2609,7 @@ static BOOL parse_cie_details(dwarf2_traverse_context_t* ctx, struct frame_info*
 
     /* 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;
@@ -2619,7 +2619,10 @@ static BOOL parse_cie_details(dwarf2_traverse_context_t* ctx, struct frame_info*
 
     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;
@@ -2761,7 +2764,7 @@ static void execute_cfa_instructions(dwarf2_traverse_context_t* ctx,
                 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;
@@ -2773,7 +2776,7 @@ static void execute_cfa_instructions(dwarf2_traverse_context_t* ctx,
                 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;
             }
@@ -2820,7 +2823,7 @@ static void execute_cfa_instructions(dwarf2_traverse_context_t* ctx,
             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;
@@ -2832,7 +2835,7 @@ static void execute_cfa_instructions(dwarf2_traverse_context_t* ctx,
             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;
         }
@@ -2842,7 +2845,7 @@ static void execute_cfa_instructions(dwarf2_traverse_context_t* ctx,
             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;
         }
@@ -2852,7 +2855,7 @@ static void execute_cfa_instructions(dwarf2_traverse_context_t* ctx,
             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;
@@ -2864,8 +2867,8 @@ static void execute_cfa_instructions(dwarf2_traverse_context_t* ctx,
             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;
@@ -2893,7 +2896,7 @@ static void execute_cfa_instructions(dwarf2_traverse_context_t* ctx,
             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;
@@ -2906,7 +2909,7 @@ static void execute_cfa_instructions(dwarf2_traverse_context_t* ctx,
             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;
@@ -2940,7 +2943,7 @@ static void execute_cfa_instructions(dwarf2_traverse_context_t* ctx,
             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;
@@ -2965,7 +2968,7 @@ static void execute_cfa_instructions(dwarf2_traverse_context_t* ctx,
 /* 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))
@@ -2980,7 +2983,7 @@ static ULONG_PTR get_context_reg(CONTEXT *context, ULONG_PTR dw_reg)
 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)
@@ -3013,8 +3016,8 @@ static void set_context_reg(struct cpu_stack_walk* csw, CONTEXT *context, ULONG_
 /* 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);
 
@@ -3235,7 +3238,7 @@ BOOL dwarf2_virtual_unwind(struct cpu_stack_walk* csw, ULONG_PTR ip, CONTEXT* co
 
     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;
@@ -3251,6 +3254,10 @@ BOOL dwarf2_virtual_unwind(struct cpu_stack_walk* csw, ULONG_PTR ip, CONTEXT* co
     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;
index 5af8358..86a277c 100644 (file)
 #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)
 
@@ -96,6 +107,30 @@ struct image_file_map
             }*                          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;
@@ -125,6 +160,13 @@ extern void         elf_unmap_section(struct image_section_map* ism) DECLSPEC_HI
 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;
@@ -138,9 +180,10 @@ static inline BOOL image_find_section(struct image_file_map* fmap, const char* n
     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;
     }
 }
@@ -151,9 +194,10 @@ static inline const char* image_map_section(struct image_section_map* ism)
     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;
     }
 }
@@ -164,9 +208,10 @@ static inline void image_unmap_section(struct image_section_map* ism)
     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;
     }
 }
@@ -177,9 +222,10 @@ static inline DWORD_PTR image_get_map_rva(const struct image_section_map* ism)
     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;
     }
 }
@@ -190,9 +236,10 @@ static inline unsigned image_get_map_size(const struct image_section_map* ism)
     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;
     }
 }
index bfff27e..ac70af4 100644 (file)
@@ -60,8 +60,29 @@ struct dyld_all_image_infos {
 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;
@@ -79,36 +100,15 @@ struct macho_info
     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
@@ -118,13 +118,13 @@ static void macho_unmap_file(struct macho_file_map* fmap);
  * 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;
@@ -141,21 +141,24 @@ static void macho_calc_range(const struct macho_file_map* fmap, unsigned offset,
  *
  * 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;
 }
 
@@ -164,24 +167,30 @@ static const char* macho_map_range(const struct macho_file_map* fmap, unsigned o
  *
  * 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;
     }
 }
 
@@ -193,14 +202,14 @@ static void macho_unmap_range(const void** mapped, const struct macho_file_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);
@@ -208,33 +217,33 @@ static BOOL macho_map_ranges(const struct macho_file_map* fmap,
 
     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);
 }
 
 /******************************************************************
@@ -245,14 +254,14 @@ static BOOL macho_map_ranges(const struct macho_file_map* fmap,
  * 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);
@@ -260,24 +269,112 @@ static void macho_unmap_ranges(const struct macho_file_map* fmap,
 
     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
  *
@@ -285,10 +382,10 @@ static void macho_unmap_ranges(const struct macho_file_map* fmap,
  */
 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);
     }
 
@@ -302,10 +399,10 @@ static const struct load_command* macho_map_load_commands(struct macho_file_map*
  */
 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);
     }
 }
@@ -341,7 +438,7 @@ static int macho_enum_load_commands(struct macho_file_map* fmap, unsigned cmd,
 
     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);
 
@@ -361,47 +458,95 @@ static int macho_enum_load_commands(struct macho_file_map* fmap, unsigned cmd,
 }
 
 /******************************************************************
- *              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 = &section[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;
 }
 
 /******************************************************************
@@ -409,8 +554,9 @@ static int macho_accum_segs_range(struct macho_file_map* fmap,
  *
  * 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;
@@ -420,9 +566,14 @@ static BOOL macho_map_file(const WCHAR* filenameW, struct macho_file_map* fmap)
 
     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)))
@@ -462,20 +613,18 @@ static BOOL macho_map_file(const WCHAR* filenameW, struct macho_file_map* fmap)
             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");
     }
 
@@ -485,8 +634,8 @@ static BOOL macho_map_file(const WCHAR* filenameW, struct macho_file_map* fmap)
         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)
     {
@@ -494,26 +643,50 @@ static BOOL macho_map_file(const WCHAR* filenameW, struct macho_file_map* fmap)
         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;
 }
@@ -523,51 +696,36 @@ done:
  *
  * 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;
 }
 
 /******************************************************************
@@ -579,17 +737,19 @@ static int macho_fill_sect_is_code(struct macho_file_map* fmap,
  */
 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
@@ -652,24 +812,24 @@ static int macho_parse_symtab(struct macho_file_map* fmap,
 {
     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;
@@ -846,39 +1006,125 @@ static void macho_finish_stabs(struct module* module, struct hash_table* ht_symt
 }
 
 /******************************************************************
- *              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);
 }
 
 /******************************************************************
@@ -886,12 +1132,12 @@ static BOOL macho_load_debug_info_from_map(struct module* module,
  *
  * 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)
     {
@@ -899,15 +1145,44 @@ BOOL macho_load_debug_info(struct module* module, struct macho_file_map* fmap)
         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;
 }
 
@@ -919,18 +1194,27 @@ BOOL macho_load_debug_info(struct module* module, struct macho_file_map* fmap)
 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
  *
@@ -945,7 +1229,7 @@ static BOOL macho_load_file(struct process* pcs, const WCHAR* filename,
                             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);
@@ -972,8 +1256,8 @@ static BOOL macho_load_file(struct process* pcs, const WCHAR* filename,
             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;
             }
@@ -1013,27 +1297,30 @@ static BOOL macho_load_file(struct process* pcs, const WCHAR* filename,
             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;
@@ -1439,6 +1726,30 @@ struct module*  macho_load_module(struct process* pcs, const WCHAR* name, unsign
 
 #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;
@@ -1465,7 +1776,7 @@ struct module*  macho_load_module(struct process* pcs, const WCHAR* name, unsign
     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;
 }
index dc6bc17..ff67f69 100644 (file)
@@ -365,7 +365,7 @@ BOOL module_get_debug(struct module_pair* pair)
             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:
index d86ecea..31e8b44 100644 (file)
@@ -38,8 +38,6 @@
 
 WINE_DEFAULT_DEBUG_CHANNEL(dbghelp_msc);
 
-#define MAX_PATHNAME_LEN 1024
-
 struct pdb_stream_name
 {
     const char* name;
@@ -1974,6 +1972,12 @@ static BOOL codeview_snarf(const struct msc_debug_info* msc_dbg, const BYTE* roo
         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;
 
index 399185c..5e09f97 100644 (file)
@@ -311,16 +311,6 @@ const char* pe_map_directory(struct module* module, int dirno, DWORD* size)
                            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);
index 065556c..faa9f47 100644 (file)
@@ -88,7 +88,11 @@ 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)
@@ -1442,7 +1446,7 @@ BOOL stabs_parse(struct module* module, unsigned long load_offset,
                 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;
                 }
@@ -1592,7 +1596,7 @@ BOOL stabs_parse(struct module* module, unsigned long load_offset,
        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;
@@ -1638,8 +1642,8 @@ BOOL stabs_parse(struct module* module, unsigned long load_offset,
             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);
index fceebb1..f62fb1a 100644 (file)
@@ -64,7 +64,7 @@ reactos/dll/win32/cryptdlg            # Synced to WineStaging-1.7.37
 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