Wine-Devel
By thread
wine-devel@list.winehq.org
By month
Messages by month
- ----- 2026 -----
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2025 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2024 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2023 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2022 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2021 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2020 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2019 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2018 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2017 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2016 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2015 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2014 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2013 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2012 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2011 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2010 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2009 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2008 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2007 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2006 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2005 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2004 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2003 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2002 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2001 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
July 2018
- 74 participants
- 1144 messages
[PATCH 1/6] dbghelp: Use WOW64_CONTEXT instead of CONTEXT for i386 backend.
by Zebediah Figura
Signed-off-by: Zebediah Figura <z.figura12(a)gmail.com>
---
dlls/dbghelp/cpu_arm.c | 29 ++++++++++--------
dlls/dbghelp/cpu_arm64.c | 28 ++++++++++--------
dlls/dbghelp/cpu_i386.c | 67 +++++++++++++++++++-----------------------
dlls/dbghelp/cpu_ppc.c | 5 ++--
dlls/dbghelp/cpu_x86_64.c | 29 ++++++++++--------
dlls/dbghelp/dbghelp_private.h | 19 ++++++++----
dlls/dbghelp/dwarf.c | 18 +++++++-----
dlls/dbghelp/msc.c | 4 +--
8 files changed, 109 insertions(+), 90 deletions(-)
diff --git a/dlls/dbghelp/cpu_arm.c b/dlls/dbghelp/cpu_arm.c
index d741bc5..15091d3 100644
--- a/dlls/dbghelp/cpu_arm.c
+++ b/dlls/dbghelp/cpu_arm.c
@@ -63,13 +63,14 @@ enum st_mode {stm_start, stm_arm, stm_done};
* modify (at least) context.Pc using unwind information
* either out of debug info (dwarf), or simple Lr trace
*/
-static BOOL fetch_next_frame(struct cpu_stack_walk* csw,
- CONTEXT* context, DWORD_PTR curr_pc)
+static BOOL fetch_next_frame(struct cpu_stack_walk* csw, union ctx *pcontext,
+ DWORD_PTR curr_pc)
{
DWORD_PTR xframe;
DWORD oldReturn = context->Lr;
+ CONTEXT *context = &pcontext->ctx;
- if (dwarf2_virtual_unwind(csw, curr_pc, context, &xframe))
+ if (dwarf2_virtual_unwind(csw, curr_pc, pcontext, &xframe))
{
context->Sp = xframe;
context->Pc = oldReturn;
@@ -82,7 +83,8 @@ static BOOL fetch_next_frame(struct cpu_stack_walk* csw,
return TRUE;
}
-static BOOL arm_stack_walk(struct cpu_stack_walk* csw, LPSTACKFRAME64 frame, CONTEXT* context)
+static BOOL arm_stack_walk(struct cpu_stack_walk *csw, STACKFRAME64 *frame,
+ union ctx *context);
{
unsigned deltapc = curr_count <= 1 ? 0 : 4;
@@ -109,8 +111,8 @@ static BOOL arm_stack_walk(struct cpu_stack_walk* csw, LPSTACKFRAME64 frame, CON
}
else
{
- if (context->Sp != frame->AddrStack.Offset) FIXME("inconsistent Stack Pointer\n");
- if (context->Pc != frame->AddrPC.Offset) FIXME("inconsistent Program Counter\n");
+ if (context->ctx.Sp != frame->AddrStack.Offset) FIXME("inconsistent Stack Pointer\n");
+ if (context->ctx.Pc != frame->AddrPC.Offset) FIXME("inconsistent Program Counter\n");
if (frame->AddrReturn.Offset == 0) goto done_err;
if (!fetch_next_frame(csw, context, frame->AddrPC.Offset - deltapc))
@@ -120,10 +122,10 @@ static BOOL arm_stack_walk(struct cpu_stack_walk* csw, LPSTACKFRAME64 frame, CON
memset(&frame->Params, 0, sizeof(frame->Params));
/* set frame information */
- frame->AddrStack.Offset = context->Sp;
- frame->AddrReturn.Offset = context->Lr;
- frame->AddrFrame.Offset = context->R11;
- frame->AddrPC.Offset = context->Pc;
+ frame->AddrStack.Offset = context->ctx.Sp;
+ frame->AddrReturn.Offset = context->ctx.Lr;
+ frame->AddrFrame.Offset = context->ctx.R11;
+ frame->AddrPC.Offset = context->ctx.Pc;
frame->Far = TRUE;
frame->Virtual = TRUE;
@@ -144,7 +146,8 @@ done_err:
return FALSE;
}
#else
-static BOOL arm_stack_walk(struct cpu_stack_walk* csw, LPSTACKFRAME64 frame, CONTEXT* context)
+static BOOL arm_stack_walk(struct cpu_stack_walk *csw, STACKFRAME64 *frame,
+ union ctx *context)
{
return FALSE;
}
@@ -159,9 +162,11 @@ static unsigned arm_map_dwarf_register(unsigned regno, BOOL eh_frame)
return CV_ARM_NOREG;
}
-static void* arm_fetch_context_reg(CONTEXT* ctx, unsigned regno, unsigned* size)
+static void *arm_fetch_context_reg(union ctx *pctx, unsigned regno, unsigned *size)
{
#ifdef __arm__
+ CONTEXT *ctx = &pctx->ctx;
+
switch (regno)
{
case CV_ARM_R0 + 0: *size = sizeof(ctx->R0); return &ctx->R0;
diff --git a/dlls/dbghelp/cpu_arm64.c b/dlls/dbghelp/cpu_arm64.c
index f50b325..6cabc5b 100644
--- a/dlls/dbghelp/cpu_arm64.c
+++ b/dlls/dbghelp/cpu_arm64.c
@@ -65,13 +65,13 @@ enum st_mode {stm_start, stm_arm64, stm_done};
* modify (at least) context.Pc using unwind information
* either out of debug info (dwarf), or simple Lr trace
*/
-static BOOL fetch_next_frame(struct cpu_stack_walk* csw,
- CONTEXT* context, DWORD_PTR curr_pc)
+static BOOL fetch_next_frame(struct cpu_stack_walk* csw, union ctx *pcontext,
+ DWORD_PTR curr_pc)
{
DWORD_PTR xframe;
DWORD_PTR oldReturn = context->u.s.Lr;
- if (dwarf2_virtual_unwind(csw, curr_pc, context, &xframe))
+ if (dwarf2_virtual_unwind(csw, curr_pc, pcontext, &xframe))
{
context->Sp = xframe;
context->Pc = oldReturn;
@@ -84,7 +84,8 @@ static BOOL fetch_next_frame(struct cpu_stack_walk* csw,
return TRUE;
}
-static BOOL arm64_stack_walk(struct cpu_stack_walk* csw, LPSTACKFRAME64 frame, CONTEXT* context)
+static BOOL arm64_stack_walk(struct cpu_stack_walk *csw, STACKFRAME64 *frame,
+ union ctx *context)
{
unsigned deltapc = curr_count <= 1 ? 0 : 4;
@@ -111,8 +112,8 @@ static BOOL arm64_stack_walk(struct cpu_stack_walk* csw, LPSTACKFRAME64 frame, C
}
else
{
- if (context->Sp != frame->AddrStack.Offset) FIXME("inconsistent Stack Pointer\n");
- if (context->Pc != frame->AddrPC.Offset) FIXME("inconsistent Program Counter\n");
+ if (context->ctx.Sp != frame->AddrStack.Offset) FIXME("inconsistent Stack Pointer\n");
+ if (context->ctx.Pc != frame->AddrPC.Offset) FIXME("inconsistent Program Counter\n");
if (frame->AddrReturn.Offset == 0) goto done_err;
if (!fetch_next_frame(csw, context, frame->AddrPC.Offset - deltapc))
@@ -122,10 +123,10 @@ static BOOL arm64_stack_walk(struct cpu_stack_walk* csw, LPSTACKFRAME64 frame, C
memset(&frame->Params, 0, sizeof(frame->Params));
/* set frame information */
- frame->AddrStack.Offset = context->Sp;
- frame->AddrReturn.Offset = context->u.s.Lr;
- frame->AddrFrame.Offset = context->u.s.Fp;
- frame->AddrPC.Offset = context->Pc;
+ frame->AddrStack.Offset = context->ctx.Sp;
+ frame->AddrReturn.Offset = context->ctx.u.s.Lr;
+ frame->AddrFrame.Offset = context->ctx.u.s.Fp;
+ frame->AddrPC.Offset = context->ctx.Pc;
frame->Far = TRUE;
frame->Virtual = TRUE;
@@ -146,7 +147,8 @@ done_err:
return FALSE;
}
#else
-static BOOL arm64_stack_walk(struct cpu_stack_walk* csw, LPSTACKFRAME64 frame, CONTEXT* context)
+static BOOL arm64_stack_walk(struct cpu_stack_walk* csw, STACKFRAME64 *frame,
+ union ctx *ctx)
{
return FALSE;
}
@@ -164,9 +166,11 @@ static unsigned arm64_map_dwarf_register(unsigned regno, BOOL eh_frame)
return CV_ARM64_NOREG;
}
-static void* arm64_fetch_context_reg(CONTEXT* ctx, unsigned regno, unsigned* size)
+static void *arm64_fetch_context_reg(union ctx *pctx, unsigned regno, unsigned *size)
{
#ifdef __aarch64__
+ CONTEXT *ctx = pctx;
+
switch (regno)
{
case CV_ARM64_X0 + 0:
diff --git a/dlls/dbghelp/cpu_i386.c b/dlls/dbghelp/cpu_i386.c
index 9e207bb..4880fd4 100644
--- a/dlls/dbghelp/cpu_i386.c
+++ b/dlls/dbghelp/cpu_i386.c
@@ -86,20 +86,20 @@ static BOOL i386_get_addr(HANDLE hThread, const CONTEXT* ctx,
return FALSE;
}
-#ifdef __i386__
/* fetch_next_frame32()
*
* modify (at least) context.{eip, esp, ebp} using unwind information
* either out of debug info (dwarf, pdb), or simple stack unwind
*/
static BOOL fetch_next_frame32(struct cpu_stack_walk* csw,
- CONTEXT* context, DWORD_PTR curr_pc)
+ union ctx *pcontext, DWORD_PTR curr_pc)
{
DWORD_PTR xframe;
struct pdb_cmd_pair cpair[4];
DWORD val32;
+ WOW64_CONTEXT *context = &pcontext->x86;
- if (dwarf2_virtual_unwind(csw, curr_pc, context, &xframe))
+ if (dwarf2_virtual_unwind(csw, curr_pc, pcontext, &xframe))
{
context->Esp = xframe;
return TRUE;
@@ -109,7 +109,7 @@ static BOOL fetch_next_frame32(struct cpu_stack_walk* csw,
cpair[2].name = "$eip"; cpair[2].pvalue = &context->Eip;
cpair[3].name = NULL; cpair[3].pvalue = NULL;
- if (!pdb_virtual_unwind(csw, curr_pc, context, cpair))
+ if (!pdb_virtual_unwind(csw, curr_pc, pcontext, cpair))
{
/* do a simple unwind using ebp
* we assume a "regular" prologue in the function has been used
@@ -130,7 +130,6 @@ static BOOL fetch_next_frame32(struct cpu_stack_walk* csw,
}
return TRUE;
}
-#endif
enum st_mode {stm_start, stm_32bit, stm_16bit, stm_done};
@@ -147,7 +146,8 @@ enum st_mode {stm_start, stm_32bit, stm_16bit, stm_done};
#define set_curr_mode(m) {frame->Reserved[__CurrentModeCount] &= ~0x0F; frame->Reserved[__CurrentModeCount] |= (m & 0x0F);}
#define inc_curr_count() (frame->Reserved[__CurrentModeCount] += 0x10)
-static BOOL i386_stack_walk(struct cpu_stack_walk* csw, LPSTACKFRAME64 frame, CONTEXT* context)
+static BOOL i386_stack_walk(struct cpu_stack_walk *csw, STACKFRAME64 *frame,
+ union ctx *context)
{
STACK32FRAME frame32;
STACK16FRAME frame16;
@@ -157,10 +157,8 @@ static BOOL i386_stack_walk(struct cpu_stack_walk* csw, LPSTACKFRAME64 frame, CO
WORD val16;
DWORD val32;
BOOL do_switch;
-#ifdef __i386__
unsigned deltapc;
- CONTEXT _context;
-#endif
+ union ctx _context;
/* sanity check */
if (curr_mode >= stm_done) return FALSE;
@@ -174,7 +172,6 @@ static BOOL i386_stack_walk(struct cpu_stack_walk* csw, LPSTACKFRAME64 frame, CO
wine_dbgstr_longlong(curr_count),
(void*)(DWORD_PTR)curr_switch, (void*)(DWORD_PTR)next_switch);
-#ifdef __i386__
/* if we're at first call (which doesn't actually unwind, it just computes ReturnPC,
* or if we're doing the first real unwind (count == 1), then we can directly use
* eip. otherwise, eip is *after* the insn that actually made the call to
@@ -190,15 +187,18 @@ static BOOL i386_stack_walk(struct cpu_stack_walk* csw, LPSTACKFRAME64 frame, CO
/* setup a pseudo context for the rest of the code (esp. unwinding) */
context = &_context;
memset(context, 0, sizeof(*context));
- context->ContextFlags = CONTEXT_CONTROL | CONTEXT_SEGMENTS;
- if (frame->AddrPC.Mode != AddrModeFlat) context->SegCs = frame->AddrPC.Segment;
- context->Eip = frame->AddrPC.Offset;
- if (frame->AddrFrame.Mode != AddrModeFlat) context->SegSs = frame->AddrFrame.Segment;
- context->Ebp = frame->AddrFrame.Offset;
- if (frame->AddrStack.Mode != AddrModeFlat) context->SegSs = frame->AddrStack.Segment;
- context->Esp = frame->AddrStack.Offset;
+ context->x86.ContextFlags = WOW64_CONTEXT_CONTROL | WOW64_CONTEXT_SEGMENTS;
+ if (frame->AddrPC.Mode != AddrModeFlat)
+ context->x86.SegCs = frame->AddrPC.Segment;
+ context->x86.Eip = frame->AddrPC.Offset;
+ if (frame->AddrFrame.Mode != AddrModeFlat)
+ context->x86.SegSs = frame->AddrFrame.Segment;
+ context->x86.Ebp = frame->AddrFrame.Offset;
+ if (frame->AddrStack.Mode != AddrModeFlat)
+ context->x86.SegSs = frame->AddrStack.Segment;
+ context->x86.Esp = frame->AddrStack.Offset;
}
-#endif
+
if (curr_mode == stm_start)
{
THREAD_BASIC_INFORMATION info;
@@ -396,18 +396,16 @@ static BOOL i386_stack_walk(struct cpu_stack_walk* csw, LPSTACKFRAME64 frame, CO
}
else
{
-#ifdef __i386__
if (!fetch_next_frame32(csw, context, sw_xlat_addr(csw, &frame->AddrPC) - deltapc))
goto done_err;
frame->AddrStack.Mode = frame->AddrFrame.Mode = frame->AddrPC.Mode = AddrModeFlat;
- frame->AddrStack.Offset = context->Esp;
- frame->AddrFrame.Offset = context->Ebp;
- if (frame->AddrReturn.Offset != context->Eip)
+ frame->AddrStack.Offset = context->x86.Esp;
+ frame->AddrFrame.Offset = context->x86.Ebp;
+ if (frame->AddrReturn.Offset != context->x86.Eip)
FIXME("new PC=%s different from Eip=%x\n",
- wine_dbgstr_longlong(frame->AddrReturn.Offset), context->Eip);
- frame->AddrPC.Offset = context->Eip;
-#endif
+ wine_dbgstr_longlong(frame->AddrReturn.Offset), context->x86.Eip);
+ frame->AddrPC.Offset = context->x86.Eip;
}
}
}
@@ -454,14 +452,13 @@ static BOOL i386_stack_walk(struct cpu_stack_walk* csw, LPSTACKFRAME64 frame, CO
sw_read_mem(csw, p + (2 + i) * sizeof(WORD), &val16, sizeof(val16));
frame->Params[i] = val16;
}
-#ifdef __i386__
if (context)
{
#define SET(field, seg, reg) \
switch (frame->field.Mode) \
{ \
- case AddrModeFlat: context->reg = frame->field.Offset; break; \
- case AddrMode1616: context->seg = frame->field.Segment; context->reg = frame->field.Offset; break; \
+ case AddrModeFlat: context->x86.reg = frame->field.Offset; break; \
+ case AddrMode1616: context->x86.seg = frame->field.Segment; context->x86.reg = frame->field.Offset; break; \
default: assert(0); \
}
SET(AddrStack, SegSs, Esp);
@@ -469,19 +466,17 @@ static BOOL i386_stack_walk(struct cpu_stack_walk* csw, LPSTACKFRAME64 frame, CO
SET(AddrReturn, SegCs, Eip);
#undef SET
}
-#endif
}
else
{
unsigned int i;
-#ifdef __i386__
- CONTEXT newctx = *context;
+ union ctx newctx = *context;
if (!fetch_next_frame32(csw, &newctx, frame->AddrPC.Offset - deltapc))
goto done_err;
frame->AddrReturn.Mode = AddrModeFlat;
- frame->AddrReturn.Offset = newctx.Eip;
-#endif
+ frame->AddrReturn.Offset = newctx.x86.Eip;
+
for (i = 0; i < ARRAY_SIZE(frame->Params); i++)
{
sw_read_mem(csw, frame->AddrFrame.Offset + (2 + i) * sizeof(DWORD), &val32, sizeof(val32));
@@ -568,9 +563,10 @@ reg: fop 31
return reg;
}
-static void* i386_fetch_context_reg(CONTEXT* ctx, unsigned regno, unsigned* size)
+static void *i386_fetch_context_reg(union ctx *pctx, unsigned regno, unsigned *size)
{
-#ifdef __i386__
+ WOW64_CONTEXT *ctx = &pctx->x86;
+
switch (regno)
{
case CV_REG_EAX: *size = sizeof(ctx->Eax); return &ctx->Eax;
@@ -611,7 +607,6 @@ static void* i386_fetch_context_reg(CONTEXT* ctx, unsigned regno, unsigned* size
case CV_REG_GS: *size = sizeof(ctx->SegGs); return &ctx->SegGs;
}
-#endif
FIXME("Unknown register %x\n", regno);
return NULL;
}
diff --git a/dlls/dbghelp/cpu_ppc.c b/dlls/dbghelp/cpu_ppc.c
index a481685..e1e1cb3 100644
--- a/dlls/dbghelp/cpu_ppc.c
+++ b/dlls/dbghelp/cpu_ppc.c
@@ -48,7 +48,8 @@ static BOOL ppc_get_addr(HANDLE hThread, const CONTEXT* ctx,
return FALSE;
}
-static BOOL ppc_stack_walk(struct cpu_stack_walk* csw, LPSTACKFRAME64 frame, CONTEXT* context)
+static BOOL ppc_stack_walk(struct cpu_stack_walk* csw, STACKFRAME64 *frame,
+ union ctx *ctx)
{
FIXME("not done\n");
return FALSE;
@@ -60,7 +61,7 @@ static unsigned ppc_map_dwarf_register(unsigned regno, BOOL eh_frame)
return 0;
}
-static void* ppc_fetch_context_reg(CONTEXT* ctx, unsigned regno, unsigned* size)
+static void *ppc_fetch_context_reg(union ctx *ctx, unsigned regno, unsigned *size)
{
FIXME("NIY\n");
return NULL;
diff --git a/dlls/dbghelp/cpu_x86_64.c b/dlls/dbghelp/cpu_x86_64.c
index 67b710c..be6d3f4 100644
--- a/dlls/dbghelp/cpu_x86_64.c
+++ b/dlls/dbghelp/cpu_x86_64.c
@@ -576,12 +576,13 @@ static BOOL interpret_function_table_entry(struct cpu_stack_walk* csw,
* modify (at least) context.{rip, rsp, rbp} using unwind information
* either out of PE exception handlers, debug info (dwarf), or simple stack unwind
*/
-static BOOL fetch_next_frame(struct cpu_stack_walk* csw, CONTEXT* context,
+static BOOL fetch_next_frame(struct cpu_stack_walk *csw, union ctx *pcontext,
DWORD_PTR curr_pc, void** prtf)
{
DWORD_PTR cfa;
RUNTIME_FUNCTION* rtf;
DWORD64 base;
+ CONTEXT *context = &pcontext->ctx;
if (!curr_pc || !(base = sw_module_base(csw, curr_pc))) return FALSE;
rtf = sw_table_access(csw, curr_pc);
@@ -590,7 +591,7 @@ static BOOL fetch_next_frame(struct cpu_stack_walk* csw, CONTEXT* context,
{
return interpret_function_table_entry(csw, context, rtf, base);
}
- else if (dwarf2_virtual_unwind(csw, curr_pc, context, &cfa))
+ else if (dwarf2_virtual_unwind(csw, curr_pc, pcontext, &cfa))
{
context->Rsp = cfa;
TRACE("next function rip=%016lx\n", context->Rip);
@@ -608,7 +609,8 @@ static BOOL fetch_next_frame(struct cpu_stack_walk* csw, CONTEXT* context,
return default_unwind(csw, context);
}
-static BOOL x86_64_stack_walk(struct cpu_stack_walk* csw, LPSTACKFRAME64 frame, CONTEXT* context)
+static BOOL x86_64_stack_walk(struct cpu_stack_walk *csw, STACKFRAME64 *frame,
+ union ctx *context)
{
unsigned deltapc = curr_count <= 1 ? 0 : 1;
@@ -643,8 +645,8 @@ static BOOL x86_64_stack_walk(struct cpu_stack_walk* csw, LPSTACKFRAME64 frame,
}
else
{
- if (context->Rsp != frame->AddrStack.Offset) FIXME("inconsistent Stack Pointer\n");
- if (context->Rip != frame->AddrPC.Offset) FIXME("inconsistent Instruction Pointer\n");
+ if (context->ctx.Rsp != frame->AddrStack.Offset) FIXME("inconsistent Stack Pointer\n");
+ if (context->ctx.Rip != frame->AddrPC.Offset) FIXME("inconsistent Instruction Pointer\n");
if (frame->AddrReturn.Offset == 0) goto done_err;
if (!fetch_next_frame(csw, context, frame->AddrPC.Offset - deltapc, &frame->FuncTableEntry))
@@ -655,17 +657,17 @@ static BOOL x86_64_stack_walk(struct cpu_stack_walk* csw, LPSTACKFRAME64 frame,
memset(&frame->Params, 0, sizeof(frame->Params));
/* set frame information */
- frame->AddrStack.Offset = context->Rsp;
- frame->AddrFrame.Offset = context->Rbp;
- frame->AddrPC.Offset = context->Rip;
+ frame->AddrStack.Offset = context->ctx.Rsp;
+ frame->AddrFrame.Offset = context->ctx.Rbp;
+ frame->AddrPC.Offset = context->ctx.Rip;
if (1)
{
- CONTEXT newctx = *context;
+ union ctx newctx = *context;
if (!fetch_next_frame(csw, &newctx, frame->AddrPC.Offset - deltapc, NULL))
goto done_err;
frame->AddrReturn.Mode = AddrModeFlat;
- frame->AddrReturn.Offset = newctx.Rip;
+ frame->AddrReturn.Offset = newctx.ctx.Rip;
}
frame->Far = TRUE;
@@ -687,7 +689,8 @@ done_err:
return FALSE;
}
#else
-static BOOL x86_64_stack_walk(struct cpu_stack_walk* csw, LPSTACKFRAME64 frame, CONTEXT* context)
+static BOOL x86_64_stack_walk(struct cpu_stack_walk *csw, STACKFRAME64 *frame,
+ union ctx *ctx)
{
return FALSE;
}
@@ -777,9 +780,11 @@ static unsigned x86_64_map_dwarf_register(unsigned regno, BOOL eh_frame)
return reg;
}
-static void* x86_64_fetch_context_reg(CONTEXT* ctx, unsigned regno, unsigned* size)
+static void *x86_64_fetch_context_reg(union ctx *pctx, unsigned regno, unsigned *size)
{
#ifdef __x86_64__
+ CONTEXT *ctx = &pctx->ctx;
+
switch (regno)
{
case CV_AMD64_RAX: *size = sizeof(ctx->Rax); return &ctx->Rax;
diff --git a/dlls/dbghelp/dbghelp_private.h b/dlls/dbghelp/dbghelp_private.h
index 76f5d00..871b81e 100644
--- a/dlls/dbghelp/dbghelp_private.h
+++ b/dlls/dbghelp/dbghelp_private.h
@@ -511,6 +511,12 @@ struct dump_context
MINIDUMP_CALLBACK_INFORMATION* cb;
};
+union ctx
+{
+ CONTEXT ctx;
+ WOW64_CONTEXT x86;
+};
+
enum cpu_addr {cpu_addr_pc, cpu_addr_stack, cpu_addr_frame};
struct cpu
{
@@ -523,7 +529,8 @@ struct cpu
enum cpu_addr, ADDRESS64* addr);
/* stack manipulation */
- BOOL (*stack_walk)(struct cpu_stack_walk* csw, LPSTACKFRAME64 frame, CONTEXT* context);
+ BOOL (*stack_walk)(struct cpu_stack_walk *csw, STACKFRAME64 *frame,
+ union ctx *ctx);
/* module manipulation */
void* (*find_runtime_function)(struct module*, DWORD64 addr);
@@ -532,7 +539,7 @@ struct cpu
unsigned (*map_dwarf_register)(unsigned regno, BOOL eh_frame);
/* context related manipulation */
- void* (*fetch_context_reg)(CONTEXT* context, unsigned regno, unsigned* size);
+ void * (*fetch_context_reg)(union ctx *ctx, unsigned regno, unsigned *size);
const char* (*fetch_regname)(unsigned regno);
/* minidump per CPU extension */
@@ -645,8 +652,8 @@ struct pdb_cmd_pair {
const char* name;
DWORD* pvalue;
};
-extern BOOL pdb_virtual_unwind(struct cpu_stack_walk* csw, DWORD_PTR ip,
- CONTEXT* context, struct pdb_cmd_pair* cpair) DECLSPEC_HIDDEN;
+extern BOOL pdb_virtual_unwind(struct cpu_stack_walk *csw, DWORD_PTR ip,
+ union ctx *context, struct pdb_cmd_pair *cpair) DECLSPEC_HIDDEN;
/* path.c */
extern BOOL path_find_symbol_file(const struct process* pcs, PCSTR full_path,
@@ -684,8 +691,8 @@ extern BOOL stabs_parse(struct module* module, unsigned long load_offset
extern BOOL dwarf2_parse(struct module* module, unsigned long load_offset,
const struct elf_thunk_area* thunks,
struct image_file_map* fmap) DECLSPEC_HIDDEN;
-extern BOOL dwarf2_virtual_unwind(struct cpu_stack_walk* csw, DWORD_PTR ip,
- CONTEXT* context, ULONG_PTR* cfa) DECLSPEC_HIDDEN;
+extern BOOL dwarf2_virtual_unwind(struct cpu_stack_walk *csw, DWORD_PTR ip,
+ union ctx *ctx, ULONG_PTR *cfa) DECLSPEC_HIDDEN;
/* stack.c */
extern BOOL sw_read_mem(struct cpu_stack_walk* csw, DWORD64 addr, void* ptr, DWORD sz) DECLSPEC_HIDDEN;
diff --git a/dlls/dbghelp/dwarf.c b/dlls/dbghelp/dwarf.c
index dc3ec29..e07c9f0 100644
--- a/dlls/dbghelp/dwarf.c
+++ b/dlls/dbghelp/dwarf.c
@@ -3008,7 +3008,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)
+static ULONG_PTR get_context_reg(union ctx *context, ULONG_PTR dw_reg)
{
unsigned regno = dbghelp_current_cpu->map_dwarf_register(dw_reg, TRUE), sz;
ULONG_PTR* ptr = dbghelp_current_cpu->fetch_context_reg(context, regno, &sz);
@@ -3022,8 +3022,8 @@ static ULONG_PTR get_context_reg(CONTEXT *context, ULONG_PTR dw_reg)
}
/* set a context register from its dwarf number */
-static void set_context_reg(struct cpu_stack_walk* csw, CONTEXT *context, ULONG_PTR dw_reg,
- ULONG_PTR val, BOOL isdebuggee)
+static void set_context_reg(struct cpu_stack_walk* csw, union ctx *context,
+ ULONG_PTR dw_reg, ULONG_PTR val, BOOL isdebuggee)
{
unsigned regno = dbghelp_current_cpu->map_dwarf_register(dw_reg, TRUE), sz;
ULONG_PTR* ptr = dbghelp_current_cpu->fetch_context_reg(context, regno, &sz);
@@ -3056,7 +3056,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)
+static void copy_context_reg(union ctx *dstcontext, ULONG_PTR dwregdst,
+ union ctx *srccontext, ULONG_PTR dwregsrc)
{
unsigned regdstno = dbghelp_current_cpu->map_dwarf_register(dwregdst, TRUE), szdst;
unsigned regsrcno = dbghelp_current_cpu->map_dwarf_register(dwregsrc, TRUE), szsrc;
@@ -3073,7 +3074,7 @@ static void copy_context_reg(CONTEXT *dstcontext, ULONG_PTR dwregdst, CONTEXT* s
}
static ULONG_PTR eval_expression(const struct module* module, struct cpu_stack_walk* csw,
- const unsigned char* zp, CONTEXT *context)
+ const unsigned char* zp, union ctx *context)
{
dwarf2_traverse_context_t ctx;
ULONG_PTR reg, sz, tmp, stack[64];
@@ -3184,11 +3185,11 @@ static ULONG_PTR eval_expression(const struct module* module, struct cpu_stack_w
}
static void apply_frame_state(const struct module* module, struct cpu_stack_walk* csw,
- CONTEXT *context, struct frame_state *state, ULONG_PTR* cfa)
+ union ctx *context, struct frame_state *state, ULONG_PTR* cfa)
{
unsigned int i;
ULONG_PTR value;
- CONTEXT new_context = *context;
+ union ctx new_context = *context;
switch (state->cfa_rule)
{
@@ -3240,7 +3241,8 @@ static void apply_frame_state(const struct module* module, struct cpu_stack_walk
* dwarf2_virtual_unwind
*
*/
-BOOL dwarf2_virtual_unwind(struct cpu_stack_walk* csw, ULONG_PTR ip, CONTEXT* context, ULONG_PTR* cfa)
+BOOL dwarf2_virtual_unwind(struct cpu_stack_walk *csw, ULONG_PTR ip,
+ union ctx *context, ULONG_PTR *cfa)
{
struct module_pair pair;
struct frame_info info;
diff --git a/dlls/dbghelp/msc.c b/dlls/dbghelp/msc.c
index cc1259d..20c716e 100644
--- a/dlls/dbghelp/msc.c
+++ b/dlls/dbghelp/msc.c
@@ -3196,8 +3196,8 @@ done:
return FALSE;
}
-BOOL pdb_virtual_unwind(struct cpu_stack_walk* csw, DWORD_PTR ip,
- CONTEXT* context, struct pdb_cmd_pair* cpair)
+BOOL pdb_virtual_unwind(struct cpu_stack_walk *csw, DWORD_PTR ip,
+ union ctx *context, struct pdb_cmd_pair *cpair)
{
struct module_pair pair;
struct pdb_module_info* pdb_info;
--
2.7.4
July 31, 2018
[PATCH 13/13 v2] msvcp90: Add implementation of _Concurrent_vector_Internal_push_back.
by Hua Meng
Signed-off-by: Hua meng <161220092(a)smail.nju.edu.cn>
---
dlls/msvcp90/misc.c | 20 +++++++++++++++++---
1 file changed, 17 insertions(+), 3 deletions(-)
diff --git a/dlls/msvcp90/misc.c b/dlls/msvcp90/misc.c
index 2e1bf9542f..342fed7c08 100644
--- a/dlls/msvcp90/misc.c
+++ b/dlls/msvcp90/misc.c
@@ -2198,10 +2198,24 @@ MSVCP_size_t __thiscall _Concurrent_vector_base_v4__Internal_grow_to_at_least_wi
/* ?_Internal_push_back(a)_Concurrent_vector_base_v4@details(a)Concurrency@@IEAAPEAX_KAEA_K(a)Z */
DEFINE_THISCALL_WRAPPER(_Concurrent_vector_base_v4__Internal_push_back, 12)
void * __thiscall _Concurrent_vector_base_v4__Internal_push_back(
- _Concurrent_vector_base_v4 *this, MSVCP_size_t len1, MSVCP_size_t *len2)
+ _Concurrent_vector_base_v4 *this, MSVCP_size_t element_size, MSVCP_size_t *idx)
{
- FIXME("(%p %ld %p) stub\n", this, len1, len2);
- return NULL;
+ MSVCP_size_t index, seg, segment_base;
+ void *data;
+
+ TRACE("(%p %ld %p)\n", this, element_size, idx);
+
+ do {
+ index = this->early_size;
+ _Concurrent_vector_base_v4__Internal_reserve(this, index + 1,
+ element_size, MSVCP_SIZE_T_MAX / element_size);
+ } while(InterlockedCompareExchangeSizeT(&this->early_size, index + 1, index) != index);
+ seg = _vector_base_v4__Segment_index_of(index);
+ segment_base = (seg == 0) ? 0 : (1 << seg);
+ data = (BYTE*)this->segment[seg] + element_size * (index - segment_base);
+ *idx = index;
+
+ return data;
}
/* ?_Internal_resize(a)_Concurrent_vector_base_v4@details(a)Concurrency@@IAEXIIIP6AXPAXI(a)ZP6AX0PBXI@Z2(a)Z */
--
2.11.0
July 31, 2018
[PATCH 12/13 v2] msvcp90: Add implementation of _Concurrent_vector_Internal_resize.
by Hua Meng
Signed-off-by: Hua meng <161220092(a)smail.nju.edu.cn>
---
dlls/msvcp90/misc.c | 32 +++++++++++++++++++++++++++++---
1 file changed, 29 insertions(+), 3 deletions(-)
diff --git a/dlls/msvcp90/misc.c b/dlls/msvcp90/misc.c
index 50ef82adee..2e1bf9542f 100644
--- a/dlls/msvcp90/misc.c
+++ b/dlls/msvcp90/misc.c
@@ -2208,11 +2208,37 @@ void * __thiscall _Concurrent_vector_base_v4__Internal_push_back(
/* ?_Internal_resize(a)_Concurrent_vector_base_v4@details(a)Concurrency@@IEAAX_K00P6AXPEAX0(a)ZP6AX1PEBX0@Z3(a)Z */
DEFINE_THISCALL_WRAPPER(_Concurrent_vector_base_v4__Internal_resize, 28)
void __thiscall _Concurrent_vector_base_v4__Internal_resize(
- _Concurrent_vector_base_v4 *this, MSVCP_size_t len1, MSVCP_size_t len2,
- MSVCP_size_t len3, void (__cdecl *clear)(void*, MSVCP_size_t),
+ _Concurrent_vector_base_v4 *this, MSVCP_size_t resize, MSVCP_size_t element_size,
+ MSVCP_size_t max_size, void (__cdecl *clear)(void*, MSVCP_size_t),
void (__cdecl *copy)(void*, const void*, MSVCP_size_t), const void *v)
{
- FIXME("(%p %ld %ld %ld %p %p %p) stub\n", this, len1, len2, len3, clear, copy, v);
+ MSVCP_size_t size, seg_no, end_seg_no, clear_element;
+
+ TRACE("(%p %ld %ld %ld %p %p %p)\n", this, resize, element_size, max_size, clear, copy, v);
+
+ if(resize > max_size) _vector_base_v4__Internal_throw_exception(this, 0);
+ size = this->early_size;
+ if(resize > size)
+ _Concurrent_vector_base_v4__Internal_grow_to_at_least_with_result(this,
+ resize, element_size, copy, v);
+ else if(resize == 0)
+ _Concurrent_vector_base_v4__Internal_clear(this, clear);
+ else if(resize < size)
+ {
+ seg_no = _vector_base_v4__Segment_index_of(size - 1);
+ end_seg_no = _vector_base_v4__Segment_index_of(resize - 1);
+ clear_element = size - (seg_no ? 1 << seg_no : 2);
+ if(clear_element > 0)
+ clear(this->segment[seg_no], clear_element);
+ if(seg_no) seg_no--;
+ for(; seg_no > end_seg_no; seg_no--)
+ clear(this->segment[seg_no], 1 << seg_no);
+ clear_element = (1 << (end_seg_no + 1)) - resize;
+ if(clear_element > 0)
+ clear((BYTE**)this->segment[end_seg_no] + element_size * (resize - ((1 << end_seg_no) & ~1)),
+ clear_element);
+ this->early_size = resize;
+ }
}
/* ?_Internal_swap(a)_Concurrent_vector_base_v4@details(a)Concurrency@@IAEXAAV123@@Z */
--
2.11.0
July 31, 2018
[PATCH 11/13 v2] msvcp90: Add implementation of _Concurrent_vector_Internal_compact.
by Hua Meng
Signed-off-by: Hua meng <161220092(a)smail.nju.edu.cn>
---
dlls/msvcp90/misc.c | 41 ++++++++++++++++++++++++++++++++++++++---
1 file changed, 38 insertions(+), 3 deletions(-)
diff --git a/dlls/msvcp90/misc.c b/dlls/msvcp90/misc.c
index d84af851c7..50ef82adee 100644
--- a/dlls/msvcp90/misc.c
+++ b/dlls/msvcp90/misc.c
@@ -1784,6 +1784,13 @@ typedef struct __Concurrent_vector_base_v4
#define STORAGE_SIZE (sizeof(this->storage) / sizeof(this->storage[0]))
#define SEGMENT_SIZE (sizeof(void*) * 8)
+typedef struct compact_block
+{
+ MSVCP_size_t first_block;
+ void *blocks[SEGMENT_SIZE];
+ int size_check;
+}compact_block;
+
/* based on wined3d_log2i from wined3d.h */
/* Return the integer base-2 logarithm of (x|1). Result is 0 for x == 0. */
static inline unsigned int log2i(unsigned int x)
@@ -1997,12 +2004,40 @@ MSVCP_size_t __thiscall _Concurrent_vector_base_v4__Internal_clear(
/* ?_Internal_compact(a)_Concurrent_vector_base_v4@details(a)Concurrency@@IEAAPEAX_KPEAXP6AX10(a)ZP6AX1PEBX0@Z(a)Z */
DEFINE_THISCALL_WRAPPER(_Concurrent_vector_base_v4__Internal_compact, 20)
void * __thiscall _Concurrent_vector_base_v4__Internal_compact(
- _Concurrent_vector_base_v4 *this, MSVCP_size_t len, void *v,
+ _Concurrent_vector_base_v4 *this, MSVCP_size_t element_size, void *v,
void (__cdecl *clear)(void*, MSVCP_size_t),
void (__cdecl *copy)(void*, const void*, MSVCP_size_t))
{
- FIXME("(%p %ld %p %p %p) stub\n", this, len, v, clear, copy);
- return NULL;
+ compact_block *b;
+ MSVCP_size_t size, seg_no, copy_element, clear_element;
+ int i;
+
+ TRACE("(%p %ld %p %p %p)\n", this, element_size, v, clear, copy);
+
+ size = this->early_size;
+ seg_no = _vector_base_v4__Segment_index_of(size - 1);
+ if(this->first_block == seg_no + 1) return v;
+ b = v;
+ b->first_block = this->first_block;
+ memset(b->blocks, 0, sizeof(b->blocks));
+ memcpy(b->blocks, this->segment,
+ (this->segment == this->storage ? STORAGE_SIZE : SEGMENT_SIZE) * sizeof(this->segment[0]));
+ memset(this->segment, 0,
+ (this->segment == this->storage ? STORAGE_SIZE : SEGMENT_SIZE) * sizeof(this->segment[0]));
+ this->first_block = 0;
+ _Concurrent_vector_base_v4__Internal_reserve(this, size, element_size,
+ MSVCP_SIZE_T_MAX / element_size);
+ for(i = 0; i < seg_no; i++)
+ copy(this->segment[i], b->blocks[i], i ? 1 << i : 2);
+ copy_element = size - ((1 << seg_no) & ~1);
+ if(copy_element > 0)
+ copy(this->segment[seg_no], b->blocks[seg_no], copy_element);
+ for(i = 0; i < seg_no; i++)
+ clear(b->blocks[i], i ? 1 << i : 2);
+ clear_element = size - ((1 << seg_no) & ~1);
+ if(clear_element > 0)
+ clear(b->blocks[seg_no], clear_element);
+ return v;
}
/* ?_Internal_copy(a)_Concurrent_vector_base_v4@details(a)Concurrency@@IAEXABV123(a)IP6AXPAXPBXI@Z(a)Z */
--
2.11.0
July 31, 2018
[PATCH 10/13 v2] msvcp90: Add implementation of _Concurrent_vector_Internal_swap.
by Hua Meng
Signed-off-by: Hua meng <161220092(a)smail.nju.edu.cn>
---
dlls/msvcp90/misc.c | 14 ++++++++++++--
1 file changed, 12 insertions(+), 2 deletions(-)
diff --git a/dlls/msvcp90/misc.c b/dlls/msvcp90/misc.c
index 24488b41e0..d84af851c7 100644
--- a/dlls/msvcp90/misc.c
+++ b/dlls/msvcp90/misc.c
@@ -2184,9 +2184,19 @@ void __thiscall _Concurrent_vector_base_v4__Internal_resize(
/* ?_Internal_swap(a)_Concurrent_vector_base_v4@details(a)Concurrency@@IEAAXAEAV123@@Z */
DEFINE_THISCALL_WRAPPER(_Concurrent_vector_base_v4__Internal_swap, 8)
void __thiscall _Concurrent_vector_base_v4__Internal_swap(
- _Concurrent_vector_base_v4 *this, const _Concurrent_vector_base_v4 *v)
+ _Concurrent_vector_base_v4 *this, _Concurrent_vector_base_v4 *v)
{
- FIXME("(%p %p) stub\n", this, v);
+ _Concurrent_vector_base_v4 temp;
+
+ TRACE("(%p %p)\n", this, v);
+
+ temp = *this;
+ *this = *v;
+ *v = temp;
+ if(v->segment == this->storage)
+ v->segment = v->storage;
+ if(this->segment == v->storage)
+ this->segment = this->storage;
}
#endif
--
2.11.0
July 31, 2018
[PATCH 09/13 v2] msvcp90: Add implementation of _Concurrent_vector_Internal_grow_to_at_least_with_result.
by Hua Meng
Signed-off-by: Hua meng <161220092(a)smail.nju.edu.cn>
---
dlls/msvcp90/misc.c | 26 ++++++++++++++++++++++++--
1 file changed, 24 insertions(+), 2 deletions(-)
diff --git a/dlls/msvcp90/misc.c b/dlls/msvcp90/misc.c
index 5142563f90..24488b41e0 100644
--- a/dlls/msvcp90/misc.c
+++ b/dlls/msvcp90/misc.c
@@ -2133,8 +2133,30 @@ MSVCP_size_t __thiscall _Concurrent_vector_base_v4__Internal_grow_to_at_least_wi
_Concurrent_vector_base_v4 *this, MSVCP_size_t count, MSVCP_size_t element_size,
void (__cdecl *copy)(void*, const void*, MSVCP_size_t), const void *v)
{
- FIXME("(%p %ld %ld %p %p) stub\n", this, count, element_size, copy, v);
- return 0;
+ MSVCP_size_t size, seg_no, last_seg_no, remain_size;
+
+ TRACE("(%p %ld %ld %p %p)\n", this, count, element_size, copy, v);
+
+ _Concurrent_vector_base_v4__Internal_reserve(this, count, element_size,
+ MSVCP_SIZE_T_MAX / element_size);
+ do {
+ size = this->early_size;
+ if(size >= count) return size;
+ } while(InterlockedCompareExchangeSizeT(&this->early_size, count, size) != size);
+
+ seg_no = size ? _vector_base_v4__Segment_index_of(size - 1) : 0;
+ last_seg_no = _vector_base_v4__Segment_index_of(count - 1);
+ remain_size = min(count, 1 << (seg_no + 1)) - size;
+ if(remain_size > 0)
+ copy(((BYTE**)this->segment[seg_no] + element_size * (size - ((1 << seg_no) & ~1))), v,
+ remain_size);
+ if(seg_no != last_seg_no)
+ {
+ for(seg_no++; seg_no < last_seg_no; seg_no++)
+ copy(this->segment[seg_no], v, 1 << seg_no);
+ copy(this->segment[last_seg_no], v, count - (1 << last_seg_no));
+ }
+ return size;
}
/* ?_Internal_push_back(a)_Concurrent_vector_base_v4@details(a)Concurrency@@IAEPAXIAAI(a)Z */
--
2.11.0
July 31, 2018
[PATCH 08/13 v2] msvcp90: Add implementation of _Concurrent_vector_Internal_grow_by.
by Hua Meng
Signed-off-by: Hua meng <161220092(a)smail.nju.edu.cn>
---
dlls/msvcp90/misc.c | 26 ++++++++++++++++++++++++--
1 file changed, 24 insertions(+), 2 deletions(-)
diff --git a/dlls/msvcp90/misc.c b/dlls/msvcp90/misc.c
index f396d69c69..5142563f90 100644
--- a/dlls/msvcp90/misc.c
+++ b/dlls/msvcp90/misc.c
@@ -2100,8 +2100,30 @@ MSVCP_size_t __thiscall _Concurrent_vector_base_v4__Internal_grow_by(
_Concurrent_vector_base_v4 *this, MSVCP_size_t count, MSVCP_size_t element_size,
void (__cdecl *copy)(void*, const void*, MSVCP_size_t), const void *v)
{
- FIXME("(%p %ld %ld %p %p) stub\n", this, count, element_size, copy, v);
- return 0;
+ MSVCP_size_t size, seg_no, last_seg_no, remain_size;
+
+ TRACE("(%p %ld %ld %p %p)\n", this, count, element_size, copy, v);
+
+ if(count == 0) return this->early_size;
+ do {
+ size = this->early_size;
+ _Concurrent_vector_base_v4__Internal_reserve(this, size + count, element_size,
+ MSVCP_SIZE_T_MAX / element_size);
+ } while(InterlockedCompareExchangeSizeT(&this->early_size, size + count, size) != size);
+
+ seg_no = size ? _vector_base_v4__Segment_index_of(size - 1) : 0;
+ last_seg_no = _vector_base_v4__Segment_index_of(size + count - 1);
+ remain_size = min(size + count, 1 << (seg_no + 1)) - size;
+ if(remain_size > 0)
+ copy(((BYTE**)this->segment[seg_no] + element_size * (size - ((1 << seg_no) & ~1))), v,
+ remain_size);
+ if(seg_no != last_seg_no)
+ {
+ for(seg_no++; seg_no < last_seg_no; seg_no++)
+ copy(this->segment[seg_no], v, 1 << seg_no);
+ copy(this->segment[last_seg_no], v, size + count - (1 << last_seg_no));
+ }
+ return size;
}
/* ?_Internal_grow_to_at_least_with_result(a)_Concurrent_vector_base_v4@details(a)Concurrency@@IAEIIIP6AXPAXPBXI(a)Z1@Z */
--
2.11.0
July 31, 2018
[PATCH 07/13 v2] msvcp90: Add implementation of _Concurrent_vector_Internal_assign.
by Hua Meng
Signed-off-by: Hua meng <161220092(a)smail.nju.edu.cn>
---
dlls/msvcp90/misc.c | 74 ++++++++++++++++++++++++++++++++++++++++++++---------
1 file changed, 62 insertions(+), 12 deletions(-)
diff --git a/dlls/msvcp90/misc.c b/dlls/msvcp90/misc.c
index aa969d2200..f396d69c69 100644
--- a/dlls/msvcp90/misc.c
+++ b/dlls/msvcp90/misc.c
@@ -1912,18 +1912,6 @@ void __thiscall _Concurrent_vector_base_v4_dtor(
free(this->segment);
}
-/* ?_Internal_assign(a)_Concurrent_vector_base_v4@details(a)Concurrency@@IAEXABV123(a)IP6AXPAXI@ZP6AX1PBXI(a)Z4@Z */
-/* ?_Internal_assign(a)_Concurrent_vector_base_v4@details(a)Concurrency@@IEAAXAEBV123(a)_KP6AXPEAX1@ZP6AX2PEBX1(a)Z5@Z */
-DEFINE_THISCALL_WRAPPER(_Concurrent_vector_base_v4__Internal_assign, 24)
-void __thiscall _Concurrent_vector_base_v4__Internal_assign(
- _Concurrent_vector_base_v4 *this, const _Concurrent_vector_base_v4 *v,
- MSVCP_size_t len, void (__cdecl *func0)(void*, MSVCP_size_t),
- void (__cdecl *func1)(void*, const void*, MSVCP_size_t),
- void (__cdecl *func2)(void*, const void*, MSVCP_size_t))
-{
- FIXME("(%p %p %ld %p %p %p) stub\n", this, v, len, func0, func1, func2);
-}
-
/* ?_Internal_capacity(a)_Concurrent_vector_base_v4@details(a)Concurrency@@IBEIXZ */
/* ?_Internal_capacity(a)_Concurrent_vector_base_v4@details(a)Concurrency@@IEBA_KXZ */
DEFINE_THISCALL_WRAPPER(_Concurrent_vector_base_v4__Internal_capacity, 4)
@@ -2043,6 +2031,68 @@ void __thiscall _Concurrent_vector_base_v4__Internal_copy(
this->early_size = v_size;
}
+/* ?_Internal_assign(a)_Concurrent_vector_base_v4@details(a)Concurrency@@IAEXABV123(a)IP6AXPAXI@ZP6AX1PBXI(a)Z4@Z */
+/* ?_Internal_assign(a)_Concurrent_vector_base_v4@details(a)Concurrency@@IEAAXAEBV123(a)_KP6AXPEAX1@ZP6AX2PEBX1(a)Z5@Z */
+DEFINE_THISCALL_WRAPPER(_Concurrent_vector_base_v4__Internal_assign, 24)
+void __thiscall _Concurrent_vector_base_v4__Internal_assign(
+ _Concurrent_vector_base_v4 *this, const _Concurrent_vector_base_v4 *v,
+ MSVCP_size_t element_size, void (__cdecl *clear)(void*, MSVCP_size_t),
+ void (__cdecl *assign)(void*, const void*, MSVCP_size_t),
+ void (__cdecl *copy)(void*, const void*, MSVCP_size_t))
+{
+ MSVCP_size_t v_size, seg_no, v_seg_no, remain_element;
+ int i;
+
+ TRACE("(%p %p %ld %p %p %p)\n", this, v, element_size, clear, assign, copy);
+
+ v_size = v->early_size;
+ if(!v_size) {
+ _Concurrent_vector_base_v4__Internal_clear(this, clear);
+ return;
+ }
+ if(!this->early_size) {
+ _Concurrent_vector_base_v4__Internal_copy(this, v, element_size, copy);
+ return;
+ }
+ seg_no = _vector_base_v4__Segment_index_of(this->early_size - 1);
+ v_seg_no = _vector_base_v4__Segment_index_of(v_size - 1);
+
+ for(i = 0; i < min(seg_no, v_seg_no); i++)
+ assign(this->segment[i], v->segment[i], i ? 1 << i : 2);
+ remain_element = min(this->early_size, v_size) - (1 << i & ~1);
+ if(remain_element != 0)
+ assign(this->segment[i], v->segment[i], remain_element);
+
+ if(this->early_size > v_size)
+ {
+ if((i ? 1 << i : 2) - remain_element > 0)
+ clear((BYTE**)this->segment[i] + element_size * remain_element,
+ (i ? 1 << i : 2) - remain_element);
+ if(i < seg_no)
+ {
+ for(i++; i < seg_no; i++)
+ clear(this->segment[i], 1 << i);
+ clear(this->segment[i], this->early_size - (1 << i));
+ }
+ }
+ else if(this->early_size < v_size)
+ {
+ if((i ? 1 << i : 2) - remain_element > 0)
+ copy((BYTE**)this->segment[i] + element_size * remain_element,
+ (BYTE**)v->segment[i] + element_size * remain_element,
+ (i ? 1 << i : 2) - remain_element);
+ if(i < v_seg_no)
+ {
+ _Concurrent_vector_base_v4__Internal_reserve(this, v_size,
+ element_size, MSVCP_SIZE_T_MAX / element_size);
+ for(i++; i < v_seg_no; i++)
+ copy(this->segment[i], v->segment[i], 1 << i);
+ copy(this->segment[i], v->segment[i], v->early_size - (1 << i));
+ }
+ }
+ this->early_size = v_size;
+}
+
/* ?_Internal_grow_by(a)_Concurrent_vector_base_v4@details(a)Concurrency@@IAEIIIP6AXPAXPBXI(a)Z1@Z */
/* ?_Internal_grow_by(a)_Concurrent_vector_base_v4@details(a)Concurrency@@IEAA_K_K0P6AXPEAXPEBX0(a)Z2@Z */
DEFINE_THISCALL_WRAPPER(_Concurrent_vector_base_v4__Internal_grow_by, 20)
--
2.11.0
July 31, 2018
[PATCH 06/13 v2] msvcp90: Add implementation of _Concurrent_vector_Internal_copy.
by Hua Meng
Signed-off-by: Hua meng <161220092(a)smail.nju.edu.cn>
---
dlls/msvcp90/misc.c | 20 ++++++++++++++++++--
dlls/msvcp90/msvcp90.h | 1 +
2 files changed, 19 insertions(+), 2 deletions(-)
diff --git a/dlls/msvcp90/misc.c b/dlls/msvcp90/misc.c
index a2baf12567..aa969d2200 100644
--- a/dlls/msvcp90/misc.c
+++ b/dlls/msvcp90/misc.c
@@ -2022,9 +2022,25 @@ void * __thiscall _Concurrent_vector_base_v4__Internal_compact(
DEFINE_THISCALL_WRAPPER(_Concurrent_vector_base_v4__Internal_copy, 16)
void __thiscall _Concurrent_vector_base_v4__Internal_copy(
_Concurrent_vector_base_v4 *this, const _Concurrent_vector_base_v4 *v,
- MSVCP_size_t len, void (__cdecl *copy)(void*, const void*, MSVCP_size_t))
+ MSVCP_size_t element_size, void (__cdecl *copy)(void*, const void*, MSVCP_size_t))
{
- FIXME("(%p %p %ld %p) stub\n", this, v, len, copy);
+ MSVCP_size_t seg_no, v_size;
+ int i;
+
+ TRACE("(%p %p %ld %p)\n", this, v, element_size, copy);
+
+ v_size = v->early_size;
+ if(!v_size) {
+ this->early_size = 0;
+ return;
+ }
+ _Concurrent_vector_base_v4__Internal_reserve(this, v_size,
+ element_size, MSVCP_SIZE_T_MAX / element_size);
+ seg_no = _vector_base_v4__Segment_index_of(v_size - 1);
+ for(i = 0; i < seg_no; i++)
+ copy(this->segment[i], v->segment[i], i ? 1 << i : 2);
+ copy(this->segment[i], v->segment[i], v_size - (1 << i & ~1));
+ this->early_size = v_size;
}
/* ?_Internal_grow_by(a)_Concurrent_vector_base_v4@details(a)Concurrency@@IAEIIIP6AXPAXPBXI(a)Z1@Z */
diff --git a/dlls/msvcp90/msvcp90.h b/dlls/msvcp90/msvcp90.h
index 16eaa48c53..40fbe4ba80 100644
--- a/dlls/msvcp90/msvcp90.h
+++ b/dlls/msvcp90/msvcp90.h
@@ -25,6 +25,7 @@
typedef unsigned char MSVCP_bool;
typedef SIZE_T MSVCP_size_t;
+#define MSVCP_SIZE_T_MAX (~(MSVCP_size_t)0)
#if _MSVCP_VER >= 100
typedef __int64 DECLSPEC_ALIGN(8) streamoff;
typedef __int64 DECLSPEC_ALIGN(8) streamsize;
--
2.11.0
July 31, 2018
[PATCH 05/13 v2] msvcp90: Add implementation of _Concurrent_vector_Internal_clear.
by Hua Meng
Signed-off-by: Hua meng <161220092(a)smail.nju.edu.cn>
---
dlls/msvcp90/misc.c | 18 ++++++++++++++++--
1 file changed, 16 insertions(+), 2 deletions(-)
diff --git a/dlls/msvcp90/misc.c b/dlls/msvcp90/misc.c
index 34a30cf5e1..a2baf12567 100644
--- a/dlls/msvcp90/misc.c
+++ b/dlls/msvcp90/misc.c
@@ -1987,8 +1987,22 @@ DEFINE_THISCALL_WRAPPER(_Concurrent_vector_base_v4__Internal_clear, 8)
MSVCP_size_t __thiscall _Concurrent_vector_base_v4__Internal_clear(
_Concurrent_vector_base_v4 *this, void (__cdecl *clear)(void*, MSVCP_size_t))
{
- FIXME("(%p %p) stub\n", this, clear);
- return 0;
+ MSVCP_size_t seg_no, elems;
+ int i;
+
+ TRACE("(%p %p)\n", this, clear);
+
+ seg_no = this->early_size ? _vector_base_v4__Segment_index_of(this->early_size) + 1 : 0;
+ for(i = seg_no - 1; i >= 0; i--) {
+ elems = this->early_size - (1 << i & ~1);
+ clear(this->segment[i], elems);
+ this->early_size -= elems;
+ }
+ while(seg_no < (this->segment == this->storage ? STORAGE_SIZE : SEGMENT_SIZE)) {
+ if(!this->segment[seg_no]) break;
+ seg_no++;
+ }
+ return seg_no;
}
/* ?_Internal_compact(a)_Concurrent_vector_base_v4@details(a)Concurrency@@IAEPAXIPAXP6AX0I(a)ZP6AX0PBXI@Z(a)Z */
--
2.11.0
July 31, 2018