selfhost: drop snake_case locals in dyn/dynout/obj + w6a + cgen + ww driver
This commit is contained in:
@@ -99,21 +99,21 @@ fn emitrex(a: *asm_, regbit: i32, rmbit: i32, w: i32) void = {
|
||||
|
||||
// ModR/M + (optional) SIB + displacement for [base+disp].
|
||||
// Special-cases SP (needs SIB) and BP (forces explicit disp).
|
||||
fn emitmodrmmem(a: *asm_, reg_field: i32, base: i32, disp: i64) void = {
|
||||
fn emitmodrmmem(a: *asm_, regfield: i32, base: i32, disp: i64) void = {
|
||||
let rm: i32 = rcode(base);
|
||||
let needsib: bool = (rm == 4);
|
||||
let forced_disp: bool = false;
|
||||
if (rm == 5) { if (disp == 0i64) { forced_disp = true; }; };
|
||||
let forceddisp: bool = false;
|
||||
if (rm == 5) { if (disp == 0i64) { forceddisp = true; }; };
|
||||
|
||||
let mod: i32 = 2;
|
||||
if (disp == 0i64) {
|
||||
if (!forced_disp) { mod = 0; }
|
||||
if (!forceddisp) { mod = 0; }
|
||||
else { mod = 1; };
|
||||
} else {
|
||||
if (disp >= -128i64) { if (disp <= 127i64) { mod = 1; }; };
|
||||
};
|
||||
|
||||
emitbyte(a, modrmbyte(mod, reg_field, rm));
|
||||
emitbyte(a, modrmbyte(mod, regfield, rm));
|
||||
if (needsib) {
|
||||
emitbyte(a, 36u8); // 0x24: scale=0 idx=4(none) base=4
|
||||
};
|
||||
@@ -132,17 +132,17 @@ fn encoderr(a: *asm_, opcode: u8, src: i32, dst: i32) void = {
|
||||
};
|
||||
|
||||
// reg→mem(base, disp) (e.g. MOVQ src reg into mem; opcode = 0x89).
|
||||
fn encoderm(a: *asm_, opcode: u8, src_reg: i32, base: i32, disp: i64) void = {
|
||||
emitrex(a, rhi(src_reg), rhi(base), 1);
|
||||
fn encoderm(a: *asm_, opcode: u8, srcreg: i32, base: i32, disp: i64) void = {
|
||||
emitrex(a, rhi(srcreg), rhi(base), 1);
|
||||
emitbyte(a, opcode);
|
||||
emitmodrmmem(a, rcode(src_reg), base, disp);
|
||||
emitmodrmmem(a, rcode(srcreg), base, disp);
|
||||
};
|
||||
|
||||
// mem(base, disp) → reg (e.g. MOVQ mem into reg; opcode = 0x8B).
|
||||
fn encodemr(a: *asm_, opcode: u8, dst_reg: i32, base: i32, disp: i64) void = {
|
||||
emitrex(a, rhi(dst_reg), rhi(base), 1);
|
||||
fn encodemr(a: *asm_, opcode: u8, dstreg: i32, base: i32, disp: i64) void = {
|
||||
emitrex(a, rhi(dstreg), rhi(base), 1);
|
||||
emitbyte(a, opcode);
|
||||
emitmodrmmem(a, rcode(dst_reg), base, disp);
|
||||
emitmodrmmem(a, rcode(dstreg), base, disp);
|
||||
};
|
||||
|
||||
// OPCODE /n imm32 reg form (e.g. ADDQ $imm, reg).
|
||||
@@ -162,29 +162,29 @@ fn encodeunary(a: *asm_, opcode: u8, subop: i32, dst: i32) void = {
|
||||
|
||||
// SSE2 helpers. Plan 9 syntax: source first, destination second.
|
||||
// For ADDSD-style ops we put dst in the reg field, src in r/m.
|
||||
fn sserr(a: *asm_, prefix: u8, op2: u8, reg_op: i32, rm_op: i32) void = {
|
||||
fn sserr(a: *asm_, prefix: u8, op2: u8, regop: i32, rmop: i32) void = {
|
||||
if (prefix != 0u8) { emitbyte(a, prefix); };
|
||||
emitrex(a, rhi(reg_op), rhi(rm_op), 0);
|
||||
emitrex(a, rhi(regop), rhi(rmop), 0);
|
||||
emitbyte(a, 15u8); // 0x0F
|
||||
emitbyte(a, op2);
|
||||
emitbyte(a, modrmbyte(3, rcode(reg_op), rcode(rm_op)));
|
||||
emitbyte(a, modrmbyte(3, rcode(regop), rcode(rmop)));
|
||||
};
|
||||
|
||||
fn ssemrload(a: *asm_, prefix: u8, op2: u8, reg_op: i32, base: i32, disp: i64) void = {
|
||||
fn ssemrload(a: *asm_, prefix: u8, op2: u8, regop: i32, base: i32, disp: i64) void = {
|
||||
if (prefix != 0u8) { emitbyte(a, prefix); };
|
||||
emitrex(a, rhi(reg_op), rhi(base), 0);
|
||||
emitrex(a, rhi(regop), rhi(base), 0);
|
||||
emitbyte(a, 15u8);
|
||||
emitbyte(a, op2);
|
||||
emitmodrmmem(a, rcode(reg_op), base, disp);
|
||||
emitmodrmmem(a, rcode(regop), base, disp);
|
||||
};
|
||||
|
||||
// REX.W variant of sse_rr (CVTTSD2SI / CVTSI2SD).
|
||||
fn sserrw(a: *asm_, prefix: u8, op2: u8, reg_op: i32, rm_op: i32) void = {
|
||||
fn sserrw(a: *asm_, prefix: u8, op2: u8, regop: i32, rmop: i32) void = {
|
||||
if (prefix != 0u8) { emitbyte(a, prefix); };
|
||||
emitrex(a, rhi(reg_op), rhi(rm_op), 1);
|
||||
emitrex(a, rhi(regop), rhi(rmop), 1);
|
||||
emitbyte(a, 15u8);
|
||||
emitbyte(a, op2);
|
||||
emitbyte(a, modrmbyte(3, rcode(reg_op), rcode(rm_op)));
|
||||
emitbyte(a, modrmbyte(3, rcode(regop), rcode(rmop)));
|
||||
};
|
||||
|
||||
// ---- label resolution / fixups ----------------------------------------
|
||||
@@ -629,7 +629,7 @@ export fn encode(a: *asm_) i32 = {
|
||||
|
||||
// Conditional jumps. 0x0F + cc + rel32.
|
||||
let cc: u8 = 0u8;
|
||||
let is_jcc: bool = true;
|
||||
let isjcc: bool = true;
|
||||
if (op == A_JE) { cc = 132u8; } // 0x84
|
||||
else { if (op == A_JZ) { cc = 132u8; }
|
||||
else { if (op == A_JNE) { cc = 133u8; }
|
||||
@@ -642,8 +642,8 @@ export fn encode(a: *asm_) i32 = {
|
||||
else { if (op == A_JBE) { cc = 134u8; }
|
||||
else { if (op == A_JA) { cc = 135u8; }
|
||||
else { if (op == A_JAE) { cc = 131u8; }
|
||||
else { is_jcc = false; };};};};};};};};};};};};
|
||||
if (is_jcc) {
|
||||
else { isjcc = false; };};};};};};};};};};};};
|
||||
if (isjcc) {
|
||||
emitbyte(a, 15u8);
|
||||
emitbyte(a, cc);
|
||||
addfixup(a, a.textlen, p.to.asym);
|
||||
|
||||
@@ -841,12 +841,12 @@ fn parseoperand(a: *asm_, p: *u8, offin: u64, n: u64, out: *aoperand) u64 = {
|
||||
|
||||
// number(REG) — possibly signed — or bare $NUM-less constant
|
||||
let cur: u64 = off;
|
||||
let is_num: bool = false;
|
||||
let isnum: bool = false;
|
||||
if (cur < n) {
|
||||
if (p[cur] == 45u8) { is_num = true; }
|
||||
else { if (p[cur] >= 48u8) { if (p[cur] <= 57u8) { is_num = true; }; }; };
|
||||
if (p[cur] == 45u8) { isnum = true; }
|
||||
else { if (p[cur] >= 48u8) { if (p[cur] <= 57u8) { isnum = true; }; }; };
|
||||
};
|
||||
if (is_num) {
|
||||
if (isnum) {
|
||||
let v: i64;
|
||||
let used: u64;
|
||||
v, used = parsenum(p + off, n - off);
|
||||
@@ -974,11 +974,11 @@ export fn parse(a: *asm_) i32 = {
|
||||
if (line[0u64] != 9u8) {
|
||||
if (isidstart(line[i]: i32)) {
|
||||
let q: u64 = i;
|
||||
let scan_id: bool = true;
|
||||
for (scan_id) {
|
||||
if (q >= n) { scan_id = false; }
|
||||
let scanid: bool = true;
|
||||
for (scanid) {
|
||||
if (q >= n) { scanid = false; }
|
||||
else { if (isidcont(line[q]: i32)) { q += 1u64; }
|
||||
else { scan_id = false; }; };
|
||||
else { scanid = false; }; };
|
||||
};
|
||||
if (q < n) { if (line[q] == 58u8) { // ':'
|
||||
let nm: str = dupstr(a.a, line + i, q - i);
|
||||
@@ -1023,26 +1023,26 @@ export fn parse(a: *asm_) i32 = {
|
||||
if (opc == A_TEXT) {
|
||||
// TEXT name,$framesize — find first ',' as the end of name.
|
||||
let q: u64 = r0;
|
||||
let comma_pos: u64 = n;
|
||||
let scan_t: bool = true;
|
||||
for (scan_t) {
|
||||
if (q >= n) { scan_t = false; }
|
||||
else { if (line[q] == 44u8) { comma_pos = q; scan_t = false; }
|
||||
let commapos: u64 = n;
|
||||
let scant: bool = true;
|
||||
for (scant) {
|
||||
if (q >= n) { scant = false; }
|
||||
else { if (line[q] == 44u8) { commapos = q; scant = false; }
|
||||
else { q += 1u64; }; };
|
||||
};
|
||||
let to_op: *aoperand = pr.to;
|
||||
to_op.atype = D_EXTERN;
|
||||
to_op.asym = dupstr(a.a, line + r0, comma_pos - r0);
|
||||
if (comma_pos < n) {
|
||||
let p2: u64 = comma_pos + 1u64;
|
||||
let toop: *aoperand = pr.to;
|
||||
toop.atype = D_EXTERN;
|
||||
toop.asym = dupstr(a.a, line + r0, commapos - r0);
|
||||
if (commapos < n) {
|
||||
let p2: u64 = commapos + 1u64;
|
||||
p2 = skipws(line, p2, n);
|
||||
if (p2 < n) { if (line[p2] == 36u8) { p2 += 1u64; }; };
|
||||
let v: i64;
|
||||
let used: u64;
|
||||
v, used = parsenum(line + p2, n - p2);
|
||||
let from_op: *aoperand = pr.from;
|
||||
from_op.atype = D_CONST;
|
||||
from_op.offset = v;
|
||||
let fromop: *aoperand = pr.from;
|
||||
fromop.atype = D_CONST;
|
||||
fromop.offset = v;
|
||||
};
|
||||
a.line += 1; continue;
|
||||
};
|
||||
@@ -1051,31 +1051,31 @@ export fn parse(a: *asm_) i32 = {
|
||||
// DATA name(SB),"escaped bytes" — find first '(' as end of name.
|
||||
let q: u64 = r0;
|
||||
let lparen: u64 = n;
|
||||
let scan_d: bool = true;
|
||||
for (scan_d) {
|
||||
if (q >= n) { scan_d = false; }
|
||||
else { if (line[q] == 40u8) { lparen = q; scan_d = false; }
|
||||
let scand: bool = true;
|
||||
for (scand) {
|
||||
if (q >= n) { scand = false; }
|
||||
else { if (line[q] == 40u8) { lparen = q; scand = false; }
|
||||
else { q += 1u64; }; };
|
||||
};
|
||||
let to_op: *aoperand = pr.to;
|
||||
to_op.atype = D_EXTERN;
|
||||
to_op.asym = dupstr(a.a, line + r0, lparen - r0);
|
||||
let toop: *aoperand = pr.to;
|
||||
toop.atype = D_EXTERN;
|
||||
toop.asym = dupstr(a.a, line + r0, lparen - r0);
|
||||
// Skip past `(SB)` to land just after ')'.
|
||||
let p2: u64 = lparen;
|
||||
let scan_d2: bool = true;
|
||||
for (scan_d2) {
|
||||
if (p2 >= n) { scan_d2 = false; }
|
||||
else { if (line[p2] == 41u8) { p2 += 1u64; scan_d2 = false; }
|
||||
let scand2: bool = true;
|
||||
for (scand2) {
|
||||
if (p2 >= n) { scand2 = false; }
|
||||
else { if (line[p2] == 41u8) { p2 += 1u64; scand2 = false; }
|
||||
else { p2 += 1u64; }; };
|
||||
};
|
||||
// Skip ws / ',' / tab between `)` and the `"`.
|
||||
let scan_d3: bool = true;
|
||||
for (scan_d3) {
|
||||
if (p2 >= n) { scan_d3 = false; }
|
||||
let scand3: bool = true;
|
||||
for (scand3) {
|
||||
if (p2 >= n) { scand3 = false; }
|
||||
else { if (line[p2] == 32u8) { p2 += 1u64; }
|
||||
else { if (line[p2] == 44u8) { p2 += 1u64; }
|
||||
else { if (line[p2] == 9u8) { p2 += 1u64; }
|
||||
else { scan_d3 = false; }; }; }; };
|
||||
else { scand3 = false; }; }; }; };
|
||||
};
|
||||
if (p2 >= n) { perr(a, "DATA missing payload"); a.line += 1; continue; };
|
||||
if (line[p2] != 34u8) { perr(a, "DATA expects \"...\""); a.line += 1; continue; };
|
||||
@@ -1258,21 +1258,21 @@ fn emitrex(a: *asm_, regbit: i32, rmbit: i32, w: i32) void = {
|
||||
|
||||
// ModR/M + (optional) SIB + displacement for [base+disp].
|
||||
// Special-cases SP (needs SIB) and BP (forces explicit disp).
|
||||
fn emitmodrmmem(a: *asm_, reg_field: i32, base: i32, disp: i64) void = {
|
||||
fn emitmodrmmem(a: *asm_, regfield: i32, base: i32, disp: i64) void = {
|
||||
let rm: i32 = rcode(base);
|
||||
let needsib: bool = (rm == 4);
|
||||
let forced_disp: bool = false;
|
||||
if (rm == 5) { if (disp == 0i64) { forced_disp = true; }; };
|
||||
let forceddisp: bool = false;
|
||||
if (rm == 5) { if (disp == 0i64) { forceddisp = true; }; };
|
||||
|
||||
let mod: i32 = 2;
|
||||
if (disp == 0i64) {
|
||||
if (!forced_disp) { mod = 0; }
|
||||
if (!forceddisp) { mod = 0; }
|
||||
else { mod = 1; };
|
||||
} else {
|
||||
if (disp >= -128i64) { if (disp <= 127i64) { mod = 1; }; };
|
||||
};
|
||||
|
||||
emitbyte(a, modrmbyte(mod, reg_field, rm));
|
||||
emitbyte(a, modrmbyte(mod, regfield, rm));
|
||||
if (needsib) {
|
||||
emitbyte(a, 36u8); // 0x24: scale=0 idx=4(none) base=4
|
||||
};
|
||||
@@ -1291,17 +1291,17 @@ fn encoderr(a: *asm_, opcode: u8, src: i32, dst: i32) void = {
|
||||
};
|
||||
|
||||
// reg→mem(base, disp) (e.g. MOVQ src reg into mem; opcode = 0x89).
|
||||
fn encoderm(a: *asm_, opcode: u8, src_reg: i32, base: i32, disp: i64) void = {
|
||||
emitrex(a, rhi(src_reg), rhi(base), 1);
|
||||
fn encoderm(a: *asm_, opcode: u8, srcreg: i32, base: i32, disp: i64) void = {
|
||||
emitrex(a, rhi(srcreg), rhi(base), 1);
|
||||
emitbyte(a, opcode);
|
||||
emitmodrmmem(a, rcode(src_reg), base, disp);
|
||||
emitmodrmmem(a, rcode(srcreg), base, disp);
|
||||
};
|
||||
|
||||
// mem(base, disp) → reg (e.g. MOVQ mem into reg; opcode = 0x8B).
|
||||
fn encodemr(a: *asm_, opcode: u8, dst_reg: i32, base: i32, disp: i64) void = {
|
||||
emitrex(a, rhi(dst_reg), rhi(base), 1);
|
||||
fn encodemr(a: *asm_, opcode: u8, dstreg: i32, base: i32, disp: i64) void = {
|
||||
emitrex(a, rhi(dstreg), rhi(base), 1);
|
||||
emitbyte(a, opcode);
|
||||
emitmodrmmem(a, rcode(dst_reg), base, disp);
|
||||
emitmodrmmem(a, rcode(dstreg), base, disp);
|
||||
};
|
||||
|
||||
// OPCODE /n imm32 reg form (e.g. ADDQ $imm, reg).
|
||||
@@ -1321,29 +1321,29 @@ fn encodeunary(a: *asm_, opcode: u8, subop: i32, dst: i32) void = {
|
||||
|
||||
// SSE2 helpers. Plan 9 syntax: source first, destination second.
|
||||
// For ADDSD-style ops we put dst in the reg field, src in r/m.
|
||||
fn sserr(a: *asm_, prefix: u8, op2: u8, reg_op: i32, rm_op: i32) void = {
|
||||
fn sserr(a: *asm_, prefix: u8, op2: u8, regop: i32, rmop: i32) void = {
|
||||
if (prefix != 0u8) { emitbyte(a, prefix); };
|
||||
emitrex(a, rhi(reg_op), rhi(rm_op), 0);
|
||||
emitrex(a, rhi(regop), rhi(rmop), 0);
|
||||
emitbyte(a, 15u8); // 0x0F
|
||||
emitbyte(a, op2);
|
||||
emitbyte(a, modrmbyte(3, rcode(reg_op), rcode(rm_op)));
|
||||
emitbyte(a, modrmbyte(3, rcode(regop), rcode(rmop)));
|
||||
};
|
||||
|
||||
fn ssemrload(a: *asm_, prefix: u8, op2: u8, reg_op: i32, base: i32, disp: i64) void = {
|
||||
fn ssemrload(a: *asm_, prefix: u8, op2: u8, regop: i32, base: i32, disp: i64) void = {
|
||||
if (prefix != 0u8) { emitbyte(a, prefix); };
|
||||
emitrex(a, rhi(reg_op), rhi(base), 0);
|
||||
emitrex(a, rhi(regop), rhi(base), 0);
|
||||
emitbyte(a, 15u8);
|
||||
emitbyte(a, op2);
|
||||
emitmodrmmem(a, rcode(reg_op), base, disp);
|
||||
emitmodrmmem(a, rcode(regop), base, disp);
|
||||
};
|
||||
|
||||
// REX.W variant of sse_rr (CVTTSD2SI / CVTSI2SD).
|
||||
fn sserrw(a: *asm_, prefix: u8, op2: u8, reg_op: i32, rm_op: i32) void = {
|
||||
fn sserrw(a: *asm_, prefix: u8, op2: u8, regop: i32, rmop: i32) void = {
|
||||
if (prefix != 0u8) { emitbyte(a, prefix); };
|
||||
emitrex(a, rhi(reg_op), rhi(rm_op), 1);
|
||||
emitrex(a, rhi(regop), rhi(rmop), 1);
|
||||
emitbyte(a, 15u8);
|
||||
emitbyte(a, op2);
|
||||
emitbyte(a, modrmbyte(3, rcode(reg_op), rcode(rm_op)));
|
||||
emitbyte(a, modrmbyte(3, rcode(regop), rcode(rmop)));
|
||||
};
|
||||
|
||||
// ---- label resolution / fixups ----------------------------------------
|
||||
@@ -1788,7 +1788,7 @@ export fn encode(a: *asm_) i32 = {
|
||||
|
||||
// Conditional jumps. 0x0F + cc + rel32.
|
||||
let cc: u8 = 0u8;
|
||||
let is_jcc: bool = true;
|
||||
let isjcc: bool = true;
|
||||
if (op == A_JE) { cc = 132u8; } // 0x84
|
||||
else { if (op == A_JZ) { cc = 132u8; }
|
||||
else { if (op == A_JNE) { cc = 133u8; }
|
||||
@@ -1801,8 +1801,8 @@ export fn encode(a: *asm_) i32 = {
|
||||
else { if (op == A_JBE) { cc = 134u8; }
|
||||
else { if (op == A_JA) { cc = 135u8; }
|
||||
else { if (op == A_JAE) { cc = 131u8; }
|
||||
else { is_jcc = false; };};};};};};};};};};};};
|
||||
if (is_jcc) {
|
||||
else { isjcc = false; };};};};};};};};};};};};
|
||||
if (isjcc) {
|
||||
emitbyte(a, 15u8);
|
||||
emitbyte(a, cc);
|
||||
addfixup(a, a.textlen, p.to.asym);
|
||||
@@ -1962,11 +1962,11 @@ export fn emitelf(a: *asm_, fd: i32) i32 = {
|
||||
bufputb(&str_, &zero, 1u64);
|
||||
|
||||
// Section name offsets.
|
||||
let shn_text: u32 = bufputcstr(&shstr, ".text");
|
||||
let shn_rela: u32 = bufputcstr(&shstr, ".rela.text");
|
||||
let shn_symtab: u32 = bufputcstr(&shstr, ".symtab");
|
||||
let shn_strtab: u32 = bufputcstr(&shstr, ".strtab");
|
||||
let shn_shstrtab: u32 = bufputcstr(&shstr, ".shstrtab");
|
||||
let shntext: u32 = bufputcstr(&shstr, ".text");
|
||||
let shnrela: u32 = bufputcstr(&shstr, ".rela.text");
|
||||
let shnsymtab: u32 = bufputcstr(&shstr, ".symtab");
|
||||
let shnstrtab: u32 = bufputcstr(&shstr, ".strtab");
|
||||
let shnshstrtab: u32 = bufputcstr(&shstr, ".shstrtab");
|
||||
|
||||
// Symbol 0 — STN_UNDEF (24 zero bytes).
|
||||
let zsym: [24]u8;
|
||||
@@ -1983,8 +1983,8 @@ export fn emitelf(a: *asm_, fd: i32) i32 = {
|
||||
let entry: [24]u8;
|
||||
let ei: i32 = 0;
|
||||
for (ei < 24) { entry[ei] = 0u8; ei += 1; };
|
||||
let st_name: u32 = bufputcstr(&str_, s.name);
|
||||
wru32(entry.ptr, 0u64, st_name);
|
||||
let stname: u32 = bufputcstr(&str_, s.name);
|
||||
wru32(entry.ptr, 0u64, stname);
|
||||
if (s.defined != 0) {
|
||||
wru8(entry.ptr, 4u64, ((STB_GLOBAL << 4u8) | STT_FUNC));
|
||||
wru16(entry.ptr, 6u64, SH_TEXT);
|
||||
@@ -2004,8 +2004,8 @@ export fn emitelf(a: *asm_, fd: i32) i32 = {
|
||||
for (r != nil) {
|
||||
let entry: [24]u8;
|
||||
wru64(entry.ptr, 0u64, r.off);
|
||||
let r_info: u64 = (r.asy.idx: u64 << 32u64) | (r.kind: u64 & 4294967295u64);
|
||||
wru64(entry.ptr, 8u64, r_info);
|
||||
let rinfo: u64 = (r.asy.idx: u64 << 32u64) | (r.kind: u64 & 4294967295u64);
|
||||
wru64(entry.ptr, 8u64, rinfo);
|
||||
wru64(entry.ptr, 16u64, r.addend: u64);
|
||||
bufputb(&rela, entry.ptr, 24u64);
|
||||
r = r.rnext;
|
||||
@@ -2013,13 +2013,13 @@ export fn emitelf(a: *asm_, fd: i32) i32 = {
|
||||
|
||||
// File offsets.
|
||||
let off: u64 = EHDR_SZ;
|
||||
let off_text: u64 = off; off = off + a.textlen;
|
||||
let off_rela: u64 = off; off = off + rela.n;
|
||||
let off_sym: u64 = off; off = off + sym.n;
|
||||
let off_str: u64 = off; off = off + str_.n;
|
||||
let off_shstr: u64 = off; off = off + shstr.n;
|
||||
let offtext: u64 = off; off = off + a.textlen;
|
||||
let offrela: u64 = off; off = off + rela.n;
|
||||
let offsym: u64 = off; off = off + sym.n;
|
||||
let offstr: u64 = off; off = off + str_.n;
|
||||
let offshstr: u64 = off; off = off + shstr.n;
|
||||
for ((off & 7u64) != 0u64) { off += 1u64; };
|
||||
let off_shdr: u64 = off;
|
||||
let offshdr: u64 = off;
|
||||
let NSECT: u16 = 6u16;
|
||||
|
||||
// ---- Ehdr ----
|
||||
@@ -2038,7 +2038,7 @@ export fn emitelf(a: *asm_, fd: i32) i32 = {
|
||||
wru32(eh.ptr, 20u64, EV_CURRENT_W);
|
||||
wru64(eh.ptr, 24u64, 0u64); // e_entry
|
||||
wru64(eh.ptr, 32u64, 0u64); // e_phoff
|
||||
wru64(eh.ptr, 40u64, off_shdr); // e_shoff
|
||||
wru64(eh.ptr, 40u64, offshdr); // e_shoff
|
||||
wru32(eh.ptr, 48u64, 0u32); // e_flags
|
||||
wru16(eh.ptr, 52u64, 64u16); // e_ehsize
|
||||
wru16(eh.ptr, 54u64, 0u16); // e_phentsize
|
||||
@@ -2080,20 +2080,20 @@ export fn emitelf(a: *asm_, fd: i32) i32 = {
|
||||
// .text
|
||||
sn = 0;
|
||||
for (sn < 64) { shbuf[sn] = 0u8; sn += 1; };
|
||||
wru32(shbuf.ptr, 0u64, shn_text);
|
||||
wru32(shbuf.ptr, 0u64, shntext);
|
||||
wru32(shbuf.ptr, 4u64, SHT_PROGBITS_C);
|
||||
wru64(shbuf.ptr, 8u64, SHF_ALLOC | SHF_EXECINSTR);
|
||||
wru64(shbuf.ptr, 24u64, off_text);
|
||||
wru64(shbuf.ptr, 24u64, offtext);
|
||||
wru64(shbuf.ptr, 32u64, a.textlen);
|
||||
wru64(shbuf.ptr, 48u64, 1u64); // sh_addralign
|
||||
os.writefull(fd, shbuf.ptr, 64u64);
|
||||
// .rela.text
|
||||
sn = 0;
|
||||
for (sn < 64) { shbuf[sn] = 0u8; sn += 1; };
|
||||
wru32(shbuf.ptr, 0u64, shn_rela);
|
||||
wru32(shbuf.ptr, 0u64, shnrela);
|
||||
wru32(shbuf.ptr, 4u64, SHT_RELA_C);
|
||||
wru64(shbuf.ptr, 8u64, SHF_INFO_LINK);
|
||||
wru64(shbuf.ptr, 24u64, off_rela);
|
||||
wru64(shbuf.ptr, 24u64, offrela);
|
||||
wru64(shbuf.ptr, 32u64, rela.n);
|
||||
wru32(shbuf.ptr, 40u64, 3u32); // sh_link = symtab idx
|
||||
wru32(shbuf.ptr, 44u64, 1u32); // sh_info = .text idx
|
||||
@@ -2103,9 +2103,9 @@ export fn emitelf(a: *asm_, fd: i32) i32 = {
|
||||
// .symtab
|
||||
sn = 0;
|
||||
for (sn < 64) { shbuf[sn] = 0u8; sn += 1; };
|
||||
wru32(shbuf.ptr, 0u64, shn_symtab);
|
||||
wru32(shbuf.ptr, 0u64, shnsymtab);
|
||||
wru32(shbuf.ptr, 4u64, SHT_SYMTAB_C);
|
||||
wru64(shbuf.ptr, 24u64, off_sym);
|
||||
wru64(shbuf.ptr, 24u64, offsym);
|
||||
wru64(shbuf.ptr, 32u64, sym.n);
|
||||
wru32(shbuf.ptr, 40u64, 4u32); // sh_link = strtab
|
||||
wru32(shbuf.ptr, 44u64, 1u32); // sh_info = one local (STN_UNDEF)
|
||||
@@ -2115,18 +2115,18 @@ export fn emitelf(a: *asm_, fd: i32) i32 = {
|
||||
// .strtab
|
||||
sn = 0;
|
||||
for (sn < 64) { shbuf[sn] = 0u8; sn += 1; };
|
||||
wru32(shbuf.ptr, 0u64, shn_strtab);
|
||||
wru32(shbuf.ptr, 0u64, shnstrtab);
|
||||
wru32(shbuf.ptr, 4u64, SHT_STRTAB_C);
|
||||
wru64(shbuf.ptr, 24u64, off_str);
|
||||
wru64(shbuf.ptr, 24u64, offstr);
|
||||
wru64(shbuf.ptr, 32u64, str_.n);
|
||||
wru64(shbuf.ptr, 48u64, 1u64);
|
||||
os.writefull(fd, shbuf.ptr, 64u64);
|
||||
// .shstrtab
|
||||
sn = 0;
|
||||
for (sn < 64) { shbuf[sn] = 0u8; sn += 1; };
|
||||
wru32(shbuf.ptr, 0u64, shn_shstrtab);
|
||||
wru32(shbuf.ptr, 0u64, shnshstrtab);
|
||||
wru32(shbuf.ptr, 4u64, SHT_STRTAB_C);
|
||||
wru64(shbuf.ptr, 24u64, off_shstr);
|
||||
wru64(shbuf.ptr, 24u64, offshstr);
|
||||
wru64(shbuf.ptr, 32u64, shstr.n);
|
||||
wru64(shbuf.ptr, 48u64, 1u64);
|
||||
os.writefull(fd, shbuf.ptr, 64u64);
|
||||
|
||||
@@ -120,11 +120,11 @@ export fn emitelf(a: *asm_, fd: i32) i32 = {
|
||||
bufputb(&str_, &zero, 1u64);
|
||||
|
||||
// Section name offsets.
|
||||
let shn_text: u32 = bufputcstr(&shstr, ".text");
|
||||
let shn_rela: u32 = bufputcstr(&shstr, ".rela.text");
|
||||
let shn_symtab: u32 = bufputcstr(&shstr, ".symtab");
|
||||
let shn_strtab: u32 = bufputcstr(&shstr, ".strtab");
|
||||
let shn_shstrtab: u32 = bufputcstr(&shstr, ".shstrtab");
|
||||
let shntext: u32 = bufputcstr(&shstr, ".text");
|
||||
let shnrela: u32 = bufputcstr(&shstr, ".rela.text");
|
||||
let shnsymtab: u32 = bufputcstr(&shstr, ".symtab");
|
||||
let shnstrtab: u32 = bufputcstr(&shstr, ".strtab");
|
||||
let shnshstrtab: u32 = bufputcstr(&shstr, ".shstrtab");
|
||||
|
||||
// Symbol 0 — STN_UNDEF (24 zero bytes).
|
||||
let zsym: [24]u8;
|
||||
@@ -141,8 +141,8 @@ export fn emitelf(a: *asm_, fd: i32) i32 = {
|
||||
let entry: [24]u8;
|
||||
let ei: i32 = 0;
|
||||
for (ei < 24) { entry[ei] = 0u8; ei += 1; };
|
||||
let st_name: u32 = bufputcstr(&str_, s.name);
|
||||
wru32(entry.ptr, 0u64, st_name);
|
||||
let stname: u32 = bufputcstr(&str_, s.name);
|
||||
wru32(entry.ptr, 0u64, stname);
|
||||
if (s.defined != 0) {
|
||||
wru8(entry.ptr, 4u64, ((STB_GLOBAL << 4u8) | STT_FUNC));
|
||||
wru16(entry.ptr, 6u64, SH_TEXT);
|
||||
@@ -162,8 +162,8 @@ export fn emitelf(a: *asm_, fd: i32) i32 = {
|
||||
for (r != nil) {
|
||||
let entry: [24]u8;
|
||||
wru64(entry.ptr, 0u64, r.off);
|
||||
let r_info: u64 = (r.asy.idx: u64 << 32u64) | (r.kind: u64 & 4294967295u64);
|
||||
wru64(entry.ptr, 8u64, r_info);
|
||||
let rinfo: u64 = (r.asy.idx: u64 << 32u64) | (r.kind: u64 & 4294967295u64);
|
||||
wru64(entry.ptr, 8u64, rinfo);
|
||||
wru64(entry.ptr, 16u64, r.addend: u64);
|
||||
bufputb(&rela, entry.ptr, 24u64);
|
||||
r = r.rnext;
|
||||
@@ -171,13 +171,13 @@ export fn emitelf(a: *asm_, fd: i32) i32 = {
|
||||
|
||||
// File offsets.
|
||||
let off: u64 = EHDR_SZ;
|
||||
let off_text: u64 = off; off = off + a.textlen;
|
||||
let off_rela: u64 = off; off = off + rela.n;
|
||||
let off_sym: u64 = off; off = off + sym.n;
|
||||
let off_str: u64 = off; off = off + str_.n;
|
||||
let off_shstr: u64 = off; off = off + shstr.n;
|
||||
let offtext: u64 = off; off = off + a.textlen;
|
||||
let offrela: u64 = off; off = off + rela.n;
|
||||
let offsym: u64 = off; off = off + sym.n;
|
||||
let offstr: u64 = off; off = off + str_.n;
|
||||
let offshstr: u64 = off; off = off + shstr.n;
|
||||
for ((off & 7u64) != 0u64) { off += 1u64; };
|
||||
let off_shdr: u64 = off;
|
||||
let offshdr: u64 = off;
|
||||
let NSECT: u16 = 6u16;
|
||||
|
||||
// ---- Ehdr ----
|
||||
@@ -196,7 +196,7 @@ export fn emitelf(a: *asm_, fd: i32) i32 = {
|
||||
wru32(eh.ptr, 20u64, EV_CURRENT_W);
|
||||
wru64(eh.ptr, 24u64, 0u64); // e_entry
|
||||
wru64(eh.ptr, 32u64, 0u64); // e_phoff
|
||||
wru64(eh.ptr, 40u64, off_shdr); // e_shoff
|
||||
wru64(eh.ptr, 40u64, offshdr); // e_shoff
|
||||
wru32(eh.ptr, 48u64, 0u32); // e_flags
|
||||
wru16(eh.ptr, 52u64, 64u16); // e_ehsize
|
||||
wru16(eh.ptr, 54u64, 0u16); // e_phentsize
|
||||
@@ -238,20 +238,20 @@ export fn emitelf(a: *asm_, fd: i32) i32 = {
|
||||
// .text
|
||||
sn = 0;
|
||||
for (sn < 64) { shbuf[sn] = 0u8; sn += 1; };
|
||||
wru32(shbuf.ptr, 0u64, shn_text);
|
||||
wru32(shbuf.ptr, 0u64, shntext);
|
||||
wru32(shbuf.ptr, 4u64, SHT_PROGBITS_C);
|
||||
wru64(shbuf.ptr, 8u64, SHF_ALLOC | SHF_EXECINSTR);
|
||||
wru64(shbuf.ptr, 24u64, off_text);
|
||||
wru64(shbuf.ptr, 24u64, offtext);
|
||||
wru64(shbuf.ptr, 32u64, a.textlen);
|
||||
wru64(shbuf.ptr, 48u64, 1u64); // sh_addralign
|
||||
os.writefull(fd, shbuf.ptr, 64u64);
|
||||
// .rela.text
|
||||
sn = 0;
|
||||
for (sn < 64) { shbuf[sn] = 0u8; sn += 1; };
|
||||
wru32(shbuf.ptr, 0u64, shn_rela);
|
||||
wru32(shbuf.ptr, 0u64, shnrela);
|
||||
wru32(shbuf.ptr, 4u64, SHT_RELA_C);
|
||||
wru64(shbuf.ptr, 8u64, SHF_INFO_LINK);
|
||||
wru64(shbuf.ptr, 24u64, off_rela);
|
||||
wru64(shbuf.ptr, 24u64, offrela);
|
||||
wru64(shbuf.ptr, 32u64, rela.n);
|
||||
wru32(shbuf.ptr, 40u64, 3u32); // sh_link = symtab idx
|
||||
wru32(shbuf.ptr, 44u64, 1u32); // sh_info = .text idx
|
||||
@@ -261,9 +261,9 @@ export fn emitelf(a: *asm_, fd: i32) i32 = {
|
||||
// .symtab
|
||||
sn = 0;
|
||||
for (sn < 64) { shbuf[sn] = 0u8; sn += 1; };
|
||||
wru32(shbuf.ptr, 0u64, shn_symtab);
|
||||
wru32(shbuf.ptr, 0u64, shnsymtab);
|
||||
wru32(shbuf.ptr, 4u64, SHT_SYMTAB_C);
|
||||
wru64(shbuf.ptr, 24u64, off_sym);
|
||||
wru64(shbuf.ptr, 24u64, offsym);
|
||||
wru64(shbuf.ptr, 32u64, sym.n);
|
||||
wru32(shbuf.ptr, 40u64, 4u32); // sh_link = strtab
|
||||
wru32(shbuf.ptr, 44u64, 1u32); // sh_info = one local (STN_UNDEF)
|
||||
@@ -273,18 +273,18 @@ export fn emitelf(a: *asm_, fd: i32) i32 = {
|
||||
// .strtab
|
||||
sn = 0;
|
||||
for (sn < 64) { shbuf[sn] = 0u8; sn += 1; };
|
||||
wru32(shbuf.ptr, 0u64, shn_strtab);
|
||||
wru32(shbuf.ptr, 0u64, shnstrtab);
|
||||
wru32(shbuf.ptr, 4u64, SHT_STRTAB_C);
|
||||
wru64(shbuf.ptr, 24u64, off_str);
|
||||
wru64(shbuf.ptr, 24u64, offstr);
|
||||
wru64(shbuf.ptr, 32u64, str_.n);
|
||||
wru64(shbuf.ptr, 48u64, 1u64);
|
||||
os.writefull(fd, shbuf.ptr, 64u64);
|
||||
// .shstrtab
|
||||
sn = 0;
|
||||
for (sn < 64) { shbuf[sn] = 0u8; sn += 1; };
|
||||
wru32(shbuf.ptr, 0u64, shn_shstrtab);
|
||||
wru32(shbuf.ptr, 0u64, shnshstrtab);
|
||||
wru32(shbuf.ptr, 4u64, SHT_STRTAB_C);
|
||||
wru64(shbuf.ptr, 24u64, off_shstr);
|
||||
wru64(shbuf.ptr, 24u64, offshstr);
|
||||
wru64(shbuf.ptr, 32u64, shstr.n);
|
||||
wru64(shbuf.ptr, 48u64, 1u64);
|
||||
os.writefull(fd, shbuf.ptr, 64u64);
|
||||
|
||||
@@ -259,12 +259,12 @@ fn parseoperand(a: *asm_, p: *u8, offin: u64, n: u64, out: *aoperand) u64 = {
|
||||
|
||||
// number(REG) — possibly signed — or bare $NUM-less constant
|
||||
let cur: u64 = off;
|
||||
let is_num: bool = false;
|
||||
let isnum: bool = false;
|
||||
if (cur < n) {
|
||||
if (p[cur] == 45u8) { is_num = true; }
|
||||
else { if (p[cur] >= 48u8) { if (p[cur] <= 57u8) { is_num = true; }; }; };
|
||||
if (p[cur] == 45u8) { isnum = true; }
|
||||
else { if (p[cur] >= 48u8) { if (p[cur] <= 57u8) { isnum = true; }; }; };
|
||||
};
|
||||
if (is_num) {
|
||||
if (isnum) {
|
||||
let v: i64;
|
||||
let used: u64;
|
||||
v, used = parsenum(p + off, n - off);
|
||||
@@ -392,11 +392,11 @@ export fn parse(a: *asm_) i32 = {
|
||||
if (line[0u64] != 9u8) {
|
||||
if (isidstart(line[i]: i32)) {
|
||||
let q: u64 = i;
|
||||
let scan_id: bool = true;
|
||||
for (scan_id) {
|
||||
if (q >= n) { scan_id = false; }
|
||||
let scanid: bool = true;
|
||||
for (scanid) {
|
||||
if (q >= n) { scanid = false; }
|
||||
else { if (isidcont(line[q]: i32)) { q += 1u64; }
|
||||
else { scan_id = false; }; };
|
||||
else { scanid = false; }; };
|
||||
};
|
||||
if (q < n) { if (line[q] == 58u8) { // ':'
|
||||
let nm: str = dupstr(a.a, line + i, q - i);
|
||||
@@ -441,26 +441,26 @@ export fn parse(a: *asm_) i32 = {
|
||||
if (opc == A_TEXT) {
|
||||
// TEXT name,$framesize — find first ',' as the end of name.
|
||||
let q: u64 = r0;
|
||||
let comma_pos: u64 = n;
|
||||
let scan_t: bool = true;
|
||||
for (scan_t) {
|
||||
if (q >= n) { scan_t = false; }
|
||||
else { if (line[q] == 44u8) { comma_pos = q; scan_t = false; }
|
||||
let commapos: u64 = n;
|
||||
let scant: bool = true;
|
||||
for (scant) {
|
||||
if (q >= n) { scant = false; }
|
||||
else { if (line[q] == 44u8) { commapos = q; scant = false; }
|
||||
else { q += 1u64; }; };
|
||||
};
|
||||
let to_op: *aoperand = pr.to;
|
||||
to_op.atype = D_EXTERN;
|
||||
to_op.asym = dupstr(a.a, line + r0, comma_pos - r0);
|
||||
if (comma_pos < n) {
|
||||
let p2: u64 = comma_pos + 1u64;
|
||||
let toop: *aoperand = pr.to;
|
||||
toop.atype = D_EXTERN;
|
||||
toop.asym = dupstr(a.a, line + r0, commapos - r0);
|
||||
if (commapos < n) {
|
||||
let p2: u64 = commapos + 1u64;
|
||||
p2 = skipws(line, p2, n);
|
||||
if (p2 < n) { if (line[p2] == 36u8) { p2 += 1u64; }; };
|
||||
let v: i64;
|
||||
let used: u64;
|
||||
v, used = parsenum(line + p2, n - p2);
|
||||
let from_op: *aoperand = pr.from;
|
||||
from_op.atype = D_CONST;
|
||||
from_op.offset = v;
|
||||
let fromop: *aoperand = pr.from;
|
||||
fromop.atype = D_CONST;
|
||||
fromop.offset = v;
|
||||
};
|
||||
a.line += 1; continue;
|
||||
};
|
||||
@@ -469,31 +469,31 @@ export fn parse(a: *asm_) i32 = {
|
||||
// DATA name(SB),"escaped bytes" — find first '(' as end of name.
|
||||
let q: u64 = r0;
|
||||
let lparen: u64 = n;
|
||||
let scan_d: bool = true;
|
||||
for (scan_d) {
|
||||
if (q >= n) { scan_d = false; }
|
||||
else { if (line[q] == 40u8) { lparen = q; scan_d = false; }
|
||||
let scand: bool = true;
|
||||
for (scand) {
|
||||
if (q >= n) { scand = false; }
|
||||
else { if (line[q] == 40u8) { lparen = q; scand = false; }
|
||||
else { q += 1u64; }; };
|
||||
};
|
||||
let to_op: *aoperand = pr.to;
|
||||
to_op.atype = D_EXTERN;
|
||||
to_op.asym = dupstr(a.a, line + r0, lparen - r0);
|
||||
let toop: *aoperand = pr.to;
|
||||
toop.atype = D_EXTERN;
|
||||
toop.asym = dupstr(a.a, line + r0, lparen - r0);
|
||||
// Skip past `(SB)` to land just after ')'.
|
||||
let p2: u64 = lparen;
|
||||
let scan_d2: bool = true;
|
||||
for (scan_d2) {
|
||||
if (p2 >= n) { scan_d2 = false; }
|
||||
else { if (line[p2] == 41u8) { p2 += 1u64; scan_d2 = false; }
|
||||
let scand2: bool = true;
|
||||
for (scand2) {
|
||||
if (p2 >= n) { scand2 = false; }
|
||||
else { if (line[p2] == 41u8) { p2 += 1u64; scand2 = false; }
|
||||
else { p2 += 1u64; }; };
|
||||
};
|
||||
// Skip ws / ',' / tab between `)` and the `"`.
|
||||
let scan_d3: bool = true;
|
||||
for (scan_d3) {
|
||||
if (p2 >= n) { scan_d3 = false; }
|
||||
let scand3: bool = true;
|
||||
for (scand3) {
|
||||
if (p2 >= n) { scand3 = false; }
|
||||
else { if (line[p2] == 32u8) { p2 += 1u64; }
|
||||
else { if (line[p2] == 44u8) { p2 += 1u64; }
|
||||
else { if (line[p2] == 9u8) { p2 += 1u64; }
|
||||
else { scan_d3 = false; }; }; }; };
|
||||
else { scand3 = false; }; }; }; };
|
||||
};
|
||||
if (p2 >= n) { perr(a, "DATA missing payload"); a.line += 1; continue; };
|
||||
if (line[p2] != 34u8) { perr(a, "DATA expects \"...\""); a.line += 1; continue; };
|
||||
|
||||
Reference in New Issue
Block a user