From 9bac505f2a96d9fdc8fe8c86a7feb66a0ed3704e Mon Sep 17 00:00:00 2001 From: Eric Pouech Date: Mon, 10 Nov 2008 11:27:52 +0100 Subject: [PATCH] dbghelp: Properly add CPU info to minidump. --- dlls/dbghelp/minidump.c | 75 +++++++++++++++++++++++++++++++++++++++-- 1 file changed, 73 insertions(+), 2 deletions(-) diff --git a/dlls/dbghelp/minidump.c b/dlls/dbghelp/minidump.c index c506be4e1ef..cc124157544 100644 --- a/dlls/dbghelp/minidump.c +++ b/dlls/dbghelp/minidump.c @@ -556,6 +556,44 @@ static unsigned dump_modules(struct dump_context* dc, BOOL dump_elf) return sz; } +/* Calls cpuid with an eax of 'ax' and returns the 16 bytes in *p + * We are compiled with -fPIC, so we can't clobber ebx. + */ +static inline void do_x86cpuid(unsigned int ax, unsigned int *p) +{ +#if defined(__GNUC__) && defined(__i386__) + __asm__("pushl %%ebx\n\t" + "cpuid\n\t" + "movl %%ebx, %%esi\n\t" + "popl %%ebx" + : "=a" (p[0]), "=S" (p[1]), "=c" (p[2]), "=d" (p[3]) + : "0" (ax)); +#endif +} + +/* From xf86info havecpuid.c 1.11 */ +static inline int have_x86cpuid(void) +{ +#if defined(__GNUC__) && defined(__i386__) + unsigned int f1, f2; + __asm__("pushfl\n\t" + "pushfl\n\t" + "popl %0\n\t" + "movl %0,%1\n\t" + "xorl %2,%0\n\t" + "pushl %0\n\t" + "popfl\n\t" + "pushfl\n\t" + "popl %0\n\t" + "popfl" + : "=&r" (f1), "=&r" (f2) + : "ir" (0x00200000)); + return ((f1^f2) & 0x00200000) != 0; +#else + return 0; +#endif +} + /****************************************************************** * dump_system_info * @@ -587,9 +625,42 @@ static unsigned dump_system_info(struct dump_context* dc) mdSysInfo.u1.Reserved1 = 0; mdSysInfo.u1.s.SuiteMask = VER_SUITE_TERMINAL; - FIXME("fill in CPU vendorID and feature set\n"); - memset(&mdSysInfo.Cpu, 0, sizeof(mdSysInfo.Cpu)); + if (have_x86cpuid()) + { + unsigned regs0[4], regs1[4]; + do_x86cpuid(0, regs0); + mdSysInfo.Cpu.X86CpuInfo.VendorId[0] = regs0[1]; + mdSysInfo.Cpu.X86CpuInfo.VendorId[1] = regs0[2]; + mdSysInfo.Cpu.X86CpuInfo.VendorId[2] = regs0[3]; + do_x86cpuid(1, regs1); + mdSysInfo.Cpu.X86CpuInfo.VersionInformation = regs1[0]; + mdSysInfo.Cpu.X86CpuInfo.FeatureInformation = regs1[3]; + mdSysInfo.Cpu.X86CpuInfo.AMDExtendedCpuFeatures = 0; + if (regs0[1] == 0x68747541 /* "Auth" */ && + regs0[3] == 0x69746e65 /* "enti" */ && + regs0[2] == 0x444d4163 /* "cAMD" */) + { + do_x86cpuid(0x80000000, regs1); /* get vendor cpuid level */ + if (regs1[0] >= 0x80000001) + { + do_x86cpuid(0x80000001, regs1); /* get vendor features */ + mdSysInfo.Cpu.X86CpuInfo.AMDExtendedCpuFeatures = regs1[3]; + } + } + } + else + { + unsigned i; + ULONG64 one = 1; + + mdSysInfo.Cpu.OtherCpuInfo.ProcessorFeatures[0] = 0; + mdSysInfo.Cpu.OtherCpuInfo.ProcessorFeatures[1] = 0; + + for (i = 0; i < sizeof(mdSysInfo.Cpu.OtherCpuInfo.ProcessorFeatures[0]) * 8; i++) + if (IsProcessorFeaturePresent(i)) + mdSysInfo.Cpu.OtherCpuInfo.ProcessorFeatures[0] |= one << i; + } append(dc, &mdSysInfo, sizeof(mdSysInfo)); /* write the service pack version string after this stream. It is referenced within the