diff --git a/linux-ramdump-parser-v2/parsers/roareadiff.py b/linux-ramdump-parser-v2/parsers/roareadiff.py
index cd04574a52017ded12521c18359a184ff0e5410c..77634efed84326c65eaf09c0151fd6c624c1f456 100644
--- a/linux-ramdump-parser-v2/parsers/roareadiff.py
+++ b/linux-ramdump-parser-v2/parsers/roareadiff.py
@@ -17,10 +17,15 @@ from parser_util import register_parser, RamParser
ELF32HEADERFORMAT = '<16sHHIIIIIHHHHHH'
ELF32HEADERSIZE = struct.calcsize(ELF32HEADERFORMAT)
+ELF64HEADERFORMAT = '<16sHHIQQQIHHHHHH'
+ELF64HEADERSIZE = struct.calcsize(ELF64HEADERFORMAT)
PRG32HEADERFORMAT = 'IIIIIIII'
PRG32HEADERSIZE = struct.calcsize(PRG32HEADERFORMAT)
+PRG64HEADERFORMAT = 'IIQQQQQQ'
+PRG64HEADERSIZE = struct.calcsize(PRG64HEADERFORMAT)
PF_W = 2
-
+OUTPUT_SIZE=256
+LUMP_SIZE=4096
@register_parser('--check-rodata', 'check rodata in dump against the static image')
class ROData(RamParser):
@@ -31,6 +36,17 @@ class ROData(RamParser):
with self.ramdump.open_file('roareadiff.txt') as roarea_out:
+ if self.ramdump.arm64:
+ elfheaderformat = ELF64HEADERFORMAT
+ elfheadersize = ELF64HEADERSIZE
+ prgheaderformat = PRG64HEADERFORMAT
+ prgheadersize = PRG64HEADERSIZE
+ else:
+ elfheaderformat = ELF32HEADERFORMAT
+ elfheadersize = ELF32HEADERSIZE
+ prgheaderformat = PRG32HEADERFORMAT
+ prgheadersize = PRG32HEADERSIZE
+
fd = open(self.ramdump.vmlinux, 'rb')
if not fd:
print_out_str('Could not open {0}.'.format(file_path))
@@ -38,66 +54,86 @@ class ROData(RamParser):
ElfHeader = namedtuple(
'ElfHeader', 'ident type machine version entry phoff shoff flags ehsize phentsize phnum shentsize shnum shstrndx')
- raw_elfheader = fd.read(ELF32HEADERSIZE)
+ raw_elfheader = fd.read(elfheadersize)
elfheader = ElfHeader._make(
- struct.unpack(ELF32HEADERFORMAT, raw_elfheader))
+ struct.unpack(elfheaderformat, raw_elfheader))
- PrgHeader = namedtuple(
- 'Prgheader', 'type offset vaddr paddr filesz memsz flags align')
+ if self.ramdump.arm64:
+ PrgHeader = namedtuple(
+ 'Prgheader', 'type flags offset vaddr paddr filesz memsz align')
+ else:
+ PrgHeader = namedtuple(
+ 'Prgheader', 'type offset vaddr paddr filesz memsz flags align')
for i in range(elfheader.phnum):
- fd.seek(elfheader.phoff + i * PRG32HEADERSIZE)
- raw_prgheader = fd.read(PRG32HEADERSIZE)
+ fd.seek(elfheader.phoff + i * prgheadersize)
+ raw_prgheader = fd.read(prgheadersize)
prgheader = PrgHeader._make(
- struct.unpack(PRG32HEADERFORMAT, raw_prgheader))
+ struct.unpack(prgheaderformat, raw_prgheader))
if not prgheader.flags & PF_W:
- count = prgheader.vaddr
- detect = 0
- printed_once = False
- while count < prgheader.vaddr + prgheader.memsz:
- fd.seek(prgheader.offset + (count - prgheader.vaddr))
- ram_value = self.ramdump.read_word(count)
- vm_value = struct.unpack('I', fd.read(4))[0]
- if ram_value is None:
- break
-
- if detect == 0 and vm_value != ram_value:
- if not printed_once:
- print_out_str(
- 'Differences found! Differences written to roareadiff.txt')
- printed_once = True
- ddr_str = 'detect RO area differences between vmlinux and DDR at 0x{0:0>8x}\n'.format(
- count)
- ddr_str += 'from DDR:\n'
- ddr_str += '{0:0>8x} *{1:0>8x}'.format(count,
- ram_value)
- vmlinux_str = 'from vmlinux:\n'
- vmlinux_str += '{0:0>8x} *{1:0>8x}'.format(count,
- vm_value)
- detect += 1
- elif 0 < detect and detect < 64:
- if detect % 8 == 0:
- ddr_str += '\n{0:0>8x} '.format(count)
- vmlinux_str += '\n{0:0>8x} '.format(count)
- ddr_str += ' '
- vmlinux_str += ' '
- if vm_value != ram_value:
- ddr_str += '*'
- vmlinux_str += '*'
- else:
- ddr_str += ' '
- vmlinux_str += ' '
- ddr_str += '{0:0>8x}'.format(ram_value)
- vmlinux_str += '{0:0>8x}'.format(vm_value)
- detect += 1
- elif detect == 64:
- ddr_str += '\n\n'
- vmlinux_str += '\n\n'
- roarea_out.write(ddr_str)
- roarea_out.write(vmlinux_str)
- detect = 0
- continue
+ fd.seek(prgheader.offset)
+ count = prgheader.paddr
+ while count < prgheader.paddr + prgheader.memsz:
+ if prgheader.paddr + prgheader.memsz - count < LUMP_SIZE:
+ max_read_size = prgheader.paddr + prgheader.memsz - count
+ else:
+ max_read_size = LUMP_SIZE
- count += 4
+ ram_values = self.ramdump.read_physical(self.ramdump.virt_to_phys(count), max_read_size)
+ vm_values = fd.read(max_read_size)
+ if ram_values != vm_values:
+ detect = 0xFFFFFFFF
+ print_out_str(
+ 'Differences found! Differences written to roareadiff.txt')
+ i = 0
+ while i < max_read_size:
+ ram_value = struct.unpack_from('I', ram_values, i)[0]
+ vm_value = struct.unpack_from('I', vm_values, i)[0]
+ if detect == 64:
+ ddr_str += ddr_ascii + '\n\n'
+ vmlinux_str += vm_ascii + '\n\n'
+ roarea_out.write(ddr_str)
+ roarea_out.write(vmlinux_str)
+ detect = 0xFFFFFFFF
+ if detect == 0xFFFFFFFF and ram_value != vm_value:
+ ddr_str = 'detect RO area differences between vmlinux and DDR at 0x{0:0>8x}\n'.format(
+ count + i)
+ ddr_str += 'from DDR:'
+ vmlinux_str = 'from vmlinux:'
+ ddr_ascii = ' '
+ vm_ascii = ' '
+ detect = 0
+ if max_read_size < i + OUTPUT_SIZE and max_read_size == LUMP_SIZE:
+ max_read_size = i + OUTPUT_SIZE
+ ram_values = self.ramdump.read_physical(self.ramdump.virt_to_phys(count), max_read_size)
+ fd.seek(prgheader.offset + count - prgheader.paddr)
+ vm_values = fd.read(max_read_size)
+ if 0 <= detect and detect < 64:
+ if detect % 8 == 0:
+ ddr_str += ddr_ascii + '\n{0:0>8x} '.format(count + i)
+ vmlinux_str += vm_ascii + '\n{0:0>8x} '.format(count + i)
+ ddr_ascii = ' '
+ vm_ascii = ' '
+ ddr_str += ' '
+ vmlinux_str += ' '
+ if ram_value != vm_value:
+ ddr_str += '*'
+ vmlinux_str += '*'
+ else:
+ ddr_str += ' '
+ vmlinux_str += ' '
+ ddr_str += '{0:0>8x}'.format(ram_value)
+ vmlinux_str += '{0:0>8x}'.format(vm_value)
+ for j in range(4):
+ ddr_ascii += '{0:c}'.format(struct.unpack('B', ram_values[i + j])[0]).rstrip()
+ vm_ascii += '{0:c}'.format(struct.unpack('B', vm_values[i + j])[0]).rstrip()
+ detect += 1
+ i = i + 4
+ if detect != 0xFFFFFFFF:
+ ddr_str += ' ' * (7 - ((detect - 1) % 8)) + ddr_ascii + '\n\n'
+ vmlinux_str += ' ' * (7 - ((detect - 1) % 8)) + vm_ascii + '\n\n'
+ roarea_out.write(ddr_str)
+ roarea_out.write(vmlinux_str)
+ count += max_read_size
fd.close()