📄 outobj.c
字号:
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 + -