insns.pl: use less cantankerous string expansion; better error info
[nasm.git] / output / outelf.c
blob1ebb02623a1fc29a8d2bbb6dbeba663f82570273
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 void elf_deflabel(char *name, int32_t segment, int64_t offset,
731 int is_global, char *special)
733 int pos = strslen;
734 struct elf_symbol *sym;
735 bool special_used = false;
737 #if defined(DEBUG) && DEBUG>2
738 nasm_debug(" elf_deflabel: %s, seg=%"PRIx32", off=%"PRIx64", is_global=%d, %s\n",
739 name, segment, offset, is_global, special);
740 #endif
741 if (name[0] == '.' && name[1] == '.' && name[2] != '@') {
743 * This is a NASM special symbol. We never allow it into
744 * the ELF symbol table, even if it's a valid one. If it
745 * _isn't_ a valid one, we should barf immediately.
747 * FIXME: tlsie is Elf32 only, and gottpoff is Elfx32|64 only.
749 if (strcmp(name, "..gotpc") && strcmp(name, "..gotoff") &&
750 strcmp(name, "..got") && strcmp(name, "..plt") &&
751 strcmp(name, "..sym") && strcmp(name, "..gottpoff") &&
752 strcmp(name, "..tlsie"))
753 nasm_nonfatal("unrecognised special symbol `%s'", name);
754 return;
757 if (is_global == 3) {
758 struct elf_symbol **s;
760 * Fix up a forward-reference symbol size from the first
761 * pass.
763 for (s = &fwds; *s; s = &(*s)->nextfwd)
764 if (!strcmp((*s)->name, name)) {
765 struct tokenval tokval;
766 expr *e;
767 char *p = nasm_skip_spaces(nasm_skip_word(special));
769 stdscan_reset();
770 stdscan_set(p);
771 tokval.t_type = TOKEN_INVALID;
772 e = evaluate(stdscan, NULL, &tokval, NULL, 1, NULL);
773 if (e) {
774 if (!is_simple(e))
775 nasm_nonfatal("cannot use relocatable"
776 " expression as symbol size");
777 else
778 (*s)->size = reloc_value(e);
782 * Remove it from the list of unresolved sizes.
784 nasm_free((*s)->name);
785 *s = (*s)->nextfwd;
786 return;
788 return; /* it wasn't an important one */
791 saa_wbytes(strs, name, (int32_t)(1 + strlen(name)));
792 strslen += 1 + strlen(name);
794 lastsym = sym = saa_wstruct(syms);
796 memset(&sym->symv, 0, sizeof(struct rbtree));
798 sym->strpos = pos;
799 sym->type = is_global ? SYM_GLOBAL : SYM_LOCAL;
800 sym->other = STV_DEFAULT;
801 sym->size = 0;
802 if (segment == NO_SEG)
803 sym->section = XSHN_ABS;
804 else {
805 const struct elf_section *s;
806 sym->section = XSHN_UNDEF;
807 if (segment == def_seg) {
808 /* we have to be sure at least text section is there */
809 int tempint;
810 if (segment != elf_section_names(".text", &tempint))
811 nasm_panic("strange segment conditions in ELF driver");
813 s = raa_read_ptr(section_by_index, segment >> 1);
814 if (s)
815 sym->section = s->shndx;
818 if (is_global == 2) {
819 sym->size = offset;
820 sym->symv.key = 0;
821 sym->section = XSHN_COMMON;
823 * We have a common variable. Check the special text to see
824 * if it's a valid number and power of two; if so, store it
825 * as the alignment for the common variable.
827 if (special) {
828 bool err;
829 sym->symv.key = readnum(special, &err);
830 if (err)
831 nasm_nonfatal("alignment constraint `%s' is not a"
832 " valid number", special);
833 else if ((sym->symv.key | (sym->symv.key - 1)) != 2 * sym->symv.key - 1)
834 nasm_nonfatal("alignment constraint `%s' is not a"
835 " power of two", special);
837 special_used = true;
838 } else
839 sym->symv.key = (sym->section == XSHN_UNDEF ? 0 : offset);
841 if (sym->type == SYM_GLOBAL) {
843 * If sym->section == SHN_ABS, then the first line of the
844 * else section would cause a core dump, because its a reference
845 * beyond the end of the section array.
846 * This behaviour is exhibited by this code:
847 * GLOBAL crash_nasm
848 * crash_nasm equ 0
849 * To avoid such a crash, such requests are silently discarded.
850 * This may not be the best solution.
852 if (sym->section == XSHN_UNDEF || sym->section == XSHN_COMMON) {
853 bsym = raa_write(bsym, segment, nglobs);
854 } else if (sym->section != XSHN_ABS) {
856 * This is a global symbol; so we must add it to the rbtree
857 * of global symbols in its section.
859 * In addition, we check the special text for symbol
860 * type and size information.
862 sects[sym->section-1]->gsyms =
863 rb_insert(sects[sym->section-1]->gsyms, &sym->symv);
865 if (special) {
866 int n = strcspn(special, " \t");
868 if (!nasm_strnicmp(special, "function", n))
869 sym->type |= STT_FUNC;
870 else if (!nasm_strnicmp(special, "data", n) ||
871 !nasm_strnicmp(special, "object", n))
872 sym->type |= STT_OBJECT;
873 else if (!nasm_strnicmp(special, "notype", n))
874 sym->type |= STT_NOTYPE;
875 else
876 nasm_nonfatal("unrecognised symbol type `%.*s'",
877 n, special);
878 special += n;
880 special = nasm_skip_spaces(special);
881 if (*special) {
882 n = strcspn(special, " \t");
883 if (!nasm_strnicmp(special, "default", n))
884 sym->other = STV_DEFAULT;
885 else if (!nasm_strnicmp(special, "internal", n))
886 sym->other = STV_INTERNAL;
887 else if (!nasm_strnicmp(special, "hidden", n))
888 sym->other = STV_HIDDEN;
889 else if (!nasm_strnicmp(special, "protected", n))
890 sym->other = STV_PROTECTED;
891 else
892 n = 0;
893 special += n;
896 if (*special) {
897 struct tokenval tokval;
898 expr *e;
899 int fwd = 0;
900 char *saveme = stdscan_get();
902 while (special[n] && nasm_isspace(special[n]))
903 n++;
905 * We have a size expression; attempt to
906 * evaluate it.
908 stdscan_reset();
909 stdscan_set(special + n);
910 tokval.t_type = TOKEN_INVALID;
911 e = evaluate(stdscan, NULL, &tokval, &fwd, 0, NULL);
912 if (fwd) {
913 sym->nextfwd = fwds;
914 fwds = sym;
915 sym->name = nasm_strdup(name);
916 } else if (e) {
917 if (!is_simple(e))
918 nasm_nonfatal("cannot use relocatable"
919 " expression as symbol size");
920 else
921 sym->size = reloc_value(e);
923 stdscan_set(saveme);
925 special_used = true;
928 * If TLS segment, mark symbol accordingly.
930 if (sects[sym->section - 1]->flags & SHF_TLS) {
931 sym->type &= 0xf0;
932 sym->type |= STT_TLS;
935 sym->globnum = nglobs;
936 nglobs++;
937 } else
938 nlocals++;
940 if (special && !special_used)
941 nasm_nonfatal("no special symbol features supported here");
944 static void elf_add_reloc(struct elf_section *sect, int32_t segment,
945 int64_t offset, int type)
947 struct elf_reloc *r;
949 r = *sect->tail = nasm_zalloc(sizeof(struct elf_reloc));
950 sect->tail = &r->next;
952 r->address = sect->len;
953 r->offset = offset;
955 if (segment != NO_SEG) {
956 const struct elf_section *s;
957 s = raa_read_ptr(section_by_index, segment >> 1);
958 if (s)
959 r->symbol = s->shndx + 1;
960 else
961 r->symbol = GLOBAL_TEMP_BASE + raa_read(bsym, segment);
963 r->type = type;
965 sect->nrelocs++;
969 * This routine deals with ..got and ..sym relocations: the more
970 * complicated kinds. In shared-library writing, some relocations
971 * with respect to global symbols must refer to the precise symbol
972 * rather than referring to an offset from the base of the section
973 * _containing_ the symbol. Such relocations call to this routine,
974 * which searches the symbol list for the symbol in question.
976 * R_386_GOT32 | R_X86_64_GOT32 references require the _exact_ symbol address to be
977 * used; R_386_32 | R_X86_64_32 references can be at an offset from the symbol.
978 * The boolean argument `exact' tells us this.
980 * Return value is the adjusted value of `addr', having become an
981 * offset from the symbol rather than the section. Should always be
982 * zero when returning from an exact call.
984 * Limitation: if you define two symbols at the same place,
985 * confusion will occur.
987 * Inefficiency: we search, currently, using a linked list which
988 * isn't even necessarily sorted.
990 static int64_t elf_add_gsym_reloc(struct elf_section *sect,
991 int32_t segment, uint64_t offset,
992 int64_t pcrel, int type, bool exact)
994 struct elf_reloc *r;
995 struct elf_section *s;
996 struct elf_symbol *sym;
997 struct rbtree *srb;
1000 * First look up the segment/offset pair and find a global
1001 * symbol corresponding to it. If it's not one of our segments,
1002 * then it must be an external symbol, in which case we're fine
1003 * doing a normal elf_add_reloc after first sanity-checking
1004 * that the offset from the symbol is zero.
1006 s = raa_read_ptr(section_by_index, segment >> 1);
1007 if (!s) {
1008 if (exact && offset)
1009 nasm_nonfatal("invalid access to an external symbol");
1010 else
1011 elf_add_reloc(sect, segment, offset - pcrel, type);
1012 return 0;
1015 srb = rb_search(s->gsyms, offset);
1016 if (!srb || (exact && srb->key != offset)) {
1017 nasm_nonfatal("unable to find a suitable global symbol"
1018 " for this reference");
1019 return 0;
1021 sym = container_of(srb, struct elf_symbol, symv);
1023 r = *sect->tail = nasm_malloc(sizeof(struct elf_reloc));
1024 sect->tail = &r->next;
1026 r->next = NULL;
1027 r->address = sect->len;
1028 r->offset = offset - pcrel - sym->symv.key;
1029 r->symbol = GLOBAL_TEMP_BASE + sym->globnum;
1030 r->type = type;
1032 sect->nrelocs++;
1033 return r->offset;
1036 static void elf32_out(int32_t segto, const void *data,
1037 enum out_type type, uint64_t size,
1038 int32_t segment, int32_t wrt)
1040 struct elf_section *s;
1041 int64_t addr;
1042 int reltype, bytes;
1043 static struct symlininfo sinfo;
1046 * handle absolute-assembly (structure definitions)
1048 if (segto == NO_SEG) {
1049 if (type != OUT_RESERVE)
1050 nasm_nonfatal("attempt to assemble code in [ABSOLUTE] space");
1051 return;
1054 s = raa_read_ptr(section_by_index, segto >> 1);
1055 if (!s) {
1056 int tempint; /* ignored */
1057 if (segto != elf_section_names(".text", &tempint))
1058 nasm_panic("strange segment conditions in ELF driver");
1059 else
1060 s = sects[nsects - 1];
1063 /* again some stabs debugging stuff */
1064 sinfo.offset = s->len;
1065 sinfo.section = s->shndx;
1066 sinfo.segto = segto;
1067 sinfo.name = s->name;
1068 dfmt->debug_output(TY_DEBUGSYMLIN, &sinfo);
1069 /* end of debugging stuff */
1071 if (s->type == SHT_NOBITS && type != OUT_RESERVE) {
1072 nasm_warn(WARN_OTHER, "attempt to initialize memory in"
1073 " BSS section `%s': ignored", s->name);
1074 s->len += realsize(type, size);
1075 return;
1078 switch (type) {
1079 case OUT_RESERVE:
1080 if (s->type != SHT_NOBITS) {
1081 nasm_warn(WARN_ZEROING, "uninitialized space declared in"
1082 " non-BSS section `%s': zeroing", s->name);
1083 elf_sect_write(s, NULL, size);
1084 } else
1085 s->len += size;
1086 break;
1088 case OUT_RAWDATA:
1089 elf_sect_write(s, data, size);
1090 break;
1092 case OUT_ADDRESS:
1094 bool err = false;
1095 int asize = abs((int)size);
1097 addr = *(int64_t *)data;
1098 if (segment != NO_SEG) {
1099 if (segment & 1) {
1100 nasm_nonfatal("ELF format does not support"
1101 " segment base references");
1102 } else {
1103 if (wrt == NO_SEG) {
1105 * The if() is a hack to deal with compilers which
1106 * don't handle switch() statements with 64-bit
1107 * expressions.
1109 switch (asize) {
1110 case 1:
1111 elf_add_reloc(s, segment, 0, R_386_8);
1112 break;
1113 case 2:
1114 elf_add_reloc(s, segment, 0, R_386_16);
1115 break;
1116 case 4:
1117 elf_add_reloc(s, segment, 0, R_386_32);
1118 break;
1119 default: /* Error issued further down */
1120 err = true;
1121 break;
1123 } else if (wrt == elf_gotpc_sect + 1) {
1125 * The user will supply GOT relative to $$. ELF
1126 * will let us have GOT relative to $. So we
1127 * need to fix up the data item by $-$$.
1129 err = asize != 4;
1130 addr += s->len;
1131 elf_add_reloc(s, segment, 0, R_386_GOTPC);
1132 } else if (wrt == elf_gotoff_sect + 1) {
1133 err = asize != 4;
1134 elf_add_reloc(s, segment, 0, R_386_GOTOFF);
1135 } else if (wrt == elf_tlsie_sect + 1) {
1136 err = asize != 4;
1137 addr = elf_add_gsym_reloc(s, segment, addr, 0,
1138 R_386_TLS_IE, true);
1139 } else if (wrt == elf_got_sect + 1) {
1140 err = asize != 4;
1141 addr = elf_add_gsym_reloc(s, segment, addr, 0,
1142 R_386_GOT32, true);
1143 } else if (wrt == elf_sym_sect + 1) {
1144 switch (asize) {
1145 case 1:
1146 addr = elf_add_gsym_reloc(s, segment, addr, 0,
1147 R_386_8, false);
1148 break;
1149 case 2:
1150 addr = elf_add_gsym_reloc(s, segment, addr, 0,
1151 R_386_16, false);
1152 break;
1153 case 4:
1154 addr = elf_add_gsym_reloc(s, segment, addr, 0,
1155 R_386_32, false);
1156 break;
1157 default:
1158 err = true;
1159 break;
1161 } else if (wrt == elf_plt_sect + 1) {
1162 nasm_nonfatal("ELF format cannot produce non-PC-"
1163 "relative PLT references");
1164 } else {
1165 nasm_nonfatal("ELF format does not support this"
1166 " use of WRT");
1167 wrt = NO_SEG; /* we can at least _try_ to continue */
1172 if (err) {
1173 nasm_nonfatal("Unsupported %d-bit ELF relocation", asize << 3);
1175 elf_sect_writeaddr(s, addr, asize);
1176 break;
1179 case OUT_REL1ADR:
1180 reltype = R_386_PC8;
1181 bytes = 1;
1182 goto rel12adr;
1183 case OUT_REL2ADR:
1184 reltype = R_386_PC16;
1185 bytes = 2;
1186 goto rel12adr;
1188 rel12adr:
1189 addr = *(int64_t *)data - size;
1190 nasm_assert(segment != segto);
1191 if (segment != NO_SEG && (segment & 1)) {
1192 nasm_nonfatal("ELF format does not support"
1193 " segment base references");
1194 } else {
1195 if (wrt == NO_SEG) {
1196 elf_add_reloc(s, segment, 0, reltype);
1197 } else {
1198 nasm_nonfatal("Unsupported %d-bit ELF relocation", bytes << 3);
1201 elf_sect_writeaddr(s, addr, bytes);
1202 break;
1204 case OUT_REL4ADR:
1205 addr = *(int64_t *)data - size;
1206 if (segment == segto)
1207 nasm_panic("intra-segment OUT_REL4ADR");
1208 if (segment != NO_SEG && (segment & 1)) {
1209 nasm_nonfatal("ELF format does not support"
1210 " segment base references");
1211 } else {
1212 if (wrt == NO_SEG) {
1213 elf_add_reloc(s, segment, 0, R_386_PC32);
1214 } else if (wrt == elf_plt_sect + 1) {
1215 elf_add_reloc(s, segment, 0, R_386_PLT32);
1216 } else if (wrt == elf_gotpc_sect + 1 ||
1217 wrt == elf_gotoff_sect + 1 ||
1218 wrt == elf_got_sect + 1) {
1219 nasm_nonfatal("ELF format cannot produce PC-"
1220 "relative GOT references");
1221 } else {
1222 nasm_nonfatal("ELF format does not support this"
1223 " use of WRT");
1224 wrt = NO_SEG; /* we can at least _try_ to continue */
1227 elf_sect_writeaddr(s, addr, 4);
1228 break;
1230 case OUT_REL8ADR:
1231 nasm_nonfatal("32-bit ELF format does not support 64-bit relocations");
1232 addr = 0;
1233 elf_sect_writeaddr(s, addr, 8);
1234 break;
1236 default:
1237 panic();
1240 static void elf64_out(int32_t segto, const void *data,
1241 enum out_type type, uint64_t size,
1242 int32_t segment, int32_t wrt)
1244 struct elf_section *s;
1245 int64_t addr;
1246 int reltype, bytes;
1247 static struct symlininfo sinfo;
1250 * handle absolute-assembly (structure definitions)
1252 if (segto == NO_SEG) {
1253 if (type != OUT_RESERVE)
1254 nasm_nonfatal("attempt to assemble code in [ABSOLUTE] space");
1255 return;
1258 s = raa_read_ptr(section_by_index, segto >> 1);
1259 if (!s) {
1260 int tempint; /* ignored */
1261 if (segto != elf_section_names(".text", &tempint))
1262 nasm_panic("strange segment conditions in ELF driver");
1263 else
1264 s = sects[nsects - 1];
1267 /* again some stabs debugging stuff */
1268 sinfo.offset = s->len;
1269 sinfo.section = s->shndx;
1270 sinfo.segto = segto;
1271 sinfo.name = s->name;
1272 dfmt->debug_output(TY_DEBUGSYMLIN, &sinfo);
1273 /* end of debugging stuff */
1275 if (s->type == SHT_NOBITS && type != OUT_RESERVE) {
1276 nasm_warn(WARN_OTHER, "attempt to initialize memory in"
1277 " BSS section `%s': ignored", s->name);
1278 s->len += realsize(type, size);
1279 return;
1282 switch (type) {
1283 case OUT_RESERVE:
1284 if (s->type != SHT_NOBITS) {
1285 nasm_warn(WARN_ZEROING, "uninitialized space declared in"
1286 " non-BSS section `%s': zeroing", s->name);
1287 elf_sect_write(s, NULL, size);
1288 } else
1289 s->len += size;
1290 break;
1292 case OUT_RAWDATA:
1293 if (segment != NO_SEG)
1294 nasm_panic("OUT_RAWDATA with other than NO_SEG");
1295 elf_sect_write(s, data, size);
1296 break;
1298 case OUT_ADDRESS:
1300 int isize = (int)size;
1301 int asize = abs((int)size);
1303 addr = *(int64_t *)data;
1304 if (segment == NO_SEG) {
1305 /* Do nothing */
1306 } else if (segment & 1) {
1307 nasm_nonfatal("ELF format does not support"
1308 " segment base references");
1309 } else {
1310 if (wrt == NO_SEG) {
1311 switch (isize) {
1312 case 1:
1313 case -1:
1314 elf_add_reloc(s, segment, addr, R_X86_64_8);
1315 break;
1316 case 2:
1317 case -2:
1318 elf_add_reloc(s, segment, addr, R_X86_64_16);
1319 break;
1320 case 4:
1321 elf_add_reloc(s, segment, addr, R_X86_64_32);
1322 break;
1323 case -4:
1324 elf_add_reloc(s, segment, addr, R_X86_64_32S);
1325 break;
1326 case 8:
1327 case -8:
1328 elf_add_reloc(s, segment, addr, R_X86_64_64);
1329 break;
1330 default:
1331 nasm_panic("internal error elf64-hpa-871");
1332 break;
1334 addr = 0;
1335 } else if (wrt == elf_gotpc_sect + 1) {
1337 * The user will supply GOT relative to $$. ELF
1338 * will let us have GOT relative to $. So we
1339 * need to fix up the data item by $-$$.
1341 addr += s->len;
1342 elf_add_reloc(s, segment, addr, R_X86_64_GOTPC32);
1343 addr = 0;
1344 } else if (wrt == elf_gotoff_sect + 1) {
1345 if (asize != 8) {
1346 nasm_nonfatal("ELF64 requires ..gotoff "
1347 "references to be qword");
1348 } else {
1349 elf_add_reloc(s, segment, addr, R_X86_64_GOTOFF64);
1350 addr = 0;
1352 } else if (wrt == elf_got_sect + 1) {
1353 switch (asize) {
1354 case 4:
1355 elf_add_gsym_reloc(s, segment, addr, 0,
1356 R_X86_64_GOT32, true);
1357 addr = 0;
1358 break;
1359 case 8:
1360 elf_add_gsym_reloc(s, segment, addr, 0,
1361 R_X86_64_GOT64, true);
1362 addr = 0;
1363 break;
1364 default:
1365 nasm_nonfatal("invalid ..got reference");
1366 break;
1368 } else if (wrt == elf_sym_sect + 1) {
1369 switch (isize) {
1370 case 1:
1371 case -1:
1372 elf_add_gsym_reloc(s, segment, addr, 0,
1373 R_X86_64_8, false);
1374 addr = 0;
1375 break;
1376 case 2:
1377 case -2:
1378 elf_add_gsym_reloc(s, segment, addr, 0,
1379 R_X86_64_16, false);
1380 addr = 0;
1381 break;
1382 case 4:
1383 elf_add_gsym_reloc(s, segment, addr, 0,
1384 R_X86_64_32, false);
1385 addr = 0;
1386 break;
1387 case -4:
1388 elf_add_gsym_reloc(s, segment, addr, 0,
1389 R_X86_64_32S, false);
1390 addr = 0;
1391 break;
1392 case 8:
1393 case -8:
1394 elf_add_gsym_reloc(s, segment, addr, 0,
1395 R_X86_64_64, false);
1396 addr = 0;
1397 break;
1398 default:
1399 nasm_panic("internal error elf64-hpa-903");
1400 break;
1402 } else if (wrt == elf_plt_sect + 1) {
1403 nasm_nonfatal("ELF format cannot produce non-PC-"
1404 "relative PLT references");
1405 } else {
1406 nasm_nonfatal("ELF format does not support this"
1407 " use of WRT");
1410 elf_sect_writeaddr(s, addr, asize);
1411 break;
1414 case OUT_REL1ADR:
1415 reltype = R_X86_64_PC8;
1416 bytes = 1;
1417 goto rel12adr;
1419 case OUT_REL2ADR:
1420 reltype = R_X86_64_PC16;
1421 bytes = 2;
1422 goto rel12adr;
1424 rel12adr:
1425 addr = *(int64_t *)data - size;
1426 if (segment == segto)
1427 nasm_panic("intra-segment OUT_REL1ADR");
1428 if (segment == NO_SEG) {
1429 /* Do nothing */
1430 } else if (segment & 1) {
1431 nasm_nonfatal("ELF format does not support"
1432 " segment base references");
1433 } else {
1434 if (wrt == NO_SEG) {
1435 elf_add_reloc(s, segment, addr, reltype);
1436 addr = 0;
1437 } else {
1438 nasm_nonfatal("Unsupported %d-bit ELF relocation", bytes << 3);
1441 elf_sect_writeaddr(s, addr, bytes);
1442 break;
1444 case OUT_REL4ADR:
1445 addr = *(int64_t *)data - size;
1446 if (segment == segto)
1447 nasm_panic("intra-segment OUT_REL4ADR");
1448 if (segment == NO_SEG) {
1449 /* Do nothing */
1450 } else if (segment & 1) {
1451 nasm_nonfatal("ELF64 format does not support"
1452 " segment base references");
1453 } else {
1454 if (wrt == NO_SEG) {
1455 elf_add_reloc(s, segment, addr, R_X86_64_PC32);
1456 addr = 0;
1457 } else if (wrt == elf_plt_sect + 1) {
1458 elf_add_gsym_reloc(s, segment, addr+size, size,
1459 R_X86_64_PLT32, true);
1460 addr = 0;
1461 } else if (wrt == elf_gotpc_sect + 1 ||
1462 wrt == elf_got_sect + 1) {
1463 elf_add_gsym_reloc(s, segment, addr+size, size,
1464 R_X86_64_GOTPCREL, true);
1465 addr = 0;
1466 } else if (wrt == elf_gotoff_sect + 1 ||
1467 wrt == elf_got_sect + 1) {
1468 nasm_nonfatal("ELF64 requires ..gotoff references to be "
1469 "qword absolute");
1470 } else if (wrt == elf_gottpoff_sect + 1) {
1471 elf_add_gsym_reloc(s, segment, addr+size, size,
1472 R_X86_64_GOTTPOFF, true);
1473 addr = 0;
1474 } else {
1475 nasm_nonfatal("ELF64 format does not support this"
1476 " use of WRT");
1479 elf_sect_writeaddr(s, addr, 4);
1480 break;
1482 case OUT_REL8ADR:
1483 addr = *(int64_t *)data - size;
1484 if (segment == segto)
1485 nasm_panic("intra-segment OUT_REL8ADR");
1486 if (segment == NO_SEG) {
1487 /* Do nothing */
1488 } else if (segment & 1) {
1489 nasm_nonfatal("ELF64 format does not support"
1490 " segment base references");
1491 } else {
1492 if (wrt == NO_SEG) {
1493 elf_add_reloc(s, segment, addr, R_X86_64_PC64);
1494 addr = 0;
1495 } else if (wrt == elf_gotpc_sect + 1 ||
1496 wrt == elf_got_sect + 1) {
1497 elf_add_gsym_reloc(s, segment, addr+size, size,
1498 R_X86_64_GOTPCREL64, true);
1499 addr = 0;
1500 } else if (wrt == elf_gotoff_sect + 1 ||
1501 wrt == elf_got_sect + 1) {
1502 nasm_nonfatal("ELF64 requires ..gotoff references to be "
1503 "absolute");
1504 } else if (wrt == elf_gottpoff_sect + 1) {
1505 nasm_nonfatal("ELF64 requires ..gottpoff references to be "
1506 "dword");
1507 } else {
1508 nasm_nonfatal("ELF64 format does not support this"
1509 " use of WRT");
1512 elf_sect_writeaddr(s, addr, 8);
1513 break;
1515 default:
1516 panic();
1520 static void elfx32_out(int32_t segto, const void *data,
1521 enum out_type type, uint64_t size,
1522 int32_t segment, int32_t wrt)
1524 struct elf_section *s;
1525 int64_t addr;
1526 int reltype, bytes;
1527 static struct symlininfo sinfo;
1530 * handle absolute-assembly (structure definitions)
1532 if (segto == NO_SEG) {
1533 if (type != OUT_RESERVE)
1534 nasm_nonfatal("attempt to assemble code in [ABSOLUTE] space");
1535 return;
1538 s = raa_read_ptr(section_by_index, segto >> 1);
1539 if (!s) {
1540 int tempint; /* ignored */
1541 if (segto != elf_section_names(".text", &tempint))
1542 nasm_panic("strange segment conditions in ELF driver");
1543 else
1544 s = sects[nsects - 1];
1547 /* again some stabs debugging stuff */
1548 sinfo.offset = s->len;
1549 sinfo.section = s->shndx;
1550 sinfo.segto = segto;
1551 sinfo.name = s->name;
1552 dfmt->debug_output(TY_DEBUGSYMLIN, &sinfo);
1553 /* end of debugging stuff */
1555 if (s->type == SHT_NOBITS && type != OUT_RESERVE) {
1556 nasm_warn(WARN_OTHER, "attempt to initialize memory in"
1557 " BSS section `%s': ignored", s->name);
1558 s->len += realsize(type, size);
1559 return;
1562 switch (type) {
1563 case OUT_RESERVE:
1564 if (s->type != SHT_NOBITS) {
1565 nasm_warn(WARN_ZEROING, "uninitialized space declared in"
1566 " non-BSS section `%s': zeroing", s->name);
1567 elf_sect_write(s, NULL, size);
1568 } else
1569 s->len += size;
1570 break;
1572 case OUT_RAWDATA:
1573 if (segment != NO_SEG)
1574 nasm_panic("OUT_RAWDATA with other than NO_SEG");
1575 elf_sect_write(s, data, size);
1576 break;
1578 case OUT_ADDRESS:
1580 int isize = (int)size;
1581 int asize = abs((int)size);
1583 addr = *(int64_t *)data;
1584 if (segment == NO_SEG) {
1585 /* Do nothing */
1586 } else if (segment & 1) {
1587 nasm_nonfatal("ELF format does not support"
1588 " segment base references");
1589 } else {
1590 if (wrt == NO_SEG) {
1591 switch (isize) {
1592 case 1:
1593 case -1:
1594 elf_add_reloc(s, segment, addr, R_X86_64_8);
1595 break;
1596 case 2:
1597 case -2:
1598 elf_add_reloc(s, segment, addr, R_X86_64_16);
1599 break;
1600 case 4:
1601 elf_add_reloc(s, segment, addr, R_X86_64_32);
1602 break;
1603 case -4:
1604 elf_add_reloc(s, segment, addr, R_X86_64_32S);
1605 break;
1606 case 8:
1607 case -8:
1608 elf_add_reloc(s, segment, addr, R_X86_64_64);
1609 break;
1610 default:
1611 nasm_panic("internal error elfx32-hpa-871");
1612 break;
1614 addr = 0;
1615 } else if (wrt == elf_gotpc_sect + 1) {
1617 * The user will supply GOT relative to $$. ELF
1618 * will let us have GOT relative to $. So we
1619 * need to fix up the data item by $-$$.
1621 addr += s->len;
1622 elf_add_reloc(s, segment, addr, R_X86_64_GOTPC32);
1623 addr = 0;
1624 } else if (wrt == elf_gotoff_sect + 1) {
1625 nasm_nonfatal("ELFX32 doesn't support "
1626 "R_X86_64_GOTOFF64");
1627 } else if (wrt == elf_got_sect + 1) {
1628 switch (asize) {
1629 case 4:
1630 elf_add_gsym_reloc(s, segment, addr, 0,
1631 R_X86_64_GOT32, true);
1632 addr = 0;
1633 break;
1634 default:
1635 nasm_nonfatal("invalid ..got reference");
1636 break;
1638 } else if (wrt == elf_sym_sect + 1) {
1639 switch (isize) {
1640 case 1:
1641 case -1:
1642 elf_add_gsym_reloc(s, segment, addr, 0,
1643 R_X86_64_8, false);
1644 addr = 0;
1645 break;
1646 case 2:
1647 case -2:
1648 elf_add_gsym_reloc(s, segment, addr, 0,
1649 R_X86_64_16, false);
1650 addr = 0;
1651 break;
1652 case 4:
1653 elf_add_gsym_reloc(s, segment, addr, 0,
1654 R_X86_64_32, false);
1655 addr = 0;
1656 break;
1657 case -4:
1658 elf_add_gsym_reloc(s, segment, addr, 0,
1659 R_X86_64_32S, false);
1660 addr = 0;
1661 break;
1662 case 8:
1663 case -8:
1664 elf_add_gsym_reloc(s, segment, addr, 0,
1665 R_X86_64_64, false);
1666 addr = 0;
1667 break;
1668 default:
1669 nasm_panic("internal error elfx32-hpa-903");
1670 break;
1672 } else if (wrt == elf_plt_sect + 1) {
1673 nasm_nonfatal("ELF format cannot produce non-PC-"
1674 "relative PLT references");
1675 } else {
1676 nasm_nonfatal("ELF format does not support this"
1677 " use of WRT");
1680 elf_sect_writeaddr(s, addr, asize);
1681 break;
1684 case OUT_REL1ADR:
1685 reltype = R_X86_64_PC8;
1686 bytes = 1;
1687 goto rel12adr;
1689 case OUT_REL2ADR:
1690 reltype = R_X86_64_PC16;
1691 bytes = 2;
1692 goto rel12adr;
1694 rel12adr:
1695 addr = *(int64_t *)data - size;
1696 if (segment == segto)
1697 nasm_panic("intra-segment OUT_REL1ADR");
1698 if (segment == NO_SEG) {
1699 /* Do nothing */
1700 } else if (segment & 1) {
1701 nasm_nonfatal("ELF format does not support"
1702 " segment base references");
1703 } else {
1704 if (wrt == NO_SEG) {
1705 elf_add_reloc(s, segment, addr, reltype);
1706 addr = 0;
1707 } else {
1708 nasm_nonfatal("unsupported %d-bit ELF relocation", bytes << 3);
1711 elf_sect_writeaddr(s, addr, bytes);
1712 break;
1714 case OUT_REL4ADR:
1715 addr = *(int64_t *)data - size;
1716 if (segment == segto)
1717 nasm_panic("intra-segment OUT_REL4ADR");
1718 if (segment == NO_SEG) {
1719 /* Do nothing */
1720 } else if (segment & 1) {
1721 nasm_nonfatal("ELFX32 format does not support"
1722 " segment base references");
1723 } else {
1724 if (wrt == NO_SEG) {
1725 elf_add_reloc(s, segment, addr, R_X86_64_PC32);
1726 addr = 0;
1727 } else if (wrt == elf_plt_sect + 1) {
1728 elf_add_gsym_reloc(s, segment, addr+size, size,
1729 R_X86_64_PLT32, true);
1730 addr = 0;
1731 } else if (wrt == elf_gotpc_sect + 1 ||
1732 wrt == elf_got_sect + 1) {
1733 elf_add_gsym_reloc(s, segment, addr+size, size,
1734 R_X86_64_GOTPCREL, true);
1735 addr = 0;
1736 } else if (wrt == elf_gotoff_sect + 1 ||
1737 wrt == elf_got_sect + 1) {
1738 nasm_nonfatal("invalid ..gotoff reference");
1739 } else if (wrt == elf_gottpoff_sect + 1) {
1740 elf_add_gsym_reloc(s, segment, addr+size, size,
1741 R_X86_64_GOTTPOFF, true);
1742 addr = 0;
1743 } else {
1744 nasm_nonfatal("ELFX32 format does not support this use of WRT");
1747 elf_sect_writeaddr(s, addr, 4);
1748 break;
1750 case OUT_REL8ADR:
1751 nasm_nonfatal("32-bit ELF format does not support 64-bit relocations");
1752 addr = 0;
1753 elf_sect_writeaddr(s, addr, 8);
1754 break;
1756 default:
1757 panic();
1762 * Section index/count with a specified overflow value (usually SHN_INDEX,
1763 * but 0 for e_shnum.
1765 static inline uint16_t elf_shndx(int section, uint16_t overflow)
1767 return cpu_to_le16(section < (int)SHN_LORESERVE ? section : overflow);
1770 struct ehdr_common {
1771 uint8_t e_ident[EI_NIDENT];
1772 uint16_t e_type;
1773 uint16_t e_machine;
1774 uint32_t e_version;
1777 union ehdr {
1778 Elf32_Ehdr ehdr32;
1779 Elf64_Ehdr ehdr64;
1780 struct ehdr_common com;
1783 static void elf_write(void)
1785 int align;
1786 char *p;
1787 int i;
1788 size_t symtablocal;
1789 int sec_shstrtab, sec_symtab, sec_strtab;
1790 union ehdr ehdr;
1793 * Add any sections we don't already have:
1794 * rel/rela sections for the user sections, debug sections, and
1795 * the ELF special sections.
1798 sec_debug = nsections;
1799 if (dfmt_is_stabs()) {
1800 /* in case the debug information is wanted, just add these three sections... */
1801 add_sectname("", ".stab");
1802 add_sectname("", ".stabstr");
1803 add_sectname(efmt->relpfx, ".stab");
1804 } else if (dfmt_is_dwarf()) {
1805 /* the dwarf debug standard specifies the following ten sections,
1806 not all of which are currently implemented,
1807 although all of them are defined. */
1808 add_sectname("", ".debug_aranges");
1809 add_sectname(".rela", ".debug_aranges");
1810 add_sectname("", ".debug_pubnames");
1811 add_sectname("", ".debug_info");
1812 add_sectname(".rela", ".debug_info");
1813 add_sectname("", ".debug_abbrev");
1814 add_sectname("", ".debug_line");
1815 add_sectname(".rela", ".debug_line");
1816 add_sectname("", ".debug_frame");
1817 add_sectname("", ".debug_loc");
1820 sec_shstrtab = add_sectname("", ".shstrtab");
1821 sec_symtab = add_sectname("", ".symtab");
1822 sec_strtab = add_sectname("", ".strtab");
1825 * Build the symbol table and relocation tables.
1827 symtablocal = elf_build_symtab();
1829 /* Do we need an .symtab_shndx section? */
1830 if (symtab_shndx)
1831 add_sectname("", ".symtab_shndx");
1833 for (i = 0; i < nsects; i++) {
1834 if (sects[i]->head) {
1835 add_sectname(efmt->relpfx, sects[i]->name);
1836 sects[i]->rel = efmt->elf_build_reltab(sects[i]->head);
1841 * Output the ELF header.
1843 nasm_zero(ehdr);
1845 /* These fields are in the same place for 32 and 64 bits */
1846 memcpy(&ehdr.com.e_ident[EI_MAG0], ELFMAG, SELFMAG);
1847 ehdr.com.e_ident[EI_CLASS] = efmt->ei_class;
1848 ehdr.com.e_ident[EI_DATA] = ELFDATA2LSB;
1849 ehdr.com.e_ident[EI_VERSION] = EV_CURRENT;
1850 ehdr.com.e_ident[EI_OSABI] = elf_osabi;
1851 ehdr.com.e_ident[EI_ABIVERSION] = elf_abiver;
1852 ehdr.com.e_type = cpu_to_le16(ET_REL);
1853 ehdr.com.e_machine = cpu_to_le16(efmt->e_machine);
1854 ehdr.com.e_version = cpu_to_le16(EV_CURRENT);
1856 if (!efmt->elf64) {
1857 ehdr.ehdr32.e_shoff = cpu_to_le32(sizeof ehdr);
1858 ehdr.ehdr32.e_ehsize = cpu_to_le16(sizeof(Elf32_Ehdr));
1859 ehdr.ehdr32.e_shentsize = cpu_to_le16(sizeof(Elf32_Shdr));
1860 ehdr.ehdr32.e_shnum = elf_shndx(nsections, 0);
1861 ehdr.ehdr32.e_shstrndx = elf_shndx(sec_shstrtab, SHN_XINDEX);
1862 } else {
1863 ehdr.ehdr64.e_shoff = cpu_to_le64(sizeof ehdr);
1864 ehdr.ehdr64.e_ehsize = cpu_to_le16(sizeof(Elf64_Ehdr));
1865 ehdr.ehdr64.e_shentsize = cpu_to_le16(sizeof(Elf64_Shdr));
1866 ehdr.ehdr64.e_shnum = elf_shndx(nsections, 0);
1867 ehdr.ehdr64.e_shstrndx = elf_shndx(sec_shstrtab, SHN_XINDEX);
1870 nasm_write(&ehdr, sizeof(ehdr), ofile);
1871 elf_foffs = sizeof ehdr + efmt->shdr_size * nsections;
1874 * Now output the section header table.
1876 align = ALIGN(elf_foffs, SEC_FILEALIGN) - elf_foffs;
1877 elf_foffs += align;
1878 elf_nsect = 0;
1879 elf_sects = nasm_malloc(sizeof(*elf_sects) * nsections);
1881 /* SHN_UNDEF */
1882 elf_section_header(0, SHT_NULL, 0, NULL, false,
1883 nsections > (int)SHN_LORESERVE ? nsections : 0,
1884 sec_shstrtab >= (int)SHN_LORESERVE ? sec_shstrtab : 0,
1885 0, 0, 0);
1886 p = shstrtab + 1;
1888 /* The normal sections */
1889 for (i = 0; i < nsects; i++) {
1890 elf_section_header(p - shstrtab, sects[i]->type, sects[i]->flags,
1891 sects[i]->data, true,
1892 sects[i]->len, 0, 0,
1893 sects[i]->align, sects[i]->entsize);
1894 p += strlen(p) + 1;
1897 /* The debugging sections */
1898 if (dfmt_is_stabs()) {
1899 /* for debugging information, create the last three sections
1900 which are the .stab , .stabstr and .rel.stab sections respectively */
1902 /* this function call creates the stab sections in memory */
1903 stabs_generate();
1905 if (stabbuf && stabstrbuf && stabrelbuf) {
1906 elf_section_header(p - shstrtab, SHT_PROGBITS, 0, stabbuf, false,
1907 stablen, sec_stabstr, 0, 4, 12);
1908 p += strlen(p) + 1;
1910 elf_section_header(p - shstrtab, SHT_STRTAB, 0, stabstrbuf, false,
1911 stabstrlen, 0, 0, 4, 0);
1912 p += strlen(p) + 1;
1914 /* link -> symtable info -> section to refer to */
1915 elf_section_header(p - shstrtab, efmt->reltype, 0,
1916 stabrelbuf, false, stabrellen,
1917 sec_symtab, sec_stab,
1918 efmt->word, efmt->rel_size);
1919 p += strlen(p) + 1;
1921 } else if (dfmt_is_dwarf()) {
1922 /* for dwarf debugging information, create the ten dwarf sections */
1924 /* this function call creates the dwarf sections in memory */
1925 if (dwarf_fsect)
1926 dwarf_generate();
1928 elf_section_header(p - shstrtab, SHT_PROGBITS, 0, arangesbuf, false,
1929 arangeslen, 0, 0, 1, 0);
1930 p += strlen(p) + 1;
1932 elf_section_header(p - shstrtab, SHT_RELA, 0, arangesrelbuf, false,
1933 arangesrellen, sec_symtab,
1934 sec_debug_aranges,
1935 efmt->word, efmt->rela_size);
1936 p += strlen(p) + 1;
1938 elf_section_header(p - shstrtab, SHT_PROGBITS, 0, pubnamesbuf,
1939 false, pubnameslen, 0, 0, 1, 0);
1940 p += strlen(p) + 1;
1942 elf_section_header(p - shstrtab, SHT_PROGBITS, 0, infobuf, false,
1943 infolen, 0, 0, 1, 0);
1944 p += strlen(p) + 1;
1946 elf_section_header(p - shstrtab, SHT_RELA, 0, inforelbuf, false,
1947 inforellen, sec_symtab,
1948 sec_debug_info,
1949 efmt->word, efmt->rela_size);
1950 p += strlen(p) + 1;
1952 elf_section_header(p - shstrtab, SHT_PROGBITS, 0, abbrevbuf, false,
1953 abbrevlen, 0, 0, 1, 0);
1954 p += strlen(p) + 1;
1956 elf_section_header(p - shstrtab, SHT_PROGBITS, 0, linebuf, false,
1957 linelen, 0, 0, 1, 0);
1958 p += strlen(p) + 1;
1960 elf_section_header(p - shstrtab, SHT_RELA, 0, linerelbuf, false,
1961 linerellen, sec_symtab,
1962 sec_debug_line,
1963 efmt->word, efmt->rela_size);
1964 p += strlen(p) + 1;
1966 elf_section_header(p - shstrtab, SHT_PROGBITS, 0, framebuf, false,
1967 framelen, 0, 0, 8, 0);
1968 p += strlen(p) + 1;
1970 elf_section_header(p - shstrtab, SHT_PROGBITS, 0, locbuf, false,
1971 loclen, 0, 0, 1, 0);
1972 p += strlen(p) + 1;
1975 /* .shstrtab */
1976 elf_section_header(p - shstrtab, SHT_STRTAB, 0, shstrtab, false,
1977 shstrtablen, 0, 0, 1, 0);
1978 p += strlen(p) + 1;
1980 /* .symtab */
1981 elf_section_header(p - shstrtab, SHT_SYMTAB, 0, symtab, true,
1982 symtab->datalen, sec_strtab, symtablocal,
1983 efmt->word, efmt->sym_size);
1984 p += strlen(p) + 1;
1986 /* .strtab */
1987 elf_section_header(p - shstrtab, SHT_STRTAB, 0, strs, true,
1988 strslen, 0, 0, 1, 0);
1989 p += strlen(p) + 1
1991 /* .symtab_shndx */
1992 if (symtab_shndx) {
1993 elf_section_header(p - shstrtab, SHT_SYMTAB_SHNDX, 0,
1994 symtab_shndx, true, symtab_shndx->datalen,
1995 sec_symtab, 0, 1, 0);
1996 p += strlen(p) + 1;
1999 /* The relocation sections */
2000 for (i = 0; i < nsects; i++) {
2001 if (sects[i]->rel) {
2002 elf_section_header(p - shstrtab, efmt->reltype, 0,
2003 sects[i]->rel, true, sects[i]->rel->datalen,
2004 sec_symtab, sects[i]->shndx,
2005 efmt->word, efmt->rel_size);
2006 p += strlen(p) + 1;
2009 fwritezero(align, ofile);
2012 * Now output the sections.
2014 elf_write_sections();
2016 nasm_free(elf_sects);
2017 saa_free(symtab);
2018 if (symtab_shndx)
2019 saa_free(symtab_shndx);
2022 static size_t nsyms;
2024 static void elf_sym(const struct elf_symbol *sym)
2026 int shndx = sym->section;
2029 * Careful here. This relies on sym->section being signed; for
2030 * special section indicies this value needs to be cast to
2031 * (int16_t) so that it sign-extends, however, here SHN_LORESERVE
2032 * is used as an unsigned constant.
2034 if (shndx >= (int)SHN_LORESERVE) {
2035 if (unlikely(!symtab_shndx)) {
2036 /* Create symtab_shndx and fill previous entries with zero */
2037 symtab_shndx = saa_init(1);
2038 saa_wbytes(symtab_shndx, NULL, nsyms << 2);
2040 } else {
2041 shndx = 0; /* Section index table always write zero */
2044 if (symtab_shndx)
2045 saa_write32(symtab_shndx, shndx);
2047 efmt->elf_sym(sym);
2048 nsyms++;
2051 static void elf32_sym(const struct elf_symbol *sym)
2053 Elf32_Sym sym32;
2055 sym32.st_name = cpu_to_le32(sym->strpos);
2056 sym32.st_value = cpu_to_le32(sym->symv.key);
2057 sym32.st_size = cpu_to_le32(sym->size);
2058 sym32.st_info = sym->type;
2059 sym32.st_other = sym->other;
2060 sym32.st_shndx = elf_shndx(sym->section, SHN_XINDEX);
2061 saa_wbytes(symtab, &sym32, sizeof sym32);
2064 static void elf64_sym(const struct elf_symbol *sym)
2066 Elf64_Sym sym64;
2068 sym64.st_name = cpu_to_le32(sym->strpos);
2069 sym64.st_value = cpu_to_le64(sym->symv.key);
2070 sym64.st_size = cpu_to_le64(sym->size);
2071 sym64.st_info = sym->type;
2072 sym64.st_other = sym->other;
2073 sym64.st_shndx = elf_shndx(sym->section, SHN_XINDEX);
2074 saa_wbytes(symtab, &sym64, sizeof sym64);
2077 static size_t elf_build_symtab(void)
2079 struct elf_symbol *sym, xsym;
2080 size_t nlocal;
2081 int i;
2083 symtab = saa_init(1);
2084 symtab_shndx = NULL;
2087 * Zero symbol first as required by spec.
2089 nasm_zero(xsym);
2090 elf_sym(&xsym);
2093 * Next, an entry for the file name.
2095 nasm_zero(xsym);
2096 xsym.strpos = 1;
2097 xsym.type = ELF32_ST_INFO(STB_LOCAL, STT_FILE);
2098 xsym.section = XSHN_ABS;
2099 elf_sym(&xsym);
2102 * Now some standard symbols defining the segments, for relocation
2103 * purposes.
2105 nasm_zero(xsym);
2106 for (i = 1; i <= nsects; i++) {
2107 xsym.type = ELF64_ST_INFO(STB_LOCAL, STT_SECTION);
2108 xsym.section = i;
2109 elf_sym(&xsym);
2113 * dwarf needs symbols for debug sections
2114 * which are relocation targets.
2116 if (dfmt_is_dwarf()) {
2117 dwarf_infosym = nsyms;
2118 xsym.section = sec_debug_info;
2119 elf_sym(&xsym);
2121 dwarf_abbrevsym = nsyms;
2122 xsym.section = sec_debug_abbrev;
2123 elf_sym(&xsym);
2125 dwarf_linesym = nsyms;
2126 xsym.section = sec_debug_line;
2127 elf_sym(&xsym);
2131 * Now the other local symbols.
2133 saa_rewind(syms);
2134 while ((sym = saa_rstruct(syms))) {
2135 if (sym->type & SYM_GLOBAL)
2136 continue;
2138 elf_sym(sym);
2141 nlocal = nsyms;
2144 * Now the global symbols.
2146 saa_rewind(syms);
2147 while ((sym = saa_rstruct(syms))) {
2148 if (!(sym->type & SYM_GLOBAL))
2149 continue;
2151 elf_sym(sym);
2154 return nlocal;
2157 static struct SAA *elf32_build_reltab(const struct elf_reloc *r)
2159 struct SAA *s;
2160 int32_t global_offset;
2161 Elf32_Rel rel32;
2163 if (!r)
2164 return NULL;
2166 s = saa_init(1L);
2169 * How to onvert from a global placeholder to a real symbol index;
2170 * the +2 refers to the two special entries, the null entry and
2171 * the filename entry.
2173 global_offset = -GLOBAL_TEMP_BASE + nsects + nlocals + ndebugs + 2;
2175 while (r) {
2176 int32_t sym = r->symbol;
2178 if (sym >= GLOBAL_TEMP_BASE)
2179 sym += global_offset;
2181 rel32.r_offset = cpu_to_le32(r->address);
2182 rel32.r_info = cpu_to_le32(ELF32_R_INFO(sym, r->type));
2183 saa_wbytes(s, &rel32, sizeof rel32);
2185 r = r->next;
2188 return s;
2191 static struct SAA *elfx32_build_reltab(const struct elf_reloc *r)
2193 struct SAA *s;
2194 int32_t global_offset;
2195 Elf32_Rela rela32;
2197 if (!r)
2198 return NULL;
2200 s = saa_init(1L);
2203 * How to onvert from a global placeholder to a real symbol index;
2204 * the +2 refers to the two special entries, the null entry and
2205 * the filename entry.
2207 global_offset = -GLOBAL_TEMP_BASE + nsects + nlocals + ndebugs + 2;
2209 while (r) {
2210 int32_t sym = r->symbol;
2212 if (sym >= GLOBAL_TEMP_BASE)
2213 sym += global_offset;
2215 rela32.r_offset = cpu_to_le32(r->address);
2216 rela32.r_info = cpu_to_le32(ELF32_R_INFO(sym, r->type));
2217 rela32.r_addend = cpu_to_le32(r->offset);
2218 saa_wbytes(s, &rela32, sizeof rela32);
2220 r = r->next;
2223 return s;
2226 static struct SAA *elf64_build_reltab(const struct elf_reloc *r)
2228 struct SAA *s;
2229 int32_t global_offset;
2230 Elf64_Rela rela64;
2232 if (!r)
2233 return NULL;
2235 s = saa_init(1L);
2238 * How to onvert from a global placeholder to a real symbol index;
2239 * the +2 refers to the two special entries, the null entry and
2240 * the filename entry.
2242 global_offset = -GLOBAL_TEMP_BASE + nsects + nlocals + ndebugs + 2;
2244 while (r) {
2245 int32_t sym = r->symbol;
2247 if (sym >= GLOBAL_TEMP_BASE)
2248 sym += global_offset;
2250 rela64.r_offset = cpu_to_le64(r->address);
2251 rela64.r_info = cpu_to_le64(ELF64_R_INFO(sym, r->type));
2252 rela64.r_addend = cpu_to_le64(r->offset);
2253 saa_wbytes(s, &rela64, sizeof rela64);
2255 r = r->next;
2258 return s;
2261 static void elf_section_header(int name, int type, uint64_t flags,
2262 void *data, bool is_saa, uint64_t datalen,
2263 int link, int info,
2264 uint64_t align, uint64_t entsize)
2266 elf_sects[elf_nsect].data = data;
2267 elf_sects[elf_nsect].len = datalen;
2268 elf_sects[elf_nsect].is_saa = is_saa;
2269 elf_nsect++;
2271 if (!efmt->elf64) {
2272 Elf32_Shdr shdr;
2274 shdr.sh_name = cpu_to_le32(name);
2275 shdr.sh_type = cpu_to_le32(type);
2276 shdr.sh_flags = cpu_to_le32(flags);
2277 shdr.sh_addr = 0;
2278 shdr.sh_offset = cpu_to_le32(type == SHT_NULL ? 0 : elf_foffs);
2279 shdr.sh_size = cpu_to_le32(datalen);
2280 if (data)
2281 elf_foffs += ALIGN(datalen, SEC_FILEALIGN);
2282 shdr.sh_link = cpu_to_le32(link);
2283 shdr.sh_info = cpu_to_le32(info);
2284 shdr.sh_addralign = cpu_to_le32(align);
2285 shdr.sh_entsize = cpu_to_le32(entsize);
2287 nasm_write(&shdr, sizeof shdr, ofile);
2288 } else {
2289 Elf64_Shdr shdr;
2291 shdr.sh_name = cpu_to_le32(name);
2292 shdr.sh_type = cpu_to_le32(type);
2293 shdr.sh_flags = cpu_to_le64(flags);
2294 shdr.sh_addr = 0;
2295 shdr.sh_offset = cpu_to_le64(type == SHT_NULL ? 0 : elf_foffs);
2296 shdr.sh_size = cpu_to_le64(datalen);
2297 if (data)
2298 elf_foffs += ALIGN(datalen, SEC_FILEALIGN);
2299 shdr.sh_link = cpu_to_le32(link);
2300 shdr.sh_info = cpu_to_le32(info);
2301 shdr.sh_addralign = cpu_to_le64(align);
2302 shdr.sh_entsize = cpu_to_le64(entsize);
2304 nasm_write(&shdr, sizeof shdr, ofile);
2308 static void elf_write_sections(void)
2310 int i;
2311 for (i = 0; i < elf_nsect; i++)
2312 if (elf_sects[i].data) {
2313 int32_t len = elf_sects[i].len;
2314 int32_t reallen = ALIGN(len, SEC_FILEALIGN);
2315 int32_t align = reallen - len;
2316 if (elf_sects[i].is_saa)
2317 saa_fpwrite(elf_sects[i].data, ofile);
2318 else
2319 nasm_write(elf_sects[i].data, len, ofile);
2320 fwritezero(align, ofile);
2324 static void elf_sect_write(struct elf_section *sect, const void *data, size_t len)
2326 saa_wbytes(sect->data, data, len);
2327 sect->len += len;
2330 static void elf_sect_writeaddr(struct elf_section *sect, int64_t data, size_t len)
2332 saa_writeaddr(sect->data, data, len);
2333 sect->len += len;
2336 static void elf_sectalign(int32_t seg, unsigned int value)
2338 struct elf_section *s;
2340 s = raa_read_ptr(section_by_index, seg >> 1);
2341 if (!s || !is_power2(value))
2342 return;
2344 if (value > s->align)
2345 s->align = value;
2348 extern macros_t elf_stdmac[];
2350 /* Claim "elf" as a pragma namespace, for the future */
2351 static const struct pragma_facility elf_pragma_list[] =
2353 { "elf", NULL },
2354 { NULL, NULL } /* Implements the canonical output name */
2358 static const struct dfmt elf32_df_dwarf = {
2359 "ELF32 (i386) dwarf debug format for Linux/Unix",
2360 "dwarf",
2361 dwarf_init,
2362 dwarf_linenum,
2363 null_debug_deflabel,
2364 null_debug_directive,
2365 debug_typevalue,
2366 dwarf_output,
2367 dwarf_cleanup,
2368 NULL /* pragma list */
2371 static const struct dfmt elf32_df_stabs = {
2372 "ELF32 (i386) stabs debug format for Linux/Unix",
2373 "stabs",
2374 null_debug_init,
2375 stabs_linenum,
2376 null_debug_deflabel,
2377 null_debug_directive,
2378 debug_typevalue,
2379 stabs_output,
2380 stabs_cleanup,
2381 NULL /* pragma list */
2384 static const struct dfmt * const elf32_debugs_arr[3] =
2385 { &elf32_df_dwarf, &elf32_df_stabs, NULL };
2387 const struct ofmt of_elf32 = {
2388 "ELF32 (i386) object files (e.g. Linux)",
2389 "elf32",
2390 ".o",
2393 elf32_debugs_arr,
2394 &elf32_df_stabs,
2395 elf_stdmac,
2396 elf32_init,
2397 null_reset,
2398 nasm_do_legacy_output,
2399 elf32_out,
2400 elf_deflabel,
2401 elf_section_names,
2402 NULL,
2403 elf_sectalign,
2404 null_segbase,
2405 elf_directive,
2406 elf_cleanup,
2407 elf_pragma_list,
2410 static const struct dfmt elf64_df_dwarf = {
2411 "ELF64 (x86-64) dwarf debug format for Linux/Unix",
2412 "dwarf",
2413 dwarf_init,
2414 dwarf_linenum,
2415 null_debug_deflabel,
2416 null_debug_directive,
2417 debug_typevalue,
2418 dwarf_output,
2419 dwarf_cleanup,
2420 NULL /* pragma list */
2423 static const struct dfmt elf64_df_stabs = {
2424 "ELF64 (x86-64) stabs debug format for Linux/Unix",
2425 "stabs",
2426 null_debug_init,
2427 stabs_linenum,
2428 null_debug_deflabel,
2429 null_debug_directive,
2430 debug_typevalue,
2431 stabs_output,
2432 stabs_cleanup,
2433 NULL /* pragma list */
2436 static const struct dfmt * const elf64_debugs_arr[3] =
2437 { &elf64_df_dwarf, &elf64_df_stabs, NULL };
2439 const struct ofmt of_elf64 = {
2440 "ELF64 (x86_64) object files (e.g. Linux)",
2441 "elf64",
2442 ".o",
2445 elf64_debugs_arr,
2446 &elf64_df_stabs,
2447 elf_stdmac,
2448 elf64_init,
2449 null_reset,
2450 nasm_do_legacy_output,
2451 elf64_out,
2452 elf_deflabel,
2453 elf_section_names,
2454 NULL,
2455 elf_sectalign,
2456 null_segbase,
2457 elf_directive,
2458 elf_cleanup,
2459 elf_pragma_list,
2462 static const struct dfmt elfx32_df_dwarf = {
2463 "ELFX32 (x86-64) dwarf debug format for Linux/Unix",
2464 "dwarf",
2465 dwarf_init,
2466 dwarf_linenum,
2467 null_debug_deflabel,
2468 null_debug_directive,
2469 debug_typevalue,
2470 dwarf_output,
2471 dwarf_cleanup,
2472 NULL /* pragma list */
2475 static const struct dfmt elfx32_df_stabs = {
2476 "ELFX32 (x86-64) stabs debug format for Linux/Unix",
2477 "stabs",
2478 null_debug_init,
2479 stabs_linenum,
2480 null_debug_deflabel,
2481 null_debug_directive,
2482 debug_typevalue,
2483 stabs_output,
2484 stabs_cleanup,
2485 elf_pragma_list,
2488 static const struct dfmt * const elfx32_debugs_arr[3] =
2489 { &elfx32_df_dwarf, &elfx32_df_stabs, NULL };
2491 const struct ofmt of_elfx32 = {
2492 "ELFX32 (x86_64) object files (e.g. Linux)",
2493 "elfx32",
2494 ".o",
2497 elfx32_debugs_arr,
2498 &elfx32_df_stabs,
2499 elf_stdmac,
2500 elfx32_init,
2501 null_reset,
2502 nasm_do_legacy_output,
2503 elfx32_out,
2504 elf_deflabel,
2505 elf_section_names,
2506 NULL,
2507 elf_sectalign,
2508 null_segbase,
2509 elf_directive,
2510 elf_cleanup,
2511 NULL /* pragma list */
2514 static bool is_elf64(void)
2516 return ofmt == &of_elf64;
2519 static bool is_elf32(void)
2521 return ofmt == &of_elf32;
2524 static bool is_elfx32(void)
2526 return ofmt == &of_elfx32;
2529 static bool dfmt_is_stabs(void)
2531 return dfmt == &elf32_df_stabs ||
2532 dfmt == &elfx32_df_stabs ||
2533 dfmt == &elf64_df_stabs;
2536 static bool dfmt_is_dwarf(void)
2538 return dfmt == &elf32_df_dwarf ||
2539 dfmt == &elfx32_df_dwarf ||
2540 dfmt == &elf64_df_dwarf;
2543 /* common debugging routines */
2544 static void debug_typevalue(int32_t type)
2546 int32_t stype, ssize;
2547 switch (TYM_TYPE(type)) {
2548 case TY_LABEL:
2549 ssize = 0;
2550 stype = STT_NOTYPE;
2551 break;
2552 case TY_BYTE:
2553 ssize = 1;
2554 stype = STT_OBJECT;
2555 break;
2556 case TY_WORD:
2557 ssize = 2;
2558 stype = STT_OBJECT;
2559 break;
2560 case TY_DWORD:
2561 ssize = 4;
2562 stype = STT_OBJECT;
2563 break;
2564 case TY_FLOAT:
2565 ssize = 4;
2566 stype = STT_OBJECT;
2567 break;
2568 case TY_QWORD:
2569 ssize = 8;
2570 stype = STT_OBJECT;
2571 break;
2572 case TY_TBYTE:
2573 ssize = 10;
2574 stype = STT_OBJECT;
2575 break;
2576 case TY_OWORD:
2577 ssize = 16;
2578 stype = STT_OBJECT;
2579 break;
2580 case TY_YWORD:
2581 ssize = 32;
2582 stype = STT_OBJECT;
2583 break;
2584 case TY_ZWORD:
2585 ssize = 64;
2586 stype = STT_OBJECT;
2587 break;
2588 case TY_COMMON:
2589 ssize = 0;
2590 stype = STT_COMMON;
2591 break;
2592 case TY_SEG:
2593 ssize = 0;
2594 stype = STT_SECTION;
2595 break;
2596 case TY_EXTERN:
2597 ssize = 0;
2598 stype = STT_NOTYPE;
2599 break;
2600 case TY_EQU:
2601 ssize = 0;
2602 stype = STT_NOTYPE;
2603 break;
2604 default:
2605 ssize = 0;
2606 stype = STT_NOTYPE;
2607 break;
2609 if (stype == STT_OBJECT && lastsym && !lastsym->type) {
2610 lastsym->size = ssize;
2611 lastsym->type = stype;
2615 /* stabs debugging routines */
2617 static void stabs_linenum(const char *filename, int32_t linenumber, int32_t segto)
2619 (void)segto;
2620 if (!stabs_filename) {
2621 stabs_filename = nasm_malloc(strlen(filename) + 1);
2622 strcpy(stabs_filename, filename);
2623 } else {
2624 if (strcmp(stabs_filename, filename)) {
2625 /* yep, a memory leak...this program is one-shot anyway, so who cares...
2626 in fact, this leak comes in quite handy to maintain a list of files
2627 encountered so far in the symbol lines... */
2629 /* why not nasm_free(stabs_filename); we're done with the old one */
2631 stabs_filename = nasm_malloc(strlen(filename) + 1);
2632 strcpy(stabs_filename, filename);
2635 debug_immcall = 1;
2636 currentline = linenumber;
2639 static void stabs_output(int type, void *param)
2641 struct symlininfo *s;
2642 struct linelist *el;
2643 if (type == TY_DEBUGSYMLIN) {
2644 if (debug_immcall) {
2645 s = (struct symlininfo *)param;
2646 if (!(sects[s->section]->flags & SHF_EXECINSTR))
2647 return; /* line info is only collected for executable sections */
2648 numlinestabs++;
2649 el = nasm_malloc(sizeof(struct linelist));
2650 el->info.offset = s->offset;
2651 el->info.section = s->section;
2652 el->info.name = s->name;
2653 el->line = currentline;
2654 el->filename = stabs_filename;
2655 el->next = 0;
2656 if (stabslines) {
2657 stabslines->last->next = el;
2658 stabslines->last = el;
2659 } else {
2660 stabslines = el;
2661 stabslines->last = el;
2665 debug_immcall = 0;
2668 /* for creating the .stab , .stabstr and .rel.stab sections in memory */
2670 static void stabs_generate(void)
2672 int i, numfiles, strsize, numstabs = 0, currfile, mainfileindex;
2673 uint8_t *sbuf, *ssbuf, *rbuf, *sptr, *rptr;
2674 char **allfiles;
2675 int *fileidx;
2677 struct linelist *ptr;
2679 ptr = stabslines;
2681 allfiles = nasm_zalloc(numlinestabs * sizeof(char *));
2682 numfiles = 0;
2683 while (ptr) {
2684 if (numfiles == 0) {
2685 allfiles[0] = ptr->filename;
2686 numfiles++;
2687 } else {
2688 for (i = 0; i < numfiles; i++) {
2689 if (!strcmp(allfiles[i], ptr->filename))
2690 break;
2692 if (i >= numfiles) {
2693 allfiles[i] = ptr->filename;
2694 numfiles++;
2697 ptr = ptr->next;
2699 strsize = 1;
2700 fileidx = nasm_malloc(numfiles * sizeof(int));
2701 for (i = 0; i < numfiles; i++) {
2702 fileidx[i] = strsize;
2703 strsize += strlen(allfiles[i]) + 1;
2705 currfile = mainfileindex = 0;
2706 for (i = 0; i < numfiles; i++) {
2707 if (!strcmp(allfiles[i], elf_module)) {
2708 currfile = mainfileindex = i;
2709 break;
2714 * worst case size of the stab buffer would be:
2715 * the sourcefiles changes each line, which would mean 1 SOL, 1 SYMLIN per line
2716 * plus one "ending" entry
2718 sbuf = nasm_malloc((numlinestabs * 2 + 4) *
2719 sizeof(struct stabentry));
2720 ssbuf = nasm_malloc(strsize);
2721 rbuf = nasm_malloc(numlinestabs * (is_elf64() ? 16 : 8) * (2 + 3));
2722 rptr = rbuf;
2724 for (i = 0; i < numfiles; i++)
2725 strcpy((char *)ssbuf + fileidx[i], allfiles[i]);
2726 ssbuf[0] = 0;
2728 stabstrlen = strsize; /* set global variable for length of stab strings */
2730 sptr = sbuf;
2731 ptr = stabslines;
2732 numstabs = 0;
2734 if (ptr) {
2736 * this is the first stab, its strx points to the filename of the
2737 * the source-file, the n_desc field should be set to the number
2738 * of remaining stabs
2740 WRITE_STAB(sptr, fileidx[0], 0, 0, 0, stabstrlen);
2742 /* this is the stab for the main source file */
2743 WRITE_STAB(sptr, fileidx[mainfileindex], N_SO, 0, 0, 0);
2745 /* relocation table entry */
2748 * Since the symbol table has two entries before
2749 * the section symbols, the index in the info.section
2750 * member must be adjusted by adding 2
2753 if (is_elf32()) {
2754 WRITELONG(rptr, (sptr - sbuf) - 4);
2755 WRITELONG(rptr, ((ptr->info.section + 2) << 8) | R_386_32);
2756 } else if (is_elfx32()) {
2757 WRITELONG(rptr, (sptr - sbuf) - 4);
2758 WRITELONG(rptr, ((ptr->info.section + 2) << 8) | R_X86_64_32);
2759 WRITELONG(rptr, 0);
2760 } else {
2761 nasm_assert(is_elf64());
2762 WRITEDLONG(rptr, (int64_t)(sptr - sbuf) - 4);
2763 WRITELONG(rptr, R_X86_64_32);
2764 WRITELONG(rptr, ptr->info.section + 2);
2765 WRITEDLONG(rptr, 0);
2767 numstabs++;
2770 if (is_elf32()) {
2771 while (ptr) {
2772 if (strcmp(allfiles[currfile], ptr->filename)) {
2773 /* oops file has changed... */
2774 for (i = 0; i < numfiles; i++)
2775 if (!strcmp(allfiles[i], ptr->filename))
2776 break;
2777 currfile = i;
2778 WRITE_STAB(sptr, fileidx[currfile], N_SOL, 0, 0,
2779 ptr->info.offset);
2780 numstabs++;
2782 /* relocation table entry */
2783 WRITELONG(rptr, (sptr - sbuf) - 4);
2784 WRITELONG(rptr, ((ptr->info.section + 2) << 8) | R_386_32);
2787 WRITE_STAB(sptr, 0, N_SLINE, 0, ptr->line, ptr->info.offset);
2788 numstabs++;
2790 /* relocation table entry */
2791 WRITELONG(rptr, (sptr - sbuf) - 4);
2792 WRITELONG(rptr, ((ptr->info.section + 2) << 8) | R_386_32);
2794 ptr = ptr->next;
2796 } else if (is_elfx32()) {
2797 while (ptr) {
2798 if (strcmp(allfiles[currfile], ptr->filename)) {
2799 /* oops file has changed... */
2800 for (i = 0; i < numfiles; i++)
2801 if (!strcmp(allfiles[i], ptr->filename))
2802 break;
2803 currfile = i;
2804 WRITE_STAB(sptr, fileidx[currfile], N_SOL, 0, 0,
2805 ptr->info.offset);
2806 numstabs++;
2808 /* relocation table entry */
2809 WRITELONG(rptr, (sptr - sbuf) - 4);
2810 WRITELONG(rptr, ((ptr->info.section + 2) << 8) | R_X86_64_32);
2811 WRITELONG(rptr, ptr->info.offset);
2814 WRITE_STAB(sptr, 0, N_SLINE, 0, ptr->line, ptr->info.offset);
2815 numstabs++;
2817 /* relocation table entry */
2818 WRITELONG(rptr, (sptr - sbuf) - 4);
2819 WRITELONG(rptr, ((ptr->info.section + 2) << 8) | R_X86_64_32);
2820 WRITELONG(rptr, ptr->info.offset);
2822 ptr = ptr->next;
2824 } else {
2825 nasm_assert(is_elf64());
2826 while (ptr) {
2827 if (strcmp(allfiles[currfile], ptr->filename)) {
2828 /* oops file has changed... */
2829 for (i = 0; i < numfiles; i++)
2830 if (!strcmp(allfiles[i], ptr->filename))
2831 break;
2832 currfile = i;
2833 WRITE_STAB(sptr, fileidx[currfile], N_SOL, 0, 0,
2834 ptr->info.offset);
2835 numstabs++;
2837 /* relocation table entry */
2838 WRITEDLONG(rptr, (int64_t)(sptr - sbuf) - 4);
2839 WRITELONG(rptr, R_X86_64_32);
2840 WRITELONG(rptr, ptr->info.section + 2);
2841 WRITEDLONG(rptr, ptr->info.offset);
2844 WRITE_STAB(sptr, 0, N_SLINE, 0, ptr->line, ptr->info.offset);
2845 numstabs++;
2847 /* relocation table entry */
2848 WRITEDLONG(rptr, (int64_t)(sptr - sbuf) - 4);
2849 WRITELONG(rptr, R_X86_64_32);
2850 WRITELONG(rptr, ptr->info.section + 2);
2851 WRITEDLONG(rptr, ptr->info.offset);
2853 ptr = ptr->next;
2857 /* this is an "ending" token */
2858 WRITE_STAB(sptr, 0, N_SO, 0, 0, 0);
2859 numstabs++;
2861 ((struct stabentry *)sbuf)->n_desc = numstabs;
2863 nasm_free(allfiles);
2864 nasm_free(fileidx);
2866 stablen = (sptr - sbuf);
2867 stabrellen = (rptr - rbuf);
2868 stabrelbuf = rbuf;
2869 stabbuf = sbuf;
2870 stabstrbuf = ssbuf;
2873 static void stabs_cleanup(void)
2875 struct linelist *ptr, *del;
2876 if (!stabslines)
2877 return;
2879 ptr = stabslines;
2880 while (ptr) {
2881 del = ptr;
2882 ptr = ptr->next;
2883 nasm_free(del);
2886 nasm_free(stabbuf);
2887 nasm_free(stabrelbuf);
2888 nasm_free(stabstrbuf);
2891 /* dwarf routines */
2893 static void dwarf_init(void)
2895 ndebugs = 3; /* 3 debug symbols */
2898 static void dwarf_linenum(const char *filename, int32_t linenumber,
2899 int32_t segto)
2901 (void)segto;
2902 dwarf_findfile(filename);
2903 debug_immcall = 1;
2904 currentline = linenumber;
2907 /* called from elf_out with type == TY_DEBUGSYMLIN */
2908 static void dwarf_output(int type, void *param)
2910 int ln, aa, inx, maxln, soc;
2911 struct symlininfo *s;
2912 struct SAA *plinep;
2914 (void)type;
2916 s = (struct symlininfo *)param;
2918 /* line number info is only gathered for executable sections */
2919 if (!(sects[s->section]->flags & SHF_EXECINSTR))
2920 return;
2922 /* Check if section index has changed */
2923 if (!(dwarf_csect && (dwarf_csect->section) == (s->section)))
2924 dwarf_findsect(s->section);
2926 /* do nothing unless line or file has changed */
2927 if (!debug_immcall)
2928 return;
2930 ln = currentline - dwarf_csect->line;
2931 aa = s->offset - dwarf_csect->offset;
2932 inx = dwarf_clist->line;
2933 plinep = dwarf_csect->psaa;
2934 /* check for file change */
2935 if (!(inx == dwarf_csect->file)) {
2936 saa_write8(plinep,DW_LNS_set_file);
2937 saa_write8(plinep,inx);
2938 dwarf_csect->file = inx;
2940 /* check for line change */
2941 if (ln) {
2942 /* test if in range of special op code */
2943 maxln = line_base + line_range;
2944 soc = (ln - line_base) + (line_range * aa) + opcode_base;
2945 if (ln >= line_base && ln < maxln && soc < 256) {
2946 saa_write8(plinep,soc);
2947 } else {
2948 saa_write8(plinep,DW_LNS_advance_line);
2949 saa_wleb128s(plinep,ln);
2950 if (aa) {
2951 saa_write8(plinep,DW_LNS_advance_pc);
2952 saa_wleb128u(plinep,aa);
2954 saa_write8(plinep,DW_LNS_copy);
2956 dwarf_csect->line = currentline;
2957 dwarf_csect->offset = s->offset;
2960 /* show change handled */
2961 debug_immcall = 0;
2965 static void dwarf_generate(void)
2967 uint8_t *pbuf;
2968 int indx;
2969 struct linelist *ftentry;
2970 struct SAA *paranges, *ppubnames, *pinfo, *pabbrev, *plines, *plinep;
2971 struct SAA *parangesrel, *plinesrel, *pinforel;
2972 struct sectlist *psect;
2973 size_t saalen, linepoff, totlen, highaddr;
2975 if (is_elf32()) {
2976 /* write epilogues for each line program range */
2977 /* and build aranges section */
2978 paranges = saa_init(1L);
2979 parangesrel = saa_init(1L);
2980 saa_write16(paranges,2); /* dwarf version */
2981 saa_write32(parangesrel, paranges->datalen+4);
2982 saa_write32(parangesrel, (dwarf_infosym << 8) + R_386_32); /* reloc to info */
2983 saa_write32(parangesrel, 0);
2984 saa_write32(paranges,0); /* offset into info */
2985 saa_write8(paranges,4); /* pointer size */
2986 saa_write8(paranges,0); /* not segmented */
2987 saa_write32(paranges,0); /* padding */
2988 /* iterate though sectlist entries */
2989 psect = dwarf_fsect;
2990 totlen = 0;
2991 highaddr = 0;
2992 for (indx = 0; indx < dwarf_nsections; indx++) {
2993 plinep = psect->psaa;
2994 /* Line Number Program Epilogue */
2995 saa_write8(plinep,2); /* std op 2 */
2996 saa_write8(plinep,(sects[psect->section]->len)-psect->offset);
2997 saa_write8(plinep,DW_LNS_extended_op);
2998 saa_write8(plinep,1); /* operand length */
2999 saa_write8(plinep,DW_LNE_end_sequence);
3000 totlen += plinep->datalen;
3001 /* range table relocation entry */
3002 saa_write32(parangesrel, paranges->datalen + 4);
3003 saa_write32(parangesrel, ((uint32_t) (psect->section + 2) << 8) + R_386_32);
3004 saa_write32(parangesrel, (uint32_t) 0);
3005 /* range table entry */
3006 saa_write32(paranges,0x0000); /* range start */
3007 saa_write32(paranges,sects[psect->section]->len); /* range length */
3008 highaddr += sects[psect->section]->len;
3009 /* done with this entry */
3010 psect = psect->next;
3012 saa_write32(paranges,0); /* null address */
3013 saa_write32(paranges,0); /* null length */
3014 saalen = paranges->datalen;
3015 arangeslen = saalen + 4;
3016 arangesbuf = pbuf = nasm_malloc(arangeslen);
3017 WRITELONG(pbuf,saalen); /* initial length */
3018 saa_rnbytes(paranges, pbuf, saalen);
3019 saa_free(paranges);
3020 } else if (is_elfx32()) {
3021 /* write epilogues for each line program range */
3022 /* and build aranges section */
3023 paranges = saa_init(1L);
3024 parangesrel = saa_init(1L);
3025 saa_write16(paranges,3); /* dwarf version */
3026 saa_write32(parangesrel, paranges->datalen+4);
3027 saa_write32(parangesrel, (dwarf_infosym << 8) + R_X86_64_32); /* reloc to info */
3028 saa_write32(parangesrel, 0);
3029 saa_write32(paranges,0); /* offset into info */
3030 saa_write8(paranges,4); /* pointer size */
3031 saa_write8(paranges,0); /* not segmented */
3032 saa_write32(paranges,0); /* padding */
3033 /* iterate though sectlist entries */
3034 psect = dwarf_fsect;
3035 totlen = 0;
3036 highaddr = 0;
3037 for (indx = 0; indx < dwarf_nsections; indx++) {
3038 plinep = psect->psaa;
3039 /* Line Number Program Epilogue */
3040 saa_write8(plinep,2); /* std op 2 */
3041 saa_write8(plinep,(sects[psect->section]->len)-psect->offset);
3042 saa_write8(plinep,DW_LNS_extended_op);
3043 saa_write8(plinep,1); /* operand length */
3044 saa_write8(plinep,DW_LNE_end_sequence);
3045 totlen += plinep->datalen;
3046 /* range table relocation entry */
3047 saa_write32(parangesrel, paranges->datalen + 4);
3048 saa_write32(parangesrel, ((uint32_t) (psect->section + 2) << 8) + R_X86_64_32);
3049 saa_write32(parangesrel, (uint32_t) 0);
3050 /* range table entry */
3051 saa_write32(paranges,0x0000); /* range start */
3052 saa_write32(paranges,sects[psect->section]->len); /* range length */
3053 highaddr += sects[psect->section]->len;
3054 /* done with this entry */
3055 psect = psect->next;
3057 saa_write32(paranges,0); /* null address */
3058 saa_write32(paranges,0); /* null length */
3059 saalen = paranges->datalen;
3060 arangeslen = saalen + 4;
3061 arangesbuf = pbuf = nasm_malloc(arangeslen);
3062 WRITELONG(pbuf,saalen); /* initial length */
3063 saa_rnbytes(paranges, pbuf, saalen);
3064 saa_free(paranges);
3065 } else {
3066 nasm_assert(is_elf64());
3067 /* write epilogues for each line program range */
3068 /* and build aranges section */
3069 paranges = saa_init(1L);
3070 parangesrel = saa_init(1L);
3071 saa_write16(paranges,3); /* dwarf version */
3072 saa_write64(parangesrel, paranges->datalen+4);
3073 saa_write64(parangesrel, (dwarf_infosym << 32) + R_X86_64_32); /* reloc to info */
3074 saa_write64(parangesrel, 0);
3075 saa_write32(paranges,0); /* offset into info */
3076 saa_write8(paranges,8); /* pointer size */
3077 saa_write8(paranges,0); /* not segmented */
3078 saa_write32(paranges,0); /* padding */
3079 /* iterate though sectlist entries */
3080 psect = dwarf_fsect;
3081 totlen = 0;
3082 highaddr = 0;
3083 for (indx = 0; indx < dwarf_nsections; indx++) {
3084 plinep = psect->psaa;
3085 /* Line Number Program Epilogue */
3086 saa_write8(plinep,2); /* std op 2 */
3087 saa_write8(plinep,(sects[psect->section]->len)-psect->offset);
3088 saa_write8(plinep,DW_LNS_extended_op);
3089 saa_write8(plinep,1); /* operand length */
3090 saa_write8(plinep,DW_LNE_end_sequence);
3091 totlen += plinep->datalen;
3092 /* range table relocation entry */
3093 saa_write64(parangesrel, paranges->datalen + 4);
3094 saa_write64(parangesrel, ((uint64_t) (psect->section + 2) << 32) + R_X86_64_64);
3095 saa_write64(parangesrel, (uint64_t) 0);
3096 /* range table entry */
3097 saa_write64(paranges,0x0000); /* range start */
3098 saa_write64(paranges,sects[psect->section]->len); /* range length */
3099 highaddr += sects[psect->section]->len;
3100 /* done with this entry */
3101 psect = psect->next;
3103 saa_write64(paranges,0); /* null address */
3104 saa_write64(paranges,0); /* null length */
3105 saalen = paranges->datalen;
3106 arangeslen = saalen + 4;
3107 arangesbuf = pbuf = nasm_malloc(arangeslen);
3108 WRITELONG(pbuf,saalen); /* initial length */
3109 saa_rnbytes(paranges, pbuf, saalen);
3110 saa_free(paranges);
3113 /* build rela.aranges section */
3114 arangesrellen = saalen = parangesrel->datalen;
3115 arangesrelbuf = pbuf = nasm_malloc(arangesrellen);
3116 saa_rnbytes(parangesrel, pbuf, saalen);
3117 saa_free(parangesrel);
3119 /* build pubnames section */
3120 ppubnames = saa_init(1L);
3121 saa_write16(ppubnames,3); /* dwarf version */
3122 saa_write32(ppubnames,0); /* offset into info */
3123 saa_write32(ppubnames,0); /* space used in info */
3124 saa_write32(ppubnames,0); /* end of list */
3125 saalen = ppubnames->datalen;
3126 pubnameslen = saalen + 4;
3127 pubnamesbuf = pbuf = nasm_malloc(pubnameslen);
3128 WRITELONG(pbuf,saalen); /* initial length */
3129 saa_rnbytes(ppubnames, pbuf, saalen);
3130 saa_free(ppubnames);
3132 if (is_elf32()) {
3133 /* build info section */
3134 pinfo = saa_init(1L);
3135 pinforel = saa_init(1L);
3136 saa_write16(pinfo,2); /* dwarf version */
3137 saa_write32(pinforel, pinfo->datalen + 4);
3138 saa_write32(pinforel, (dwarf_abbrevsym << 8) + R_386_32); /* reloc to abbrev */
3139 saa_write32(pinforel, 0);
3140 saa_write32(pinfo,0); /* offset into abbrev */
3141 saa_write8(pinfo,4); /* pointer size */
3142 saa_write8(pinfo,1); /* abbrviation number LEB128u */
3143 saa_write32(pinforel, pinfo->datalen + 4);
3144 saa_write32(pinforel, ((dwarf_fsect->section + 2) << 8) + R_386_32);
3145 saa_write32(pinforel, 0);
3146 saa_write32(pinfo,0); /* DW_AT_low_pc */
3147 saa_write32(pinforel, pinfo->datalen + 4);
3148 saa_write32(pinforel, ((dwarf_fsect->section + 2) << 8) + R_386_32);
3149 saa_write32(pinforel, 0);
3150 saa_write32(pinfo,highaddr); /* DW_AT_high_pc */
3151 saa_write32(pinforel, pinfo->datalen + 4);
3152 saa_write32(pinforel, (dwarf_linesym << 8) + R_386_32); /* reloc to line */
3153 saa_write32(pinforel, 0);
3154 saa_write32(pinfo,0); /* DW_AT_stmt_list */
3155 saa_wbytes(pinfo, elf_module, strlen(elf_module)+1);
3156 saa_wbytes(pinfo, nasm_signature(), nasm_signature_len()+1);
3157 saa_write16(pinfo,DW_LANG_Mips_Assembler);
3158 saa_write8(pinfo,2); /* abbrviation number LEB128u */
3159 saa_write32(pinforel, pinfo->datalen + 4);
3160 saa_write32(pinforel, ((dwarf_fsect->section + 2) << 8) + R_386_32);
3161 saa_write32(pinforel, 0);
3162 saa_write32(pinfo,0); /* DW_AT_low_pc */
3163 saa_write32(pinfo,0); /* DW_AT_frame_base */
3164 saa_write8(pinfo,0); /* end of entries */
3165 saalen = pinfo->datalen;
3166 infolen = saalen + 4;
3167 infobuf = pbuf = nasm_malloc(infolen);
3168 WRITELONG(pbuf,saalen); /* initial length */
3169 saa_rnbytes(pinfo, pbuf, saalen);
3170 saa_free(pinfo);
3171 } else if (is_elfx32()) {
3172 /* build info section */
3173 pinfo = saa_init(1L);
3174 pinforel = saa_init(1L);
3175 saa_write16(pinfo,3); /* dwarf version */
3176 saa_write32(pinforel, pinfo->datalen + 4);
3177 saa_write32(pinforel, (dwarf_abbrevsym << 8) + R_X86_64_32); /* reloc to abbrev */
3178 saa_write32(pinforel, 0);
3179 saa_write32(pinfo,0); /* offset into abbrev */
3180 saa_write8(pinfo,4); /* pointer size */
3181 saa_write8(pinfo,1); /* abbrviation number LEB128u */
3182 saa_write32(pinforel, pinfo->datalen + 4);
3183 saa_write32(pinforel, ((dwarf_fsect->section + 2) << 8) + R_X86_64_32);
3184 saa_write32(pinforel, 0);
3185 saa_write32(pinfo,0); /* DW_AT_low_pc */
3186 saa_write32(pinforel, pinfo->datalen + 4);
3187 saa_write32(pinforel, ((dwarf_fsect->section + 2) << 8) + R_X86_64_32);
3188 saa_write32(pinforel, 0);
3189 saa_write32(pinfo,highaddr); /* DW_AT_high_pc */
3190 saa_write32(pinforel, pinfo->datalen + 4);
3191 saa_write32(pinforel, (dwarf_linesym << 8) + R_X86_64_32); /* reloc to line */
3192 saa_write32(pinforel, 0);
3193 saa_write32(pinfo,0); /* DW_AT_stmt_list */
3194 saa_wbytes(pinfo, elf_module, strlen(elf_module)+1);
3195 saa_wbytes(pinfo, nasm_signature(), nasm_signature_len()+1);
3196 saa_write16(pinfo,DW_LANG_Mips_Assembler);
3197 saa_write8(pinfo,2); /* abbrviation number LEB128u */
3198 saa_write32(pinforel, pinfo->datalen + 4);
3199 saa_write32(pinforel, ((dwarf_fsect->section + 2) << 8) + R_X86_64_32);
3200 saa_write32(pinforel, 0);
3201 saa_write32(pinfo,0); /* DW_AT_low_pc */
3202 saa_write32(pinfo,0); /* DW_AT_frame_base */
3203 saa_write8(pinfo,0); /* end of entries */
3204 saalen = pinfo->datalen;
3205 infolen = saalen + 4;
3206 infobuf = pbuf = nasm_malloc(infolen);
3207 WRITELONG(pbuf,saalen); /* initial length */
3208 saa_rnbytes(pinfo, pbuf, saalen);
3209 saa_free(pinfo);
3210 } else {
3211 nasm_assert(is_elf64());
3212 /* build info section */
3213 pinfo = saa_init(1L);
3214 pinforel = saa_init(1L);
3215 saa_write16(pinfo,3); /* dwarf version */
3216 saa_write64(pinforel, pinfo->datalen + 4);
3217 saa_write64(pinforel, (dwarf_abbrevsym << 32) + R_X86_64_32); /* reloc to abbrev */
3218 saa_write64(pinforel, 0);
3219 saa_write32(pinfo,0); /* offset into abbrev */
3220 saa_write8(pinfo,8); /* pointer size */
3221 saa_write8(pinfo,1); /* abbrviation number LEB128u */
3222 saa_write64(pinforel, pinfo->datalen + 4);
3223 saa_write64(pinforel, ((uint64_t)(dwarf_fsect->section + 2) << 32) + R_X86_64_64);
3224 saa_write64(pinforel, 0);
3225 saa_write64(pinfo,0); /* DW_AT_low_pc */
3226 saa_write64(pinforel, pinfo->datalen + 4);
3227 saa_write64(pinforel, ((uint64_t)(dwarf_fsect->section + 2) << 32) + R_X86_64_64);
3228 saa_write64(pinforel, 0);
3229 saa_write64(pinfo,highaddr); /* DW_AT_high_pc */
3230 saa_write64(pinforel, pinfo->datalen + 4);
3231 saa_write64(pinforel, (dwarf_linesym << 32) + R_X86_64_32); /* reloc to line */
3232 saa_write64(pinforel, 0);
3233 saa_write32(pinfo,0); /* DW_AT_stmt_list */
3234 saa_wbytes(pinfo, elf_module, strlen(elf_module)+1);
3235 saa_wbytes(pinfo, nasm_signature(), nasm_signature_len()+1);
3236 saa_write16(pinfo,DW_LANG_Mips_Assembler);
3237 saa_write8(pinfo,2); /* abbrviation number LEB128u */
3238 saa_write64(pinforel, pinfo->datalen + 4);
3239 saa_write64(pinforel, ((uint64_t)(dwarf_fsect->section + 2) << 32) + R_X86_64_64);
3240 saa_write64(pinforel, 0);
3241 saa_write64(pinfo,0); /* DW_AT_low_pc */
3242 saa_write64(pinfo,0); /* DW_AT_frame_base */
3243 saa_write8(pinfo,0); /* end of entries */
3244 saalen = pinfo->datalen;
3245 infolen = saalen + 4;
3246 infobuf = pbuf = nasm_malloc(infolen);
3247 WRITELONG(pbuf,saalen); /* initial length */
3248 saa_rnbytes(pinfo, pbuf, saalen);
3249 saa_free(pinfo);
3252 /* build rela.info section */
3253 inforellen = saalen = pinforel->datalen;
3254 inforelbuf = pbuf = nasm_malloc(inforellen);
3255 saa_rnbytes(pinforel, pbuf, saalen);
3256 saa_free(pinforel);
3258 /* build abbrev section */
3259 pabbrev = saa_init(1L);
3260 saa_write8(pabbrev,1); /* entry number LEB128u */
3261 saa_write8(pabbrev,DW_TAG_compile_unit); /* tag LEB128u */
3262 saa_write8(pabbrev,1); /* has children */
3263 /* the following attributes and forms are all LEB128u values */
3264 saa_write8(pabbrev,DW_AT_low_pc);
3265 saa_write8(pabbrev,DW_FORM_addr);
3266 saa_write8(pabbrev,DW_AT_high_pc);
3267 saa_write8(pabbrev,DW_FORM_addr);
3268 saa_write8(pabbrev,DW_AT_stmt_list);
3269 saa_write8(pabbrev,DW_FORM_data4);
3270 saa_write8(pabbrev,DW_AT_name);
3271 saa_write8(pabbrev,DW_FORM_string);
3272 saa_write8(pabbrev,DW_AT_producer);
3273 saa_write8(pabbrev,DW_FORM_string);
3274 saa_write8(pabbrev,DW_AT_language);
3275 saa_write8(pabbrev,DW_FORM_data2);
3276 saa_write16(pabbrev,0); /* end of entry */
3277 /* LEB128u usage same as above */
3278 saa_write8(pabbrev,2); /* entry number */
3279 saa_write8(pabbrev,DW_TAG_subprogram);
3280 saa_write8(pabbrev,0); /* no children */
3281 saa_write8(pabbrev,DW_AT_low_pc);
3282 saa_write8(pabbrev,DW_FORM_addr);
3283 saa_write8(pabbrev,DW_AT_frame_base);
3284 saa_write8(pabbrev,DW_FORM_data4);
3285 saa_write16(pabbrev,0); /* end of entry */
3286 /* Terminal zero entry */
3287 saa_write8(pabbrev,0);
3288 abbrevlen = saalen = pabbrev->datalen;
3289 abbrevbuf = pbuf = nasm_malloc(saalen);
3290 saa_rnbytes(pabbrev, pbuf, saalen);
3291 saa_free(pabbrev);
3293 /* build line section */
3294 /* prolog */
3295 plines = saa_init(1L);
3296 saa_write8(plines,1); /* Minimum Instruction Length */
3297 saa_write8(plines,1); /* Initial value of 'is_stmt' */
3298 saa_write8(plines,line_base); /* Line Base */
3299 saa_write8(plines,line_range); /* Line Range */
3300 saa_write8(plines,opcode_base); /* Opcode Base */
3301 /* standard opcode lengths (# of LEB128u operands) */
3302 saa_write8(plines,0); /* Std opcode 1 length */
3303 saa_write8(plines,1); /* Std opcode 2 length */
3304 saa_write8(plines,1); /* Std opcode 3 length */
3305 saa_write8(plines,1); /* Std opcode 4 length */
3306 saa_write8(plines,1); /* Std opcode 5 length */
3307 saa_write8(plines,0); /* Std opcode 6 length */
3308 saa_write8(plines,0); /* Std opcode 7 length */
3309 saa_write8(plines,0); /* Std opcode 8 length */
3310 saa_write8(plines,1); /* Std opcode 9 length */
3311 saa_write8(plines,0); /* Std opcode 10 length */
3312 saa_write8(plines,0); /* Std opcode 11 length */
3313 saa_write8(plines,1); /* Std opcode 12 length */
3314 /* Directory Table */
3315 saa_write8(plines,0); /* End of table */
3316 /* File Name Table */
3317 ftentry = dwarf_flist;
3318 for (indx = 0; indx < dwarf_numfiles; indx++) {
3319 saa_wbytes(plines, ftentry->filename, (int32_t)(strlen(ftentry->filename) + 1));
3320 saa_write8(plines,0); /* directory LEB128u */
3321 saa_write8(plines,0); /* time LEB128u */
3322 saa_write8(plines,0); /* size LEB128u */
3323 ftentry = ftentry->next;
3325 saa_write8(plines,0); /* End of table */
3326 linepoff = plines->datalen;
3327 linelen = linepoff + totlen + 10;
3328 linebuf = pbuf = nasm_malloc(linelen);
3329 WRITELONG(pbuf,linelen-4); /* initial length */
3330 WRITESHORT(pbuf,3); /* dwarf version */
3331 WRITELONG(pbuf,linepoff); /* offset to line number program */
3332 /* write line header */
3333 saalen = linepoff;
3334 saa_rnbytes(plines, pbuf, saalen); /* read a given no. of bytes */
3335 pbuf += linepoff;
3336 saa_free(plines);
3337 /* concatonate line program ranges */
3338 linepoff += 13;
3339 plinesrel = saa_init(1L);
3340 psect = dwarf_fsect;
3341 if (is_elf32()) {
3342 for (indx = 0; indx < dwarf_nsections; indx++) {
3343 saa_write32(plinesrel, linepoff);
3344 saa_write32(plinesrel, ((uint32_t) (psect->section + 2) << 8) + R_386_32);
3345 saa_write32(plinesrel, (uint32_t) 0);
3346 plinep = psect->psaa;
3347 saalen = plinep->datalen;
3348 saa_rnbytes(plinep, pbuf, saalen);
3349 pbuf += saalen;
3350 linepoff += saalen;
3351 saa_free(plinep);
3352 /* done with this entry */
3353 psect = psect->next;
3355 } else if (is_elfx32()) {
3356 for (indx = 0; indx < dwarf_nsections; indx++) {
3357 saa_write32(plinesrel, linepoff);
3358 saa_write32(plinesrel, ((psect->section + 2) << 8) + R_X86_64_32);
3359 saa_write32(plinesrel, 0);
3360 plinep = psect->psaa;
3361 saalen = plinep->datalen;
3362 saa_rnbytes(plinep, pbuf, saalen);
3363 pbuf += saalen;
3364 linepoff += saalen;
3365 saa_free(plinep);
3366 /* done with this entry */
3367 psect = psect->next;
3369 } else {
3370 nasm_assert(is_elf64());
3371 for (indx = 0; indx < dwarf_nsections; indx++) {
3372 saa_write64(plinesrel, linepoff);
3373 saa_write64(plinesrel, ((uint64_t) (psect->section + 2) << 32) + R_X86_64_64);
3374 saa_write64(plinesrel, (uint64_t) 0);
3375 plinep = psect->psaa;
3376 saalen = plinep->datalen;
3377 saa_rnbytes(plinep, pbuf, saalen);
3378 pbuf += saalen;
3379 linepoff += saalen;
3380 saa_free(plinep);
3381 /* done with this entry */
3382 psect = psect->next;
3386 /* build rela.lines section */
3387 linerellen =saalen = plinesrel->datalen;
3388 linerelbuf = pbuf = nasm_malloc(linerellen);
3389 saa_rnbytes(plinesrel, pbuf, saalen);
3390 saa_free(plinesrel);
3392 /* build frame section */
3393 framelen = 4;
3394 framebuf = pbuf = nasm_malloc(framelen);
3395 WRITELONG(pbuf,framelen-4); /* initial length */
3397 /* build loc section */
3398 loclen = 16;
3399 locbuf = pbuf = nasm_malloc(loclen);
3400 if (is_elf32()) {
3401 WRITELONG(pbuf,0); /* null beginning offset */
3402 WRITELONG(pbuf,0); /* null ending offset */
3403 } else if (is_elfx32()) {
3404 WRITELONG(pbuf,0); /* null beginning offset */
3405 WRITELONG(pbuf,0); /* null ending offset */
3406 } else {
3407 nasm_assert(is_elf64());
3408 WRITEDLONG(pbuf,0); /* null beginning offset */
3409 WRITEDLONG(pbuf,0); /* null ending offset */
3413 static void dwarf_cleanup(void)
3415 nasm_free(arangesbuf);
3416 nasm_free(arangesrelbuf);
3417 nasm_free(pubnamesbuf);
3418 nasm_free(infobuf);
3419 nasm_free(inforelbuf);
3420 nasm_free(abbrevbuf);
3421 nasm_free(linebuf);
3422 nasm_free(linerelbuf);
3423 nasm_free(framebuf);
3424 nasm_free(locbuf);
3427 static void dwarf_findfile(const char * fname)
3429 int finx;
3430 struct linelist *match;
3432 /* return if fname is current file name */
3433 if (dwarf_clist && !(strcmp(fname, dwarf_clist->filename)))
3434 return;
3436 /* search for match */
3437 match = 0;
3438 if (dwarf_flist) {
3439 match = dwarf_flist;
3440 for (finx = 0; finx < dwarf_numfiles; finx++) {
3441 if (!(strcmp(fname, match->filename))) {
3442 dwarf_clist = match;
3443 return;
3445 match = match->next;
3449 /* add file name to end of list */
3450 dwarf_clist = nasm_malloc(sizeof(struct linelist));
3451 dwarf_numfiles++;
3452 dwarf_clist->line = dwarf_numfiles;
3453 dwarf_clist->filename = nasm_malloc(strlen(fname) + 1);
3454 strcpy(dwarf_clist->filename,fname);
3455 dwarf_clist->next = 0;
3456 if (!dwarf_flist) { /* if first entry */
3457 dwarf_flist = dwarf_elist = dwarf_clist;
3458 dwarf_clist->last = 0;
3459 } else { /* chain to previous entry */
3460 dwarf_elist->next = dwarf_clist;
3461 dwarf_elist = dwarf_clist;
3465 static void dwarf_findsect(const int index)
3467 int sinx;
3468 struct sectlist *match;
3469 struct SAA *plinep;
3471 /* return if index is current section index */
3472 if (dwarf_csect && (dwarf_csect->section == index))
3473 return;
3475 /* search for match */
3476 match = 0;
3477 if (dwarf_fsect) {
3478 match = dwarf_fsect;
3479 for (sinx = 0; sinx < dwarf_nsections; sinx++) {
3480 if (match->section == index) {
3481 dwarf_csect = match;
3482 return;
3484 match = match->next;
3488 /* add entry to end of list */
3489 dwarf_csect = nasm_malloc(sizeof(struct sectlist));
3490 dwarf_nsections++;
3491 dwarf_csect->psaa = plinep = saa_init(1L);
3492 dwarf_csect->line = 1;
3493 dwarf_csect->offset = 0;
3494 dwarf_csect->file = 1;
3495 dwarf_csect->section = index;
3496 dwarf_csect->next = 0;
3497 /* set relocatable address at start of line program */
3498 saa_write8(plinep,DW_LNS_extended_op);
3499 saa_write8(plinep,is_elf64() ? 9 : 5); /* operand length */
3500 saa_write8(plinep,DW_LNE_set_address);
3501 if (is_elf64())
3502 saa_write64(plinep,0); /* Start Address */
3503 else
3504 saa_write32(plinep,0); /* Start Address */
3506 if (!dwarf_fsect) { /* if first entry */
3507 dwarf_fsect = dwarf_esect = dwarf_csect;
3508 dwarf_csect->last = 0;
3509 } else { /* chain to previous entry */
3510 dwarf_esect->next = dwarf_csect;
3511 dwarf_esect = dwarf_csect;
3515 #endif /* defined(OF_ELF32) || defined(OF_ELF64) || defined(OF_ELFX32) */