aboutsummaryrefslogtreecommitdiff
path: root/src/processor
diff options
context:
space:
mode:
authordigit@chromium.org <digit@chromium.org@4c0a9323-5329-0410-9bdc-e9ce6186880e>2013-04-24 10:06:14 +0000
committerdigit@chromium.org <digit@chromium.org@4c0a9323-5329-0410-9bdc-e9ce6186880e>2013-04-24 10:06:14 +0000
commit593eff42ca4a5c38835577cf83152f356d262414 (patch)
tree6102e9d82b8f109d9aab1d52bdff2e4d75fcb9fe /src/processor
parentCleanup: Remove duplicate wording in license headers. (diff)
downloadbreakpad-593eff42ca4a5c38835577cf83152f356d262414.tar.xz
Improve ARM CPU info reporting.
This patch improves several things for Linux/ARM: - Better detection of the number of CPUs on the target device. The content of /proc/cpuinfo only matches the number of "online" CPUs, which varies over time with recent Android devices. - Reconstruct the CPUID and ELF hwcaps values from /proc/cpuinfo, this is useful to better identify target devices in minidumps. - Make minidump_dump display the new information in useful ways. - Write a small helper class to parse /proc/cpuinfo and also use it for x86/64. - Write a small helper class to parse sysfds cpu lists. - Add a my_memchr() implementation. - Add unit tests. Tested on a Nexus S (1 CPU), Galaxy Nexus (2 CPUs) and a Nexus 4 (4 CPUs). Review URL: https://breakpad.appspot.com/540003 git-svn-id: http://google-breakpad.googlecode.com/svn/trunk@1160 4c0a9323-5329-0410-9bdc-e9ce6186880e
Diffstat (limited to 'src/processor')
-rw-r--r--src/processor/minidump_processor.cc123
-rw-r--r--src/processor/synth_minidump.cc3
2 files changed, 126 insertions, 0 deletions
diff --git a/src/processor/minidump_processor.cc b/src/processor/minidump_processor.cc
index afe15ca6..2d14cb37 100644
--- a/src/processor/minidump_processor.cc
+++ b/src/processor/minidump_processor.cc
@@ -305,6 +305,128 @@ static const MDRawSystemInfo* GetSystemInfo(Minidump *dump,
return minidump_system_info->system_info();
}
+// Extract CPU info string from ARM-specific MDRawSystemInfo structure.
+// raw_info: pointer to source MDRawSystemInfo.
+// cpu_info: address of target string, cpu info text will be appended to it.
+static void GetARMCpuInfo(const MDRawSystemInfo* raw_info,
+ std::string* cpu_info) {
+ assert(raw_info != NULL && cpu_info != NULL);
+
+ // Write ARM architecture version.
+ char cpu_string[32];
+ snprintf(cpu_string, sizeof(cpu_string), "ARMv%d",
+ raw_info->processor_level);
+ cpu_info->append(cpu_string);
+
+ // There is no good list of implementer id values, but the following
+ // pages provide some help:
+ // http://comments.gmane.org/gmane.linux.linaro.devel/6903
+ // http://forum.xda-developers.com/archive/index.php/t-480226.html
+ const struct {
+ uint32_t id;
+ const char* name;
+ } vendors[] = {
+ { 0x41, "ARM" },
+ { 0x51, "Qualcomm" },
+ { 0x56, "Marvell" },
+ { 0x69, "Intel/Marvell" },
+ };
+ const struct {
+ uint32_t id;
+ const char* name;
+ } parts[] = {
+ { 0x4100c050, "Cortex-A5" },
+ { 0x4100c080, "Cortex-A8" },
+ { 0x4100c090, "Cortex-A9" },
+ { 0x4100c0f0, "Cortex-A15" },
+ { 0x4100c140, "Cortex-R4" },
+ { 0x4100c150, "Cortex-R5" },
+ { 0x4100b360, "ARM1136" },
+ { 0x4100b560, "ARM1156" },
+ { 0x4100b760, "ARM1176" },
+ { 0x4100b020, "ARM11-MPCore" },
+ { 0x41009260, "ARM926" },
+ { 0x41009460, "ARM946" },
+ { 0x41009660, "ARM966" },
+ { 0x510006f0, "Krait" },
+ { 0x510000f0, "Scorpion" },
+ };
+
+ const struct {
+ uint32_t hwcap;
+ const char* name;
+ } features[] = {
+ { MD_CPU_ARM_ELF_HWCAP_SWP, "swp" },
+ { MD_CPU_ARM_ELF_HWCAP_HALF, "half" },
+ { MD_CPU_ARM_ELF_HWCAP_THUMB, "thumb" },
+ { MD_CPU_ARM_ELF_HWCAP_26BIT, "26bit" },
+ { MD_CPU_ARM_ELF_HWCAP_FAST_MULT, "fastmult" },
+ { MD_CPU_ARM_ELF_HWCAP_FPA, "fpa" },
+ { MD_CPU_ARM_ELF_HWCAP_VFP, "vfpv2" },
+ { MD_CPU_ARM_ELF_HWCAP_EDSP, "edsp" },
+ { MD_CPU_ARM_ELF_HWCAP_JAVA, "java" },
+ { MD_CPU_ARM_ELF_HWCAP_IWMMXT, "iwmmxt" },
+ { MD_CPU_ARM_ELF_HWCAP_CRUNCH, "crunch" },
+ { MD_CPU_ARM_ELF_HWCAP_THUMBEE, "thumbee" },
+ { MD_CPU_ARM_ELF_HWCAP_NEON, "neon" },
+ { MD_CPU_ARM_ELF_HWCAP_VFPv3, "vfpv3" },
+ { MD_CPU_ARM_ELF_HWCAP_VFPv3D16, "vfpv3d16" },
+ { MD_CPU_ARM_ELF_HWCAP_TLS, "tls" },
+ { MD_CPU_ARM_ELF_HWCAP_VFPv4, "vfpv4" },
+ { MD_CPU_ARM_ELF_HWCAP_IDIVA, "idiva" },
+ { MD_CPU_ARM_ELF_HWCAP_IDIVT, "idivt" },
+ };
+
+ uint32_t cpuid = raw_info->cpu.arm_cpu_info.cpuid;
+ if (cpuid != 0) {
+ // Extract vendor name from CPUID
+ const char* vendor = NULL;
+ uint32_t vendor_id = (cpuid >> 24) & 0xff;
+ for (size_t i = 0; i < sizeof(vendors)/sizeof(vendors[0]); ++i) {
+ if (vendors[i].id == vendor_id) {
+ vendor = vendors[i].name;
+ break;
+ }
+ }
+ cpu_info->append(" ");
+ if (vendor) {
+ cpu_info->append(vendor);
+ } else {
+ snprintf(cpu_string, sizeof(cpu_string), "vendor(0x%x)", vendor_id);
+ cpu_info->append(cpu_string);
+ }
+
+ // Extract part name from CPUID
+ uint32_t part_id = (cpuid & 0xff00fff0);
+ const char* part = NULL;
+ for (size_t i = 0; i < sizeof(parts)/sizeof(parts[0]); ++i) {
+ if (parts[i].id == part_id) {
+ part = parts[i].name;
+ break;
+ }
+ }
+ cpu_info->append(" ");
+ if (part != NULL) {
+ cpu_info->append(part);
+ } else {
+ snprintf(cpu_string, sizeof(cpu_string), "part(0x%x)", part_id);
+ cpu_info->append(cpu_string);
+ }
+ }
+ uint32_t elf_hwcaps = raw_info->cpu.arm_cpu_info.elf_hwcaps;
+ if (elf_hwcaps != 0) {
+ cpu_info->append(" features: ");
+ const char* comma = "";
+ for (size_t i = 0; i < sizeof(features)/sizeof(features[0]); ++i) {
+ if (elf_hwcaps & features[i].hwcap) {
+ cpu_info->append(comma);
+ cpu_info->append(features[i].name);
+ comma = ",";
+ }
+ }
+ }
+}
+
// static
bool MinidumpProcessor::GetCPUInfo(Minidump *dump, SystemInfo *info) {
assert(dump);
@@ -359,6 +481,7 @@ bool MinidumpProcessor::GetCPUInfo(Minidump *dump, SystemInfo *info) {
case MD_CPU_ARCHITECTURE_ARM: {
info->cpu = "arm";
+ GetARMCpuInfo(raw_system_info, &info->cpu_info);
break;
}
diff --git a/src/processor/synth_minidump.cc b/src/processor/synth_minidump.cc
index 377368ac..0940a357 100644
--- a/src/processor/synth_minidump.cc
+++ b/src/processor/synth_minidump.cc
@@ -77,6 +77,9 @@ SystemInfo::SystemInfo(const Dump &dump,
D32(system_info.cpu.x86_cpu_info.version_information);
D32(system_info.cpu.x86_cpu_info.feature_information);
D32(system_info.cpu.x86_cpu_info.amd_extended_cpu_features);
+ } else if (system_info.processor_architecture == MD_CPU_ARCHITECTURE_ARM) {
+ D32(system_info.cpu.arm_cpu_info.cpuid);
+ D32(system_info.cpu.arm_cpu_info.elf_hwcaps);
} else {
D64(system_info.cpu.other_cpu_info.processor_features[0]);
D64(system_info.cpu.other_cpu_info.processor_features[1]);