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

📄 outieee.c

📁 CC386 is a general-purpose 32-bit C compiler. It is not an optimizing compiler but given that the co
💻 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 + -