summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorOri Bernstein <ori@eigenstate.org>2017-11-29 00:49:02 -0800
committerOri Bernstein <ori@eigenstate.org>2017-11-29 00:49:02 -0800
commit99277ccb136c3d8715073c8b067c23f05c1d08e8 (patch)
tree6793ec7617eff56965428d9ab289a6d7ef9bc9f7
parent189e00e249009aba59fa963ef2cd0f2dac832129 (diff)
downloadlnk-master.tar.gz
More work on output formats.HEADmaster
-rw-r--r--aout.myr7
-rw-r--r--elf.myr7
-rw-r--r--main.myr105
-rw-r--r--types.myr6
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
+ ;;
;;