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