summaryrefslogblamecommitdiffstats
path: root/tester/covoar/CoverageMapBase.cc
blob: 70732606fc68a93f6c9d23238a70ba8d7240b6f4 (plain) (tree)
1
2
3
4
5
6
7
8
9



                                         
                                                          


                                                                 
                   


                   
 
                
                        
 



                            






                                    
   
   
 


                              

   
 






                                   
   
                          
   
 
                                   


                                        
 
                                                     


                                                           
 
                                                    
   
                               
                                                                       

     
                                       

                                 
                                                                        

     

                      
 
                                                                
   
                               
                                                                       

     
                                       

                                
                                                                        

     
                      

   
                                                                     
   
                                                 
 


                                                                  
                     
 

                      



                                                            
                                        
                                                                
                              


                                                       
                           
                                                    
                              

                                                       


                         
   
 



                                   
                                
   

                                                               
 

                                     
   
 
                                                          
   

                                                               
 

                                                                    

                                  
                    


       


                 
                                    
   


                                           
                          
     




                                           

                              
                        

     
                

   

                                                                
                                     

   




                                                  


                                
 
                                        
                           
                    
     


                    

                                                               


                           
              
                
       






                                                     


                                       
                                     

   

                                                                      
                                         

   
                                                                               
   
                             

                                         
                                          
                                   


                    
 
                 
   
 

                                                           

                                  
                                


       
                                                                            

   
                                                                       
   

                                  
                                


       
                                                                            

   
                                                                    
   
                                    
                                                     
     



                                                                      
                                     
                   

     
                                                   



                                                          
                                    
                                          
     

   
                                                                             
   
                                    
                                                 
     



                                                             
                        

                                                                              
                    

     




                                                                    
                                     
               

     
                                          

   
                                                       
   
                                    
                                         
     



                                                       
                                     
                   

     
                                    

   
                                                    
   
                                     
             

     
                                    



                                                          
                                     
                   

     
                                       

   
                                                       
   
                                     
             

     
                                     

   
                                                          
   
                                     
             

     
                                        



                                                                
                                     
                   

     
                                                 
 
                                              



                                                               
                                     
                   

     
                                                 
 
                                              



                                                             
                       

                                     
                     
                                                       
                     

     
                  

   
                                                                             
   
                                    
                                                 
     



                                                                    
                                     
               

     
                                          



                                                          
                       

                                     
                     
                                                    
                     

     


                  
                                                                          
   
                                     
             

     
                                            



                                                                 
                                     
               

     
                                       

   

/*! @file CoverageMapBase.cc
 *  @brief CoverageMapBase Implementation
 *
 *  This file contains the implementation of the functions
 *  which provide a base level of functionality of a CoverageMap.
 */

#include <limits.h>

#include <iostream>
#include <iomanip>

#include <rld.h>
#include <rtems-utils.h>

#include "CoverageMapBase.h"

namespace Coverage {

  AddressInfo::AddressInfo()
    : isStartOfInstruction( false ),
      wasExecuted( false ),
      isBranch( false ),
      isNop( false ),
      wasTaken( false ),
      wasNotTaken( false )
  {
  }

  AddressRange::AddressRange()
    : lowAddress( 0 ),
      highAddress( 0 )
  {
  }

  AddressRange::AddressRange(
    const std::string& name,
    uint32_t           lowAddress,
    uint32_t           highAddress)
    : fileName( name ),
      lowAddress( lowAddress ),
      highAddress( highAddress )
  {
    info.resize( size() );
  }

  size_t AddressRange::size() const
  {
    return highAddress - lowAddress + 1;
  }

  bool AddressRange::inside( uint32_t address ) const
  {
    return address >= lowAddress && address <= highAddress;
  }

  AddressInfo& AddressRange::get( uint32_t address )
  {
    if ( !inside( address ) ) {
      throw rld::error( "address outside range", "AddressRange::get" );
    }

    size_t slot = address - lowAddress;

    if ( slot >= info.size () ) {
      throw rld::error( "address slot not found", "AddressRange::get" );
    }

    return info[slot];
  }

  const AddressInfo& AddressRange::get( uint32_t address ) const
  {
    if ( !inside( address ) ) {
      throw rld::error( "address outside range", "AddressRange::get" );
    }

    size_t slot = address - lowAddress;

    if ( slot >= info.size() ) {
      throw rld::error( "address slot not found", "AddressRange::get" );
    }

    return info[slot];
  }

  void AddressRange::dump( std::ostream& out, bool show_slots ) const
  {
    rtems::utils::ostream_guard old_state( out );

    out << std::hex << std::setfill( '0' )
        << "Address range: low = " << std::setw( 8 ) << lowAddress
        << " high = " << std::setw( 8 ) << highAddress
        << std::endl;

    if (show_slots) {
      size_t slot = 0;

      for ( auto& i : info ) {
        out << std::hex << std::setfill( '0' )
            << "0x" << std::setw( 8 ) << slot++ + lowAddress
            << "- isStartOfInstruction:"
            << (char*) ( i.isStartOfInstruction ? "yes" : "no" )
            << " wasExecuted:"
            << (char*) ( i.wasExecuted ? "yes" : "no" )
            << "\n           isBranch:"
            << (char*) ( i.isBranch ? "yes" : "no" )
            << " wasTaken:"
            << (char*) ( i.wasTaken ? "yes" : "no" )
            << " wasNotTaken:"
            << (char*) ( i.wasNotTaken ? "yes" : "no" )
            << std::dec << std::setfill( ' ' )
            << std::endl;
      }
    }
  }

  CoverageMapBase::CoverageMapBase(
    const std::string& exefileName,
    uint32_t           low,
    uint32_t           high
  ) : exefileName( exefileName )
  {
    Ranges.push_back( AddressRange( exefileName, low, high ) );
  }

  CoverageMapBase::~CoverageMapBase()
  {
  }

  void CoverageMapBase::Add( uint32_t low, uint32_t high )
  {
    Ranges.push_back( AddressRange( exefileName, low, high ) );
  }

  bool CoverageMapBase::validAddress( const uint32_t address ) const
  {
    for ( auto& r : Ranges ) {
      if ( r.inside( address ) ) {
        return true;
      }
    }

    return false;
  }

  void CoverageMapBase::dump() const
  {
    std::cerr << "Coverage Map Contents\n";

    for ( auto& r : Ranges ) {
      r.dump( std::cerr );
    }
  }

  uint32_t CoverageMapBase::getSize() const
  {
    size_t size = 0;

    for ( auto& r : Ranges ) {
      size += r.size ();
    }

    return size;
  }

  uint32_t CoverageMapBase::getSizeOfRange( size_t index ) const
  {
    return Ranges.at( index ).size();
  }

  bool CoverageMapBase::getBeginningOfInstruction(
    uint32_t  address,
    uint32_t* beginning
  ) const
  {
    bool         status = false;
    uint32_t     start;
    AddressRange range;

    status = getRange( address, range );
    if ( status != true ) {
      return status;
    }

    start = address;

    while ( start >= range.lowAddress ) {
      if ( isStartOfInstruction( start - range.lowAddress ) ) {
        *beginning = start;
        status = true;
        break;
      } else {
        start--;
      }
    }

    return status;
  }

  int32_t CoverageMapBase::getFirstLowAddress() const
  {
    /*
     * This is broken, do not trust it.
     */
    return Ranges.front().lowAddress;
  }

  uint32_t CoverageMapBase::getLowAddressOfRange( size_t index ) const
  {
    return Ranges.at( index ).lowAddress;
  }

  bool CoverageMapBase::getRange( uint32_t address, AddressRange& range ) const
  {
    for ( auto r : Ranges ) {
      if ( r.inside( address ) ) {
        range.lowAddress  = r.lowAddress;
        range.highAddress = r.highAddress;
        range.info        = r.info;
        return true;
      }
    }

    return false;
  }

  AddressInfo& CoverageMapBase::getInfo( uint32_t address )
  {
    for ( auto& r : Ranges ) {
      if ( r.inside( address ) ) {
        return r.get( address );
      }
    }

    throw rld::error( "address out of bounds", "CoverageMapBase::getInfo" );
  }

  const AddressInfo& CoverageMapBase::getInfo( uint32_t address ) const
  {
    for ( auto& r : Ranges ) {
      if ( r.inside( address ) ) {
        return r.get( address );
      }
    }

    throw rld::error( "address out of bounds", "CoverageMapBase::getInfo" );
  }

  void CoverageMapBase::setIsStartOfInstruction( uint32_t  address )
  {
    if ( validAddress( address ) ) {
      getInfo( address ).isStartOfInstruction = true;
    }
  }

  bool CoverageMapBase::isStartOfInstruction( uint32_t address ) const
  {
    if ( !validAddress( address ) ) {
      return false;
    }

    return getInfo( address ).isStartOfInstruction;
  }

  void CoverageMapBase::setWasExecuted( uint32_t address )
  {
    if ( validAddress( address ) ) {
      getInfo( address ).wasExecuted += 1;
    }
  }

  void CoverageMapBase::sumWasExecuted( uint32_t address, uint32_t addition )
  {
    if ( validAddress( address ) ) {
      getInfo( address ).wasExecuted += addition;
    }
  }

  bool CoverageMapBase::wasExecuted( uint32_t address ) const
  {
    bool result = false;

    if ( validAddress( address ) && ( getInfo( address ).wasExecuted > 0 ) ) {
      result = true;
    }

    return result;
  }

  uint32_t CoverageMapBase::getWasExecuted( uint32_t address ) const
  {
    if ( !validAddress( address ) ) {
      return 0;
    }

    return getInfo( address ).wasExecuted;
  }

  void CoverageMapBase::setIsBranch( uint32_t address )
  {
    if ( validAddress( address ) ) {
      getInfo( address ).isBranch = true;
    }
  }

  bool CoverageMapBase::isNop( uint32_t address ) const
  {
    if ( !validAddress( address ) ) {
      return false;
    }

    return getInfo( address ).isNop;
  }

  void CoverageMapBase::setIsNop( uint32_t address )
  {
    if ( !validAddress( address ) ) {
      return;
    }

    getInfo( address ).isNop = true;
  }

  bool CoverageMapBase::isBranch( uint32_t address ) const
  {
    if ( !validAddress( address ) ) {
      return false;
    }

    return getInfo( address ).isBranch;
  }

  void CoverageMapBase::setWasTaken( uint32_t address )
  {
    if ( !validAddress( address ) ) {
      return;
    }

    getInfo( address ).wasTaken += 1;
  }

  void CoverageMapBase::setWasNotTaken( uint32_t address )
  {
    if ( !validAddress( address ) ) {
      return;
    }

    getInfo( address ).wasNotTaken += 1;
  }

  bool CoverageMapBase::wasAlwaysTaken( uint32_t address ) const
  {
    if ( !validAddress( address ) ) {
      return false;
    }

    const AddressInfo& info = getInfo( address );

    return info.wasTaken && !info.wasNotTaken;
  }

  bool CoverageMapBase::wasNeverTaken( uint32_t address ) const
  {
    if ( !validAddress( address ) ) {
      return false;
    }

    const AddressInfo& info = getInfo( address );

    return !info.wasTaken && info.wasNotTaken;
  }

  bool CoverageMapBase::wasNotTaken( uint32_t address ) const
  {
    bool result = true;

    if ( !validAddress( address ) ) {
      result = false;
    } else if ( getInfo( address ).wasNotTaken <= 0 ) {
      result = false;
    }

    return result;
  }

  void CoverageMapBase::sumWasNotTaken( uint32_t address, uint32_t addition )
  {
    if ( validAddress( address ) ) {
      getInfo( address ).wasNotTaken += addition;
    }
  }

  uint32_t CoverageMapBase::getWasNotTaken( uint32_t address ) const
  {
    if ( !validAddress( address ) ) {
      return 0;
    }

    return getInfo( address ).wasNotTaken;
  }

  bool CoverageMapBase::wasTaken( uint32_t address ) const
  {
    bool result = true;

    if ( !validAddress( address ) ) {
      result = false;
    } else if ( getInfo( address ).wasTaken <= 0 ) {
      result = false;
    }

    return result;
  }

  void CoverageMapBase::sumWasTaken( uint32_t address, uint32_t addition )
  {
    if ( !validAddress( address ) ) {
      return;
    }

    getInfo( address ).wasTaken += addition;
  }

  uint32_t CoverageMapBase::getWasTaken( uint32_t address ) const
  {
    if ( !validAddress( address ) ) {
      return 0;
    }

    return getInfo( address ).wasTaken;
  }
}