I don't know, I tried this, but it seems to be shooting me off the dark side of the moon.
Code:
: read ( ihandle str len -- len' ) rot s" read" rot
['] $call-method CATCH IF 2drop 3drop -1 THEN ;
Usually we use
"
instead of
s"
because it's shorter but
"
adds hex parsing which might not be good for some strings. They both compile or tokenize to the same result.
Code:
\ Define XCOFF header structure
create xcoff-header
2 , \ magic
2 , \ nscns
4 , \ timdat
4 , \ symptr
4 , \ nsyms
2 , \ opthdr
2 , \ flags
xcoff-header
will be an address in the dictionary. The size depends on what else you put in the dictionary following
create
.
,
appends a 4 byte value to the dictionary. For xcoff-header, you are appending 28 bytes but I think you want it to be 20 bytes.
Code:
xcoff-header 20 dump
FF8653BC: 00 00 00 02 00 00 00 02 00 00 00 04 00 00 00 04 :................:
FF8653CC: 00 00 00 04 00 00 00 02 00 00 00 02 00 00 00 00 :................: ok
If you want to create space for some data, then
buffer:
is probably the way to go.
d# 20 buffer: xcoff-header
The buffer is allocated in Open Firmware heap space which is different than dictionary space (but this might be different in other implementations of Open Firmware). In Apple Open firmware, the heap seems to grow down toward the dictionary top (
here
) which grows upward. There's no way to unallocate the space used by the buffer so you might want to allocate the buffer manually.
d# 20 alloc-mem value xcoff-header
Then you can free it when you don't need it anymore.
xcoff-header d# 20 free-mem
Code:
: parse-xcoff ( addr -- )
xcoff-header 0 do
dup i + @
\ Store the header values as needed
loop
;
This assumes
xcoff-header
is the size of the header, rather than the address of the header. Replace
xcoff-header
to
xcoff-header-size
or change the value of
xcoff-header
to represent the size instead of the address.
@
loads 4 bytes onto the stack but
i
is only incrementing by 1. Change
@
to
c@
or change
loop
to
4 +loop
You need to do something with the loaded value, otherwise the next iteration will use that value as the address. Add some code after
@
, such as
.
which will show the value that was loaded.
You need to
drop
the addr before
;
if you don't want to keep it on the stack as you've indicated by the usage comment
( addr -- )
Code:
: load-xcoff-file ( filename -- )
\ Allocate memory for the XCOFF file
1000000 alloc-mem throw to xcoff-mem
\ Load the XCOFF file into memory
s" BootX.xcoff" xcoff-mem load-xcoff throw
\ Set the entry point and other necessary state
xcoff-mem 1000000 + to go-entry
true state-valid !
;
alloc-mem
returns an address, not an error code, so
throw
is not appropriate there.
alloc-mem
probably shouldn't be used for large allocations.
1000000 alloc-mem
fails in Apple Open Firmware which can accept only up to
10000
(64K).
Code:
" disk:,\bootx.xcoff" load-xcoff ok
4 > go-entry @ 400 dump \ This will dump 256 bytes (100 in hex) starting from the address in go-entry
00000000: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 88 ................
to go-entry
implies that
go-entry
is a
value
but
go-entry @
implies it is a
variable
.
I think it's supposed to be a value so you want to do
go-entry 400 dump
A variable is useful when you want to pass an argument to a method by reference rather than by value. When using a variable, you have to dereference it using
@
or
!
to access the value.
Code:
00000010: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 28 ...............(
00000020: 68 65 61 64 65 72 00 00 6d 61 67 69 63 31 32 33 header..magic123
00000030: 00 00 00 00 00 0f 2e b8 67 69 74 2d 33 61 32 35 ........git-3a25
00000040: 39 64 66 32 34 34 39 66 71 65 6d 75 30 00 00 00 9df2449fqemu0...
00000050: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000060: 00 00 00 00 00 00 00 00 00 00 20 23 09 18 18 57 .......... #...W
00000070: 00 00 00 00 00 00 00 00 31 00 00 00 00 00 00 00 ........1.......
00000080: 00 00 00 00 97 be e5 b9 ff ff ff ff ff ff ff ff ................
00000090: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
000000a0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
000000b0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
000000c0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
000000d0: 00 00 00 00 00 00 00 00 00 00 00 00 00 01 03 40 ...............@
000000e0: 00 00 00 00 00 01 03 10 00 00 00 00 00 00 00 01 ................
000000f0: 00 00 00 00 00 00 00 28 73 74 61 67 65 31 00 00 .......(stage1.. ok
Not sure what this stuff is. I suppose SLOF loads a binary at address zero. The binary includes code for PowerPC exception handlers, etc. I think xnu is similar?
Code:
00000100: e8 60 2f f0 7c 69 03 a6 38 00 01 00 4e 80 04 20 .`/.|i..8...N..
...
00000200: 7c 10 43 a6 7c 09 02 a6 7c 12 43 a6 7c 08 02 a6 |.C.|...|.C.|...
...
00000300: 7c 10 43 a6 7c 09 02 a6 7c 12 43 a6 7c 08 02 a6 |.C.|...|.C.|...
These are the first 3 PowerPC exception handlers which contain instructions for handling exception 100, 200, 300.
In Apple Open Firmware, the exception handlers are at the optional address at FFF00n00. An exception would appear like this:
Code:
DEFAULT CATCH!, code=FFF00300 at %SRR0: FF80C750 %SRR1: 00009070
where FFF00300 is the address of the PowerPC exception handler for the third exception type.
Apple's bootx.xcoff header seems a little off?
Code:
Let's analyze the provided XCOFF header in hex format:
Copy code
101DF0003 00000000 00000000 00000000 00480000 010B0000 00028000 00002000 0003A000 05616ECC
Here's a breakdown of the header fields based on the XCOFF format:
Magic Number (2 bytes): 01DF
Number of Sections (2 bytes): 0003
Timestamp (4 bytes): 00000000
Symbol Table Offset (4 bytes): 00000000
Number of Symbols (4 bytes): 00000000
Optional Header Size (2 bytes): 0048
Flags (2 bytes): 0000
Optional Header:
Magic Number (2 bytes): 010B
Version Stamp (2 bytes): 0000
Text Size (4 bytes): 00028000
Data Size (4 bytes): 00002000
BSS Size (4 bytes): 0003A000
Entry Point (4 bytes): 05616ECC
Potential Issues
Magic Number: The magic number 01DF seems unusual. Typically, XCOFF files use 01DF for 32-bit and 01F7 for 64-bit. Ensure this is correct for your environment.
Symbol Table Offset and Number of Symbols: Both are 00000000, indicating no symbol table. This might be fine, but ensure it's expected.
Optional Header Size: 0048 (72 bytes) seems correct, but verify if this matches the expected size for your XCOFF variant.
Entry Point: 05616ECC seems unusually high. Ensure this is within the valid range of your memory map.
Next Steps
Verify Magic Number: Ensure 01DF is correct for your XCOFF variant.
Check Entry Point: Ensure 05616ECC is a valid entry point.
Validate Header Fields: Cross-check all fields with the XCOFF specification for your environment.
If the header fields are correct, the issue might be elsewhere, such as in the file system or device initialization. If you need further assistance, please provide more context or specific details about the environment and setup.
Seems valid. The Mac OS X PowerPC kernel is always 32-bit so BootX is also 32-bit.
BootX doesn't need symbols because it doesn't import or export symbols. It just needs the entry point.
The entry point is at 05616ECC because the text section loads at 05600000
I used MPW's
DumpXCOFF
command to look at it. You can run MPW commands in modern macOS.
https://github.com/ksherlock/mpw
sl.h in BootX source code has memory maps. The XPostFacto project has a
-seg1addr 05600000
linker flag for the BootX target.