Debugger: Restrict registers via CPU feature detection.

DebuggerInterface,Architecture{X86,X8664}:
- Add hook function for retrieving a feature flag mask for the target CPU,
  and corresponding implementation in Architecture-specific classes.

ArchitectureX86:
- Read CPU features on init, and use them to restrict the exposed set of
  registers such that the MMX and SSE registers will only be visible
  if the target CPU actually supports the respective instructions.
This commit is contained in:
Rene Gollent
2015-04-26 16:38:30 -04:00
parent 3127a22868
commit 5fb2009931
7 changed files with 93 additions and 20 deletions
+3 -1
View File
@@ -1,6 +1,6 @@
/*
* Copyright 2009, Ingo Weinhold, [email protected].
* Copyright 2011-2012, Rene Gollent, [email protected].
* Copyright 2011-2015, Rene Gollent, [email protected].
* Distributed under the terms of the MIT License.
*/
#ifndef ARCHITECTURE_H
@@ -70,6 +70,8 @@ public:
RegisterMap** _fromDwarf) const = 0;
// returns references
virtual status_t GetCpuFeatures(uint32& flags) = 0;
virtual status_t CreateCpuState(CpuState*& _state) = 0;
virtual status_t CreateCpuState(const void* cpuStateData,
size_t size, CpuState*& _state) = 0;
+58 -17
View File
@@ -1,6 +1,6 @@
/*
* Copyright 2009-2012, Ingo Weinhold, [email protected].
* Copyright 2011-2014, Rene Gollent, [email protected].
* Copyright 2011-2015, Rene Gollent, [email protected].
* Distributed under the terms of the MIT License.
*/
@@ -29,6 +29,10 @@
#include "disasm/DisassemblerX86.h"
#define IA32_FEATURE_MMX (1 << 23)
#define IA32_FEATURE_SSE (1 << 25)
static const int32 kFromDwarfRegisters[] = {
X86_REGISTER_EAX,
X86_REGISTER_ECX,
@@ -124,6 +128,7 @@ struct ArchitectureX86::FromDwarfRegisterMap : RegisterMap {
ArchitectureX86::ArchitectureX86(TeamMemory* teamMemory)
:
Architecture(teamMemory, 4, false),
fFeatureFlags(0),
fAssemblyLanguage(NULL),
fToDwarfRegisterMap(NULL),
fFromDwarfRegisterMap(NULL)
@@ -149,6 +154,20 @@ ArchitectureX86::Init()
if (fAssemblyLanguage == NULL)
return B_NO_MEMORY;
#if defined(__INTEL__)
cpuid_info info;
status_t error = get_cpuid(&info, 1, 0);
if (error != B_OK)
return error;
if ((info.eax_1.features & IA32_FEATURE_MMX) != 0)
fFeatureFlags |= X86_CPU_FEATURE_FLAG_MMX;
if ((info.eax_1.features & IA32_FEATURE_SSE) != 0)
fFeatureFlags |= X86_CPU_FEATURE_FLAG_SSE;
#endif
try {
_AddIntegerRegister(X86_REGISTER_EIP, "eip", B_UINT32_TYPE,
REGISTER_TYPE_INSTRUCTION_POINTER, false);
@@ -193,23 +212,35 @@ ArchitectureX86::Init()
_AddFPRegister(X86_REGISTER_ST6, "st6");
_AddFPRegister(X86_REGISTER_ST7, "st7");
_AddSIMDRegister(X86_REGISTER_MM0, "mm0", sizeof(uint64));
_AddSIMDRegister(X86_REGISTER_MM1, "mm1", sizeof(uint64));
_AddSIMDRegister(X86_REGISTER_MM2, "mm2", sizeof(uint64));
_AddSIMDRegister(X86_REGISTER_MM3, "mm3", sizeof(uint64));
_AddSIMDRegister(X86_REGISTER_MM4, "mm4", sizeof(uint64));
_AddSIMDRegister(X86_REGISTER_MM5, "mm5", sizeof(uint64));
_AddSIMDRegister(X86_REGISTER_MM6, "mm6", sizeof(uint64));
_AddSIMDRegister(X86_REGISTER_MM7, "mm7", sizeof(uint64));
if ((fFeatureFlags & X86_CPU_FEATURE_FLAG_MMX) != 0) {
_AddSIMDRegister(X86_REGISTER_MM0, "mm0", sizeof(uint64));
_AddSIMDRegister(X86_REGISTER_MM1, "mm1", sizeof(uint64));
_AddSIMDRegister(X86_REGISTER_MM2, "mm2", sizeof(uint64));
_AddSIMDRegister(X86_REGISTER_MM3, "mm3", sizeof(uint64));
_AddSIMDRegister(X86_REGISTER_MM4, "mm4", sizeof(uint64));
_AddSIMDRegister(X86_REGISTER_MM5, "mm5", sizeof(uint64));
_AddSIMDRegister(X86_REGISTER_MM6, "mm6", sizeof(uint64));
_AddSIMDRegister(X86_REGISTER_MM7, "mm7", sizeof(uint64));
}
_AddSIMDRegister(X86_REGISTER_XMM0, "xmm0", sizeof(x86_xmm_register));
_AddSIMDRegister(X86_REGISTER_XMM1, "xmm1", sizeof(x86_xmm_register));
_AddSIMDRegister(X86_REGISTER_XMM2, "xmm2", sizeof(x86_xmm_register));
_AddSIMDRegister(X86_REGISTER_XMM3, "xmm3", sizeof(x86_xmm_register));
_AddSIMDRegister(X86_REGISTER_XMM4, "xmm4", sizeof(x86_xmm_register));
_AddSIMDRegister(X86_REGISTER_XMM5, "xmm5", sizeof(x86_xmm_register));
_AddSIMDRegister(X86_REGISTER_XMM6, "xmm6", sizeof(x86_xmm_register));
_AddSIMDRegister(X86_REGISTER_XMM7, "xmm7", sizeof(x86_xmm_register));
if ((fFeatureFlags & X86_CPU_FEATURE_FLAG_SSE) != 0) {
_AddSIMDRegister(X86_REGISTER_XMM0, "xmm0",
sizeof(x86_xmm_register));
_AddSIMDRegister(X86_REGISTER_XMM1, "xmm1",
sizeof(x86_xmm_register));
_AddSIMDRegister(X86_REGISTER_XMM2, "xmm2",
sizeof(x86_xmm_register));
_AddSIMDRegister(X86_REGISTER_XMM3, "xmm3",
sizeof(x86_xmm_register));
_AddSIMDRegister(X86_REGISTER_XMM4, "xmm4",
sizeof(x86_xmm_register));
_AddSIMDRegister(X86_REGISTER_XMM5, "xmm5",
sizeof(x86_xmm_register));
_AddSIMDRegister(X86_REGISTER_XMM6, "xmm6",
sizeof(x86_xmm_register));
_AddSIMDRegister(X86_REGISTER_XMM7, "xmm7",
sizeof(x86_xmm_register));
}
} catch (std::bad_alloc) {
return B_NO_MEMORY;
@@ -246,6 +277,7 @@ ArchitectureX86::Registers() const
}
status_t
ArchitectureX86::InitRegisterRules(CfaContext& context) const
{
@@ -279,6 +311,15 @@ ArchitectureX86::GetDwarfRegisterMaps(RegisterMap** _toDwarf,
}
status_t
ArchitectureX86::GetCpuFeatures(uint32& flags)
{
flags = fFeatureFlags;
return B_OK;
}
status_t
ArchitectureX86::CreateCpuState(CpuState*& _state)
{
+11 -1
View File
@@ -1,6 +1,6 @@
/*
* Copyright 2009, Ingo Weinhold, [email protected].
* Copyright 2011-2014, Rene Gollent, [email protected].
* Copyright 2011-2015, Rene Gollent, [email protected].
* Distributed under the terms of the MIT License.
*/
#ifndef ARCHITECTURE_X86_H
@@ -13,6 +13,13 @@
#include "Register.h"
enum {
X86_CPU_FEATURE_FLAG_NONE = 0,
X86_CPU_FEATURE_FLAG_MMX = 1,
X86_CPU_FEATURE_FLAG_SSE = 2
};
class SourceLanguage;
@@ -32,6 +39,8 @@ public:
virtual status_t GetDwarfRegisterMaps(RegisterMap** _toDwarf,
RegisterMap** _fromDwarf) const;
virtual status_t GetCpuFeatures(uint32& flags);
virtual status_t CreateCpuState(CpuState*& _state);
virtual status_t CreateCpuState(const void* cpuStateData,
size_t size, CpuState*& _state);
@@ -94,6 +103,7 @@ private:
FunctionDebugInfo* function) const;
private:
uint32 fFeatureFlags;
Array<Register> fRegisters;
SourceLanguage* fAssemblyLanguage;
ToDwarfRegisterMap* fToDwarfRegisterMap;
@@ -341,6 +341,15 @@ ArchitectureX8664::GetDwarfRegisterMaps(RegisterMap** _toDwarf,
}
status_t
ArchitectureX8664::GetCpuFeatures(uint32& flags)
{
// TODO: implement if/when it winds up being needed.
flags = 0;
return B_OK;
}
status_t
ArchitectureX8664::CreateCpuState(CpuState*& _state)
{
@@ -33,6 +33,8 @@ public:
virtual status_t GetDwarfRegisterMaps(RegisterMap** _toDwarf,
RegisterMap** _fromDwarf) const;
virtual status_t GetCpuFeatures(uint32& flags);
virtual status_t CreateCpuState(CpuState*& _state);
virtual status_t CreateCpuState(const void* cpuStateData,
size_t size, CpuState*& _state);
@@ -1,6 +1,6 @@
/*
* Copyright 2009-2012, Ingo Weinhold, ingo_weinhold@gmx.de.
* Copyright 2010-2013, Rene Gollent, rene@gollent.com.
* Copyright 2010-2015, Rene Gollent, rene@gollent.com.
* Distributed under the terms of the MIT License.
*/
@@ -701,6 +701,13 @@ DebuggerInterface::SetCpuState(thread_id thread, const CpuState* state)
}
status_t
DebuggerInterface::GetCpuFeatures(uint32& flags)
{
return fArchitecture->GetCpuFeatures(flags);
}
ssize_t
DebuggerInterface::ReadMemory(target_addr_t address, void* buffer, size_t size)
{
@@ -80,6 +80,8 @@ public:
virtual status_t SetCpuState(thread_id thread,
const CpuState* state);
virtual status_t GetCpuFeatures(uint32& flags);
// TeamMemory
virtual ssize_t ReadMemory(target_addr_t address, void* buffer,
size_t size);