⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 8prefix.c

📁 这是一个同样来自贝尔实验室的和UNIX有着渊源的操作系统, 其简洁的设计和实现易于我们学习和理解
💻 C
字号:
/* * Pre-resolve references inside an object file. * Mark such functions static so that linking with * other object files can't get at them. * Also rename "main". */#include <u.h>#include <libc.h>#include <bio.h>#include "/sys/src/cmd/8c/8.out.h"typedef struct Sym Sym;struct Sym{	char *name;	char *newname;	short type;	short version;	Sym *link;};typedef struct Obj Obj;struct Obj{	int fd;	int version;	uchar *bp;	uchar *ep;	char *name;};enum{	NHASH = 10007};Sym *hash[NHASH];int nsymbol;int renamemain = 1;Sym *xsym[256];int version = 1;Obj **obj;int nobj;Biobuf bout;char *prefix;int verbose;void *emalloc(ulong);Sym *lookup(char*, int);Obj *openobj(char*);void walkobj(Obj*, void (*fn)(int, Sym*, uchar*, int));void walkobjs(void (*fn)(int, Sym*, uchar*, int));void dump(int, Sym*, uchar*, int);void nop(int, Sym*, uchar*, int);void owrite(int, Sym*, uchar*, int);int zaddr(uchar*, Sym**);void renamesyms(int, Sym*, uchar*, int);voidusage(void){	fprint(2, "usage: 8prelink [-mv] prefix file.8...\n");	exits("usage");}voidmain(int argc, char **argv){	int i;	Obj *o;	ARGBEGIN{	case 'm':		renamemain = 0;		break;	case 'v':		verbose = 1;		break;	default:		usage();	}ARGEND		if(argc < 2)		usage();		prefix = argv[0];	argv++;	argc--;	nobj = argc;	obj = emalloc(nobj*sizeof obj[0]);	for(i=0; i<argc; i++)		obj[i] = openobj(argv[i]);	walkobjs(nop);	/* initialize symbol table */	if(verbose)		walkobjs(dump);	walkobjs(renamesyms);		for(i=0; i<nobj; i++){		o = obj[i];		seek(o->fd, 0, 0);		Binit(&bout, o->fd, OWRITE);		walkobj(o, owrite);		Bflush(&bout);	}	exits(0);}voidrenamesyms(int op, Sym *sym, uchar*, int){	if(sym && sym->version==0 && !sym->newname)	switch(op){	case AGLOBL:	case AINIT:	case ADATA:	case ATEXT:		if(!renamemain && strcmp(sym->name, "main") == 0)			break;		sym->newname = smprint("%s%s", prefix, sym->name);		break;	}	}voiddump(int op, Sym *sym, uchar*, int){	if(sym && sym->version==0)	switch(op){	case AGLOBL:	case AINIT:	case ADATA:	case ATEXT:		print("%s\n", sym->name);		break;	}	}voidnop(int, Sym*, uchar*, int){}voidowrite(int op, Sym *sym, uchar *p, int l){	switch(op){	case ASIGNAME:		Bwrite(&bout, p, 4);		p += 4;		l -= 4;	case ANAME:		if(sym->newname){			Bwrite(&bout, p, 4);			Bwrite(&bout, sym->newname, strlen(sym->newname)+1);			break;		}	default:		Bwrite(&bout, p, l);		break;	}}intzaddr(uchar *p, Sym **symp){	int c, t;		t = p[0];	c = 1;	if(t & T_INDEX)		c += 2;	if(t & T_OFFSET)		c += 4;	if(t & T_SYM){		if(symp)			*symp = xsym[p[c]];		c++;	}	if(t & T_FCONST)		c += 8;	else if(t & T_SCONST)		c += NSNAME;	if(t & T_TYPE)		c++;	return c;}void*emalloc(ulong n){	void *v;		v = mallocz(n, 1);	if(v == nil)		sysfatal("out of memory");	return v;}Sym*lookup(char *symb, int v){	Sym *s;	char *p;	long h;	int l, c;	h = v;	for(p=symb; c = *p; p++)		h = h+h+h + c;	l = (p - symb) + 1;	if(h < 0)		h = ~h;	h %= NHASH;	for(s = hash[h]; s != nil; s = s->link)		if(s->version == v)		if(memcmp(s->name, symb, l) == 0)			return s;	s = emalloc(sizeof *s);	s->name = emalloc(l + 1);	memmove(s->name, symb, l);	s->link = hash[h];	s->type = 0;	s->version = v;	hash[h] = s;	nsymbol++;	return s;}Obj*openobj(char *name){	Dir *d;	Obj *obj;		obj = emalloc(sizeof *obj);	obj->name = name;	obj->version = version++;	if((obj->fd = open(name, ORDWR)) < 0)		sysfatal("open %s: %r", name);	if((d = dirfstat(obj->fd)) == nil)		sysfatal("dirfstat: %r");	obj->bp = emalloc(d->length);	if(readn(obj->fd, obj->bp, d->length) != d->length)		sysfatal("read %s: %r", name);	obj->ep = obj->bp+d->length;	return obj;}voidwalkobjs(void (*fn)(int, Sym*, uchar*, int)){	int i;		for(i=0; i<nobj; i++)		walkobj(obj[i], fn);}voidwalkobj(Obj *obj, void (*fn)(int, Sym*, uchar*, int)){	int op, type;	Sym *sym;	uchar *p, *p0;	for(p=obj->bp; p+4<=obj->ep; ){		op = p[0] | (p[1]<<8);		if(op <= AXXX || op >= ALAST)			sysfatal("%s: opcode out of range - probably not a .8 file", obj->name);		p0 = p;		switch(op){		case ASIGNAME:			p += 4;	/* sign */		case ANAME:			type = p[2];			sym = lookup((char*)p+4, type==D_STATIC ? obj->version : 0);			xsym[p[3]] = sym;			p += 4+strlen(sym->name)+1;			fn(op, sym, p0, p-p0);			break;				default:			p += 6;			p += zaddr(p, &sym);			p += zaddr(p, nil);			fn(op, sym, p0, p-p0);			break;		}	}}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -