711 lines · 11.5 KB · C
RawDownload
#include "lib9.h"#include "isa.h"#include "interp.h"#include "runt.h"#include "loadermod.h"#include "raise.h"#include <kernel.h> static uchar	Instmap[] = Loader_Inst_map;static Type*	Tinst;static uchar	Tdescmap[] = Loader_Typedesc_map;static Type*	Tdesc;static uchar	Tlinkmap[] = Loader_Link_map;static Type*	Tlink;static uchar	Importmap[] = Loader_Import_map;static Type*	Timport;static uchar	Exceptmap[] = Loader_Except_map;static Type*	Texcept;static uchar	Handlermap[] = Loader_Handler_map;static Type*	Thandler; voidloadermodinit(void){	sysinit();	builtinmod("$Loader", Loadermodtab, Loadermodlen);	Tinst = dtype(freeheap, sizeof(Loader_Inst), Instmap, sizeof(Instmap));	Tdesc = dtype(freeheap, sizeof(Loader_Typedesc), Tdescmap, sizeof(Tdescmap));	Tlink = dtype(freeheap, sizeof(Loader_Link), Tlinkmap, sizeof(Tlinkmap));	Timport = dtype(freeheap, sizeof(Loader_Import), Importmap, sizeof(Importmap));	Texcept = dtype(freeheap, sizeof(Loader_Except), Exceptmap, sizeof(Exceptmap));	Thandler = dtype(freeheap, sizeof(Loader_Handler), Handlermap, sizeof(Handlermap));} static voidbrunpatch(Loader_Inst *ip, Module *m){	switch(ip->op) {	case ICALL:	case IJMP:	case IBEQW:	case IBNEW:	case IBLTW:	case IBLEW:	case IBGTW:	case IBGEW:	case IBEQB:	case IBNEB:	case IBLTB:	case IBLEB:	case IBGTB:	case IBGEB:	case IBEQF:	case IBNEF:	case IBLTF:	case IBLEF:	case IBGTF:	case IBGEF:	case IBEQC:	case IBNEC:	case IBLTC:	case IBLEC:	case IBGTC:	case IBGEC:	case IBEQL:	case IBNEL:	case IBLTL:	case IBLEL:	case IBGTL:	case IBGEL:	case ISPAWN:		ip->dst = (Inst*)ip->dst - m->prog;		break;	}} voidLoader_ifetch(void *a){	Heap *h;	Array *ar;	Module *m;	Inst *i, *ie;	Loader_Inst *li;	F_Loader_ifetch *f; 	f = a;	destroy(*f->ret);	*f->ret = H; 	if(f->mp == H)		return;	m = f->mp->m;	if(m == H)		return;	if(m->compiled) {		kwerrstr("compiled module");		return;	} 	h = nheap(sizeof(Array)+m->nprog*sizeof(Loader_Inst));	h->t = &Tarray;	h->t->ref++;	ar = H2D(Array*, h);	ar->t = Tinst;	Tinst->ref++;	ar->len = m->nprog;	ar->root = H;	ar->data = (uchar*)ar+sizeof(Array); 	li = (Loader_Inst*)ar->data;	i = m->prog;	ie = i + m->nprog;	while(i < ie) {		li->op = i->op;		li->addr = i->add;		li->src = i->s.imm;		li->dst = i->d.imm;		li->mid = i->reg;		if(UDST(i->add) == AIMM)			brunpatch(li, m);		li++;		i++;	} 	*f->ret = ar;} voidLoader_link(void *a){	Link *p;	Heap *h;	Type **t;	int nlink;	Module *m;	Array *ar;	Loader_Link *ll;	F_Loader_link *f;		f = a;	destroy(*f->ret);	*f->ret = H; 	if(f->mp == H)		return;	m = f->mp->m;	if(m == H)		return; 	nlink = 0;	for(p = m->ext; p->name; p++)		nlink++; 	h = nheap(sizeof(Array)+nlink*sizeof(Loader_Link));	h->t = &Tarray;	h->t->ref++;	ar = H2D(Array*, h);	ar->t = Tlink;	Tlink->ref++;	ar->len = nlink;	ar->root = H;	ar->data = (uchar*)ar+sizeof(Array); 	ll = (Loader_Link*)ar->data;	for(p = m->ext; p->name; p++) {		ll->name = c2string(p->name, strlen(p->name));		ll->sig = p->sig;		if(m->prog == nil) {			ll->pc = -1;			ll->tdesc = -1;		} else {			ll->pc = p->u.pc - m->prog;			ll->tdesc = 0;			for(t = m->type; *t != p->frame; t++)				ll->tdesc++;		}		ll++;	} 	*f->ret = ar;} voidLoader_imports(void *a){	F_Loader_imports *f;	Import *i1, **i2;	Loader_Import *li;	Array *ar, **ai;	Module *m;	int nimports; 	f = a;	destroy(*f->ret);	*f->ret = H; 	if(f->mp == H)		return;	m = f->mp->m;	if(m == H)		return;	if (m->ldt == nil)		return; 	nimports = 0;	for(i2 = m->ldt; *i2 != nil; i2++){		nimports++;	} 	ar = H2D(Array*, heaparray(&Tptr, nimports));	ai = (Array**)ar->data; 	for(i2 = m->ldt; *i2 != nil; i2++){		nimports = 0;		for(i1 = *i2; i1->name != nil; i1++)			nimports++; 		*ai = H2D(Array*, heaparray(Timport, nimports));		li = (Loader_Import*)(*ai)->data;		for(i1 = *i2; i1->name != nil; i1++){			li->name = c2string(i1->name, strlen(i1->name));			li->sig = i1->sig;			li++;		}		ai++;	} 	*f->ret = ar;} voidLoader_setimports(void *fp){	F_Loader_setimports *f;	Loader_Import *li;	Import *i1, **i2;	Array **ar;	Module *m;	int i, j; 	f = fp; 	*f->ret = -1;	if(f->mp == H || f->imp == H)		return;	m = f->mp->m;	if(m == H)		return;	if(m->compiled) {		kwerrstr("compiled module");		return;	} 	// Free existing import table	if(m->ldt != nil){		for(i2 = m->ldt; *i2 != nil; i2++){			for(i1 = *i2; i1->name != nil; i1++)				free(i1->name);			free(*i2);		}		free(m->ldt);	} 	// And set the new one	m->ldt = (Import**)malloc((f->imp->len+1)*sizeof(Import*));	if(m->ldt == nil){		kwerrstr(exNomem);		return;	} 	ar = (Array**)f->imp->data;	for (i = 0; i < f->imp->len; i++){		if (ar[i] == H)			continue; 		m->ldt[i] = (Import*)malloc((ar[i]->len+1)*sizeof(Import));		if (m->ldt[i] == nil){			free(m->ldt);			kwerrstr(exNomem);			return;		} 		li = (Loader_Import*)ar[i]->data;		for (j = 0; j < ar[i]->len; j++){			m->ldt[i][j].name = strdup(string2c(li[j].name));			m->ldt[i][j].sig = li[j].sig;		}		// The end of links marker		m->ldt[i][ar[i]->len].name = nil;	} 	// Don't forget to say the world we now have ldt	m->rt |= HASLDT; 	*f->ret = 0;}  voidLoader_handlers(void *a){	F_Loader_handlers *f;	Handler *h;	Except *e;	Loader_Handler *hi;	Loader_Except *ei;	Array *ar, *ai;	Module *m;	int nhandlers;	int nexcepts; 	f = a;	destroy(*f->ret);	*f->ret = H; 	if (f->mp == H)		return;	m = f->mp->m;	if (m == H)		return;	if (m->htab == nil)		return; 	nhandlers = 0;	for(h = m->htab; h->etab != nil; h++)		nhandlers++;		ar = H2D(Array*, heaparray(Thandler, nhandlers));	hi = (Loader_Handler*)ar->data; 	for(h = m->htab; h->etab != nil; h++){		hi->pc1 = h->pc1;		hi->pc2 = h->pc2;		hi->eoff = h->eoff;		hi->tdesc = -1; 		nexcepts = 1;		for (e = h->etab; e->s != nil; e++)			nexcepts++; 		ai = H2D(Array*, heaparray(Texcept, nexcepts));		ei = (Loader_Except*)ai->data;		for (e = h->etab; e->s != nil; e++) {			ei->e = c2string(e->s, strlen(e->s));			ei->pc = e->pc;			ei++;		}		ei->e = H;		ei->pc = e->pc; 		hi->etab = ai;		hi++;	} 	*f->ret = ar;} voidLoader_sethandlers(void *fp){	F_Loader_sethandlers *f;	Handler *h;	Except *e;	Loader_Handler *hi;	Loader_Except *ei;	Array *ar, *ai;	Module *m;	int i, j; 	f = fp; 	*f->ret = -1;	if(f->mp == H || f->handlers == H)		return;	m = f->mp->m;	if(m == H)		return;	if(m->compiled) {		return;	} 	// Free existing handler table	if((m->rt & HASEXCEPT) && m->htab != nil){		for(h = m->htab; h->etab != nil; h++){			for(e = h->etab; e->s != nil; e++)				free(e->s);			free(h->etab);		}		free(m->htab);	} 	// And set the new one	m->htab = (Handler*)malloc((f->handlers->len+1)*sizeof(Handler));	if(m->htab == nil){		kwerrstr(exNomem);		return;	} 	h = m->htab;	hi = (Loader_Handler*)f->handlers->data;	for (i = 0; i < f->handlers->len; i++) {		h->pc1 = hi->pc1;		h->pc2 = hi->pc2;		h->eoff = hi->eoff;		h->t = nil;		if (hi->tdesc != -1)			h->t = m->type[hi->tdesc];		h->ne = 0; 		h->etab = malloc((hi->etab->len)*sizeof(Except));		if(h->etab == nil){			kwerrstr(exNomem);			return;		}		e = h->etab;		ei = (Loader_Except*)hi->etab->data;		for (j = 0; j < hi->etab->len; j++) {			e->s = nil;			if (ei->e != H)				e->s = strdup(string2c(ei->e));			e->pc = ei->pc;			ei++;			e++;		} 		hi++;		h++;	}	// The end of table marker	h->etab = nil; 	// Don't forget to say the world we now have ldt	m->rt |= HASEXCEPT; 	*f->ret = 0;} voidLoader_tdesc(void *a){	int i;	Heap *h;	Type *t;	Array *ar;	Module *m;	F_Loader_tdesc *f;	Loader_Typedesc *lt; 	f = a;	destroy(*f->ret);	*f->ret = H; 	if(f->mp == H)		return;	m = f->mp->m;	if(m == H)		return; 	h = nheap(sizeof(Array)+m->ntype*sizeof(Loader_Typedesc));	h->t = &Tarray;	h->t->ref++;	ar = H2D(Array*, h);	ar->t = Tdesc;	Tdesc->ref++;	ar->len = m->ntype;	ar->root = H;	ar->data = (uchar*)ar+sizeof(Array); 	lt = (Loader_Typedesc*)ar->data;	for(i = 0; i < m->ntype; i++) {		t = m->type[i];		lt->size = t->size;		lt->map = H;		if(t->np != 0)			lt->map = mem2array(t->map, t->np);		lt++;	} 	*f->ret = ar;} voidLoader_newmod(void *a){	Heap *h;	Module *m;	Array *ia;	Modlink *ml;	Inst *i, *ie;	Loader_Inst *li;	F_Loader_newmod *f; 	f = a;	destroy(*f->ret);	*f->ret = H; 	if(f->inst == H || f->data == H) {		kwerrstr("nil parameters");		return;

Lines 1–500 of 711.