NASM 2.15rc9
[nasm.git] / output / outelf.c
blob8af0f1206938178e689fae88b0037070c67afd0e
1 /* ----------------------------------------------------------------------- *
3 * Copyright 1996-2019 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 * Common code for outelf32 and outelf64
38 #include "compiler.h"
41 #include "nasm.h"
42 #include "nasmlib.h"
43 #include "error.h"
44 #include "saa.h"
45 #include "raa.h"
46 #include "stdscan.h"
47 #include "eval.h"
48 #include "outform.h"
49 #include "outlib.h"
50 #include "rbtree.h"
51 #include "hashtbl.h"
52 #include "ver.h"
54 #include "dwarf.h"
55 #include "stabs.h"
56 #include "outelf.h"
57 #include "elf.h"
59 #if defined(OF_ELF32) || defined(OF_ELF64) || defined(OF_ELFX32)
61 #define SECT_DELTA 32
62 static struct elf_section **sects;
63 static int nsects, sectlen;
65 #define SHSTR_DELTA 256
66 static char *shstrtab;
67 static int shstrtablen, shstrtabsize;
69 static struct SAA *syms;
70 static uint32_t nlocals, nglobs, ndebugs; /* Symbol counts */
72 static int32_t def_seg;
74 static struct RAA *bsym;
76 static struct SAA *symtab, *symtab_shndx;
78 static struct SAA *strs;
79 static uint32_t strslen;
81 static struct RAA *section_by_index;
82 static struct hash_table section_by_name;
84 static struct elf_symbol *fwds;
86 static char elf_module[FILENAME_MAX];
88 extern const struct ofmt of_elf32;
89 extern const struct ofmt of_elf64;
90 extern const struct ofmt of_elfx32;
92 static struct ELF_SECTDATA {
93 void *data;
94 int64_t len;
95 bool is_saa;
96 } *elf_sects;
98 static int elf_nsect, nsections;
99 static int64_t elf_foffs;
101 static void elf_write(void);
102 static void elf_sect_write(struct elf_section *, const void *, size_t);
103 static void elf_sect_writeaddr(struct elf_section *, int64_t, size_t);
104 static void elf_section_header(int name, int type, uint64_t flags,
105 void *data, bool is_saa, uint64_t datalen,
106 int link, int info,
107 uint64_t align, uint64_t entsize);
108 static void elf_write_sections(void);
109 static size_t elf_build_symtab(void);
110 static int add_sectname(const char *, const char *);
112 /* First debugging section index */
113 static int sec_debug;
115 struct erel {
116 int offset;
117 int info;
120 struct symlininfo {
121 int offset;
122 int section; /* index into sects[] */
123 int segto; /* internal section number */
124 char *name; /* shallow-copied pointer of section name */
127 struct linelist {
128 struct linelist *next;
129 struct linelist *last;
130 struct symlininfo info;
131 char *filename;
132 int line;
135 struct sectlist {
136 struct SAA *psaa;
137 int section;
138 int line;
139 int offset;
140 int file;
141 struct sectlist *next;
142 struct sectlist *last;
145 /* common debug variables */
146 static int currentline = 1;
147 static int debug_immcall = 0;
149 /* stabs debug variables */
150 static struct linelist *stabslines = 0;
151 static int numlinestabs = 0;
152 static char *stabs_filename = 0;
153 static uint8_t *stabbuf = 0, *stabstrbuf = 0, *stabrelbuf = 0;
154 static int stablen, stabstrlen, stabrellen;
156 /* dwarf debug variables */
157 static struct linelist *dwarf_flist = 0, *dwarf_clist = 0, *dwarf_elist = 0;
158 static struct sectlist *dwarf_fsect = 0, *dwarf_csect = 0, *dwarf_esect = 0;
159 static int dwarf_numfiles = 0, dwarf_nsections;
160 static uint8_t *arangesbuf = 0, *arangesrelbuf = 0, *pubnamesbuf = 0, *infobuf = 0, *inforelbuf = 0,
161 *abbrevbuf = 0, *linebuf = 0, *linerelbuf = 0, *framebuf = 0, *locbuf = 0;
162 static int8_t line_base = -5, line_range = 14, opcode_base = 13;
163 static int arangeslen, arangesrellen, pubnameslen, infolen, inforellen,
164 abbrevlen, linelen, linerellen, framelen, loclen;
165 static int64_t dwarf_infosym, dwarf_abbrevsym, dwarf_linesym;
167 static struct elf_symbol *lastsym;
169 /* common debugging routines */
170 static void debug_typevalue(int32_t);
172 /* stabs debugging routines */
173 static void stabs_linenum(const char *filename, int32_t linenumber, int32_t);
174 static void stabs_output(int, void *);
175 static void stabs_generate(void);
176 static void stabs_cleanup(void);
178 /* dwarf debugging routines */
179 static void dwarf_init(void);
180 static void dwarf_linenum(const char *filename, int32_t linenumber, int32_t);
181 static void dwarf_output(int, void *);
182 static void dwarf_generate(void);
183 static void dwarf_cleanup(void);
184 static void dwarf_findfile(const char *);
185 static void dwarf_findsect(const int);
187 struct elf_format_info {
188 size_t word; /* Word size (4 or 8) */
189 size_t ehdr_size; /* Size of the ELF header */
190 size_t shdr_size; /* Size of a section header */
191 size_t sym_size; /* Size of a symbol */
192 size_t rel_size; /* Size of a reltype relocation */
193 size_t rela_size; /* Size of a RELA relocation */
194 char relpfx[8]; /* Relocation section prefix */
195 uint32_t reltype; /* Relocation section type */
196 uint16_t e_machine; /* Header e_machine field */
197 uint8_t ei_class; /* ELFCLASS32 or ELFCLASS64 */
198 bool elf64; /* 64-bit ELF */
200 /* Write a symbol */
201 void (*elf_sym)(const struct elf_symbol *);
203 /* Build a relocation table */
204 struct SAA *(*elf_build_reltab)(const struct elf_reloc *);
206 static const struct elf_format_info *efmt;
208 static void elf32_sym(const struct elf_symbol *sym);
209 static void elf64_sym(const struct elf_symbol *sym);
211 static struct SAA *elf32_build_reltab(const struct elf_reloc *r);
212 static struct SAA *elfx32_build_reltab(const struct elf_reloc *r);
213 static struct SAA *elf64_build_reltab(const struct elf_reloc *r);
215 static bool dfmt_is_stabs(void);
216 static bool dfmt_is_dwarf(void);
219 * Special NASM section numbers which are used to define ELF special
220 * symbols.
222 static int32_t elf_gotpc_sect, elf_gotoff_sect;
223 static int32_t elf_got_sect, elf_plt_sect;
224 static int32_t elf_sym_sect, elf_gottpoff_sect, elf_tlsie_sect;
226 uint8_t elf_osabi = 0; /* Default OSABI = 0 (System V or Linux) */
227 uint8_t elf_abiver = 0; /* Current ABI version */
229 /* Known sections with nonstandard defaults. -n means n*pointer size. */
230 struct elf_known_section {
231 const char *name; /* Name of section */
232 int type; /* Section type (SHT_) */
233 uint32_t flags; /* Section flags (SHF_) */
234 int align; /* Section alignment */
235 int entsize; /* Entry size, if applicable */
238 static const struct elf_known_section elf_known_sections[] = {
239 { ".text", SHT_PROGBITS, SHF_ALLOC|SHF_EXECINSTR, 16, 0 },
240 { ".rodata", SHT_PROGBITS, SHF_ALLOC, 4, 0 },
241 { ".lrodata", SHT_PROGBITS, SHF_ALLOC, 4, 0 },
242 { ".data", SHT_PROGBITS, SHF_ALLOC|SHF_WRITE, 4, 0 },
243 { ".ldata", SHT_PROGBITS, SHF_ALLOC|SHF_WRITE, 4, 0 },
244 { ".bss", SHT_NOBITS, SHF_ALLOC|SHF_WRITE, 4, 0 },
245 { ".lbss", SHT_NOBITS, SHF_ALLOC|SHF_WRITE, 4, 0 },
246 { ".tdata", SHT_PROGBITS, SHF_ALLOC|SHF_WRITE|SHF_TLS, 4, 0 },
247 { ".tbss", SHT_NOBITS, SHF_ALLOC|SHF_WRITE|SHF_TLS, 4, 0 },
248 { ".comment", SHT_PROGBITS, 0, 1, 0 },
249 { ".preinit_array", SHT_PREINIT_ARRAY, SHF_ALLOC, -1, -1 },
250 { ".init_array", SHT_INIT_ARRAY, SHF_ALLOC, -1, -1 },
251 { ".fini_array", SHT_FINI_ARRAY, SHF_ALLOC, -1, -1 },
252 { ".note", SHT_NOTE, 0, 4, 0 },
253 { NULL /*default*/, SHT_PROGBITS, SHF_ALLOC, 1, 0 }
256 struct size_unit {
257 char name[8];
258 int bytes;
259 int align;
261 static const struct size_unit size_units[] =
263 { "byte", 1, 1 },
264 { "word", 2, 2 },
265 { "dword", 4, 4 },
266 { "qword", 8, 8 },
267 { "tword", 10, 2 },
268 { "tbyte", 10, 2 },
269 { "oword", 16, 16 },
270 { "xword", 16, 16 },
271 { "yword", 32, 32 },
272 { "zword", 64, 64 },
273 { "pointer", -1, -1 },
274 { "", 0, 0 }
277 static inline size_t to_bytes(int val)
279 return (val >= 0) ? (size_t)val : -val * efmt->word;
282 /* parse section attributes */
283 static void elf_section_attrib(char *name, char *attr, uint32_t *flags_and, uint32_t *flags_or,
284 uint64_t *alignp, uint64_t *entsize, int *type)
286 char *opt, *val, *next;
287 uint64_t align = 0;
288 uint64_t xalign = 0;
290 opt = nasm_skip_spaces(attr);
291 if (!opt || !*opt)
292 return;
294 while ((opt = nasm_opt_val(opt, &val, &next))) {
295 if (!nasm_stricmp(opt, "align")) {
296 if (!val) {
297 nasm_nonfatal("section align without value specified");
298 } else {
299 bool err;
300 uint64_t a = readnum(val, &err);
301 if (a && !is_power2(a)) {
302 nasm_error(ERR_NONFATAL,
303 "section alignment %"PRId64" is not a power of two",
305 } else if (a > align) {
306 align = a;
309 } else if (!nasm_stricmp(opt, "alloc")) {
310 *flags_and |= SHF_ALLOC;
311 *flags_or |= SHF_ALLOC;
312 } else if (!nasm_stricmp(opt, "noalloc")) {
313 *flags_and |= SHF_ALLOC;
314 *flags_or &= ~SHF_ALLOC;
315 } else if (!nasm_stricmp(opt, "exec")) {
316 *flags_and |= SHF_EXECINSTR;
317 *flags_or |= SHF_EXECINSTR;
318 } else if (!nasm_stricmp(opt, "noexec")) {
319 *flags_and |= SHF_EXECINSTR;
320 *flags_or &= ~SHF_EXECINSTR;
321 } else if (!nasm_stricmp(opt, "write")) {
322 *flags_and |= SHF_WRITE;
323 *flags_or |= SHF_WRITE;
324 } else if (!nasm_stricmp(opt, "nowrite") ||
325 !nasm_stricmp(opt, "readonly")) {
326 *flags_and |= SHF_WRITE;
327 *flags_or &= ~SHF_WRITE;
328 } else if (!nasm_stricmp(opt, "tls")) {
329 *flags_and |= SHF_TLS;
330 *flags_or |= SHF_TLS;
331 } else if (!nasm_stricmp(opt, "notls")) {
332 *flags_and |= SHF_TLS;
333 *flags_or &= ~SHF_TLS;
334 } else if (!nasm_stricmp(opt, "merge")) {
335 *flags_and |= SHF_MERGE;
336 *flags_or |= SHF_MERGE;
337 } else if (!nasm_stricmp(opt, "nomerge")) {
338 *flags_and |= SHF_MERGE;
339 *flags_or &= ~SHF_MERGE;
340 } else if (!nasm_stricmp(opt, "strings")) {
341 *flags_and |= SHF_STRINGS;
342 *flags_or |= SHF_STRINGS;
343 } else if (!nasm_stricmp(opt, "nostrings")) {
344 *flags_and |= SHF_STRINGS;
345 *flags_or &= ~SHF_STRINGS;
346 } else if (!nasm_stricmp(opt, "progbits")) {
347 *type = SHT_PROGBITS;
348 } else if (!nasm_stricmp(opt, "nobits")) {
349 *type = SHT_NOBITS;
350 } else if (!nasm_stricmp(opt, "note")) {
351 *type = SHT_NOTE;
352 } else if (!nasm_stricmp(opt, "preinit_array")) {
353 *type = SHT_PREINIT_ARRAY;
354 } else if (!nasm_stricmp(opt, "init_array")) {
355 *type = SHT_INIT_ARRAY;
356 } else if (!nasm_stricmp(opt, "fini_array")) {
357 *type = SHT_FINI_ARRAY;
358 } else {
359 uint64_t mult;
360 size_t l;
361 const char *a = strchr(opt, '*');
362 bool err;
363 const struct size_unit *su;
365 if (a) {
366 l = a - opt - 1;
367 mult = readnum(a+1, &err);
368 } else {
369 l = strlen(opt);
370 mult = 1;
373 for (su = size_units; su->bytes; su++) {
374 if (!nasm_strnicmp(opt, su->name, l))
375 break;
378 if (su->bytes) {
379 *entsize = to_bytes(su->bytes) * mult;
380 xalign = to_bytes(su->align);
381 } else {
382 /* Unknown attribute */
383 nasm_warn(WARN_OTHER,
384 "unknown section attribute '%s' ignored on"
385 " declaration of section `%s'", opt, name);
388 opt = next;
391 switch (*type) {
392 case SHT_PREINIT_ARRAY:
393 case SHT_INIT_ARRAY:
394 case SHT_FINI_ARRAY:
395 if (!xalign)
396 xalign = efmt->word;
397 if (!*entsize)
398 *entsize = efmt->word;
399 break;
400 default:
401 break;
404 if (!align)
405 align = xalign;
406 if (!align)
407 align = SHA_ANY;
409 *alignp = align;
412 static enum directive_result
413 elf_directive(enum directive directive, char *value)
415 int64_t n;
416 bool err;
417 char *p;
419 switch (directive) {
420 case D_OSABI:
421 if (!pass_first()) /* XXX: Why? */
422 return DIRR_OK;
424 n = readnum(value, &err);
425 if (err) {
426 nasm_nonfatal("`osabi' directive requires a parameter");
427 return DIRR_ERROR;
430 if (n < 0 || n > 255) {
431 nasm_nonfatal("valid osabi numbers are 0 to 255");
432 return DIRR_ERROR;
435 elf_osabi = n;
436 elf_abiver = 0;
438 p = strchr(value,',');
439 if (!p)
440 return DIRR_OK;
442 n = readnum(p + 1, &err);
443 if (err || n < 0 || n > 255) {
444 nasm_nonfatal("invalid ABI version number (valid: 0 to 255)");
445 return DIRR_ERROR;
448 elf_abiver = n;
449 return DIRR_OK;
451 default:
452 return DIRR_UNKNOWN;
456 static void elf_init(void);
458 static void elf32_init(void)
460 static const struct elf_format_info ef_elf32 = {
462 sizeof(Elf32_Ehdr),
463 sizeof(Elf32_Shdr),
464 sizeof(Elf32_Sym),
465 sizeof(Elf32_Rel),
466 sizeof(Elf32_Rela),
467 ".rel",
468 SHT_REL,
469 EM_386,
470 ELFCLASS32,
471 false,
473 elf32_sym,
474 elf32_build_reltab
476 efmt = &ef_elf32;
477 elf_init();
480 static void elfx32_init(void)
482 static const struct elf_format_info ef_elfx32 = {
484 sizeof(Elf32_Ehdr),
485 sizeof(Elf32_Shdr),
486 sizeof(Elf32_Sym),
487 sizeof(Elf32_Rela),
488 sizeof(Elf32_Rela),
489 ".rela",
490 SHT_RELA,
491 EM_X86_64,
492 ELFCLASS32,
493 false,
495 elf32_sym,
496 elfx32_build_reltab
498 efmt = &ef_elfx32;
499 elf_init();
502 static void elf64_init(void)
504 static const struct elf_format_info ef_elf64 = {
506 sizeof(Elf64_Ehdr),
507 sizeof(Elf64_Shdr),
508 sizeof(Elf64_Sym),
509 sizeof(Elf64_Rela),
510 sizeof(Elf64_Rela),
511 ".rela",
512 SHT_RELA,
513 EM_X86_64,
514 ELFCLASS64,
515 true,
517 elf64_sym,
518 elf64_build_reltab
520 efmt = &ef_elf64;
521 elf_init();
524 static void elf_init(void)
526 static const char * const reserved_sections[] = {
527 ".shstrtab", ".strtab", ".symtab", ".symtab_shndx", NULL
529 const char * const *p;
531 strlcpy(elf_module, inname, sizeof(elf_module));
532 sects = NULL;
533 nsects = sectlen = 0;
534 syms = saa_init((int32_t)sizeof(struct elf_symbol));
535 nlocals = nglobs = ndebugs = 0;
536 bsym = raa_init();
537 strs = saa_init(1L);
538 saa_wbytes(strs, "\0", 1L);
539 saa_wbytes(strs, elf_module, strlen(elf_module)+1);
540 strslen = 2 + strlen(elf_module);
541 shstrtab = NULL;
542 shstrtablen = shstrtabsize = 0;;
543 add_sectname("", ""); /* SHN_UNDEF */
545 fwds = NULL;
547 section_by_index = raa_init();
550 * Add reserved section names to the section hash, with NULL
551 * as the data pointer
553 for (p = reserved_sections; *p; p++) {
554 struct hash_insert hi;
555 hash_find(&section_by_name, *p, &hi);
556 hash_add(&hi, *p, NULL);
560 * FIXME: tlsie is Elf32 only and
561 * gottpoff is Elfx32|64 only.
563 elf_gotpc_sect = seg_alloc();
564 backend_label("..gotpc", elf_gotpc_sect + 1, 0L);
565 elf_gotoff_sect = seg_alloc();
566 backend_label("..gotoff", elf_gotoff_sect + 1, 0L);
567 elf_got_sect = seg_alloc();
568 backend_label("..got", elf_got_sect + 1, 0L);
569 elf_plt_sect = seg_alloc();
570 backend_label("..plt", elf_plt_sect + 1, 0L);
571 elf_sym_sect = seg_alloc();
572 backend_label("..sym", elf_sym_sect + 1, 0L);
573 elf_gottpoff_sect = seg_alloc();
574 backend_label("..gottpoff", elf_gottpoff_sect + 1, 0L);
575 elf_tlsie_sect = seg_alloc();
576 backend_label("..tlsie", elf_tlsie_sect + 1, 0L);
578 def_seg = seg_alloc();
581 static void elf_cleanup(void)
583 struct elf_reloc *r;
584 int i;
586 elf_write();
587 for (i = 0; i < nsects; i++) {
588 if (sects[i]->type != SHT_NOBITS)
589 saa_free(sects[i]->data);
590 if (sects[i]->rel)
591 saa_free(sects[i]->rel);
592 while (sects[i]->head) {
593 r = sects[i]->head;
594 sects[i]->head = sects[i]->head->next;
595 nasm_free(r);
598 hash_free(&section_by_name);
599 raa_free(section_by_index);
600 nasm_free(sects);
601 saa_free(syms);
602 raa_free(bsym);
603 saa_free(strs);
604 dfmt->cleanup();
608 * Add entry to the elf .shstrtab section and increment nsections.
609 * Returns the section index for this new section.
611 * IMPORTANT: this needs to match the order the section headers are
612 * emitted.
614 static int add_sectname(const char *firsthalf, const char *secondhalf)
616 int l1 = strlen(firsthalf);
617 int l2 = strlen(secondhalf);
619 while (shstrtablen + l1 + l2 + 1 > shstrtabsize)
620 shstrtab = nasm_realloc(shstrtab, (shstrtabsize += SHSTR_DELTA));
622 memcpy(shstrtab + shstrtablen, firsthalf, l1);
623 shstrtablen += l1;
624 memcpy(shstrtab + shstrtablen, secondhalf, l2+1);
625 shstrtablen += l2 + 1;
627 return nsections++;
630 static struct elf_section *
631 elf_make_section(char *name, int type, int flags, uint64_t align)
633 struct elf_section *s;
635 s = nasm_zalloc(sizeof(*s));
637 if (type != SHT_NOBITS)
638 s->data = saa_init(1L);
639 s->tail = &s->head;
640 if (!strcmp(name, ".text"))
641 s->index = def_seg;
642 else
643 s->index = seg_alloc();
645 s->name = nasm_strdup(name);
646 s->type = type;
647 s->flags = flags;
648 s->align = align;
649 s->shndx = add_sectname("", name);
651 if (nsects >= sectlen)
652 sects = nasm_realloc(sects, (sectlen += SECT_DELTA) * sizeof(*sects));
653 sects[nsects++] = s;
655 return s;
658 static int32_t elf_section_names(char *name, int *bits)
660 char *p;
661 uint32_t flags, flags_and, flags_or;
662 uint64_t align, entsize;
663 void **hp;
664 struct elf_section *s;
665 struct hash_insert hi;
666 int type;
668 if (!name) {
669 *bits = ofmt->maxbits;
670 return def_seg;
673 p = nasm_skip_word(name);
674 if (*p)
675 *p++ = '\0';
676 flags_and = flags_or = type = align = entsize = 0;
678 elf_section_attrib(name, p, &flags_and, &flags_or, &align, &entsize, &type);
680 hp = hash_find(&section_by_name, name, &hi);
681 if (hp) {
682 s = *hp;
683 if (!s) {
684 nasm_nonfatal("attempt to redefine reserved section name `%s'", name);
685 return NO_SEG;
687 } else {
688 const struct elf_known_section *ks = elf_known_sections;
690 while (ks->name) {
691 if (!strcmp(name, ks->name))
692 break;
693 ks++;
696 type = type ? type : ks->type;
697 if (!align)
698 align = to_bytes(ks->align);
699 if (!entsize)
700 entsize = to_bytes(ks->entsize);
701 flags = (ks->flags & ~flags_and) | flags_or;
703 s = elf_make_section(name, type, flags, align);
704 hash_add(&hi, s->name, s);
705 section_by_index = raa_write_ptr(section_by_index, s->index >> 1, s);
708 if ((type && s->type != type)
709 || ((s->flags & flags_and) != flags_or)
710 || (entsize && s->entsize && entsize != s->entsize)) {
711 nasm_warn(WARN_OTHER, "incompatible section attributes ignored on"
712 " redeclaration of section `%s'", name);
715 if (align > s->align)
716 s->align = align;
718 if (entsize && !s->entsize)
719 s->entsize = entsize;
721 if ((flags_or & SHF_MERGE) && s->entsize == 0) {
722 if (!(s->flags & SHF_STRINGS))
723 nasm_nonfatal("section attribute merge specified without an entry size or `strings'");
724 s->entsize = 1;
727 return s->index;
730 static inline bool sym_type_local(int type)
732 return ELF32_ST_BIND(type) == STB_LOCAL;
735 static void elf_deflabel(char *name, int32_t segment, int64_t offset,
736 int is_global, char *special)
738 int pos = strslen;
739 struct elf_symbol *sym;
740 const char *spcword = nasm_skip_spaces(special);
741 int bind, type; /* st_info components */
742 const struct elf_section *sec = NULL;
744 if (debug_level(2)) {
745 nasm_debug(" elf_deflabel: %s, seg=%"PRIx32", off=%"PRIx64", is_global=%d, %s\n",
746 name, segment, offset, is_global, special);
749 if (name[0] == '.' && name[1] == '.' && name[2] != '@') {
751 * This is a NASM special symbol. We never allow it into
752 * the ELF symbol table, even if it's a valid one. If it
753 * _isn't_ a valid one, we should barf immediately.
755 * FIXME: tlsie is Elf32 only, and gottpoff is Elfx32|64 only.
757 if (strcmp(name, "..gotpc") && strcmp(name, "..gotoff") &&
758 strcmp(name, "..got") && strcmp(name, "..plt") &&
759 strcmp(name, "..sym") && strcmp(name, "..gottpoff") &&
760 strcmp(name, "..tlsie"))
761 nasm_nonfatal("unrecognised special symbol `%s'", name);
762 return;
765 if (is_global == 3) {
766 struct elf_symbol **s;
768 * Fix up a forward-reference symbol size from the first
769 * pass.
771 for (s = &fwds; *s; s = &(*s)->nextfwd)
772 if (!strcmp((*s)->name, name)) {
773 struct tokenval tokval;
774 expr *e;
775 char *p = nasm_skip_spaces(nasm_skip_word(special));
777 stdscan_reset();
778 stdscan_set(p);
779 tokval.t_type = TOKEN_INVALID;
780 e = evaluate(stdscan, NULL, &tokval, NULL, 1, NULL);
781 if (e) {
782 if (!is_simple(e))
783 nasm_nonfatal("cannot use relocatable"
784 " expression as symbol size");
785 else
786 (*s)->size = reloc_value(e);
790 * Remove it from the list of unresolved sizes.
792 nasm_free((*s)->name);
793 *s = (*s)->nextfwd;
794 return;
796 return; /* it wasn't an important one */
799 saa_wbytes(strs, name, (int32_t)(1 + strlen(name)));
800 strslen += 1 + strlen(name);
802 lastsym = sym = saa_wstruct(syms);
804 memset(&sym->symv, 0, sizeof(struct rbtree));
806 sym->strpos = pos;
807 bind = is_global ? STB_GLOBAL : STB_LOCAL;
808 type = STT_NOTYPE;
809 sym->other = STV_DEFAULT;
810 sym->size = 0;
811 if (segment == NO_SEG) {
812 sym->section = XSHN_ABS;
813 } else {
814 sym->section = XSHN_UNDEF;
815 if (segment == def_seg) {
816 /* we have to be sure at least text section is there */
817 int tempint;
818 if (segment != elf_section_names(".text", &tempint))
819 nasm_panic("strange segment conditions in ELF driver");
821 sec = raa_read_ptr(section_by_index, segment >> 1);
822 if (sec)
823 sym->section = sec->shndx;
826 if (is_global == 2) {
827 sym->size = offset;
828 sym->symv.key = 0;
829 sym->section = XSHN_COMMON;
831 * We have a common variable. Check the special text to see
832 * if it's a valid number and power of two; if so, store it
833 * as the alignment for the common variable.
835 * XXX: this should allow an expression.
837 if (spcword) {
838 bool err;
839 sym->symv.key = readnum(spcword, &err);
840 if (err)
841 nasm_nonfatal("alignment constraint `%s' is not a"
842 " valid number", special);
843 else if (!is_power2(sym->symv.key))
844 nasm_nonfatal("alignment constraint `%s' is not a"
845 " power of two", special);
846 spcword = nasm_skip_spaces(nasm_skip_word(spcword));
848 } else {
849 sym->symv.key = (sym->section == XSHN_UNDEF ? 0 : offset);
852 if (spcword && *spcword) {
853 const char *wend;
854 bool ok = true;
856 while (ok) {
857 size_t wlen;
858 wend = nasm_skip_word(spcword);
859 wlen = wend - spcword;
861 switch (wlen) {
862 case 4:
863 if (!nasm_strnicmp(spcword, "data", wlen))
864 type = STT_OBJECT;
865 else if (!nasm_strnicmp(spcword, "weak", wlen))
866 bind = STB_WEAK;
867 else
868 ok = false;
869 break;
871 case 6:
872 if (!nasm_strnicmp(spcword, "notype", wlen))
873 type = STT_NOTYPE;
874 else if (!nasm_strnicmp(spcword, "object", wlen))
875 type = STT_OBJECT;
876 else if (!nasm_strnicmp(spcword, "hidden", wlen))
877 sym->other = STV_HIDDEN;
878 else if (!nasm_strnicmp(spcword, "strong", wlen))
879 bind = STB_GLOBAL;
880 else
881 ok = false;
882 break;
884 case 7:
885 if (!nasm_strnicmp(spcword, "default", wlen))
886 sym->other = STV_DEFAULT;
887 else
888 ok = false;
889 break;
891 case 8:
892 if (!nasm_strnicmp(spcword, "function", wlen))
893 type = STT_FUNC;
894 else if (!nasm_stricmp(spcword, "internal"))
895 sym->other = STV_INTERNAL;
896 else
897 ok = false;
898 break;
900 case 9:
901 if (!nasm_strnicmp(spcword, "protected", wlen))
902 sym->other = STV_PROTECTED;
903 else
904 ok = false;
905 break;
907 default:
908 ok = false;
909 break;
912 if (ok)
913 spcword = nasm_skip_spaces(wend);
915 if (!is_global && bind != STB_LOCAL) {
916 nasm_nonfatal("weak and strong only applies to global symbols");
917 bind = STB_LOCAL;
920 if (spcword && *spcword) {
921 struct tokenval tokval;
922 expr *e;
923 int fwd = 0;
924 char *saveme = stdscan_get();
927 * We have a size expression; attempt to
928 * evaluate it.
930 stdscan_reset();
931 stdscan_set((char *)spcword);
932 tokval.t_type = TOKEN_INVALID;
933 e = evaluate(stdscan, NULL, &tokval, &fwd, 0, NULL);
934 if (fwd) {
935 sym->nextfwd = fwds;
936 fwds = sym;
937 sym->name = nasm_strdup(name);
938 } else if (e) {
939 if (!is_simple(e))
940 nasm_nonfatal("cannot use relocatable"
941 " expression as symbol size");
942 else
943 sym->size = reloc_value(e);
945 stdscan_set(saveme);
950 * If it is in a TLS segment, mark symbol accordingly.
952 if (sec && (sec->flags & SHF_TLS))
953 type = STT_TLS;
955 /* Note: ELF32_ST_INFO() and ELF64_ST_INFO() are identical */
956 sym->type = ELF32_ST_INFO(bind, type);
958 if (sym_type_local(sym->type)) {
959 nlocals++;
960 } else {
962 * If sym->section == SHN_ABS, then the first line of the
963 * else section would cause a core dump, because its a reference
964 * beyond the end of the section array.
965 * This behaviour is exhibited by this code:
966 * GLOBAL crash_nasm
967 * crash_nasm equ 0
968 * To avoid such a crash, such requests are silently discarded.
969 * This may not be the best solution.
971 if (sym->section == XSHN_UNDEF || sym->section == XSHN_COMMON) {
972 bsym = raa_write(bsym, segment, nglobs);
973 } else if (sym->section != XSHN_ABS) {
975 * This is a global symbol; so we must add it to the rbtree
976 * of global symbols in its section.
978 * In addition, we check the special text for symbol
979 * type and size information.
981 sects[sym->section-1]->gsyms =
982 rb_insert(sects[sym->section-1]->gsyms, &sym->symv);
985 sym->globnum = nglobs;
986 nglobs++;
990 static void elf_add_reloc(struct elf_section *sect, int32_t segment,
991 int64_t offset, int type)
993 struct elf_reloc *r;
995 r = *sect->tail = nasm_zalloc(sizeof(struct elf_reloc));
996 sect->tail = &r->next;
998 r->address = sect->len;
999 r->offset = offset;
1001 if (segment != NO_SEG) {
1002 const struct elf_section *s;
1003 s = raa_read_ptr(section_by_index, segment >> 1);
1004 if (s)
1005 r->symbol = s->shndx + 1;
1006 else
1007 r->symbol = GLOBAL_TEMP_BASE + raa_read(bsym, segment);
1009 r->type = type;
1011 sect->nrelocs++;
1015 * This routine deals with ..got and ..sym relocations: the more
1016 * complicated kinds. In shared-library writing, some relocations
1017 * with respect to global symbols must refer to the precise symbol
1018 * rather than referring to an offset from the base of the section
1019 * _containing_ the symbol. Such relocations call to this routine,
1020 * which searches the symbol list for the symbol in question.
1022 * R_386_GOT32 | R_X86_64_GOT32 references require the _exact_ symbol address to be
1023 * used; R_386_32 | R_X86_64_32 references can be at an offset from the symbol.
1024 * The boolean argument `exact' tells us this.
1026 * Return value is the adjusted value of `addr', having become an
1027 * offset from the symbol rather than the section. Should always be
1028 * zero when returning from an exact call.
1030 * Limitation: if you define two symbols at the same place,
1031 * confusion will occur.
1033 * Inefficiency: we search, currently, using a linked list which
1034 * isn't even necessarily sorted.
1036 static int64_t elf_add_gsym_reloc(struct elf_section *sect,
1037 int32_t segment, uint64_t offset,
1038 int64_t pcrel, int type, bool exact)
1040 struct elf_reloc *r;
1041 struct elf_section *s;
1042 struct elf_symbol *sym;
1043 struct rbtree *srb;
1046 * First look up the segment/offset pair and find a global
1047 * symbol corresponding to it. If it's not one of our segments,
1048 * then it must be an external symbol, in which case we're fine
1049 * doing a normal elf_add_reloc after first sanity-checking
1050 * that the offset from the symbol is zero.
1052 s = raa_read_ptr(section_by_index, segment >> 1);
1053 if (!s) {
1054 if (exact && offset)
1055 nasm_nonfatal("invalid access to an external symbol");
1056 else
1057 elf_add_reloc(sect, segment, offset - pcrel, type);
1058 return 0;
1061 srb = rb_search(s->gsyms, offset);
1062 if (!srb || (exact && srb->key != offset)) {
1063 nasm_nonfatal("unable to find a suitable global symbol"
1064 " for this reference");
1065 return 0;
1067 sym = container_of(srb, struct elf_symbol, symv);
1069 r = *sect->tail = nasm_malloc(sizeof(struct elf_reloc));
1070 sect->tail = &r->next;
1072 r->next = NULL;
1073 r->address = sect->len;
1074 r->offset = offset - pcrel - sym->symv.key;
1075 r->symbol = GLOBAL_TEMP_BASE + sym->globnum;
1076 r->type = type;
1078 sect->nrelocs++;
1079 return r->offset;
1082 static void elf32_out(int32_t segto, const void *data,
1083 enum out_type type, uint64_t size,
1084 int32_t segment, int32_t wrt)
1086 struct elf_section *s;
1087 int64_t addr;
1088 int reltype, bytes;
1089 static struct symlininfo sinfo;
1092 * handle absolute-assembly (structure definitions)
1094 if (segto == NO_SEG) {
1095 if (type != OUT_RESERVE)
1096 nasm_nonfatal("attempt to assemble code in [ABSOLUTE] space");
1097 return;
1100 s = raa_read_ptr(section_by_index, segto >> 1);
1101 if (!s) {
1102 int tempint; /* ignored */
1103 if (segto != elf_section_names(".text", &tempint))
1104 nasm_panic("strange segment conditions in ELF driver");
1105 else
1106 s = sects[nsects - 1];
1109 /* again some stabs debugging stuff */
1110 sinfo.offset = s->len;
1111 /* Adjust to an index of the section table. */
1112 sinfo.section = s->shndx - 1;
1113 sinfo.segto = segto;
1114 sinfo.name = s->name;
1115 dfmt->debug_output(TY_DEBUGSYMLIN, &sinfo);
1116 /* end of debugging stuff */
1118 if (s->type == SHT_NOBITS && type != OUT_RESERVE) {
1119 nasm_warn(WARN_OTHER, "attempt to initialize memory in"
1120 " BSS section `%s': ignored", s->name);
1121 s->len += realsize(type, size);
1122 return;
1125 switch (type) {
1126 case OUT_RESERVE:
1127 if (s->type != SHT_NOBITS) {
1128 nasm_warn(WARN_ZEROING, "uninitialized space declared in"
1129 " non-BSS section `%s': zeroing", s->name);
1130 elf_sect_write(s, NULL, size);
1131 } else
1132 s->len += size;
1133 break;
1135 case OUT_RAWDATA:
1136 elf_sect_write(s, data, size);
1137 break;
1139 case OUT_ADDRESS:
1141 bool err = false;
1142 int asize = abs((int)size);
1144 addr = *(int64_t *)data;
1145 if (segment != NO_SEG) {
1146 if (segment & 1) {
1147 nasm_nonfatal("ELF format does not support"
1148 " segment base references");
1149 } else {
1150 if (wrt == NO_SEG) {
1152 * The if() is a hack to deal with compilers which
1153 * don't handle switch() statements with 64-bit
1154 * expressions.
1156 switch (asize) {
1157 case 1:
1158 elf_add_reloc(s, segment, 0, R_386_8);
1159 break;
1160 case 2:
1161 elf_add_reloc(s, segment, 0, R_386_16);
1162 break;
1163 case 4:
1164 elf_add_reloc(s, segment, 0, R_386_32);
1165 break;
1166 default: /* Error issued further down */
1167 err = true;
1168 break;
1170 } else if (wrt == elf_gotpc_sect + 1) {
1172 * The user will supply GOT relative to $$. ELF
1173 * will let us have GOT relative to $. So we
1174 * need to fix up the data item by $-$$.
1176 err = asize != 4;
1177 addr += s->len;
1178 elf_add_reloc(s, segment, 0, R_386_GOTPC);
1179 } else if (wrt == elf_gotoff_sect + 1) {
1180 err = asize != 4;
1181 elf_add_reloc(s, segment, 0, R_386_GOTOFF);
1182 } else if (wrt == elf_tlsie_sect + 1) {
1183 err = asize != 4;
1184 addr = elf_add_gsym_reloc(s, segment, addr, 0,
1185 R_386_TLS_IE, true);
1186 } else if (wrt == elf_got_sect + 1) {
1187 err = asize != 4;
1188 addr = elf_add_gsym_reloc(s, segment, addr, 0,
1189 R_386_GOT32, true);
1190 } else if (wrt == elf_sym_sect + 1) {
1191 switch (asize) {
1192 case 1:
1193 addr = elf_add_gsym_reloc(s, segment, addr, 0,
1194 R_386_8, false);
1195 break;
1196 case 2:
1197 addr = elf_add_gsym_reloc(s, segment, addr, 0,
1198 R_386_16, false);
1199 break;
1200 case 4:
1201 addr = elf_add_gsym_reloc(s, segment, addr, 0,
1202 R_386_32, false);
1203 break;
1204 default:
1205 err = true;
1206 break;
1208 } else if (wrt == elf_plt_sect + 1) {
1209 nasm_nonfatal("ELF format cannot produce non-PC-"
1210 "relative PLT references");
1211 } else {
1212 nasm_nonfatal("ELF format does not support this"
1213 " use of WRT");
1214 wrt = NO_SEG; /* we can at least _try_ to continue */
1219 if (err) {
1220 nasm_nonfatal("Unsupported %d-bit ELF relocation", asize << 3);
1222 elf_sect_writeaddr(s, addr, asize);
1223 break;
1226 case OUT_REL1ADR:
1227 reltype = R_386_PC8;
1228 bytes = 1;
1229 goto rel12adr;
1230 case OUT_REL2ADR:
1231 reltype = R_386_PC16;
1232 bytes = 2;
1233 goto rel12adr;
1235 rel12adr:
1236 addr = *(int64_t *)data - size;
1237 nasm_assert(segment != segto);
1238 if (segment != NO_SEG && (segment & 1)) {
1239 nasm_nonfatal("ELF format does not support"
1240 " segment base references");
1241 } else {
1242 if (wrt == NO_SEG) {
1243 elf_add_reloc(s, segment, 0, reltype);
1244 } else {
1245 nasm_nonfatal("Unsupported %d-bit ELF relocation", bytes << 3);
1248 elf_sect_writeaddr(s, addr, bytes);
1249 break;
1251 case OUT_REL4ADR:
1252 addr = *(int64_t *)data - size;
1253 if (segment == segto)
1254 nasm_panic("intra-segment OUT_REL4ADR");
1255 if (segment != NO_SEG && (segment & 1)) {
1256 nasm_nonfatal("ELF format does not support"
1257 " segment base references");
1258 } else {
1259 if (wrt == NO_SEG) {
1260 elf_add_reloc(s, segment, 0, R_386_PC32);
1261 } else if (wrt == elf_plt_sect + 1) {
1262 elf_add_reloc(s, segment, 0, R_386_PLT32);
1263 } else if (wrt == elf_gotpc_sect + 1 ||
1264 wrt == elf_gotoff_sect + 1 ||
1265 wrt == elf_got_sect + 1) {
1266 nasm_nonfatal("ELF format cannot produce PC-"
1267 "relative GOT references");
1268 } else {
1269 nasm_nonfatal("ELF format does not support this"
1270 " use of WRT");
1271 wrt = NO_SEG; /* we can at least _try_ to continue */
1274 elf_sect_writeaddr(s, addr, 4);
1275 break;
1277 case OUT_REL8ADR:
1278 nasm_nonfatal("32-bit ELF format does not support 64-bit relocations");
1279 addr = 0;
1280 elf_sect_writeaddr(s, addr, 8);
1281 break;
1283 default:
1284 panic();
1287 static void elf64_out(int32_t segto, const void *data,
1288 enum out_type type, uint64_t size,
1289 int32_t segment, int32_t wrt)
1291 struct elf_section *s;
1292 int64_t addr;
1293 int reltype, bytes;
1294 static struct symlininfo sinfo;
1297 * handle absolute-assembly (structure definitions)
1299 if (segto == NO_SEG) {
1300 if (type != OUT_RESERVE)
1301 nasm_nonfatal("attempt to assemble code in [ABSOLUTE] space");
1302 return;
1305 s = raa_read_ptr(section_by_index, segto >> 1);
1306 if (!s) {
1307 int tempint; /* ignored */
1308 if (segto != elf_section_names(".text", &tempint))
1309 nasm_panic("strange segment conditions in ELF driver");
1310 else
1311 s = sects[nsects - 1];
1314 /* again some stabs debugging stuff */
1315 sinfo.offset = s->len;
1316 /* Adjust to an index of the section table. */
1317 sinfo.section = s->shndx - 1;
1318 sinfo.segto = segto;
1319 sinfo.name = s->name;
1320 dfmt->debug_output(TY_DEBUGSYMLIN, &sinfo);
1321 /* end of debugging stuff */
1323 if (s->type == SHT_NOBITS && type != OUT_RESERVE) {
1324 nasm_warn(WARN_OTHER, "attempt to initialize memory in"
1325 " BSS section `%s': ignored", s->name);
1326 s->len += realsize(type, size);
1327 return;
1330 switch (type) {
1331 case OUT_RESERVE:
1332 if (s->type != SHT_NOBITS) {
1333 nasm_warn(WARN_ZEROING, "uninitialized space declared in"
1334 " non-BSS section `%s': zeroing", s->name);
1335 elf_sect_write(s, NULL, size);
1336 } else
1337 s->len += size;
1338 break;
1340 case OUT_RAWDATA:
1341 if (segment != NO_SEG)
1342 nasm_panic("OUT_RAWDATA with other than NO_SEG");
1343 elf_sect_write(s, data, size);
1344 break;
1346 case OUT_ADDRESS:
1348 int isize = (int)size;
1349 int asize = abs((int)size);
1351 addr = *(int64_t *)data;
1352 if (segment == NO_SEG) {
1353 /* Do nothing */
1354 } else if (segment & 1) {
1355 nasm_nonfatal("ELF format does not support"
1356 " segment base references");
1357 } else {
1358 if (wrt == NO_SEG) {
1359 switch (isize) {
1360 case 1:
1361 case -1:
1362 elf_add_reloc(s, segment, addr, R_X86_64_8);
1363 break;
1364 case 2:
1365 case -2:
1366 elf_add_reloc(s, segment, addr, R_X86_64_16);
1367 break;
1368 case 4:
1369 elf_add_reloc(s, segment, addr, R_X86_64_32);
1370 break;
1371 case -4:
1372 elf_add_reloc(s, segment, addr, R_X86_64_32S);
1373 break;
1374 case 8:
1375 case -8:
1376 elf_add_reloc(s, segment, addr, R_X86_64_64);
1377 break;
1378 default:
1379 nasm_panic("internal error elf64-hpa-871");
1380 break;
1382 addr = 0;
1383 } else if (wrt == elf_gotpc_sect + 1) {
1385 * The user will supply GOT relative to $$. ELF
1386 * will let us have GOT relative to $. So we
1387 * need to fix up the data item by $-$$.
1389 addr += s->len;
1390 elf_add_reloc(s, segment, addr, R_X86_64_GOTPC32);
1391 addr = 0;
1392 } else if (wrt == elf_gotoff_sect + 1) {
1393 if (asize != 8) {
1394 nasm_nonfatal("ELF64 requires ..gotoff "
1395 "references to be qword");
1396 } else {
1397 elf_add_reloc(s, segment, addr, R_X86_64_GOTOFF64);
1398 addr = 0;
1400 } else if (wrt == elf_got_sect + 1) {
1401 switch (asize) {
1402 case 4:
1403 elf_add_gsym_reloc(s, segment, addr, 0,
1404 R_X86_64_GOT32, true);
1405 addr = 0;
1406 break;
1407 case 8:
1408 elf_add_gsym_reloc(s, segment, addr, 0,
1409 R_X86_64_GOT64, true);
1410 addr = 0;
1411 break;
1412 default:
1413 nasm_nonfatal("invalid ..got reference");
1414 break;
1416 } else if (wrt == elf_sym_sect + 1) {
1417 switch (isize) {
1418 case 1:
1419 case -1:
1420 elf_add_gsym_reloc(s, segment, addr, 0,
1421 R_X86_64_8, false);
1422 addr = 0;
1423 break;
1424 case 2:
1425 case -2:
1426 elf_add_gsym_reloc(s, segment, addr, 0,
1427 R_X86_64_16, false);
1428 addr = 0;
1429 break;
1430 case 4:
1431 elf_add_gsym_reloc(s, segment, addr, 0,
1432 R_X86_64_32, false);
1433 addr = 0;
1434 break;
1435 case -4:
1436 elf_add_gsym_reloc(s, segment, addr, 0,
1437 R_X86_64_32S, false);
1438 addr = 0;
1439 break;
1440 case 8:
1441 case -8:
1442 elf_add_gsym_reloc(s, segment, addr, 0,
1443 R_X86_64_64, false);
1444 addr = 0;
1445 break;
1446 default:
1447 nasm_panic("internal error elf64-hpa-903");
1448 break;
1450 } else if (wrt == elf_plt_sect + 1) {
1451 nasm_nonfatal("ELF format cannot produce non-PC-"
1452 "relative PLT references");
1453 } else {
1454 nasm_nonfatal("ELF format does not support this"
1455 " use of WRT");
1458 elf_sect_writeaddr(s, addr, asize);
1459 break;
1462 case OUT_REL1ADR:
1463 reltype = R_X86_64_PC8;
1464 bytes = 1;
1465 goto rel12adr;
1467 case OUT_REL2ADR:
1468 reltype = R_X86_64_PC16;
1469 bytes = 2;
1470 goto rel12adr;
1472 rel12adr:
1473 addr = *(int64_t *)data - size;
1474 if (segment == segto)
1475 nasm_panic("intra-segment OUT_REL1ADR");
1476 if (segment == NO_SEG) {
1477 /* Do nothing */
1478 } else if (segment & 1) {
1479 nasm_nonfatal("ELF format does not support"
1480 " segment base references");
1481 } else {
1482 if (wrt == NO_SEG) {
1483 elf_add_reloc(s, segment, addr, reltype);
1484 addr = 0;
1485 } else {
1486 nasm_nonfatal("Unsupported %d-bit ELF relocation", bytes << 3);
1489 elf_sect_writeaddr(s, addr, bytes);
1490 break;
1492 case OUT_REL4ADR:
1493 addr = *(int64_t *)data - size;
1494 if (segment == segto)
1495 nasm_panic("intra-segment OUT_REL4ADR");
1496 if (segment == NO_SEG) {
1497 /* Do nothing */
1498 } else if (segment & 1) {
1499 nasm_nonfatal("ELF64 format does not support"
1500 " segment base references");
1501 } else {
1502 if (wrt == NO_SEG) {
1503 elf_add_reloc(s, segment, addr, R_X86_64_PC32);
1504 addr = 0;
1505 } else if (wrt == elf_plt_sect + 1) {
1506 elf_add_gsym_reloc(s, segment, addr+size, size,
1507 R_X86_64_PLT32, true);
1508 addr = 0;
1509 } else if (wrt == elf_gotpc_sect + 1 ||
1510 wrt == elf_got_sect + 1) {
1511 elf_add_gsym_reloc(s, segment, addr+size, size,
1512 R_X86_64_GOTPCREL, true);
1513 addr = 0;
1514 } else if (wrt == elf_gotoff_sect + 1 ||
1515 wrt == elf_got_sect + 1) {
1516 nasm_nonfatal("ELF64 requires ..gotoff references to be "
1517 "qword absolute");
1518 } else if (wrt == elf_gottpoff_sect + 1) {
1519 elf_add_gsym_reloc(s, segment, addr+size, size,
1520 R_X86_64_GOTTPOFF, true);
1521 addr = 0;
1522 } else {
1523 nasm_nonfatal("ELF64 format does not support this"
1524 " use of WRT");
1527 elf_sect_writeaddr(s, addr, 4);
1528 break;
1530 case OUT_REL8ADR:
1531 addr = *(int64_t *)data - size;
1532 if (segment == segto)
1533 nasm_panic("intra-segment OUT_REL8ADR");
1534 if (segment == NO_SEG) {
1535 /* Do nothing */
1536 } else if (segment & 1) {
1537 nasm_nonfatal("ELF64 format does not support"
1538 " segment base references");
1539 } else {
1540 if (wrt == NO_SEG) {
1541 elf_add_reloc(s, segment, addr, R_X86_64_PC64);
1542 addr = 0;
1543 } else if (wrt == elf_gotpc_sect + 1 ||
1544 wrt == elf_got_sect + 1) {
1545 elf_add_gsym_reloc(s, segment, addr+size, size,
1546 R_X86_64_GOTPCREL64, true);
1547 addr = 0;
1548 } else if (wrt == elf_gotoff_sect + 1 ||
1549 wrt == elf_got_sect + 1) {
1550 nasm_nonfatal("ELF64 requires ..gotoff references to be "
1551 "absolute");
1552 } else if (wrt == elf_gottpoff_sect + 1) {
1553 nasm_nonfatal("ELF64 requires ..gottpoff references to be "
1554 "dword");
1555 } else {
1556 nasm_nonfatal("ELF64 format does not support this"
1557 " use of WRT");
1560 elf_sect_writeaddr(s, addr, 8);
1561 break;
1563 default:
1564 panic();
1568 static void elfx32_out(int32_t segto, const void *data,
1569 enum out_type type, uint64_t size,
1570 int32_t segment, int32_t wrt)
1572 struct elf_section *s;
1573 int64_t addr;
1574 int reltype, bytes;
1575 static struct symlininfo sinfo;
1578 * handle absolute-assembly (structure definitions)
1580 if (segto == NO_SEG) {
1581 if (type != OUT_RESERVE)
1582 nasm_nonfatal("attempt to assemble code in [ABSOLUTE] space");
1583 return;
1586 s = raa_read_ptr(section_by_index, segto >> 1);
1587 if (!s) {
1588 int tempint; /* ignored */
1589 if (segto != elf_section_names(".text", &tempint))
1590 nasm_panic("strange segment conditions in ELF driver");
1591 else
1592 s = sects[nsects - 1];
1595 /* again some stabs debugging stuff */
1596 sinfo.offset = s->len;
1597 /* Adjust to an index of the section table. */
1598 sinfo.section = s->shndx - 1;
1599 sinfo.segto = segto;
1600 sinfo.name = s->name;
1601 dfmt->debug_output(TY_DEBUGSYMLIN, &sinfo);
1602 /* end of debugging stuff */
1604 if (s->type == SHT_NOBITS && type != OUT_RESERVE) {
1605 nasm_warn(WARN_OTHER, "attempt to initialize memory in"
1606 " BSS section `%s': ignored", s->name);
1607 s->len += realsize(type, size);
1608 return;
1611 switch (type) {
1612 case OUT_RESERVE:
1613 if (s->type != SHT_NOBITS) {
1614 nasm_warn(WARN_ZEROING, "uninitialized space declared in"
1615 " non-BSS section `%s': zeroing", s->name);
1616 elf_sect_write(s, NULL, size);
1617 } else
1618 s->len += size;
1619 break;
1621 case OUT_RAWDATA:
1622 if (segment != NO_SEG)
1623 nasm_panic("OUT_RAWDATA with other than NO_SEG");
1624 elf_sect_write(s, data, size);
1625 break;
1627 case OUT_ADDRESS:
1629 int isize = (int)size;
1630 int asize = abs((int)size);
1632 addr = *(int64_t *)data;
1633 if (segment == NO_SEG) {
1634 /* Do nothing */
1635 } else if (segment & 1) {
1636 nasm_nonfatal("ELF format does not support"
1637 " segment base references");
1638 } else {
1639 if (wrt == NO_SEG) {
1640 switch (isize) {
1641 case 1:
1642 case -1:
1643 elf_add_reloc(s, segment, addr, R_X86_64_8);
1644 break;
1645 case 2:
1646 case -2:
1647 elf_add_reloc(s, segment, addr, R_X86_64_16);
1648 break;
1649 case 4:
1650 elf_add_reloc(s, segment, addr, R_X86_64_32);
1651 break;
1652 case -4:
1653 elf_add_reloc(s, segment, addr, R_X86_64_32S);
1654 break;
1655 case 8:
1656 case -8:
1657 elf_add_reloc(s, segment, addr, R_X86_64_64);
1658 break;
1659 default:
1660 nasm_panic("internal error elfx32-hpa-871");
1661 break;
1663 addr = 0;
1664 } else if (wrt == elf_gotpc_sect + 1) {
1666 * The user will supply GOT relative to $$. ELF
1667 * will let us have GOT relative to $. So we
1668 * need to fix up the data item by $-$$.
1670 addr += s->len;
1671 elf_add_reloc(s, segment, addr, R_X86_64_GOTPC32);
1672 addr = 0;
1673 } else if (wrt == elf_gotoff_sect + 1) {
1674 nasm_nonfatal("ELFX32 doesn't support "
1675 "R_X86_64_GOTOFF64");
1676 } else if (wrt == elf_got_sect + 1) {
1677 switch (asize) {
1678 case 4:
1679 elf_add_gsym_reloc(s, segment, addr, 0,
1680 R_X86_64_GOT32, true);
1681 addr = 0;
1682 break;
1683 default:
1684 nasm_nonfatal("invalid ..got reference");
1685 break;
1687 } else if (wrt == elf_sym_sect + 1) {
1688 switch (isize) {
1689 case 1:
1690 case -1:
1691 elf_add_gsym_reloc(s, segment, addr, 0,
1692 R_X86_64_8, false);
1693 addr = 0;
1694 break;
1695 case 2:
1696 case -2:
1697 elf_add_gsym_reloc(s, segment, addr, 0,
1698 R_X86_64_16, false);
1699 addr = 0;
1700 break;
1701 case 4:
1702 elf_add_gsym_reloc(s, segment, addr, 0,
1703 R_X86_64_32, false);
1704 addr = 0;
1705 break;
1706 case -4:
1707 elf_add_gsym_reloc(s, segment, addr, 0,
1708 R_X86_64_32S, false);
1709 addr = 0;
1710 break;
1711 case 8:
1712 case -8:
1713 elf_add_gsym_reloc(s, segment, addr, 0,
1714 R_X86_64_64, false);
1715 addr = 0;
1716 break;
1717 default:
1718 nasm_panic("internal error elfx32-hpa-903");
1719 break;
1721 } else if (wrt == elf_plt_sect + 1) {
1722 nasm_nonfatal("ELF format cannot produce non-PC-"
1723 "relative PLT references");
1724 } else {
1725 nasm_nonfatal("ELF format does not support this"
1726 " use of WRT");
1729 elf_sect_writeaddr(s, addr, asize);
1730 break;
1733 case OUT_REL1ADR:
1734 reltype = R_X86_64_PC8;
1735 bytes = 1;
1736 goto rel12adr;
1738 case OUT_REL2ADR:
1739 reltype = R_X86_64_PC16;
1740 bytes = 2;
1741 goto rel12adr;
1743 rel12adr:
1744 addr = *(int64_t *)data - size;
1745 if (segment == segto)
1746 nasm_panic("intra-segment OUT_REL1ADR");
1747 if (segment == NO_SEG) {
1748 /* Do nothing */
1749 } else if (segment & 1) {
1750 nasm_nonfatal("ELF format does not support"
1751 " segment base references");
1752 } else {
1753 if (wrt == NO_SEG) {
1754 elf_add_reloc(s, segment, addr, reltype);
1755 addr = 0;
1756 } else {
1757 nasm_nonfatal("unsupported %d-bit ELF relocation", bytes << 3);
1760 elf_sect_writeaddr(s, addr, bytes);
1761 break;
1763 case OUT_REL4ADR:
1764 addr = *(int64_t *)data - size;
1765 if (segment == segto)
1766 nasm_panic("intra-segment OUT_REL4ADR");
1767 if (segment == NO_SEG) {
1768 /* Do nothing */
1769 } else if (segment & 1) {
1770 nasm_nonfatal("ELFX32 format does not support"
1771 " segment base references");
1772 } else {
1773 if (wrt == NO_SEG) {
1774 elf_add_reloc(s, segment, addr, R_X86_64_PC32);
1775 addr = 0;
1776 } else if (wrt == elf_plt_sect + 1) {
1777 elf_add_gsym_reloc(s, segment, addr+size, size,
1778 R_X86_64_PLT32, true);
1779 addr = 0;
1780 } else if (wrt == elf_gotpc_sect + 1 ||
1781 wrt == elf_got_sect + 1) {
1782 elf_add_gsym_reloc(s, segment, addr+size, size,
1783 R_X86_64_GOTPCREL, true);
1784 addr = 0;
1785 } else if (wrt == elf_gotoff_sect + 1 ||
1786 wrt == elf_got_sect + 1) {
1787 nasm_nonfatal("invalid ..gotoff reference");
1788 } else if (wrt == elf_gottpoff_sect + 1) {
1789 elf_add_gsym_reloc(s, segment, addr+size, size,
1790 R_X86_64_GOTTPOFF, true);
1791 addr = 0;
1792 } else {
1793 nasm_nonfatal("ELFX32 format does not support this use of WRT");
1796 elf_sect_writeaddr(s, addr, 4);
1797 break;
1799 case OUT_REL8ADR:
1800 nasm_nonfatal("32-bit ELF format does not support 64-bit relocations");
1801 addr = 0;
1802 elf_sect_writeaddr(s, addr, 8);
1803 break;
1805 default:
1806 panic();
1811 * Section index/count with a specified overflow value (usually SHN_INDEX,
1812 * but 0 for e_shnum.
1814 static inline uint16_t elf_shndx(int section, uint16_t overflow)
1816 return cpu_to_le16(section < (int)SHN_LORESERVE ? section : overflow);
1819 struct ehdr_common {
1820 uint8_t e_ident[EI_NIDENT];
1821 uint16_t e_type;
1822 uint16_t e_machine;
1823 uint32_t e_version;
1826 union ehdr {
1827 Elf32_Ehdr ehdr32;
1828 Elf64_Ehdr ehdr64;
1829 struct ehdr_common com;
1832 static void elf_write(void)
1834 int align;
1835 char *p;
1836 int i;
1837 size_t symtablocal;
1838 int sec_shstrtab, sec_symtab, sec_strtab;
1839 union ehdr ehdr;
1842 * Add any sections we don't already have:
1843 * rel/rela sections for the user sections, debug sections, and
1844 * the ELF special sections.
1847 sec_debug = nsections;
1848 if (dfmt_is_stabs()) {
1849 /* in case the debug information is wanted, just add these three sections... */
1850 add_sectname("", ".stab");
1851 add_sectname("", ".stabstr");
1852 add_sectname(efmt->relpfx, ".stab");
1853 } else if (dfmt_is_dwarf()) {
1854 /* the dwarf debug standard specifies the following ten sections,
1855 not all of which are currently implemented,
1856 although all of them are defined. */
1857 add_sectname("", ".debug_aranges");
1858 add_sectname(".rela", ".debug_aranges");
1859 add_sectname("", ".debug_pubnames");
1860 add_sectname("", ".debug_info");
1861 add_sectname(".rela", ".debug_info");
1862 add_sectname("", ".debug_abbrev");
1863 add_sectname("", ".debug_line");
1864 add_sectname(".rela", ".debug_line");
1865 add_sectname("", ".debug_frame");
1866 add_sectname("", ".debug_loc");
1869 sec_shstrtab = add_sectname("", ".shstrtab");
1870 sec_symtab = add_sectname("", ".symtab");
1871 sec_strtab = add_sectname("", ".strtab");
1874 * Build the symbol table and relocation tables.
1876 symtablocal = elf_build_symtab();
1878 /* Do we need an .symtab_shndx section? */
1879 if (symtab_shndx)
1880 add_sectname("", ".symtab_shndx");
1882 for (i = 0; i < nsects; i++) {
1883 if (sects[i]->head) {
1884 add_sectname(efmt->relpfx, sects[i]->name);
1885 sects[i]->rel = efmt->elf_build_reltab(sects[i]->head);
1890 * Output the ELF header.
1892 nasm_zero(ehdr);
1894 /* These fields are in the same place for 32 and 64 bits */
1895 memcpy(&ehdr.com.e_ident[EI_MAG0], ELFMAG, SELFMAG);
1896 ehdr.com.e_ident[EI_CLASS] = efmt->ei_class;
1897 ehdr.com.e_ident[EI_DATA] = ELFDATA2LSB;
1898 ehdr.com.e_ident[EI_VERSION] = EV_CURRENT;
1899 ehdr.com.e_ident[EI_OSABI] = elf_osabi;
1900 ehdr.com.e_ident[EI_ABIVERSION] = elf_abiver;
1901 ehdr.com.e_type = cpu_to_le16(ET_REL);
1902 ehdr.com.e_machine = cpu_to_le16(efmt->e_machine);
1903 ehdr.com.e_version = cpu_to_le16(EV_CURRENT);
1905 if (!efmt->elf64) {
1906 ehdr.ehdr32.e_shoff = cpu_to_le32(sizeof ehdr);
1907 ehdr.ehdr32.e_ehsize = cpu_to_le16(sizeof(Elf32_Ehdr));
1908 ehdr.ehdr32.e_shentsize = cpu_to_le16(sizeof(Elf32_Shdr));
1909 ehdr.ehdr32.e_shnum = elf_shndx(nsections, 0);
1910 ehdr.ehdr32.e_shstrndx = elf_shndx(sec_shstrtab, SHN_XINDEX);
1911 } else {
1912 ehdr.ehdr64.e_shoff = cpu_to_le64(sizeof ehdr);
1913 ehdr.ehdr64.e_ehsize = cpu_to_le16(sizeof(Elf64_Ehdr));
1914 ehdr.ehdr64.e_shentsize = cpu_to_le16(sizeof(Elf64_Shdr));
1915 ehdr.ehdr64.e_shnum = elf_shndx(nsections, 0);
1916 ehdr.ehdr64.e_shstrndx = elf_shndx(sec_shstrtab, SHN_XINDEX);
1919 nasm_write(&ehdr, sizeof(ehdr), ofile);
1920 elf_foffs = sizeof ehdr + efmt->shdr_size * nsections;
1923 * Now output the section header table.
1925 align = ALIGN(elf_foffs, SEC_FILEALIGN) - elf_foffs;
1926 elf_foffs += align;
1927 elf_nsect = 0;
1928 elf_sects = nasm_malloc(sizeof(*elf_sects) * nsections);
1930 /* SHN_UNDEF */
1931 elf_section_header(0, SHT_NULL, 0, NULL, false,
1932 nsections > (int)SHN_LORESERVE ? nsections : 0,
1933 sec_shstrtab >= (int)SHN_LORESERVE ? sec_shstrtab : 0,
1934 0, 0, 0);
1935 p = shstrtab + 1;
1937 /* The normal sections */
1938 for (i = 0; i < nsects; i++) {
1939 elf_section_header(p - shstrtab, sects[i]->type, sects[i]->flags,
1940 sects[i]->data, true,
1941 sects[i]->len, 0, 0,
1942 sects[i]->align, sects[i]->entsize);
1943 p += strlen(p) + 1;
1946 /* The debugging sections */
1947 if (dfmt_is_stabs()) {
1948 /* for debugging information, create the last three sections
1949 which are the .stab , .stabstr and .rel.stab sections respectively */
1951 /* this function call creates the stab sections in memory */
1952 stabs_generate();
1954 if (stabbuf && stabstrbuf && stabrelbuf) {
1955 elf_section_header(p - shstrtab, SHT_PROGBITS, 0, stabbuf, false,
1956 stablen, sec_stabstr, 0, 4, 12);
1957 p += strlen(p) + 1;
1959 elf_section_header(p - shstrtab, SHT_STRTAB, 0, stabstrbuf, false,
1960 stabstrlen, 0, 0, 4, 0);
1961 p += strlen(p) + 1;
1963 /* link -> symtable info -> section to refer to */
1964 elf_section_header(p - shstrtab, efmt->reltype, 0,
1965 stabrelbuf, false, stabrellen,
1966 sec_symtab, sec_stab,
1967 efmt->word, efmt->rel_size);
1968 p += strlen(p) + 1;
1970 } else if (dfmt_is_dwarf()) {
1971 /* for dwarf debugging information, create the ten dwarf sections */
1973 /* this function call creates the dwarf sections in memory */
1974 if (dwarf_fsect)
1975 dwarf_generate();
1977 elf_section_header(p - shstrtab, SHT_PROGBITS, 0, arangesbuf, false,
1978 arangeslen, 0, 0, 1, 0);
1979 p += strlen(p) + 1;
1981 elf_section_header(p - shstrtab, SHT_RELA, 0, arangesrelbuf, false,
1982 arangesrellen, sec_symtab,
1983 sec_debug_aranges,
1984 efmt->word, efmt->rela_size);
1985 p += strlen(p) + 1;
1987 elf_section_header(p - shstrtab, SHT_PROGBITS, 0, pubnamesbuf,
1988 false, pubnameslen, 0, 0, 1, 0);
1989 p += strlen(p) + 1;
1991 elf_section_header(p - shstrtab, SHT_PROGBITS, 0, infobuf, false,
1992 infolen, 0, 0, 1, 0);
1993 p += strlen(p) + 1;
1995 elf_section_header(p - shstrtab, SHT_RELA, 0, inforelbuf, false,
1996 inforellen, sec_symtab,
1997 sec_debug_info,
1998 efmt->word, efmt->rela_size);
1999 p += strlen(p) + 1;
2001 elf_section_header(p - shstrtab, SHT_PROGBITS, 0, abbrevbuf, false,
2002 abbrevlen, 0, 0, 1, 0);
2003 p += strlen(p) + 1;
2005 elf_section_header(p - shstrtab, SHT_PROGBITS, 0, linebuf, false,
2006 linelen, 0, 0, 1, 0);
2007 p += strlen(p) + 1;
2009 elf_section_header(p - shstrtab, SHT_RELA, 0, linerelbuf, false,
2010 linerellen, sec_symtab,
2011 sec_debug_line,
2012 efmt->word, efmt->rela_size);
2013 p += strlen(p) + 1;
2015 elf_section_header(p - shstrtab, SHT_PROGBITS, 0, framebuf, false,
2016 framelen, 0, 0, 8, 0);
2017 p += strlen(p) + 1;
2019 elf_section_header(p - shstrtab, SHT_PROGBITS, 0, locbuf, false,
2020 loclen, 0, 0, 1, 0);
2021 p += strlen(p) + 1;
2024 /* .shstrtab */
2025 elf_section_header(p - shstrtab, SHT_STRTAB, 0, shstrtab, false,
2026 shstrtablen, 0, 0, 1, 0);
2027 p += strlen(p) + 1;
2029 /* .symtab */
2030 elf_section_header(p - shstrtab, SHT_SYMTAB, 0, symtab, true,
2031 symtab->datalen, sec_strtab, symtablocal,
2032 efmt->word, efmt->sym_size);
2033 p += strlen(p) + 1;
2035 /* .strtab */
2036 elf_section_header(p - shstrtab, SHT_STRTAB, 0, strs, true,
2037 strslen, 0, 0, 1, 0);
2038 p += strlen(p) + 1
2040 /* .symtab_shndx */
2041 if (symtab_shndx) {
2042 elf_section_header(p - shstrtab, SHT_SYMTAB_SHNDX, 0,
2043 symtab_shndx, true, symtab_shndx->datalen,
2044 sec_symtab, 0, 1, 0);
2045 p += strlen(p) + 1;
2048 /* The relocation sections */
2049 for (i = 0; i < nsects; i++) {
2050 if (sects[i]->rel) {
2051 elf_section_header(p - shstrtab, efmt->reltype, 0,
2052 sects[i]->rel, true, sects[i]->rel->datalen,
2053 sec_symtab, sects[i]->shndx,
2054 efmt->word, efmt->rel_size);
2055 p += strlen(p) + 1;
2058 fwritezero(align, ofile);
2061 * Now output the sections.
2063 elf_write_sections();
2065 nasm_free(elf_sects);
2066 saa_free(symtab);
2067 if (symtab_shndx)
2068 saa_free(symtab_shndx);
2071 static size_t nsyms;
2073 static void elf_sym(const struct elf_symbol *sym)
2075 int shndx = sym->section;
2078 * Careful here. This relies on sym->section being signed; for
2079 * special section indicies this value needs to be cast to
2080 * (int16_t) so that it sign-extends, however, here SHN_LORESERVE
2081 * is used as an unsigned constant.
2083 if (shndx >= (int)SHN_LORESERVE) {
2084 if (unlikely(!symtab_shndx)) {
2085 /* Create symtab_shndx and fill previous entries with zero */
2086 symtab_shndx = saa_init(1);
2087 saa_wbytes(symtab_shndx, NULL, nsyms << 2);
2089 } else {
2090 shndx = 0; /* Section index table always write zero */
2093 if (symtab_shndx)
2094 saa_write32(symtab_shndx, shndx);
2096 efmt->elf_sym(sym);
2097 nsyms++;
2100 static void elf32_sym(const struct elf_symbol *sym)
2102 Elf32_Sym sym32;
2104 sym32.st_name = cpu_to_le32(sym->strpos);
2105 sym32.st_value = cpu_to_le32(sym->symv.key);
2106 sym32.st_size = cpu_to_le32(sym->size);
2107 sym32.st_info = sym->type;
2108 sym32.st_other = sym->other;
2109 sym32.st_shndx = elf_shndx(sym->section, SHN_XINDEX);
2110 saa_wbytes(symtab, &sym32, sizeof sym32);
2113 static void elf64_sym(const struct elf_symbol *sym)
2115 Elf64_Sym sym64;
2117 sym64.st_name = cpu_to_le32(sym->strpos);
2118 sym64.st_value = cpu_to_le64(sym->symv.key);
2119 sym64.st_size = cpu_to_le64(sym->size);
2120 sym64.st_info = sym->type;
2121 sym64.st_other = sym->other;
2122 sym64.st_shndx = elf_shndx(sym->section, SHN_XINDEX);
2123 saa_wbytes(symtab, &sym64, sizeof sym64);
2126 static size_t elf_build_symtab(void)
2128 struct elf_symbol *sym, xsym;
2129 size_t nlocal;
2130 int i;
2132 symtab = saa_init(1);
2133 symtab_shndx = NULL;
2136 * Zero symbol first as required by spec.
2138 nasm_zero(xsym);
2139 elf_sym(&xsym);
2142 * Next, an entry for the file name.
2144 nasm_zero(xsym);
2145 xsym.strpos = 1;
2146 xsym.type = ELF32_ST_INFO(STB_LOCAL, STT_FILE);
2147 xsym.section = XSHN_ABS;
2148 elf_sym(&xsym);
2151 * Now some standard symbols defining the segments, for relocation
2152 * purposes.
2154 nasm_zero(xsym);
2155 for (i = 1; i <= nsects; i++) {
2156 xsym.type = ELF64_ST_INFO(STB_LOCAL, STT_SECTION);
2157 xsym.section = i;
2158 elf_sym(&xsym);
2162 * dwarf needs symbols for debug sections
2163 * which are relocation targets.
2165 if (dfmt_is_dwarf()) {
2166 dwarf_infosym = nsyms;
2167 xsym.section = sec_debug_info;
2168 elf_sym(&xsym);
2170 dwarf_abbrevsym = nsyms;
2171 xsym.section = sec_debug_abbrev;
2172 elf_sym(&xsym);
2174 dwarf_linesym = nsyms;
2175 xsym.section = sec_debug_line;
2176 elf_sym(&xsym);
2180 * Now the other local symbols.
2182 saa_rewind(syms);
2183 while ((sym = saa_rstruct(syms))) {
2184 if (!sym_type_local(sym->type))
2185 continue;
2187 elf_sym(sym);
2190 nlocal = nsyms;
2193 * Now the global symbols.
2195 saa_rewind(syms);
2196 while ((sym = saa_rstruct(syms))) {
2197 if (sym_type_local(sym->type))
2198 continue;
2200 elf_sym(sym);
2203 return nlocal;
2206 static struct SAA *elf32_build_reltab(const struct elf_reloc *r)
2208 struct SAA *s;
2209 int32_t global_offset;
2210 Elf32_Rel rel32;
2212 if (!r)
2213 return NULL;
2215 s = saa_init(1L);
2218 * How to onvert from a global placeholder to a real symbol index;
2219 * the +2 refers to the two special entries, the null entry and
2220 * the filename entry.
2222 global_offset = -GLOBAL_TEMP_BASE + nsects + nlocals + ndebugs + 2;
2224 while (r) {
2225 int32_t sym = r->symbol;
2227 if (sym >= GLOBAL_TEMP_BASE)
2228 sym += global_offset;
2230 rel32.r_offset = cpu_to_le32(r->address);
2231 rel32.r_info = cpu_to_le32(ELF32_R_INFO(sym, r->type));
2232 saa_wbytes(s, &rel32, sizeof rel32);
2234 r = r->next;
2237 return s;
2240 static struct SAA *elfx32_build_reltab(const struct elf_reloc *r)
2242 struct SAA *s;
2243 int32_t global_offset;
2244 Elf32_Rela rela32;
2246 if (!r)
2247 return NULL;
2249 s = saa_init(1L);
2252 * How to onvert from a global placeholder to a real symbol index;
2253 * the +2 refers to the two special entries, the null entry and
2254 * the filename entry.
2256 global_offset = -GLOBAL_TEMP_BASE + nsects + nlocals + ndebugs + 2;
2258 while (r) {
2259 int32_t sym = r->symbol;
2261 if (sym >= GLOBAL_TEMP_BASE)
2262 sym += global_offset;
2264 rela32.r_offset = cpu_to_le32(r->address);
2265 rela32.r_info = cpu_to_le32(ELF32_R_INFO(sym, r->type));
2266 rela32.r_addend = cpu_to_le32(r->offset);
2267 saa_wbytes(s, &rela32, sizeof rela32);
2269 r = r->next;
2272 return s;
2275 static struct SAA *elf64_build_reltab(const struct elf_reloc *r)
2277 struct SAA *s;
2278 int32_t global_offset;
2279 Elf64_Rela rela64;
2281 if (!r)
2282 return NULL;
2284 s = saa_init(1L);
2287 * How to onvert from a global placeholder to a real symbol index;
2288 * the +2 refers to the two special entries, the null entry and
2289 * the filename entry.
2291 global_offset = -GLOBAL_TEMP_BASE + nsects + nlocals + ndebugs + 2;
2293 while (r) {
2294 int32_t sym = r->symbol;
2296 if (sym >= GLOBAL_TEMP_BASE)
2297 sym += global_offset;
2299 rela64.r_offset = cpu_to_le64(r->address);
2300 rela64.r_info = cpu_to_le64(ELF64_R_INFO(sym, r->type));
2301 rela64.r_addend = cpu_to_le64(r->offset);
2302 saa_wbytes(s, &rela64, sizeof rela64);
2304 r = r->next;
2307 return s;
2310 static void elf_section_header(int name, int type, uint64_t flags,
2311 void *data, bool is_saa, uint64_t datalen,
2312 int link, int info,
2313 uint64_t align, uint64_t entsize)
2315 elf_sects[elf_nsect].data = data;
2316 elf_sects[elf_nsect].len = datalen;
2317 elf_sects[elf_nsect].is_saa = is_saa;
2318 elf_nsect++;
2320 if (!efmt->elf64) {
2321 Elf32_Shdr shdr;
2323 shdr.sh_name = cpu_to_le32(name);
2324 shdr.sh_type = cpu_to_le32(type);
2325 shdr.sh_flags = cpu_to_le32(flags);
2326 shdr.sh_addr = 0;
2327 shdr.sh_offset = cpu_to_le32(type == SHT_NULL ? 0 : elf_foffs);
2328 shdr.sh_size = cpu_to_le32(datalen);
2329 if (data)
2330 elf_foffs += ALIGN(datalen, SEC_FILEALIGN);
2331 shdr.sh_link = cpu_to_le32(link);
2332 shdr.sh_info = cpu_to_le32(info);
2333 shdr.sh_addralign = cpu_to_le32(align);
2334 shdr.sh_entsize = cpu_to_le32(entsize);
2336 nasm_write(&shdr, sizeof shdr, ofile);
2337 } else {
2338 Elf64_Shdr shdr;
2340 shdr.sh_name = cpu_to_le32(name);
2341 shdr.sh_type = cpu_to_le32(type);
2342 shdr.sh_flags = cpu_to_le64(flags);
2343 shdr.sh_addr = 0;
2344 shdr.sh_offset = cpu_to_le64(type == SHT_NULL ? 0 : elf_foffs);
2345 shdr.sh_size = cpu_to_le64(datalen);
2346 if (data)
2347 elf_foffs += ALIGN(datalen, SEC_FILEALIGN);
2348 shdr.sh_link = cpu_to_le32(link);
2349 shdr.sh_info = cpu_to_le32(info);
2350 shdr.sh_addralign = cpu_to_le64(align);
2351 shdr.sh_entsize = cpu_to_le64(entsize);
2353 nasm_write(&shdr, sizeof shdr, ofile);
2357 static void elf_write_sections(void)
2359 int i;
2360 for (i = 0; i < elf_nsect; i++)
2361 if (elf_sects[i].data) {
2362 int32_t len = elf_sects[i].len;
2363 int32_t reallen = ALIGN(len, SEC_FILEALIGN);
2364 int32_t align = reallen - len;
2365 if (elf_sects[i].is_saa)
2366 saa_fpwrite(elf_sects[i].data, ofile);
2367 else
2368 nasm_write(elf_sects[i].data, len, ofile);
2369 fwritezero(align, ofile);
2373 static void elf_sect_write(struct elf_section *sect, const void *data, size_t len)
2375 saa_wbytes(sect->data, data, len);
2376 sect->len += len;
2379 static void elf_sect_writeaddr(struct elf_section *sect, int64_t data, size_t len)
2381 saa_writeaddr(sect->data, data, len);
2382 sect->len += len;
2385 static void elf_sectalign(int32_t seg, unsigned int value)
2387 struct elf_section *s;
2389 s = raa_read_ptr(section_by_index, seg >> 1);
2390 if (!s || !is_power2(value))
2391 return;
2393 if (value > s->align)
2394 s->align = value;
2397 extern macros_t elf_stdmac[];
2399 /* Claim "elf" as a pragma namespace, for the future */
2400 static const struct pragma_facility elf_pragma_list[] =
2402 { "elf", NULL },
2403 { NULL, NULL } /* Implements the canonical output name */
2407 static const struct dfmt elf32_df_dwarf = {
2408 "ELF32 (i386) dwarf (newer)",
2409 "dwarf",
2410 dwarf_init,
2411 dwarf_linenum,
2412 null_debug_deflabel,
2413 null_debug_directive,
2414 debug_typevalue,
2415 dwarf_output,
2416 dwarf_cleanup,
2417 NULL /* pragma list */
2420 static const struct dfmt elf32_df_stabs = {
2421 "ELF32 (i386) stabs (older)",
2422 "stabs",
2423 null_debug_init,
2424 stabs_linenum,
2425 null_debug_deflabel,
2426 null_debug_directive,
2427 debug_typevalue,
2428 stabs_output,
2429 stabs_cleanup,
2430 NULL /* pragma list */
2433 static const struct dfmt * const elf32_debugs_arr[3] =
2434 { &elf32_df_dwarf, &elf32_df_stabs, NULL };
2436 const struct ofmt of_elf32 = {
2437 "ELF32 (i386) (Linux, most Unix variants)",
2438 "elf32",
2439 ".o",
2442 elf32_debugs_arr,
2443 &elf32_df_dwarf,
2444 elf_stdmac,
2445 elf32_init,
2446 null_reset,
2447 nasm_do_legacy_output,
2448 elf32_out,
2449 elf_deflabel,
2450 elf_section_names,
2451 NULL,
2452 elf_sectalign,
2453 null_segbase,
2454 elf_directive,
2455 elf_cleanup,
2456 elf_pragma_list,
2459 static const struct dfmt elf64_df_dwarf = {
2460 "ELF64 (x86-64) dwarf (newer)",
2461 "dwarf",
2462 dwarf_init,
2463 dwarf_linenum,
2464 null_debug_deflabel,
2465 null_debug_directive,
2466 debug_typevalue,
2467 dwarf_output,
2468 dwarf_cleanup,
2469 NULL /* pragma list */
2472 static const struct dfmt elf64_df_stabs = {
2473 "ELF64 (x86-64) stabs (older)",
2474 "stabs",
2475 null_debug_init,
2476 stabs_linenum,
2477 null_debug_deflabel,
2478 null_debug_directive,
2479 debug_typevalue,
2480 stabs_output,
2481 stabs_cleanup,
2482 NULL /* pragma list */
2485 static const struct dfmt * const elf64_debugs_arr[3] =
2486 { &elf64_df_dwarf, &elf64_df_stabs, NULL };
2488 const struct ofmt of_elf64 = {
2489 "ELF64 (x86-64) (Linux, most Unix variants)",
2490 "elf64",
2491 ".o",
2494 elf64_debugs_arr,
2495 &elf64_df_dwarf,
2496 elf_stdmac,
2497 elf64_init,
2498 null_reset,
2499 nasm_do_legacy_output,
2500 elf64_out,
2501 elf_deflabel,
2502 elf_section_names,
2503 NULL,
2504 elf_sectalign,
2505 null_segbase,
2506 elf_directive,
2507 elf_cleanup,
2508 elf_pragma_list,
2511 static const struct dfmt elfx32_df_dwarf = {
2512 "ELFx32 (x86-64) dwarf (newer)",
2513 "dwarf",
2514 dwarf_init,
2515 dwarf_linenum,
2516 null_debug_deflabel,
2517 null_debug_directive,
2518 debug_typevalue,
2519 dwarf_output,
2520 dwarf_cleanup,
2521 NULL /* pragma list */
2524 static const struct dfmt elfx32_df_stabs = {
2525 "ELFx32 (x86-64) stabs (older)",
2526 "stabs",
2527 null_debug_init,
2528 stabs_linenum,
2529 null_debug_deflabel,
2530 null_debug_directive,
2531 debug_typevalue,
2532 stabs_output,
2533 stabs_cleanup,
2534 elf_pragma_list,
2537 static const struct dfmt * const elfx32_debugs_arr[3] =
2538 { &elfx32_df_dwarf, &elfx32_df_stabs, NULL };
2540 const struct ofmt of_elfx32 = {
2541 "ELFx32 (ELF32 for x86-64) (Linux)",
2542 "elfx32",
2543 ".o",
2546 elfx32_debugs_arr,
2547 &elfx32_df_dwarf,
2548 elf_stdmac,
2549 elfx32_init,
2550 null_reset,
2551 nasm_do_legacy_output,
2552 elfx32_out,
2553 elf_deflabel,
2554 elf_section_names,
2555 NULL,
2556 elf_sectalign,
2557 null_segbase,
2558 elf_directive,
2559 elf_cleanup,
2560 NULL /* pragma list */
2563 static bool is_elf64(void)
2565 return ofmt == &of_elf64;
2568 static bool is_elf32(void)
2570 return ofmt == &of_elf32;
2573 static bool is_elfx32(void)
2575 return ofmt == &of_elfx32;
2578 static bool dfmt_is_stabs(void)
2580 return dfmt == &elf32_df_stabs ||
2581 dfmt == &elfx32_df_stabs ||
2582 dfmt == &elf64_df_stabs;
2585 static bool dfmt_is_dwarf(void)
2587 return dfmt == &elf32_df_dwarf ||
2588 dfmt == &elfx32_df_dwarf ||
2589 dfmt == &elf64_df_dwarf;
2592 /* common debugging routines */
2593 static void debug_typevalue(int32_t type)
2595 int32_t stype, ssize;
2596 switch (TYM_TYPE(type)) {
2597 case TY_LABEL:
2598 ssize = 0;
2599 stype = STT_NOTYPE;
2600 break;
2601 case TY_BYTE:
2602 ssize = 1;
2603 stype = STT_OBJECT;
2604 break;
2605 case TY_WORD:
2606 ssize = 2;
2607 stype = STT_OBJECT;
2608 break;
2609 case TY_DWORD:
2610 ssize = 4;
2611 stype = STT_OBJECT;
2612 break;
2613 case TY_FLOAT:
2614 ssize = 4;
2615 stype = STT_OBJECT;
2616 break;
2617 case TY_QWORD:
2618 ssize = 8;
2619 stype = STT_OBJECT;
2620 break;
2621 case TY_TBYTE:
2622 ssize = 10;
2623 stype = STT_OBJECT;
2624 break;
2625 case TY_OWORD:
2626 ssize = 16;
2627 stype = STT_OBJECT;
2628 break;
2629 case TY_YWORD:
2630 ssize = 32;
2631 stype = STT_OBJECT;
2632 break;
2633 case TY_ZWORD:
2634 ssize = 64;
2635 stype = STT_OBJECT;
2636 break;
2637 case TY_COMMON:
2638 ssize = 0;
2639 stype = STT_COMMON;
2640 break;
2641 case TY_SEG:
2642 ssize = 0;
2643 stype = STT_SECTION;
2644 break;
2645 case TY_EXTERN:
2646 ssize = 0;
2647 stype = STT_NOTYPE;
2648 break;
2649 case TY_EQU:
2650 ssize = 0;
2651 stype = STT_NOTYPE;
2652 break;
2653 default:
2654 ssize = 0;
2655 stype = STT_NOTYPE;
2656 break;
2658 if (stype == STT_OBJECT && lastsym && !lastsym->type) {
2659 lastsym->size = ssize;
2660 lastsym->type = stype;
2664 /* stabs debugging routines */
2666 static void stabs_linenum(const char *filename, int32_t linenumber, int32_t segto)
2668 (void)segto;
2669 if (!stabs_filename) {
2670 stabs_filename = nasm_malloc(strlen(filename) + 1);
2671 strcpy(stabs_filename, filename);
2672 } else {
2673 if (strcmp(stabs_filename, filename)) {
2674 /* yep, a memory leak...this program is one-shot anyway, so who cares...
2675 in fact, this leak comes in quite handy to maintain a list of files
2676 encountered so far in the symbol lines... */
2678 /* why not nasm_free(stabs_filename); we're done with the old one */
2680 stabs_filename = nasm_malloc(strlen(filename) + 1);
2681 strcpy(stabs_filename, filename);
2684 debug_immcall = 1;
2685 currentline = linenumber;
2688 static void stabs_output(int type, void *param)
2690 struct symlininfo *s;
2691 struct linelist *el;
2692 if (type == TY_DEBUGSYMLIN) {
2693 if (debug_immcall) {
2694 s = (struct symlininfo *)param;
2695 if (!(sects[s->section]->flags & SHF_EXECINSTR))
2696 return; /* line info is only collected for executable sections */
2697 numlinestabs++;
2698 el = nasm_malloc(sizeof(struct linelist));
2699 el->info.offset = s->offset;
2700 el->info.section = s->section;
2701 el->info.name = s->name;
2702 el->line = currentline;
2703 el->filename = stabs_filename;
2704 el->next = 0;
2705 if (stabslines) {
2706 stabslines->last->next = el;
2707 stabslines->last = el;
2708 } else {
2709 stabslines = el;
2710 stabslines->last = el;
2714 debug_immcall = 0;
2717 /* for creating the .stab , .stabstr and .rel.stab sections in memory */
2719 static void stabs_generate(void)
2721 int i, numfiles, strsize, numstabs = 0, currfile, mainfileindex;
2722 uint8_t *sbuf, *ssbuf, *rbuf, *sptr, *rptr;
2723 char **allfiles;
2724 int *fileidx;
2726 struct linelist *ptr;
2728 ptr = stabslines;
2730 allfiles = nasm_zalloc(numlinestabs * sizeof(char *));
2731 numfiles = 0;
2732 while (ptr) {
2733 if (numfiles == 0) {
2734 allfiles[0] = ptr->filename;
2735 numfiles++;
2736 } else {
2737 for (i = 0; i < numfiles; i++) {
2738 if (!strcmp(allfiles[i], ptr->filename))
2739 break;
2741 if (i >= numfiles) {
2742 allfiles[i] = ptr->filename;
2743 numfiles++;
2746 ptr = ptr->next;
2748 strsize = 1;
2749 fileidx = nasm_malloc(numfiles * sizeof(int));
2750 for (i = 0; i < numfiles; i++) {
2751 fileidx[i] = strsize;
2752 strsize += strlen(allfiles[i]) + 1;
2754 currfile = mainfileindex = 0;
2755 for (i = 0; i < numfiles; i++) {
2756 if (!strcmp(allfiles[i], elf_module)) {
2757 currfile = mainfileindex = i;
2758 break;
2763 * worst case size of the stab buffer would be:
2764 * the sourcefiles changes each line, which would mean 1 SOL, 1 SYMLIN per line
2765 * plus one "ending" entry
2767 sbuf = nasm_malloc((numlinestabs * 2 + 4) *
2768 sizeof(struct stabentry));
2769 ssbuf = nasm_malloc(strsize);
2770 rbuf = nasm_malloc(numlinestabs * (is_elf64() ? 16 : 8) * (2 + 3));
2771 rptr = rbuf;
2773 for (i = 0; i < numfiles; i++)
2774 strcpy((char *)ssbuf + fileidx[i], allfiles[i]);
2775 ssbuf[0] = 0;
2777 stabstrlen = strsize; /* set global variable for length of stab strings */
2779 sptr = sbuf;
2780 ptr = stabslines;
2781 numstabs = 0;
2783 if (ptr) {
2785 * this is the first stab, its strx points to the filename of the
2786 * the source-file, the n_desc field should be set to the number
2787 * of remaining stabs
2789 WRITE_STAB(sptr, fileidx[0], 0, 0, 0, stabstrlen);
2791 /* this is the stab for the main source file */
2792 WRITE_STAB(sptr, fileidx[mainfileindex], N_SO, 0, 0, 0);
2794 /* relocation table entry */
2797 * Since the symbol table has two entries before
2798 * the section symbols, the index in the info.section
2799 * member must be adjusted by adding 2
2802 if (is_elf32()) {
2803 WRITELONG(rptr, (sptr - sbuf) - 4);
2804 WRITELONG(rptr, ((ptr->info.section + 2) << 8) | R_386_32);
2805 } else if (is_elfx32()) {
2806 WRITELONG(rptr, (sptr - sbuf) - 4);
2807 WRITELONG(rptr, ((ptr->info.section + 2) << 8) | R_X86_64_32);
2808 WRITELONG(rptr, 0);
2809 } else {
2810 nasm_assert(is_elf64());
2811 WRITEDLONG(rptr, (int64_t)(sptr - sbuf) - 4);
2812 WRITELONG(rptr, R_X86_64_32);
2813 WRITELONG(rptr, ptr->info.section + 2);
2814 WRITEDLONG(rptr, 0);
2816 numstabs++;
2819 if (is_elf32()) {
2820 while (ptr) {
2821 if (strcmp(allfiles[currfile], ptr->filename)) {
2822 /* oops file has changed... */
2823 for (i = 0; i < numfiles; i++)
2824 if (!strcmp(allfiles[i], ptr->filename))
2825 break;
2826 currfile = i;
2827 WRITE_STAB(sptr, fileidx[currfile], N_SOL, 0, 0,
2828 ptr->info.offset);
2829 numstabs++;
2831 /* relocation table entry */
2832 WRITELONG(rptr, (sptr - sbuf) - 4);
2833 WRITELONG(rptr, ((ptr->info.section + 2) << 8) | R_386_32);
2836 WRITE_STAB(sptr, 0, N_SLINE, 0, ptr->line, ptr->info.offset);
2837 numstabs++;
2839 /* relocation table entry */
2840 WRITELONG(rptr, (sptr - sbuf) - 4);
2841 WRITELONG(rptr, ((ptr->info.section + 2) << 8) | R_386_32);
2843 ptr = ptr->next;
2845 } else if (is_elfx32()) {
2846 while (ptr) {
2847 if (strcmp(allfiles[currfile], ptr->filename)) {
2848 /* oops file has changed... */
2849 for (i = 0; i < numfiles; i++)
2850 if (!strcmp(allfiles[i], ptr->filename))
2851 break;
2852 currfile = i;
2853 WRITE_STAB(sptr, fileidx[currfile], N_SOL, 0, 0,
2854 ptr->info.offset);
2855 numstabs++;
2857 /* relocation table entry */
2858 WRITELONG(rptr, (sptr - sbuf) - 4);
2859 WRITELONG(rptr, ((ptr->info.section + 2) << 8) | R_X86_64_32);
2860 WRITELONG(rptr, ptr->info.offset);
2863 WRITE_STAB(sptr, 0, N_SLINE, 0, ptr->line, ptr->info.offset);
2864 numstabs++;
2866 /* relocation table entry */
2867 WRITELONG(rptr, (sptr - sbuf) - 4);
2868 WRITELONG(rptr, ((ptr->info.section + 2) << 8) | R_X86_64_32);
2869 WRITELONG(rptr, ptr->info.offset);
2871 ptr = ptr->next;
2873 } else {
2874 nasm_assert(is_elf64());
2875 while (ptr) {
2876 if (strcmp(allfiles[currfile], ptr->filename)) {
2877 /* oops file has changed... */
2878 for (i = 0; i < numfiles; i++)
2879 if (!strcmp(allfiles[i], ptr->filename))
2880 break;
2881 currfile = i;
2882 WRITE_STAB(sptr, fileidx[currfile], N_SOL, 0, 0,
2883 ptr->info.offset);
2884 numstabs++;
2886 /* relocation table entry */
2887 WRITEDLONG(rptr, (int64_t)(sptr - sbuf) - 4);
2888 WRITELONG(rptr, R_X86_64_32);
2889 WRITELONG(rptr, ptr->info.section + 2);
2890 WRITEDLONG(rptr, ptr->info.offset);
2893 WRITE_STAB(sptr, 0, N_SLINE, 0, ptr->line, ptr->info.offset);
2894 numstabs++;
2896 /* relocation table entry */
2897 WRITEDLONG(rptr, (int64_t)(sptr - sbuf) - 4);
2898 WRITELONG(rptr, R_X86_64_32);
2899 WRITELONG(rptr, ptr->info.section + 2);
2900 WRITEDLONG(rptr, ptr->info.offset);
2902 ptr = ptr->next;
2906 /* this is an "ending" token */
2907 WRITE_STAB(sptr, 0, N_SO, 0, 0, 0);
2908 numstabs++;
2910 ((struct stabentry *)sbuf)->n_desc = numstabs;
2912 nasm_free(allfiles);
2913 nasm_free(fileidx);
2915 stablen = (sptr - sbuf);
2916 stabrellen = (rptr - rbuf);
2917 stabrelbuf = rbuf;
2918 stabbuf = sbuf;
2919 stabstrbuf = ssbuf;
2922 static void stabs_cleanup(void)
2924 struct linelist *ptr, *del;
2925 if (!stabslines)
2926 return;
2928 ptr = stabslines;
2929 while (ptr) {
2930 del = ptr;
2931 ptr = ptr->next;
2932 nasm_free(del);
2935 nasm_free(stabbuf);
2936 nasm_free(stabrelbuf);
2937 nasm_free(stabstrbuf);
2940 /* dwarf routines */
2942 static void dwarf_init(void)
2944 ndebugs = 3; /* 3 debug symbols */
2947 static void dwarf_linenum(const char *filename, int32_t linenumber,
2948 int32_t segto)
2950 (void)segto;
2951 dwarf_findfile(filename);
2952 debug_immcall = 1;
2953 currentline = linenumber;
2956 /* called from elf_out with type == TY_DEBUGSYMLIN */
2957 static void dwarf_output(int type, void *param)
2959 int ln, aa, inx, maxln, soc;
2960 struct symlininfo *s;
2961 struct SAA *plinep;
2963 (void)type;
2965 s = (struct symlininfo *)param;
2967 /* line number info is only gathered for executable sections */
2968 if (!(sects[s->section]->flags & SHF_EXECINSTR))
2969 return;
2971 /* Check if section index has changed */
2972 if (!(dwarf_csect && (dwarf_csect->section) == (s->section)))
2973 dwarf_findsect(s->section);
2975 /* do nothing unless line or file has changed */
2976 if (!debug_immcall)
2977 return;
2979 ln = currentline - dwarf_csect->line;
2980 aa = s->offset - dwarf_csect->offset;
2981 inx = dwarf_clist->line;
2982 plinep = dwarf_csect->psaa;
2983 /* check for file change */
2984 if (!(inx == dwarf_csect->file)) {
2985 saa_write8(plinep,DW_LNS_set_file);
2986 saa_write8(plinep,inx);
2987 dwarf_csect->file = inx;
2989 /* check for line change */
2990 if (ln) {
2991 /* test if in range of special op code */
2992 maxln = line_base + line_range;
2993 soc = (ln - line_base) + (line_range * aa) + opcode_base;
2994 if (ln >= line_base && ln < maxln && soc < 256) {
2995 saa_write8(plinep,soc);
2996 } else {
2997 saa_write8(plinep,DW_LNS_advance_line);
2998 saa_wleb128s(plinep,ln);
2999 if (aa) {
3000 saa_write8(plinep,DW_LNS_advance_pc);
3001 saa_wleb128u(plinep,aa);
3003 saa_write8(plinep,DW_LNS_copy);
3005 dwarf_csect->line = currentline;
3006 dwarf_csect->offset = s->offset;
3009 /* show change handled */
3010 debug_immcall = 0;
3014 static void dwarf_generate(void)
3016 uint8_t *pbuf;
3017 int indx;
3018 struct linelist *ftentry;
3019 struct SAA *paranges, *ppubnames, *pinfo, *pabbrev, *plines, *plinep;
3020 struct SAA *parangesrel, *plinesrel, *pinforel;
3021 struct sectlist *psect;
3022 size_t saalen, linepoff, totlen, highaddr;
3024 if (is_elf32()) {
3025 /* write epilogues for each line program range */
3026 /* and build aranges section */
3027 paranges = saa_init(1L);
3028 parangesrel = saa_init(1L);
3029 saa_write16(paranges,2); /* dwarf version */
3030 saa_write32(parangesrel, paranges->datalen+4);
3031 saa_write32(parangesrel, (dwarf_infosym << 8) + R_386_32); /* reloc to info */
3032 saa_write32(parangesrel, 0);
3033 saa_write32(paranges,0); /* offset into info */
3034 saa_write8(paranges,4); /* pointer size */
3035 saa_write8(paranges,0); /* not segmented */
3036 saa_write32(paranges,0); /* padding */
3037 /* iterate though sectlist entries */
3038 psect = dwarf_fsect;
3039 totlen = 0;
3040 highaddr = 0;
3041 for (indx = 0; indx < dwarf_nsections; indx++) {
3042 plinep = psect->psaa;
3043 /* Line Number Program Epilogue */
3044 saa_write8(plinep,2); /* std op 2 */
3045 saa_write8(plinep,(sects[psect->section]->len)-psect->offset);
3046 saa_write8(plinep,DW_LNS_extended_op);
3047 saa_write8(plinep,1); /* operand length */
3048 saa_write8(plinep,DW_LNE_end_sequence);
3049 totlen += plinep->datalen;
3050 /* range table relocation entry */
3051 saa_write32(parangesrel, paranges->datalen + 4);
3052 saa_write32(parangesrel, ((uint32_t) (psect->section + 2) << 8) + R_386_32);
3053 saa_write32(parangesrel, (uint32_t) 0);
3054 /* range table entry */
3055 saa_write32(paranges,0x0000); /* range start */
3056 saa_write32(paranges,sects[psect->section]->len); /* range length */
3057 highaddr += sects[psect->section]->len;
3058 /* done with this entry */
3059 psect = psect->next;
3061 saa_write32(paranges,0); /* null address */
3062 saa_write32(paranges,0); /* null length */
3063 saalen = paranges->datalen;
3064 arangeslen = saalen + 4;
3065 arangesbuf = pbuf = nasm_malloc(arangeslen);
3066 WRITELONG(pbuf,saalen); /* initial length */
3067 saa_rnbytes(paranges, pbuf, saalen);
3068 saa_free(paranges);
3069 } else if (is_elfx32()) {
3070 /* write epilogues for each line program range */
3071 /* and build aranges section */
3072 paranges = saa_init(1L);
3073 parangesrel = saa_init(1L);
3074 saa_write16(paranges,3); /* dwarf version */
3075 saa_write32(parangesrel, paranges->datalen+4);
3076 saa_write32(parangesrel, (dwarf_infosym << 8) + R_X86_64_32); /* reloc to info */
3077 saa_write32(parangesrel, 0);
3078 saa_write32(paranges,0); /* offset into info */
3079 saa_write8(paranges,4); /* pointer size */
3080 saa_write8(paranges,0); /* not segmented */
3081 saa_write32(paranges,0); /* padding */
3082 /* iterate though sectlist entries */
3083 psect = dwarf_fsect;
3084 totlen = 0;
3085 highaddr = 0;
3086 for (indx = 0; indx < dwarf_nsections; indx++) {
3087 plinep = psect->psaa;
3088 /* Line Number Program Epilogue */
3089 saa_write8(plinep,2); /* std op 2 */
3090 saa_write8(plinep,(sects[psect->section]->len)-psect->offset);
3091 saa_write8(plinep,DW_LNS_extended_op);
3092 saa_write8(plinep,1); /* operand length */
3093 saa_write8(plinep,DW_LNE_end_sequence);
3094 totlen += plinep->datalen;
3095 /* range table relocation entry */
3096 saa_write32(parangesrel, paranges->datalen + 4);
3097 saa_write32(parangesrel, ((uint32_t) (psect->section + 2) << 8) + R_X86_64_32);
3098 saa_write32(parangesrel, (uint32_t) 0);
3099 /* range table entry */
3100 saa_write32(paranges,0x0000); /* range start */
3101 saa_write32(paranges,sects[psect->section]->len); /* range length */
3102 highaddr += sects[psect->section]->len;
3103 /* done with this entry */
3104 psect = psect->next;
3106 saa_write32(paranges,0); /* null address */
3107 saa_write32(paranges,0); /* null length */
3108 saalen = paranges->datalen;
3109 arangeslen = saalen + 4;
3110 arangesbuf = pbuf = nasm_malloc(arangeslen);
3111 WRITELONG(pbuf,saalen); /* initial length */
3112 saa_rnbytes(paranges, pbuf, saalen);
3113 saa_free(paranges);
3114 } else {
3115 nasm_assert(is_elf64());
3116 /* write epilogues for each line program range */
3117 /* and build aranges section */
3118 paranges = saa_init(1L);
3119 parangesrel = saa_init(1L);
3120 saa_write16(paranges,3); /* dwarf version */
3121 saa_write64(parangesrel, paranges->datalen+4);
3122 saa_write64(parangesrel, (dwarf_infosym << 32) + R_X86_64_32); /* reloc to info */
3123 saa_write64(parangesrel, 0);
3124 saa_write32(paranges,0); /* offset into info */
3125 saa_write8(paranges,8); /* pointer size */
3126 saa_write8(paranges,0); /* not segmented */
3127 saa_write32(paranges,0); /* padding */
3128 /* iterate though sectlist entries */
3129 psect = dwarf_fsect;
3130 totlen = 0;
3131 highaddr = 0;
3132 for (indx = 0; indx < dwarf_nsections; indx++) {
3133 plinep = psect->psaa;
3134 /* Line Number Program Epilogue */
3135 saa_write8(plinep,2); /* std op 2 */
3136 saa_write8(plinep,(sects[psect->section]->len)-psect->offset);
3137 saa_write8(plinep,DW_LNS_extended_op);
3138 saa_write8(plinep,1); /* operand length */
3139 saa_write8(plinep,DW_LNE_end_sequence);
3140 totlen += plinep->datalen;
3141 /* range table relocation entry */
3142 saa_write64(parangesrel, paranges->datalen + 4);
3143 saa_write64(parangesrel, ((uint64_t) (psect->section + 2) << 32) + R_X86_64_64);
3144 saa_write64(parangesrel, (uint64_t) 0);
3145 /* range table entry */
3146 saa_write64(paranges,0x0000); /* range start */
3147 saa_write64(paranges,sects[psect->section]->len); /* range length */
3148 highaddr += sects[psect->section]->len;
3149 /* done with this entry */
3150 psect = psect->next;
3152 saa_write64(paranges,0); /* null address */
3153 saa_write64(paranges,0); /* null length */
3154 saalen = paranges->datalen;
3155 arangeslen = saalen + 4;
3156 arangesbuf = pbuf = nasm_malloc(arangeslen);
3157 WRITELONG(pbuf,saalen); /* initial length */
3158 saa_rnbytes(paranges, pbuf, saalen);
3159 saa_free(paranges);
3162 /* build rela.aranges section */
3163 arangesrellen = saalen = parangesrel->datalen;
3164 arangesrelbuf = pbuf = nasm_malloc(arangesrellen);
3165 saa_rnbytes(parangesrel, pbuf, saalen);
3166 saa_free(parangesrel);
3168 /* build pubnames section */
3169 ppubnames = saa_init(1L);
3170 saa_write16(ppubnames,3); /* dwarf version */
3171 saa_write32(ppubnames,0); /* offset into info */
3172 saa_write32(ppubnames,0); /* space used in info */
3173 saa_write32(ppubnames,0); /* end of list */
3174 saalen = ppubnames->datalen;
3175 pubnameslen = saalen + 4;
3176 pubnamesbuf = pbuf = nasm_malloc(pubnameslen);
3177 WRITELONG(pbuf,saalen); /* initial length */
3178 saa_rnbytes(ppubnames, pbuf, saalen);
3179 saa_free(ppubnames);
3181 if (is_elf32()) {
3182 /* build info section */
3183 pinfo = saa_init(1L);
3184 pinforel = saa_init(1L);
3185 saa_write16(pinfo,2); /* dwarf version */
3186 saa_write32(pinforel, pinfo->datalen + 4);
3187 saa_write32(pinforel, (dwarf_abbrevsym << 8) + R_386_32); /* reloc to abbrev */
3188 saa_write32(pinforel, 0);
3189 saa_write32(pinfo,0); /* offset into abbrev */
3190 saa_write8(pinfo,4); /* pointer size */
3191 saa_write8(pinfo,1); /* abbrviation number LEB128u */
3192 saa_write32(pinforel, pinfo->datalen + 4);
3193 saa_write32(pinforel, ((dwarf_fsect->section + 2) << 8) + R_386_32);
3194 saa_write32(pinforel, 0);
3195 saa_write32(pinfo,0); /* DW_AT_low_pc */
3196 saa_write32(pinforel, pinfo->datalen + 4);
3197 saa_write32(pinforel, ((dwarf_fsect->section + 2) << 8) + R_386_32);
3198 saa_write32(pinforel, 0);
3199 saa_write32(pinfo,highaddr); /* DW_AT_high_pc */
3200 saa_write32(pinforel, pinfo->datalen + 4);
3201 saa_write32(pinforel, (dwarf_linesym << 8) + R_386_32); /* reloc to line */
3202 saa_write32(pinforel, 0);
3203 saa_write32(pinfo,0); /* DW_AT_stmt_list */
3204 saa_wbytes(pinfo, elf_module, strlen(elf_module)+1);
3205 saa_wbytes(pinfo, nasm_signature(), nasm_signature_len()+1);
3206 saa_write16(pinfo,DW_LANG_Mips_Assembler);
3207 saa_write8(pinfo,2); /* abbrviation number LEB128u */
3208 saa_write32(pinforel, pinfo->datalen + 4);
3209 saa_write32(pinforel, ((dwarf_fsect->section + 2) << 8) + R_386_32);
3210 saa_write32(pinforel, 0);
3211 saa_write32(pinfo,0); /* DW_AT_low_pc */
3212 saa_write32(pinfo,0); /* DW_AT_frame_base */
3213 saa_write8(pinfo,0); /* end of entries */
3214 saalen = pinfo->datalen;
3215 infolen = saalen + 4;
3216 infobuf = pbuf = nasm_malloc(infolen);
3217 WRITELONG(pbuf,saalen); /* initial length */
3218 saa_rnbytes(pinfo, pbuf, saalen);
3219 saa_free(pinfo);
3220 } else if (is_elfx32()) {
3221 /* build info section */
3222 pinfo = saa_init(1L);
3223 pinforel = saa_init(1L);
3224 saa_write16(pinfo,3); /* dwarf version */
3225 saa_write32(pinforel, pinfo->datalen + 4);
3226 saa_write32(pinforel, (dwarf_abbrevsym << 8) + R_X86_64_32); /* reloc to abbrev */
3227 saa_write32(pinforel, 0);
3228 saa_write32(pinfo,0); /* offset into abbrev */
3229 saa_write8(pinfo,4); /* pointer size */
3230 saa_write8(pinfo,1); /* abbrviation number LEB128u */
3231 saa_write32(pinforel, pinfo->datalen + 4);
3232 saa_write32(pinforel, ((dwarf_fsect->section + 2) << 8) + R_X86_64_32);
3233 saa_write32(pinforel, 0);
3234 saa_write32(pinfo,0); /* DW_AT_low_pc */
3235 saa_write32(pinforel, pinfo->datalen + 4);
3236 saa_write32(pinforel, ((dwarf_fsect->section + 2) << 8) + R_X86_64_32);
3237 saa_write32(pinforel, 0);
3238 saa_write32(pinfo,highaddr); /* DW_AT_high_pc */
3239 saa_write32(pinforel, pinfo->datalen + 4);
3240 saa_write32(pinforel, (dwarf_linesym << 8) + R_X86_64_32); /* reloc to line */
3241 saa_write32(pinforel, 0);
3242 saa_write32(pinfo,0); /* DW_AT_stmt_list */
3243 saa_wbytes(pinfo, elf_module, strlen(elf_module)+1);
3244 saa_wbytes(pinfo, nasm_signature(), nasm_signature_len()+1);
3245 saa_write16(pinfo,DW_LANG_Mips_Assembler);
3246 saa_write8(pinfo,2); /* abbrviation number LEB128u */
3247 saa_write32(pinforel, pinfo->datalen + 4);
3248 saa_write32(pinforel, ((dwarf_fsect->section + 2) << 8) + R_X86_64_32);
3249 saa_write32(pinforel, 0);
3250 saa_write32(pinfo,0); /* DW_AT_low_pc */
3251 saa_write32(pinfo,0); /* DW_AT_frame_base */
3252 saa_write8(pinfo,0); /* end of entries */
3253 saalen = pinfo->datalen;
3254 infolen = saalen + 4;
3255 infobuf = pbuf = nasm_malloc(infolen);
3256 WRITELONG(pbuf,saalen); /* initial length */
3257 saa_rnbytes(pinfo, pbuf, saalen);
3258 saa_free(pinfo);
3259 } else {
3260 nasm_assert(is_elf64());
3261 /* build info section */
3262 pinfo = saa_init(1L);
3263 pinforel = saa_init(1L);
3264 saa_write16(pinfo,3); /* dwarf version */
3265 saa_write64(pinforel, pinfo->datalen + 4);
3266 saa_write64(pinforel, (dwarf_abbrevsym << 32) + R_X86_64_32); /* reloc to abbrev */
3267 saa_write64(pinforel, 0);
3268 saa_write32(pinfo,0); /* offset into abbrev */
3269 saa_write8(pinfo,8); /* pointer size */
3270 saa_write8(pinfo,1); /* abbrviation number LEB128u */
3271 saa_write64(pinforel, pinfo->datalen + 4);
3272 saa_write64(pinforel, ((uint64_t)(dwarf_fsect->section + 2) << 32) + R_X86_64_64);
3273 saa_write64(pinforel, 0);
3274 saa_write64(pinfo,0); /* DW_AT_low_pc */
3275 saa_write64(pinforel, pinfo->datalen + 4);
3276 saa_write64(pinforel, ((uint64_t)(dwarf_fsect->section + 2) << 32) + R_X86_64_64);
3277 saa_write64(pinforel, 0);
3278 saa_write64(pinfo,highaddr); /* DW_AT_high_pc */
3279 saa_write64(pinforel, pinfo->datalen + 4);
3280 saa_write64(pinforel, (dwarf_linesym << 32) + R_X86_64_32); /* reloc to line */
3281 saa_write64(pinforel, 0);
3282 saa_write32(pinfo,0); /* DW_AT_stmt_list */
3283 saa_wbytes(pinfo, elf_module, strlen(elf_module)+1);
3284 saa_wbytes(pinfo, nasm_signature(), nasm_signature_len()+1);
3285 saa_write16(pinfo,DW_LANG_Mips_Assembler);
3286 saa_write8(pinfo,2); /* abbrviation number LEB128u */
3287 saa_write64(pinforel, pinfo->datalen + 4);
3288 saa_write64(pinforel, ((uint64_t)(dwarf_fsect->section + 2) << 32) + R_X86_64_64);
3289 saa_write64(pinforel, 0);
3290 saa_write64(pinfo,0); /* DW_AT_low_pc */
3291 saa_write64(pinfo,0); /* DW_AT_frame_base */
3292 saa_write8(pinfo,0); /* end of entries */
3293 saalen = pinfo->datalen;
3294 infolen = saalen + 4;
3295 infobuf = pbuf = nasm_malloc(infolen);
3296 WRITELONG(pbuf,saalen); /* initial length */
3297 saa_rnbytes(pinfo, pbuf, saalen);
3298 saa_free(pinfo);
3301 /* build rela.info section */
3302 inforellen = saalen = pinforel->datalen;
3303 inforelbuf = pbuf = nasm_malloc(inforellen);
3304 saa_rnbytes(pinforel, pbuf, saalen);
3305 saa_free(pinforel);
3307 /* build abbrev section */
3308 pabbrev = saa_init(1L);
3309 saa_write8(pabbrev,1); /* entry number LEB128u */
3310 saa_write8(pabbrev,DW_TAG_compile_unit); /* tag LEB128u */
3311 saa_write8(pabbrev,1); /* has children */
3312 /* the following attributes and forms are all LEB128u values */
3313 saa_write8(pabbrev,DW_AT_low_pc);
3314 saa_write8(pabbrev,DW_FORM_addr);
3315 saa_write8(pabbrev,DW_AT_high_pc);
3316 saa_write8(pabbrev,DW_FORM_addr);
3317 saa_write8(pabbrev,DW_AT_stmt_list);
3318 saa_write8(pabbrev,DW_FORM_data4);
3319 saa_write8(pabbrev,DW_AT_name);
3320 saa_write8(pabbrev,DW_FORM_string);
3321 saa_write8(pabbrev,DW_AT_producer);
3322 saa_write8(pabbrev,DW_FORM_string);
3323 saa_write8(pabbrev,DW_AT_language);
3324 saa_write8(pabbrev,DW_FORM_data2);
3325 saa_write16(pabbrev,0); /* end of entry */
3326 /* LEB128u usage same as above */
3327 saa_write8(pabbrev,2); /* entry number */
3328 saa_write8(pabbrev,DW_TAG_subprogram);
3329 saa_write8(pabbrev,0); /* no children */
3330 saa_write8(pabbrev,DW_AT_low_pc);
3331 saa_write8(pabbrev,DW_FORM_addr);
3332 saa_write8(pabbrev,DW_AT_frame_base);
3333 saa_write8(pabbrev,DW_FORM_data4);
3334 saa_write16(pabbrev,0); /* end of entry */
3335 /* Terminal zero entry */
3336 saa_write8(pabbrev,0);
3337 abbrevlen = saalen = pabbrev->datalen;
3338 abbrevbuf = pbuf = nasm_malloc(saalen);
3339 saa_rnbytes(pabbrev, pbuf, saalen);
3340 saa_free(pabbrev);
3342 /* build line section */
3343 /* prolog */
3344 plines = saa_init(1L);
3345 saa_write8(plines,1); /* Minimum Instruction Length */
3346 saa_write8(plines,1); /* Initial value of 'is_stmt' */
3347 saa_write8(plines,line_base); /* Line Base */
3348 saa_write8(plines,line_range); /* Line Range */
3349 saa_write8(plines,opcode_base); /* Opcode Base */
3350 /* standard opcode lengths (# of LEB128u operands) */
3351 saa_write8(plines,0); /* Std opcode 1 length */
3352 saa_write8(plines,1); /* Std opcode 2 length */
3353 saa_write8(plines,1); /* Std opcode 3 length */
3354 saa_write8(plines,1); /* Std opcode 4 length */
3355 saa_write8(plines,1); /* Std opcode 5 length */
3356 saa_write8(plines,0); /* Std opcode 6 length */
3357 saa_write8(plines,0); /* Std opcode 7 length */
3358 saa_write8(plines,0); /* Std opcode 8 length */
3359 saa_write8(plines,1); /* Std opcode 9 length */
3360 saa_write8(plines,0); /* Std opcode 10 length */
3361 saa_write8(plines,0); /* Std opcode 11 length */
3362 saa_write8(plines,1); /* Std opcode 12 length */
3363 /* Directory Table */
3364 saa_write8(plines,0); /* End of table */
3365 /* File Name Table */
3366 ftentry = dwarf_flist;
3367 for (indx = 0; indx < dwarf_numfiles; indx++) {
3368 saa_wbytes(plines, ftentry->filename, (int32_t)(strlen(ftentry->filename) + 1));
3369 saa_write8(plines,0); /* directory LEB128u */
3370 saa_write8(plines,0); /* time LEB128u */
3371 saa_write8(plines,0); /* size LEB128u */
3372 ftentry = ftentry->next;
3374 saa_write8(plines,0); /* End of table */
3375 linepoff = plines->datalen;
3376 linelen = linepoff + totlen + 10;
3377 linebuf = pbuf = nasm_malloc(linelen);
3378 WRITELONG(pbuf,linelen-4); /* initial length */
3379 WRITESHORT(pbuf,3); /* dwarf version */
3380 WRITELONG(pbuf,linepoff); /* offset to line number program */
3381 /* write line header */
3382 saalen = linepoff;
3383 saa_rnbytes(plines, pbuf, saalen); /* read a given no. of bytes */
3384 pbuf += linepoff;
3385 saa_free(plines);
3386 /* concatonate line program ranges */
3387 linepoff += 13;
3388 plinesrel = saa_init(1L);
3389 psect = dwarf_fsect;
3390 if (is_elf32()) {
3391 for (indx = 0; indx < dwarf_nsections; indx++) {
3392 saa_write32(plinesrel, linepoff);
3393 saa_write32(plinesrel, ((uint32_t) (psect->section + 2) << 8) + R_386_32);
3394 saa_write32(plinesrel, (uint32_t) 0);
3395 plinep = psect->psaa;
3396 saalen = plinep->datalen;
3397 saa_rnbytes(plinep, pbuf, saalen);
3398 pbuf += saalen;
3399 linepoff += saalen;
3400 saa_free(plinep);
3401 /* done with this entry */
3402 psect = psect->next;
3404 } else if (is_elfx32()) {
3405 for (indx = 0; indx < dwarf_nsections; indx++) {
3406 saa_write32(plinesrel, linepoff);
3407 saa_write32(plinesrel, ((psect->section + 2) << 8) + R_X86_64_32);
3408 saa_write32(plinesrel, 0);
3409 plinep = psect->psaa;
3410 saalen = plinep->datalen;
3411 saa_rnbytes(plinep, pbuf, saalen);
3412 pbuf += saalen;
3413 linepoff += saalen;
3414 saa_free(plinep);
3415 /* done with this entry */
3416 psect = psect->next;
3418 } else {
3419 nasm_assert(is_elf64());
3420 for (indx = 0; indx < dwarf_nsections; indx++) {
3421 saa_write64(plinesrel, linepoff);
3422 saa_write64(plinesrel, ((uint64_t) (psect->section + 2) << 32) + R_X86_64_64);
3423 saa_write64(plinesrel, (uint64_t) 0);
3424 plinep = psect->psaa;
3425 saalen = plinep->datalen;
3426 saa_rnbytes(plinep, pbuf, saalen);
3427 pbuf += saalen;
3428 linepoff += saalen;
3429 saa_free(plinep);
3430 /* done with this entry */
3431 psect = psect->next;
3435 /* build rela.lines section */
3436 linerellen =saalen = plinesrel->datalen;
3437 linerelbuf = pbuf = nasm_malloc(linerellen);
3438 saa_rnbytes(plinesrel, pbuf, saalen);
3439 saa_free(plinesrel);
3441 /* build frame section */
3442 if (0) {
3443 /* This only applies if there is at least one frame defined */
3444 framelen = 4;
3445 framebuf = pbuf = nasm_malloc(framelen);
3446 WRITELONG(pbuf,framelen-4); /* initial length */
3447 } else {
3448 framelen = 0;
3451 /* build loc section */
3452 loclen = 16;
3453 locbuf = pbuf = nasm_malloc(loclen);
3454 if (is_elf32()) {
3455 WRITELONG(pbuf,0); /* null beginning offset */
3456 WRITELONG(pbuf,0); /* null ending offset */
3457 } else if (is_elfx32()) {
3458 WRITELONG(pbuf,0); /* null beginning offset */
3459 WRITELONG(pbuf,0); /* null ending offset */
3460 } else {
3461 nasm_assert(is_elf64());
3462 WRITEDLONG(pbuf,0); /* null beginning offset */
3463 WRITEDLONG(pbuf,0); /* null ending offset */
3467 static void dwarf_cleanup(void)
3469 nasm_free(arangesbuf);
3470 nasm_free(arangesrelbuf);
3471 nasm_free(pubnamesbuf);
3472 nasm_free(infobuf);
3473 nasm_free(inforelbuf);
3474 nasm_free(abbrevbuf);
3475 nasm_free(linebuf);
3476 nasm_free(linerelbuf);
3477 nasm_free(framebuf);
3478 nasm_free(locbuf);
3481 static void dwarf_findfile(const char * fname)
3483 int finx;
3484 struct linelist *match;
3486 /* return if fname is current file name */
3487 if (dwarf_clist && !(strcmp(fname, dwarf_clist->filename)))
3488 return;
3490 /* search for match */
3491 match = 0;
3492 if (dwarf_flist) {
3493 match = dwarf_flist;
3494 for (finx = 0; finx < dwarf_numfiles; finx++) {
3495 if (!(strcmp(fname, match->filename))) {
3496 dwarf_clist = match;
3497 return;
3499 match = match->next;
3503 /* add file name to end of list */
3504 dwarf_clist = nasm_malloc(sizeof(struct linelist));
3505 dwarf_numfiles++;
3506 dwarf_clist->line = dwarf_numfiles;
3507 dwarf_clist->filename = nasm_malloc(strlen(fname) + 1);
3508 strcpy(dwarf_clist->filename,fname);
3509 dwarf_clist->next = 0;
3510 if (!dwarf_flist) { /* if first entry */
3511 dwarf_flist = dwarf_elist = dwarf_clist;
3512 dwarf_clist->last = 0;
3513 } else { /* chain to previous entry */
3514 dwarf_elist->next = dwarf_clist;
3515 dwarf_elist = dwarf_clist;
3519 static void dwarf_findsect(const int index)
3521 int sinx;
3522 struct sectlist *match;
3523 struct SAA *plinep;
3525 /* return if index is current section index */
3526 if (dwarf_csect && (dwarf_csect->section == index))
3527 return;
3529 /* search for match */
3530 match = 0;
3531 if (dwarf_fsect) {
3532 match = dwarf_fsect;
3533 for (sinx = 0; sinx < dwarf_nsections; sinx++) {
3534 if (match->section == index) {
3535 dwarf_csect = match;
3536 return;
3538 match = match->next;
3542 /* add entry to end of list */
3543 dwarf_csect = nasm_malloc(sizeof(struct sectlist));
3544 dwarf_nsections++;
3545 dwarf_csect->psaa = plinep = saa_init(1L);
3546 dwarf_csect->line = 1;
3547 dwarf_csect->offset = 0;
3548 dwarf_csect->file = 1;
3549 dwarf_csect->section = index;
3550 dwarf_csect->next = 0;
3551 /* set relocatable address at start of line program */
3552 saa_write8(plinep,DW_LNS_extended_op);
3553 saa_write8(plinep,is_elf64() ? 9 : 5); /* operand length */
3554 saa_write8(plinep,DW_LNE_set_address);
3555 if (is_elf64())
3556 saa_write64(plinep,0); /* Start Address */
3557 else
3558 saa_write32(plinep,0); /* Start Address */
3560 if (!dwarf_fsect) { /* if first entry */
3561 dwarf_fsect = dwarf_esect = dwarf_csect;
3562 dwarf_csect->last = 0;
3563 } else { /* chain to previous entry */
3564 dwarf_esect->next = dwarf_csect;
3565 dwarf_esect = dwarf_csect;
3569 #endif /* defined(OF_ELF32) || defined(OF_ELF64) || defined(OF_ELFX32) */