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