ReactOS  0.4.14-dev-614-gbfd8a84
minidump.c
Go to the documentation of this file.
1 /*
2  * File minidump.c - management of dumps (read & write)
3  *
4  * Copyright (C) 2004-2005, Eric Pouech
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19  */
20 
21 #include <time.h>
22 
23 #define NONAMELESSUNION
24 #define NONAMELESSSTRUCT
25 
26 #include "ntstatus.h"
27 #define WIN32_NO_STATUS
28 #include "dbghelp_private.h"
29 #include "winternl.h"
30 #include "psapi.h"
31 #include "wine/debug.h"
32 
34 
35 /******************************************************************
36  * fetch_process_info
37  *
38  * reads system wide process information, and gather from it the threads information
39  * for process of id 'pid'
40  */
42 {
43  ULONG buf_size = 0x1000;
44  NTSTATUS nts;
45  void* pcs_buffer = NULL;
46 
47  if (!(pcs_buffer = HeapAlloc(GetProcessHeap(), 0, buf_size))) return FALSE;
48  for (;;)
49  {
51  pcs_buffer, buf_size, NULL);
52  if (nts != STATUS_INFO_LENGTH_MISMATCH) break;
53  pcs_buffer = HeapReAlloc(GetProcessHeap(), 0, pcs_buffer, buf_size *= 2);
54  if (!pcs_buffer) return FALSE;
55  }
56 
57  if (nts == STATUS_SUCCESS)
58  {
59  SYSTEM_PROCESS_INFORMATION* spi = pcs_buffer;
60  unsigned i;
61 
62  for (;;)
63  {
64  if (HandleToUlong(spi->UniqueProcessId) == dc->pid)
65  {
66  dc->num_threads = spi->dwThreadCount;
67  dc->threads = HeapAlloc(GetProcessHeap(), 0,
68  dc->num_threads * sizeof(dc->threads[0]));
69  if (!dc->threads) goto failed;
70  for (i = 0; i < dc->num_threads; i++)
71  {
72  dc->threads[i].tid = HandleToULong(spi->ti[i].ClientId.UniqueThread);
73  dc->threads[i].prio_class = spi->ti[i].dwBasePriority; /* FIXME */
74  dc->threads[i].curr_prio = spi->ti[i].dwCurrentPriority;
75  }
76  HeapFree(GetProcessHeap(), 0, pcs_buffer);
77  return TRUE;
78  }
79  if (!spi->NextEntryOffset) break;
80  spi = (SYSTEM_PROCESS_INFORMATION*)((char*)spi + spi->NextEntryOffset);
81  }
82  }
83 failed:
84  HeapFree(GetProcessHeap(), 0, pcs_buffer);
85  return FALSE;
86 }
87 
88 static void fetch_thread_stack(struct dump_context* dc, const void* teb_addr,
89  const CONTEXT* ctx, MINIDUMP_MEMORY_DESCRIPTOR* mmd)
90 {
91  NT_TIB tib;
93 
94  if (ReadProcessMemory(dc->hProcess, teb_addr, &tib, sizeof(tib), NULL) &&
96  dbghelp_current_cpu->get_addr(NULL /* FIXME */, ctx, cpu_addr_stack, &addr) && addr.Mode == AddrModeFlat)
97  {
98  if (addr.Offset)
99  {
100  addr.Offset -= dbghelp_current_cpu->word_size;
101  /* make sure stack pointer is within the established range of the stack. It could have
102  been clobbered by whatever caused the original exception. */
103  if (addr.Offset < (ULONG_PTR)tib.StackLimit || addr.Offset > (ULONG_PTR)tib.StackBase)
105 
106  else
107  mmd->StartOfMemoryRange = addr.Offset;
108  }
109  else
112  }
113 }
114 
115 /******************************************************************
116  * fetch_thread_info
117  *
118  * fetches some information about thread of id 'tid'
119  */
120 static BOOL fetch_thread_info(struct dump_context* dc, int thd_idx,
122  MINIDUMP_THREAD* mdThd, CONTEXT* ctx)
123 {
124  DWORD tid = dc->threads[thd_idx].tid;
125  HANDLE hThread;
127 
128  memset(ctx, 0, sizeof(*ctx));
129 
130  mdThd->ThreadId = tid;
131  mdThd->SuspendCount = 0;
132  mdThd->Teb = 0;
133  mdThd->Stack.StartOfMemoryRange = 0;
134  mdThd->Stack.Memory.DataSize = 0;
135  mdThd->Stack.Memory.Rva = 0;
136  mdThd->ThreadContext.DataSize = 0;
137  mdThd->ThreadContext.Rva = 0;
138  mdThd->PriorityClass = dc->threads[thd_idx].prio_class;
139  mdThd->Priority = dc->threads[thd_idx].curr_prio;
140 
142  {
143  FIXME("Couldn't open thread %u (%u)\n", tid, GetLastError());
144  return FALSE;
145  }
146 
148  &tbi, sizeof(tbi), NULL) == STATUS_SUCCESS)
149  {
150  mdThd->Teb = (ULONG_PTR)tbi.TebBaseAddress;
151  if (tbi.ExitStatus == STILL_ACTIVE)
152  {
153  if (tid != GetCurrentThreadId() &&
154  (mdThd->SuspendCount = SuspendThread(hThread)) != (DWORD)-1)
155  {
156  ctx->ContextFlags = CONTEXT_FULL;
157  if (!GetThreadContext(hThread, ctx))
158  memset(ctx, 0, sizeof(*ctx));
159 
160  fetch_thread_stack(dc, tbi.TebBaseAddress, ctx, &mdThd->Stack);
162  }
163  else if (tid == GetCurrentThreadId() && except)
164  {
165  CONTEXT lctx, *pctx;
166  mdThd->SuspendCount = 1;
167  if (except->ClientPointers)
168  {
170 
171  ReadProcessMemory(dc->hProcess, except->ExceptionPointers,
172  &ep, sizeof(ep), NULL);
173  ReadProcessMemory(dc->hProcess, ep.ContextRecord,
174  &lctx, sizeof(lctx), NULL);
175  pctx = &lctx;
176  }
177  else pctx = except->ExceptionPointers->ContextRecord;
178 
179  *ctx = *pctx;
180  fetch_thread_stack(dc, tbi.TebBaseAddress, pctx, &mdThd->Stack);
181  }
182  else mdThd->SuspendCount = 0;
183  }
184  }
186  return TRUE;
187 }
188 
189 /******************************************************************
190  * add_module
191  *
192  * Add a module to a dump context
193  */
194 static BOOL add_module(struct dump_context* dc, const WCHAR* name,
196  BOOL is_elf)
197 {
198  if (!dc->modules)
199  {
200  dc->alloc_modules = 32;
201  dc->modules = HeapAlloc(GetProcessHeap(), 0,
202  dc->alloc_modules * sizeof(*dc->modules));
203  }
204  else if(dc->num_modules >= dc->alloc_modules)
205  {
206  dc->alloc_modules *= 2;
207  dc->modules = HeapReAlloc(GetProcessHeap(), 0, dc->modules,
208  dc->alloc_modules * sizeof(*dc->modules));
209  }
210  if (!dc->modules)
211  {
212  dc->alloc_modules = dc->num_modules = 0;
213  return FALSE;
214  }
215  if (is_elf ||
217  dc->modules[dc->num_modules].name,
218  sizeof(dc->modules[dc->num_modules].name) / sizeof(WCHAR)))
219  lstrcpynW(dc->modules[dc->num_modules].name, name,
220  sizeof(dc->modules[dc->num_modules].name) / sizeof(WCHAR));
221  dc->modules[dc->num_modules].base = base;
222  dc->modules[dc->num_modules].size = size;
223  dc->modules[dc->num_modules].timestamp = timestamp;
224  dc->modules[dc->num_modules].checksum = checksum;
225  dc->modules[dc->num_modules].is_elf = is_elf;
226  dc->num_modules++;
227 
228  return TRUE;
229 }
230 
231 /******************************************************************
232  * fetch_pe_module_info_cb
233  *
234  * Callback for accumulating in dump_context a PE modules set
235  */
237  PVOID user)
238 {
239  struct dump_context* dc = user;
240  IMAGE_NT_HEADERS nth;
241 
242  if (!validate_addr64(base)) return FALSE;
243 
244  if (pe_load_nt_header(dc->hProcess, base, &nth))
247  FALSE);
248  return TRUE;
249 }
250 
251 /******************************************************************
252  * fetch_elf_module_info_cb
253  *
254  * Callback for accumulating in dump_context an ELF modules set
255  */
256 static BOOL fetch_elf_module_info_cb(const WCHAR* name, unsigned long base,
257  void* user)
258 {
259  struct dump_context* dc = user;
260  DWORD_PTR rbase;
262 
263  /* FIXME: there's no relevant timestamp on ELF modules */
264  /* NB: if we have a non-null base from the live-target use it (whenever
265  * the ELF module is relocatable or not). If we have a null base (ELF
266  * module isn't relocatable) then grab its base address from ELF file
267  */
268  if (!elf_fetch_file_info(name, &rbase, &size, &checksum))
269  size = checksum = 0;
270  add_module(dc, name, base ? base : rbase, size, 0 /* FIXME */, checksum, TRUE);
271  return TRUE;
272 }
273 
274 /******************************************************************
275  * fetch_macho_module_info_cb
276  *
277  * Callback for accumulating in dump_context a Mach-O modules set
278  */
279 static BOOL fetch_macho_module_info_cb(const WCHAR* name, unsigned long base,
280  void* user)
281 {
282  struct dump_context* dc = (struct dump_context*)user;
283  DWORD_PTR rbase;
285 
286  /* FIXME: there's no relevant timestamp on Mach-O modules */
287  /* NB: if we have a non-null base from the live-target use it. If we have
288  * a null base, then grab its base address from Mach-O file.
289  */
290  if (!macho_fetch_file_info(dc->hProcess, name, base, &rbase, &size, &checksum))
291  size = checksum = 0;
292  add_module(dc, name, base ? base : rbase, size, 0 /* FIXME */, checksum, TRUE);
293  return TRUE;
294 }
295 
296 static void fetch_modules_info(struct dump_context* dc)
297 {
299  /* Since we include ELF modules in a separate stream from the regular PE ones,
300  * we can always include those ELF modules (they don't eat lots of space)
301  * And it's always a good idea to have a trace of the loaded ELF modules for
302  * a given application in a post mortem debugging condition.
303  */
306 }
307 
309 {
310  DWORD handle;
311  DWORD sz;
312  static const WCHAR backslashW[] = {'\\', '\0'};
313 
314  memset(ffi, 0, sizeof(*ffi));
316  {
317  void* info = HeapAlloc(GetProcessHeap(), 0, sz);
319  {
321  UINT len;
322 
323  if (VerQueryValueW(info, backslashW, (void*)&ptr, &len))
324  memcpy(ffi, ptr, min(len, sizeof(*ffi)));
325  }
327  }
328 }
329 
330 /******************************************************************
331  * minidump_add_memory_block
332  *
333  * Add a memory block to be dumped in a minidump
334  * If rva is non 0, it's the rva in the minidump where has to be stored
335  * also the rva of the memory block when written (this allows us to reference
336  * a memory block from outside the list of memory blocks).
337  */
339 {
340  if (!dc->mem)
341  {
342  dc->alloc_mem = 32;
343  dc->mem = HeapAlloc(GetProcessHeap(), 0, dc->alloc_mem * sizeof(*dc->mem));
344  }
345  else if (dc->num_mem >= dc->alloc_mem)
346  {
347  dc->alloc_mem *= 2;
348  dc->mem = HeapReAlloc(GetProcessHeap(), 0, dc->mem,
349  dc->alloc_mem * sizeof(*dc->mem));
350  }
351  if (dc->mem)
352  {
353  dc->mem[dc->num_mem].base = base;
354  dc->mem[dc->num_mem].size = size;
355  dc->mem[dc->num_mem].rva = rva;
356  dc->num_mem++;
357  }
358  else dc->num_mem = dc->alloc_mem = 0;
359 }
360 
361 /******************************************************************
362  * writeat
363  *
364  * Writes a chunk of data at a given position in the minidump
365  */
366 static void writeat(struct dump_context* dc, RVA rva, const void* data, unsigned size)
367 {
368  DWORD written;
369 
370  SetFilePointer(dc->hFile, rva, NULL, FILE_BEGIN);
371  WriteFile(dc->hFile, data, size, &written, NULL);
372 }
373 
374 /******************************************************************
375  * append
376  *
377  * writes a new chunk of data to the minidump, increasing the current
378  * rva in dc
379  */
380 static void append(struct dump_context* dc, const void* data, unsigned size)
381 {
382  writeat(dc, dc->rva, data, size);
383  dc->rva += size;
384 }
385 
386 /******************************************************************
387  * dump_exception_info
388  *
389  * Write in File the exception information from pcs
390  */
391 static unsigned dump_exception_info(struct dump_context* dc,
393 {
395  EXCEPTION_RECORD rec, *prec;
396  CONTEXT ctx, *pctx;
397  DWORD i;
398 
399  mdExcpt.ThreadId = except->ThreadId;
400  mdExcpt.__alignment = 0;
401  if (except->ClientPointers)
402  {
404 
405  ReadProcessMemory(dc->hProcess,
406  except->ExceptionPointers, &ep, sizeof(ep), NULL);
407  ReadProcessMemory(dc->hProcess,
408  ep.ExceptionRecord, &rec, sizeof(rec), NULL);
409  ReadProcessMemory(dc->hProcess,
410  ep.ContextRecord, &ctx, sizeof(ctx), NULL);
411  prec = &rec;
412  pctx = &ctx;
413  }
414  else
415  {
416  prec = except->ExceptionPointers->ExceptionRecord;
417  pctx = except->ExceptionPointers->ContextRecord;
418  }
425  for (i = 0; i < mdExcpt.ExceptionRecord.NumberParameters; i++)
427  mdExcpt.ThreadContext.DataSize = sizeof(*pctx);
428  mdExcpt.ThreadContext.Rva = dc->rva + sizeof(mdExcpt);
429 
430  append(dc, &mdExcpt, sizeof(mdExcpt));
431  append(dc, pctx, sizeof(*pctx));
432  return sizeof(mdExcpt);
433 }
434 
435 /******************************************************************
436  * dump_modules
437  *
438  * Write in File the modules from pcs
439  */
440 static unsigned dump_modules(struct dump_context* dc, BOOL dump_elf)
441 {
443  MINIDUMP_MODULE_LIST mdModuleList;
444  char tmp[1024];
445  MINIDUMP_STRING* ms = (MINIDUMP_STRING*)tmp;
446  ULONG i, nmod;
447  RVA rva_base;
449  unsigned sz;
450 
451  for (i = nmod = 0; i < dc->num_modules; i++)
452  {
453  if ((dc->modules[i].is_elf && dump_elf) ||
454  (!dc->modules[i].is_elf && !dump_elf))
455  nmod++;
456  }
457 
458  mdModuleList.NumberOfModules = 0;
459  /* reserve space for mdModuleList
460  * FIXME: since we don't support 0 length arrays, we cannot use the
461  * size of mdModuleList
462  * FIXME: if we don't ask for all modules in cb, we'll get a hole in the file
463  */
464 
465  /* the stream size is just the size of the module index. It does not include the data for the
466  names of each module. *Technically* the names are supposed to go into the common string table
467  in the minidump file. Since each string is referenced by RVA they can all safely be located
468  anywhere between streams in the file, so the end of this stream is sufficient. */
469  rva_base = dc->rva;
470  dc->rva += sz = sizeof(mdModuleList.NumberOfModules) + sizeof(mdModule) * nmod;
471  for (i = 0; i < dc->num_modules; i++)
472  {
473  if ((dc->modules[i].is_elf && !dump_elf) ||
474  (!dc->modules[i].is_elf && dump_elf))
475  continue;
476 
478  if (dc->type & MiniDumpWithDataSegs)
480  if (dc->type & MiniDumpWithProcessThreadData)
482  if (dc->type & MiniDumpWithCodeSegs)
484  ms->Length = (lstrlenW(dc->modules[i].name) + 1) * sizeof(WCHAR);
485  if (sizeof(ULONG) + ms->Length > sizeof(tmp))
486  FIXME("Buffer overflow!!!\n");
487  lstrcpyW(ms->Buffer, dc->modules[i].name);
488 
489  if (dc->cb)
490  {
493 
494  cbin.ProcessId = dc->pid;
495  cbin.ProcessHandle = dc->hProcess;
497 
498  cbin.u.Module.FullPath = ms->Buffer;
499  cbin.u.Module.BaseOfImage = dc->modules[i].base;
500  cbin.u.Module.SizeOfImage = dc->modules[i].size;
501  cbin.u.Module.CheckSum = dc->modules[i].checksum;
502  cbin.u.Module.TimeDateStamp = dc->modules[i].timestamp;
503  memset(&cbin.u.Module.VersionInfo, 0, sizeof(cbin.u.Module.VersionInfo));
504  cbin.u.Module.CvRecord = NULL;
505  cbin.u.Module.SizeOfCvRecord = 0;
506  cbin.u.Module.MiscRecord = NULL;
507  cbin.u.Module.SizeOfMiscRecord = 0;
508 
509  cbout.u.ModuleWriteFlags = flags_out;
510  if (!dc->cb->CallbackRoutine(dc->cb->CallbackParam, &cbin, &cbout))
511  continue;
512  flags_out &= cbout.u.ModuleWriteFlags;
513  }
515  {
516  /* fetch CPU dependent module info (like UNWIND_INFO) */
517  dbghelp_current_cpu->fetch_minidump_module(dc, i, flags_out);
518 
519  mdModule.BaseOfImage = dc->modules[i].base;
520  mdModule.SizeOfImage = dc->modules[i].size;
521  mdModule.CheckSum = dc->modules[i].checksum;
522  mdModule.TimeDateStamp = dc->modules[i].timestamp;
523  mdModule.ModuleNameRva = dc->rva;
524  ms->Length -= sizeof(WCHAR);
525  append(dc, ms, sizeof(ULONG) + ms->Length + sizeof(WCHAR));
526  fetch_module_versioninfo(ms->Buffer, &mdModule.VersionInfo);
527  mdModule.CvRecord.DataSize = 0; /* FIXME */
528  mdModule.CvRecord.Rva = 0; /* FIXME */
529  mdModule.MiscRecord.DataSize = 0; /* FIXME */
530  mdModule.MiscRecord.Rva = 0; /* FIXME */
531  mdModule.Reserved0 = 0; /* FIXME */
532  mdModule.Reserved1 = 0; /* FIXME */
533  writeat(dc,
534  rva_base + sizeof(mdModuleList.NumberOfModules) +
535  mdModuleList.NumberOfModules++ * sizeof(mdModule),
536  &mdModule, sizeof(mdModule));
537  }
538  }
539  writeat(dc, rva_base, &mdModuleList.NumberOfModules,
540  sizeof(mdModuleList.NumberOfModules));
541 
542  return sz;
543 }
544 
545 /* Calls cpuid with an eax of 'ax' and returns the 16 bytes in *p
546  * We are compiled with -fPIC, so we can't clobber ebx.
547  */
548 static inline void do_x86cpuid(unsigned int ax, unsigned int *p)
549 {
550 #if defined(__GNUC__) && defined(__i386__)
551  __asm__("pushl %%ebx\n\t"
552  "cpuid\n\t"
553  "movl %%ebx, %%esi\n\t"
554  "popl %%ebx"
555  : "=a" (p[0]), "=S" (p[1]), "=c" (p[2]), "=d" (p[3])
556  : "0" (ax));
557 #endif
558 }
559 
560 /* From xf86info havecpuid.c 1.11 */
561 static inline int have_x86cpuid(void)
562 {
563 #if defined(__GNUC__) && defined(__i386__)
564  unsigned int f1, f2;
565  __asm__("pushfl\n\t"
566  "pushfl\n\t"
567  "popl %0\n\t"
568  "movl %0,%1\n\t"
569  "xorl %2,%0\n\t"
570  "pushl %0\n\t"
571  "popfl\n\t"
572  "pushfl\n\t"
573  "popl %0\n\t"
574  "popfl"
575  : "=&r" (f1), "=&r" (f2)
576  : "ir" (0x00200000));
577  return ((f1^f2) & 0x00200000) != 0;
578 #else
579  return 0;
580 #endif
581 }
582 
583 /******************************************************************
584  * dump_system_info
585  *
586  * Dumps into File the information about the system
587  */
588 static unsigned dump_system_info(struct dump_context* dc)
589 {
590  MINIDUMP_SYSTEM_INFO mdSysInfo;
591  SYSTEM_INFO sysInfo;
592  OSVERSIONINFOW osInfo;
593  DWORD written;
594  ULONG slen;
595  DWORD wine_extra = 0;
596 
597  const char *(CDECL *wine_get_build_id)(void);
598  void (CDECL *wine_get_host_version)(const char **sysname, const char **release);
599  const char* build_id = NULL;
600  const char* sys_name = NULL;
601  const char* release_name = NULL;
602 
603  GetSystemInfo(&sysInfo);
604  osInfo.dwOSVersionInfoSize = sizeof(osInfo);
605  GetVersionExW(&osInfo);
606 
607  wine_get_build_id = (void *)GetProcAddress(GetModuleHandleA("ntdll.dll"), "wine_get_build_id");
608  wine_get_host_version = (void *)GetProcAddress(GetModuleHandleA("ntdll.dll"), "wine_get_host_version");
609  if (wine_get_build_id && wine_get_host_version)
610  {
611  /* cheat minidump system information by adding specific wine information */
612  wine_extra = 4 + 4 * sizeof(slen);
613  build_id = wine_get_build_id();
614  wine_get_host_version(&sys_name, &release_name);
615  wine_extra += strlen(build_id) + 1 + strlen(sys_name) + 1 + strlen(release_name) + 1;
616  }
617 
618  mdSysInfo.ProcessorArchitecture = sysInfo.u.s.wProcessorArchitecture;
619  mdSysInfo.ProcessorLevel = sysInfo.wProcessorLevel;
620  mdSysInfo.ProcessorRevision = sysInfo.wProcessorRevision;
621  mdSysInfo.u.s.NumberOfProcessors = sysInfo.dwNumberOfProcessors;
622  mdSysInfo.u.s.ProductType = VER_NT_WORKSTATION; /* FIXME */
623  mdSysInfo.MajorVersion = osInfo.dwMajorVersion;
624  mdSysInfo.MinorVersion = osInfo.dwMinorVersion;
625  mdSysInfo.BuildNumber = osInfo.dwBuildNumber;
626  mdSysInfo.PlatformId = osInfo.dwPlatformId;
627 
628  mdSysInfo.CSDVersionRva = dc->rva + sizeof(mdSysInfo) + wine_extra;
629  mdSysInfo.u1.Reserved1 = 0;
630  mdSysInfo.u1.s.SuiteMask = VER_SUITE_TERMINAL;
631 
632  if (have_x86cpuid())
633  {
634  unsigned regs0[4], regs1[4];
635 
636  do_x86cpuid(0, regs0);
637  mdSysInfo.Cpu.X86CpuInfo.VendorId[0] = regs0[1];
638  mdSysInfo.Cpu.X86CpuInfo.VendorId[1] = regs0[3];
639  mdSysInfo.Cpu.X86CpuInfo.VendorId[2] = regs0[2];
640  do_x86cpuid(1, regs1);
641  mdSysInfo.Cpu.X86CpuInfo.VersionInformation = regs1[0];
642  mdSysInfo.Cpu.X86CpuInfo.FeatureInformation = regs1[3];
643  mdSysInfo.Cpu.X86CpuInfo.AMDExtendedCpuFeatures = 0;
644  if (regs0[1] == 0x68747541 /* "Auth" */ &&
645  regs0[3] == 0x69746e65 /* "enti" */ &&
646  regs0[2] == 0x444d4163 /* "cAMD" */)
647  {
648  do_x86cpuid(0x80000000, regs1); /* get vendor cpuid level */
649  if (regs1[0] >= 0x80000001)
650  {
651  do_x86cpuid(0x80000001, regs1); /* get vendor features */
652  mdSysInfo.Cpu.X86CpuInfo.AMDExtendedCpuFeatures = regs1[3];
653  }
654  }
655  }
656  else
657  {
658  unsigned i;
659  ULONG64 one = 1;
660 
661  mdSysInfo.Cpu.OtherCpuInfo.ProcessorFeatures[0] = 0;
662  mdSysInfo.Cpu.OtherCpuInfo.ProcessorFeatures[1] = 0;
663 
664  for (i = 0; i < sizeof(mdSysInfo.Cpu.OtherCpuInfo.ProcessorFeatures[0]) * 8; i++)
666  mdSysInfo.Cpu.OtherCpuInfo.ProcessorFeatures[0] |= one << i;
667  }
668  append(dc, &mdSysInfo, sizeof(mdSysInfo));
669 
670  /* write Wine specific system information just behind the structure, and before any string */
671  if (wine_extra)
672  {
673  char code[] = {'W','I','N','E'};
674 
675  WriteFile(dc->hFile, code, 4, &written, NULL);
676  /* number of sub-info, so that we can extend structure if needed */
677  slen = 3;
678  WriteFile(dc->hFile, &slen, sizeof(slen), &written, NULL);
679  /* we store offsets from just after the WINE marker */
680  slen = 4 * sizeof(DWORD);
681  WriteFile(dc->hFile, &slen, sizeof(slen), &written, NULL);
682  slen += strlen(build_id) + 1;
683  WriteFile(dc->hFile, &slen, sizeof(slen), &written, NULL);
684  slen += strlen(sys_name) + 1;
685  WriteFile(dc->hFile, &slen, sizeof(slen), &written, NULL);
686  WriteFile(dc->hFile, build_id, strlen(build_id) + 1, &written, NULL);
687  WriteFile(dc->hFile, sys_name, strlen(sys_name) + 1, &written, NULL);
688  WriteFile(dc->hFile, release_name, strlen(release_name) + 1, &written, NULL);
689  dc->rva += wine_extra;
690  }
691 
692  /* write the service pack version string after this stream. It is referenced within the
693  stream by its RVA in the file. */
694  slen = lstrlenW(osInfo.szCSDVersion) * sizeof(WCHAR);
695  WriteFile(dc->hFile, &slen, sizeof(slen), &written, NULL);
696  WriteFile(dc->hFile, osInfo.szCSDVersion, slen, &written, NULL);
697  dc->rva += sizeof(ULONG) + slen;
698 
699  return sizeof(mdSysInfo);
700 }
701 
702 /******************************************************************
703  * dump_threads
704  *
705  * Dumps into File the information about running threads
706  */
707 static unsigned dump_threads(struct dump_context* dc,
709 {
710  MINIDUMP_THREAD mdThd;
711  MINIDUMP_THREAD_LIST mdThdList;
712  unsigned i, sz;
713  RVA rva_base;
715  CONTEXT ctx;
716 
717  mdThdList.NumberOfThreads = 0;
718 
719  rva_base = dc->rva;
720  dc->rva += sz = sizeof(mdThdList.NumberOfThreads) + dc->num_threads * sizeof(mdThd);
721 
722  for (i = 0; i < dc->num_threads; i++)
723  {
724  fetch_thread_info(dc, i, except, &mdThd, &ctx);
725 
728  if (dc->type & MiniDumpWithProcessThreadData)
730  if (dc->type & MiniDumpWithThreadInfo)
732 
733  if (dc->cb)
734  {
737 
738  cbin.ProcessId = dc->pid;
739  cbin.ProcessHandle = dc->hProcess;
741  cbin.u.Thread.ThreadId = dc->threads[i].tid;
742  cbin.u.Thread.ThreadHandle = 0; /* FIXME */
743  cbin.u.Thread.Context = ctx;
744  cbin.u.Thread.SizeOfContext = sizeof(CONTEXT);
745  cbin.u.Thread.StackBase = mdThd.Stack.StartOfMemoryRange;
746  cbin.u.Thread.StackEnd = mdThd.Stack.StartOfMemoryRange +
747  mdThd.Stack.Memory.DataSize;
748 
749  cbout.u.ThreadWriteFlags = flags_out;
750  if (!dc->cb->CallbackRoutine(dc->cb->CallbackParam, &cbin, &cbout))
751  continue;
752  flags_out &= cbout.u.ThreadWriteFlags;
753  }
755  {
757  {
758  mdThd.ThreadContext.Rva = dc->rva;
759  mdThd.ThreadContext.DataSize = sizeof(CONTEXT);
760  append(dc, &ctx, sizeof(CONTEXT));
761  }
763  {
765  mdThd.Stack.Memory.DataSize,
766  rva_base + sizeof(mdThdList.NumberOfThreads) +
767  mdThdList.NumberOfThreads * sizeof(mdThd) +
768  FIELD_OFFSET(MINIDUMP_THREAD, Stack.Memory.Rva));
769  }
770  writeat(dc,
771  rva_base + sizeof(mdThdList.NumberOfThreads) +
772  mdThdList.NumberOfThreads * sizeof(mdThd),
773  &mdThd, sizeof(mdThd));
774  mdThdList.NumberOfThreads++;
775  }
776  /* fetch CPU dependent thread info (like 256 bytes around program counter */
777  dbghelp_current_cpu->fetch_minidump_thread(dc, i, flags_out, &ctx);
778  }
779  writeat(dc, rva_base,
780  &mdThdList.NumberOfThreads, sizeof(mdThdList.NumberOfThreads));
781 
782  return sz;
783 }
784 
785 /******************************************************************
786  * dump_memory_info
787  *
788  * dumps information about the memory of the process (stack of the threads)
789  */
790 static unsigned dump_memory_info(struct dump_context* dc)
791 {
792  MINIDUMP_MEMORY_LIST mdMemList;
794  DWORD written;
795  unsigned i, pos, len, sz;
796  RVA rva_base;
797  char tmp[1024];
798 
799  mdMemList.NumberOfMemoryRanges = dc->num_mem;
800  append(dc, &mdMemList.NumberOfMemoryRanges,
801  sizeof(mdMemList.NumberOfMemoryRanges));
802  rva_base = dc->rva;
803  sz = mdMemList.NumberOfMemoryRanges * sizeof(mdMem);
804  dc->rva += sz;
805  sz += sizeof(mdMemList.NumberOfMemoryRanges);
806 
807  for (i = 0; i < dc->num_mem; i++)
808  {
809  mdMem.StartOfMemoryRange = dc->mem[i].base;
810  mdMem.Memory.Rva = dc->rva;
811  mdMem.Memory.DataSize = dc->mem[i].size;
812  SetFilePointer(dc->hFile, dc->rva, NULL, FILE_BEGIN);
813  for (pos = 0; pos < dc->mem[i].size; pos += sizeof(tmp))
814  {
815  len = min(dc->mem[i].size - pos, sizeof(tmp));
816  if (ReadProcessMemory(dc->hProcess,
817  (void*)(DWORD_PTR)(dc->mem[i].base + pos),
818  tmp, len, NULL))
819  WriteFile(dc->hFile, tmp, len, &written, NULL);
820  }
821  dc->rva += mdMem.Memory.DataSize;
822  writeat(dc, rva_base + i * sizeof(mdMem), &mdMem, sizeof(mdMem));
823  if (dc->mem[i].rva)
824  {
825  writeat(dc, dc->mem[i].rva, &mdMem.Memory.Rva, sizeof(mdMem.Memory.Rva));
826  }
827  }
828 
829  return sz;
830 }
831 
832 static unsigned dump_misc_info(struct dump_context* dc)
833 {
834  MINIDUMP_MISC_INFO mmi;
835 
836  mmi.SizeOfInfo = sizeof(mmi);
838  mmi.ProcessId = dc->pid;
839  /* FIXME: create/user/kernel time */
840  mmi.ProcessCreateTime = 0;
841  mmi.ProcessKernelTime = 0;
842  mmi.ProcessUserTime = 0;
843 
844  append(dc, &mmi, sizeof(mmi));
845  return sizeof(mmi);
846 }
847 
848 /******************************************************************
849  * MiniDumpWriteDump (DEBUGHLP.@)
850  *
851  */
854  PMINIDUMP_EXCEPTION_INFORMATION ExceptionParam,
855  PMINIDUMP_USER_STREAM_INFORMATION UserStreamParam,
856  PMINIDUMP_CALLBACK_INFORMATION CallbackParam)
857 {
858  static const MINIDUMP_DIRECTORY emptyDir = {UnusedStream, {0, 0}};
859  MINIDUMP_HEADER mdHead;
860  MINIDUMP_DIRECTORY mdDir;
861  DWORD i, nStreams, idx_stream;
862  struct dump_context dc;
863 
864  dc.hProcess = hProcess;
865  dc.hFile = hFile;
866  dc.pid = pid;
867  dc.modules = NULL;
868  dc.num_modules = 0;
869  dc.alloc_modules = 0;
870  dc.threads = NULL;
871  dc.num_threads = 0;
872  dc.cb = CallbackParam;
873  dc.type = DumpType;
874  dc.mem = NULL;
875  dc.num_mem = 0;
876  dc.alloc_mem = 0;
877  dc.rva = 0;
878 
879  if (!fetch_process_info(&dc)) return FALSE;
881 
882  /* 1) init */
883  nStreams = 6 + (ExceptionParam ? 1 : 0) +
884  (UserStreamParam ? UserStreamParam->UserStreamCount : 0);
885 
886  /* pad the directory size to a multiple of 4 for alignment purposes */
887  nStreams = (nStreams + 3) & ~3;
888 
890  FIXME("NIY MiniDumpWithDataSegs\n");
892  FIXME("NIY MiniDumpWithFullMemory\n");
894  FIXME("NIY MiniDumpWithHandleData\n");
896  FIXME("NIY MiniDumpFilterMemory\n");
898  FIXME("NIY MiniDumpScanMemory\n");
899 
900  /* 2) write header */
901  mdHead.Signature = MINIDUMP_SIGNATURE;
902  mdHead.Version = MINIDUMP_VERSION; /* NOTE: native puts in an 'implementation specific' value in the high order word of this member */
903  mdHead.NumberOfStreams = nStreams;
904  mdHead.CheckSum = 0; /* native sets a 0 checksum in its files */
905  mdHead.StreamDirectoryRva = sizeof(mdHead);
906  mdHead.u.TimeDateStamp = time(NULL);
907  mdHead.Flags = DumpType;
908  append(&dc, &mdHead, sizeof(mdHead));
909 
910  /* 3) write stream directories */
911  dc.rva += nStreams * sizeof(mdDir);
912  idx_stream = 0;
913 
914  /* 3.1) write data stream directories */
915 
916  /* must be first in minidump */
918  mdDir.Location.Rva = dc.rva;
920  writeat(&dc, mdHead.StreamDirectoryRva + idx_stream++ * sizeof(mdDir),
921  &mdDir, sizeof(mdDir));
922 
924  mdDir.Location.Rva = dc.rva;
925  mdDir.Location.DataSize = dump_threads(&dc, ExceptionParam);
926  writeat(&dc, mdHead.StreamDirectoryRva + idx_stream++ * sizeof(mdDir),
927  &mdDir, sizeof(mdDir));
928 
930  mdDir.Location.Rva = dc.rva;
932  writeat(&dc, mdHead.StreamDirectoryRva + idx_stream++ * sizeof(mdDir),
933  &mdDir, sizeof(mdDir));
934 
935  mdDir.StreamType = 0xfff0; /* FIXME: this is part of MS reserved streams */
936  mdDir.Location.Rva = dc.rva;
937  mdDir.Location.DataSize = dump_modules(&dc, TRUE);
938  writeat(&dc, mdHead.StreamDirectoryRva + idx_stream++ * sizeof(mdDir),
939  &mdDir, sizeof(mdDir));
940 
942  mdDir.Location.Rva = dc.rva;
944  writeat(&dc, mdHead.StreamDirectoryRva + idx_stream++ * sizeof(mdDir),
945  &mdDir, sizeof(mdDir));
946 
947  mdDir.StreamType = MiscInfoStream;
948  mdDir.Location.Rva = dc.rva;
950  writeat(&dc, mdHead.StreamDirectoryRva + idx_stream++ * sizeof(mdDir),
951  &mdDir, sizeof(mdDir));
952 
953  /* 3.2) write exception information (if any) */
954  if (ExceptionParam)
955  {
956  mdDir.StreamType = ExceptionStream;
957  mdDir.Location.Rva = dc.rva;
958  mdDir.Location.DataSize = dump_exception_info(&dc, ExceptionParam);
959  writeat(&dc, mdHead.StreamDirectoryRva + idx_stream++ * sizeof(mdDir),
960  &mdDir, sizeof(mdDir));
961  }
962 
963  /* 3.3) write user defined streams (if any) */
964  if (UserStreamParam)
965  {
966  for (i = 0; i < UserStreamParam->UserStreamCount; i++)
967  {
968  mdDir.StreamType = UserStreamParam->UserStreamArray[i].Type;
969  mdDir.Location.DataSize = UserStreamParam->UserStreamArray[i].BufferSize;
970  mdDir.Location.Rva = dc.rva;
971  writeat(&dc, mdHead.StreamDirectoryRva + idx_stream++ * sizeof(mdDir),
972  &mdDir, sizeof(mdDir));
973  append(&dc, UserStreamParam->UserStreamArray[i].Buffer,
974  UserStreamParam->UserStreamArray[i].BufferSize);
975  }
976  }
977 
978  /* fill the remaining directory entries with 0's (unused stream types) */
979  /* NOTE: this should always come last in the dump! */
980  for (i = idx_stream; i < nStreams; i++)
981  writeat(&dc, mdHead.StreamDirectoryRva + i * sizeof(emptyDir), &emptyDir, sizeof(emptyDir));
982 
983  HeapFree(GetProcessHeap(), 0, dc.mem);
984  HeapFree(GetProcessHeap(), 0, dc.modules);
985  HeapFree(GetProcessHeap(), 0, dc.threads);
986 
987  return TRUE;
988 }
989 
990 /******************************************************************
991  * MiniDumpReadDumpStream (DEBUGHLP.@)
992  *
993  *
994  */
996  PMINIDUMP_DIRECTORY* pdir,
997  PVOID* stream, ULONG* size)
998 {
999  MINIDUMP_HEADER* mdHead = base;
1000 
1001  if (mdHead->Signature == MINIDUMP_SIGNATURE)
1002  {
1004  DWORD i;
1005 
1006  dir = (MINIDUMP_DIRECTORY*)((char*)base + mdHead->StreamDirectoryRva);
1007  for (i = 0; i < mdHead->NumberOfStreams; i++, dir++)
1008  {
1009  if (dir->StreamType == str_idx)
1010  {
1011  if (pdir) *pdir = dir;
1012  if (stream) *stream = (char*)base + dir->Location.Rva;
1013  if (size) *size = dir->Location.DataSize;
1014  return TRUE;
1015  }
1016  }
1017  }
1019  return FALSE;
1020 }
#define ERROR_INVALID_PARAMETER
Definition: compat.h:91
ULONG NumberOfMemoryRanges
Definition: dbghelp.h:806
#define VER_NT_WORKSTATION
BOOL WINAPI WriteFile(IN HANDLE hFile, IN LPCVOID lpBuffer, IN DWORD nNumberOfBytesToWrite OPTIONAL, OUT LPDWORD lpNumberOfBytesWritten, IN LPOVERLAPPED lpOverlapped OPTIONAL)
Definition: rw.c:24
const uint16_t * PCWSTR
Definition: typedefs.h:55
_In_ ULONG_PTR _In_ ULONG _Out_ ULONG_PTR * pid
Definition: winddi.h:3835
#define THREAD_ALL_ACCESS
Definition: nt_native.h:1339
namespace GUID const ADDRINFOEXW ADDRINFOEXW struct timeval OVERLAPPED LPLOOKUPSERVICE_COMPLETION_ROUTINE HANDLE * handle
Definition: sock.c:82
#define TRUE
Definition: types.h:120
NTSYSAPI NTSTATUS NTAPI NtQuerySystemInformation(IN SYSTEM_INFORMATION_CLASS SystemInfoClass, OUT PVOID SystemInfoBuffer, IN ULONG SystemInfoBufferSize, OUT PULONG BytesReturned OPTIONAL)
#define CloseHandle
Definition: compat.h:406
struct png_info_def **typedef void(__cdecl typeof(png_destroy_read_struct))(struct png_struct_def **
Definition: typeof.h:49
static unsigned dump_modules(struct dump_context *dc, BOOL dump_elf)
Definition: minidump.c:440
#define STATUS_INFO_LENGTH_MISMATCH
Definition: udferr_usr.h:133
DWORD NumberOfStreams
Definition: dbghelp.h:787
#define DWORD_PTR
Definition: treelist.c:76
ULONG NumberParameters
Definition: dbghelp.h:763
struct cpu * dbghelp_current_cpu
Definition: dbghelp.c:150
const WCHAR * LPCWSTR
Definition: xmlstorage.h:185
WCHAR Buffer[1]
Definition: dbghelp.h:846
MINIDUMP_LOCATION_DESCRIPTOR ThreadContext
Definition: dbghelp.h:904
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
union _MINIDUMP_SYSTEM_INFO::_CPU_INFORMATION Cpu
VOID DumpType(DWORD dwTypeIndex, PENUMINFO pei, INT indent, BOOL bMembers)
Definition: symdump.c:695
#define MINIDUMP_VERSION
Definition: dbghelp.h:596
MINIDUMP_THREAD_CALLBACK Thread
Definition: compat.h:979
BOOL WINAPI MiniDumpWriteDump(HANDLE hProcess, DWORD pid, HANDLE hFile, MINIDUMP_TYPE DumpType, PMINIDUMP_EXCEPTION_INFORMATION ExceptionParam, PMINIDUMP_USER_STREAM_INFORMATION UserStreamParam, PMINIDUMP_CALLBACK_INFORMATION CallbackParam)
Definition: minidump.c:852
LONG NTSTATUS
Definition: precomp.h:26
BOOL macho_fetch_file_info(HANDLE process, const WCHAR *name, unsigned long load_addr, DWORD_PTR *base, DWORD *size, DWORD *checksum) DECLSPEC_HIDDEN
#define HandleToUlong(h)
Definition: basetsd.h:79
WCHAR szCSDVersion[128]
Definition: rtltypes.h:247
MINIDUMP_MODULE_CALLBACK Module
Definition: compat.h:981
DWORD WINAPI GetLastError(VOID)
Definition: except.c:1059
#define HandleToULong(h)
Definition: basetsd.h:95
_In_ BOOL _In_ HANDLE hProcess
Definition: mapping.h:70
#define ReadProcessMemory(a, b, c, d, e)
Definition: compat.h:423
__u16 time
Definition: mkdosfs.c:366
#define VER_SUITE_TERMINAL
static void append(struct dump_context *dc, const void *data, unsigned size)
Definition: minidump.c:380
BOOL WINAPI GetVersionExW(IN LPOSVERSIONINFOW lpVersionInformation)
Definition: version.c:37
const char * filename
Definition: ioapi.h:135
static BOOL fetch_macho_module_info_cb(const WCHAR *name, unsigned long base, void *user)
Definition: minidump.c:279
#define lstrlenW
Definition: compat.h:415
#define DWORD
Definition: nt_native.h:44
ULONG64 Flags
Definition: dbghelp.h:795
struct _CONTEXT CONTEXT
#define MINIDUMP_MISC1_PROCESS_ID
Definition: dbghelp.h:810
IMAGE_OPTIONAL_HEADER32 OptionalHeader
Definition: ntddk_ex.h:184
PVOID ExceptionAddress
Definition: compat.h:199
static BOOL fetch_process_info(struct dump_context *dc)
Definition: minidump.c:41
#define lstrcpynW
Definition: compat.h:405
DWORD WINAPI DECLSPEC_HOTPATCH SetFilePointer(HANDLE hFile, LONG lDistanceToMove, PLONG lpDistanceToMoveHigh, DWORD dwMoveMethod)
Definition: fileinfo.c:204
static double one
Definition: j0_y0.c:80
uint32_t ULONG_PTR
Definition: typedefs.h:63
DWORD ExceptionCode
Definition: compat.h:196
static void fetch_thread_stack(struct dump_context *dc, const void *teb_addr, const CONTEXT *ctx, MINIDUMP_MEMORY_DESCRIPTOR *mmd)
Definition: minidump.c:88
BOOL WINAPI GetThreadContext(IN HANDLE hThread, OUT LPCONTEXT lpContext)
Definition: thread.c:500
UCHAR NumberOfProcessors
Definition: dbghelp.h:859
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
WORD wProcessorRevision
Definition: winbase.h:1141
ULONG __unusedAlignment
Definition: dbghelp.h:764
unsigned int BOOL
Definition: ntddk_ex.h:94
GLuint base
Definition: 3dtext.c:35
__asm__("\t.globl GetPhys\n" "GetPhys:\t\n" "mflr 0\n\t" "stwu 0,-16(1)\n\t" "mfmsr 5\n\t" "andi. 6,5,0xffef\n\t" "mtmsr 6\n\t" "isync\n\t" "sync\n\t" "lwz 3,0(3)\n\t" "mtmsr 5\n\t" "isync\n\t" "sync\n\t" "lwz 0,0(1)\n\t" "addi 1,1,16\n\t" "mtlr 0\n\t" "blr")
USHORT ProcessorArchitecture
Definition: dbghelp.h:851
ULONG ExceptionFlags
Definition: dbghelp.h:760
BOOL WINAPI MiniDumpReadDumpStream(PVOID base, ULONG str_idx, PMINIDUMP_DIRECTORY *pdir, PVOID *stream, ULONG *size)
Definition: minidump.c:995
BOOL pe_load_nt_header(HANDLE hProc, DWORD64 base, IMAGE_NT_HEADERS *nth) DECLSPEC_HIDDEN
Definition: pe_module.c:837
#define FIXME(fmt,...)
Definition: debug.h:110
MINIDUMP_LOCATION_DESCRIPTOR Location
Definition: dbghelp.h:754
static PVOID ptr
Definition: dispmode.c:27
ULONG64 ExceptionAddress
Definition: dbghelp.h:762
static unsigned dump_threads(struct dump_context *dc, const MINIDUMP_EXCEPTION_INFORMATION *except)
Definition: minidump.c:707
ecx edi ebx edx edi decl ecx esi eax jecxz decl eax andl eax esi movl edx movl TEMP incl eax andl eax ecx incl ebx eax jnz xchgl ecx incl TEMP esp ecx subl ebx pushl ecx ecx edx ecx ecx mm0 mm4 mm0 mm4 mm1 mm5 mm1 mm5 mm2 mm6 mm2 mm6 mm3 mm7 mm3 mm7 paddd mm0 paddd mm4 paddd mm0 paddd mm4 paddd mm0 paddd mm4 movq mm1 movq mm5 mm1 mm5 paddd mm0 paddd mm4 mm0 mm4 packssdw mm0 packssdw mm4 mm1 punpckldq mm0 pand mm1 pand mm0 por mm1 movq edi esi edx edi decl ecx jnz popl ecx ecx jecxz mm0 mm0 mm1 mm1 mm2 mm2 mm3 mm3 paddd mm0 paddd mm0 paddd mm0 movq mm1 mm1 paddd mm0 mm0 packssdw mm0 movd eax movw ax
Definition: synth_sse3d.h:171
#define GetModuleFileNameExW(w, x, y, z)
Definition: compat.h:579
ULONG ProcessKernelTime
Definition: dbghelp.h:820
smooth NULL
Definition: ftsmooth.c:416
MINIDUMP_EXCEPTION ExceptionRecord
Definition: dbghelp.h:779
VS_FIXEDFILEINFO VersionInfo
Definition: compat.h:958
INT nStreams
Definition: api.c:60
static void fetch_modules_info(struct dump_context *dc)
Definition: minidump.c:296
unsigned int dir
Definition: maze.c:112
mdToken mdModule
Definition: cordebug.idl:72
IMAGE_FILE_HEADER FileHeader
Definition: ntddk_ex.h:183
ULONG ThreadId
Definition: dbghelp.h:898
DWORD WINAPI GetCurrentThreadId(VOID)
Definition: thread.c:458
BOOL WINAPI EnumerateLoadedModulesW64(HANDLE hProcess, PENUMLOADED_MODULES_CALLBACKW64 EnumLoadedModulesCallback, PVOID UserContext)
Definition: module.c:906
ULONG ContextFlags
Definition: nt_native.h:1426
static BOOL fetch_elf_module_info_cb(const WCHAR *name, unsigned long base, void *user)
Definition: minidump.c:256
PCONTEXT ContextRecord
Definition: rtltypes.h:197
static const WCHAR backslashW[]
static unsigned dump_memory_info(struct dump_context *dc)
Definition: minidump.c:790
#define CONTEXT_FULL
Definition: nt_native.h:1375
ULONG_PTR ExceptionInformation[EXCEPTION_MAXIMUM_PARAMETERS]
Definition: compat.h:201
GLsizeiptr size
Definition: glext.h:5919
ULONG dwMajorVersion
Definition: rtltypes.h:243
#define GetProcessHeap()
Definition: compat.h:403
PVOID WINAPI HeapAlloc(HANDLE, DWORD, SIZE_T)
if(!(yy_init))
Definition: macro.lex.yy.c:714
__wchar_t WCHAR
Definition: xmlstorage.h:180
DWORD TimeDateStamp
Definition: dbghelp.h:793
#define STILL_ACTIVE
Definition: winbase.h:230
static unsigned dump_misc_info(struct dump_context *dc)
Definition: minidump.c:832
ULONG dwOSVersionInfoSize
Definition: rtltypes.h:242
#define WINAPI
Definition: msvc.h:6
unsigned long DWORD
Definition: ntddk_ex.h:95
unsigned flags_out
#define SetLastError(x)
Definition: compat.h:417
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
NTSTATUS NTAPI NtQueryInformationThread(IN HANDLE ThreadHandle, IN THREADINFOCLASS ThreadInformationClass, OUT PVOID ThreadInformation, IN ULONG ThreadInformationLength, OUT PULONG ReturnLength OPTIONAL)
Definition: query.c:2497
ULONG dwBuildNumber
Definition: rtltypes.h:245
unsigned __int64 ULONG64
Definition: imports.h:198
GLenum const GLvoid * addr
Definition: glext.h:9621
DWORD WINAPI SuspendThread(IN HANDLE hThread)
Definition: thread.c:641
Definition: parse.h:22
DWORD WINAPI GetFileVersionInfoSizeW(LPCWSTR filename, LPDWORD handle)
Definition: version.c:611
WINE_DEFAULT_DEBUG_CHANNEL(dbghelp)
HANDLE WINAPI OpenThread(IN DWORD dwDesiredAccess, IN BOOL bInheritHandle, IN DWORD dwThreadId)
Definition: thread.c:402
DWORD Signature
Definition: dbghelp.h:785
#define except(x)
Definition: btrfs_drv.h:135
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
GLenum GLsizei len
Definition: glext.h:6722
HMODULE WINAPI DECLSPEC_HOTPATCH GetModuleHandleA(LPCSTR lpModuleName)
Definition: loader.c:821
WORD wProcessorLevel
Definition: winbase.h:1140
static cab_ULONG checksum(const cab_UBYTE *data, cab_UWORD bytes, cab_ULONG csum)
Definition: fdi.c:353
ULONG SuspendCount
Definition: dbghelp.h:899
uint32_t DWORD_PTR
Definition: typedefs.h:63
_In_ HANDLE hFile
Definition: mswsock.h:90
ULONG dwPlatformId
Definition: rtltypes.h:246
static void writeat(struct dump_context *dc, RVA rva, const void *data, unsigned size)
Definition: minidump.c:366
static unsigned dump_system_info(struct dump_context *dc)
Definition: minidump.c:588
struct _EXCEPTION_RECORD * ExceptionRecord
Definition: compat.h:198
static BOOL fetch_thread_info(struct dump_context *dc, int thd_idx, const MINIDUMP_EXCEPTION_INFORMATION *except, MINIDUMP_THREAD *mdThd, CONTEXT *ctx)
Definition: minidump.c:120
ULONG ProcessCreateTime
Definition: dbghelp.h:818
MINIDUMP_LOCATION_DESCRIPTOR ThreadContext
Definition: dbghelp.h:780
ULONG Priority
Definition: dbghelp.h:901
MINIDUMP_MEMORY_DESCRIPTOR Stack
Definition: dbghelp.h:903
#define f1(x, y, z)
Definition: sha1.c:30
static unsigned dump_exception_info(struct dump_context *dc, const MINIDUMP_EXCEPTION_INFORMATION *except)
Definition: minidump.c:391
#define FILE_BEGIN
Definition: winbase.h:112
USHORT ProcessorRevision
Definition: dbghelp.h:853
uint64_t DWORD64
Definition: typedefs.h:65
#define lstrcpyW
Definition: compat.h:414
BOOL WINAPI IsProcessorFeaturePresent(IN DWORD ProcessorFeature)
Definition: sysinfo.c:168
struct _MINIDUMP_SYSTEM_INFO::_CPU_INFORMATION::@2724 OtherCpuInfo
PVOID StackBase
Definition: compat.h:380
#define CDECL
Definition: compat.h:21
RVA StreamDirectoryRva
Definition: dbghelp.h:788
void minidump_add_memory_block(struct dump_context *dc, ULONG64 base, ULONG size, ULONG rva)
Definition: minidump.c:338
#define HeapReAlloc
Definition: compat.h:401
static int have_x86cpuid(void)
Definition: minidump.c:561
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:254
VOID WINAPI GetSystemInfo(IN LPSYSTEM_INFO lpSystemInfo)
Definition: sysinfo.c:142
#define min(a, b)
Definition: monoChain.cc:55
static void fetch_module_versioninfo(LPCWSTR filename, VS_FIXEDFILEINFO *ffi)
Definition: minidump.c:308
unsigned int UINT
Definition: ndis.h:50
HANDLE hThread
Definition: wizard.c:27
static BOOL WINAPI fetch_pe_module_info_cb(PCWSTR name, DWORD64 base, ULONG size, PVOID user)
Definition: minidump.c:236
ULONG64 ExceptionRecord
Definition: dbghelp.h:761
WORD wProcessorArchitecture
Definition: winbase.h:1129
BOOL WINAPI GetFileVersionInfoW(LPCWSTR filename, DWORD handle, DWORD datasize, LPVOID data)
Definition: version.c:845
ULONG dwMinorVersion
Definition: rtltypes.h:244
Definition: name.c:38
DWORD RVA
Definition: compat.h:911
DWORD dwNumberOfProcessors
Definition: winbase.h:1137
DWORD WINAPI ResumeThread(IN HANDLE hThread)
Definition: thread.c:566
unsigned int ULONG
Definition: retypes.h:1
#define ULONG_PTR
Definition: config.h:101
DWORD ExceptionFlags
Definition: compat.h:197
static const WCHAR dc[]
struct _MINIDUMP_SYSTEM_INFO::_CPU_INFORMATION::@2723 X86CpuInfo
#define GetProcAddress(x, y)
Definition: compat.h:418
PVOID StackLimit
Definition: compat.h:381
PEXCEPTION_RECORD ExceptionRecord
Definition: rtltypes.h:196
BOOL elf_fetch_file_info(const WCHAR *name, DWORD_PTR *base, DWORD *size, DWORD *checksum) DECLSPEC_HIDDEN
Definition: elf_module.c:1814
BOOL macho_enum_modules(HANDLE hProc, enum_modules_cb, void *) DECLSPEC_HIDDEN
DWORD NumberParameters
Definition: compat.h:200
GLfloat GLfloat p
Definition: glext.h:8902
static void do_x86cpuid(unsigned int ax, unsigned int *p)
Definition: minidump.c:548
BOOL validate_addr64(DWORD64 addr)
Definition: dbghelp.c:93
ULONG PriorityClass
Definition: dbghelp.h:900
return STATUS_SUCCESS
Definition: btrfs.c:2938
BOOL elf_enum_modules(HANDLE hProc, enum_modules_cb, void *) DECLSPEC_HIDDEN
Definition: elf_module.c:1825
int f2(S1 &, S2 &)
#define memset(x, y, z)
Definition: compat.h:39
MINIDUMP_LOCATION_DESCRIPTOR Memory
Definition: dbghelp.h:801
DWORD CheckSum
Definition: dbghelp.h:789
static TfClientId tid
void user(int argc, const char *argv[])
Definition: cmds.c:1350
ULONG ProcessUserTime
Definition: dbghelp.h:819
#define HeapFree(x, y, z)
Definition: compat.h:402
static BOOL add_module(struct dump_context *dc, const WCHAR *name, DWORD64 base, DWORD size, DWORD timestamp, DWORD checksum, BOOL is_elf)
Definition: minidump.c:194
#define MINIDUMP_SIGNATURE
Definition: dbghelp.h:595
ULONG64 Teb
Definition: dbghelp.h:902
PMINIDUMP_USER_STREAM UserStreamArray
Definition: dbghelp.h:923
ULONG64 ExceptionInformation[EXCEPTION_MAXIMUM_PARAMETERS]
Definition: dbghelp.h:765
BOOL WINAPI VerQueryValueW(LPCVOID pBlock, LPCWSTR lpSubBlock, LPVOID *lplpBuffer, PUINT puLen)
Definition: version.c:1049
enum _MINIDUMP_TYPE MINIDUMP_TYPE