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

📄 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 页
字号:
{
    obj_index (orp, orp->parm[0]);
    obj_index (orp, orp->parm[1]);
}
/*
 * Initializer for a local vars record.
 */
static void ori_local(ObjRecord *orp) 
{
    obj_byte (orp, 0x40);
    obj_byte (orp, dSYM);
}

/*
 * Null initializer for records that continue without any header info
 */
static void ori_null(ObjRecord *orp) 
{
    (void) orp;  /* Do nothing */
}

/*
 * This concludes the low level section of outobj.c
 */

static char obj_infile[FILENAME_MAX];

static efunc error;
static evalfunc evaluate;
static ldfunc deflabel;
static FILE *ofp;
static long first_seg;
static int any_segs;
static int passtwo;
static int arrindex;

#define GROUP_MAX 256		       /* we won't _realistically_ have more
					* than this many segs in a group */
#define EXT_BLKSIZ 256		       /* block size for externals list */

struct Segment;			       /* need to know these structs exist */
struct Group;

struct LineNumber {
    struct LineNumber *next;
    struct Segment *segment;
    long offset;
    long lineno;
};

static struct FileName {
    struct FileName *next;
    char *name;
    struct LineNumber *lnhead, **lntail;
    int index;
} *fnhead, **fntail;

static struct Array {
    struct Array *next;
    unsigned size;
    int basetype;
} *arrhead, **arrtail;

#define ARRAYBOT 31 /* magic number  for first array index */


static struct Public {
    struct Public *next;
    char *name;
    long offset;
    long segment;		       /* only if it's far-absolute */
    int type;                          /* only for local debug syms */
    int global;                 /* DAL */
} *fpubhead, **fpubtail, *last_defined;

static struct External {
    struct External *next;
    char *name;
    long commonsize;
    long commonelem;		       /* element size if FAR, else zero */
    long virtual_parent_obj_index ; /* DAL object index of virtual seg's parent */
    int index;			       /* OBJ-file external index */
    enum {
	DEFWRT_NONE,		       /* no unusual default-WRT */
	DEFWRT_STRING,		       /* a string we don't yet understand */
	DEFWRT_SEGMENT,		       /* a segment */
	DEFWRT_GROUP		       /* a group */
    } defwrt_type;
    union {
	char *string;
	struct Segment *seg;
	struct Group *grp;
    } defwrt_ptr;
    struct External *next_dws;	       /* next with DEFWRT_STRING */
} *exthead, **exttail, *dws;

static int externals;

static struct ExtBack {
    struct ExtBack *next;
    struct External *exts[EXT_BLKSIZ];
} *ebhead, **ebtail;

static struct Segment {
    struct Segment *next;
    long index;			       /* the NASM segment id */
    long obj_index;		       /* the OBJ-file segment index */
    struct Group *grp;		       /* the group it belongs to */
    unsigned long currentpos;
    long align;			       /* can be SEG_ABS + absolute addr */
    enum {
	CMB_PRIVATE = 0,
	CMB_PUBLIC = 2,
	CMB_STACK = 5,
   CMB_COMMON = 6,
   CMB_BORLANDVIRTUAL = 15 /* DAL */
    } combine;
    long use32;			       /* is this segment 32-bit? */
    struct Public *pubhead, **pubtail, *lochead, **loctail;
    char *name;
    char *segclass, *overlay;	       /* `class' is a C++ keyword :-) */
    ObjRecord *orp;
    int lsdebseg ; /* DAL - the debug info segment number to use */
} *seghead, **segtail, *obj_seg_needs_update;

static struct Group {
    struct Group *next;
    char *name;
    long index;			       /* NASM segment id */
    long obj_index;		       /* OBJ-file group index */
    long nentries;		       /* number of elements... */
    long nindices;		       /* ...and number of index elts... */
    union {
	long index;
	char *name;
    } segs[GROUP_MAX];		       /* ...in this */
} *grphead, **grptail, *obj_grp_needs_update;

static struct ImpDef {
    struct ImpDef *next;
    char *extname;
    char *libname;
    unsigned int impindex;
    char *impname;
} *imphead, **imptail;

static struct ExpDef {
    struct ExpDef *next;
    char *intname;
    char *extname;
    unsigned int ordinal;
    int flags;
} *exphead, **exptail;

#define EXPDEF_FLAG_ORDINAL  0x80
#define EXPDEF_FLAG_RESIDENT 0x40
#define EXPDEF_FLAG_NODATA   0x20
#define EXPDEF_MASK_PARMCNT  0x1F

static long obj_entry_seg, obj_entry_ofs;

struct ofmt of_obj;

/* The current segment */
static struct Segment *current_seg;

static long obj_segment (char *, int, int *);
static void obj_write_file(int debuginfo);
static int obj_directive (char *, char *, int);
static void dbgls_createsegs(void) ; /* DAL */


static void obj_init (FILE *fp, efunc errfunc, ldfunc ldef, evalfunc eval) 
{
    ofp = fp;
    error = errfunc;
    evaluate = eval;
    deflabel = ldef;
    first_seg = seg_alloc();
    any_segs = FALSE;
    fpubhead = NULL;
    fpubtail = &fpubhead;
    exthead = NULL;
    exttail = &exthead;
    imphead = NULL;
    imptail = &imphead;
    exphead = NULL;
    exptail = &exphead;
    dws = NULL;
    externals = 0;
    ebhead = NULL;
    ebtail = &ebhead;
    seghead = obj_seg_needs_update = NULL;
    segtail = &seghead;
    grphead = obj_grp_needs_update = NULL;
    grptail = &grphead;
    obj_entry_seg = NO_SEG;
    obj_uppercase = FALSE;
    obj_use32 = FALSE;
    passtwo = 0;
    current_seg = NULL;

    of_obj.current_dfmt->init (&of_obj,NULL,fp,errfunc);
}

static int obj_set_info(enum geninfo type, char **val)
{
    (void) type;
    (void) val;

    return 0;
}
static void obj_cleanup (int debuginfo) 
{
    /* start DAL */
    if (debuginfo && dbg_type == dbg_ls)
        dbgls_createsegs() ;
    /* end DAL */
    obj_write_file(debuginfo);
    of_obj.current_dfmt->cleanup();
    fclose (ofp);
    while (seghead) {
	struct Segment *segtmp = seghead;
	seghead = seghead->next;
	while (segtmp->pubhead) {
	    struct Public *pubtmp = segtmp->pubhead;
	    segtmp->pubhead = pubtmp->next;
	    nasm_free (pubtmp->name);
	    nasm_free (pubtmp);
	}
	nasm_free (segtmp->segclass);
	nasm_free (segtmp->overlay);
	nasm_free (segtmp);
    }
    while (fpubhead) {
	struct Public *pubtmp = fpubhead;
	fpubhead = fpubhead->next;
	nasm_free (pubtmp->name);
	nasm_free (pubtmp);
    }
    while (exthead) {
	struct External *exttmp = exthead;
	exthead = exthead->next;
	nasm_free (exttmp);
    }
    while (imphead) {
	struct ImpDef *imptmp = imphead;
	imphead = imphead->next;
	nasm_free (imptmp->extname);
	nasm_free (imptmp->libname);
	nasm_free (imptmp->impname);   /* nasm_free won't mind if it's NULL */
	nasm_free (imptmp);
    }
    while (exphead) {
	struct ExpDef *exptmp = exphead;
	exphead = exphead->next;
	nasm_free (exptmp->extname);
	nasm_free (exptmp->intname);
	nasm_free (exptmp);
    }
    while (ebhead) {
	struct ExtBack *ebtmp = ebhead;
	ebhead = ebhead->next;
	nasm_free (ebtmp);
    }
    while (grphead) {
	struct Group *grptmp = grphead;
	grphead = grphead->next;
	nasm_free (grptmp);
    }
}

static void obj_ext_set_defwrt (struct External *ext, char *id) 
{
    struct Segment *seg;
    struct Group *grp;

    for (seg = seghead; seg; seg = seg->next)
	if (!strcmp(seg->name, id)) {
	    ext->defwrt_type = DEFWRT_SEGMENT;
	    ext->defwrt_ptr.seg = seg;
	    nasm_free (id);
	    return;
	}

    for (grp = grphead; grp; grp = grp->next)
	if (!strcmp(grp->name, id)) {
	    ext->defwrt_type = DEFWRT_GROUP;
	    ext->defwrt_ptr.grp = grp;
	    nasm_free (id);
	    return;
	}

    ext->defwrt_type = DEFWRT_STRING;
    ext->defwrt_ptr.string = id;
    ext->next_dws = dws;
    dws = ext;
}

static void obj_deflabel (char *name, long segment,
			  long offset, int is_global, char *special) 
{
    /*
     * We have three cases:
     *
     * (i) `segment' is a segment-base. If so, set the name field
     * for the segment or group structure it refers to, and then
     * return.
     *
     * (ii) `segment' is one of our segments, or a SEG_ABS segment.
     * Save the label position for later output of a PUBDEF record.
     * (Or a MODPUB, if we work out how.)
     *
     * (iii) `segment' is not one of our segments. Save the label
     * position for later output of an EXTDEF, and also store a
     * back-reference so that we can map later references to this
     * segment number to the external index.
     */
    struct External *ext;
    struct ExtBack *eb;
    struct Segment *seg;
    int i;
    int used_special = FALSE;	       /* have we used the special text? */

#if defined(DEBUG) && DEBUG>2
fprintf(stderr, " obj_deflabel: %s, seg=%ld, off=%ld, is_global=%d, %s\n",
      name, segment, offset, is_global, special);
#endif

    /*
     * 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] != '@') {
	if (!strcmp(name, "..start")) {
	    obj_entry_seg = segment;
	    obj_entry_ofs = offset;
	    return;
	}
	error (ERR_NONFATAL, "unrecognised special symbol `%s'", name);
    }

    /*
     * Case (i):
     */
    if (obj_seg_needs_update) {
	obj_seg_needs_update->name = name;
	return;
    } else if (obj_grp_needs_update) {
	obj_grp_needs_update->name = name;
	return;
    }
    if (segment < SEG_ABS && segment != NO_SEG && segment % 2)
	return;

    if (segment >= SEG_ABS || segment == NO_SEG) {
	/*
	 * SEG_ABS subcase of (ii).
	 */
	if (is_global) {
	    struct Public *pub;

	    pub = *fpubtail = nasm_malloc(sizeof(*pub));
	    fpubtail = &pub->next;
	    pub->next = NULL;
	    pub->name = nasm_strdup(name);
	    pub->offset = offset;
	    pub->segment = (segment == NO_SEG ? 0 : segment & ~SEG_ABS);
	}
	if (special)
	    error(ERR_NONFATAL, "OBJ supports no special symbol features"
		  " for this symbol type");
	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'.
     */
    if (!any_segs && segment == first_seg) {
	int tempint;		       /* ignored */
	if (segment != obj_segment("__NASMDEFSEG", 2, &tempint))
	    error (ERR_PANIC, "strange segment conditions in OBJ driver");
    }

    for (seg = seghead; seg && is_global; seg = seg->next)
	if (seg->index == segment) {
	    struct Public *loc = nasm_malloc (sizeof(*loc));
	    /*
	     * Case (ii). Maybe MODPUB someday?
	     */
	    *seg->pubtail = loc;
	    seg->pubtail = &loc->next;
	    loc->next = NULL;
	    loc->name = nasm_strdup(name);
	    loc->offset = offset;
                  
	    if (special)
		error(ERR_NONFATAL, "OBJ supports no special symbol features"
		      " for this symbol type");
	    return;
	}

    /*
     * Case (iii).
     */
    if (is_global) {
        ext = *exttail = nasm_malloc(sizeof(*ext));
        ext->next = NULL;
        exttail = &ext->next;
        ext->name = name;
        ext->virtual_parent_obj_index = 0 ; /* DAL */
	/* Place by default all externs into the current segment */
        ext->defwrt_type = DEFWRT_NONE;

/* 28-Apr-2002 - John Coffman
  The following code was introduced on 12-Aug-2000, and breaks fixups
  on code passed thru the MSC 5.1 linker (3.66) and MSC 6.00A linker
  (5.10).  It was introduced after FIXUP32 was added, and may be needed
  for 32-bit segments.  The following will get 16-bit segments working
  again, and maybe someone can correct the 'if' condition which is
  actually needed.
*/
#if 0
	if (current_seg) {
#else
	if (current_seg && current_seg->use32) {
	    if (current_seg->grp) {
		ext->defwrt_type = DEFWRT_GROUP;
		ext->defwrt_ptr.grp = current_seg->grp;
	    } else {
		ext->defwrt_type = DEFWRT_SEGMENT;
		ext->defwrt_ptr.seg = current_seg;
	    }
	}
#endif

        if (is_global == 2) {
	    ext->commonsize = offset;
	    ext->commonelem = 1;	       /* default FAR */
        } else
	    ext->commonsize = 0;
    }
    else
	return;

    /*
     * Now process the special text, if any, to find default-WRT
     * specifications and common-variable element-size and near/far
     * specifications.
     */
    while (special && *special) {
	used_special = TRUE;

	/*
	 * We might have a default-WRT specification.
	 */
	if (!nasm_strnicmp(special, "wrt", 3)) {
	    char *p;

⌨️ 快捷键说明

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