📄 outieee.c
字号:
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 + -