📄 outieee.c
字号:
break;
i -= EXT_BLKSIZ;
}
/* if we have an extern decide the type and make a record
*/
if (eb) {
s.ftype = FT_EXTWRT;
s.addend = 0;
s.id2 = eb->index[i];
} else
error(ERR_NONFATAL,
"Source of WRT must be an offset");
}
} else
error(ERR_PANIC,
"unrecognised WRT value in ieee_write_fixup");
} else
error(ERR_NONFATAL, "target of WRT must be a section ");
}
s.size = size;
ieee_install_fixup(segto, &s);
return;
}
/* Pure segment fixup ? */
if (segment != NO_SEG) {
s.ftype = FT_SEG;
s.id1 = 0;
if (segment >= SEG_ABS) {
/* absolute far segment fixup */
s.id1 = -(segment - ~SEG_ABS);
} else if (segment % 2) {
/* fixup to named segment */
/* look it up */
for (target = seghead; target; target = target->next)
if (target->index == segment - 1)
break;
if (target)
s.id1 = target->ieee_index;
else {
/*
* Now we assume the segment field is being used
* to hold an extern index
*/
long i = segment / 2;
struct ExtBack *eb = ebhead;
while (i > EXT_BLKSIZ) {
if (eb)
eb = eb->next;
else
break;
i -= EXT_BLKSIZ;
}
/* if we have an extern decide the type and make a record
*/
if (eb) {
if (realtype == OUT_REL2ADR || realtype == OUT_REL4ADR) {
error(ERR_PANIC,
"Segment of a rel not supported in ieee_write_fixup");
} else {
/* If we want the segment */
s.ftype = FT_EXTSEG;
s.addend = 0;
s.id1 = eb->index[i];
}
} else
/* If we get here the seg value doesn't make sense */
error(ERR_PANIC,
"unrecognised segment value in ieee_write_fixup");
}
} else {
/* Assume we are offsetting directly from a section
* So look up the target segment
*/
for (target = seghead; target; target = target->next)
if (target->index == segment)
break;
if (target) {
if (realtype == OUT_REL2ADR || realtype == OUT_REL4ADR) {
/* PC rel to a known offset */
s.id1 = target->ieee_index;
s.ftype = FT_REL;
s.size = size;
s.addend = offset;
} else {
/* We were offsetting from a seg */
s.id1 = target->ieee_index;
s.ftype = FT_OFS;
s.size = size;
s.addend = offset;
}
} else {
/*
* Now we assume the segment field is being used
* to hold an extern index
*/
long i = segment / 2;
struct ExtBack *eb = ebhead;
while (i > EXT_BLKSIZ) {
if (eb)
eb = eb->next;
else
break;
i -= EXT_BLKSIZ;
}
/* if we have an extern decide the type and make a record
*/
if (eb) {
if (realtype == OUT_REL2ADR || realtype == OUT_REL4ADR) {
s.ftype = FT_EXTREL;
s.addend = 0;
s.id1 = eb->index[i];
} else {
/* else we want the external offset */
s.ftype = FT_EXT;
s.addend = 0;
s.id1 = eb->index[i];
}
} else
/* If we get here the seg value doesn't make sense */
error(ERR_PANIC,
"unrecognised segment value in ieee_write_fixup");
}
}
if (size != 2 && s.ftype == FT_SEG)
error(ERR_NONFATAL, "IEEE format can only handle 2-byte"
" segment base references");
s.size = size;
ieee_install_fixup(segto, &s);
return;
}
/* should never get here */
}
static void ieee_install_fixup(struct ieeeSection *seg,
struct ieeeFixupp *fix)
{
struct ieeeFixupp *f;
f = nasm_malloc(sizeof(struct ieeeFixupp));
memcpy(f, fix, sizeof(struct ieeeFixupp));
f->offset = seg->currentpos;
seg->currentpos += fix->size;
f->next = NULL;
if (seg->fptr)
seg->flptr = seg->flptr->next = f;
else
seg->fptr = seg->flptr = f;
}
/*
* segment registry
*/
static long ieee_segment(char *name, int pass, int *bits)
{
/*
* We call the label manager here to define a name for the new
* segment, and when our _own_ label-definition stub gets
* called in return, it should register the new segment name
* using the pointer it gets passed. That way we save memory,
* by sponging off the label manager.
*/
if (!name) {
*bits = 16;
if (!any_segs)
return 0;
return seghead->index;
} else {
struct ieeeSection *seg;
int ieee_idx, attrs, rn_error;
char *p;
/*
* Look for segment attributes.
*/
attrs = 0;
while (*name == '.')
name++; /* hack, but a documented one */
p = name;
while (*p && !isspace(*p))
p++;
if (*p) {
*p++ = '\0';
while (*p && isspace(*p))
*p++ = '\0';
}
while (*p) {
while (*p && !isspace(*p))
p++;
if (*p) {
*p++ = '\0';
while (*p && isspace(*p))
*p++ = '\0';
}
attrs++;
}
ieee_idx = 1;
for (seg = seghead; seg; seg = seg->next) {
ieee_idx++;
if (!strcmp(seg->name, name)) {
if (attrs > 0 && pass == 1)
error(ERR_WARNING, "segment attributes specified on"
" redeclaration of segment: ignoring");
if (seg->use32)
*bits = 32;
else
*bits = 16;
return seg->index;
}
}
*segtail = seg = nasm_malloc(sizeof(*seg));
seg->next = NULL;
segtail = &seg->next;
seg->index = seg_alloc();
seg->ieee_index = ieee_idx;
any_segs = TRUE;
seg->name = NULL;
seg->currentpos = 0;
seg->align = 1; /* default */
seg->use32 = *bits == 32; /* default to user spec */
seg->combine = CMB_PUBLIC; /* default */
seg->pubhead = NULL;
seg->pubtail = &seg->pubhead;
seg->data = NULL;
seg->fptr = NULL;
seg->lochead = NULL;
seg->loctail = &seg->lochead;
/*
* 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, "use16"))
seg->use32 = FALSE;
else if (!nasm_stricmp(p, "use32"))
seg->use32 = TRUE;
else if (!nasm_strnicmp(p, "align=", 6)) {
seg->align = readnum(p + 6, &rn_error);
if (seg->align == 0)
seg->align = 1;
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 8:
case 32:
case 64:
case 128:
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");
}
}
ieee_seg_needs_update = seg;
if (seg->align >= SEG_ABS)
deflabel(name, NO_SEG, seg->align - SEG_ABS,
NULL, FALSE, FALSE, &of_ieee, error);
else
deflabel(name, seg->index + 1, 0L,
NULL, FALSE, FALSE, &of_ieee, error);
ieee_seg_needs_update = NULL;
if (seg->use32)
*bits = 32;
else
*bits = 16;
return seg->index;
}
}
/*
* directives supported
*/
static int ieee_directive(char *directive, char *value, int pass)
{
(void)value;
(void)pass;
if (!strcmp(directive, "uppercase")) {
ieee_uppercase = TRUE;
return 1;
}
return 0;
}
/*
* Return segment data
*/
static long ieee_segbase(long segment)
{
struct ieeeSection *seg;
/*
* Find the segment in our list.
*/
for (seg = seghead; seg; seg = seg->next)
if (seg->index == segment - 1)
break;
if (!seg)
return segment; /* not one of ours - leave it alone */
if (seg->align >= SEG_ABS)
return seg->align; /* absolute segment */
return segment; /* no special treatment */
}
/*
* filename
*/
static void ieee_filename(char *inname, char *outname, efunc error)
{
strcpy(ieee_infile, inname);
standard_extension(inname, outname, ".o", error);
}
static void ieee_write_file(int debuginfo)
{
struct tm *thetime;
time_t reltime;
struct FileName *fn;
struct ieeeSection *seg;
struct ieeePublic *pub, *loc;
struct ieeeExternal *ext;
struct ieeeObjData *data;
struct ieeeFixupp *fix;
struct Array *arr;
static char boast[] = "The Netwide Assembler " NASM_VER;
int i;
/*
* Write the module header
*/
ieee_putascii("MBFNASM,%02X%s.\r\n", strlen(ieee_infile), ieee_infile);
/*
* Write the NASM boast comment.
*/
ieee_putascii("CO0,%02X%s.\r\n", strlen(boast), boast);
/*
* write processor-specific information
*/
ieee_putascii("AD8,4,L.\r\n");
/*
* date and time
*/
time(&reltime);
thetime = localtime(&reltime);
ieee_putascii("DT%04d%02d%02d%02d%02d%02d.\r\n",
1900 + thetime->tm_year, thetime->tm_mon + 1,
thetime->tm_mday, thetime->tm_hour, thetime->tm_min,
thetime->tm_sec);
/*
* if debugging, dump file names
*/
for (fn = fnhead; fn && debuginfo; fn = fn->next) {
ieee_putascii("C0105,%02X%s.\r\n", strlen(fn->name), fn->name);
}
ieee_putascii("CO101,07ENDHEAD.\r\n");
/*
* the standard doesn't specify when to put checksums,
* we'll just do it periodically.
*/
ieee_putcs(FALSE);
/*
* Write the section headers
*/
seg = seghead;
if (!debuginfo && !strcmp(seg->name, "??LINE"))
seg = seg->next;
while (seg) {
char buf[256];
char attrib;
switch (seg->combine) {
case CMB_PUBLIC:
default:
attrib = 'C';
break;
case CMB_PRIVATE:
attrib = 'S';
break;
case CMB_COMMON:
attrib = 'M';
break;
}
ieee_unqualified_name(buf, seg->name);
if (seg->align >= SEG_ABS) {
ieee_putascii("ST%X,A,%02X%s.\r\n", seg->ieee_index,
strlen(buf), buf);
ieee_putascii("ASL%X,%lX.\r\n", seg->ieee_index,
(seg->align - SEG_ABS) * 16);
} else {
ieee_putascii("ST%X,%c,%02X%s.\r\n", seg->ieee_index, attrib,
strlen(buf), buf);
ieee_putascii("SA%X,%lX.\r\n", seg->ieee_index, seg->align);
ieee_putascii("ASS%X,%X.\r\n", seg->ieee_index,
seg->currentpos);
}
seg = seg->next;
}
/*
* write the start address if there is one
*/
if (ieee_entry_seg) {
for (seg = seghead; seg; seg = seg->next)
if (seg->index == ieee_entry_seg)
break;
if (!seg)
error(ERR_PANIC, "Start address records are incorrect");
else
ieee_putascii("ASG,R%X,%lX,+.\r\n", seg->ieee_index,
ieee_entry_ofs);
}
ieee_putcs(FALSE);
/*
* Write the publics
*/
i = 1;
for (seg = seghead; seg; seg = seg->next) {
for (pub = seg->pubhead; pub; pub = pub->next) {
char buf[256];
ieee_unqualified_name(buf, pub->name);
ieee_putascii("NI%X,%02X%s.\r\n", i, strlen(buf), buf);
if (pub->segment == -1)
ieee_putascii("ASI%X,R%X,%lX,+.\r\n", i, pub->index,
pub->offset);
else
ieee_putascii("ASI%X,%lX,%lX,+.\r\n", i, pub->segment * 16,
pub->offset);
if (debuginfo) {
if (pub->type >= 0x100)
ieee_putascii("ATI%X,T%X.\r\n", i, pub->type - 0x100);
else
ieee_putascii("ATI%X,%X.\r\n", i, pub->type);
}
i++;
}
}
pub = fpubhead;
i = 1;
while (pub) {
char buf[256];
ieee_unqualified_name(buf, pub->name);
ieee_putascii("NI%X,%02X%s.\r\n", i, strlen(buf), buf);
if (pub->segment == -1)
ieee_putascii("ASI%X,R%X,%lX,+.\r\n", i, pub->index,
pub->offset);
else
ieee_putascii("ASI%X,%lX,%lX,+.\r\n", i, pub->segment * 16,
pub->offset);
if (debuginfo) {
if (pub->type >= 0x100)
ieee_putascii("ATI%X,T%X.\r\n", i, pub->type - 0x100);
else
ieee_putascii("ATI%X,%X.\r\n", i, pub->type);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -