ReactOS 0.4.15-dev-7994-gb388cb6
cpu_x86_64.c
Go to the documentation of this file.
1/*
2 * File cpu_x86_64.c
3 *
4 * Copyright (C) 1999, 2005 Alexandre Julliard
5 * Copyright (C) 2009, 2011 Eric Pouech.
6 *
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
11 *
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
20 */
21
22#include <assert.h>
23
24#define NONAMELESSUNION
25#define NONAMELESSSTRUCT
26#include "ntstatus.h"
27#define WIN32_NO_STATUS
28#include "dbghelp_private.h"
29#include "winternl.h"
30#include "wine/debug.h"
31
33
34/* x86-64 unwind information, for PE modules, as described on MSDN */
35
36typedef enum _UNWIND_OP_CODES
37{
48
49typedef union _UNWIND_CODE
50{
51 struct
52 {
56 } u;
59
60typedef struct _UNWIND_INFO
61{
68 UNWIND_CODE UnwindCode[1]; /* actually CountOfCodes (aligned) */
69/*
70 * union
71 * {
72 * OPTIONAL ULONG ExceptionHandler;
73 * OPTIONAL ULONG FunctionEntry;
74 * };
75 * OPTIONAL ULONG ExceptionData[];
76 */
78
81{
82 addr->Mode = AddrModeFlat;
83 switch (ca)
84 {
85#ifdef __x86_64__
86 case cpu_addr_pc: addr->Segment = ctx->SegCs; addr->Offset = ctx->Rip; return TRUE;
87 case cpu_addr_stack: addr->Segment = ctx->SegSs; addr->Offset = ctx->Rsp; return TRUE;
88 case cpu_addr_frame: addr->Segment = ctx->SegSs; addr->Offset = ctx->Rbp; return TRUE;
89#endif
90 default: addr->Mode = -1;
91 return FALSE;
92 }
93}
94
95#ifdef __x86_64__
96
97enum st_mode {stm_start, stm_64bit, stm_done};
98
99/* indexes in Reserved array */
100#define __CurrentMode 0
101#define __CurrentCount 1
102/* #define __ 2 (unused) */
103
104#define curr_mode (frame->Reserved[__CurrentMode])
105#define curr_count (frame->Reserved[__CurrentCount])
106/* #define ??? (frame->Reserved[__]) (unused) */
107
108union handler_data
109{
112};
113
114static void dump_unwind_info(struct cpu_stack_walk* csw, ULONG64 base, RUNTIME_FUNCTION *function)
115{
116 static const char * const reg_names[16] =
117 { "rax", "rcx", "rdx", "rbx", "rsp", "rbp", "rsi", "rdi",
118 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15" };
119
120 union handler_data handler_data;
121 char buffer[sizeof(UNWIND_INFO) + 256 * sizeof(UNWIND_CODE)];
123 unsigned int i, count;
124 RUNTIME_FUNCTION snext;
126
127 TRACE("**** func %x-%x\n", function->BeginAddress, function->EndAddress);
128 for (;;)
129 {
130 if (function->UnwindData & 1)
131 {
132 if (!sw_read_mem(csw, base + function->UnwindData, &snext, sizeof(snext)))
133 {
134 TRACE("Couldn't unwind RUNTIME_INFO at %lx\n", base + function->UnwindData);
135 return;
136 }
137 TRACE("unwind info for function %p-%p chained to function %p-%p\n",
138 (char*)base + function->BeginAddress, (char*)base + function->EndAddress,
139 (char*)base + snext.BeginAddress, (char*)base + snext.EndAddress);
140 function = &snext;
141 continue;
142 }
143 addr = base + function->UnwindData;
144 if (!sw_read_mem(csw, addr, info, FIELD_OFFSET(UNWIND_INFO, UnwindCode)) ||
145 !sw_read_mem(csw, addr + FIELD_OFFSET(UNWIND_INFO, UnwindCode),
146 info->UnwindCode, info->CountOfCodes * sizeof(UNWIND_CODE)))
147 {
148 FIXME("couldn't read memory for UNWIND_INFO at %lx\n", addr);
149 return;
150 }
151 TRACE("unwind info at %p flags %x prolog 0x%x bytes function %p-%p\n",
152 (char*)addr, info->Flags, info->SizeOfProlog,
153 (char*)base + function->BeginAddress, (char*)base + function->EndAddress);
154
155 if (info->FrameRegister)
156 TRACE(" frame register %s offset 0x%x(%%rsp)\n",
157 reg_names[info->FrameRegister], info->FrameOffset * 16);
158
159 for (i = 0; i < info->CountOfCodes; i++)
160 {
161 TRACE(" 0x%x: ", info->UnwindCode[i].u.CodeOffset);
162 switch (info->UnwindCode[i].u.UnwindOp)
163 {
164 case UWOP_PUSH_NONVOL:
165 TRACE("pushq %%%s\n", reg_names[info->UnwindCode[i].u.OpInfo]);
166 break;
167 case UWOP_ALLOC_LARGE:
168 if (info->UnwindCode[i].u.OpInfo)
169 {
170 count = *(DWORD*)&info->UnwindCode[i+1];
171 i += 2;
172 }
173 else
174 {
175 count = *(USHORT*)&info->UnwindCode[i+1] * 8;
176 i++;
177 }
178 TRACE("subq $0x%x,%%rsp\n", count);
179 break;
180 case UWOP_ALLOC_SMALL:
181 count = (info->UnwindCode[i].u.OpInfo + 1) * 8;
182 TRACE("subq $0x%x,%%rsp\n", count);
183 break;
184 case UWOP_SET_FPREG:
185 TRACE("leaq 0x%x(%%rsp),%s\n",
186 info->FrameOffset * 16, reg_names[info->FrameRegister]);
187 break;
188 case UWOP_SAVE_NONVOL:
189 count = *(USHORT*)&info->UnwindCode[i+1] * 8;
190 TRACE("movq %%%s,0x%x(%%rsp)\n", reg_names[info->UnwindCode[i].u.OpInfo], count);
191 i++;
192 break;
194 count = *(DWORD*)&info->UnwindCode[i+1];
195 TRACE("movq %%%s,0x%x(%%rsp)\n", reg_names[info->UnwindCode[i].u.OpInfo], count);
196 i += 2;
197 break;
198 case UWOP_SAVE_XMM128:
199 count = *(USHORT*)&info->UnwindCode[i+1] * 16;
200 TRACE("movaps %%xmm%u,0x%x(%%rsp)\n", info->UnwindCode[i].u.OpInfo, count);
201 i++;
202 break;
204 count = *(DWORD*)&info->UnwindCode[i+1];
205 TRACE("movaps %%xmm%u,0x%x(%%rsp)\n", info->UnwindCode[i].u.OpInfo, count);
206 i += 2;
207 break;
209 TRACE("PUSH_MACHFRAME %u\n", info->UnwindCode[i].u.OpInfo);
210 break;
211 default:
212 FIXME("unknown code %u\n", info->UnwindCode[i].u.UnwindOp);
213 break;
214 }
215 }
216
217 addr += FIELD_OFFSET(UNWIND_INFO, UnwindCode) +
218 ((info->CountOfCodes + 1) & ~1) * sizeof(UNWIND_CODE);
219 if (info->Flags & UNW_FLAG_CHAININFO)
220 {
221 if (!sw_read_mem(csw, addr, &handler_data, sizeof(handler_data.chain)))
222 {
223 FIXME("couldn't read memory for handler_data.chain\n");
224 return;
225 }
226 TRACE(" chained to function %p-%p\n",
227 (char*)base + handler_data.chain.BeginAddress,
228 (char*)base + handler_data.chain.EndAddress);
229 function = &handler_data.chain;
230 continue;
231 }
233 {
234 if (!sw_read_mem(csw, addr, &handler_data, sizeof(handler_data.handler)))
235 {
236 FIXME("couldn't read memory for handler_data.handler\n");
237 return;
238 }
239 TRACE(" handler %p data at %p\n",
240 (char*)base + handler_data.handler, (char*)addr + sizeof(handler_data.handler));
241 }
242 break;
243 }
244}
245
246/* highly derived from dlls/ntdll/signal_x86_64.c */
247static ULONG64 get_int_reg(CONTEXT *context, int reg)
248{
249 return *(&context->Rax + reg);
250}
251
252static void set_int_reg(CONTEXT *context, int reg, ULONG64 val)
253{
254 *(&context->Rax + reg) = val;
255}
256
257static void set_float_reg(CONTEXT *context, int reg, M128A val)
258{
259 *(&context->u.s.Xmm0 + reg) = val;
260}
261
262static int get_opcode_size(UNWIND_CODE op)
263{
264 switch (op.u.UnwindOp)
265 {
266 case UWOP_ALLOC_LARGE:
267 return 2 + (op.u.OpInfo != 0);
268 case UWOP_SAVE_NONVOL:
269 case UWOP_SAVE_XMM128:
270 return 2;
273 return 3;
274 default:
275 return 1;
276 }
277}
278
279static BOOL is_inside_epilog(struct cpu_stack_walk* csw, DWORD64 pc,
280 DWORD64 base, const RUNTIME_FUNCTION *function )
281{
282 BYTE op0, op1, op2;
283 LONG val32;
284
285 if (!sw_read_mem(csw, pc, &op0, 1)) return FALSE;
286
287 /* add or lea must be the first instruction, and it must have a rex.W prefix */
288 if ((op0 & 0xf8) == 0x48)
289 {
290 if (!sw_read_mem(csw, pc + 1, &op1, 1)) return FALSE;
291 if (!sw_read_mem(csw, pc + 2, &op2, 1)) return FALSE;
292 switch (op1)
293 {
294 case 0x81: /* add $nnnn,%rsp */
295 if (op0 == 0x48 && op2 == 0xc4)
296 {
297 pc += 7;
298 break;
299 }
300 return FALSE;
301 case 0x83: /* add $n,%rsp */
302 if (op0 == 0x48 && op2 == 0xc4)
303 {
304 pc += 4;
305 break;
306 }
307 return FALSE;
308 case 0x8d: /* lea n(reg),%rsp */
309 if (op0 & 0x06) return FALSE; /* rex.RX must be cleared */
310 if (((op2 >> 3) & 7) != 4) return FALSE; /* dest reg mus be %rsp */
311 if ((op2 & 7) == 4) return FALSE; /* no SIB byte allowed */
312 if ((op2 >> 6) == 1) /* 8-bit offset */
313 {
314 pc += 4;
315 break;
316 }
317 if ((op2 >> 6) == 2) /* 32-bit offset */
318 {
319 pc += 7;
320 break;
321 }
322 return FALSE;
323 }
324 }
325
326 /* now check for various pop instructions */
327 for (;;)
328 {
329 if (!sw_read_mem(csw, pc, &op0, 1)) return FALSE;
330 if ((op0 & 0xf0) == 0x40) /* rex prefix */
331 {
332 if (!sw_read_mem(csw, ++pc, &op0, 1)) return FALSE;
333 }
334
335 switch (op0)
336 {
337 case 0x58: /* pop %rax/%r8 */
338 case 0x59: /* pop %rcx/%r9 */
339 case 0x5a: /* pop %rdx/%r10 */
340 case 0x5b: /* pop %rbx/%r11 */
341 case 0x5c: /* pop %rsp/%r12 */
342 case 0x5d: /* pop %rbp/%r13 */
343 case 0x5e: /* pop %rsi/%r14 */
344 case 0x5f: /* pop %rdi/%r15 */
345 pc++;
346 continue;
347 case 0xc2: /* ret $nn */
348 case 0xc3: /* ret */
349 return TRUE;
350 case 0xe9: /* jmp nnnn */
351 if (!sw_read_mem(csw, pc + 1, &val32, sizeof(LONG))) return FALSE;
352 pc += 5 + val32;
353 if (pc - base >= function->BeginAddress && pc - base < function->EndAddress)
354 continue;
355 break;
356 case 0xeb: /* jmp n */
357 if (!sw_read_mem(csw, pc + 1, &op1, 1)) return FALSE;
358 pc += 2 + (signed char)op1;
359 if (pc - base >= function->BeginAddress && pc - base < function->EndAddress)
360 continue;
361 break;
362 case 0xf3: /* rep; ret (for amd64 prediction bug) */
363 if (!sw_read_mem(csw, pc + 1, &op1, 1)) return FALSE;
364 return op1 == 0xc3;
365 }
366 return FALSE;
367 }
368}
369
370static BOOL interpret_epilog(struct cpu_stack_walk* csw, ULONG64 pc, CONTEXT *context )
371{
372 BYTE insn, val8;
373 WORD val16;
374 LONG val32;
375 DWORD64 val64;
376
377 for (;;)
378 {
379 BYTE rex = 0;
380
381 if (!sw_read_mem(csw, pc, &insn, 1)) return FALSE;
382 if ((insn & 0xf0) == 0x40)
383 {
384 rex = insn & 0x0f; /* rex prefix */
385 if (!sw_read_mem(csw, ++pc, &insn, 1)) return FALSE;
386 }
387
388 switch (insn)
389 {
390 case 0x58: /* pop %rax/r8 */
391 case 0x59: /* pop %rcx/r9 */
392 case 0x5a: /* pop %rdx/r10 */
393 case 0x5b: /* pop %rbx/r11 */
394 case 0x5c: /* pop %rsp/r12 */
395 case 0x5d: /* pop %rbp/r13 */
396 case 0x5e: /* pop %rsi/r14 */
397 case 0x5f: /* pop %rdi/r15 */
398 if (!sw_read_mem(csw, context->Rsp, &val64, sizeof(DWORD64))) return FALSE;
399 set_int_reg(context, insn - 0x58 + (rex & 1) * 8, val64);
400 context->Rsp += sizeof(ULONG64);
401 pc++;
402 continue;
403 case 0x81: /* add $nnnn,%rsp */
404 if (!sw_read_mem(csw, pc + 2, &val32, sizeof(LONG))) return FALSE;
405 context->Rsp += val32;
406 pc += 2 + sizeof(LONG);
407 continue;
408 case 0x83: /* add $n,%rsp */
409 if (!sw_read_mem(csw, pc + 2, &val8, sizeof(BYTE))) return FALSE;
410 context->Rsp += (signed char)val8;
411 pc += 3;
412 continue;
413 case 0x8d:
414 if (!sw_read_mem(csw, pc + 1, &insn, sizeof(BYTE))) return FALSE;
415 if ((insn >> 6) == 1) /* lea n(reg),%rsp */
416 {
417 if (!sw_read_mem(csw, pc + 2, &val8, sizeof(BYTE))) return FALSE;
418 context->Rsp = get_int_reg( context, (insn & 7) + (rex & 1) * 8 ) + (signed char)val8;
419 pc += 3;
420 }
421 else /* lea nnnn(reg),%rsp */
422 {
423 if (!sw_read_mem(csw, pc + 2, &val32, sizeof(LONG))) return FALSE;
424 context->Rsp = get_int_reg( context, (insn & 7) + (rex & 1) * 8 ) + val32;
425 pc += 2 + sizeof(LONG);
426 }
427 continue;
428 case 0xc2: /* ret $nn */
429 if (!sw_read_mem(csw, context->Rsp, &val64, sizeof(DWORD64))) return FALSE;
430 if (!sw_read_mem(csw, pc + 1, &val16, sizeof(WORD))) return FALSE;
431 context->Rip = val64;
432 context->Rsp += sizeof(ULONG64) + val16;
433 return TRUE;
434 case 0xc3: /* ret */
435 case 0xf3: /* rep; ret */
436 if (!sw_read_mem(csw, context->Rsp, &val64, sizeof(DWORD64))) return FALSE;
437 context->Rip = val64;
438 context->Rsp += sizeof(ULONG64);
439 return TRUE;
440 case 0xe9: /* jmp nnnn */
441 if (!sw_read_mem(csw, pc + 1, &val32, sizeof(LONG))) return FALSE;
442 pc += 5 + val32;
443 continue;
444 case 0xeb: /* jmp n */
445 if (!sw_read_mem(csw, pc + 1, &val8, sizeof(BYTE))) return FALSE;
446 pc += 2 + (signed char)val8;
447 continue;
448 }
449 FIXME("unsupported insn %x\n", insn);
450 return FALSE;
451 }
452}
453
454static BOOL default_unwind(struct cpu_stack_walk* csw, CONTEXT* context)
455{
456 if (!sw_read_mem(csw, context->Rsp, &context->Rip, sizeof(DWORD64)))
457 {
458 WARN("Cannot read new frame offset %s\n", wine_dbgstr_longlong(context->Rsp));
459 return FALSE;
460 }
461 context->Rsp += sizeof(DWORD64);
462 return TRUE;
463}
464
465static BOOL interpret_function_table_entry(struct cpu_stack_walk* csw,
467{
468 char buffer[sizeof(UNWIND_INFO) + 256 * sizeof(UNWIND_CODE)];
470 unsigned i;
471 DWORD64 newframe, prolog_offset, off, value;
472 M128A floatvalue;
473 union handler_data handler_data;
474
475 /* FIXME: we have some assumptions here */
477 dump_unwind_info(csw, sw_module_base(csw, context->Rip), function);
478 newframe = context->Rsp;
479 for (;;)
480 {
481 if (!sw_read_mem(csw, base + function->UnwindData, info, sizeof(*info)) ||
482 !sw_read_mem(csw, base + function->UnwindData + FIELD_OFFSET(UNWIND_INFO, UnwindCode),
483 info->UnwindCode, info->CountOfCodes * sizeof(UNWIND_CODE)))
484 {
485 WARN("Couldn't read unwind_code at %lx\n", base + function->UnwindData);
486 return FALSE;
487 }
488
489 if (info->Version != 1)
490 {
491 WARN("unknown unwind info version %u at %lx\n", info->Version, base + function->UnwindData);
492 return FALSE;
493 }
494
495 if (info->FrameRegister)
496 newframe = get_int_reg(context, info->FrameRegister) - info->FrameOffset * 16;
497
498 /* check if in prolog */
499 if (context->Rip >= base + function->BeginAddress &&
500 context->Rip < base + function->BeginAddress + info->SizeOfProlog)
501 {
502 prolog_offset = context->Rip - base - function->BeginAddress;
503 }
504 else
505 {
506 prolog_offset = ~0;
507 if (is_inside_epilog(csw, context->Rip, base, function))
508 {
509 interpret_epilog(csw, context->Rip, context);
510 return TRUE;
511 }
512 }
513
514 for (i = 0; i < info->CountOfCodes; i += get_opcode_size(info->UnwindCode[i]))
515 {
516 if (prolog_offset < info->UnwindCode[i].u.CodeOffset) continue; /* skip it */
517
518 switch (info->UnwindCode[i].u.UnwindOp)
519 {
520 case UWOP_PUSH_NONVOL: /* pushq %reg */
521 if (!sw_read_mem(csw, context->Rsp, &value, sizeof(DWORD64))) return FALSE;
522 set_int_reg(context, info->UnwindCode[i].u.OpInfo, value);
523 context->Rsp += sizeof(ULONG64);
524 break;
525 case UWOP_ALLOC_LARGE: /* subq $nn,%rsp */
526 if (info->UnwindCode[i].u.OpInfo) context->Rsp += *(DWORD*)&info->UnwindCode[i+1];
527 else context->Rsp += *(USHORT*)&info->UnwindCode[i+1] * 8;
528 break;
529 case UWOP_ALLOC_SMALL: /* subq $n,%rsp */
530 context->Rsp += (info->UnwindCode[i].u.OpInfo + 1) * 8;
531 break;
532 case UWOP_SET_FPREG: /* leaq nn(%rsp),%framereg */
533 context->Rsp = newframe;
534 break;
535 case UWOP_SAVE_NONVOL: /* movq %reg,n(%rsp) */
536 off = newframe + *(USHORT*)&info->UnwindCode[i+1] * 8;
537 if (!sw_read_mem(csw, off, &value, sizeof(DWORD64))) return FALSE;
538 set_int_reg(context, info->UnwindCode[i].u.OpInfo, value);
539 break;
540 case UWOP_SAVE_NONVOL_FAR: /* movq %reg,nn(%rsp) */
541 off = newframe + *(DWORD*)&info->UnwindCode[i+1];
542 if (!sw_read_mem(csw, off, &value, sizeof(DWORD64))) return FALSE;
543 set_int_reg(context, info->UnwindCode[i].u.OpInfo, value);
544 break;
545 case UWOP_SAVE_XMM128: /* movaps %xmmreg,n(%rsp) */
546 off = newframe + *(USHORT*)&info->UnwindCode[i+1] * 16;
547 if (!sw_read_mem(csw, off, &floatvalue, sizeof(M128A))) return FALSE;
548 set_float_reg(context, info->UnwindCode[i].u.OpInfo, floatvalue);
549 break;
550 case UWOP_SAVE_XMM128_FAR: /* movaps %xmmreg,nn(%rsp) */
551 off = newframe + *(DWORD*)&info->UnwindCode[i+1];
552 if (!sw_read_mem(csw, off, &floatvalue, sizeof(M128A))) return FALSE;
553 set_float_reg(context, info->UnwindCode[i].u.OpInfo, floatvalue);
554 break;
556 FIXME("PUSH_MACHFRAME %u\n", info->UnwindCode[i].u.OpInfo);
557 break;
558 default:
559 FIXME("unknown code %u\n", info->UnwindCode[i].u.UnwindOp);
560 break;
561 }
562 }
563 if (!(info->Flags & UNW_FLAG_CHAININFO)) break;
564 if (!sw_read_mem(csw, base + function->UnwindData + FIELD_OFFSET(UNWIND_INFO, UnwindCode) +
565 ((info->CountOfCodes + 1) & ~1) * sizeof(UNWIND_CODE),
566 &handler_data, sizeof(handler_data))) return FALSE;
567 function = &handler_data.chain; /* restart with the chained info */
568 }
569 return default_unwind(csw, context);
570}
571
572/* fetch_next_frame()
573 *
574 * modify (at least) context.{rip, rsp, rbp} using unwind information
575 * either out of PE exception handlers, debug info (dwarf), or simple stack unwind
576 */
577static BOOL fetch_next_frame(struct cpu_stack_walk *csw, union ctx *pcontext,
578 DWORD_PTR curr_pc, void** prtf)
579{
580 DWORD64 cfa;
581 RUNTIME_FUNCTION* rtf;
583 CONTEXT *context = &pcontext->ctx;
584
585 if (!curr_pc || !(base = sw_module_base(csw, curr_pc))) return FALSE;
586 rtf = sw_table_access(csw, curr_pc);
587 if (prtf) *prtf = rtf;
588 if (rtf)
589 {
590 return interpret_function_table_entry(csw, context, rtf, base);
591 }
592 else if (dwarf2_virtual_unwind(csw, curr_pc, pcontext, &cfa))
593 {
594 context->Rsp = cfa;
595 TRACE("next function rip=%016lx\n", context->Rip);
596 TRACE(" rax=%016lx rbx=%016lx rcx=%016lx rdx=%016lx\n",
597 context->Rax, context->Rbx, context->Rcx, context->Rdx);
598 TRACE(" rsi=%016lx rdi=%016lx rbp=%016lx rsp=%016lx\n",
599 context->Rsi, context->Rdi, context->Rbp, context->Rsp);
600 TRACE(" r8=%016lx r9=%016lx r10=%016lx r11=%016lx\n",
601 context->R8, context->R9, context->R10, context->R11);
602 TRACE(" r12=%016lx r13=%016lx r14=%016lx r15=%016lx\n",
603 context->R12, context->R13, context->R14, context->R15);
604 return TRUE;
605 }
606 else
607 return default_unwind(csw, context);
608}
609
610static BOOL x86_64_stack_walk(struct cpu_stack_walk *csw, STACKFRAME64 *frame,
611 union ctx *context)
612{
613 unsigned deltapc = curr_count <= 1 ? 0 : 1;
614
615 /* sanity check */
616 if (curr_mode >= stm_done) return FALSE;
617 assert(!csw->is32);
618
619 TRACE("Enter: PC=%s Frame=%s Return=%s Stack=%s Mode=%s Count=%s\n",
620 wine_dbgstr_addr(&frame->AddrPC),
624 curr_mode == stm_start ? "start" : "64bit",
626
627 if (curr_mode == stm_start)
628 {
629 if ((frame->AddrPC.Mode == AddrModeFlat) &&
630 (frame->AddrFrame.Mode != AddrModeFlat))
631 {
632 WARN("Bad AddrPC.Mode / AddrFrame.Mode combination\n");
633 goto done_err;
634 }
635
636 /* Init done */
637 curr_mode = stm_64bit;
638 frame->AddrReturn.Mode = frame->AddrStack.Mode = AddrModeFlat;
639 /* don't set up AddrStack on first call. Either the caller has set it up, or
640 * we will get it in the next frame
641 */
642 memset(&frame->AddrBStore, 0, sizeof(frame->AddrBStore));
643 }
644 else
645 {
646 if (context->ctx.Rsp != frame->AddrStack.Offset) FIXME("inconsistent Stack Pointer\n");
647 if (context->ctx.Rip != frame->AddrPC.Offset) FIXME("inconsistent Instruction Pointer\n");
648
649 if (frame->AddrReturn.Offset == 0) goto done_err;
650 if (!fetch_next_frame(csw, context, frame->AddrPC.Offset - deltapc, &frame->FuncTableEntry))
651 goto done_err;
652 deltapc = 1;
653 }
654
655 memset(&frame->Params, 0, sizeof(frame->Params));
656
657 /* set frame information */
658 frame->AddrStack.Offset = context->ctx.Rsp;
659 frame->AddrFrame.Offset = context->ctx.Rbp;
660 frame->AddrPC.Offset = context->ctx.Rip;
661 if (1)
662 {
663 union ctx newctx = *context;
664
665 if (!fetch_next_frame(csw, &newctx, frame->AddrPC.Offset - deltapc, NULL))
666 goto done_err;
668 frame->AddrReturn.Offset = newctx.ctx.Rip;
669 }
670
671 frame->Far = TRUE;
672 frame->Virtual = TRUE;
673 curr_count++;
674
675 TRACE("Leave: PC=%s Frame=%s Return=%s Stack=%s Mode=%s Count=%s FuncTable=%p\n",
676 wine_dbgstr_addr(&frame->AddrPC),
680 curr_mode == stm_start ? "start" : "64bit",
682 frame->FuncTableEntry);
683
684 return TRUE;
685done_err:
687 return FALSE;
688}
689#else
691 union ctx *ctx)
692{
693 return FALSE;
694}
695#endif
696
698{
699#ifdef __x86_64__
700 RUNTIME_FUNCTION* rtf;
701 ULONG size;
702 int min, max;
703
705 if (rtf) for (min = 0, max = size / sizeof(*rtf); min <= max; )
706 {
707 int pos = (min + max) / 2;
708 if (addr < module->module.BaseOfImage + rtf[pos].BeginAddress) max = pos - 1;
709 else if (addr >= module->module.BaseOfImage + rtf[pos].EndAddress) min = pos + 1;
710 else
711 {
712 rtf += pos;
713 while (rtf->UnwindData & 1) /* follow chained entry */
714 {
715 FIXME("RunTime_Function outside IMAGE_DIRECTORY_ENTRY_EXCEPTION unimplemented yet!\n");
716 return NULL;
717 /* we need to read into the other process */
718 /* rtf = (RUNTIME_FUNCTION*)(module->module.BaseOfImage + (rtf->UnwindData & ~1)); */
719 }
720 return rtf;
721 }
722 }
723#endif
724 return NULL;
725}
726
727static unsigned x86_64_map_dwarf_register(unsigned regno, const struct module* module, BOOL eh_frame)
728{
729 unsigned reg;
730
731 if (regno >= 17 && regno <= 24)
732 reg = CV_AMD64_XMM0 + regno - 17;
733 else if (regno >= 25 && regno <= 32)
734 reg = CV_AMD64_XMM8 + regno - 25;
735 else if (regno >= 33 && regno <= 40)
736 reg = CV_AMD64_ST0 + regno - 33;
737 else switch (regno)
738 {
739 case 0: reg = CV_AMD64_RAX; break;
740 case 1: reg = CV_AMD64_RDX; break;
741 case 2: reg = CV_AMD64_RCX; break;
742 case 3: reg = CV_AMD64_RBX; break;
743 case 4: reg = CV_AMD64_RSI; break;
744 case 5: reg = CV_AMD64_RDI; break;
745 case 6: reg = CV_AMD64_RBP; break;
746 case 7: reg = CV_AMD64_RSP; break;
747 case 8: reg = CV_AMD64_R8; break;
748 case 9: reg = CV_AMD64_R9; break;
749 case 10: reg = CV_AMD64_R10; break;
750 case 11: reg = CV_AMD64_R11; break;
751 case 12: reg = CV_AMD64_R12; break;
752 case 13: reg = CV_AMD64_R13; break;
753 case 14: reg = CV_AMD64_R14; break;
754 case 15: reg = CV_AMD64_R15; break;
755 case 16: reg = CV_AMD64_RIP; break;
756 case 49: reg = CV_AMD64_EFLAGS; break;
757 case 50: reg = CV_AMD64_ES; break;
758 case 51: reg = CV_AMD64_CS; break;
759 case 52: reg = CV_AMD64_SS; break;
760 case 53: reg = CV_AMD64_DS; break;
761 case 54: reg = CV_AMD64_FS; break;
762 case 55: reg = CV_AMD64_GS; break;
763 case 62: reg = CV_AMD64_TR; break;
764 case 63: reg = CV_AMD64_LDTR; break;
765 case 64: reg = CV_AMD64_MXCSR; break;
766 case 65: reg = CV_AMD64_CTRL; break;
767 case 66: reg = CV_AMD64_STAT; break;
768/*
769 * 56-57 reserved
770 * 58 %fs.base
771 * 59 %gs.base
772 * 60-61 reserved
773 */
774 default:
775 FIXME("Don't know how to map register %d\n", regno);
776 return 0;
777 }
778 return reg;
779}
780
781static void *x86_64_fetch_context_reg(union ctx *pctx, unsigned regno, unsigned *size)
782{
783#ifdef __x86_64__
784 CONTEXT *ctx = &pctx->ctx;
785
786 switch (regno)
787 {
788 case CV_AMD64_RAX: *size = sizeof(ctx->Rax); return &ctx->Rax;
789 case CV_AMD64_RDX: *size = sizeof(ctx->Rdx); return &ctx->Rdx;
790 case CV_AMD64_RCX: *size = sizeof(ctx->Rcx); return &ctx->Rcx;
791 case CV_AMD64_RBX: *size = sizeof(ctx->Rbx); return &ctx->Rbx;
792 case CV_AMD64_RSI: *size = sizeof(ctx->Rsi); return &ctx->Rsi;
793 case CV_AMD64_RDI: *size = sizeof(ctx->Rdi); return &ctx->Rdi;
794 case CV_AMD64_RBP: *size = sizeof(ctx->Rbp); return &ctx->Rbp;
795 case CV_AMD64_RSP: *size = sizeof(ctx->Rsp); return &ctx->Rsp;
796 case CV_AMD64_R8: *size = sizeof(ctx->R8); return &ctx->R8;
797 case CV_AMD64_R9: *size = sizeof(ctx->R9); return &ctx->R9;
798 case CV_AMD64_R10: *size = sizeof(ctx->R10); return &ctx->R10;
799 case CV_AMD64_R11: *size = sizeof(ctx->R11); return &ctx->R11;
800 case CV_AMD64_R12: *size = sizeof(ctx->R12); return &ctx->R12;
801 case CV_AMD64_R13: *size = sizeof(ctx->R13); return &ctx->R13;
802 case CV_AMD64_R14: *size = sizeof(ctx->R14); return &ctx->R14;
803 case CV_AMD64_R15: *size = sizeof(ctx->R15); return &ctx->R15;
804 case CV_AMD64_RIP: *size = sizeof(ctx->Rip); return &ctx->Rip;
805
806 case CV_AMD64_XMM0 + 0: *size = sizeof(ctx->u.s.Xmm0 ); return &ctx->u.s.Xmm0;
807 case CV_AMD64_XMM0 + 1: *size = sizeof(ctx->u.s.Xmm1 ); return &ctx->u.s.Xmm1;
808 case CV_AMD64_XMM0 + 2: *size = sizeof(ctx->u.s.Xmm2 ); return &ctx->u.s.Xmm2;
809 case CV_AMD64_XMM0 + 3: *size = sizeof(ctx->u.s.Xmm3 ); return &ctx->u.s.Xmm3;
810 case CV_AMD64_XMM0 + 4: *size = sizeof(ctx->u.s.Xmm4 ); return &ctx->u.s.Xmm4;
811 case CV_AMD64_XMM0 + 5: *size = sizeof(ctx->u.s.Xmm5 ); return &ctx->u.s.Xmm5;
812 case CV_AMD64_XMM0 + 6: *size = sizeof(ctx->u.s.Xmm6 ); return &ctx->u.s.Xmm6;
813 case CV_AMD64_XMM0 + 7: *size = sizeof(ctx->u.s.Xmm7 ); return &ctx->u.s.Xmm7;
814 case CV_AMD64_XMM8 + 0: *size = sizeof(ctx->u.s.Xmm8 ); return &ctx->u.s.Xmm8;
815 case CV_AMD64_XMM8 + 1: *size = sizeof(ctx->u.s.Xmm9 ); return &ctx->u.s.Xmm9;
816 case CV_AMD64_XMM8 + 2: *size = sizeof(ctx->u.s.Xmm10); return &ctx->u.s.Xmm10;
817 case CV_AMD64_XMM8 + 3: *size = sizeof(ctx->u.s.Xmm11); return &ctx->u.s.Xmm11;
818 case CV_AMD64_XMM8 + 4: *size = sizeof(ctx->u.s.Xmm12); return &ctx->u.s.Xmm12;
819 case CV_AMD64_XMM8 + 5: *size = sizeof(ctx->u.s.Xmm13); return &ctx->u.s.Xmm13;
820 case CV_AMD64_XMM8 + 6: *size = sizeof(ctx->u.s.Xmm14); return &ctx->u.s.Xmm14;
821 case CV_AMD64_XMM8 + 7: *size = sizeof(ctx->u.s.Xmm15); return &ctx->u.s.Xmm15;
822
823 case CV_AMD64_ST0 + 0: *size = sizeof(ctx->u.s.Legacy[0]); return &ctx->u.s.Legacy[0];
824 case CV_AMD64_ST0 + 1: *size = sizeof(ctx->u.s.Legacy[1]); return &ctx->u.s.Legacy[1];
825 case CV_AMD64_ST0 + 2: *size = sizeof(ctx->u.s.Legacy[2]); return &ctx->u.s.Legacy[2];
826 case CV_AMD64_ST0 + 3: *size = sizeof(ctx->u.s.Legacy[3]); return &ctx->u.s.Legacy[3];
827 case CV_AMD64_ST0 + 4: *size = sizeof(ctx->u.s.Legacy[4]); return &ctx->u.s.Legacy[4];
828 case CV_AMD64_ST0 + 5: *size = sizeof(ctx->u.s.Legacy[5]); return &ctx->u.s.Legacy[5];
829 case CV_AMD64_ST0 + 6: *size = sizeof(ctx->u.s.Legacy[6]); return &ctx->u.s.Legacy[6];
830 case CV_AMD64_ST0 + 7: *size = sizeof(ctx->u.s.Legacy[7]); return &ctx->u.s.Legacy[7];
831
832 case CV_AMD64_EFLAGS: *size = sizeof(ctx->EFlags); return &ctx->EFlags;
833 case CV_AMD64_ES: *size = sizeof(ctx->SegEs); return &ctx->SegEs;
834 case CV_AMD64_CS: *size = sizeof(ctx->SegCs); return &ctx->SegCs;
835 case CV_AMD64_SS: *size = sizeof(ctx->SegSs); return &ctx->SegSs;
836 case CV_AMD64_DS: *size = sizeof(ctx->SegDs); return &ctx->SegDs;
837 case CV_AMD64_FS: *size = sizeof(ctx->SegFs); return &ctx->SegFs;
838 case CV_AMD64_GS: *size = sizeof(ctx->SegGs); return &ctx->SegGs;
839
840 }
841#endif
842 FIXME("Unknown register %x\n", regno);
843 return NULL;
844}
845
846static const char* x86_64_fetch_regname(unsigned regno)
847{
848 switch (regno)
849 {
850 case CV_AMD64_RAX: return "rax";
851 case CV_AMD64_RDX: return "rdx";
852 case CV_AMD64_RCX: return "rcx";
853 case CV_AMD64_RBX: return "rbx";
854 case CV_AMD64_RSI: return "rsi";
855 case CV_AMD64_RDI: return "rdi";
856 case CV_AMD64_RBP: return "rbp";
857 case CV_AMD64_RSP: return "rsp";
858 case CV_AMD64_R8: return "r8";
859 case CV_AMD64_R9: return "r9";
860 case CV_AMD64_R10: return "r10";
861 case CV_AMD64_R11: return "r11";
862 case CV_AMD64_R12: return "r12";
863 case CV_AMD64_R13: return "r13";
864 case CV_AMD64_R14: return "r14";
865 case CV_AMD64_R15: return "r15";
866 case CV_AMD64_RIP: return "rip";
867
868 case CV_AMD64_XMM0 + 0: return "xmm0";
869 case CV_AMD64_XMM0 + 1: return "xmm1";
870 case CV_AMD64_XMM0 + 2: return "xmm2";
871 case CV_AMD64_XMM0 + 3: return "xmm3";
872 case CV_AMD64_XMM0 + 4: return "xmm4";
873 case CV_AMD64_XMM0 + 5: return "xmm5";
874 case CV_AMD64_XMM0 + 6: return "xmm6";
875 case CV_AMD64_XMM0 + 7: return "xmm7";
876 case CV_AMD64_XMM8 + 0: return "xmm8";
877 case CV_AMD64_XMM8 + 1: return "xmm9";
878 case CV_AMD64_XMM8 + 2: return "xmm10";
879 case CV_AMD64_XMM8 + 3: return "xmm11";
880 case CV_AMD64_XMM8 + 4: return "xmm12";
881 case CV_AMD64_XMM8 + 5: return "xmm13";
882 case CV_AMD64_XMM8 + 6: return "xmm14";
883 case CV_AMD64_XMM8 + 7: return "xmm15";
884
885 case CV_AMD64_ST0 + 0: return "st0";
886 case CV_AMD64_ST0 + 1: return "st1";
887 case CV_AMD64_ST0 + 2: return "st2";
888 case CV_AMD64_ST0 + 3: return "st3";
889 case CV_AMD64_ST0 + 4: return "st4";
890 case CV_AMD64_ST0 + 5: return "st5";
891 case CV_AMD64_ST0 + 6: return "st6";
892 case CV_AMD64_ST0 + 7: return "st7";
893
894 case CV_AMD64_EFLAGS: return "eflags";
895 case CV_AMD64_ES: return "es";
896 case CV_AMD64_CS: return "cs";
897 case CV_AMD64_SS: return "ss";
898 case CV_AMD64_DS: return "ds";
899 case CV_AMD64_FS: return "fs";
900 case CV_AMD64_GS: return "gs";
901 }
902 FIXME("Unknown register %x\n", regno);
903 return NULL;
904}
905
906static BOOL x86_64_fetch_minidump_thread(struct dump_context* dc, unsigned index, unsigned flags, const CONTEXT* ctx)
907{
908 if (ctx->ContextFlags && (flags & ThreadWriteInstructionWindow))
909 {
910 /* FIXME: crop values across module boundaries, */
911#ifdef __x86_64__
912 ULONG64 base = ctx->Rip <= 0x80 ? 0 : ctx->Rip - 0x80;
913 minidump_add_memory_block(dc, base, ctx->Rip + 0x80 - base, 0);
914#endif
915 }
916
917 return TRUE;
918}
919
920static BOOL x86_64_fetch_minidump_module(struct dump_context* dc, unsigned index, unsigned flags)
921{
922 /* FIXME: not sure about the flags... */
923 if (1)
924 {
925 /* FIXME: crop values across module boundaries, */
926#ifdef __x86_64__
927 struct process* pcs;
928 struct module* module;
929 const RUNTIME_FUNCTION* rtf;
930 ULONG size;
931
932 if (!(pcs = process_find_by_handle(dc->process->handle)) ||
933 !(module = module_find_by_addr(pcs, dc->modules[index].base, DMT_UNKNOWN)))
934 return FALSE;
936 if (rtf)
937 {
938 const RUNTIME_FUNCTION* end = (const RUNTIME_FUNCTION*)((const char*)rtf + size);
940
941 while (rtf + 1 < end)
942 {
943 while (rtf->UnwindData & 1) /* follow chained entry */
944 {
945 FIXME("RunTime_Function outside IMAGE_DIRECTORY_ENTRY_EXCEPTION unimplemented yet!\n");
946 return FALSE;
947 /* we need to read into the other process */
948 /* rtf = (RUNTIME_FUNCTION*)(module->module.BaseOfImage + (rtf->UnwindData & ~1)); */
949 }
950 if (read_process_memory(dc->process, dc->modules[index].base + rtf->UnwindData, &ui, sizeof(ui)))
951 minidump_add_memory_block(dc, dc->modules[index].base + rtf->UnwindData,
952 FIELD_OFFSET(UNWIND_INFO, UnwindCode) + ui.CountOfCodes * sizeof(UNWIND_CODE), 0);
953 rtf++;
954 }
955 }
956#endif
957 }
958
959 return TRUE;
960}
961
964 8,
974};
#define WINE_DEFAULT_DEBUG_CHANNEL(t)
Definition: precomp.h:23
#define FIXME(fmt,...)
Definition: debug.h:111
#define WARN(fmt,...)
Definition: debug.h:112
st_mode
Definition: cpu_i386.c:139
@ stm_start
Definition: cpu_i386.c:139
@ stm_done
Definition: cpu_i386.c:139
#define curr_count
Definition: cpu_i386.c:147
#define curr_mode
Definition: cpu_i386.c:146
static BOOL x86_64_stack_walk(struct cpu_stack_walk *csw, STACKFRAME64 *frame, union ctx *ctx)
Definition: cpu_x86_64.c:690
enum _UNWIND_OP_CODES UNWIND_CODE_OPS
static BOOL x86_64_fetch_minidump_module(struct dump_context *dc, unsigned index, unsigned flags)
Definition: cpu_x86_64.c:920
union _UNWIND_CODE UNWIND_CODE
struct _UNWIND_INFO * PUNWIND_INFO
static BOOL x86_64_get_addr(HANDLE hThread, const CONTEXT *ctx, enum cpu_addr ca, ADDRESS64 *addr)
Definition: cpu_x86_64.c:79
_UNWIND_OP_CODES
Definition: cpu_x86_64.c:37
@ UWOP_SET_FPREG
Definition: cpu_x86_64.c:41
@ UWOP_SAVE_XMM128_FAR
Definition: cpu_x86_64.c:45
@ UWOP_ALLOC_LARGE
Definition: cpu_x86_64.c:39
@ UWOP_PUSH_MACHFRAME
Definition: cpu_x86_64.c:46
@ UWOP_SAVE_XMM128
Definition: cpu_x86_64.c:44
@ UWOP_SAVE_NONVOL_FAR
Definition: cpu_x86_64.c:43
@ UWOP_PUSH_NONVOL
Definition: cpu_x86_64.c:38
@ UWOP_ALLOC_SMALL
Definition: cpu_x86_64.c:40
@ UWOP_SAVE_NONVOL
Definition: cpu_x86_64.c:42
struct _UNWIND_INFO UNWIND_INFO
static void * x86_64_find_runtime_function(struct module *module, DWORD64 addr)
Definition: cpu_x86_64.c:697
union _UNWIND_CODE * PUNWIND_CODE
static const char * x86_64_fetch_regname(unsigned regno)
Definition: cpu_x86_64.c:846
DECLSPEC_HIDDEN struct cpu cpu_x86_64
Definition: cpu_x86_64.c:962
static BOOL x86_64_fetch_minidump_thread(struct dump_context *dc, unsigned index, unsigned flags, const CONTEXT *ctx)
Definition: cpu_x86_64.c:906
static void * x86_64_fetch_context_reg(union ctx *pctx, unsigned regno, unsigned *size)
Definition: cpu_x86_64.c:781
static unsigned x86_64_map_dwarf_register(unsigned regno, const struct module *module, BOOL eh_frame)
Definition: cpu_x86_64.c:727
cpu_addr
@ cpu_addr_frame
@ cpu_addr_pc
@ cpu_addr_stack
void * sw_table_access(struct cpu_stack_walk *csw, DWORD64 addr) DECLSPEC_HIDDEN
Definition: stack.c:119
const char * pe_map_directory(struct module *module, int dirno, DWORD *size) DECLSPEC_HIDDEN
Definition: pe_module.c:331
static BOOL read_process_memory(const struct process *process, UINT64 addr, void *buf, size_t size)
BOOL dwarf2_virtual_unwind(struct cpu_stack_walk *csw, DWORD_PTR ip, union ctx *ctx, DWORD64 *cfa) DECLSPEC_HIDDEN
Definition: dwarf.c:3258
DWORD64 sw_module_base(struct cpu_stack_walk *csw, DWORD64 addr) DECLSPEC_HIDDEN
Definition: stack.c:127
void minidump_add_memory_block(struct dump_context *dc, ULONG64 base, ULONG size, ULONG rva) DECLSPEC_HIDDEN
Definition: minidump.c:355
BOOL sw_read_mem(struct cpu_stack_walk *csw, DWORD64 addr, void *ptr, DWORD sz) DECLSPEC_HIDDEN
Definition: stack.c:95
struct module * module_find_by_addr(const struct process *pcs, DWORD64 addr, enum module_type type) DECLSPEC_HIDDEN
Definition: module.c:420
@ DMT_UNKNOWN
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
UINT op
Definition: effect.c:236
#define DECLSPEC_HIDDEN
Definition: precomp.h:8
static const WCHAR ca[]
Definition: main.c:455
@ AddrModeFlat
Definition: compat.h:1159
static __inline const char * wine_dbgstr_longlong(ULONGLONG ll)
Definition: compat.h:49
@ CV_AMD64_XMM8
Definition: compat.h:2186
@ CV_AMD64_RSI
Definition: compat.h:2192
@ CV_AMD64_XMM0
Definition: compat.h:2161
@ CV_AMD64_RIP
Definition: compat.h:2129
@ CV_AMD64_R9
Definition: compat.h:2198
@ CV_AMD64_LDTR
Definition: compat.h:2145
@ CV_AMD64_ST0
Definition: compat.h:2149
@ CV_AMD64_CS
Definition: compat.h:2123
@ CV_AMD64_R13
Definition: compat.h:2202
@ CV_AMD64_MXCSR
Definition: compat.h:2165
@ CV_AMD64_RBX
Definition: compat.h:2189
@ CV_AMD64_RDI
Definition: compat.h:2193
@ CV_AMD64_FS
Definition: compat.h:2126
@ CV_AMD64_CTRL
Definition: compat.h:2150
@ CV_AMD64_STAT
Definition: compat.h:2151
@ CV_AMD64_ES
Definition: compat.h:2122
@ CV_AMD64_EFLAGS
Definition: compat.h:2130
@ CV_AMD64_SS
Definition: compat.h:2124
@ CV_AMD64_R15
Definition: compat.h:2204
@ CV_AMD64_R14
Definition: compat.h:2203
@ CV_AMD64_R12
Definition: compat.h:2201
@ CV_AMD64_RDX
Definition: compat.h:2191
@ CV_AMD64_R11
Definition: compat.h:2200
@ CV_AMD64_R8
Definition: compat.h:2197
@ CV_AMD64_TR
Definition: compat.h:2146
@ CV_AMD64_RBP
Definition: compat.h:2194
@ CV_AMD64_RAX
Definition: compat.h:2188
@ CV_AMD64_GS
Definition: compat.h:2127
@ CV_AMD64_RCX
Definition: compat.h:2190
@ CV_AMD64_RSP
Definition: compat.h:2195
@ CV_AMD64_R10
Definition: compat.h:2199
@ CV_AMD64_DS
Definition: compat.h:2125
@ ThreadWriteInstructionWindow
Definition: compat.h:1150
const char * wine_dbgstr_addr(const ADDRESS64 *addr)
Definition: dbghelp.c:142
struct process * process_find_by_handle(HANDLE hProcess)
Definition: dbghelp.c:99
UINT(* handler)(MSIPACKAGE *)
Definition: action.c:7482
unsigned char
Definition: typeof.h:29
#define assert(x)
Definition: debug.h:53
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
unsigned short WORD
Definition: ntddk_ex.h:93
GLuint GLuint end
Definition: gl.h:1545
GLuint GLuint GLsizei count
Definition: gl.h:1545
GLsizeiptr size
Definition: glext.h:5919
GLuint buffer
Definition: glext.h:5915
GLuint index
Definition: glext.h:6031
GLbitfield flags
Definition: glext.h:7161
GLenum const GLvoid * addr
Definition: glext.h:9621
GLuint GLfloat * val
Definition: glext.h:7180
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble * u
Definition: glfuncs.h:240
static int rex
Definition: i386-dis.c:279
static int reg
Definition: i386-dis.c:1290
if(dx< 0)
Definition: linetemp.h:194
static const WCHAR dc[]
unsigned __int64 ULONG64
Definition: imports.h:198
#define min(a, b)
Definition: monoChain.cc:55
HANDLE hThread
Definition: wizard.c:28
#define IMAGE_FILE_MACHINE_AMD64
Definition: ntimage.h:17
UINT ui
Definition: oleauto.h:49
#define IMAGE_DIRECTORY_ENTRY_EXCEPTION
Definition: pedump.c:262
long LONG
Definition: pedump.c:60
unsigned short USHORT
Definition: pedump.c:61
@ UNW_FLAG_EHANDLER
Definition: rsym64.h:109
@ UNW_FLAG_CHAININFO
Definition: rsym64.h:111
@ UNW_FLAG_UHANDLER
Definition: rsym64.h:110
#define memset(x, y, z)
Definition: compat.h:39
#define TRACE(s)
Definition: solgame.cpp:4
DWORD64 BaseOfImage
Definition: compat.h:1070
PVOID FuncTableEntry
Definition: compat.h:1406
ADDRESS64 AddrBStore
Definition: compat.h:1405
ADDRESS64 AddrStack
Definition: compat.h:1404
ADDRESS64 AddrFrame
Definition: compat.h:1403
ADDRESS64 AddrPC
Definition: compat.h:1401
DWORD64 Params[4]
Definition: compat.h:1407
BOOL Virtual
Definition: compat.h:1409
ADDRESS64 AddrReturn
Definition: compat.h:1402
BYTE CountOfCodes
Definition: cpu_x86_64.c:65
BYTE FrameRegister
Definition: cpu_x86_64.c:66
BYTE Version
Definition: cpu_x86_64.c:62
BYTE SizeOfProlog
Definition: cpu_x86_64.c:64
UNWIND_CODE UnwindCode[1]
Definition: cpu_x86_64.c:68
BYTE FrameOffset
Definition: cpu_x86_64.c:67
ADDRESS_MODE Mode
Definition: compat.h:1176
DWORD64 Offset
Definition: compat.h:1174
Definition: http.c:7252
IMAGEHLP_MODULEW64 module
#define max(a, b)
Definition: svc.c:63
struct sock * chain
Definition: tcpcore.h:1
uint32_t DWORD_PTR
Definition: typedefs.h:65
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:255
uint64_t DWORD64
Definition: typedefs.h:67
uint32_t ULONG
Definition: typedefs.h:59
BYTE UnwindOp
Definition: cpu_x86_64.c:54
BYTE CodeOffset
Definition: cpu_x86_64.c:53
USHORT FrameOffset
Definition: cpu_x86_64.c:57
struct _UNWIND_CODE::@371 u
CONTEXT ctx
Definition: pdh_main.c:94
M128A
Definition: ketypes.h:937
unsigned char BYTE
Definition: xxhash.c:193