// Inferno utils/8l/asm.c
// http://code.google.com/p/inferno-os/source/browse/utils/8l/asm.c
//
//	Copyright © 1994-1999 Lucent Technologies Inc.  All rights reserved.
//	Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net)
//	Portions Copyright © 1997-1999 Vita Nuova Limited
//	Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com)
//	Portions Copyright © 2004,2006 Bruce Ellis
//	Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net)
//	Revisions Copyright © 2000-2007 Lucent Technologies Inc. and others
//	Portions Copyright © 2009 The Go Authors.  All rights reserved.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.

// Data layout and relocation.

#include	"l.h"
#include	"../ld/lib.h"
#include	"../ld/elf.h"
#include	"../ld/pe.h"

void	dynreloc(void);
static vlong addaddrplus4(Sym *s, Sym *t, int32 add);

/*
 * divide-and-conquer list-link
 * sort of Sym* structures.
 * Used for the data block.
 */
int
datcmp(Sym *s1, Sym *s2)
{
	if(s1->type != s2->type)
		return (int)s1->type - (int)s2->type;
	if(s1->size != s2->size) {
		if(s1->size < s2->size)
			return -1;
		return +1;
	}
	return strcmp(s1->name, s2->name);
}

Sym*
datsort(Sym *l)
{
	Sym *l1, *l2, *le;

	if(l == 0 || l->next == 0)
		return l;

	l1 = l;
	l2 = l;
	for(;;) {
		l2 = l2->next;
		if(l2 == 0)
			break;
		l2 = l2->next;
		if(l2 == 0)
			break;
		l1 = l1->next;
	}

	l2 = l1->next;
	l1->next = 0;
	l1 = datsort(l);
	l2 = datsort(l2);

	/* set up lead element */
	if(datcmp(l1, l2) < 0) {
		l = l1;
		l1 = l1->next;
	} else {
		l = l2;
		l2 = l2->next;
	}
	le = l;

	for(;;) {
		if(l1 == 0) {
			while(l2) {
				le->next = l2;
				le = l2;
				l2 = l2->next;
			}
			le->next = 0;
			break;
		}
		if(l2 == 0) {
			while(l1) {
				le->next = l1;
				le = l1;
				l1 = l1->next;
			}
			break;
		}
		if(datcmp(l1, l2) < 0) {
			le->next = l1;
			le = l1;
			l1 = l1->next;
		} else {
			le->next = l2;
			le = l2;
			l2 = l2->next;
		}
	}
	le->next = 0;
	return l;
}

Reloc*
addrel(Sym *s)
{
	if(s->nr >= s->maxr) {
		if(s->maxr == 0)
			s->maxr = 4;
		else
			s->maxr <<= 1;
		s->r = realloc(s->r, s->maxr*sizeof s->r[0]);
		if(s->r == 0) {
			diag("out of memory");
			errorexit();
		}
		memset(s->r+s->nr, 0, (s->maxr-s->nr)*sizeof s->r[0]);
	}
	return &s->r[s->nr++];
}

void
relocsym(Sym *s)
{
	Reloc *r;
	Prog p;
	int32 i, off, siz, fl;
	vlong o;
	uchar *cast;
	
	cursym = s;
	memset(&p, 0, sizeof p);
	for(r=s->r; r<s->r+s->nr; r++) {
		off = r->off;
		siz = r->siz;
		if(off < 0 || off+(siz&~Rbig) > s->np) {
			diag("%s: invalid relocation %d+%d not in [%d,%d)", s->name, off, siz&~Rbig, 0, s->np);
			continue;
		}
		if(r->sym != S && (r->sym->type == 0 || r->sym->type == SXREF)) {
			diag("%s: not defined", r->sym->name);
			continue;
		}
		if(r->type >= 256)
			continue;

		if(r->sym != S && r->sym->type == SDYNIMPORT)
			diag("unhandled relocation for %s (type %d rtype %d)", r->sym->name, r->sym->type, r->type);

		if(r->sym != S && !r->sym->reachable)
			diag("unreachable sym in relocation: %s %s", s->name, r->sym->name);

		switch(r->type) {
		default:
			o = 0;
			if(archreloc(r, s, &o) < 0)
				diag("unknown reloc %d", r->type);
			break;
		case D_ADDR:
			o = symaddr(r->sym) + r->add;
			break;
		case D_PCREL:
			o = symaddr(r->sym) + r->add - (s->value + r->off + r->siz);
			break;
		case D_SIZE:
			o = r->sym->size + r->add;
			break;
		}
//print("relocate %s %p %s => %p %p %p %p [%p]\n", s->name, s->value+off, r->sym ? r->sym->name : "<nil>", (void*)symaddr(r->sym), (void*)s->value, (void*)r->off, (void*)r->siz, (void*)o);
		switch(siz) {
		default:
			cursym = s;
			diag("bad reloc size %#ux for %s", siz, r->sym->name);
		case 4 + Rbig:
			fl = o;
			s->p[off] = fl>>24;
			s->p[off+1] = fl>>16;
			s->p[off+2] = fl>>8;
			s->p[off+3] = fl;
			break;
		case 4 + Rlittle:
			fl = o;
			s->p[off] = fl;
			s->p[off+1] = fl>>8;
			s->p[off+2] = fl>>16;
			s->p[off+3] = fl>>24;
			break;
		case 4:
			fl = o;
			cast = (uchar*)&fl;
			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;
		}		
	}
}

void
reloc(void)
{
	Sym *s;
	
	if(debug['v'])
		Bprint(&bso, "%5.2f reloc\n", cputime());
	Bflush(&bso);

	for(s=textp; s!=S; s=s->next)
		relocsym(s);
	for(s=datap; s!=S; s=s->next)
		relocsym(s);
}

void
dynrelocsym(Sym *s)
{
	Reloc *r;
	
	if(HEADTYPE == Hwindows) {
		Sym *rel, *targ;
		
		rel = lookup(".rel", 0);
		if(s == rel)
			return;
		for(r=s->r; r<s->r+s->nr; r++) {
			targ = r->sym;
			if(r->sym->plt == -2 && r->sym->got != -2) { // make dynimport JMP table for PE object files.
				targ->plt = rel->size;
				r->sym = rel;
				r->add = targ->plt;
				
				// jmp *addr
				if(thechar == '8') {
					adduint8(rel, 0xff);
					adduint8(rel, 0x25);
					addaddr(rel, targ);
					adduint8(rel, 0x90);
					adduint8(rel, 0x90);
				} else {
					adduint8(rel, 0xff);
					adduint8(rel, 0x24);
					adduint8(rel, 0x25);
					addaddrplus4(rel, targ, 0);
					adduint8(rel, 0x90);
				}
			} else if(r->sym->plt >= 0) {
				r->sym = rel;
				r->add = targ->plt;
			}
		}
		return;
	}

	for(r=s->r; r<s->r+s->nr; r++)
		if(r->sym->type == SDYNIMPORT || r->type >= 256)
			adddynrel(s, r);
}

void
dynreloc(void)
{
	Sym *s;
	
	// -d supresses dynamic loader format, so we may as well not
	// compute these sections or mark their symbols as reachable.
	if(debug['d'] && HEADTYPE != Hwindows)
		return;
	if(debug['v'])
		Bprint(&bso, "%5.2f reloc\n", cputime());
	Bflush(&bso);

	for(s=textp; s!=S; s=s->next)
		dynrelocsym(s);
	for(s=datap; s!=S; s=s->next)
		dynrelocsym(s);
	if(iself)
		elfdynhash();
}

void
symgrow(Sym *s, int32 siz)
{
	if(s->np >= siz)
		return;

	if(s->maxp < siz) {
		if(s->maxp == 0)
			s->maxp = 8;
		while(s->maxp < siz)
			s->maxp <<= 1;
		s->p = realloc(s->p, s->maxp);
		if(s->p == nil) {
			diag("out of memory");
			errorexit();
		}
		memset(s->p+s->np, 0, s->maxp-s->np);
	}
	s->np = siz;
}

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;
	}
}

static void
blk(Sym *allsym, int32 addr, int32 size)
{
	Sym *sym;
	int32 eaddr;
	uchar *p, *ep;

	for(sym = allsym; sym != nil; sym = sym->next)
		if(!(sym->type&SSUB) && sym->value >= addr)
			break;

	eaddr = addr+size;
	for(; sym != nil; sym = sym->next) {
		if(sym->type&SSUB)
			continue;
		if(sym->value >= eaddr)
			break;
		if(sym->value < addr) {
			diag("phase error: addr=%#llx but sym=%#llx type=%d", (vlong)addr, (vlong)sym->value, sym->type);
			errorexit();
		}
		cursym = sym;
		for(; addr < sym->value; addr++)
			cput(0);
		p = sym->p;
		ep = p + sym->np;
		while(p < ep)
			cput(*p++);
		addr += sym->np;
		for(; addr < sym->value+sym->size; addr++)
			cput(0);
		if(addr != sym->value+sym->size) {
			diag("phase error: addr=%#llx value+size=%#llx", (vlong)addr, (vlong)sym->value+sym->size);
			errorexit();
		}
	}
	
	for(; addr < eaddr; addr++)
		cput(0);
	cflush();
}
			
void
codeblk(int32 addr, int32 size)
{
	Sym *sym;
	int32 eaddr, n, epc;
	Prog *p;
	uchar *q;

	if(debug['a'])
		Bprint(&bso, "codeblk [%#x,%#x) at offset %#llx\n", addr, addr+size, cpos());

	blk(textp, addr, size);

	/* again for printing */
	if(!debug['a'])
		return;

	for(sym = textp; sym != nil; sym = sym->next) {
		if(!sym->reachable)
			continue;
		if(sym->value >= addr)
			break;
	}

	eaddr = addr + size;
	for(; sym != nil; sym = sym->next) {
		if(!sym->reachable)
			continue;
		if(sym->value >= eaddr)
			break;

		if(addr < sym->value) {
			Bprint(&bso, "%-20s %.8llux|", "_", (vlong)addr);
			for(; addr < sym->value; addr++)
				Bprint(&bso, " %.2ux", 0);
			Bprint(&bso, "\n");
		}
		p = sym->text;
		if(p == nil) {
			Bprint(&bso, "%.6llux\t%-20s | foreign text\n", (vlong)addr, sym->name);
			n = sym->size;
			q = sym->p;
			
			while(n >= 16) {
				Bprint(&bso, "%.6ux\t%-20.16I\n", addr, q);
				addr += 16;
				q += 16;
				n -= 16;
			}
			if(n > 0)
				Bprint(&bso, "%.6ux\t%-20.*I\n", addr, (int)n, q);
			addr += n;
			continue;
		}
			
		Bprint(&bso, "%.6llux\t%-20s | %P\n", (vlong)sym->value, sym->name, p);
		for(p = p->link; p != P; p = p->link) {
			if(p->link != P)
				epc = p->link->pc;
			else
				epc = sym->value + sym->size;
			Bprint(&bso, "%.6llux\t", (uvlong)p->pc);
			q = sym->p + p->pc - sym->value;
			n = epc - p->pc;
			Bprint(&bso, "%-20.*I | %P\n", (int)n, q, p);
			addr += n;
		}
	}

	if(addr < eaddr) {
		Bprint(&bso, "%-20s %.8llux|", "_", (vlong)addr);
		for(; addr < eaddr; addr++)
			Bprint(&bso, " %.2ux", 0);
	}
	Bflush(&bso);
}
			
void
datblk(int32 addr, int32 size)
{
	Sym *sym;
	int32 eaddr;
	uchar *p, *ep;

	if(debug['a'])
		Bprint(&bso, "datblk [%#x,%#x) at offset %#llx\n", addr, addr+size, cpos());

	blk(datap, addr, size);

	/* again for printing */
	if(!debug['a'])
		return;

	for(sym = datap; sym != nil; sym = sym->next)
		if(sym->value >= addr)
			break;

	eaddr = addr + size;
	for(; sym != nil; sym = sym->next) {
		if(sym->value >= eaddr)
			break;
		if(addr < sym->value) {
			Bprint(&bso, "%-20s %.8ux| 00 ...\n", "(pre-pad)", addr);
			addr = sym->value;
		}
		Bprint(&bso, "%-20s %.8ux|", sym->name, (uint)addr);
		p = sym->p;
		ep = p + sym->np;
		while(p < ep)
			Bprint(&bso, " %.2ux", *p++);
		addr += sym->np;
		for(; addr < sym->value+sym->size; addr++)
			Bprint(&bso, " %.2ux", 0);
		Bprint(&bso, "\n");
	}

	if(addr < eaddr)
		Bprint(&bso, "%-20s %.8ux| 00 ...\n", "(post-pad)", (uint)addr);
	Bprint(&bso, "%-20s %.8ux|\n", "", (uint)eaddr);
}

void
strnput(char *s, int n)
{
	for(; *s && n > 0; s++) {
		cput(*s);
		n--;
	}
	while(n > 0) {
		cput(0);
		n--;
	}
}

vlong
addstring(Sym *s, char *str)
{
	int n;
	int32 r;

	if(s->type == 0)
		s->type = SDATA;
	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;
}

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;
}

vlong
adduint8(Sym *s, uint8 v)
{
	return adduintxx(s, v, 1);
}

vlong
adduint16(Sym *s, uint16 v)
{
	return adduintxx(s, v, 2);
}

vlong
adduint32(Sym *s, uint32 v)
{
	return adduintxx(s, v, 4);
}

vlong
adduint64(Sym *s, uint64 v)
{
	return adduintxx(s, v, 8);
}

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;
}

static vlong
addaddrplus4(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->siz = 4;
	r->type = D_ADDR;
	r->add = add;
	return i;
}

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;
}

vlong
addaddr(Sym *s, Sym *t)
{
	return addaddrplus(s, t, 0);
}

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;
}

void
dodata(void)
{
	int32 t, datsize;
	Section *sect;
	Sym *s, *last, **l;

	if(debug['v'])
		Bprint(&bso, "%5.2f dodata\n", cputime());
	Bflush(&bso);

	last = nil;
	datap = nil;

	for(s=allsym; s!=S; s=s->allsym) {
		if(!s->reachable || s->special)
			continue;
		if(STEXT < s->type && s->type < SXREF) {
			if(last == nil)
				datap = s;
			else
				last->next = s;
			s->next = nil;
			last = s;
		}
	}

	for(s = datap; s != nil; s = s->next) {
		if(s->np > 0 && s->type == SBSS)
			s->type = SDATA;
		if(s->np > s->size)
			diag("%s: initialize bounds (%lld < %d)",
				s->name, (vlong)s->size, s->np);
	}
	
	/*
	 * now that we have the datap list, but before we start
	 * to assign addresses, record all the necessary
	 * dynamic relocations.  these will grow the relocation
	 * symbol, which is itself data.
	 */
	dynreloc();
	
	/* some symbols may no longer belong in datap (Mach-O) */
	for(l=&datap; (s=*l) != nil; ) {
		if(s->type <= STEXT || SXREF <= s->type)
			*l = s->next;
		else
			l = &s->next;
	}
	*l = nil;

	datap = datsort(datap);

	/*
	 * allocate data sections.  list is sorted by type,
	 * so we can just walk it for each piece we want to emit.
	 */

	/* read-only data */
	sect = addsection(&segtext, ".rodata", 04);
	sect->vaddr = 0;
	datsize = 0;
	s = datap;
	for(; s != nil && s->type < SSYMTAB; s = s->next) {
		s->type = SRODATA;
		s->value = datsize;
		datsize += rnd(s->size, PtrSize);
	}
	sect->len = datsize - sect->vaddr;

	/* gosymtab */
	sect = addsection(&segtext, ".gosymtab", 04);
	sect->vaddr = datsize;
	for(; s != nil && s->type < SPCLNTAB; s = s->next) {
		s->type = SRODATA;
		s->value = datsize;
		datsize += s->size;
	}
	sect->len = datsize - sect->vaddr;
	datsize = rnd(datsize, PtrSize);

	/* gopclntab */
	sect = addsection(&segtext, ".gopclntab", 04);
	sect->vaddr = datsize;
	for(; s != nil && s->type < SELFROSECT; s = s->next) {
		s->type = SRODATA;
		s->value = datsize;
		datsize += s->size;
	}
	sect->len = datsize - sect->vaddr;
	datsize = rnd(datsize, PtrSize);

	/* read-only ELF sections */
	for(; s != nil && s->type < SELFSECT; s = s->next) {
		sect = addsection(&segtext, s->name, 04);
		sect->vaddr = datsize;
		s->type = SRODATA;
		s->value = datsize;
		datsize += rnd(s->size, PtrSize);
		sect->len = datsize - sect->vaddr;
	}

	/* writable ELF sections */
	datsize = 0;
	for(; s != nil && s->type < SDATA; s = s->next) {
		sect = addsection(&segdata, s->name, 06);
		sect->vaddr = datsize;
		s->type = SDATA;
		s->value = datsize;
		datsize += rnd(s->size, PtrSize);
		sect->len = datsize - sect->vaddr;
	}

	/* data */
	sect = addsection(&segdata, ".data", 06);
	sect->vaddr = datsize;
	for(; s != nil && s->type < SBSS; s = s->next) {
		s->type = SDATA;
		t = s->size;
		if(t == 0 && s->name[0] != '.') {
			diag("%s: no size", s->name);
			t = 1;
		}
		if(t >= PtrSize)
			t = rnd(t, PtrSize);
		else if(t > 2)
			t = rnd(t, 4);
		if(t & 1) {
			;
		} else if(t & 2)
			datsize = rnd(datsize, 2);
		else if(t & 4)
			datsize = rnd(datsize, 4);
		else
			datsize = rnd(datsize, 8);
		s->value = datsize;
		datsize += t;
	}
	sect->len = datsize - sect->vaddr;

	/* bss */
	sect = addsection(&segdata, ".bss", 06);
	sect->vaddr = datsize;
	for(; s != nil; s = s->next) {
		if(s->type != SBSS) {
			cursym = s;
			diag("unexpected symbol type %d", s->type);
		}
		t = s->size;
		if(t >= PtrSize)
			t = rnd(t, PtrSize);
		else if(t > 2)
			t = rnd(t, 4);
		if(t & 1) {
			;
		} else if(t & 2)
			datsize = rnd(datsize, 2);
		else if(t & 4)
			datsize = rnd(datsize, 4);
		else
			datsize = rnd(datsize, 8);
		s->value = datsize;
		datsize += t;
	}
	sect->len = datsize - sect->vaddr;
}

// assign addresses to text
void
textaddress(void)
{
	uvlong va;
	Prog *p;
	Section *sect;
	Sym *sym, *sub;

	addsection(&segtext, ".text", 05);

	// Assign PCs in text segment.
	// Could parallelize, by assigning to text 
	// and then letting threads copy down, but probably not worth it.
	sect = segtext.sect;
	va = INITTEXT;
	sect->vaddr = va;
	for(sym = textp; sym != nil; sym = sym->next) {
		if(sym->type & SSUB)
			continue;
		sym->value = 0;
		for(sub = sym; sub != S; sub = sub->sub) {
			sub->value += va;
			for(p = sub->text; p != P; p = p->link)
				p->pc += sub->value;
		}
		if(sym->size == 0 && sym->sub != S) {
			cursym = sym;
		}
		va += sym->size;
	}
	sect->len = va - sect->vaddr;
}

// assign addresses
void
address(void)
{
	Section *s, *text, *data, *rodata, *symtab, *pclntab;
	Sym *sym, *sub;
	uvlong va;

	va = INITTEXT;
	segtext.rwx = 05;
	segtext.vaddr = va;
	segtext.fileoff = HEADR;
	for(s=segtext.sect; s != nil; s=s->next) {
		s->vaddr = va;
		va += rnd(s->len, PtrSize);
	}
	segtext.len = va - INITTEXT;
	segtext.filelen = segtext.len;

	va = rnd(va, INITRND);

	segdata.rwx = 06;
	segdata.vaddr = va;
	segdata.fileoff = va - segtext.vaddr + segtext.fileoff;
	segdata.filelen = 0;
	if(HEADTYPE == Hwindows)
		segdata.fileoff = segtext.fileoff + rnd(segtext.len, PEFILEALIGN);
	if(HEADTYPE == Hplan9x32)
		segdata.fileoff = segtext.fileoff + segtext.filelen;
	data = nil;
	for(s=segdata.sect; s != nil; s=s->next) {
		s->vaddr = va;
		va += s->len;
		segdata.filelen += s->len;
		segdata.len = va - segdata.vaddr;
		if(strcmp(s->name, ".data") == 0)
			data = s;
	}
	segdata.filelen -= data->next->len; // deduct .bss

	text = segtext.sect;
	rodata = text->next;
	symtab = rodata->next;
	pclntab = symtab->next;

	for(sym = datap; sym != nil; sym = sym->next) {
		cursym = sym;
		if(sym->type < SDATA)
			sym->value += rodata->vaddr;
		else
			sym->value += segdata.sect->vaddr;
		for(sub = sym->sub; sub != nil; sub = sub->sub)
			sub->value += sym->value;
	}
	
	xdefine("text", STEXT, text->vaddr);
	xdefine("etext", STEXT, text->vaddr + text->len);
	xdefine("rodata", SRODATA, rodata->vaddr);
	xdefine("erodata", SRODATA, rodata->vaddr + rodata->len);
	xdefine("symtab", SRODATA, symtab->vaddr);
	xdefine("esymtab", SRODATA, symtab->vaddr + symtab->len);
	xdefine("pclntab", SRODATA, pclntab->vaddr);
	xdefine("epclntab", SRODATA, pclntab->vaddr + pclntab->len);
	xdefine("data", SBSS, data->vaddr);
	xdefine("edata", SBSS, data->vaddr + data->len);
	xdefine("end", SBSS, segdata.vaddr + segdata.len);
}
