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 */
179 static void dwarf_init(void);
180 static void dwarf_linenum(const char *filename
, int32_t linenumber
, int32_t);
181 static void dwarf_output(int, void *);
182 static void dwarf_generate(void);
183 static void dwarf_cleanup(void);
184 static void dwarf_findfile(const char *);
185 static void dwarf_findsect(const int);
187 struct elf_format_info
{
188 size_t word
; /* Word size (4 or 8) */
189 size_t ehdr_size
; /* Size of the ELF header */
190 size_t shdr_size
; /* Size of a section header */
191 size_t sym_size
; /* Size of a symbol */
192 size_t rel_size
; /* Size of a reltype relocation */
193 size_t rela_size
; /* Size of a RELA relocation */
194 char relpfx
[8]; /* Relocation section prefix */
195 uint32_t reltype
; /* Relocation section type */
196 uint16_t e_machine
; /* Header e_machine field */
197 uint8_t ei_class
; /* ELFCLASS32 or ELFCLASS64 */
198 bool elf64
; /* 64-bit ELF */
201 void (*elf_sym
)(const struct elf_symbol
*);
203 /* Build a relocation table */
204 struct SAA
*(*elf_build_reltab
)(const struct elf_reloc
*);
206 static const struct elf_format_info
*efmt
;
208 static void elf32_sym(const struct elf_symbol
*sym
);
209 static void elf64_sym(const struct elf_symbol
*sym
);
211 static struct SAA
*elf32_build_reltab(const struct elf_reloc
*r
);
212 static struct SAA
*elfx32_build_reltab(const struct elf_reloc
*r
);
213 static struct SAA
*elf64_build_reltab(const struct elf_reloc
*r
);
215 static bool dfmt_is_stabs(void);
216 static bool dfmt_is_dwarf(void);
219 * Special NASM section numbers which are used to define ELF special
222 static int32_t elf_gotpc_sect
, elf_gotoff_sect
;
223 static int32_t elf_got_sect
, elf_plt_sect
;
224 static int32_t elf_sym_sect
, elf_gottpoff_sect
, elf_tlsie_sect
;
226 uint8_t elf_osabi
= 0; /* Default OSABI = 0 (System V or Linux) */
227 uint8_t elf_abiver
= 0; /* Current ABI version */
229 /* Known sections with nonstandard defaults. -n means n*pointer size. */
230 struct elf_known_section
{
231 const char *name
; /* Name of section */
232 int type
; /* Section type (SHT_) */
233 uint32_t flags
; /* Section flags (SHF_) */
234 int align
; /* Section alignment */
235 int entsize
; /* Entry size, if applicable */
238 static const struct elf_known_section elf_known_sections
[] = {
239 { ".text", SHT_PROGBITS
, SHF_ALLOC
|SHF_EXECINSTR
, 16, 0 },
240 { ".rodata", SHT_PROGBITS
, SHF_ALLOC
, 4, 0 },
241 { ".lrodata", SHT_PROGBITS
, SHF_ALLOC
, 4, 0 },
242 { ".data", SHT_PROGBITS
, SHF_ALLOC
|SHF_WRITE
, 4, 0 },
243 { ".ldata", SHT_PROGBITS
, SHF_ALLOC
|SHF_WRITE
, 4, 0 },
244 { ".bss", SHT_NOBITS
, SHF_ALLOC
|SHF_WRITE
, 4, 0 },
245 { ".lbss", SHT_NOBITS
, SHF_ALLOC
|SHF_WRITE
, 4, 0 },
246 { ".tdata", SHT_PROGBITS
, SHF_ALLOC
|SHF_WRITE
|SHF_TLS
, 4, 0 },
247 { ".tbss", SHT_NOBITS
, SHF_ALLOC
|SHF_WRITE
|SHF_TLS
, 4, 0 },
248 { ".comment", SHT_PROGBITS
, 0, 1, 0 },
249 { ".preinit_array", SHT_PREINIT_ARRAY
, SHF_ALLOC
, -1, -1 },
250 { ".init_array", SHT_INIT_ARRAY
, SHF_ALLOC
, -1, -1 },
251 { ".fini_array", SHT_FINI_ARRAY
, SHF_ALLOC
, -1, -1 },
252 { ".note", SHT_NOTE
, 0, 4, 0 },
253 { NULL
/*default*/, SHT_PROGBITS
, SHF_ALLOC
, 1, 0 }
261 static const struct size_unit size_units
[] =
273 { "pointer", -1, -1 },
277 static inline size_t to_bytes(int val
)
279 return (val
>= 0) ? (size_t)val
: -val
* efmt
->word
;
282 /* parse section attributes */
283 static void elf_section_attrib(char *name
, char *attr
, uint32_t *flags_and
, uint32_t *flags_or
,
284 uint64_t *alignp
, uint64_t *entsize
, int *type
)
286 char *opt
, *val
, *next
;
290 opt
= nasm_skip_spaces(attr
);
294 while ((opt
= nasm_opt_val(opt
, &val
, &next
))) {
295 if (!nasm_stricmp(opt
, "align")) {
297 nasm_nonfatal("section align without value specified");
300 uint64_t a
= readnum(val
, &err
);
301 if (a
&& !is_power2(a
)) {
302 nasm_error(ERR_NONFATAL
,
303 "section alignment %"PRId64
" is not a power of two",
305 } else if (a
> align
) {
309 } else if (!nasm_stricmp(opt
, "alloc")) {
310 *flags_and
|= SHF_ALLOC
;
311 *flags_or
|= SHF_ALLOC
;
312 } else if (!nasm_stricmp(opt
, "noalloc")) {
313 *flags_and
|= SHF_ALLOC
;
314 *flags_or
&= ~SHF_ALLOC
;
315 } else if (!nasm_stricmp(opt
, "exec")) {
316 *flags_and
|= SHF_EXECINSTR
;
317 *flags_or
|= SHF_EXECINSTR
;
318 } else if (!nasm_stricmp(opt
, "noexec")) {
319 *flags_and
|= SHF_EXECINSTR
;
320 *flags_or
&= ~SHF_EXECINSTR
;
321 } else if (!nasm_stricmp(opt
, "write")) {
322 *flags_and
|= SHF_WRITE
;
323 *flags_or
|= SHF_WRITE
;
324 } else if (!nasm_stricmp(opt
, "nowrite") ||
325 !nasm_stricmp(opt
, "readonly")) {
326 *flags_and
|= SHF_WRITE
;
327 *flags_or
&= ~SHF_WRITE
;
328 } else if (!nasm_stricmp(opt
, "tls")) {
329 *flags_and
|= SHF_TLS
;
330 *flags_or
|= SHF_TLS
;
331 } else if (!nasm_stricmp(opt
, "notls")) {
332 *flags_and
|= SHF_TLS
;
333 *flags_or
&= ~SHF_TLS
;
334 } else if (!nasm_stricmp(opt
, "merge")) {
335 *flags_and
|= SHF_MERGE
;
336 *flags_or
|= SHF_MERGE
;
337 } else if (!nasm_stricmp(opt
, "nomerge")) {
338 *flags_and
|= SHF_MERGE
;
339 *flags_or
&= ~SHF_MERGE
;
340 } else if (!nasm_stricmp(opt
, "strings")) {
341 *flags_and
|= SHF_STRINGS
;
342 *flags_or
|= SHF_STRINGS
;
343 } else if (!nasm_stricmp(opt
, "nostrings")) {
344 *flags_and
|= SHF_STRINGS
;
345 *flags_or
&= ~SHF_STRINGS
;
346 } else if (!nasm_stricmp(opt
, "progbits")) {
347 *type
= SHT_PROGBITS
;
348 } else if (!nasm_stricmp(opt
, "nobits")) {
350 } else if (!nasm_stricmp(opt
, "note")) {
352 } else if (!nasm_stricmp(opt
, "preinit_array")) {
353 *type
= SHT_PREINIT_ARRAY
;
354 } else if (!nasm_stricmp(opt
, "init_array")) {
355 *type
= SHT_INIT_ARRAY
;
356 } else if (!nasm_stricmp(opt
, "fini_array")) {
357 *type
= SHT_FINI_ARRAY
;
361 const char *a
= strchr(opt
, '*');
363 const struct size_unit
*su
;
367 mult
= readnum(a
+1, &err
);
373 for (su
= size_units
; su
->bytes
; su
++) {
374 if (!nasm_strnicmp(opt
, su
->name
, l
))
379 *entsize
= to_bytes(su
->bytes
) * mult
;
380 xalign
= to_bytes(su
->align
);
382 /* Unknown attribute */
383 nasm_warn(WARN_OTHER
,
384 "unknown section attribute '%s' ignored on"
385 " declaration of section `%s'", opt
, name
);
392 case SHT_PREINIT_ARRAY
:
398 *entsize
= efmt
->word
;
412 static enum directive_result
413 elf_directive(enum directive directive
, char *value
)
421 if (!pass_first()) /* XXX: Why? */
424 n
= readnum(value
, &err
);
426 nasm_nonfatal("`osabi' directive requires a parameter");
430 if (n
< 0 || n
> 255) {
431 nasm_nonfatal("valid osabi numbers are 0 to 255");
438 p
= strchr(value
,',');
442 n
= readnum(p
+ 1, &err
);
443 if (err
|| n
< 0 || n
> 255) {
444 nasm_nonfatal("invalid ABI version number (valid: 0 to 255)");
456 static void elf_init(void);
458 static void elf32_init(void)
460 static const struct elf_format_info ef_elf32
= {
480 static void elfx32_init(void)
482 static const struct elf_format_info ef_elfx32
= {
502 static void elf64_init(void)
504 static const struct elf_format_info ef_elf64
= {
524 static void elf_init(void)
526 static const char * const reserved_sections
[] = {
527 ".shstrtab", ".strtab", ".symtab", ".symtab_shndx", NULL
529 const char * const *p
;
531 strlcpy(elf_module
, inname
, sizeof(elf_module
));
533 nsects
= sectlen
= 0;
534 syms
= saa_init((int32_t)sizeof(struct elf_symbol
));
535 nlocals
= nglobs
= ndebugs
= 0;
538 saa_wbytes(strs
, "\0", 1L);
539 saa_wbytes(strs
, elf_module
, strlen(elf_module
)+1);
540 strslen
= 2 + strlen(elf_module
);
542 shstrtablen
= shstrtabsize
= 0;;
543 add_sectname("", ""); /* SHN_UNDEF */
547 section_by_index
= raa_init();
550 * Add reserved section names to the section hash, with NULL
551 * as the data pointer
553 for (p
= reserved_sections
; *p
; p
++) {
554 struct hash_insert hi
;
555 hash_find(§ion_by_name
, *p
, &hi
);
556 hash_add(&hi
, *p
, NULL
);
560 * FIXME: tlsie is Elf32 only and
561 * gottpoff is Elfx32|64 only.
563 elf_gotpc_sect
= seg_alloc();
564 backend_label("..gotpc", elf_gotpc_sect
+ 1, 0L);
565 elf_gotoff_sect
= seg_alloc();
566 backend_label("..gotoff", elf_gotoff_sect
+ 1, 0L);
567 elf_got_sect
= seg_alloc();
568 backend_label("..got", elf_got_sect
+ 1, 0L);
569 elf_plt_sect
= seg_alloc();
570 backend_label("..plt", elf_plt_sect
+ 1, 0L);
571 elf_sym_sect
= seg_alloc();
572 backend_label("..sym", elf_sym_sect
+ 1, 0L);
573 elf_gottpoff_sect
= seg_alloc();
574 backend_label("..gottpoff", elf_gottpoff_sect
+ 1, 0L);
575 elf_tlsie_sect
= seg_alloc();
576 backend_label("..tlsie", elf_tlsie_sect
+ 1, 0L);
578 def_seg
= seg_alloc();
581 static void elf_cleanup(void)
587 for (i
= 0; i
< nsects
; i
++) {
588 if (sects
[i
]->type
!= SHT_NOBITS
)
589 saa_free(sects
[i
]->data
);
591 saa_free(sects
[i
]->rel
);
592 while (sects
[i
]->head
) {
594 sects
[i
]->head
= sects
[i
]->head
->next
;
598 hash_free(§ion_by_name
);
599 raa_free(section_by_index
);
608 * Add entry to the elf .shstrtab section and increment nsections.
609 * Returns the section index for this new section.
611 * IMPORTANT: this needs to match the order the section headers are
614 static int add_sectname(const char *firsthalf
, const char *secondhalf
)
616 int l1
= strlen(firsthalf
);
617 int l2
= strlen(secondhalf
);
619 while (shstrtablen
+ l1
+ l2
+ 1 > shstrtabsize
)
620 shstrtab
= nasm_realloc(shstrtab
, (shstrtabsize
+= SHSTR_DELTA
));
622 memcpy(shstrtab
+ shstrtablen
, firsthalf
, l1
);
624 memcpy(shstrtab
+ shstrtablen
, secondhalf
, l2
+1);
625 shstrtablen
+= l2
+ 1;
630 static struct elf_section
*
631 elf_make_section(char *name
, int type
, int flags
, uint64_t align
)
633 struct elf_section
*s
;
635 s
= nasm_zalloc(sizeof(*s
));
637 if (type
!= SHT_NOBITS
)
638 s
->data
= saa_init(1L);
640 if (!strcmp(name
, ".text"))
643 s
->index
= seg_alloc();
645 s
->name
= nasm_strdup(name
);
649 s
->shndx
= add_sectname("", name
);
651 if (nsects
>= sectlen
)
652 sects
= nasm_realloc(sects
, (sectlen
+= SECT_DELTA
) * sizeof(*sects
));
658 static int32_t elf_section_names(char *name
, int *bits
)
661 uint32_t flags
, flags_and
, flags_or
;
662 uint64_t align
, entsize
;
664 struct elf_section
*s
;
665 struct hash_insert hi
;
669 *bits
= ofmt
->maxbits
;
673 p
= nasm_skip_word(name
);
676 flags_and
= flags_or
= type
= align
= entsize
= 0;
678 elf_section_attrib(name
, p
, &flags_and
, &flags_or
, &align
, &entsize
, &type
);
680 hp
= hash_find(§ion_by_name
, name
, &hi
);
684 nasm_nonfatal("attempt to redefine reserved section name `%s'", name
);
688 const struct elf_known_section
*ks
= elf_known_sections
;
691 if (!strcmp(name
, ks
->name
))
696 type
= type
? type
: ks
->type
;
698 align
= to_bytes(ks
->align
);
700 entsize
= to_bytes(ks
->entsize
);
701 flags
= (ks
->flags
& ~flags_and
) | flags_or
;
703 s
= elf_make_section(name
, type
, flags
, align
);
704 hash_add(&hi
, s
->name
, s
);
705 section_by_index
= raa_write_ptr(section_by_index
, s
->index
>> 1, s
);
708 if ((type
&& s
->type
!= type
)
709 || ((s
->flags
& flags_and
) != flags_or
)
710 || (entsize
&& s
->entsize
&& entsize
!= s
->entsize
)) {
711 nasm_warn(WARN_OTHER
, "incompatible section attributes ignored on"
712 " redeclaration of section `%s'", name
);
715 if (align
> s
->align
)
718 if (entsize
&& !s
->entsize
)
719 s
->entsize
= entsize
;
721 if ((flags_or
& SHF_MERGE
) && s
->entsize
== 0) {
722 if (!(s
->flags
& SHF_STRINGS
))
723 nasm_nonfatal("section attribute merge specified without an entry size or `strings'");
730 static void elf_deflabel(char *name
, int32_t segment
, int64_t offset
,
731 int is_global
, char *special
)
734 struct elf_symbol
*sym
;
735 bool special_used
= false;
737 #if defined(DEBUG) && DEBUG>2
738 nasm_debug(" elf_deflabel: %s, seg=%"PRIx32
", off=%"PRIx64
", is_global=%d, %s\n",
739 name
, segment
, offset
, is_global
, special
);
741 if (name
[0] == '.' && name
[1] == '.' && name
[2] != '@') {
743 * This is a NASM special symbol. We never allow it into
744 * the ELF symbol table, even if it's a valid one. If it
745 * _isn't_ a valid one, we should barf immediately.
747 * FIXME: tlsie is Elf32 only, and gottpoff is Elfx32|64 only.
749 if (strcmp(name
, "..gotpc") && strcmp(name
, "..gotoff") &&
750 strcmp(name
, "..got") && strcmp(name
, "..plt") &&
751 strcmp(name
, "..sym") && strcmp(name
, "..gottpoff") &&
752 strcmp(name
, "..tlsie"))
753 nasm_nonfatal("unrecognised special symbol `%s'", name
);
757 if (is_global
== 3) {
758 struct elf_symbol
**s
;
760 * Fix up a forward-reference symbol size from the first
763 for (s
= &fwds
; *s
; s
= &(*s
)->nextfwd
)
764 if (!strcmp((*s
)->name
, name
)) {
765 struct tokenval tokval
;
767 char *p
= nasm_skip_spaces(nasm_skip_word(special
));
771 tokval
.t_type
= TOKEN_INVALID
;
772 e
= evaluate(stdscan
, NULL
, &tokval
, NULL
, 1, NULL
);
775 nasm_nonfatal("cannot use relocatable"
776 " expression as symbol size");
778 (*s
)->size
= reloc_value(e
);
782 * Remove it from the list of unresolved sizes.
784 nasm_free((*s
)->name
);
788 return; /* it wasn't an important one */
791 saa_wbytes(strs
, name
, (int32_t)(1 + strlen(name
)));
792 strslen
+= 1 + strlen(name
);
794 lastsym
= sym
= saa_wstruct(syms
);
796 memset(&sym
->symv
, 0, sizeof(struct rbtree
));
799 sym
->type
= is_global
? SYM_GLOBAL
: SYM_LOCAL
;
800 sym
->other
= STV_DEFAULT
;
802 if (segment
== NO_SEG
)
803 sym
->section
= XSHN_ABS
;
805 const struct elf_section
*s
;
806 sym
->section
= XSHN_UNDEF
;
807 if (segment
== def_seg
) {
808 /* we have to be sure at least text section is there */
810 if (segment
!= elf_section_names(".text", &tempint
))
811 nasm_panic("strange segment conditions in ELF driver");
813 s
= raa_read_ptr(section_by_index
, segment
>> 1);
815 sym
->section
= s
->shndx
;
818 if (is_global
== 2) {
821 sym
->section
= XSHN_COMMON
;
823 * We have a common variable. Check the special text to see
824 * if it's a valid number and power of two; if so, store it
825 * as the alignment for the common variable.
829 sym
->symv
.key
= readnum(special
, &err
);
831 nasm_nonfatal("alignment constraint `%s' is not a"
832 " valid number", special
);
833 else if ((sym
->symv
.key
| (sym
->symv
.key
- 1)) != 2 * sym
->symv
.key
- 1)
834 nasm_nonfatal("alignment constraint `%s' is not a"
835 " power of two", special
);
839 sym
->symv
.key
= (sym
->section
== XSHN_UNDEF
? 0 : offset
);
841 if (sym
->type
== SYM_GLOBAL
) {
843 * If sym->section == SHN_ABS, then the first line of the
844 * else section would cause a core dump, because its a reference
845 * beyond the end of the section array.
846 * This behaviour is exhibited by this code:
849 * To avoid such a crash, such requests are silently discarded.
850 * This may not be the best solution.
852 if (sym
->section
== XSHN_UNDEF
|| sym
->section
== XSHN_COMMON
) {
853 bsym
= raa_write(bsym
, segment
, nglobs
);
854 } else if (sym
->section
!= XSHN_ABS
) {
856 * This is a global symbol; so we must add it to the rbtree
857 * of global symbols in its section.
859 * In addition, we check the special text for symbol
860 * type and size information.
862 sects
[sym
->section
-1]->gsyms
=
863 rb_insert(sects
[sym
->section
-1]->gsyms
, &sym
->symv
);
866 int n
= strcspn(special
, " \t");
868 if (!nasm_strnicmp(special
, "function", n
))
869 sym
->type
|= STT_FUNC
;
870 else if (!nasm_strnicmp(special
, "data", n
) ||
871 !nasm_strnicmp(special
, "object", n
))
872 sym
->type
|= STT_OBJECT
;
873 else if (!nasm_strnicmp(special
, "notype", n
))
874 sym
->type
|= STT_NOTYPE
;
876 nasm_nonfatal("unrecognised symbol type `%.*s'",
880 special
= nasm_skip_spaces(special
);
882 n
= strcspn(special
, " \t");
883 if (!nasm_strnicmp(special
, "default", n
))
884 sym
->other
= STV_DEFAULT
;
885 else if (!nasm_strnicmp(special
, "internal", n
))
886 sym
->other
= STV_INTERNAL
;
887 else if (!nasm_strnicmp(special
, "hidden", n
))
888 sym
->other
= STV_HIDDEN
;
889 else if (!nasm_strnicmp(special
, "protected", n
))
890 sym
->other
= STV_PROTECTED
;
897 struct tokenval tokval
;
900 char *saveme
= stdscan_get();
902 while (special
[n
] && nasm_isspace(special
[n
]))
905 * We have a size expression; attempt to
909 stdscan_set(special
+ n
);
910 tokval
.t_type
= TOKEN_INVALID
;
911 e
= evaluate(stdscan
, NULL
, &tokval
, &fwd
, 0, NULL
);
915 sym
->name
= nasm_strdup(name
);
918 nasm_nonfatal("cannot use relocatable"
919 " expression as symbol size");
921 sym
->size
= reloc_value(e
);
928 * If TLS segment, mark symbol accordingly.
930 if (sects
[sym
->section
- 1]->flags
& SHF_TLS
) {
932 sym
->type
|= STT_TLS
;
935 sym
->globnum
= nglobs
;
940 if (special
&& !special_used
)
941 nasm_nonfatal("no special symbol features supported here");
944 static void elf_add_reloc(struct elf_section
*sect
, int32_t segment
,
945 int64_t offset
, int type
)
949 r
= *sect
->tail
= nasm_zalloc(sizeof(struct elf_reloc
));
950 sect
->tail
= &r
->next
;
952 r
->address
= sect
->len
;
955 if (segment
!= NO_SEG
) {
956 const struct elf_section
*s
;
957 s
= raa_read_ptr(section_by_index
, segment
>> 1);
959 r
->symbol
= s
->shndx
+ 1;
961 r
->symbol
= GLOBAL_TEMP_BASE
+ raa_read(bsym
, segment
);
969 * This routine deals with ..got and ..sym relocations: the more
970 * complicated kinds. In shared-library writing, some relocations
971 * with respect to global symbols must refer to the precise symbol
972 * rather than referring to an offset from the base of the section
973 * _containing_ the symbol. Such relocations call to this routine,
974 * which searches the symbol list for the symbol in question.
976 * R_386_GOT32 | R_X86_64_GOT32 references require the _exact_ symbol address to be
977 * used; R_386_32 | R_X86_64_32 references can be at an offset from the symbol.
978 * The boolean argument `exact' tells us this.
980 * Return value is the adjusted value of `addr', having become an
981 * offset from the symbol rather than the section. Should always be
982 * zero when returning from an exact call.
984 * Limitation: if you define two symbols at the same place,
985 * confusion will occur.
987 * Inefficiency: we search, currently, using a linked list which
988 * isn't even necessarily sorted.
990 static int64_t elf_add_gsym_reloc(struct elf_section
*sect
,
991 int32_t segment
, uint64_t offset
,
992 int64_t pcrel
, int type
, bool exact
)
995 struct elf_section
*s
;
996 struct elf_symbol
*sym
;
1000 * First look up the segment/offset pair and find a global
1001 * symbol corresponding to it. If it's not one of our segments,
1002 * then it must be an external symbol, in which case we're fine
1003 * doing a normal elf_add_reloc after first sanity-checking
1004 * that the offset from the symbol is zero.
1006 s
= raa_read_ptr(section_by_index
, segment
>> 1);
1008 if (exact
&& offset
)
1009 nasm_nonfatal("invalid access to an external symbol");
1011 elf_add_reloc(sect
, segment
, offset
- pcrel
, type
);
1015 srb
= rb_search(s
->gsyms
, offset
);
1016 if (!srb
|| (exact
&& srb
->key
!= offset
)) {
1017 nasm_nonfatal("unable to find a suitable global symbol"
1018 " for this reference");
1021 sym
= container_of(srb
, struct elf_symbol
, symv
);
1023 r
= *sect
->tail
= nasm_malloc(sizeof(struct elf_reloc
));
1024 sect
->tail
= &r
->next
;
1027 r
->address
= sect
->len
;
1028 r
->offset
= offset
- pcrel
- sym
->symv
.key
;
1029 r
->symbol
= GLOBAL_TEMP_BASE
+ sym
->globnum
;
1036 static void elf32_out(int32_t segto
, const void *data
,
1037 enum out_type type
, uint64_t size
,
1038 int32_t segment
, int32_t wrt
)
1040 struct elf_section
*s
;
1043 static struct symlininfo sinfo
;
1046 * handle absolute-assembly (structure definitions)
1048 if (segto
== NO_SEG
) {
1049 if (type
!= OUT_RESERVE
)
1050 nasm_nonfatal("attempt to assemble code in [ABSOLUTE] space");
1054 s
= raa_read_ptr(section_by_index
, segto
>> 1);
1056 int tempint
; /* ignored */
1057 if (segto
!= elf_section_names(".text", &tempint
))
1058 nasm_panic("strange segment conditions in ELF driver");
1060 s
= sects
[nsects
- 1];
1063 /* again some stabs debugging stuff */
1064 sinfo
.offset
= s
->len
;
1065 sinfo
.section
= s
->shndx
;
1066 sinfo
.segto
= segto
;
1067 sinfo
.name
= s
->name
;
1068 dfmt
->debug_output(TY_DEBUGSYMLIN
, &sinfo
);
1069 /* end of debugging stuff */
1071 if (s
->type
== SHT_NOBITS
&& type
!= OUT_RESERVE
) {
1072 nasm_warn(WARN_OTHER
, "attempt to initialize memory in"
1073 " BSS section `%s': ignored", s
->name
);
1074 s
->len
+= realsize(type
, size
);
1080 if (s
->type
!= SHT_NOBITS
) {
1081 nasm_warn(WARN_ZEROING
, "uninitialized space declared in"
1082 " non-BSS section `%s': zeroing", s
->name
);
1083 elf_sect_write(s
, NULL
, size
);
1089 elf_sect_write(s
, data
, size
);
1095 int asize
= abs((int)size
);
1097 addr
= *(int64_t *)data
;
1098 if (segment
!= NO_SEG
) {
1100 nasm_nonfatal("ELF format does not support"
1101 " segment base references");
1103 if (wrt
== NO_SEG
) {
1105 * The if() is a hack to deal with compilers which
1106 * don't handle switch() statements with 64-bit
1111 elf_add_reloc(s
, segment
, 0, R_386_8
);
1114 elf_add_reloc(s
, segment
, 0, R_386_16
);
1117 elf_add_reloc(s
, segment
, 0, R_386_32
);
1119 default: /* Error issued further down */
1123 } else if (wrt
== elf_gotpc_sect
+ 1) {
1125 * The user will supply GOT relative to $$. ELF
1126 * will let us have GOT relative to $. So we
1127 * need to fix up the data item by $-$$.
1131 elf_add_reloc(s
, segment
, 0, R_386_GOTPC
);
1132 } else if (wrt
== elf_gotoff_sect
+ 1) {
1134 elf_add_reloc(s
, segment
, 0, R_386_GOTOFF
);
1135 } else if (wrt
== elf_tlsie_sect
+ 1) {
1137 addr
= elf_add_gsym_reloc(s
, segment
, addr
, 0,
1138 R_386_TLS_IE
, true);
1139 } else if (wrt
== elf_got_sect
+ 1) {
1141 addr
= elf_add_gsym_reloc(s
, segment
, addr
, 0,
1143 } else if (wrt
== elf_sym_sect
+ 1) {
1146 addr
= elf_add_gsym_reloc(s
, segment
, addr
, 0,
1150 addr
= elf_add_gsym_reloc(s
, segment
, addr
, 0,
1154 addr
= elf_add_gsym_reloc(s
, segment
, addr
, 0,
1161 } else if (wrt
== elf_plt_sect
+ 1) {
1162 nasm_nonfatal("ELF format cannot produce non-PC-"
1163 "relative PLT references");
1165 nasm_nonfatal("ELF format does not support this"
1167 wrt
= NO_SEG
; /* we can at least _try_ to continue */
1173 nasm_nonfatal("Unsupported %d-bit ELF relocation", asize
<< 3);
1175 elf_sect_writeaddr(s
, addr
, asize
);
1180 reltype
= R_386_PC8
;
1184 reltype
= R_386_PC16
;
1189 addr
= *(int64_t *)data
- size
;
1190 nasm_assert(segment
!= segto
);
1191 if (segment
!= NO_SEG
&& (segment
& 1)) {
1192 nasm_nonfatal("ELF format does not support"
1193 " segment base references");
1195 if (wrt
== NO_SEG
) {
1196 elf_add_reloc(s
, segment
, 0, reltype
);
1198 nasm_nonfatal("Unsupported %d-bit ELF relocation", bytes
<< 3);
1201 elf_sect_writeaddr(s
, addr
, bytes
);
1205 addr
= *(int64_t *)data
- size
;
1206 if (segment
== segto
)
1207 nasm_panic("intra-segment OUT_REL4ADR");
1208 if (segment
!= NO_SEG
&& (segment
& 1)) {
1209 nasm_nonfatal("ELF format does not support"
1210 " segment base references");
1212 if (wrt
== NO_SEG
) {
1213 elf_add_reloc(s
, segment
, 0, R_386_PC32
);
1214 } else if (wrt
== elf_plt_sect
+ 1) {
1215 elf_add_reloc(s
, segment
, 0, R_386_PLT32
);
1216 } else if (wrt
== elf_gotpc_sect
+ 1 ||
1217 wrt
== elf_gotoff_sect
+ 1 ||
1218 wrt
== elf_got_sect
+ 1) {
1219 nasm_nonfatal("ELF format cannot produce PC-"
1220 "relative GOT references");
1222 nasm_nonfatal("ELF format does not support this"
1224 wrt
= NO_SEG
; /* we can at least _try_ to continue */
1227 elf_sect_writeaddr(s
, addr
, 4);
1231 nasm_nonfatal("32-bit ELF format does not support 64-bit relocations");
1233 elf_sect_writeaddr(s
, addr
, 8);
1240 static void elf64_out(int32_t segto
, const void *data
,
1241 enum out_type type
, uint64_t size
,
1242 int32_t segment
, int32_t wrt
)
1244 struct elf_section
*s
;
1247 static struct symlininfo sinfo
;
1250 * handle absolute-assembly (structure definitions)
1252 if (segto
== NO_SEG
) {
1253 if (type
!= OUT_RESERVE
)
1254 nasm_nonfatal("attempt to assemble code in [ABSOLUTE] space");
1258 s
= raa_read_ptr(section_by_index
, segto
>> 1);
1260 int tempint
; /* ignored */
1261 if (segto
!= elf_section_names(".text", &tempint
))
1262 nasm_panic("strange segment conditions in ELF driver");
1264 s
= sects
[nsects
- 1];
1267 /* again some stabs debugging stuff */
1268 sinfo
.offset
= s
->len
;
1269 sinfo
.section
= s
->shndx
;
1270 sinfo
.segto
= segto
;
1271 sinfo
.name
= s
->name
;
1272 dfmt
->debug_output(TY_DEBUGSYMLIN
, &sinfo
);
1273 /* end of debugging stuff */
1275 if (s
->type
== SHT_NOBITS
&& type
!= OUT_RESERVE
) {
1276 nasm_warn(WARN_OTHER
, "attempt to initialize memory in"
1277 " BSS section `%s': ignored", s
->name
);
1278 s
->len
+= realsize(type
, size
);
1284 if (s
->type
!= SHT_NOBITS
) {
1285 nasm_warn(WARN_ZEROING
, "uninitialized space declared in"
1286 " non-BSS section `%s': zeroing", s
->name
);
1287 elf_sect_write(s
, NULL
, size
);
1293 if (segment
!= NO_SEG
)
1294 nasm_panic("OUT_RAWDATA with other than NO_SEG");
1295 elf_sect_write(s
, data
, size
);
1300 int isize
= (int)size
;
1301 int asize
= abs((int)size
);
1303 addr
= *(int64_t *)data
;
1304 if (segment
== NO_SEG
) {
1306 } else if (segment
& 1) {
1307 nasm_nonfatal("ELF format does not support"
1308 " segment base references");
1310 if (wrt
== NO_SEG
) {
1314 elf_add_reloc(s
, segment
, addr
, R_X86_64_8
);
1318 elf_add_reloc(s
, segment
, addr
, R_X86_64_16
);
1321 elf_add_reloc(s
, segment
, addr
, R_X86_64_32
);
1324 elf_add_reloc(s
, segment
, addr
, R_X86_64_32S
);
1328 elf_add_reloc(s
, segment
, addr
, R_X86_64_64
);
1331 nasm_panic("internal error elf64-hpa-871");
1335 } else if (wrt
== elf_gotpc_sect
+ 1) {
1337 * The user will supply GOT relative to $$. ELF
1338 * will let us have GOT relative to $. So we
1339 * need to fix up the data item by $-$$.
1342 elf_add_reloc(s
, segment
, addr
, R_X86_64_GOTPC32
);
1344 } else if (wrt
== elf_gotoff_sect
+ 1) {
1346 nasm_nonfatal("ELF64 requires ..gotoff "
1347 "references to be qword");
1349 elf_add_reloc(s
, segment
, addr
, R_X86_64_GOTOFF64
);
1352 } else if (wrt
== elf_got_sect
+ 1) {
1355 elf_add_gsym_reloc(s
, segment
, addr
, 0,
1356 R_X86_64_GOT32
, true);
1360 elf_add_gsym_reloc(s
, segment
, addr
, 0,
1361 R_X86_64_GOT64
, true);
1365 nasm_nonfatal("invalid ..got reference");
1368 } else if (wrt
== elf_sym_sect
+ 1) {
1372 elf_add_gsym_reloc(s
, segment
, addr
, 0,
1378 elf_add_gsym_reloc(s
, segment
, addr
, 0,
1379 R_X86_64_16
, false);
1383 elf_add_gsym_reloc(s
, segment
, addr
, 0,
1384 R_X86_64_32
, false);
1388 elf_add_gsym_reloc(s
, segment
, addr
, 0,
1389 R_X86_64_32S
, false);
1394 elf_add_gsym_reloc(s
, segment
, addr
, 0,
1395 R_X86_64_64
, false);
1399 nasm_panic("internal error elf64-hpa-903");
1402 } else if (wrt
== elf_plt_sect
+ 1) {
1403 nasm_nonfatal("ELF format cannot produce non-PC-"
1404 "relative PLT references");
1406 nasm_nonfatal("ELF format does not support this"
1410 elf_sect_writeaddr(s
, addr
, asize
);
1415 reltype
= R_X86_64_PC8
;
1420 reltype
= R_X86_64_PC16
;
1425 addr
= *(int64_t *)data
- size
;
1426 if (segment
== segto
)
1427 nasm_panic("intra-segment OUT_REL1ADR");
1428 if (segment
== NO_SEG
) {
1430 } else if (segment
& 1) {
1431 nasm_nonfatal("ELF format does not support"
1432 " segment base references");
1434 if (wrt
== NO_SEG
) {
1435 elf_add_reloc(s
, segment
, addr
, reltype
);
1438 nasm_nonfatal("Unsupported %d-bit ELF relocation", bytes
<< 3);
1441 elf_sect_writeaddr(s
, addr
, bytes
);
1445 addr
= *(int64_t *)data
- size
;
1446 if (segment
== segto
)
1447 nasm_panic("intra-segment OUT_REL4ADR");
1448 if (segment
== NO_SEG
) {
1450 } else if (segment
& 1) {
1451 nasm_nonfatal("ELF64 format does not support"
1452 " segment base references");
1454 if (wrt
== NO_SEG
) {
1455 elf_add_reloc(s
, segment
, addr
, R_X86_64_PC32
);
1457 } else if (wrt
== elf_plt_sect
+ 1) {
1458 elf_add_gsym_reloc(s
, segment
, addr
+size
, size
,
1459 R_X86_64_PLT32
, true);
1461 } else if (wrt
== elf_gotpc_sect
+ 1 ||
1462 wrt
== elf_got_sect
+ 1) {
1463 elf_add_gsym_reloc(s
, segment
, addr
+size
, size
,
1464 R_X86_64_GOTPCREL
, true);
1466 } else if (wrt
== elf_gotoff_sect
+ 1 ||
1467 wrt
== elf_got_sect
+ 1) {
1468 nasm_nonfatal("ELF64 requires ..gotoff references to be "
1470 } else if (wrt
== elf_gottpoff_sect
+ 1) {
1471 elf_add_gsym_reloc(s
, segment
, addr
+size
, size
,
1472 R_X86_64_GOTTPOFF
, true);
1475 nasm_nonfatal("ELF64 format does not support this"
1479 elf_sect_writeaddr(s
, addr
, 4);
1483 addr
= *(int64_t *)data
- size
;
1484 if (segment
== segto
)
1485 nasm_panic("intra-segment OUT_REL8ADR");
1486 if (segment
== NO_SEG
) {
1488 } else if (segment
& 1) {
1489 nasm_nonfatal("ELF64 format does not support"
1490 " segment base references");
1492 if (wrt
== NO_SEG
) {
1493 elf_add_reloc(s
, segment
, addr
, R_X86_64_PC64
);
1495 } else if (wrt
== elf_gotpc_sect
+ 1 ||
1496 wrt
== elf_got_sect
+ 1) {
1497 elf_add_gsym_reloc(s
, segment
, addr
+size
, size
,
1498 R_X86_64_GOTPCREL64
, true);
1500 } else if (wrt
== elf_gotoff_sect
+ 1 ||
1501 wrt
== elf_got_sect
+ 1) {
1502 nasm_nonfatal("ELF64 requires ..gotoff references to be "
1504 } else if (wrt
== elf_gottpoff_sect
+ 1) {
1505 nasm_nonfatal("ELF64 requires ..gottpoff references to be "
1508 nasm_nonfatal("ELF64 format does not support this"
1512 elf_sect_writeaddr(s
, addr
, 8);
1520 static void elfx32_out(int32_t segto
, const void *data
,
1521 enum out_type type
, uint64_t size
,
1522 int32_t segment
, int32_t wrt
)
1524 struct elf_section
*s
;
1527 static struct symlininfo sinfo
;
1530 * handle absolute-assembly (structure definitions)
1532 if (segto
== NO_SEG
) {
1533 if (type
!= OUT_RESERVE
)
1534 nasm_nonfatal("attempt to assemble code in [ABSOLUTE] space");
1538 s
= raa_read_ptr(section_by_index
, segto
>> 1);
1540 int tempint
; /* ignored */
1541 if (segto
!= elf_section_names(".text", &tempint
))
1542 nasm_panic("strange segment conditions in ELF driver");
1544 s
= sects
[nsects
- 1];
1547 /* again some stabs debugging stuff */
1548 sinfo
.offset
= s
->len
;
1549 sinfo
.section
= s
->shndx
;
1550 sinfo
.segto
= segto
;
1551 sinfo
.name
= s
->name
;
1552 dfmt
->debug_output(TY_DEBUGSYMLIN
, &sinfo
);
1553 /* end of debugging stuff */
1555 if (s
->type
== SHT_NOBITS
&& type
!= OUT_RESERVE
) {
1556 nasm_warn(WARN_OTHER
, "attempt to initialize memory in"
1557 " BSS section `%s': ignored", s
->name
);
1558 s
->len
+= realsize(type
, size
);
1564 if (s
->type
!= SHT_NOBITS
) {
1565 nasm_warn(WARN_ZEROING
, "uninitialized space declared in"
1566 " non-BSS section `%s': zeroing", s
->name
);
1567 elf_sect_write(s
, NULL
, size
);
1573 if (segment
!= NO_SEG
)
1574 nasm_panic("OUT_RAWDATA with other than NO_SEG");
1575 elf_sect_write(s
, data
, size
);
1580 int isize
= (int)size
;
1581 int asize
= abs((int)size
);
1583 addr
= *(int64_t *)data
;
1584 if (segment
== NO_SEG
) {
1586 } else if (segment
& 1) {
1587 nasm_nonfatal("ELF format does not support"
1588 " segment base references");
1590 if (wrt
== NO_SEG
) {
1594 elf_add_reloc(s
, segment
, addr
, R_X86_64_8
);
1598 elf_add_reloc(s
, segment
, addr
, R_X86_64_16
);
1601 elf_add_reloc(s
, segment
, addr
, R_X86_64_32
);
1604 elf_add_reloc(s
, segment
, addr
, R_X86_64_32S
);
1608 elf_add_reloc(s
, segment
, addr
, R_X86_64_64
);
1611 nasm_panic("internal error elfx32-hpa-871");
1615 } else if (wrt
== elf_gotpc_sect
+ 1) {
1617 * The user will supply GOT relative to $$. ELF
1618 * will let us have GOT relative to $. So we
1619 * need to fix up the data item by $-$$.
1622 elf_add_reloc(s
, segment
, addr
, R_X86_64_GOTPC32
);
1624 } else if (wrt
== elf_gotoff_sect
+ 1) {
1625 nasm_nonfatal("ELFX32 doesn't support "
1626 "R_X86_64_GOTOFF64");
1627 } else if (wrt
== elf_got_sect
+ 1) {
1630 elf_add_gsym_reloc(s
, segment
, addr
, 0,
1631 R_X86_64_GOT32
, true);
1635 nasm_nonfatal("invalid ..got reference");
1638 } else if (wrt
== elf_sym_sect
+ 1) {
1642 elf_add_gsym_reloc(s
, segment
, addr
, 0,
1648 elf_add_gsym_reloc(s
, segment
, addr
, 0,
1649 R_X86_64_16
, false);
1653 elf_add_gsym_reloc(s
, segment
, addr
, 0,
1654 R_X86_64_32
, false);
1658 elf_add_gsym_reloc(s
, segment
, addr
, 0,
1659 R_X86_64_32S
, false);
1664 elf_add_gsym_reloc(s
, segment
, addr
, 0,
1665 R_X86_64_64
, false);
1669 nasm_panic("internal error elfx32-hpa-903");
1672 } else if (wrt
== elf_plt_sect
+ 1) {
1673 nasm_nonfatal("ELF format cannot produce non-PC-"
1674 "relative PLT references");
1676 nasm_nonfatal("ELF format does not support this"
1680 elf_sect_writeaddr(s
, addr
, asize
);
1685 reltype
= R_X86_64_PC8
;
1690 reltype
= R_X86_64_PC16
;
1695 addr
= *(int64_t *)data
- size
;
1696 if (segment
== segto
)
1697 nasm_panic("intra-segment OUT_REL1ADR");
1698 if (segment
== NO_SEG
) {
1700 } else if (segment
& 1) {
1701 nasm_nonfatal("ELF format does not support"
1702 " segment base references");
1704 if (wrt
== NO_SEG
) {
1705 elf_add_reloc(s
, segment
, addr
, reltype
);
1708 nasm_nonfatal("unsupported %d-bit ELF relocation", bytes
<< 3);
1711 elf_sect_writeaddr(s
, addr
, bytes
);
1715 addr
= *(int64_t *)data
- size
;
1716 if (segment
== segto
)
1717 nasm_panic("intra-segment OUT_REL4ADR");
1718 if (segment
== NO_SEG
) {
1720 } else if (segment
& 1) {
1721 nasm_nonfatal("ELFX32 format does not support"
1722 " segment base references");
1724 if (wrt
== NO_SEG
) {
1725 elf_add_reloc(s
, segment
, addr
, R_X86_64_PC32
);
1727 } else if (wrt
== elf_plt_sect
+ 1) {
1728 elf_add_gsym_reloc(s
, segment
, addr
+size
, size
,
1729 R_X86_64_PLT32
, true);
1731 } else if (wrt
== elf_gotpc_sect
+ 1 ||
1732 wrt
== elf_got_sect
+ 1) {
1733 elf_add_gsym_reloc(s
, segment
, addr
+size
, size
,
1734 R_X86_64_GOTPCREL
, true);
1736 } else if (wrt
== elf_gotoff_sect
+ 1 ||
1737 wrt
== elf_got_sect
+ 1) {
1738 nasm_nonfatal("invalid ..gotoff reference");
1739 } else if (wrt
== elf_gottpoff_sect
+ 1) {
1740 elf_add_gsym_reloc(s
, segment
, addr
+size
, size
,
1741 R_X86_64_GOTTPOFF
, true);
1744 nasm_nonfatal("ELFX32 format does not support this use of WRT");
1747 elf_sect_writeaddr(s
, addr
, 4);
1751 nasm_nonfatal("32-bit ELF format does not support 64-bit relocations");
1753 elf_sect_writeaddr(s
, addr
, 8);
1762 * Section index/count with a specified overflow value (usually SHN_INDEX,
1763 * but 0 for e_shnum.
1765 static inline uint16_t elf_shndx(int section
, uint16_t overflow
)
1767 return cpu_to_le16(section
< (int)SHN_LORESERVE
? section
: overflow
);
1770 struct ehdr_common
{
1771 uint8_t e_ident
[EI_NIDENT
];
1780 struct ehdr_common com
;
1783 static void elf_write(void)
1789 int sec_shstrtab
, sec_symtab
, sec_strtab
;
1793 * Add any sections we don't already have:
1794 * rel/rela sections for the user sections, debug sections, and
1795 * the ELF special sections.
1798 sec_debug
= nsections
;
1799 if (dfmt_is_stabs()) {
1800 /* in case the debug information is wanted, just add these three sections... */
1801 add_sectname("", ".stab");
1802 add_sectname("", ".stabstr");
1803 add_sectname(efmt
->relpfx
, ".stab");
1804 } else if (dfmt_is_dwarf()) {
1805 /* the dwarf debug standard specifies the following ten sections,
1806 not all of which are currently implemented,
1807 although all of them are defined. */
1808 add_sectname("", ".debug_aranges");
1809 add_sectname(".rela", ".debug_aranges");
1810 add_sectname("", ".debug_pubnames");
1811 add_sectname("", ".debug_info");
1812 add_sectname(".rela", ".debug_info");
1813 add_sectname("", ".debug_abbrev");
1814 add_sectname("", ".debug_line");
1815 add_sectname(".rela", ".debug_line");
1816 add_sectname("", ".debug_frame");
1817 add_sectname("", ".debug_loc");
1820 sec_shstrtab
= add_sectname("", ".shstrtab");
1821 sec_symtab
= add_sectname("", ".symtab");
1822 sec_strtab
= add_sectname("", ".strtab");
1825 * Build the symbol table and relocation tables.
1827 symtablocal
= elf_build_symtab();
1829 /* Do we need an .symtab_shndx section? */
1831 add_sectname("", ".symtab_shndx");
1833 for (i
= 0; i
< nsects
; i
++) {
1834 if (sects
[i
]->head
) {
1835 add_sectname(efmt
->relpfx
, sects
[i
]->name
);
1836 sects
[i
]->rel
= efmt
->elf_build_reltab(sects
[i
]->head
);
1841 * Output the ELF header.
1845 /* These fields are in the same place for 32 and 64 bits */
1846 memcpy(&ehdr
.com
.e_ident
[EI_MAG0
], ELFMAG
, SELFMAG
);
1847 ehdr
.com
.e_ident
[EI_CLASS
] = efmt
->ei_class
;
1848 ehdr
.com
.e_ident
[EI_DATA
] = ELFDATA2LSB
;
1849 ehdr
.com
.e_ident
[EI_VERSION
] = EV_CURRENT
;
1850 ehdr
.com
.e_ident
[EI_OSABI
] = elf_osabi
;
1851 ehdr
.com
.e_ident
[EI_ABIVERSION
] = elf_abiver
;
1852 ehdr
.com
.e_type
= cpu_to_le16(ET_REL
);
1853 ehdr
.com
.e_machine
= cpu_to_le16(efmt
->e_machine
);
1854 ehdr
.com
.e_version
= cpu_to_le16(EV_CURRENT
);
1857 ehdr
.ehdr32
.e_shoff
= cpu_to_le32(sizeof ehdr
);
1858 ehdr
.ehdr32
.e_ehsize
= cpu_to_le16(sizeof(Elf32_Ehdr
));
1859 ehdr
.ehdr32
.e_shentsize
= cpu_to_le16(sizeof(Elf32_Shdr
));
1860 ehdr
.ehdr32
.e_shnum
= elf_shndx(nsections
, 0);
1861 ehdr
.ehdr32
.e_shstrndx
= elf_shndx(sec_shstrtab
, SHN_XINDEX
);
1863 ehdr
.ehdr64
.e_shoff
= cpu_to_le64(sizeof ehdr
);
1864 ehdr
.ehdr64
.e_ehsize
= cpu_to_le16(sizeof(Elf64_Ehdr
));
1865 ehdr
.ehdr64
.e_shentsize
= cpu_to_le16(sizeof(Elf64_Shdr
));
1866 ehdr
.ehdr64
.e_shnum
= elf_shndx(nsections
, 0);
1867 ehdr
.ehdr64
.e_shstrndx
= elf_shndx(sec_shstrtab
, SHN_XINDEX
);
1870 nasm_write(&ehdr
, sizeof(ehdr
), ofile
);
1871 elf_foffs
= sizeof ehdr
+ efmt
->shdr_size
* nsections
;
1874 * Now output the section header table.
1876 align
= ALIGN(elf_foffs
, SEC_FILEALIGN
) - elf_foffs
;
1879 elf_sects
= nasm_malloc(sizeof(*elf_sects
) * nsections
);
1882 elf_section_header(0, SHT_NULL
, 0, NULL
, false,
1883 nsections
> (int)SHN_LORESERVE
? nsections
: 0,
1884 sec_shstrtab
>= (int)SHN_LORESERVE
? sec_shstrtab
: 0,
1888 /* The normal sections */
1889 for (i
= 0; i
< nsects
; i
++) {
1890 elf_section_header(p
- shstrtab
, sects
[i
]->type
, sects
[i
]->flags
,
1891 sects
[i
]->data
, true,
1892 sects
[i
]->len
, 0, 0,
1893 sects
[i
]->align
, sects
[i
]->entsize
);
1897 /* The debugging sections */
1898 if (dfmt_is_stabs()) {
1899 /* for debugging information, create the last three sections
1900 which are the .stab , .stabstr and .rel.stab sections respectively */
1902 /* this function call creates the stab sections in memory */
1905 if (stabbuf
&& stabstrbuf
&& stabrelbuf
) {
1906 elf_section_header(p
- shstrtab
, SHT_PROGBITS
, 0, stabbuf
, false,
1907 stablen
, sec_stabstr
, 0, 4, 12);
1910 elf_section_header(p
- shstrtab
, SHT_STRTAB
, 0, stabstrbuf
, false,
1911 stabstrlen
, 0, 0, 4, 0);
1914 /* link -> symtable info -> section to refer to */
1915 elf_section_header(p
- shstrtab
, efmt
->reltype
, 0,
1916 stabrelbuf
, false, stabrellen
,
1917 sec_symtab
, sec_stab
,
1918 efmt
->word
, efmt
->rel_size
);
1921 } else if (dfmt_is_dwarf()) {
1922 /* for dwarf debugging information, create the ten dwarf sections */
1924 /* this function call creates the dwarf sections in memory */
1928 elf_section_header(p
- shstrtab
, SHT_PROGBITS
, 0, arangesbuf
, false,
1929 arangeslen
, 0, 0, 1, 0);
1932 elf_section_header(p
- shstrtab
, SHT_RELA
, 0, arangesrelbuf
, false,
1933 arangesrellen
, sec_symtab
,
1935 efmt
->word
, efmt
->rela_size
);
1938 elf_section_header(p
- shstrtab
, SHT_PROGBITS
, 0, pubnamesbuf
,
1939 false, pubnameslen
, 0, 0, 1, 0);
1942 elf_section_header(p
- shstrtab
, SHT_PROGBITS
, 0, infobuf
, false,
1943 infolen
, 0, 0, 1, 0);
1946 elf_section_header(p
- shstrtab
, SHT_RELA
, 0, inforelbuf
, false,
1947 inforellen
, sec_symtab
,
1949 efmt
->word
, efmt
->rela_size
);
1952 elf_section_header(p
- shstrtab
, SHT_PROGBITS
, 0, abbrevbuf
, false,
1953 abbrevlen
, 0, 0, 1, 0);
1956 elf_section_header(p
- shstrtab
, SHT_PROGBITS
, 0, linebuf
, false,
1957 linelen
, 0, 0, 1, 0);
1960 elf_section_header(p
- shstrtab
, SHT_RELA
, 0, linerelbuf
, false,
1961 linerellen
, sec_symtab
,
1963 efmt
->word
, efmt
->rela_size
);
1966 elf_section_header(p
- shstrtab
, SHT_PROGBITS
, 0, framebuf
, false,
1967 framelen
, 0, 0, 8, 0);
1970 elf_section_header(p
- shstrtab
, SHT_PROGBITS
, 0, locbuf
, false,
1971 loclen
, 0, 0, 1, 0);
1976 elf_section_header(p
- shstrtab
, SHT_STRTAB
, 0, shstrtab
, false,
1977 shstrtablen
, 0, 0, 1, 0);
1981 elf_section_header(p
- shstrtab
, SHT_SYMTAB
, 0, symtab
, true,
1982 symtab
->datalen
, sec_strtab
, symtablocal
,
1983 efmt
->word
, efmt
->sym_size
);
1987 elf_section_header(p
- shstrtab
, SHT_STRTAB
, 0, strs
, true,
1988 strslen
, 0, 0, 1, 0);
1993 elf_section_header(p
- shstrtab
, SHT_SYMTAB_SHNDX
, 0,
1994 symtab_shndx
, true, symtab_shndx
->datalen
,
1995 sec_symtab
, 0, 1, 0);
1999 /* The relocation sections */
2000 for (i
= 0; i
< nsects
; i
++) {
2001 if (sects
[i
]->rel
) {
2002 elf_section_header(p
- shstrtab
, efmt
->reltype
, 0,
2003 sects
[i
]->rel
, true, sects
[i
]->rel
->datalen
,
2004 sec_symtab
, sects
[i
]->shndx
,
2005 efmt
->word
, efmt
->rel_size
);
2009 fwritezero(align
, ofile
);
2012 * Now output the sections.
2014 elf_write_sections();
2016 nasm_free(elf_sects
);
2019 saa_free(symtab_shndx
);
2022 static size_t nsyms
;
2024 static void elf_sym(const struct elf_symbol
*sym
)
2026 int shndx
= sym
->section
;
2029 * Careful here. This relies on sym->section being signed; for
2030 * special section indicies this value needs to be cast to
2031 * (int16_t) so that it sign-extends, however, here SHN_LORESERVE
2032 * is used as an unsigned constant.
2034 if (shndx
>= (int)SHN_LORESERVE
) {
2035 if (unlikely(!symtab_shndx
)) {
2036 /* Create symtab_shndx and fill previous entries with zero */
2037 symtab_shndx
= saa_init(1);
2038 saa_wbytes(symtab_shndx
, NULL
, nsyms
<< 2);
2041 shndx
= 0; /* Section index table always write zero */
2045 saa_write32(symtab_shndx
, shndx
);
2051 static void elf32_sym(const struct elf_symbol
*sym
)
2055 sym32
.st_name
= cpu_to_le32(sym
->strpos
);
2056 sym32
.st_value
= cpu_to_le32(sym
->symv
.key
);
2057 sym32
.st_size
= cpu_to_le32(sym
->size
);
2058 sym32
.st_info
= sym
->type
;
2059 sym32
.st_other
= sym
->other
;
2060 sym32
.st_shndx
= elf_shndx(sym
->section
, SHN_XINDEX
);
2061 saa_wbytes(symtab
, &sym32
, sizeof sym32
);
2064 static void elf64_sym(const struct elf_symbol
*sym
)
2068 sym64
.st_name
= cpu_to_le32(sym
->strpos
);
2069 sym64
.st_value
= cpu_to_le64(sym
->symv
.key
);
2070 sym64
.st_size
= cpu_to_le64(sym
->size
);
2071 sym64
.st_info
= sym
->type
;
2072 sym64
.st_other
= sym
->other
;
2073 sym64
.st_shndx
= elf_shndx(sym
->section
, SHN_XINDEX
);
2074 saa_wbytes(symtab
, &sym64
, sizeof sym64
);
2077 static size_t elf_build_symtab(void)
2079 struct elf_symbol
*sym
, xsym
;
2083 symtab
= saa_init(1);
2084 symtab_shndx
= NULL
;
2087 * Zero symbol first as required by spec.
2093 * Next, an entry for the file name.
2097 xsym
.type
= ELF32_ST_INFO(STB_LOCAL
, STT_FILE
);
2098 xsym
.section
= XSHN_ABS
;
2102 * Now some standard symbols defining the segments, for relocation
2106 for (i
= 1; i
<= nsects
; i
++) {
2107 xsym
.type
= ELF64_ST_INFO(STB_LOCAL
, STT_SECTION
);
2113 * dwarf needs symbols for debug sections
2114 * which are relocation targets.
2116 if (dfmt_is_dwarf()) {
2117 dwarf_infosym
= nsyms
;
2118 xsym
.section
= sec_debug_info
;
2121 dwarf_abbrevsym
= nsyms
;
2122 xsym
.section
= sec_debug_abbrev
;
2125 dwarf_linesym
= nsyms
;
2126 xsym
.section
= sec_debug_line
;
2131 * Now the other local symbols.
2134 while ((sym
= saa_rstruct(syms
))) {
2135 if (sym
->type
& SYM_GLOBAL
)
2144 * Now the global symbols.
2147 while ((sym
= saa_rstruct(syms
))) {
2148 if (!(sym
->type
& SYM_GLOBAL
))
2157 static struct SAA
*elf32_build_reltab(const struct elf_reloc
*r
)
2160 int32_t global_offset
;
2169 * How to onvert from a global placeholder to a real symbol index;
2170 * the +2 refers to the two special entries, the null entry and
2171 * the filename entry.
2173 global_offset
= -GLOBAL_TEMP_BASE
+ nsects
+ nlocals
+ ndebugs
+ 2;
2176 int32_t sym
= r
->symbol
;
2178 if (sym
>= GLOBAL_TEMP_BASE
)
2179 sym
+= global_offset
;
2181 rel32
.r_offset
= cpu_to_le32(r
->address
);
2182 rel32
.r_info
= cpu_to_le32(ELF32_R_INFO(sym
, r
->type
));
2183 saa_wbytes(s
, &rel32
, sizeof rel32
);
2191 static struct SAA
*elfx32_build_reltab(const struct elf_reloc
*r
)
2194 int32_t global_offset
;
2203 * How to onvert from a global placeholder to a real symbol index;
2204 * the +2 refers to the two special entries, the null entry and
2205 * the filename entry.
2207 global_offset
= -GLOBAL_TEMP_BASE
+ nsects
+ nlocals
+ ndebugs
+ 2;
2210 int32_t sym
= r
->symbol
;
2212 if (sym
>= GLOBAL_TEMP_BASE
)
2213 sym
+= global_offset
;
2215 rela32
.r_offset
= cpu_to_le32(r
->address
);
2216 rela32
.r_info
= cpu_to_le32(ELF32_R_INFO(sym
, r
->type
));
2217 rela32
.r_addend
= cpu_to_le32(r
->offset
);
2218 saa_wbytes(s
, &rela32
, sizeof rela32
);
2226 static struct SAA
*elf64_build_reltab(const struct elf_reloc
*r
)
2229 int32_t global_offset
;
2238 * How to onvert from a global placeholder to a real symbol index;
2239 * the +2 refers to the two special entries, the null entry and
2240 * the filename entry.
2242 global_offset
= -GLOBAL_TEMP_BASE
+ nsects
+ nlocals
+ ndebugs
+ 2;
2245 int32_t sym
= r
->symbol
;
2247 if (sym
>= GLOBAL_TEMP_BASE
)
2248 sym
+= global_offset
;
2250 rela64
.r_offset
= cpu_to_le64(r
->address
);
2251 rela64
.r_info
= cpu_to_le64(ELF64_R_INFO(sym
, r
->type
));
2252 rela64
.r_addend
= cpu_to_le64(r
->offset
);
2253 saa_wbytes(s
, &rela64
, sizeof rela64
);
2261 static void elf_section_header(int name
, int type
, uint64_t flags
,
2262 void *data
, bool is_saa
, uint64_t datalen
,
2264 uint64_t align
, uint64_t entsize
)
2266 elf_sects
[elf_nsect
].data
= data
;
2267 elf_sects
[elf_nsect
].len
= datalen
;
2268 elf_sects
[elf_nsect
].is_saa
= is_saa
;
2274 shdr
.sh_name
= cpu_to_le32(name
);
2275 shdr
.sh_type
= cpu_to_le32(type
);
2276 shdr
.sh_flags
= cpu_to_le32(flags
);
2278 shdr
.sh_offset
= cpu_to_le32(type
== SHT_NULL
? 0 : elf_foffs
);
2279 shdr
.sh_size
= cpu_to_le32(datalen
);
2281 elf_foffs
+= ALIGN(datalen
, SEC_FILEALIGN
);
2282 shdr
.sh_link
= cpu_to_le32(link
);
2283 shdr
.sh_info
= cpu_to_le32(info
);
2284 shdr
.sh_addralign
= cpu_to_le32(align
);
2285 shdr
.sh_entsize
= cpu_to_le32(entsize
);
2287 nasm_write(&shdr
, sizeof shdr
, ofile
);
2291 shdr
.sh_name
= cpu_to_le32(name
);
2292 shdr
.sh_type
= cpu_to_le32(type
);
2293 shdr
.sh_flags
= cpu_to_le64(flags
);
2295 shdr
.sh_offset
= cpu_to_le64(type
== SHT_NULL
? 0 : elf_foffs
);
2296 shdr
.sh_size
= cpu_to_le64(datalen
);
2298 elf_foffs
+= ALIGN(datalen
, SEC_FILEALIGN
);
2299 shdr
.sh_link
= cpu_to_le32(link
);
2300 shdr
.sh_info
= cpu_to_le32(info
);
2301 shdr
.sh_addralign
= cpu_to_le64(align
);
2302 shdr
.sh_entsize
= cpu_to_le64(entsize
);
2304 nasm_write(&shdr
, sizeof shdr
, ofile
);
2308 static void elf_write_sections(void)
2311 for (i
= 0; i
< elf_nsect
; i
++)
2312 if (elf_sects
[i
].data
) {
2313 int32_t len
= elf_sects
[i
].len
;
2314 int32_t reallen
= ALIGN(len
, SEC_FILEALIGN
);
2315 int32_t align
= reallen
- len
;
2316 if (elf_sects
[i
].is_saa
)
2317 saa_fpwrite(elf_sects
[i
].data
, ofile
);
2319 nasm_write(elf_sects
[i
].data
, len
, ofile
);
2320 fwritezero(align
, ofile
);
2324 static void elf_sect_write(struct elf_section
*sect
, const void *data
, size_t len
)
2326 saa_wbytes(sect
->data
, data
, len
);
2330 static void elf_sect_writeaddr(struct elf_section
*sect
, int64_t data
, size_t len
)
2332 saa_writeaddr(sect
->data
, data
, len
);
2336 static void elf_sectalign(int32_t seg
, unsigned int value
)
2338 struct elf_section
*s
;
2340 s
= raa_read_ptr(section_by_index
, seg
>> 1);
2341 if (!s
|| !is_power2(value
))
2344 if (value
> s
->align
)
2348 extern macros_t elf_stdmac
[];
2350 /* Claim "elf" as a pragma namespace, for the future */
2351 static const struct pragma_facility elf_pragma_list
[] =
2354 { NULL
, NULL
} /* Implements the canonical output name */
2358 static const struct dfmt elf32_df_dwarf
= {
2359 "ELF32 (i386) dwarf debug format for Linux/Unix",
2363 null_debug_deflabel
,
2364 null_debug_directive
,
2368 NULL
/* pragma list */
2371 static const struct dfmt elf32_df_stabs
= {
2372 "ELF32 (i386) stabs debug format for Linux/Unix",
2376 null_debug_deflabel
,
2377 null_debug_directive
,
2381 NULL
/* pragma list */
2384 static const struct dfmt
* const elf32_debugs_arr
[3] =
2385 { &elf32_df_dwarf
, &elf32_df_stabs
, NULL
};
2387 const struct ofmt of_elf32
= {
2388 "ELF32 (i386) object files (e.g. Linux)",
2398 nasm_do_legacy_output
,
2410 static const struct dfmt elf64_df_dwarf
= {
2411 "ELF64 (x86-64) dwarf debug format for Linux/Unix",
2415 null_debug_deflabel
,
2416 null_debug_directive
,
2420 NULL
/* pragma list */
2423 static const struct dfmt elf64_df_stabs
= {
2424 "ELF64 (x86-64) stabs debug format for Linux/Unix",
2428 null_debug_deflabel
,
2429 null_debug_directive
,
2433 NULL
/* pragma list */
2436 static const struct dfmt
* const elf64_debugs_arr
[3] =
2437 { &elf64_df_dwarf
, &elf64_df_stabs
, NULL
};
2439 const struct ofmt of_elf64
= {
2440 "ELF64 (x86_64) object files (e.g. Linux)",
2450 nasm_do_legacy_output
,
2462 static const struct dfmt elfx32_df_dwarf
= {
2463 "ELFX32 (x86-64) dwarf debug format for Linux/Unix",
2467 null_debug_deflabel
,
2468 null_debug_directive
,
2472 NULL
/* pragma list */
2475 static const struct dfmt elfx32_df_stabs
= {
2476 "ELFX32 (x86-64) stabs debug format for Linux/Unix",
2480 null_debug_deflabel
,
2481 null_debug_directive
,
2488 static const struct dfmt
* const elfx32_debugs_arr
[3] =
2489 { &elfx32_df_dwarf
, &elfx32_df_stabs
, NULL
};
2491 const struct ofmt of_elfx32
= {
2492 "ELFX32 (x86_64) object files (e.g. Linux)",
2502 nasm_do_legacy_output
,
2511 NULL
/* pragma list */
2514 static bool is_elf64(void)
2516 return ofmt
== &of_elf64
;
2519 static bool is_elf32(void)
2521 return ofmt
== &of_elf32
;
2524 static bool is_elfx32(void)
2526 return ofmt
== &of_elfx32
;
2529 static bool dfmt_is_stabs(void)
2531 return dfmt
== &elf32_df_stabs
||
2532 dfmt
== &elfx32_df_stabs
||
2533 dfmt
== &elf64_df_stabs
;
2536 static bool dfmt_is_dwarf(void)
2538 return dfmt
== &elf32_df_dwarf
||
2539 dfmt
== &elfx32_df_dwarf
||
2540 dfmt
== &elf64_df_dwarf
;
2543 /* common debugging routines */
2544 static void debug_typevalue(int32_t type
)
2546 int32_t stype
, ssize
;
2547 switch (TYM_TYPE(type
)) {
2594 stype
= STT_SECTION
;
2609 if (stype
== STT_OBJECT
&& lastsym
&& !lastsym
->type
) {
2610 lastsym
->size
= ssize
;
2611 lastsym
->type
= stype
;
2615 /* stabs debugging routines */
2617 static void stabs_linenum(const char *filename
, int32_t linenumber
, int32_t segto
)
2620 if (!stabs_filename
) {
2621 stabs_filename
= nasm_malloc(strlen(filename
) + 1);
2622 strcpy(stabs_filename
, filename
);
2624 if (strcmp(stabs_filename
, filename
)) {
2625 /* yep, a memory leak...this program is one-shot anyway, so who cares...
2626 in fact, this leak comes in quite handy to maintain a list of files
2627 encountered so far in the symbol lines... */
2629 /* why not nasm_free(stabs_filename); we're done with the old one */
2631 stabs_filename
= nasm_malloc(strlen(filename
) + 1);
2632 strcpy(stabs_filename
, filename
);
2636 currentline
= linenumber
;
2639 static void stabs_output(int type
, void *param
)
2641 struct symlininfo
*s
;
2642 struct linelist
*el
;
2643 if (type
== TY_DEBUGSYMLIN
) {
2644 if (debug_immcall
) {
2645 s
= (struct symlininfo
*)param
;
2646 if (!(sects
[s
->section
]->flags
& SHF_EXECINSTR
))
2647 return; /* line info is only collected for executable sections */
2649 el
= nasm_malloc(sizeof(struct linelist
));
2650 el
->info
.offset
= s
->offset
;
2651 el
->info
.section
= s
->section
;
2652 el
->info
.name
= s
->name
;
2653 el
->line
= currentline
;
2654 el
->filename
= stabs_filename
;
2657 stabslines
->last
->next
= el
;
2658 stabslines
->last
= el
;
2661 stabslines
->last
= el
;
2668 /* for creating the .stab , .stabstr and .rel.stab sections in memory */
2670 static void stabs_generate(void)
2672 int i
, numfiles
, strsize
, numstabs
= 0, currfile
, mainfileindex
;
2673 uint8_t *sbuf
, *ssbuf
, *rbuf
, *sptr
, *rptr
;
2677 struct linelist
*ptr
;
2681 allfiles
= nasm_zalloc(numlinestabs
* sizeof(char *));
2684 if (numfiles
== 0) {
2685 allfiles
[0] = ptr
->filename
;
2688 for (i
= 0; i
< numfiles
; i
++) {
2689 if (!strcmp(allfiles
[i
], ptr
->filename
))
2692 if (i
>= numfiles
) {
2693 allfiles
[i
] = ptr
->filename
;
2700 fileidx
= nasm_malloc(numfiles
* sizeof(int));
2701 for (i
= 0; i
< numfiles
; i
++) {
2702 fileidx
[i
] = strsize
;
2703 strsize
+= strlen(allfiles
[i
]) + 1;
2705 currfile
= mainfileindex
= 0;
2706 for (i
= 0; i
< numfiles
; i
++) {
2707 if (!strcmp(allfiles
[i
], elf_module
)) {
2708 currfile
= mainfileindex
= i
;
2714 * worst case size of the stab buffer would be:
2715 * the sourcefiles changes each line, which would mean 1 SOL, 1 SYMLIN per line
2716 * plus one "ending" entry
2718 sbuf
= nasm_malloc((numlinestabs
* 2 + 4) *
2719 sizeof(struct stabentry
));
2720 ssbuf
= nasm_malloc(strsize
);
2721 rbuf
= nasm_malloc(numlinestabs
* (is_elf64() ? 16 : 8) * (2 + 3));
2724 for (i
= 0; i
< numfiles
; i
++)
2725 strcpy((char *)ssbuf
+ fileidx
[i
], allfiles
[i
]);
2728 stabstrlen
= strsize
; /* set global variable for length of stab strings */
2736 * this is the first stab, its strx points to the filename of the
2737 * the source-file, the n_desc field should be set to the number
2738 * of remaining stabs
2740 WRITE_STAB(sptr
, fileidx
[0], 0, 0, 0, stabstrlen
);
2742 /* this is the stab for the main source file */
2743 WRITE_STAB(sptr
, fileidx
[mainfileindex
], N_SO
, 0, 0, 0);
2745 /* relocation table entry */
2748 * Since the symbol table has two entries before
2749 * the section symbols, the index in the info.section
2750 * member must be adjusted by adding 2
2754 WRITELONG(rptr
, (sptr
- sbuf
) - 4);
2755 WRITELONG(rptr
, ((ptr
->info
.section
+ 2) << 8) | R_386_32
);
2756 } else if (is_elfx32()) {
2757 WRITELONG(rptr
, (sptr
- sbuf
) - 4);
2758 WRITELONG(rptr
, ((ptr
->info
.section
+ 2) << 8) | R_X86_64_32
);
2761 nasm_assert(is_elf64());
2762 WRITEDLONG(rptr
, (int64_t)(sptr
- sbuf
) - 4);
2763 WRITELONG(rptr
, R_X86_64_32
);
2764 WRITELONG(rptr
, ptr
->info
.section
+ 2);
2765 WRITEDLONG(rptr
, 0);
2772 if (strcmp(allfiles
[currfile
], ptr
->filename
)) {
2773 /* oops file has changed... */
2774 for (i
= 0; i
< numfiles
; i
++)
2775 if (!strcmp(allfiles
[i
], ptr
->filename
))
2778 WRITE_STAB(sptr
, fileidx
[currfile
], N_SOL
, 0, 0,
2782 /* relocation table entry */
2783 WRITELONG(rptr
, (sptr
- sbuf
) - 4);
2784 WRITELONG(rptr
, ((ptr
->info
.section
+ 2) << 8) | R_386_32
);
2787 WRITE_STAB(sptr
, 0, N_SLINE
, 0, ptr
->line
, ptr
->info
.offset
);
2790 /* relocation table entry */
2791 WRITELONG(rptr
, (sptr
- sbuf
) - 4);
2792 WRITELONG(rptr
, ((ptr
->info
.section
+ 2) << 8) | R_386_32
);
2796 } else if (is_elfx32()) {
2798 if (strcmp(allfiles
[currfile
], ptr
->filename
)) {
2799 /* oops file has changed... */
2800 for (i
= 0; i
< numfiles
; i
++)
2801 if (!strcmp(allfiles
[i
], ptr
->filename
))
2804 WRITE_STAB(sptr
, fileidx
[currfile
], N_SOL
, 0, 0,
2808 /* relocation table entry */
2809 WRITELONG(rptr
, (sptr
- sbuf
) - 4);
2810 WRITELONG(rptr
, ((ptr
->info
.section
+ 2) << 8) | R_X86_64_32
);
2811 WRITELONG(rptr
, ptr
->info
.offset
);
2814 WRITE_STAB(sptr
, 0, N_SLINE
, 0, ptr
->line
, ptr
->info
.offset
);
2817 /* relocation table entry */
2818 WRITELONG(rptr
, (sptr
- sbuf
) - 4);
2819 WRITELONG(rptr
, ((ptr
->info
.section
+ 2) << 8) | R_X86_64_32
);
2820 WRITELONG(rptr
, ptr
->info
.offset
);
2825 nasm_assert(is_elf64());
2827 if (strcmp(allfiles
[currfile
], ptr
->filename
)) {
2828 /* oops file has changed... */
2829 for (i
= 0; i
< numfiles
; i
++)
2830 if (!strcmp(allfiles
[i
], ptr
->filename
))
2833 WRITE_STAB(sptr
, fileidx
[currfile
], N_SOL
, 0, 0,
2837 /* relocation table entry */
2838 WRITEDLONG(rptr
, (int64_t)(sptr
- sbuf
) - 4);
2839 WRITELONG(rptr
, R_X86_64_32
);
2840 WRITELONG(rptr
, ptr
->info
.section
+ 2);
2841 WRITEDLONG(rptr
, ptr
->info
.offset
);
2844 WRITE_STAB(sptr
, 0, N_SLINE
, 0, ptr
->line
, ptr
->info
.offset
);
2847 /* relocation table entry */
2848 WRITEDLONG(rptr
, (int64_t)(sptr
- sbuf
) - 4);
2849 WRITELONG(rptr
, R_X86_64_32
);
2850 WRITELONG(rptr
, ptr
->info
.section
+ 2);
2851 WRITEDLONG(rptr
, ptr
->info
.offset
);
2857 /* this is an "ending" token */
2858 WRITE_STAB(sptr
, 0, N_SO
, 0, 0, 0);
2861 ((struct stabentry
*)sbuf
)->n_desc
= numstabs
;
2863 nasm_free(allfiles
);
2866 stablen
= (sptr
- sbuf
);
2867 stabrellen
= (rptr
- rbuf
);
2873 static void stabs_cleanup(void)
2875 struct linelist
*ptr
, *del
;
2887 nasm_free(stabrelbuf
);
2888 nasm_free(stabstrbuf
);
2891 /* dwarf routines */
2893 static void dwarf_init(void)
2895 ndebugs
= 3; /* 3 debug symbols */
2898 static void dwarf_linenum(const char *filename
, int32_t linenumber
,
2902 dwarf_findfile(filename
);
2904 currentline
= linenumber
;
2907 /* called from elf_out with type == TY_DEBUGSYMLIN */
2908 static void dwarf_output(int type
, void *param
)
2910 int ln
, aa
, inx
, maxln
, soc
;
2911 struct symlininfo
*s
;
2916 s
= (struct symlininfo
*)param
;
2918 /* line number info is only gathered for executable sections */
2919 if (!(sects
[s
->section
]->flags
& SHF_EXECINSTR
))
2922 /* Check if section index has changed */
2923 if (!(dwarf_csect
&& (dwarf_csect
->section
) == (s
->section
)))
2924 dwarf_findsect(s
->section
);
2926 /* do nothing unless line or file has changed */
2930 ln
= currentline
- dwarf_csect
->line
;
2931 aa
= s
->offset
- dwarf_csect
->offset
;
2932 inx
= dwarf_clist
->line
;
2933 plinep
= dwarf_csect
->psaa
;
2934 /* check for file change */
2935 if (!(inx
== dwarf_csect
->file
)) {
2936 saa_write8(plinep
,DW_LNS_set_file
);
2937 saa_write8(plinep
,inx
);
2938 dwarf_csect
->file
= inx
;
2940 /* check for line change */
2942 /* test if in range of special op code */
2943 maxln
= line_base
+ line_range
;
2944 soc
= (ln
- line_base
) + (line_range
* aa
) + opcode_base
;
2945 if (ln
>= line_base
&& ln
< maxln
&& soc
< 256) {
2946 saa_write8(plinep
,soc
);
2948 saa_write8(plinep
,DW_LNS_advance_line
);
2949 saa_wleb128s(plinep
,ln
);
2951 saa_write8(plinep
,DW_LNS_advance_pc
);
2952 saa_wleb128u(plinep
,aa
);
2954 saa_write8(plinep
,DW_LNS_copy
);
2956 dwarf_csect
->line
= currentline
;
2957 dwarf_csect
->offset
= s
->offset
;
2960 /* show change handled */
2965 static void dwarf_generate(void)
2969 struct linelist
*ftentry
;
2970 struct SAA
*paranges
, *ppubnames
, *pinfo
, *pabbrev
, *plines
, *plinep
;
2971 struct SAA
*parangesrel
, *plinesrel
, *pinforel
;
2972 struct sectlist
*psect
;
2973 size_t saalen
, linepoff
, totlen
, highaddr
;
2976 /* write epilogues for each line program range */
2977 /* and build aranges section */
2978 paranges
= saa_init(1L);
2979 parangesrel
= saa_init(1L);
2980 saa_write16(paranges
,2); /* dwarf version */
2981 saa_write32(parangesrel
, paranges
->datalen
+4);
2982 saa_write32(parangesrel
, (dwarf_infosym
<< 8) + R_386_32
); /* reloc to info */
2983 saa_write32(parangesrel
, 0);
2984 saa_write32(paranges
,0); /* offset into info */
2985 saa_write8(paranges
,4); /* pointer size */
2986 saa_write8(paranges
,0); /* not segmented */
2987 saa_write32(paranges
,0); /* padding */
2988 /* iterate though sectlist entries */
2989 psect
= dwarf_fsect
;
2992 for (indx
= 0; indx
< dwarf_nsections
; indx
++) {
2993 plinep
= psect
->psaa
;
2994 /* Line Number Program Epilogue */
2995 saa_write8(plinep
,2); /* std op 2 */
2996 saa_write8(plinep
,(sects
[psect
->section
]->len
)-psect
->offset
);
2997 saa_write8(plinep
,DW_LNS_extended_op
);
2998 saa_write8(plinep
,1); /* operand length */
2999 saa_write8(plinep
,DW_LNE_end_sequence
);
3000 totlen
+= plinep
->datalen
;
3001 /* range table relocation entry */
3002 saa_write32(parangesrel
, paranges
->datalen
+ 4);
3003 saa_write32(parangesrel
, ((uint32_t) (psect
->section
+ 2) << 8) + R_386_32
);
3004 saa_write32(parangesrel
, (uint32_t) 0);
3005 /* range table entry */
3006 saa_write32(paranges
,0x0000); /* range start */
3007 saa_write32(paranges
,sects
[psect
->section
]->len
); /* range length */
3008 highaddr
+= sects
[psect
->section
]->len
;
3009 /* done with this entry */
3010 psect
= psect
->next
;
3012 saa_write32(paranges
,0); /* null address */
3013 saa_write32(paranges
,0); /* null length */
3014 saalen
= paranges
->datalen
;
3015 arangeslen
= saalen
+ 4;
3016 arangesbuf
= pbuf
= nasm_malloc(arangeslen
);
3017 WRITELONG(pbuf
,saalen
); /* initial length */
3018 saa_rnbytes(paranges
, pbuf
, saalen
);
3020 } else if (is_elfx32()) {
3021 /* write epilogues for each line program range */
3022 /* and build aranges section */
3023 paranges
= saa_init(1L);
3024 parangesrel
= saa_init(1L);
3025 saa_write16(paranges
,3); /* dwarf version */
3026 saa_write32(parangesrel
, paranges
->datalen
+4);
3027 saa_write32(parangesrel
, (dwarf_infosym
<< 8) + R_X86_64_32
); /* reloc to info */
3028 saa_write32(parangesrel
, 0);
3029 saa_write32(paranges
,0); /* offset into info */
3030 saa_write8(paranges
,4); /* pointer size */
3031 saa_write8(paranges
,0); /* not segmented */
3032 saa_write32(paranges
,0); /* padding */
3033 /* iterate though sectlist entries */
3034 psect
= dwarf_fsect
;
3037 for (indx
= 0; indx
< dwarf_nsections
; indx
++) {
3038 plinep
= psect
->psaa
;
3039 /* Line Number Program Epilogue */
3040 saa_write8(plinep
,2); /* std op 2 */
3041 saa_write8(plinep
,(sects
[psect
->section
]->len
)-psect
->offset
);
3042 saa_write8(plinep
,DW_LNS_extended_op
);
3043 saa_write8(plinep
,1); /* operand length */
3044 saa_write8(plinep
,DW_LNE_end_sequence
);
3045 totlen
+= plinep
->datalen
;
3046 /* range table relocation entry */
3047 saa_write32(parangesrel
, paranges
->datalen
+ 4);
3048 saa_write32(parangesrel
, ((uint32_t) (psect
->section
+ 2) << 8) + R_X86_64_32
);
3049 saa_write32(parangesrel
, (uint32_t) 0);
3050 /* range table entry */
3051 saa_write32(paranges
,0x0000); /* range start */
3052 saa_write32(paranges
,sects
[psect
->section
]->len
); /* range length */
3053 highaddr
+= sects
[psect
->section
]->len
;
3054 /* done with this entry */
3055 psect
= psect
->next
;
3057 saa_write32(paranges
,0); /* null address */
3058 saa_write32(paranges
,0); /* null length */
3059 saalen
= paranges
->datalen
;
3060 arangeslen
= saalen
+ 4;
3061 arangesbuf
= pbuf
= nasm_malloc(arangeslen
);
3062 WRITELONG(pbuf
,saalen
); /* initial length */
3063 saa_rnbytes(paranges
, pbuf
, saalen
);
3066 nasm_assert(is_elf64());
3067 /* write epilogues for each line program range */
3068 /* and build aranges section */
3069 paranges
= saa_init(1L);
3070 parangesrel
= saa_init(1L);
3071 saa_write16(paranges
,3); /* dwarf version */
3072 saa_write64(parangesrel
, paranges
->datalen
+4);
3073 saa_write64(parangesrel
, (dwarf_infosym
<< 32) + R_X86_64_32
); /* reloc to info */
3074 saa_write64(parangesrel
, 0);
3075 saa_write32(paranges
,0); /* offset into info */
3076 saa_write8(paranges
,8); /* pointer size */
3077 saa_write8(paranges
,0); /* not segmented */
3078 saa_write32(paranges
,0); /* padding */
3079 /* iterate though sectlist entries */
3080 psect
= dwarf_fsect
;
3083 for (indx
= 0; indx
< dwarf_nsections
; indx
++) {
3084 plinep
= psect
->psaa
;
3085 /* Line Number Program Epilogue */
3086 saa_write8(plinep
,2); /* std op 2 */
3087 saa_write8(plinep
,(sects
[psect
->section
]->len
)-psect
->offset
);
3088 saa_write8(plinep
,DW_LNS_extended_op
);
3089 saa_write8(plinep
,1); /* operand length */
3090 saa_write8(plinep
,DW_LNE_end_sequence
);
3091 totlen
+= plinep
->datalen
;
3092 /* range table relocation entry */
3093 saa_write64(parangesrel
, paranges
->datalen
+ 4);
3094 saa_write64(parangesrel
, ((uint64_t) (psect
->section
+ 2) << 32) + R_X86_64_64
);
3095 saa_write64(parangesrel
, (uint64_t) 0);
3096 /* range table entry */
3097 saa_write64(paranges
,0x0000); /* range start */
3098 saa_write64(paranges
,sects
[psect
->section
]->len
); /* range length */
3099 highaddr
+= sects
[psect
->section
]->len
;
3100 /* done with this entry */
3101 psect
= psect
->next
;
3103 saa_write64(paranges
,0); /* null address */
3104 saa_write64(paranges
,0); /* null length */
3105 saalen
= paranges
->datalen
;
3106 arangeslen
= saalen
+ 4;
3107 arangesbuf
= pbuf
= nasm_malloc(arangeslen
);
3108 WRITELONG(pbuf
,saalen
); /* initial length */
3109 saa_rnbytes(paranges
, pbuf
, saalen
);
3113 /* build rela.aranges section */
3114 arangesrellen
= saalen
= parangesrel
->datalen
;
3115 arangesrelbuf
= pbuf
= nasm_malloc(arangesrellen
);
3116 saa_rnbytes(parangesrel
, pbuf
, saalen
);
3117 saa_free(parangesrel
);
3119 /* build pubnames section */
3120 ppubnames
= saa_init(1L);
3121 saa_write16(ppubnames
,3); /* dwarf version */
3122 saa_write32(ppubnames
,0); /* offset into info */
3123 saa_write32(ppubnames
,0); /* space used in info */
3124 saa_write32(ppubnames
,0); /* end of list */
3125 saalen
= ppubnames
->datalen
;
3126 pubnameslen
= saalen
+ 4;
3127 pubnamesbuf
= pbuf
= nasm_malloc(pubnameslen
);
3128 WRITELONG(pbuf
,saalen
); /* initial length */
3129 saa_rnbytes(ppubnames
, pbuf
, saalen
);
3130 saa_free(ppubnames
);
3133 /* build info section */
3134 pinfo
= saa_init(1L);
3135 pinforel
= saa_init(1L);
3136 saa_write16(pinfo
,2); /* dwarf version */
3137 saa_write32(pinforel
, pinfo
->datalen
+ 4);
3138 saa_write32(pinforel
, (dwarf_abbrevsym
<< 8) + R_386_32
); /* reloc to abbrev */
3139 saa_write32(pinforel
, 0);
3140 saa_write32(pinfo
,0); /* offset into abbrev */
3141 saa_write8(pinfo
,4); /* pointer size */
3142 saa_write8(pinfo
,1); /* abbrviation number LEB128u */
3143 saa_write32(pinforel
, pinfo
->datalen
+ 4);
3144 saa_write32(pinforel
, ((dwarf_fsect
->section
+ 2) << 8) + R_386_32
);
3145 saa_write32(pinforel
, 0);
3146 saa_write32(pinfo
,0); /* DW_AT_low_pc */
3147 saa_write32(pinforel
, pinfo
->datalen
+ 4);
3148 saa_write32(pinforel
, ((dwarf_fsect
->section
+ 2) << 8) + R_386_32
);
3149 saa_write32(pinforel
, 0);
3150 saa_write32(pinfo
,highaddr
); /* DW_AT_high_pc */
3151 saa_write32(pinforel
, pinfo
->datalen
+ 4);
3152 saa_write32(pinforel
, (dwarf_linesym
<< 8) + R_386_32
); /* reloc to line */
3153 saa_write32(pinforel
, 0);
3154 saa_write32(pinfo
,0); /* DW_AT_stmt_list */
3155 saa_wbytes(pinfo
, elf_module
, strlen(elf_module
)+1);
3156 saa_wbytes(pinfo
, nasm_signature(), nasm_signature_len()+1);
3157 saa_write16(pinfo
,DW_LANG_Mips_Assembler
);
3158 saa_write8(pinfo
,2); /* abbrviation number LEB128u */
3159 saa_write32(pinforel
, pinfo
->datalen
+ 4);
3160 saa_write32(pinforel
, ((dwarf_fsect
->section
+ 2) << 8) + R_386_32
);
3161 saa_write32(pinforel
, 0);
3162 saa_write32(pinfo
,0); /* DW_AT_low_pc */
3163 saa_write32(pinfo
,0); /* DW_AT_frame_base */
3164 saa_write8(pinfo
,0); /* end of entries */
3165 saalen
= pinfo
->datalen
;
3166 infolen
= saalen
+ 4;
3167 infobuf
= pbuf
= nasm_malloc(infolen
);
3168 WRITELONG(pbuf
,saalen
); /* initial length */
3169 saa_rnbytes(pinfo
, pbuf
, saalen
);
3171 } else if (is_elfx32()) {
3172 /* build info section */
3173 pinfo
= saa_init(1L);
3174 pinforel
= saa_init(1L);
3175 saa_write16(pinfo
,3); /* dwarf version */
3176 saa_write32(pinforel
, pinfo
->datalen
+ 4);
3177 saa_write32(pinforel
, (dwarf_abbrevsym
<< 8) + R_X86_64_32
); /* reloc to abbrev */
3178 saa_write32(pinforel
, 0);
3179 saa_write32(pinfo
,0); /* offset into abbrev */
3180 saa_write8(pinfo
,4); /* pointer size */
3181 saa_write8(pinfo
,1); /* abbrviation number LEB128u */
3182 saa_write32(pinforel
, pinfo
->datalen
+ 4);
3183 saa_write32(pinforel
, ((dwarf_fsect
->section
+ 2) << 8) + R_X86_64_32
);
3184 saa_write32(pinforel
, 0);
3185 saa_write32(pinfo
,0); /* DW_AT_low_pc */
3186 saa_write32(pinforel
, pinfo
->datalen
+ 4);
3187 saa_write32(pinforel
, ((dwarf_fsect
->section
+ 2) << 8) + R_X86_64_32
);
3188 saa_write32(pinforel
, 0);
3189 saa_write32(pinfo
,highaddr
); /* DW_AT_high_pc */
3190 saa_write32(pinforel
, pinfo
->datalen
+ 4);
3191 saa_write32(pinforel
, (dwarf_linesym
<< 8) + R_X86_64_32
); /* reloc to line */
3192 saa_write32(pinforel
, 0);
3193 saa_write32(pinfo
,0); /* DW_AT_stmt_list */
3194 saa_wbytes(pinfo
, elf_module
, strlen(elf_module
)+1);
3195 saa_wbytes(pinfo
, nasm_signature(), nasm_signature_len()+1);
3196 saa_write16(pinfo
,DW_LANG_Mips_Assembler
);
3197 saa_write8(pinfo
,2); /* abbrviation number LEB128u */
3198 saa_write32(pinforel
, pinfo
->datalen
+ 4);
3199 saa_write32(pinforel
, ((dwarf_fsect
->section
+ 2) << 8) + R_X86_64_32
);
3200 saa_write32(pinforel
, 0);
3201 saa_write32(pinfo
,0); /* DW_AT_low_pc */
3202 saa_write32(pinfo
,0); /* DW_AT_frame_base */
3203 saa_write8(pinfo
,0); /* end of entries */
3204 saalen
= pinfo
->datalen
;
3205 infolen
= saalen
+ 4;
3206 infobuf
= pbuf
= nasm_malloc(infolen
);
3207 WRITELONG(pbuf
,saalen
); /* initial length */
3208 saa_rnbytes(pinfo
, pbuf
, saalen
);
3211 nasm_assert(is_elf64());
3212 /* build info section */
3213 pinfo
= saa_init(1L);
3214 pinforel
= saa_init(1L);
3215 saa_write16(pinfo
,3); /* dwarf version */
3216 saa_write64(pinforel
, pinfo
->datalen
+ 4);
3217 saa_write64(pinforel
, (dwarf_abbrevsym
<< 32) + R_X86_64_32
); /* reloc to abbrev */
3218 saa_write64(pinforel
, 0);
3219 saa_write32(pinfo
,0); /* offset into abbrev */
3220 saa_write8(pinfo
,8); /* pointer size */
3221 saa_write8(pinfo
,1); /* abbrviation number LEB128u */
3222 saa_write64(pinforel
, pinfo
->datalen
+ 4);
3223 saa_write64(pinforel
, ((uint64_t)(dwarf_fsect
->section
+ 2) << 32) + R_X86_64_64
);
3224 saa_write64(pinforel
, 0);
3225 saa_write64(pinfo
,0); /* DW_AT_low_pc */
3226 saa_write64(pinforel
, pinfo
->datalen
+ 4);
3227 saa_write64(pinforel
, ((uint64_t)(dwarf_fsect
->section
+ 2) << 32) + R_X86_64_64
);
3228 saa_write64(pinforel
, 0);
3229 saa_write64(pinfo
,highaddr
); /* DW_AT_high_pc */
3230 saa_write64(pinforel
, pinfo
->datalen
+ 4);
3231 saa_write64(pinforel
, (dwarf_linesym
<< 32) + R_X86_64_32
); /* reloc to line */
3232 saa_write64(pinforel
, 0);
3233 saa_write32(pinfo
,0); /* DW_AT_stmt_list */
3234 saa_wbytes(pinfo
, elf_module
, strlen(elf_module
)+1);
3235 saa_wbytes(pinfo
, nasm_signature(), nasm_signature_len()+1);
3236 saa_write16(pinfo
,DW_LANG_Mips_Assembler
);
3237 saa_write8(pinfo
,2); /* abbrviation number LEB128u */
3238 saa_write64(pinforel
, pinfo
->datalen
+ 4);
3239 saa_write64(pinforel
, ((uint64_t)(dwarf_fsect
->section
+ 2) << 32) + R_X86_64_64
);
3240 saa_write64(pinforel
, 0);
3241 saa_write64(pinfo
,0); /* DW_AT_low_pc */
3242 saa_write64(pinfo
,0); /* DW_AT_frame_base */
3243 saa_write8(pinfo
,0); /* end of entries */
3244 saalen
= pinfo
->datalen
;
3245 infolen
= saalen
+ 4;
3246 infobuf
= pbuf
= nasm_malloc(infolen
);
3247 WRITELONG(pbuf
,saalen
); /* initial length */
3248 saa_rnbytes(pinfo
, pbuf
, saalen
);
3252 /* build rela.info section */
3253 inforellen
= saalen
= pinforel
->datalen
;
3254 inforelbuf
= pbuf
= nasm_malloc(inforellen
);
3255 saa_rnbytes(pinforel
, pbuf
, saalen
);
3258 /* build abbrev section */
3259 pabbrev
= saa_init(1L);
3260 saa_write8(pabbrev
,1); /* entry number LEB128u */
3261 saa_write8(pabbrev
,DW_TAG_compile_unit
); /* tag LEB128u */
3262 saa_write8(pabbrev
,1); /* has children */
3263 /* the following attributes and forms are all LEB128u values */
3264 saa_write8(pabbrev
,DW_AT_low_pc
);
3265 saa_write8(pabbrev
,DW_FORM_addr
);
3266 saa_write8(pabbrev
,DW_AT_high_pc
);
3267 saa_write8(pabbrev
,DW_FORM_addr
);
3268 saa_write8(pabbrev
,DW_AT_stmt_list
);
3269 saa_write8(pabbrev
,DW_FORM_data4
);
3270 saa_write8(pabbrev
,DW_AT_name
);
3271 saa_write8(pabbrev
,DW_FORM_string
);
3272 saa_write8(pabbrev
,DW_AT_producer
);
3273 saa_write8(pabbrev
,DW_FORM_string
);
3274 saa_write8(pabbrev
,DW_AT_language
);
3275 saa_write8(pabbrev
,DW_FORM_data2
);
3276 saa_write16(pabbrev
,0); /* end of entry */
3277 /* LEB128u usage same as above */
3278 saa_write8(pabbrev
,2); /* entry number */
3279 saa_write8(pabbrev
,DW_TAG_subprogram
);
3280 saa_write8(pabbrev
,0); /* no children */
3281 saa_write8(pabbrev
,DW_AT_low_pc
);
3282 saa_write8(pabbrev
,DW_FORM_addr
);
3283 saa_write8(pabbrev
,DW_AT_frame_base
);
3284 saa_write8(pabbrev
,DW_FORM_data4
);
3285 saa_write16(pabbrev
,0); /* end of entry */
3286 /* Terminal zero entry */
3287 saa_write8(pabbrev
,0);
3288 abbrevlen
= saalen
= pabbrev
->datalen
;
3289 abbrevbuf
= pbuf
= nasm_malloc(saalen
);
3290 saa_rnbytes(pabbrev
, pbuf
, saalen
);
3293 /* build line section */
3295 plines
= saa_init(1L);
3296 saa_write8(plines
,1); /* Minimum Instruction Length */
3297 saa_write8(plines
,1); /* Initial value of 'is_stmt' */
3298 saa_write8(plines
,line_base
); /* Line Base */
3299 saa_write8(plines
,line_range
); /* Line Range */
3300 saa_write8(plines
,opcode_base
); /* Opcode Base */
3301 /* standard opcode lengths (# of LEB128u operands) */
3302 saa_write8(plines
,0); /* Std opcode 1 length */
3303 saa_write8(plines
,1); /* Std opcode 2 length */
3304 saa_write8(plines
,1); /* Std opcode 3 length */
3305 saa_write8(plines
,1); /* Std opcode 4 length */
3306 saa_write8(plines
,1); /* Std opcode 5 length */
3307 saa_write8(plines
,0); /* Std opcode 6 length */
3308 saa_write8(plines
,0); /* Std opcode 7 length */
3309 saa_write8(plines
,0); /* Std opcode 8 length */
3310 saa_write8(plines
,1); /* Std opcode 9 length */
3311 saa_write8(plines
,0); /* Std opcode 10 length */
3312 saa_write8(plines
,0); /* Std opcode 11 length */
3313 saa_write8(plines
,1); /* Std opcode 12 length */
3314 /* Directory Table */
3315 saa_write8(plines
,0); /* End of table */
3316 /* File Name Table */
3317 ftentry
= dwarf_flist
;
3318 for (indx
= 0; indx
< dwarf_numfiles
; indx
++) {
3319 saa_wbytes(plines
, ftentry
->filename
, (int32_t)(strlen(ftentry
->filename
) + 1));
3320 saa_write8(plines
,0); /* directory LEB128u */
3321 saa_write8(plines
,0); /* time LEB128u */
3322 saa_write8(plines
,0); /* size LEB128u */
3323 ftentry
= ftentry
->next
;
3325 saa_write8(plines
,0); /* End of table */
3326 linepoff
= plines
->datalen
;
3327 linelen
= linepoff
+ totlen
+ 10;
3328 linebuf
= pbuf
= nasm_malloc(linelen
);
3329 WRITELONG(pbuf
,linelen
-4); /* initial length */
3330 WRITESHORT(pbuf
,3); /* dwarf version */
3331 WRITELONG(pbuf
,linepoff
); /* offset to line number program */
3332 /* write line header */
3334 saa_rnbytes(plines
, pbuf
, saalen
); /* read a given no. of bytes */
3337 /* concatonate line program ranges */
3339 plinesrel
= saa_init(1L);
3340 psect
= dwarf_fsect
;
3342 for (indx
= 0; indx
< dwarf_nsections
; indx
++) {
3343 saa_write32(plinesrel
, linepoff
);
3344 saa_write32(plinesrel
, ((uint32_t) (psect
->section
+ 2) << 8) + R_386_32
);
3345 saa_write32(plinesrel
, (uint32_t) 0);
3346 plinep
= psect
->psaa
;
3347 saalen
= plinep
->datalen
;
3348 saa_rnbytes(plinep
, pbuf
, saalen
);
3352 /* done with this entry */
3353 psect
= psect
->next
;
3355 } else if (is_elfx32()) {
3356 for (indx
= 0; indx
< dwarf_nsections
; indx
++) {
3357 saa_write32(plinesrel
, linepoff
);
3358 saa_write32(plinesrel
, ((psect
->section
+ 2) << 8) + R_X86_64_32
);
3359 saa_write32(plinesrel
, 0);
3360 plinep
= psect
->psaa
;
3361 saalen
= plinep
->datalen
;
3362 saa_rnbytes(plinep
, pbuf
, saalen
);
3366 /* done with this entry */
3367 psect
= psect
->next
;
3370 nasm_assert(is_elf64());
3371 for (indx
= 0; indx
< dwarf_nsections
; indx
++) {
3372 saa_write64(plinesrel
, linepoff
);
3373 saa_write64(plinesrel
, ((uint64_t) (psect
->section
+ 2) << 32) + R_X86_64_64
);
3374 saa_write64(plinesrel
, (uint64_t) 0);
3375 plinep
= psect
->psaa
;
3376 saalen
= plinep
->datalen
;
3377 saa_rnbytes(plinep
, pbuf
, saalen
);
3381 /* done with this entry */
3382 psect
= psect
->next
;
3386 /* build rela.lines section */
3387 linerellen
=saalen
= plinesrel
->datalen
;
3388 linerelbuf
= pbuf
= nasm_malloc(linerellen
);
3389 saa_rnbytes(plinesrel
, pbuf
, saalen
);
3390 saa_free(plinesrel
);
3392 /* build frame section */
3394 framebuf
= pbuf
= nasm_malloc(framelen
);
3395 WRITELONG(pbuf
,framelen
-4); /* initial length */
3397 /* build loc section */
3399 locbuf
= pbuf
= nasm_malloc(loclen
);
3401 WRITELONG(pbuf
,0); /* null beginning offset */
3402 WRITELONG(pbuf
,0); /* null ending offset */
3403 } else if (is_elfx32()) {
3404 WRITELONG(pbuf
,0); /* null beginning offset */
3405 WRITELONG(pbuf
,0); /* null ending offset */
3407 nasm_assert(is_elf64());
3408 WRITEDLONG(pbuf
,0); /* null beginning offset */
3409 WRITEDLONG(pbuf
,0); /* null ending offset */
3413 static void dwarf_cleanup(void)
3415 nasm_free(arangesbuf
);
3416 nasm_free(arangesrelbuf
);
3417 nasm_free(pubnamesbuf
);
3419 nasm_free(inforelbuf
);
3420 nasm_free(abbrevbuf
);
3422 nasm_free(linerelbuf
);
3423 nasm_free(framebuf
);
3427 static void dwarf_findfile(const char * fname
)
3430 struct linelist
*match
;
3432 /* return if fname is current file name */
3433 if (dwarf_clist
&& !(strcmp(fname
, dwarf_clist
->filename
)))
3436 /* search for match */
3439 match
= dwarf_flist
;
3440 for (finx
= 0; finx
< dwarf_numfiles
; finx
++) {
3441 if (!(strcmp(fname
, match
->filename
))) {
3442 dwarf_clist
= match
;
3445 match
= match
->next
;
3449 /* add file name to end of list */
3450 dwarf_clist
= nasm_malloc(sizeof(struct linelist
));
3452 dwarf_clist
->line
= dwarf_numfiles
;
3453 dwarf_clist
->filename
= nasm_malloc(strlen(fname
) + 1);
3454 strcpy(dwarf_clist
->filename
,fname
);
3455 dwarf_clist
->next
= 0;
3456 if (!dwarf_flist
) { /* if first entry */
3457 dwarf_flist
= dwarf_elist
= dwarf_clist
;
3458 dwarf_clist
->last
= 0;
3459 } else { /* chain to previous entry */
3460 dwarf_elist
->next
= dwarf_clist
;
3461 dwarf_elist
= dwarf_clist
;
3465 static void dwarf_findsect(const int index
)
3468 struct sectlist
*match
;
3471 /* return if index is current section index */
3472 if (dwarf_csect
&& (dwarf_csect
->section
== index
))
3475 /* search for match */
3478 match
= dwarf_fsect
;
3479 for (sinx
= 0; sinx
< dwarf_nsections
; sinx
++) {
3480 if (match
->section
== index
) {
3481 dwarf_csect
= match
;
3484 match
= match
->next
;
3488 /* add entry to end of list */
3489 dwarf_csect
= nasm_malloc(sizeof(struct sectlist
));
3491 dwarf_csect
->psaa
= plinep
= saa_init(1L);
3492 dwarf_csect
->line
= 1;
3493 dwarf_csect
->offset
= 0;
3494 dwarf_csect
->file
= 1;
3495 dwarf_csect
->section
= index
;
3496 dwarf_csect
->next
= 0;
3497 /* set relocatable address at start of line program */
3498 saa_write8(plinep
,DW_LNS_extended_op
);
3499 saa_write8(plinep
,is_elf64() ? 9 : 5); /* operand length */
3500 saa_write8(plinep
,DW_LNE_set_address
);
3502 saa_write64(plinep
,0); /* Start Address */
3504 saa_write32(plinep
,0); /* Start Address */
3506 if (!dwarf_fsect
) { /* if first entry */
3507 dwarf_fsect
= dwarf_esect
= dwarf_csect
;
3508 dwarf_csect
->last
= 0;
3509 } else { /* chain to previous entry */
3510 dwarf_esect
->next
= dwarf_csect
;
3511 dwarf_esect
= dwarf_csect
;
3515 #endif /* defined(OF_ELF32) || defined(OF_ELF64) || defined(OF_ELFX32) */