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

📄 outieee.c

📁 开源的nasm编译器源码,研究编译器原理很有帮且
💻 C
📖 第 1 页 / 共 3 页
字号:
	    if (pub->type >= 0x100)	    	ieee_putascii("ATI%X,T%X.\r\n", i, pub->type - 0x100);	    else	    	ieee_putascii("ATI%X,%X.\r\n", i, pub->type);	} 	i++;        pub = pub->next;    }    /*     * Write the externals     */    ext = exthead;    i = 1;    while (ext) {	char buf[256];	ieee_unqualified_name(buf,ext->name);       	ieee_putascii("NX%X,%02X%s.\r\n",i++, strlen(buf), buf);        ext = ext->next;    }    ieee_putcs(FALSE);    /*     * IEEE doesn't have a standard pass break record     * so use the ladsoft variant     */    ieee_putascii("CO100,06ENDSYM.\r\n");    /*     * now put types     */    i = ARRAY_BOT;    for (arr = arrhead; arr && debuginfo; arr = arr->next) {	ieee_putascii("TY%X,20,%X,%lX.\r\n",i++,arr->basetype,arr->size);    }    /*     * now put locals     */    i = 1;    for (seg = seghead; seg && debuginfo; seg = seg->next) {        for (loc = seg->lochead; loc; loc = loc->next) {	    char buf[256];	    ieee_unqualified_name(buf,loc->name);       	    ieee_putascii("NN%X,%02X%s.\r\n",i, strlen(buf), buf);	    if (loc->segment == -1)         	    	ieee_putascii("ASN%X,R%X,%lX,+.\r\n", i, loc->index,loc->offset);	    else       	    	ieee_putascii("ASN%X,%lX,%lX,+.\r\n", i, loc->segment*16,loc->offset);	    if (debuginfo) {		if (loc->type >= 0x100)	 	    ieee_putascii("ATN%X,T%X.\r\n", i, loc->type - 0x100);		else	    	    ieee_putascii("ATN%X,%X.\r\n", i, loc->type);	    } 	    i++;        }    }    /*     *  put out section data;     */     seg = seghead;    if (!debuginfo && !strcmp(seg->name,"??LINE"))	seg = seg->next;    while (seg) {	if (seg->currentpos) {	    long size,org = 0;	    data = seg->data;	    ieee_putascii("SB%X.\r\n",seg->ieee_index);	    fix = seg->fptr;	    while (fix) {		size = HUNKSIZE - (org %HUNKSIZE);		size = size +org > seg->currentpos ? seg->currentpos-org : size;		size = fix->offset - org > size ? size : fix->offset-org;		org = ieee_putld(org,org+size,data->data);		if (org % HUNKSIZE == 0)		    data = data->next;		if (org == fix->offset) {		    org += ieee_putlr(fix);		    fix = fix->next;		}	    }	    while (org < seg->currentpos && data) {		size = seg->currentpos-org > HUNKSIZE ? HUNKSIZE : seg->currentpos - org;		org = ieee_putld(org,org+size,data->data);		data = data->next;	    }	    ieee_putcs(FALSE);			}	seg = seg->next;    }    /*     * module end record     */    ieee_putascii("ME.\r\n");}static void ieee_write_byte(struct ieeeSection *seg, int data) {    int temp;    if (!(temp = seg->currentpos++ % HUNKSIZE))	ieee_data_new(seg);    seg->datacurr->data[temp] = data;}static void ieee_write_word(struct ieeeSection *seg, int data) {    ieee_write_byte(seg, data & 0xFF);    ieee_write_byte(seg,(data >> 8) & 0xFF);}static void ieee_write_dword(struct ieeeSection *seg, long data) {    ieee_write_byte(seg, data & 0xFF);    ieee_write_byte(seg,(data >> 8) & 0xFF);    ieee_write_byte(seg,(data >> 16) & 0xFF);    ieee_write_byte(seg,(data >> 24) & 0xFF);}static void ieee_putascii(char *format, ...){	char buffer[256];	int i,l;	va_list ap;	va_start(ap, format);	vsprintf(buffer, format, ap);	l = strlen(buffer);	for (i=0; i < l; i++)		if ((buffer[i] & 0xff) > 31)			checksum+=buffer[i];	va_end(ap);	fprintf(ofp,buffer);}/* * put out a checksum record */static void ieee_putcs(int toclear){	if (toclear) {		ieee_putascii("CS.\r\n");	}	else {		checksum += 'C';		checksum += 'S';		ieee_putascii("CS%02X.\r\n",checksum & 127);	}	checksum = 0;}static long ieee_putld(long start, long end, unsigned char *buf){	long val;	if (start == end)		return(start);	val = start % HUNKSIZE;	/* fill up multiple lines */	while (end - start >= LDPERLINE) {		int i;		ieee_putascii("LD");		for (i=0; i < LDPERLINE; i++) {			ieee_putascii("%02X",buf[val++]);			start++;		}		ieee_putascii(".\r\n");	}	/* if no partial lines */	if (start == end)		return(start);	/* make a partial line */	ieee_putascii("LD");	while (start < end) {		ieee_putascii("%02X",buf[val++]);		start++;	}	ieee_putascii(".\r\n");	return(start);}static long ieee_putlr(struct ieeeFixupp *p){/* * To deal with the vagaries of segmentation the LADsoft linker * defines two types of segments: absolute and virtual.  Note that * 'absolute' in this context is a different thing from the IEEE * definition of an absolute segment type, which is also supported. If a * sement is linked in virtual mode the low limit (L-var) is * subtracted from each R,X, and P variable which appears in an * expression, so that we can have relative offsets.  Meanwhile * in the ABSOLUTE mode this subtraction is not done and * so we can use absolute offsets from 0.  In the LADsoft linker * this configuration is not done in the assemblker source but in * a source the linker reads.  Generally this type of thing only * becomes an issue if real mode code is used.  A pure 32-bit linker could * get away without defining the virtual mode... */	char buf[40];	long size=p->size;	switch(p->ftype) {	    case FT_SEG:	        if (p->id1 < 0)		    sprintf(buf,"%lX",-p->id1);		else		    sprintf(buf,"L%lX,10,/",p->id1);		break;	    case FT_OFS:		sprintf(buf,"R%lX,%lX,+",p->id1,p->addend);		break;	    case FT_REL:		sprintf(buf,"R%lX,%lX,+,P,-,%X,-",p->id1,p->addend,p->size);		break;			    case FT_WRT:	        if (p->id2 < 0)		    sprintf(buf,"R%lX,%lX,+,L%lX,+,%lX,-",p->id2,p->addend,p->id2,-p->id1*16);		else		    sprintf(buf,"R%lX,%lX,+,L%lX,+,L%lX,-",p->id2,p->addend,p->id2,p->id1);		break;	    case FT_EXT:		sprintf(buf,"X%lX",p->id1);		break;	    case FT_EXTREL:		sprintf(buf,"X%lX,P,-,%lX,-",p->id1,size);		break;	    case FT_EXTSEG:		/* We needed a non-ieee hack here.		 * We introduce the Y variable, which is the low		 * limit of the native segment the extern resides in		 */		sprintf(buf,"Y%lX,10,/",p->id1);		break;	    case FT_EXTWRT:	        if (p->id2 < 0)		    sprintf(buf,"X%lX,Y%lX,+,%lX,-",p->id2,p->id2,-p->id1*16);		else		    sprintf(buf,"X%lX,Y%lX,+,L%lX,-",p->id2,p->id2,p->id1);		break;	}	ieee_putascii("LR(%s,%lX).\r\n", buf, size);	return(size);}/* Dump all segment data (text and fixups )*/static void ieee_unqualified_name(char *dest, char *source){    if (ieee_uppercase) {	while (*source)	    *dest++ = toupper(*source++);        *dest = 0;    }    else strcpy(dest,source);}void dbgls_init(struct ofmt * of, void * id, FILE * fp, efunc error){    int tempint;    (void) of;    (void) id;    (void) fp;    (void) error;    fnhead = NULL;    fntail = &fnhead;    arrindex = ARRAY_BOT ;    arrhead = NULL;    arrtail = &arrhead;    ieee_segment("??LINE", 2, &tempint);    any_segs = FALSE;}static void dbgls_cleanup(void){    struct ieeeSection *segtmp;    while (fnhead) {	struct FileName *fntemp = fnhead;	fnhead = fnhead->next;	nasm_free (fntemp->name);	nasm_free (fntemp);    }    for (segtmp = seghead; segtmp; segtmp = segtmp->next) {	while (segtmp->lochead) {	    struct ieeePublic *loctmp = segtmp->lochead;	    segtmp->lochead = loctmp->next;	    nasm_free (loctmp->name);	    nasm_free (loctmp);	}    }    while (arrhead) {	struct Array *arrtmp = arrhead;        arrhead = arrhead->next;        nasm_free (arrtmp);    }}/* * because this routine is not bracketed in * the main program, this routine will be called even if there * is no request for debug info * so, we have to make sure the ??LINE segment is avaialbe * as the first segment when this debug format is selected */static void dbgls_linnum (const char *lnfname, long lineno, long segto){    struct FileName *fn;    struct ieeeSection *seg;    int i = 0;    if (segto == NO_SEG)	return;    /*     * If `any_segs' is still FALSE, we must define a default     * segment.     */    if (!any_segs) {	int tempint;		       /* ignored */	if (segto != ieee_segment("__NASMDEFSEG", 2, &tempint))	    error (ERR_PANIC, "strange segment conditions in OBJ driver");    }    /*     * Find the segment we are targetting.     */    for (seg = seghead; seg; seg = seg->next)	if (seg->index == segto)	    break;    if (!seg)	error (ERR_PANIC, "lineno directed to nonexistent segment?");    for (fn = fnhead; fn; fn = fnhead->next) {	if (!nasm_stricmp(lnfname,fn->name))	    break;        i++;    }    if (!fn) {	fn = nasm_malloc ( sizeof( *fn));	fn->name = nasm_malloc ( strlen(lnfname) + 1) ;	fn->index = i;        strcpy (fn->name,lnfname);	fn->next = NULL;	*fntail = fn;	fntail = &fn->next;    }    ieee_write_byte(seghead, fn->index);    ieee_write_word(seghead, lineno);    ieee_write_fixup (segto, NO_SEG, seghead, 4, OUT_ADDRESS, seg->currentpos);}static void dbgls_deflabel (char *name, long segment,			  long offset, int is_global, char *special) {    struct ieeeSection *seg;    int used_special;		/* have we used the special text? */    /* Keep compiler from warning about special and used_special */    used_special = special ? FALSE : FALSE;    /*     * If it's a special-retry from pass two, discard it.     */    if (is_global == 3)	return;    /*     * First check for the double-period, signifying something     * unusual.     */    if (name[0] == '.' && name[1] == '.' && name[2] != '@') {	return;    }    /*     * Case (i):     */    if (ieee_seg_needs_update)	return;    if (segment < SEG_ABS && segment != NO_SEG && segment % 2)	return;    if (segment >= SEG_ABS || segment == NO_SEG) {	return;    }    /*     * If `any_segs' is still FALSE, we might need to define a     * default segment, if they're trying to declare a label in     * `first_seg'.  But the label should exist due to a prior     * call to ieee_deflabel so we can skip that.     */    for (seg = seghead; seg; seg = seg->next)	if (seg->index == segment) {	    struct ieeePublic *loc;	    /*	     * Case (ii). Maybe MODPUB someday?	     */	    if (!is_global) {	    	last_defined = loc  = nasm_malloc (sizeof(*loc));	    	*seg->loctail = loc;	    	seg->loctail = &loc->next;	    	loc->next = NULL;	    	loc->name = nasm_strdup(name);	    	loc->offset = offset;		loc->segment = -1;		loc->index = seg->ieee_index;	    }	}}static void dbgls_typevalue (long type){    int elem = TYM_ELEMENTS(type);    type = TYM_TYPE(type);    if (! last_defined)	return;    switch (type) {	case TY_BYTE:	    last_defined->type = 1; /* unsigned char */	    break;	case TY_WORD:	    last_defined->type = 3; /* unsigned word */	    break;	case TY_DWORD:	    last_defined->type = 5; /* unsigned dword */	    break;	case TY_FLOAT:	    last_defined->type = 9; /* float */	    break;	case TY_QWORD:	    last_defined->type = 10; /* qword */	    break;	case TY_TBYTE:	    last_defined->type = 11; /* TBYTE */	    break;	default:	    last_defined->type = 0x10; /* near label */	    break;    }                   if (elem > 1) {        struct Array *arrtmp = nasm_malloc (sizeof(*arrtmp));        int vtype = last_defined->type;        arrtmp->size = elem;        arrtmp->basetype = vtype;        arrtmp->next = NULL;        last_defined->type = arrindex++ + 0x100;        *arrtail = arrtmp;        arrtail = & (arrtmp->next);    }    last_defined = NULL;}static void dbgls_output (int output_type, void *param){    (void) output_type;    (void) param;}static struct dfmt ladsoft_debug_form = {    "LADsoft Debug Records",    "ladsoft",    dbgls_init,    dbgls_linnum,    dbgls_deflabel,    null_debug_routine,    dbgls_typevalue,    dbgls_output,    dbgls_cleanup,};static struct dfmt *ladsoft_debug_arr[3] = {	&ladsoft_debug_form,	&null_debug_form,	NULL};struct ofmt of_ieee = {    "IEEE-695 (LADsoft variant) object file format",    "ieee",    NULL,    ladsoft_debug_arr,    &null_debug_form,    NULL,    ieee_init,    ieee_set_info,    ieee_out,    ieee_deflabel,    ieee_segment,    ieee_segbase,    ieee_directive,    ieee_filename,    ieee_cleanup};#endif /* OF_IEEE */

⌨️ 快捷键说明

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