diff options
| author | Zane Shelley <zshelle@us.ibm.com> | 2017-01-31 10:21:32 -0600 |
|---|---|---|
| committer | Zane C. Shelley <zshelle@us.ibm.com> | 2017-02-10 17:34:54 -0500 |
| commit | a56b9bde18a2baac1b4e9b8f31ba1d7ff8f4ca71 (patch) | |
| tree | 50ffe23b298c73f48e625f3563d2cda875328844 /src/usr/diag/prdf/common/util | |
| parent | 500d4171608d4619d547f3a4dccedc67a3278561 (diff) | |
| download | talos-hostboot-a56b9bde18a2baac1b4e9b8f31ba1d7ff8f4ca71.tar.gz talos-hostboot-a56b9bde18a2baac1b4e9b8f31ba1d7ff8f4ca71.zip | |
PRD: cleaned BitString::Pattern()
This function had a off-by-one error that could access memory beyond
the available memory space.
Change-Id: I762d0e24f0cc7ecd42e7f9393b0dc5b3b8bddefc
RTC: 167819
Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/35688
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/36201
Tested-by: FSP CI Jenkins <fsp-CI-jenkins+hostboot@us.ibm.com>
Tested-by: Jenkins OP Build CI <op-jenkins+hostboot@us.ibm.com>
Diffstat (limited to 'src/usr/diag/prdf/common/util')
| -rwxr-xr-x | src/usr/diag/prdf/common/util/prdfBitKey.C | 8 | ||||
| -rwxr-xr-x | src/usr/diag/prdf/common/util/prdfBitString.C | 98 | ||||
| -rwxr-xr-x | src/usr/diag/prdf/common/util/prdfBitString.H | 134 |
3 files changed, 92 insertions, 148 deletions
diff --git a/src/usr/diag/prdf/common/util/prdfBitKey.C b/src/usr/diag/prdf/common/util/prdfBitKey.C index f7d211103..c8fdbedd7 100755 --- a/src/usr/diag/prdf/common/util/prdfBitKey.C +++ b/src/usr/diag/prdf/common/util/prdfBitKey.C @@ -137,7 +137,7 @@ BitKey & BitKey::operator=(const BitKey & bit_list) if(iv_Capacity) { BitString bs(iv_Capacity,DataPtr()); - bs.Pattern(0x00000000); + bs.clearAll(); } ReAllocate(bit_list.iv_Capacity); if(IsDirect()) // implies bit_list is also direct @@ -167,7 +167,7 @@ BitKey & BitKey::operator=(const BitString & bit_string) if(iv_Capacity) { BitString bs(iv_Capacity,DataPtr()); - bs.Pattern(0x00000000); + bs.clearAll(); } ReAllocate(bit_string.getBitLen()); BitString dbs(iv_Capacity,DataPtr()); @@ -182,7 +182,7 @@ BitKey & BitKey::operator=(const char * string_ptr) if(iv_Capacity) { BitString bs(iv_Capacity,DataPtr()); - bs.Pattern(0x00000000); + bs.clearAll(); } while(*string_ptr != '\0') @@ -360,7 +360,7 @@ void BitKey::ReAllocate(uint32_t i_len) { uint32_t * newBuffer = new uint32_t[wordsize]; BitString dbs(iv_Capacity,newBuffer); - dbs.Pattern(0x00000000); + dbs.clearAll(); BitString sbs(oldSize,oldPtr); dbs.SetBits(sbs); iv_storage1 = 0; diff --git a/src/usr/diag/prdf/common/util/prdfBitString.C b/src/usr/diag/prdf/common/util/prdfBitString.C index fad644a08..16c4b97f8 100755 --- a/src/usr/diag/prdf/common/util/prdfBitString.C +++ b/src/usr/diag/prdf/common/util/prdfBitString.C @@ -42,6 +42,35 @@ namespace PRDF // BitString class //############################################################################## +void BitString::setPattern( uint32_t i_sPos, uint32_t i_sLen, + CPU_WORD i_pattern, uint32_t i_pLen ) +{ + PRDF_ASSERT(nullptr != getBufAddr()); // must to have a valid address + PRDF_ASSERT(0 < i_sLen); // must have at least one bit + PRDF_ASSERT(i_sPos + i_sLen <= getBitLen()); // field must be within range + PRDF_ASSERT(0 < i_pLen); // must have at least one bit + PRDF_ASSERT(i_pLen <= CPU_WORD_BIT_LEN); // i_pLen length must be valid + + // Get a bit string for the pattern subset (right justified). + BitStringOffset bso ( CPU_WORD_BIT_LEN - i_pLen, i_pLen, &i_pattern ); + + // Iterate the range in chunks the size of i_pLen. + uint32_t endPos = i_sPos + i_sLen; + for ( uint32_t pos = i_sPos; pos < endPos; pos += i_pLen ) + { + // The true chunk size is either i_pLen or the leftovers at the end. + uint32_t len = std::min( i_pLen, endPos - pos ); + + // Get this chunk's pattern value, truncate (left justified) if needed. + CPU_WORD pattern = bso.GetField( 0, len ); + + // Set the pattern in this string. + SetField( pos, len, pattern ); + } +} + +//------------------------------------------------------------------------------ + uint32_t BitString::GetSetCount(uint32_t bit_position, uint32_t leng ) const @@ -221,69 +250,6 @@ void BitString::SetBits } } -// ------------------------------------------------------------------------------------------------ - -// Function Specification ////////////////////////////////////////// -// -// Title: Pattern -// -// Purpose: This function sets the the specified bits with the -// specifed pattern. The number of bits sets is -// specified by the length and begins at the specified -// offest. The pattern is repeated as often as necessary -// as specified by the pattern_bit_length. -// -// Side-effects: Bit String may be modified. -// -// Dependencies: Parameters must specifiy valid bits in both the -// bit string and the pattern. -// -// Time Complexity: O(m) where m is the number of bits to modify -// (parameter l) -// -// Examples: o(0), l(10), pattern(0xA), pattern_bit_length(4) -// Old String: 0000000000 -// New String: 1010101010 -// -// o(3), l(4), pattern(0x3), pattern_bit_length(3) -// Old String: 0001001000 -// New String: 0000110000 -// -// End Function Specification ////////////////////////////////////// - -void BitString::Pattern -( - uint32_t o, - uint32_t l, - CPU_WORD pattern, - uint32_t pattern_bit_length - ) -{ - PRDF_ASSERT(((o + l) <= iv_bitLen) && - (pattern_bit_length <= CPU_WORD_BIT_LEN)); - - uint32_t current_offset; - - // current_offset = offset + o; - current_offset = o; - while(true) - { - if(l > pattern_bit_length) - { - /* Set values using full CPU_WORDs */ - SetField(current_offset, pattern_bit_length, pattern); - l -= pattern_bit_length; - current_offset += pattern_bit_length; - } - else - { - /* Set value in remainder of last CPU_WORD */ - SetField(current_offset, l, pattern); - break; - } - } -} - // Function Specification ////////////////////////////////////////// // // Title: Is Set @@ -588,7 +554,7 @@ BitStringBuffer BitString::operator>>(uint32_t count) const { BitStringBuffer l_bsb(this->getBitLen()); BitString * l_bsbp = &l_bsb; // dg03a - stupid trick to get to GetRelativePosition() - // l_bsb.Clear(); + // l_bsb.clearAll(); if(count < this->getBitLen()) { //bso overlays bsb at offset = count @@ -605,7 +571,7 @@ BitStringBuffer BitString::operator>>(uint32_t count) const BitStringBuffer BitString::operator<<(uint32_t count) const { BitStringBuffer l_bsb(this->getBitLen()); - // l_bsb.Clear(); + // l_bsb.clearAll(); if(count < this->getBitLen()) { // bso overlays *this at offset = count @@ -686,7 +652,7 @@ void BitStringBuffer::initBuffer() setBufAddr( new CPU_WORD[ getNumCpuWords(getBitLen()) ] ); // Clear the new buffer. - Clear(); + if ( !IsZero() ) clearAll(); } /*--------------------------------------------------------------------*/ diff --git a/src/usr/diag/prdf/common/util/prdfBitString.H b/src/usr/diag/prdf/common/util/prdfBitString.H index dbc6c2242..2fe911b47 100755 --- a/src/usr/diag/prdf/common/util/prdfBitString.H +++ b/src/usr/diag/prdf/common/util/prdfBitString.H @@ -138,6 +138,62 @@ class BitString return (i_bitLen + i_offset + CPU_WORD_BIT_LEN-1) / CPU_WORD_BIT_LEN; } + /** @brief Sets the entire bit string to 1's. */ + void setAll() { setPattern(CPU_WORD_MASK); } + + /** @brief Sets the entire bit string to 0's. */ + void clearAll() { setPattern(0); } + + /** + * @brief Sets a range within the string based on the pattern and length + * provided. + * @param i_sPos Starting position of this string. + * @param i_sLen The length of the target range. + * @param i_pattern The pattern to set (right justified). + * @param i_pLen The length of the pattern. + * @pre nullptr != getBufAddr() + * @pre 0 < i_sLen + * @pre i_sPos + i_sLen <= getBitLen() + * @pre 0 < i_pLen <= CPU_WORD_BIT_LEN + * @post The pattern is repeated/truncated as needed. + * + * Examples: i_sPos(0), i_sLen(10), i_pattern(0xA), i_pLen(4) + * Old String: 0000000000 + * New String: 1010101010 + * + * i_sPos(3), i_sLen(4), i_pattern(0x3), i_pLen(3) + * Old String: 0001001000 + * New String: 0000110000 + */ + void setPattern( uint32_t i_sPos, uint32_t i_sLen, + CPU_WORD i_pattern, uint32_t i_pLen ); + + /** + * @brief Sets entire string based on the pattern and length provided. + * @param i_pattern The pattern to set (right justified). + * @param i_pLen The length of the pattern. + * @note See definition above for prerequisites. + * @post The entire string is filled with the pattern. + * @post The pattern is repeated/truncated as needed. + */ + void setPattern( CPU_WORD i_pattern, uint32_t i_pLen ) + { + setPattern( 0, getBitLen(), i_pattern, i_pLen ); + } + + /** + * @brief Sets entire string based on the pattern provided (length of + * CPU_WORD). + * @param i_pattern The pattern to set. + * @note See definition above for prerequisites. + * @post The entire string is filled with the pattern. + * @post The pattern is repeated/truncated as needed. + */ + void setPattern( CPU_WORD i_pattern ) + { + setPattern( i_pattern, CPU_WORD_BIT_LEN ); + } + /*! Comparison \remarks The bitstrings must be the same length and have the same bits set to be equal @@ -237,45 +293,6 @@ class BitString unsigned int dpos = 0); /*! - Set bits in this string based on the range and pattern provided - \param iPos: bit pos in this string to start - \param iLen: # of bits to modify - \param iPattern: Pattern to set - \param iPatternLen: # of bit in pattern to use (right justfied) - \pre (iPos + iLen) <= getBitLen() - \post Range of specified bits filled with pattern. The pattern is repeated as needed - \verbatim - Examples: iPos(0), iLen(10), iPattern(0xA), iPatternLen(4) - Old String: 0000000000 - New String: 1010101010 - - iPos(3), iLen(4), iPattern(0x3), iPatternLen(3) - Old String: 0001001000 - New String: 0000110000 - \endverbatim - */ - void Pattern(uint32_t iPos, - uint32_t iLen, - CPU_WORD iPattern, - uint32_t pattern_bit_length); - - /*! - Set entire string based on the pattern provided - \param iPattern: Pattern to set - \param iPatternLen: # of bit in pattern to use (right justfied) - \post BitString is filled with pattern. The pattern is repeated/truncated as needed - */ - void Pattern(CPU_WORD iPattern, - uint32_t iPatternLen); - - /*! - Set entire string based on the pattern provided - \param iPattern: Pattern to set - \post BitString is filled with pattern. The pattern is repeated/truncated as needed - */ - void Pattern(CPU_WORD pattern); - - /*! Query if bit is set (1) \returns [true|false] \param iPos: bit position to test @@ -297,12 +314,6 @@ class BitString void Clear(uint32_t bit_position); /*! - Clear the entire bit string - \post IsZero() == true - */ - void Clear(void) { Pattern(0); } - - /*! Test equivalence \returns [true | false] \notes Both strings must be of equal length and have same values to be equal @@ -625,39 +636,6 @@ BitString & BitString::operator= return(*this); } -// Function Specification ////////////////////////////////////////// -// -// Title: Pattern -// -// Purpose: This function sets this entire Bit String with the -// specifed pattern. The pattern is repeated as often as -// necessary as specified by the pattern_bit_length. -// -// Side-effects: Bit String is be modified. -// -// Dependencies: None. -// -// Time Complexity: O(m) where m is the number of bits to modify -// (parameter l) -// -// Examples: See Pattern(uint32_t, uint32_t, CPU_WORD, uint32_t) -// -// End Function Specification ////////////////////////////////////// - -inline -void BitString::Pattern(CPU_WORD pattern,uint32_t pattern_bit_length) -{ - Pattern(0, getBitLen(), pattern, pattern_bit_length); -} - - -inline -void BitString::Pattern(CPU_WORD pattern) -{ - Pattern(0, getBitLen(), pattern, CPU_WORD_SIZE); -} - - inline uint32_t BitString::GetSetCount(void) const { return(GetSetCount(0, getBitLen())); |

