out: Elf32 -- Unify dwarf_ nums
[nasm.git] / output / outelf64.c
blob93696b16e5a1a31d34e8f2ae6eb5f65107b5064d
1 /* ----------------------------------------------------------------------- *
3 * Copyright 1996-2016 The NASM Authors - All Rights Reserved
4 * See the file AUTHORS included with the NASM distribution for
5 * the specific copyright holders.
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following
9 * conditions are met:
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.
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.
32 * ----------------------------------------------------------------------- */
35 * outelf64.c output routines for the Netwide Assembler to produce
36 * ELF64 (x86_64 of course) object file format
39 #include "compiler.h"
41 #include <stdio.h>
42 #include <stdlib.h>
43 #include <string.h>
44 #include <ctype.h>
46 #include "nasm.h"
47 #include "nasmlib.h"
48 #include "saa.h"
49 #include "raa.h"
50 #include "stdscan.h"
51 #include "eval.h"
52 #include "output/outform.h"
53 #include "output/outlib.h"
54 #include "rbtree.h"
55 #include "ver.h"
57 #include "output/dwarf.h"
58 #include "output/stabs.h"
59 #include "output/outelf.h"
61 #ifdef OF_ELF64
63 #define SECT_DELTA 32
64 static struct elf_section **sects;
65 static int nsects, sectlen;
67 #define SHSTR_DELTA 256
68 static char *shstrtab;
69 static int shstrtablen, shstrtabsize;
71 static struct SAA *syms;
72 static uint32_t nlocals, nglobs, ndebugs; /* Symbol counts */
74 static int32_t def_seg;
76 static struct RAA *bsym;
78 static struct SAA *strs;
79 static uint32_t strslen;
81 static struct elf_symbol *fwds;
83 static char elf_module[FILENAME_MAX];
85 extern const struct ofmt of_elf64;
87 static struct ELF_SECTDATA {
88 void *data;
89 int64_t len;
90 bool is_saa;
91 } *elf_sects;
92 static int elf_nsect, nsections;
93 static int64_t elf_foffs;
95 static void elf_write(void);
96 static void elf_sect_write(struct elf_section *, const void *, size_t);
97 static void elf_sect_writeaddr(struct elf_section *, int64_t, size_t);
98 static void elf_section_header(int, int, uint64_t, void *, bool, uint64_t, int, int,
99 int, int);
100 static void elf_write_sections(void);
101 static struct SAA *elf_build_symtab(int32_t *, int32_t *);
102 static struct SAA *elf_build_reltab(uint64_t *, struct elf_reloc *);
103 static void add_sectname(char *, char *);
105 struct erel {
106 int offset, info;
109 struct symlininfo {
110 int offset;
111 int section; /* index into sects[] */
112 int segto; /* internal section number */
113 char *name; /* shallow-copied pointer of section name */
116 struct linelist {
117 struct linelist *next;
118 struct linelist *last;
119 struct symlininfo info;
120 char *filename;
121 int line;
124 struct sectlist {
125 struct SAA *psaa;
126 int section;
127 int line;
128 int offset;
129 int file;
130 struct sectlist *next;
131 struct sectlist *last;
134 /* common debug variables */
135 static int currentline = 1;
136 static int debug_immcall = 0;
138 /* stabs debug variables */
139 static struct linelist *stabslines = 0;
140 static int numlinestabs = 0;
141 static char *stabs_filename = 0;
142 static uint8_t *stabbuf = 0, *stabstrbuf = 0, *stabrelbuf = 0;
143 static int stablen, stabstrlen, stabrellen;
145 /* dwarf debug variables */
146 static struct linelist *dwarf_flist = 0, *dwarf_clist = 0, *dwarf_elist = 0;
147 static struct sectlist *dwarf_fsect = 0, *dwarf_csect = 0, *dwarf_esect = 0;
148 static int dwarf_numfiles = 0, dwarf_nsections;
149 static uint8_t *arangesbuf = 0, *arangesrelbuf = 0, *pubnamesbuf = 0, *infobuf = 0, *inforelbuf = 0,
150 *abbrevbuf = 0, *linebuf = 0, *linerelbuf = 0, *framebuf = 0, *locbuf = 0;
151 static int8_t line_base = -5, line_range = 14, opcode_base = 13;
152 static int arangeslen, arangesrellen, pubnameslen, infolen, inforellen,
153 abbrevlen, linelen, linerellen, framelen, loclen;
154 static int64_t dwarf_infosym, dwarf_abbrevsym, dwarf_linesym;
156 static const struct dfmt df_dwarf;
157 static const struct dfmt df_stabs;
158 static struct elf_symbol *lastsym;
160 /* common debugging routines */
161 static void debug_typevalue(int32_t);
163 /* stabs debugging routines */
164 static void stabs_linenum(const char *filename, int32_t linenumber, int32_t);
165 static void stabs_output(int, void *);
166 static void stabs_generate(void);
167 static void stabs_cleanup(void);
169 /* dwarf debugging routines */
170 static void dwarf_init(void);
171 static void dwarf_linenum(const char *filename, int32_t linenumber, int32_t);
172 static void dwarf_output(int, void *);
173 static void dwarf_generate(void);
174 static void dwarf_cleanup(void);
175 static void dwarf_findfile(const char *);
176 static void dwarf_findsect(const int);
179 * Special NASM section numbers which are used to define ELF special
180 * symbols.
182 static int32_t elf_gotpc_sect, elf_gotoff_sect;
183 static int32_t elf_got_sect, elf_plt_sect;
184 static int32_t elf_sym_sect, elf_gottpoff_sect, elf_tlsie_sect;
186 static void elf_init(void)
188 sects = NULL;
189 nsects = sectlen = 0;
190 syms = saa_init((int32_t)sizeof(struct elf_symbol));
191 nlocals = nglobs = ndebugs = 0;
192 bsym = raa_init();
193 strs = saa_init(1L);
194 saa_wbytes(strs, "\0", 1L);
195 saa_wbytes(strs, elf_module, strlen(elf_module)+1);
196 strslen = 2 + strlen(elf_module);
197 shstrtab = NULL;
198 shstrtablen = shstrtabsize = 0;;
199 add_sectname("", "");
201 fwds = NULL;
203 elf_gotpc_sect = seg_alloc();
204 define_label("..gotpc", elf_gotpc_sect + 1, 0L, NULL, false, false);
205 elf_gotoff_sect = seg_alloc();
206 define_label("..gotoff", elf_gotoff_sect + 1, 0L, NULL, false, false);
207 elf_got_sect = seg_alloc();
208 define_label("..got", elf_got_sect + 1, 0L, NULL, false, false);
209 elf_plt_sect = seg_alloc();
210 define_label("..plt", elf_plt_sect + 1, 0L, NULL, false, false);
211 elf_sym_sect = seg_alloc();
212 define_label("..sym", elf_sym_sect + 1, 0L, NULL, false, false);
213 elf_gottpoff_sect = seg_alloc();
214 define_label("..gottpoff", elf_gottpoff_sect + 1, 0L, NULL, false, false);
216 def_seg = seg_alloc();
219 static void elf_cleanup(void)
221 struct elf_reloc *r;
222 int i;
224 elf_write();
225 for (i = 0; i < nsects; i++) {
226 if (sects[i]->type != SHT_NOBITS)
227 saa_free(sects[i]->data);
228 if (sects[i]->head)
229 saa_free(sects[i]->rel);
230 while (sects[i]->head) {
231 r = sects[i]->head;
232 sects[i]->head = sects[i]->head->next;
233 nasm_free(r);
236 nasm_free(sects);
237 saa_free(syms);
238 raa_free(bsym);
239 saa_free(strs);
240 dfmt->cleanup();
243 /* add entry to the elf .shstrtab section */
244 static void add_sectname(char *firsthalf, char *secondhalf)
246 int len = strlen(firsthalf) + strlen(secondhalf);
247 while (shstrtablen + len + 1 > shstrtabsize)
248 shstrtab = nasm_realloc(shstrtab, (shstrtabsize += SHSTR_DELTA));
249 strcpy(shstrtab + shstrtablen, firsthalf);
250 strcat(shstrtab + shstrtablen, secondhalf);
251 shstrtablen += len + 1;
254 static int elf_make_section(char *name, int type, int flags, int align)
256 struct elf_section *s;
258 s = nasm_zalloc(sizeof(*s));
260 if (type != SHT_NOBITS)
261 s->data = saa_init(1L);
262 s->tail = &s->head;
263 if (!strcmp(name, ".text"))
264 s->index = def_seg;
265 else
266 s->index = seg_alloc();
267 add_sectname("", name);
269 s->name = nasm_strdup(name);
270 s->type = type;
271 s->flags = flags;
272 s->align = align;
274 if (nsects >= sectlen)
275 sects = nasm_realloc(sects, (sectlen += SECT_DELTA) * sizeof(*sects));
276 sects[nsects++] = s;
278 return nsects - 1;
281 static int32_t elf_section_names(char *name, int pass, int *bits)
283 char *p;
284 uint32_t flags, flags_and, flags_or;
285 uint64_t align;
286 int type, i;
288 if (!name) {
289 *bits = ofmt->maxbits;
290 return def_seg;
293 p = nasm_skip_word(name);
294 if (*p)
295 *p++ = '\0';
296 flags_and = flags_or = type = align = 0;
298 elf_section_attrib(name, p, pass, &flags_and,
299 &flags_or, &align, &type);
301 if (!strcmp(name, ".shstrtab") ||
302 !strcmp(name, ".symtab") ||
303 !strcmp(name, ".strtab")) {
304 nasm_error(ERR_NONFATAL, "attempt to redefine reserved section"
305 "name `%s'", name);
306 return NO_SEG;
309 for (i = 0; i < nsects; i++)
310 if (!strcmp(name, sects[i]->name))
311 break;
312 if (i == nsects) {
313 const struct elf_known_section *ks = elf_known_sections;
315 while (ks->name) {
316 if (!strcmp(name, ks->name))
317 break;
318 ks++;
321 type = type ? type : ks->type;
322 align = align ? align : ks->align;
323 flags = (ks->flags & ~flags_and) | flags_or;
325 i = elf_make_section(name, type, flags, align);
326 } else if (pass == 1) {
327 if ((type && sects[i]->type != type)
328 || (align && sects[i]->align != align)
329 || (flags_and && ((sects[i]->flags & flags_and) != flags_or)))
330 nasm_error(ERR_WARNING, "incompatible section attributes ignored on"
331 " redeclaration of section `%s'", name);
334 return sects[i]->index;
337 static void elf_deflabel(char *name, int32_t segment, int64_t offset,
338 int is_global, char *special)
340 int pos = strslen;
341 struct elf_symbol *sym;
342 bool special_used = false;
344 #if defined(DEBUG) && DEBUG>2
345 nasm_error(ERR_DEBUG,
346 " elf_deflabel: %s, seg=%"PRIx32", off=%"PRIx64", is_global=%d, %s\n",
347 name, segment, offset, is_global, special);
348 #endif
349 if (name[0] == '.' && name[1] == '.' && name[2] != '@') {
351 * This is a NASM special symbol. We never allow it into
352 * the ELF symbol table, even if it's a valid one. If it
353 * _isn't_ a valid one, we should barf immediately.
355 if (strcmp(name, "..gotpc") && strcmp(name, "..gotoff") &&
356 strcmp(name, "..got") && strcmp(name, "..plt") &&
357 strcmp(name, "..sym") && strcmp(name, "..gottpoff"))
358 nasm_error(ERR_NONFATAL, "unrecognised special symbol `%s'", name);
359 return;
362 if (is_global == 3) {
363 struct elf_symbol **s;
365 * Fix up a forward-reference symbol size from the first
366 * pass.
368 for (s = &fwds; *s; s = &(*s)->nextfwd)
369 if (!strcmp((*s)->name, name)) {
370 struct tokenval tokval;
371 expr *e;
372 char *p = nasm_skip_spaces(nasm_skip_word(special));
374 stdscan_reset();
375 stdscan_set(p);
376 tokval.t_type = TOKEN_INVALID;
377 e = evaluate(stdscan, NULL, &tokval, NULL, 1, NULL);
378 if (e) {
379 if (!is_simple(e))
380 nasm_error(ERR_NONFATAL, "cannot use relocatable"
381 " expression as symbol size");
382 else
383 (*s)->size = reloc_value(e);
387 * Remove it from the list of unresolved sizes.
389 nasm_free((*s)->name);
390 *s = (*s)->nextfwd;
391 return;
393 return; /* it wasn't an important one */
396 saa_wbytes(strs, name, (int32_t)(1 + strlen(name)));
397 strslen += 1 + strlen(name);
399 lastsym = sym = saa_wstruct(syms);
401 memset(&sym->symv, 0, sizeof(struct rbtree));
403 sym->strpos = pos;
404 sym->type = is_global ? SYM_GLOBAL : SYM_LOCAL;
405 sym->other = STV_DEFAULT;
406 sym->size = 0;
407 if (segment == NO_SEG)
408 sym->section = SHN_ABS;
409 else {
410 int i;
411 sym->section = SHN_UNDEF;
412 if (segment == def_seg) {
413 /* we have to be sure at least text section is there */
414 int tempint;
415 if (segment != elf_section_names(".text", 2, &tempint))
416 nasm_panic(0, "strange segment conditions in ELF driver");
418 for (i = 0; i < nsects; i++) {
419 if (segment == sects[i]->index) {
420 sym->section = i + 1;
421 break;
426 if (is_global == 2) {
427 sym->size = offset;
428 sym->symv.key = 0;
429 sym->section = SHN_COMMON;
431 * We have a common variable. Check the special text to see
432 * if it's a valid number and power of two; if so, store it
433 * as the alignment for the common variable.
435 if (special) {
436 bool err;
437 sym->symv.key = readnum(special, &err);
438 if (err)
439 nasm_error(ERR_NONFATAL, "alignment constraint `%s' is not a"
440 " valid number", special);
441 else if ((sym->symv.key | (sym->symv.key - 1)) != 2 * sym->symv.key - 1)
442 nasm_error(ERR_NONFATAL, "alignment constraint `%s' is not a"
443 " power of two", special);
445 special_used = true;
446 } else
447 sym->symv.key = (sym->section == SHN_UNDEF ? 0 : offset);
449 if (sym->type == SYM_GLOBAL) {
451 * If sym->section == SHN_ABS, then the first line of the
452 * else section would cause a core dump, because its a reference
453 * beyond the end of the section array.
454 * This behaviour is exhibited by this code:
455 * GLOBAL crash_nasm
456 * crash_nasm equ 0
457 * To avoid such a crash, such requests are silently discarded.
458 * This may not be the best solution.
460 if (sym->section == SHN_UNDEF || sym->section == SHN_COMMON) {
461 bsym = raa_write(bsym, segment, nglobs);
462 } else if (sym->section != SHN_ABS) {
464 * This is a global symbol; so we must add it to the rbtree
465 * of global symbols in its section.
467 * In addition, we check the special text for symbol
468 * type and size information.
470 sects[sym->section-1]->gsyms =
471 rb_insert(sects[sym->section-1]->gsyms, &sym->symv);
473 if (special) {
474 int n = strcspn(special, " \t");
476 if (!nasm_strnicmp(special, "function", n))
477 sym->type |= STT_FUNC;
478 else if (!nasm_strnicmp(special, "data", n) ||
479 !nasm_strnicmp(special, "object", n))
480 sym->type |= STT_OBJECT;
481 else if (!nasm_strnicmp(special, "notype", n))
482 sym->type |= STT_NOTYPE;
483 else
484 nasm_error(ERR_NONFATAL, "unrecognised symbol type `%.*s'",
485 n, special);
486 special += n;
488 special = nasm_skip_spaces(special);
489 if (*special) {
490 n = strcspn(special, " \t");
491 if (!nasm_strnicmp(special, "default", n))
492 sym->other = STV_DEFAULT;
493 else if (!nasm_strnicmp(special, "internal", n))
494 sym->other = STV_INTERNAL;
495 else if (!nasm_strnicmp(special, "hidden", n))
496 sym->other = STV_HIDDEN;
497 else if (!nasm_strnicmp(special, "protected", n))
498 sym->other = STV_PROTECTED;
499 else
500 n = 0;
501 special += n;
504 if (*special) {
505 struct tokenval tokval;
506 expr *e;
507 int fwd = 0;
508 char *saveme = stdscan_get();
510 while (special[n] && nasm_isspace(special[n]))
511 n++;
513 * We have a size expression; attempt to
514 * evaluate it.
516 stdscan_reset();
517 stdscan_set(special + n);
518 tokval.t_type = TOKEN_INVALID;
519 e = evaluate(stdscan, NULL, &tokval, &fwd, 0, NULL);
520 if (fwd) {
521 sym->nextfwd = fwds;
522 fwds = sym;
523 sym->name = nasm_strdup(name);
524 } else if (e) {
525 if (!is_simple(e))
526 nasm_error(ERR_NONFATAL, "cannot use relocatable"
527 " expression as symbol size");
528 else
529 sym->size = reloc_value(e);
531 stdscan_set(saveme);
533 special_used = true;
536 * If TLS segment, mark symbol accordingly.
538 if (sects[sym->section - 1]->flags & SHF_TLS) {
539 sym->type &= 0xf0;
540 sym->type |= STT_TLS;
543 sym->globnum = nglobs;
544 nglobs++;
545 } else
546 nlocals++;
548 if (special && !special_used)
549 nasm_error(ERR_NONFATAL, "no special symbol features supported here");
552 static void elf_add_reloc(struct elf_section *sect, int32_t segment,
553 int64_t offset, int type)
555 struct elf_reloc *r;
557 r = *sect->tail = nasm_zalloc(sizeof(struct elf_reloc));
558 sect->tail = &r->next;
560 r->address = sect->len;
561 r->offset = offset;
563 if (segment != NO_SEG) {
564 int i;
565 for (i = 0; i < nsects; i++)
566 if (segment == sects[i]->index)
567 r->symbol = i + 2;
568 if (!r->symbol)
569 r->symbol = GLOBAL_TEMP_BASE + raa_read(bsym, segment);
571 r->type = type;
573 sect->nrelocs++;
577 * This routine deals with ..got and ..sym relocations: the more
578 * complicated kinds. In shared-library writing, some relocations
579 * with respect to global symbols must refer to the precise symbol
580 * rather than referring to an offset from the base of the section
581 * _containing_ the symbol. Such relocations call to this routine,
582 * which searches the symbol list for the symbol in question.
584 * R_X86_64_GOT32 references require the _exact_ symbol address to be
585 * used; R_X86_64_32 references can be at an offset from the symbol.
586 * The boolean argument `exact' tells us this.
588 * Return value is the adjusted value of `addr', having become an
589 * offset from the symbol rather than the section. Should always be
590 * zero when returning from an exact call.
592 * Limitation: if you define two symbols at the same place,
593 * confusion will occur.
595 * Inefficiency: we search, currently, using a linked list which
596 * isn't even necessarily sorted.
598 static void elf_add_gsym_reloc(struct elf_section *sect,
599 int32_t segment, uint64_t offset, int64_t pcrel,
600 int type, bool exact)
602 struct elf_reloc *r;
603 struct elf_section *s;
604 struct elf_symbol *sym;
605 struct rbtree *srb;
606 int i;
609 * First look up the segment/offset pair and find a global
610 * symbol corresponding to it. If it's not one of our segments,
611 * then it must be an external symbol, in which case we're fine
612 * doing a normal elf_add_reloc after first sanity-checking
613 * that the offset from the symbol is zero.
615 s = NULL;
616 for (i = 0; i < nsects; i++)
617 if (segment == sects[i]->index) {
618 s = sects[i];
619 break;
622 if (!s) {
623 if (exact && offset)
624 nasm_error(ERR_NONFATAL, "invalid access to an external symbol");
625 else
626 elf_add_reloc(sect, segment, offset - pcrel, type);
627 return;
630 srb = rb_search(s->gsyms, offset);
631 if (!srb || (exact && srb->key != offset)) {
632 nasm_error(ERR_NONFATAL, "unable to find a suitable global symbol"
633 " for this reference");
634 return;
636 sym = container_of(srb, struct elf_symbol, symv);
638 r = *sect->tail = nasm_malloc(sizeof(struct elf_reloc));
639 sect->tail = &r->next;
640 r->next = NULL;
642 r->address = sect->len;
643 r->offset = offset - pcrel - sym->symv.key;
644 r->symbol = GLOBAL_TEMP_BASE + sym->globnum;
645 r->type = type;
647 sect->nrelocs++;
650 static void elf_out(int32_t segto, const void *data,
651 enum out_type type, uint64_t size,
652 int32_t segment, int32_t wrt)
654 struct elf_section *s;
655 int64_t addr;
656 int reltype, bytes;
657 int i;
658 static struct symlininfo sinfo;
660 #if defined(DEBUG) && DEBUG>2
661 if (data)
662 nasm_error(ERR_DEBUG,
663 " elf_out line: %d type: %x seg: %"PRIx32" segto: %"PRIx32" bytes: %"PRIx64" data: %"PRIx64"\n",
664 currentline, type, segment, segto, size, *(int64_t *)data);
665 else
666 nasm_error(ERR_DEBUG,
667 " elf_out line: %d type: %x seg: %"PRIx32" segto: %"PRIx32" bytes: %"PRIx64"\n",
668 currentline, type, segment, segto, size);
669 #endif
672 * handle absolute-assembly (structure definitions)
674 if (segto == NO_SEG) {
675 if (type != OUT_RESERVE)
676 nasm_error(ERR_NONFATAL, "attempt to assemble code in [ABSOLUTE]"
677 " space");
678 return;
681 s = NULL;
682 for (i = 0; i < nsects; i++)
683 if (segto == sects[i]->index) {
684 s = sects[i];
685 break;
687 if (!s) {
688 int tempint; /* ignored */
689 if (segto != elf_section_names(".text", 2, &tempint))
690 nasm_panic(0, "strange segment conditions in ELF driver");
691 else {
692 s = sects[nsects - 1];
693 i = nsects - 1;
697 /* again some stabs debugging stuff */
698 sinfo.offset = s->len;
699 sinfo.section = i;
700 sinfo.segto = segto;
701 sinfo.name = s->name;
702 dfmt->debug_output(TY_DEBUGSYMLIN, &sinfo);
703 /* end of debugging stuff */
705 if (s->type == SHT_NOBITS && type != OUT_RESERVE) {
706 nasm_error(ERR_WARNING, "attempt to initialize memory in"
707 " BSS section `%s': ignored", s->name);
708 s->len += realsize(type, size);
709 return;
712 switch (type) {
713 case OUT_RESERVE:
714 if (s->type == SHT_PROGBITS) {
715 nasm_error(ERR_WARNING, "uninitialized space declared in"
716 " non-BSS section `%s': zeroing", s->name);
717 elf_sect_write(s, NULL, size);
718 } else
719 s->len += size;
720 break;
722 case OUT_RAWDATA:
723 if (segment != NO_SEG)
724 nasm_panic(0, "OUT_RAWDATA with other than NO_SEG");
725 elf_sect_write(s, data, size);
726 break;
728 case OUT_ADDRESS:
730 int isize = (int)size;
731 int asize = abs((int)size);
733 addr = *(int64_t *)data;
734 if (segment == NO_SEG) {
735 /* Do nothing */
736 } else if (segment % 2) {
737 nasm_error(ERR_NONFATAL, "ELF format does not support"
738 " segment base references");
739 } else {
740 if (wrt == NO_SEG) {
741 switch (isize) {
742 case 1:
743 case -1:
744 elf_add_reloc(s, segment, addr, R_X86_64_8);
745 break;
746 case 2:
747 case -2:
748 elf_add_reloc(s, segment, addr, R_X86_64_16);
749 break;
750 case 4:
751 elf_add_reloc(s, segment, addr, R_X86_64_32);
752 break;
753 case -4:
754 elf_add_reloc(s, segment, addr, R_X86_64_32S);
755 break;
756 case 8:
757 case -8:
758 elf_add_reloc(s, segment, addr, R_X86_64_64);
759 break;
760 default:
761 nasm_panic(0, "internal error elf64-hpa-871");
762 break;
764 addr = 0;
765 } else if (wrt == elf_gotpc_sect + 1) {
767 * The user will supply GOT relative to $$. ELF
768 * will let us have GOT relative to $. So we
769 * need to fix up the data item by $-$$.
771 addr += s->len;
772 elf_add_reloc(s, segment, addr, R_X86_64_GOTPC32);
773 addr = 0;
774 } else if (wrt == elf_gotoff_sect + 1) {
775 if (asize != 8) {
776 nasm_error(ERR_NONFATAL, "ELF64 requires ..gotoff "
777 "references to be qword");
778 } else {
779 elf_add_reloc(s, segment, addr, R_X86_64_GOTOFF64);
780 addr = 0;
782 } else if (wrt == elf_got_sect + 1) {
783 switch (asize) {
784 case 4:
785 elf_add_gsym_reloc(s, segment, addr, 0,
786 R_X86_64_GOT32, true);
787 addr = 0;
788 break;
789 case 8:
790 elf_add_gsym_reloc(s, segment, addr, 0,
791 R_X86_64_GOT64, true);
792 addr = 0;
793 break;
794 default:
795 nasm_error(ERR_NONFATAL, "invalid ..got reference");
796 break;
798 } else if (wrt == elf_sym_sect + 1) {
799 switch (isize) {
800 case 1:
801 case -1:
802 elf_add_gsym_reloc(s, segment, addr, 0,
803 R_X86_64_8, false);
804 addr = 0;
805 break;
806 case 2:
807 case -2:
808 elf_add_gsym_reloc(s, segment, addr, 0,
809 R_X86_64_16, false);
810 addr = 0;
811 break;
812 case 4:
813 elf_add_gsym_reloc(s, segment, addr, 0,
814 R_X86_64_32, false);
815 addr = 0;
816 break;
817 case -4:
818 elf_add_gsym_reloc(s, segment, addr, 0,
819 R_X86_64_32S, false);
820 addr = 0;
821 break;
822 case 8:
823 case -8:
824 elf_add_gsym_reloc(s, segment, addr, 0,
825 R_X86_64_64, false);
826 addr = 0;
827 break;
828 default:
829 nasm_panic(0, "internal error elf64-hpa-903");
830 break;
832 } else if (wrt == elf_plt_sect + 1) {
833 nasm_error(ERR_NONFATAL, "ELF format cannot produce non-PC-"
834 "relative PLT references");
835 } else {
836 nasm_error(ERR_NONFATAL, "ELF format does not support this"
837 " use of WRT");
840 elf_sect_writeaddr(s, addr, asize);
841 break;
844 case OUT_REL1ADR:
845 reltype = R_X86_64_PC8;
846 bytes = 1;
847 goto rel12adr;
849 case OUT_REL2ADR:
850 reltype = R_X86_64_PC16;
851 bytes = 2;
852 goto rel12adr;
854 rel12adr:
855 addr = *(int64_t *)data - size;
856 if (segment == segto)
857 nasm_panic(0, "intra-segment OUT_REL1ADR");
858 if (segment == NO_SEG) {
859 /* Do nothing */
860 } else if (segment % 2) {
861 nasm_error(ERR_NONFATAL, "ELF format does not support"
862 " segment base references");
863 } else {
864 if (wrt == NO_SEG) {
865 elf_add_reloc(s, segment, addr, reltype);
866 addr = 0;
867 } else {
868 nasm_error(ERR_NONFATAL,
869 "Unsupported non-32-bit ELF relocation");
872 elf_sect_writeaddr(s, addr, bytes);
873 break;
875 case OUT_REL4ADR:
876 addr = *(int64_t *)data - size;
877 if (segment == segto)
878 nasm_panic(0, "intra-segment OUT_REL4ADR");
879 if (segment == NO_SEG) {
880 /* Do nothing */
881 } else if (segment % 2) {
882 nasm_error(ERR_NONFATAL, "ELF64 format does not support"
883 " segment base references");
884 } else {
885 if (wrt == NO_SEG) {
886 elf_add_reloc(s, segment, addr, R_X86_64_PC32);
887 addr = 0;
888 } else if (wrt == elf_plt_sect + 1) {
889 elf_add_gsym_reloc(s, segment, addr+size, size,
890 R_X86_64_PLT32, true);
891 addr = 0;
892 } else if (wrt == elf_gotpc_sect + 1 ||
893 wrt == elf_got_sect + 1) {
894 elf_add_gsym_reloc(s, segment, addr+size, size,
895 R_X86_64_GOTPCREL, true);
896 addr = 0;
897 } else if (wrt == elf_gotoff_sect + 1 ||
898 wrt == elf_got_sect + 1) {
899 nasm_error(ERR_NONFATAL, "ELF64 requires ..gotoff references to be "
900 "qword absolute");
901 } else if (wrt == elf_gottpoff_sect + 1) {
902 elf_add_gsym_reloc(s, segment, addr+size, size,
903 R_X86_64_GOTTPOFF, true);
904 addr = 0;
905 } else {
906 nasm_error(ERR_NONFATAL, "ELF64 format does not support this"
907 " use of WRT");
910 elf_sect_writeaddr(s, addr, 4);
911 break;
913 case OUT_REL8ADR:
914 addr = *(int64_t *)data - size;
915 if (segment == segto)
916 nasm_panic(0, "intra-segment OUT_REL8ADR");
917 if (segment == NO_SEG) {
918 /* Do nothing */
919 } else if (segment % 2) {
920 nasm_error(ERR_NONFATAL, "ELF64 format does not support"
921 " segment base references");
922 } else {
923 if (wrt == NO_SEG) {
924 elf_add_reloc(s, segment, addr, R_X86_64_PC64);
925 addr = 0;
926 } else if (wrt == elf_gotpc_sect + 1 ||
927 wrt == elf_got_sect + 1) {
928 elf_add_gsym_reloc(s, segment, addr+size, size,
929 R_X86_64_GOTPCREL64, true);
930 addr = 0;
931 } else if (wrt == elf_gotoff_sect + 1 ||
932 wrt == elf_got_sect + 1) {
933 nasm_error(ERR_NONFATAL, "ELF64 requires ..gotoff references to be "
934 "absolute");
935 } else if (wrt == elf_gottpoff_sect + 1) {
936 nasm_error(ERR_NONFATAL, "ELF64 requires ..gottpoff references to be "
937 "dword");
938 } else {
939 nasm_error(ERR_NONFATAL, "ELF64 format does not support this"
940 " use of WRT");
943 elf_sect_writeaddr(s, addr, 8);
944 break;
948 static void elf_write(void)
950 int align;
951 char *p;
952 int i;
954 struct SAA *symtab;
955 int32_t symtablen, symtablocal;
958 * Work out how many sections we will have. We have SHN_UNDEF,
959 * then the flexible user sections, then the fixed sections
960 * `.shstrtab', `.symtab' and `.strtab', then optionally
961 * relocation sections for the user sections.
963 nsections = sec_numspecial + 1;
964 if (dfmt == &df_stabs)
965 nsections += 3;
966 else if (dfmt == &df_dwarf)
967 nsections += 10;
969 add_sectname("", ".shstrtab");
970 add_sectname("", ".symtab");
971 add_sectname("", ".strtab");
972 for (i = 0; i < nsects; i++) {
973 nsections++; /* for the section itself */
974 if (sects[i]->head) {
975 nsections++; /* for its relocations */
976 add_sectname(".rela", sects[i]->name);
980 if (dfmt == &df_stabs) {
981 /* in case the debug information is wanted, just add these three sections... */
982 add_sectname("", ".stab");
983 add_sectname("", ".stabstr");
984 add_sectname(".rel", ".stab");
985 } else if (dfmt == &df_dwarf) {
986 /* the dwarf debug standard specifies the following ten sections,
987 not all of which are currently implemented,
988 although all of them are defined. */
989 #define debug_aranges (int64_t) (nsections-10)
990 #define debug_info (int64_t) (nsections-7)
991 #define debug_abbrev (int64_t) (nsections-5)
992 #define debug_line (int64_t) (nsections-4)
993 add_sectname("", ".debug_aranges");
994 add_sectname(".rela", ".debug_aranges");
995 add_sectname("", ".debug_pubnames");
996 add_sectname("", ".debug_info");
997 add_sectname(".rela", ".debug_info");
998 add_sectname("", ".debug_abbrev");
999 add_sectname("", ".debug_line");
1000 add_sectname(".rela", ".debug_line");
1001 add_sectname("", ".debug_frame");
1002 add_sectname("", ".debug_loc");
1006 * Output the ELF header.
1008 nasm_write("\177ELF\2\1\1", 7, ofile);
1009 fputc(elf_osabi, ofile);
1010 fputc(elf_abiver, ofile);
1011 fwritezero(7, ofile);
1012 fwriteint16_t(ET_REL, ofile); /* relocatable file */
1013 fwriteint16_t(EM_X86_64, ofile); /* processor ID */
1014 fwriteint32_t(1L, ofile); /* EV_CURRENT file format version */
1015 fwriteint64_t(0L, ofile); /* no entry point */
1016 fwriteint64_t(0L, ofile); /* no program header table */
1017 fwriteint64_t(0x40L, ofile); /* section headers straight after
1018 * ELF header plus alignment */
1019 fwriteint32_t(0L, ofile); /* 386 defines no special flags */
1020 fwriteint16_t(0x40, ofile); /* size of ELF header */
1021 fwriteint16_t(0, ofile); /* no program header table, again */
1022 fwriteint16_t(0, ofile); /* still no program header table */
1023 fwriteint16_t(sizeof(Elf64_Shdr), ofile); /* size of section header */
1024 fwriteint16_t(nsections, ofile); /* number of sections */
1025 fwriteint16_t(sec_shstrtab, ofile); /* string table section index for
1026 * section header table */
1029 * Build the symbol table and relocation tables.
1031 symtab = elf_build_symtab(&symtablen, &symtablocal);
1032 for (i = 0; i < nsects; i++)
1033 if (sects[i]->head)
1034 sects[i]->rel = elf_build_reltab(&sects[i]->rellen,
1035 sects[i]->head);
1038 * Now output the section header table.
1041 elf_foffs = 0x40 + sizeof(Elf64_Shdr) * nsections;
1042 align = ALIGN(elf_foffs, SEC_FILEALIGN) - elf_foffs;
1043 elf_foffs += align;
1044 elf_nsect = 0;
1045 elf_sects = nasm_malloc(sizeof(*elf_sects) * nsections);
1047 /* SHN_UNDEF */
1048 elf_section_header(0, SHT_NULL, 0, NULL, false, 0, SHN_UNDEF, 0, 0, 0);
1049 p = shstrtab + 1;
1051 /* The normal sections */
1052 for (i = 0; i < nsects; i++) {
1053 elf_section_header(p - shstrtab, sects[i]->type, sects[i]->flags,
1054 (sects[i]->type == SHT_PROGBITS ?
1055 sects[i]->data : NULL), true,
1056 sects[i]->len, 0, 0, sects[i]->align, 0);
1057 p += strlen(p) + 1;
1060 /* .shstrtab */
1061 elf_section_header(p - shstrtab, SHT_STRTAB, 0, shstrtab, false,
1062 shstrtablen, 0, 0, 1, 0);
1063 p += strlen(p) + 1;
1065 /* .symtab */
1066 elf_section_header(p - shstrtab, SHT_SYMTAB, 0, symtab, true,
1067 symtablen, sec_strtab, symtablocal, 8, 24);
1068 p += strlen(p) + 1;
1070 /* .strtab */
1071 elf_section_header(p - shstrtab, SHT_STRTAB, 0, strs, true,
1072 strslen, 0, 0, 1, 0);
1073 p += strlen(p) + 1;
1075 /* The relocation sections */
1076 for (i = 0; i < nsects; i++)
1077 if (sects[i]->head) {
1078 elf_section_header(p - shstrtab, SHT_RELA, 0, sects[i]->rel, true,
1079 sects[i]->rellen, sec_symtab, i + 1, 8, 24);
1080 p += strlen(p) + 1;
1083 if (dfmt == &df_stabs) {
1084 /* for debugging information, create the last three sections
1085 which are the .stab , .stabstr and .rel.stab sections respectively */
1087 /* this function call creates the stab sections in memory */
1088 stabs_generate();
1090 if (stabbuf && stabstrbuf && stabrelbuf) {
1091 elf_section_header(p - shstrtab, SHT_PROGBITS, 0, stabbuf, false,
1092 stablen, sec_stabstr, 0, 4, 12);
1093 p += strlen(p) + 1;
1095 elf_section_header(p - shstrtab, SHT_STRTAB, 0, stabstrbuf, false,
1096 stabstrlen, 0, 0, 4, 0);
1097 p += strlen(p) + 1;
1099 /* link -> symtable info -> section to refer to */
1100 elf_section_header(p - shstrtab, SHT_REL, 0, stabrelbuf, false,
1101 stabrellen, sec_symtab, sec_stab, 4, 16);
1102 p += strlen(p) + 1;
1104 } else if (dfmt == &df_dwarf) {
1105 /* for dwarf debugging information, create the ten dwarf sections */
1107 /* this function call creates the dwarf sections in memory */
1108 if (dwarf_fsect)
1109 dwarf_generate();
1111 elf_section_header(p - shstrtab, SHT_PROGBITS, 0, arangesbuf, false,
1112 arangeslen, 0, 0, 1, 0);
1113 p += strlen(p) + 1;
1115 elf_section_header(p - shstrtab, SHT_RELA, 0, arangesrelbuf, false,
1116 arangesrellen, sec_symtab, debug_aranges, 1, 24);
1117 p += strlen(p) + 1;
1119 elf_section_header(p - shstrtab, SHT_PROGBITS, 0, pubnamesbuf, false,
1120 pubnameslen, 0, 0, 1, 0);
1121 p += strlen(p) + 1;
1123 elf_section_header(p - shstrtab, SHT_PROGBITS, 0, infobuf, false,
1124 infolen, 0, 0, 1, 0);
1125 p += strlen(p) + 1;
1127 elf_section_header(p - shstrtab, SHT_RELA, 0, inforelbuf, false,
1128 inforellen, sec_symtab, debug_info, 1, 24);
1129 p += strlen(p) + 1;
1131 elf_section_header(p - shstrtab, SHT_PROGBITS, 0, abbrevbuf, false,
1132 abbrevlen, 0, 0, 1, 0);
1133 p += strlen(p) + 1;
1135 elf_section_header(p - shstrtab, SHT_PROGBITS, 0, linebuf, false,
1136 linelen, 0, 0, 1, 0);
1137 p += strlen(p) + 1;
1139 elf_section_header(p - shstrtab, SHT_RELA, 0, linerelbuf, false,
1140 linerellen, sec_symtab, debug_line, 1, 24);
1141 p += strlen(p) + 1;
1143 elf_section_header(p - shstrtab, SHT_PROGBITS, 0, framebuf, false,
1144 framelen, 0, 0, 8, 0);
1145 p += strlen(p) + 1;
1147 elf_section_header(p - shstrtab, SHT_PROGBITS, 0, locbuf, false,
1148 loclen, 0, 0, 1, 0);
1149 p += strlen(p) + 1;
1151 fwritezero(align, ofile);
1154 * Now output the sections.
1156 elf_write_sections();
1158 nasm_free(elf_sects);
1159 saa_free(symtab);
1162 static struct SAA *elf_build_symtab(int32_t *len, int32_t *local)
1164 struct SAA *s = saa_init(1L);
1165 struct elf_symbol *sym;
1166 uint8_t entry[24], *p;
1167 int i;
1169 *len = *local = 0;
1172 * First, an all-zeros entry, required by the ELF spec.
1174 saa_wbytes(s, NULL, 24L); /* null symbol table entry */
1175 *len += 24;
1176 (*local)++;
1179 * Next, an entry for the file name.
1181 p = entry;
1182 WRITELONG(p, 1); /* we know it's 1st entry in strtab */
1183 WRITESHORT(p, STT_FILE); /* type FILE */
1184 WRITESHORT(p, SHN_ABS);
1185 WRITEDLONG(p, (uint64_t) 0); /* no value */
1186 WRITEDLONG(p, (uint64_t) 0); /* no size either */
1187 saa_wbytes(s, entry, 24L);
1188 *len += 24;
1189 (*local)++;
1192 * Now some standard symbols defining the segments, for relocation
1193 * purposes.
1195 for (i = 1; i <= nsects; i++) {
1196 p = entry;
1197 WRITELONG(p, 0); /* no symbol name */
1198 WRITESHORT(p, STT_SECTION); /* type, binding, and visibility */
1199 WRITESHORT(p, i); /* section id */
1200 WRITEDLONG(p, (uint64_t) 0); /* offset zero */
1201 WRITEDLONG(p, (uint64_t) 0); /* size zero */
1202 saa_wbytes(s, entry, 24L);
1203 *len += 24;
1204 (*local)++;
1208 * Now the other local symbols.
1210 saa_rewind(syms);
1211 while ((sym = saa_rstruct(syms))) {
1212 if (sym->type & SYM_GLOBAL)
1213 continue;
1214 p = entry;
1215 WRITELONG(p, sym->strpos); /* index into symbol string table */
1216 WRITECHAR(p, sym->type); /* type and binding */
1217 WRITECHAR(p, sym->other); /* visibility */
1218 WRITESHORT(p, sym->section); /* index into section header table */
1219 WRITEDLONG(p, (int64_t)sym->symv.key); /* value of symbol */
1220 WRITEDLONG(p, (int64_t)sym->size); /* size of symbol */
1221 saa_wbytes(s, entry, 24L);
1222 *len += 24;
1223 (*local)++;
1226 * dwarf needs symbols for debug sections
1227 * which are relocation targets.
1229 if (dfmt == &df_dwarf) {
1230 dwarf_infosym = *local;
1231 p = entry;
1232 WRITELONG(p, 0); /* no symbol name */
1233 WRITESHORT(p, STT_SECTION); /* type, binding, and visibility */
1234 WRITESHORT(p, debug_info); /* section id */
1235 WRITEDLONG(p, (uint64_t) 0); /* offset zero */
1236 WRITEDLONG(p, (uint64_t) 0); /* size zero */
1237 saa_wbytes(s, entry, 24L);
1238 *len += 24;
1239 (*local)++;
1240 dwarf_abbrevsym = *local;
1241 p = entry;
1242 WRITELONG(p, 0); /* no symbol name */
1243 WRITESHORT(p, STT_SECTION); /* type, binding, and visibility */
1244 WRITESHORT(p, debug_abbrev); /* section id */
1245 WRITEDLONG(p, (uint64_t) 0); /* offset zero */
1246 WRITEDLONG(p, (uint64_t) 0); /* size zero */
1247 saa_wbytes(s, entry, 24L);
1248 *len += 24;
1249 (*local)++;
1250 dwarf_linesym = *local;
1251 p = entry;
1252 WRITELONG(p, 0); /* no symbol name */
1253 WRITESHORT(p, STT_SECTION); /* type, binding, and visibility */
1254 WRITESHORT(p, debug_line); /* section id */
1255 WRITEDLONG(p, (uint64_t) 0); /* offset zero */
1256 WRITEDLONG(p, (uint64_t) 0); /* size zero */
1257 saa_wbytes(s, entry, 24L);
1258 *len += 24;
1259 (*local)++;
1263 * Now the global symbols.
1265 saa_rewind(syms);
1266 while ((sym = saa_rstruct(syms))) {
1267 if (!(sym->type & SYM_GLOBAL))
1268 continue;
1269 p = entry;
1270 WRITELONG(p, sym->strpos);
1271 WRITECHAR(p, sym->type); /* type and binding */
1272 WRITECHAR(p, sym->other); /* visibility */
1273 WRITESHORT(p, sym->section);
1274 WRITEDLONG(p, (int64_t)sym->symv.key);
1275 WRITEDLONG(p, (int64_t)sym->size);
1276 saa_wbytes(s, entry, 24L);
1277 *len += 24;
1280 return s;
1283 static struct SAA *elf_build_reltab(uint64_t *len, struct elf_reloc *r)
1285 struct SAA *s;
1286 uint8_t *p, entry[24];
1287 int32_t global_offset;
1289 if (!r)
1290 return NULL;
1292 s = saa_init(1L);
1293 *len = 0;
1296 * How to onvert from a global placeholder to a real symbol index;
1297 * the +2 refers to the two special entries, the null entry and
1298 * the filename entry.
1300 global_offset = -GLOBAL_TEMP_BASE + nsects + nlocals + ndebugs + 2;
1302 while (r) {
1303 int32_t sym = r->symbol;
1305 if (sym >= GLOBAL_TEMP_BASE)
1306 sym += global_offset;
1308 p = entry;
1309 WRITEDLONG(p, r->address);
1310 WRITELONG(p, r->type);
1311 WRITELONG(p, sym);
1312 WRITEDLONG(p, r->offset);
1313 saa_wbytes(s, entry, 24L);
1314 *len += 24;
1316 r = r->next;
1319 return s;
1322 static void elf_section_header(int name, int type, uint64_t flags,
1323 void *data, bool is_saa, uint64_t datalen,
1324 int link, int info, int align, int eltsize)
1326 elf_sects[elf_nsect].data = data;
1327 elf_sects[elf_nsect].len = datalen;
1328 elf_sects[elf_nsect].is_saa = is_saa;
1329 elf_nsect++;
1331 fwriteint32_t((int32_t)name, ofile);
1332 fwriteint32_t((int32_t)type, ofile);
1333 fwriteint64_t((int64_t)flags, ofile);
1334 fwriteint64_t(0L, ofile); /* no address, ever, in object files */
1335 fwriteint64_t(type == 0 ? 0L : elf_foffs, ofile);
1336 fwriteint64_t(datalen, ofile);
1337 if (data)
1338 elf_foffs += ALIGN(datalen, SEC_FILEALIGN);
1339 fwriteint32_t((int32_t)link, ofile);
1340 fwriteint32_t((int32_t)info, ofile);
1341 fwriteint64_t((int64_t)align, ofile);
1342 fwriteint64_t((int64_t)eltsize, ofile);
1345 static void elf_write_sections(void)
1347 int i;
1348 for (i = 0; i < elf_nsect; i++)
1349 if (elf_sects[i].data) {
1350 int32_t len = elf_sects[i].len;
1351 int32_t reallen = ALIGN(len, SEC_FILEALIGN);
1352 int32_t align = reallen - len;
1353 if (elf_sects[i].is_saa)
1354 saa_fpwrite(elf_sects[i].data, ofile);
1355 else
1356 nasm_write(elf_sects[i].data, len, ofile);
1357 fwritezero(align, ofile);
1361 static void elf_sect_write(struct elf_section *sect, const void *data, size_t len)
1363 saa_wbytes(sect->data, data, len);
1364 sect->len += len;
1367 static void elf_sect_writeaddr(struct elf_section *sect, int64_t data, size_t len)
1369 saa_writeaddr(sect->data, data, len);
1370 sect->len += len;
1373 static void elf_sectalign(int32_t seg, unsigned int value)
1375 struct elf_section *s = NULL;
1376 int i;
1378 for (i = 0; i < nsects; i++) {
1379 if (sects[i]->index == seg) {
1380 s = sects[i];
1381 break;
1384 if (!s || !is_power2(value))
1385 return;
1387 if (value > s->align)
1388 s->align = value;
1391 static int32_t elf_segbase(int32_t segment)
1393 return segment;
1396 static void elf_filename(char *inname, char *outname)
1398 strcpy(elf_module, inname);
1399 standard_extension(inname, outname, ".o");
1402 extern macros_t elf_stdmac[];
1404 static int elf_set_info(enum geninfo type, char **val)
1406 (void)type;
1407 (void)val;
1408 return 0;
1410 static const struct dfmt df_dwarf = {
1411 "ELF64 (x86-64) dwarf debug format for Linux/Unix",
1412 "dwarf",
1413 dwarf_init,
1414 dwarf_linenum,
1415 null_debug_deflabel,
1416 null_debug_directive,
1417 debug_typevalue,
1418 dwarf_output,
1419 dwarf_cleanup
1421 static const struct dfmt df_stabs = {
1422 "ELF64 (x86-64) stabs debug format for Linux/Unix",
1423 "stabs",
1424 null_debug_init,
1425 stabs_linenum,
1426 null_debug_deflabel,
1427 null_debug_directive,
1428 debug_typevalue,
1429 stabs_output,
1430 stabs_cleanup
1433 static const struct dfmt * const elf64_debugs_arr[3] =
1434 { &df_dwarf, &df_stabs, NULL };
1436 const struct ofmt of_elf64 = {
1437 "ELF64 (x86_64) object files (e.g. Linux)",
1438 "elf64",
1441 elf64_debugs_arr,
1442 &df_stabs,
1443 elf_stdmac,
1444 elf_init,
1445 elf_set_info,
1446 elf_out,
1447 elf_deflabel,
1448 elf_section_names,
1449 elf_sectalign,
1450 elf_segbase,
1451 elf_directive,
1452 elf_filename,
1453 elf_cleanup
1456 /* common debugging routines */
1457 static void debug_typevalue(int32_t type)
1459 int32_t stype, ssize;
1460 switch (TYM_TYPE(type)) {
1461 case TY_LABEL:
1462 ssize = 0;
1463 stype = STT_NOTYPE;
1464 break;
1465 case TY_BYTE:
1466 ssize = 1;
1467 stype = STT_OBJECT;
1468 break;
1469 case TY_WORD:
1470 ssize = 2;
1471 stype = STT_OBJECT;
1472 break;
1473 case TY_DWORD:
1474 ssize = 4;
1475 stype = STT_OBJECT;
1476 break;
1477 case TY_FLOAT:
1478 ssize = 4;
1479 stype = STT_OBJECT;
1480 break;
1481 case TY_QWORD:
1482 ssize = 8;
1483 stype = STT_OBJECT;
1484 break;
1485 case TY_TBYTE:
1486 ssize = 10;
1487 stype = STT_OBJECT;
1488 break;
1489 case TY_OWORD:
1490 ssize = 16;
1491 stype = STT_OBJECT;
1492 break;
1493 case TY_YWORD:
1494 ssize = 32;
1495 stype = STT_OBJECT;
1496 break;
1497 case TY_COMMON:
1498 ssize = 0;
1499 stype = STT_COMMON;
1500 break;
1501 case TY_SEG:
1502 ssize = 0;
1503 stype = STT_SECTION;
1504 break;
1505 case TY_EXTERN:
1506 ssize = 0;
1507 stype = STT_NOTYPE;
1508 break;
1509 case TY_EQU:
1510 ssize = 0;
1511 stype = STT_NOTYPE;
1512 break;
1513 default:
1514 ssize = 0;
1515 stype = STT_NOTYPE;
1516 break;
1518 if (stype == STT_OBJECT && lastsym && !lastsym->type) {
1519 lastsym->size = ssize;
1520 lastsym->type = stype;
1524 /* stabs debugging routines */
1526 static void stabs_linenum(const char *filename, int32_t linenumber, int32_t segto)
1528 (void)segto;
1529 if (!stabs_filename) {
1530 stabs_filename = (char *)nasm_malloc(strlen(filename) + 1);
1531 strcpy(stabs_filename, filename);
1532 } else {
1533 if (strcmp(stabs_filename, filename)) {
1534 /* yep, a memory leak...this program is one-shot anyway, so who cares...
1535 in fact, this leak comes in quite handy to maintain a list of files
1536 encountered so far in the symbol lines... */
1538 /* why not nasm_free(stabs_filename); we're done with the old one */
1540 stabs_filename = (char *)nasm_malloc(strlen(filename) + 1);
1541 strcpy(stabs_filename, filename);
1544 debug_immcall = 1;
1545 currentline = linenumber;
1548 static void stabs_output(int type, void *param)
1550 struct symlininfo *s;
1551 struct linelist *el;
1552 if (type == TY_DEBUGSYMLIN) {
1553 if (debug_immcall) {
1554 s = (struct symlininfo *)param;
1555 if (!(sects[s->section]->flags & SHF_EXECINSTR))
1556 return; /* line info is only collected for executable sections */
1557 numlinestabs++;
1558 el = (struct linelist *)nasm_malloc(sizeof(struct linelist));
1559 el->info.offset = s->offset;
1560 el->info.section = s->section;
1561 el->info.name = s->name;
1562 el->line = currentline;
1563 el->filename = stabs_filename;
1564 el->next = 0;
1565 if (stabslines) {
1566 stabslines->last->next = el;
1567 stabslines->last = el;
1568 } else {
1569 stabslines = el;
1570 stabslines->last = el;
1574 debug_immcall = 0;
1577 /* for creating the .stab , .stabstr and .rel.stab sections in memory */
1579 static void stabs_generate(void)
1581 int i, numfiles, strsize, numstabs = 0, currfile, mainfileindex;
1582 uint8_t *sbuf, *ssbuf, *rbuf, *sptr, *rptr;
1583 char **allfiles;
1584 int *fileidx;
1586 struct linelist *ptr;
1588 ptr = stabslines;
1590 allfiles = (char **)nasm_zalloc(numlinestabs * sizeof(char *));
1591 numfiles = 0;
1592 while (ptr) {
1593 if (numfiles == 0) {
1594 allfiles[0] = ptr->filename;
1595 numfiles++;
1596 } else {
1597 for (i = 0; i < numfiles; i++) {
1598 if (!strcmp(allfiles[i], ptr->filename))
1599 break;
1601 if (i >= numfiles) {
1602 allfiles[i] = ptr->filename;
1603 numfiles++;
1606 ptr = ptr->next;
1608 strsize = 1;
1609 fileidx = (int *)nasm_malloc(numfiles * sizeof(int));
1610 for (i = 0; i < numfiles; i++) {
1611 fileidx[i] = strsize;
1612 strsize += strlen(allfiles[i]) + 1;
1614 mainfileindex = 0;
1615 for (i = 0; i < numfiles; i++) {
1616 if (!strcmp(allfiles[i], elf_module)) {
1617 mainfileindex = i;
1618 break;
1623 * worst case size of the stab buffer would be:
1624 * the sourcefiles changes each line, which would mean 1 SOL, 1 SYMLIN per line
1625 * plus one "ending" entry
1627 sbuf = (uint8_t *)nasm_malloc((numlinestabs * 2 + 4) *
1628 sizeof(struct stabentry));
1629 ssbuf = (uint8_t *)nasm_malloc(strsize);
1630 rbuf = (uint8_t *)nasm_malloc(numlinestabs * 16 * (2 + 3));
1631 rptr = rbuf;
1633 for (i = 0; i < numfiles; i++)
1634 strcpy((char *)ssbuf + fileidx[i], allfiles[i]);
1635 ssbuf[0] = 0;
1637 stabstrlen = strsize; /* set global variable for length of stab strings */
1639 sptr = sbuf;
1640 ptr = stabslines;
1641 numstabs = 0;
1643 if (ptr) {
1645 * this is the first stab, its strx points to the filename of the
1646 * the source-file, the n_desc field should be set to the number
1647 * of remaining stabs
1649 WRITE_STAB(sptr, fileidx[0], 0, 0, 0, stabstrlen);
1651 /* this is the stab for the main source file */
1652 WRITE_STAB(sptr, fileidx[mainfileindex], N_SO, 0, 0, 0);
1654 /* relocation table entry */
1657 * Since the symbol table has two entries before
1658 * the section symbols, the index in the info.section
1659 * member must be adjusted by adding 2
1662 WRITEDLONG(rptr, (int64_t)(sptr - sbuf) - 4);
1663 WRITELONG(rptr, R_X86_64_32);
1664 WRITELONG(rptr, ptr->info.section + 2);
1666 numstabs++;
1667 currfile = mainfileindex;
1670 while (ptr) {
1671 if (strcmp(allfiles[currfile], ptr->filename)) {
1672 /* oops file has changed... */
1673 for (i = 0; i < numfiles; i++)
1674 if (!strcmp(allfiles[i], ptr->filename))
1675 break;
1676 currfile = i;
1677 WRITE_STAB(sptr, fileidx[currfile], N_SOL, 0, 0,
1678 ptr->info.offset);
1679 numstabs++;
1681 /* relocation table entry */
1683 WRITEDLONG(rptr, (int64_t)(sptr - sbuf) - 4);
1684 WRITELONG(rptr, R_X86_64_32);
1685 WRITELONG(rptr, ptr->info.section + 2);
1688 WRITE_STAB(sptr, 0, N_SLINE, 0, ptr->line, ptr->info.offset);
1689 numstabs++;
1691 /* relocation table entry */
1693 WRITEDLONG(rptr, (int64_t)(sptr - sbuf) - 4);
1694 WRITELONG(rptr, R_X86_64_32);
1695 WRITELONG(rptr, ptr->info.section + 2);
1697 ptr = ptr->next;
1701 /* this is an "ending" token */
1702 WRITE_STAB(sptr, 0, N_SO, 0, 0, 0);
1703 numstabs++;
1705 ((struct stabentry *)sbuf)->n_desc = numstabs;
1707 nasm_free(allfiles);
1708 nasm_free(fileidx);
1710 stablen = (sptr - sbuf);
1711 stabrellen = (rptr - rbuf);
1712 stabrelbuf = rbuf;
1713 stabbuf = sbuf;
1714 stabstrbuf = ssbuf;
1717 static void stabs_cleanup(void)
1719 struct linelist *ptr, *del;
1720 if (!stabslines)
1721 return;
1723 ptr = stabslines;
1724 while (ptr) {
1725 del = ptr;
1726 ptr = ptr->next;
1727 nasm_free(del);
1730 nasm_free(stabbuf);
1731 nasm_free(stabrelbuf);
1732 nasm_free(stabstrbuf);
1735 /* dwarf routines */
1737 static void dwarf_init(void)
1739 ndebugs = 3; /* 3 debug symbols */
1742 static void dwarf_linenum(const char *filename, int32_t linenumber,
1743 int32_t segto)
1745 (void)segto;
1746 dwarf_findfile(filename);
1747 debug_immcall = 1;
1748 currentline = linenumber;
1751 /* called from elf_out with type == TY_DEBUGSYMLIN */
1752 static void dwarf_output(int type, void *param)
1754 int ln, aa, inx, maxln, soc;
1755 struct symlininfo *s;
1756 struct SAA *plinep;
1758 (void)type;
1760 s = (struct symlininfo *)param;
1762 /* line number info is only gathered for executable sections */
1763 if (!(sects[s->section]->flags & SHF_EXECINSTR))
1764 return;
1766 /* Check if section index has changed */
1767 if (!(dwarf_csect && (dwarf_csect->section) == (s->section)))
1768 dwarf_findsect(s->section);
1770 /* do nothing unless line or file has changed */
1771 if (!debug_immcall)
1772 return;
1774 ln = currentline - dwarf_csect->line;
1775 aa = s->offset - dwarf_csect->offset;
1776 inx = dwarf_clist->line;
1777 plinep = dwarf_csect->psaa;
1778 /* check for file change */
1779 if (!(inx == dwarf_csect->file)) {
1780 saa_write8(plinep,DW_LNS_set_file);
1781 saa_write8(plinep,inx);
1782 dwarf_csect->file = inx;
1784 /* check for line change */
1785 if (ln) {
1786 /* test if in range of special op code */
1787 maxln = line_base + line_range;
1788 soc = (ln - line_base) + (line_range * aa) + opcode_base;
1789 if (ln >= line_base && ln < maxln && soc < 256) {
1790 saa_write8(plinep,soc);
1791 } else {
1792 saa_write8(plinep,DW_LNS_advance_line);
1793 saa_wleb128s(plinep,ln);
1794 if (aa) {
1795 saa_write8(plinep,DW_LNS_advance_pc);
1796 saa_wleb128u(plinep,aa);
1799 dwarf_csect->line = currentline;
1800 dwarf_csect->offset = s->offset;
1803 /* show change handled */
1804 debug_immcall = 0;
1808 static void dwarf_generate(void)
1810 uint8_t *pbuf;
1811 int indx;
1812 struct linelist *ftentry;
1813 struct SAA *paranges, *ppubnames, *pinfo, *pabbrev, *plines, *plinep;
1814 struct SAA *parangesrel, *plinesrel, *pinforel;
1815 struct sectlist *psect;
1816 size_t saalen, linepoff, totlen, highaddr;
1818 /* write epilogues for each line program range */
1819 /* and build aranges section */
1820 paranges = saa_init(1L);
1821 parangesrel = saa_init(1L);
1822 saa_write16(paranges,3); /* dwarf version */
1823 saa_write64(parangesrel, paranges->datalen+4);
1824 saa_write64(parangesrel, (dwarf_infosym << 32) + R_X86_64_32); /* reloc to info */
1825 saa_write64(parangesrel, 0);
1826 saa_write32(paranges,0); /* offset into info */
1827 saa_write8(paranges,8); /* pointer size */
1828 saa_write8(paranges,0); /* not segmented */
1829 saa_write32(paranges,0); /* padding */
1830 /* iterate though sectlist entries */
1831 psect = dwarf_fsect;
1832 totlen = 0;
1833 highaddr = 0;
1834 for (indx = 0; indx < dwarf_nsections; indx++) {
1835 plinep = psect->psaa;
1836 /* Line Number Program Epilogue */
1837 saa_write8(plinep,2); /* std op 2 */
1838 saa_write8(plinep,(sects[psect->section]->len)-psect->offset);
1839 saa_write8(plinep,DW_LNS_extended_op);
1840 saa_write8(plinep,1); /* operand length */
1841 saa_write8(plinep,DW_LNE_end_sequence);
1842 totlen += plinep->datalen;
1843 /* range table relocation entry */
1844 saa_write64(parangesrel, paranges->datalen + 4);
1845 saa_write64(parangesrel, ((uint64_t) (psect->section + 2) << 32) + R_X86_64_64);
1846 saa_write64(parangesrel, (uint64_t) 0);
1847 /* range table entry */
1848 saa_write64(paranges,0x0000); /* range start */
1849 saa_write64(paranges,sects[psect->section]->len); /* range length */
1850 highaddr += sects[psect->section]->len;
1851 /* done with this entry */
1852 psect = psect->next;
1854 saa_write64(paranges,0); /* null address */
1855 saa_write64(paranges,0); /* null length */
1856 saalen = paranges->datalen;
1857 arangeslen = saalen + 4;
1858 arangesbuf = pbuf = nasm_malloc(arangeslen);
1859 WRITELONG(pbuf,saalen); /* initial length */
1860 saa_rnbytes(paranges, pbuf, saalen);
1861 saa_free(paranges);
1863 /* build rela.aranges section */
1864 arangesrellen = saalen = parangesrel->datalen;
1865 arangesrelbuf = pbuf = nasm_malloc(arangesrellen);
1866 saa_rnbytes(parangesrel, pbuf, saalen);
1867 saa_free(parangesrel);
1869 /* build pubnames section */
1870 ppubnames = saa_init(1L);
1871 saa_write16(ppubnames,3); /* dwarf version */
1872 saa_write32(ppubnames,0); /* offset into info */
1873 saa_write32(ppubnames,0); /* space used in info */
1874 saa_write32(ppubnames,0); /* end of list */
1875 saalen = ppubnames->datalen;
1876 pubnameslen = saalen + 4;
1877 pubnamesbuf = pbuf = nasm_malloc(pubnameslen);
1878 WRITELONG(pbuf,saalen); /* initial length */
1879 saa_rnbytes(ppubnames, pbuf, saalen);
1880 saa_free(ppubnames);
1882 /* build info section */
1883 pinfo = saa_init(1L);
1884 pinforel = saa_init(1L);
1885 saa_write16(pinfo,3); /* dwarf version */
1886 saa_write64(pinforel, pinfo->datalen + 4);
1887 saa_write64(pinforel, (dwarf_abbrevsym << 32) + R_X86_64_32); /* reloc to abbrev */
1888 saa_write64(pinforel, 0);
1889 saa_write32(pinfo,0); /* offset into abbrev */
1890 saa_write8(pinfo,8); /* pointer size */
1891 saa_write8(pinfo,1); /* abbrviation number LEB128u */
1892 saa_write64(pinforel, pinfo->datalen + 4);
1893 saa_write64(pinforel, ((uint64_t)(dwarf_fsect->section + 2) << 32) + R_X86_64_64);
1894 saa_write64(pinforel, 0);
1895 saa_write64(pinfo,0); /* DW_AT_low_pc */
1896 saa_write64(pinforel, pinfo->datalen + 4);
1897 saa_write64(pinforel, ((uint64_t)(dwarf_fsect->section + 2) << 32) + R_X86_64_64);
1898 saa_write64(pinforel, 0);
1899 saa_write64(pinfo,highaddr); /* DW_AT_high_pc */
1900 saa_write64(pinforel, pinfo->datalen + 4);
1901 saa_write64(pinforel, (dwarf_linesym << 32) + R_X86_64_32); /* reloc to line */
1902 saa_write64(pinforel, 0);
1903 saa_write32(pinfo,0); /* DW_AT_stmt_list */
1904 saa_wbytes(pinfo, elf_module, strlen(elf_module)+1);
1905 saa_wbytes(pinfo, nasm_signature, strlen(nasm_signature)+1);
1906 saa_write16(pinfo,DW_LANG_Mips_Assembler);
1907 saa_write8(pinfo,2); /* abbrviation number LEB128u */
1908 saa_write64(pinforel, pinfo->datalen + 4);
1909 saa_write64(pinforel, ((uint64_t)(dwarf_fsect->section + 2) << 32) + R_X86_64_64);
1910 saa_write64(pinforel, 0);
1911 saa_write64(pinfo,0); /* DW_AT_low_pc */
1912 saa_write64(pinfo,0); /* DW_AT_frame_base */
1913 saa_write8(pinfo,0); /* end of entries */
1914 saalen = pinfo->datalen;
1915 infolen = saalen + 4;
1916 infobuf = pbuf = nasm_malloc(infolen);
1917 WRITELONG(pbuf,saalen); /* initial length */
1918 saa_rnbytes(pinfo, pbuf, saalen);
1919 saa_free(pinfo);
1921 /* build rela.info section */
1922 inforellen = saalen = pinforel->datalen;
1923 inforelbuf = pbuf = nasm_malloc(inforellen);
1924 saa_rnbytes(pinforel, pbuf, saalen);
1925 saa_free(pinforel);
1927 /* build abbrev section */
1928 pabbrev = saa_init(1L);
1929 saa_write8(pabbrev,1); /* entry number LEB128u */
1930 saa_write8(pabbrev,DW_TAG_compile_unit); /* tag LEB128u */
1931 saa_write8(pabbrev,1); /* has children */
1932 /* the following attributes and forms are all LEB128u values */
1933 saa_write8(pabbrev,DW_AT_low_pc);
1934 saa_write8(pabbrev,DW_FORM_addr);
1935 saa_write8(pabbrev,DW_AT_high_pc);
1936 saa_write8(pabbrev,DW_FORM_addr);
1937 saa_write8(pabbrev,DW_AT_stmt_list);
1938 saa_write8(pabbrev,DW_FORM_data4);
1939 saa_write8(pabbrev,DW_AT_name);
1940 saa_write8(pabbrev,DW_FORM_string);
1941 saa_write8(pabbrev,DW_AT_producer);
1942 saa_write8(pabbrev,DW_FORM_string);
1943 saa_write8(pabbrev,DW_AT_language);
1944 saa_write8(pabbrev,DW_FORM_data2);
1945 saa_write16(pabbrev,0); /* end of entry */
1946 /* LEB128u usage same as above */
1947 saa_write8(pabbrev,2); /* entry number */
1948 saa_write8(pabbrev,DW_TAG_subprogram);
1949 saa_write8(pabbrev,0); /* no children */
1950 saa_write8(pabbrev,DW_AT_low_pc);
1951 saa_write8(pabbrev,DW_FORM_addr);
1952 saa_write8(pabbrev,DW_AT_frame_base);
1953 saa_write8(pabbrev,DW_FORM_data4);
1954 saa_write16(pabbrev,0); /* end of entry */
1955 abbrevlen = saalen = pabbrev->datalen;
1956 abbrevbuf = pbuf = nasm_malloc(saalen);
1957 saa_rnbytes(pabbrev, pbuf, saalen);
1958 saa_free(pabbrev);
1960 /* build line section */
1961 /* prolog */
1962 plines = saa_init(1L);
1963 saa_write8(plines,1); /* Minimum Instruction Length */
1964 saa_write8(plines,1); /* Initial value of 'is_stmt' */
1965 saa_write8(plines,line_base); /* Line Base */
1966 saa_write8(plines,line_range); /* Line Range */
1967 saa_write8(plines,opcode_base); /* Opcode Base */
1968 /* standard opcode lengths (# of LEB128u operands) */
1969 saa_write8(plines,0); /* Std opcode 1 length */
1970 saa_write8(plines,1); /* Std opcode 2 length */
1971 saa_write8(plines,1); /* Std opcode 3 length */
1972 saa_write8(plines,1); /* Std opcode 4 length */
1973 saa_write8(plines,1); /* Std opcode 5 length */
1974 saa_write8(plines,0); /* Std opcode 6 length */
1975 saa_write8(plines,0); /* Std opcode 7 length */
1976 saa_write8(plines,0); /* Std opcode 8 length */
1977 saa_write8(plines,1); /* Std opcode 9 length */
1978 saa_write8(plines,0); /* Std opcode 10 length */
1979 saa_write8(plines,0); /* Std opcode 11 length */
1980 saa_write8(plines,1); /* Std opcode 12 length */
1981 /* Directory Table */
1982 saa_write8(plines,0); /* End of table */
1983 /* File Name Table */
1984 ftentry = dwarf_flist;
1985 for (indx = 0; indx < dwarf_numfiles; indx++) {
1986 saa_wbytes(plines, ftentry->filename, (int32_t)(strlen(ftentry->filename) + 1));
1987 saa_write8(plines,0); /* directory LEB128u */
1988 saa_write8(plines,0); /* time LEB128u */
1989 saa_write8(plines,0); /* size LEB128u */
1990 ftentry = ftentry->next;
1992 saa_write8(plines,0); /* End of table */
1993 linepoff = plines->datalen;
1994 linelen = linepoff + totlen + 10;
1995 linebuf = pbuf = nasm_malloc(linelen);
1996 WRITELONG(pbuf,linelen-4); /* initial length */
1997 WRITESHORT(pbuf,3); /* dwarf version */
1998 WRITELONG(pbuf,linepoff); /* offset to line number program */
1999 /* write line header */
2000 saalen = linepoff;
2001 saa_rnbytes(plines, pbuf, saalen); /* read a given no. of bytes */
2002 pbuf += linepoff;
2003 saa_free(plines);
2004 /* concatonate line program ranges */
2005 linepoff += 13;
2006 plinesrel = saa_init(1L);
2007 psect = dwarf_fsect;
2008 for (indx = 0; indx < dwarf_nsections; indx++) {
2009 saa_write64(plinesrel, linepoff);
2010 saa_write64(plinesrel, ((uint64_t) (psect->section + 2) << 32) + R_X86_64_64);
2011 saa_write64(plinesrel, (uint64_t) 0);
2012 plinep = psect->psaa;
2013 saalen = plinep->datalen;
2014 saa_rnbytes(plinep, pbuf, saalen);
2015 pbuf += saalen;
2016 linepoff += saalen;
2017 saa_free(plinep);
2018 /* done with this entry */
2019 psect = psect->next;
2023 /* build rela.lines section */
2024 linerellen =saalen = plinesrel->datalen;
2025 linerelbuf = pbuf = nasm_malloc(linerellen);
2026 saa_rnbytes(plinesrel, pbuf, saalen);
2027 saa_free(plinesrel);
2029 /* build frame section */
2030 framelen = 4;
2031 framebuf = pbuf = nasm_malloc(framelen);
2032 WRITELONG(pbuf,framelen-4); /* initial length */
2034 /* build loc section */
2035 loclen = 16;
2036 locbuf = pbuf = nasm_malloc(loclen);
2037 WRITEDLONG(pbuf,0); /* null beginning offset */
2038 WRITEDLONG(pbuf,0); /* null ending offset */
2041 static void dwarf_cleanup(void)
2043 nasm_free(arangesbuf);
2044 nasm_free(arangesrelbuf);
2045 nasm_free(pubnamesbuf);
2046 nasm_free(infobuf);
2047 nasm_free(inforelbuf);
2048 nasm_free(abbrevbuf);
2049 nasm_free(linebuf);
2050 nasm_free(linerelbuf);
2051 nasm_free(framebuf);
2052 nasm_free(locbuf);
2055 static void dwarf_findfile(const char * fname)
2057 int finx;
2058 struct linelist *match;
2060 /* return if fname is current file name */
2061 if (dwarf_clist && !(strcmp(fname, dwarf_clist->filename)))
2062 return;
2064 /* search for match */
2065 match = 0;
2066 if (dwarf_flist) {
2067 match = dwarf_flist;
2068 for (finx = 0; finx < dwarf_numfiles; finx++) {
2069 if (!(strcmp(fname, match->filename))) {
2070 dwarf_clist = match;
2071 return;
2076 /* add file name to end of list */
2077 dwarf_clist = (struct linelist *)nasm_malloc(sizeof(struct linelist));
2078 dwarf_numfiles++;
2079 dwarf_clist->line = dwarf_numfiles;
2080 dwarf_clist->filename = nasm_malloc(strlen(fname) + 1);
2081 strcpy(dwarf_clist->filename,fname);
2082 dwarf_clist->next = 0;
2083 if (!dwarf_flist) { /* if first entry */
2084 dwarf_flist = dwarf_elist = dwarf_clist;
2085 dwarf_clist->last = 0;
2086 } else { /* chain to previous entry */
2087 dwarf_elist->next = dwarf_clist;
2088 dwarf_elist = dwarf_clist;
2092 static void dwarf_findsect(const int index)
2094 int sinx;
2095 struct sectlist *match;
2096 struct SAA *plinep;
2098 /* return if index is current section index */
2099 if (dwarf_csect && (dwarf_csect->section == index))
2100 return;
2102 /* search for match */
2103 match = 0;
2104 if (dwarf_fsect) {
2105 match = dwarf_fsect;
2106 for (sinx = 0; sinx < dwarf_nsections; sinx++) {
2107 if (match->section == index) {
2108 dwarf_csect = match;
2109 return;
2111 match = match->next;
2115 /* add entry to end of list */
2116 dwarf_csect = (struct sectlist *)nasm_malloc(sizeof(struct sectlist));
2117 dwarf_nsections++;
2118 dwarf_csect->psaa = plinep = saa_init(1L);
2119 dwarf_csect->line = 1;
2120 dwarf_csect->offset = 0;
2121 dwarf_csect->file = 1;
2122 dwarf_csect->section = index;
2123 dwarf_csect->next = 0;
2124 /* set relocatable address at start of line program */
2125 saa_write8(plinep,DW_LNS_extended_op);
2126 saa_write8(plinep,9); /* operand length */
2127 saa_write8(plinep,DW_LNE_set_address);
2128 saa_write64(plinep,0); /* Start Address */
2130 if (!dwarf_fsect) { /* if first entry */
2131 dwarf_fsect = dwarf_esect = dwarf_csect;
2132 dwarf_csect->last = 0;
2133 } else { /* chain to previous entry */
2134 dwarf_esect->next = dwarf_csect;
2135 dwarf_esect = dwarf_csect;
2139 #endif /* OF_ELF */