outcoff.c
上传用户:yuppie_zhu
上传日期:2007-01-08
资源大小:535k
文件大小:20k
源码类别:

编译器/解释器

开发平台:

C/C++

  1. /* outcoff.c output routines for the Netwide Assembler to produce
  2.  * COFF object files (for DJGPP and Win32)
  3.  *
  4.  * The Netwide Assembler is copyright (C) 1996 Simon Tatham and
  5.  * Julian Hall. All rights reserved. The software is
  6.  * redistributable under the licence given in the file "Licence"
  7.  * distributed in the NASM archive.
  8.  */
  9. #include <stdio.h>
  10. #include <stdlib.h>
  11. #include <string.h>
  12. #include <ctype.h>
  13. #include <time.h>
  14. #include "nasm.h"
  15. #include "nasmlib.h"
  16. #include "outform.h"
  17. #if defined(OF_COFF) || defined(OF_WIN32)
  18. /*
  19.  * Notes on COFF:
  20.  *
  21.  * (0) When I say `standard COFF' below, I mean `COFF as output and
  22.  * used by DJGPP'. I assume DJGPP gets it right.
  23.  *
  24.  * (1) Win32 appears to interpret the term `relative relocation'
  25.  * differently from standard COFF. Standard COFF understands a
  26.  * relative relocation to mean that during relocation you add the
  27.  * address of the symbol you're referencing, and subtract the base
  28.  * address of the section you're in. Win32 COFF, by contrast, seems
  29.  * to add the address of the symbol and then subtract the address
  30.  * of THE BYTE AFTER THE RELOCATED DWORD. Hence the two formats are
  31.  * subtly incompatible.
  32.  *
  33.  * (2) Win32 doesn't bother putting any flags in the header flags
  34.  * field (at offset 0x12 into the file).
  35.  *
  36.  * (3) Win32 uses some extra flags into the section header table:
  37.  * it defines flags 0x80000000 (writable), 0x40000000 (readable)
  38.  * and 0x20000000 (executable), and uses them in the expected
  39.  * combinations. It also defines 0x00100000 through 0x00700000 for
  40.  * section alignments of 1 through 64 bytes.
  41.  *
  42.  * (4) Both standard COFF and Win32 COFF seem to use the DWORD
  43.  * field directly after the section name in the section header
  44.  * table for something strange: they store what the address of the
  45.  * section start point _would_ be, if you laid all the sections end
  46.  * to end starting at zero. Dunno why. Microsoft's documentation
  47.  * lists this field as "Virtual Size of Section", which doesn't
  48.  * seem to fit at all. In fact, Win32 even includes non-linked
  49.  * sections such as .drectve in this calculation.
  50.  *
  51.  * (5) Standard COFF does something very strange to common
  52.  * variables: the relocation point for a common variable is as far
  53.  * _before_ the variable as its size stretches out _after_ it. So
  54.  * we must fix up common variable references. Win32 seems to be
  55.  * sensible on this one.
  56.  */
  57. /* Flag which version of COFF we are currently outputting. */
  58. static int win32;
  59. struct Reloc {
  60.     struct Reloc *next;
  61.     long address;        /* relative to _start_ of section */
  62.     long symbol;        /* symbol number */
  63.     enum {
  64. SECT_SYMBOLS,
  65. ABS_SYMBOL,
  66. REAL_SYMBOLS
  67.     } symbase;        /* relocation for symbol number :) */
  68.     int relative;        /* TRUE or FALSE */
  69. };
  70. struct Symbol {
  71.     char name[9];
  72.     long strpos;        /* string table position of name */
  73.     int section;        /* section number where it's defined
  74. * - in COFF codes, not NASM codes */
  75.     int is_global;        /* is it a global symbol or not? */
  76.     long value;        /* address, or COMMON variable size */
  77. };
  78. static FILE *coffp;
  79. static efunc error;
  80. static char coff_infile[FILENAME_MAX];
  81. struct Section {
  82.     struct SAA *data;
  83.     unsigned long len;
  84.     int nrelocs;
  85.     long index;
  86.     struct Reloc *head, **tail;
  87.     unsigned long flags;        /* section flags */
  88.     char name[9];
  89.     long pos, relpos;
  90. };
  91. #define TEXT_FLAGS (win32 ? 0x60500020L : 0x20L)
  92. #define DATA_FLAGS (win32 ? 0xC0300040L : 0x40L)
  93. #define BSS_FLAGS (win32 ? 0xC0300080L : 0x80L)
  94. #define INFO_FLAGS 0x00100A00L
  95. #define SECT_DELTA 32
  96. static struct Section **sects;
  97. static int nsects, sectlen;
  98. static struct SAA *syms;
  99. static unsigned long nsyms;
  100. static long def_seg;
  101. static int initsym;
  102. static struct RAA *bsym, *symval;
  103. static struct SAA *strs;
  104. static unsigned long strslen;
  105. static void coff_gen_init(FILE *, efunc);
  106. static void coff_sect_write (struct Section *, unsigned char *,
  107.      unsigned long);
  108. static void coff_write (void);
  109. static void coff_section_header (char *, long, long, long, long, int, long);
  110. static void coff_write_relocs (struct Section *);
  111. static void coff_write_symbols (void);
  112. static void coff_win32_init(FILE *fp,  efunc errfunc,
  113.     ldfunc ldef, evalfunc eval) 
  114. {
  115.     win32 = TRUE;
  116.     (void) ldef;        /* placate optimisers */
  117.     coff_gen_init(fp, errfunc);
  118. }
  119. static void coff_std_init(FILE *fp, efunc errfunc, ldfunc ldef, evalfunc eval) 
  120. {
  121.     win32 = FALSE;
  122.     (void) ldef;        /* placate optimisers */
  123.     coff_gen_init(fp, errfunc);
  124. }
  125. static void coff_gen_init(FILE *fp, efunc errfunc) 
  126. {
  127.     coffp = fp;
  128.     error = errfunc;
  129.     sects = NULL;
  130.     nsects = sectlen = 0;
  131.     syms = saa_init((long)sizeof(struct Symbol));
  132.     nsyms = 0;
  133.     bsym = raa_init();
  134.     symval = raa_init();
  135.     strs = saa_init(1L);
  136.     strslen = 0;
  137.     def_seg = seg_alloc();
  138. }
  139. static void coff_cleanup(int debuginfo) 
  140. {
  141.     struct Reloc *r;
  142.     int i;
  143.     (void) debuginfo;
  144.     coff_write();
  145.     fclose (coffp);
  146.     for (i=0; i<nsects; i++) {
  147. if (sects[i]->data)
  148.     saa_free (sects[i]->data);
  149. while (sects[i]->head) {
  150.     r = sects[i]->head;
  151.     sects[i]->head = sects[i]->head->next;
  152.     nasm_free (r);
  153. }
  154. nasm_free (sects[i]);
  155.     }
  156.     nasm_free (sects);
  157.     saa_free (syms);
  158.     raa_free (bsym);
  159.     raa_free (symval);
  160.     saa_free (strs);
  161. }
  162. static int coff_make_section (char *name, unsigned long flags) 
  163. {
  164.     struct Section *s;
  165.     s = nasm_malloc (sizeof(*s));
  166.     if (flags != BSS_FLAGS)
  167. s->data = saa_init (1L);
  168.     else
  169. s->data = NULL;
  170.     s->head = NULL;
  171.     s->tail = &s->head;
  172.     s->len = 0;
  173.     s->nrelocs = 0;
  174.     if (!strcmp(name, ".text"))
  175. s->index = def_seg;
  176.     else
  177. s->index = seg_alloc();
  178.     strncpy (s->name, name, 8);
  179.     s->name[8] = '';
  180.     s->flags = flags;
  181.     if (nsects >= sectlen)
  182. sects = nasm_realloc (sects, (sectlen += SECT_DELTA)*sizeof(*sects));
  183.     sects[nsects++] = s;
  184.     return nsects-1;
  185. }
  186. static long coff_section_names (char *name, int pass, int *bits) 
  187. {
  188.     char *p;
  189.     unsigned long flags, align_and = ~0L, align_or = 0L;
  190.     int i;
  191.     /*
  192.      * Default is 32 bits.
  193.      */
  194.     if (!name)
  195. *bits = 32;
  196.     if (!name)
  197. return def_seg;
  198.     p = name;
  199.     while (*p && !isspace(*p)) p++;
  200.     if (*p) *p++ = '';
  201.     if (strlen(name) > 8) {
  202. error (ERR_WARNING, "COFF section names limited to 8 characters:"
  203.        " truncating");
  204. name[8] = '';
  205.     }
  206.     flags = 0;
  207.     while (*p && isspace(*p)) p++;
  208.     while (*p) {
  209. char *q = p;
  210. while (*p && !isspace(*p)) p++;
  211. if (*p) *p++ = '';
  212. while (*p && isspace(*p)) p++;
  213. if (!nasm_stricmp(q, "code") || !nasm_stricmp(q, "text")) {
  214.     flags = TEXT_FLAGS;
  215. } else if (!nasm_stricmp(q, "data")) {
  216.     flags = DATA_FLAGS;
  217. } else if (!nasm_stricmp(q, "bss")) {
  218.     flags = BSS_FLAGS;
  219. } else if (!nasm_stricmp(q, "info")) {
  220.     if (win32)
  221. flags = INFO_FLAGS;
  222.     else {
  223. flags = DATA_FLAGS;    /* gotta do something */
  224. error (ERR_NONFATAL, "standard COFF does not support"
  225.        " informational sections");
  226.     }
  227. } else if (!nasm_strnicmp(q,"align=",6)) {
  228.     if (!win32)
  229. error (ERR_NONFATAL, "standard COFF does not support"
  230.        " section alignment specification");
  231.     else {
  232. if (q[6+strspn(q+6,"0123456789")])
  233.     error(ERR_NONFATAL, "argument to `align' is not numeric");
  234. else {
  235.     unsigned int align = atoi(q+6);
  236.     if (!align || ((align-1) & align))
  237. error(ERR_NONFATAL, "argument to `align' is not a"
  238.       " power of two");
  239.     else if (align > 64)
  240. error(ERR_NONFATAL, "Win32 cannot align sections"
  241.       " to better than 64-byte boundaries");
  242.     else {
  243. align_and = ~0x00F00000L;
  244. align_or = (align == 1 ? 0x00100000L :
  245.     align == 2 ? 0x00200000L :
  246.     align == 4 ? 0x00300000L :
  247.     align == 8 ? 0x00400000L :
  248.     align == 16 ? 0x00500000L :
  249.     align == 32 ? 0x00600000L : 0x00700000L);
  250.     }
  251. }
  252.     }
  253. }
  254.     }
  255.     for (i=0; i<nsects; i++)
  256. if (!strcmp(name, sects[i]->name))
  257.     break;
  258.     if (i == nsects) {
  259. if (!flags) {
  260.     if (!strcmp(name, ".data"))
  261. flags = DATA_FLAGS;
  262.     else if (!strcmp(name, ".bss"))
  263. flags = BSS_FLAGS;
  264.     else
  265. flags = TEXT_FLAGS;
  266. }
  267. i = coff_make_section (name, flags);
  268. if (flags)
  269.     sects[i]->flags = flags;
  270. sects[i]->flags &= align_and;
  271. sects[i]->flags |= align_or;
  272.     } else if (pass == 1) {
  273. if (flags)
  274.     error (ERR_WARNING, "section attributes ignored on"
  275.    " redeclaration of section `%s'", name);
  276.     }
  277.     return sects[i]->index;
  278. }
  279. static void coff_deflabel (char *name, long segment, long offset,
  280.    int is_global, char *special) 
  281. {
  282.     int pos = strslen+4;
  283.     struct Symbol *sym;
  284.     if (special)
  285. error (ERR_NONFATAL, "binary format does not support any"
  286.        " special symbol types");
  287.     if (name[0] == '.' && name[1] == '.' && name[2] != '@') {
  288. error (ERR_NONFATAL, "unrecognised special symbol `%s'", name);
  289. return;
  290.     }
  291.     if (strlen(name) > 8) {
  292. saa_wbytes (strs, name, (long)(1+strlen(name)));
  293. strslen += 1+strlen(name);
  294.     } else
  295. pos = -1;
  296.     sym = saa_wstruct (syms);
  297.     sym->strpos = pos;
  298.     if (pos == -1)
  299. strcpy (sym->name, name);
  300.     sym->is_global = !!is_global;
  301.     if (segment == NO_SEG)
  302. sym->section = -1;      /* absolute symbol */
  303.     else {
  304. int i;
  305. sym->section = 0;
  306. for (i=0; i<nsects; i++)
  307.     if (segment == sects[i]->index) {
  308. sym->section = i+1;
  309. break;
  310.     }
  311. if (!sym->section)
  312.     sym->is_global = TRUE;
  313.     }
  314.     if (is_global == 2)
  315. sym->value = offset;
  316.     else
  317. sym->value = (sym->section == 0 ? 0 : offset);
  318.     /*
  319.      * define the references from external-symbol segment numbers
  320.      * to these symbol records.
  321.      */
  322.     if (sym->section == 0)
  323. bsym = raa_write (bsym, segment, nsyms);
  324.     if (segment != NO_SEG)
  325. symval = raa_write (symval, segment, sym->section ? 0 : sym->value);
  326.     nsyms++;
  327. }
  328. static long coff_add_reloc (struct Section *sect, long segment,
  329.     int relative) 
  330. {
  331.     struct Reloc *r;
  332.     r = *sect->tail = nasm_malloc(sizeof(struct Reloc));
  333.     sect->tail = &r->next;
  334.     r->next = NULL;
  335.     r->address = sect->len;
  336.     if (segment == NO_SEG)
  337. r->symbol = 0, r->symbase = ABS_SYMBOL;
  338.     else {
  339. int i;
  340. r->symbase = REAL_SYMBOLS;
  341. for (i=0; i<nsects; i++)
  342.     if (segment == sects[i]->index) {
  343. r->symbol = i*2;
  344. r->symbase = SECT_SYMBOLS;
  345. break;
  346.     }
  347. if (r->symbase == REAL_SYMBOLS)
  348.     r->symbol = raa_read (bsym, segment);
  349.     }
  350.     r->relative = relative;
  351.     sect->nrelocs++;
  352.     /*
  353.      * Return the fixup for standard COFF common variables.
  354.      */
  355.     if (r->symbase == REAL_SYMBOLS && !win32)
  356. return raa_read (symval, segment);
  357.     else
  358. return 0;
  359. }
  360. static void coff_out (long segto, void *data, unsigned long type,
  361.       long segment, long wrt) 
  362. {
  363.     struct Section *s;
  364.     long realbytes = type & OUT_SIZMASK;
  365.     unsigned char mydata[4], *p;
  366.     int i;
  367.     if (wrt != NO_SEG) {
  368. wrt = NO_SEG;        /* continue to do _something_ */
  369. error (ERR_NONFATAL, "WRT not supported by COFF output formats");
  370.     }
  371.     type &= OUT_TYPMASK;
  372.     /*
  373.      * handle absolute-assembly (structure definitions)
  374.      */
  375.     if (segto == NO_SEG) {
  376. if (type != OUT_RESERVE)
  377.     error (ERR_NONFATAL, "attempt to assemble code in [ABSOLUTE]"
  378.    " space");
  379. return;
  380.     }
  381.     s = NULL;
  382.     for (i=0; i<nsects; i++)
  383. if (segto == sects[i]->index) {
  384.     s = sects[i];
  385.     break;
  386. }
  387.     if (!s) {
  388. int tempint;        /* ignored */
  389. if (segto != coff_section_names (".text", 2, &tempint))
  390.     error (ERR_PANIC, "strange segment conditions in COFF driver");
  391. else
  392.     s = sects[nsects-1];
  393.     }
  394.     if (!s->data && type != OUT_RESERVE) {
  395. error(ERR_WARNING, "attempt to initialise memory in"
  396.       " BSS section `%s': ignored", s->name);
  397. if (type == OUT_REL2ADR)
  398.     realbytes = 2;
  399. else if (type == OUT_REL4ADR)
  400.     realbytes = 4;
  401. s->len += realbytes;
  402. return;
  403.     }
  404.     if (type == OUT_RESERVE) {
  405. if (s->data) {
  406.     error(ERR_WARNING, "uninitialised space declared in"
  407.   " non-BSS section `%s': zeroing", s->name);
  408.     coff_sect_write (s, NULL, realbytes);
  409. } else
  410.     s->len += realbytes;
  411.     } else if (type == OUT_RAWDATA) {
  412. if (segment != NO_SEG)
  413.     error(ERR_PANIC, "OUT_RAWDATA with other than NO_SEG");
  414. coff_sect_write (s, data, realbytes);
  415.     } else if (type == OUT_ADDRESS) {
  416. if (realbytes != 4 && (segment != NO_SEG || wrt != NO_SEG))
  417.     error(ERR_NONFATAL, "COFF format does not support non-32-bit"
  418.   " relocations");
  419. else {
  420.     long fix = 0;
  421.     if (segment != NO_SEG || wrt != NO_SEG) {
  422. if (wrt != NO_SEG) {
  423.     error(ERR_NONFATAL, "COFF format does not support"
  424.   " WRT types");
  425. } else if (segment % 2) {
  426.     error(ERR_NONFATAL, "COFF format does not support"
  427.   " segment base references");
  428. } else
  429.     fix = coff_add_reloc (s, segment, FALSE);
  430.     }
  431.     p = mydata;
  432.     WRITELONG (p, *(long *)data + fix);
  433.     coff_sect_write (s, mydata, realbytes);
  434. }
  435.     } else if (type == OUT_REL2ADR) {
  436. error(ERR_NONFATAL, "COFF format does not support 16-bit"
  437.       " relocations");
  438.     } else if (type == OUT_REL4ADR) {
  439. if (segment == segto)
  440.     error(ERR_PANIC, "intra-segment OUT_REL4ADR");
  441. else if (segment == NO_SEG && win32)
  442.     error(ERR_NONFATAL, "Win32 COFF does not correctly support"
  443.   " relative references to absolute addresses");
  444. else {
  445.     long fix = 0;
  446.     if (segment != NO_SEG && segment % 2) {
  447. error(ERR_NONFATAL, "COFF format does not support"
  448.       " segment base references");
  449.     } else
  450. fix = coff_add_reloc (s, segment, TRUE);
  451.     p = mydata;
  452.     if (win32) {
  453. WRITELONG (p, *(long*)data + 4 - realbytes + fix);
  454.     } else {
  455. WRITELONG (p, *(long*)data-(realbytes + s->len) + fix);
  456.     }
  457.     coff_sect_write (s, mydata, 4L);
  458. }
  459.     }
  460. }
  461. static void coff_sect_write (struct Section *sect,
  462.      unsigned char *data, unsigned long len) 
  463. {
  464.     saa_wbytes (sect->data, data, len);
  465.     sect->len += len;
  466. }
  467. static int coff_directives (char *directive, char *value, int pass) 
  468. {
  469.     return 0;
  470. }
  471. static void coff_write (void) 
  472. {
  473.     long pos, sympos, vsize;
  474.     int i;
  475.     /*
  476.      * Work out how big the file will get. Calculate the start of
  477.      * the `real' symbols at the same time.
  478.      */
  479.     pos = 0x14 + 0x28 * nsects;
  480.     initsym = 3;        /* two for the file, one absolute */
  481.     for (i=0; i<nsects; i++) {
  482. if (sects[i]->data) {
  483.     sects[i]->pos = pos;
  484.     pos += sects[i]->len;
  485.     sects[i]->relpos = pos;
  486.     pos += 10 * sects[i]->nrelocs;
  487. } else
  488.     sects[i]->pos = sects[i]->relpos = 0L;
  489. initsym += 2;        /* two for each section */
  490.     }
  491.     sympos = pos;
  492.     /*
  493.      * Output the COFF header.
  494.      */
  495.     fwriteshort (0x14C, coffp);        /* MACHINE_i386 */
  496.     fwriteshort (nsects, coffp);       /* number of sections */
  497.     fwritelong (time(NULL), coffp);    /* time stamp */
  498.     fwritelong (sympos, coffp);
  499.     fwritelong (nsyms + initsym, coffp);
  500.     fwriteshort (0, coffp);        /* no optional header */
  501.     /* Flags: 32-bit, no line numbers. Win32 doesn't even bother with them. */
  502.     fwriteshort (win32 ? 0 : 0x104, coffp);
  503.     /*
  504.      * Output the section headers.
  505.      */
  506.     vsize = 0L;
  507.     for (i=0; i<nsects; i++) {
  508. coff_section_header (sects[i]->name, vsize, sects[i]->len,
  509.      sects[i]->pos, sects[i]->relpos,
  510.      sects[i]->nrelocs, sects[i]->flags);
  511. vsize += sects[i]->len;
  512.     }
  513.     /*
  514.      * Output the sections and their relocations.
  515.      */
  516.     for (i=0; i<nsects; i++)
  517. if (sects[i]->data) {
  518.     saa_fpwrite (sects[i]->data, coffp);
  519.     coff_write_relocs (sects[i]);
  520. }
  521.     /*
  522.      * Output the symbol and string tables.
  523.      */
  524.     coff_write_symbols();
  525.     fwritelong (strslen+4, coffp);     /* length includes length count */
  526.     saa_fpwrite (strs, coffp);
  527. }
  528. static void coff_section_header (char *name, long vsize,
  529.  long datalen, long datapos,
  530.  long relpos, int nrelocs, long flags) 
  531. {
  532.     char padname[8];
  533.     memset (padname, 0, 8);
  534.     strncpy (padname, name, 8);
  535.     fwrite (padname, 8, 1, coffp);
  536.     fwritelong (vsize, coffp);
  537.     fwritelong (0L, coffp);        /* RVA/offset - we ignore */
  538.     fwritelong (datalen, coffp);
  539.     fwritelong (datapos, coffp);
  540.     fwritelong (relpos, coffp);
  541.     fwritelong (0L, coffp);        /* no line numbers - we don't do 'em */
  542.     fwriteshort (nrelocs, coffp);
  543.     fwriteshort (0, coffp);        /* again, no line numbers */
  544.     fwritelong (flags, coffp);
  545. }
  546. static void coff_write_relocs (struct Section *s) 
  547. {
  548.     struct Reloc *r;
  549.     for (r = s->head; r; r = r->next) {
  550. fwritelong (r->address, coffp);
  551. fwritelong (r->symbol + (r->symbase == REAL_SYMBOLS ? initsym :
  552.  r->symbase == ABS_SYMBOL ? initsym-1 :
  553.  r->symbase == SECT_SYMBOLS ? 2 : 0), coffp);
  554. /*
  555.  * Strange: Microsoft's COFF documentation says 0x03 for an
  556.  * absolute relocation, but both Visual C++ and DJGPP agree
  557.  * that in fact it's 0x06. I'll use 0x06 until someone
  558.  * argues.
  559.  */
  560. fwriteshort (r->relative ? 0x14 : 0x06, coffp);
  561.     }
  562. }
  563. static void coff_symbol (char *name, long strpos, long value,
  564.  int section, int type, int aux) 
  565. {
  566.     char padname[8];
  567.     if (name) {
  568. memset (padname, 0, 8);
  569. strncpy (padname, name, 8);
  570. fwrite (padname, 8, 1, coffp);
  571.     } else {
  572. fwritelong (0L, coffp);
  573. fwritelong (strpos, coffp);
  574.     }
  575.     fwritelong (value, coffp);
  576.     fwriteshort (section, coffp);
  577.     fwriteshort (0, coffp);
  578.     fputc (type, coffp);
  579.     fputc (aux, coffp);
  580. }
  581. static void coff_write_symbols (void) 
  582. {
  583.     char filename[18];
  584.     int i;
  585.     /*
  586.      * The `.file' record, and the file name auxiliary record.
  587.      */
  588.     coff_symbol (".file", 0L, 0L, -2, 0x67, 1);
  589.     memset (filename, 0, 18);
  590.     strncpy (filename, coff_infile, 18);
  591.     fwrite (filename, 18, 1, coffp);
  592.     /*
  593.      * The section records, with their auxiliaries.
  594.      */
  595.     memset (filename, 0, 18);        /* useful zeroed buffer */
  596.     for (i=0; i<nsects; i++) {
  597. coff_symbol (sects[i]->name, 0L, 0L, i+1, 3, 1);
  598. fwritelong (sects[i]->len, coffp);
  599. fwriteshort (sects[i]->nrelocs, coffp);
  600. fwrite (filename, 12, 1, coffp);
  601.     }
  602.     /*
  603.      * The absolute symbol, for relative-to-absolute relocations.
  604.      */
  605.     coff_symbol (".absolut", 0L, 0L, -1, 3, 0);
  606.     /*
  607.      * The real symbols.
  608.      */
  609.     saa_rewind (syms);
  610.     for (i=0; i<nsyms; i++) {
  611. struct Symbol *sym = saa_rstruct (syms);
  612. coff_symbol (sym->strpos == -1 ? sym->name : NULL,
  613.      sym->strpos, sym->value, sym->section,
  614.      sym->is_global ? 2 : 3, 0);
  615.     }
  616. }
  617. static long coff_segbase (long segment) 
  618. {
  619.     return segment;
  620. }
  621. static void coff_std_filename (char *inname, char *outname, efunc error) 
  622. {
  623.     strcpy(coff_infile, inname);
  624.     standard_extension (inname, outname, ".o", error);
  625. }
  626. static void coff_win32_filename (char *inname, char *outname, efunc error) 
  627. {
  628.     strcpy(coff_infile, inname);
  629.     standard_extension (inname, outname, ".obj", error);
  630. }
  631. static char *coff_stdmac[] = {
  632.     "%define __SECT__ [section .text]",
  633.     "%macro __NASM_CDecl__ 1",
  634.     "%endmacro",
  635.     NULL
  636. };
  637. static int coff_set_info(enum geninfo type, char **val)
  638. {
  639.     return 0;
  640. }
  641. #endif /* defined(OF_COFF) || defined(OF_WIN32) */
  642. #ifdef OF_COFF
  643. struct ofmt of_coff = {
  644.     "COFF (i386) object files (e.g. DJGPP for DOS)",
  645.     "coff",
  646.     NULL,
  647.     null_debug_arr,
  648.     &null_debug_form,
  649.     coff_stdmac,
  650.     coff_std_init,
  651.     coff_set_info,
  652.     coff_out,
  653.     coff_deflabel,
  654.     coff_section_names,
  655.     coff_segbase,
  656.     coff_directives,
  657.     coff_std_filename,
  658.     coff_cleanup
  659. };
  660. #endif
  661. #ifdef OF_WIN32
  662. struct ofmt of_win32 = {
  663.     "Microsoft Win32 (i386) object files",
  664.     "win32",
  665.     NULL,
  666.     null_debug_arr,
  667.     &null_debug_form,
  668.     coff_stdmac,
  669.     coff_win32_init,
  670.     coff_set_info,
  671.     coff_out,
  672.     coff_deflabel,
  673.     coff_section_names,
  674.     coff_segbase,
  675.     coff_directives,
  676.     coff_win32_filename,
  677.     coff_cleanup
  678. };
  679. #endif