📄 outcoff.c
字号:
char *q, *name;
if (pass == 2)
return 1; /* ignore in pass two */
name = q = value;
while (*q && !nasm_isspace(*q))
q++;
if (nasm_isspace(*q)) {
*q++ = '\0';
while (*q && nasm_isspace(*q))
q++;
}
if (!*name) {
error(ERR_NONFATAL, "`export' directive requires export name");
return 1;
}
if (*q) {
error(ERR_NONFATAL, "unrecognized export qualifier `%s'", q);
return 1;
}
AddExport(name);
return 1;
} else if (win32 && !strcmp(directive,"safeseh")) {
static int sxseg=-1;
int i;
if (sxseg==-1)
{ for (i = 0; i < nsects; i++)
if (!strcmp(".sxdata",sects[i]->name))
break;
if (i == nsects)
sxseg = coff_make_section(".sxdata",0x200);
else
sxseg = i;
}
if (pass==2) {
uint32_t n;
saa_rewind(syms);
for (n = 0; n < nsyms; n++) {
struct Symbol *sym = saa_rstruct(syms);
bool equals;
/* sym->strpos is biased by 4, because symbol
* table is prefixed with table length */
if (sym->strpos >=4) {
char *name = nasm_malloc(sym->namlen+1);
saa_fread(strs, sym->strpos-4, name, sym->namlen);
name[sym->namlen] = '\0';
equals = !strcmp(value,name);
nasm_free(name);
}
else
equals = !strcmp(value,sym->name);
if (equals) {
/* this value arithmetics effectively reflects
* initsym in coff_write(): 2 for file, 1 for
* .absolute and two per each section */
unsigned char value[4],*p=value;
WRITELONG(p,n + 2 + 1 + nsects*2);
coff_sect_write(sects[sxseg],value,4);
sym->type = 0x20;
break;
}
}
if (n == nsyms) {
error(ERR_NONFATAL,
"`safeseh' directive requires valid symbol");
}
}
return 1;
}
return 0;
}
static void coff_write(void)
{
int32_t pos, sympos, vsize;
int i;
BuildExportTable(); /* fill in the .drectve section with -export's */
if (win32) {
/* add default value for @feat.00, this allows to 'link /safeseh' */
uint32_t n;
saa_rewind(syms);
for (n = 0; n < nsyms; n++) {
struct Symbol *sym = saa_rstruct(syms);
if (sym->strpos == -1 && !strcmp("@feat.00",sym->name))
break;
}
if (n == nsyms)
coff_deflabel("@feat.00",NO_SEG,1,0,NULL);
}
/*
* Work out how big the file will get. Calculate the start of
* the `real' symbols at the same time.
*/
pos = 0x14 + 0x28 * nsects;
initsym = 3; /* two for the file, one absolute */
for (i = 0; i < nsects; i++) {
if (sects[i]->data) {
sects[i]->pos = pos;
pos += sects[i]->len;
sects[i]->relpos = pos;
pos += 10 * sects[i]->nrelocs;
} else
sects[i]->pos = sects[i]->relpos = 0L;
initsym += 2; /* two for each section */
}
sympos = pos;
/*
* Output the COFF header.
*/
if (win64)
fwriteint16_t(0x8664, coffp); /* MACHINE_x86-64 */
else
fwriteint16_t(0x014C, coffp); /* MACHINE_i386 */
fwriteint16_t(nsects, coffp); /* number of sections */
fwriteint32_t(time(NULL), coffp); /* time stamp */
fwriteint32_t(sympos, coffp);
fwriteint32_t(nsyms + initsym, coffp);
fwriteint16_t(0, coffp); /* no optional header */
/* Flags: 32-bit, no line numbers. Win32 doesn't even bother with them. */
fwriteint16_t((win32 | win64) ? 0 : 0x104, coffp);
/*
* Output the section headers.
*/
vsize = 0L;
for (i = 0; i < nsects; i++) {
coff_section_header(sects[i]->name, vsize, sects[i]->len,
sects[i]->pos, sects[i]->relpos,
sects[i]->nrelocs, sects[i]->flags);
vsize += sects[i]->len;
}
/*
* Output the sections and their relocations.
*/
for (i = 0; i < nsects; i++)
if (sects[i]->data) {
saa_fpwrite(sects[i]->data, coffp);
coff_write_relocs(sects[i]);
}
/*
* Output the symbol and string tables.
*/
coff_write_symbols();
fwriteint32_t(strslen + 4, coffp); /* length includes length count */
saa_fpwrite(strs, coffp);
}
static void coff_section_header(char *name, int32_t vsize,
int32_t datalen, int32_t datapos,
int32_t relpos, int nrelocs, int32_t flags)
{
char padname[8];
(void)vsize;
memset(padname, 0, 8);
strncpy(padname, name, 8);
fwrite(padname, 8, 1, coffp);
fwriteint32_t(0, coffp); /* Virtual size field - set to 0 or vsize */
fwriteint32_t(0L, coffp); /* RVA/offset - we ignore */
fwriteint32_t(datalen, coffp);
fwriteint32_t(datapos, coffp);
fwriteint32_t(relpos, coffp);
fwriteint32_t(0L, coffp); /* no line numbers - we don't do 'em */
fwriteint16_t(nrelocs, coffp);
fwriteint16_t(0, coffp); /* again, no line numbers */
fwriteint32_t(flags, coffp);
}
static void coff_write_relocs(struct Section *s)
{
struct Reloc *r;
for (r = s->head; r; r = r->next) {
fwriteint32_t(r->address, coffp);
fwriteint32_t(r->symbol + (r->symbase == REAL_SYMBOLS ? initsym :
r->symbase == ABS_SYMBOL ? initsym - 1 :
r->symbase == SECT_SYMBOLS ? 2 : 0),
coffp);
fwriteint16_t(r->type, coffp);
}
}
static void coff_symbol(char *name, int32_t strpos, int32_t value,
int section, int type, int storageclass, int aux)
{
char padname[8];
if (name) {
memset(padname, 0, 8);
strncpy(padname, name, 8);
fwrite(padname, 8, 1, coffp);
} else {
fwriteint32_t(0, coffp);
fwriteint32_t(strpos, coffp);
}
fwriteint32_t(value, coffp);
fwriteint16_t(section, coffp);
fwriteint16_t(type, coffp);
fputc(storageclass, coffp);
fputc(aux, coffp);
}
static void coff_write_symbols(void)
{
char filename[18];
uint32_t i;
/*
* The `.file' record, and the file name auxiliary record.
*/
coff_symbol(".file", 0L, 0L, -2, 0, 0x67, 1);
memset(filename, 0, 18);
strncpy(filename, coff_infile, 18);
fwrite(filename, 18, 1, coffp);
/*
* The section records, with their auxiliaries.
*/
memset(filename, 0, 18); /* useful zeroed buffer */
for (i = 0; i < (uint32_t) nsects; i++) {
coff_symbol(sects[i]->name, 0L, 0L, i + 1, 0, 3, 1);
fwriteint32_t(sects[i]->len, coffp);
fwriteint16_t(sects[i]->nrelocs, coffp);
fwrite(filename, 12, 1, coffp);
}
/*
* The absolute symbol, for relative-to-absolute relocations.
*/
coff_symbol(".absolut", 0L, 0L, -1, 0, 3, 0);
/*
* The real symbols.
*/
saa_rewind(syms);
for (i = 0; i < nsyms; i++) {
struct Symbol *sym = saa_rstruct(syms);
coff_symbol(sym->strpos == -1 ? sym->name : NULL,
sym->strpos, sym->value, sym->section,
sym->type, sym->is_global ? 2 : 3, 0);
}
}
static int32_t coff_segbase(int32_t segment)
{
return segment;
}
static void coff_std_filename(char *inname, char *outname, efunc error)
{
strcpy(coff_infile, inname);
standard_extension(inname, outname, ".o", error);
}
static void coff_win32_filename(char *inname, char *outname, efunc error)
{
strcpy(coff_infile, inname);
standard_extension(inname, outname, ".obj", error);
}
extern macros_t coff_stdmac[];
static int coff_set_info(enum geninfo type, char **val)
{
(void)type;
(void)val;
return 0;
}
#endif /* defined(OF_COFF) || defined(OF_WIN32) */
#ifdef OF_COFF
struct ofmt of_coff = {
"COFF (i386) object files (e.g. DJGPP for DOS)",
"coff",
NULL,
null_debug_arr,
&null_debug_form,
coff_stdmac,
coff_std_init,
coff_set_info,
coff_out,
coff_deflabel,
coff_section_names,
coff_segbase,
coff_directives,
coff_std_filename,
coff_cleanup
};
#endif
#ifdef OF_WIN32
struct ofmt of_win32 = {
"Microsoft Win32 (i386) object files",
"win32",
NULL,
null_debug_arr,
&null_debug_form,
coff_stdmac,
coff_win32_init,
coff_set_info,
coff_out,
coff_deflabel,
coff_section_names,
coff_segbase,
coff_directives,
coff_win32_filename,
coff_cleanup
};
#endif
#ifdef OF_WIN64
struct ofmt of_win64 = {
"Microsoft Win64 (x86-64) object files",
"win64",
NULL,
null_debug_arr,
&null_debug_form,
coff_stdmac,
coff_win64_init,
coff_set_info,
coff_out,
coff_deflabel,
coff_section_names,
coff_segbase,
coff_directives,
coff_win32_filename,
coff_cleanup
};
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -