summaryrefslogtreecommitdiff
path: root/main.myr
diff options
context:
space:
mode:
Diffstat (limited to 'main.myr')
-rw-r--r--main.myr105
1 files changed, 62 insertions, 43 deletions
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)