void add_addr_to_list(struct nl_object *obj, void *data) { char buf[INET6_ADDRSTRLEN+5]; std::list<vaddress> *list = static_cast<std::list<vaddress>*>(data); struct nl_addr *naddr = rtnl_addr_get_local((struct rtnl_addr *) obj); int ifindex = 0; int scope = rtnl_addr_get_scope((struct rtnl_addr *) obj); if (scope == rtnl_str2scope("link")) ifindex = rtnl_addr_get_ifindex((struct rtnl_addr *) obj); if (naddr) { int family = nl_addr_get_family(naddr); nl_addr2str( naddr, buf, sizeof( buf ) ); vaddress vaddr(vaddress::Family(family), vaddress::strip_netmask(std::string(buf)), ifindex, false); list->push_back( vaddr ); } struct nl_addr *baddr = rtnl_addr_get_broadcast((struct rtnl_addr *) obj); if (baddr) { int family = nl_addr_get_family(baddr); nl_addr2str( baddr, buf, sizeof( buf ) ); vaddress vaddr(vaddress::Family(family), vaddress::strip_netmask(std::string(buf)), ifindex, true); list->push_back( vaddr ); } }
static void sysexec(void) { u32int name, argv, *argvt; char *namet, **argvv; int i, argc, rc; Segment *seg1, *seg2; name = arg(0); argv = arg(1); namet = strdup(vaddr(name, 0, &seg1)); segunlock(seg1); argvt = vaddr(argv, 0, &seg1); if(systrace) fprint(2, "exec(%#ux=\"%s\", %#ux)\n", name, namet, argv); for(argc = 0; argvt[argc]; argc++) ; argvv = emalloc(sizeof(char *) * argc); for(i = 0; i < argc; i++) { argvv[i] = strdup(vaddr(argvt[i], 0, &seg2)); segunlock(seg2); } segunlock(seg1); rc = loadtext(namet, argc, argvv); for(i = 0; i < argc; i++) free(argvv[i]); free(argvv); if(rc < 0) P->R[0] = noteerr(rc, 0); free(namet); }
void putmem_b(ulong addr, uchar data) { uchar *va; va = vaddr(addr); va += addr&(BY2PG-1); va[0] = data; if(membpt) brkchk(addr, Write); }
uchar getmem_b(ulong addr) { uchar *va; if(membpt) brkchk(addr, Read); va = vaddr(addr); va += addr&(BY2PG-1); return va[0]; }
static void syssemrelease(void) { u32int addr, count; long *addrt; Segment *seg; addr = arg(0); count = arg(1); if(systrace) fprint(2, "semrelease(%#ux, %ud)\n", addr, count); addrt = vaddr(addr, 4, &seg); P->R[0] = noteerr(semrelease(addrt, count), 0); segunlock(seg); }
static void relput4(Prog *p, Adr *a) { vlong v; Reloc rel, *r; v = vaddr(a, &rel); if(rel.siz != 0) { if(rel.siz != 4) diag("bad reloc"); r = addrel(cursym); *r = rel; r->off = p->pc + andptr - and; } put4(v); }
ushort getmem_h(ulong addr) { uchar *va; if(addr&1) { Bprint(bioout, "mem_address_not_aligned [load addr %.8lux]\n", addr); longjmp(errjmp, 0); } if(membpt) brkchk(addr, Read); va = vaddr(addr); va += addr&(BY2PG-1); return va[0]<<8 | va[1]; }
void putmem_h(ulong addr, short data) { uchar *va; if(addr&1) { Bprint(bioout, "mem_address_not_aligned [store addr %.8lux]\n", addr); longjmp(errjmp, 0); } va = vaddr(addr); va += addr&(BY2PG-1); va[0] = data>>8; va[1] = data; if(membpt) brkchk(addr, Write); }
static void sysseek(void) { u32int fd, type; vlong n, *ret; Segment *seg; ret = vaddr(arg(0), 8, &seg); fd = arg(1); n = argv(2); type = arg(4); if(systrace) fprint(2, "seek(%d, %lld, %d)\n", fd, n, type); *ret = seek(fd, n, type); if(*ret < 0) noteerr(0, 1); segunlock(seg); }
ulong ifetch(ulong addr) { uchar *va; ulong px; if(addr&3) { Bprint(bioout, "instruction_address_not_aligned [addr %.8lux]\n", addr); longjmp(errjmp, 0); } if(icache.on) updateicache(addr); va = vaddr(addr); px = (addr-textbase)/PROFGRAN; if(px < iprofsize) iprof[px]++; va += addr&(BY2PG-1); return va[0]<<24 | va[1]<<16 | va[2]<<8 | va[3]; }
void doasm(Prog *p) { Optab *o; Prog *q, pp; uchar *t; int z, op, ft, tt, breg; int32 v, pre; Reloc rel, *r; Adr *a; curp = p; // TODO pre = prefixof(&p->from); if(pre) *andptr++ = pre; pre = prefixof(&p->to); if(pre) *andptr++ = pre; if(p->ft == 0) p->ft = oclass(&p->from); if(p->tt == 0) p->tt = oclass(&p->to); ft = p->ft * Ymax; tt = p->tt * Ymax; o = &optab[p->as]; t = o->ytab; if(t == 0) { diag("asmins: noproto %P", p); return; } for(z=0; *t; z+=t[3],t+=4) if(ycover[ft+t[0]]) if(ycover[tt+t[1]]) goto found; goto domov; found: switch(o->prefix) { case Pq: /* 16 bit escape and opcode escape */ *andptr++ = Pe; *andptr++ = Pm; break; case Pf2: /* xmm opcode escape */ case Pf3: *andptr++ = o->prefix; *andptr++ = Pm; break; case Pm: /* opcode escape */ *andptr++ = Pm; break; case Pe: /* 16 bit escape */ *andptr++ = Pe; break; case Pb: /* botch */ break; } op = o->op[z]; switch(t[2]) { default: diag("asmins: unknown z %d %P", t[2], p); return; case Zpseudo: break; case Zlit: for(; op = o->op[z]; z++) *andptr++ = op; break; case Zlitm_r: for(; op = o->op[z]; z++) *andptr++ = op; asmand(&p->from, reg[p->to.type]); break; case Zm_r: *andptr++ = op; asmand(&p->from, reg[p->to.type]); break; case Zm2_r: *andptr++ = op; *andptr++ = o->op[z+1]; asmand(&p->from, reg[p->to.type]); break; case Zm_r_xm: mediaop(o, op, t[3], z); asmand(&p->from, reg[p->to.type]); break; case Zm_r_i_xm: mediaop(o, op, t[3], z); asmand(&p->from, reg[p->to.type]); *andptr++ = p->to.offset; break; case Zibm_r: while ((op = o->op[z++]) != 0) *andptr++ = op; asmand(&p->from, reg[p->to.type]); *andptr++ = p->to.offset; break; case Zaut_r: *andptr++ = 0x8d; /* leal */ if(p->from.type != D_ADDR) diag("asmins: Zaut sb type ADDR"); p->from.type = p->from.index; p->from.index = D_NONE; p->ft = 0; asmand(&p->from, reg[p->to.type]); p->from.index = p->from.type; p->from.type = D_ADDR; p->ft = 0; break; case Zm_o: *andptr++ = op; asmand(&p->from, o->op[z+1]); break; case Zr_m: *andptr++ = op; asmand(&p->to, reg[p->from.type]); break; case Zr_m_xm: mediaop(o, op, t[3], z); asmand(&p->to, reg[p->from.type]); break; case Zr_m_i_xm: mediaop(o, op, t[3], z); asmand(&p->to, reg[p->from.type]); *andptr++ = p->from.offset; break; case Zo_m: *andptr++ = op; asmand(&p->to, o->op[z+1]); break; case Zm_ibo: *andptr++ = op; asmand(&p->from, o->op[z+1]); *andptr++ = vaddr(&p->to, nil); break; case Zibo_m: *andptr++ = op; asmand(&p->to, o->op[z+1]); *andptr++ = vaddr(&p->from, nil); break; case Z_ib: case Zib_: if(t[2] == Zib_) a = &p->from; else a = &p->to; v = vaddr(a, nil); *andptr++ = op; *andptr++ = v; break; case Zib_rp: *andptr++ = op + reg[p->to.type]; *andptr++ = vaddr(&p->from, nil); break; case Zil_rp: *andptr++ = op + reg[p->to.type]; if(o->prefix == Pe) { v = vaddr(&p->from, nil); *andptr++ = v; *andptr++ = v>>8; } else
void asmand(Adr *a, int r) { int32 v; int t, scale; Reloc rel; v = a->offset; t = a->type; rel.siz = 0; if(a->index != D_NONE && a->index != D_FS && a->index != D_GS) { if(t < D_INDIR || t >= 2*D_INDIR) { switch(t) { default: goto bad; case D_STATIC: case D_EXTERN: t = D_NONE; v = vaddr(a, &rel); break; case D_AUTO: case D_PARAM: t = D_SP; break; } } else t -= D_INDIR; if(t == D_NONE) { *andptr++ = (0 << 6) | (4 << 0) | (r << 3); asmidx(a->scale, a->index, t); goto putrelv; } if(v == 0 && rel.siz == 0 && t != D_BP) { *andptr++ = (0 << 6) | (4 << 0) | (r << 3); asmidx(a->scale, a->index, t); return; } if(v >= -128 && v < 128 && rel.siz == 0) { *andptr++ = (1 << 6) | (4 << 0) | (r << 3); asmidx(a->scale, a->index, t); *andptr++ = v; return; } *andptr++ = (2 << 6) | (4 << 0) | (r << 3); asmidx(a->scale, a->index, t); goto putrelv; } if(t >= D_AL && t <= D_F7 || t >= D_X0 && t <= D_X7) { if(v) goto bad; *andptr++ = (3 << 6) | (reg[t] << 0) | (r << 3); return; } scale = a->scale; if(t < D_INDIR || t >= 2*D_INDIR) { switch(a->type) { default: goto bad; case D_STATIC: case D_EXTERN: t = D_NONE; v = vaddr(a, &rel); break; case D_AUTO: case D_PARAM: t = D_SP; break; } scale = 1; } else t -= D_INDIR; if(t == D_NONE || (D_CS <= t && t <= D_GS)) { *andptr++ = (0 << 6) | (5 << 0) | (r << 3); goto putrelv; } if(t == D_SP) { if(v == 0 && rel.siz == 0) { *andptr++ = (0 << 6) | (4 << 0) | (r << 3); asmidx(scale, D_NONE, t); return; } if(v >= -128 && v < 128 && rel.siz == 0) { *andptr++ = (1 << 6) | (4 << 0) | (r << 3); asmidx(scale, D_NONE, t); *andptr++ = v; return; } *andptr++ = (2 << 6) | (4 << 0) | (r << 3); asmidx(scale, D_NONE, t); goto putrelv; } if(t >= D_AX && t <= D_DI) { if(v == 0 && rel.siz == 0 && t != D_BP) { *andptr++ = (0 << 6) | (reg[t] << 0) | (r << 3); return; } if(v >= -128 && v < 128 && rel.siz == 0 && a->index != D_FS && a->index != D_GS) { andptr[0] = (1 << 6) | (reg[t] << 0) | (r << 3); andptr[1] = v; andptr += 2; return; } *andptr++ = (2 << 6) | (reg[t] << 0) | (r << 3); goto putrelv; } goto bad; putrelv: if(rel.siz != 0) { Reloc *r; if(rel.siz != 4) { diag("bad rel"); goto bad; } r = addrel(cursym); *r = rel; r->off = curp->pc + andptr - and; } else if(iself && linkmode == LinkExternal && istls(a) && HEADTYPE != Hopenbsd) { Reloc *r; Sym *s; r = addrel(cursym); r->off = curp->pc + andptr - and; r->add = a->offset-tlsoffset; r->xadd = r->add; r->siz = 4; r->type = D_TLS; s = lookup("runtime.tlsgm", 0); r->sym = s; r->xsym = s; v = 0; } put4(v); return; bad: diag("asmand: bad address %D", a); return; }
void asmand(Adr *a, int r) { int32 v; int t, scale; Reloc rel; v = a->offset; t = a->type; rel.siz = 0; if(a->index != D_NONE) { if(t < D_INDIR || t >= 2*D_INDIR) { switch(t) { default: goto bad; case D_STATIC: case D_EXTERN: t = D_NONE; v = vaddr(a, &rel); break; case D_AUTO: case D_PARAM: t = D_SP; break; } } else t -= D_INDIR; if(t == D_NONE) { *andptr++ = (0 << 6) | (4 << 0) | (r << 3); asmidx(a->scale, a->index, t); goto putrelv; } if(v == 0 && rel.siz == 0 && t != D_BP) { *andptr++ = (0 << 6) | (4 << 0) | (r << 3); asmidx(a->scale, a->index, t); return; } if(v >= -128 && v < 128 && rel.siz == 0) { *andptr++ = (1 << 6) | (4 << 0) | (r << 3); asmidx(a->scale, a->index, t); *andptr++ = v; return; } *andptr++ = (2 << 6) | (4 << 0) | (r << 3); asmidx(a->scale, a->index, t); goto putrelv; } if(t >= D_AL && t <= D_F7 || t >= D_X0 && t <= D_X7) { if(v) goto bad; *andptr++ = (3 << 6) | (reg[t] << 0) | (r << 3); return; } scale = a->scale; if(t < D_INDIR || t >= 2*D_INDIR) { switch(a->type) { default: goto bad; case D_STATIC: case D_EXTERN: t = D_NONE; v = vaddr(a, &rel); break; case D_AUTO: case D_PARAM: t = D_SP; break; } scale = 1; } else t -= D_INDIR; if(t == D_NONE || (D_CS <= t && t <= D_GS)) { *andptr++ = (0 << 6) | (5 << 0) | (r << 3); goto putrelv; } if(t == D_SP) { if(v == 0 && rel.siz == 0) { *andptr++ = (0 << 6) | (4 << 0) | (r << 3); asmidx(scale, D_NONE, t); return; } if(v >= -128 && v < 128 && rel.siz == 0) { *andptr++ = (1 << 6) | (4 << 0) | (r << 3); asmidx(scale, D_NONE, t); *andptr++ = v; return; } *andptr++ = (2 << 6) | (4 << 0) | (r << 3); asmidx(scale, D_NONE, t); goto putrelv; } if(t >= D_AX && t <= D_DI) { if(v == 0 && rel.siz == 0 && t != D_BP) { *andptr++ = (0 << 6) | (reg[t] << 0) | (r << 3); return; } if(v >= -128 && v < 128 && rel.siz == 0) { andptr[0] = (1 << 6) | (reg[t] << 0) | (r << 3); andptr[1] = v; andptr += 2; return; } *andptr++ = (2 << 6) | (reg[t] << 0) | (r << 3); goto putrelv; } goto bad; putrelv: if(rel.siz != 0) { Reloc *r; if(rel.siz != 4) { diag("bad rel"); goto bad; } r = addrel(cursym); *r = rel; r->off = curp->pc + andptr - and; } put4(v); return; bad: diag("asmand: bad address %D", a); return; }