Package vstruct :: Package defs :: Module ihex
[hide private]
[frames] | no frames]

Source Code for Module vstruct.defs.ihex

  1   
  2  ''' 
  3  Parser objects for the Intel Hex file format. 
  4  ''' 
  5  import vstruct 
  6  from vstruct.primitives import * 
  7   
  8  IHEX_REC_DATA           = 0 
  9  IHEX_REC_EOF            = 1 
 10  IHEX_REC_EXSEG          = 2 # Extended Segment Address Records 
 11  IHEX_REC_STARTSEG       = 3 # The beginning code segment value 
 12  IHEX_REC_EXLINADDR      = 4 # Extended Linear Address Records 
 13  IHEX_REC_STARTLINADDR   = 5 # 32bit entry point 
 14   
15 -class IHexChunk(vstruct.VStruct):
16
17 - def __init__(self):
18 vstruct.VStruct.__init__(self) 19 self.startcode = v_bytes(1) 20 self.bytecount = v_bytes(2) 21 self.address = v_bytes(4) 22 self.recordtype = v_bytes(2) 23 self.data = v_bytes(0) 24 self.csum = v_bytes(2)
25
26 - def pcb_bytecount(self):
27 dsize = int(self.bytecount, 16) 28 self.vsGetField('data').vsSetLength( 2 * dsize )
29
30 - def getAddress(self):
31 ''' 32 Parse the address field and return the int type. 33 ''' 34 return int( self.address, 16 )
35
36 - def getData(self):
37 ''' 38 Return the binary data payload for this chunk. 39 ''' 40 return self.data.decode('hex')
41
42 -class IHexFile(vstruct.VArray):
43
44 - def vsParse(self, bytes, offset=0):
45 46 lines = bytes[offset:].splitlines() 47 48 for line in lines: 49 offset += 1 # there is an eaten newline for each 50 if not line: 51 continue 52 53 c = IHexChunk() 54 c.vsParse( line ) 55 offset += len( c ) 56 57 self.vsAddElement( c ) 58 59 if int(c.recordtype, 16) == IHEX_REC_EOF: 60 break 61 62 return offset
63
64 - def getEntryPoint(self):
65 ''' 66 If a 32bit linear start address is defined for this file, 67 return it. Returns None if the 32bit entry point extension 68 is not present. 69 ''' 70 for fname, chunk in self: 71 ctype = int( chunk.recordtype, 16 ) 72 if ctype == IHEX_REC_STARTLINADDR: 73 return int( chunk.data, 16 )
74
75 - def getMemoryMaps(self):
76 ''' 77 Retrieve a set of memory maps defined by this hex file. 78 79 Memory maps are returned as a list of 80 ( va, perms, fname, bytes ) tuples. 81 ''' 82 import envi.memory as e_mem 83 84 # Get all the binary parts.... 85 baseaddr = 0 86 memparts = [] 87 88 for fname, chunk in self: 89 90 ctype = int( chunk.recordtype, 16 ) 91 92 if ctype == IHEX_REC_DATA: 93 addr = chunk.getAddress() + baseaddr 94 memparts.append( (addr, chunk.getData()) ) 95 continue 96 97 if ctype == IHEX_REC_EXSEG: 98 baseaddr = int( chunk.data, 16 ) << 4 99 continue 100 101 if ctype == IHEX_REC_EXLINADDR: 102 baseaddr = int( chunk.data, 16 ) << 16 103 continue 104 105 if ctype == IHEX_REC_EOF: 106 break 107 108 raise Exception('Unhandled IHEX chunk: %s' % chunk.recordtype) 109 110 memparts.sort() 111 112 maps = [] 113 for addr, bytes in memparts: 114 # is this the next contiguous chunk? 115 if maps and addr == ( maps[-1][0] + len(maps[-1][3]) ): 116 maps[-1][3] += bytes 117 else: 118 maps.append( [ addr, e_mem.MM_RWX, '', bytes ] ) 119 120 return maps
121 122 if __name__ == '__main__': 123 124 example = ''' 125 :020000021000EC 126 :10C20000E0A5E6F6FDFFE0AEE00FE6FCFDFFE6FD93 127 :10C21000FFFFF6F50EFE4B66F2FA0CFEF2F40EFE90 128 :10C22000F04EF05FF06CF07DCA0050C2F086F097DF 129 :10C23000F04AF054BCF5204830592D02E018BB03F9 130 :020000020000FC 131 :04000000FA00000200 132 :00000001FF 133 ''' 134 example1 = ''' 135 :10001300AC12AD13AE10AF1112002F8E0E8F0F2244 136 :10000300E50B250DF509E50A350CF5081200132259 137 :03000000020023D8 138 :0C002300787FE4F6D8FD7581130200031D 139 :10002F00EFF88DF0A4FFEDC5F0CEA42EFEEC88F016 140 :04003F00A42EFE22CB 141 :00000001FF 142 ''' 143 example2 = ''' 144 :10010000214601360121470136007EFE09D2190140 145 :100110002146017EB7C20001FF5F16002148011988 146 :10012000194E79234623965778239EDA3F01B2CAA7 147 :100130003F0156702B5E712B722B732146013421C7 148 :00000001FF 149 asdf 150 ''' 151 152 example3 = ''' 153 :100000003C932014BBE0AD7A3EAC4D261FB267A4F2 154 :100010008121F4C2D641A503B6038C9932A36EBCEC 155 :10002000D204306AE84404FCE8C7452DE0BE3160E4 156 :100030005CC6E94D3F4E62765AC237EAD3C2895157 157 :0200000400F00A 158 :10000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00 159 :020000040030CA 160 :1000000000270F0F0083F500FFC0FFE0FF400000C5 161 :020000040020DA 162 :080000000102030405060708D4 163 :00000001FF 164 ''' 165 166 import sys 167 h = IHexFile() 168 h.vsParse( file(sys.argv[1], 'rb').read() ) 169 #print h.tree() 170 171 for addr,perms,fname,bytes in h.getMemoryMaps(): 172 print '0x%.8x: %r' % ( addr, bytes ) 173 174 print h.getEntryPoint() 175