📄 outcoff.c
字号:
if (segto == NO_SEG) { if (type != OUT_RESERVE) error (ERR_NONFATAL, "attempt to assemble code in [ABSOLUTE]" " space"); return; } s = NULL; for (i=0; i<nsects; i++) if (segto == sects[i]->index) { s = sects[i]; break; } if (!s) { int tempint; /* ignored */ if (segto != coff_section_names (".text", 2, &tempint)) error (ERR_PANIC, "strange segment conditions in COFF driver"); else s = sects[nsects-1]; } if (!s->data && type != OUT_RESERVE) { error(ERR_WARNING, "attempt to initialise memory in" " BSS section `%s': ignored", s->name); if (type == OUT_REL2ADR) realbytes = 2; else if (type == OUT_REL4ADR) realbytes = 4; s->len += realbytes; return; } if (type == OUT_RESERVE) { if (s->data) { error(ERR_WARNING, "uninitialised space declared in" " non-BSS section `%s': zeroing", s->name); coff_sect_write (s, NULL, realbytes); } else s->len += realbytes; } else if (type == OUT_RAWDATA) { if (segment != NO_SEG) error(ERR_PANIC, "OUT_RAWDATA with other than NO_SEG"); coff_sect_write (s, data, realbytes); } else if (type == OUT_ADDRESS) { if (realbytes != 4 && (segment != NO_SEG || wrt != NO_SEG)) error(ERR_NONFATAL, "COFF format does not support non-32-bit" " relocations"); else { long fix = 0; if (segment != NO_SEG || wrt != NO_SEG) { if (wrt != NO_SEG) { error(ERR_NONFATAL, "COFF format does not support" " WRT types"); } else if (segment % 2) { error(ERR_NONFATAL, "COFF format does not support" " segment base references"); } else fix = coff_add_reloc (s, segment, FALSE); } p = mydata; WRITELONG (p, *(long *)data + fix); coff_sect_write (s, mydata, realbytes); } } else if (type == OUT_REL2ADR) { error(ERR_NONFATAL, "COFF format does not support 16-bit" " relocations"); } else if (type == OUT_REL4ADR) { if (segment == segto) error(ERR_PANIC, "intra-segment OUT_REL4ADR"); else if (segment == NO_SEG && win32) error(ERR_NONFATAL, "Win32 COFF does not correctly support" " relative references to absolute addresses"); else { long fix = 0; if (segment != NO_SEG && segment % 2) { error(ERR_NONFATAL, "COFF format does not support" " segment base references"); } else fix = coff_add_reloc (s, segment, TRUE); p = mydata; if (win32) { WRITELONG (p, *(long*)data + 4 - realbytes + fix); } else { WRITELONG (p, *(long*)data-(realbytes + s->len) + fix); } coff_sect_write (s, mydata, 4L); } }}static void coff_sect_write (struct Section *sect, const unsigned char *data, unsigned long len) { saa_wbytes (sect->data, data, len); sect->len += len;}typedef struct tagString { struct tagString *Next; int len; char *String;} STRING;#define EXPORT_SECTION_NAME ".drectve"#define EXPORT_SECTION_FLAGS INFO_FLAGS /* #define EXPORT_SECTION_NAME ".text"#define EXPORT_SECTION_FLAGS TEXT_FLAGS*/static STRING *Exports = NULL;static struct Section *directive_sec;void AddExport(char *name){ STRING *rvp = Exports,*newS; newS = (STRING *)nasm_malloc(sizeof(STRING)); newS->len = strlen(name); newS->Next = NULL; newS->String = (char*)nasm_malloc( newS->len + 1 ); strcpy( newS->String, name ); if (rvp == NULL) { int i; for (i=0; i<nsects; i++) if (!strcmp( EXPORT_SECTION_NAME, sects[i]->name)) break; if( i == nsects ) directive_sec = sects[coff_make_section( EXPORT_SECTION_NAME, EXPORT_SECTION_FLAGS )]; else directive_sec = sects[i]; Exports = newS; } else { while (rvp->Next) { if (!strcmp(rvp->String,name)) return; rvp = rvp->Next; } rvp->Next = newS; }}void BuildExportTable(void){ STRING *rvp = Exports, *next; unsigned char buf[256]; int len; if (rvp == NULL) return; while (rvp) { len = sprintf( (char*)buf, "-export:%s ", rvp->String ); coff_sect_write( directive_sec, buf, len ); rvp = rvp->Next; } next = Exports; while( ( rvp = next ) ) { next = rvp->Next; nasm_free( rvp->String ); nasm_free( rvp ); } Exports = NULL;}static int coff_directives (char *directive, char *value, int pass) { if (!strcmp(directive, "export")) { char *q, *name; if (pass == 2) return 1; /* ignore in pass two */ name = q = value; while (*q && !isspace(*q)) q++; if (isspace(*q)) { *q++ = '\0'; while (*q && isspace(*q)) q++; } if (!*name) { error(ERR_NONFATAL, "`export' directive requires export name"); return 1; } if(*q) { error(ERR_NONFATAL, "unrecognised export qualifier `%s'", q); return 1; } AddExport( name ); return 1; } return 0;}static void coff_write (void) { long pos, sympos, vsize; int i; BuildExportTable(); /* fill in the .drectve section with -export's */ /* * 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. */ fwriteshort (0x14C, coffp); /* MACHINE_i386 */ fwriteshort (nsects, coffp); /* number of sections */ fwritelong (time(NULL), coffp); /* time stamp */ fwritelong (sympos, coffp); fwritelong (nsyms + initsym, coffp); fwriteshort (0, coffp); /* no optional header */ /* Flags: 32-bit, no line numbers. Win32 doesn't even bother with them. */ fwriteshort (win32 ? 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(); fwritelong (strslen+4, coffp); /* length includes length count */ saa_fpwrite (strs, coffp);}static void coff_section_header (char *name, long vsize, long datalen, long datapos, long relpos, int nrelocs, long flags) { char padname[8]; memset (padname, 0, 8); strncpy (padname, name, 8); fwrite (padname, 8, 1, coffp); fwritelong (vsize, coffp); fwritelong (0L, coffp); /* RVA/offset - we ignore */ fwritelong (datalen, coffp); fwritelong (datapos, coffp); fwritelong (relpos, coffp); fwritelong (0L, coffp); /* no line numbers - we don't do 'em */ fwriteshort (nrelocs, coffp); fwriteshort (0, coffp); /* again, no line numbers */ fwritelong (flags, coffp);}static void coff_write_relocs (struct Section *s) { struct Reloc *r; for (r = s->head; r; r = r->next) { fwritelong (r->address, coffp); fwritelong (r->symbol + (r->symbase == REAL_SYMBOLS ? initsym : r->symbase == ABS_SYMBOL ? initsym-1 : r->symbase == SECT_SYMBOLS ? 2 : 0), coffp); /* * Strange: Microsoft's COFF documentation says 0x03 for an * absolute relocation, but both Visual C++ and DJGPP agree * that in fact it's 0x06. I'll use 0x06 until someone * argues. */ fwriteshort (r->relative ? 0x14 : 0x06, coffp); }}static void coff_symbol (char *name, long strpos, long value, int section, int type, int aux) { char padname[8]; if (name) { memset (padname, 0, 8); strncpy (padname, name, 8); fwrite (padname, 8, 1, coffp); } else { fwritelong (0L, coffp); fwritelong (strpos, coffp); } fwritelong (value, coffp); fwriteshort (section, coffp); fwriteshort (0, coffp); fputc (type, coffp); fputc (aux, coffp);}static void coff_write_symbols (void){ char filename[18]; unsigned long i; /* * The `.file' record, and the file name auxiliary record. */ coff_symbol (".file", 0L, 0L, -2, 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 < nsects; i++) { coff_symbol (sects[i]->name, 0L, 0L, i+1, 3, 1); fwritelong (sects[i]->len, coffp); fwriteshort (sects[i]->nrelocs, coffp); fwrite (filename, 12, 1, coffp); } /* * The absolute symbol, for relative-to-absolute relocations. */ coff_symbol (".absolut", 0L, 0L, -1, 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->is_global ? 2 : 3, 0); }}static long coff_segbase (long 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);}static const char *coff_stdmac[] = { "%define __SECT__ [section .text]", "%macro __NASM_CDecl__ 1", "%endmacro", "%imacro export 1+.nolist", "[export %1]", "%endmacro", NULL};static int coff_set_info(enum geninfo type, char **val){ return 0;}#endif /* defined(OF_COFF) || defined(OF_WIN32) */#ifdef OF_COFFstruct 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_WIN32struct 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
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -