Skip to content

Commit

Permalink
PRD: cleaned BitString::Mask()
Browse files Browse the repository at this point in the history
This function had a off-by-one error that could access memory beyond
the available memory space.

Change-Id: I32e547c7238e3307f189334638c6239ea6940e62
RTC: 167819
Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/35690
Tested-by: Jenkins Server <pfd-jenkins+hostboot@us.ibm.com>
Reviewed-by: Benjamin J. Weisenbeck <bweisenb@us.ibm.com>
Reviewed-by: Caleb N. Palmer <cnpalmer@us.ibm.com>
Reviewed-by: Zane C. Shelley <zshelle@us.ibm.com>
Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/36203
Tested-by: FSP CI Jenkins <fsp-CI-jenkins+hostboot@us.ibm.com>
  • Loading branch information
zane131 committed Feb 10, 2017
1 parent 982dd4c commit 4885380
Show file tree
Hide file tree
Showing 5 changed files with 33 additions and 99 deletions.
2 changes: 1 addition & 1 deletion src/usr/diag/prdf/common/framework/register/iipscr.C
Expand Up @@ -120,7 +120,7 @@ uint32_t SCAN_COMM_REGISTER_CLASS::Read
if(rc == SUCCESS)
{
BIT_STRING_CLASS & bitString = AccessBitString();
bitString.Mask(mask);
bitString.maskString(mask);
}

return(rc);
Expand Down
Expand Up @@ -110,14 +110,14 @@ const BIT_STRING_CLASS & ErrorRegisterMask::Read()
scr_rc = scr.Read();
bitString = *scr.GetBitString();
// apply software mask
bitString.Mask(bitStringMask);
bitString.maskString(bitStringMask);
// apply hardware mask - if scan comm register for it was specified
if(&xMaskScr != NULL) /*constant condition*/ // dg00
{ // dg00
int32_t rc = xMaskScr.Read(); // dg00
if(rc == SUCCESS) // dg00
{ // dg00
bitString.Mask(*(xMaskScr.GetBitString())); // dg00
bitString.maskString(*(xMaskScr.GetBitString())); // dg00
} // dg00
} // dg00

Expand Down
2 changes: 1 addition & 1 deletion src/usr/diag/prdf/common/util/prdfBitKey.C
Expand Up @@ -326,7 +326,7 @@ void BitKey::removeBits(const BitKey & i_bk)
{
BitString mybs(iv_Capacity,(CPU_WORD *)DataPtr());
const BitString yobs(i_bk.iv_Capacity,(CPU_WORD *)i_bk.cDataPtr());
mybs.Mask(yobs);
mybs.maskString(yobs);
}

//------------------------------------------------------------------------------
Expand Down
89 changes: 18 additions & 71 deletions src/usr/diag/prdf/common/util/prdfBitString.C
Expand Up @@ -128,6 +128,24 @@ void BitString::setString( const BitString & i_sStr, uint32_t i_sPos,

//------------------------------------------------------------------------------

void BitString::maskString( const BitString & i_mask )
{
// Get the length of the smallest string.
uint32_t actLen = std::min( getBitLen(), i_mask.getBitLen() );

for ( uint32_t pos = 0; pos < actLen; pos += CPU_WORD_BIT_LEN )
{
uint32_t len = std::min( actLen - pos, CPU_WORD_BIT_LEN );

CPU_WORD dVal = GetField( pos, len );
CPU_WORD sVal = i_mask.GetField( pos, len );

SetField( pos, len, dVal & ~sVal );
}
}

//------------------------------------------------------------------------------

uint32_t BitString::GetSetCount(uint32_t bit_position,
uint32_t leng
) const
Expand Down Expand Up @@ -367,77 +385,6 @@ bool BitString::IsZero() const
return true; // everything was zero
}

// Function Specification //////////////////////////////////////////
//
// Title: Mask
//
// Purpose: This function masks the bits in the string with the
// corresponding bits in the specified Bit String. For
// each corresponding position, if the bit in the
// parameter Bit String is set(1), the bit in this string
// is cleared(0). If the length of the parameter string
// is greater than the length of this string, then the
// extra bits are ignored. If the length of the
// parameter string are less than this the length of
// this string, then the extra bits in this string are
// not modified.
//
// Side-effects: Bit String may be modified.
//
// Dependencies: None.
//
// Time Complexity: O(m) where m is the length
//
// Examples: Parameter String: 1001
// Old String: 1100
// New String: 0100
//
// Parameter String: 100111
// Old String: 1100
// New String: 0100
//
// Parameter String: 1001
// Old String: 110001
// New String: 010001
//
// End Function Specification //////////////////////////////////////

void BitString::Mask
(
const BitString & string
)
{
CPU_WORD value, string_value;
uint32_t current_offset;
uint32_t l;

/* Use smaller length */
l = std::min(iv_bitLen, string.iv_bitLen);

current_offset = 0;
while(true)
{
if(l > CPU_WORD_BIT_LEN)
{
/* Set values using full CPU_WORDs */
value = GetField(current_offset, CPU_WORD_BIT_LEN);
string_value = string.GetField(current_offset, CPU_WORD_BIT_LEN);
SetField(current_offset, CPU_WORD_BIT_LEN,
value & (~string_value));
l -= CPU_WORD_BIT_LEN;
current_offset += CPU_WORD_BIT_LEN;
}
else
{
/* Set value in remainder of last CPU_WORD */
value = GetField(current_offset, l);
string_value = string.GetField(current_offset, l);
SetField(current_offset, l, value & (~string_value));
break;
}
}
}

//-------------------------------------------------------------------------------------------------

CPU_WORD * BitString::GetRelativePosition(uint32_t & oBitOffset, uint32_t iBitPos) const
Expand Down
35 changes: 11 additions & 24 deletions src/usr/diag/prdf/common/util/prdfBitString.H
Expand Up @@ -228,6 +228,17 @@ class BitString
setString( i_sStr, 0, i_sStr.getBitLen() );
}

/**
* @brief Masks (clears) any bits set in this string that correspond to bits
* set in the given string (this & ~mask).
* @param i_mask The mask string.
* @note If the length of the given string is greater than the length of
* this string, then the extra bits are ignored.
* @note If the length of the given string is less than the length of this
* string, then the extra bits in this string are not modified.
*/
void maskString( const BitString & i_mask );

/*!
Comparison
\remarks The bitstrings must be the same length and have the same bits set to be equal
Expand Down Expand Up @@ -334,30 +345,6 @@ class BitString
*/
bool IsZero(void) const;

/*!
Mask off (Clear) bits positions in this string that are Set in the string provided
\param bitString containing the mask
\post Set bit positions in string provided are cleared in this string
\notes If the parameter string is longer than this string than extra bits are ignored.
If the parameter string is shorter than this string than extra bits in this string
are not modified.
\verbatim
Examples: Parameter String: 1001
Old String: 1100
New String: 0100
Parameter String: 100111
Old String: 1100
New String: 0100
Parameter String: 1001
Old String: 110001
New String: 010001
\endverbatim
*/
void Mask(const BitString & string);

/*!
Utility to Right justify a "Left-justified" value
\param iLen: length of bit field to justify
Expand Down

0 comments on commit 4885380

Please sign in to comment.