gaps.py 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110
  1. #!/usr/bin/env python3
  2. #
  3. # Copyright (c) 2021 Project CHIP Authors
  4. #
  5. # Licensed under the Apache License, Version 2.0 (the "License");
  6. # you may not use this file except in compliance with the License.
  7. # You may obtain a copy of the License at
  8. #
  9. # http://www.apache.org/licenses/LICENSE-2.0
  10. #
  11. # Unless required by applicable law or agreed to in writing, software
  12. # distributed under the License is distributed on an "AS IS" BASIS,
  13. # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14. # See the License for the specific language governing permissions and
  15. # limitations under the License.
  16. #
  17. """Dump memory that does not belong to any symbol."""
  18. import sys
  19. import memdf.collect
  20. import memdf.report
  21. import memdf.select
  22. from elftools.elf.elffile import ELFFile # type: ignore
  23. from memdf import Config, ConfigDescription
  24. CONFIG: ConfigDescription = {
  25. **memdf.util.config.CONFIG,
  26. **memdf.select.SECTION_CONFIG,
  27. **memdf.select.REGION_CONFIG,
  28. **memdf.report.REPORT_LIMIT_CONFIG,
  29. **memdf.report.OUTPUT_FILE_CONFIG
  30. }
  31. def hexdump(data, start, length, address=0):
  32. while length > 0:
  33. iaddress = address & ~0xF
  34. h = ''
  35. s = ''
  36. for i in range(0, 16):
  37. if length == 0 or (iaddress + i < address):
  38. h += ' --'
  39. s += ' '
  40. else:
  41. b = data[start]
  42. start += 1
  43. length -= 1
  44. address += 1
  45. h += f' {b:02X}'
  46. c = chr(b)
  47. if c.isascii() and c.isprintable():
  48. s += c
  49. else:
  50. s += '.'
  51. yield f'{iaddress:08X}: {h} {s}'
  52. def main(argv):
  53. status = 0
  54. try:
  55. config = Config().init(CONFIG)
  56. config.argparse.add_argument('inputs', metavar='FILE', nargs='+')
  57. config.parse(argv)
  58. config['collect.method'] = 'elftools'
  59. config['args.tag_inputs'] = True
  60. dfs = memdf.collect.collect_files(config)
  61. elf = {}
  62. for filename in config['args.inputs']:
  63. elf[filename] = {
  64. 'elffile': ELFFile(open(filename, 'rb')),
  65. 'section': {},
  66. 'data': {},
  67. 'limit': {},
  68. }
  69. with memdf.report.open_output(config) as fp:
  70. for i in dfs['gap'].itertuples():
  71. e = elf[i.input]
  72. if i.section in e['section']:
  73. section = e['section'][i.section]
  74. data = e['data'][i.section]
  75. limit = e['limit'][i.section]
  76. else:
  77. section = e['elffile'].get_section_by_name(i.section)
  78. data = section.data()
  79. limit = memdf.select.get_limit(
  80. config, 'section', i.section)
  81. e['section'][i.section] = section
  82. e['data'][i.section] = data
  83. e['limit'][i.section] = limit
  84. if limit and i.size < limit:
  85. continue
  86. offset = i.address - section['sh_addr']
  87. assert section['sh_size'] == len(data)
  88. print('\n{:08X} length {} in section {} of {}'.format(
  89. i.address, i.size, i.section, i.input), file=fp)
  90. for i in hexdump(data, offset, i.size, i.address):
  91. print(i, file=fp)
  92. except Exception as exception:
  93. raise exception
  94. return status
  95. if __name__ == '__main__':
  96. sys.exit(main(sys.argv))