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