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

📄 outobj.c

📁 开源的nasm编译器源码,研究编译器原理很有帮且
💻 C
📖 第 1 页 / 共 5 页
字号:
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 */} *fpubhead, **fpubtail, *last_defined;static struct External {    struct External *next;    char *name;    long commonsize;    long commonelem;		       /* element size if FAR, else zero */    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    } 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;} *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  0x1Fstatic 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 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) {    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>2fprintf(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;	/* 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;	    int len;	    special += 3;	    special += strspn(special, " \t");	    p = nasm_strndup(special, len = strcspn(special, ":"));	    obj_ext_set_defwrt (ext, p);	    special += len;	    if (*special && *special != ':')		error(ERR_NONFATAL, "`:' expected in special symbol"		      " text for `%s'", ext->name);	    else if (*special == ':')		special++;	}	/*	 * The NEAR or FAR keywords specify nearness or	 * farness. FAR gives default element size 1.	 */	if (!nasm_strnicmp(special, "far", 3)) {	    if (ext->commonsize)		ext->commonelem = 1;	    else		error(ERR_NONFATAL, "`%s': `far' keyword may only be applied"		      " to common variables\n", ext->name);	    special += 3;	    special += strspn(special, " \t");	} else if (!nasm_strnicmp(special, "near", 4)) {	    if (ext->commonsize)		ext->commonelem = 0;	    else		error(ERR_NONFATAL, "`%s': `far' keyword may only be applied"		      " to common variables\n", ext->name);	    special += 4;	    special += strspn(special, " \t");	}	/*	 * If it's a common, and anything else remains on the line	 * before a further colon, evaluate it as an expression and	 * use that as the element size. Forward references aren't	 * allowed.	 */	if (*special == ':')	    special++;	else if (*special) {	    if (ext->commonsize) {		expr *e;		struct tokenval tokval;		stdscan_reset();		stdscan_bufptr = special;		tokval.t_type = TOKEN_INVALID;		e = evaluate(stdscan, NULL, &tokval, NULL, 1, error, NULL);		if (e) {		    if (!is_simple(e))			error (ERR_NONFATAL, "cannot use relocatable"			       " expression as common-variable element size");		    else			ext->commonelem = reloc_value(e);		}		special = stdscan_bufptr;	    } else {		error (ERR_NONFATAL, "`%s': element-size specifications only"		       " apply to common variables", ext->name);		while (*special && *special != ':')		    special++;		if (*special == ':')		    special++;	    }	}    }    i = segment/2;    eb = ebhead;    if (!eb) {	eb = *ebtail = nasm_malloc(sizeof(*eb));	eb->next = NULL;	ebtail = &eb->next;    }    while (i >= EXT_BLKSIZ) {	if (eb && eb->next)	    eb = eb->next;	else {	    eb = *ebtail = nasm_malloc(sizeof(*eb));	    eb->next = NULL;	    ebtail = &eb->next;	}	i -= EXT_BLKSIZ;    }    eb->exts[i] = ext;    ext->index = ++externals;    if (special && !used_special)	error(ERR_NONFATAL, "OBJ supports no special symbol features"	      " for this symbol type");}/* forward declaration */static void obj_write_fixup (ObjRecord *orp, int bytes,    int segrel, long seg, long wrt, struct Segment *segto);static void obj_out (long segto, const void *data, unsigned long type,		     long segment, long wrt) {    unsigned long size, realtype;    const unsigned char *ucdata;    long ldata;    struct Segment *seg;    ObjRecord *orp;

⌨️ 快捷键说明

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