summaryrefslogtreecommitdiffstats
path: root/covoar/SymbolTable.cc
blob: 8a575ee50f61f680fb27078a1d72852b605994cf (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
/*! @file SymbolTable.cc
 *  @brief SymbolTable Implementation
 *
 *  This file contains ...
 */

#include <assert.h>
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "SymbolTable.h"
#include "app_common.h"

namespace Coverage {

  SymbolTable::SymbolTable()
  {
  }

  SymbolTable::~SymbolTable()
  {
  }

  void SymbolTable::addSymbol(
    const std::string& symbol,
    const uint32_t     start,
    const uint32_t     length
  )
  {
    uint32_t         end = 0;
    symbol_entry_t   entry;
    symbolInfo_t     symbolData;

    // Add an entry to the address map.
    end = start + length - 1;
    entry.low = start;
    entry.high = end;
    entry.symbol = symbol;
    contents[ end ] = entry;

    // Add an entry to the symbol information map.
    symbolData.startingAddress = start;
    symbolData.length = length;
     
    if ( info[ symbol ].empty() == false ) {
      if ( info[symbol ].front().length != length ) {
        fprintf(stderr, "ERROR==> Different lengths for the symbol %s\n", symbol.c_str() );
        exit( 0 );
      }
    }
    
    info[ symbol ].push_back( symbolData );
  }

  SymbolTable::symbolInfo* SymbolTable::getInfo(
    const std::string& symbol
  )
  {
    info_t::iterator it = info.find( symbol );

    if (it == info.end())
      return NULL;
    else
      return (&(it->second));
  }

  uint32_t SymbolTable::getLength(
    const std::string& symbol
  )
  {
    info_t::iterator it = info.find( symbol );

    if (it == info.end())
      return 0;
    else
      return ((*it).second.front().length);
  }

  std::string SymbolTable::getSymbol(
    uint32_t address
  )
  {
    contents_t::iterator it;

    // Ensure that the symbol table is not empty.
    if ( contents.size() == 0 )
      return "";

    // Find the first entry whose end address is greater
    // than the specified address.
    it = contents.lower_bound( address );

    // If an entry was found and its low address is less than or
    // equal to the specified address, then return the symbol.
    if ((it != contents.end()) && ((it->second).low <= address ))
      return (it->second).symbol;

    return "";
  }

  void SymbolTable::dumpSymbolTable( void )
  {
    symbolInfo   		symbolTable;
    symbolInfoIterator_t 	symbolIterator;
    infoIterator_t		infoIterator;

    for (infoIterator = info.begin() ; infoIterator != info.end(); infoIterator++)
    {
      for (symbolIterator = infoIterator->second.begin() ; symbolIterator != infoIterator->second.end(); symbolIterator++)
      {
         fprintf( stdout, "%s:\tStarting address = %#x\tLength = %u\n", infoIterator->first.c_str(), symbolIterator->startingAddress, symbolIterator->length );
      }
    }
  }

}