245 lines
5.0 KiB
Python
Executable File
245 lines
5.0 KiB
Python
Executable File
######################################
|
|
#
|
|
#
|
|
#
|
|
######################################
|
|
|
|
import os, re, sys
|
|
|
|
g_filename = ''
|
|
g_prevAddress = 0
|
|
g_maxOutput = 50
|
|
g_cutoff = 1024
|
|
g_filter = ''
|
|
g_prevTuple = []
|
|
spaces = ["", " ", " ", " ", " ", " ", " ", " ", " ", " ", " "]
|
|
|
|
SIZE = 0
|
|
BINDING = 1
|
|
TYPE = 2
|
|
SECTION = 3
|
|
NAME = 4
|
|
OVERFLOW = 5
|
|
|
|
g_local = 0
|
|
g_global = 1
|
|
g_weak = 2
|
|
|
|
g_bss = [[], [], []]
|
|
g_data = [[], [], []]
|
|
g_init = [[], [], []]
|
|
g_opd = [[], [], []]
|
|
g_rodata = [[], [], []]
|
|
g_text = [[], [], []]
|
|
|
|
def usage():
|
|
if len(sys.argv) < 2:
|
|
print 'USAGE: python ps3bin_parser.py <filename> [results] [cutoff] [filter]'
|
|
exit(-1)
|
|
|
|
global g_filename
|
|
g_filename = sys.argv[1]
|
|
|
|
global g_maxOutput
|
|
if len(sys.argv) > 2:
|
|
g_maxOutput = int(sys.argv[2])
|
|
|
|
global g_cutoff
|
|
if len(sys.argv) > 3:
|
|
g_cutoff = int(sys.argv[3])
|
|
|
|
global g_filter
|
|
if len(sys.argv) > 4:
|
|
g_filter = sys.argv[4]
|
|
|
|
print "Max Results = ", g_maxOutput
|
|
print "Cutoff = ", g_cutoff
|
|
print "Filter = ", g_filter
|
|
|
|
def parse_line(line):
|
|
items = []
|
|
for item in line.split(', '):
|
|
nums = item.split('/')
|
|
if (len(nums) > 1):
|
|
items.append((nums[0], int(nums[1]), int(nums[2]), int(nums[3])))
|
|
return items
|
|
|
|
def covert_spaces(line):
|
|
i = 10
|
|
while i > 1:
|
|
line = line.replace(spaces[i], '\t')
|
|
i -= 1
|
|
|
|
return line
|
|
|
|
def parse_data(fin):
|
|
global g_prevAddress
|
|
global g_prevTuple
|
|
prevLine = ""
|
|
|
|
# OPEN
|
|
fout = open(g_filename[0 : g_filename.find('.')] + ".map", "w")
|
|
|
|
while 1:
|
|
line = fin.readline()
|
|
line = line[0: len(line) - 1]
|
|
if not line:
|
|
break
|
|
|
|
if line.startswith('0x'):
|
|
line = line.replace(' ', '\t', 1)
|
|
else:
|
|
fout.write(line + "\n")
|
|
g_prevTuple = []
|
|
continue
|
|
|
|
tuple = []
|
|
line = covert_spaces(line)
|
|
for item in line.split('\t'):
|
|
if len(item) > 0:
|
|
tuple.append(item)
|
|
|
|
if "Source" == tuple[TYPE]:
|
|
tuple[TYPE] = tuple[TYPE] + "_" + tuple[SECTION]
|
|
tuple[SECTION] = tuple[NAME]
|
|
tuple[NAME] = tuple[OVERFLOW]
|
|
|
|
address = int(tuple[SIZE], 16)
|
|
tuple[SIZE] = 0
|
|
|
|
if len(tuple) < 5:
|
|
print "ERROR: Invalid tuple length!", tuple
|
|
fout.write(line + "\n")
|
|
g_prevAddress = address
|
|
g_prevTuple = []
|
|
continue
|
|
|
|
# Add to list
|
|
section = tuple[SECTION]
|
|
|
|
if len(g_prevTuple) > 0:
|
|
bytes = address - g_prevAddress
|
|
|
|
if bytes > 0:
|
|
g_prevTuple[SIZE] = bytes
|
|
|
|
index = -1
|
|
if 'Local' == g_prevTuple[BINDING]:
|
|
index = g_local
|
|
elif 'Global' == g_prevTuple[BINDING]:
|
|
index = g_global
|
|
elif 'Weak' == g_prevTuple[BINDING]:
|
|
index = g_weak
|
|
|
|
if '.bss' == section:
|
|
g_bss[index].append(g_prevTuple)
|
|
elif '.data' == section:
|
|
g_data[index].append(g_prevTuple)
|
|
elif '.init' == section:
|
|
g_init[index].append(g_prevTuple)
|
|
elif '.opd' == section:
|
|
g_opd[index].append(g_prevTuple)
|
|
elif '.rodata' == section:
|
|
g_rodata[index].append(g_prevTuple)
|
|
elif '.text' == section:
|
|
g_text[index].append(g_prevTuple)
|
|
|
|
#fout.write(str(bytes) + "\t" + prevLine[prevLine.find(' '): len(prevLine)] + "\n")
|
|
fout.write(str(bytes) + "\t" + g_prevTuple[BINDING] + "\t" + g_prevTuple[TYPE] + "\t" + g_prevTuple[SECTION] + "\t" + g_prevTuple[NAME] + "\n")
|
|
|
|
g_prevAddress = address
|
|
g_prevTuple = tuple
|
|
prevLine = line
|
|
|
|
if len(g_filter) > 0:
|
|
if -1 == line.find(g_filter):
|
|
g_prevTuple = []
|
|
|
|
fout.close()
|
|
|
|
def compare(a, b):
|
|
return -cmp(a[SIZE] , b[SIZE]) # compare as integers
|
|
|
|
def print_output(data, header):
|
|
if 0 == len(data):
|
|
return
|
|
|
|
i = 0
|
|
init = False
|
|
|
|
data.sort(compare)
|
|
|
|
for item in data:
|
|
if item[SIZE] < g_cutoff:
|
|
break
|
|
|
|
if (False == init):
|
|
print '[', header, ']'
|
|
init = True
|
|
|
|
kb = (item[SIZE] / 1024) + 1
|
|
if len(item[TYPE]) >= 8:
|
|
padding = "\t"
|
|
else:
|
|
padding = "\t\t"
|
|
|
|
print "%4dK" % kb, "\t", item[BINDING], "\t", item[TYPE], padding, item[NAME]
|
|
i = i + 1
|
|
if i >= g_maxOutput:
|
|
break
|
|
|
|
if i > 0:
|
|
print
|
|
|
|
def main():
|
|
usage()
|
|
|
|
fin = open(g_filename, "r")
|
|
parse_data(fin)
|
|
fin.close()
|
|
|
|
# .bss
|
|
print_output(g_bss[g_local], ".bss")
|
|
print_output(g_bss[g_global], ".bss")
|
|
print_output(g_bss[g_weak], ".bss")
|
|
|
|
# .data
|
|
print_output(g_data[g_local], ".data")
|
|
print_output(g_data[g_global], ".data")
|
|
print_output(g_data[g_weak], ".data")
|
|
|
|
# .init
|
|
print_output(g_init[g_local], ".init")
|
|
print_output(g_init[g_global], ".init")
|
|
print_output(g_init[g_weak], ".init")
|
|
|
|
# .opd
|
|
print_output(g_opd[g_local], ".opd")
|
|
print_output(g_opd[g_global], ".opd")
|
|
print_output(g_opd[g_weak], ".opd")
|
|
|
|
# .rodata
|
|
print_output(g_rodata[g_local], ".rodata")
|
|
print_output(g_rodata[g_global], ".rodata")
|
|
print_output(g_rodata[g_weak], ".rodata")
|
|
|
|
# .text
|
|
print_output(g_text[g_local], ".text")
|
|
print_output(g_text[g_global], ".text")
|
|
print_output(g_text[g_weak], ".text")
|
|
|
|
main()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|