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

📄 outobj.c

📁 CC386 is a general-purpose 32-bit C compiler. It is not an optimizing compiler but given that the co
💻 C
📖 第 1 页 / 共 5 页
字号:
	export->flags = flags;

	return 1;
    }
    return 0;
}

static long obj_segbase (long segment) 
{
    struct Segment *seg;

    /*
     * Find the segment in our list.
     */
    for (seg = seghead; seg; seg = seg->next)
	if (seg->index == segment-1)
	    break;

    if (!seg) {
	/*
	 * Might be an external with a default WRT.
	 */
	long i = segment/2;
	struct ExtBack *eb = ebhead;
	struct External *e;

	while (i > EXT_BLKSIZ) {
	    if (eb)
		eb = eb->next;
	    else
		break;
	    i -= EXT_BLKSIZ;
	}
	if (eb) {
	    e = eb->exts[i];
	    if (e->defwrt_type == DEFWRT_NONE)
		return segment;	       /* fine */
	    else if (e->defwrt_type == DEFWRT_SEGMENT)
		return e->defwrt_ptr.seg->index+1;
	    else if (e->defwrt_type == DEFWRT_GROUP)
		return e->defwrt_ptr.grp->index+1;
	    else
		return NO_SEG;	       /* can't tell what it is */
	}

	return segment;		       /* not one of ours - leave it alone */
    }

    if (seg->align >= SEG_ABS)
	return seg->align;	       /* absolute segment */
    if (seg->grp)
	return seg->grp->index+1;      /* grouped segment */

    return segment;		       /* no special treatment */
}

static void obj_filename (char *inname, char *outname, efunc lerror) 
{
    strcpy(obj_infile, inname);
    standard_extension (inname, outname, ".obj", lerror);
}

static void obj_write_file (int debuginfo) 
{
    struct Segment *seg, *entry_seg_ptr = 0;
    struct FileName *fn;
    struct LineNumber *ln;
    struct Group *grp;
    struct Public *pub, *loc;
    struct External *ext;
    struct ImpDef *imp;
    struct ExpDef *export;
    static char boast[] = "The Netwide Assembler " NASM_VER;
    int lname_idx;
    ObjRecord *orp;

    /*
     * Write the THEADR module header.
     */
    orp = obj_new();
    orp->type = THEADR;
    obj_name (orp, obj_infile);
    obj_emit2 (orp);

    /*
     * Write the NASM boast comment.
     */
    orp->type = COMENT;
    obj_rword (orp, 0);   /* comment type zero */
    obj_name (orp, boast);
    obj_emit2 (orp);

     /* DAL start */
    if (debuginfo && dbg_type == dbg_ls) {
    	for (fn = fnhead; fn; fn = fn->next) {
        /* write out depslist file name */
            orp->type = COMENT;
            orp->ori = ori_null;
            obj_byte (orp, 0x40);
            obj_byte (orp, dDEPNAME);
            obj_filetime(orp, fn->name);
            obj_name( orp,fn->name);
            obj_emit2 (orp);
        }
    }
    /* DAL end */

    orp->type = COMENT;
    /*
     * Write the IMPDEF records, if any.
     */
    for (imp = imphead; imp; imp = imp->next) {
	obj_rword (orp, 0xA0);   /* comment class A0 */
	obj_byte (orp, 1);   /* subfunction 1: IMPDEF */
	if (imp->impname)
	    obj_byte (orp, 0);   /* import by name */
	else
	    obj_byte (orp, 1);   /* import by ordinal */
	obj_name (orp, imp->extname);
	obj_name (orp, imp->libname);
	if (imp->impname)
	    obj_name (orp, imp->impname);
	else
	    obj_word (orp, imp->impindex);
	obj_emit2 (orp);
    }

    /*
     * Write the EXPDEF records, if any.
     */
    for (export = exphead; export; export = export->next) {
	obj_rword (orp, 0xA0);   /* comment class A0 */
	obj_byte (orp, 2);   /* subfunction 2: EXPDEF */
	obj_byte (orp, export->flags);
	obj_name (orp, export->extname);
	obj_name (orp, export->intname);
	if (export->flags & EXPDEF_FLAG_ORDINAL)
	    obj_word (orp, export->ordinal);
	obj_emit2 (orp);
    }

    /* we're using extended OMF if we put in debug info*/
    if (debuginfo) {
      orp->type = COMENT;
      obj_byte (orp, 0x40);
      obj_byte (orp, dEXTENDED);
      obj_emit2 (orp);
    }

    /*
     * Write the first LNAMES record, containing LNAME one, which
     * is null. Also initialise the LNAME counter.
     */
    orp->type = LNAMES;
    obj_byte (orp, 0);
    lname_idx = 1;
    /*
     * Write some LNAMES for the segment names
     */
    for (seg = seghead; seg; seg = seg->next) {
   if (seg->combine != CMB_BORLANDVIRTUAL) { /* DAL */
    orp = obj_name (orp, seg->name);
    if (seg->segclass)
	    orp = obj_name (orp, seg->segclass);
    if (seg->overlay)
	    orp = obj_name (orp, seg->overlay);
    obj_commit (orp);
   }
    }
    /*
     * Write some LNAMES for the group names
     */
    for (grp = grphead; grp; grp = grp->next) {
	orp = obj_name (orp, grp->name);
	obj_commit (orp);
    }
    obj_emit (orp);


    /*
     * Write the SEGDEF records.
     */
    orp->type = SEGDEF;
    for (seg = seghead; seg; seg = seg->next) {
  if (seg->combine != CMB_BORLANDVIRTUAL) { /* DAL */
	int acbp;
	unsigned long seglen = seg->currentpos;

	acbp = (seg->combine << 2);    /* C field */

	if (seg->use32)
	    acbp |= 0x01;	       /* P bit is Use32 flag */
	else if (seglen == 0x10000L) {
	    seglen = 0;                /* This special case may be needed for old linkers */
	    acbp |= 0x02;	       /* B bit */
	}


	/* A field */
	if (seg->align >= SEG_ABS)
	    /* acbp |= 0x00 */;
	else if (seg->align >= 4096) {
	    if (seg->align > 4096)
		error(ERR_NONFATAL, "segment `%s' requires more alignment"
		      " than OBJ format supports", seg->name);
	    acbp |= 0xC0;	       /* PharLap extension */
	} else if (seg->align >= 256) {
	    acbp |= 0x80;
	} else if (seg->align >= 16) {
	    acbp |= 0x60;
	} else if (seg->align >= 4) {
	    acbp |= 0xA0;
	} else if (seg->align >= 2) {
	    acbp |= 0x40;
	} else
	    acbp |= 0x20;

	obj_byte (orp, acbp);
	if (seg->align & SEG_ABS) {
	    obj_x (orp, seg->align - SEG_ABS);  /* Frame */
	    obj_byte (orp, 0);  /* Offset */
	}
	obj_x (orp, seglen);
	obj_index (orp, ++lname_idx);
	obj_index (orp, seg->segclass ? ++lname_idx : 1);
	obj_index (orp, seg->overlay ? ++lname_idx : 1);
	obj_emit2 (orp);
  }
    }

    /*
     * Write the GRPDEF records.
     */
    orp->type = GRPDEF;
    for (grp = grphead; grp; grp = grp->next) {
	int i;

	if (grp->nindices != grp->nentries) {
	    for (i = grp->nindices; i < grp->nentries; i++) {
		error(ERR_NONFATAL, "group `%s' contains undefined segment"
		      " `%s'", grp->name, grp->segs[i].name);
		nasm_free (grp->segs[i].name);
		grp->segs[i].name = NULL;
	    }
	}
	obj_index (orp, ++lname_idx);
	for (i = 0; i < grp->nindices; i++) {
	    obj_byte (orp, 0xFF);
	    obj_index (orp, grp->segs[i].index);
	}
	obj_emit2 (orp);
    }

    /*
     * Write the PUBDEF records: first the ones in the segments,
     * then the far-absolutes.
     */
    orp->type = PUBDEF;
    orp->ori = ori_pubdef;
    for (seg = seghead; seg; seg = seg->next) {
  if (seg->combine != CMB_BORLANDVIRTUAL) {
	orp->parm[0] = seg->grp ? seg->grp->obj_index : 0;
	orp->parm[1] = seg->obj_index;
	for (pub = seg->pubhead; pub; pub = pub->next) {
	    orp = obj_name (orp, pub->name);
	    orp = obj_x (orp, pub->offset);
	    orp = obj_byte (orp, 0);  /* type index */
	    obj_commit (orp);
	}
	obj_emit (orp);
  }
    }
    orp->parm[0] = 0;
    orp->parm[1] = 0;
    for (pub = fpubhead; pub; pub = pub->next) {   /* pub-crawl :-) */
	if (orp->parm[2] != pub->segment) {
	    obj_emit (orp);
	    orp->parm[2] = pub->segment;
	}
	orp = obj_name (orp, pub->name);
	orp = obj_x (orp, pub->offset);
	orp = obj_byte (orp, 0);  /* type index */
	obj_commit (orp);
    }
    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 && !ext->virtual_parent_obj_index) { /* DAL */
	    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); 
/* DAL */
      if (ext->virtual_parent_obj_index) {
    int i = 1 ;
    for (seg = seghead; seg; seg = seg->next, i++)
     if (seg->combine != CMB_BORLANDVIRTUAL)
      if (i == ext->virtual_parent_obj_index)
       break ;
       orp= obj_byte(orp, seg->obj_index) ;
       orp = obj_value(orp, ext->defwrt_ptr.seg->currentpos) ;
      } else {
/* END DAL */
	    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 && dbg_type == dbg_bi) { /* DAL */
      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);
            if (dbg_type == dbg_bi)
                obj_byte( orp,0);
            else
                obj_byte(orp,seg->lsdebseg) ;
            obj_name( orp,fn->name);
            obj_filetime(orp, fn->name); /* DAL put in real time */
	    obj_emit2 (orp);

	    /* write out line numbers this file */

            orp->type = LINNUM;
        /* Begin DAL */
            if (dbg_type == dbg_ls)
                orp->type = LINN32 ;
        /* End DAL */
            orp->ori = ori_linnum;
	    for (ln = fn->lnhead; ln; ln = ln->next) {
		if (

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -