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

📄 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 页
字号:
	seg->orp = obj_new();
	seg->orp->up = &(seg->orp);
	seg->orp->ori = ori_ledata;
	seg->orp->type = LEDATA;
	seg->orp->parm[1] = obj_idx;
    seg->lsdebseg = -1 ; /* DAL */

	/*
	 * Process the segment attributes.
	 */
	p = name;
	while (attrs--) {
	    p += strlen(p);
	    while (!*p) p++;

	    /*
	     * `p' contains a segment attribute.
	     */
	    if (!nasm_stricmp(p, "private"))
		seg->combine = CMB_PRIVATE;
	    else if (!nasm_stricmp(p, "public"))
		seg->combine = CMB_PUBLIC;
	    else if (!nasm_stricmp(p, "common"))
		seg->combine = CMB_COMMON;
	    else if (!nasm_stricmp(p, "stack"))
		seg->combine = CMB_STACK;
/* DAL */
       else if (!nasm_stricmp(p, "virtual")) {
      struct External *ext ;
      seg->combine = CMB_BORLANDVIRTUAL ;
      seg->obj_index = obj_idx = ++externals | 0xc0000 ;
      seg->orp->parm[1] = obj_idx;
	  seg->use32 = current_seg->use32 ;
	  seg->align = current_seg->align ;
        ext = *exttail = nasm_malloc(sizeof(*ext));
        ext->next = NULL;
        exttail = &ext->next;
        ext->name = nasm_strdup(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) {
		ext->defwrt_type = DEFWRT_SEGMENT;
		ext->defwrt_ptr.seg = seg;
	}
#endif

	    ext->commonsize = 0;
      if (current_seg)
     ext->virtual_parent_obj_index = current_seg->obj_index ;
      else
     ext->virtual_parent_obj_index = 1 ;
       }
/* END DAL */
	    else if (!nasm_stricmp(p, "use16"))
		seg->use32 = FALSE;
	    else if (!nasm_stricmp(p, "use32"))
		seg->use32 = TRUE;
	    else if (!nasm_stricmp(p, "flat")) {
		/*
		 * This segment is an OS/2 FLAT segment. That means
		 * that its default group is group FLAT, even if
		 * the group FLAT does not explicitly _contain_ the
		 * segment.
		 * 
		 * When we see this, we must create the group
		 * `FLAT', containing no segments, if it does not
		 * already exist; then we must set the default
		 * group of this segment to be the FLAT group.
		 */
		struct Group *grp;
		for (grp = grphead; grp; grp = grp->next)
		    if (!strcmp(grp->name, "FLAT"))
			break;
		if (!grp) {
		    obj_directive ("group", "FLAT", 1);
		    for (grp = grphead; grp; grp = grp->next)
			if (!strcmp(grp->name, "FLAT"))
			    break;
		    if (!grp)
			error (ERR_PANIC, "failure to define FLAT?!");
		}
		seg->grp = grp;
        /* DAL start */
        } else if (!nasm_strnicmp(p, "lsdebseg=",9)) {
            if (!nasm_strnicmp(p+9,"code",4)) {
                seg->lsdebseg = 1 ;
            } else if (!nasm_strnicmp(p+9,"data",4)) {
                seg->lsdebseg = 2 ;
            } else if (!nasm_strnicmp(p+9,"bss",3)) {
                seg->lsdebseg = 3 ;
            } else if (!nasm_strnicmp(p+9,"const",5)) {
                seg->lsdebseg = 4 ;
            } else if (!nasm_strnicmp(p+9,"string",6)) {
                seg->lsdebseg = 5 ;
            } else
                error(ERR_NONFATAL, "Invalid LS debug segment type") ;
        /* DAL end */        
        } else if (!nasm_strnicmp(p, "class=", 6)) {
		seg->segclass = nasm_strdup(p+6);
            /* START DAL */
            if (seg->lsdebseg == -1) 
                if (!nasm_strnicmp(p+6,"code",4)) {
                    seg->lsdebseg = 1 ;
                } else if (!nasm_strnicmp(p+6,"data",4)) {
                    seg->lsdebseg = 2 ;
                } else if (!nasm_strnicmp(p+6,"bss",3)) {
                    seg->lsdebseg = 3 ;
                } else if (!nasm_strnicmp(p+6,"const",5)) {
                    seg->lsdebseg = 4 ;
                } else if (!nasm_strnicmp(p+6,"string",6)) {
                    seg->lsdebseg = 5 ;
                }
            /* END DAL */
        } else if (!nasm_strnicmp(p, "overlay=", 8))
		seg->overlay = nasm_strdup(p+8);
	    else if (!nasm_strnicmp(p, "align=", 6)) {
		seg->align = readnum(p+6, &rn_error);
		if (rn_error) {
		    seg->align = 1;
		    error (ERR_NONFATAL, "segment alignment should be"
			   " numeric");
		}
		switch ((int) seg->align) {
		  case 1:	       /* BYTE */
		  case 2:	       /* WORD */
		  case 4:	       /* DWORD */
		  case 16:	       /* PARA */
		  case 256:	       /* PAGE */
		  case 4096:	       /* PharLap extension */
		    break;
		  case 8:
		    error(ERR_WARNING, "OBJ format does not support alignment"
			  " of 8: rounding up to 16");
		    seg->align = 16;
		    break;
		  case 32:
		  case 64:
		  case 128:
		    error(ERR_WARNING, "OBJ format does not support alignment"
			  " of %d: rounding up to 256", seg->align);
		    seg->align = 256;
		    break;
		  case 512:
		  case 1024:
		  case 2048:
		    error(ERR_WARNING, "OBJ format does not support alignment"
			  " of %d: rounding up to 4096", seg->align);
		    seg->align = 4096;
		    break;
		  default:
		    error(ERR_NONFATAL, "invalid alignment value %d",
			  seg->align);
		    seg->align = 1;
		    break;
		}
	    } else if (!nasm_strnicmp(p, "absolute=", 9)) {
		seg->align = SEG_ABS + readnum(p+9, &rn_error);
		if (rn_error)
		    error (ERR_NONFATAL, "argument to `absolute' segment"
			   " attribute should be numeric");
	    }
	}

        /* We need to know whenever we have at least one 32-bit segment */
        obj_use32 |= seg->use32;

	obj_seg_needs_update = seg;
	if (seg->align >= SEG_ABS)
	    deflabel (name, NO_SEG, seg->align - SEG_ABS,
		      NULL, FALSE, FALSE, &of_obj, error);
	else
	    deflabel (name, seg->index+1, 0L,
		      NULL, FALSE, FALSE, &of_obj, error);
	obj_seg_needs_update = NULL;

	/*
	 * See if this segment is defined in any groups.
	 */
	for (grp = grphead; grp; grp = grp->next) {
	    for (i = grp->nindices; i < grp->nentries; i++) {
		if (!strcmp(grp->segs[i].name, seg->name)) {
		    nasm_free (grp->segs[i].name);
		    grp->segs[i] = grp->segs[grp->nindices];
		    grp->segs[grp->nindices++].index = seg->obj_index;
		    if (seg->grp)
			error(ERR_WARNING, "segment `%s' is already part of"
			      " a group: first one takes precedence",
			      seg->name);
		    else
			seg->grp = grp;
		}
	    }
	}

	/*
	 * Walk through the list of externals with unresolved
	 * default-WRT clauses, and resolve any that point at this
	 * segment.
	 */
	extp = &dws;
	while (*extp) {
	    if ((*extp)->defwrt_type == DEFWRT_STRING &&
		!strcmp((*extp)->defwrt_ptr.string, seg->name)) {
		nasm_free((*extp)->defwrt_ptr.string);
		(*extp)->defwrt_type = DEFWRT_SEGMENT;
		(*extp)->defwrt_ptr.seg = seg;
		*extp = (*extp)->next_dws;
	    } else
		extp = &(*extp)->next_dws;
	}

	if (seg->use32)
	    *bits = 32;
	else
	    *bits = 16;
	current_seg = seg;
	return seg->index;
    }
}

static int obj_directive (char *directive, char *value, int pass) 
{
    if (!strcmp(directive, "group")) {
	char *p, *q, *v;
	if (pass == 1) {
	    struct Group *grp;
	    struct Segment *seg;
	    struct External **extp;
	    int obj_idx;

	    q = value;
	    while (*q == '.')
		q++;		       /* hack, but a documented one */
	    v = q;
	    while (*q && !isspace(*q))
		q++;
	    if (isspace(*q)) {
		*q++ = '\0';
		while (*q && isspace(*q))
		    q++;
	    }
	    /*
	     * Here we used to sanity-check the group directive to
	     * ensure nobody tried to declare a group containing no
	     * segments. However, OS/2 does this as standard
	     * practice, so the sanity check has been removed.
	     *
	     * if (!*q) {
	     *     error(ERR_NONFATAL,"GROUP directive contains no segments");
	     *     return 1;
	     * }
	     */

	    obj_idx = 1;
	    for (grp = grphead; grp; grp = grp->next) {
		obj_idx++;
		if (!strcmp(grp->name, v)) {
		    error(ERR_NONFATAL, "group `%s' defined twice", v);
		    return 1;
		}
	    }

	    *grptail = grp = nasm_malloc(sizeof(*grp));
	    grp->next = NULL;
	    grptail = &grp->next;
	    grp->index = seg_alloc();
	    grp->obj_index = obj_idx;
	    grp->nindices = grp->nentries = 0;
	    grp->name = NULL;

	    obj_grp_needs_update = grp;
	    deflabel (v, grp->index+1, 0L,
		      NULL, FALSE, FALSE, &of_obj, error);
	    obj_grp_needs_update = NULL;

	    while (*q) {
		p = q;
		while (*q && !isspace(*q))
		    q++;
		if (isspace(*q)) {
		    *q++ = '\0';
		    while (*q && isspace(*q))
			q++;
		}
		/*
		 * Now p contains a segment name. Find it.
		 */
		for (seg = seghead; seg; seg = seg->next)
		    if (!strcmp(seg->name, p))
			break;
		if (seg) {
		    /*
		     * We have a segment index. Shift a name entry
		     * to the end of the array to make room.
		     */
		    grp->segs[grp->nentries++] = grp->segs[grp->nindices];
		    grp->segs[grp->nindices++].index = seg->obj_index;
		    if (seg->grp)
			error(ERR_WARNING, "segment `%s' is already part of"
			      " a group: first one takes precedence",
			      seg->name);
		    else
			seg->grp = grp;
		} else {
		    /*
		     * We have an as-yet undefined segment.
		     * Remember its name, for later.
		     */
		    grp->segs[grp->nentries++].name = nasm_strdup(p);
		}
	    }

	    /*
	     * Walk through the list of externals with unresolved
	     * default-WRT clauses, and resolve any that point at
	     * this group.
	     */
	    extp = &dws;
	    while (*extp) {
		if ((*extp)->defwrt_type == DEFWRT_STRING &&
		    !strcmp((*extp)->defwrt_ptr.string, grp->name)) {
		    nasm_free((*extp)->defwrt_ptr.string);
		    (*extp)->defwrt_type = DEFWRT_GROUP;
		    (*extp)->defwrt_ptr.grp = grp;
		    *extp = (*extp)->next_dws;
	    } else
		    extp = &(*extp)->next_dws;
	    }
	}
	return 1;
    }
    if (!strcmp(directive, "uppercase")) {
	obj_uppercase = TRUE;
	return 1;
    }
    if (!strcmp(directive, "import")) {
	char *q, *extname, *libname, *impname;

	if (pass == 2)
	    return 1;		       /* ignore in pass two */
	extname = q = value;
	while (*q && !isspace(*q))
	    q++;
	if (isspace(*q)) {
	    *q++ = '\0';
	    while (*q && isspace(*q))
		q++;
	}

	libname = q;
	while (*q && !isspace(*q))
	    q++;
	if (isspace(*q)) {
	    *q++ = '\0';
	    while (*q && isspace(*q))
		q++;
	}

	impname = q;

	if (!*extname || !*libname)
	    error(ERR_NONFATAL, "`import' directive requires symbol name"
		  " and library name");
	else {
	    struct ImpDef *imp;
	    int err = FALSE;

	    imp = *imptail = nasm_malloc(sizeof(struct ImpDef));
	    imptail = &imp->next;
	    imp->next = NULL;
	    imp->extname = nasm_strdup(extname);
	    imp->libname = nasm_strdup(libname);
	    imp->impindex = readnum(impname, &err);
	    if (!*impname || err)
		imp->impname = nasm_strdup(impname);
	    else
		imp->impname = NULL;
	}

	return 1;
    }
    if (!strcmp(directive, "export")) {
	char *q, *extname, *intname, *v;
	struct ExpDef *export;
	int flags = 0;
	unsigned int ordinal = 0;

	if (pass == 2)
	    return 1;		       /* ignore in pass two */
	intname = q = value;
	while (*q && !isspace(*q))
	    q++;
	if (isspace(*q)) {
	    *q++ = '\0';
	    while (*q && isspace(*q))
		q++;
	}

	extname = q;
	while (*q && !isspace(*q))
	    q++;
	if (isspace(*q)) {
	    *q++ = '\0';
	    while (*q && isspace(*q))
		q++;
	}

	if (!*intname) {
	    error(ERR_NONFATAL, "`export' directive requires export name");
	    return 1;
	}
	if (!*extname) {
	    extname = intname;
	    intname = "";
	}
	while (*q) {
	    v = q;
	    while (*q && !isspace(*q))
		q++;
	    if (isspace(*q)) {
		*q++ = '\0';
		while (*q && isspace(*q))
		    q++;
	    }
	    if (!nasm_stricmp(v, "resident"))
		flags |= EXPDEF_FLAG_RESIDENT;
	    else if (!nasm_stricmp(v, "nodata"))
		flags |= EXPDEF_FLAG_NODATA;
	    else if (!nasm_strnicmp(v, "parm=", 5)) {
		int err = FALSE;
		flags |= EXPDEF_MASK_PARMCNT & readnum(v+5, &err);
		if (err) {
		    error(ERR_NONFATAL,
			  "value `%s' for `parm' is non-numeric", v+5);
		    return 1;
		}
	    } else {
		int err = FALSE;
		ordinal = readnum(v, &err);
		if (err) {
		    error(ERR_NONFATAL, "unrecognised export qualifier `%s'",
			  v);
		    return 1;
		}
		flags |= EXPDEF_FLAG_ORDINAL;
	    }
	}

	export = *exptail = nasm_malloc(sizeof(struct ExpDef));
	exptail = &export->next;
	export->next = NULL;
	export->extname = nasm_strdup(extname);
	export->intname = nasm_strdup(intname);
	export->ordinal = ordinal;

⌨️ 快捷键说明

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