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

编译器/解释器

开发平台:

C/C++

  1. /* outieee.c output routines for the Netwide Assembler to produce
  2.  * IEEE-std object files
  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. /* notes: I have tried to make this correspond to the IEEE version
  10.  * of the standard, specifically the primary ASCII version.  It should
  11.  * be trivial to create the binary version given this source (which is
  12.  * one of MANY things that have to be done to make this correspond to
  13.  * the hp-microtek version of the standard).
  14.  *
  15.  * 16-bit support is assumed to use 24-bit addresses
  16.  * The linker can sort out segmentation-specific stuff
  17.  * if it keeps track of externals
  18.  * in terms of being relative to section bases
  19.  *
  20.  * A non-standard variable type, the 'Yn' variable, has been introduced.
  21.  * Basically it is a reference to extern 'n'- denoting the low limit
  22.  * (L-variable) of the section that extern 'n' is defined in.  Like the
  23.  * x variable, there may be no explicit assignment to it, it is derived
  24.  * from the public definition corresponding to the extern name.  This
  25.  * is required because the one thing the mufom guys forgot to do well was
  26.  * take into account segmented architectures.
  27.  *
  28.  * I use comment classes for various things and these are undefined by
  29.  * the standard.
  30.  *
  31.  * Debug info should be considered totally non-standard (local labels are
  32.  * standard but linenum records are not covered by the standard.
  33.  * Type defs have the standard format but absolute meanings for ordinal
  34.  * types are not covered by the standard.)
  35.  *
  36.  * David Lindauer, LADsoft
  37.  */
  38. #include <stdio.h>
  39. #include <stdlib.h>
  40. #include <string.h>
  41. #include <time.h>
  42. #include <stdarg.h>  /* Note: we need the ANSI version of stdarg.h */
  43. #include <ctype.h>
  44. #include "nasm.h"
  45. #include "nasmlib.h"
  46. #include "outform.h"
  47. #ifdef OF_IEEE
  48. #define ARRAY_BOT 0x1
  49. static char ieee_infile[FILENAME_MAX];
  50. static int ieee_uppercase;
  51. static efunc error;
  52. static ldfunc deflabel;
  53. static FILE *ofp;
  54. static int any_segs;
  55. static int arrindex;
  56. #define HUNKSIZE 1024        /* Size of the data hunk */
  57. #define EXT_BLKSIZ 512
  58. #define LDPERLINE 32 /* bytes per line in output */
  59. struct ieeeSection;
  60. struct LineNumber {
  61.     struct LineNumber *next;
  62.     struct ieeeSection *segment;
  63.     long offset;
  64.     long lineno;
  65. };
  66. static struct FileName {
  67.     struct FileName *next;
  68.     char *name;
  69.     long index;
  70. } *fnhead, **fntail;
  71. static struct Array {
  72.     struct Array *next;
  73.     unsigned size;
  74.     int basetype;
  75. } *arrhead, **arrtail;
  76. static struct ieeePublic {
  77.     struct ieeePublic *next;
  78.     char *name;
  79.     long offset;
  80.     long segment;        /* only if it's far-absolute */
  81.     long index;
  82.     int type;   /* for debug purposes */
  83. } *fpubhead, **fpubtail, *last_defined;
  84. static struct ieeeExternal {
  85.     struct ieeeExternal *next;
  86.     char *name;
  87.     long commonsize;
  88. } *exthead, **exttail;
  89. static int externals;
  90. static struct ExtBack {
  91.     struct ExtBack *next;
  92.     int index[EXT_BLKSIZ];
  93. } *ebhead, **ebtail;
  94. /* NOTE: the first segment MUST be the lineno segment */
  95. static struct ieeeSection {
  96.     struct ieeeObjData *data,*datacurr;
  97.     struct ieeeSection *next;
  98.     struct ieeeFixupp *fptr, * flptr;
  99.     long index;        /* the NASM segment id */
  100.     long ieee_index;        /* the OBJ-file segment index */
  101.     long currentpos;
  102.     long align;        /* can be SEG_ABS + absolute addr */
  103.     long startpos;
  104.     enum {
  105. CMB_PRIVATE = 0,
  106. CMB_PUBLIC = 2,
  107. CMB_COMMON = 6
  108.     } combine;
  109.     long use32;        /* is this segment 32-bit? */
  110.     struct ieeePublic *pubhead, **pubtail, *lochead, **loctail;
  111.     char *name;
  112. } *seghead, **segtail, *ieee_seg_needs_update;
  113. struct ieeeObjData {
  114.     struct ieeeObjData *next;
  115.     unsigned char data[HUNKSIZE];
  116. };
  117. struct ieeeFixupp {
  118.     struct ieeeFixupp *next;
  119.     enum { 
  120. FT_SEG = 0,
  121. FT_REL = 1,
  122. FT_OFS = 2,
  123. FT_EXT = 3,
  124. FT_WRT = 4,
  125. FT_EXTREL = 5,
  126. FT_EXTWRT = 6,
  127. FT_EXTSEG = 7
  128.     } ftype;
  129.     short size;
  130.     long id1;
  131.     long id2;
  132.     long offset;
  133.     long addend;
  134. };
  135. static long ieee_entry_seg, ieee_entry_ofs;
  136. static int checksum;
  137. extern struct ofmt of_ieee;
  138. static void ieee_data_new(struct ieeeSection *);
  139. static void ieee_write_fixup (long, long, struct ieeeSection *,
  140. int, long, long);
  141. static void ieee_install_fixup(struct ieeeSection *, struct ieeeFixupp *);
  142. static long ieee_segment (char *, int, int *);
  143. static void ieee_write_file(int debuginfo);
  144. static void ieee_write_byte(struct ieeeSection *, int);
  145. static void ieee_write_word(struct ieeeSection *, int);
  146. static void ieee_write_dword(struct ieeeSection *, long);
  147. static void ieee_putascii(char *, ...);
  148. static void ieee_putcs(int);
  149. static long ieee_putld(long, long, unsigned char *);
  150. static long ieee_putlr(struct ieeeFixupp *);
  151. static void ieee_unqualified_name(char *, char *);
  152. /* 
  153.  * pup init 
  154.  */
  155. static void ieee_init (FILE *fp, efunc errfunc, ldfunc ldef, evalfunc eval) 
  156. {
  157.     (void) eval;
  158.     ofp = fp;
  159.     error = errfunc;
  160.     deflabel = ldef;
  161.     any_segs = FALSE;
  162.     fpubhead = NULL;
  163.     fpubtail = &fpubhead;
  164.     exthead = NULL;
  165.     exttail = &exthead;
  166.     externals = 1;
  167.     ebhead = NULL;
  168.     ebtail = &ebhead;
  169.     seghead = ieee_seg_needs_update = NULL;
  170.     segtail = &seghead;
  171.     ieee_entry_seg = NO_SEG;
  172.     ieee_uppercase = FALSE;
  173.     checksum = 0;
  174.     of_ieee.current_dfmt->init (&of_ieee,NULL,fp,errfunc);
  175. }
  176. static int ieee_set_info(enum geninfo type, char **val)
  177. {
  178.     (void) type;
  179.     (void) val;
  180.     return 0;
  181. }
  182. /*
  183.  * Rundown
  184.  */
  185. static void ieee_cleanup (int debuginfo) 
  186. {
  187.     ieee_write_file(debuginfo);
  188.     of_ieee.current_dfmt->cleanup ();
  189.     fclose (ofp);
  190.     while (seghead) {
  191. struct ieeeSection *segtmp = seghead;
  192. seghead = seghead->next;
  193. while (segtmp->pubhead) {
  194.     struct ieeePublic *pubtmp = segtmp->pubhead;
  195.     segtmp->pubhead = pubtmp->next;
  196.     nasm_free (pubtmp);
  197. }
  198. while (segtmp->fptr) {
  199.     struct ieeeFixupp *fixtmp = segtmp->fptr;
  200.     segtmp->fptr = fixtmp->next;
  201.     nasm_free(fixtmp);
  202. }
  203. while (segtmp->data) {
  204.     struct ieeeObjData *dattmp = segtmp->data;
  205.     segtmp->data = dattmp->next;
  206.     nasm_free(dattmp);
  207. }
  208. nasm_free (segtmp);
  209.     }
  210.     while (fpubhead) {
  211. struct ieeePublic *pubtmp = fpubhead;
  212. fpubhead = fpubhead->next;
  213. nasm_free (pubtmp);
  214.     }
  215.     while (exthead) {
  216. struct ieeeExternal *exttmp = exthead;
  217. exthead = exthead->next;
  218. nasm_free (exttmp);
  219.     }
  220.     while (ebhead) {
  221. struct ExtBack *ebtmp = ebhead;
  222. ebhead = ebhead->next;
  223. nasm_free (ebtmp);
  224.     }
  225. }
  226. /*
  227.  * callback for labels
  228.  */
  229. static void ieee_deflabel (char *name, long segment,
  230.   long offset, int is_global, char *special) {
  231.     /*
  232.      * We have three cases:
  233.      *
  234.      * (i) `segment' is a segment-base. If so, set the name field
  235.      * for the segment structure it refers to, and then
  236.      * return.
  237.      *
  238.      * (ii) `segment' is one of our segments, or a SEG_ABS segment.
  239.      * Save the label position for later output of a PUBDEF record.
  240.      * 
  241.      *
  242.      * (iii) `segment' is not one of our segments. Save the label
  243.      * position for later output of an EXTDEF.
  244.      */
  245.     struct ieeeExternal *ext;
  246.     struct ExtBack *eb;
  247.     struct ieeeSection *seg;
  248.     int i;
  249.     if (special) {
  250.         error(ERR_NONFATAL, "unrecognised symbol type `%s'", special);
  251.     }
  252.     /*
  253.      * First check for the double-period, signifying something
  254.      * unusual.
  255.      */
  256.     if (name[0] == '.' && name[1] == '.') {
  257. if (!strcmp(name, "..start")) {
  258.     ieee_entry_seg = segment;
  259.     ieee_entry_ofs = offset;
  260. }
  261. return;
  262.     }
  263.     /*
  264.      * Case (i):
  265.      */
  266.     if (ieee_seg_needs_update) {
  267. ieee_seg_needs_update->name = name;
  268. return;
  269.     } 
  270.     if (segment < SEG_ABS && segment != NO_SEG && segment % 2)
  271. return;
  272.     /*
  273.      * case (ii)
  274.      */
  275.     if (segment >= SEG_ABS) {
  276. /*
  277.  * SEG_ABS subcase of (ii).
  278.  */
  279. if (is_global) {
  280.     struct ieeePublic *pub;
  281.     pub = *fpubtail = nasm_malloc(sizeof(*pub));
  282.     fpubtail = &pub->next;
  283.     pub->next = NULL;
  284.     pub->name = name;
  285.     pub->offset = offset;
  286.     pub->segment = segment & ~SEG_ABS;
  287. }
  288. return;
  289.     }
  290.     for (seg = seghead; seg && is_global; seg = seg->next)
  291. if (seg->index == segment) {
  292. struct ieeePublic *pub;
  293.     last_defined = pub = *seg->pubtail = nasm_malloc(sizeof(*pub));
  294.     seg->pubtail = &pub->next;
  295.     pub->next = NULL;
  296.     pub->name = name;
  297.     pub->offset = offset;
  298.     pub->index = seg->ieee_index;
  299.     pub->segment = -1;
  300.     return;
  301. }
  302.     /*
  303.      * Case (iii).
  304.      */
  305.     if (is_global) {
  306.         ext = *exttail = nasm_malloc(sizeof(*ext));
  307.         ext->next = NULL;
  308.         exttail = &ext->next;
  309.         ext->name = name;
  310.         if (is_global == 2)
  311.     ext->commonsize = offset;
  312.      else
  313.     ext->commonsize = 0;
  314.      i = segment/2;
  315.      eb = ebhead;
  316.      if (!eb) {
  317.     eb = *ebtail = nasm_malloc(sizeof(*eb));
  318.     eb->next = NULL;
  319.     ebtail = &eb->next;
  320.         }
  321.      while (i > EXT_BLKSIZ) {
  322.     if (eb && eb->next)
  323.         eb = eb->next;
  324.     else {
  325.         eb = *ebtail = nasm_malloc(sizeof(*eb));
  326.      eb->next = NULL;
  327.      ebtail = &eb->next;
  328.     }
  329.     i -= EXT_BLKSIZ;
  330.      }
  331.         eb->index[i] = externals++;
  332.     }
  333. }
  334. /*
  335.  * Put data out
  336.  */
  337. static void ieee_out (long segto, void *data, unsigned long type,
  338.      long segment, long wrt) {
  339.     long size, realtype;
  340.     unsigned char *ucdata;
  341.     long ldata;
  342.     struct ieeeSection *seg;
  343.     /*
  344.      * handle absolute-assembly (structure definitions)
  345.      */
  346.     if (segto == NO_SEG) {
  347. if ((type & OUT_TYPMASK) != OUT_RESERVE)
  348.     error (ERR_NONFATAL, "attempt to assemble code in [ABSOLUTE]"
  349.    " space");
  350. return;
  351.     }
  352.     /*
  353.      * If `any_segs' is still FALSE, we must define a default
  354.      * segment.
  355.      */
  356.     if (!any_segs) {
  357. int tempint;        /* ignored */
  358. if (segto != ieee_segment("__NASMDEFSEG", 2, &tempint))
  359.     error (ERR_PANIC, "strange segment conditions in IEEE driver");
  360.     }
  361.     /*
  362.      * Find the segment we are targetting.
  363.      */
  364.     for (seg = seghead; seg; seg = seg->next)
  365. if (seg->index == segto)
  366.     break;
  367.     if (!seg)
  368. error (ERR_PANIC, "code directed to nonexistent segment?");
  369.     size = type & OUT_SIZMASK;
  370.     realtype = type & OUT_TYPMASK;
  371.     if (realtype == OUT_RAWDATA) {
  372. ucdata = data;
  373. while (size--)
  374.     ieee_write_byte(seg,*ucdata++);
  375.     } else if (realtype == OUT_ADDRESS || realtype == OUT_REL2ADR ||
  376.        realtype == OUT_REL4ADR) {
  377. if (segment == NO_SEG && realtype != OUT_ADDRESS)
  378.     error(ERR_NONFATAL, "relative call to absolute address not"
  379.   " supported by IEEE format");
  380. ldata = *(long *)data;
  381. if (realtype == OUT_REL2ADR)
  382.     ldata += (size-2);
  383. if (realtype == OUT_REL4ADR)
  384.     ldata += (size-4);
  385. ieee_write_fixup (segment, wrt, seg, size, realtype,ldata);
  386. if (size == 2)
  387.     ieee_write_word (seg, ldata);
  388. else
  389.     ieee_write_dword (seg, ldata);
  390.     } 
  391.     else if (realtype == OUT_RESERVE) {
  392. while (size--)
  393.     ieee_write_byte(seg,0);
  394.     }
  395. }
  396. static void ieee_data_new(struct ieeeSection *segto) {
  397.     
  398.     if (!segto->data)
  399. segto->data = segto->datacurr = nasm_malloc(sizeof(*(segto->datacurr)));
  400.     else
  401. segto->datacurr = segto->datacurr->next = nasm_malloc(sizeof(*(segto->datacurr)));
  402.     segto->datacurr->next = NULL;
  403. }
  404. /*
  405.  * this routine is unalduterated bloatware.  I usually don't do this
  406.  * but I might as well see what it is like on a harmless program.
  407.  * If anyone wants to optimize this is a good canditate!
  408.  */
  409. static void ieee_write_fixup (long segment, long wrt, struct ieeeSection * segto,
  410. int size, long realtype, long offset) {
  411.     struct ieeeSection *target;
  412.     struct ieeeFixupp s;
  413.     /* Don't put a fixup for things NASM can calculate */
  414.     if (wrt == NO_SEG && segment == NO_SEG)
  415. return;
  416.     s.ftype = -1;
  417.     /* if it is a WRT offset */
  418.     if (wrt != NO_SEG) {
  419. s.ftype = FT_WRT;
  420. s.addend = offset;
  421. if (wrt >= SEG_ABS)
  422.     s.id1 = -(wrt-SEG_ABS);
  423. else {
  424.     if (wrt %2 && realtype != OUT_REL2ADR && realtype != OUT_REL4ADR) {
  425. wrt--;
  426.      for (target = seghead; target; target = target->next)
  427.             if (target->index == wrt)
  428.              break;
  429.              if (target) {
  430.             s.id1 = target->ieee_index;
  431.          for (target = seghead; target; target = target->next)
  432.              if (target->index == segment)
  433.                  break;
  434.     if (target) 
  435.      s.id2 = target->ieee_index;
  436.             else {
  437. /*
  438.  * Now we assume the segment field is being used
  439.  * to hold an extern index
  440.    */
  441. long i = segment/2;
  442. struct ExtBack *eb = ebhead;
  443. while (i > EXT_BLKSIZ) {
  444.     if (eb)
  445. eb = eb->next;
  446.     else
  447. break;
  448.     i -= EXT_BLKSIZ;
  449. }
  450. /* if we have an extern decide the type and make a record
  451.  */
  452. if (eb) {
  453.         s.ftype = FT_EXTWRT;
  454.         s.addend = 0;
  455.          s.id2 = eb->index[i];
  456. }
  457. else
  458.     error(ERR_NONFATAL,
  459. "Source of WRT must be an offset");
  460.     }
  461. }
  462.      else 
  463.             error(ERR_PANIC,
  464.           "unrecognised WRT value in ieee_write_fixup");
  465.     }
  466.     else 
  467. error(ERR_NONFATAL,"target of WRT must be a section ");
  468. }
  469. s.size = size;
  470. ieee_install_fixup(segto,&s);
  471. return;
  472.     }
  473.     /* Pure segment fixup ? */
  474.     if (segment != NO_SEG) {
  475. s.ftype = FT_SEG;
  476. s.id1 = 0;
  477. if (segment >= SEG_ABS) {
  478.     /* absolute far segment fixup */
  479.     s.id1 = -(segment -~SEG_ABS);
  480. }
  481. else if (segment % 2) {
  482.     /* fixup to named segment */
  483.     /* look it up */
  484.     for (target = seghead; target; target = target->next)
  485.         if (target->index == segment-1)
  486.             break;
  487.          if (target)
  488.         s.id1 = target->ieee_index;
  489.     else {
  490. /*
  491.  * Now we assume the segment field is being used
  492.  * to hold an extern index
  493.  */
  494. long i = segment/2;
  495. struct ExtBack *eb = ebhead;
  496. while (i > EXT_BLKSIZ) {
  497.     if (eb)
  498. eb = eb->next;
  499.     else
  500. break;
  501.     i -= EXT_BLKSIZ;
  502. }
  503. /* if we have an extern decide the type and make a record
  504.  */
  505. if (eb) {
  506.     if (realtype == OUT_REL2ADR || realtype == OUT_REL4ADR) {
  507. error(ERR_PANIC,"Segment of a rel not supported in ieee_write_fixup");
  508.     }
  509.     else {
  510. /* If we want the segment */
  511.     s.ftype = FT_EXTSEG;
  512.     s.addend = 0;
  513.     s.id1 = eb->index[i];
  514.     }
  515.     
  516. }
  517. else 
  518.     /* If we get here the seg value doesn't make sense */
  519.             error(ERR_PANIC,
  520.           "unrecognised segment value in ieee_write_fixup");
  521.     }
  522.         } else {
  523.     /* Assume we are offsetting directly from a section
  524.           * So look up the target segment
  525.      */
  526.     for (target = seghead; target; target = target->next)
  527.         if (target->index == segment)
  528.             break;
  529.          if (target) {
  530. if (realtype == OUT_REL2ADR || realtype == OUT_REL4ADR) {
  531.     /* PC rel to a known offset */
  532.             s.id1 = target->ieee_index;
  533.     s.ftype = FT_REL;
  534.     s.size = size;
  535.     s.addend = offset;
  536. }
  537. else {
  538.     /* We were offsetting from a seg */
  539.             s.id1 = target->ieee_index;
  540.     s.ftype = FT_OFS;
  541.     s.size = size;
  542.     s.addend = offset;
  543. }
  544.     }
  545.     else {
  546. /*
  547.  * Now we assume the segment field is being used
  548.  * to hold an extern index
  549.  */
  550. long i = segment/2;
  551. struct ExtBack *eb = ebhead;
  552. while (i > EXT_BLKSIZ) {
  553.     if (eb)
  554. eb = eb->next;
  555.     else
  556. break;
  557.     i -= EXT_BLKSIZ;
  558. }
  559. /* if we have an extern decide the type and make a record
  560.  */
  561. if (eb) {
  562.     if (realtype == OUT_REL2ADR || realtype == OUT_REL4ADR) {
  563.         s.ftype = FT_EXTREL;
  564.         s.addend = 0;
  565.         s.id1 = eb->index[i];
  566.     }
  567.     else {
  568.     /* else we want the external offset */
  569.     s.ftype = FT_EXT;
  570.     s.addend = 0;
  571.     s.id1 = eb->index[i];
  572.     }
  573.     
  574. }
  575. else 
  576.     /* If we get here the seg value doesn't make sense */
  577.             error(ERR_PANIC,
  578.           "unrecognised segment value in ieee_write_fixup");
  579.     }
  580. }
  581. if (size != 2 && s.ftype == FT_SEG)
  582.     error(ERR_NONFATAL, "IEEE format can only handle 2-byte"
  583.      " segment base references");
  584. s.size = size;
  585. ieee_install_fixup(segto,&s);
  586. return;
  587.     }
  588.     /* should never get here */
  589. }
  590. static void ieee_install_fixup(struct ieeeSection *seg, struct ieeeFixupp *fix)
  591. {
  592.     struct ieeeFixupp *f;
  593.     f = nasm_malloc(sizeof(struct ieeeFixupp));
  594.     memcpy(f,fix,sizeof(struct ieeeFixupp));
  595.     f->offset = seg->currentpos;
  596.     seg->currentpos += fix->size;
  597.     f->next = NULL;
  598.     if (seg->fptr)
  599. seg->flptr = seg->flptr->next = f;
  600.     else
  601. seg->fptr = seg->flptr = f;
  602. }
  603. /*
  604.  * segment registry
  605.  */
  606. static long ieee_segment (char *name, int pass, int *bits) {
  607.     /*
  608.      * We call the label manager here to define a name for the new
  609.      * segment, and when our _own_ label-definition stub gets
  610.      * called in return, it should register the new segment name
  611.      * using the pointer it gets passed. That way we save memory,
  612.      * by sponging off the label manager.
  613.      */
  614.     if (!name) {
  615. *bits = 16;
  616. if (!any_segs)
  617. return 0;
  618. return seghead->index;
  619.     } else {
  620. struct ieeeSection *seg;
  621. int ieee_idx, attrs, rn_error;
  622. char *p;
  623. /*
  624.  * Look for segment attributes.
  625.  */
  626. attrs = 0;
  627. while (*name == '.')
  628.     name++;        /* hack, but a documented one */
  629. p = name;
  630. while (*p && !isspace(*p))
  631.     p++;
  632. if (*p) {
  633.     *p++ = '';
  634.     while (*p && isspace(*p))
  635. *p++ = '';
  636. }
  637. while (*p) {
  638.     while (*p && !isspace(*p))
  639. p++;
  640.     if (*p) {
  641. *p++ = '';
  642. while (*p && isspace(*p))
  643.     *p++ = '';
  644.     }
  645.     attrs++;
  646. }
  647. ieee_idx = 1;
  648. for (seg = seghead; seg; seg = seg->next) {
  649.     ieee_idx++;
  650.     if (!strcmp(seg->name, name)) {
  651. if (attrs > 0 && pass == 1)
  652.     error(ERR_WARNING, "segment attributes specified on"
  653.   " redeclaration of segment: ignoring");
  654. if (seg->use32)
  655.     *bits = 32;
  656. else
  657.     *bits = 16;
  658. return seg->index;
  659.     }
  660. }
  661. *segtail = seg = nasm_malloc(sizeof(*seg));
  662. seg->next = NULL;
  663. segtail = &seg->next;
  664. seg->index = seg_alloc();
  665. seg->ieee_index = ieee_idx;
  666. any_segs = TRUE;
  667. seg->name = NULL;
  668. seg->currentpos = 0;
  669. seg->align = 1;        /* default */
  670. seg->use32 = *bits == 32;      /* default to user spec */
  671. seg->combine = CMB_PUBLIC;     /* default */
  672. seg->pubhead = NULL;
  673. seg->pubtail = &seg->pubhead;
  674. seg->data = NULL;
  675. seg->fptr = NULL;
  676. seg->lochead = NULL;
  677. seg->loctail = &seg->lochead;
  678. /*
  679.  * Process the segment attributes.
  680.  */
  681. p = name;
  682. while (attrs--) {
  683.     p += strlen(p);
  684.     while (!*p) p++;
  685.     /*
  686.      * `p' contains a segment attribute.
  687.      */
  688.     if (!nasm_stricmp(p, "private"))
  689. seg->combine = CMB_PRIVATE;
  690.     else if (!nasm_stricmp(p, "public"))
  691. seg->combine = CMB_PUBLIC;
  692.     else if (!nasm_stricmp(p, "common"))
  693. seg->combine = CMB_COMMON;
  694.     else if (!nasm_stricmp(p, "use16"))
  695. seg->use32 = FALSE;
  696.     else if (!nasm_stricmp(p, "use32"))
  697. seg->use32 = TRUE;
  698.     else if (!nasm_strnicmp(p, "align=", 6)) {
  699. seg->align = readnum(p+6, &rn_error);
  700. if (seg->align == 0)
  701.     seg->align = 1;
  702. if (rn_error) {
  703.     seg->align = 1;
  704.     error (ERR_NONFATAL, "segment alignment should be"
  705.    " numeric");
  706. }
  707. switch ((int) seg->align) {
  708.   case 1:        /* BYTE */
  709.   case 2:        /* WORD */
  710.   case 4:        /* DWORD */
  711.   case 16:        /* PARA */
  712.   case 256:        /* PAGE */
  713.   case 8:
  714.   case 32:
  715.   case 64:
  716.   case 128:
  717.     break;
  718.   default:
  719.     error(ERR_NONFATAL, "invalid alignment value %d",
  720.   seg->align);
  721.     seg->align = 1;
  722.     break;
  723. }
  724.     } else if (!nasm_strnicmp(p, "absolute=", 9)) {
  725. seg->align = SEG_ABS + readnum(p+9, &rn_error);
  726. if (rn_error)
  727.     error (ERR_NONFATAL, "argument to `absolute' segment"
  728.    " attribute should be numeric");
  729.     }
  730. }
  731. ieee_seg_needs_update = seg;
  732. if (seg->align >= SEG_ABS)
  733.     deflabel (name, NO_SEG, seg->align - SEG_ABS, 
  734. NULL, FALSE, FALSE, &of_ieee, error);
  735. else
  736.     deflabel (name, seg->index+1, 0L, 
  737. NULL, FALSE, FALSE, &of_ieee, error);
  738. ieee_seg_needs_update = NULL;
  739. if (seg->use32)
  740.     *bits = 32;
  741. else
  742.     *bits = 16;
  743. return seg->index;
  744.     }
  745. }
  746. /*
  747.  * directives supported
  748.  */
  749. static int ieee_directive (char *directive, char *value, int pass) 
  750. {
  751.     
  752.     (void) value;
  753.     (void) pass;
  754.     if (!strcmp(directive, "uppercase")) {
  755. ieee_uppercase = TRUE;
  756. return 1;
  757.     }
  758.     return 0;
  759. }
  760. /*
  761.  * Return segment data
  762.  */
  763. static long ieee_segbase (long segment) 
  764. {
  765.     struct ieeeSection *seg;
  766.     /*
  767.      * Find the segment in our list.
  768.      */
  769.     for (seg = seghead; seg; seg = seg->next)
  770. if (seg->index == segment-1)
  771.     break;
  772.     if (!seg)
  773. return segment;        /* not one of ours - leave it alone */
  774.     if (seg->align >= SEG_ABS)
  775. return seg->align;        /* absolute segment */
  776.     return segment;        /* no special treatment */
  777. }
  778. /*
  779.  * filename
  780.  */
  781. static void ieee_filename (char *inname, char *outname, efunc error) {
  782.     strcpy(ieee_infile, inname);
  783.     standard_extension (inname, outname, ".o", error);
  784. }
  785. static void ieee_write_file (int debuginfo) {
  786.     struct tm *thetime;
  787.     time_t reltime;
  788.     struct FileName *fn;
  789.     struct ieeeSection *seg;
  790.     struct ieeePublic *pub, *loc;
  791.     struct ieeeExternal *ext;
  792.     struct ieeeObjData *data;
  793.     struct ieeeFixupp *fix;
  794.     struct Array *arr;
  795.     static char boast[] = "The Netwide Assembler " NASM_VER;
  796.     int i;
  797.     /*
  798.      * Write the module header
  799.      */
  800.     ieee_putascii("MBFNASM,%02X%s.rn",strlen(ieee_infile),ieee_infile);
  801.     /*
  802.      * Write the NASM boast comment.
  803.      */
  804.     ieee_putascii("CO0,%02X%s.rn",strlen(boast),boast);
  805.     /* 
  806.      * write processor-specific information
  807.      */
  808.     ieee_putascii("AD8,4,L.rn");
  809.     /*
  810.      * date and time
  811.      */
  812.     time(&reltime);
  813.     thetime = localtime(&reltime);
  814.     ieee_putascii("DT%04d%02d%02d%02d%02d%02d.rn", 
  815. 1900+thetime->tm_year,thetime->tm_mon+1,thetime->tm_mday,
  816. thetime->tm_hour, thetime->tm_min, thetime->tm_sec);
  817.     /* 
  818.      * if debugging, dump file names
  819.      */
  820.     for (fn = fnhead; fn && debuginfo; fn = fn->next) {
  821. ieee_putascii("C0105,%02X%s.rn",strlen(fn->name),fn->name);
  822.     }
  823.      
  824.     ieee_putascii("CO101,07ENDHEAD.rn");
  825.     /*
  826.      * the standard doesn't specify when to put checksums,
  827.      * we'll just do it periodically.
  828.      */
  829.     ieee_putcs(FALSE);
  830.     /* 
  831.      * Write the section headers
  832.      */
  833.     seg = seghead;
  834.     if (!debuginfo && !strcmp(seg->name,"??LINE"))
  835. seg = seg->next;
  836.     while (seg) {
  837. char buf[256];
  838. char attrib;
  839. switch(seg->combine) {
  840.     case CMB_PUBLIC:
  841.     default:
  842. attrib = 'C';
  843. break;
  844.     case CMB_PRIVATE:
  845. attrib = 'S';
  846. break;
  847.     case CMB_COMMON:
  848. attrib = 'M';
  849. break;
  850.    }
  851. ieee_unqualified_name(buf,seg->name);
  852. if (seg->align >= SEG_ABS) {
  853.     ieee_putascii("ST%X,A,%02X%s.rn",seg->ieee_index,strlen(buf), buf);
  854.     ieee_putascii("ASL%X,%lX.rn",seg->ieee_index, (seg->align - SEG_ABS)*16);
  855. }
  856. else {
  857.     ieee_putascii("ST%X,%c,%02X%s.rn",seg->ieee_index,attrib,strlen(buf), buf);
  858.     ieee_putascii("SA%X,%lX.rn",seg->ieee_index,seg->align);
  859.     ieee_putascii("ASS%X,%X.rn",seg->ieee_index, seg->currentpos);
  860. }
  861. seg = seg->next;
  862.     }
  863.     /*
  864.      * write the start address if there is one
  865.      */
  866.     if (ieee_entry_seg) {
  867.         for (seg = seghead; seg; seg = seg->next)
  868.     if (seg->index == ieee_entry_seg)
  869. break;
  870. if (!seg)
  871.     error(ERR_PANIC,"Start address records are incorrect");
  872. else 
  873.     ieee_putascii("ASG,R%X,%lX,+.rn",seg->ieee_index, ieee_entry_ofs);
  874.     }
  875.     ieee_putcs(FALSE);
  876.     /*
  877.      * Write the publics
  878.      */
  879.     i = 1;
  880.     for (seg = seghead; seg; seg = seg->next) {
  881.         for (pub = seg->pubhead; pub; pub = pub->next) {
  882.     char buf[256];
  883.     ieee_unqualified_name(buf,pub->name);
  884.             ieee_putascii("NI%X,%02X%s.rn",i, strlen(buf), buf);
  885.     if (pub->segment == -1)  
  886.              ieee_putascii("ASI%X,R%X,%lX,+.rn", i, pub->index,pub->offset);
  887.     else
  888.              ieee_putascii("ASI%X,%lX,%lX,+.rn", i, pub->segment*16,pub->offset);
  889.     if (debuginfo)
  890.      if (pub->type >= 0x100)
  891.          ieee_putascii("ATI%X,T%X.rn", i, pub->type - 0x100);
  892. else
  893.          ieee_putascii("ATI%X,%X.rn", i, pub->type);
  894.       i++;
  895.         }
  896.     }
  897.     pub = fpubhead;
  898.     i = 1;
  899.     while (pub) {
  900. char buf[256];
  901. ieee_unqualified_name(buf,pub->name);
  902.         ieee_putascii("NI%X,%02X%s.rn",i, strlen(buf), buf);
  903. if (pub->segment == -1)  
  904.             ieee_putascii("ASI%X,R%X,%lX,+.rn", i, pub->index,pub->offset);
  905. else
  906.             ieee_putascii("ASI%X,%lX,%lX,+.rn", i, pub->segment*16,pub->offset);
  907. if (debuginfo)
  908.     if (pub->type >= 0x100)
  909.      ieee_putascii("ATI%X,T%X.rn", i, pub->type - 0x100);
  910.     else
  911.      ieee_putascii("ATI%X,%X.rn", i, pub->type);
  912.   i++;
  913.         pub = pub->next;
  914.     }
  915.     /*
  916.      * Write the externals
  917.      */
  918.     ext = exthead;
  919.     i = 1;
  920.     while (ext) {
  921. char buf[256];
  922. ieee_unqualified_name(buf,ext->name);
  923.         ieee_putascii("NX%X,%02X%s.rn",i++, strlen(buf), buf);
  924.         ext = ext->next;
  925.     }
  926.     ieee_putcs(FALSE);
  927.     /*
  928.      * IEEE doesn't have a standard pass break record
  929.      * so use the ladsoft variant
  930.      */
  931.     ieee_putascii("CO100,06ENDSYM.rn");
  932.     /*
  933.      * now put types
  934.      */
  935.     i = ARRAY_BOT;
  936.     for (arr = arrhead; arr && debuginfo; arr = arr->next) {
  937. ieee_putascii("TY%X,20,%X,%lX.rn",i++,arr->basetype,arr->size);
  938.     }
  939.     /*
  940.      * now put locals
  941.      */
  942.     i = 1;
  943.     for (seg = seghead; seg && debuginfo; seg = seg->next) {
  944.         for (loc = seg->lochead; loc; loc = loc->next) {
  945.     char buf[256];
  946.     ieee_unqualified_name(buf,loc->name);
  947.             ieee_putascii("NN%X,%02X%s.rn",i, strlen(buf), buf);
  948.     if (loc->segment == -1)  
  949.              ieee_putascii("ASN%X,R%X,%lX,+.rn", i, loc->index,loc->offset);
  950.     else
  951.              ieee_putascii("ASN%X,%lX,%lX,+.rn", i, loc->segment*16,loc->offset);
  952.     if (debuginfo)
  953. if (loc->type >= 0x100)
  954.       ieee_putascii("ATN%X,T%X.rn", i, loc->type - 0x100);
  955. else
  956.          ieee_putascii("ATN%X,%X.rn", i, loc->type);
  957.       i++;
  958.         }
  959.     }
  960.     /*
  961.      *  put out section data;
  962.      */ 
  963.     seg = seghead;
  964.     if (!debuginfo && !strcmp(seg->name,"??LINE"))
  965. seg = seg->next;
  966.     while (seg) {
  967. if (seg->currentpos) {
  968.     long size,org = 0;
  969.     data = seg->data;
  970.     ieee_putascii("SB%X.rn",seg->ieee_index);
  971.     fix = seg->fptr;
  972.     while (fix) {
  973. size = HUNKSIZE - (org %HUNKSIZE);
  974. size = size +org > seg->currentpos ? seg->currentpos-org : size;
  975. size = fix->offset - org > size ? size : fix->offset-org;
  976. org = ieee_putld(org,org+size,data->data);
  977. if (org % HUNKSIZE == 0)
  978.     data = data->next;
  979. if (org == fix->offset) {
  980.     org += ieee_putlr(fix);
  981.     fix = fix->next;
  982. }
  983.     }
  984.     while (org < seg->currentpos && data) {
  985. size = seg->currentpos-org > HUNKSIZE ? HUNKSIZE : seg->currentpos - org;
  986. org = ieee_putld(org,org+size,data->data);
  987. data = data->next;
  988.     }
  989.     ieee_putcs(FALSE);
  990. }
  991. seg = seg->next;
  992.     }
  993.     /*
  994.      * module end record
  995.      */
  996.     ieee_putascii("ME.rn");
  997. }
  998. static void ieee_write_byte(struct ieeeSection *seg, int data) {
  999.     int temp;
  1000.     if (!(temp = seg->currentpos++ % HUNKSIZE))
  1001. ieee_data_new(seg);
  1002.     seg->datacurr->data[temp] = data;
  1003. }
  1004. static void ieee_write_word(struct ieeeSection *seg, int data) {
  1005.     ieee_write_byte(seg, data & 0xFF);
  1006.     ieee_write_byte(seg,(data >> 8) & 0xFF);
  1007. }
  1008. static void ieee_write_dword(struct ieeeSection *seg, long data) {
  1009.     ieee_write_byte(seg, data & 0xFF);
  1010.     ieee_write_byte(seg,(data >> 8) & 0xFF);
  1011.     ieee_write_byte(seg,(data >> 16) & 0xFF);
  1012.     ieee_write_byte(seg,(data >> 24) & 0xFF);
  1013. }
  1014. static void ieee_putascii(char *format, ...)
  1015. {
  1016. char buffer[256];
  1017. int i,l;
  1018. va_list ap;
  1019. va_start(ap, format);
  1020. vsprintf(buffer, format, ap);
  1021. l = strlen(buffer);
  1022. for (i=0; i < l; i++)
  1023. if ((buffer[i] & 0xff) > 31)
  1024. checksum+=buffer[i];
  1025. va_end(ap);
  1026. fprintf(ofp,buffer);
  1027. }
  1028. /*
  1029.  * put out a checksum record */
  1030. static void ieee_putcs(int toclear)
  1031. {
  1032. if (toclear) {
  1033. ieee_putascii("CS.rn");
  1034. }
  1035. else {
  1036. checksum += 'C';
  1037. checksum += 'S';
  1038. ieee_putascii("CS%02X.rn",checksum & 127);
  1039. }
  1040. checksum = 0;
  1041. }
  1042. static long ieee_putld(long start, long end, unsigned char *buf)
  1043. {
  1044. long val;
  1045. if (start == end)
  1046. return(start);
  1047. val = start % HUNKSIZE;
  1048. /* fill up multiple lines */
  1049. while (end - start >= LDPERLINE) {
  1050. int i;
  1051. ieee_putascii("LD");
  1052. for (i=0; i < LDPERLINE; i++) {
  1053. ieee_putascii("%02X",buf[val++]);
  1054. start++;
  1055. }
  1056. ieee_putascii(".rn");
  1057. }
  1058. /* if no partial lines */
  1059. if (start == end)
  1060. return(start);
  1061. /* make a partial line */
  1062. ieee_putascii("LD");
  1063. while (start < end) {
  1064. ieee_putascii("%02X",buf[val++]);
  1065. start++;
  1066. }
  1067. ieee_putascii(".rn");
  1068. return(start);
  1069. }
  1070. static long ieee_putlr(struct ieeeFixupp *p)
  1071. {
  1072. /*
  1073.  * To deal with the vagaries of segmentation the LADsoft linker
  1074.  * defines two types of segments: absolute and virtual.  Note that
  1075.  * 'absolute' in this context is a different thing from the IEEE
  1076.  * definition of an absolute segment type, which is also supported. If a
  1077.  * sement is linked in virtual mode the low limit (L-var) is
  1078.  * subtracted from each R,X, and P variable which appears in an
  1079.  * expression, so that we can have relative offsets.  Meanwhile
  1080.  * in the ABSOLUTE mode this subtraction is not done and
  1081.  * so we can use absolute offsets from 0.  In the LADsoft linker
  1082.  * this configuration is not done in the assemblker source but in
  1083.  * a source the linker reads.  Generally this type of thing only
  1084.  * becomes an issue if real mode code is used.  A pure 32-bit linker could
  1085.  * get away without defining the virtual mode...
  1086.  */
  1087. char buf[40];
  1088. long size=p->size;
  1089. switch(p->ftype) {
  1090.     case FT_SEG:
  1091.         if (p->id1 < 0)
  1092.     sprintf(buf,"%lX",-p->id1);
  1093. else
  1094.     sprintf(buf,"L%lX,10,/",p->id1);
  1095. break;
  1096.     case FT_OFS:
  1097. sprintf(buf,"R%lX,%lX,+",p->id1,p->addend);
  1098. break;
  1099.     case FT_REL:
  1100. sprintf(buf,"R%lX,%lX,+,P,-,%X,-",p->id1,p->addend,p->size);
  1101. break;
  1102.     case FT_WRT:
  1103.         if (p->id2 < 0)
  1104.     sprintf(buf,"R%lX,%lX,+,L%lX,+,%lX,-",p->id2,p->addend,p->id2,-p->id1*16);
  1105. else
  1106.     sprintf(buf,"R%lX,%lX,+,L%lX,+,L%lX,-",p->id2,p->addend,p->id2,p->id1);
  1107. break;
  1108.     case FT_EXT:
  1109. sprintf(buf,"X%lX",p->id1);
  1110. break;
  1111.     case FT_EXTREL:
  1112. sprintf(buf,"X%lX,P,-,%lX,-",p->id1,size);
  1113. break;
  1114.     case FT_EXTSEG:
  1115. /* We needed a non-ieee hack here.
  1116.  * We introduce the Y variable, which is the low
  1117.  * limit of the native segment the extern resides in
  1118.  */
  1119. sprintf(buf,"Y%lX,10,/",p->id1);
  1120. break;
  1121.     case FT_EXTWRT:
  1122.         if (p->id2 < 0)
  1123.     sprintf(buf,"X%lX,Y%lX,+,%lX,-",p->id2,p->id2,-p->id1*16);
  1124. else
  1125.     sprintf(buf,"X%lX,Y%lX,+,L%lX,-",p->id2,p->id2,p->id1);
  1126. break;
  1127. }
  1128. ieee_putascii("LR(%s,%lX).rn", buf, size);
  1129. return(size);
  1130. }
  1131. /* Dump all segment data (text and fixups )*/
  1132. static void ieee_unqualified_name(char *dest, char *source)
  1133. {
  1134.     if (ieee_uppercase) {
  1135. while (*source)
  1136.     *dest++ = toupper(*source++);
  1137.         *dest = 0;
  1138.     }
  1139.     else strcpy(dest,source);
  1140. }
  1141. void dbgls_init(struct ofmt * of, void * id, FILE * fp, efunc error)
  1142. {
  1143.     int tempint;
  1144.     (void) of;
  1145.     (void) id;
  1146.     (void) fp;
  1147.     (void) error;
  1148.     fnhead = NULL;
  1149.     fntail = &fnhead;
  1150.     arrindex = ARRAY_BOT ;
  1151.     arrhead = NULL;
  1152.     arrtail = &arrhead;
  1153.     ieee_segment("??LINE", 2, &tempint);
  1154.     any_segs = FALSE;
  1155. }
  1156. static void dbgls_cleanup(void)
  1157. {
  1158.     struct ieeeSection *segtmp;
  1159.     while (fnhead) {
  1160. struct FileName *fntemp = fnhead;
  1161. fnhead = fnhead->next;
  1162. nasm_free (fntemp->name);
  1163. nasm_free (fntemp);
  1164.     }
  1165.     for (segtmp = seghead; segtmp; segtmp = segtmp->next) {
  1166. while (segtmp->lochead) {
  1167.     struct ieeePublic *loctmp = segtmp->lochead;
  1168.     segtmp->lochead = loctmp->next;
  1169.     nasm_free (loctmp->name);
  1170.     nasm_free (loctmp);
  1171. }
  1172.     }
  1173.     while (arrhead) {
  1174. struct Array *arrtmp = arrhead;
  1175.         arrhead = arrhead->next;
  1176.         nasm_free (arrtmp);
  1177.     }
  1178. }
  1179. /*
  1180.  * because this routine is not bracketed in
  1181.  * the main program, this routine will be called even if there
  1182.  * is no request for debug info
  1183.  * so, we have to make sure the ??LINE segment is avaialbe
  1184.  * as the first segment when this debug format is selected
  1185.  */
  1186. static void dbgls_linnum (const char *lnfname, long lineno, long segto)
  1187. {
  1188.     struct FileName *fn;
  1189.     struct ieeeSection *seg;
  1190.     int i = 0;
  1191.     if (segto == NO_SEG)
  1192. return;
  1193.     /*
  1194.      * If `any_segs' is still FALSE, we must define a default
  1195.      * segment.
  1196.      */
  1197.     if (!any_segs) {
  1198. int tempint;        /* ignored */
  1199. if (segto != ieee_segment("__NASMDEFSEG", 2, &tempint))
  1200.     error (ERR_PANIC, "strange segment conditions in OBJ driver");
  1201.     }
  1202.     /*
  1203.      * Find the segment we are targetting.
  1204.      */
  1205.     for (seg = seghead; seg; seg = seg->next)
  1206. if (seg->index == segto)
  1207.     break;
  1208.     if (!seg)
  1209. error (ERR_PANIC, "lineno directed to nonexistent segment?");
  1210.     for (fn = fnhead; fn; fn = fnhead->next) {
  1211. if (!nasm_stricmp(lnfname,fn->name))
  1212.     break;
  1213.         i++;
  1214.     }
  1215.     if (!fn) {
  1216. fn = nasm_malloc ( sizeof( *fn));
  1217. fn->name = nasm_malloc ( strlen(lnfname) + 1) ;
  1218. fn->index = i;
  1219.         strcpy (fn->name,lnfname);
  1220. fn->next = NULL;
  1221. *fntail = fn;
  1222. fntail = &fn->next;
  1223.     }
  1224.     ieee_write_byte(seghead, fn->index);
  1225.     ieee_write_word(seghead, lineno);
  1226.     ieee_write_fixup (segto, NO_SEG, seghead, 4,OUT_ADDRESS,seg->currentpos);
  1227. }
  1228. static void dbgls_deflabel (char *name, long segment,
  1229.   long offset, int is_global, char *special) 
  1230. {
  1231.     struct ieeeSection *seg;
  1232.     int used_special; /* have we used the special text? */
  1233.     /* Keep compiler from warning about special and used_special */
  1234.     used_special = special ? FALSE : FALSE;
  1235.     /*
  1236.      * If it's a special-retry from pass two, discard it.
  1237.      */
  1238.     if (is_global == 3)
  1239. return;
  1240.     /*
  1241.      * First check for the double-period, signifying something
  1242.      * unusual.
  1243.      */
  1244.     if (name[0] == '.' && name[1] == '.' && name[2] != '@') {
  1245. return;
  1246.     }
  1247.     /*
  1248.      * Case (i):
  1249.      */
  1250.     if (ieee_seg_needs_update)
  1251. return;
  1252.     if (segment < SEG_ABS && segment != NO_SEG && segment % 2)
  1253. return;
  1254.     if (segment >= SEG_ABS || segment == NO_SEG) {
  1255. return;
  1256.     }
  1257.     /*
  1258.      * If `any_segs' is still FALSE, we might need to define a
  1259.      * default segment, if they're trying to declare a label in
  1260.      * `first_seg'.  But the label should exist due to a prior
  1261.      * call to ieee_deflabel so we can skip that.
  1262.      */
  1263.     for (seg = seghead; seg; seg = seg->next)
  1264. if (seg->index == segment) {
  1265.     struct ieeePublic *loc;
  1266.     /*
  1267.      * Case (ii). Maybe MODPUB someday?
  1268.      */
  1269.     if (!is_global) {
  1270.      last_defined = loc  = nasm_malloc (sizeof(*loc));
  1271.      *seg->loctail = loc;
  1272.      seg->loctail = &loc->next;
  1273.      loc->next = NULL;
  1274.      loc->name = nasm_strdup(name);
  1275.      loc->offset = offset;
  1276. loc->segment = -1;
  1277. loc->index = seg->ieee_index;
  1278.     }
  1279. }
  1280. }
  1281. static void dbgls_typevalue (long type)
  1282. {
  1283.     int elem = TYM_ELEMENTS(type);
  1284.     type = TYM_TYPE(type);
  1285.     if (! last_defined)
  1286. return;
  1287.     switch (type) {
  1288. case TY_BYTE:
  1289.     last_defined->type = 1; /* unsigned char */
  1290.     break;
  1291. case TY_WORD:
  1292.     last_defined->type = 3; /* unsigned word */
  1293.     break;
  1294. case TY_DWORD:
  1295.     last_defined->type = 5; /* unsigned dword */
  1296.     break;
  1297. case TY_FLOAT:
  1298.     last_defined->type = 9; /* float */
  1299.     break;
  1300. case TY_QWORD:
  1301.     last_defined->type = 10; /* qword */
  1302.     break;
  1303. case TY_TBYTE:
  1304.     last_defined->type = 11; /* TBYTE */
  1305.     break;
  1306. default:
  1307.     last_defined->type = 0x10; /* near label */
  1308.     break;
  1309.     }
  1310.                
  1311.     if (elem > 1) {
  1312.         struct Array *arrtmp = nasm_malloc (sizeof(*arrtmp));
  1313.         int vtype = last_defined->type;
  1314.         arrtmp->size = elem;
  1315.         arrtmp->basetype = vtype;
  1316.         arrtmp->next = NULL;
  1317.         last_defined->type = arrindex++ + 0x100;
  1318.         *arrtail = arrtmp;
  1319.         arrtail = & (arrtmp->next);
  1320.     }
  1321.     last_defined = NULL;
  1322. }
  1323. static void dbgls_output (int output_type, void *param)
  1324. {
  1325.     (void) output_type;
  1326.     (void) param;
  1327. }
  1328. static struct dfmt ladsoft_debug_form = {
  1329.     "LADsoft Debug Records",
  1330.     "ladsoft",
  1331.     dbgls_init,
  1332.     dbgls_linnum,
  1333.     dbgls_deflabel,
  1334.     null_debug_routine,
  1335.     dbgls_typevalue,
  1336.     dbgls_output,
  1337.     dbgls_cleanup,
  1338. };
  1339. static struct dfmt *ladsoft_debug_arr[3] = {
  1340. &ladsoft_debug_form,
  1341. &null_debug_form,
  1342. NULL
  1343. };
  1344. struct ofmt of_ieee = {
  1345.     "IEEE-695 (LADsoft variant) object file format",
  1346.     "ieee",
  1347.     NULL,
  1348.     ladsoft_debug_arr,
  1349.     &null_debug_form,
  1350.     NULL,
  1351.     ieee_init,
  1352.     ieee_set_info,
  1353.     ieee_out,
  1354.     ieee_deflabel,
  1355.     ieee_segment,
  1356.     ieee_segbase,
  1357.     ieee_directive,
  1358.     ieee_filename,
  1359.     ieee_cleanup
  1360. };
  1361. #endif /* OF_IEEE */