mirror of
https://github.com/yuzu-emu/breakpad.git
synced 2024-11-24 16:25:49 +01:00
Fill in CPU info in mini-dump for Arm64.
Adds Arm64 varients of CPUFillThreadInfo and CPUFillFromUContext and WriteCPUInformation for the Linux/Android client. BUG=354405,335641 R=mark@chromium.org Review URL: https://breakpad.appspot.com/1464002 git-svn-id: http://google-breakpad.googlecode.com/svn/trunk@1310 4c0a9323-5329-0410-9bdc-e9ce6186880e
This commit is contained in:
parent
6b0703a093
commit
a2245d6744
@ -378,12 +378,34 @@ typedef MDRawContextARM64 RawContextCPU;
|
|||||||
|
|
||||||
void CPUFillFromThreadInfo(MDRawContextARM64* out,
|
void CPUFillFromThreadInfo(MDRawContextARM64* out,
|
||||||
const google_breakpad::ThreadInfo& info) {
|
const google_breakpad::ThreadInfo& info) {
|
||||||
// TODO(rmcilroy): Implement for arm64.
|
out->context_flags = MD_CONTEXT_ARM64_FULL;
|
||||||
|
|
||||||
|
out->cpsr = static_cast<uint32_t>(info.regs.pstate);
|
||||||
|
for (int i = 0; i < MD_CONTEXT_ARM64_REG_SP; ++i)
|
||||||
|
out->iregs[i] = info.regs.regs[i];
|
||||||
|
out->iregs[MD_CONTEXT_ARM64_REG_SP] = info.regs.sp;
|
||||||
|
out->iregs[MD_CONTEXT_ARM64_REG_PC] = info.regs.pc;
|
||||||
|
|
||||||
|
out->float_save.fpsr = info.fpregs.fpsr;
|
||||||
|
out->float_save.fpcr = info.fpregs.fpcr;
|
||||||
|
my_memcpy(&out->float_save.regs, &info.fpregs.vregs,
|
||||||
|
MD_FLOATINGSAVEAREA_ARM64_FPR_COUNT * 16);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CPUFillFromUContext(MDRawContextARM64* out, const ucontext* uc,
|
void CPUFillFromUContext(MDRawContextARM64* out, const ucontext* uc,
|
||||||
const struct fpsimd_context* fpregs) {
|
const struct fpsimd_context* fpregs) {
|
||||||
// TODO(rmcilroy): Implement for arm64.
|
out->context_flags = MD_CONTEXT_ARM64_FULL;
|
||||||
|
|
||||||
|
out->cpsr = static_cast<uint32_t>(uc->uc_mcontext.pstate);
|
||||||
|
for (int i = 0; i < MD_CONTEXT_ARM64_REG_SP; ++i)
|
||||||
|
out->iregs[i] = uc->uc_mcontext.regs[i];
|
||||||
|
out->iregs[MD_CONTEXT_ARM64_REG_SP] = uc->uc_mcontext.sp;
|
||||||
|
out->iregs[MD_CONTEXT_ARM64_REG_PC] = uc->uc_mcontext.pc;
|
||||||
|
|
||||||
|
out->float_save.fpsr = fpregs->fpsr;
|
||||||
|
out->float_save.fpcr = fpregs->fpcr;
|
||||||
|
my_memcpy(&out->float_save.regs, &fpregs->vregs,
|
||||||
|
MD_FLOATINGSAVEAREA_ARM64_FPR_COUNT * 16);
|
||||||
}
|
}
|
||||||
|
|
||||||
#elif defined(__mips__)
|
#elif defined(__mips__)
|
||||||
@ -1328,7 +1350,7 @@ class MinidumpWriter {
|
|||||||
bool found;
|
bool found;
|
||||||
} cpu_info_table[] = {
|
} cpu_info_table[] = {
|
||||||
{ "processor", -1, false },
|
{ "processor", -1, false },
|
||||||
#if !defined(__mips__)
|
#if defined(__i386__) || defined(__x86_64__)
|
||||||
{ "model", 0, false },
|
{ "model", 0, false },
|
||||||
{ "stepping", 0, false },
|
{ "stepping", 0, false },
|
||||||
{ "cpu family", 0, false },
|
{ "cpu family", 0, false },
|
||||||
@ -1402,7 +1424,7 @@ class MinidumpWriter {
|
|||||||
cpu_info_table[0].value++;
|
cpu_info_table[0].value++;
|
||||||
|
|
||||||
sys_info->number_of_processors = cpu_info_table[0].value;
|
sys_info->number_of_processors = cpu_info_table[0].value;
|
||||||
#if !defined(__mips__)
|
#if defined(__i386__) || defined(__x86_64__)
|
||||||
sys_info->processor_level = cpu_info_table[3].value;
|
sys_info->processor_level = cpu_info_table[3].value;
|
||||||
sys_info->processor_revision = cpu_info_table[1].value << 8 |
|
sys_info->processor_revision = cpu_info_table[1].value << 8 |
|
||||||
cpu_info_table[2].value;
|
cpu_info_table[2].value;
|
||||||
@ -1414,7 +1436,7 @@ class MinidumpWriter {
|
|||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
#elif defined(__arm__)
|
#elif defined(__arm__) || defined(__aarch64__)
|
||||||
bool WriteCPUInformation(MDRawSystemInfo* sys_info) {
|
bool WriteCPUInformation(MDRawSystemInfo* sys_info) {
|
||||||
// The CPUID value is broken up in several entries in /proc/cpuinfo.
|
// The CPUID value is broken up in several entries in /proc/cpuinfo.
|
||||||
// This table is used to rebuild it from the entries.
|
// This table is used to rebuild it from the entries.
|
||||||
@ -1436,6 +1458,7 @@ class MinidumpWriter {
|
|||||||
const char* tag;
|
const char* tag;
|
||||||
uint32_t hwcaps;
|
uint32_t hwcaps;
|
||||||
} cpu_features_entries[] = {
|
} cpu_features_entries[] = {
|
||||||
|
#if defined(__arm__)
|
||||||
{ "swp", MD_CPU_ARM_ELF_HWCAP_SWP },
|
{ "swp", MD_CPU_ARM_ELF_HWCAP_SWP },
|
||||||
{ "half", MD_CPU_ARM_ELF_HWCAP_HALF },
|
{ "half", MD_CPU_ARM_ELF_HWCAP_HALF },
|
||||||
{ "thumb", MD_CPU_ARM_ELF_HWCAP_THUMB },
|
{ "thumb", MD_CPU_ARM_ELF_HWCAP_THUMB },
|
||||||
@ -1456,10 +1479,18 @@ class MinidumpWriter {
|
|||||||
{ "idiva", MD_CPU_ARM_ELF_HWCAP_IDIVA },
|
{ "idiva", MD_CPU_ARM_ELF_HWCAP_IDIVA },
|
||||||
{ "idivt", MD_CPU_ARM_ELF_HWCAP_IDIVT },
|
{ "idivt", MD_CPU_ARM_ELF_HWCAP_IDIVT },
|
||||||
{ "idiv", MD_CPU_ARM_ELF_HWCAP_IDIVA | MD_CPU_ARM_ELF_HWCAP_IDIVT },
|
{ "idiv", MD_CPU_ARM_ELF_HWCAP_IDIVA | MD_CPU_ARM_ELF_HWCAP_IDIVT },
|
||||||
|
#elif defined(__aarch64__)
|
||||||
|
// No hwcaps on aarch64.
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
// processor_architecture should always be set, do this first
|
// processor_architecture should always be set, do this first
|
||||||
sys_info->processor_architecture = MD_CPU_ARCHITECTURE_ARM;
|
sys_info->processor_architecture =
|
||||||
|
#if defined(__aarch64__)
|
||||||
|
MD_CPU_ARCHITECTURE_ARM64;
|
||||||
|
#else
|
||||||
|
MD_CPU_ARCHITECTURE_ARM;
|
||||||
|
#endif
|
||||||
|
|
||||||
// /proc/cpuinfo is not readable under various sandboxed environments
|
// /proc/cpuinfo is not readable under various sandboxed environments
|
||||||
// (e.g. Android services with the android:isolatedProcess attribute)
|
// (e.g. Android services with the android:isolatedProcess attribute)
|
||||||
@ -1543,13 +1574,14 @@ class MinidumpWriter {
|
|||||||
sys_info->cpu.arm_cpu_info.cpuid |=
|
sys_info->cpu.arm_cpu_info.cpuid |=
|
||||||
static_cast<uint32_t>(result);
|
static_cast<uint32_t>(result);
|
||||||
}
|
}
|
||||||
|
#if defined(__arm__)
|
||||||
// Get the architecture version from the "Processor" field.
|
// Get the architecture version from the "Processor" field.
|
||||||
// Note that it is also available in the "CPU architecture" field,
|
// Note that it is also available in the "CPU architecture" field,
|
||||||
// however, some existing kernels are misconfigured and will report
|
// however, some existing kernels are misconfigured and will report
|
||||||
// invalid values here (e.g. 6, while the CPU is ARMv7-A based).
|
// invalid values here (e.g. 6, while the CPU is ARMv7-A based).
|
||||||
// The "Processor" field doesn't have this issue.
|
// The "Processor" field doesn't have this issue.
|
||||||
if (!my_strcmp(field, "Processor")) {
|
if (!my_strcmp(field, "Processor")) {
|
||||||
unsigned value_len;
|
size_t value_len;
|
||||||
const char* value = reader->GetValueAndLen(&value_len);
|
const char* value = reader->GetValueAndLen(&value_len);
|
||||||
// Expected format: <text> (v<level><endian>)
|
// Expected format: <text> (v<level><endian>)
|
||||||
// Where <text> is some text like "ARMv7 Processor rev 2"
|
// Where <text> is some text like "ARMv7 Processor rev 2"
|
||||||
@ -1568,9 +1600,23 @@ class MinidumpWriter {
|
|||||||
sys_info->processor_level = static_cast<uint16_t>(arch_level);
|
sys_info->processor_level = static_cast<uint16_t>(arch_level);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#elif defined(__aarch64__)
|
||||||
|
// The aarch64 architecture does not provide the architecture level
|
||||||
|
// in the Processor field, so we instead check the "CPU architecture"
|
||||||
|
// field.
|
||||||
|
if (!my_strcmp(field, "CPU architecture")) {
|
||||||
|
uintptr_t arch_level = 0;
|
||||||
|
const char* value = reader->GetValue();
|
||||||
|
const char* p = value;
|
||||||
|
p = my_read_decimal_ptr(&arch_level, value);
|
||||||
|
if (p == value)
|
||||||
|
continue;
|
||||||
|
sys_info->processor_level = static_cast<uint16_t>(arch_level);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
// Rebuild the ELF hwcaps from the 'Features' field.
|
// Rebuild the ELF hwcaps from the 'Features' field.
|
||||||
if (!my_strcmp(field, "Features")) {
|
if (!my_strcmp(field, "Features")) {
|
||||||
unsigned value_len;
|
size_t value_len;
|
||||||
const char* value = reader->GetValueAndLen(&value_len);
|
const char* value = reader->GetValueAndLen(&value_len);
|
||||||
|
|
||||||
// Parse each space-separated tag.
|
// Parse each space-separated tag.
|
||||||
@ -1605,11 +1651,6 @@ class MinidumpWriter {
|
|||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
#elif defined(__aarch64__)
|
|
||||||
bool WriteCPUInformation(MDRawSystemInfo* sys_info) {
|
|
||||||
// TODO(rmcilroy): Implement for arm64.
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
#else
|
#else
|
||||||
# error "Unsupported CPU"
|
# error "Unsupported CPU"
|
||||||
#endif
|
#endif
|
||||||
|
Loading…
Reference in New Issue
Block a user