Exemple #1
0
vlong
adduintxx(Sym *s, uint64 v, int wid)
{
	int32 off;

	off = s->size;
	setuintxx(s, off, v, wid);
	return off;
}
Exemple #2
0
int
duintxx(Sym *s, int off, uint64 v, int wid)
{
	// Update symbol data directly instead of generating a
	// DATA instruction that liblink will have to interpret later.
	// This reduces compilation time and memory usage.
	off = rnd(off, wid);
	return setuintxx(ctxt, linksym(s), off, v, wid);
}
Exemple #3
0
void
setuint64(Sym *s, vlong r, uint64 v)
{
	setuintxx(s, r, v, 8);
}
Exemple #4
0
void
setuint32(Sym *s, vlong r, uint32 v)
{
	setuintxx(s, r, v, 4);
}
Exemple #5
0
void
setuint16(Sym *s, vlong r, uint16 v)
{
	setuintxx(s, r, v, 2);
}
Exemple #6
0
void
setuint8(Sym *s, vlong r, uint8 v)
{
	setuintxx(s, r, v, 1);
}
Exemple #7
0
void
dodata(void)
{
	int32 n, datsize;
	Section *sect;
	Sym *s, *last, **l;
	Sym *gcdata1, *gcbss1;

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

	// define garbage collection symbols
	gcdata1 = lookup("gcdata", 0);
	gcdata1->type = STYPE;
	gcdata1->reachable = 1;
	gcbss1 = lookup("gcbss", 0);
	gcbss1->type = STYPE;
	gcbss1->reachable = 1;

	// size of .data and .bss section. the zero value is later replaced by the actual size of the section.
	adduintxx(gcdata1, 0, PtrSize);
	adduintxx(gcbss1, 0, PtrSize);

	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 > 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.
	 *
	 * on darwin, we need the symbol table numbers for dynreloc.
	 */
	if(HEADTYPE == Hdarwin)
		machosymorder();
	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;

	if(flag_shared) {
		for(s=datap; s != nil; s = s->next) {
			if(s->rel_ro)
				s->type = SDATARELRO;
		}
	}
	datap = listsort(datap, datcmp, offsetof(Sym, next));

	/*
	 * allocate sections.  list is sorted by type,
	 * so we can just walk it for each piece we want to emit.
	 * segdata is processed before segtext, because we need
	 * to see all symbols in the .data and .bss sections in order
	 * to generate garbage collection information.
	 */

	/* begin segdata */

	/* skip symbols belonging to segtext */
	s = datap;
	for(; s != nil && s->type < SELFSECT; s = s->next)
		;

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

	/* pointer-free data */
	sect = addsection(&segdata, ".noptrdata", 06);
	sect->align = maxalign(s, SDATARELRO-1);
	datsize = rnd(datsize, sect->align);
	sect->vaddr = datsize;
	lookup("noptrdata", 0)->sect = sect;
	lookup("enoptrdata", 0)->sect = sect;
	for(; s != nil && s->type < SDATARELRO; s = s->next) {
		datsize = aligndatsize(datsize, s);
		s->sect = sect;
		s->type = SDATA;
		s->value = datsize;
		datsize += s->size;
	}
	sect->len = datsize - sect->vaddr;

	/* dynamic relocated rodata */
	if(flag_shared) {
		sect = addsection(&segdata, ".data.rel.ro", 06);
		sect->align = maxalign(s, SDATARELRO);
		datsize = rnd(datsize, sect->align);
		sect->vaddr = datsize;
		lookup("datarelro", 0)->sect = sect;
		lookup("edatarelro", 0)->sect = sect;
		for(; s != nil && s->type == SDATARELRO; s = s->next) {
			datsize = aligndatsize(datsize, s);
			s->sect = sect;
			s->type = SDATA;
			s->value = datsize;
			datsize += s->size;
		}
		sect->len = datsize - sect->vaddr;
	}

	/* data */
	sect = addsection(&segdata, ".data", 06);
	sect->align = maxalign(s, SBSS-1);
	datsize = rnd(datsize, sect->align);
	sect->vaddr = datsize;
	lookup("data", 0)->sect = sect;
	lookup("edata", 0)->sect = sect;
	for(; s != nil && s->type < SBSS; s = s->next) {
		if(s->type == SDATARELRO) {
			cursym = s;
			diag("unexpected symbol type %d", s->type);
		}
		s->sect = sect;
		s->type = SDATA;
		datsize = aligndatsize(datsize, s);
		s->value = datsize;
		gcaddsym(gcdata1, s, datsize - sect->vaddr);  // gc
		datsize += s->size;
	}
	sect->len = datsize - sect->vaddr;

	adduintxx(gcdata1, GC_END, PtrSize);
	setuintxx(gcdata1, 0, sect->len, PtrSize);

	/* bss */
	sect = addsection(&segdata, ".bss", 06);
	sect->align = maxalign(s, SNOPTRBSS-1);
	datsize = rnd(datsize, sect->align);
	sect->vaddr = datsize;
	lookup("bss", 0)->sect = sect;
	lookup("ebss", 0)->sect = sect;
	for(; s != nil && s->type < SNOPTRBSS; s = s->next) {
		s->sect = sect;
		datsize = aligndatsize(datsize, s);
		s->value = datsize;
		gcaddsym(gcbss1, s, datsize - sect->vaddr);  // gc
		datsize += s->size;
	}
	sect->len = datsize - sect->vaddr;

	adduintxx(gcbss1, GC_END, PtrSize);
	setuintxx(gcbss1, 0, sect->len, PtrSize);

	/* pointer-free bss */
	sect = addsection(&segdata, ".noptrbss", 06);
	sect->align = maxalign(s, SNOPTRBSS);
	datsize = rnd(datsize, sect->align);
	sect->vaddr = datsize;
	lookup("noptrbss", 0)->sect = sect;
	lookup("enoptrbss", 0)->sect = sect;
	for(; s != nil; s = s->next) {
		if(s->type > SNOPTRBSS) {
			cursym = s;
			diag("unexpected symbol type %d", s->type);
		}
		datsize = aligndatsize(datsize, s);
		s->sect = sect;
		s->value = datsize;
		datsize += s->size;
	}
	sect->len = datsize - sect->vaddr;
	lookup("end", 0)->sect = sect;

	/* we finished segdata, begin segtext */
	s = datap;
	datsize = 0;

	/* read-only data */
	sect = addsection(&segtext, ".rodata", 04);
	sect->align = maxalign(s, STYPELINK-1);
	sect->vaddr = 0;
	lookup("rodata", 0)->sect = sect;
	lookup("erodata", 0)->sect = sect;
	datsize = 0;
	for(; s != nil && s->type < STYPELINK; s = s->next) {
		datsize = aligndatsize(datsize, s);
		s->sect = sect;
		s->type = SRODATA;
		s->value = datsize;
		datsize += s->size;
	}
	sect->len = datsize - sect->vaddr;

	/* typelink */
	sect = addsection(&segtext, ".typelink", 04);
	sect->align = maxalign(s, STYPELINK);
	datsize = rnd(datsize, sect->align);
	sect->vaddr = datsize;
	lookup("typelink", 0)->sect = sect;
	lookup("etypelink", 0)->sect = sect;
	for(; s != nil && s->type == STYPELINK; s = s->next) {
		datsize = aligndatsize(datsize, s);
		s->sect = sect;
		s->type = SRODATA;
		s->value = datsize;
		datsize += s->size;
	}
	sect->len = datsize - sect->vaddr;

	/* gosymtab */
	sect = addsection(&segtext, ".gosymtab", 04);
	sect->align = maxalign(s, SPCLNTAB-1);
	datsize = rnd(datsize, sect->align);
	sect->vaddr = datsize;
	lookup("symtab", 0)->sect = sect;
	lookup("esymtab", 0)->sect = sect;
	for(; s != nil && s->type < SPCLNTAB; s = s->next) {
		datsize = aligndatsize(datsize, s);
		s->sect = sect;
		s->type = SRODATA;
		s->value = datsize;
		datsize += s->size;
	}
	sect->len = datsize - sect->vaddr;

	/* gopclntab */
	sect = addsection(&segtext, ".gopclntab", 04);
	sect->align = maxalign(s, SELFROSECT-1);
	datsize = rnd(datsize, sect->align);
	sect->vaddr = datsize;
	lookup("pclntab", 0)->sect = sect;
	lookup("epclntab", 0)->sect = sect;
	for(; s != nil && s->type < SELFROSECT; s = s->next) {
		datsize = aligndatsize(datsize, s);
		s->sect = sect;
		s->type = SRODATA;
		s->value = datsize;
		datsize += s->size;
	}
	sect->len = datsize - sect->vaddr;

	/* read-only ELF, Mach-O sections */
	for(; s != nil && s->type < SELFSECT; s = s->next) {
		sect = addsection(&segtext, s->name, 04);
		sect->align = symalign(s);
		datsize = rnd(datsize, sect->align);
		sect->vaddr = datsize;
		s->sect = sect;
		s->type = SRODATA;
		s->value = datsize;
		datsize += s->size;
		sect->len = datsize - sect->vaddr;
	}
	
	/* number the sections */
	n = 1;
	for(sect = segtext.sect; sect != nil; sect = sect->next)
		sect->extnum = n++;
	for(sect = segdata.sect; sect != nil; sect = sect->next)
		sect->extnum = n++;
}