summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorOri Bernstein <ori@eigenstate.org>2017-09-27 21:12:55 -0700
committerOri Bernstein <ori@eigenstate.org>2017-09-27 21:12:55 -0700
commit189e00e249009aba59fa963ef2cd0f2dac832129 (patch)
tree8f281222101d99eee58f62d9ed4c8fa31422db87
parent2eb61ae0040a66043b41863c2348fdacd37cc091 (diff)
downloadlnk-189e00e249009aba59fa963ef2cd0f2dac832129.tar.gz
Implement Plan 9 a.out
-rw-r--r--aout.myr31
-rw-r--r--elf.myr11
-rw-r--r--main.myr32
3 files changed, 50 insertions, 24 deletions
diff --git a/aout.myr b/aout.myr
index 8288a45..579f47b 100644
--- a/aout.myr
+++ b/aout.myr
@@ -1,4 +1,5 @@
use std
+use bio
use "types"
@@ -7,5 +8,35 @@ pkg =
;;
const emitaout = {lnk
+ match bio.create(lnk.outf, bio.Wr, 0o755)
+ | `std.Err e:
+ std.fatal("could not open output: {}\n", e)
+ | `std.Ok f:
+ w32(f, magic(26))
+ w32(f, lnk.text.len)
+ w32(f, lnk.data.len)
+ w32(f, (lnk.bss : uint32))
+ w32(f, 0) /* syms */
+ w32(f, (lnk.entry : uint32))
+ w32(f, 0) /* pc/sp offset tab */
+ w32(f, 0) /* pc/lnum tab */
+ wstr(f, lnk.text)
+ wstr(f, lnk.data)
+ bio.close(f)
+ ;;
}
+const magic = {arch
+ -> 0x00008000 | 4*arch*arch+7
+}
+
+const wstr = {f, s; check(bio.write(f, s))}
+const w32 = {f, v : uint32; check(bio.putbe32(f, v))}
+
+generic check = {st : bio.status(@a)
+ match st
+ | `bio.Ok _: /* nothing */
+ | `bio.Err e: std.fatal("i/o error: {}\n", e)
+ | `bio.Eof: std.fatal("i/o error: eof\n")
+ ;;
+}
diff --git a/elf.myr b/elf.myr
index 1e25536..fd6fda3 100644
--- a/elf.myr
+++ b/elf.myr
@@ -46,7 +46,7 @@ const emitelf = {lnk
std.fatal("could not open output: {}\n", e)
| `std.Ok f:
header(f, lnk)
- //ident(f, lnk)
+ //brand(f, lnk)
//strtab(f, lnk)
sdata(f, lnk, lnk.text, Align)
sdata(f, lnk, lnk.data, Align)
@@ -79,7 +79,6 @@ const header = {f, lnk
w16(f, 0)
phdrs(f, lnk)
- //shdr(f, lnk)
}
const phdrs = {f, lnk
@@ -109,14 +108,6 @@ const sdata = {f, lnk, buf, align
wstr(f, buf)
}
-//const sectionheader = {f, lnk
-// /* text section */
-// /* data section */
-// /* rodata section */
-// /* bss section */
-// /* strtab */
-//}
-
const wstr = {f, s; check(bio.write(f, s))}
const w8 = {f, v; check(bio.putb(f, v))}
const w16 = {f, v; check(bio.putle16(f, v))}
diff --git a/main.myr b/main.myr
index 7cb835a..c4cc8a3 100644
--- a/main.myr
+++ b/main.myr
@@ -32,6 +32,7 @@ const main = {args
.data="",
.rodata="",
.bss = 0,
+ .base=0x200028,
.outf=outf,
.sys=sys,
@@ -80,19 +81,6 @@ const link = {lnk
;;
}
-const addsym = {lnk, buf, sym
- match std.htget(lnk.stab, sym.name)
- | `std.None:
- sym.off = buf#.len
- std.sljoin(buf, sym.buf)
- std.htput(lnk.stab, sym.name, sym)
- | `std.Some old:
- if sym.kind & Symonce == 0 || old.kind & Symonce == 0
- std.fatal("duplicate symbol {}\n", sym.name)
- ;;
- ;;
-}
-
const relocate = {lnk, r
var buf : byte[8]
var addr, sz
@@ -120,7 +108,7 @@ const relocate = {lnk, r
| _:
std.fatal("corrupt relocation\n")
;;
- if addr > (1ul << 8*sz)
+ if addr > (1ul << 8*sz + lnk.base)
std.fatal("relocation overflow in {}\n", s.name)
;;
if r.off + sz > lnk.cur.len
@@ -133,6 +121,22 @@ const relocate = {lnk, r
;;
}
+const addsym = {lnk, buf, sym
+ match std.htget(lnk.stab, sym.name)
+ | `std.None:
+ sym.off = buf#.len
+ std.sljoin(buf, sym.buf)
+ std.htput(lnk.stab, sym.name, sym)
+ if std.sleq(sym.name, "_start") || std.sleq(sym.name, "start")
+ lnk.entry = lnk.base + sym.off
+ ;;
+ | `std.Some old:
+ if sym.kind & Symonce == 0 || old.kind & Symonce == 0
+ std.fatal("duplicate symbol {}\n", sym.name)
+ ;;
+ ;;
+}
+
const loadobj = {lnk, path
var rel, str, sym, o
var obj