From 48853801cd21f72f5e109c559ba8e60c7d28927b Mon Sep 17 00:00:00 2001 From: Zane Shelley Date: Tue, 31 Jan 2017 14:15:14 -0600 Subject: [PATCH] PRD: cleaned BitString::Mask() 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 Reviewed-by: Benjamin J. Weisenbeck Reviewed-by: Caleb N. Palmer Reviewed-by: Zane C. Shelley Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/36203 Tested-by: FSP CI Jenkins --- .../prdf/common/framework/register/iipscr.C | 2 +- .../register/prdfErrorRegisterMask.C | 4 +- src/usr/diag/prdf/common/util/prdfBitKey.C | 2 +- src/usr/diag/prdf/common/util/prdfBitString.C | 89 ++++--------------- src/usr/diag/prdf/common/util/prdfBitString.H | 35 +++----- 5 files changed, 33 insertions(+), 99 deletions(-) diff --git a/src/usr/diag/prdf/common/framework/register/iipscr.C b/src/usr/diag/prdf/common/framework/register/iipscr.C index 127992be5a0..bfc68ca3385 100755 --- a/src/usr/diag/prdf/common/framework/register/iipscr.C +++ b/src/usr/diag/prdf/common/framework/register/iipscr.C @@ -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); diff --git a/src/usr/diag/prdf/common/framework/register/prdfErrorRegisterMask.C b/src/usr/diag/prdf/common/framework/register/prdfErrorRegisterMask.C index 64aa1000930..0c083d03e49 100755 --- a/src/usr/diag/prdf/common/framework/register/prdfErrorRegisterMask.C +++ b/src/usr/diag/prdf/common/framework/register/prdfErrorRegisterMask.C @@ -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 diff --git a/src/usr/diag/prdf/common/util/prdfBitKey.C b/src/usr/diag/prdf/common/util/prdfBitKey.C index beb527866cb..79f64857289 100755 --- a/src/usr/diag/prdf/common/util/prdfBitKey.C +++ b/src/usr/diag/prdf/common/util/prdfBitKey.C @@ -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); } //------------------------------------------------------------------------------ diff --git a/src/usr/diag/prdf/common/util/prdfBitString.C b/src/usr/diag/prdf/common/util/prdfBitString.C index 7bc6ab7ee26..324dca132ae 100755 --- a/src/usr/diag/prdf/common/util/prdfBitString.C +++ b/src/usr/diag/prdf/common/util/prdfBitString.C @@ -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 @@ -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 diff --git a/src/usr/diag/prdf/common/util/prdfBitString.H b/src/usr/diag/prdf/common/util/prdfBitString.H index fe50ec13008..a54477fff75 100755 --- a/src/usr/diag/prdf/common/util/prdfBitString.H +++ b/src/usr/diag/prdf/common/util/prdfBitString.H @@ -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 @@ -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