CreateSectionTable.py 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145
  1. # This file is used to process section data generated by `objdump -s`
  2. import re
  3. class SectionTable(object):
  4. class Section(object):
  5. SECTION_START_PATTERN = re.compile("Contents of section (.+?):")
  6. DATA_PATTERN = re.compile("([0-9a-f]{4,8})")
  7. def __init__(self, name, start_address, data):
  8. self.name = name
  9. self.start_address = start_address
  10. self.data = data
  11. def __contains__(self, item):
  12. if (item["region"] == self.name or item["region"] == "any") \
  13. and (self.start_address <= item["address"] < (self.start_address + len(self.data))):
  14. return True
  15. else:
  16. return False
  17. def __getitem__(self, item):
  18. if isinstance(item, int):
  19. return self.data[item - self.start_address]
  20. elif isinstance(item, slice):
  21. start = item.start if item.start is None else item.start - self.start_address
  22. stop = item.stop if item.stop is None else item.stop - self.start_address
  23. return self.data[start:stop]
  24. return self.data[item]
  25. def __str__(self):
  26. return "%s [%08x - %08x]" % (self.name, self.start_address, self.start_address+len(self.data))
  27. __repr__ = __str__
  28. @classmethod
  29. def parse_raw_data(cls, raw_data):
  30. name = ""
  31. data = ""
  32. start_address = 0
  33. # first find start line
  34. for i, line in enumerate(raw_data):
  35. if line.find("Contents of section ") != -1: # do strcmp first to speed up
  36. match = cls.SECTION_START_PATTERN.search(line)
  37. if match is not None:
  38. name = match.group(1)
  39. raw_data = raw_data[i+1:]
  40. break
  41. else:
  42. # do some error handling
  43. raw_data = [""] # add a dummy first data line
  44. pass
  45. def process_data_line(line_to_process):
  46. # first remove the ascii part
  47. hex_part = line_to_process.split(" ")[0]
  48. # process rest part
  49. data_list = cls.DATA_PATTERN.findall(hex_part)
  50. try:
  51. _address = int(data_list[0], base=16)
  52. except IndexError:
  53. _address = -1
  54. def hex_to_str(hex_data):
  55. if len(hex_data) % 2 == 1:
  56. hex_data = "0" + hex_data # append zero at the beginning
  57. _length = len(hex_data)
  58. return "".join([chr(int(hex_data[_i:_i+2], base=16))
  59. for _i in range(0, _length, 2)])
  60. pass
  61. return _address, "".join([hex_to_str(x) for x in data_list[1:]])
  62. # handle first line:
  63. address, _data = process_data_line(raw_data[0])
  64. if address != -1:
  65. start_address = address
  66. data += _data
  67. raw_data = raw_data[1:]
  68. for i, line in enumerate(raw_data):
  69. address, _data = process_data_line(line)
  70. if address == -1:
  71. raw_data = raw_data[i:]
  72. break
  73. else:
  74. data += _data
  75. else:
  76. # do error handling
  77. raw_data = []
  78. pass
  79. return cls(name, start_address, data) if start_address != -1 else None,\
  80. None if len(raw_data) == 0 else raw_data
  81. pass
  82. def __init__(self, file_name):
  83. with open(file_name, "rb") as f:
  84. raw_data = f.readlines()
  85. self.table = []
  86. while raw_data:
  87. section, raw_data = self.Section.parse_raw_data(raw_data)
  88. self.table.append(section)
  89. def get_unsigned_int(self, region, address, size=4, endian="LE"):
  90. if address % 4 != 0 or size % 4 != 0:
  91. print "warning: try to access without 4 bytes aligned"
  92. key = {"address": address, "region": region}
  93. for section in self.table:
  94. if key in section:
  95. tmp = section[address:address+size]
  96. value = 0
  97. for i in range(size):
  98. if endian == "LE":
  99. value += ord(tmp[i]) << (i*8)
  100. elif endian == "BE":
  101. value += ord(tmp[i]) << ((size - i - 1) * 8)
  102. else:
  103. print "only support LE or BE for parameter endian"
  104. assert False
  105. break
  106. else:
  107. value = None
  108. return value
  109. def get_string(self, region, address):
  110. value = None
  111. key = {"address": address, "region": region}
  112. for section in self.table:
  113. if key in section:
  114. value = section[address:]
  115. for i, c in enumerate(value):
  116. if c == '\0':
  117. value = value[:i]
  118. break
  119. break
  120. return value
  121. pass
  122. def main():
  123. pass
  124. if __name__ == '__main__':
  125. main()