Initial support for ELF64
[platform/upstream/nasm.git] / nasmlib.c
1 /* nasmlib.c    library routines for the Netwide Assembler
2  *
3  * The Netwide Assembler is copyright (C) 1996 Simon Tatham and
4  * Julian Hall. All rights reserved. The software is
5  * redistributable under the licence given in the file "Licence"
6  * distributed in the NASM archive.
7  */
8
9 #include <stdio.h>
10 #include <stdlib.h>
11 #include <string.h>
12 #include <ctype.h>
13 #include <inttypes.h>
14
15 #include "nasm.h"
16 #include "nasmlib.h"
17 #include "insns.h"              /* For MAX_KEYWORD */
18
19 int globalbits = 0;    /* defined in nasm.h, works better here for ASM+DISASM */
20
21 static efunc nasm_malloc_error;
22
23 #ifdef LOGALLOC
24 static FILE *logfp;
25 #endif
26
27 void nasm_set_malloc_error(efunc error)
28 {
29     nasm_malloc_error = error;
30 #ifdef LOGALLOC
31     logfp = fopen("malloc.log", "w");
32     setvbuf(logfp, NULL, _IOLBF, BUFSIZ);
33     fprintf(logfp, "null pointer is %p\n", NULL);
34 #endif
35 }
36
37 #ifdef LOGALLOC
38 void *nasm_malloc_log(char *file, int line, size_t size)
39 #else
40 void *nasm_malloc(size_t size)
41 #endif
42 {
43     void *p = malloc(size);
44     if (!p)
45         nasm_malloc_error(ERR_FATAL | ERR_NOFILE, "out of memory");
46 #ifdef LOGALLOC
47     else
48         fprintf(logfp, "%s %d malloc(%ld) returns %p\n",
49                 file, line, (int32_t)size, p);
50 #endif
51     return p;
52 }
53
54 #ifdef LOGALLOC
55 void *nasm_realloc_log(char *file, int line, void *q, size_t size)
56 #else
57 void *nasm_realloc(void *q, size_t size)
58 #endif
59 {
60     void *p = q ? realloc(q, size) : malloc(size);
61     if (!p)
62         nasm_malloc_error(ERR_FATAL | ERR_NOFILE, "out of memory");
63 #ifdef LOGALLOC
64     else if (q)
65         fprintf(logfp, "%s %d realloc(%p,%ld) returns %p\n",
66                 file, line, q, (int32_t)size, p);
67     else
68         fprintf(logfp, "%s %d malloc(%ld) returns %p\n",
69                 file, line, (int32_t)size, p);
70 #endif
71     return p;
72 }
73
74 #ifdef LOGALLOC
75 void nasm_free_log(char *file, int line, void *q)
76 #else
77 void nasm_free(void *q)
78 #endif
79 {
80     if (q) {
81         free(q);
82 #ifdef LOGALLOC
83         fprintf(logfp, "%s %d free(%p)\n", file, line, q);
84 #endif
85     }
86 }
87
88 #ifdef LOGALLOC
89 char *nasm_strdup_log(char *file, int line, const char *s)
90 #else
91 char *nasm_strdup(const char *s)
92 #endif
93 {
94     char *p;
95     int size = strlen(s) + 1;
96
97     p = malloc(size);
98     if (!p)
99         nasm_malloc_error(ERR_FATAL | ERR_NOFILE, "out of memory");
100 #ifdef LOGALLOC
101     else
102         fprintf(logfp, "%s %d strdup(%ld) returns %p\n",
103                 file, line, (int32_t)size, p);
104 #endif
105     strcpy(p, s);
106     return p;
107 }
108
109 #ifdef LOGALLOC
110 char *nasm_strndup_log(char *file, int line, char *s, size_t len)
111 #else
112 char *nasm_strndup(char *s, size_t len)
113 #endif
114 {
115     char *p;
116     int size = len + 1;
117
118     p = malloc(size);
119     if (!p)
120         nasm_malloc_error(ERR_FATAL | ERR_NOFILE, "out of memory");
121 #ifdef LOGALLOC
122     else
123         fprintf(logfp, "%s %d strndup(%ld) returns %p\n",
124                 file, line, (int32_t)size, p);
125 #endif
126     strncpy(p, s, len);
127     p[len] = '\0';
128     return p;
129 }
130
131 #if !defined(stricmp) && !defined(strcasecmp)
132 int nasm_stricmp(const char *s1, const char *s2)
133 {
134     while (*s1 && tolower(*s1) == tolower(*s2))
135         s1++, s2++;
136     if (!*s1 && !*s2)
137         return 0;
138     else if (tolower(*s1) < tolower(*s2))
139         return -1;
140     else
141         return 1;
142 }
143 #endif
144
145 #if !defined(strnicmp) && !defined(strncasecmp)
146 int nasm_strnicmp(const char *s1, const char *s2, int n)
147 {
148     while (n > 0 && *s1 && tolower(*s1) == tolower(*s2))
149         s1++, s2++, n--;
150     if ((!*s1 && !*s2) || n == 0)
151         return 0;
152     else if (tolower(*s1) < tolower(*s2))
153         return -1;
154     else
155         return 1;
156 }
157 #endif
158
159 #define lib_isnumchar(c)   ( isalnum(c) || (c) == '$')
160 #define numvalue(c)  ((c)>='a' ? (c)-'a'+10 : (c)>='A' ? (c)-'A'+10 : (c)-'0')
161
162 int64_t readnum(char *str, int *error)
163 {
164     char *r = str, *q;
165     int32_t radix;
166     uint64_t result, checklimit;
167     int digit, last;
168     int warn = FALSE;
169     int sign = 1;
170
171     *error = FALSE;
172
173     while (isspace(*r))
174         r++;                    /* find start of number */
175
176     /*
177      * If the number came from make_tok_num (as a result of an %assign), it
178      * might have a '-' built into it (rather than in a preceeding token).
179      */
180     if (*r == '-') {
181         r++;
182         sign = -1;
183     }
184
185     q = r;
186
187     while (lib_isnumchar(*q))
188         q++;                    /* find end of number */
189
190     /*
191      * If it begins 0x, 0X or $, or ends in H, it's in hex. if it
192      * ends in Q, it's octal. if it ends in B, it's binary.
193      * Otherwise, it's ordinary decimal.
194      */
195     if (*r == '0' && (r[1] == 'x' || r[1] == 'X'))
196         radix = 16, r += 2;
197     else if (*r == '$')
198         radix = 16, r++;
199     else if (q[-1] == 'H' || q[-1] == 'h')
200         radix = 16, q--;
201     else if (q[-1] == 'Q' || q[-1] == 'q' || q[-1] == 'O' || q[-1] == 'o')
202         radix = 8, q--;
203     else if (q[-1] == 'B' || q[-1] == 'b')
204         radix = 2, q--;
205     else
206         radix = 10;
207
208     /*
209      * If this number has been found for us by something other than
210      * the ordinary scanners, then it might be malformed by having
211      * nothing between the prefix and the suffix. Check this case
212      * now.
213      */
214     if (r >= q) {
215         *error = TRUE;
216         return 0;
217     }
218     
219     /*
220      * `checklimit' must be 2**(32|64) / radix. We can't do that in
221      * 32/64-bit arithmetic, which we're (probably) using, so we
222      * cheat: since we know that all radices we use are even, we
223      * can divide 2**(31|63) by radix/2 instead.
224      */
225     if (globalbits == 64)
226         checklimit = 0x8000000000000000ULL / (radix >> 1);
227     else
228         checklimit = 0x80000000UL / (radix >> 1);
229
230     /*
231      * Calculate the highest allowable value for the last digit of a
232      * 32-bit constant... in radix 10, it is 6, otherwise it is 0
233      */
234     last = (radix == 10 ? 6 : 0);
235
236     result = 0;
237     while (*r && r < q) {
238         if (*r < '0' || (*r > '9' && *r < 'A')
239             || (digit = numvalue(*r)) >= radix) {
240             *error = TRUE;
241             return 0;
242         }
243         if (result > checklimit || (result == checklimit && digit >= last)) {
244             warn = TRUE;
245         }
246
247         result = radix * result + digit;
248         r++;
249     }
250
251     if (warn)
252         nasm_malloc_error(ERR_WARNING | ERR_PASS1 | ERR_WARN_NOV,
253                           "numeric constant %s does not fit in 32 bits",
254                           str);
255
256     return result * sign;
257 }
258
259 int64_t readstrnum(char *str, int length, int *warn)
260 {
261     int64_t charconst = 0;
262     int i;
263
264     *warn = FALSE;
265
266     str += length;
267     if (globalbits == 64) {
268         for (i = 0; i < length; i++) {
269             if (charconst & 0xFF00000000000000ULL)
270                 *warn = TRUE;
271             charconst = (charconst << 8) + (uint8_t)*--str;
272         }
273     } else {
274         for (i = 0; i < length; i++) {
275             if (charconst & 0xFF000000UL)
276                 *warn = TRUE;
277             charconst = (charconst << 8) + (uint8_t)*--str;
278         }
279     }
280     return charconst;
281 }
282
283 static int32_t next_seg;
284
285 void seg_init(void)
286 {
287     next_seg = 0;
288 }
289
290 int32_t seg_alloc(void)
291 {
292     return (next_seg += 2) - 2;
293 }
294
295 void fwriteint16_t(int data, FILE * fp)
296 {
297     fputc((int)(data & 255), fp);
298     fputc((int)((data >> 8) & 255), fp);
299 }
300
301 void fwriteint32_t(int32_t data, FILE * fp)
302 {
303     fputc((int)(data & 255), fp);
304     fputc((int)((data >> 8) & 255), fp);
305     fputc((int)((data >> 16) & 255), fp);
306     fputc((int)((data >> 24) & 255), fp);
307 }
308
309 void fwriteint64_t(int64_t data, FILE * fp)
310 {
311     fputc((int)(data & 255), fp);
312     fputc((int)((data >> 8) & 255), fp);
313     fputc((int)((data >> 16) & 255), fp);
314     fputc((int)((data >> 24) & 255), fp);
315     fputc((int)((data >> 32) & 255), fp);
316     fputc((int)((data >> 40) & 255), fp);
317     fputc((int)((data >> 48) & 255), fp);
318     fputc((int)((data >> 56) & 255), fp);
319 }
320
321 void standard_extension(char *inname, char *outname, char *extension,
322                         efunc error)
323 {
324     char *p, *q;
325
326     if (*outname)               /* file name already exists, */
327         return;                 /* so do nothing */
328     q = inname;
329     p = outname;
330     while (*q)
331         *p++ = *q++;            /* copy, and find end of string */
332     *p = '\0';                  /* terminate it */
333     while (p > outname && *--p != '.') ;        /* find final period (or whatever) */
334     if (*p != '.')
335         while (*p)
336             p++;                /* go back to end if none found */
337     if (!strcmp(p, extension)) {        /* is the extension already there? */
338         if (*extension)
339             error(ERR_WARNING | ERR_NOFILE,
340                   "file name already ends in `%s': "
341                   "output will be in `nasm.out'", extension);
342         else
343             error(ERR_WARNING | ERR_NOFILE,
344                   "file name already has no extension: "
345                   "output will be in `nasm.out'");
346         strcpy(outname, "nasm.out");
347     } else
348         strcpy(p, extension);
349 }
350
351 #define LEAFSIZ (sizeof(RAA)-sizeof(RAA_UNION)+sizeof(RAA_LEAF))
352 #define BRANCHSIZ (sizeof(RAA)-sizeof(RAA_UNION)+sizeof(RAA_BRANCH))
353
354 #define LAYERSIZ(r) ( (r)->layers==0 ? RAA_BLKSIZE : RAA_LAYERSIZE )
355
356 static struct RAA *real_raa_init(int layers)
357 {
358     struct RAA *r;
359     int i;
360
361     if (layers == 0) {
362         r = nasm_malloc(LEAFSIZ);
363         r->layers = 0;
364         memset(r->u.l.data, 0, sizeof(r->u.l.data));
365         r->stepsize = 1L;
366     } else {
367         r = nasm_malloc(BRANCHSIZ);
368         r->layers = layers;
369         for (i = 0; i < RAA_LAYERSIZE; i++)
370             r->u.b.data[i] = NULL;
371         r->stepsize = RAA_BLKSIZE;
372         while (--layers)
373             r->stepsize *= RAA_LAYERSIZE;
374     }
375     return r;
376 }
377
378 struct RAA *raa_init(void)
379 {
380     return real_raa_init(0);
381 }
382
383 void raa_free(struct RAA *r)
384 {
385     if (r->layers == 0)
386         nasm_free(r);
387     else {
388         struct RAA **p;
389         for (p = r->u.b.data; p - r->u.b.data < RAA_LAYERSIZE; p++)
390             if (*p)
391                 raa_free(*p);
392     }
393 }
394
395 int32_t raa_read(struct RAA *r, int32_t posn)
396 {
397     if (posn >= r->stepsize * LAYERSIZ(r))
398         return 0;               /* Return 0 for undefined entries */
399     while (r->layers > 0) {
400         ldiv_t l;
401         l = ldiv(posn, r->stepsize);
402         r = r->u.b.data[l.quot];
403         posn = l.rem;
404         if (!r)
405             return 0;           /* Return 0 for undefined entries */
406     }
407     return r->u.l.data[posn];
408 }
409
410 struct RAA *raa_write(struct RAA *r, int32_t posn, int32_t value)
411 {
412     struct RAA *result;
413
414     if (posn < 0)
415         nasm_malloc_error(ERR_PANIC, "negative position in raa_write");
416
417     while (r->stepsize * LAYERSIZ(r) <= posn) {
418         /*
419          * Must add a layer.
420          */
421         struct RAA *s;
422         int i;
423
424         s = nasm_malloc(BRANCHSIZ);
425         for (i = 0; i < RAA_LAYERSIZE; i++)
426             s->u.b.data[i] = NULL;
427         s->layers = r->layers + 1;
428         s->stepsize = LAYERSIZ(r) * r->stepsize;
429         s->u.b.data[0] = r;
430         r = s;
431     }
432
433     result = r;
434
435     while (r->layers > 0) {
436         ldiv_t l;
437         struct RAA **s;
438         l = ldiv(posn, r->stepsize);
439         s = &r->u.b.data[l.quot];
440         if (!*s)
441             *s = real_raa_init(r->layers - 1);
442         r = *s;
443         posn = l.rem;
444     }
445
446     r->u.l.data[posn] = value;
447
448     return result;
449 }
450
451 #define SAA_MAXLEN 8192
452
453 struct SAA *saa_init(int32_t elem_len)
454 {
455     struct SAA *s;
456
457     if (elem_len > SAA_MAXLEN)
458         nasm_malloc_error(ERR_PANIC | ERR_NOFILE,
459                           "SAA with huge elements");
460
461     s = nasm_malloc(sizeof(struct SAA));
462     s->posn = s->start = 0L;
463     s->elem_len = elem_len;
464     s->length = SAA_MAXLEN - (SAA_MAXLEN % elem_len);
465     s->data = nasm_malloc(s->length);
466     s->next = NULL;
467     s->end = s;
468
469     return s;
470 }
471
472 void saa_free(struct SAA *s)
473 {
474     struct SAA *t;
475
476     while (s) {
477         t = s->next;
478         nasm_free(s->data);
479         nasm_free(s);
480         s = t;
481     }
482 }
483
484 void *saa_wstruct(struct SAA *s)
485 {
486     void *p;
487
488     if (s->end->length - s->end->posn < s->elem_len) {
489         s->end->next = nasm_malloc(sizeof(struct SAA));
490         s->end->next->start = s->end->start + s->end->posn;
491         s->end = s->end->next;
492         s->end->length = s->length;
493         s->end->next = NULL;
494         s->end->posn = 0L;
495         s->end->data = nasm_malloc(s->length);
496     }
497
498     p = s->end->data + s->end->posn;
499     s->end->posn += s->elem_len;
500     return p;
501 }
502
503 void saa_wbytes(struct SAA *s, const void *data, int32_t len)
504 {
505     const char *d = data;
506
507     while (len > 0) {
508         int32_t l = s->end->length - s->end->posn;
509         if (l > len)
510             l = len;
511         if (l > 0) {
512             if (d) {
513                 memcpy(s->end->data + s->end->posn, d, l);
514                 d += l;
515             } else
516                 memset(s->end->data + s->end->posn, 0, l);
517             s->end->posn += l;
518             len -= l;
519         }
520         if (len > 0) {
521             s->end->next = nasm_malloc(sizeof(struct SAA));
522             s->end->next->start = s->end->start + s->end->posn;
523             s->end = s->end->next;
524             s->end->length = s->length;
525             s->end->next = NULL;
526             s->end->posn = 0L;
527             s->end->data = nasm_malloc(s->length);
528         }
529     }
530 }
531
532 void saa_rewind(struct SAA *s)
533 {
534     s->rptr = s;
535     s->rpos = 0L;
536 }
537
538 void *saa_rstruct(struct SAA *s)
539 {
540     void *p;
541
542     if (!s->rptr)
543         return NULL;
544
545     if (s->rptr->posn - s->rpos < s->elem_len) {
546         s->rptr = s->rptr->next;
547         if (!s->rptr)
548             return NULL;        /* end of array */
549         s->rpos = 0L;
550     }
551
552     p = s->rptr->data + s->rpos;
553     s->rpos += s->elem_len;
554     return p;
555 }
556
557 void *saa_rbytes(struct SAA *s, int32_t *len)
558 {
559     void *p;
560
561     if (!s->rptr)
562         return NULL;
563
564     p = s->rptr->data + s->rpos;
565     *len = s->rptr->posn - s->rpos;
566     s->rptr = s->rptr->next;
567     s->rpos = 0L;
568     return p;
569 }
570
571 void saa_rnbytes(struct SAA *s, void *data, int32_t len)
572 {
573     char *d = data;
574
575     while (len > 0) {
576         int32_t l;
577
578         if (!s->rptr)
579             return;
580
581         l = s->rptr->posn - s->rpos;
582         if (l > len)
583             l = len;
584         if (l > 0) {
585             memcpy(d, s->rptr->data + s->rpos, l);
586             d += l;
587             s->rpos += l;
588             len -= l;
589         }
590         if (len > 0) {
591             s->rptr = s->rptr->next;
592             s->rpos = 0L;
593         }
594     }
595 }
596
597 void saa_fread(struct SAA *s, int32_t posn, void *data, int32_t len)
598 {
599     struct SAA *p;
600     int64_t pos;
601     char *cdata = data;
602
603     if (!s->rptr || posn < s->rptr->start)
604         saa_rewind(s);
605     p = s->rptr;
606     while (posn >= p->start + p->posn) {
607         p = p->next;
608         if (!p)
609             return;             /* what else can we do?! */
610     }
611
612     pos = posn - p->start;
613     while (len) {
614         int64_t l = p->posn - pos;
615         if (l > len)
616             l = len;
617         memcpy(cdata, p->data + pos, l);
618         len -= l;
619         cdata += l;
620         p = p->next;
621         if (!p)
622             return;
623         pos = 0LL;
624     }
625     s->rptr = p;
626 }
627
628 void saa_fwrite(struct SAA *s, int32_t posn, void *data, int32_t len)
629 {
630     struct SAA *p;
631     int64_t pos;
632     char *cdata = data;
633
634     if (!s->rptr || posn < s->rptr->start)
635         saa_rewind(s);
636     p = s->rptr;
637     while (posn >= p->start + p->posn) {
638         p = p->next;
639         if (!p)
640             return;             /* what else can we do?! */
641     }
642
643     pos = posn - p->start;
644     while (len) {
645         int64_t l = p->posn - pos;
646         if (l > len)
647             l = len;
648         memcpy(p->data + pos, cdata, l);
649         len -= l;
650         cdata += l;
651         p = p->next;
652         if (!p)
653             return;
654         pos = 0LL;
655     }
656     s->rptr = p;
657 }
658
659 void saa_fpwrite(struct SAA *s, FILE * fp)
660 {
661     char *data;
662     int32_t len;
663
664     saa_rewind(s);
665 //    while ((data = saa_rbytes(s, &len)))
666     for (; (data = saa_rbytes(s, &len));)
667         fwrite(data, 1, len, fp);
668 }
669
670 /*
671  * Register, instruction, condition-code and prefix keywords used
672  * by the scanner.
673  */
674 #include "names.c"
675 static const char *special_names[] = {
676     "byte", "dword", "far", "long", "near", "nosplit", "qword",
677     "short", "strict", "to", "tword", "word"
678 };
679 static const char *prefix_names[] = {
680     "a16", "a32", "lock", "o16", "o32", "rep", "repe", "repne",
681     "repnz", "repz", "times"
682 };
683
684 const char *prefix_name(int token)
685 {
686     unsigned int prefix = token-PREFIX_ENUM_START;
687     if (prefix > sizeof prefix_names / sizeof(const char *))
688         return NULL;
689
690     return prefix_names[prefix];
691 }
692
693 /*
694  * Standard scanner routine used by parser.c and some output
695  * formats. It keeps a succession of temporary-storage strings in
696  * stdscan_tempstorage, which can be cleared using stdscan_reset.
697  */
698 static char **stdscan_tempstorage = NULL;
699 static int stdscan_tempsize = 0, stdscan_templen = 0;
700 #define STDSCAN_TEMP_DELTA 256
701
702 static void stdscan_pop(void)
703 {
704     nasm_free(stdscan_tempstorage[--stdscan_templen]);
705 }
706
707 void stdscan_reset(void)
708 {
709     while (stdscan_templen > 0)
710         stdscan_pop();
711 }
712
713 /*
714  * Unimportant cleanup is done to avoid confusing people who are trying
715  * to debug real memory leaks
716  */
717 void nasmlib_cleanup(void)
718 {
719     stdscan_reset();
720     nasm_free(stdscan_tempstorage);
721 }
722
723 static char *stdscan_copy(char *p, int len)
724 {
725     char *text;
726
727     text = nasm_malloc(len + 1);
728     strncpy(text, p, len);
729     text[len] = '\0';
730
731     if (stdscan_templen >= stdscan_tempsize) {
732         stdscan_tempsize += STDSCAN_TEMP_DELTA;
733         stdscan_tempstorage = nasm_realloc(stdscan_tempstorage,
734                                            stdscan_tempsize *
735                                            sizeof(char *));
736     }
737     stdscan_tempstorage[stdscan_templen++] = text;
738
739     return text;
740 }
741
742 char *stdscan_bufptr = NULL;
743 int stdscan(void *private_data, struct tokenval *tv)
744 {
745     char ourcopy[MAX_KEYWORD + 1], *r, *s;
746
747     (void)private_data;         /* Don't warn that this parameter is unused */
748
749     while (isspace(*stdscan_bufptr))
750         stdscan_bufptr++;
751     if (!*stdscan_bufptr)
752         return tv->t_type = 0;
753
754     /* we have a token; either an id, a number or a char */
755     if (isidstart(*stdscan_bufptr) ||
756         (*stdscan_bufptr == '$' && isidstart(stdscan_bufptr[1]))) {
757         /* now we've got an identifier */
758         int i;
759         int is_sym = FALSE;
760
761         if (*stdscan_bufptr == '$') {
762             is_sym = TRUE;
763             stdscan_bufptr++;
764         }
765
766         r = stdscan_bufptr++;
767         /* read the entire buffer to advance the buffer pointer but... */
768         while (isidchar(*stdscan_bufptr))
769             stdscan_bufptr++;
770
771         /* ... copy only up to IDLEN_MAX-1 characters */
772         tv->t_charptr = stdscan_copy(r, stdscan_bufptr - r < IDLEN_MAX ?
773                                      stdscan_bufptr - r : IDLEN_MAX - 1);
774
775         if (is_sym || stdscan_bufptr - r > MAX_KEYWORD)
776             return tv->t_type = TOKEN_ID;       /* bypass all other checks */
777
778         for (s = tv->t_charptr, r = ourcopy; *s; s++)
779             *r++ = tolower(*s);
780         *r = '\0';
781         /* right, so we have an identifier sitting in temp storage. now,
782          * is it actually a register or instruction name, or what? */
783         if ((tv->t_integer = bsi(ourcopy, reg_names,
784                                  elements(reg_names))) >= 0) {
785             tv->t_integer += EXPR_REG_START;
786             return tv->t_type = TOKEN_REG;
787         } else if ((tv->t_integer = bsi(ourcopy, insn_names,
788                                         elements(insn_names))) >= 0) {
789             return tv->t_type = TOKEN_INSN;
790         }
791         for (i = 0; i < elements(icn); i++)
792             if (!strncmp(ourcopy, icn[i], strlen(icn[i]))) {
793                 char *p = ourcopy + strlen(icn[i]);
794                 tv->t_integer = ico[i];
795                 if ((tv->t_inttwo = bsi(p, conditions,
796                                         elements(conditions))) >= 0)
797                     return tv->t_type = TOKEN_INSN;
798             }
799         if ((tv->t_integer = bsi(ourcopy, prefix_names,
800                                  elements(prefix_names))) >= 0) {
801             tv->t_integer += PREFIX_ENUM_START;
802             return tv->t_type = TOKEN_PREFIX;
803         }
804         if ((tv->t_integer = bsi(ourcopy, special_names,
805                                  elements(special_names))) >= 0)
806             return tv->t_type = TOKEN_SPECIAL;
807         if (!nasm_stricmp(ourcopy, "seg"))
808             return tv->t_type = TOKEN_SEG;
809         if (!nasm_stricmp(ourcopy, "wrt"))
810             return tv->t_type = TOKEN_WRT;
811         return tv->t_type = TOKEN_ID;
812     } else if (*stdscan_bufptr == '$' && !isnumchar(stdscan_bufptr[1])) {
813         /*
814          * It's a $ sign with no following hex number; this must
815          * mean it's a Here token ($), evaluating to the current
816          * assembly location, or a Base token ($$), evaluating to
817          * the base of the current segment.
818          */
819         stdscan_bufptr++;
820         if (*stdscan_bufptr == '$') {
821             stdscan_bufptr++;
822             return tv->t_type = TOKEN_BASE;
823         }
824         return tv->t_type = TOKEN_HERE;
825     } else if (isnumstart(*stdscan_bufptr)) {   /* now we've got a number */
826         int rn_error;
827
828         r = stdscan_bufptr++;
829         while (isnumchar(*stdscan_bufptr))
830             stdscan_bufptr++;
831
832         if (*stdscan_bufptr == '.') {
833             /*
834              * a floating point constant
835              */
836             stdscan_bufptr++;
837             while (isnumchar(*stdscan_bufptr) ||
838                    ((stdscan_bufptr[-1] == 'e'
839                      || stdscan_bufptr[-1] == 'E')
840                     && (*stdscan_bufptr == '-' || *stdscan_bufptr == '+'))) {
841                 stdscan_bufptr++;
842             }
843             tv->t_charptr = stdscan_copy(r, stdscan_bufptr - r);
844             return tv->t_type = TOKEN_FLOAT;
845         }
846         r = stdscan_copy(r, stdscan_bufptr - r);
847         tv->t_integer = readnum(r, &rn_error);
848         stdscan_pop();
849         if (rn_error)
850             return tv->t_type = TOKEN_ERRNUM;   /* some malformation occurred */
851         tv->t_charptr = NULL;
852         return tv->t_type = TOKEN_NUM;
853     } else if (*stdscan_bufptr == '\'' || *stdscan_bufptr == '"') {     /* a char constant */
854         char quote = *stdscan_bufptr++, *r;
855         int rn_warn;
856         r = tv->t_charptr = stdscan_bufptr;
857         while (*stdscan_bufptr && *stdscan_bufptr != quote)
858             stdscan_bufptr++;
859         tv->t_inttwo = stdscan_bufptr - r;      /* store full version */
860         if (!*stdscan_bufptr)
861             return tv->t_type = TOKEN_ERRNUM;   /* unmatched quotes */
862         stdscan_bufptr++;       /* skip over final quote */
863         tv->t_integer = readstrnum(r, tv->t_inttwo, &rn_warn);
864         /* FIXME: rn_warn is not checked! */
865         return tv->t_type = TOKEN_NUM;
866     } else if (*stdscan_bufptr == ';') {        /* a comment has happened - stay */
867         return tv->t_type = 0;
868     } else if (stdscan_bufptr[0] == '>' && stdscan_bufptr[1] == '>') {
869         stdscan_bufptr += 2;
870         return tv->t_type = TOKEN_SHR;
871     } else if (stdscan_bufptr[0] == '<' && stdscan_bufptr[1] == '<') {
872         stdscan_bufptr += 2;
873         return tv->t_type = TOKEN_SHL;
874     } else if (stdscan_bufptr[0] == '/' && stdscan_bufptr[1] == '/') {
875         stdscan_bufptr += 2;
876         return tv->t_type = TOKEN_SDIV;
877     } else if (stdscan_bufptr[0] == '%' && stdscan_bufptr[1] == '%') {
878         stdscan_bufptr += 2;
879         return tv->t_type = TOKEN_SMOD;
880     } else if (stdscan_bufptr[0] == '=' && stdscan_bufptr[1] == '=') {
881         stdscan_bufptr += 2;
882         return tv->t_type = TOKEN_EQ;
883     } else if (stdscan_bufptr[0] == '<' && stdscan_bufptr[1] == '>') {
884         stdscan_bufptr += 2;
885         return tv->t_type = TOKEN_NE;
886     } else if (stdscan_bufptr[0] == '!' && stdscan_bufptr[1] == '=') {
887         stdscan_bufptr += 2;
888         return tv->t_type = TOKEN_NE;
889     } else if (stdscan_bufptr[0] == '<' && stdscan_bufptr[1] == '=') {
890         stdscan_bufptr += 2;
891         return tv->t_type = TOKEN_LE;
892     } else if (stdscan_bufptr[0] == '>' && stdscan_bufptr[1] == '=') {
893         stdscan_bufptr += 2;
894         return tv->t_type = TOKEN_GE;
895     } else if (stdscan_bufptr[0] == '&' && stdscan_bufptr[1] == '&') {
896         stdscan_bufptr += 2;
897         return tv->t_type = TOKEN_DBL_AND;
898     } else if (stdscan_bufptr[0] == '^' && stdscan_bufptr[1] == '^') {
899         stdscan_bufptr += 2;
900         return tv->t_type = TOKEN_DBL_XOR;
901     } else if (stdscan_bufptr[0] == '|' && stdscan_bufptr[1] == '|') {
902         stdscan_bufptr += 2;
903         return tv->t_type = TOKEN_DBL_OR;
904     } else                      /* just an ordinary char */
905         return tv->t_type = (uint8_t)(*stdscan_bufptr++);
906 }
907
908 /*
909  * Return TRUE if the argument is a simple scalar. (Or a far-
910  * absolute, which counts.)
911  */
912 int is_simple(expr * vect)
913 {
914     while (vect->type && !vect->value)
915         vect++;
916     if (!vect->type)
917         return 1;
918     if (vect->type != EXPR_SIMPLE)
919         return 0;
920     do {
921         vect++;
922     } while (vect->type && !vect->value);
923     if (vect->type && vect->type < EXPR_SEGBASE + SEG_ABS)
924         return 0;
925     return 1;
926 }
927
928 /*
929  * Return TRUE if the argument is a simple scalar, _NOT_ a far-
930  * absolute.
931  */
932 int is_really_simple(expr * vect)
933 {
934     while (vect->type && !vect->value)
935         vect++;
936     if (!vect->type)
937         return 1;
938     if (vect->type != EXPR_SIMPLE)
939         return 0;
940     do {
941         vect++;
942     } while (vect->type && !vect->value);
943     if (vect->type)
944         return 0;
945     return 1;
946 }
947
948 /*
949  * Return TRUE if the argument is relocatable (i.e. a simple
950  * scalar, plus at most one segment-base, plus possibly a WRT).
951  */
952 int is_reloc(expr * vect)
953 {
954     while (vect->type && !vect->value)  /* skip initial value-0 terms */
955         vect++;
956     if (!vect->type)            /* trivially return TRUE if nothing */
957         return 1;               /* is present apart from value-0s */
958     if (vect->type < EXPR_SIMPLE)       /* FALSE if a register is present */
959         return 0;
960     if (vect->type == EXPR_SIMPLE) {    /* skip over a pure number term... */
961         do {
962             vect++;
963         } while (vect->type && !vect->value);
964         if (!vect->type)        /* ...returning TRUE if that's all */
965             return 1;
966     }
967     if (vect->type == EXPR_WRT) {       /* skip over a WRT term... */
968         do {
969             vect++;
970         } while (vect->type && !vect->value);
971         if (!vect->type)        /* ...returning TRUE if that's all */
972             return 1;
973     }
974     if (vect->value != 0 && vect->value != 1)
975         return 0;               /* segment base multiplier non-unity */
976     do {                        /* skip over _one_ seg-base term... */
977         vect++;
978     } while (vect->type && !vect->value);
979     if (!vect->type)            /* ...returning TRUE if that's all */
980         return 1;
981     return 0;                   /* And return FALSE if there's more */
982 }
983
984 /*
985  * Return TRUE if the argument contains an `unknown' part.
986  */
987 int is_unknown(expr * vect)
988 {
989     while (vect->type && vect->type < EXPR_UNKNOWN)
990         vect++;
991     return (vect->type == EXPR_UNKNOWN);
992 }
993
994 /*
995  * Return TRUE if the argument contains nothing but an `unknown'
996  * part.
997  */
998 int is_just_unknown(expr * vect)
999 {
1000     while (vect->type && !vect->value)
1001         vect++;
1002     return (vect->type == EXPR_UNKNOWN);
1003 }
1004
1005 /*
1006  * Return the scalar part of a relocatable vector. (Including
1007  * simple scalar vectors - those qualify as relocatable.)
1008  */
1009 int64_t reloc_value(expr * vect)
1010 {
1011     while (vect->type && !vect->value)
1012         vect++;
1013     if (!vect->type)
1014         return 0;
1015     if (vect->type == EXPR_SIMPLE)
1016         return vect->value;
1017     else
1018         return 0;
1019 }
1020
1021 /*
1022  * Return the segment number of a relocatable vector, or NO_SEG for
1023  * simple scalars.
1024  */
1025 int32_t reloc_seg(expr * vect)
1026 {
1027     while (vect->type && (vect->type == EXPR_WRT || !vect->value))
1028         vect++;
1029     if (vect->type == EXPR_SIMPLE) {
1030         do {
1031             vect++;
1032         } while (vect->type && (vect->type == EXPR_WRT || !vect->value));
1033     }
1034     if (!vect->type)
1035         return NO_SEG;
1036     else
1037         return vect->type - EXPR_SEGBASE;
1038 }
1039
1040 /*
1041  * Return the WRT segment number of a relocatable vector, or NO_SEG
1042  * if no WRT part is present.
1043  */
1044 int32_t reloc_wrt(expr * vect)
1045 {
1046     while (vect->type && vect->type < EXPR_WRT)
1047         vect++;
1048     if (vect->type == EXPR_WRT) {
1049         return vect->value;
1050     } else
1051         return NO_SEG;
1052 }
1053
1054 /*
1055  * Binary search.
1056  */
1057 int bsi(char *string, const char **array, int size)
1058 {
1059     int i = -1, j = size;       /* always, i < index < j */
1060     while (j - i >= 2) {
1061         int k = (i + j) / 2;
1062         int l = strcmp(string, array[k]);
1063         if (l < 0)              /* it's in the first half */
1064             j = k;
1065         else if (l > 0)         /* it's in the second half */
1066             i = k;
1067         else                    /* we've got it :) */
1068             return k;
1069     }
1070     return -1;                  /* we haven't got it :( */
1071 }
1072
1073 static char *file_name = NULL;
1074 static int32_t line_number = 0;
1075
1076 char *src_set_fname(char *newname)
1077 {
1078     char *oldname = file_name;
1079     file_name = newname;
1080     return oldname;
1081 }
1082
1083 int32_t src_set_linnum(int32_t newline)
1084 {
1085     int32_t oldline = line_number;
1086     line_number = newline;
1087     return oldline;
1088 }
1089
1090 int32_t src_get_linnum(void)
1091 {
1092     return line_number;
1093 }
1094
1095 int src_get(int32_t *xline, char **xname)
1096 {
1097     if (!file_name || !*xname || strcmp(*xname, file_name)) {
1098         nasm_free(*xname);
1099         *xname = file_name ? nasm_strdup(file_name) : NULL;
1100         *xline = line_number;
1101         return -2;
1102     }
1103     if (*xline != line_number) {
1104         int32_t tmp = line_number - *xline;
1105         *xline = line_number;
1106         return tmp;
1107     }
1108     return 0;
1109 }
1110
1111 void nasm_quote(char **str)
1112 {
1113     int ln = strlen(*str);
1114     char q = (*str)[0];
1115     char *p;
1116     if (ln > 1 && (*str)[ln - 1] == q && (q == '"' || q == '\''))
1117         return;
1118     q = '"';
1119     if (strchr(*str, q))
1120         q = '\'';
1121     p = nasm_malloc(ln + 3);
1122     strcpy(p + 1, *str);
1123     nasm_free(*str);
1124     p[ln + 1] = p[0] = q;
1125     p[ln + 2] = 0;
1126     *str = p;
1127 }
1128
1129 char *nasm_strcat(char *one, char *two)
1130 {
1131     char *rslt;
1132     int l1 = strlen(one);
1133     rslt = nasm_malloc(l1 + strlen(two) + 1);
1134     strcpy(rslt, one);
1135     strcpy(rslt + l1, two);
1136     return rslt;
1137 }
1138
1139 void null_debug_init(struct ofmt *of, void *id, FILE * fp, efunc error)
1140 {
1141         (void)of;
1142         (void)id;
1143         (void)fp;
1144         (void)error;
1145 }
1146 void null_debug_linenum(const char *filename, int32_t linenumber, int32_t segto)
1147 {
1148         (void)filename;
1149         (void)linenumber;
1150         (void)segto;    
1151 }
1152 void null_debug_deflabel(char *name, int32_t segment, int32_t offset,
1153                          int is_global, char *special)
1154 {
1155         (void)name;
1156         (void)segment;
1157         (void)offset;
1158         (void)is_global;
1159         (void)special;
1160 }
1161 void null_debug_routine(const char *directive, const char *params)
1162 {
1163         (void)directive;
1164         (void)params;
1165 }
1166 void null_debug_typevalue(int32_t type)
1167 {
1168         (void)type;
1169 }
1170 void null_debug_output(int type, void *param)
1171 {
1172         (void)type;
1173         (void)param;
1174 }
1175 void null_debug_cleanup(void)
1176 {
1177 }
1178
1179 struct dfmt null_debug_form = {
1180     "Null debug format",
1181     "null",
1182     null_debug_init,
1183     null_debug_linenum,
1184     null_debug_deflabel,
1185     null_debug_routine,
1186     null_debug_typevalue,
1187     null_debug_output,
1188     null_debug_cleanup
1189 };
1190
1191 struct dfmt *null_debug_arr[2] = { &null_debug_form, NULL };