示例#1
0
文件: elf.c 项目: abustany/go
void
elfdynhash(void)
{
	Sym *s, *sy, *dynstr;
	int i, j, nbucket, b, nfile;
	uint32 hc, *chain, *buckets;
	int nsym;
	char *name;
	Elfaux **need;
	Elflib *needlib;
	Elflib *l;
	Elfaux *x;
	
	if(!iself)
		return;

	nsym = nelfsym;
	s = lookup(".hash", 0);
	s->type = SELFROSECT;
	s->reachable = 1;

	i = nsym;
	nbucket = 1;
	while(i > 0) {
		++nbucket;
		i >>= 1;
	}

	needlib = nil;
	need = malloc(nsym * sizeof need[0]);
	chain = malloc(nsym * sizeof chain[0]);
	buckets = malloc(nbucket * sizeof buckets[0]);
	if(need == nil || chain == nil || buckets == nil) {
		cursym = nil;
		diag("out of memory");
		errorexit();
	}
	memset(need, 0, nsym * sizeof need[0]);
	memset(chain, 0, nsym * sizeof chain[0]);
	memset(buckets, 0, nbucket * sizeof buckets[0]);
	for(sy=allsym; sy!=S; sy=sy->allsym) {
		if (sy->dynid <= 0)
			continue;

		if(sy->dynimpvers)
			need[sy->dynid] = addelflib(&needlib, sy->dynimplib, sy->dynimpvers);

		name = sy->extname;
		hc = elfhash((uchar*)name);

		b = hc % nbucket;
		chain[sy->dynid] = buckets[b];
		buckets[b] = sy->dynid;
	}

	adduint32(s, nbucket);
	adduint32(s, nsym);
	for(i = 0; i<nbucket; i++)
		adduint32(s, buckets[i]);
	for(i = 0; i<nsym; i++)
		adduint32(s, chain[i]);

	free(chain);
	free(buckets);
	
	// version symbols
	dynstr = lookup(".dynstr", 0);
	s = lookup(".gnu.version_r", 0);
	i = 2;
	nfile = 0;
	for(l=needlib; l; l=l->next) {
		nfile++;
		// header
		adduint16(s, 1);  // table version
		j = 0;
		for(x=l->aux; x; x=x->next)
			j++;
		adduint16(s, j);	// aux count
		adduint32(s, addstring(dynstr, l->file));  // file string offset
		adduint32(s, 16);  // offset from header to first aux
		if(l->next)
			adduint32(s, 16+j*16);  // offset from this header to next
		else
			adduint32(s, 0);
		
		for(x=l->aux; x; x=x->next) {
			x->num = i++;
			// aux struct
			adduint32(s, elfhash((uchar*)x->vers));  // hash
			adduint16(s, 0);  // flags
			adduint16(s, x->num);  // other - index we refer to this by
			adduint32(s, addstring(dynstr, x->vers));  // version string offset
			if(x->next)
				adduint32(s, 16);  // offset from this aux to next
			else
				adduint32(s, 0);
		}
	}

	// version references
	s = lookup(".gnu.version", 0);
	for(i=0; i<nsym; i++) {
		if(i == 0)
			adduint16(s, 0); // first entry - no symbol
		else if(need[i] == nil)
			adduint16(s, 1); // global
		else
			adduint16(s, need[i]->num);
	}

	free(need);

	s = lookup(".dynamic", 0);
	elfverneed = nfile;
	if(elfverneed) {
		elfwritedynentsym(s, DT_VERNEED, lookup(".gnu.version_r", 0));
		elfwritedynent(s, DT_VERNEEDNUM, nfile);
		elfwritedynentsym(s, DT_VERSYM, lookup(".gnu.version", 0));
	}
	elfwritedynent(s, DT_NULL, 0);
}
示例#2
0
文件: asm.c 项目: peterfyj/u12proj
void
doelf(void)
{
	Sym *s, *shstrtab, *dynstr;

	if(!iself)
		return;

	/* predefine strings we need for section headers */
	shstrtab = lookup(".shstrtab", 0);
	shstrtab->type = SELFDATA;
	shstrtab->reachable = 1;

	elfstr[ElfStrEmpty] = addstring(shstrtab, "");
	elfstr[ElfStrText] = addstring(shstrtab, ".text");
	elfstr[ElfStrData] = addstring(shstrtab, ".data");
	addstring(shstrtab, ".rodata");
	elfstr[ElfStrBss] = addstring(shstrtab, ".bss");
	if(!debug['s']) {	
		elfstr[ElfStrGosymcounts] = addstring(shstrtab, ".gosymcounts");
		elfstr[ElfStrGosymtab] = addstring(shstrtab, ".gosymtab");
		elfstr[ElfStrGopclntab] = addstring(shstrtab, ".gopclntab");
	}
	elfstr[ElfStrShstrtab] = addstring(shstrtab, ".shstrtab");

	if(!debug['d']) {	/* -d suppresses dynamic loader format */
		elfstr[ElfStrInterp] = addstring(shstrtab, ".interp");
		elfstr[ElfStrHash] = addstring(shstrtab, ".hash");
		elfstr[ElfStrGot] = addstring(shstrtab, ".got");
		elfstr[ElfStrGotPlt] = addstring(shstrtab, ".got.plt");
		elfstr[ElfStrDynamic] = addstring(shstrtab, ".dynamic");
		elfstr[ElfStrDynsym] = addstring(shstrtab, ".dynsym");
		elfstr[ElfStrDynstr] = addstring(shstrtab, ".dynstr");
		elfstr[ElfStrRel] = addstring(shstrtab, ".rel");
		elfstr[ElfStrRelPlt] = addstring(shstrtab, ".rel.plt");
		elfstr[ElfStrPlt] = addstring(shstrtab, ".plt");

		/* interpreter string */
		s = lookup(".interp", 0);
		s->reachable = 1;
		s->type = SELFDATA;	// TODO: rodata

		/* dynamic symbol table - first entry all zeros */
		s = lookup(".dynsym", 0);
		s->type = SELFDATA;
		s->reachable = 1;
		s->value += ELF32SYMSIZE;

		/* dynamic string table */
		s = lookup(".dynstr", 0);
		s->type = SELFDATA;
		s->reachable = 1;
		if(s->size == 0)
			addstring(s, "");
		dynstr = s;

		/* relocation table */
		s = lookup(".rel", 0);
		s->reachable = 1;
		s->type = SELFDATA;

		/* global offset table */
		s = lookup(".got", 0);
		s->reachable = 1;
		s->type = SELFDATA;
		
		/* hash */
		s = lookup(".hash", 0);
		s->reachable = 1;
		s->type = SELFDATA;

		/* got.plt */
		s = lookup(".got.plt", 0);
		s->reachable = 1;
		s->type = SDATA;	// writable, so not SELFDATA
		
		s = lookup(".plt", 0);
		s->reachable = 1;
		s->type = SELFDATA;

		s = lookup(".rel.plt", 0);
		s->reachable = 1;
		s->type = SELFDATA;
		
		elfsetupplt();

		/* define dynamic elf table */
		s = lookup(".dynamic", 0);
		s->reachable = 1;
		s->type = SELFDATA;

		/*
		 * .dynamic table
		 */
		elfwritedynentsym(s, DT_HASH, lookup(".hash", 0));
		elfwritedynentsym(s, DT_SYMTAB, lookup(".dynsym", 0));
		elfwritedynent(s, DT_SYMENT, ELF32SYMSIZE);
		elfwritedynentsym(s, DT_STRTAB, lookup(".dynstr", 0));
		elfwritedynentsymsize(s, DT_STRSZ, lookup(".dynstr", 0));
		elfwritedynentsym(s, DT_REL, lookup(".rel", 0));
		elfwritedynentsymsize(s, DT_RELSZ, lookup(".rel", 0));
		elfwritedynent(s, DT_RELENT, ELF32RELSIZE);
		if(rpath)
			elfwritedynent(s, DT_RUNPATH, addstring(dynstr, rpath));
		elfwritedynentsym(s, DT_PLTGOT, lookup(".got.plt", 0));
		elfwritedynent(s, DT_PLTREL, DT_REL);
		elfwritedynentsymsize(s, DT_PLTRELSZ, lookup(".rel.plt", 0));
		elfwritedynentsym(s, DT_JMPREL, lookup(".rel.plt", 0));
		elfwritedynent(s, DT_NULL, 0);
	}
}