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:
@@ -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;
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user