Beispiel #1
0
Datei: data.c Projekt: pipul/lab
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;
}
Beispiel #2
0
Datei: data.c Projekt: pipul/lab
void
dodata(void)
{
	int32 t, datsize;
	Section *sect, *noptr;
	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 > 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) {
		if(s->align != 0)
			datsize = rnd(datsize, s->align);
		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);
		if(s->align != 0)
			datsize = rnd(datsize, s->align);
		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 < SNOPTRDATA; s = s->next) {
		sect = addsection(&segdata, s->name, 06);
		if(s->align != 0)
			datsize = rnd(datsize, s->align);
		sect->vaddr = datsize;
		s->type = SDATA;
		s->value = datsize;
		datsize += rnd(s->size, PtrSize);
		sect->len = datsize - sect->vaddr;
	}
	
	/* pointer-free data, then data */
	sect = addsection(&segdata, ".noptrdata", 06);
	sect->vaddr = datsize;
	noptr = sect;
	for(; ; s = s->next) {
		if((s == nil || s->type >= SDATA) && sect == noptr) {
			// finish noptrdata, start data
			datsize = rnd(datsize, 8);
			sect->len = datsize - sect->vaddr;
			sect = addsection(&segdata, ".data", 06);
			sect->vaddr = datsize;
		}
		if(s == nil || s->type >= SBSS) {
			// finish data
			sect->len = datsize - sect->vaddr;
			break;
		}
		s->type = SDATA;
		t = s->size;
		if(t >= PtrSize)
			t = rnd(t, PtrSize);
		else if(t > 2)
			t = rnd(t, 4);
		if(s->align != 0)
			datsize = rnd(datsize, s->align);
		else 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;
	}

	/* bss, then pointer-free bss */
	noptr = nil;
	sect = addsection(&segdata, ".bss", 06);
	sect->vaddr = datsize;
	for(; ; s = s->next) {
		if((s == nil || s->type >= SNOPTRBSS) && noptr == nil) {
			// finish bss, start noptrbss
			datsize = rnd(datsize, 8);
			sect->len = datsize - sect->vaddr;
			sect = addsection(&segdata, ".noptrbss", 06);
			sect->vaddr = datsize;
			noptr = sect;
		}
		if(s == nil) {
			sect->len = datsize - sect->vaddr;
			break;
		}
		if(s->type > SNOPTRBSS) {
			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(s->align != 0)
			datsize = rnd(datsize, s->align);
		else 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;
	}
}
Beispiel #3
0
void
dodata(void)
{
	int32 t, 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("gcdata1", 0);
	gcdata1->type = SGCDATA;
	gcdata1->reachable = 1;
	gcbss1 = lookup("gcbss1", 0);
	gcbss1->type = SGCBSS;
	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.
	 */
	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 = datsort(datap);

	/*
	 * 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);
		if(s->align != 0)
			datsize = rnd(datsize, s->align);
		sect->vaddr = datsize;
		s->sect = sect;
		s->type = SDATA;
		s->value = datsize;
		datsize += rnd(s->size, PtrSize);
		sect->len = datsize - sect->vaddr;
	}

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

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

	/* data */
	sect = addsection(&segdata, ".data", 06);
	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;
		t = alignsymsize(s->size);
		datsize = aligndatsize(datsize, s);
		s->value = datsize;
		gcaddsym(gcdata1, s, datsize - sect->vaddr);  // gc
		datsize += t;
	}
	sect->len = datsize - sect->vaddr;
	datsize = rnd(datsize, PtrSize);

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

	/* bss */
	sect = addsection(&segdata, ".bss", 06);
	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;
		t = alignsymsize(s->size);
		datsize = aligndatsize(datsize, s);
		s->value = datsize;
		gcaddsym(gcbss1, s, datsize - sect->vaddr);  // gc
		datsize += t;
	}
	sect->len = datsize - sect->vaddr;
	datsize = rnd(datsize, PtrSize);

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

	/* pointer-free bss */
	sect = addsection(&segdata, ".noptrbss", 06);
	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);
		}
		s->sect = sect;
		t = alignsymsize(s->size);
		datsize = aligndatsize(datsize, s);
		s->value = datsize;
		datsize += t;
	}
	sect->len = datsize - sect->vaddr;
	lookup("end", 0)->sect = sect;

	/* we finished segdata, begin segtext */

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

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

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

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

	/* gosymtab */
	sect = addsection(&segtext, ".gosymtab", 04);
	sect->vaddr = datsize;
	lookup("symtab", 0)->sect = sect;
	lookup("esymtab", 0)->sect = sect;
	for(; s != nil && s->type < SPCLNTAB; s = s->next) {
		s->sect = sect;
		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;
	lookup("pclntab", 0)->sect = sect;
	lookup("epclntab", 0)->sect = sect;
	for(; s != nil && s->type < SELFROSECT; s = s->next) {
		s->sect = sect;
		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);
		if(s->align != 0)
			datsize = rnd(datsize, s->align);
		sect->vaddr = datsize;
		s->sect = sect;
		s->type = SRODATA;
		s->value = datsize;
		datsize += rnd(s->size, PtrSize);
		sect->len = datsize - sect->vaddr;
	}
}