Taking a peek under the hood of Propeller binaries
TheDarkWraith
Posts: 7
Since I can't find any documentation on the compiler for the Propeller that's used in the Propeller tool software I decided to 'take a peek under the hood' and see what was going on. I wanted to play around with self-modifying code and the only way to figure out how to do this is to figure out what the compiler was doing and the structure of the BINs. I've gathered this data so far just today from testing and exploring the BINs in a hex editor. Enjoy.
LONG = 4 bytes
WORD = 2 bytes
UInt16 = 2 bytes
UInt32 = 4 bytes
A byte value of 0x32 signals end of method (if viewing in hex editor)
+0x0 = clock frequency (UInt32)
+0x4 = CLK register (BYTE)
+0x5 = unknown (BYTE)
+0x6 = size of initialization header in bytes (UInt16 - might be a BYTE but seems unlikely)
+0x8 = address of end of code/start of variables (UInt16)
+0xA = address of end of variables/start of stack (UInt16) - interesting to note that the last two longs are always 0xFFF9FFFF
+0xC = address of first method (UInt16)
+0xE = address of ? - usually +0x4 more than +0xA address (UInt16)
+0x10 = address of ? - points to something (UInt16) NOTE: have to add init header size to get true address
+0x12 = number of methods + 1 (BYTE)
+0x13 = appears to define number of additional method style pointers - not sure (BYTE)
+0x14 = start of method pointers. Each pointer is an UInt32. These are encoded with the first WORD as the address (add init header size to get true
address) and the next WORD as the size (in bytes) of the temp variables. The compiler places all the PUB methods first then the PRI methods in the
order found in the source code
(((number of methods - 1) * 4) + (number of additional method style pointers * 4) + 0x14) = start of DAT section
(first method pointer address + init header size) - start of DAT section = size of DAT section in bytes
(address of end of code/start of variables - (first method pointer address + init header size)) = size of code in bytes (It's interesting to note that
the size of code in bytes does not equal the stated Program: x Longs)
((address of end of variables/stack of stack - address of end of code/start of variables) - 8[the two 0xFFF9FFFF longs]) = size of variables in bytes
(which agrees with stated Variable: x Longs)
((0x8000 - address of end of variables/start of stack) + 8[the two 0xFFF9FFFF longs]) = size of stack/free in bytes (which agrees with stated
Stack/Free: x Longs)
These two 0xFFF9FFFF longs are throwing me for a loop. Not sure what their purpose is.
I did this on a project containing just one object (the top level object). Now just have to figure out how other objects defined in the top level object are encoded in the BIN
LONG = 4 bytes
WORD = 2 bytes
UInt16 = 2 bytes
UInt32 = 4 bytes
A byte value of 0x32 signals end of method (if viewing in hex editor)
+0x0 = clock frequency (UInt32)
+0x4 = CLK register (BYTE)
+0x5 = unknown (BYTE)
+0x6 = size of initialization header in bytes (UInt16 - might be a BYTE but seems unlikely)
+0x8 = address of end of code/start of variables (UInt16)
+0xA = address of end of variables/start of stack (UInt16) - interesting to note that the last two longs are always 0xFFF9FFFF
+0xC = address of first method (UInt16)
+0xE = address of ? - usually +0x4 more than +0xA address (UInt16)
+0x10 = address of ? - points to something (UInt16) NOTE: have to add init header size to get true address
+0x12 = number of methods + 1 (BYTE)
+0x13 = appears to define number of additional method style pointers - not sure (BYTE)
+0x14 = start of method pointers. Each pointer is an UInt32. These are encoded with the first WORD as the address (add init header size to get true
address) and the next WORD as the size (in bytes) of the temp variables. The compiler places all the PUB methods first then the PRI methods in the
order found in the source code
(((number of methods - 1) * 4) + (number of additional method style pointers * 4) + 0x14) = start of DAT section
(first method pointer address + init header size) - start of DAT section = size of DAT section in bytes
(address of end of code/start of variables - (first method pointer address + init header size)) = size of code in bytes (It's interesting to note that
the size of code in bytes does not equal the stated Program: x Longs)
((address of end of variables/stack of stack - address of end of code/start of variables) - 8[the two 0xFFF9FFFF longs]) = size of variables in bytes
(which agrees with stated Variable: x Longs)
((0x8000 - address of end of variables/start of stack) + 8[the two 0xFFF9FFFF longs]) = size of stack/free in bytes (which agrees with stated
Stack/Free: x Longs)
These two 0xFFF9FFFF longs are throwing me for a loop. Not sure what their purpose is.
I did this on a project containing just one object (the top level object). Now just have to figure out how other objects defined in the top level object are encoded in the BIN
Comments