Example #1
0
File: data.c Project: pipul/lab
vlong
addstring(Sym *s, char *str)
{
	int n;
	int32 r;

	if(s->type == 0)
		s->type = SNOPTRDATA;
	s->reachable = 1;
	r = s->size;
	n = strlen(str)+1;
	if(strcmp(s->name, ".shstrtab") == 0)
		elfsetstring(str, r);
	symgrow(s, r+n);
	memmove(s->p+r, str, n);
	s->size += n;
	return r;
}
Example #2
0
File: data.c Project: pipul/lab
vlong
addsize(Sym *s, Sym *t)
{
	vlong i;
	Reloc *r;

	if(s->type == 0)
		s->type = SDATA;
	s->reachable = 1;
	i = s->size;
	s->size += PtrSize;
	symgrow(s, s->size);
	r = addrel(s);
	r->sym = t;
	r->off = i;
	r->siz = PtrSize;
	r->type = D_SIZE;
	return i;
}
Example #3
0
File: data.c Project: pipul/lab
vlong
addpcrelplus(Sym *s, Sym *t, int32 add)
{
	vlong i;
	Reloc *r;
	
	if(s->type == 0)
		s->type = SDATA;
	s->reachable = 1;
	i = s->size;
	s->size += 4;
	symgrow(s, s->size);
	r = addrel(s);
	r->sym = t;
	r->off = i;
	r->add = add;
	r->type = D_PCREL;
	r->siz = 4;
	return i;
}
Example #4
0
File: data.c Project: pipul/lab
vlong
addaddrplus(Sym *s, Sym *t, int32 add)
{
	vlong i;
	Reloc *r;

	if(s->type == 0)
		s->type = SDATA;
	s->reachable = 1;
	i = s->size;
	s->size += PtrSize;
	symgrow(s, s->size);
	r = addrel(s);
	r->sym = t;
	r->off = i;
	r->siz = PtrSize;
	r->type = D_ADDR;
	r->add = add;
	return i;
}
Example #5
0
File: data.c Project: hfeeki/golang
vlong
setaddrplus(Sym *s, vlong off, Sym *t, int32 add)
{
	Reloc *r;

	if(s->type == 0)
		s->type = SDATA;
	s->reachable = 1;
	if(off+PtrSize > s->size) {
		s->size = off + PtrSize;
		symgrow(s, s->size);
	}
	r = addrel(s);
	r->sym = t;
	r->off = off;
	r->siz = PtrSize;
	r->type = D_ADDR;
	r->add = add;
	return off;
}
Example #6
0
File: data.c Project: pipul/lab
vlong
adduintxx(Sym *s, uint64 v, int wid)
{
	int32 i, r, fl;
	vlong o;
	uchar *cast;

	if(s->type == 0)
		s->type = SDATA;
	s->reachable = 1;
	r = s->size;
	s->size += wid;
	symgrow(s, s->size);
	assert(r+wid <= s->size);
	fl = v;
	cast = (uchar*)&fl;
	switch(wid) {
	case 1:
		s->p[r] = cast[inuxi1[0]];
		break;
	case 2:
		for(i=0; i<2; i++)
			s->p[r+i] = cast[inuxi2[i]];
		break;
	case 4:
		for(i=0; i<4; i++)
			s->p[r+i] = cast[inuxi4[i]];
		break;
	case 8:
		o = v;
		cast = (uchar*)&o;
		for(i=0; i<8; i++)
			s->p[r+i] = cast[inuxi8[i]];
		break;
	}
	return r;
}
Example #7
0
File: data.c Project: hfeeki/golang
vlong
setuintxx(Sym *s, vlong off, uint64 v, int wid)
{
	int32 i, fl;
	vlong o;
	uchar *cast;

	if(s->type == 0)
		s->type = SDATA;
	s->reachable = 1;
	if(s->size < off+wid) {
		s->size = off+wid;
		symgrow(s, s->size);
	}
	fl = v;
	cast = (uchar*)&fl;
	switch(wid) {
	case 1:
		s->p[off] = cast[inuxi1[0]];
		break;
	case 2:
		for(i=0; i<2; i++)
			s->p[off+i] = cast[inuxi2[i]];
		break;
	case 4:
		for(i=0; i<4; i++)
			s->p[off+i] = cast[inuxi4[i]];
		break;
	case 8:
		o = v;
		cast = (uchar*)&o;
		for(i=0; i<8; i++)
			s->p[off+i] = cast[inuxi8[i]];
		break;
	}
	return off;
}
Example #8
0
File: data.c Project: pipul/lab
void
savedata(Sym *s, Prog *p, char *pn)
{
	int32 off, siz, i, fl;
	uchar *cast;
	vlong o;
	Reloc *r;

	off = p->from.offset;
	siz = p->datasize;
	if(off < 0 || siz < 0 || off >= 1<<30 || siz >= 100)
		mangle(pn);
	symgrow(s, off+siz);

	switch(p->to.type) {
	default:
		diag("bad data: %P", p);
		break;

	case D_FCONST:
		switch(siz) {
		default:
		case 4:
			fl = ieeedtof(&p->to.ieee);
			cast = (uchar*)&fl;
			for(i=0; i<4; i++)
				s->p[off+i] = cast[fnuxi4[i]];
			break;
		case 8:
			cast = (uchar*)&p->to.ieee;
			for(i=0; i<8; i++)
				s->p[off+i] = cast[fnuxi8[i]];
			break;
		}
		break;
	
	case D_SCONST:
		for(i=0; i<siz; i++)
			s->p[off+i] = p->to.scon[i];
		break;
	
	case D_CONST:
		if(p->to.sym)
			goto Addr;
		o = p->to.offset;
		fl = o;
		cast = (uchar*)&fl;
		switch(siz) {
		default:
			diag("bad nuxi %d\n%P", siz, p);
			break;
		case 1:
			s->p[off] = cast[inuxi1[0]];
			break;
		case 2:
			for(i=0; i<2; i++)
				s->p[off+i] = cast[inuxi2[i]];
			break;
		case 4:
			for(i=0; i<4; i++)
				s->p[off+i] = cast[inuxi4[i]];
			break;
		case 8:
			cast = (uchar*)&o;
			for(i=0; i<8; i++)
				s->p[off+i] = cast[inuxi8[i]];
			break;
		}
		break;

	case D_ADDR:
	case D_SIZE:
	Addr:
		r = addrel(s);
		r->off = off;
		r->siz = siz;
		r->sym = p->to.sym;
		r->type = p->to.type;
		if(r->type != D_SIZE)
			r->type = D_ADDR;
		r->add = p->to.offset;
		break;
	}
}
Example #9
0
File: asm.c Project: timnau/golang
void
adddynsym(Sym *s)
{
    Sym *d, *str;
    int t;
    char *name;
    vlong off;

    if(s->dynid >= 0)
        return;

    if(s->dynimpname == nil)
        diag("adddynsym: no dynamic name for %s", s->name);

    if(iself) {
        s->dynid = nelfsym++;

        d = lookup(".dynsym", 0);

        /* name */
        name = s->dynimpname;
        if(name == nil)
            name = s->name;
        adduint32(d, addstring(lookup(".dynstr", 0), name));

        /* value */
        if(s->type == SDYNIMPORT)
            adduint32(d, 0);
        else
            addaddr(d, s);

        /* size */
        adduint32(d, 0);

        /* type */
        t = STB_GLOBAL << 4;
        if(s->dynexport && (s->type&SMASK) == STEXT)
            t |= STT_FUNC;
        else
            t |= STT_OBJECT;
        adduint8(d, t);
        adduint8(d, 0);

        /* shndx */
        if(!s->dynexport && s->dynimpname != nil)
            adduint16(d, SHN_UNDEF);
        else {
            switch(s->type) {
            default:
            case STEXT:
                t = 11;
                break;
            case SRODATA:
                t = 12;
                break;
            case SDATA:
                t = 13;
                break;
            case SBSS:
                t = 14;
                break;
            }
            adduint16(d, t);
        }
    } else if(HEADTYPE == Hdarwin) {
        // Mach-O symbol nlist32
        d = lookup(".dynsym", 0);
        name = s->dynimpname;
        if(name == nil)
            name = s->name;
        if(d->size == 0 && ndynexp > 0) { // pre-allocate for dynexps
            symgrow(d, ndynexp*12);
        }
        if(s->dynid <= -100) { // pre-allocated, see cmd/ld/go.c:^sortdynexp()
            s->dynid = -s->dynid-100;
            off = s->dynid*12;
        } else {
            off = d->size;
            s->dynid = off/12;
        }
        // darwin still puts _ prefixes on all C symbols
        str = lookup(".dynstr", 0);
        setuint32(d, off, str->size);
        off += 4;
        adduint8(str, '_');
        addstring(str, name);
        if(s->type == SDYNIMPORT) {
            setuint8(d, off, 0x01); // type - N_EXT - external symbol
            off++;
            setuint8(d, off, 0); // section
            off++;
        } else {
            setuint8(d, off, 0x0f);
            off++;
            switch(s->type) {
            default:
            case STEXT:
                setuint8(d, off, 1);
                break;
            case SDATA:
                setuint8(d, off, 2);
                break;
            case SBSS:
                setuint8(d, off, 4);
                break;
            }
            off++;
        }
        setuint16(d, off, 0); // desc
        off += 2;
        if(s->type == SDYNIMPORT)
            setuint32(d, off, 0); // value
        else
            setaddr(d, off, s);
        off += 4;
    } else if(HEADTYPE != Hwindows) {
        diag("adddynsym: unsupported binary format");
    }
}
Example #10
0
void
span1(Sym *s)
{
	Prog *p, *q;
	int32 c, v, loop;
	uchar *bp;
	int n, m, i;

	cursym = s;
	
	if(s->p != nil)
		return;

	for(p = s->text; p != P; p = p->link) {
		p->back = 2;	// use short branches first time through
		if((q = p->pcond) != P && (q->back & 2))
			p->back |= 1;	// backward jump

		if(p->as == AADJSP) {
			p->to.type = D_SP;
			v = -p->from.offset;
			p->from.offset = v;
			p->as = p->mode != 64? AADDL: AADDQ;
			if(v < 0) {
				p->as = p->mode != 64? ASUBL: ASUBQ;
				v = -v;
				p->from.offset = v;
			}
			if(v == 0)
				p->as = ANOP;
		}
	}
	
	n = 0;
	do {
		loop = 0;
		memset(s->r, 0, s->nr*sizeof s->r[0]);
		s->nr = 0;
		s->np = 0;
		c = 0;
		for(p = s->text; p != P; p = p->link) {
			p->pc = c;

			// process forward jumps to p
			for(q = p->comefrom; q != P; q = q->forwd) {
				v = p->pc - (q->pc + q->mark);
				if(q->back & 2)	{	// short
					if(v > 127) {
						loop++;
						q->back ^= 2;
					}
					if(q->as == AJCXZL)
						s->p[q->pc+2] = v;
					else
						s->p[q->pc+1] = v;
				} else {
					bp = s->p + q->pc + q->mark - 4;
					*bp++ = v;
					*bp++ = v>>8;
					*bp++ = v>>16;
					*bp = v>>24;
				}	
			}
			p->comefrom = P;

			asmins(p);
			p->pc = c;
			m = andptr-and;
			symgrow(s, p->pc+m);
			memmove(s->p+p->pc, and, m);
			p->mark = m;
			c += m;
		}
		if(++n > 20) {
			diag("span must be looping");
			errorexit();
		}
	} while(loop);
	s->size = c;

	if(debug['a'] > 1) {
		print("span1 %s %lld (%d tries)\n %.6ux", s->name, s->size, n, 0);
		for(i=0; i<s->np; i++) {
			print(" %.2ux", s->p[i]);
			if(i%16 == 15)
				print("\n  %.6ux", i+1);
		}
		if(i%16)
			print("\n");
	
		for(i=0; i<s->nr; i++) {
			Reloc *r;
			
			r = &s->r[i];
			print(" rel %#.4ux/%d %s%+lld\n", r->off, r->siz, r->sym->name, r->add);
		}
	}
}