regularized spelling of license to match name of LICENSE file
[platform/upstream/nasm.git] / output / outelf64.c
1 /* outelf.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
10 #include "compiler.h"
11
12 #include <stdio.h>
13 #include <stdlib.h>
14 #include <string.h>
15 #include <ctype.h>
16 #include <inttypes.h>
17
18 #include "nasm.h"
19 #include "nasmlib.h"
20 #include "stdscan.h"
21 #include "outform.h"
22
23 /* Definitions in lieu of elf.h */
24
25 #define SHT_PROGBITS 1
26 #define SHT_RELA          4             /* Relocation entries with addends */
27 #define SHT_NOBITS 8
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 typedef uint32_t Elf64_Word;
54 typedef uint64_t Elf64_Xword;
55 typedef uint64_t Elf64_Addr;
56 typedef uint64_t Elf64_Off;
57 typedef struct
58 {
59   Elf64_Word    sh_name;                /* Section name (string tbl index) */
60   Elf64_Word    sh_type;                /* Section type */
61   Elf64_Xword   sh_flags;               /* Section flags */
62   Elf64_Addr    sh_addr;                /* Section virtual addr at execution */
63   Elf64_Off     sh_offset;              /* Section file offset */
64   Elf64_Xword   sh_size;                /* Section size in bytes */
65   Elf64_Word    sh_link;                /* Link to another section */
66   Elf64_Word    sh_info;                /* Additional section information */
67   Elf64_Xword   sh_addralign;           /* Section alignment */
68   Elf64_Xword   sh_entsize;             /* Entry size if section holds table */
69 } Elf64_Shdr;
70
71
72 #ifdef OF_ELF64
73
74
75 struct Reloc {
76     struct Reloc *next;
77     int64_t address;               /* relative to _start_ of section */
78     int64_t symbol;                /* symbol index */
79     int type;                   /* type of relocation */
80 };
81
82 struct Symbol {
83     int32_t strpos;                /* string table position of name */
84     int32_t section;               /* section ID of the symbol */
85     int type;                   /* symbol type */
86     int other;                     /* symbol visibility */
87     int64_t value;                 /* address, or COMMON variable align */
88     int32_t size;                  /* size of symbol */
89     int32_t globnum;               /* symbol table offset if global */
90     struct Symbol *next;        /* list of globals in each section */
91     struct Symbol *nextfwd;     /* list of unresolved-size symbols */
92     char *name;                 /* used temporarily if in above list */
93 };
94
95
96 struct Section {
97     struct SAA *data;
98     uint64_t len, size;
99     uint32_t nrelocs;
100     int32_t index;
101     uint32_t type;             /* SHT_PROGBITS or SHT_NOBITS */
102     uint64_t align;            /* alignment: power of two */
103     uint64_t flags;            /* section flags */
104     char *name;
105     struct SAA *rel;
106     uint64_t rellen;
107     struct Reloc *head, **tail;
108     struct Symbol *gsyms;       /* global symbols in section */
109 };
110
111 #define SECT_DELTA 32
112 static struct Section **sects;
113 static int nsects, sectlen;
114
115 #define SHSTR_DELTA 256
116 static char *shstrtab;
117 static int shstrtablen, shstrtabsize;
118
119 static struct SAA *syms;
120 static uint32_t nlocals, nglobs;
121
122 static int32_t def_seg;
123
124 static struct RAA *bsym;
125
126 static struct SAA *strs;
127 static uint32_t strslen;
128
129 static FILE *elffp;
130 static efunc error;
131 static evalfunc evaluate;
132
133 static struct Symbol *fwds;
134
135 static char elf_module[FILENAME_MAX];
136
137 static uint8_t elf_osabi = 0;   /* Default OSABI = 0 (System V or Linux) */
138 static uint8_t elf_abiver = 0;  /* Current ABI version */
139
140 extern struct ofmt of_elf64;
141
142 #define SHN_UNDEF 0
143
144 #define SYM_GLOBAL 0x10
145
146 #define STV_DEFAULT 0
147 #define STV_INTERNAL 1
148 #define STV_HIDDEN 2
149 #define STV_PROTECTED 3
150
151 #define GLOBAL_TEMP_BASE 16     /* bigger than any constant sym id */
152
153 #define SEG_ALIGN 16            /* alignment of sections in file */
154 #define SEG_ALIGN_1 (SEG_ALIGN-1)
155
156 static const char align_str[SEG_ALIGN] = "";    /* ANSI will pad this with 0s */
157
158 #define ELF_MAX_SECTIONS 16     /* really 10, but let's play safe */
159 static struct ELF_SECTDATA {
160     void *data;
161     int64_t len;
162     bool is_saa;
163 } *elf_sects;
164 static int elf_nsect;
165 static int64_t elf_foffs;
166
167 static void elf_write(void);
168 static void elf_sect_write(struct Section *, const uint8_t *,
169                            uint64_t);
170 static void elf_section_header(int, int, uint64_t, void *, bool, uint64_t, int, int,
171                                int, int);
172 static void elf_write_sections(void);
173 static struct SAA *elf_build_symtab(int32_t *, int32_t *);
174 static struct SAA *elf_build_reltab(uint64_t *, struct Reloc *);
175 static void add_sectname(char *, char *);
176
177 /* this stuff is needed for the stabs debugging format */
178 #define N_SO 0x64               /* ID for main source file */
179 #define N_SOL 0x84              /* ID for sub-source file */
180 #define N_BINCL 0x82
181 #define N_EINCL 0xA2
182 #define N_SLINE 0x44
183 #define TY_STABSSYMLIN 0x40     /* ouch */
184
185 struct stabentry {
186     uint32_t n_strx;
187     uint8_t n_type;
188     uint8_t n_other;
189     uint16_t n_desc;
190     uint32_t n_value;
191 };
192
193 struct erel {
194     int offset, info;
195 };
196
197 struct symlininfo {
198     int offset;
199     int section;                /* section index */
200     char *name;                 /* shallow-copied pointer of section name */
201 };
202
203 struct linelist {
204     struct symlininfo info;
205     int line;
206     char *filename;
207     struct linelist *next;
208     struct linelist *last;
209 };
210
211 static struct linelist *stabslines = 0;
212 static int stabs_immcall = 0;
213 static int currentline = 0;
214 static int numlinestabs = 0;
215 static char *stabs_filename = 0;
216 static int symtabsection;
217 static uint8_t *stabbuf = 0, *stabstrbuf = 0, *stabrelbuf = 0;
218 static int stablen, stabstrlen, stabrellen;
219
220 static struct dfmt df_stabs;
221 static struct Symbol *lastsym;
222
223 void stabs64_init(struct ofmt *, void *, FILE *, efunc);
224 void stabs64_linenum(const char *filename, int32_t linenumber, int32_t);
225 void stabs64_deflabel(char *, int32_t, int64_t, int, char *);
226 void stabs64_directive(const char *, const char *);
227 void stabs64_typevalue(int32_t);
228 void stabs64_output(int, void *);
229 void stabs64_generate(void);
230 void stabs64_cleanup(void);
231
232 /* end of stabs debugging stuff */
233
234 /*
235  * Special section numbers which are used to define ELF special
236  * symbols, which can be used with WRT to provide PIC relocation
237  * types.
238  */
239 static int32_t elf_gotpc_sect, elf_gotoff_sect;
240 static int32_t elf_got_sect, elf_plt_sect;
241 static int32_t elf_sym_sect;
242
243 static void elf_init(FILE * fp, efunc errfunc, ldfunc ldef, evalfunc eval)
244 {
245     maxbits = 64;
246     elffp = fp;
247     error = errfunc;
248     evaluate = eval;
249     (void)ldef;                 /* placate optimisers */
250     sects = NULL;
251     nsects = sectlen = 0;
252     syms = saa_init((int32_t)sizeof(struct Symbol));
253     nlocals = nglobs = 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     ldef("..gotpc", elf_gotpc_sect + 1, 0L, NULL, false, false, &of_elf64,
267          error);
268     elf_gotoff_sect = seg_alloc();
269     ldef("..gotoff", elf_gotoff_sect + 1, 0L, NULL, false, false, &of_elf64,
270          error);
271     elf_got_sect = seg_alloc();
272     ldef("..got", elf_got_sect + 1, 0L, NULL, false, false, &of_elf64,
273          error);
274     elf_plt_sect = seg_alloc();
275     ldef("..plt", elf_plt_sect + 1, 0L, NULL, false, false, &of_elf64,
276          error);
277     elf_sym_sect = seg_alloc();
278     ldef("..sym", elf_sym_sect + 1, 0L, NULL, false, false, &of_elf64,
279          error);
280
281     def_seg = seg_alloc();
282 }
283
284 static void elf_cleanup(int debuginfo)
285 {
286     struct Reloc *r;
287     int i;
288
289     (void)debuginfo;
290
291     elf_write();
292     fclose(elffp);
293     for (i = 0; i < nsects; i++) {
294         if (sects[i]->type != SHT_NOBITS)
295             saa_free(sects[i]->data);
296         if (sects[i]->head)
297             saa_free(sects[i]->rel);
298         while (sects[i]->head) {
299             r = sects[i]->head;
300             sects[i]->head = sects[i]->head->next;
301             nasm_free(r);
302         }
303     }
304     nasm_free(sects);
305     saa_free(syms);
306     raa_free(bsym);
307     saa_free(strs);
308     if (of_elf64.current_dfmt) {
309         of_elf64.current_dfmt->cleanup();
310     }
311 }
312
313 static void add_sectname(char *firsthalf, char *secondhalf)
314 {
315     int len = strlen(firsthalf) + strlen(secondhalf);
316     while (shstrtablen + len + 1 > shstrtabsize)
317         shstrtab = nasm_realloc(shstrtab, (shstrtabsize += SHSTR_DELTA));
318     strcpy(shstrtab + shstrtablen, firsthalf);
319     strcat(shstrtab + shstrtablen, secondhalf);
320     shstrtablen += len + 1;
321 }
322
323 static int elf_make_section(char *name, int type, int flags, int align)
324 {
325     struct Section *s;
326
327     s = nasm_malloc(sizeof(*s));
328
329     if (type != SHT_NOBITS)
330         s->data = saa_init(1L);
331     s->head = NULL;
332     s->tail = &s->head;
333     s->len = s->size = 0;
334     s->nrelocs = 0;
335     if (!strcmp(name, ".text"))
336         s->index = def_seg;
337     else
338         s->index = seg_alloc();
339     add_sectname("", name);
340     s->name = nasm_malloc(1 + strlen(name));
341     strcpy(s->name, name);
342     s->type = type;
343     s->flags = flags;
344     s->align = align;
345     s->gsyms = NULL;
346
347     if (nsects >= sectlen)
348         sects =
349             nasm_realloc(sects, (sectlen += SECT_DELTA) * sizeof(*sects));
350     sects[nsects++] = s;
351
352     return nsects - 1;
353 }
354
355 static int32_t elf_section_names(char *name, int pass, int *bits)
356 {
357     char *p;
358     unsigned flags_and, flags_or;
359     uint64_t type, align;
360     int i;
361
362     /*
363      * Default is 64 bits.
364      */
365     if (!name) {
366         *bits = 64;
367         return def_seg;
368     }
369
370     p = name;
371     while (*p && !isspace(*p))
372         p++;
373     if (*p)
374         *p++ = '\0';
375     flags_and = flags_or = type = align = 0;
376
377     while (*p && isspace(*p))
378         p++;
379     while (*p) {
380         char *q = p;
381         while (*p && !isspace(*p))
382             p++;
383         if (*p)
384             *p++ = '\0';
385         while (*p && isspace(*p))
386             p++;
387
388         if (!nasm_strnicmp(q, "align=", 6)) {
389             align = atoi(q + 6);
390             if (align == 0)
391                 align = 1;
392             if ((align - 1) & align) {  /* means it's not a power of two */
393                 error(ERR_NONFATAL, "section alignment %d is not"
394                       " a power of two", align);
395                 align = 1;
396             }
397         } else if (!nasm_stricmp(q, "alloc")) {
398             flags_and |= SHF_ALLOC;
399             flags_or |= SHF_ALLOC;
400         } else if (!nasm_stricmp(q, "noalloc")) {
401             flags_and |= SHF_ALLOC;
402             flags_or &= ~SHF_ALLOC;
403         } else if (!nasm_stricmp(q, "exec")) {
404             flags_and |= SHF_EXECINSTR;
405             flags_or |= SHF_EXECINSTR;
406         } else if (!nasm_stricmp(q, "noexec")) {
407             flags_and |= SHF_EXECINSTR;
408             flags_or &= ~SHF_EXECINSTR;
409         } else if (!nasm_stricmp(q, "write")) {
410             flags_and |= SHF_WRITE;
411             flags_or |= SHF_WRITE;
412         } else if (!nasm_stricmp(q, "nowrite")) {
413             flags_and |= SHF_WRITE;
414             flags_or &= ~SHF_WRITE;
415         } else if (!nasm_stricmp(q, "progbits")) {
416             type = SHT_PROGBITS;
417         } else if (!nasm_stricmp(q, "nobits")) {
418             type = SHT_NOBITS;
419         }
420     }
421
422     if (!strcmp(name, ".comment") ||
423         !strcmp(name, ".shstrtab") ||
424         !strcmp(name, ".symtab") || !strcmp(name, ".strtab")) {
425         error(ERR_NONFATAL, "attempt to redefine reserved section"
426               "name `%s'", name);
427         return NO_SEG;
428     }
429
430     for (i = 0; i < nsects; i++)
431         if (!strcmp(name, sects[i]->name))
432             break;
433     if (i == nsects) {
434         if (!strcmp(name, ".text"))
435             i = elf_make_section(name, SHT_PROGBITS,
436                                  SHF_ALLOC | SHF_EXECINSTR, 16);
437         else if (!strcmp(name, ".rodata"))
438             i = elf_make_section(name, SHT_PROGBITS, SHF_ALLOC, 4);
439         else if (!strcmp(name, ".data"))
440             i = elf_make_section(name, SHT_PROGBITS,
441                                  SHF_ALLOC | SHF_WRITE, 4);
442         else if (!strcmp(name, ".bss"))
443             i = elf_make_section(name, SHT_NOBITS,
444                                  SHF_ALLOC | SHF_WRITE, 4);
445         else
446             i = elf_make_section(name, SHT_PROGBITS, SHF_ALLOC, 1);
447         if (type)
448             sects[i]->type = type;
449         if (align)
450             sects[i]->align = align;
451         sects[i]->flags &= ~flags_and;
452         sects[i]->flags |= flags_or;
453     } else if (pass == 1) {
454           if ((type && sects[i]->type != type)
455              || (align && sects[i]->align != align)
456              || (flags_and && ((sects[i]->flags & flags_and) != flags_or)))
457             error(ERR_WARNING, "incompatible section attributes ignored on"
458                   " redeclaration of section `%s'", name);
459     }
460
461     return sects[i]->index;
462 }
463
464 static void elf_deflabel(char *name, int32_t segment, int64_t offset,
465                          int is_global, char *special)
466 {
467     int pos = strslen;
468     struct Symbol *sym;
469     bool special_used = false;
470
471 #if defined(DEBUG) && DEBUG>2
472     fprintf(stderr,
473             " elf_deflabel: %s, seg=%x, off=%x, is_global=%d, %s\n",
474             name, segment, offset, is_global, special);
475 #endif
476     if (name[0] == '.' && name[1] == '.' && name[2] != '@') {
477         /*
478          * This is a NASM special symbol. We never allow it into
479          * the ELF symbol table, even if it's a valid one. If it
480          * _isn't_ a valid one, we should barf immediately.
481          */
482         if (strcmp(name, "..gotpc") && strcmp(name, "..gotoff") &&
483             strcmp(name, "..got") && strcmp(name, "..plt") &&
484             strcmp(name, "..sym"))
485             error(ERR_NONFATAL, "unrecognised special symbol `%s'", name);
486         return;
487     }
488
489     if (is_global == 3) {
490         struct Symbol **s;
491         /*
492          * Fix up a forward-reference symbol size from the first
493          * pass.
494          */
495         for (s = &fwds; *s; s = &(*s)->nextfwd)
496             if (!strcmp((*s)->name, name)) {
497                 struct tokenval tokval;
498                 expr *e;
499                 char *p = special;
500
501                 while (*p && !isspace(*p))
502                     p++;
503                 while (*p && isspace(*p))
504                     p++;
505                 stdscan_reset();
506                 stdscan_bufptr = p;
507                 tokval.t_type = TOKEN_INVALID;
508                 e = evaluate(stdscan, NULL, &tokval, NULL, 1, error, NULL);
509                 if (e) {
510                     if (!is_simple(e))
511                         error(ERR_NONFATAL, "cannot use relocatable"
512                               " expression as symbol size");
513                     else
514                         (*s)->size = reloc_value(e);
515                 }
516
517                 /*
518                  * Remove it from the list of unresolved sizes.
519                  */
520                 nasm_free((*s)->name);
521                 *s = (*s)->nextfwd;
522                 return;
523             }
524         return;                 /* it wasn't an important one */
525     }
526
527     saa_wbytes(strs, name, (int32_t)(1 + strlen(name)));
528     strslen += 1 + strlen(name);
529
530     lastsym = sym = saa_wstruct(syms);
531
532     sym->strpos = pos;
533     sym->type = is_global ? SYM_GLOBAL : 0;
534     sym->other = STV_DEFAULT;
535     sym->size = 0;
536     if (segment == NO_SEG)
537         sym->section = SHN_ABS;
538     else {
539         int i;
540         sym->section = SHN_UNDEF;
541         if (nsects == 0 && segment == def_seg) {
542             int tempint;
543             if (segment != elf_section_names(".text", 2, &tempint))
544                 error(ERR_PANIC,
545                       "strange segment conditions in ELF driver");
546             sym->section = nsects;
547         } else {
548             for (i = 0; i < nsects; i++)
549                 if (segment == sects[i]->index) {
550                     sym->section = i + 1;
551                     break;
552                 }
553         }
554     }
555
556     if (is_global == 2) {
557         sym->size = offset;
558         sym->value = 0;
559         sym->section = SHN_COMMON;
560         /*
561          * We have a common variable. Check the special text to see
562          * if it's a valid number and power of two; if so, store it
563          * as the alignment for the common variable.
564          */
565         if (special) {
566             bool err;
567             sym->value = readnum(special, &err);
568             if (err)
569                 error(ERR_NONFATAL, "alignment constraint `%s' is not a"
570                       " valid number", special);
571             else if ((sym->value | (sym->value - 1)) != 2 * sym->value - 1)
572                 error(ERR_NONFATAL, "alignment constraint `%s' is not a"
573                       " power of two", special);
574         }
575         special_used = true;
576     } else
577         sym->value = (sym->section == SHN_UNDEF ? 0 : offset);
578
579     if (sym->type == SYM_GLOBAL) {
580         /*
581          * If sym->section == SHN_ABS, then the first line of the
582          * else section would cause a core dump, because its a reference
583          * beyond the end of the section array.
584          * This behaviour is exhibited by this code:
585          *     GLOBAL crash_nasm
586          *     crash_nasm equ 0
587          * To avoid such a crash, such requests are silently discarded.
588          * This may not be the best solution.
589          */
590         if (sym->section == SHN_UNDEF || sym->section == SHN_COMMON) {
591             bsym = raa_write(bsym, segment, nglobs);
592         } else if (sym->section != SHN_ABS) {
593             /*
594              * This is a global symbol; so we must add it to the linked
595              * list of global symbols in its section. We'll push it on
596              * the beginning of the list, because it doesn't matter
597              * much which end we put it on and it's easier like this.
598              *
599              * In addition, we check the special text for symbol
600              * type and size information.
601              */
602             sym->next = sects[sym->section - 1]->gsyms;
603             sects[sym->section - 1]->gsyms = sym;
604
605             if (special) {
606                 int n = strcspn(special, " \t");
607
608                 if (!nasm_strnicmp(special, "function", n))
609                     sym->type |= STT_FUNC;
610                 else if (!nasm_strnicmp(special, "data", n) ||
611                          !nasm_strnicmp(special, "object", n))
612                     sym->type |= STT_OBJECT;
613                 else if (!nasm_strnicmp(special, "notype", n))
614                     sym->type |= STT_NOTYPE;
615                 else
616                     error(ERR_NONFATAL, "unrecognised symbol type `%.*s'",
617                           n, special);
618                 special += n;
619
620                 while (isspace(*special))
621                     ++special;
622                 if (*special) {
623                     n = strcspn(special, " \t");
624                     if (!nasm_strnicmp(special, "default", n))
625                         sym->other = STV_DEFAULT;
626                     else if (!nasm_strnicmp(special, "internal", n))
627                         sym->other = STV_INTERNAL;
628                     else if (!nasm_strnicmp(special, "hidden", n))
629                         sym->other = STV_HIDDEN;
630                     else if (!nasm_strnicmp(special, "protected", n))
631                         sym->other = STV_PROTECTED;
632                     else
633                         n = 0;
634                     special += n;
635                 }
636
637                 if (*special) {
638                     struct tokenval tokval;
639                     expr *e;
640                     int fwd = 0;
641                     char *saveme = stdscan_bufptr;      /* bugfix? fbk 8/10/00 */
642
643                     while (special[n] && isspace(special[n]))
644                         n++;
645                     /*
646                      * We have a size expression; attempt to
647                      * evaluate it.
648                      */
649                     stdscan_reset();
650                     stdscan_bufptr = special + n;
651                     tokval.t_type = TOKEN_INVALID;
652                     e = evaluate(stdscan, NULL, &tokval, &fwd, 0, error,
653                                  NULL);
654                     if (fwd) {
655                         sym->nextfwd = fwds;
656                         fwds = sym;
657                         sym->name = nasm_strdup(name);
658                     } else if (e) {
659                         if (!is_simple(e))
660                             error(ERR_NONFATAL, "cannot use relocatable"
661                                   " expression as symbol size");
662                         else
663                             sym->size = reloc_value(e);
664                     }
665                     stdscan_bufptr = saveme;    /* bugfix? fbk 8/10/00 */
666                 }
667                 special_used = true;
668             }
669         }
670         sym->globnum = nglobs;
671         nglobs++;
672     } else
673         nlocals++;
674
675     if (special && !special_used)
676         error(ERR_NONFATAL, "no special symbol features supported here");
677 }
678
679 static void elf_add_reloc(struct Section *sect, int32_t segment, int type)
680 {
681     struct Reloc *r;
682
683     r = *sect->tail = nasm_malloc(sizeof(struct Reloc));
684     sect->tail = &r->next;
685     r->next = NULL;
686
687     r->address = sect->len;
688     if (segment == NO_SEG)
689         r->symbol = 0;
690     else {
691         int i;
692         r->symbol = 0;
693         for (i = 0; i < nsects; i++)
694             if (segment == sects[i]->index)
695                 r->symbol = i + 2;
696         if (!r->symbol)
697             r->symbol = GLOBAL_TEMP_BASE + raa_read(bsym, segment);
698     }
699     r->type = type;
700
701     sect->nrelocs++;
702 }
703
704 /*
705  * This routine deals with ..got and ..sym relocations: the more
706  * complicated kinds. In shared-library writing, some relocations
707  * with respect to global symbols must refer to the precise symbol
708  * rather than referring to an offset from the base of the section
709  * _containing_ the symbol. Such relocations call to this routine,
710  * which searches the symbol list for the symbol in question.
711  *
712  * R_386_GOT32 references require the _exact_ symbol address to be
713  * used; R_386_32 references can be at an offset from the symbol.
714  * The boolean argument `exact' tells us this.
715  *
716  * Return value is the adjusted value of `addr', having become an
717  * offset from the symbol rather than the section. Should always be
718  * zero when returning from an exact call.
719  *
720  * Limitation: if you define two symbols at the same place,
721  * confusion will occur.
722  *
723  * Inefficiency: we search, currently, using a linked list which
724  * isn't even necessarily sorted.
725  */
726 static int32_t elf_add_gsym_reloc(struct Section *sect,
727                                int32_t segment, int64_t offset,
728                                int type, bool exact)
729 {
730     struct Reloc *r;
731     struct Section *s;
732     struct Symbol *sym, *sm;
733     int i;
734
735     /*
736      * First look up the segment/offset pair and find a global
737      * symbol corresponding to it. If it's not one of our segments,
738      * then it must be an external symbol, in which case we're fine
739      * doing a normal elf_add_reloc after first sanity-checking
740      * that the offset from the symbol is zero.
741      */
742     s = NULL;
743     for (i = 0; i < nsects; i++)
744         if (segment == sects[i]->index) {
745             s = sects[i];
746             break;
747         }
748     if (!s) {
749         if (exact && offset != 0)
750             error(ERR_NONFATAL, "unable to find a suitable global symbol"
751                   " for this reference");
752         else
753             elf_add_reloc(sect, segment, type);
754         return offset;
755     }
756
757     if (exact) {
758         /*
759          * Find a symbol pointing _exactly_ at this one.
760          */
761         for (sym = s->gsyms; sym; sym = sym->next)
762             if (sym->value == offset)
763                 break;
764     } else {
765         /*
766          * Find the nearest symbol below this one.
767          */
768         sym = NULL;
769         for (sm = s->gsyms; sm; sm = sm->next)
770             if (sm->value <= offset && (!sym || sm->value > sym->value))
771                 sym = sm;
772     }
773     if (!sym && exact) {
774         error(ERR_NONFATAL, "unable to find a suitable global symbol"
775               " for this reference");
776         return 0;
777     }
778
779     r = *sect->tail = nasm_malloc(sizeof(struct Reloc));
780     sect->tail = &r->next;
781     r->next = NULL;
782
783     r->address = sect->len;
784     r->symbol = GLOBAL_TEMP_BASE + sym->globnum;
785     r->type = type;
786
787     sect->nrelocs++;
788
789     return offset - sym->value;
790 }
791
792 static void elf_out(int32_t segto, const void *data,
793                     enum out_type type, uint64_t size,
794                     int32_t segment, int32_t wrt)
795 {
796     struct Section *s;
797     int64_t addr;
798     uint8_t mydata[16], *p;
799     int i;
800     static struct symlininfo sinfo;
801
802 #if defined(DEBUG) && DEBUG>2
803     fprintf(stderr,
804             " elf_out type: %x seg: %d bytes: %x data: %"PRIx64"\n",
805                (type >> 24), segment, size, *(int64_t *)data);
806 #endif
807
808     /*
809      * handle absolute-assembly (structure definitions)
810      */
811     if (segto == NO_SEG) {
812         if (type != OUT_RESERVE)
813             error(ERR_NONFATAL, "attempt to assemble code in [ABSOLUTE]"
814                   " space");
815         return;
816     }
817
818     s = NULL;
819     for (i = 0; i < nsects; i++)
820         if (segto == sects[i]->index) {
821             s = sects[i];
822             break;
823         }
824     if (!s) {
825         int tempint;            /* ignored */
826         if (segto != elf_section_names(".text", 2, &tempint))
827             error(ERR_PANIC, "strange segment conditions in ELF driver");
828         else {
829             s = sects[nsects - 1];
830             i = nsects - 1;
831         }
832     }
833
834     /* again some stabs debugging stuff */
835     if (of_elf64.current_dfmt) {
836         sinfo.offset = s->len;
837         sinfo.section = i;
838         sinfo.name = s->name;
839         of_elf64.current_dfmt->debug_output(TY_STABSSYMLIN, &sinfo);
840     }
841     /* end of debugging stuff */
842
843     if (s->type == SHT_NOBITS && type != OUT_RESERVE) {
844         error(ERR_WARNING, "attempt to initialize memory in"
845               " BSS section `%s': ignored", s->name);
846         if (type == OUT_REL2ADR)
847             size = 2;
848         else if (type == OUT_REL4ADR)
849             size = 4;
850         s->len += size;
851         return;
852     }
853
854     if (type == OUT_RESERVE) {
855         if (s->type == SHT_PROGBITS) {
856             error(ERR_WARNING, "uninitialized space declared in"
857                   " non-BSS section `%s': zeroing", s->name);
858             elf_sect_write(s, NULL, size);
859         } else
860             s->len += size;
861     } else if (type == OUT_RAWDATA) {
862         if (segment != NO_SEG)
863             error(ERR_PANIC, "OUT_RAWDATA with other than NO_SEG");
864         elf_sect_write(s, data, size);
865     } else if (type == OUT_ADDRESS) {
866         bool gnu16 = false;
867         addr = *(int64_t *)data;
868         if (segment != NO_SEG) {
869             if (segment % 2) {
870                 error(ERR_NONFATAL, "ELF format does not support"
871                       " segment base references");
872             } else {
873                 if (wrt == NO_SEG) {
874                     switch ((int)size) {
875                     case 2:
876                         elf_add_reloc(s, segment, R_X86_64_16);
877                         break;
878                     case 4:
879                         elf_add_reloc(s, segment, R_X86_64_32);
880                         break;
881                     case 8:
882                         elf_add_reloc(s, segment, R_X86_64_64);
883                         break;
884                     default:
885                         error(ERR_PANIC, "internal error elf64-hpa-871");
886                         break;
887                     }
888                 } else if (wrt == elf_gotpc_sect + 1) {
889                     /*
890                      * The user will supply GOT relative to $$. ELF
891                      * will let us have GOT relative to $. So we
892                      * need to fix up the data item by $-$$.
893                      */
894                     addr += s->len;
895                     elf_add_reloc(s, segment, R_X86_64_GOTPCREL);
896                 } else if (wrt == elf_gotoff_sect + 1) {
897                     elf_add_reloc(s, segment, R_X86_64_GOTTPOFF);
898                 } else if (wrt == elf_got_sect + 1) {
899                     addr = elf_add_gsym_reloc(s, segment, addr,
900                                               R_X86_64_GOT32, true);
901                 } else if (wrt == elf_sym_sect + 1) {
902                     switch ((int)size) {
903                     case 2:
904                         gnu16 = true;
905                         addr = elf_add_gsym_reloc(s, segment, addr,
906                                                   R_X86_64_16, false);
907                         break;
908                     case 4:
909                         addr = elf_add_gsym_reloc(s, segment, addr,
910                                                   R_X86_64_32, false);
911                         break;
912                     case 8:
913                         addr = elf_add_gsym_reloc(s, segment, addr,
914                                                   R_X86_64_64, false);
915                         break;
916                     default:
917                         error(ERR_PANIC, "internal error elf64-hpa-903");
918                         break;
919                     }
920                 } else if (wrt == elf_plt_sect + 1) {
921                     error(ERR_NONFATAL, "ELF format cannot produce non-PC-"
922                           "relative PLT references");
923                 } else {
924                     error(ERR_NONFATAL, "ELF format does not support this"
925                           " use of WRT");
926                     wrt = NO_SEG;       /* we can at least _try_ to continue */
927                 }
928             }
929         }
930         p = mydata;
931         if (gnu16) {
932             WRITESHORT(p, addr);
933         } else {
934             if (size != 8 && size != 4 && segment != NO_SEG) {
935                 error(ERR_NONFATAL,
936                       "Unsupported non-64-bit ELF relocation");
937             }
938             if (size == 4) WRITELONG(p, addr);
939             else WRITEDLONG(p, (int64_t)addr);
940         }
941         elf_sect_write(s, mydata, size);
942     } else if (type == OUT_REL2ADR) {
943         if (segment == segto)
944             error(ERR_PANIC, "intra-segment OUT_REL2ADR");
945         if (segment != NO_SEG && segment % 2) {
946             error(ERR_NONFATAL, "ELF format does not support"
947                   " segment base references");
948         } else {
949             if (wrt == NO_SEG) {
950                 elf_add_reloc(s, segment, R_X86_64_PC16);
951             } else {
952                 error(ERR_NONFATAL,
953                       "Unsupported non-32-bit ELF relocation [2]");
954             }
955         }
956         p = mydata;
957         WRITESHORT(p, *(int64_t *)data - size);
958         elf_sect_write(s, mydata, 2L);
959     } else if (type == OUT_REL4ADR) {
960         if (segment == segto)
961             error(ERR_PANIC, "intra-segment OUT_REL4ADR");
962         if (segment != NO_SEG && segment % 2) {
963             error(ERR_NONFATAL, "ELF format does not support"
964                   " segment base references");
965         } else {
966             if (wrt == NO_SEG) {
967                 elf_add_reloc(s, segment, R_X86_64_PC32);
968             } else if (wrt == elf_plt_sect + 1) {
969                 elf_add_reloc(s, segment, R_X86_64_PLT32);
970             } else if (wrt == elf_gotpc_sect + 1 ||
971                        wrt == elf_gotoff_sect + 1 ||
972                        wrt == elf_got_sect + 1) {
973                 error(ERR_NONFATAL, "ELF format cannot produce PC-"
974                       "relative GOT references");
975             } else {
976                 error(ERR_NONFATAL, "ELF format does not support this"
977                       " use of WRT");
978                 wrt = NO_SEG;   /* we can at least _try_ to continue */
979             }
980         }
981         p = mydata;
982         WRITELONG(p, *(int64_t *)data - size);
983         elf_sect_write(s, mydata, 4L);
984     }
985 }
986
987 static void elf_write(void)
988 {
989     int nsections, align;
990     int scount;
991     char *p;
992     int commlen;
993     char comment[64];
994     int i;
995
996     struct SAA *symtab;
997     int32_t symtablen, symtablocal;
998
999     /*
1000      * Work out how many sections we will have. We have SHN_UNDEF,
1001      * then the flexible user sections, then the four fixed
1002      * sections `.comment', `.shstrtab', `.symtab' and `.strtab',
1003      * then optionally relocation sections for the user sections.
1004      */
1005     if (of_elf64.current_dfmt == &df_stabs)
1006         nsections = 8;
1007     else
1008         nsections = 5;          /* SHN_UNDEF and the fixed ones */
1009
1010     add_sectname("", ".comment");
1011     add_sectname("", ".shstrtab");
1012     add_sectname("", ".symtab");
1013     add_sectname("", ".strtab");
1014     for (i = 0; i < nsects; i++) {
1015         nsections++;            /* for the section itself */
1016         if (sects[i]->head) {
1017             nsections++;        /* for its relocations without addends*/
1018             add_sectname(".rela", sects[i]->name);
1019         }
1020     }
1021
1022     if (of_elf64.current_dfmt == &df_stabs) {
1023         /* in case the debug information is wanted, just add these three sections... */
1024         add_sectname("", ".stab");
1025         add_sectname("", ".stabstr");
1026         add_sectname(".rel", ".stab");
1027     }
1028
1029     /*
1030      * Do the comment.
1031      */
1032     *comment = '\0';
1033     commlen =
1034         2 + sprintf(comment + 1, "The Netwide Assembler %s", NASM_VER);
1035
1036     /*
1037      * Output the ELF header.
1038      */
1039     fwrite("\177ELF\2\1\1", 7, 1, elffp);
1040     fputc(elf_osabi, elffp);
1041     fputc(elf_abiver, elffp);
1042     fwrite("\0\0\0\0\0\0\0", 7, 1, elffp);
1043     fwriteint16_t(ET_REL, elffp);      /* relocatable file */
1044     fwriteint16_t(EM_X86_64, elffp);      /* processor ID */
1045     fwriteint32_t(1L, elffp);      /* EV_CURRENT file format version */
1046     fwriteint64_t(0L, elffp);      /* no entry point */
1047     fwriteint64_t(0L, elffp);      /* no program header table */
1048     fwriteint64_t(0x40L, elffp);   /* section headers straight after
1049                                  * ELF header plus alignment */
1050     fwriteint32_t(0L, elffp);      /* 386 defines no special flags */
1051     fwriteint16_t(0x40, elffp);   /* size of ELF header */
1052     fwriteint16_t(0, elffp);      /* no program header table, again */
1053     fwriteint16_t(0, elffp);      /* still no program header table */
1054     fwriteint16_t(sizeof(Elf64_Shdr), elffp);   /* size of section header */
1055     fwriteint16_t(nsections, elffp);      /* number of sections */
1056     fwriteint16_t(nsects + 2, elffp);     /* string table section index for
1057                                          * section header table */
1058
1059     /*
1060      * Build the symbol table and relocation tables.
1061      */
1062     symtab = elf_build_symtab(&symtablen, &symtablocal);
1063     for (i = 0; i < nsects; i++)
1064         if (sects[i]->head)
1065             sects[i]->rel = elf_build_reltab(&sects[i]->rellen,
1066                                              sects[i]->head);
1067
1068     /*
1069      * Now output the section header table.
1070      */
1071
1072     elf_foffs = 0x40 + sizeof(Elf64_Shdr) * nsections;
1073     align = ((elf_foffs + SEG_ALIGN_1) & ~SEG_ALIGN_1) - elf_foffs;
1074     elf_foffs += align;
1075     elf_nsect = 0;
1076     elf_sects = nasm_malloc(sizeof(*elf_sects) * (2 * nsects + 10));
1077
1078     elf_section_header(0, 0, 0, NULL, false, 0L, 0, 0, 0, 0);   /* SHN_UNDEF */
1079     scount = 1;                 /* needed for the stabs debugging to track the symtable section */
1080     p = shstrtab + 1;
1081     for (i = 0; i < nsects; i++) {
1082         elf_section_header(p - shstrtab, sects[i]->type, sects[i]->flags,
1083                            (sects[i]->type == SHT_PROGBITS ?
1084                             sects[i]->data : NULL), true,
1085                            sects[i]->len, 0, 0, sects[i]->align, 0);
1086         p += strlen(p) + 1;
1087         scount++;               /* dito */
1088     }
1089     elf_section_header(p - shstrtab, 1, 0, comment, false, (int32_t)commlen, 0, 0, 1, 0);  /* .comment */
1090     scount++;                   /* dito */
1091     p += strlen(p) + 1;
1092     elf_section_header(p - shstrtab, 3, 0, shstrtab, false, (int32_t)shstrtablen, 0, 0, 1, 0);     /* .shstrtab */
1093     scount++;                   /* dito */
1094     p += strlen(p) + 1;
1095     elf_section_header(p - shstrtab, 2, 0, symtab, true, symtablen, nsects + 4, symtablocal, 4, 24);    /* .symtab */
1096     symtabsection = scount;     /* now we got the symtab section index in the ELF file */
1097     p += strlen(p) + 1;
1098     elf_section_header(p - shstrtab, 3, 0, strs, true, strslen, 0, 0, 1, 0);    /* .strtab */
1099     for (i = 0; i < nsects; i++)
1100         if (sects[i]->head) {
1101             p += strlen(p) + 1;
1102             elf_section_header(p - shstrtab,SHT_RELA, 0, sects[i]->rel, true,
1103                                sects[i]->rellen, nsects + 3, i + 1, 4, 24);
1104         }
1105     if (of_elf64.current_dfmt == &df_stabs) {
1106         /* for debugging information, create the last three sections
1107            which are the .stab , .stabstr and .rel.stab sections respectively */
1108
1109         /* this function call creates the stab sections in memory */
1110         stabs64_generate();
1111
1112         if ((stabbuf) && (stabstrbuf) && (stabrelbuf)) {
1113             p += strlen(p) + 1;
1114             elf_section_header(p - shstrtab, 1, 0, stabbuf, false, stablen,
1115                                nsections - 2, 0, 4, 12);
1116
1117             p += strlen(p) + 1;
1118             elf_section_header(p - shstrtab, 3, 0, stabstrbuf, false,
1119                                stabstrlen, 0, 0, 4, 0);
1120
1121             p += strlen(p) + 1;
1122             /* link -> symtable  info -> section to refer to */
1123             elf_section_header(p - shstrtab, 9, 0, stabrelbuf, false,
1124                                stabrellen, symtabsection, nsections - 3, 4,
1125                                16);
1126         }
1127     }
1128     fwrite(align_str, align, 1, elffp);
1129
1130     /*
1131      * Now output the sections.
1132      */
1133     elf_write_sections();
1134
1135     nasm_free(elf_sects);
1136     saa_free(symtab);
1137 }
1138
1139 static struct SAA *elf_build_symtab(int32_t *len, int32_t *local)
1140 {
1141     struct SAA *s = saa_init(1L);
1142     struct Symbol *sym;
1143     uint8_t entry[24], *p;
1144     int i;
1145
1146     *len = *local = 0;
1147
1148     /*
1149      * First, an all-zeros entry, required by the ELF spec.
1150      */
1151     saa_wbytes(s, NULL, 24L);   /* null symbol table entry */
1152     *len += 24;
1153     (*local)++;
1154
1155     /*
1156      * Next, an entry for the file name.
1157      */
1158     p = entry;
1159     WRITELONG(p, 1);            /* we know it's 1st entry in strtab */
1160     WRITESHORT(p, STT_FILE);    /* type FILE */
1161     WRITESHORT(p, SHN_ABS);
1162     WRITEDLONG(p, (uint64_t) 0);  /* no value */
1163     WRITEDLONG(p, (uint64_t) 0);  /* no size either */
1164     saa_wbytes(s, entry, 24L);
1165     *len += 24;
1166     (*local)++;
1167
1168     /*
1169      * Now some standard symbols defining the segments, for relocation
1170      * purposes.
1171      */
1172     for (i = 1; i <= nsects; i++) {
1173         p = entry;
1174         WRITELONG(p, 0);        /* no symbol name */
1175         WRITESHORT(p, STT_SECTION);       /* type, binding, and visibility */
1176         WRITESHORT(p, i);       /* section id */
1177         WRITEDLONG(p, (uint64_t) 0);        /* offset zero */
1178         WRITEDLONG(p, (uint64_t) 0);        /* size zero */
1179         saa_wbytes(s, entry, 24L);
1180         *len += 24;
1181         (*local)++;
1182     }
1183
1184     /*
1185      * Now the other local symbols.
1186      */
1187     saa_rewind(syms);
1188     while ((sym = saa_rstruct(syms))) {
1189         if (sym->type & SYM_GLOBAL)
1190             continue;
1191         p = entry;
1192         WRITELONG(p, sym->strpos);
1193         WRITECHAR(p, sym->type);        /* type and binding */
1194         WRITECHAR(p, sym->other);       /* visibility */
1195         WRITESHORT(p, sym->section);
1196         WRITEDLONG(p, (int64_t)sym->value);
1197         WRITEDLONG(p, (int64_t)sym->size);
1198         saa_wbytes(s, entry, 24L);
1199         *len += 24;
1200         (*local)++;
1201     }
1202
1203     /*
1204      * Now the global symbols.
1205      */
1206     saa_rewind(syms);
1207     while ((sym = saa_rstruct(syms))) {
1208         if (!(sym->type & SYM_GLOBAL))
1209             continue;
1210         p = entry;
1211         WRITELONG(p, sym->strpos);
1212         WRITECHAR(p, sym->type);        /* type and binding */
1213         WRITECHAR(p, sym->other);       /* visibility */
1214         WRITESHORT(p, sym->section);
1215         WRITEDLONG(p, (int64_t)sym->value);
1216         WRITEDLONG(p, (int64_t)sym->size);
1217         saa_wbytes(s, entry, 24L);
1218         *len += 24;
1219     }
1220
1221     return s;
1222 }
1223
1224 static struct SAA *elf_build_reltab(uint64_t *len, struct Reloc *r)
1225 {
1226     struct SAA *s;
1227     uint8_t *p, entry[24];
1228
1229     if (!r)
1230         return NULL;
1231
1232     s = saa_init(1L);
1233     *len = 0;
1234
1235     while (r) {
1236         int64_t sym = r->symbol;
1237
1238         if (sym >= GLOBAL_TEMP_BASE)
1239             sym += -GLOBAL_TEMP_BASE + (nsects + 2) + nlocals;
1240
1241         p = entry;
1242         WRITEDLONG(p, r->address);
1243         WRITEDLONG(p, (sym << 32) + r->type);
1244         WRITEDLONG(p, (uint64_t) 0);
1245         saa_wbytes(s, entry, 24L);
1246         *len += 24;
1247
1248         r = r->next;
1249     }
1250
1251     return s;
1252 }
1253
1254 static void elf_section_header(int name, int type, uint64_t flags,
1255                                void *data, bool is_saa, uint64_t datalen,
1256                                int link, int info, int align, int eltsize)
1257 {
1258     elf_sects[elf_nsect].data = data;
1259     elf_sects[elf_nsect].len = datalen;
1260     elf_sects[elf_nsect].is_saa = is_saa;
1261     elf_nsect++;
1262
1263     fwriteint32_t((int32_t)name, elffp);
1264     fwriteint32_t((int32_t)type, elffp);
1265     fwriteint64_t((int64_t)flags, elffp);
1266     fwriteint64_t(0L, elffp);      /* no address, ever, in object files */
1267     fwriteint64_t(type == 0 ? 0L : elf_foffs, elffp);
1268     fwriteint64_t(datalen, elffp);
1269     if (data)
1270         elf_foffs += (datalen + SEG_ALIGN_1) & ~SEG_ALIGN_1;
1271     fwriteint32_t((int32_t)link, elffp);
1272     fwriteint32_t((int32_t)info, elffp);
1273     fwriteint64_t((int64_t)align, elffp);
1274     fwriteint64_t((int64_t)eltsize, elffp);
1275 }
1276
1277 static void elf_write_sections(void)
1278 {
1279     int i;
1280     for (i = 0; i < elf_nsect; i++)
1281         if (elf_sects[i].data) {
1282             int32_t len = elf_sects[i].len;
1283             int32_t reallen = (len + SEG_ALIGN_1) & ~SEG_ALIGN_1;
1284             int32_t align = reallen - len;
1285             if (elf_sects[i].is_saa)
1286                 saa_fpwrite(elf_sects[i].data, elffp);
1287             else
1288                 fwrite(elf_sects[i].data, len, 1, elffp);
1289             fwrite(align_str, align, 1, elffp);
1290         }
1291 }
1292
1293 static void elf_sect_write(struct Section *sect,
1294                            const uint8_t *data, uint64_t len)
1295 {
1296     saa_wbytes(sect->data, data, len);
1297     sect->len += len;
1298 }
1299
1300 static int32_t elf_segbase(int32_t segment)
1301 {
1302     return segment;
1303 }
1304
1305 static int elf_directive(char *directive, char *value, int pass)
1306 {
1307     bool err;
1308     int64_t n;
1309     char *p;
1310
1311     if (!strcmp(directive, "osabi")) {
1312         if (pass == 2)
1313             return 1;           /* ignore in pass 2 */
1314
1315         n = readnum(value, &err);
1316         if (err) {
1317             error(ERR_NONFATAL, "`osabi' directive requires a parameter");
1318             return 1;
1319         }
1320         if (n < 0 || n > 255) {
1321             error(ERR_NONFATAL, "valid osabi numbers are 0 to 255");
1322             return 1;
1323         }
1324         elf_osabi  = n;
1325         elf_abiver = 0;
1326
1327         if ((p = strchr(value,',')) == NULL)
1328             return 1;
1329
1330         n = readnum(p+1, &err);
1331         if (err || n < 0 || n > 255) {
1332             error(ERR_NONFATAL, "invalid ABI version number (valid: 0 to 255)");
1333             return 1;
1334         }
1335         
1336         elf_abiver = n;
1337         return 1;
1338     }
1339         
1340     return 0;
1341 }
1342
1343 static void elf_filename(char *inname, char *outname, efunc error)
1344 {
1345     strcpy(elf_module, inname);
1346     standard_extension(inname, outname, ".o", error);
1347 }
1348
1349 static const char *elf_stdmac[] = {
1350     "%define __SECT__ [section .text]",
1351     "%macro __NASM_CDecl__ 1",
1352     "%define $_%1 $%1",
1353     "%endmacro",
1354     "%macro osabi 1+.nolist",
1355     "[osabi %1]",
1356     "%endmacro",
1357     NULL
1358 };
1359 static int elf_set_info(enum geninfo type, char **val)
1360 {
1361     (void)type;
1362     (void)val;
1363     return 0;
1364 }
1365
1366 static struct dfmt df_stabs = {
1367     "ELF64 (X86_64) stabs debug format for Linux",
1368     "stabs",
1369     stabs64_init,
1370     stabs64_linenum,
1371     stabs64_deflabel,
1372     stabs64_directive,
1373     stabs64_typevalue,
1374     stabs64_output,
1375     stabs64_cleanup
1376 };
1377
1378 struct dfmt *elf64_debugs_arr[2] = { &df_stabs, NULL };
1379
1380 struct ofmt of_elf64 = {
1381     "ELF64 (x86_64) object files (e.g. Linux)",
1382     "elf64",
1383     NULL,
1384     elf64_debugs_arr,
1385     &null_debug_form,
1386     elf_stdmac,
1387     elf_init,
1388     elf_set_info,
1389     elf_out,
1390     elf_deflabel,
1391     elf_section_names,
1392     elf_segbase,
1393     elf_directive,
1394     elf_filename,
1395     elf_cleanup
1396 };
1397
1398 /* again, the stabs debugging stuff (code) */
1399
1400 void stabs64_init(struct ofmt *of, void *id, FILE * fp, efunc error)
1401 {
1402     (void)of;
1403     (void)id;
1404     (void)fp;
1405     (void)error;
1406 }
1407
1408 void stabs64_linenum(const char *filename, int32_t linenumber, int32_t segto)
1409 {
1410     (void)segto;
1411
1412     if (!stabs_filename) {
1413         stabs_filename = (char *)nasm_malloc(strlen(filename) + 1);
1414         strcpy(stabs_filename, filename);
1415     } else {
1416         if (strcmp(stabs_filename, filename)) {
1417             /* yep, a memory leak...this program is one-shot anyway, so who cares...
1418                in fact, this leak comes in quite handy to maintain a list of files
1419                encountered so far in the symbol lines... */
1420
1421             /* why not nasm_free(stabs_filename); we're done with the old one */
1422
1423             stabs_filename = (char *)nasm_malloc(strlen(filename) + 1);
1424             strcpy(stabs_filename, filename);
1425         }
1426     }
1427     stabs_immcall = 1;
1428     currentline = linenumber;
1429 }
1430
1431 void stabs64_deflabel(char *name, int32_t segment, int64_t offset, int is_global,
1432                     char *special)
1433 {
1434     (void)name;
1435     (void)segment;
1436     (void)offset;
1437     (void)is_global;
1438     (void)special;
1439 }
1440
1441 void stabs64_directive(const char *directive, const char *params)
1442 {
1443     (void)directive;
1444     (void)params;
1445 }
1446
1447 void stabs64_typevalue(int32_t type)
1448 {
1449     int32_t stype, ssize;
1450     switch (TYM_TYPE(type)) {
1451         case TY_LABEL:
1452             ssize = 0;
1453             stype = STT_NOTYPE;
1454             break;
1455         case TY_BYTE:
1456             ssize = 1;
1457             stype = STT_OBJECT;
1458             break;
1459         case TY_WORD:
1460             ssize = 2;
1461             stype = STT_OBJECT;
1462             break;
1463         case TY_DWORD:
1464             ssize = 4;
1465             stype = STT_OBJECT;
1466             break;
1467         case TY_FLOAT:
1468             ssize = 4;
1469             stype = STT_OBJECT;
1470             break;
1471         case TY_QWORD:
1472             ssize = 8;
1473             stype = STT_OBJECT;
1474             break;
1475         case TY_TBYTE:
1476             ssize = 10;
1477             stype = STT_OBJECT;
1478             break;
1479         case TY_OWORD:
1480             ssize = 16;
1481             stype = STT_OBJECT;
1482             break;
1483         case TY_COMMON:
1484             ssize = 0;
1485             stype = STT_COMMON;
1486             break;
1487         case TY_SEG:
1488             ssize = 0;
1489             stype = STT_SECTION;
1490             break;
1491         case TY_EXTERN:
1492             ssize = 0;
1493             stype = STT_NOTYPE;
1494             break;
1495         case TY_EQU:
1496             ssize = 0;
1497             stype = STT_NOTYPE;
1498             break;
1499         default:
1500             ssize = 0;
1501             stype = STT_NOTYPE;
1502             break;
1503     }
1504     if (stype == STT_OBJECT && !lastsym->type) {
1505         lastsym->size = ssize;
1506         lastsym->type = stype;
1507     }
1508 }
1509
1510 void stabs64_output(int type, void *param)
1511 {
1512     struct symlininfo *s;
1513     struct linelist *el;
1514     if (type == TY_STABSSYMLIN) {
1515         if (stabs_immcall) {
1516             s = (struct symlininfo *)param;
1517             if (!(sects[s->section]->flags & SHF_EXECINSTR))
1518                 return;         /* we are only interested in the text stuff */
1519             numlinestabs++;
1520             el = (struct linelist *)nasm_malloc(sizeof(struct linelist));
1521             el->info.offset = s->offset;
1522             el->info.section = s->section;
1523             el->info.name = s->name;
1524             el->line = currentline;
1525             el->filename = stabs_filename;
1526             el->next = 0;
1527             if (stabslines) {
1528                 stabslines->last->next = el;
1529                 stabslines->last = el;
1530             } else {
1531                 stabslines = el;
1532                 stabslines->last = el;
1533             }
1534         }
1535     }
1536     stabs_immcall = 0;
1537 }
1538
1539 #define WRITE_STAB(p,n_strx,n_type,n_other,n_desc,n_value) \
1540   do {\
1541     WRITELONG(p,n_strx); \
1542     WRITECHAR(p,n_type); \
1543     WRITECHAR(p,n_other); \
1544     WRITESHORT(p,n_desc); \
1545     WRITELONG(p,n_value); \
1546   } while (0)
1547
1548 /* for creating the .stab , .stabstr and .rel.stab sections in memory */
1549
1550 void stabs64_generate(void)
1551 {
1552     int i, numfiles, strsize, numstabs = 0, currfile, mainfileindex;
1553     uint8_t *sbuf, *ssbuf, *rbuf, *sptr, *rptr;
1554     char **allfiles;
1555     int *fileidx;
1556
1557     struct linelist *ptr;
1558
1559     ptr = stabslines;
1560
1561     allfiles = (char **)nasm_malloc(numlinestabs * sizeof(int8_t *));
1562     for (i = 0; i < numlinestabs; i++)
1563         allfiles[i] = 0;
1564     numfiles = 0;
1565     while (ptr) {
1566         if (numfiles == 0) {
1567             allfiles[0] = ptr->filename;
1568             numfiles++;
1569         } else {
1570             for (i = 0; i < numfiles; i++) {
1571                 if (!strcmp(allfiles[i], ptr->filename))
1572                     break;
1573             }
1574             if (i >= numfiles) {
1575                 allfiles[i] = ptr->filename;
1576                 numfiles++;
1577             }
1578         }
1579         ptr = ptr->next;
1580     }
1581     strsize = 1;
1582     fileidx = (int *)nasm_malloc(numfiles * sizeof(int));
1583     for (i = 0; i < numfiles; i++) {
1584         fileidx[i] = strsize;
1585         strsize += strlen(allfiles[i]) + 1;
1586     }
1587     mainfileindex = 0;
1588     for (i = 0; i < numfiles; i++) {
1589         if (!strcmp(allfiles[i], elf_module)) {
1590             mainfileindex = i;
1591             break;
1592         }
1593     }
1594
1595     /* worst case size of the stab buffer would be:
1596        the sourcefiles changes each line, which would mean 1 SOL, 1 SYMLIN per line
1597      */
1598     sbuf =
1599         (uint8_t *)nasm_malloc((numlinestabs * 2 + 3) *
1600                                      sizeof(struct stabentry));
1601
1602     ssbuf = (uint8_t *)nasm_malloc(strsize);
1603
1604     rbuf = (uint8_t *)nasm_malloc(numlinestabs * 16 * (2 + 3));
1605     rptr = rbuf;
1606
1607     for (i = 0; i < numfiles; i++) {
1608         strcpy((char *)ssbuf + fileidx[i], allfiles[i]);
1609     }
1610     ssbuf[0] = 0;
1611
1612     stabstrlen = strsize;       /* set global variable for length of stab strings */
1613
1614     sptr = sbuf;
1615     ptr = stabslines;
1616     numstabs = 0;
1617
1618     if (ptr) {
1619         /* this is the first stab, its strx points to the filename of the
1620         the source-file, the n_desc field should be set to the number
1621         of remaining stabs
1622         */
1623         WRITE_STAB(sptr, fileidx[0], 0, 0, 0, strlen(allfiles[0] + 12));
1624
1625         /* this is the stab for the main source file */
1626         WRITE_STAB(sptr, fileidx[mainfileindex], N_SO, 0, 0, 0);
1627
1628         /* relocation table entry */
1629
1630         /* Since the symbol table has two entries before */
1631         /* the section symbols, the index in the info.section */
1632         /* member must be adjusted by adding 2 */
1633
1634         WRITEDLONG(rptr, (int64_t)(sptr - sbuf) - 4);
1635         WRITELONG(rptr, R_X86_64_32);
1636         WRITELONG(rptr, ptr->info.section + 2);
1637
1638         numstabs++;
1639         currfile = mainfileindex;
1640     }
1641
1642     while (ptr) {
1643         if (strcmp(allfiles[currfile], ptr->filename)) {
1644             /* oops file has changed... */
1645             for (i = 0; i < numfiles; i++)
1646                 if (!strcmp(allfiles[i], ptr->filename))
1647                     break;
1648             currfile = i;
1649             WRITE_STAB(sptr, fileidx[currfile], N_SOL, 0, 0,
1650                        ptr->info.offset);
1651             numstabs++;
1652
1653             /* relocation table entry */
1654
1655             WRITEDLONG(rptr, (int64_t)(sptr - sbuf) - 4);
1656             WRITELONG(rptr, R_X86_64_32);
1657             WRITELONG(rptr, ptr->info.section + 2);
1658         }
1659
1660         WRITE_STAB(sptr, 0, N_SLINE, 0, ptr->line, ptr->info.offset);
1661         numstabs++;
1662
1663         /* relocation table entry */
1664
1665         WRITEDLONG(rptr, (int64_t)(sptr - sbuf) - 4);
1666         WRITELONG(rptr, R_X86_64_32);
1667         WRITELONG(rptr, ptr->info.section + 2);
1668
1669         ptr = ptr->next;
1670
1671     }
1672
1673     ((struct stabentry *)sbuf)->n_desc = numstabs;
1674
1675     nasm_free(allfiles);
1676     nasm_free(fileidx);
1677
1678     stablen = (sptr - sbuf);
1679     stabrellen = (rptr - rbuf);
1680     stabrelbuf = rbuf;
1681     stabbuf = sbuf;
1682     stabstrbuf = ssbuf;
1683 }
1684
1685 void stabs64_cleanup(void)
1686 {
1687     struct linelist *ptr, *del;
1688     if (!stabslines)
1689         return;
1690     ptr = stabslines;
1691     while (ptr) {
1692         del = ptr;
1693         ptr = ptr->next;
1694         nasm_free(del);
1695     }
1696     if (stabbuf)
1697         nasm_free(stabbuf);
1698     if (stabrelbuf)
1699         nasm_free(stabrelbuf);
1700     if (stabstrbuf)
1701         nasm_free(stabstrbuf);
1702 }
1703
1704 #endif                          /* OF_ELF */