📄 outobj.c
字号:
} obj_emit (orp); /* * Write the EXTDEF and COMDEF records, in order. */ orp->ori = ori_null; for (ext = exthead; ext; ext = ext->next) { if (ext->commonsize == 0) { if (orp->type != EXTDEF) { obj_emit (orp); orp->type = EXTDEF; } orp = obj_name (orp, ext->name); orp = obj_index (orp, 0); } else { if (orp->type != COMDEF) { obj_emit (orp); orp->type = COMDEF; } orp = obj_name (orp, ext->name); orp = obj_index (orp, 0); if (ext->commonelem) { orp = obj_byte (orp, 0x61);/* far communal */ orp = obj_value (orp, (ext->commonsize / ext->commonelem)); orp = obj_value (orp, ext->commonelem); } else { orp = obj_byte (orp, 0x62);/* near communal */ orp = obj_value (orp, ext->commonsize); } } obj_commit (orp); } obj_emit (orp); /* * Write a COMENT record stating that the linker's first pass * may stop processing at this point. Exception is if our * MODEND record specifies a start point, in which case, * according to some variants of the documentation, this COMENT * should be omitted. So we'll omit it just in case. * But, TASM puts it in all the time so if we are using * TASM debug stuff we are putting it in */ if (debuginfo || obj_entry_seg == NO_SEG) { orp->type = COMENT; obj_byte (orp, 0x40); obj_byte (orp, dLINKPASS); obj_byte (orp, 1); obj_emit2 (orp); } /* * 1) put out the compiler type * 2) Put out the type info. The only type we are using is near label #19 */ if (debuginfo) { int i; struct Array *arrtmp = arrhead; orp->type = COMENT; obj_byte (orp, 0x40); obj_byte (orp, dCOMPDEF); obj_byte (orp, 4); obj_byte (orp, 0); obj_emit2 (orp); obj_byte (orp, 0x40); obj_byte (orp, dTYPEDEF); obj_word (orp, 0x18); /* type # for linking */ obj_word (orp, 6); /* size of type */ obj_byte (orp, 0x2a); /* absolute type for debugging */ obj_emit2 (orp); obj_byte (orp, 0x40); obj_byte (orp, dTYPEDEF); obj_word (orp, 0x19); /* type # for linking */ obj_word (orp, 0); /* size of type */ obj_byte (orp, 0x24); /* absolute type for debugging */ obj_byte (orp, 0); /* near/far specifier */ obj_emit2 (orp); obj_byte (orp, 0x40); obj_byte (orp, dTYPEDEF); obj_word (orp, 0x1A); /* type # for linking */ obj_word (orp, 0); /* size of type */ obj_byte (orp, 0x24); /* absolute type for debugging */ obj_byte (orp, 1); /* near/far specifier */ obj_emit2 (orp); obj_byte (orp, 0x40); obj_byte (orp, dTYPEDEF); obj_word (orp, 0x1b); /* type # for linking */ obj_word (orp, 0); /* size of type */ obj_byte (orp, 0x23); /* absolute type for debugging */ obj_byte (orp, 0); obj_byte (orp, 0); obj_byte (orp, 0); obj_emit2 (orp); obj_byte (orp, 0x40); obj_byte (orp, dTYPEDEF); obj_word (orp, 0x1c); /* type # for linking */ obj_word (orp, 0); /* size of type */ obj_byte (orp, 0x23); /* absolute type for debugging */ obj_byte (orp, 0); obj_byte (orp, 4); obj_byte (orp, 0); obj_emit2 (orp); obj_byte (orp, 0x40); obj_byte (orp, dTYPEDEF); obj_word (orp, 0x1d); /* type # for linking */ obj_word (orp, 0); /* size of type */ obj_byte (orp, 0x23); /* absolute type for debugging */ obj_byte (orp, 0); obj_byte (orp, 1); obj_byte (orp, 0); obj_emit2 (orp); obj_byte (orp, 0x40); obj_byte (orp, dTYPEDEF); obj_word (orp, 0x1e); /* type # for linking */ obj_word (orp, 0); /* size of type */ obj_byte (orp, 0x23); /* absolute type for debugging */ obj_byte (orp, 0); obj_byte (orp, 5); obj_byte (orp, 0); obj_emit2 (orp); /* put out the array types */ for (i= ARRAYBOT; i < arrindex; i++) { obj_byte (orp, 0x40); obj_byte (orp, dTYPEDEF); obj_word (orp, i ); /* type # for linking */ obj_word (orp, arrtmp->size); /* size of type */ obj_byte (orp, 0x1A); /* absolute type for debugging (array)*/ obj_byte (orp, arrtmp->basetype ); /* base type */ obj_emit2 (orp); arrtmp = arrtmp->next ; } } /* * write out line number info with a LINNUM record * switch records when we switch segments, and output the * file in a pseudo-TASM fashion. The record switch is naive; that * is that one file may have many records for the same segment * if there are lots of segment switches */ if (fnhead && debuginfo) { seg = fnhead->lnhead->segment; for (fn = fnhead; fn; fn = fn->next) { /* write out current file name */ orp->type = COMENT; orp->ori = ori_null; obj_byte (orp, 0x40); obj_byte (orp, dFILNAME); obj_byte( orp,0); obj_name( orp,fn->name); obj_dword(orp, 0); obj_emit2 (orp); /* write out line numbers this file */ orp->type = LINNUM; orp->ori = ori_linnum; for (ln = fn->lnhead; ln; ln = ln->next) { if (seg != ln->segment) { /* if we get here have to flush the buffer and start * a new record for a new segment */ seg = ln->segment; obj_emit ( orp ); } orp->parm[0] = seg->grp ? seg->grp->obj_index : 0; orp->parm[1] = seg->obj_index; orp = obj_word(orp, ln->lineno); orp = obj_x(orp, ln->offset); obj_commit (orp); } obj_emit (orp); } } /* * we are going to locate the entry point segment now * rather than wait until the MODEND record, because, * then we can output a special symbol to tell where the * entry point is. * */ if (obj_entry_seg != NO_SEG) { for (seg = seghead; seg; seg = seg->next) { if (seg->index == obj_entry_seg) { entry_seg_ptr = seg; break; } } if (!seg) error(ERR_NONFATAL, "entry point is not in this module"); } /* * get ready to put out symbol records */ orp->type = COMENT; orp->ori = ori_local; /* * put out a symbol for the entry point * no dots in this symbol, because, borland does * not (officially) support dots in label names * and I don't know what various versions of TLINK will do */ if (debuginfo && obj_entry_seg != NO_SEG) { orp = obj_name (orp,"start_of_program"); orp = obj_word (orp,0x19); /* type: near label */ orp = obj_index (orp, seg->grp ? seg->grp->obj_index : 0); orp = obj_index (orp, seg->obj_index); orp = obj_x (orp, obj_entry_ofs); obj_commit (orp); } /* * put out the local labels */ for (seg = seghead; seg && debuginfo; seg = seg->next) { /* labels this seg */ for (loc = seg->lochead; loc; loc = loc->next) { orp = obj_name (orp,loc->name); orp = obj_word (orp, loc->type); orp = obj_index (orp, seg->grp ? seg->grp->obj_index : 0); orp = obj_index (orp, seg->obj_index); orp = obj_x (orp,loc->offset); obj_commit (orp); } } if (orp->used) obj_emit (orp); /* * Write the LEDATA/FIXUPP pairs. */ for (seg = seghead; seg; seg = seg->next) { obj_emit (seg->orp); nasm_free (seg->orp); } /* * Write the MODEND module end marker. */ orp->type = obj_use32 ? MODE32 : MODEND; orp->ori = ori_null; if (entry_seg_ptr) { orp->type = entry_seg_ptr->use32 ? MODE32 : MODEND; obj_byte (orp, 0xC1); seg = entry_seg_ptr; if (seg->grp) { obj_byte (orp, 0x10); obj_index (orp, seg->grp->obj_index); } else { /* * the below changed to prevent TLINK crashing. * Previous more efficient version read: * * obj_byte (orp, 0x50); */ obj_byte (orp, 0x00); obj_index (orp, seg->obj_index); } obj_index (orp, seg->obj_index); obj_x (orp, obj_entry_ofs); } else obj_byte (orp, 0); obj_emit2 (orp); nasm_free (orp);}void obj_fwrite(ObjRecord *orp) { unsigned int cksum, len; unsigned char *ptr; cksum = orp->type; if (orp->x_size == 32) cksum |= 1; fputc (cksum, ofp); len = orp->committed+1; cksum += (len & 0xFF) + ((len>>8) & 0xFF); fwriteshort (len, ofp); fwrite (orp->buf, 1, len-1, ofp); for (ptr=orp->buf; --len; ptr++) cksum += *ptr; fputc ( (-cksum) & 0xFF, ofp);}static const char *obj_stdmac[] = { "%define __SECT__ [section .text]", "%imacro group 1+.nolist", "[group %1]", "%endmacro", "%imacro uppercase 0+.nolist", "[uppercase %1]", "%endmacro", "%imacro export 1+.nolist", "[export %1]", "%endmacro", "%imacro import 1+.nolist", "[import %1]", "%endmacro", "%macro __NASM_CDecl__ 1", "%endmacro", NULL};void dbgbi_init(struct ofmt * of, void * id, FILE * fp, efunc error){ (void) of; (void) id; (void) fp; (void) error; fnhead = NULL; fntail = &fnhead; arrindex = ARRAYBOT ; arrhead = NULL; arrtail = &arrhead;}static void dbgbi_cleanup(void){ struct Segment *segtmp; while (fnhead) { struct FileName *fntemp = fnhead; while (fnhead->lnhead) { struct LineNumber *lntemp = fnhead->lnhead; fnhead->lnhead = lntemp->next; nasm_free( lntemp); } fnhead = fnhead->next; nasm_free (fntemp->name); nasm_free (fntemp); } for (segtmp=seghead; segtmp; segtmp=segtmp->next) { while (segtmp->lochead) { struct Public *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); }}static void dbgbi_linnum (const char *lnfname, long lineno, long segto){ struct FileName *fn; struct LineNumber *ln; struct Segment *seg; 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 != obj_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) */ for (fn = fnhead; fn; fn = fn->next) /* fbk - Austin Lunnen - John Fine*/ if (!nasm_stricmp(lnfname,fn->name)) break; if (!fn) { fn = nasm_malloc ( sizeof( *fn)); fn->name = nasm_malloc ( strlen(lnfname) + 1) ; strcpy (fn->name,lnfname); fn->lnhead = NULL; fn->lntail = & fn->lnhead; fn->next = NULL; *fntail = fn; fntail = &fn->next; } ln = nasm_malloc ( sizeof( *ln)); ln->segment = seg; ln->offset = seg->currentpos; ln->lineno = lineno; ln->next = NULL; *fn->lntail = ln; fn->lntail = &ln->next;}static void dbgbi_deflabel (char *name, long segment, long offset, int is_global, char *special) { struct Segment *seg; (void) special; /* * 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 (obj_seg_needs_update) { return; } else if (obj_grp_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 obj_deflabel so we can skip that. */ for (seg = seghead; seg; seg = seg->next) if (seg->index == segment) { struct Public *loc = nasm_malloc (sizeof(*loc)); /* * Case (ii). Maybe MODPUB someday? */ last_defined = *seg->loctail = loc; seg->loctail = &loc->next; loc->next = NULL; loc->name = nasm_strdup(name); loc->offset = offset; }}static void dbgbi_typevalue (long type){ int vsize; int elem = TYM_ELEMENTS(type); type = TYM_TYPE(type); if (!last_defined) return; switch (type) { case TY_BYTE: last_defined->type = 8; /* unsigned char */ vsize = 1; break; case TY_WORD: last_defined->type = 10; /* unsigned word */ vsize = 2; break; case TY_DWORD: last_defined->type = 12; /* unsigned dword */ vsize = 4; break; case TY_FLOAT: last_defined->type = 14; /* float */ vsize = 4; break; case TY_QWORD: last_defined->type = 15; /* qword */ vsize = 8; break; case TY_TBYTE: last_defined->type = 16; /* TBYTE */ vsize = 10; break; default: last_defined->type = 0x19; /*label */ vsize = 0; break; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -