1#=========================================================================
2# SparseMemoryImage
3#=========================================================================
4# This is a basic class representing a sparse memory image using
5# "sections" and "symbols". Sections are tuples of <name,addr,data> where
6# the addr specifies where the data lives in a flat memory space. Symbols
7# are simply name to address mappings.
8#
9# Author : Christopher Batten
10# Date   : May 20, 2014
11
12
13import binascii
14
15
16class SparseMemoryImage:
17
18  #-----------------------------------------------------------------------
19  # Nested Class: Section
20  #-----------------------------------------------------------------------
21
22  class Section:
23
24    def __init__( self, name="", addr=0x00000000, data=bytearray() ):
25      self.name = name
26      self.addr = addr
27      self.data = data
28
29    def __str__( self ):
30      return "{}: addr={} data={}" \
31        .format( self.name, hex(self.addr), binascii.hexlify(self.data) )
32
33    def __eq__( self, other ):
34      return     self.name == other.name \
35             and self.addr == other.addr \
36             and self.data == other.data
37
38  #-----------------------------------------------------------------------
39  # Constructor
40  #-----------------------------------------------------------------------
41
42  def __init__( self ):
43    self.sections = []
44    self.symbols  = {}
45
46  #-----------------------------------------------------------------------
47  # add/get sections
48  #-----------------------------------------------------------------------
49
50  def add_section( self, section, addr=None, data=None ):
51    if isinstance( section, SparseMemoryImage.Section ):
52      self.sections.append( section )
53    else:
54      sec = SparseMemoryImage.Section( section, addr, data )
55      self.sections.append( sec )
56
57  def get_section( self, section_name ):
58    for section in self.sections:
59      if section_name == section.name:
60        return section
61    raise KeyError( "Could not find section {}!", section_name )
62
63  def get_sections( self ):
64    return self.sections
65
66  #-----------------------------------------------------------------------
67  # print_section_table
68  #-----------------------------------------------------------------------
69
70  def print_section_table( self ):
71    idx = 0
72    print( "Idx Name           Addr     Size" )
73    for section in self.sections:
74      print( "{:>3} {:<14} {:0>8x} {}" \
75        .format( idx, section.name, section.addr, len(section.data) ) )
76      idx += 1
77
78  #-----------------------------------------------------------------------
79  # add/get symbols
80  #-----------------------------------------------------------------------
81
82  def add_symbol( self, symbol_name, symbol_addr ):
83    self.symbols[ symbol_name ] = symbol_addr
84
85  def get_symbol( self, symbol_name ):
86    return self.symbols[ symbol_name ]
87
88  #-----------------------------------------------------------------------
89  # equality
90  #-----------------------------------------------------------------------
91
92  def __eq__( self, other ):
93    return     self.sections == other.sections \
94           and self.symbols  == other.symbols
95
96  #-----------------------------------------------------------------------
97  # print_symbol_table
98  #-----------------------------------------------------------------------
99
100  def print_symbol_table( self ):
101    for key,value in self.symbols.iteritems():
102      print( " {:0>8x} {}".format( value, key ) )
103