Merge pull request #438 from s4Ys369/revert-434-patch-1
[sm64pc.git] / tools / patch_libmalloc.py
blob582504bf08ead79ad50f792f6fe7a62fb037ead6
1 #!/usr/bin/env python
3 # Patches the malloc() function in libmalloc.so to allocate more than the
4 # specified number of bytes. This is needed to work around issues with the
5 # compiler occasionally crashing.
7 # This script replaces the "move a1, a0" (00 80 28 25) instruction with
8 # "addiu a1, a0, n" (24 85 nn nn), which causes the malloc function to add n to
9 # the size parameter that was passed in.
11 import hashlib
12 import os.path
13 import sys
15 # file to patch
16 filename = 'tools/ido5.3_compiler/lib/libmalloc.so'
17 # Expected (unpatched) hash of file
18 filehash = 'adde672b5d79b52ca3cce9a47c7cb648'
19 # location in file to patch
20 address = 0xAB4
22 # Get parameter
23 if len(sys.argv) != 2:
24 print('Usage: ' + sys.argv[0] + ' n\n where n is the number of extra bytes to allocate in malloc()')
25 exit(1)
26 n = int(sys.argv[1])
28 # Original instruction "move a1, a0"
29 oldinsn = bytearray([0x00, 0x80, 0x28, 0x25])
31 # New instruction "addiu a1, a0, n"
32 newinsn = bytearray([0x24, 0x85, (n >> 8) & 0xFF, (n & 0xFF)])
34 # Patch the file
35 try:
36 with open(filename, 'rb+') as f:
37 # Read file contents
38 contents = bytearray(f.read())
40 # Unpatch the file by restoring original instruction
41 contents[address:address+4] = oldinsn
43 # Verify the (unpatched) hash of the file
44 md5 = hashlib.md5()
45 md5.update(contents)
46 if md5.hexdigest() != filehash:
47 print('Error: ' + filename + ' does not appear to be the correct version.')
48 exit(1)
50 # Patch the file
51 if n != 0:
52 contents[address:address+4] = newinsn
54 # Write file
55 f.seek(0, os.SEEK_SET)
56 f.write(contents)
57 except IOError as e:
58 print('Error: Could not open library file for writing: ' + str(e))