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