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