📄 obj386.c
字号:
return sp->mainsym->value.i;
}
default:
DIAG("Unknown segment type in omfGetSeg");
DIAG(sp->name);
return codeseg;
}
// also fix the value.i field of local funcs...
}
//-------------------------------------------------------------------------
void omfputpub(SYM *sp)
{
int l = 0;
char buf[512], obuf[512];
int seg, group, pos;
if (sp->gennedvirtfunc)
return ;
if (sp->value.classdata.templatedata)
return ;
if (sp->value.classdata.cppflags &PF_INLINE)
return ;
if ((sp->tp->cflags &DF_CONST) && scalarnonfloat(sp->tp) && sp
->storage_class == sc_static)
return ;
seg = omfgetseg(sp);
putsym(buf, sp, sp->name);
if (seg != 1 && !(seg &0xc0000000))
group = 1;
else
group = 0;
obuf[0] = group;
l += put_ident(obuf + 1, seg) - 1;
pos = (obuf[2+l] = strlen(buf)) + 3;
strcpy(obuf + 3+l, buf);
*(int*)(obuf + pos + l) = sp->mainsym->offset;
obuf[pos + 4+l] = 0;
emit_record(PUBDEF, obuf, pos + 5+l);
}
//-------------------------------------------------------------------------
void omfpubdumphash(HASHREC **syms)
{
int i;
SYM *sp;
for (i = 0; i < HASHTABLESIZE; i++)
{
if ((sp = (SYM*)syms[i]) != 0)
{
while (sp)
{
if (sp->storage_class == sc_global && !(sp
->value.classdata.cppflags &PF_INLINE))
{
omfputpub(sp);
}
if (sp->storage_class == sc_defunc)
{
SYM *sp1 = sp->tp->lst.head;
while (sp1)
{
if (sp1->storage_class == sc_global && !(sp
->value.classdata.cppflags &PF_INLINE))
{
omfputpub(sp1);
}
sp1 = sp1->next;
}
}
if (sp->storage_class == sc_namespace && !sp
->value.classdata.parentns->anonymous)
omfpubdumphash(sp->value.classdata.parentns->table);
sp = sp->next;
}
}
}
}
//-------------------------------------------------------------------------
void omfPublics(void)
{
SYM *sp;
LIST *lf = localfuncs;
int i;
omfpubdumphash(gsyms);
while (lf)
{
SYM *sp = lf->data;
if (sp->storage_class == sc_global && !(sp->value.classdata.cppflags
&PF_INLINE))
{
omfputpub(sp);
}
lf = lf->link;
}
for (i = 0; i < HASHTABLESIZE; i++)
{
struct _templatelist *tl;
if ((tl = (struct templatelist*)templateFuncs[i]) != 0)
{
while (tl)
{
if (tl->sp->value.classdata.templatedata->hasbody && tl
->finalsp)
{
omfputpub(tl->finalsp);
} tl = tl->next;
}
}
}
}
//-------------------------------------------------------------------------
void omfputexport(SYM *sp)
{
char buf[512], obuf[512];
int l;
putsym(buf, sp, sp->name);
l = strlen(buf);
*(short*)obuf = 0xa000;
obuf[2] = 2; // export
obuf[3] = 0; // export flags
obuf[4] = l;
strcpy(obuf + 5, buf);
buf[5+l] = l;
strcpy(obuf + 6+l, buf);
emit_record(COMENT, obuf, 6+2 * l);
}
//-------------------------------------------------------------------------
void omfExports(void)
{
SYM *sp;
int i;
LIST *lf = localfuncs;
while (lf)
{
sp = lf->data;
if (sp->storage_class == sc_global && sp->mainsym->exportable && !(sp->value.classdata.cppflags & PF_INLINE))
{
omfputexport(sp);
}
lf = lf->link;
}
for (i = 0; i < HASHTABLESIZE; i++)
{
if ((sp = (SYM*)gsyms[i]) != 0)
{
while (sp)
{
if (sp->storage_class == sc_global && sp->mainsym->exportable)
{
omfputexport(sp);
}
if (sp->storage_class == sc_defunc) {
SYM *sp1 = sp->tp->lst.head ;
while (sp1) {
if (sp1->storage_class == sc_global && sp1->mainsym->exportable &&
!(sp1->value.classdata.cppflags & PF_INLINE))
{
omfputexport(sp1);
}
sp1 = sp1->next;
}
}
sp = sp->next;
}
}
}
}
//-------------------------------------------------------------------------
void omfPassSeperator(void)
{
char buf[3];
buf[0] = 0x40;
buf[1] = 0xa2;
buf[2] = 0x01;
emit_record(COMENT, buf, 3);
}
//-------------------------------------------------------------------------
int omfFixups(int seg, EMIT_LIST *rec, char *data, char *buf, int *len)
{
int indent = 0, pos = 0;
int fixeddat = FALSE;
FIXUP *fixups = rec->fixups;
while (fixups)
{
SYM *sp;
int rel = FALSE, iseg;
int fixdat = 0, tdat;
int offset = fixups->address - rec->address;
int locat = (offset >> 8) + (offset << 8);
int segrel = FALSE;
switch (fixups->fmode)
{
case fm_relsymbol:
rel = TRUE;
case fm_symbol:
if (fixups->sym->storage_class == sc_abs)
{
if (rel)
DIAG("Relative absolute in omfFixups");
else
*(int*)(rec->data + offset) += sp->mainsym->offset;
continue;
}
iseg = omfgetseg(fixups->sym);
{
SYM *sp = fixups->sym;
if (sp->mainsym)
sp = sp->mainsym;
if (sp->storage_class == sc_member && sp
->value.classdata.gdeclare && sp
->value.classdata.gdeclare->storage_class == sc_global)
sp = sp->value.classdata.gdeclare;
if (sp->storage_class == sc_global || sp->storage_class ==
sc_static || (sp->storage_class == sc_external || sp
->storage_class == sc_externalfunc) && !sp->mainsym
->extflag)
{
if (rel)
{
if (iseg == seg)
{
*(int*)(data + offset) = sp->mainsym->offset -
fixups->address - 4;
}
else
{
locat |= 0xa4;
fixdat = 0x54;
if (!(iseg &0xc0000000))
tdat = segxlattab[iseg];
else
tdat = iseg;
segrel = TRUE;
*(int*)(data + offset) = sp->mainsym->offset;
}
}
else
{
locat |= 0xe4;
fixdat = 0x04;
if (!(iseg &0xc0000000))
tdat = segxlattab[iseg];
else
tdat = iseg;
// printf("%s:%x:%x:%p:%p\n",sp->name,sp->offset,sp->mainsym->offset,sp,sp->mainsym) ;
*(int*)(data + offset) += sp->mainsym->offset;
segrel = TRUE;
}
/* segment relative */
}
else
{
if (rel)
{
locat |= 0xa4;
fixdat = 0x56;
tdat = sp->value.i;
}
else
{
locat |= 0xe4;
fixdat = 0x06;
tdat = sp->value.i;
}
/* extdef relative */
}
}
break;
case fm_rellabel:
rel = TRUE;
case fm_label:
iseg = LabelSeg(fixups->label);
if (rel)
{
if (iseg == seg)
*(int*)(data + offset) = LabelAddress(fixups->label) -
fixups->address - 4;
else
{
locat |= 0xa4;
fixdat = 0x54;
if (!(iseg &0xc0000000))
tdat = segxlattab[iseg];
else
tdat = iseg;
}
}
else
{
*(int*)(data + offset) += LabelAddress(fixups->label);
locat |= 0xe4;
fixdat = 0x04;
if (!(iseg &0xc0000000))
tdat = segxlattab[iseg];
else
tdat = iseg;
segrel = TRUE;
}
/* segment relative */
break;
}
if (fixdat)
{
int len = 5+((tdat &0x3fffffff) > 127) + !!(tdat &0xc0000000);
if (!fixeddat && pos + len >= 1024)
{
fixeddat = TRUE;
indent = 1024-pos;
pos = 1024;
}
buf[pos++] = locat &0xff;
buf[pos++] = locat >> 8;
if ((fixdat &0x70) == 0x00)
{
if (segrel && (tdat == 2 || tdat == 3 || tdat == segxlattab[4]
|| tdat == segxlattab[5]))
{
buf[pos++] = fixdat | 0x10; /* grouped, 1st group */
buf[pos++] = 1;
}
else
buf[pos++] = fixdat | 0x50;
}
else
buf[pos++] = fixdat;
pos += put_ident(buf + pos, tdat);
if (tdat == 0)
DIAG("omfFixups - null index");
}
fixups = fixups->next;
}
*len = pos;
return indent;
}
//-------------------------------------------------------------------------
void omfComDefData(void)
{
VIRTUAL_LIST *v = virtualFirst;
char buf[1500], *p;
while (v)
{
EMIT_LIST *rec = v->seg->first;
while (rec)
{
int indent;
int len;
char fbuf[2048];
p = buf;
p += put_ident(p, v->sp->value.i);
*((int*)(p))++ = rec->address;
memcpy(p, rec->data, rec->filled);
indent = omfFixups(virtseg, rec, p, fbuf, &len);
emit_record(LEDATA, buf, rec->filled + p - buf);
if (len)
if (len < 1024)
emit_record(FIXUPP, fbuf, len);
else
{
emit_record(FIXUPP, fbuf, 1024-indent);
emit_record(FIXUPP, fbuf + 1024, len - 1024);
}
rec = rec->next;
}
v = v->next;
}
}
//-------------------------------------------------------------------------
void omfData(void)
{
char buf[1100];
int i;
for (i = 1; i < MAX_SEGS; i++)
if (segxlattab[i] && segs[i].curlast)
{
if (i == bssxseg)
{
buf[0] = segxlattab[i];
*(int*)(buf + 1) = 0; /* offset */
*(int*)(buf + 5) = segs[i].curlast; /* repeat count */
*(short*)(buf + 9) = 0; /* block count */
*(buf + 11) = 1; /* num bytes */
*(buf + 12) = 0; /* data */
emit_record(LIDATA, buf, 13);
}
else
{
EMIT_LIST *rec = segs[i].first;
while (rec)
{
int indent;
int len;
char fbuf[2048];
buf[0] = segxlattab[i];
*(int*)(buf + 1) = rec->address;
memcpy(buf + 5, rec->data, rec->filled);
indent = omfFixups(i, rec, buf + 5, fbuf, &len);
emit_record(LEDATA, buf, rec->filled + 5);
if (len)
if (len < 1024)
emit_record(FIXUPP, fbuf, len);
else
{
emit_record(FIXUPP, fbuf, 1024-indent);
emit_record(FIXUPP, fbuf + 1024, len - 1024);
}
rec = rec->next;
}
}
}
}
//-------------------------------------------------------------------------
void omfSourceFile(char *file, int num)
{
unsigned short time, date;
char buf[256];
int fd;
*(short*)buf = 0xe800;
buf[2] = num;
strcpy(buf + 4, fullqualify(file));
buf[3] = strlen(buf + 4);
if (_dos_open(file, 0, &fd))
{
time = 0;
date = 0;
}
else
{
_dos_getftime(fd, &date, &time);
_dos_close(fd);
}
*(short*)(buf + 4+buf[3]) = time;
*(short*)(buf + 6+buf[3]) = date;
emit_record(COMENT, buf, 8+buf[3]);
}
//-------------------------------------------------------------------------
void omfLineNumbers(int file)
{
LINEBUF *l = linelist;
char buf[1100], *p;
int lastnum = - 1;
while (l)
{
p = buf;
*p++ = 0;
*p++ = segxlattab[codeseg];
while (l && p - buf < 1024-6)
{
if (l->file == file)
{
// if (l->address != lastnum) {
*(short*)p = l->lineno;
*(int*)(p + 2) = l->address;
p += 6;
lastnum = l->address;
// }
}
l = l->next;
}
if (p - buf > 2)
{
emit_record(LINNUM, buf, p - buf);
}
}
}
//-------------------------------------------------------------------------
void omfEmitLineInfo(void)
{
int i, q;
FILELIST *l;
omfSourceFile(infile, 1);
omfLineNumbers(0);
for (i = 1, q = 2, l = incfiles; l; i++, l = l->link)
if (l->hascode)
{
omfSourceFile(l->data, q++);
omfLineNumbers(i);
}
}
//-------------------------------------------------------------------------
void omfModEnd(void)
{
char buf = 0;
emit_record(MODEND, &buf, 1);
}
//-------------------------------------------------------------------------
void output_obj_file(void)
{
LIST *l = incfiles;
extIndex = extSize = 0;
omfFileName();
omfTranslatorName();
omfFileTime(fullqualify(infile));
while (l)
{
omfFileTime(l->data);
l = l->link;
}
omfFileTime(0);
omfDebugMarker();
omfLibMod();
omfLNames();
omfSegs();
omfComDefs();
omfGroups();
omfExtDefs();
omfImports();
omfPublics();
omfExports();
omfPassSeperator();
if (prm_debug)
omfEmitLineInfo();
omfComDefData();
omfData();
omfModEnd();
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -