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

📄 outieee.c

📁 开源的nasm编译器源码,研究编译器原理很有帮且
💻 C
📖 第 1 页 / 共 3 页
字号:
				eb = eb->next;			    else				break;			    i -= EXT_BLKSIZ;			}				/* if we have an extern decide the type and make a record			 */			if (eb) {			        s.ftype = FT_EXTWRT;			        s.addend = 0;		        	s.id2 = eb->index[i];			}			else			    error(ERR_NONFATAL,				"Source of WRT must be an offset");		    }					}	    	else 	            error(ERR_PANIC,		          "unrecognised WRT value in ieee_write_fixup");	    }	    else 		error(ERR_NONFATAL,"target of WRT must be a section ");	}	s.size = size;	ieee_install_fixup(segto,&s);	return;    }    /* Pure segment fixup ? */    if (segment != NO_SEG) {	s.ftype = FT_SEG;	s.id1 = 0;	if (segment >= SEG_ABS) {	    /* absolute far segment fixup */	    s.id1 = -(segment -~SEG_ABS);	}	else if (segment % 2) {	    /* fixup to named segment */	    /* look it up */	    for (target = seghead; target; target = target->next)	        if (target->index == segment-1)	            break;    	    if (target)	        s.id1 = target->ieee_index;	    else {		/*		 * Now we assume the segment field is being used		 * to hold an extern index		 */		long i = segment/2;		struct ExtBack *eb = ebhead;		while (i > EXT_BLKSIZ) {		    if (eb)			eb = eb->next;		    else			break;		    i -= EXT_BLKSIZ;		}		/* if we have an extern decide the type and make a record		 */		if (eb) {		    if (realtype == OUT_REL2ADR || realtype == OUT_REL4ADR) {			error(ERR_PANIC,"Segment of a rel not supported in ieee_write_fixup");		    }		    else {				/* If we want the segment */			    s.ftype = FT_EXTSEG;			    s.addend = 0;			    s.id1 = eb->index[i];		    }		    		}		else 		    /* If we get here the seg value doesn't make sense */	            error(ERR_PANIC,		          "unrecognised segment value in ieee_write_fixup");	    }        } else {	    /* Assume we are offsetting directly from a section    	     * So look up the target segment	     */	    for (target = seghead; target; target = target->next)	        if (target->index == segment)	            break;    	    if (target) {		if (realtype == OUT_REL2ADR || realtype == OUT_REL4ADR) {		    /* PC rel to a known offset */	            s.id1 = target->ieee_index;		    s.ftype = FT_REL;		    s.size = size;		    s.addend = offset;		}		else {		    /* We were offsetting from a seg */	            s.id1 = target->ieee_index;		    s.ftype = FT_OFS;		    s.size = size;		    s.addend = offset;		}	    }	    else {		/*		 * Now we assume the segment field is being used		 * to hold an extern index		 */		long i = segment/2;		struct ExtBack *eb = ebhead;		while (i > EXT_BLKSIZ) {		    if (eb)			eb = eb->next;		    else			break;		    i -= EXT_BLKSIZ;		}		/* if we have an extern decide the type and make a record		 */		if (eb) {		    if (realtype == OUT_REL2ADR || realtype == OUT_REL4ADR) {		        s.ftype = FT_EXTREL;		        s.addend = 0;		        s.id1 = eb->index[i];		    }		    else {			    /* else we want the external offset */			    s.ftype = FT_EXT;			    s.addend = 0;			    s.id1 = eb->index[i];		    }		    		}		else 		    /* If we get here the seg value doesn't make sense */	            error(ERR_PANIC,		          "unrecognised segment value in ieee_write_fixup");	    }	}	if (size != 2 && s.ftype == FT_SEG)	    error(ERR_NONFATAL, "IEEE format can only handle 2-byte"		     " segment base references");	s.size = size;	ieee_install_fixup(segto,&s);	return;    }    /* should never get here */}static void ieee_install_fixup(struct ieeeSection *seg, struct ieeeFixupp *fix){    struct ieeeFixupp *f;    f = nasm_malloc(sizeof(struct ieeeFixupp));    memcpy(f,fix,sizeof(struct ieeeFixupp));    f->offset = seg->currentpos;    seg->currentpos += fix->size;    f->next = NULL;    if (seg->fptr)	seg->flptr = seg->flptr->next = f;    else	seg->fptr = seg->flptr = f;}/* * segment registry */static long ieee_segment (char *name, int pass, int *bits) {    /*     * We call the label manager here to define a name for the new     * segment, and when our _own_ label-definition stub gets     * called in return, it should register the new segment name     * using the pointer it gets passed. That way we save memory,     * by sponging off the label manager.     */    if (!name) {	*bits = 16;	if (!any_segs)		return 0;	return seghead->index;    } else {	struct ieeeSection *seg;	int ieee_idx, attrs, rn_error;	char *p;	/*	 * Look for segment attributes.	 */	attrs = 0;	while (*name == '.')	    name++;		       /* hack, but a documented one */	p = name;	while (*p && !isspace(*p))	    p++;	if (*p) {	    *p++ = '\0';	    while (*p && isspace(*p))		*p++ = '\0';	}	while (*p) {	    while (*p && !isspace(*p))		p++;	    if (*p) {		*p++ = '\0';		while (*p && isspace(*p))		    *p++ = '\0';	    }	    attrs++;	}	ieee_idx = 1;	for (seg = seghead; seg; seg = seg->next) {	    ieee_idx++;	    if (!strcmp(seg->name, name)) {		if (attrs > 0 && pass == 1)		    error(ERR_WARNING, "segment attributes specified on"			  " redeclaration of segment: ignoring");		if (seg->use32)		    *bits = 32;		else		    *bits = 16;		return seg->index;	    }	}	*segtail = seg = nasm_malloc(sizeof(*seg));	seg->next = NULL;	segtail = &seg->next;	seg->index = seg_alloc();	seg->ieee_index = ieee_idx;	any_segs = TRUE;	seg->name = NULL;	seg->currentpos = 0;	seg->align = 1;		       /* default */	seg->use32 = *bits == 32;      /* default to user spec */	seg->combine = CMB_PUBLIC;     /* default */	seg->pubhead = NULL;	seg->pubtail = &seg->pubhead;	seg->data = NULL;	seg->fptr = NULL;	seg->lochead = NULL;	seg->loctail = &seg->lochead;	/*	 * Process the segment attributes.	 */	p = name;	while (attrs--) {	    p += strlen(p);	    while (!*p) p++;	    /*	     * `p' contains a segment attribute.	     */	    if (!nasm_stricmp(p, "private"))		seg->combine = CMB_PRIVATE;	    else if (!nasm_stricmp(p, "public"))		seg->combine = CMB_PUBLIC;	    else if (!nasm_stricmp(p, "common"))		seg->combine = CMB_COMMON;	    else if (!nasm_stricmp(p, "use16"))		seg->use32 = FALSE;	    else if (!nasm_stricmp(p, "use32"))		seg->use32 = TRUE;	    else if (!nasm_strnicmp(p, "align=", 6)) {		seg->align = readnum(p+6, &rn_error);		if (seg->align == 0)		    seg->align = 1;		if (rn_error) {		    seg->align = 1;		    error (ERR_NONFATAL, "segment alignment should be"			   " numeric");		}		switch ((int) seg->align) {		  case 1:	       /* BYTE */		  case 2:	       /* WORD */		  case 4:	       /* DWORD */		  case 16:	       /* PARA */		  case 256:	       /* PAGE */		  case 8:		  case 32:		  case 64:		  case 128:		    break;		  default:		    error(ERR_NONFATAL, "invalid alignment value %d",			  seg->align);		    seg->align = 1;		    break;		}	    } else if (!nasm_strnicmp(p, "absolute=", 9)) {		seg->align = SEG_ABS + readnum(p+9, &rn_error);		if (rn_error)		    error (ERR_NONFATAL, "argument to `absolute' segment"			   " attribute should be numeric");	    }	}	ieee_seg_needs_update = seg;	if (seg->align >= SEG_ABS)	    deflabel (name, NO_SEG, seg->align - SEG_ABS, 			NULL, FALSE, FALSE, &of_ieee, error);	else	    deflabel (name, seg->index+1, 0L, 			NULL, FALSE, FALSE, &of_ieee, error);	ieee_seg_needs_update = NULL;	if (seg->use32)	    *bits = 32;	else	    *bits = 16;	return seg->index;    }}/* * directives supported */static int ieee_directive (char *directive, char *value, int pass) {        (void) value;    (void) pass;    if (!strcmp(directive, "uppercase")) {	ieee_uppercase = TRUE;	return 1;    }    return 0;}/* * Return segment data */static long ieee_segbase (long segment) {    struct ieeeSection *seg;    /*     * Find the segment in our list.     */    for (seg = seghead; seg; seg = seg->next)	if (seg->index == segment-1)	    break;    if (!seg)	return segment;		       /* not one of ours - leave it alone */    if (seg->align >= SEG_ABS)	return seg->align;	       /* absolute segment */    return segment;		       /* no special treatment */}/* * filename */static void ieee_filename (char *inname, char *outname, efunc error) {    strcpy(ieee_infile, inname);    standard_extension (inname, outname, ".o", error);}static void ieee_write_file (int debuginfo) {    struct tm *thetime;    time_t reltime;    struct FileName *fn;    struct ieeeSection *seg;    struct ieeePublic *pub, *loc;    struct ieeeExternal *ext;    struct ieeeObjData *data;    struct ieeeFixupp *fix;    struct Array *arr;    static char boast[] = "The Netwide Assembler " NASM_VER;    int i;    /*     * Write the module header     */    ieee_putascii("MBFNASM,%02X%s.\r\n",strlen(ieee_infile),ieee_infile);    /*     * Write the NASM boast comment.     */    ieee_putascii("CO0,%02X%s.\r\n",strlen(boast),boast);    /*      * write processor-specific information     */    ieee_putascii("AD8,4,L.\r\n");    /*     * date and time     */    time(&reltime);    thetime = localtime(&reltime);    ieee_putascii("DT%04d%02d%02d%02d%02d%02d.\r\n", 			1900+thetime->tm_year,thetime->tm_mon+1,thetime->tm_mday,			thetime->tm_hour, thetime->tm_min, thetime->tm_sec);    /*      * if debugging, dump file names     */    for (fn = fnhead; fn && debuginfo; fn = fn->next) {	ieee_putascii("C0105,%02X%s.\r\n",strlen(fn->name),fn->name);    }         ieee_putascii("CO101,07ENDHEAD.\r\n");    /*     * the standard doesn't specify when to put checksums,     * we'll just do it periodically.     */    ieee_putcs(FALSE);    /*      * Write the section headers     */    seg = seghead;    if (!debuginfo && !strcmp(seg->name,"??LINE"))	seg = seg->next;    while (seg) {	char buf[256];	char attrib;	switch(seg->combine) {	    case CMB_PUBLIC:	    default:		attrib = 'C';		break;	    case CMB_PRIVATE:		attrib = 'S';		break;	    case CMB_COMMON:		attrib = 'M';		break;  	}	ieee_unqualified_name(buf,seg->name);	if (seg->align >= SEG_ABS) {	    ieee_putascii("ST%X,A,%02X%s.\r\n",seg->ieee_index,strlen(buf), buf);	    ieee_putascii("ASL%X,%lX.\r\n",seg->ieee_index, (seg->align - SEG_ABS)*16);	}	else {	    ieee_putascii("ST%X,%c,%02X%s.\r\n",seg->ieee_index,attrib,strlen(buf), buf);	    ieee_putascii("SA%X,%lX.\r\n",seg->ieee_index,seg->align);	    ieee_putascii("ASS%X,%X.\r\n",seg->ieee_index, seg->currentpos);	}	seg = seg->next;    }    /*     * write the start address if there is one     */    if (ieee_entry_seg) {        for (seg = seghead; seg; seg = seg->next)	    if (seg->index == ieee_entry_seg)		break;	if (!seg)	    error(ERR_PANIC,"Start address records are incorrect");	else 	    ieee_putascii("ASG,R%X,%lX,+.\r\n",seg->ieee_index, ieee_entry_ofs);    }	    ieee_putcs(FALSE);    /*     * Write the publics     */    i = 1;    for (seg = seghead; seg; seg = seg->next) {        for (pub = seg->pubhead; pub; pub = pub->next) {	    char buf[256];	    ieee_unqualified_name(buf,pub->name);       	    ieee_putascii("NI%X,%02X%s.\r\n",i, strlen(buf), buf);	    if (pub->segment == -1)         	    	ieee_putascii("ASI%X,R%X,%lX,+.\r\n", i, pub->index,pub->offset);	    else       	    	ieee_putascii("ASI%X,%lX,%lX,+.\r\n", i, pub->segment*16,pub->offset);	    if (debuginfo) {	    	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 = fpubhead;    i = 1;    while (pub) {	char buf[256];	ieee_unqualified_name(buf,pub->name);       	ieee_putascii("NI%X,%02X%s.\r\n",i, strlen(buf), buf);	if (pub->segment == -1)         	    ieee_putascii("ASI%X,R%X,%lX,+.\r\n", i, pub->index,pub->offset);	else       	    ieee_putascii("ASI%X,%lX,%lX,+.\r\n", i, pub->segment*16,pub->offset);	if (debuginfo) {

⌨️ 快捷键说明

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