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

📄 outobj.c

📁 开源的nasm编译器源码,研究编译器原理很有帮且
💻 C
📖 第 1 页 / 共 5 页
字号:
    }    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 + -