Пример #1
0
	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 );
		}
	}
Пример #2
0
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);
}
Пример #3
0
void
putmem_b(ulong addr, uchar data)
{
	uchar *va;

	va = vaddr(addr);
	va += addr&(BY2PG-1);
	va[0] = data;
	if(membpt)
		brkchk(addr, Write);
}
Пример #4
0
uchar
getmem_b(ulong addr)
{
	uchar *va;

	if(membpt)
		brkchk(addr, Read);

	va = vaddr(addr);
	va += addr&(BY2PG-1);
	return va[0];
}
Пример #5
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);
}
Пример #6
0
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);
}
Пример #7
0
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];
}
Пример #8
0
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);
}
Пример #9
0
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);
}
Пример #10
0
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];
}
Пример #11
0
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
Пример #12
0
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;
}
Пример #13
0
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;
}