|
|
@@ -0,0 +1,145 @@
|
|
|
+# This file is used to process section data generated by `objdump -s`
|
|
|
+import re
|
|
|
+
|
|
|
+
|
|
|
+class SectionTable(object):
|
|
|
+
|
|
|
+ class Section(object):
|
|
|
+ SECTION_START_PATTERN = re.compile("Contents of section (.+?):")
|
|
|
+ DATA_PATTERN = re.compile("([0-9a-f]{4,8})")
|
|
|
+
|
|
|
+ def __init__(self, name, start_address, data):
|
|
|
+ self.name = name
|
|
|
+ self.start_address = start_address
|
|
|
+ self.data = data
|
|
|
+
|
|
|
+ def __contains__(self, item):
|
|
|
+ if (item["region"] == self.name or item["region"] == "any") \
|
|
|
+ and (self.start_address <= item["address"] < (self.start_address + len(self.data))):
|
|
|
+ return True
|
|
|
+ else:
|
|
|
+ return False
|
|
|
+
|
|
|
+ def __getitem__(self, item):
|
|
|
+ if isinstance(item, int):
|
|
|
+ return self.data[item - self.start_address]
|
|
|
+ elif isinstance(item, slice):
|
|
|
+ start = item.start if item.start is None else item.start - self.start_address
|
|
|
+ stop = item.stop if item.stop is None else item.stop - self.start_address
|
|
|
+ return self.data[start:stop]
|
|
|
+ return self.data[item]
|
|
|
+
|
|
|
+ def __str__(self):
|
|
|
+ return "%s [%08x - %08x]" % (self.name, self.start_address, self.start_address+len(self.data))
|
|
|
+
|
|
|
+ __repr__ = __str__
|
|
|
+
|
|
|
+ @classmethod
|
|
|
+ def parse_raw_data(cls, raw_data):
|
|
|
+ name = ""
|
|
|
+ data = ""
|
|
|
+ start_address = 0
|
|
|
+ # first find start line
|
|
|
+ for i, line in enumerate(raw_data):
|
|
|
+ if line.find("Contents of section ") != -1: # do strcmp first to speed up
|
|
|
+ match = cls.SECTION_START_PATTERN.search(line)
|
|
|
+ if match is not None:
|
|
|
+ name = match.group(1)
|
|
|
+ raw_data = raw_data[i+1:]
|
|
|
+ break
|
|
|
+ else:
|
|
|
+ # do some error handling
|
|
|
+ raw_data = [""] # add a dummy first data line
|
|
|
+ pass
|
|
|
+
|
|
|
+ def process_data_line(line_to_process):
|
|
|
+ # first remove the ascii part
|
|
|
+ hex_part = line_to_process.split(" ")[0]
|
|
|
+ # process rest part
|
|
|
+ data_list = cls.DATA_PATTERN.findall(hex_part)
|
|
|
+ try:
|
|
|
+ _address = int(data_list[0], base=16)
|
|
|
+ except IndexError:
|
|
|
+ _address = -1
|
|
|
+
|
|
|
+ def hex_to_str(hex_data):
|
|
|
+ if len(hex_data) % 2 == 1:
|
|
|
+ hex_data = "0" + hex_data # append zero at the beginning
|
|
|
+ _length = len(hex_data)
|
|
|
+ return "".join([chr(int(hex_data[_i:_i+2], base=16))
|
|
|
+ for _i in range(0, _length, 2)])
|
|
|
+ pass
|
|
|
+
|
|
|
+ return _address, "".join([hex_to_str(x) for x in data_list[1:]])
|
|
|
+
|
|
|
+ # handle first line:
|
|
|
+ address, _data = process_data_line(raw_data[0])
|
|
|
+ if address != -1:
|
|
|
+ start_address = address
|
|
|
+ data += _data
|
|
|
+ raw_data = raw_data[1:]
|
|
|
+ for i, line in enumerate(raw_data):
|
|
|
+ address, _data = process_data_line(line)
|
|
|
+ if address == -1:
|
|
|
+ raw_data = raw_data[i:]
|
|
|
+ break
|
|
|
+ else:
|
|
|
+ data += _data
|
|
|
+ else:
|
|
|
+ # do error handling
|
|
|
+ raw_data = []
|
|
|
+ pass
|
|
|
+ return cls(name, start_address, data) if start_address != -1 else None,\
|
|
|
+ None if len(raw_data) == 0 else raw_data
|
|
|
+ pass
|
|
|
+
|
|
|
+ def __init__(self, file_name):
|
|
|
+ with open(file_name, "rb") as f:
|
|
|
+ raw_data = f.readlines()
|
|
|
+ self.table = []
|
|
|
+ while raw_data:
|
|
|
+ section, raw_data = self.Section.parse_raw_data(raw_data)
|
|
|
+ self.table.append(section)
|
|
|
+
|
|
|
+ def get_unsigned_int(self, region, address, size=4, endian="LE"):
|
|
|
+ if address % 4 != 0 or size % 4 != 0:
|
|
|
+ print "warning: try to access without 4 bytes aligned"
|
|
|
+ key = {"address": address, "region": region}
|
|
|
+ for section in self.table:
|
|
|
+ if key in section:
|
|
|
+ tmp = section[address:address+size]
|
|
|
+ value = 0
|
|
|
+ for i in range(size):
|
|
|
+ if endian == "LE":
|
|
|
+ value += ord(tmp[i]) << (i*8)
|
|
|
+ elif endian == "BE":
|
|
|
+ value += ord(tmp[i]) << ((size - i - 1) * 8)
|
|
|
+ else:
|
|
|
+ print "only support LE or BE for parameter endian"
|
|
|
+ assert False
|
|
|
+ break
|
|
|
+ else:
|
|
|
+ value = None
|
|
|
+ return value
|
|
|
+
|
|
|
+ def get_string(self, region, address):
|
|
|
+ value = None
|
|
|
+ key = {"address": address, "region": region}
|
|
|
+ for section in self.table:
|
|
|
+ if key in section:
|
|
|
+ value = section[address:]
|
|
|
+ for i, c in enumerate(value):
|
|
|
+ if c == '\0':
|
|
|
+ value = value[:i]
|
|
|
+ break
|
|
|
+ break
|
|
|
+ return value
|
|
|
+ pass
|
|
|
+
|
|
|
+
|
|
|
+def main():
|
|
|
+ pass
|
|
|
+
|
|
|
+
|
|
|
+if __name__ == '__main__':
|
|
|
+ main()
|