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
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
59 #if defined(OF_ELF32) || defined(OF_ELF64) || defined(OF_ELFX32)
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
{
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
,
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
;
122 int section
; /* index into sects[] */
123 int segto
; /* internal section number */
124 char *name
; /* shallow-copied pointer of section name */
128 struct linelist
*next
;
129 struct linelist
*last
;
130 struct symlininfo info
;
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() */
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 */
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
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 }
286 static const struct size_unit size_units
[] =
298 { "pointer", -1, -1 },
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
;
315 opt
= nasm_skip_spaces(attr
);
319 while ((opt
= nasm_opt_val(opt
, &val
, &next
))) {
320 if (!nasm_stricmp(opt
, "align")) {
322 nasm_nonfatal("section align without value specified");
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
) {
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")) {
375 } else if (!nasm_stricmp(opt
, "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
;
386 const char *a
= strchr(opt
, '*');
388 const struct size_unit
*su
;
392 mult
= readnum(a
+1, &err
);
398 for (su
= size_units
; su
->bytes
; su
++) {
399 if (!nasm_strnicmp(opt
, su
->name
, l
))
404 *entsize
= to_bytes(su
->bytes
) * mult
;
405 xalign
= to_bytes(su
->align
);
407 /* Unknown attribute */
408 nasm_warn(WARN_OTHER
,
409 "unknown section attribute '%s' ignored on"
410 " declaration of section `%s'", opt
, name
);
417 case SHT_PREINIT_ARRAY
:
423 *entsize
= efmt
->word
;
437 static enum directive_result
438 elf_directive(enum directive directive
, char *value
)
446 if (!pass_first()) /* XXX: Why? */
449 n
= readnum(value
, &err
);
451 nasm_nonfatal("`osabi' directive requires a parameter");
455 if (n
< 0 || n
> 255) {
456 nasm_nonfatal("valid osabi numbers are 0 to 255");
463 p
= strchr(value
,',');
467 n
= readnum(p
+ 1, &err
);
468 if (err
|| n
< 0 || n
> 255) {
469 nasm_nonfatal("invalid ABI version number (valid: 0 to 255)");
481 static void elf_init(void);
483 static void elf32_init(void)
485 static const struct elf_format_info ef_elf32
= {
505 static void elfx32_init(void)
507 static const struct elf_format_info ef_elfx32
= {
527 static void elf64_init(void)
529 static const struct elf_format_info ef_elf64
= {
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
));
558 nsects
= sectlen
= 0;
559 syms
= saa_init((int32_t)sizeof(struct elf_symbol
));
560 nlocals
= nglobs
= ndebugs
= 0;
563 saa_wbytes(strs
, "\0", 1L);
564 saa_wbytes(strs
, elf_module
, strlen(elf_module
)+1);
565 strslen
= 2 + strlen(elf_module
);
567 shstrtablen
= shstrtabsize
= 0;;
568 add_sectname("", ""); /* SHN_UNDEF */
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(§ion_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)
612 for (i
= 0; i
< nsects
; i
++) {
613 if (sects
[i
]->type
!= SHT_NOBITS
)
614 saa_free(sects
[i
]->data
);
616 saa_free(sects
[i
]->rel
);
617 while (sects
[i
]->head
) {
619 sects
[i
]->head
= sects
[i
]->head
->next
;
623 hash_free(§ion_by_name
);
624 raa_free(section_by_index
);
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
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
);
649 memcpy(shstrtab
+ shstrtablen
, secondhalf
, l2
+1);
650 shstrtablen
+= l2
+ 1;
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);
665 if (!strcmp(name
, ".text"))
668 s
->index
= seg_alloc();
670 s
->name
= nasm_strdup(name
);
674 s
->shndx
= add_sectname("", name
);
676 if (nsects
>= sectlen
)
677 sects
= nasm_realloc(sects
, (sectlen
+= SECT_DELTA
) * sizeof(*sects
));
683 static int32_t elf_section_names(char *name
, int *bits
)
686 uint32_t flags
, flags_and
, flags_or
;
687 uint64_t align
, entsize
;
689 struct elf_section
*s
;
690 struct hash_insert hi
;
694 *bits
= ofmt
->maxbits
;
698 p
= nasm_skip_word(name
);
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(§ion_by_name
, name
, &hi
);
709 nasm_nonfatal("attempt to redefine reserved section name `%s'", name
);
713 const struct elf_known_section
*ks
= elf_known_sections
;
716 if (!strcmp(name
, ks
->name
))
721 type
= type
? type
: ks
->type
;
723 align
= to_bytes(ks
->align
);
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
)
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'");
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
)
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
);
790 if (is_global
== 3) {
791 struct elf_symbol
**s
;
793 * Fix up a forward-reference symbol size from the first
796 for (s
= &fwds
; *s
; s
= &(*s
)->nextfwd
)
797 if (!strcmp((*s
)->name
, name
)) {
798 struct tokenval tokval
;
800 char *p
= nasm_skip_spaces(nasm_skip_word(special
));
804 tokval
.t_type
= TOKEN_INVALID
;
805 e
= evaluate(stdscan
, NULL
, &tokval
, NULL
, 1, NULL
);
808 nasm_nonfatal("cannot use relocatable"
809 " expression as symbol size");
811 (*s
)->size
= reloc_value(e
);
815 * Remove it from the list of unresolved sizes.
817 nasm_free((*s
)->name
);
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
));
832 bind
= is_global
? STB_GLOBAL
: STB_LOCAL
;
834 sym
->other
= STV_DEFAULT
;
836 if (segment
== NO_SEG
) {
837 sym
->section
= XSHN_ABS
;
839 sym
->section
= XSHN_UNDEF
;
840 if (segment
== def_seg
) {
841 /* we have to be sure at least text section is there */
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);
848 sym
->section
= sec
->shndx
;
851 if (is_global
== 2) {
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.
864 sym
->symv
.key
= readnum(spcword
, &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
));
874 sym
->symv
.key
= (sym
->section
== XSHN_UNDEF
? 0 : offset
);
877 if (spcword
&& *spcword
) {
883 wend
= nasm_skip_word(spcword
);
884 wlen
= wend
- spcword
;
888 if (!nasm_strnicmp(spcword
, "data", wlen
))
890 else if (!nasm_strnicmp(spcword
, "weak", wlen
))
897 if (!nasm_strnicmp(spcword
, "notype", wlen
))
899 else if (!nasm_strnicmp(spcword
, "object", wlen
))
901 else if (!nasm_strnicmp(spcword
, "hidden", wlen
))
902 sym
->other
= STV_HIDDEN
;
903 else if (!nasm_strnicmp(spcword
, "strong", wlen
))
910 if (!nasm_strnicmp(spcword
, "default", wlen
))
911 sym
->other
= STV_DEFAULT
;
917 if (!nasm_strnicmp(spcword
, "function", wlen
))
919 else if (!nasm_stricmp(spcword
, "internal"))
920 sym
->other
= STV_INTERNAL
;
926 if (!nasm_strnicmp(spcword
, "protected", wlen
))
927 sym
->other
= STV_PROTECTED
;
938 spcword
= nasm_skip_spaces(wend
);
940 if (!is_global
&& bind
!= STB_LOCAL
) {
941 nasm_nonfatal("weak and strong only applies to global symbols");
945 if (spcword
&& *spcword
) {
946 struct tokenval tokval
;
949 char *saveme
= stdscan_get();
952 * We have a size expression; attempt to
956 stdscan_set((char *)spcword
);
957 tokval
.t_type
= TOKEN_INVALID
;
958 e
= evaluate(stdscan
, NULL
, &tokval
, &fwd
, 0, NULL
);
962 sym
->name
= nasm_strdup(name
);
965 nasm_nonfatal("cannot use relocatable"
966 " expression as symbol size");
968 sym
->size
= reloc_value(e
);
975 * If it is in a TLS segment, mark symbol accordingly.
977 if (sec
&& (sec
->flags
& SHF_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
)) {
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:
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
;
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
;
1026 if (segment
!= NO_SEG
) {
1027 const struct elf_section
*s
;
1028 s
= raa_read_ptr(section_by_index
, segment
>> 1);
1030 r
->symbol
= s
->shndx
+ 1;
1032 r
->symbol
= GLOBAL_TEMP_BASE
+ raa_read(bsym
, segment
);
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
;
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);
1079 if (exact
&& offset
)
1080 nasm_nonfatal("invalid access to an external symbol");
1082 elf_add_reloc(sect
, segment
, offset
- pcrel
, type
);
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");
1092 sym
= container_of(srb
, struct elf_symbol
, symv
);
1094 r
= *sect
->tail
= nasm_malloc(sizeof(struct elf_reloc
));
1095 sect
->tail
= &r
->next
;
1098 r
->address
= sect
->len
;
1099 r
->offset
= offset
- pcrel
- sym
->symv
.key
;
1100 r
->symbol
= GLOBAL_TEMP_BASE
+ sym
->globnum
;
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
;
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");
1125 s
= raa_read_ptr(section_by_index
, segto
>> 1);
1127 int tempint
; /* ignored */
1128 if (segto
!= elf_section_names(".text", &tempint
))
1129 nasm_panic("strange segment conditions in ELF driver");
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
);
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
);
1161 elf_sect_write(s
, data
, size
);
1167 int asize
= abs((int)size
);
1169 addr
= *(int64_t *)data
;
1170 if (segment
!= NO_SEG
) {
1172 nasm_nonfatal("ELF format does not support"
1173 " segment base references");
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
1183 elf_add_reloc(s
, segment
, 0, R_386_8
);
1186 elf_add_reloc(s
, segment
, 0, R_386_16
);
1189 elf_add_reloc(s
, segment
, 0, R_386_32
);
1191 default: /* Error issued further down */
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 $-$$.
1203 elf_add_reloc(s
, segment
, 0, R_386_GOTPC
);
1204 } else if (wrt
== elf_gotoff_sect
+ 1) {
1206 elf_add_reloc(s
, segment
, 0, R_386_GOTOFF
);
1207 } else if (wrt
== elf_tlsie_sect
+ 1) {
1209 addr
= elf_add_gsym_reloc(s
, segment
, addr
, 0,
1210 R_386_TLS_IE
, true);
1211 } else if (wrt
== elf_got_sect
+ 1) {
1213 addr
= elf_add_gsym_reloc(s
, segment
, addr
, 0,
1215 } else if (wrt
== elf_sym_sect
+ 1) {
1218 addr
= elf_add_gsym_reloc(s
, segment
, addr
, 0,
1222 addr
= elf_add_gsym_reloc(s
, segment
, addr
, 0,
1226 addr
= elf_add_gsym_reloc(s
, segment
, addr
, 0,
1233 } else if (wrt
== elf_plt_sect
+ 1) {
1234 nasm_nonfatal("ELF format cannot produce non-PC-"
1235 "relative PLT references");
1237 nasm_nonfatal("ELF format does not support this"
1239 wrt
= NO_SEG
; /* we can at least _try_ to continue */
1245 nasm_nonfatal("Unsupported %d-bit ELF relocation", asize
<< 3);
1247 elf_sect_writeaddr(s
, addr
, asize
);
1252 reltype
= R_386_PC8
;
1256 reltype
= R_386_PC16
;
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");
1267 if (wrt
== NO_SEG
) {
1268 elf_add_reloc(s
, segment
, 0, reltype
);
1270 nasm_nonfatal("Unsupported %d-bit ELF relocation", bytes
<< 3);
1273 elf_sect_writeaddr(s
, addr
, bytes
);
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");
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");
1294 nasm_nonfatal("ELF format does not support this"
1296 wrt
= NO_SEG
; /* we can at least _try_ to continue */
1299 elf_sect_writeaddr(s
, addr
, 4);
1303 nasm_nonfatal("32-bit ELF format does not support 64-bit relocations");
1305 elf_sect_writeaddr(s
, addr
, 8);
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
;
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");
1330 s
= raa_read_ptr(section_by_index
, segto
>> 1);
1332 int tempint
; /* ignored */
1333 if (segto
!= elf_section_names(".text", &tempint
))
1334 nasm_panic("strange segment conditions in ELF driver");
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
);
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
);
1366 if (segment
!= NO_SEG
)
1367 nasm_panic("OUT_RAWDATA with other than NO_SEG");
1368 elf_sect_write(s
, data
, size
);
1373 int isize
= (int)size
;
1374 int asize
= abs((int)size
);
1376 addr
= *(int64_t *)data
;
1377 if (segment
== NO_SEG
) {
1379 } else if (segment
& 1) {
1380 nasm_nonfatal("ELF format does not support"
1381 " segment base references");
1383 if (wrt
== NO_SEG
) {
1387 elf_add_reloc(s
, segment
, addr
, R_X86_64_8
);
1391 elf_add_reloc(s
, segment
, addr
, R_X86_64_16
);
1394 elf_add_reloc(s
, segment
, addr
, R_X86_64_32
);
1397 elf_add_reloc(s
, segment
, addr
, R_X86_64_32S
);
1401 elf_add_reloc(s
, segment
, addr
, R_X86_64_64
);
1404 nasm_panic("internal error elf64-hpa-871");
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 $-$$.
1415 elf_add_reloc(s
, segment
, addr
, R_X86_64_GOTPC32
);
1417 } else if (wrt
== elf_gotoff_sect
+ 1) {
1419 nasm_nonfatal("ELF64 requires ..gotoff "
1420 "references to be qword");
1422 elf_add_reloc(s
, segment
, addr
, R_X86_64_GOTOFF64
);
1425 } else if (wrt
== elf_got_sect
+ 1) {
1428 elf_add_gsym_reloc(s
, segment
, addr
, 0,
1429 R_X86_64_GOT32
, true);
1433 elf_add_gsym_reloc(s
, segment
, addr
, 0,
1434 R_X86_64_GOT64
, true);
1438 nasm_nonfatal("invalid ..got reference");
1441 } else if (wrt
== elf_sym_sect
+ 1) {
1445 elf_add_gsym_reloc(s
, segment
, addr
, 0,
1451 elf_add_gsym_reloc(s
, segment
, addr
, 0,
1452 R_X86_64_16
, false);
1456 elf_add_gsym_reloc(s
, segment
, addr
, 0,
1457 R_X86_64_32
, false);
1461 elf_add_gsym_reloc(s
, segment
, addr
, 0,
1462 R_X86_64_32S
, false);
1467 elf_add_gsym_reloc(s
, segment
, addr
, 0,
1468 R_X86_64_64
, false);
1472 nasm_panic("internal error elf64-hpa-903");
1475 } else if (wrt
== elf_plt_sect
+ 1) {
1476 nasm_nonfatal("ELF format cannot produce non-PC-"
1477 "relative PLT references");
1479 nasm_nonfatal("ELF format does not support this"
1483 elf_sect_writeaddr(s
, addr
, asize
);
1488 reltype
= R_X86_64_PC8
;
1493 reltype
= R_X86_64_PC16
;
1498 addr
= *(int64_t *)data
- size
;
1499 if (segment
== segto
)
1500 nasm_panic("intra-segment OUT_REL1ADR");
1501 if (segment
== NO_SEG
) {
1503 } else if (segment
& 1) {
1504 nasm_nonfatal("ELF format does not support"
1505 " segment base references");
1507 if (wrt
== NO_SEG
) {
1508 elf_add_reloc(s
, segment
, addr
, reltype
);
1511 nasm_nonfatal("Unsupported %d-bit ELF relocation", bytes
<< 3);
1514 elf_sect_writeaddr(s
, addr
, bytes
);
1518 addr
= *(int64_t *)data
- size
;
1519 if (segment
== segto
)
1520 nasm_panic("intra-segment OUT_REL4ADR");
1521 if (segment
== NO_SEG
) {
1523 } else if (segment
& 1) {
1524 nasm_nonfatal("ELF64 format does not support"
1525 " segment base references");
1527 if (wrt
== NO_SEG
) {
1528 elf_add_reloc(s
, segment
, addr
, R_X86_64_PC32
);
1530 } else if (wrt
== elf_plt_sect
+ 1) {
1531 elf_add_gsym_reloc(s
, segment
, addr
+size
, size
,
1532 R_X86_64_PLT32
, true);
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);
1539 } else if (wrt
== elf_gotoff_sect
+ 1 ||
1540 wrt
== elf_got_sect
+ 1) {
1541 nasm_nonfatal("ELF64 requires ..gotoff references to be "
1543 } else if (wrt
== elf_gottpoff_sect
+ 1) {
1544 elf_add_gsym_reloc(s
, segment
, addr
+size
, size
,
1545 R_X86_64_GOTTPOFF
, true);
1548 nasm_nonfatal("ELF64 format does not support this"
1552 elf_sect_writeaddr(s
, addr
, 4);
1556 addr
= *(int64_t *)data
- size
;
1557 if (segment
== segto
)
1558 nasm_panic("intra-segment OUT_REL8ADR");
1559 if (segment
== NO_SEG
) {
1561 } else if (segment
& 1) {
1562 nasm_nonfatal("ELF64 format does not support"
1563 " segment base references");
1565 if (wrt
== NO_SEG
) {
1566 elf_add_reloc(s
, segment
, addr
, R_X86_64_PC64
);
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);
1573 } else if (wrt
== elf_gotoff_sect
+ 1 ||
1574 wrt
== elf_got_sect
+ 1) {
1575 nasm_nonfatal("ELF64 requires ..gotoff references to be "
1577 } else if (wrt
== elf_gottpoff_sect
+ 1) {
1578 nasm_nonfatal("ELF64 requires ..gottpoff references to be "
1581 nasm_nonfatal("ELF64 format does not support this"
1585 elf_sect_writeaddr(s
, addr
, 8);
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
;
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");
1611 s
= raa_read_ptr(section_by_index
, segto
>> 1);
1613 int tempint
; /* ignored */
1614 if (segto
!= elf_section_names(".text", &tempint
))
1615 nasm_panic("strange segment conditions in ELF driver");
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
);
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
);
1647 if (segment
!= NO_SEG
)
1648 nasm_panic("OUT_RAWDATA with other than NO_SEG");
1649 elf_sect_write(s
, data
, size
);
1654 int isize
= (int)size
;
1655 int asize
= abs((int)size
);
1657 addr
= *(int64_t *)data
;
1658 if (segment
== NO_SEG
) {
1660 } else if (segment
& 1) {
1661 nasm_nonfatal("ELF format does not support"
1662 " segment base references");
1664 if (wrt
== NO_SEG
) {
1668 elf_add_reloc(s
, segment
, addr
, R_X86_64_8
);
1672 elf_add_reloc(s
, segment
, addr
, R_X86_64_16
);
1675 elf_add_reloc(s
, segment
, addr
, R_X86_64_32
);
1678 elf_add_reloc(s
, segment
, addr
, R_X86_64_32S
);
1682 elf_add_reloc(s
, segment
, addr
, R_X86_64_64
);
1685 nasm_panic("internal error elfx32-hpa-871");
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 $-$$.
1696 elf_add_reloc(s
, segment
, addr
, R_X86_64_GOTPC32
);
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) {
1704 elf_add_gsym_reloc(s
, segment
, addr
, 0,
1705 R_X86_64_GOT32
, true);
1709 nasm_nonfatal("invalid ..got reference");
1712 } else if (wrt
== elf_sym_sect
+ 1) {
1716 elf_add_gsym_reloc(s
, segment
, addr
, 0,
1722 elf_add_gsym_reloc(s
, segment
, addr
, 0,
1723 R_X86_64_16
, false);
1727 elf_add_gsym_reloc(s
, segment
, addr
, 0,
1728 R_X86_64_32
, false);
1732 elf_add_gsym_reloc(s
, segment
, addr
, 0,
1733 R_X86_64_32S
, false);
1738 elf_add_gsym_reloc(s
, segment
, addr
, 0,
1739 R_X86_64_64
, false);
1743 nasm_panic("internal error elfx32-hpa-903");
1746 } else if (wrt
== elf_plt_sect
+ 1) {
1747 nasm_nonfatal("ELF format cannot produce non-PC-"
1748 "relative PLT references");
1750 nasm_nonfatal("ELF format does not support this"
1754 elf_sect_writeaddr(s
, addr
, asize
);
1759 reltype
= R_X86_64_PC8
;
1764 reltype
= R_X86_64_PC16
;
1769 addr
= *(int64_t *)data
- size
;
1770 if (segment
== segto
)
1771 nasm_panic("intra-segment OUT_REL1ADR");
1772 if (segment
== NO_SEG
) {
1774 } else if (segment
& 1) {
1775 nasm_nonfatal("ELF format does not support"
1776 " segment base references");
1778 if (wrt
== NO_SEG
) {
1779 elf_add_reloc(s
, segment
, addr
, reltype
);
1782 nasm_nonfatal("unsupported %d-bit ELF relocation", bytes
<< 3);
1785 elf_sect_writeaddr(s
, addr
, bytes
);
1789 addr
= *(int64_t *)data
- size
;
1790 if (segment
== segto
)
1791 nasm_panic("intra-segment OUT_REL4ADR");
1792 if (segment
== NO_SEG
) {
1794 } else if (segment
& 1) {
1795 nasm_nonfatal("ELFX32 format does not support"
1796 " segment base references");
1798 if (wrt
== NO_SEG
) {
1799 elf_add_reloc(s
, segment
, addr
, R_X86_64_PC32
);
1801 } else if (wrt
== elf_plt_sect
+ 1) {
1802 elf_add_gsym_reloc(s
, segment
, addr
+size
, size
,
1803 R_X86_64_PLT32
, true);
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);
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);
1818 nasm_nonfatal("ELFX32 format does not support this use of WRT");
1821 elf_sect_writeaddr(s
, addr
, 4);
1825 nasm_nonfatal("32-bit ELF format does not support 64-bit relocations");
1827 elf_sect_writeaddr(s
, addr
, 8);
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
];
1854 struct ehdr_common com
;
1857 static void elf_write(void)
1863 int sec_shstrtab
, sec_symtab
, sec_strtab
;
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? */
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.
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
);
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
);
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
;
1953 elf_sects
= nasm_malloc(sizeof(*elf_sects
) * nsections
);
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,
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
);
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 */
1979 if (stabbuf
&& stabstrbuf
&& stabrelbuf
) {
1980 elf_section_header(p
- shstrtab
, SHT_PROGBITS
, 0, stabbuf
, false,
1981 stablen
, sec_stabstr
, 0, 4, 12);
1984 elf_section_header(p
- shstrtab
, SHT_STRTAB
, 0, stabstrbuf
, false,
1985 stabstrlen
, 0, 0, 4, 0);
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
);
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 */
2002 elf_section_header(p
- shstrtab
, SHT_PROGBITS
, 0, arangesbuf
, false,
2003 arangeslen
, 0, 0, 1, 0);
2006 elf_section_header(p
- shstrtab
, SHT_RELA
, 0, arangesrelbuf
, false,
2007 arangesrellen
, sec_symtab
,
2009 efmt
->word
, efmt
->rela_size
);
2012 elf_section_header(p
- shstrtab
, SHT_PROGBITS
, 0, pubnamesbuf
,
2013 false, pubnameslen
, 0, 0, 1, 0);
2016 elf_section_header(p
- shstrtab
, SHT_PROGBITS
, 0, infobuf
, false,
2017 infolen
, 0, 0, 1, 0);
2020 elf_section_header(p
- shstrtab
, SHT_RELA
, 0, inforelbuf
, false,
2021 inforellen
, sec_symtab
,
2023 efmt
->word
, efmt
->rela_size
);
2026 elf_section_header(p
- shstrtab
, SHT_PROGBITS
, 0, abbrevbuf
, false,
2027 abbrevlen
, 0, 0, 1, 0);
2030 elf_section_header(p
- shstrtab
, SHT_PROGBITS
, 0, linebuf
, false,
2031 linelen
, 0, 0, 1, 0);
2034 elf_section_header(p
- shstrtab
, SHT_RELA
, 0, linerelbuf
, false,
2035 linerellen
, sec_symtab
,
2037 efmt
->word
, efmt
->rela_size
);
2040 elf_section_header(p
- shstrtab
, SHT_PROGBITS
, 0, framebuf
, false,
2041 framelen
, 0, 0, 8, 0);
2044 elf_section_header(p
- shstrtab
, SHT_PROGBITS
, 0, locbuf
, false,
2045 loclen
, 0, 0, 1, 0);
2050 elf_section_header(p
- shstrtab
, SHT_STRTAB
, 0, shstrtab
, false,
2051 shstrtablen
, 0, 0, 1, 0);
2055 elf_section_header(p
- shstrtab
, SHT_SYMTAB
, 0, symtab
, true,
2056 symtab
->datalen
, sec_strtab
, symtablocal
,
2057 efmt
->word
, efmt
->sym_size
);
2061 elf_section_header(p
- shstrtab
, SHT_STRTAB
, 0, strs
, true,
2062 strslen
, 0, 0, 1, 0);
2067 elf_section_header(p
- shstrtab
, SHT_SYMTAB_SHNDX
, 0,
2068 symtab_shndx
, true, symtab_shndx
->datalen
,
2069 sec_symtab
, 0, 1, 0);
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
);
2083 fwritezero(align
, ofile
);
2086 * Now output the sections.
2088 elf_write_sections();
2090 nasm_free(elf_sects
);
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);
2115 shndx
= 0; /* Section index table always write zero */
2119 saa_write32(symtab_shndx
, shndx
);
2125 static void elf32_sym(const struct elf_symbol
*sym
)
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
)
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
;
2157 symtab
= saa_init(1);
2158 symtab_shndx
= NULL
;
2161 * Zero symbol first as required by spec.
2167 * Next, an entry for the file name.
2171 xsym
.type
= ELF32_ST_INFO(STB_LOCAL
, STT_FILE
);
2172 xsym
.section
= XSHN_ABS
;
2176 * Now some standard symbols defining the segments, for relocation
2180 for (i
= 1; i
<= nsects
; i
++) {
2181 xsym
.type
= ELF64_ST_INFO(STB_LOCAL
, STT_SECTION
);
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
;
2195 dwarf_abbrevsym
= nsyms
;
2196 xsym
.section
= sec_debug_abbrev
;
2199 dwarf_linesym
= nsyms
;
2200 xsym
.section
= sec_debug_line
;
2205 * Now the other local symbols.
2208 while ((sym
= saa_rstruct(syms
))) {
2209 if (!sym_type_local(sym
->type
))
2218 * Now the global symbols.
2221 while ((sym
= saa_rstruct(syms
))) {
2222 if (sym_type_local(sym
->type
))
2231 static struct SAA
*elf32_build_reltab(const struct elf_reloc
*r
)
2234 int32_t global_offset
;
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;
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
);
2265 static struct SAA
*elfx32_build_reltab(const struct elf_reloc
*r
)
2268 int32_t global_offset
;
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;
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
);
2300 static struct SAA
*elf64_build_reltab(const struct elf_reloc
*r
)
2303 int32_t global_offset
;
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;
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
);
2335 static void elf_section_header(int name
, int type
, uint64_t flags
,
2336 void *data
, bool is_saa
, uint64_t datalen
,
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
;
2348 shdr
.sh_name
= cpu_to_le32(name
);
2349 shdr
.sh_type
= cpu_to_le32(type
);
2350 shdr
.sh_flags
= cpu_to_le32(flags
);
2352 shdr
.sh_offset
= cpu_to_le32(type
== SHT_NULL
? 0 : elf_foffs
);
2353 shdr
.sh_size
= cpu_to_le32(datalen
);
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
);
2365 shdr
.sh_name
= cpu_to_le32(name
);
2366 shdr
.sh_type
= cpu_to_le32(type
);
2367 shdr
.sh_flags
= cpu_to_le64(flags
);
2369 shdr
.sh_offset
= cpu_to_le64(type
== SHT_NULL
? 0 : elf_foffs
);
2370 shdr
.sh_size
= cpu_to_le64(datalen
);
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)
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
);
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
);
2404 static void elf_sect_writeaddr(struct elf_section
*sect
, int64_t data
, size_t len
)
2406 saa_writeaddr(sect
->data
, data
, 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
))
2418 if (value
> s
->align
)
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
[] =
2428 { NULL
, NULL
} /* Implements the canonical output name */
2432 static const struct dfmt elf32_df_dwarf
= {
2433 "ELF32 (i386) dwarf (newer)",
2437 null_debug_deflabel
,
2438 null_debug_directive
,
2442 NULL
/* pragma list */
2445 static const struct dfmt elf32_df_stabs
= {
2446 "ELF32 (i386) stabs (older)",
2450 null_debug_deflabel
,
2451 null_debug_directive
,
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)",
2472 nasm_do_legacy_output
,
2484 static const struct dfmt elf64_df_dwarf
= {
2485 "ELF64 (x86-64) dwarf (newer)",
2489 null_debug_deflabel
,
2490 null_debug_directive
,
2494 NULL
/* pragma list */
2497 static const struct dfmt elf64_df_stabs
= {
2498 "ELF64 (x86-64) stabs (older)",
2502 null_debug_deflabel
,
2503 null_debug_directive
,
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)",
2524 nasm_do_legacy_output
,
2536 static const struct dfmt elfx32_df_dwarf
= {
2537 "ELFx32 (x86-64) dwarf (newer)",
2541 null_debug_deflabel
,
2542 null_debug_directive
,
2546 NULL
/* pragma list */
2549 static const struct dfmt elfx32_df_stabs
= {
2550 "ELFx32 (x86-64) stabs (older)",
2554 null_debug_deflabel
,
2555 null_debug_directive
,
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)",
2576 nasm_do_legacy_output
,
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
)) {
2668 stype
= STT_SECTION
;
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
)
2694 if (!stabs_filename
) {
2695 stabs_filename
= nasm_malloc(strlen(filename
) + 1);
2696 strcpy(stabs_filename
, filename
);
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
);
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 */
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
;
2731 stabslines
->last
->next
= el
;
2732 stabslines
->last
= el
;
2735 stabslines
->last
= el
;
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
;
2751 struct linelist
*ptr
;
2755 allfiles
= nasm_zalloc(numlinestabs
* sizeof(char *));
2758 if (numfiles
== 0) {
2759 allfiles
[0] = ptr
->filename
;
2762 for (i
= 0; i
< numfiles
; i
++) {
2763 if (!strcmp(allfiles
[i
], ptr
->filename
))
2766 if (i
>= numfiles
) {
2767 allfiles
[i
] = ptr
->filename
;
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
;
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));
2798 for (i
= 0; i
< numfiles
; i
++)
2799 strcpy((char *)ssbuf
+ fileidx
[i
], allfiles
[i
]);
2802 stabstrlen
= strsize
; /* set global variable for length of stab strings */
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
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
);
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);
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
))
2852 WRITE_STAB(sptr
, fileidx
[currfile
], N_SOL
, 0, 0,
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
);
2864 /* relocation table entry */
2865 WRITELONG(rptr
, (sptr
- sbuf
) - 4);
2866 WRITELONG(rptr
, ((ptr
->info
.section
+ 2) << 8) | R_386_32
);
2870 } else if (is_elfx32()) {
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
))
2878 WRITE_STAB(sptr
, fileidx
[currfile
], N_SOL
, 0, 0,
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
);
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
);
2899 nasm_assert(is_elf64());
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
))
2907 WRITE_STAB(sptr
, fileidx
[currfile
], N_SOL
, 0, 0,
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
);
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
);
2931 /* this is an "ending" token */
2932 WRITE_STAB(sptr
, 0, N_SO
, 0, 0, 0);
2935 ((struct stabentry
*)sbuf
)->n_desc
= numstabs
;
2937 nasm_free(allfiles
);
2940 stablen
= (sptr
- sbuf
);
2941 stabrellen
= (rptr
- rbuf
);
2947 static void stabs_cleanup(void)
2949 struct linelist
*ptr
, *del
;
2961 nasm_free(stabrelbuf
);
2962 nasm_free(stabstrbuf
);
2965 /* dwarf routines */
2967 static void dwarf_init_common(const struct dwarf_format
*fmt
)
2970 ndebugs
= 3; /* 3 debug symbols */
2973 static void dwarf32_init(void)
2975 static const struct dwarf_format dwfmt32
= {
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
= {
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
= {
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
,
3034 dwarf_findfile(filename
);
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
;
3048 s
= (struct symlininfo
*)param
;
3050 /* line number info is only gathered for executable sections */
3051 if (!(sects
[s
->section
]->flags
& SHF_EXECINSTR
))
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 */
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 */
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
);
3080 saa_write8(plinep
,DW_LNS_advance_line
);
3081 saa_wleb128s(plinep
,ln
);
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 */
3097 static void dwarf_generate(void)
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
;
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
;
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
);
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
;
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
);
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
;
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
);
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 */
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
);
3265 /* Don't write a section without actual information */
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
);
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
);
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
);
3389 /* build rela.info section */
3390 inforellen
= saalen
= pinforel
->datalen
;
3391 inforelbuf
= pbuf
= nasm_malloc(inforellen
);
3392 saa_rnbytes(pinforel
, pbuf
, saalen
);
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
);
3430 /* build line section */
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 */
3471 saa_rnbytes(plines
, pbuf
, saalen
); /* read a given no. of bytes */
3474 /* concatonate line program ranges */
3476 plinesrel
= saa_init(1L);
3477 psect
= dwarf_fsect
;
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
);
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
);
3503 /* done with this entry */
3504 psect
= psect
->next
;
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
);
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 */
3532 framebuf
= pbuf
= nasm_malloc(framelen
);
3533 WRITELONG(pbuf
,framelen
-4); /* initial length */
3535 /* Leave .debug_frame empty if not used! */
3539 /* build .debug_loc section */
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 */
3547 nasm_assert(is_elf64());
3548 WRITEDLONG(pbuf
,0); /* null beginning offset */
3549 WRITEDLONG(pbuf
,0); /* null ending offset */
3552 /* Leave .debug_frame empty if not used! */
3557 static void dwarf_cleanup(void)
3559 nasm_free(arangesbuf
);
3560 nasm_free(arangesrelbuf
);
3561 nasm_free(pubnamesbuf
);
3563 nasm_free(inforelbuf
);
3564 nasm_free(abbrevbuf
);
3566 nasm_free(linerelbuf
);
3567 nasm_free(framebuf
);
3571 static void dwarf_findfile(const char * fname
)
3574 struct linelist
*match
;
3576 /* return if fname is current file name */
3577 if (dwarf_clist
&& !(strcmp(fname
, dwarf_clist
->filename
)))
3580 /* search for match */
3583 match
= dwarf_flist
;
3584 for (finx
= 0; finx
< dwarf_numfiles
; finx
++) {
3585 if (!(strcmp(fname
, match
->filename
))) {
3586 dwarf_clist
= match
;
3589 match
= match
->next
;
3593 /* add file name to end of list */
3594 dwarf_clist
= nasm_malloc(sizeof(struct linelist
));
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
)
3612 struct sectlist
*match
;
3615 /* return if index is current section index */
3616 if (dwarf_csect
&& (dwarf_csect
->section
== index
))
3619 /* search for match */
3622 match
= dwarf_fsect
;
3623 for (sinx
= 0; sinx
< dwarf_nsections
; sinx
++) {
3624 if (match
->section
== index
) {
3625 dwarf_csect
= match
;
3628 match
= match
->next
;
3632 /* add entry to end of list */
3633 dwarf_csect
= nasm_malloc(sizeof(struct sectlist
));
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
);
3646 saa_write64(plinep
,0); /* Start Address */
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) */