rbtree: add rb_search_exact()
[nasm.git] / output / outelf.c
blob61af0208b737416419d7732fa89018e37455b925
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 */
180 /* This should match the order in elf_write() */
181 enum dwarf_sect {
182 DWARF_ARANGES,
183 DWARF_RELA_ARANGES,
184 DWARF_PUBNAMES,
185 DWARF_INFO,
186 DWARF_RELA_INFO,
187 DWARF_ABBREV,
188 DWARF_LINE,
189 DWARF_RELA_LINE,
190 DWARF_FRAME,
191 DWARF_LOC,
192 DWARF_NSECT
195 struct dwarf_format {
196 uint16_t dwarf_version;
197 uint16_t sect_version[DWARF_NSECT];
198 /* ... add more here to generalize further */
200 const struct dwarf_format *dwfmt;
202 static void dwarf32_init(void);
203 static void dwarfx32_init(void);
204 static void dwarf64_init(void);
205 static void dwarf_linenum(const char *filename, int32_t linenumber, int32_t);
206 static void dwarf_output(int, void *);
207 static void dwarf_generate(void);
208 static void dwarf_cleanup(void);
209 static void dwarf_findfile(const char *);
210 static void dwarf_findsect(const int);
212 struct elf_format_info {
213 size_t word; /* Word size (4 or 8) */
214 size_t ehdr_size; /* Size of the ELF header */
215 size_t shdr_size; /* Size of a section header */
216 size_t sym_size; /* Size of a symbol */
217 size_t rel_size; /* Size of a reltype relocation */
218 size_t rela_size; /* Size of a RELA relocation */
219 char relpfx[8]; /* Relocation section prefix */
220 uint32_t reltype; /* Relocation section type */
221 uint16_t e_machine; /* Header e_machine field */
222 uint8_t ei_class; /* ELFCLASS32 or ELFCLASS64 */
223 bool elf64; /* 64-bit ELF */
225 /* Write a symbol */
226 void (*elf_sym)(const struct elf_symbol *);
228 /* Build a relocation table */
229 struct SAA *(*elf_build_reltab)(const struct elf_reloc *);
231 static const struct elf_format_info *efmt;
233 static void elf32_sym(const struct elf_symbol *sym);
234 static void elf64_sym(const struct elf_symbol *sym);
236 static struct SAA *elf32_build_reltab(const struct elf_reloc *r);
237 static struct SAA *elfx32_build_reltab(const struct elf_reloc *r);
238 static struct SAA *elf64_build_reltab(const struct elf_reloc *r);
240 static bool dfmt_is_stabs(void);
241 static bool dfmt_is_dwarf(void);
244 * Special NASM section numbers which are used to define ELF special
245 * symbols.
247 static int32_t elf_gotpc_sect, elf_gotoff_sect;
248 static int32_t elf_got_sect, elf_plt_sect;
249 static int32_t elf_sym_sect, elf_gottpoff_sect, elf_tlsie_sect;
251 uint8_t elf_osabi = 0; /* Default OSABI = 0 (System V or Linux) */
252 uint8_t elf_abiver = 0; /* Current ABI version */
254 /* Known sections with nonstandard defaults. -n means n*pointer size. */
255 struct elf_known_section {
256 const char *name; /* Name of section */
257 int type; /* Section type (SHT_) */
258 uint32_t flags; /* Section flags (SHF_) */
259 int align; /* Section alignment */
260 int entsize; /* Entry size, if applicable */
263 static const struct elf_known_section elf_known_sections[] = {
264 { ".text", SHT_PROGBITS, SHF_ALLOC|SHF_EXECINSTR, 16, 0 },
265 { ".rodata", SHT_PROGBITS, SHF_ALLOC, 4, 0 },
266 { ".lrodata", SHT_PROGBITS, SHF_ALLOC, 4, 0 },
267 { ".data", SHT_PROGBITS, SHF_ALLOC|SHF_WRITE, 4, 0 },
268 { ".ldata", SHT_PROGBITS, SHF_ALLOC|SHF_WRITE, 4, 0 },
269 { ".bss", SHT_NOBITS, SHF_ALLOC|SHF_WRITE, 4, 0 },
270 { ".lbss", SHT_NOBITS, SHF_ALLOC|SHF_WRITE, 4, 0 },
271 { ".tdata", SHT_PROGBITS, SHF_ALLOC|SHF_WRITE|SHF_TLS, 4, 0 },
272 { ".tbss", SHT_NOBITS, SHF_ALLOC|SHF_WRITE|SHF_TLS, 4, 0 },
273 { ".comment", SHT_PROGBITS, 0, 1, 0 },
274 { ".preinit_array", SHT_PREINIT_ARRAY, SHF_ALLOC, -1, -1 },
275 { ".init_array", SHT_INIT_ARRAY, SHF_ALLOC, -1, -1 },
276 { ".fini_array", SHT_FINI_ARRAY, SHF_ALLOC, -1, -1 },
277 { ".note", SHT_NOTE, 0, 4, 0 },
278 { NULL /*default*/, SHT_PROGBITS, SHF_ALLOC, 1, 0 }
281 struct size_unit {
282 char name[8];
283 int bytes;
284 int align;
286 static const struct size_unit size_units[] =
288 { "byte", 1, 1 },
289 { "word", 2, 2 },
290 { "dword", 4, 4 },
291 { "qword", 8, 8 },
292 { "tword", 10, 2 },
293 { "tbyte", 10, 2 },
294 { "oword", 16, 16 },
295 { "xword", 16, 16 },
296 { "yword", 32, 32 },
297 { "zword", 64, 64 },
298 { "pointer", -1, -1 },
299 { "", 0, 0 }
302 static inline size_t to_bytes(int val)
304 return (val >= 0) ? (size_t)val : -val * efmt->word;
307 /* parse section attributes */
308 static void elf_section_attrib(char *name, char *attr, uint32_t *flags_and, uint32_t *flags_or,
309 uint64_t *alignp, uint64_t *entsize, int *type)
311 char *opt, *val, *next;
312 uint64_t align = 0;
313 uint64_t xalign = 0;
315 opt = nasm_skip_spaces(attr);
316 if (!opt || !*opt)
317 return;
319 while ((opt = nasm_opt_val(opt, &val, &next))) {
320 if (!nasm_stricmp(opt, "align")) {
321 if (!val) {
322 nasm_nonfatal("section align without value specified");
323 } else {
324 bool err;
325 uint64_t a = readnum(val, &err);
326 if (a && !is_power2(a)) {
327 nasm_error(ERR_NONFATAL,
328 "section alignment %"PRId64" is not a power of two",
330 } else if (a > align) {
331 align = a;
334 } else if (!nasm_stricmp(opt, "alloc")) {
335 *flags_and |= SHF_ALLOC;
336 *flags_or |= SHF_ALLOC;
337 } else if (!nasm_stricmp(opt, "noalloc")) {
338 *flags_and |= SHF_ALLOC;
339 *flags_or &= ~SHF_ALLOC;
340 } else if (!nasm_stricmp(opt, "exec")) {
341 *flags_and |= SHF_EXECINSTR;
342 *flags_or |= SHF_EXECINSTR;
343 } else if (!nasm_stricmp(opt, "noexec")) {
344 *flags_and |= SHF_EXECINSTR;
345 *flags_or &= ~SHF_EXECINSTR;
346 } else if (!nasm_stricmp(opt, "write")) {
347 *flags_and |= SHF_WRITE;
348 *flags_or |= SHF_WRITE;
349 } else if (!nasm_stricmp(opt, "nowrite") ||
350 !nasm_stricmp(opt, "readonly")) {
351 *flags_and |= SHF_WRITE;
352 *flags_or &= ~SHF_WRITE;
353 } else if (!nasm_stricmp(opt, "tls")) {
354 *flags_and |= SHF_TLS;
355 *flags_or |= SHF_TLS;
356 } else if (!nasm_stricmp(opt, "notls")) {
357 *flags_and |= SHF_TLS;
358 *flags_or &= ~SHF_TLS;
359 } else if (!nasm_stricmp(opt, "merge")) {
360 *flags_and |= SHF_MERGE;
361 *flags_or |= SHF_MERGE;
362 } else if (!nasm_stricmp(opt, "nomerge")) {
363 *flags_and |= SHF_MERGE;
364 *flags_or &= ~SHF_MERGE;
365 } else if (!nasm_stricmp(opt, "strings")) {
366 *flags_and |= SHF_STRINGS;
367 *flags_or |= SHF_STRINGS;
368 } else if (!nasm_stricmp(opt, "nostrings")) {
369 *flags_and |= SHF_STRINGS;
370 *flags_or &= ~SHF_STRINGS;
371 } else if (!nasm_stricmp(opt, "progbits")) {
372 *type = SHT_PROGBITS;
373 } else if (!nasm_stricmp(opt, "nobits")) {
374 *type = SHT_NOBITS;
375 } else if (!nasm_stricmp(opt, "note")) {
376 *type = SHT_NOTE;
377 } else if (!nasm_stricmp(opt, "preinit_array")) {
378 *type = SHT_PREINIT_ARRAY;
379 } else if (!nasm_stricmp(opt, "init_array")) {
380 *type = SHT_INIT_ARRAY;
381 } else if (!nasm_stricmp(opt, "fini_array")) {
382 *type = SHT_FINI_ARRAY;
383 } else {
384 uint64_t mult;
385 size_t l;
386 const char *a = strchr(opt, '*');
387 bool err;
388 const struct size_unit *su;
390 if (a) {
391 l = a - opt - 1;
392 mult = readnum(a+1, &err);
393 } else {
394 l = strlen(opt);
395 mult = 1;
398 for (su = size_units; su->bytes; su++) {
399 if (!nasm_strnicmp(opt, su->name, l))
400 break;
403 if (su->bytes) {
404 *entsize = to_bytes(su->bytes) * mult;
405 xalign = to_bytes(su->align);
406 } else {
407 /* Unknown attribute */
408 nasm_warn(WARN_OTHER,
409 "unknown section attribute '%s' ignored on"
410 " declaration of section `%s'", opt, name);
413 opt = next;
416 switch (*type) {
417 case SHT_PREINIT_ARRAY:
418 case SHT_INIT_ARRAY:
419 case SHT_FINI_ARRAY:
420 if (!xalign)
421 xalign = efmt->word;
422 if (!*entsize)
423 *entsize = efmt->word;
424 break;
425 default:
426 break;
429 if (!align)
430 align = xalign;
431 if (!align)
432 align = SHA_ANY;
434 *alignp = align;
437 static enum directive_result
438 elf_directive(enum directive directive, char *value)
440 int64_t n;
441 bool err;
442 char *p;
444 switch (directive) {
445 case D_OSABI:
446 if (!pass_first()) /* XXX: Why? */
447 return DIRR_OK;
449 n = readnum(value, &err);
450 if (err) {
451 nasm_nonfatal("`osabi' directive requires a parameter");
452 return DIRR_ERROR;
455 if (n < 0 || n > 255) {
456 nasm_nonfatal("valid osabi numbers are 0 to 255");
457 return DIRR_ERROR;
460 elf_osabi = n;
461 elf_abiver = 0;
463 p = strchr(value,',');
464 if (!p)
465 return DIRR_OK;
467 n = readnum(p + 1, &err);
468 if (err || n < 0 || n > 255) {
469 nasm_nonfatal("invalid ABI version number (valid: 0 to 255)");
470 return DIRR_ERROR;
473 elf_abiver = n;
474 return DIRR_OK;
476 default:
477 return DIRR_UNKNOWN;
481 static void elf_init(void);
483 static void elf32_init(void)
485 static const struct elf_format_info ef_elf32 = {
487 sizeof(Elf32_Ehdr),
488 sizeof(Elf32_Shdr),
489 sizeof(Elf32_Sym),
490 sizeof(Elf32_Rel),
491 sizeof(Elf32_Rela),
492 ".rel",
493 SHT_REL,
494 EM_386,
495 ELFCLASS32,
496 false,
498 elf32_sym,
499 elf32_build_reltab
501 efmt = &ef_elf32;
502 elf_init();
505 static void elfx32_init(void)
507 static const struct elf_format_info ef_elfx32 = {
509 sizeof(Elf32_Ehdr),
510 sizeof(Elf32_Shdr),
511 sizeof(Elf32_Sym),
512 sizeof(Elf32_Rela),
513 sizeof(Elf32_Rela),
514 ".rela",
515 SHT_RELA,
516 EM_X86_64,
517 ELFCLASS32,
518 false,
520 elf32_sym,
521 elfx32_build_reltab
523 efmt = &ef_elfx32;
524 elf_init();
527 static void elf64_init(void)
529 static const struct elf_format_info ef_elf64 = {
531 sizeof(Elf64_Ehdr),
532 sizeof(Elf64_Shdr),
533 sizeof(Elf64_Sym),
534 sizeof(Elf64_Rela),
535 sizeof(Elf64_Rela),
536 ".rela",
537 SHT_RELA,
538 EM_X86_64,
539 ELFCLASS64,
540 true,
542 elf64_sym,
543 elf64_build_reltab
545 efmt = &ef_elf64;
546 elf_init();
549 static void elf_init(void)
551 static const char * const reserved_sections[] = {
552 ".shstrtab", ".strtab", ".symtab", ".symtab_shndx", NULL
554 const char * const *p;
556 strlcpy(elf_module, inname, sizeof(elf_module));
557 sects = NULL;
558 nsects = sectlen = 0;
559 syms = saa_init((int32_t)sizeof(struct elf_symbol));
560 nlocals = nglobs = ndebugs = 0;
561 bsym = raa_init();
562 strs = saa_init(1L);
563 saa_wbytes(strs, "\0", 1L);
564 saa_wbytes(strs, elf_module, strlen(elf_module)+1);
565 strslen = 2 + strlen(elf_module);
566 shstrtab = NULL;
567 shstrtablen = shstrtabsize = 0;;
568 add_sectname("", ""); /* SHN_UNDEF */
570 fwds = NULL;
572 section_by_index = raa_init();
575 * Add reserved section names to the section hash, with NULL
576 * as the data pointer
578 for (p = reserved_sections; *p; p++) {
579 struct hash_insert hi;
580 hash_find(&section_by_name, *p, &hi);
581 hash_add(&hi, *p, NULL);
585 * FIXME: tlsie is Elf32 only and
586 * gottpoff is Elfx32|64 only.
588 elf_gotpc_sect = seg_alloc();
589 backend_label("..gotpc", elf_gotpc_sect + 1, 0L);
590 elf_gotoff_sect = seg_alloc();
591 backend_label("..gotoff", elf_gotoff_sect + 1, 0L);
592 elf_got_sect = seg_alloc();
593 backend_label("..got", elf_got_sect + 1, 0L);
594 elf_plt_sect = seg_alloc();
595 backend_label("..plt", elf_plt_sect + 1, 0L);
596 elf_sym_sect = seg_alloc();
597 backend_label("..sym", elf_sym_sect + 1, 0L);
598 elf_gottpoff_sect = seg_alloc();
599 backend_label("..gottpoff", elf_gottpoff_sect + 1, 0L);
600 elf_tlsie_sect = seg_alloc();
601 backend_label("..tlsie", elf_tlsie_sect + 1, 0L);
603 def_seg = seg_alloc();
606 static void elf_cleanup(void)
608 struct elf_reloc *r;
609 int i;
611 elf_write();
612 for (i = 0; i < nsects; i++) {
613 if (sects[i]->type != SHT_NOBITS)
614 saa_free(sects[i]->data);
615 if (sects[i]->rel)
616 saa_free(sects[i]->rel);
617 while (sects[i]->head) {
618 r = sects[i]->head;
619 sects[i]->head = sects[i]->head->next;
620 nasm_free(r);
623 hash_free(&section_by_name);
624 raa_free(section_by_index);
625 nasm_free(sects);
626 saa_free(syms);
627 raa_free(bsym);
628 saa_free(strs);
629 dfmt->cleanup();
633 * Add entry to the elf .shstrtab section and increment nsections.
634 * Returns the section index for this new section.
636 * IMPORTANT: this needs to match the order the section headers are
637 * emitted.
639 static int add_sectname(const char *firsthalf, const char *secondhalf)
641 int l1 = strlen(firsthalf);
642 int l2 = strlen(secondhalf);
644 while (shstrtablen + l1 + l2 + 1 > shstrtabsize)
645 shstrtab = nasm_realloc(shstrtab, (shstrtabsize += SHSTR_DELTA));
647 memcpy(shstrtab + shstrtablen, firsthalf, l1);
648 shstrtablen += l1;
649 memcpy(shstrtab + shstrtablen, secondhalf, l2+1);
650 shstrtablen += l2 + 1;
652 return nsections++;
655 static struct elf_section *
656 elf_make_section(char *name, int type, int flags, uint64_t align)
658 struct elf_section *s;
660 s = nasm_zalloc(sizeof(*s));
662 if (type != SHT_NOBITS)
663 s->data = saa_init(1L);
664 s->tail = &s->head;
665 if (!strcmp(name, ".text"))
666 s->index = def_seg;
667 else
668 s->index = seg_alloc();
670 s->name = nasm_strdup(name);
671 s->type = type;
672 s->flags = flags;
673 s->align = align;
674 s->shndx = add_sectname("", name);
676 if (nsects >= sectlen)
677 sects = nasm_realloc(sects, (sectlen += SECT_DELTA) * sizeof(*sects));
678 sects[nsects++] = s;
680 return s;
683 static int32_t elf_section_names(char *name, int *bits)
685 char *p;
686 uint32_t flags, flags_and, flags_or;
687 uint64_t align, entsize;
688 void **hp;
689 struct elf_section *s;
690 struct hash_insert hi;
691 int type;
693 if (!name) {
694 *bits = ofmt->maxbits;
695 return def_seg;
698 p = nasm_skip_word(name);
699 if (*p)
700 *p++ = '\0';
701 flags_and = flags_or = type = align = entsize = 0;
703 elf_section_attrib(name, p, &flags_and, &flags_or, &align, &entsize, &type);
705 hp = hash_find(&section_by_name, name, &hi);
706 if (hp) {
707 s = *hp;
708 if (!s) {
709 nasm_nonfatal("attempt to redefine reserved section name `%s'", name);
710 return NO_SEG;
712 } else {
713 const struct elf_known_section *ks = elf_known_sections;
715 while (ks->name) {
716 if (!strcmp(name, ks->name))
717 break;
718 ks++;
721 type = type ? type : ks->type;
722 if (!align)
723 align = to_bytes(ks->align);
724 if (!entsize)
725 entsize = to_bytes(ks->entsize);
726 flags = (ks->flags & ~flags_and) | flags_or;
728 s = elf_make_section(name, type, flags, align);
729 hash_add(&hi, s->name, s);
730 section_by_index = raa_write_ptr(section_by_index, s->index >> 1, s);
733 if ((type && s->type != type)
734 || ((s->flags & flags_and) != flags_or)
735 || (entsize && s->entsize && entsize != s->entsize)) {
736 nasm_warn(WARN_OTHER, "incompatible section attributes ignored on"
737 " redeclaration of section `%s'", name);
740 if (align > s->align)
741 s->align = align;
743 if (entsize && !s->entsize)
744 s->entsize = entsize;
746 if ((flags_or & SHF_MERGE) && s->entsize == 0) {
747 if (!(s->flags & SHF_STRINGS))
748 nasm_nonfatal("section attribute merge specified without an entry size or `strings'");
749 s->entsize = 1;
752 return s->index;
755 static inline bool sym_type_local(int type)
757 return ELF32_ST_BIND(type) == STB_LOCAL;
760 static void elf_deflabel(char *name, int32_t segment, int64_t offset,
761 int is_global, char *special)
763 int pos = strslen;
764 struct elf_symbol *sym;
765 const char *spcword = nasm_skip_spaces(special);
766 int bind, type; /* st_info components */
767 const struct elf_section *sec = NULL;
769 if (debug_level(2)) {
770 nasm_debug(" elf_deflabel: %s, seg=%"PRIx32", off=%"PRIx64", is_global=%d, %s\n",
771 name, segment, offset, is_global, special);
774 if (name[0] == '.' && name[1] == '.' && name[2] != '@') {
776 * This is a NASM special symbol. We never allow it into
777 * the ELF symbol table, even if it's a valid one. If it
778 * _isn't_ a valid one, we should barf immediately.
780 * FIXME: tlsie is Elf32 only, and gottpoff is Elfx32|64 only.
782 if (strcmp(name, "..gotpc") && strcmp(name, "..gotoff") &&
783 strcmp(name, "..got") && strcmp(name, "..plt") &&
784 strcmp(name, "..sym") && strcmp(name, "..gottpoff") &&
785 strcmp(name, "..tlsie"))
786 nasm_nonfatal("unrecognised special symbol `%s'", name);
787 return;
790 if (is_global == 3) {
791 struct elf_symbol **s;
793 * Fix up a forward-reference symbol size from the first
794 * pass.
796 for (s = &fwds; *s; s = &(*s)->nextfwd)
797 if (!strcmp((*s)->name, name)) {
798 struct tokenval tokval;
799 expr *e;
800 char *p = nasm_skip_spaces(nasm_skip_word(special));
802 stdscan_reset();
803 stdscan_set(p);
804 tokval.t_type = TOKEN_INVALID;
805 e = evaluate(stdscan, NULL, &tokval, NULL, 1, NULL);
806 if (e) {
807 if (!is_simple(e))
808 nasm_nonfatal("cannot use relocatable"
809 " expression as symbol size");
810 else
811 (*s)->size = reloc_value(e);
815 * Remove it from the list of unresolved sizes.
817 nasm_free((*s)->name);
818 *s = (*s)->nextfwd;
819 return;
821 return; /* it wasn't an important one */
824 saa_wbytes(strs, name, (int32_t)(1 + strlen(name)));
825 strslen += 1 + strlen(name);
827 lastsym = sym = saa_wstruct(syms);
829 memset(&sym->symv, 0, sizeof(struct rbtree));
831 sym->strpos = pos;
832 bind = is_global ? STB_GLOBAL : STB_LOCAL;
833 type = STT_NOTYPE;
834 sym->other = STV_DEFAULT;
835 sym->size = 0;
836 if (segment == NO_SEG) {
837 sym->section = XSHN_ABS;
838 } else {
839 sym->section = XSHN_UNDEF;
840 if (segment == def_seg) {
841 /* we have to be sure at least text section is there */
842 int tempint;
843 if (segment != elf_section_names(".text", &tempint))
844 nasm_panic("strange segment conditions in ELF driver");
846 sec = raa_read_ptr(section_by_index, segment >> 1);
847 if (sec)
848 sym->section = sec->shndx;
851 if (is_global == 2) {
852 sym->size = offset;
853 sym->symv.key = 0;
854 sym->section = XSHN_COMMON;
856 * We have a common variable. Check the special text to see
857 * if it's a valid number and power of two; if so, store it
858 * as the alignment for the common variable.
860 * XXX: this should allow an expression.
862 if (spcword) {
863 bool err;
864 sym->symv.key = readnum(spcword, &err);
865 if (err)
866 nasm_nonfatal("alignment constraint `%s' is not a"
867 " valid number", special);
868 else if (!is_power2(sym->symv.key))
869 nasm_nonfatal("alignment constraint `%s' is not a"
870 " power of two", special);
871 spcword = nasm_skip_spaces(nasm_skip_word(spcword));
873 } else {
874 sym->symv.key = (sym->section == XSHN_UNDEF ? 0 : offset);
877 if (spcword && *spcword) {
878 const char *wend;
879 bool ok = true;
881 while (ok) {
882 size_t wlen;
883 wend = nasm_skip_word(spcword);
884 wlen = wend - spcword;
886 switch (wlen) {
887 case 4:
888 if (!nasm_strnicmp(spcword, "data", wlen))
889 type = STT_OBJECT;
890 else if (!nasm_strnicmp(spcword, "weak", wlen))
891 bind = STB_WEAK;
892 else
893 ok = false;
894 break;
896 case 6:
897 if (!nasm_strnicmp(spcword, "notype", wlen))
898 type = STT_NOTYPE;
899 else if (!nasm_strnicmp(spcword, "object", wlen))
900 type = STT_OBJECT;
901 else if (!nasm_strnicmp(spcword, "hidden", wlen))
902 sym->other = STV_HIDDEN;
903 else if (!nasm_strnicmp(spcword, "strong", wlen))
904 bind = STB_GLOBAL;
905 else
906 ok = false;
907 break;
909 case 7:
910 if (!nasm_strnicmp(spcword, "default", wlen))
911 sym->other = STV_DEFAULT;
912 else
913 ok = false;
914 break;
916 case 8:
917 if (!nasm_strnicmp(spcword, "function", wlen))
918 type = STT_FUNC;
919 else if (!nasm_stricmp(spcword, "internal"))
920 sym->other = STV_INTERNAL;
921 else
922 ok = false;
923 break;
925 case 9:
926 if (!nasm_strnicmp(spcword, "protected", wlen))
927 sym->other = STV_PROTECTED;
928 else
929 ok = false;
930 break;
932 default:
933 ok = false;
934 break;
937 if (ok)
938 spcword = nasm_skip_spaces(wend);
940 if (!is_global && bind != STB_LOCAL) {
941 nasm_nonfatal("weak and strong only applies to global symbols");
942 bind = STB_LOCAL;
945 if (spcword && *spcword) {
946 struct tokenval tokval;
947 expr *e;
948 int fwd = 0;
949 char *saveme = stdscan_get();
952 * We have a size expression; attempt to
953 * evaluate it.
955 stdscan_reset();
956 stdscan_set((char *)spcword);
957 tokval.t_type = TOKEN_INVALID;
958 e = evaluate(stdscan, NULL, &tokval, &fwd, 0, NULL);
959 if (fwd) {
960 sym->nextfwd = fwds;
961 fwds = sym;
962 sym->name = nasm_strdup(name);
963 } else if (e) {
964 if (!is_simple(e))
965 nasm_nonfatal("cannot use relocatable"
966 " expression as symbol size");
967 else
968 sym->size = reloc_value(e);
970 stdscan_set(saveme);
975 * If it is in a TLS segment, mark symbol accordingly.
977 if (sec && (sec->flags & SHF_TLS))
978 type = STT_TLS;
980 /* Note: ELF32_ST_INFO() and ELF64_ST_INFO() are identical */
981 sym->type = ELF32_ST_INFO(bind, type);
983 if (sym_type_local(sym->type)) {
984 nlocals++;
985 } else {
987 * If sym->section == SHN_ABS, then the first line of the
988 * else section would cause a core dump, because its a reference
989 * beyond the end of the section array.
990 * This behaviour is exhibited by this code:
991 * GLOBAL crash_nasm
992 * crash_nasm equ 0
993 * To avoid such a crash, such requests are silently discarded.
994 * This may not be the best solution.
996 if (sym->section == XSHN_UNDEF || sym->section == XSHN_COMMON) {
997 bsym = raa_write(bsym, segment, nglobs);
998 } else if (sym->section != XSHN_ABS) {
1000 * This is a global symbol; so we must add it to the rbtree
1001 * of global symbols in its section.
1003 * In addition, we check the special text for symbol
1004 * type and size information.
1006 sects[sym->section-1]->gsyms =
1007 rb_insert(sects[sym->section-1]->gsyms, &sym->symv);
1010 sym->globnum = nglobs;
1011 nglobs++;
1015 static void elf_add_reloc(struct elf_section *sect, int32_t segment,
1016 int64_t offset, int type)
1018 struct elf_reloc *r;
1020 r = *sect->tail = nasm_zalloc(sizeof(struct elf_reloc));
1021 sect->tail = &r->next;
1023 r->address = sect->len;
1024 r->offset = offset;
1026 if (segment != NO_SEG) {
1027 const struct elf_section *s;
1028 s = raa_read_ptr(section_by_index, segment >> 1);
1029 if (s)
1030 r->symbol = s->shndx + 1;
1031 else
1032 r->symbol = GLOBAL_TEMP_BASE + raa_read(bsym, segment);
1034 r->type = type;
1036 sect->nrelocs++;
1040 * This routine deals with ..got and ..sym relocations: the more
1041 * complicated kinds. In shared-library writing, some relocations
1042 * with respect to global symbols must refer to the precise symbol
1043 * rather than referring to an offset from the base of the section
1044 * _containing_ the symbol. Such relocations call to this routine,
1045 * which searches the symbol list for the symbol in question.
1047 * R_386_GOT32 | R_X86_64_GOT32 references require the _exact_ symbol address to be
1048 * used; R_386_32 | R_X86_64_32 references can be at an offset from the symbol.
1049 * The boolean argument `exact' tells us this.
1051 * Return value is the adjusted value of `addr', having become an
1052 * offset from the symbol rather than the section. Should always be
1053 * zero when returning from an exact call.
1055 * Limitation: if you define two symbols at the same place,
1056 * confusion will occur.
1058 * Inefficiency: we search, currently, using a linked list which
1059 * isn't even necessarily sorted.
1061 static int64_t elf_add_gsym_reloc(struct elf_section *sect,
1062 int32_t segment, uint64_t offset,
1063 int64_t pcrel, int type, bool exact)
1065 struct elf_reloc *r;
1066 struct elf_section *s;
1067 struct elf_symbol *sym;
1068 struct rbtree *srb;
1071 * First look up the segment/offset pair and find a global
1072 * symbol corresponding to it. If it's not one of our segments,
1073 * then it must be an external symbol, in which case we're fine
1074 * doing a normal elf_add_reloc after first sanity-checking
1075 * that the offset from the symbol is zero.
1077 s = raa_read_ptr(section_by_index, segment >> 1);
1078 if (!s) {
1079 if (exact && offset)
1080 nasm_nonfatal("invalid access to an external symbol");
1081 else
1082 elf_add_reloc(sect, segment, offset - pcrel, type);
1083 return 0;
1086 srb = rb_search(s->gsyms, offset);
1087 if (!srb || (exact && srb->key != offset)) {
1088 nasm_nonfatal("unable to find a suitable global symbol"
1089 " for this reference");
1090 return 0;
1092 sym = container_of(srb, struct elf_symbol, symv);
1094 r = *sect->tail = nasm_malloc(sizeof(struct elf_reloc));
1095 sect->tail = &r->next;
1097 r->next = NULL;
1098 r->address = sect->len;
1099 r->offset = offset - pcrel - sym->symv.key;
1100 r->symbol = GLOBAL_TEMP_BASE + sym->globnum;
1101 r->type = type;
1103 sect->nrelocs++;
1104 return r->offset;
1107 static void elf32_out(int32_t segto, const void *data,
1108 enum out_type type, uint64_t size,
1109 int32_t segment, int32_t wrt)
1111 struct elf_section *s;
1112 int64_t addr;
1113 int reltype, bytes;
1114 static struct symlininfo sinfo;
1117 * handle absolute-assembly (structure definitions)
1119 if (segto == NO_SEG) {
1120 if (type != OUT_RESERVE)
1121 nasm_nonfatal("attempt to assemble code in [ABSOLUTE] space");
1122 return;
1125 s = raa_read_ptr(section_by_index, segto >> 1);
1126 if (!s) {
1127 int tempint; /* ignored */
1128 if (segto != elf_section_names(".text", &tempint))
1129 nasm_panic("strange segment conditions in ELF driver");
1130 else
1131 s = sects[nsects - 1];
1134 /* again some stabs debugging stuff */
1135 sinfo.offset = s->len;
1136 /* Adjust to an index of the section table. */
1137 sinfo.section = s->shndx - 1;
1138 sinfo.segto = segto;
1139 sinfo.name = s->name;
1140 dfmt->debug_output(TY_DEBUGSYMLIN, &sinfo);
1141 /* end of debugging stuff */
1143 if (s->type == SHT_NOBITS && type != OUT_RESERVE) {
1144 nasm_warn(WARN_OTHER, "attempt to initialize memory in"
1145 " BSS section `%s': ignored", s->name);
1146 s->len += realsize(type, size);
1147 return;
1150 switch (type) {
1151 case OUT_RESERVE:
1152 if (s->type != SHT_NOBITS) {
1153 nasm_warn(WARN_ZEROING, "uninitialized space declared in"
1154 " non-BSS section `%s': zeroing", s->name);
1155 elf_sect_write(s, NULL, size);
1156 } else
1157 s->len += size;
1158 break;
1160 case OUT_RAWDATA:
1161 elf_sect_write(s, data, size);
1162 break;
1164 case OUT_ADDRESS:
1166 bool err = false;
1167 int asize = abs((int)size);
1169 addr = *(int64_t *)data;
1170 if (segment != NO_SEG) {
1171 if (segment & 1) {
1172 nasm_nonfatal("ELF format does not support"
1173 " segment base references");
1174 } else {
1175 if (wrt == NO_SEG) {
1177 * The if() is a hack to deal with compilers which
1178 * don't handle switch() statements with 64-bit
1179 * expressions.
1181 switch (asize) {
1182 case 1:
1183 elf_add_reloc(s, segment, 0, R_386_8);
1184 break;
1185 case 2:
1186 elf_add_reloc(s, segment, 0, R_386_16);
1187 break;
1188 case 4:
1189 elf_add_reloc(s, segment, 0, R_386_32);
1190 break;
1191 default: /* Error issued further down */
1192 err = true;
1193 break;
1195 } else if (wrt == elf_gotpc_sect + 1) {
1197 * The user will supply GOT relative to $$. ELF
1198 * will let us have GOT relative to $. So we
1199 * need to fix up the data item by $-$$.
1201 err = asize != 4;
1202 addr += s->len;
1203 elf_add_reloc(s, segment, 0, R_386_GOTPC);
1204 } else if (wrt == elf_gotoff_sect + 1) {
1205 err = asize != 4;
1206 elf_add_reloc(s, segment, 0, R_386_GOTOFF);
1207 } else if (wrt == elf_tlsie_sect + 1) {
1208 err = asize != 4;
1209 addr = elf_add_gsym_reloc(s, segment, addr, 0,
1210 R_386_TLS_IE, true);
1211 } else if (wrt == elf_got_sect + 1) {
1212 err = asize != 4;
1213 addr = elf_add_gsym_reloc(s, segment, addr, 0,
1214 R_386_GOT32, true);
1215 } else if (wrt == elf_sym_sect + 1) {
1216 switch (asize) {
1217 case 1:
1218 addr = elf_add_gsym_reloc(s, segment, addr, 0,
1219 R_386_8, false);
1220 break;
1221 case 2:
1222 addr = elf_add_gsym_reloc(s, segment, addr, 0,
1223 R_386_16, false);
1224 break;
1225 case 4:
1226 addr = elf_add_gsym_reloc(s, segment, addr, 0,
1227 R_386_32, false);
1228 break;
1229 default:
1230 err = true;
1231 break;
1233 } else if (wrt == elf_plt_sect + 1) {
1234 nasm_nonfatal("ELF format cannot produce non-PC-"
1235 "relative PLT references");
1236 } else {
1237 nasm_nonfatal("ELF format does not support this"
1238 " use of WRT");
1239 wrt = NO_SEG; /* we can at least _try_ to continue */
1244 if (err) {
1245 nasm_nonfatal("Unsupported %d-bit ELF relocation", asize << 3);
1247 elf_sect_writeaddr(s, addr, asize);
1248 break;
1251 case OUT_REL1ADR:
1252 reltype = R_386_PC8;
1253 bytes = 1;
1254 goto rel12adr;
1255 case OUT_REL2ADR:
1256 reltype = R_386_PC16;
1257 bytes = 2;
1258 goto rel12adr;
1260 rel12adr:
1261 addr = *(int64_t *)data - size;
1262 nasm_assert(segment != segto);
1263 if (segment != NO_SEG && (segment & 1)) {
1264 nasm_nonfatal("ELF format does not support"
1265 " segment base references");
1266 } else {
1267 if (wrt == NO_SEG) {
1268 elf_add_reloc(s, segment, 0, reltype);
1269 } else {
1270 nasm_nonfatal("Unsupported %d-bit ELF relocation", bytes << 3);
1273 elf_sect_writeaddr(s, addr, bytes);
1274 break;
1276 case OUT_REL4ADR:
1277 addr = *(int64_t *)data - size;
1278 if (segment == segto)
1279 nasm_panic("intra-segment OUT_REL4ADR");
1280 if (segment != NO_SEG && (segment & 1)) {
1281 nasm_nonfatal("ELF format does not support"
1282 " segment base references");
1283 } else {
1284 if (wrt == NO_SEG) {
1285 elf_add_reloc(s, segment, 0, R_386_PC32);
1286 } else if (wrt == elf_plt_sect + 1) {
1287 elf_add_reloc(s, segment, 0, R_386_PLT32);
1288 } else if (wrt == elf_gotpc_sect + 1 ||
1289 wrt == elf_gotoff_sect + 1 ||
1290 wrt == elf_got_sect + 1) {
1291 nasm_nonfatal("ELF format cannot produce PC-"
1292 "relative GOT references");
1293 } else {
1294 nasm_nonfatal("ELF format does not support this"
1295 " use of WRT");
1296 wrt = NO_SEG; /* we can at least _try_ to continue */
1299 elf_sect_writeaddr(s, addr, 4);
1300 break;
1302 case OUT_REL8ADR:
1303 nasm_nonfatal("32-bit ELF format does not support 64-bit relocations");
1304 addr = 0;
1305 elf_sect_writeaddr(s, addr, 8);
1306 break;
1308 default:
1309 panic();
1312 static void elf64_out(int32_t segto, const void *data,
1313 enum out_type type, uint64_t size,
1314 int32_t segment, int32_t wrt)
1316 struct elf_section *s;
1317 int64_t addr;
1318 int reltype, bytes;
1319 static struct symlininfo sinfo;
1322 * handle absolute-assembly (structure definitions)
1324 if (segto == NO_SEG) {
1325 if (type != OUT_RESERVE)
1326 nasm_nonfatal("attempt to assemble code in [ABSOLUTE] space");
1327 return;
1330 s = raa_read_ptr(section_by_index, segto >> 1);
1331 if (!s) {
1332 int tempint; /* ignored */
1333 if (segto != elf_section_names(".text", &tempint))
1334 nasm_panic("strange segment conditions in ELF driver");
1335 else
1336 s = sects[nsects - 1];
1339 /* again some stabs debugging stuff */
1340 sinfo.offset = s->len;
1341 /* Adjust to an index of the section table. */
1342 sinfo.section = s->shndx - 1;
1343 sinfo.segto = segto;
1344 sinfo.name = s->name;
1345 dfmt->debug_output(TY_DEBUGSYMLIN, &sinfo);
1346 /* end of debugging stuff */
1348 if (s->type == SHT_NOBITS && type != OUT_RESERVE) {
1349 nasm_warn(WARN_OTHER, "attempt to initialize memory in"
1350 " BSS section `%s': ignored", s->name);
1351 s->len += realsize(type, size);
1352 return;
1355 switch (type) {
1356 case OUT_RESERVE:
1357 if (s->type != SHT_NOBITS) {
1358 nasm_warn(WARN_ZEROING, "uninitialized space declared in"
1359 " non-BSS section `%s': zeroing", s->name);
1360 elf_sect_write(s, NULL, size);
1361 } else
1362 s->len += size;
1363 break;
1365 case OUT_RAWDATA:
1366 if (segment != NO_SEG)
1367 nasm_panic("OUT_RAWDATA with other than NO_SEG");
1368 elf_sect_write(s, data, size);
1369 break;
1371 case OUT_ADDRESS:
1373 int isize = (int)size;
1374 int asize = abs((int)size);
1376 addr = *(int64_t *)data;
1377 if (segment == NO_SEG) {
1378 /* Do nothing */
1379 } else if (segment & 1) {
1380 nasm_nonfatal("ELF format does not support"
1381 " segment base references");
1382 } else {
1383 if (wrt == NO_SEG) {
1384 switch (isize) {
1385 case 1:
1386 case -1:
1387 elf_add_reloc(s, segment, addr, R_X86_64_8);
1388 break;
1389 case 2:
1390 case -2:
1391 elf_add_reloc(s, segment, addr, R_X86_64_16);
1392 break;
1393 case 4:
1394 elf_add_reloc(s, segment, addr, R_X86_64_32);
1395 break;
1396 case -4:
1397 elf_add_reloc(s, segment, addr, R_X86_64_32S);
1398 break;
1399 case 8:
1400 case -8:
1401 elf_add_reloc(s, segment, addr, R_X86_64_64);
1402 break;
1403 default:
1404 nasm_panic("internal error elf64-hpa-871");
1405 break;
1407 addr = 0;
1408 } else if (wrt == elf_gotpc_sect + 1) {
1410 * The user will supply GOT relative to $$. ELF
1411 * will let us have GOT relative to $. So we
1412 * need to fix up the data item by $-$$.
1414 addr += s->len;
1415 elf_add_reloc(s, segment, addr, R_X86_64_GOTPC32);
1416 addr = 0;
1417 } else if (wrt == elf_gotoff_sect + 1) {
1418 if (asize != 8) {
1419 nasm_nonfatal("ELF64 requires ..gotoff "
1420 "references to be qword");
1421 } else {
1422 elf_add_reloc(s, segment, addr, R_X86_64_GOTOFF64);
1423 addr = 0;
1425 } else if (wrt == elf_got_sect + 1) {
1426 switch (asize) {
1427 case 4:
1428 elf_add_gsym_reloc(s, segment, addr, 0,
1429 R_X86_64_GOT32, true);
1430 addr = 0;
1431 break;
1432 case 8:
1433 elf_add_gsym_reloc(s, segment, addr, 0,
1434 R_X86_64_GOT64, true);
1435 addr = 0;
1436 break;
1437 default:
1438 nasm_nonfatal("invalid ..got reference");
1439 break;
1441 } else if (wrt == elf_sym_sect + 1) {
1442 switch (isize) {
1443 case 1:
1444 case -1:
1445 elf_add_gsym_reloc(s, segment, addr, 0,
1446 R_X86_64_8, false);
1447 addr = 0;
1448 break;
1449 case 2:
1450 case -2:
1451 elf_add_gsym_reloc(s, segment, addr, 0,
1452 R_X86_64_16, false);
1453 addr = 0;
1454 break;
1455 case 4:
1456 elf_add_gsym_reloc(s, segment, addr, 0,
1457 R_X86_64_32, false);
1458 addr = 0;
1459 break;
1460 case -4:
1461 elf_add_gsym_reloc(s, segment, addr, 0,
1462 R_X86_64_32S, false);
1463 addr = 0;
1464 break;
1465 case 8:
1466 case -8:
1467 elf_add_gsym_reloc(s, segment, addr, 0,
1468 R_X86_64_64, false);
1469 addr = 0;
1470 break;
1471 default:
1472 nasm_panic("internal error elf64-hpa-903");
1473 break;
1475 } else if (wrt == elf_plt_sect + 1) {
1476 nasm_nonfatal("ELF format cannot produce non-PC-"
1477 "relative PLT references");
1478 } else {
1479 nasm_nonfatal("ELF format does not support this"
1480 " use of WRT");
1483 elf_sect_writeaddr(s, addr, asize);
1484 break;
1487 case OUT_REL1ADR:
1488 reltype = R_X86_64_PC8;
1489 bytes = 1;
1490 goto rel12adr;
1492 case OUT_REL2ADR:
1493 reltype = R_X86_64_PC16;
1494 bytes = 2;
1495 goto rel12adr;
1497 rel12adr:
1498 addr = *(int64_t *)data - size;
1499 if (segment == segto)
1500 nasm_panic("intra-segment OUT_REL1ADR");
1501 if (segment == NO_SEG) {
1502 /* Do nothing */
1503 } else if (segment & 1) {
1504 nasm_nonfatal("ELF format does not support"
1505 " segment base references");
1506 } else {
1507 if (wrt == NO_SEG) {
1508 elf_add_reloc(s, segment, addr, reltype);
1509 addr = 0;
1510 } else {
1511 nasm_nonfatal("Unsupported %d-bit ELF relocation", bytes << 3);
1514 elf_sect_writeaddr(s, addr, bytes);
1515 break;
1517 case OUT_REL4ADR:
1518 addr = *(int64_t *)data - size;
1519 if (segment == segto)
1520 nasm_panic("intra-segment OUT_REL4ADR");
1521 if (segment == NO_SEG) {
1522 /* Do nothing */
1523 } else if (segment & 1) {
1524 nasm_nonfatal("ELF64 format does not support"
1525 " segment base references");
1526 } else {
1527 if (wrt == NO_SEG) {
1528 elf_add_reloc(s, segment, addr, R_X86_64_PC32);
1529 addr = 0;
1530 } else if (wrt == elf_plt_sect + 1) {
1531 elf_add_gsym_reloc(s, segment, addr+size, size,
1532 R_X86_64_PLT32, true);
1533 addr = 0;
1534 } else if (wrt == elf_gotpc_sect + 1 ||
1535 wrt == elf_got_sect + 1) {
1536 elf_add_gsym_reloc(s, segment, addr+size, size,
1537 R_X86_64_GOTPCREL, true);
1538 addr = 0;
1539 } else if (wrt == elf_gotoff_sect + 1 ||
1540 wrt == elf_got_sect + 1) {
1541 nasm_nonfatal("ELF64 requires ..gotoff references to be "
1542 "qword absolute");
1543 } else if (wrt == elf_gottpoff_sect + 1) {
1544 elf_add_gsym_reloc(s, segment, addr+size, size,
1545 R_X86_64_GOTTPOFF, true);
1546 addr = 0;
1547 } else {
1548 nasm_nonfatal("ELF64 format does not support this"
1549 " use of WRT");
1552 elf_sect_writeaddr(s, addr, 4);
1553 break;
1555 case OUT_REL8ADR:
1556 addr = *(int64_t *)data - size;
1557 if (segment == segto)
1558 nasm_panic("intra-segment OUT_REL8ADR");
1559 if (segment == NO_SEG) {
1560 /* Do nothing */
1561 } else if (segment & 1) {
1562 nasm_nonfatal("ELF64 format does not support"
1563 " segment base references");
1564 } else {
1565 if (wrt == NO_SEG) {
1566 elf_add_reloc(s, segment, addr, R_X86_64_PC64);
1567 addr = 0;
1568 } else if (wrt == elf_gotpc_sect + 1 ||
1569 wrt == elf_got_sect + 1) {
1570 elf_add_gsym_reloc(s, segment, addr+size, size,
1571 R_X86_64_GOTPCREL64, true);
1572 addr = 0;
1573 } else if (wrt == elf_gotoff_sect + 1 ||
1574 wrt == elf_got_sect + 1) {
1575 nasm_nonfatal("ELF64 requires ..gotoff references to be "
1576 "absolute");
1577 } else if (wrt == elf_gottpoff_sect + 1) {
1578 nasm_nonfatal("ELF64 requires ..gottpoff references to be "
1579 "dword");
1580 } else {
1581 nasm_nonfatal("ELF64 format does not support this"
1582 " use of WRT");
1585 elf_sect_writeaddr(s, addr, 8);
1586 break;
1588 default:
1589 panic();
1593 static void elfx32_out(int32_t segto, const void *data,
1594 enum out_type type, uint64_t size,
1595 int32_t segment, int32_t wrt)
1597 struct elf_section *s;
1598 int64_t addr;
1599 int reltype, bytes;
1600 static struct symlininfo sinfo;
1603 * handle absolute-assembly (structure definitions)
1605 if (segto == NO_SEG) {
1606 if (type != OUT_RESERVE)
1607 nasm_nonfatal("attempt to assemble code in [ABSOLUTE] space");
1608 return;
1611 s = raa_read_ptr(section_by_index, segto >> 1);
1612 if (!s) {
1613 int tempint; /* ignored */
1614 if (segto != elf_section_names(".text", &tempint))
1615 nasm_panic("strange segment conditions in ELF driver");
1616 else
1617 s = sects[nsects - 1];
1620 /* again some stabs debugging stuff */
1621 sinfo.offset = s->len;
1622 /* Adjust to an index of the section table. */
1623 sinfo.section = s->shndx - 1;
1624 sinfo.segto = segto;
1625 sinfo.name = s->name;
1626 dfmt->debug_output(TY_DEBUGSYMLIN, &sinfo);
1627 /* end of debugging stuff */
1629 if (s->type == SHT_NOBITS && type != OUT_RESERVE) {
1630 nasm_warn(WARN_OTHER, "attempt to initialize memory in"
1631 " BSS section `%s': ignored", s->name);
1632 s->len += realsize(type, size);
1633 return;
1636 switch (type) {
1637 case OUT_RESERVE:
1638 if (s->type != SHT_NOBITS) {
1639 nasm_warn(WARN_ZEROING, "uninitialized space declared in"
1640 " non-BSS section `%s': zeroing", s->name);
1641 elf_sect_write(s, NULL, size);
1642 } else
1643 s->len += size;
1644 break;
1646 case OUT_RAWDATA:
1647 if (segment != NO_SEG)
1648 nasm_panic("OUT_RAWDATA with other than NO_SEG");
1649 elf_sect_write(s, data, size);
1650 break;
1652 case OUT_ADDRESS:
1654 int isize = (int)size;
1655 int asize = abs((int)size);
1657 addr = *(int64_t *)data;
1658 if (segment == NO_SEG) {
1659 /* Do nothing */
1660 } else if (segment & 1) {
1661 nasm_nonfatal("ELF format does not support"
1662 " segment base references");
1663 } else {
1664 if (wrt == NO_SEG) {
1665 switch (isize) {
1666 case 1:
1667 case -1:
1668 elf_add_reloc(s, segment, addr, R_X86_64_8);
1669 break;
1670 case 2:
1671 case -2:
1672 elf_add_reloc(s, segment, addr, R_X86_64_16);
1673 break;
1674 case 4:
1675 elf_add_reloc(s, segment, addr, R_X86_64_32);
1676 break;
1677 case -4:
1678 elf_add_reloc(s, segment, addr, R_X86_64_32S);
1679 break;
1680 case 8:
1681 case -8:
1682 elf_add_reloc(s, segment, addr, R_X86_64_64);
1683 break;
1684 default:
1685 nasm_panic("internal error elfx32-hpa-871");
1686 break;
1688 addr = 0;
1689 } else if (wrt == elf_gotpc_sect + 1) {
1691 * The user will supply GOT relative to $$. ELF
1692 * will let us have GOT relative to $. So we
1693 * need to fix up the data item by $-$$.
1695 addr += s->len;
1696 elf_add_reloc(s, segment, addr, R_X86_64_GOTPC32);
1697 addr = 0;
1698 } else if (wrt == elf_gotoff_sect + 1) {
1699 nasm_nonfatal("ELFX32 doesn't support "
1700 "R_X86_64_GOTOFF64");
1701 } else if (wrt == elf_got_sect + 1) {
1702 switch (asize) {
1703 case 4:
1704 elf_add_gsym_reloc(s, segment, addr, 0,
1705 R_X86_64_GOT32, true);
1706 addr = 0;
1707 break;
1708 default:
1709 nasm_nonfatal("invalid ..got reference");
1710 break;
1712 } else if (wrt == elf_sym_sect + 1) {
1713 switch (isize) {
1714 case 1:
1715 case -1:
1716 elf_add_gsym_reloc(s, segment, addr, 0,
1717 R_X86_64_8, false);
1718 addr = 0;
1719 break;
1720 case 2:
1721 case -2:
1722 elf_add_gsym_reloc(s, segment, addr, 0,
1723 R_X86_64_16, false);
1724 addr = 0;
1725 break;
1726 case 4:
1727 elf_add_gsym_reloc(s, segment, addr, 0,
1728 R_X86_64_32, false);
1729 addr = 0;
1730 break;
1731 case -4:
1732 elf_add_gsym_reloc(s, segment, addr, 0,
1733 R_X86_64_32S, false);
1734 addr = 0;
1735 break;
1736 case 8:
1737 case -8:
1738 elf_add_gsym_reloc(s, segment, addr, 0,
1739 R_X86_64_64, false);
1740 addr = 0;
1741 break;
1742 default:
1743 nasm_panic("internal error elfx32-hpa-903");
1744 break;
1746 } else if (wrt == elf_plt_sect + 1) {
1747 nasm_nonfatal("ELF format cannot produce non-PC-"
1748 "relative PLT references");
1749 } else {
1750 nasm_nonfatal("ELF format does not support this"
1751 " use of WRT");
1754 elf_sect_writeaddr(s, addr, asize);
1755 break;
1758 case OUT_REL1ADR:
1759 reltype = R_X86_64_PC8;
1760 bytes = 1;
1761 goto rel12adr;
1763 case OUT_REL2ADR:
1764 reltype = R_X86_64_PC16;
1765 bytes = 2;
1766 goto rel12adr;
1768 rel12adr:
1769 addr = *(int64_t *)data - size;
1770 if (segment == segto)
1771 nasm_panic("intra-segment OUT_REL1ADR");
1772 if (segment == NO_SEG) {
1773 /* Do nothing */
1774 } else if (segment & 1) {
1775 nasm_nonfatal("ELF format does not support"
1776 " segment base references");
1777 } else {
1778 if (wrt == NO_SEG) {
1779 elf_add_reloc(s, segment, addr, reltype);
1780 addr = 0;
1781 } else {
1782 nasm_nonfatal("unsupported %d-bit ELF relocation", bytes << 3);
1785 elf_sect_writeaddr(s, addr, bytes);
1786 break;
1788 case OUT_REL4ADR:
1789 addr = *(int64_t *)data - size;
1790 if (segment == segto)
1791 nasm_panic("intra-segment OUT_REL4ADR");
1792 if (segment == NO_SEG) {
1793 /* Do nothing */
1794 } else if (segment & 1) {
1795 nasm_nonfatal("ELFX32 format does not support"
1796 " segment base references");
1797 } else {
1798 if (wrt == NO_SEG) {
1799 elf_add_reloc(s, segment, addr, R_X86_64_PC32);
1800 addr = 0;
1801 } else if (wrt == elf_plt_sect + 1) {
1802 elf_add_gsym_reloc(s, segment, addr+size, size,
1803 R_X86_64_PLT32, true);
1804 addr = 0;
1805 } else if (wrt == elf_gotpc_sect + 1 ||
1806 wrt == elf_got_sect + 1) {
1807 elf_add_gsym_reloc(s, segment, addr+size, size,
1808 R_X86_64_GOTPCREL, true);
1809 addr = 0;
1810 } else if (wrt == elf_gotoff_sect + 1 ||
1811 wrt == elf_got_sect + 1) {
1812 nasm_nonfatal("invalid ..gotoff reference");
1813 } else if (wrt == elf_gottpoff_sect + 1) {
1814 elf_add_gsym_reloc(s, segment, addr+size, size,
1815 R_X86_64_GOTTPOFF, true);
1816 addr = 0;
1817 } else {
1818 nasm_nonfatal("ELFX32 format does not support this use of WRT");
1821 elf_sect_writeaddr(s, addr, 4);
1822 break;
1824 case OUT_REL8ADR:
1825 nasm_nonfatal("32-bit ELF format does not support 64-bit relocations");
1826 addr = 0;
1827 elf_sect_writeaddr(s, addr, 8);
1828 break;
1830 default:
1831 panic();
1836 * Section index/count with a specified overflow value (usually SHN_INDEX,
1837 * but 0 for e_shnum.
1839 static inline uint16_t elf_shndx(int section, uint16_t overflow)
1841 return cpu_to_le16(section < (int)SHN_LORESERVE ? section : overflow);
1844 struct ehdr_common {
1845 uint8_t e_ident[EI_NIDENT];
1846 uint16_t e_type;
1847 uint16_t e_machine;
1848 uint32_t e_version;
1851 union ehdr {
1852 Elf32_Ehdr ehdr32;
1853 Elf64_Ehdr ehdr64;
1854 struct ehdr_common com;
1857 static void elf_write(void)
1859 int align;
1860 char *p;
1861 int i;
1862 size_t symtablocal;
1863 int sec_shstrtab, sec_symtab, sec_strtab;
1864 union ehdr ehdr;
1867 * Add any sections we don't already have:
1868 * rel/rela sections for the user sections, debug sections, and
1869 * the ELF special sections.
1872 sec_debug = nsections;
1873 if (dfmt_is_stabs()) {
1874 /* in case the debug information is wanted, just add these three sections... */
1875 add_sectname("", ".stab");
1876 add_sectname("", ".stabstr");
1877 add_sectname(efmt->relpfx, ".stab");
1878 } else if (dfmt_is_dwarf()) {
1879 /* the dwarf debug standard specifies the following ten sections,
1880 not all of which are currently implemented,
1881 although all of them are defined. */
1882 add_sectname("", ".debug_aranges");
1883 add_sectname(".rela", ".debug_aranges");
1884 add_sectname("", ".debug_pubnames");
1885 add_sectname("", ".debug_info");
1886 add_sectname(".rela", ".debug_info");
1887 add_sectname("", ".debug_abbrev");
1888 add_sectname("", ".debug_line");
1889 add_sectname(".rela", ".debug_line");
1890 add_sectname("", ".debug_frame");
1891 add_sectname("", ".debug_loc");
1894 sec_shstrtab = add_sectname("", ".shstrtab");
1895 sec_symtab = add_sectname("", ".symtab");
1896 sec_strtab = add_sectname("", ".strtab");
1899 * Build the symbol table and relocation tables.
1901 symtablocal = elf_build_symtab();
1903 /* Do we need an .symtab_shndx section? */
1904 if (symtab_shndx)
1905 add_sectname("", ".symtab_shndx");
1907 for (i = 0; i < nsects; i++) {
1908 if (sects[i]->head) {
1909 add_sectname(efmt->relpfx, sects[i]->name);
1910 sects[i]->rel = efmt->elf_build_reltab(sects[i]->head);
1915 * Output the ELF header.
1917 nasm_zero(ehdr);
1919 /* These fields are in the same place for 32 and 64 bits */
1920 memcpy(&ehdr.com.e_ident[EI_MAG0], ELFMAG, SELFMAG);
1921 ehdr.com.e_ident[EI_CLASS] = efmt->ei_class;
1922 ehdr.com.e_ident[EI_DATA] = ELFDATA2LSB;
1923 ehdr.com.e_ident[EI_VERSION] = EV_CURRENT;
1924 ehdr.com.e_ident[EI_OSABI] = elf_osabi;
1925 ehdr.com.e_ident[EI_ABIVERSION] = elf_abiver;
1926 ehdr.com.e_type = cpu_to_le16(ET_REL);
1927 ehdr.com.e_machine = cpu_to_le16(efmt->e_machine);
1928 ehdr.com.e_version = cpu_to_le16(EV_CURRENT);
1930 if (!efmt->elf64) {
1931 ehdr.ehdr32.e_shoff = cpu_to_le32(sizeof ehdr);
1932 ehdr.ehdr32.e_ehsize = cpu_to_le16(sizeof(Elf32_Ehdr));
1933 ehdr.ehdr32.e_shentsize = cpu_to_le16(sizeof(Elf32_Shdr));
1934 ehdr.ehdr32.e_shnum = elf_shndx(nsections, 0);
1935 ehdr.ehdr32.e_shstrndx = elf_shndx(sec_shstrtab, SHN_XINDEX);
1936 } else {
1937 ehdr.ehdr64.e_shoff = cpu_to_le64(sizeof ehdr);
1938 ehdr.ehdr64.e_ehsize = cpu_to_le16(sizeof(Elf64_Ehdr));
1939 ehdr.ehdr64.e_shentsize = cpu_to_le16(sizeof(Elf64_Shdr));
1940 ehdr.ehdr64.e_shnum = elf_shndx(nsections, 0);
1941 ehdr.ehdr64.e_shstrndx = elf_shndx(sec_shstrtab, SHN_XINDEX);
1944 nasm_write(&ehdr, sizeof(ehdr), ofile);
1945 elf_foffs = sizeof ehdr + efmt->shdr_size * nsections;
1948 * Now output the section header table.
1950 align = ALIGN(elf_foffs, SEC_FILEALIGN) - elf_foffs;
1951 elf_foffs += align;
1952 elf_nsect = 0;
1953 elf_sects = nasm_malloc(sizeof(*elf_sects) * nsections);
1955 /* SHN_UNDEF */
1956 elf_section_header(0, SHT_NULL, 0, NULL, false,
1957 nsections > (int)SHN_LORESERVE ? nsections : 0,
1958 sec_shstrtab >= (int)SHN_LORESERVE ? sec_shstrtab : 0,
1959 0, 0, 0);
1960 p = shstrtab + 1;
1962 /* The normal sections */
1963 for (i = 0; i < nsects; i++) {
1964 elf_section_header(p - shstrtab, sects[i]->type, sects[i]->flags,
1965 sects[i]->data, true,
1966 sects[i]->len, 0, 0,
1967 sects[i]->align, sects[i]->entsize);
1968 p += strlen(p) + 1;
1971 /* The debugging sections */
1972 if (dfmt_is_stabs()) {
1973 /* for debugging information, create the last three sections
1974 which are the .stab , .stabstr and .rel.stab sections respectively */
1976 /* this function call creates the stab sections in memory */
1977 stabs_generate();
1979 if (stabbuf && stabstrbuf && stabrelbuf) {
1980 elf_section_header(p - shstrtab, SHT_PROGBITS, 0, stabbuf, false,
1981 stablen, sec_stabstr, 0, 4, 12);
1982 p += strlen(p) + 1;
1984 elf_section_header(p - shstrtab, SHT_STRTAB, 0, stabstrbuf, false,
1985 stabstrlen, 0, 0, 4, 0);
1986 p += strlen(p) + 1;
1988 /* link -> symtable info -> section to refer to */
1989 elf_section_header(p - shstrtab, efmt->reltype, 0,
1990 stabrelbuf, false, stabrellen,
1991 sec_symtab, sec_stab,
1992 efmt->word, efmt->rel_size);
1993 p += strlen(p) + 1;
1995 } else if (dfmt_is_dwarf()) {
1996 /* for dwarf debugging information, create the ten dwarf sections */
1998 /* this function call creates the dwarf sections in memory */
1999 if (dwarf_fsect)
2000 dwarf_generate();
2002 elf_section_header(p - shstrtab, SHT_PROGBITS, 0, arangesbuf, false,
2003 arangeslen, 0, 0, 1, 0);
2004 p += strlen(p) + 1;
2006 elf_section_header(p - shstrtab, SHT_RELA, 0, arangesrelbuf, false,
2007 arangesrellen, sec_symtab,
2008 sec_debug_aranges,
2009 efmt->word, efmt->rela_size);
2010 p += strlen(p) + 1;
2012 elf_section_header(p - shstrtab, SHT_PROGBITS, 0, pubnamesbuf,
2013 false, pubnameslen, 0, 0, 1, 0);
2014 p += strlen(p) + 1;
2016 elf_section_header(p - shstrtab, SHT_PROGBITS, 0, infobuf, false,
2017 infolen, 0, 0, 1, 0);
2018 p += strlen(p) + 1;
2020 elf_section_header(p - shstrtab, SHT_RELA, 0, inforelbuf, false,
2021 inforellen, sec_symtab,
2022 sec_debug_info,
2023 efmt->word, efmt->rela_size);
2024 p += strlen(p) + 1;
2026 elf_section_header(p - shstrtab, SHT_PROGBITS, 0, abbrevbuf, false,
2027 abbrevlen, 0, 0, 1, 0);
2028 p += strlen(p) + 1;
2030 elf_section_header(p - shstrtab, SHT_PROGBITS, 0, linebuf, false,
2031 linelen, 0, 0, 1, 0);
2032 p += strlen(p) + 1;
2034 elf_section_header(p - shstrtab, SHT_RELA, 0, linerelbuf, false,
2035 linerellen, sec_symtab,
2036 sec_debug_line,
2037 efmt->word, efmt->rela_size);
2038 p += strlen(p) + 1;
2040 elf_section_header(p - shstrtab, SHT_PROGBITS, 0, framebuf, false,
2041 framelen, 0, 0, 8, 0);
2042 p += strlen(p) + 1;
2044 elf_section_header(p - shstrtab, SHT_PROGBITS, 0, locbuf, false,
2045 loclen, 0, 0, 1, 0);
2046 p += strlen(p) + 1;
2049 /* .shstrtab */
2050 elf_section_header(p - shstrtab, SHT_STRTAB, 0, shstrtab, false,
2051 shstrtablen, 0, 0, 1, 0);
2052 p += strlen(p) + 1;
2054 /* .symtab */
2055 elf_section_header(p - shstrtab, SHT_SYMTAB, 0, symtab, true,
2056 symtab->datalen, sec_strtab, symtablocal,
2057 efmt->word, efmt->sym_size);
2058 p += strlen(p) + 1;
2060 /* .strtab */
2061 elf_section_header(p - shstrtab, SHT_STRTAB, 0, strs, true,
2062 strslen, 0, 0, 1, 0);
2063 p += strlen(p) + 1
2065 /* .symtab_shndx */
2066 if (symtab_shndx) {
2067 elf_section_header(p - shstrtab, SHT_SYMTAB_SHNDX, 0,
2068 symtab_shndx, true, symtab_shndx->datalen,
2069 sec_symtab, 0, 1, 0);
2070 p += strlen(p) + 1;
2073 /* The relocation sections */
2074 for (i = 0; i < nsects; i++) {
2075 if (sects[i]->rel) {
2076 elf_section_header(p - shstrtab, efmt->reltype, 0,
2077 sects[i]->rel, true, sects[i]->rel->datalen,
2078 sec_symtab, sects[i]->shndx,
2079 efmt->word, efmt->rel_size);
2080 p += strlen(p) + 1;
2083 fwritezero(align, ofile);
2086 * Now output the sections.
2088 elf_write_sections();
2090 nasm_free(elf_sects);
2091 saa_free(symtab);
2092 if (symtab_shndx)
2093 saa_free(symtab_shndx);
2096 static size_t nsyms;
2098 static void elf_sym(const struct elf_symbol *sym)
2100 int shndx = sym->section;
2103 * Careful here. This relies on sym->section being signed; for
2104 * special section indicies this value needs to be cast to
2105 * (int16_t) so that it sign-extends, however, here SHN_LORESERVE
2106 * is used as an unsigned constant.
2108 if (shndx >= (int)SHN_LORESERVE) {
2109 if (unlikely(!symtab_shndx)) {
2110 /* Create symtab_shndx and fill previous entries with zero */
2111 symtab_shndx = saa_init(1);
2112 saa_wbytes(symtab_shndx, NULL, nsyms << 2);
2114 } else {
2115 shndx = 0; /* Section index table always write zero */
2118 if (symtab_shndx)
2119 saa_write32(symtab_shndx, shndx);
2121 efmt->elf_sym(sym);
2122 nsyms++;
2125 static void elf32_sym(const struct elf_symbol *sym)
2127 Elf32_Sym sym32;
2129 sym32.st_name = cpu_to_le32(sym->strpos);
2130 sym32.st_value = cpu_to_le32(sym->symv.key);
2131 sym32.st_size = cpu_to_le32(sym->size);
2132 sym32.st_info = sym->type;
2133 sym32.st_other = sym->other;
2134 sym32.st_shndx = elf_shndx(sym->section, SHN_XINDEX);
2135 saa_wbytes(symtab, &sym32, sizeof sym32);
2138 static void elf64_sym(const struct elf_symbol *sym)
2140 Elf64_Sym sym64;
2142 sym64.st_name = cpu_to_le32(sym->strpos);
2143 sym64.st_value = cpu_to_le64(sym->symv.key);
2144 sym64.st_size = cpu_to_le64(sym->size);
2145 sym64.st_info = sym->type;
2146 sym64.st_other = sym->other;
2147 sym64.st_shndx = elf_shndx(sym->section, SHN_XINDEX);
2148 saa_wbytes(symtab, &sym64, sizeof sym64);
2151 static size_t elf_build_symtab(void)
2153 struct elf_symbol *sym, xsym;
2154 size_t nlocal;
2155 int i;
2157 symtab = saa_init(1);
2158 symtab_shndx = NULL;
2161 * Zero symbol first as required by spec.
2163 nasm_zero(xsym);
2164 elf_sym(&xsym);
2167 * Next, an entry for the file name.
2169 nasm_zero(xsym);
2170 xsym.strpos = 1;
2171 xsym.type = ELF32_ST_INFO(STB_LOCAL, STT_FILE);
2172 xsym.section = XSHN_ABS;
2173 elf_sym(&xsym);
2176 * Now some standard symbols defining the segments, for relocation
2177 * purposes.
2179 nasm_zero(xsym);
2180 for (i = 1; i <= nsects; i++) {
2181 xsym.type = ELF64_ST_INFO(STB_LOCAL, STT_SECTION);
2182 xsym.section = i;
2183 elf_sym(&xsym);
2187 * dwarf needs symbols for debug sections
2188 * which are relocation targets.
2190 if (dfmt_is_dwarf()) {
2191 dwarf_infosym = nsyms;
2192 xsym.section = sec_debug_info;
2193 elf_sym(&xsym);
2195 dwarf_abbrevsym = nsyms;
2196 xsym.section = sec_debug_abbrev;
2197 elf_sym(&xsym);
2199 dwarf_linesym = nsyms;
2200 xsym.section = sec_debug_line;
2201 elf_sym(&xsym);
2205 * Now the other local symbols.
2207 saa_rewind(syms);
2208 while ((sym = saa_rstruct(syms))) {
2209 if (!sym_type_local(sym->type))
2210 continue;
2212 elf_sym(sym);
2215 nlocal = nsyms;
2218 * Now the global symbols.
2220 saa_rewind(syms);
2221 while ((sym = saa_rstruct(syms))) {
2222 if (sym_type_local(sym->type))
2223 continue;
2225 elf_sym(sym);
2228 return nlocal;
2231 static struct SAA *elf32_build_reltab(const struct elf_reloc *r)
2233 struct SAA *s;
2234 int32_t global_offset;
2235 Elf32_Rel rel32;
2237 if (!r)
2238 return NULL;
2240 s = saa_init(1L);
2243 * How to onvert from a global placeholder to a real symbol index;
2244 * the +2 refers to the two special entries, the null entry and
2245 * the filename entry.
2247 global_offset = -GLOBAL_TEMP_BASE + nsects + nlocals + ndebugs + 2;
2249 while (r) {
2250 int32_t sym = r->symbol;
2252 if (sym >= GLOBAL_TEMP_BASE)
2253 sym += global_offset;
2255 rel32.r_offset = cpu_to_le32(r->address);
2256 rel32.r_info = cpu_to_le32(ELF32_R_INFO(sym, r->type));
2257 saa_wbytes(s, &rel32, sizeof rel32);
2259 r = r->next;
2262 return s;
2265 static struct SAA *elfx32_build_reltab(const struct elf_reloc *r)
2267 struct SAA *s;
2268 int32_t global_offset;
2269 Elf32_Rela rela32;
2271 if (!r)
2272 return NULL;
2274 s = saa_init(1L);
2277 * How to onvert from a global placeholder to a real symbol index;
2278 * the +2 refers to the two special entries, the null entry and
2279 * the filename entry.
2281 global_offset = -GLOBAL_TEMP_BASE + nsects + nlocals + ndebugs + 2;
2283 while (r) {
2284 int32_t sym = r->symbol;
2286 if (sym >= GLOBAL_TEMP_BASE)
2287 sym += global_offset;
2289 rela32.r_offset = cpu_to_le32(r->address);
2290 rela32.r_info = cpu_to_le32(ELF32_R_INFO(sym, r->type));
2291 rela32.r_addend = cpu_to_le32(r->offset);
2292 saa_wbytes(s, &rela32, sizeof rela32);
2294 r = r->next;
2297 return s;
2300 static struct SAA *elf64_build_reltab(const struct elf_reloc *r)
2302 struct SAA *s;
2303 int32_t global_offset;
2304 Elf64_Rela rela64;
2306 if (!r)
2307 return NULL;
2309 s = saa_init(1L);
2312 * How to onvert from a global placeholder to a real symbol index;
2313 * the +2 refers to the two special entries, the null entry and
2314 * the filename entry.
2316 global_offset = -GLOBAL_TEMP_BASE + nsects + nlocals + ndebugs + 2;
2318 while (r) {
2319 int32_t sym = r->symbol;
2321 if (sym >= GLOBAL_TEMP_BASE)
2322 sym += global_offset;
2324 rela64.r_offset = cpu_to_le64(r->address);
2325 rela64.r_info = cpu_to_le64(ELF64_R_INFO(sym, r->type));
2326 rela64.r_addend = cpu_to_le64(r->offset);
2327 saa_wbytes(s, &rela64, sizeof rela64);
2329 r = r->next;
2332 return s;
2335 static void elf_section_header(int name, int type, uint64_t flags,
2336 void *data, bool is_saa, uint64_t datalen,
2337 int link, int info,
2338 uint64_t align, uint64_t entsize)
2340 elf_sects[elf_nsect].data = data;
2341 elf_sects[elf_nsect].len = datalen;
2342 elf_sects[elf_nsect].is_saa = is_saa;
2343 elf_nsect++;
2345 if (!efmt->elf64) {
2346 Elf32_Shdr shdr;
2348 shdr.sh_name = cpu_to_le32(name);
2349 shdr.sh_type = cpu_to_le32(type);
2350 shdr.sh_flags = cpu_to_le32(flags);
2351 shdr.sh_addr = 0;
2352 shdr.sh_offset = cpu_to_le32(type == SHT_NULL ? 0 : elf_foffs);
2353 shdr.sh_size = cpu_to_le32(datalen);
2354 if (data)
2355 elf_foffs += ALIGN(datalen, SEC_FILEALIGN);
2356 shdr.sh_link = cpu_to_le32(link);
2357 shdr.sh_info = cpu_to_le32(info);
2358 shdr.sh_addralign = cpu_to_le32(align);
2359 shdr.sh_entsize = cpu_to_le32(entsize);
2361 nasm_write(&shdr, sizeof shdr, ofile);
2362 } else {
2363 Elf64_Shdr shdr;
2365 shdr.sh_name = cpu_to_le32(name);
2366 shdr.sh_type = cpu_to_le32(type);
2367 shdr.sh_flags = cpu_to_le64(flags);
2368 shdr.sh_addr = 0;
2369 shdr.sh_offset = cpu_to_le64(type == SHT_NULL ? 0 : elf_foffs);
2370 shdr.sh_size = cpu_to_le64(datalen);
2371 if (data)
2372 elf_foffs += ALIGN(datalen, SEC_FILEALIGN);
2373 shdr.sh_link = cpu_to_le32(link);
2374 shdr.sh_info = cpu_to_le32(info);
2375 shdr.sh_addralign = cpu_to_le64(align);
2376 shdr.sh_entsize = cpu_to_le64(entsize);
2378 nasm_write(&shdr, sizeof shdr, ofile);
2382 static void elf_write_sections(void)
2384 int i;
2385 for (i = 0; i < elf_nsect; i++)
2386 if (elf_sects[i].data) {
2387 int32_t len = elf_sects[i].len;
2388 int32_t reallen = ALIGN(len, SEC_FILEALIGN);
2389 int32_t align = reallen - len;
2390 if (elf_sects[i].is_saa)
2391 saa_fpwrite(elf_sects[i].data, ofile);
2392 else
2393 nasm_write(elf_sects[i].data, len, ofile);
2394 fwritezero(align, ofile);
2398 static void elf_sect_write(struct elf_section *sect, const void *data, size_t len)
2400 saa_wbytes(sect->data, data, len);
2401 sect->len += len;
2404 static void elf_sect_writeaddr(struct elf_section *sect, int64_t data, size_t len)
2406 saa_writeaddr(sect->data, data, len);
2407 sect->len += len;
2410 static void elf_sectalign(int32_t seg, unsigned int value)
2412 struct elf_section *s;
2414 s = raa_read_ptr(section_by_index, seg >> 1);
2415 if (!s || !is_power2(value))
2416 return;
2418 if (value > s->align)
2419 s->align = value;
2422 extern macros_t elf_stdmac[];
2424 /* Claim "elf" as a pragma namespace, for the future */
2425 static const struct pragma_facility elf_pragma_list[] =
2427 { "elf", NULL },
2428 { NULL, NULL } /* Implements the canonical output name */
2432 static const struct dfmt elf32_df_dwarf = {
2433 "ELF32 (i386) dwarf (newer)",
2434 "dwarf",
2435 dwarf32_init,
2436 dwarf_linenum,
2437 null_debug_deflabel,
2438 null_debug_directive,
2439 debug_typevalue,
2440 dwarf_output,
2441 dwarf_cleanup,
2442 NULL /* pragma list */
2445 static const struct dfmt elf32_df_stabs = {
2446 "ELF32 (i386) stabs (older)",
2447 "stabs",
2448 null_debug_init,
2449 stabs_linenum,
2450 null_debug_deflabel,
2451 null_debug_directive,
2452 debug_typevalue,
2453 stabs_output,
2454 stabs_cleanup,
2455 NULL /* pragma list */
2458 static const struct dfmt * const elf32_debugs_arr[3] =
2459 { &elf32_df_dwarf, &elf32_df_stabs, NULL };
2461 const struct ofmt of_elf32 = {
2462 "ELF32 (i386) (Linux, most Unix variants)",
2463 "elf32",
2464 ".o",
2467 elf32_debugs_arr,
2468 &elf32_df_dwarf,
2469 elf_stdmac,
2470 elf32_init,
2471 null_reset,
2472 nasm_do_legacy_output,
2473 elf32_out,
2474 elf_deflabel,
2475 elf_section_names,
2476 NULL,
2477 elf_sectalign,
2478 null_segbase,
2479 elf_directive,
2480 elf_cleanup,
2481 elf_pragma_list,
2484 static const struct dfmt elf64_df_dwarf = {
2485 "ELF64 (x86-64) dwarf (newer)",
2486 "dwarf",
2487 dwarf64_init,
2488 dwarf_linenum,
2489 null_debug_deflabel,
2490 null_debug_directive,
2491 debug_typevalue,
2492 dwarf_output,
2493 dwarf_cleanup,
2494 NULL /* pragma list */
2497 static const struct dfmt elf64_df_stabs = {
2498 "ELF64 (x86-64) stabs (older)",
2499 "stabs",
2500 null_debug_init,
2501 stabs_linenum,
2502 null_debug_deflabel,
2503 null_debug_directive,
2504 debug_typevalue,
2505 stabs_output,
2506 stabs_cleanup,
2507 NULL /* pragma list */
2510 static const struct dfmt * const elf64_debugs_arr[3] =
2511 { &elf64_df_dwarf, &elf64_df_stabs, NULL };
2513 const struct ofmt of_elf64 = {
2514 "ELF64 (x86-64) (Linux, most Unix variants)",
2515 "elf64",
2516 ".o",
2519 elf64_debugs_arr,
2520 &elf64_df_dwarf,
2521 elf_stdmac,
2522 elf64_init,
2523 null_reset,
2524 nasm_do_legacy_output,
2525 elf64_out,
2526 elf_deflabel,
2527 elf_section_names,
2528 NULL,
2529 elf_sectalign,
2530 null_segbase,
2531 elf_directive,
2532 elf_cleanup,
2533 elf_pragma_list,
2536 static const struct dfmt elfx32_df_dwarf = {
2537 "ELFx32 (x86-64) dwarf (newer)",
2538 "dwarf",
2539 dwarfx32_init,
2540 dwarf_linenum,
2541 null_debug_deflabel,
2542 null_debug_directive,
2543 debug_typevalue,
2544 dwarf_output,
2545 dwarf_cleanup,
2546 NULL /* pragma list */
2549 static const struct dfmt elfx32_df_stabs = {
2550 "ELFx32 (x86-64) stabs (older)",
2551 "stabs",
2552 null_debug_init,
2553 stabs_linenum,
2554 null_debug_deflabel,
2555 null_debug_directive,
2556 debug_typevalue,
2557 stabs_output,
2558 stabs_cleanup,
2559 elf_pragma_list,
2562 static const struct dfmt * const elfx32_debugs_arr[3] =
2563 { &elfx32_df_dwarf, &elfx32_df_stabs, NULL };
2565 const struct ofmt of_elfx32 = {
2566 "ELFx32 (ELF32 for x86-64) (Linux)",
2567 "elfx32",
2568 ".o",
2571 elfx32_debugs_arr,
2572 &elfx32_df_dwarf,
2573 elf_stdmac,
2574 elfx32_init,
2575 null_reset,
2576 nasm_do_legacy_output,
2577 elfx32_out,
2578 elf_deflabel,
2579 elf_section_names,
2580 NULL,
2581 elf_sectalign,
2582 null_segbase,
2583 elf_directive,
2584 elf_cleanup,
2585 NULL /* pragma list */
2588 static bool is_elf64(void)
2590 return ofmt == &of_elf64;
2593 static bool is_elf32(void)
2595 return ofmt == &of_elf32;
2598 static bool is_elfx32(void)
2600 return ofmt == &of_elfx32;
2603 static bool dfmt_is_stabs(void)
2605 return dfmt == &elf32_df_stabs ||
2606 dfmt == &elfx32_df_stabs ||
2607 dfmt == &elf64_df_stabs;
2610 static bool dfmt_is_dwarf(void)
2612 return dfmt == &elf32_df_dwarf ||
2613 dfmt == &elfx32_df_dwarf ||
2614 dfmt == &elf64_df_dwarf;
2617 /* common debugging routines */
2618 static void debug_typevalue(int32_t type)
2620 int32_t stype, ssize;
2621 switch (TYM_TYPE(type)) {
2622 case TY_LABEL:
2623 ssize = 0;
2624 stype = STT_NOTYPE;
2625 break;
2626 case TY_BYTE:
2627 ssize = 1;
2628 stype = STT_OBJECT;
2629 break;
2630 case TY_WORD:
2631 ssize = 2;
2632 stype = STT_OBJECT;
2633 break;
2634 case TY_DWORD:
2635 ssize = 4;
2636 stype = STT_OBJECT;
2637 break;
2638 case TY_FLOAT:
2639 ssize = 4;
2640 stype = STT_OBJECT;
2641 break;
2642 case TY_QWORD:
2643 ssize = 8;
2644 stype = STT_OBJECT;
2645 break;
2646 case TY_TBYTE:
2647 ssize = 10;
2648 stype = STT_OBJECT;
2649 break;
2650 case TY_OWORD:
2651 ssize = 16;
2652 stype = STT_OBJECT;
2653 break;
2654 case TY_YWORD:
2655 ssize = 32;
2656 stype = STT_OBJECT;
2657 break;
2658 case TY_ZWORD:
2659 ssize = 64;
2660 stype = STT_OBJECT;
2661 break;
2662 case TY_COMMON:
2663 ssize = 0;
2664 stype = STT_COMMON;
2665 break;
2666 case TY_SEG:
2667 ssize = 0;
2668 stype = STT_SECTION;
2669 break;
2670 case TY_EXTERN:
2671 ssize = 0;
2672 stype = STT_NOTYPE;
2673 break;
2674 case TY_EQU:
2675 ssize = 0;
2676 stype = STT_NOTYPE;
2677 break;
2678 default:
2679 ssize = 0;
2680 stype = STT_NOTYPE;
2681 break;
2683 if (stype == STT_OBJECT && lastsym && !lastsym->type) {
2684 lastsym->size = ssize;
2685 lastsym->type = stype;
2689 /* stabs debugging routines */
2691 static void stabs_linenum(const char *filename, int32_t linenumber, int32_t segto)
2693 (void)segto;
2694 if (!stabs_filename) {
2695 stabs_filename = nasm_malloc(strlen(filename) + 1);
2696 strcpy(stabs_filename, filename);
2697 } else {
2698 if (strcmp(stabs_filename, filename)) {
2699 /* yep, a memory leak...this program is one-shot anyway, so who cares...
2700 in fact, this leak comes in quite handy to maintain a list of files
2701 encountered so far in the symbol lines... */
2703 /* why not nasm_free(stabs_filename); we're done with the old one */
2705 stabs_filename = nasm_malloc(strlen(filename) + 1);
2706 strcpy(stabs_filename, filename);
2709 debug_immcall = 1;
2710 currentline = linenumber;
2713 static void stabs_output(int type, void *param)
2715 struct symlininfo *s;
2716 struct linelist *el;
2717 if (type == TY_DEBUGSYMLIN) {
2718 if (debug_immcall) {
2719 s = (struct symlininfo *)param;
2720 if (!(sects[s->section]->flags & SHF_EXECINSTR))
2721 return; /* line info is only collected for executable sections */
2722 numlinestabs++;
2723 el = nasm_malloc(sizeof(struct linelist));
2724 el->info.offset = s->offset;
2725 el->info.section = s->section;
2726 el->info.name = s->name;
2727 el->line = currentline;
2728 el->filename = stabs_filename;
2729 el->next = 0;
2730 if (stabslines) {
2731 stabslines->last->next = el;
2732 stabslines->last = el;
2733 } else {
2734 stabslines = el;
2735 stabslines->last = el;
2739 debug_immcall = 0;
2742 /* for creating the .stab , .stabstr and .rel.stab sections in memory */
2744 static void stabs_generate(void)
2746 int i, numfiles, strsize, numstabs = 0, currfile, mainfileindex;
2747 uint8_t *sbuf, *ssbuf, *rbuf, *sptr, *rptr;
2748 char **allfiles;
2749 int *fileidx;
2751 struct linelist *ptr;
2753 ptr = stabslines;
2755 allfiles = nasm_zalloc(numlinestabs * sizeof(char *));
2756 numfiles = 0;
2757 while (ptr) {
2758 if (numfiles == 0) {
2759 allfiles[0] = ptr->filename;
2760 numfiles++;
2761 } else {
2762 for (i = 0; i < numfiles; i++) {
2763 if (!strcmp(allfiles[i], ptr->filename))
2764 break;
2766 if (i >= numfiles) {
2767 allfiles[i] = ptr->filename;
2768 numfiles++;
2771 ptr = ptr->next;
2773 strsize = 1;
2774 fileidx = nasm_malloc(numfiles * sizeof(int));
2775 for (i = 0; i < numfiles; i++) {
2776 fileidx[i] = strsize;
2777 strsize += strlen(allfiles[i]) + 1;
2779 currfile = mainfileindex = 0;
2780 for (i = 0; i < numfiles; i++) {
2781 if (!strcmp(allfiles[i], elf_module)) {
2782 currfile = mainfileindex = i;
2783 break;
2788 * worst case size of the stab buffer would be:
2789 * the sourcefiles changes each line, which would mean 1 SOL, 1 SYMLIN per line
2790 * plus one "ending" entry
2792 sbuf = nasm_malloc((numlinestabs * 2 + 4) *
2793 sizeof(struct stabentry));
2794 ssbuf = nasm_malloc(strsize);
2795 rbuf = nasm_malloc(numlinestabs * (is_elf64() ? 16 : 8) * (2 + 3));
2796 rptr = rbuf;
2798 for (i = 0; i < numfiles; i++)
2799 strcpy((char *)ssbuf + fileidx[i], allfiles[i]);
2800 ssbuf[0] = 0;
2802 stabstrlen = strsize; /* set global variable for length of stab strings */
2804 sptr = sbuf;
2805 ptr = stabslines;
2806 numstabs = 0;
2808 if (ptr) {
2810 * this is the first stab, its strx points to the filename of the
2811 * the source-file, the n_desc field should be set to the number
2812 * of remaining stabs
2814 WRITE_STAB(sptr, fileidx[0], 0, 0, 0, stabstrlen);
2816 /* this is the stab for the main source file */
2817 WRITE_STAB(sptr, fileidx[mainfileindex], N_SO, 0, 0, 0);
2819 /* relocation table entry */
2822 * Since the symbol table has two entries before
2823 * the section symbols, the index in the info.section
2824 * member must be adjusted by adding 2
2827 if (is_elf32()) {
2828 WRITELONG(rptr, (sptr - sbuf) - 4);
2829 WRITELONG(rptr, ((ptr->info.section + 2) << 8) | R_386_32);
2830 } else if (is_elfx32()) {
2831 WRITELONG(rptr, (sptr - sbuf) - 4);
2832 WRITELONG(rptr, ((ptr->info.section + 2) << 8) | R_X86_64_32);
2833 WRITELONG(rptr, 0);
2834 } else {
2835 nasm_assert(is_elf64());
2836 WRITEDLONG(rptr, (int64_t)(sptr - sbuf) - 4);
2837 WRITELONG(rptr, R_X86_64_32);
2838 WRITELONG(rptr, ptr->info.section + 2);
2839 WRITEDLONG(rptr, 0);
2841 numstabs++;
2844 if (is_elf32()) {
2845 while (ptr) {
2846 if (strcmp(allfiles[currfile], ptr->filename)) {
2847 /* oops file has changed... */
2848 for (i = 0; i < numfiles; i++)
2849 if (!strcmp(allfiles[i], ptr->filename))
2850 break;
2851 currfile = i;
2852 WRITE_STAB(sptr, fileidx[currfile], N_SOL, 0, 0,
2853 ptr->info.offset);
2854 numstabs++;
2856 /* relocation table entry */
2857 WRITELONG(rptr, (sptr - sbuf) - 4);
2858 WRITELONG(rptr, ((ptr->info.section + 2) << 8) | R_386_32);
2861 WRITE_STAB(sptr, 0, N_SLINE, 0, ptr->line, ptr->info.offset);
2862 numstabs++;
2864 /* relocation table entry */
2865 WRITELONG(rptr, (sptr - sbuf) - 4);
2866 WRITELONG(rptr, ((ptr->info.section + 2) << 8) | R_386_32);
2868 ptr = ptr->next;
2870 } else if (is_elfx32()) {
2871 while (ptr) {
2872 if (strcmp(allfiles[currfile], ptr->filename)) {
2873 /* oops file has changed... */
2874 for (i = 0; i < numfiles; i++)
2875 if (!strcmp(allfiles[i], ptr->filename))
2876 break;
2877 currfile = i;
2878 WRITE_STAB(sptr, fileidx[currfile], N_SOL, 0, 0,
2879 ptr->info.offset);
2880 numstabs++;
2882 /* relocation table entry */
2883 WRITELONG(rptr, (sptr - sbuf) - 4);
2884 WRITELONG(rptr, ((ptr->info.section + 2) << 8) | R_X86_64_32);
2885 WRITELONG(rptr, ptr->info.offset);
2888 WRITE_STAB(sptr, 0, N_SLINE, 0, ptr->line, ptr->info.offset);
2889 numstabs++;
2891 /* relocation table entry */
2892 WRITELONG(rptr, (sptr - sbuf) - 4);
2893 WRITELONG(rptr, ((ptr->info.section + 2) << 8) | R_X86_64_32);
2894 WRITELONG(rptr, ptr->info.offset);
2896 ptr = ptr->next;
2898 } else {
2899 nasm_assert(is_elf64());
2900 while (ptr) {
2901 if (strcmp(allfiles[currfile], ptr->filename)) {
2902 /* oops file has changed... */
2903 for (i = 0; i < numfiles; i++)
2904 if (!strcmp(allfiles[i], ptr->filename))
2905 break;
2906 currfile = i;
2907 WRITE_STAB(sptr, fileidx[currfile], N_SOL, 0, 0,
2908 ptr->info.offset);
2909 numstabs++;
2911 /* relocation table entry */
2912 WRITEDLONG(rptr, (int64_t)(sptr - sbuf) - 4);
2913 WRITELONG(rptr, R_X86_64_32);
2914 WRITELONG(rptr, ptr->info.section + 2);
2915 WRITEDLONG(rptr, ptr->info.offset);
2918 WRITE_STAB(sptr, 0, N_SLINE, 0, ptr->line, ptr->info.offset);
2919 numstabs++;
2921 /* relocation table entry */
2922 WRITEDLONG(rptr, (int64_t)(sptr - sbuf) - 4);
2923 WRITELONG(rptr, R_X86_64_32);
2924 WRITELONG(rptr, ptr->info.section + 2);
2925 WRITEDLONG(rptr, ptr->info.offset);
2927 ptr = ptr->next;
2931 /* this is an "ending" token */
2932 WRITE_STAB(sptr, 0, N_SO, 0, 0, 0);
2933 numstabs++;
2935 ((struct stabentry *)sbuf)->n_desc = numstabs;
2937 nasm_free(allfiles);
2938 nasm_free(fileidx);
2940 stablen = (sptr - sbuf);
2941 stabrellen = (rptr - rbuf);
2942 stabrelbuf = rbuf;
2943 stabbuf = sbuf;
2944 stabstrbuf = ssbuf;
2947 static void stabs_cleanup(void)
2949 struct linelist *ptr, *del;
2950 if (!stabslines)
2951 return;
2953 ptr = stabslines;
2954 while (ptr) {
2955 del = ptr;
2956 ptr = ptr->next;
2957 nasm_free(del);
2960 nasm_free(stabbuf);
2961 nasm_free(stabrelbuf);
2962 nasm_free(stabstrbuf);
2965 /* dwarf routines */
2967 static void dwarf_init_common(const struct dwarf_format *fmt)
2969 dwfmt = fmt;
2970 ndebugs = 3; /* 3 debug symbols */
2973 static void dwarf32_init(void)
2975 static const struct dwarf_format dwfmt32 = {
2976 2, /* DWARF 2 */
2977 /* section version numbers: */
2978 { 2, /* .debug_aranges */
2979 0, /* .rela.debug_aranges */
2980 2, /* .debug_pubnames */
2981 2, /* .debug_info */
2982 0, /* .rela.debug_info */
2983 0, /* .debug_abbrev */
2984 2, /* .debug_line */
2985 0, /* .rela.debug_line */
2986 1, /* .debug_frame */
2987 0 } /* .debug_loc */
2989 dwarf_init_common(&dwfmt32);
2992 static void dwarfx32_init(void)
2994 static const struct dwarf_format dwfmtx32 = {
2995 3, /* DWARF 3 */
2996 /* section version numbers: */
2997 { 2, /* .debug_aranges */
2998 0, /* .rela.debug_aranges */
2999 2, /* .debug_pubnames */
3000 3, /* .debug_info */
3001 0, /* .rela.debug_info */
3002 0, /* .debug_abbrev */
3003 3, /* .debug_line */
3004 0, /* .rela.debug_line */
3005 3, /* .debug_frame */
3006 0 } /* .debug_loc */
3008 dwarf_init_common(&dwfmtx32);
3011 static void dwarf64_init(void)
3013 static const struct dwarf_format dwfmt64 = {
3014 3, /* DWARF 3 */
3015 /* section version numbers: */
3016 { 2, /* .debug_aranges */
3017 0, /* .rela.debug_aranges */
3018 2, /* .debug_pubnames */
3019 3, /* .debug_info */
3020 0, /* .rela.debug_info */
3021 0, /* .debug_abbrev */
3022 3, /* .debug_line */
3023 0, /* .rela.debug_line */
3024 3, /* .debug_frame */
3025 0 } /* .debug_loc */
3027 dwarf_init_common(&dwfmt64);
3030 static void dwarf_linenum(const char *filename, int32_t linenumber,
3031 int32_t segto)
3033 (void)segto;
3034 dwarf_findfile(filename);
3035 debug_immcall = 1;
3036 currentline = linenumber;
3039 /* called from elf_out with type == TY_DEBUGSYMLIN */
3040 static void dwarf_output(int type, void *param)
3042 int ln, aa, inx, maxln, soc;
3043 struct symlininfo *s;
3044 struct SAA *plinep;
3046 (void)type;
3048 s = (struct symlininfo *)param;
3050 /* line number info is only gathered for executable sections */
3051 if (!(sects[s->section]->flags & SHF_EXECINSTR))
3052 return;
3054 /* Check if section index has changed */
3055 if (!(dwarf_csect && (dwarf_csect->section) == (s->section)))
3056 dwarf_findsect(s->section);
3058 /* do nothing unless line or file has changed */
3059 if (!debug_immcall)
3060 return;
3062 ln = currentline - dwarf_csect->line;
3063 aa = s->offset - dwarf_csect->offset;
3064 inx = dwarf_clist->line;
3065 plinep = dwarf_csect->psaa;
3066 /* check for file change */
3067 if (!(inx == dwarf_csect->file)) {
3068 saa_write8(plinep,DW_LNS_set_file);
3069 saa_write8(plinep,inx);
3070 dwarf_csect->file = inx;
3072 /* check for line change */
3073 if (ln) {
3074 /* test if in range of special op code */
3075 maxln = line_base + line_range;
3076 soc = (ln - line_base) + (line_range * aa) + opcode_base;
3077 if (ln >= line_base && ln < maxln && soc < 256) {
3078 saa_write8(plinep,soc);
3079 } else {
3080 saa_write8(plinep,DW_LNS_advance_line);
3081 saa_wleb128s(plinep,ln);
3082 if (aa) {
3083 saa_write8(plinep,DW_LNS_advance_pc);
3084 saa_wleb128u(plinep,aa);
3086 saa_write8(plinep,DW_LNS_copy);
3088 dwarf_csect->line = currentline;
3089 dwarf_csect->offset = s->offset;
3092 /* show change handled */
3093 debug_immcall = 0;
3097 static void dwarf_generate(void)
3099 uint8_t *pbuf;
3100 int indx;
3101 struct linelist *ftentry;
3102 struct SAA *paranges, *ppubnames, *pinfo, *pabbrev, *plines, *plinep;
3103 struct SAA *parangesrel, *plinesrel, *pinforel;
3104 struct sectlist *psect;
3105 size_t saalen, linepoff, totlen, highaddr;
3107 if (is_elf32()) {
3108 /* write epilogues for each line program range */
3109 /* and build aranges section */
3110 paranges = saa_init(1L);
3111 parangesrel = saa_init(1L);
3112 saa_write16(paranges, dwfmt->sect_version[DWARF_ARANGES]);
3113 saa_write32(parangesrel, paranges->datalen+4);
3114 saa_write32(parangesrel, (dwarf_infosym << 8) + R_386_32); /* reloc to info */
3115 saa_write32(parangesrel, 0);
3116 saa_write32(paranges,0); /* offset into info */
3117 saa_write8(paranges,4); /* pointer size */
3118 saa_write8(paranges,0); /* not segmented */
3119 saa_write32(paranges,0); /* padding */
3120 /* iterate though sectlist entries */
3121 psect = dwarf_fsect;
3122 totlen = 0;
3123 highaddr = 0;
3124 for (indx = 0; indx < dwarf_nsections; indx++) {
3125 plinep = psect->psaa;
3126 /* Line Number Program Epilogue */
3127 saa_write8(plinep,2); /* std op 2 */
3128 saa_write8(plinep,(sects[psect->section]->len)-psect->offset);
3129 saa_write8(plinep,DW_LNS_extended_op);
3130 saa_write8(plinep,1); /* operand length */
3131 saa_write8(plinep,DW_LNE_end_sequence);
3132 totlen += plinep->datalen;
3133 /* range table relocation entry */
3134 saa_write32(parangesrel, paranges->datalen + 4);
3135 saa_write32(parangesrel, ((uint32_t) (psect->section + 2) << 8) + R_386_32);
3136 saa_write32(parangesrel, (uint32_t) 0);
3137 /* range table entry */
3138 saa_write32(paranges,0x0000); /* range start */
3139 saa_write32(paranges,sects[psect->section]->len); /* range length */
3140 highaddr += sects[psect->section]->len;
3141 /* done with this entry */
3142 psect = psect->next;
3144 saa_write32(paranges,0); /* null address */
3145 saa_write32(paranges,0); /* null length */
3146 saalen = paranges->datalen;
3147 arangeslen = saalen + 4;
3148 arangesbuf = pbuf = nasm_malloc(arangeslen);
3149 WRITELONG(pbuf,saalen); /* initial length */
3150 saa_rnbytes(paranges, pbuf, saalen);
3151 saa_free(paranges);
3152 } else if (is_elfx32()) {
3153 /* write epilogues for each line program range */
3154 /* and build aranges section */
3155 paranges = saa_init(1L);
3156 parangesrel = saa_init(1L);
3157 saa_write16(paranges, dwfmt->sect_version[DWARF_ARANGES]);
3158 saa_write32(parangesrel, paranges->datalen+4);
3159 saa_write32(parangesrel, (dwarf_infosym << 8) + R_X86_64_32); /* reloc to info */
3160 saa_write32(parangesrel, 0);
3161 saa_write32(paranges,0); /* offset into info */
3162 saa_write8(paranges,4); /* pointer size */
3163 saa_write8(paranges,0); /* not segmented */
3164 saa_write32(paranges,0); /* padding */
3165 /* iterate though sectlist entries */
3166 psect = dwarf_fsect;
3167 totlen = 0;
3168 highaddr = 0;
3169 for (indx = 0; indx < dwarf_nsections; indx++) {
3170 plinep = psect->psaa;
3171 /* Line Number Program Epilogue */
3172 saa_write8(plinep,2); /* std op 2 */
3173 saa_write8(plinep,(sects[psect->section]->len)-psect->offset);
3174 saa_write8(plinep,DW_LNS_extended_op);
3175 saa_write8(plinep,1); /* operand length */
3176 saa_write8(plinep,DW_LNE_end_sequence);
3177 totlen += plinep->datalen;
3178 /* range table relocation entry */
3179 saa_write32(parangesrel, paranges->datalen + 4);
3180 saa_write32(parangesrel, ((uint32_t) (psect->section + 2) << 8) + R_X86_64_32);
3181 saa_write32(parangesrel, (uint32_t) 0);
3182 /* range table entry */
3183 saa_write32(paranges,0x0000); /* range start */
3184 saa_write32(paranges,sects[psect->section]->len); /* range length */
3185 highaddr += sects[psect->section]->len;
3186 /* done with this entry */
3187 psect = psect->next;
3189 saa_write32(paranges,0); /* null address */
3190 saa_write32(paranges,0); /* null length */
3191 saalen = paranges->datalen;
3192 arangeslen = saalen + 4;
3193 arangesbuf = pbuf = nasm_malloc(arangeslen);
3194 WRITELONG(pbuf,saalen); /* initial length */
3195 saa_rnbytes(paranges, pbuf, saalen);
3196 saa_free(paranges);
3197 } else {
3198 nasm_assert(is_elf64());
3199 /* write epilogues for each line program range */
3200 /* and build aranges section */
3201 paranges = saa_init(1L);
3202 parangesrel = saa_init(1L);
3203 saa_write16(paranges, dwfmt->sect_version[DWARF_ARANGES]);
3204 saa_write64(parangesrel, paranges->datalen+4);
3205 saa_write64(parangesrel, (dwarf_infosym << 32) + R_X86_64_32); /* reloc to info */
3206 saa_write64(parangesrel, 0);
3207 saa_write32(paranges,0); /* offset into info */
3208 saa_write8(paranges,8); /* pointer size */
3209 saa_write8(paranges,0); /* not segmented */
3210 saa_write32(paranges,0); /* padding */
3211 /* iterate though sectlist entries */
3212 psect = dwarf_fsect;
3213 totlen = 0;
3214 highaddr = 0;
3215 for (indx = 0; indx < dwarf_nsections; indx++) {
3216 plinep = psect->psaa;
3217 /* Line Number Program Epilogue */
3218 saa_write8(plinep,2); /* std op 2 */
3219 saa_write8(plinep,(sects[psect->section]->len)-psect->offset);
3220 saa_write8(plinep,DW_LNS_extended_op);
3221 saa_write8(plinep,1); /* operand length */
3222 saa_write8(plinep,DW_LNE_end_sequence);
3223 totlen += plinep->datalen;
3224 /* range table relocation entry */
3225 saa_write64(parangesrel, paranges->datalen + 4);
3226 saa_write64(parangesrel, ((uint64_t) (psect->section + 2) << 32) + R_X86_64_64);
3227 saa_write64(parangesrel, (uint64_t) 0);
3228 /* range table entry */
3229 saa_write64(paranges,0x0000); /* range start */
3230 saa_write64(paranges,sects[psect->section]->len); /* range length */
3231 highaddr += sects[psect->section]->len;
3232 /* done with this entry */
3233 psect = psect->next;
3235 saa_write64(paranges,0); /* null address */
3236 saa_write64(paranges,0); /* null length */
3237 saalen = paranges->datalen;
3238 arangeslen = saalen + 4;
3239 arangesbuf = pbuf = nasm_malloc(arangeslen);
3240 WRITELONG(pbuf,saalen); /* initial length */
3241 saa_rnbytes(paranges, pbuf, saalen);
3242 saa_free(paranges);
3245 /* build rela.aranges section */
3246 arangesrellen = saalen = parangesrel->datalen;
3247 arangesrelbuf = pbuf = nasm_malloc(arangesrellen);
3248 saa_rnbytes(parangesrel, pbuf, saalen);
3249 saa_free(parangesrel);
3251 /* build pubnames section */
3252 if (0) {
3253 ppubnames = saa_init(1L);
3254 saa_write16(ppubnames,dwfmt->sect_version[DWARF_PUBNAMES]);
3255 saa_write32(ppubnames,0); /* offset into info */
3256 saa_write32(ppubnames,0); /* space used in info */
3257 saa_write32(ppubnames,0); /* end of list */
3258 saalen = ppubnames->datalen;
3259 pubnameslen = saalen + 4;
3260 pubnamesbuf = pbuf = nasm_malloc(pubnameslen);
3261 WRITELONG(pbuf,saalen); /* initial length */
3262 saa_rnbytes(ppubnames, pbuf, saalen);
3263 saa_free(ppubnames);
3264 } else {
3265 /* Don't write a section without actual information */
3266 pubnameslen = 0;
3269 if (is_elf32()) {
3270 /* build info section */
3271 pinfo = saa_init(1L);
3272 pinforel = saa_init(1L);
3273 saa_write16(pinfo, dwfmt->sect_version[DWARF_INFO]);
3274 saa_write32(pinforel, pinfo->datalen + 4);
3275 saa_write32(pinforel, (dwarf_abbrevsym << 8) + R_386_32); /* reloc to abbrev */
3276 saa_write32(pinforel, 0);
3277 saa_write32(pinfo,0); /* offset into abbrev */
3278 saa_write8(pinfo,4); /* pointer size */
3279 saa_write8(pinfo,1); /* abbrviation number LEB128u */
3280 saa_write32(pinforel, pinfo->datalen + 4);
3281 saa_write32(pinforel, ((dwarf_fsect->section + 2) << 8) + R_386_32);
3282 saa_write32(pinforel, 0);
3283 saa_write32(pinfo,0); /* DW_AT_low_pc */
3284 saa_write32(pinforel, pinfo->datalen + 4);
3285 saa_write32(pinforel, ((dwarf_fsect->section + 2) << 8) + R_386_32);
3286 saa_write32(pinforel, 0);
3287 saa_write32(pinfo,highaddr); /* DW_AT_high_pc */
3288 saa_write32(pinforel, pinfo->datalen + 4);
3289 saa_write32(pinforel, (dwarf_linesym << 8) + R_386_32); /* reloc to line */
3290 saa_write32(pinforel, 0);
3291 saa_write32(pinfo,0); /* DW_AT_stmt_list */
3292 saa_wbytes(pinfo, elf_module, strlen(elf_module)+1);
3293 saa_wbytes(pinfo, nasm_signature(), nasm_signature_len()+1);
3294 saa_write16(pinfo,DW_LANG_Mips_Assembler);
3295 saa_write8(pinfo,2); /* abbrviation number LEB128u */
3296 saa_write32(pinforel, pinfo->datalen + 4);
3297 saa_write32(pinforel, ((dwarf_fsect->section + 2) << 8) + R_386_32);
3298 saa_write32(pinforel, 0);
3299 saa_write32(pinfo,0); /* DW_AT_low_pc */
3300 saa_write32(pinfo,0); /* DW_AT_frame_base */
3301 saa_write8(pinfo,0); /* end of entries */
3302 saalen = pinfo->datalen;
3303 infolen = saalen + 4;
3304 infobuf = pbuf = nasm_malloc(infolen);
3305 WRITELONG(pbuf,saalen); /* initial length */
3306 saa_rnbytes(pinfo, pbuf, saalen);
3307 saa_free(pinfo);
3308 } else if (is_elfx32()) {
3309 /* build info section */
3310 pinfo = saa_init(1L);
3311 pinforel = saa_init(1L);
3312 saa_write16(pinfo, dwfmt->sect_version[DWARF_INFO]);
3313 saa_write32(pinforel, pinfo->datalen + 4);
3314 saa_write32(pinforel, (dwarf_abbrevsym << 8) + R_X86_64_32); /* reloc to abbrev */
3315 saa_write32(pinforel, 0);
3316 saa_write32(pinfo,0); /* offset into abbrev */
3317 saa_write8(pinfo,4); /* pointer size */
3318 saa_write8(pinfo,1); /* abbrviation number LEB128u */
3319 saa_write32(pinforel, pinfo->datalen + 4);
3320 saa_write32(pinforel, ((dwarf_fsect->section + 2) << 8) + R_X86_64_32);
3321 saa_write32(pinforel, 0);
3322 saa_write32(pinfo,0); /* DW_AT_low_pc */
3323 saa_write32(pinforel, pinfo->datalen + 4);
3324 saa_write32(pinforel, ((dwarf_fsect->section + 2) << 8) + R_X86_64_32);
3325 saa_write32(pinforel, 0);
3326 saa_write32(pinfo,highaddr); /* DW_AT_high_pc */
3327 saa_write32(pinforel, pinfo->datalen + 4);
3328 saa_write32(pinforel, (dwarf_linesym << 8) + R_X86_64_32); /* reloc to line */
3329 saa_write32(pinforel, 0);
3330 saa_write32(pinfo,0); /* DW_AT_stmt_list */
3331 saa_wbytes(pinfo, elf_module, strlen(elf_module)+1);
3332 saa_wbytes(pinfo, nasm_signature(), nasm_signature_len()+1);
3333 saa_write16(pinfo,DW_LANG_Mips_Assembler);
3334 saa_write8(pinfo,2); /* abbrviation number LEB128u */
3335 saa_write32(pinforel, pinfo->datalen + 4);
3336 saa_write32(pinforel, ((dwarf_fsect->section + 2) << 8) + R_X86_64_32);
3337 saa_write32(pinforel, 0);
3338 saa_write32(pinfo,0); /* DW_AT_low_pc */
3339 saa_write32(pinfo,0); /* DW_AT_frame_base */
3340 saa_write8(pinfo,0); /* end of entries */
3341 saalen = pinfo->datalen;
3342 infolen = saalen + 4;
3343 infobuf = pbuf = nasm_malloc(infolen);
3344 WRITELONG(pbuf,saalen); /* initial length */
3345 saa_rnbytes(pinfo, pbuf, saalen);
3346 saa_free(pinfo);
3347 } else {
3348 nasm_assert(is_elf64());
3349 /* build info section */
3350 pinfo = saa_init(1L);
3351 pinforel = saa_init(1L);
3352 saa_write16(pinfo, dwfmt->sect_version[DWARF_INFO]);
3353 saa_write64(pinforel, pinfo->datalen + 4);
3354 saa_write64(pinforel, (dwarf_abbrevsym << 32) + R_X86_64_32); /* reloc to abbrev */
3355 saa_write64(pinforel, 0);
3356 saa_write32(pinfo,0); /* offset into abbrev */
3357 saa_write8(pinfo,8); /* pointer size */
3358 saa_write8(pinfo,1); /* abbrviation number LEB128u */
3359 saa_write64(pinforel, pinfo->datalen + 4);
3360 saa_write64(pinforel, ((uint64_t)(dwarf_fsect->section + 2) << 32) + R_X86_64_64);
3361 saa_write64(pinforel, 0);
3362 saa_write64(pinfo,0); /* DW_AT_low_pc */
3363 saa_write64(pinforel, pinfo->datalen + 4);
3364 saa_write64(pinforel, ((uint64_t)(dwarf_fsect->section + 2) << 32) + R_X86_64_64);
3365 saa_write64(pinforel, 0);
3366 saa_write64(pinfo,highaddr); /* DW_AT_high_pc */
3367 saa_write64(pinforel, pinfo->datalen + 4);
3368 saa_write64(pinforel, (dwarf_linesym << 32) + R_X86_64_32); /* reloc to line */
3369 saa_write64(pinforel, 0);
3370 saa_write32(pinfo,0); /* DW_AT_stmt_list */
3371 saa_wbytes(pinfo, elf_module, strlen(elf_module)+1);
3372 saa_wbytes(pinfo, nasm_signature(), nasm_signature_len()+1);
3373 saa_write16(pinfo,DW_LANG_Mips_Assembler);
3374 saa_write8(pinfo,2); /* abbrviation number LEB128u */
3375 saa_write64(pinforel, pinfo->datalen + 4);
3376 saa_write64(pinforel, ((uint64_t)(dwarf_fsect->section + 2) << 32) + R_X86_64_64);
3377 saa_write64(pinforel, 0);
3378 saa_write64(pinfo,0); /* DW_AT_low_pc */
3379 saa_write64(pinfo,0); /* DW_AT_frame_base */
3380 saa_write8(pinfo,0); /* end of entries */
3381 saalen = pinfo->datalen;
3382 infolen = saalen + 4;
3383 infobuf = pbuf = nasm_malloc(infolen);
3384 WRITELONG(pbuf,saalen); /* initial length */
3385 saa_rnbytes(pinfo, pbuf, saalen);
3386 saa_free(pinfo);
3389 /* build rela.info section */
3390 inforellen = saalen = pinforel->datalen;
3391 inforelbuf = pbuf = nasm_malloc(inforellen);
3392 saa_rnbytes(pinforel, pbuf, saalen);
3393 saa_free(pinforel);
3395 /* build abbrev section */
3396 pabbrev = saa_init(1L);
3397 saa_write8(pabbrev,1); /* entry number LEB128u */
3398 saa_write8(pabbrev,DW_TAG_compile_unit); /* tag LEB128u */
3399 saa_write8(pabbrev,1); /* has children */
3400 /* the following attributes and forms are all LEB128u values */
3401 saa_write8(pabbrev,DW_AT_low_pc);
3402 saa_write8(pabbrev,DW_FORM_addr);
3403 saa_write8(pabbrev,DW_AT_high_pc);
3404 saa_write8(pabbrev,DW_FORM_addr);
3405 saa_write8(pabbrev,DW_AT_stmt_list);
3406 saa_write8(pabbrev,DW_FORM_data4);
3407 saa_write8(pabbrev,DW_AT_name);
3408 saa_write8(pabbrev,DW_FORM_string);
3409 saa_write8(pabbrev,DW_AT_producer);
3410 saa_write8(pabbrev,DW_FORM_string);
3411 saa_write8(pabbrev,DW_AT_language);
3412 saa_write8(pabbrev,DW_FORM_data2);
3413 saa_write16(pabbrev,0); /* end of entry */
3414 /* LEB128u usage same as above */
3415 saa_write8(pabbrev,2); /* entry number */
3416 saa_write8(pabbrev,DW_TAG_subprogram);
3417 saa_write8(pabbrev,0); /* no children */
3418 saa_write8(pabbrev,DW_AT_low_pc);
3419 saa_write8(pabbrev,DW_FORM_addr);
3420 saa_write8(pabbrev,DW_AT_frame_base);
3421 saa_write8(pabbrev,DW_FORM_data4);
3422 saa_write16(pabbrev,0); /* end of entry */
3423 /* Terminal zero entry */
3424 saa_write8(pabbrev,0);
3425 abbrevlen = saalen = pabbrev->datalen;
3426 abbrevbuf = pbuf = nasm_malloc(saalen);
3427 saa_rnbytes(pabbrev, pbuf, saalen);
3428 saa_free(pabbrev);
3430 /* build line section */
3431 /* prolog */
3432 plines = saa_init(1L);
3433 saa_write8(plines,1); /* Minimum Instruction Length */
3434 saa_write8(plines,1); /* Initial value of 'is_stmt' */
3435 saa_write8(plines,line_base); /* Line Base */
3436 saa_write8(plines,line_range); /* Line Range */
3437 saa_write8(plines,opcode_base); /* Opcode Base */
3438 /* standard opcode lengths (# of LEB128u operands) */
3439 saa_write8(plines,0); /* Std opcode 1 length */
3440 saa_write8(plines,1); /* Std opcode 2 length */
3441 saa_write8(plines,1); /* Std opcode 3 length */
3442 saa_write8(plines,1); /* Std opcode 4 length */
3443 saa_write8(plines,1); /* Std opcode 5 length */
3444 saa_write8(plines,0); /* Std opcode 6 length */
3445 saa_write8(plines,0); /* Std opcode 7 length */
3446 saa_write8(plines,0); /* Std opcode 8 length */
3447 saa_write8(plines,1); /* Std opcode 9 length */
3448 saa_write8(plines,0); /* Std opcode 10 length */
3449 saa_write8(plines,0); /* Std opcode 11 length */
3450 saa_write8(plines,1); /* Std opcode 12 length */
3451 /* Directory Table */
3452 saa_write8(plines,0); /* End of table */
3453 /* File Name Table */
3454 ftentry = dwarf_flist;
3455 for (indx = 0; indx < dwarf_numfiles; indx++) {
3456 saa_wbytes(plines, ftentry->filename, (int32_t)(strlen(ftentry->filename) + 1));
3457 saa_write8(plines,0); /* directory LEB128u */
3458 saa_write8(plines,0); /* time LEB128u */
3459 saa_write8(plines,0); /* size LEB128u */
3460 ftentry = ftentry->next;
3462 saa_write8(plines,0); /* End of table */
3463 linepoff = plines->datalen;
3464 linelen = linepoff + totlen + 10;
3465 linebuf = pbuf = nasm_malloc(linelen);
3466 WRITELONG(pbuf,linelen-4); /* initial length */
3467 WRITESHORT(pbuf,dwfmt->sect_version[DWARF_LINE]);
3468 WRITELONG(pbuf,linepoff); /* offset to line number program */
3469 /* write line header */
3470 saalen = linepoff;
3471 saa_rnbytes(plines, pbuf, saalen); /* read a given no. of bytes */
3472 pbuf += linepoff;
3473 saa_free(plines);
3474 /* concatonate line program ranges */
3475 linepoff += 13;
3476 plinesrel = saa_init(1L);
3477 psect = dwarf_fsect;
3478 if (is_elf32()) {
3479 for (indx = 0; indx < dwarf_nsections; indx++) {
3480 saa_write32(plinesrel, linepoff);
3481 saa_write32(plinesrel, ((uint32_t) (psect->section + 2) << 8) + R_386_32);
3482 saa_write32(plinesrel, (uint32_t) 0);
3483 plinep = psect->psaa;
3484 saalen = plinep->datalen;
3485 saa_rnbytes(plinep, pbuf, saalen);
3486 pbuf += saalen;
3487 linepoff += saalen;
3488 saa_free(plinep);
3489 /* done with this entry */
3490 psect = psect->next;
3492 } else if (is_elfx32()) {
3493 for (indx = 0; indx < dwarf_nsections; indx++) {
3494 saa_write32(plinesrel, linepoff);
3495 saa_write32(plinesrel, ((psect->section + 2) << 8) + R_X86_64_32);
3496 saa_write32(plinesrel, 0);
3497 plinep = psect->psaa;
3498 saalen = plinep->datalen;
3499 saa_rnbytes(plinep, pbuf, saalen);
3500 pbuf += saalen;
3501 linepoff += saalen;
3502 saa_free(plinep);
3503 /* done with this entry */
3504 psect = psect->next;
3506 } else {
3507 nasm_assert(is_elf64());
3508 for (indx = 0; indx < dwarf_nsections; indx++) {
3509 saa_write64(plinesrel, linepoff);
3510 saa_write64(plinesrel, ((uint64_t) (psect->section + 2) << 32) + R_X86_64_64);
3511 saa_write64(plinesrel, (uint64_t) 0);
3512 plinep = psect->psaa;
3513 saalen = plinep->datalen;
3514 saa_rnbytes(plinep, pbuf, saalen);
3515 pbuf += saalen;
3516 linepoff += saalen;
3517 saa_free(plinep);
3518 /* done with this entry */
3519 psect = psect->next;
3523 /* build rela.lines section */
3524 linerellen =saalen = plinesrel->datalen;
3525 linerelbuf = pbuf = nasm_malloc(linerellen);
3526 saa_rnbytes(plinesrel, pbuf, saalen);
3527 saa_free(plinesrel);
3529 /* build .debug_frame section */
3530 if (0) {
3531 framelen = 4;
3532 framebuf = pbuf = nasm_malloc(framelen);
3533 WRITELONG(pbuf,framelen-4); /* initial length */
3534 } else {
3535 /* Leave .debug_frame empty if not used! */
3536 framelen = 0;
3539 /* build .debug_loc section */
3540 if (0) {
3541 loclen = 16;
3542 locbuf = pbuf = nasm_malloc(loclen);
3543 if (is_elf32() || is_elfx32()) {
3544 WRITELONG(pbuf,0); /* null beginning offset */
3545 WRITELONG(pbuf,0); /* null ending offset */
3546 } else {
3547 nasm_assert(is_elf64());
3548 WRITEDLONG(pbuf,0); /* null beginning offset */
3549 WRITEDLONG(pbuf,0); /* null ending offset */
3551 } else {
3552 /* Leave .debug_frame empty if not used! */
3553 loclen = 0;
3557 static void dwarf_cleanup(void)
3559 nasm_free(arangesbuf);
3560 nasm_free(arangesrelbuf);
3561 nasm_free(pubnamesbuf);
3562 nasm_free(infobuf);
3563 nasm_free(inforelbuf);
3564 nasm_free(abbrevbuf);
3565 nasm_free(linebuf);
3566 nasm_free(linerelbuf);
3567 nasm_free(framebuf);
3568 nasm_free(locbuf);
3571 static void dwarf_findfile(const char * fname)
3573 int finx;
3574 struct linelist *match;
3576 /* return if fname is current file name */
3577 if (dwarf_clist && !(strcmp(fname, dwarf_clist->filename)))
3578 return;
3580 /* search for match */
3581 match = 0;
3582 if (dwarf_flist) {
3583 match = dwarf_flist;
3584 for (finx = 0; finx < dwarf_numfiles; finx++) {
3585 if (!(strcmp(fname, match->filename))) {
3586 dwarf_clist = match;
3587 return;
3589 match = match->next;
3593 /* add file name to end of list */
3594 dwarf_clist = nasm_malloc(sizeof(struct linelist));
3595 dwarf_numfiles++;
3596 dwarf_clist->line = dwarf_numfiles;
3597 dwarf_clist->filename = nasm_malloc(strlen(fname) + 1);
3598 strcpy(dwarf_clist->filename,fname);
3599 dwarf_clist->next = 0;
3600 if (!dwarf_flist) { /* if first entry */
3601 dwarf_flist = dwarf_elist = dwarf_clist;
3602 dwarf_clist->last = 0;
3603 } else { /* chain to previous entry */
3604 dwarf_elist->next = dwarf_clist;
3605 dwarf_elist = dwarf_clist;
3609 static void dwarf_findsect(const int index)
3611 int sinx;
3612 struct sectlist *match;
3613 struct SAA *plinep;
3615 /* return if index is current section index */
3616 if (dwarf_csect && (dwarf_csect->section == index))
3617 return;
3619 /* search for match */
3620 match = 0;
3621 if (dwarf_fsect) {
3622 match = dwarf_fsect;
3623 for (sinx = 0; sinx < dwarf_nsections; sinx++) {
3624 if (match->section == index) {
3625 dwarf_csect = match;
3626 return;
3628 match = match->next;
3632 /* add entry to end of list */
3633 dwarf_csect = nasm_malloc(sizeof(struct sectlist));
3634 dwarf_nsections++;
3635 dwarf_csect->psaa = plinep = saa_init(1L);
3636 dwarf_csect->line = 1;
3637 dwarf_csect->offset = 0;
3638 dwarf_csect->file = 1;
3639 dwarf_csect->section = index;
3640 dwarf_csect->next = 0;
3641 /* set relocatable address at start of line program */
3642 saa_write8(plinep,DW_LNS_extended_op);
3643 saa_write8(plinep,is_elf64() ? 9 : 5); /* operand length */
3644 saa_write8(plinep,DW_LNE_set_address);
3645 if (is_elf64())
3646 saa_write64(plinep,0); /* Start Address */
3647 else
3648 saa_write32(plinep,0); /* Start Address */
3650 if (!dwarf_fsect) { /* if first entry */
3651 dwarf_fsect = dwarf_esect = dwarf_csect;
3652 dwarf_csect->last = 0;
3653 } else { /* chain to previous entry */
3654 dwarf_esect->next = dwarf_csect;
3655 dwarf_esect = dwarf_csect;
3659 #endif /* defined(OF_ELF32) || defined(OF_ELF64) || defined(OF_ELFX32) */