def extendDataSpace( offset, diff ):
""" This function will expand the data area at the given offset, starting at the first argument. The second argument is the amount to increase by.
All pointers occurring after the sum of the two arguments will be recalculated. """
def replaceHex( hexData, offset, newHex ): # Input takes a string, int, and string, respectively.
offset = offset * 2 # Doubled to count by nibbles rather than bytes, since the data is just a string.
codeEndPoint = offset + len(newHex)
return hexData[:offset] + newHex + hexData[codeEndPoint:]
global datDataHeader, datData, rtData
if datDataHeader != '' and datData != '' and rtData != '':
# Update the file header with the new file size and start of the relocation table.
filesize = int( datDataHeader[:8], 16 )
newFilesize = filesize + diff
rtStart = int( datDataHeader[8:16], 16 ) # Size of the data block
newRtStart = rtStart + diff
datDataHeader = replaceHex( datDataHeader, 0, "{0:0{1}X}".format(newFilesize, 8) + "{0:0{1}X}".format(newRtStart, 8) )
# For each entry in the relocation table, update the address it points to, and the value of the pointer there, if they point to locations beyond the extended space.
entriesUpdated = 0
pointersUpdated = 0
for nib in xrange(0, len(rtData), 8):
rtEntryNum = (nib/8)
rtEntryAddress = rtStart + rtEntryNum * 4
rtEntryString = rtData[nib:nib+8]
rtEntryValue = int( rtEntryString, 16 ) # i.e. the pointer address
pointerString = datData[rtEntryValue*2:(rtEntryValue+4)*2] # Multipled by 2 because this is per character/nibble, not per byte.
pointerValue = int( pointerString, 16 )
# If the pointer appears after the change, update its address in the relocation table accordingly.
if rtEntryValue >= offset:
newRtEntryValue = rtEntryValue + diff
datData = replaceHex( datData, rtEntryAddress, "{0:0{1}X}".format(newRtEntryValue, 8) )
entriesUpdated += 1
# If the place that the pointer points to is after the space change, update its value accordingly.
if pointerValue >= offset:
newPointerValue = pointerValue + diff
datData = replaceHex( datData, rtEntryValue, "{0:0{1}X}".format(newPointerValue, 8) )
pointersUpdated += 1
# Fill the newly extended space with zeros. (Values doubled to count by nibbles rather than bytes, since the data is just a string.)
datData = datData[:offset*2] + '0'.zfill(diff*2) + datData[offset*2:]
#msg('RT Entries updated: ' + str(entriesUpdated) + '\nPointers updated: ' + str(pointersUpdated))