[0.2.x] fixed : issue #11761 ( signed bit fields is not supported )

git-svn-id: https://pykd.svn.codeplex.com/svn@83601 9b283d60-5439-405e-af05-b73fd8c4d996
This commit is contained in:
SND\kernelnet_cp 2013-05-06 07:22:24 +00:00 committed by Mikhail I. Izmestev
parent 872e44b444
commit 963c0fdcc1
5 changed files with 74 additions and 19 deletions

View File

@ -432,6 +432,40 @@ BaseTypeVariant BitFieldVar::getValue()
m_varData->read( &val, getSize() );
if ( m_typeInfo->isSigned() )
{
ULONG width = m_typeInfo->getBitWidth();
val >>= m_typeInfo->getBitOffset();
if ( ( val & ( 1ULL << ( width -1 ) ) ) != 0 )
{
val |= ~( ( 1ULL << width ) - 1 );
}
else
{
val &= ( 1ULL << width ) - 1;
}
LONG64 signedVal = (LONG64)val;
switch ( m_typeInfo->getSize() )
{
case 1:
return (LONG)signedVal;
case 2:
return (LONG)signedVal;
case 4:
return (LONG)signedVal;
case 8:
return signedVal;
}
}
else
{
val >>= m_typeInfo->getBitOffset();
val &= ( 1 << m_typeInfo->getBitWidth() ) - 1;
@ -449,6 +483,8 @@ BaseTypeVariant BitFieldVar::getValue()
case 8:
return *(PULONG64)&val;
}
}
throw DbgException( "failed get value " );
}

View File

@ -351,6 +351,7 @@ BitFieldTypeInfo::BitFieldTypeInfo( SymbolPtr &symbol )
TypeInfoPtr typeInfo = TypeInfo::getBaseTypeInfo( symbol->getType() );
m_size = (ULONG)typeInfo->getSize();
m_signed = typeInfo->isSigned();
std::stringstream sstr;

View File

@ -171,6 +171,10 @@ public:
return false;
}
virtual bool isSigned() {
throw TypeException( getName(), "type is not based" );
}
virtual ULONG getCount() {
throw TypeException( getName(), "type is not an array" );
}
@ -276,10 +280,19 @@ private:
return true;
}
std::string m_name;
virtual bool isSigned() {
T t = static_cast<T>(-1);
return t < 0;
}
std::string m_name;
};
template<>
bool TypeInfoWrapper<bool>::isSigned() {
return false;
}
///////////////////////////////////////////////////////////////////////////////////
class BitFieldTypeInfo : public TypeInfo
@ -312,8 +325,13 @@ public:
return m_size;
}
virtual bool isSigned() {
return m_signed;
}
private:
bool m_signed;
ULONG m_size;
ULONG m_bitWidth;
ULONG m_bitPos;

View File

@ -140,11 +140,11 @@ class TypedVarTest( unittest.TestCase ):
tv = target.module.typedVar("g_structWithBits")
self.assertEqual( 4, tv.m_bit0_4 )
self.assertEqual( 1, tv.m_bit5 )
self.assertEqual( 3, tv.m_bit6_7 )
self.assertEqual( 5, tv.m_bit6_8 )
tv = target.module.typedVar("g_structWithSignBits")
self.assertEqual( 4, tv.m_bit0_4 )
self.assertEqual( -1, tv.m_bit5 )
self.assertEqual( -1, tv.m_bit6_7 )
self.assertEqual( -3, tv.m_bit6_8 )
def testTypedVarList(self):
tvl = target.module.typedVarList( target.module.g_listHead, "listStruct", "listEntry" )

View File

@ -44,13 +44,13 @@ std::string g_string;
struct structWithBits {
ULONG m_bit0_4 : 5;
ULONG m_bit5 : 1;
ULONG m_bit6_7 : 2;
ULONG m_bit6_8 : 3;
};
struct structWitSignBits {
LONG m_bit0_4 : 5;
LONG m_bit5 : 1;
LONG m_bit6_7 : 2;
LONG m_bit6_8 : 3;
};
@ -104,8 +104,8 @@ typedef struct structAbstract *pstructAbstract;
pstructAbstract g_structAbstract = 0;
structWithBits g_structWithBits = { 4, 1, 3};
structWitSignBits g_structWithSignBits = { 4, 1, 3 };
structWithBits g_structWithBits = { 4, 1, 5};
structWitSignBits g_structWithSignBits = { 4, 1, 5 };
structTest g_structTest = { 0, 500, true, 1, NULL };
structTest g_structTest1 = { 0, 500, true, 1, &g_structTest };