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