Hash even backend-specific directives, unify null functions
[platform/upstream/nasm.git] / output / outelf32.c
1 /* ----------------------------------------------------------------------- *
2  *   
3  *   Copyright 1996-2009 The NASM Authors - All Rights Reserved
4  *   See the file AUTHORS included with the NASM distribution for
5  *   the specific copyright holders.
6  *
7  *   Redistribution and use in source and binary forms, with or without
8  *   modification, are permitted provided that the following
9  *   conditions are met:
10  *
11  *   * Redistributions of source code must retain the above copyright
12  *     notice, this list of conditions and the following disclaimer.
13  *   * Redistributions in binary form must reproduce the above
14  *     copyright notice, this list of conditions and the following
15  *     disclaimer in the documentation and/or other materials provided
16  *     with the distribution.
17  *     
18  *     THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
19  *     CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
20  *     INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
21  *     MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
22  *     DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
23  *     CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24  *     SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
25  *     NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
26  *     LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27  *     HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28  *     CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
29  *     OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
30  *     EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31  *
32  * ----------------------------------------------------------------------- */
33
34 /*
35  * outelf32.c   output routines for the Netwide Assembler to produce
36  *              ELF32 (i386 of course) object file format
37  */
38
39 #include "compiler.h"
40
41 #include <stdio.h>
42 #include <stdlib.h>
43 #include <string.h>
44 #include <ctype.h>
45 #include <inttypes.h>
46
47 #include "nasm.h"
48 #include "nasmlib.h"
49 #include "saa.h"
50 #include "raa.h"
51 #include "stdscan.h"
52 #include "output/outform.h"
53 #include "output/outlib.h"
54 #include "rbtree.h"
55
56 #include "output/elf32.h"
57 #include "output/dwarf.h"
58 #include "output/outelf.h"
59
60 #ifdef OF_ELF32
61
62 /*
63  * Relocation types.
64  */
65 struct Reloc {
66     struct Reloc *next;
67     int32_t address;               /* relative to _start_ of section */
68     int32_t symbol;                /*  symbol index */
69     int type;                   /* type of relocation */
70 };
71
72 struct Symbol {
73     struct rbtree symv;        /* symbol value and symbol rbtree */
74     int32_t strpos;            /* string table position of name */
75     int32_t section;           /* section ID of the symbol */
76     int type;                  /* symbol type */
77     int other;                 /* symbol visibility */
78     int32_t size;              /* size of symbol */
79     int32_t globnum;           /* symbol table offset if global */
80     struct Symbol *nextfwd;    /* list of unresolved-size symbols */
81     char *name;                /* used temporarily if in above list */
82 };
83
84 struct Section {
85     struct SAA *data;
86     uint32_t len, size, nrelocs;
87     int32_t index;
88     int type;                   /* SHT_PROGBITS or SHT_NOBITS */
89     uint32_t align;             /* alignment: power of two */
90     uint32_t flags;             /* section flags */
91     char *name;
92     struct SAA *rel;
93     int32_t rellen;
94     struct Reloc *head, **tail;
95     struct rbtree *gsyms;       /* global symbols in section */
96 };
97
98 #define SECT_DELTA 32
99 static struct Section **sects;
100 static int nsects, sectlen;
101
102 #define SHSTR_DELTA 256
103 static char *shstrtab;
104 static int shstrtablen, shstrtabsize;
105
106 static struct SAA *syms;
107 static uint32_t nlocals, nglobs, ndebugs; /* Symbol counts */
108
109 static int32_t def_seg;
110
111 static struct RAA *bsym;
112
113 static struct SAA *strs;
114 static uint32_t strslen;
115
116 static FILE *elffp;
117 static efunc error;
118 static evalfunc evaluate;
119
120 static struct Symbol *fwds;
121
122 static char elf_module[FILENAME_MAX];
123
124 static uint8_t elf_osabi = 0;   /* Default OSABI = 0 (System V or Linux) */
125 static uint8_t elf_abiver = 0;  /* Current ABI version */
126
127 extern struct ofmt of_elf32;
128 extern struct ofmt of_elf;
129
130 #define SOC(ln,aa) ln - line_base + (line_range * aa) + opcode_base
131
132 static struct ELF_SECTDATA {
133     void *data;
134     int32_t len;
135     bool is_saa;
136 } *elf_sects;
137 static int elf_nsect, nsections;
138 static int32_t elf_foffs;
139
140 static void elf_write(void);
141 static void elf_sect_write(struct Section *, const uint8_t *,
142                            uint32_t);
143 static void elf_section_header(int, int, int, void *, bool, int32_t, int, int,
144                                int, int);
145 static void elf_write_sections(void);
146 static struct SAA *elf_build_symtab(int32_t *, int32_t *);
147 static struct SAA *elf_build_reltab(int32_t *, struct Reloc *);
148 static void add_sectname(char *, char *);
149
150 struct stabentry {
151     uint32_t n_strx;
152     uint8_t n_type;
153     uint8_t n_other;
154     uint16_t n_desc;
155     uint32_t n_value;
156 };
157
158 struct erel {
159     int offset, info;
160 };
161
162 struct symlininfo {
163     int offset;
164     int section;                /* section index */
165     char *name;                 /* shallow-copied pointer of section name */
166 };
167
168 struct linelist {
169     struct symlininfo info;
170     int line;
171     char *filename;
172     struct linelist *next;
173     struct linelist *last;
174 };
175
176 struct sectlist {
177     struct SAA *psaa;
178     int section;
179     int line;
180     int offset;
181     int file;
182     struct sectlist *next;
183     struct sectlist *last;
184 };
185
186 /* common debug variables */
187 static int currentline = 1;
188 static int debug_immcall = 0;
189
190 /* stabs debug variables */
191 static struct linelist *stabslines = 0;
192 static int numlinestabs = 0;
193 static char *stabs_filename = 0;
194 static uint8_t *stabbuf = 0, *stabstrbuf = 0, *stabrelbuf = 0;
195 static int stablen, stabstrlen, stabrellen;
196
197 /* dwarf debug variables */
198 static struct linelist *dwarf_flist = 0, *dwarf_clist = 0, *dwarf_elist = 0;
199 static struct sectlist *dwarf_fsect = 0, *dwarf_csect = 0, *dwarf_esect = 0;
200 static int dwarf_numfiles = 0, dwarf_nsections;
201 static uint8_t *arangesbuf = 0, *arangesrelbuf = 0, *pubnamesbuf = 0, *infobuf = 0,  *inforelbuf = 0,
202                *abbrevbuf = 0, *linebuf = 0, *linerelbuf = 0, *framebuf = 0, *locbuf = 0;
203 static int8_t line_base = -5, line_range = 14, opcode_base = 13;
204 static int arangeslen, arangesrellen, pubnameslen, infolen, inforellen,
205            abbrevlen, linelen, linerellen, framelen, loclen;
206 static int32_t dwarf_infosym, dwarf_abbrevsym, dwarf_linesym;
207
208 static struct dfmt df_dwarf;
209 static struct dfmt df_stabs;
210 static struct Symbol *lastsym;
211
212 /* common debugging routines */
213 static void debug32_typevalue(int32_t);
214 static void debug32_deflabel(char *, int32_t, int64_t, int, char *);
215 static void debug32_directive(const char *, const char *);
216
217 /* stabs debugging routines */
218 static void stabs32_linenum(const char *filename, int32_t linenumber, int32_t);
219 static void stabs32_output(int, void *);
220 static void stabs32_generate(void);
221 static void stabs32_cleanup(void);
222
223 /* dwarf debugging routines */
224 static void dwarf32_init(struct ofmt *, void *, FILE *, efunc);
225 static void dwarf32_linenum(const char *filename, int32_t linenumber, int32_t);
226 static void dwarf32_output(int, void *);
227 static void dwarf32_generate(void);
228 static void dwarf32_cleanup(void);
229 static void dwarf32_findfile(const char *);
230 static void dwarf32_findsect(const int);
231
232 /*
233  * Special NASM section numbers which are used to define ELF special
234  * symbols, which can be used with WRT to provide PIC and TLS
235  * relocation types.
236  */
237 static int32_t elf_gotpc_sect, elf_gotoff_sect;
238 static int32_t elf_got_sect, elf_plt_sect;
239 static int32_t elf_sym_sect, elf_tlsie_sect;
240
241 static void elf_init(FILE * fp, efunc errfunc, ldfunc ldef, evalfunc eval)
242 {
243     elffp = fp;
244     error = errfunc;
245     evaluate = eval;
246     (void)ldef;                 /* placate optimisers */
247     sects = NULL;
248     nsects = sectlen = 0;
249     syms = saa_init((int32_t)sizeof(struct Symbol));
250     nlocals = nglobs = ndebugs = 0;
251     bsym = raa_init();
252     strs = saa_init(1L);
253     saa_wbytes(strs, "\0", 1L);
254     saa_wbytes(strs, elf_module, strlen(elf_module)+1);
255     strslen = 2 + strlen(elf_module);
256     shstrtab = NULL;
257     shstrtablen = shstrtabsize = 0;;
258     add_sectname("", "");
259
260     fwds = NULL;
261
262     elf_gotpc_sect = seg_alloc();
263     ldef("..gotpc", elf_gotpc_sect + 1, 0L, NULL, false, false, &of_elf32,
264          error);
265     elf_gotoff_sect = seg_alloc();
266     ldef("..gotoff", elf_gotoff_sect + 1, 0L, NULL, false, false, &of_elf32,
267          error);
268     elf_got_sect = seg_alloc();
269     ldef("..got", elf_got_sect + 1, 0L, NULL, false, false, &of_elf32,
270          error);
271     elf_plt_sect = seg_alloc();
272     ldef("..plt", elf_plt_sect + 1, 0L, NULL, false, false, &of_elf32,
273          error);
274     elf_sym_sect = seg_alloc();
275     ldef("..sym", elf_sym_sect + 1, 0L, NULL, false, false, &of_elf32,
276          error);
277     elf_tlsie_sect = seg_alloc();
278     ldef("..tlsie", elf_tlsie_sect + 1, 0L, NULL, false, false, &of_elf32,
279          error);
280
281     def_seg = seg_alloc();
282 }
283
284 static void elf_init_hack(FILE * fp, efunc errfunc, ldfunc ldef,
285                            evalfunc eval)
286 {
287     of_elf32.current_dfmt = of_elf.current_dfmt; /* Sync debugging format */
288     elf_init(fp, errfunc, ldef, eval);
289 }
290
291 static void elf_cleanup(int debuginfo)
292 {
293     struct Reloc *r;
294     int i;
295
296     (void)debuginfo;
297
298     elf_write();
299     for (i = 0; i < nsects; i++) {
300         if (sects[i]->type != SHT_NOBITS)
301             saa_free(sects[i]->data);
302         if (sects[i]->head)
303             saa_free(sects[i]->rel);
304         while (sects[i]->head) {
305             r = sects[i]->head;
306             sects[i]->head = sects[i]->head->next;
307             nasm_free(r);
308         }
309     }
310     nasm_free(sects);
311     saa_free(syms);
312     raa_free(bsym);
313     saa_free(strs);
314     if (of_elf32.current_dfmt) {
315         of_elf32.current_dfmt->cleanup();
316     }
317 }
318
319 static void add_sectname(char *firsthalf, char *secondhalf)
320 {
321     int len = strlen(firsthalf) + strlen(secondhalf);
322     while (shstrtablen + len + 1 > shstrtabsize)
323         shstrtab = nasm_realloc(shstrtab, (shstrtabsize += SHSTR_DELTA));
324     strcpy(shstrtab + shstrtablen, firsthalf);
325     strcat(shstrtab + shstrtablen, secondhalf);
326     shstrtablen += len + 1;
327 }
328
329 static int elf_make_section(char *name, int type, int flags, int align)
330 {
331     struct Section *s;
332
333     s = nasm_malloc(sizeof(*s));
334
335     if (type != SHT_NOBITS)
336         s->data = saa_init(1L);
337     s->head = NULL;
338     s->tail = &s->head;
339     s->len = s->size = 0;
340     s->nrelocs = 0;
341     if (!strcmp(name, ".text"))
342         s->index = def_seg;
343     else
344         s->index = seg_alloc();
345     add_sectname("", name);
346     s->name = nasm_malloc(1 + strlen(name));
347     strcpy(s->name, name);
348     s->type = type;
349     s->flags = flags;
350     s->align = align;
351     s->gsyms = NULL;
352
353     if (nsects >= sectlen)
354         sects = nasm_realloc(sects, (sectlen += SECT_DELTA) * sizeof(*sects));
355     sects[nsects++] = s;
356
357     return nsects - 1;
358 }
359
360
361 static int32_t elf_section_names(char *name, int pass, int *bits)
362 {
363     char *p;
364     uint32_t flags, flags_and, flags_or;
365     uint32_t align;
366     int type, i;
367
368     /*
369      * Default is 32 bits.
370      */
371     if (!name) {
372         *bits = 32;
373         return def_seg;
374     }
375
376     p = name;
377     while (*p && !nasm_isspace(*p))
378         p++;
379     if (*p)
380         *p++ = '\0';
381     flags_and = flags_or = type = align = 0;
382
383     while (*p && nasm_isspace(*p))
384         p++;
385     while (*p) {
386         char *q = p;
387         while (*p && !nasm_isspace(*p))
388             p++;
389         if (*p)
390             *p++ = '\0';
391         while (*p && nasm_isspace(*p))
392             p++;
393
394         if (!nasm_strnicmp(q, "align=", 6)) {
395             align = atoi(q + 6);
396             if (align == 0)
397                 align = 1;
398             if ((align - 1) & align) {  /* means it's not a power of two */
399                 error(ERR_NONFATAL, "section alignment %d is not"
400                       " a power of two", align);
401                 align = 1;
402             }
403         } else if (!nasm_stricmp(q, "alloc")) {
404             flags_and |= SHF_ALLOC;
405             flags_or |= SHF_ALLOC;
406         } else if (!nasm_stricmp(q, "noalloc")) {
407             flags_and |= SHF_ALLOC;
408             flags_or &= ~SHF_ALLOC;
409         } else if (!nasm_stricmp(q, "exec")) {
410             flags_and |= SHF_EXECINSTR;
411             flags_or |= SHF_EXECINSTR;
412         } else if (!nasm_stricmp(q, "noexec")) {
413             flags_and |= SHF_EXECINSTR;
414             flags_or &= ~SHF_EXECINSTR;
415         } else if (!nasm_stricmp(q, "write")) {
416             flags_and |= SHF_WRITE;
417             flags_or |= SHF_WRITE;
418         } else if (!nasm_stricmp(q, "tls")) {
419             flags_and |= SHF_TLS;
420             flags_or |= SHF_TLS;
421         } else if (!nasm_stricmp(q, "nowrite")) {
422             flags_and |= SHF_WRITE;
423             flags_or &= ~SHF_WRITE;
424         } else if (!nasm_stricmp(q, "progbits")) {
425             type = SHT_PROGBITS;
426         } else if (!nasm_stricmp(q, "nobits")) {
427             type = SHT_NOBITS;
428         } else if (pass == 1) {
429             error(ERR_WARNING, "Unknown section attribute '%s' ignored on"
430                   " declaration of section `%s'", q, name);
431         }
432     }
433
434     if (!strcmp(name, ".shstrtab") ||
435         !strcmp(name, ".symtab") ||
436         !strcmp(name, ".strtab")) {
437         error(ERR_NONFATAL, "attempt to redefine reserved section"
438               "name `%s'", name);
439         return NO_SEG;
440     }
441
442     for (i = 0; i < nsects; i++)
443         if (!strcmp(name, sects[i]->name))
444             break;
445     if (i == nsects) {
446         const struct elf_known_section *ks = elf_known_sections;
447
448         while (ks->name) {
449             if (!strcmp(name, ks->name))
450                 break;
451             ks++;
452         }
453
454         type = type ? type : ks->type;
455         align = align ? align : ks->align;
456         flags = (ks->flags & ~flags_and) | flags_or;
457
458         i = elf_make_section(name, type, flags, align);
459     } else if (pass == 1) {
460           if ((type && sects[i]->type != type)
461               || (align && sects[i]->align != align)
462              || (flags_and && ((sects[i]->flags & flags_and) != flags_or)))
463             error(ERR_WARNING, "section attributes ignored on"
464                   " redeclaration of section `%s'", name);
465     }
466
467     return sects[i]->index;
468 }
469
470 static void elf_deflabel(char *name, int32_t segment, int64_t offset,
471                          int is_global, char *special)
472 {
473     int pos = strslen;
474     struct Symbol *sym;
475     bool special_used = false;
476
477 #if defined(DEBUG) && DEBUG>2
478     fprintf(stderr,
479             " elf_deflabel: %s, seg=%ld, off=%ld, is_global=%d, %s\n",
480             name, segment, offset, is_global, special);
481 #endif
482     if (name[0] == '.' && name[1] == '.' && name[2] != '@') {
483         /*
484          * This is a NASM special symbol. We never allow it into
485          * the ELF symbol table, even if it's a valid one. If it
486          * _isn't_ a valid one, we should barf immediately.
487          */
488         if (strcmp(name, "..gotpc") && strcmp(name, "..gotoff") &&
489             strcmp(name, "..got") && strcmp(name, "..plt") &&
490             strcmp(name, "..sym") && strcmp(name, "..tlsie"))
491             error(ERR_NONFATAL, "unrecognised special symbol `%s'", name);
492         return;
493     }
494
495     if (is_global == 3) {
496         struct Symbol **s;
497         /*
498          * Fix up a forward-reference symbol size from the first
499          * pass.
500          */
501         for (s = &fwds; *s; s = &(*s)->nextfwd)
502             if (!strcmp((*s)->name, name)) {
503                 struct tokenval tokval;
504                 expr *e;
505                 char *p = special;
506
507                 while (*p && !nasm_isspace(*p))
508                     p++;
509                 while (*p && nasm_isspace(*p))
510                     p++;
511                 stdscan_reset();
512                 stdscan_bufptr = p;
513                 tokval.t_type = TOKEN_INVALID;
514                 e = evaluate(stdscan, NULL, &tokval, NULL, 1, error, NULL);
515                 if (e) {
516                     if (!is_simple(e))
517                         error(ERR_NONFATAL, "cannot use relocatable"
518                               " expression as symbol size");
519                     else
520                         (*s)->size = reloc_value(e);
521                 }
522
523                 /*
524                  * Remove it from the list of unresolved sizes.
525                  */
526                 nasm_free((*s)->name);
527                 *s = (*s)->nextfwd;
528                 return;
529             }
530         return;                 /* it wasn't an important one */
531     }
532
533     saa_wbytes(strs, name, (int32_t)(1 + strlen(name)));
534     strslen += 1 + strlen(name);
535
536     lastsym = sym = saa_wstruct(syms);
537
538     memset(&sym->symv, 0, sizeof(struct rbtree));
539
540     sym->strpos = pos;
541     sym->type = is_global ? SYM_GLOBAL : 0;
542     sym->other = STV_DEFAULT;
543     sym->size = 0;
544     if (segment == NO_SEG)
545         sym->section = SHN_ABS;
546     else {
547         int i;
548         sym->section = SHN_UNDEF;
549         if (nsects == 0 && segment == def_seg) {
550             int tempint;
551             if (segment != elf_section_names(".text", 2, &tempint))
552                 error(ERR_PANIC,
553                       "strange segment conditions in ELF driver");
554             sym->section = nsects;
555         } else {
556             for (i = 0; i < nsects; i++)
557                 if (segment == sects[i]->index) {
558                     sym->section = i + 1;
559                     break;
560                 }
561         }
562     }
563
564     if (is_global == 2) {
565         sym->size = offset;
566         sym->symv.key = 0;
567         sym->section = SHN_COMMON;
568         /*
569          * We have a common variable. Check the special text to see
570          * if it's a valid number and power of two; if so, store it
571          * as the alignment for the common variable.
572          */
573         if (special) {
574             bool err;
575             sym->symv.key = readnum(special, &err);
576             if (err)
577                 error(ERR_NONFATAL, "alignment constraint `%s' is not a"
578                       " valid number", special);
579             else if ((sym->symv.key | (sym->symv.key - 1))
580                      != 2 * sym->symv.key - 1)
581                 error(ERR_NONFATAL, "alignment constraint `%s' is not a"
582                       " power of two", special);
583         }
584         special_used = true;
585     } else
586         sym->symv.key = (sym->section == SHN_UNDEF ? 0 : offset);
587
588     if (sym->type == SYM_GLOBAL) {
589         /*
590          * If sym->section == SHN_ABS, then the first line of the
591          * else section would cause a core dump, because its a reference
592          * beyond the end of the section array.
593          * This behaviour is exhibited by this code:
594          *     GLOBAL crash_nasm
595          *     crash_nasm equ 0
596          * To avoid such a crash, such requests are silently discarded.
597          * This may not be the best solution.
598          */
599         if (sym->section == SHN_UNDEF || sym->section == SHN_COMMON) {
600             bsym = raa_write(bsym, segment, nglobs);
601         } else if (sym->section != SHN_ABS) {
602             /*
603              * This is a global symbol; so we must add it to the rbtree
604              * of global symbols in its section.
605              *
606              * In addition, we check the special text for symbol
607              * type and size information.
608              */
609             sects[sym->section-1]->gsyms =
610                 rb_insert(sects[sym->section-1]->gsyms, &sym->symv);
611
612             if (special) {
613                 int n = strcspn(special, " \t");
614
615                 if (!nasm_strnicmp(special, "function", n))
616                     sym->type |= STT_FUNC;
617                 else if (!nasm_strnicmp(special, "data", n) ||
618                          !nasm_strnicmp(special, "object", n))
619                     sym->type |= STT_OBJECT;
620                 else if (!nasm_strnicmp(special, "notype", n))
621                     sym->type |= STT_NOTYPE;
622                 else
623                     error(ERR_NONFATAL, "unrecognised symbol type `%.*s'",
624                           n, special);
625                 special += n;
626
627                 while (nasm_isspace(*special))
628                     ++special;
629                 if (*special) {
630                     n = strcspn(special, " \t");
631                     if (!nasm_strnicmp(special, "default", n))
632                         sym->other = STV_DEFAULT;
633                     else if (!nasm_strnicmp(special, "internal", n))
634                         sym->other = STV_INTERNAL;
635                     else if (!nasm_strnicmp(special, "hidden", n))
636                         sym->other = STV_HIDDEN;
637                     else if (!nasm_strnicmp(special, "protected", n))
638                         sym->other = STV_PROTECTED;
639                     else
640                         n = 0;
641                     special += n;
642                 }
643
644                 if (*special) {
645                     struct tokenval tokval;
646                     expr *e;
647                     int fwd = 0;
648                     char *saveme = stdscan_bufptr;      /* bugfix? fbk 8/10/00 */
649
650                     while (special[n] && nasm_isspace(special[n]))
651                         n++;
652                     /*
653                      * We have a size expression; attempt to
654                      * evaluate it.
655                      */
656                     stdscan_reset();
657                     stdscan_bufptr = special + n;
658                     tokval.t_type = TOKEN_INVALID;
659                     e = evaluate(stdscan, NULL, &tokval, &fwd, 0, error,
660                                  NULL);
661                     if (fwd) {
662                         sym->nextfwd = fwds;
663                         fwds = sym;
664                         sym->name = nasm_strdup(name);
665                     } else if (e) {
666                         if (!is_simple(e))
667                             error(ERR_NONFATAL, "cannot use relocatable"
668                                   " expression as symbol size");
669                         else
670                             sym->size = reloc_value(e);
671                     }
672                     stdscan_bufptr = saveme;    /* bugfix? fbk 8/10/00 */
673                 }
674                 special_used = true;
675             }
676             /*
677              * If TLS segment, mark symbol accordingly.
678              */
679             if (sects[sym->section - 1]->flags & SHF_TLS) {
680                 sym->type &= 0xf0;
681                 sym->type |= STT_TLS;
682             }
683         }
684         sym->globnum = nglobs;
685         nglobs++;
686     } else
687         nlocals++;
688
689     if (special && !special_used)
690         error(ERR_NONFATAL, "no special symbol features supported here");
691 }
692
693 static void elf_add_reloc(struct Section *sect, int32_t segment, int type)
694 {
695     struct Reloc *r;
696
697     r = *sect->tail = nasm_malloc(sizeof(struct Reloc));
698     sect->tail = &r->next;
699     r->next = NULL;
700
701     r->address = sect->len;
702     if (segment == NO_SEG)
703         r->symbol = 0;
704     else {
705         int i;
706         r->symbol = 0;
707         for (i = 0; i < nsects; i++)
708             if (segment == sects[i]->index)
709                 r->symbol = i + 2;
710         if (!r->symbol)
711             r->symbol = GLOBAL_TEMP_BASE + raa_read(bsym, segment);
712     }
713     r->type = type;
714
715     sect->nrelocs++;
716 }
717
718 /*
719  * This routine deals with ..got and ..sym relocations: the more
720  * complicated kinds. In shared-library writing, some relocations
721  * with respect to global symbols must refer to the precise symbol
722  * rather than referring to an offset from the base of the section
723  * _containing_ the symbol. Such relocations call to this routine,
724  * which searches the symbol list for the symbol in question.
725  *
726  * R_386_GOT32 references require the _exact_ symbol address to be
727  * used; R_386_32 references can be at an offset from the symbol.
728  * The boolean argument `exact' tells us this.
729  *
730  * Return value is the adjusted value of `addr', having become an
731  * offset from the symbol rather than the section. Should always be
732  * zero when returning from an exact call.
733  *
734  * Limitation: if you define two symbols at the same place,
735  * confusion will occur.
736  *
737  * Inefficiency: we search, currently, using a linked list which
738  * isn't even necessarily sorted.
739  */
740 static int32_t elf_add_gsym_reloc(struct Section *sect,
741                                int32_t segment, uint32_t offset,
742                                int type, bool exact)
743 {
744     struct Reloc *r;
745     struct Section *s;
746     struct Symbol *sym;
747     struct rbtree *srb;
748     int i;
749
750     /*
751      * First look up the segment/offset pair and find a global
752      * symbol corresponding to it. If it's not one of our segments,
753      * then it must be an external symbol, in which case we're fine
754      * doing a normal elf_add_reloc after first sanity-checking
755      * that the offset from the symbol is zero.
756      */
757     s = NULL;
758     for (i = 0; i < nsects; i++)
759         if (segment == sects[i]->index) {
760             s = sects[i];
761             break;
762         }
763     if (!s) {
764         if (exact && offset != 0)
765             error(ERR_NONFATAL, "unable to find a suitable global symbol"
766                   " for this reference");
767         else
768             elf_add_reloc(sect, segment, type);
769         return offset;
770     }
771
772     srb = rb_search(s->gsyms, offset);
773     if (!srb || (exact && srb->key != offset)) {
774         error(ERR_NONFATAL, "unable to find a suitable global symbol"
775               " for this reference");
776         return 0;
777     }
778     sym = container_of(srb, struct Symbol, symv);
779
780     r = *sect->tail = nasm_malloc(sizeof(struct Reloc));
781     sect->tail = &r->next;
782     r->next = NULL;
783
784     r->address = sect->len;
785     r->symbol = GLOBAL_TEMP_BASE + sym->globnum;
786     r->type = type;
787
788     sect->nrelocs++;
789
790     return offset - sym->symv.key;
791 }
792
793 static void elf_out(int32_t segto, const void *data,
794                     enum out_type type, uint64_t size,
795                     int32_t segment, int32_t wrt)
796 {
797     struct Section *s;
798     int32_t addr;
799     uint8_t mydata[4], *p;
800     int i;
801     static struct symlininfo sinfo;
802
803     /*
804      * handle absolute-assembly (structure definitions)
805      */
806     if (segto == NO_SEG) {
807         if (type != OUT_RESERVE)
808             error(ERR_NONFATAL, "attempt to assemble code in [ABSOLUTE]"
809                   " space");
810         return;
811     }
812
813     s = NULL;
814     for (i = 0; i < nsects; i++)
815         if (segto == sects[i]->index) {
816             s = sects[i];
817             break;
818         }
819     if (!s) {
820         int tempint;            /* ignored */
821         if (segto != elf_section_names(".text", 2, &tempint))
822             error(ERR_PANIC, "strange segment conditions in ELF driver");
823         else {
824             s = sects[nsects - 1];
825             i = nsects - 1;
826         }
827     }
828
829     /* again some stabs debugging stuff */
830     if (of_elf32.current_dfmt) {
831         sinfo.offset = s->len;
832         sinfo.section = i;
833         sinfo.name = s->name;
834         of_elf32.current_dfmt->debug_output(TY_STABSSYMLIN, &sinfo);
835     }
836     /* end of debugging stuff */
837
838     if (s->type == SHT_NOBITS && type != OUT_RESERVE) {
839         error(ERR_WARNING, "attempt to initialize memory in"
840               " BSS section `%s': ignored", s->name);
841         s->len += realsize(type, size);
842         return;
843     }
844
845     if (type == OUT_RESERVE) {
846         if (s->type == SHT_PROGBITS) {
847             error(ERR_WARNING, "uninitialized space declared in"
848                   " non-BSS section `%s': zeroing", s->name);
849             elf_sect_write(s, NULL, size);
850         } else
851             s->len += size;
852     } else if (type == OUT_RAWDATA) {
853         if (segment != NO_SEG)
854             error(ERR_PANIC, "OUT_RAWDATA with other than NO_SEG");
855         elf_sect_write(s, data, size);
856     } else if (type == OUT_ADDRESS) {
857         bool gnu16 = false;
858         addr = *(int64_t *)data;
859         if (segment != NO_SEG) {
860             if (segment % 2) {
861                 error(ERR_NONFATAL, "ELF format does not support"
862                       " segment base references");
863             } else {
864                 if (wrt == NO_SEG) {
865                     if (size == 2) {
866                         gnu16 = true;
867                         elf_add_reloc(s, segment, R_386_16);
868                     } else {
869                         elf_add_reloc(s, segment, R_386_32);
870                     }
871                 } else if (wrt == elf_gotpc_sect + 1) {
872                     /*
873                      * The user will supply GOT relative to $$. ELF
874                      * will let us have GOT relative to $. So we
875                      * need to fix up the data item by $-$$.
876                      */
877                     addr += s->len;
878                     elf_add_reloc(s, segment, R_386_GOTPC);
879                 } else if (wrt == elf_gotoff_sect + 1) {
880                     elf_add_reloc(s, segment, R_386_GOTOFF);
881                 } else if (wrt == elf_tlsie_sect + 1) {
882                     addr = elf_add_gsym_reloc(s, segment, addr,
883                                               R_386_TLS_IE, true);
884                 } else if (wrt == elf_got_sect + 1) {
885                     addr = elf_add_gsym_reloc(s, segment, addr,
886                                               R_386_GOT32, true);
887                 } else if (wrt == elf_sym_sect + 1) {
888                     if (size == 2) {
889                         gnu16 = true;
890                         addr = elf_add_gsym_reloc(s, segment, addr,
891                                                   R_386_16, false);
892                     } else {
893                         addr = elf_add_gsym_reloc(s, segment, addr,
894                                                   R_386_32, false);
895                     }
896                 } else if (wrt == elf_plt_sect + 1) {
897                     error(ERR_NONFATAL, "ELF format cannot produce non-PC-"
898                           "relative PLT references");
899                 } else {
900                     error(ERR_NONFATAL, "ELF format does not support this"
901                           " use of WRT");
902                     wrt = NO_SEG;       /* we can at least _try_ to continue */
903                 }
904             }
905         }
906         p = mydata;
907         if (gnu16) {
908             error(ERR_WARNING | ERR_WARN_GNUELF,
909                   "16-bit relocations in ELF is a GNU extension");
910             WRITESHORT(p, addr);
911         } else {
912             if (size != 4 && segment != NO_SEG) {
913                 error(ERR_NONFATAL,
914                       "Unsupported non-32-bit ELF relocation");
915             }
916             WRITELONG(p, addr);
917         }
918         elf_sect_write(s, mydata, size);
919     } else if (type == OUT_REL2ADR) {
920         if (segment == segto)
921             error(ERR_PANIC, "intra-segment OUT_REL2ADR");
922         if (segment != NO_SEG && segment % 2) {
923             error(ERR_NONFATAL, "ELF format does not support"
924                   " segment base references");
925         } else {
926             if (wrt == NO_SEG) {
927                 error(ERR_WARNING | ERR_WARN_GNUELF,
928                       "16-bit relocations in ELF is a GNU extension");
929                 elf_add_reloc(s, segment, R_386_PC16);
930             } else {
931                 error(ERR_NONFATAL,
932                       "Unsupported non-32-bit ELF relocation");
933             }
934         }
935         p = mydata;
936         WRITESHORT(p, *(int64_t *)data - size);
937         elf_sect_write(s, mydata, 2L);
938     } else if (type == OUT_REL4ADR) {
939         if (segment == segto)
940             error(ERR_PANIC, "intra-segment OUT_REL4ADR");
941         if (segment != NO_SEG && segment % 2) {
942             error(ERR_NONFATAL, "ELF format does not support"
943                   " segment base references");
944         } else {
945             if (wrt == NO_SEG) {
946                 elf_add_reloc(s, segment, R_386_PC32);
947             } else if (wrt == elf_plt_sect + 1) {
948                 elf_add_reloc(s, segment, R_386_PLT32);
949             } else if (wrt == elf_gotpc_sect + 1 ||
950                        wrt == elf_gotoff_sect + 1 ||
951                        wrt == elf_got_sect + 1) {
952                 error(ERR_NONFATAL, "ELF format cannot produce PC-"
953                       "relative GOT references");
954             } else {
955                 error(ERR_NONFATAL, "ELF format does not support this"
956                       " use of WRT");
957                 wrt = NO_SEG;   /* we can at least _try_ to continue */
958             }
959         }
960         p = mydata;
961         WRITELONG(p, *(int64_t *)data - size);
962         elf_sect_write(s, mydata, 4L);
963     }
964 }
965
966 static void elf_write(void)
967 {
968     int align;
969     char *p;
970     int i;
971
972     struct SAA *symtab;
973     int32_t symtablen, symtablocal;
974
975     /*
976      * Work out how many sections we will have. We have SHN_UNDEF,
977      * then the flexible user sections, then the fixed sections
978      * `.shstrtab', `.symtab' and `.strtab', then optionally
979      * relocation sections for the user sections.
980      */
981     nsections = sec_numspecial + 1;
982     if (of_elf32.current_dfmt == &df_stabs)
983         nsections += 3;
984     else if (of_elf32.current_dfmt == &df_dwarf)
985         nsections += 10;
986
987     add_sectname("", ".shstrtab");
988     add_sectname("", ".symtab");
989     add_sectname("", ".strtab");
990     for (i = 0; i < nsects; i++) {
991         nsections++;            /* for the section itself */
992         if (sects[i]->head) {
993             nsections++;        /* for its relocations */
994             add_sectname(".rel", sects[i]->name);
995         }
996     }
997
998     if (of_elf32.current_dfmt == &df_stabs) {
999         /* in case the debug information is wanted, just add these three sections... */
1000         add_sectname("", ".stab");
1001         add_sectname("", ".stabstr");
1002         add_sectname(".rel", ".stab");
1003     } else if (of_elf32.current_dfmt == &df_dwarf) {
1004         /* the dwarf debug standard specifies the following ten sections,
1005            not all of which are currently implemented,
1006            although all of them are defined. */
1007         add_sectname("", ".debug_aranges");
1008         add_sectname(".rela", ".debug_aranges");
1009         add_sectname("", ".debug_pubnames");
1010         add_sectname("", ".debug_info");
1011         add_sectname(".rela", ".debug_info");
1012         add_sectname("", ".debug_abbrev");
1013         add_sectname("", ".debug_line");
1014         add_sectname(".rela", ".debug_line");
1015         add_sectname("", ".debug_frame");
1016         add_sectname("", ".debug_loc");
1017     }
1018
1019     /*
1020      * Output the ELF header.
1021      */
1022     fwrite("\177ELF\1\1\1", 7, 1, elffp);
1023     fputc(elf_osabi, elffp);
1024     fputc(elf_abiver, elffp);
1025     fwritezero(7, elffp);
1026     fwriteint16_t(1, elffp);      /* ET_REL relocatable file */
1027     fwriteint16_t(3, elffp);      /* EM_386 processor ID */
1028     fwriteint32_t(1L, elffp);      /* EV_CURRENT file format version */
1029     fwriteint32_t(0L, elffp);      /* no entry point */
1030     fwriteint32_t(0L, elffp);      /* no program header table */
1031     fwriteint32_t(0x40L, elffp);   /* section headers straight after
1032                                     * ELF header plus alignment */
1033     fwriteint32_t(0L, elffp);      /* 386 defines no special flags */
1034     fwriteint16_t(0x34, elffp);   /* size of ELF header */
1035     fwriteint16_t(0, elffp);      /* no program header table, again */
1036     fwriteint16_t(0, elffp);      /* still no program header table */
1037     fwriteint16_t(0x28, elffp);   /* size of section header */
1038     fwriteint16_t(nsections, elffp);      /* number of sections */
1039     fwriteint16_t(sec_shstrtab, elffp);   /* string table section index for
1040                                            * section header table */
1041     fwriteint32_t(0L, elffp);      /* align to 0x40 bytes */
1042     fwriteint32_t(0L, elffp);
1043     fwriteint32_t(0L, elffp);
1044
1045     /*
1046      * Build the symbol table and relocation tables.
1047      */
1048     symtab = elf_build_symtab(&symtablen, &symtablocal);
1049     for (i = 0; i < nsects; i++)
1050         if (sects[i]->head)
1051             sects[i]->rel = elf_build_reltab(&sects[i]->rellen,
1052                                              sects[i]->head);
1053
1054     /*
1055      * Now output the section header table.
1056      */
1057
1058     elf_foffs = 0x40 + 0x28 * nsections;
1059     align = ((elf_foffs + SEG_ALIGN_1) & ~SEG_ALIGN_1) - elf_foffs;
1060     elf_foffs += align;
1061     elf_nsect = 0;
1062     elf_sects = nasm_malloc(sizeof(*elf_sects) * nsections);
1063
1064     /* SHN_UNDEF */
1065     elf_section_header(0, SHT_NULL, 0, NULL, false, 0, SHN_UNDEF, 0, 0, 0);
1066     p = shstrtab + 1;
1067
1068     /* The normal sections */
1069     for (i = 0; i < nsects; i++) {
1070         elf_section_header(p - shstrtab, sects[i]->type, sects[i]->flags,
1071                            (sects[i]->type == SHT_PROGBITS ?
1072                             sects[i]->data : NULL), true,
1073                            sects[i]->len, 0, 0, sects[i]->align, 0);
1074         p += strlen(p) + 1;
1075     }
1076
1077     /* .shstrtab */
1078     elf_section_header(p - shstrtab, SHT_STRTAB, 0, shstrtab, false,
1079                        shstrtablen, 0, 0, 1, 0);
1080     p += strlen(p) + 1;
1081
1082     /* .symtab */
1083     elf_section_header(p - shstrtab, SHT_SYMTAB, 0, symtab, true,
1084                        symtablen, sec_strtab, symtablocal, 4, 16);
1085     p += strlen(p) + 1;
1086
1087     /* .strtab */
1088     elf_section_header(p - shstrtab, SHT_STRTAB, 0, strs, true,
1089                        strslen, 0, 0, 1, 0);
1090     p += strlen(p) + 1;
1091
1092     /* The relocation sections */
1093     for (i = 0; i < nsects; i++)
1094         if (sects[i]->head) {
1095             elf_section_header(p - shstrtab, SHT_REL, 0, sects[i]->rel, true,
1096                                sects[i]->rellen, sec_symtab, i + 1, 4, 8);
1097             p += strlen(p) + 1;
1098             
1099         }
1100
1101     if (of_elf32.current_dfmt == &df_stabs) {
1102         /* for debugging information, create the last three sections
1103            which are the .stab , .stabstr and .rel.stab sections respectively */
1104
1105         /* this function call creates the stab sections in memory */
1106         stabs32_generate();
1107
1108         if (stabbuf && stabstrbuf && stabrelbuf) {
1109             elf_section_header(p - shstrtab, SHT_PROGBITS, 0, stabbuf, false,
1110                                stablen, sec_stabstr, 0, 4, 12);
1111             p += strlen(p) + 1;
1112
1113             elf_section_header(p - shstrtab, SHT_STRTAB, 0, stabstrbuf, false,
1114                                stabstrlen, 0, 0, 4, 0);
1115             p += strlen(p) + 1;
1116
1117             /* link -> symtable  info -> section to refer to */
1118             elf_section_header(p - shstrtab, SHT_REL, 0, stabrelbuf, false,
1119                                stabrellen, sec_symtab, sec_stab, 4, 8);
1120             p += strlen(p) + 1;
1121         }
1122     } else if (of_elf32.current_dfmt == &df_dwarf) {
1123             /* for dwarf debugging information, create the ten dwarf sections */
1124
1125             /* this function call creates the dwarf sections in memory */
1126             if (dwarf_fsect)
1127                 dwarf32_generate();
1128
1129             elf_section_header(p - shstrtab, SHT_PROGBITS, 0, arangesbuf, false,
1130                                arangeslen, 0, 0, 1, 0);
1131             p += strlen(p) + 1;
1132
1133             elf_section_header(p - shstrtab, SHT_RELA, 0, arangesrelbuf, false,
1134                                arangesrellen, sec_symtab, sec_debug_aranges,
1135                                1, 12);
1136             p += strlen(p) + 1;
1137
1138             elf_section_header(p - shstrtab, SHT_PROGBITS, 0, pubnamesbuf,
1139                                false, pubnameslen, 0, 0, 1, 0);
1140             p += strlen(p) + 1;
1141
1142             elf_section_header(p - shstrtab, SHT_PROGBITS, 0, infobuf, false,
1143                                infolen, 0, 0, 1, 0);
1144             p += strlen(p) + 1;
1145
1146             elf_section_header(p - shstrtab, SHT_RELA, 0, inforelbuf, false,
1147                                inforellen, sec_symtab, sec_debug_info, 1, 12);
1148             p += strlen(p) + 1;
1149
1150             elf_section_header(p - shstrtab, SHT_PROGBITS, 0, abbrevbuf, false,
1151                                abbrevlen, 0, 0, 1, 0);
1152             p += strlen(p) + 1;
1153
1154             elf_section_header(p - shstrtab, SHT_PROGBITS, 0, linebuf, false,
1155                                linelen, 0, 0, 1, 0);
1156             p += strlen(p) + 1;
1157
1158             elf_section_header(p - shstrtab, SHT_RELA, 0, linerelbuf, false,
1159                                linerellen, sec_symtab, sec_debug_line, 1, 12);
1160             p += strlen(p) + 1;
1161
1162             elf_section_header(p - shstrtab, SHT_PROGBITS, 0, framebuf, false,
1163                                framelen, 0, 0, 8, 0);
1164             p += strlen(p) + 1;
1165
1166             elf_section_header(p - shstrtab, SHT_PROGBITS, 0, locbuf, false,
1167                                loclen, 0, 0, 1, 0);
1168             p += strlen(p) + 1;
1169     }
1170     fwritezero(align, elffp);
1171
1172     /*
1173      * Now output the sections.
1174      */
1175     elf_write_sections();
1176
1177     nasm_free(elf_sects);
1178     saa_free(symtab);
1179 }
1180
1181 static struct SAA *elf_build_symtab(int32_t *len, int32_t *local)
1182 {
1183     struct SAA *s = saa_init(1L);
1184     struct Symbol *sym;
1185     uint8_t entry[16], *p;
1186     int i;
1187
1188     *len = *local = 0;
1189
1190     /*
1191      * First, an all-zeros entry, required by the ELF spec.
1192      */
1193     saa_wbytes(s, NULL, 16L);   /* null symbol table entry */
1194     *len += 16;
1195     (*local)++;
1196
1197     /*
1198      * Next, an entry for the file name.
1199      */
1200     p = entry;
1201     WRITELONG(p, 1);            /* we know it's 1st entry in strtab */
1202     WRITELONG(p, 0);            /* no value */
1203     WRITELONG(p, 0);            /* no size either */
1204     WRITESHORT(p, STT_FILE);    /* type FILE */
1205     WRITESHORT(p, SHN_ABS);
1206     saa_wbytes(s, entry, 16L);
1207     *len += 16;
1208     (*local)++;
1209
1210     /*
1211      * Now some standard symbols defining the segments, for relocation
1212      * purposes.
1213      */
1214     for (i = 1; i <= nsects; i++) {
1215         p = entry;
1216         WRITELONG(p, 0);        /* no symbol name */
1217         WRITELONG(p, 0);        /* offset zero */
1218         WRITELONG(p, 0);        /* size zero */
1219         WRITESHORT(p, STT_SECTION);       /* type, binding, and visibility */
1220         WRITESHORT(p, i);       /* section id */
1221         saa_wbytes(s, entry, 16L);
1222         *len += 16;
1223         (*local)++;
1224     }
1225
1226     /*
1227      * Now the other local symbols.
1228      */
1229     saa_rewind(syms);
1230     while ((sym = saa_rstruct(syms))) {
1231         if (sym->type & SYM_GLOBAL)
1232             continue;
1233         p = entry;
1234         WRITELONG(p, sym->strpos);
1235         WRITELONG(p, sym->symv.key);
1236         WRITELONG(p, sym->size);
1237         WRITECHAR(p, sym->type);        /* type and binding */
1238         WRITECHAR(p, sym->other);       /* visibility */
1239         WRITESHORT(p, sym->section);
1240         saa_wbytes(s, entry, 16L);
1241         *len += 16;
1242         (*local)++;
1243     }
1244      /*
1245       * dwarf needs symbols for debug sections
1246       * which are relocation targets.
1247       */  
1248 //*** fix for 32 bit
1249      if (of_elf32.current_dfmt == &df_dwarf) {
1250         dwarf_infosym = *local;
1251         p = entry;
1252         WRITELONG(p, 0);        /* no symbol name */
1253         WRITELONG(p, (uint32_t) 0);        /* offset zero */
1254         WRITELONG(p, (uint32_t) 0);        /* size zero */
1255         WRITESHORT(p, STT_SECTION);       /* type, binding, and visibility */
1256         WRITESHORT(p, sec_debug_info);       /* section id */
1257         saa_wbytes(s, entry, 16L);
1258         *len += 16;
1259         (*local)++;
1260         dwarf_abbrevsym = *local;
1261         p = entry;
1262         WRITELONG(p, 0);        /* no symbol name */
1263         WRITELONG(p, (uint32_t) 0);        /* offset zero */
1264         WRITELONG(p, (uint32_t) 0);        /* size zero */
1265         WRITESHORT(p, STT_SECTION);       /* type, binding, and visibility */
1266         WRITESHORT(p, sec_debug_abbrev);       /* section id */
1267         saa_wbytes(s, entry, 16L);
1268         *len += 16;
1269         (*local)++;
1270         dwarf_linesym = *local;
1271         p = entry;
1272         WRITELONG(p, 0);        /* no symbol name */
1273         WRITELONG(p, (uint32_t) 0);        /* offset zero */
1274         WRITELONG(p, (uint32_t) 0);        /* size zero */
1275         WRITESHORT(p, STT_SECTION);       /* type, binding, and visibility */
1276         WRITESHORT(p, sec_debug_line);       /* section id */
1277         saa_wbytes(s, entry, 16L);
1278         *len += 16;
1279         (*local)++;
1280      }
1281
1282     /*
1283      * Now the global symbols.
1284      */
1285     saa_rewind(syms);
1286     while ((sym = saa_rstruct(syms))) {
1287         if (!(sym->type & SYM_GLOBAL))
1288             continue;
1289         p = entry;
1290         WRITELONG(p, sym->strpos);
1291         WRITELONG(p, sym->symv.key);
1292         WRITELONG(p, sym->size);
1293         WRITECHAR(p, sym->type);        /* type and binding */
1294         WRITECHAR(p, sym->other);       /* visibility */
1295         WRITESHORT(p, sym->section);
1296         saa_wbytes(s, entry, 16L);
1297         *len += 16;
1298     }
1299
1300     return s;
1301 }
1302
1303 static struct SAA *elf_build_reltab(int32_t *len, struct Reloc *r)
1304 {
1305     struct SAA *s;
1306     uint8_t *p, entry[8];
1307     int32_t global_offset;
1308
1309     if (!r)
1310         return NULL;
1311
1312     s = saa_init(1L);
1313     *len = 0;
1314
1315     /*
1316      * How to onvert from a global placeholder to a real symbol index;
1317      * the +2 refers to the two special entries, the null entry and
1318      * the filename entry.
1319      */
1320     global_offset = -GLOBAL_TEMP_BASE + nsects + nlocals + ndebugs + 2;
1321
1322     while (r) {
1323         int32_t sym = r->symbol;
1324
1325         /*
1326          * Create a real symbol index; the +2 refers to the two special
1327          * entries, the null entry and the filename entry.
1328          */
1329         if (sym >= GLOBAL_TEMP_BASE)
1330             sym += global_offset;
1331
1332         p = entry;
1333         WRITELONG(p, r->address);
1334         WRITELONG(p, (sym << 8) + r->type);
1335         saa_wbytes(s, entry, 8L);
1336         *len += 8;
1337
1338         r = r->next;
1339     }
1340
1341     return s;
1342 }
1343
1344 static void elf_section_header(int name, int type, int flags,
1345                                void *data, bool is_saa, int32_t datalen,
1346                                int link, int info, int align, int eltsize)
1347 {
1348     elf_sects[elf_nsect].data = data;
1349     elf_sects[elf_nsect].len = datalen;
1350     elf_sects[elf_nsect].is_saa = is_saa;
1351     elf_nsect++;
1352
1353     fwriteint32_t((int32_t)name, elffp);
1354     fwriteint32_t((int32_t)type, elffp);
1355     fwriteint32_t((int32_t)flags, elffp);
1356     fwriteint32_t(0L, elffp);      /* no address, ever, in object files */
1357     fwriteint32_t(type == 0 ? 0L : elf_foffs, elffp);
1358     fwriteint32_t(datalen, elffp);
1359     if (data)
1360         elf_foffs += (datalen + SEG_ALIGN_1) & ~SEG_ALIGN_1;
1361     fwriteint32_t((int32_t)link, elffp);
1362     fwriteint32_t((int32_t)info, elffp);
1363     fwriteint32_t((int32_t)align, elffp);
1364     fwriteint32_t((int32_t)eltsize, elffp);
1365 }
1366
1367 static void elf_write_sections(void)
1368 {
1369     int i;
1370     for (i = 0; i < elf_nsect; i++)
1371         if (elf_sects[i].data) {
1372             int32_t len = elf_sects[i].len;
1373             int32_t reallen = (len + SEG_ALIGN_1) & ~SEG_ALIGN_1;
1374             int32_t align = reallen - len;
1375             if (elf_sects[i].is_saa)
1376                 saa_fpwrite(elf_sects[i].data, elffp);
1377             else
1378                 fwrite(elf_sects[i].data, len, 1, elffp);
1379             fwritezero(align, elffp);
1380         }
1381 }
1382
1383 static void elf_sect_write(struct Section *sect,
1384                            const uint8_t *data, uint32_t len)
1385 {
1386     saa_wbytes(sect->data, data, len);
1387     sect->len += len;
1388 }
1389
1390 static int32_t elf_segbase(int32_t segment)
1391 {
1392     return segment;
1393 }
1394
1395 static int elf_directive(enum directives directive, char *value, int pass)
1396 {
1397     bool err;
1398     int64_t n;
1399     char *p;
1400
1401     switch (directive) {
1402     case D_OSABI:
1403         if (pass == 2)
1404             return 1;           /* ignore in pass 2 */
1405
1406         n = readnum(value, &err);
1407         if (err) {
1408             error(ERR_NONFATAL, "`osabi' directive requires a parameter");
1409             return 1;
1410         }
1411         if (n < 0 || n > 255) {
1412             error(ERR_NONFATAL, "valid osabi numbers are 0 to 255");
1413             return 1;
1414         }
1415         elf_osabi  = n;
1416         elf_abiver = 0;
1417
1418         if ((p = strchr(value,',')) == NULL)
1419             return 1;
1420
1421         n = readnum(p+1, &err);
1422         if (err || n < 0 || n > 255) {
1423             error(ERR_NONFATAL, "invalid ABI version number (valid: 0 to 255)");
1424             return 1;
1425         }
1426         
1427         elf_abiver = n;
1428         return 1;
1429     
1430     default:
1431         return 0;
1432     }
1433 }
1434
1435 static void elf_filename(char *inname, char *outname, efunc error)
1436 {
1437     strcpy(elf_module, inname);
1438     standard_extension(inname, outname, ".o", error);
1439 }
1440
1441 extern macros_t elf_stdmac[];
1442
1443 static int elf_set_info(enum geninfo type, char **val)
1444 {
1445     (void)type;
1446     (void)val;
1447     return 0;
1448 }
1449 static struct dfmt df_dwarf = {
1450     "ELF32 (i386) dwarf debug format for Linux/Unix",
1451     "dwarf",
1452     dwarf32_init,
1453     dwarf32_linenum,
1454     debug32_deflabel,
1455     debug32_directive,
1456     debug32_typevalue,
1457     dwarf32_output,
1458     dwarf32_cleanup
1459 };
1460 static struct dfmt df_stabs = {
1461     "ELF32 (i386) stabs debug format for Linux/Unix",
1462     "stabs",
1463     null_debug_init,
1464     stabs32_linenum,
1465     debug32_deflabel,
1466     debug32_directive,
1467     debug32_typevalue,
1468     stabs32_output,
1469     stabs32_cleanup
1470 };
1471
1472 struct dfmt *elf32_debugs_arr[3] = { &df_dwarf, &df_stabs, NULL };
1473
1474 struct ofmt of_elf32 = {
1475     "ELF32 (i386) object files (e.g. Linux)",
1476     "elf32",
1477     0,
1478     elf32_debugs_arr,
1479     &df_stabs,
1480     elf_stdmac,
1481     elf_init,
1482     elf_set_info,
1483     elf_out,
1484     elf_deflabel,
1485     elf_section_names,
1486     elf_segbase,
1487     elf_directive,
1488     elf_filename,
1489     elf_cleanup
1490 };
1491
1492 struct ofmt of_elf = {
1493     "ELF (short name for ELF32) ",
1494     "elf",
1495     0,
1496     elf32_debugs_arr,
1497     &df_stabs,
1498     elf_stdmac,
1499     elf_init_hack,
1500     elf_set_info,
1501     elf_out,
1502     elf_deflabel,
1503     elf_section_names,
1504     elf_segbase,
1505     elf_directive,
1506     elf_filename,
1507     elf_cleanup
1508 };
1509 /* again, the stabs debugging stuff (code) */
1510
1511 static void stabs32_linenum(const char *filename, int32_t linenumber,
1512                             int32_t segto)
1513 {
1514     (void)segto;
1515
1516     if (!stabs_filename) {
1517         stabs_filename = (char *)nasm_malloc(strlen(filename) + 1);
1518         strcpy(stabs_filename, filename);
1519     } else {
1520         if (strcmp(stabs_filename, filename)) {
1521             /* yep, a memory leak...this program is one-shot anyway, so who cares...
1522                in fact, this leak comes in quite handy to maintain a list of files
1523                encountered so far in the symbol lines... */
1524
1525             /* why not nasm_free(stabs_filename); we're done with the old one */
1526
1527             stabs_filename = (char *)nasm_malloc(strlen(filename) + 1);
1528             strcpy(stabs_filename, filename);
1529         }
1530     }
1531     debug_immcall = 1;
1532     currentline = linenumber;
1533 }
1534
1535 static void debug32_deflabel(char *name, int32_t segment, int64_t offset, int is_global,
1536                     char *special)
1537 {
1538    (void)name;
1539    (void)segment;
1540    (void)offset;
1541    (void)is_global;
1542    (void)special;
1543 }
1544
1545 static void debug32_directive(const char *directive, const char *params)
1546 {
1547    (void)directive;
1548    (void)params;
1549 }
1550
1551 static void debug32_typevalue(int32_t type)
1552 {
1553     int32_t stype, ssize;
1554     switch (TYM_TYPE(type)) {
1555         case TY_LABEL:
1556             ssize = 0;
1557             stype = STT_NOTYPE;
1558             break;
1559         case TY_BYTE:
1560             ssize = 1;
1561             stype = STT_OBJECT;
1562             break;
1563         case TY_WORD:
1564             ssize = 2;
1565             stype = STT_OBJECT;
1566             break;
1567         case TY_DWORD:
1568             ssize = 4;
1569             stype = STT_OBJECT;
1570             break;
1571         case TY_FLOAT:
1572             ssize = 4;
1573             stype = STT_OBJECT;
1574             break;
1575         case TY_QWORD:
1576             ssize = 8;
1577             stype = STT_OBJECT;
1578             break;
1579         case TY_TBYTE:
1580             ssize = 10;
1581             stype = STT_OBJECT;
1582             break;
1583         case TY_OWORD:
1584             ssize = 8;
1585             stype = STT_OBJECT;
1586             break;
1587         case TY_COMMON:
1588             ssize = 0;
1589             stype = STT_COMMON;
1590             break;
1591         case TY_SEG:
1592             ssize = 0;
1593             stype = STT_SECTION;
1594             break;
1595         case TY_EXTERN:
1596             ssize = 0;
1597             stype = STT_NOTYPE;
1598             break;
1599         case TY_EQU:
1600             ssize = 0;
1601             stype = STT_NOTYPE;
1602             break;
1603         default:
1604             ssize = 0;
1605             stype = STT_NOTYPE;
1606             break;
1607     }
1608     if (stype == STT_OBJECT && lastsym && !lastsym->type) {
1609         lastsym->size = ssize;
1610         lastsym->type = stype;
1611     }
1612 }
1613
1614 static void stabs32_output(int type, void *param)
1615 {
1616     struct symlininfo *s;
1617     struct linelist *el;
1618     if (type == TY_STABSSYMLIN) {
1619         if (debug_immcall) {
1620             s = (struct symlininfo *)param;
1621             if (!(sects[s->section]->flags & SHF_EXECINSTR))
1622                 return;         /* we are only interested in the text stuff */
1623             numlinestabs++;
1624             el = (struct linelist *)nasm_malloc(sizeof(struct linelist));
1625             el->info.offset = s->offset;
1626             el->info.section = s->section;
1627             el->info.name = s->name;
1628             el->line = currentline;
1629             el->filename = stabs_filename;
1630             el->next = 0;
1631             if (stabslines) {
1632                 stabslines->last->next = el;
1633                 stabslines->last = el;
1634             } else {
1635                 stabslines = el;
1636                 stabslines->last = el;
1637             }
1638         }
1639     }
1640     debug_immcall = 0;
1641 }
1642
1643 #define WRITE_STAB(p,n_strx,n_type,n_other,n_desc,n_value) \
1644   do {\
1645     WRITELONG(p,n_strx); \
1646     WRITECHAR(p,n_type); \
1647     WRITECHAR(p,n_other); \
1648     WRITESHORT(p,n_desc); \
1649     WRITELONG(p,n_value); \
1650   } while (0)
1651
1652 /* for creating the .stab , .stabstr and .rel.stab sections in memory */
1653
1654 static void stabs32_generate(void)
1655 {
1656     int i, numfiles, strsize, numstabs = 0, currfile, mainfileindex;
1657     uint8_t *sbuf, *ssbuf, *rbuf, *sptr, *rptr;
1658     char **allfiles;
1659     int *fileidx;
1660
1661     struct linelist *ptr;
1662
1663     ptr = stabslines;
1664
1665     allfiles = (char **)nasm_malloc(numlinestabs * sizeof(char *));
1666     for (i = 0; i < numlinestabs; i++)
1667         allfiles[i] = 0;
1668     numfiles = 0;
1669     while (ptr) {
1670         if (numfiles == 0) {
1671             allfiles[0] = ptr->filename;
1672             numfiles++;
1673         } else {
1674             for (i = 0; i < numfiles; i++) {
1675                 if (!strcmp(allfiles[i], ptr->filename))
1676                     break;
1677             }
1678             if (i >= numfiles) {
1679                 allfiles[i] = ptr->filename;
1680                 numfiles++;
1681             }
1682         }
1683         ptr = ptr->next;
1684     }
1685     strsize = 1;
1686     fileidx = (int *)nasm_malloc(numfiles * sizeof(int));
1687     for (i = 0; i < numfiles; i++) {
1688         fileidx[i] = strsize;
1689         strsize += strlen(allfiles[i]) + 1;
1690     }
1691     mainfileindex = 0;
1692     for (i = 0; i < numfiles; i++) {
1693         if (!strcmp(allfiles[i], elf_module)) {
1694             mainfileindex = i;
1695             break;
1696         }
1697     }
1698
1699     /* worst case size of the stab buffer would be:
1700        the sourcefiles changes each line, which would mean 1 SOL, 1 SYMLIN per line
1701      */
1702     sbuf =
1703         (uint8_t *)nasm_malloc((numlinestabs * 2 + 3) *
1704                                      sizeof(struct stabentry));
1705
1706     ssbuf = (uint8_t *)nasm_malloc(strsize);
1707
1708     rbuf = (uint8_t *)nasm_malloc(numlinestabs * 8 * (2 + 3));
1709     rptr = rbuf;
1710
1711     for (i = 0; i < numfiles; i++) {
1712         strcpy((char *)ssbuf + fileidx[i], allfiles[i]);
1713     }
1714     ssbuf[0] = 0;
1715
1716     stabstrlen = strsize;       /* set global variable for length of stab strings */
1717
1718     sptr = sbuf;
1719     ptr = stabslines;
1720     numstabs = 0;
1721
1722     if (ptr) {
1723         /* this is the first stab, its strx points to the filename of the
1724         the source-file, the n_desc field should be set to the number
1725         of remaining stabs
1726         */
1727         WRITE_STAB(sptr, fileidx[0], 0, 0, 0, strlen(allfiles[0] + 12));
1728
1729         /* this is the stab for the main source file */
1730         WRITE_STAB(sptr, fileidx[mainfileindex], N_SO, 0, 0, 0);
1731
1732         /* relocation table entry */
1733
1734         /* Since the symbol table has two entries before */
1735         /* the section symbols, the index in the info.section */
1736         /* member must be adjusted by adding 2 */
1737
1738         WRITELONG(rptr, (sptr - sbuf) - 4);
1739         WRITELONG(rptr, ((ptr->info.section + 2) << 8) | R_386_32);
1740
1741         numstabs++;
1742         currfile = mainfileindex;
1743     }
1744
1745     while (ptr) {
1746         if (strcmp(allfiles[currfile], ptr->filename)) {
1747             /* oops file has changed... */
1748             for (i = 0; i < numfiles; i++)
1749                 if (!strcmp(allfiles[i], ptr->filename))
1750                     break;
1751             currfile = i;
1752             WRITE_STAB(sptr, fileidx[currfile], N_SOL, 0, 0,
1753                        ptr->info.offset);
1754             numstabs++;
1755
1756             /* relocation table entry */
1757             WRITELONG(rptr, (sptr - sbuf) - 4);
1758             WRITELONG(rptr, ((ptr->info.section + 2) << 8) | R_386_32);
1759         }
1760
1761         WRITE_STAB(sptr, 0, N_SLINE, 0, ptr->line, ptr->info.offset);
1762         numstabs++;
1763
1764         /* relocation table entry */
1765
1766         WRITELONG(rptr, (sptr - sbuf) - 4);
1767         WRITELONG(rptr, ((ptr->info.section + 2) << 8) | R_386_32);
1768
1769         ptr = ptr->next;
1770
1771     }
1772
1773     ((struct stabentry *)sbuf)->n_desc = numstabs;
1774
1775     nasm_free(allfiles);
1776     nasm_free(fileidx);
1777
1778     stablen = (sptr - sbuf);
1779     stabrellen = (rptr - rbuf);
1780     stabrelbuf = rbuf;
1781     stabbuf = sbuf;
1782     stabstrbuf = ssbuf;
1783 }
1784
1785 static void stabs32_cleanup(void)
1786 {
1787     struct linelist *ptr, *del;
1788     if (!stabslines)
1789         return;
1790     ptr = stabslines;
1791     while (ptr) {
1792         del = ptr;
1793         ptr = ptr->next;
1794         nasm_free(del);
1795     }
1796     if (stabbuf)
1797         nasm_free(stabbuf);
1798     if (stabrelbuf)
1799         nasm_free(stabrelbuf);
1800     if (stabstrbuf)
1801         nasm_free(stabstrbuf);
1802 }
1803
1804 /* dwarf routines */
1805
1806 static void dwarf32_init(struct ofmt *of, void *id, FILE * fp, efunc error)
1807 {
1808     (void)of;
1809     (void)id;
1810     (void)fp;
1811     (void)error;
1812
1813     ndebugs = 3;                /* 3 debug symbols */
1814 }
1815
1816 static void dwarf32_linenum(const char *filename, int32_t linenumber,
1817                             int32_t segto)
1818 {
1819     (void)segto;
1820     dwarf32_findfile(filename);
1821     debug_immcall = 1;
1822     currentline = linenumber;
1823 }
1824
1825 /* called from elf_out with type == TY_DEBUGSYMLIN */
1826 static void dwarf32_output(int type, void *param)
1827 {
1828   int ln, aa, inx, maxln, soc;
1829   struct symlininfo *s;
1830   struct SAA *plinep;
1831
1832   (void)type;
1833
1834   s = (struct symlininfo *)param;
1835    /* line number info is only gathered for executable sections */
1836    if (!(sects[s->section]->flags & SHF_EXECINSTR))
1837      return;
1838   /* Check if section index has changed */
1839   if (!(dwarf_csect && (dwarf_csect->section) == (s->section)))
1840   {
1841      dwarf32_findsect(s->section);
1842   }
1843   /* do nothing unless line or file has changed */
1844   if (debug_immcall)
1845   {
1846     ln = currentline - dwarf_csect->line;
1847     aa = s->offset - dwarf_csect->offset;
1848     inx = dwarf_clist->line;
1849     plinep = dwarf_csect->psaa;
1850     /* check for file change */
1851     if (!(inx == dwarf_csect->file))
1852     {
1853        saa_write8(plinep,DW_LNS_set_file);
1854        saa_write8(plinep,inx);
1855        dwarf_csect->file = inx;
1856     }
1857     /* check for line change */
1858     if (ln)
1859     {
1860        /* test if in range of special op code */
1861        maxln = line_base + line_range;
1862        soc = (ln - line_base) + (line_range * aa) + opcode_base;
1863        if (ln >= line_base && ln < maxln && soc < 256)
1864        {
1865           saa_write8(plinep,soc);
1866        }
1867        else
1868        {
1869           if (ln)
1870           {
1871           saa_write8(plinep,DW_LNS_advance_line);
1872           saa_wleb128s(plinep,ln);
1873           }
1874           if (aa)
1875           {
1876           saa_write8(plinep,DW_LNS_advance_pc);
1877           saa_wleb128u(plinep,aa);
1878           }
1879        }
1880        dwarf_csect->line = currentline;
1881        dwarf_csect->offset = s->offset;
1882     }
1883     /* show change handled */
1884     debug_immcall = 0;
1885   }
1886 }
1887
1888
1889 static void dwarf32_generate(void)
1890 {
1891     uint8_t *pbuf;
1892     int indx;
1893     struct linelist *ftentry;
1894     struct SAA *paranges, *ppubnames, *pinfo, *pabbrev, *plines, *plinep;
1895     struct SAA *parangesrel, *plinesrel, *pinforel;
1896     struct sectlist *psect;
1897     size_t saalen, linepoff, totlen, highaddr;
1898
1899     /* write epilogues for each line program range */
1900     /* and build aranges section */
1901     paranges = saa_init(1L);
1902     parangesrel = saa_init(1L);
1903     saa_write16(paranges,2);            /* dwarf version */
1904     saa_write32(parangesrel, paranges->datalen+4);
1905     saa_write32(parangesrel, (dwarf_infosym << 8) +  R_386_32); /* reloc to info */
1906     saa_write32(parangesrel, 0);
1907     saa_write32(paranges,0);            /* offset into info */
1908     saa_write8(paranges,4);             /* pointer size */
1909     saa_write8(paranges,0);             /* not segmented */
1910     saa_write32(paranges,0);            /* padding */
1911     /* iterate though sectlist entries */
1912      psect = dwarf_fsect;
1913      totlen = 0;
1914      highaddr = 0;
1915      for (indx = 0; indx < dwarf_nsections; indx++)
1916      {
1917          plinep = psect->psaa;
1918          /* Line Number Program Epilogue */
1919          saa_write8(plinep,2);                  /* std op 2 */
1920          saa_write8(plinep,(sects[psect->section]->len)-psect->offset);
1921          saa_write8(plinep,DW_LNS_extended_op);
1922          saa_write8(plinep,1);                  /* operand length */
1923          saa_write8(plinep,DW_LNE_end_sequence);
1924          totlen += plinep->datalen;
1925          /* range table relocation entry */
1926          saa_write32(parangesrel, paranges->datalen + 4);
1927          saa_write32(parangesrel, ((uint32_t) (psect->section + 2) << 8) +  R_386_32);
1928          saa_write32(parangesrel, (uint32_t) 0);
1929          /* range table entry */
1930          saa_write32(paranges,0x0000);          /* range start */
1931          saa_write32(paranges,sects[psect->section]->len);      /* range length */
1932          highaddr += sects[psect->section]->len;
1933          /* done with this entry */
1934          psect = psect->next;
1935      }
1936     saa_write32(paranges,0);            /* null address */
1937     saa_write32(paranges,0);            /* null length */
1938     saalen = paranges->datalen;
1939     arangeslen = saalen + 4;
1940     arangesbuf = pbuf = nasm_malloc(arangeslen);
1941     WRITELONG(pbuf,saalen);                     /* initial length */
1942     saa_rnbytes(paranges, pbuf, saalen);
1943     saa_free(paranges);
1944
1945     /* build rela.aranges section */
1946     arangesrellen = saalen = parangesrel->datalen;
1947     arangesrelbuf = pbuf = nasm_malloc(arangesrellen); 
1948     saa_rnbytes(parangesrel, pbuf, saalen);
1949     saa_free(parangesrel);
1950
1951     /* build pubnames section */
1952     ppubnames = saa_init(1L);
1953     saa_write16(ppubnames,3);                   /* dwarf version */
1954     saa_write32(ppubnames,0);                   /* offset into info */
1955     saa_write32(ppubnames,0);                   /* space used in info */
1956     saa_write32(ppubnames,0);                   /* end of list */
1957     saalen = ppubnames->datalen;
1958     pubnameslen = saalen + 4;
1959     pubnamesbuf = pbuf = nasm_malloc(pubnameslen);
1960     WRITELONG(pbuf,saalen);     /* initial length */
1961     saa_rnbytes(ppubnames, pbuf, saalen);
1962     saa_free(ppubnames);
1963
1964     /* build info section */
1965     pinfo = saa_init(1L);
1966     pinforel = saa_init(1L);
1967     saa_write16(pinfo,2);                       /* dwarf version */
1968     saa_write32(pinforel, pinfo->datalen + 4);
1969     saa_write32(pinforel, (dwarf_abbrevsym << 8) +  R_386_32); /* reloc to abbrev */
1970     saa_write32(pinforel, 0);
1971     saa_write32(pinfo,0);                       /* offset into abbrev */
1972     saa_write8(pinfo,4);                        /* pointer size */
1973     saa_write8(pinfo,1);                        /* abbrviation number LEB128u */
1974     saa_write32(pinforel, pinfo->datalen + 4);
1975     saa_write32(pinforel, ((dwarf_fsect->section + 2) << 8) +  R_386_32);
1976     saa_write32(pinforel, 0);
1977     saa_write32(pinfo,0);                       /* DW_AT_low_pc */
1978     saa_write32(pinforel, pinfo->datalen + 4);
1979     saa_write32(pinforel, ((dwarf_fsect->section + 2) << 8) +  R_386_32);
1980     saa_write32(pinforel, 0);
1981     saa_write32(pinfo,highaddr);                /* DW_AT_high_pc */
1982     saa_write32(pinforel, pinfo->datalen + 4);
1983     saa_write32(pinforel, (dwarf_linesym << 8) +  R_386_32); /* reloc to line */
1984     saa_write32(pinforel, 0);
1985     saa_write32(pinfo,0);                       /* DW_AT_stmt_list */
1986     saa_wbytes(pinfo, elf_module, strlen(elf_module)+1);
1987     saa_wbytes(pinfo, nasm_signature, strlen(nasm_signature)+1);
1988     saa_write16(pinfo,DW_LANG_Mips_Assembler);
1989     saa_write8(pinfo,2);                        /* abbrviation number LEB128u */
1990     saa_write32(pinforel, pinfo->datalen + 4);
1991     saa_write32(pinforel, ((dwarf_fsect->section + 2) << 8) +  R_386_32);
1992     saa_write32(pinforel, 0);
1993     saa_write32(pinfo,0);                       /* DW_AT_low_pc */
1994     saa_write32(pinfo,0);                       /* DW_AT_frame_base */
1995     saa_write8(pinfo,0);                        /* end of entries */
1996     saalen = pinfo->datalen;
1997     infolen = saalen + 4;
1998     infobuf = pbuf = nasm_malloc(infolen);
1999     WRITELONG(pbuf,saalen);             /* initial length */
2000     saa_rnbytes(pinfo, pbuf, saalen);
2001     saa_free(pinfo);
2002
2003     /* build rela.info section */
2004     inforellen = saalen = pinforel->datalen;
2005     inforelbuf = pbuf = nasm_malloc(inforellen);
2006     saa_rnbytes(pinforel, pbuf, saalen);
2007     saa_free(pinforel); 
2008
2009     /* build abbrev section */
2010     pabbrev = saa_init(1L);
2011     saa_write8(pabbrev,1);                      /* entry number LEB128u */
2012     saa_write8(pabbrev,DW_TAG_compile_unit);    /* tag LEB128u */
2013     saa_write8(pabbrev,1);                      /* has children */
2014     /* the following attributes and forms are all LEB128u values */
2015     saa_write8(pabbrev,DW_AT_low_pc);
2016     saa_write8(pabbrev,DW_FORM_addr);
2017     saa_write8(pabbrev,DW_AT_high_pc);
2018     saa_write8(pabbrev,DW_FORM_addr);
2019     saa_write8(pabbrev,DW_AT_stmt_list);
2020     saa_write8(pabbrev,DW_FORM_data4);
2021     saa_write8(pabbrev,DW_AT_name);
2022     saa_write8(pabbrev,DW_FORM_string);
2023     saa_write8(pabbrev,DW_AT_producer);
2024     saa_write8(pabbrev,DW_FORM_string);
2025     saa_write8(pabbrev,DW_AT_language);
2026     saa_write8(pabbrev,DW_FORM_data2);
2027     saa_write16(pabbrev,0);                     /* end of entry */
2028     /* LEB128u usage same as above */
2029     saa_write8(pabbrev,2);                      /* entry number */
2030     saa_write8(pabbrev,DW_TAG_subprogram);
2031     saa_write8(pabbrev,0);                      /* no children */
2032     saa_write8(pabbrev,DW_AT_low_pc);
2033     saa_write8(pabbrev,DW_FORM_addr);
2034     saa_write8(pabbrev,DW_AT_frame_base);
2035     saa_write8(pabbrev,DW_FORM_data4);
2036     saa_write16(pabbrev,0);                     /* end of entry */
2037     abbrevlen = saalen = pabbrev->datalen;
2038     abbrevbuf = pbuf = nasm_malloc(saalen);
2039     saa_rnbytes(pabbrev, pbuf, saalen);
2040     saa_free(pabbrev);
2041
2042     /* build line section */
2043     /* prolog */
2044     plines = saa_init(1L);
2045     saa_write8(plines,1);                       /* Minimum Instruction Length */
2046     saa_write8(plines,1);                       /* Initial value of 'is_stmt' */
2047     saa_write8(plines,line_base);               /* Line Base */
2048     saa_write8(plines,line_range);      /* Line Range */
2049     saa_write8(plines,opcode_base);     /* Opcode Base */
2050     /* standard opcode lengths (# of LEB128u operands) */
2051     saa_write8(plines,0);                       /* Std opcode 1 length */
2052     saa_write8(plines,1);                       /* Std opcode 2 length */
2053     saa_write8(plines,1);                       /* Std opcode 3 length */
2054     saa_write8(plines,1);                       /* Std opcode 4 length */
2055     saa_write8(plines,1);                       /* Std opcode 5 length */
2056     saa_write8(plines,0);                       /* Std opcode 6 length */
2057     saa_write8(plines,0);                       /* Std opcode 7 length */
2058     saa_write8(plines,0);                       /* Std opcode 8 length */
2059     saa_write8(plines,1);                       /* Std opcode 9 length */
2060     saa_write8(plines,0);                       /* Std opcode 10 length */
2061     saa_write8(plines,0);                       /* Std opcode 11 length */
2062     saa_write8(plines,1);                       /* Std opcode 12 length */
2063     /* Directory Table */ 
2064     saa_write8(plines,0);                       /* End of table */
2065     /* File Name Table */
2066     ftentry = dwarf_flist;
2067     for (indx = 0;indx<dwarf_numfiles;indx++)
2068     {
2069       saa_wbytes(plines, ftentry->filename, (int32_t)(strlen(ftentry->filename) + 1));
2070       saa_write8(plines,0);                     /* directory  LEB128u */
2071       saa_write8(plines,0);                     /* time LEB128u */
2072       saa_write8(plines,0);                     /* size LEB128u */
2073       ftentry = ftentry->next;
2074     }
2075     saa_write8(plines,0);                       /* End of table */
2076     linepoff = plines->datalen;
2077     linelen = linepoff + totlen + 10;
2078     linebuf = pbuf = nasm_malloc(linelen);
2079     WRITELONG(pbuf,linelen-4);          /* initial length */
2080     WRITESHORT(pbuf,3);                 /* dwarf version */
2081     WRITELONG(pbuf,linepoff);           /* offset to line number program */
2082     /* write line header */
2083     saalen = linepoff;
2084     saa_rnbytes(plines, pbuf, saalen);   /* read a given no. of bytes */
2085     pbuf += linepoff;
2086     saa_free(plines);
2087     /* concatonate line program ranges */
2088     linepoff += 13;
2089     plinesrel = saa_init(1L);
2090     psect = dwarf_fsect;
2091     for (indx = 0; indx < dwarf_nsections; indx++)
2092     {
2093          saa_write32(plinesrel, linepoff);
2094          saa_write32(plinesrel, ((uint32_t) (psect->section + 2) << 8) +  R_386_32);
2095          saa_write32(plinesrel, (uint32_t) 0);
2096          plinep = psect->psaa;
2097          saalen = plinep->datalen;
2098          saa_rnbytes(plinep, pbuf, saalen);
2099          pbuf += saalen;
2100          linepoff += saalen;
2101          saa_free(plinep);
2102          /* done with this entry */
2103          psect = psect->next;
2104     }
2105
2106
2107     /* build rela.lines section */
2108     linerellen =saalen = plinesrel->datalen;
2109     linerelbuf = pbuf = nasm_malloc(linerellen); 
2110     saa_rnbytes(plinesrel, pbuf, saalen);
2111     saa_free(plinesrel);
2112
2113     /* build frame section */
2114     framelen = 4;
2115     framebuf = pbuf = nasm_malloc(framelen);
2116     WRITELONG(pbuf,framelen-4);         /* initial length */
2117
2118     /* build loc section */
2119     loclen = 16;
2120     locbuf = pbuf = nasm_malloc(loclen);
2121     WRITELONG(pbuf,0);          /* null  beginning offset */
2122     WRITELONG(pbuf,0);          /* null  ending offset */
2123 }
2124
2125 static void dwarf32_cleanup(void)
2126 {
2127     if (arangesbuf)
2128         nasm_free(arangesbuf);
2129     if (arangesrelbuf)
2130         nasm_free(arangesrelbuf);
2131     if (pubnamesbuf)
2132         nasm_free(pubnamesbuf);
2133     if (infobuf)
2134         nasm_free(infobuf);
2135     if (inforelbuf)
2136         nasm_free(inforelbuf);
2137     if (abbrevbuf)
2138         nasm_free(abbrevbuf);
2139     if (linebuf)
2140         nasm_free(linebuf);
2141     if (linerelbuf)
2142         nasm_free(linerelbuf);
2143     if (framebuf)
2144         nasm_free(framebuf);
2145     if (locbuf)
2146         nasm_free(locbuf);
2147 }
2148 static void dwarf32_findfile(const char * fname)
2149 {
2150    int finx;
2151    struct linelist *match;
2152
2153    /* return if fname is current file name */
2154    if (dwarf_clist && !(strcmp(fname, dwarf_clist->filename))) return;
2155    /* search for match */
2156    else 
2157    {
2158      match = 0;
2159      if (dwarf_flist)
2160      {
2161        match = dwarf_flist;
2162        for (finx = 0; finx < dwarf_numfiles; finx++)
2163        {
2164          if (!(strcmp(fname, match->filename)))
2165          {
2166            dwarf_clist = match;
2167            return;
2168          }
2169        }
2170      }
2171      /* add file name to end of list */
2172      dwarf_clist =  (struct linelist *)nasm_malloc(sizeof(struct linelist));
2173      dwarf_numfiles++;
2174      dwarf_clist->line = dwarf_numfiles;
2175      dwarf_clist->filename = nasm_malloc(strlen(fname) + 1);
2176      strcpy(dwarf_clist->filename,fname);
2177      dwarf_clist->next = 0;
2178      /* if first entry */
2179      if (!dwarf_flist)
2180      {
2181        dwarf_flist = dwarf_elist = dwarf_clist;
2182        dwarf_clist->last = 0;
2183      }
2184      /* chain to previous entry */
2185      else
2186      {
2187        dwarf_elist->next = dwarf_clist;
2188        dwarf_elist = dwarf_clist;
2189      }
2190    }
2191 }
2192 /*  */
2193 static void dwarf32_findsect(const int index)
2194 {
2195    int sinx;
2196    struct sectlist *match;
2197    struct SAA *plinep;
2198    /* return if index is current section index */
2199    if (dwarf_csect && (dwarf_csect->section == index))
2200    {
2201       return;
2202    }
2203    /* search for match */
2204    else 
2205    {
2206      match = 0;
2207      if (dwarf_fsect)
2208      {
2209        match = dwarf_fsect;
2210        for (sinx = 0; sinx < dwarf_nsections; sinx++)
2211        {
2212          if ((match->section == index))
2213          {
2214            dwarf_csect = match;
2215            return;
2216          }
2217         match = match->next;
2218        }
2219      }
2220      /* add entry to end of list */
2221      dwarf_csect =  (struct sectlist *)nasm_malloc(sizeof(struct sectlist));
2222      dwarf_nsections++;
2223      dwarf_csect->psaa = plinep = saa_init(1L);
2224      dwarf_csect->line = 1;
2225      dwarf_csect->offset = 0;
2226      dwarf_csect->file = 1;
2227      dwarf_csect->section = index;
2228      dwarf_csect->next = 0;
2229      /* set relocatable address at start of line program */
2230      saa_write8(plinep,DW_LNS_extended_op);
2231      saa_write8(plinep,5);                      /* operand length */
2232      saa_write8(plinep,DW_LNE_set_address);
2233      saa_write32(plinep,0);             /* Start Address */
2234      /* if first entry */
2235      if (!dwarf_fsect)
2236      {
2237        dwarf_fsect = dwarf_esect = dwarf_csect;
2238        dwarf_csect->last = 0;
2239      }
2240      /* chain to previous entry */
2241      else
2242      {
2243        dwarf_esect->next = dwarf_csect;
2244        dwarf_esect = dwarf_csect;
2245      }
2246    }
2247 }
2248
2249 #endif                          /* OF_ELF */