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