Well, I kept meaning to port the COM-like environment I mentioned to ELF, but as I haven't yet, here's the 32-bit Mach-O version.

It creates an executable with a single rwx page (4K ought to be enough for anybody); the input file should be a series of hex-dumped bytes, which will be loaded to (and entered at) 0x100.

For instance, piping the following through: "./machocom - a.com"

bc f0 0f 00 00
ff 35 4e 01 00 00 68 3f 01 00 00 68 01 00 00 00 e8 15 00 00 00
68 00 00 00 00 e8 00 00 00 00

b8 01 00 00 00 e8 0c 00 00 00 c3
b8 04 00 00 00 e8 01 00 00 00 c3

5a 89 e1 0f 34

48 65 6c 6c 6f 2c 20 57 6f 72 6c 64 21 0c 0d
0f 00 00 00

produces an executable "a.com" that (under an Intel OS X) prints "Hello, World!"

It ought to be trivial to modify the canned header to produce 64-bit COM files, and fairly easy to port to ELF or PE. For this purpose, one could also simplify the logic (eg. via conv=osync), but I've left in both the HERE-document substitution and the use of conv=notrunc with dd to demonstrate that quasi-quotation and backpatching are both viable techniques, should one wish to extend it instead (eg. multiple pages, or more ambitiously, to handle relocations).

-Dave

(One could also use something like xxd instead of dc and dd, but it's nice to take the oldtimers* out for a spin every now and then. Porting to a.out left as an exercise for the hardcore retroreader)

* McIlroy, "A Research UNIX Reader: Annotated Excerpts from the Programmer’s Manual, 1971-1986", p. 10
http://pic.plover.com/UnixReader/reader.pdf
Because it could run before the disk had arrived, dc—not the assembler—became the first language to run on our PDP-11.


:: :: ::

#!/bin/sh
[ -z "$1" ] && { echo "Usage: $0 file [outfile]"; exit 1; }
outf=${2:-c.out}
function hex2bin() {
    tr -C -d '0123456789ABCDEFabcdef' |\
    dd cbs=2 conv=unblock,ucase 2>/dev/null |\
    dc -e '16i100sB[lB%PlMx]sT[c?z0!=T]dsMx'
}
cat $1 | hex2bin | dd of=$outf bs=256 seek=1 2>/dev/null
comsz=$(cat $outf | wc -c |
        dc -e '16o[0n]sZ[d16>Zn]sB[256~lBxd0<T]sT?lTx' -e '[000000]P' |
        dd bs=8 count=1 2>/dev/null)
cat <<EOF | hex2bin | dd of=$outf conv=notrunc 2>/dev/null
CEFAEDFE070000000300000002000000
02000000CC0000000000000005000000
50000000010000001000000000000000
00000000000000000000000000000000
00000000000000000000000000000000
00000000000100000000000000000000
00000000000000000000000001000000
7C0000005F5F54455854000000000000
00000000000000000010000000000000
${comsz}070000000700000001000000
000000005F5F74657874000000000000
000000005F5F54455854000000000000
00000000000000000010000000010000
02000000000000000000000000000000
00000000000000000000000000000000
00000000000000000000000000000000
EOF
chmod +x $outf

--
To unsubscribe: http://lists.canonical.org/mailman/listinfo/kragen-discuss

Reply via email to