From 99277ccb136c3d8715073c8b067c23f05c1d08e8 Mon Sep 17 00:00:00 2001 From: Ori Bernstein Date: Wed, 29 Nov 2017 00:49:02 -0800 Subject: More work on output formats. --- aout.myr | 7 ++--- elf.myr | 7 ++--- main.myr | 105 +++++++++++++++++++++++++++++++++++++------------------------- types.myr | 6 ++++ 4 files changed, 74 insertions(+), 51 deletions(-) diff --git a/aout.myr b/aout.myr index 579f47b..15a9c4f 100644 --- a/aout.myr +++ b/aout.myr @@ -33,10 +33,9 @@ const magic = {arch 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) +generic check = {st match st - | `bio.Ok _: /* nothing */ - | `bio.Err e: std.fatal("i/o error: {}\n", e) - | `bio.Eof: std.fatal("i/o error: eof\n") + | `std.Ok _: /* nothing */ + | `std.Err e: std.fatal("i/o error: {}\n", e) ;; } diff --git a/elf.myr b/elf.myr index fd6fda3..1dcc7a5 100644 --- a/elf.myr +++ b/elf.myr @@ -119,10 +119,9 @@ const pad = {f, n ;; } -generic check = {st : bio.status(@a) +generic check = {st match st - | `bio.Ok _: /* nothing */ - | `bio.Err e: std.fatal("i/o error: {}\n", e) - | `bio.Eof: std.fatal("i/o error: eof\n") + | `std.Ok _: /* nothing */ + | `std.Err e: std.fatal("i/o error: {}\n", e) ;; } diff --git a/main.myr b/main.myr index c4cc8a3..18a2ba5 100644 --- a/main.myr +++ b/main.myr @@ -36,20 +36,18 @@ const main = {args .outf=outf, .sys=sys, - .stab=std.mkht(std.strhash, std.streq) + .stab=std.mkht() ] for a : cmd.args loadobj(&lnk, a) ;; link(&lnk) - std.put("text: {}\n", lnk.text) + /* + sadly, we need to brand binaries appropriately. + this means that simply knowing the format is + not enough, we need to know the target system. + */ match sys - /* generic binary targets */ - | "elf": emitelf(&lnk) - | "macho": emitmacho(&lnk) - | "aout": emitaout(&lnk) - - /* and figure it out by system */ | "openbsd": emitelf(&lnk) | "freebsd": emitelf(&lnk) | "netbsd": emitelf(&lnk) @@ -89,7 +87,6 @@ const relocate = {lnk, r | `std.None: std.fatal("unknown symbol {}\n", r.sym) | `std.Some s: - std.put("relocating: {}\n", r) addr = lnk.base + s.off + r.arg match r.kind & Relkind | Rel8: sz = 1 @@ -114,7 +111,6 @@ const relocate = {lnk, r if r.off + sz > lnk.cur.len std.fatal("out of bounds relocation in {}\n", s.name) ;; - std.put("addr: {}\n", addr) /* FIXME: endianness */ std.putle64(buf[:], addr) std.slcp(lnk.cur[r.off:r.off+sz], buf[:sz]) @@ -123,22 +119,23 @@ 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) ;; + -> void + | `std.None: /* ok */ + ;; + 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 ;; } const loadobj = {lnk, path - var rel, str, sym, o + var relsz, strsz, symsz, secsz, dstart, o var obj match std.slurp(path) @@ -150,44 +147,46 @@ const loadobj = {lnk, path std.fatal("unable to read {}: bad magic number\n", path) ;; - (str, o) = r64(obj.buf, 4) - (rel, o) = r64(obj.buf, o) - (sym, o) = r64(obj.buf, o) - obj.str = obj.buf[str:rel] - obj.rel = readrel(obj.buf[rel:sym], obj.str) - obj.sym = readsym(obj.buf[o:str], o, obj.str, obj.buf) - + (strsz, o) = r64(obj.buf, 4) + (secsz, o) = r64(obj.buf, o) + (symsz, o) = r64(obj.buf, o) + (relsz, o) = r64(obj.buf, o) + dstart = o + strsz + symsz + relsz + + obj.str = obj.buf[o:o+strsz] + o += strsz + obj.sect = readsec(obj.buf[o:o+secsz], obj.str) + o += secsz + obj.sym = readsym(obj.buf[o:o+symsz], obj.str, obj.buf[dstart:]) + o += symsz + obj.rel = readrel(obj.buf[o:o+relsz], obj.str) + o += relsz + + obj.buf = obj.buf[o:] std.slpush(&lnk.obj, obj) } -const readrel = {buf, strs - var rel, r, o +const readsec = {buf, strs + var o, s, sec o = 0 - rel = [][:] + sec = [][:] while o != buf.len - (r.sym, o) = rsym(buf, o, strs) - (r.kind, o) = r32(buf, o) - (r.off, o) = r64(buf, o) - std.put("r.kind: {x}\n", r.kind) - if (r.kind & Relarg) != 0 - (r.arg, o) = r64(buf, o) - else - r.arg = 0 - ;; - std.slpush(&rel, r) + (s.name, o) = rname(buf, o, strs) + (s.flg, o) = r32(buf, o) + std.slpush(&sec, s) ;; - -> rel + -> sec } -const readsym = {hbuf, o, strs, dbuf - var off, len +const readsym = {hbuf, strs, dbuf + var o, off, len var sym, s o = 0 sym = [][:] while o != hbuf.len - (s.name, o) = rsym(hbuf, o, strs) + (s.name, o) = rname(hbuf, o, strs) (s.kind, o) = r32(hbuf, o) (off, o) = r64(hbuf, o) (len, o) = r64(hbuf, o) @@ -200,7 +199,27 @@ const readsym = {hbuf, o, strs, dbuf -> sym } -const rsym = {buf, off, strs + +const readrel = {buf, strs + var rel, r, o + + o = 0 + rel = [][:] + while o != buf.len + (r.sym, o) = rname(buf, o, strs) + (r.kind, o) = r32(buf, o) + (r.off, o) = r64(buf, o) + if (r.kind & Relarg) != 0 + (r.arg, o) = r64(buf, o) + else + r.arg = 0 + ;; + std.slpush(&rel, r) + ;; + -> rel +} + +const rname = {buf, off, strs var sym, idx (idx, off) = r32(buf, off) diff --git a/types.myr b/types.myr index 818442e..f20cf00 100644 --- a/types.myr +++ b/types.myr @@ -48,6 +48,7 @@ pkg = rel : rel[:] buf : byte[:] str : byte[:] + sect : sect[:] /* state */ path : byte[:] @@ -70,4 +71,9 @@ pkg = off : uint64 arg : uint64 ;; + + type sect = struct + name : byte[:] + flg : uint32 + ;; ;; -- cgit v1.1