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 inline bool sym_type_local(int type
)
732 return ELF32_ST_BIND(type
) == STB_LOCAL
;
735 static void elf_deflabel(char *name
, int32_t segment
, int64_t offset
,
736 int is_global
, char *special
)
739 struct elf_symbol
*sym
;
740 const char *spcword
= nasm_skip_spaces(special
);
741 int bind
, type
; /* st_info components */
742 const struct elf_section
*sec
= NULL
;
744 if (debug_level(2)) {
745 nasm_debug(" elf_deflabel: %s, seg=%"PRIx32
", off=%"PRIx64
", is_global=%d, %s\n",
746 name
, segment
, offset
, is_global
, special
);
749 if (name
[0] == '.' && name
[1] == '.' && name
[2] != '@') {
751 * This is a NASM special symbol. We never allow it into
752 * the ELF symbol table, even if it's a valid one. If it
753 * _isn't_ a valid one, we should barf immediately.
755 * FIXME: tlsie is Elf32 only, and gottpoff is Elfx32|64 only.
757 if (strcmp(name
, "..gotpc") && strcmp(name
, "..gotoff") &&
758 strcmp(name
, "..got") && strcmp(name
, "..plt") &&
759 strcmp(name
, "..sym") && strcmp(name
, "..gottpoff") &&
760 strcmp(name
, "..tlsie"))
761 nasm_nonfatal("unrecognised special symbol `%s'", name
);
765 if (is_global
== 3) {
766 struct elf_symbol
**s
;
768 * Fix up a forward-reference symbol size from the first
771 for (s
= &fwds
; *s
; s
= &(*s
)->nextfwd
)
772 if (!strcmp((*s
)->name
, name
)) {
773 struct tokenval tokval
;
775 char *p
= nasm_skip_spaces(nasm_skip_word(special
));
779 tokval
.t_type
= TOKEN_INVALID
;
780 e
= evaluate(stdscan
, NULL
, &tokval
, NULL
, 1, NULL
);
783 nasm_nonfatal("cannot use relocatable"
784 " expression as symbol size");
786 (*s
)->size
= reloc_value(e
);
790 * Remove it from the list of unresolved sizes.
792 nasm_free((*s
)->name
);
796 return; /* it wasn't an important one */
799 saa_wbytes(strs
, name
, (int32_t)(1 + strlen(name
)));
800 strslen
+= 1 + strlen(name
);
802 lastsym
= sym
= saa_wstruct(syms
);
804 memset(&sym
->symv
, 0, sizeof(struct rbtree
));
807 bind
= is_global
? STB_GLOBAL
: STB_LOCAL
;
809 sym
->other
= STV_DEFAULT
;
811 if (segment
== NO_SEG
) {
812 sym
->section
= XSHN_ABS
;
814 sym
->section
= XSHN_UNDEF
;
815 if (segment
== def_seg
) {
816 /* we have to be sure at least text section is there */
818 if (segment
!= elf_section_names(".text", &tempint
))
819 nasm_panic("strange segment conditions in ELF driver");
821 sec
= raa_read_ptr(section_by_index
, segment
>> 1);
823 sym
->section
= sec
->shndx
;
826 if (is_global
== 2) {
829 sym
->section
= XSHN_COMMON
;
831 * We have a common variable. Check the special text to see
832 * if it's a valid number and power of two; if so, store it
833 * as the alignment for the common variable.
835 * XXX: this should allow an expression.
839 sym
->symv
.key
= readnum(spcword
, &err
);
841 nasm_nonfatal("alignment constraint `%s' is not a"
842 " valid number", special
);
843 else if (!is_power2(sym
->symv
.key
))
844 nasm_nonfatal("alignment constraint `%s' is not a"
845 " power of two", special
);
846 spcword
= nasm_skip_spaces(nasm_skip_word(spcword
));
849 sym
->symv
.key
= (sym
->section
== XSHN_UNDEF
? 0 : offset
);
852 if (spcword
&& *spcword
) {
858 wend
= nasm_skip_word(spcword
);
859 wlen
= wend
- spcword
;
863 if (!nasm_strnicmp(spcword
, "data", wlen
))
865 else if (!nasm_strnicmp(spcword
, "weak", wlen
))
872 if (!nasm_strnicmp(spcword
, "notype", wlen
))
874 else if (!nasm_strnicmp(spcword
, "object", wlen
))
876 else if (!nasm_strnicmp(spcword
, "hidden", wlen
))
877 sym
->other
= STV_HIDDEN
;
878 else if (!nasm_strnicmp(spcword
, "strong", wlen
))
885 if (!nasm_strnicmp(spcword
, "default", wlen
))
886 sym
->other
= STV_DEFAULT
;
892 if (!nasm_strnicmp(spcword
, "function", wlen
))
894 else if (!nasm_stricmp(spcword
, "internal"))
895 sym
->other
= STV_INTERNAL
;
901 if (!nasm_strnicmp(spcword
, "protected", wlen
))
902 sym
->other
= STV_PROTECTED
;
913 spcword
= nasm_skip_spaces(wend
);
915 if (!is_global
&& bind
!= STB_LOCAL
) {
916 nasm_nonfatal("weak and strong only applies to global symbols");
920 if (spcword
&& *spcword
) {
921 struct tokenval tokval
;
924 char *saveme
= stdscan_get();
927 * We have a size expression; attempt to
931 stdscan_set((char *)spcword
);
932 tokval
.t_type
= TOKEN_INVALID
;
933 e
= evaluate(stdscan
, NULL
, &tokval
, &fwd
, 0, NULL
);
937 sym
->name
= nasm_strdup(name
);
940 nasm_nonfatal("cannot use relocatable"
941 " expression as symbol size");
943 sym
->size
= reloc_value(e
);
950 * If it is in a TLS segment, mark symbol accordingly.
952 if (sec
&& (sec
->flags
& SHF_TLS
))
955 /* Note: ELF32_ST_INFO() and ELF64_ST_INFO() are identical */
956 sym
->type
= ELF32_ST_INFO(bind
, type
);
958 if (sym_type_local(sym
->type
)) {
962 * If sym->section == SHN_ABS, then the first line of the
963 * else section would cause a core dump, because its a reference
964 * beyond the end of the section array.
965 * This behaviour is exhibited by this code:
968 * To avoid such a crash, such requests are silently discarded.
969 * This may not be the best solution.
971 if (sym
->section
== XSHN_UNDEF
|| sym
->section
== XSHN_COMMON
) {
972 bsym
= raa_write(bsym
, segment
, nglobs
);
973 } else if (sym
->section
!= XSHN_ABS
) {
975 * This is a global symbol; so we must add it to the rbtree
976 * of global symbols in its section.
978 * In addition, we check the special text for symbol
979 * type and size information.
981 sects
[sym
->section
-1]->gsyms
=
982 rb_insert(sects
[sym
->section
-1]->gsyms
, &sym
->symv
);
985 sym
->globnum
= nglobs
;
990 static void elf_add_reloc(struct elf_section
*sect
, int32_t segment
,
991 int64_t offset
, int type
)
995 r
= *sect
->tail
= nasm_zalloc(sizeof(struct elf_reloc
));
996 sect
->tail
= &r
->next
;
998 r
->address
= sect
->len
;
1001 if (segment
!= NO_SEG
) {
1002 const struct elf_section
*s
;
1003 s
= raa_read_ptr(section_by_index
, segment
>> 1);
1005 r
->symbol
= s
->shndx
+ 1;
1007 r
->symbol
= GLOBAL_TEMP_BASE
+ raa_read(bsym
, segment
);
1015 * This routine deals with ..got and ..sym relocations: the more
1016 * complicated kinds. In shared-library writing, some relocations
1017 * with respect to global symbols must refer to the precise symbol
1018 * rather than referring to an offset from the base of the section
1019 * _containing_ the symbol. Such relocations call to this routine,
1020 * which searches the symbol list for the symbol in question.
1022 * R_386_GOT32 | R_X86_64_GOT32 references require the _exact_ symbol address to be
1023 * used; R_386_32 | R_X86_64_32 references can be at an offset from the symbol.
1024 * The boolean argument `exact' tells us this.
1026 * Return value is the adjusted value of `addr', having become an
1027 * offset from the symbol rather than the section. Should always be
1028 * zero when returning from an exact call.
1030 * Limitation: if you define two symbols at the same place,
1031 * confusion will occur.
1033 * Inefficiency: we search, currently, using a linked list which
1034 * isn't even necessarily sorted.
1036 static int64_t elf_add_gsym_reloc(struct elf_section
*sect
,
1037 int32_t segment
, uint64_t offset
,
1038 int64_t pcrel
, int type
, bool exact
)
1040 struct elf_reloc
*r
;
1041 struct elf_section
*s
;
1042 struct elf_symbol
*sym
;
1046 * First look up the segment/offset pair and find a global
1047 * symbol corresponding to it. If it's not one of our segments,
1048 * then it must be an external symbol, in which case we're fine
1049 * doing a normal elf_add_reloc after first sanity-checking
1050 * that the offset from the symbol is zero.
1052 s
= raa_read_ptr(section_by_index
, segment
>> 1);
1054 if (exact
&& offset
)
1055 nasm_nonfatal("invalid access to an external symbol");
1057 elf_add_reloc(sect
, segment
, offset
- pcrel
, type
);
1061 srb
= rb_search(s
->gsyms
, offset
);
1062 if (!srb
|| (exact
&& srb
->key
!= offset
)) {
1063 nasm_nonfatal("unable to find a suitable global symbol"
1064 " for this reference");
1067 sym
= container_of(srb
, struct elf_symbol
, symv
);
1069 r
= *sect
->tail
= nasm_malloc(sizeof(struct elf_reloc
));
1070 sect
->tail
= &r
->next
;
1073 r
->address
= sect
->len
;
1074 r
->offset
= offset
- pcrel
- sym
->symv
.key
;
1075 r
->symbol
= GLOBAL_TEMP_BASE
+ sym
->globnum
;
1082 static void elf32_out(int32_t segto
, const void *data
,
1083 enum out_type type
, uint64_t size
,
1084 int32_t segment
, int32_t wrt
)
1086 struct elf_section
*s
;
1089 static struct symlininfo sinfo
;
1092 * handle absolute-assembly (structure definitions)
1094 if (segto
== NO_SEG
) {
1095 if (type
!= OUT_RESERVE
)
1096 nasm_nonfatal("attempt to assemble code in [ABSOLUTE] space");
1100 s
= raa_read_ptr(section_by_index
, segto
>> 1);
1102 int tempint
; /* ignored */
1103 if (segto
!= elf_section_names(".text", &tempint
))
1104 nasm_panic("strange segment conditions in ELF driver");
1106 s
= sects
[nsects
- 1];
1109 /* again some stabs debugging stuff */
1110 sinfo
.offset
= s
->len
;
1111 /* Adjust to an index of the section table. */
1112 sinfo
.section
= s
->shndx
- 1;
1113 sinfo
.segto
= segto
;
1114 sinfo
.name
= s
->name
;
1115 dfmt
->debug_output(TY_DEBUGSYMLIN
, &sinfo
);
1116 /* end of debugging stuff */
1118 if (s
->type
== SHT_NOBITS
&& type
!= OUT_RESERVE
) {
1119 nasm_warn(WARN_OTHER
, "attempt to initialize memory in"
1120 " BSS section `%s': ignored", s
->name
);
1121 s
->len
+= realsize(type
, size
);
1127 if (s
->type
!= SHT_NOBITS
) {
1128 nasm_warn(WARN_ZEROING
, "uninitialized space declared in"
1129 " non-BSS section `%s': zeroing", s
->name
);
1130 elf_sect_write(s
, NULL
, size
);
1136 elf_sect_write(s
, data
, size
);
1142 int asize
= abs((int)size
);
1144 addr
= *(int64_t *)data
;
1145 if (segment
!= NO_SEG
) {
1147 nasm_nonfatal("ELF format does not support"
1148 " segment base references");
1150 if (wrt
== NO_SEG
) {
1152 * The if() is a hack to deal with compilers which
1153 * don't handle switch() statements with 64-bit
1158 elf_add_reloc(s
, segment
, 0, R_386_8
);
1161 elf_add_reloc(s
, segment
, 0, R_386_16
);
1164 elf_add_reloc(s
, segment
, 0, R_386_32
);
1166 default: /* Error issued further down */
1170 } else if (wrt
== elf_gotpc_sect
+ 1) {
1172 * The user will supply GOT relative to $$. ELF
1173 * will let us have GOT relative to $. So we
1174 * need to fix up the data item by $-$$.
1178 elf_add_reloc(s
, segment
, 0, R_386_GOTPC
);
1179 } else if (wrt
== elf_gotoff_sect
+ 1) {
1181 elf_add_reloc(s
, segment
, 0, R_386_GOTOFF
);
1182 } else if (wrt
== elf_tlsie_sect
+ 1) {
1184 addr
= elf_add_gsym_reloc(s
, segment
, addr
, 0,
1185 R_386_TLS_IE
, true);
1186 } else if (wrt
== elf_got_sect
+ 1) {
1188 addr
= elf_add_gsym_reloc(s
, segment
, addr
, 0,
1190 } else if (wrt
== elf_sym_sect
+ 1) {
1193 addr
= elf_add_gsym_reloc(s
, segment
, addr
, 0,
1197 addr
= elf_add_gsym_reloc(s
, segment
, addr
, 0,
1201 addr
= elf_add_gsym_reloc(s
, segment
, addr
, 0,
1208 } else if (wrt
== elf_plt_sect
+ 1) {
1209 nasm_nonfatal("ELF format cannot produce non-PC-"
1210 "relative PLT references");
1212 nasm_nonfatal("ELF format does not support this"
1214 wrt
= NO_SEG
; /* we can at least _try_ to continue */
1220 nasm_nonfatal("Unsupported %d-bit ELF relocation", asize
<< 3);
1222 elf_sect_writeaddr(s
, addr
, asize
);
1227 reltype
= R_386_PC8
;
1231 reltype
= R_386_PC16
;
1236 addr
= *(int64_t *)data
- size
;
1237 nasm_assert(segment
!= segto
);
1238 if (segment
!= NO_SEG
&& (segment
& 1)) {
1239 nasm_nonfatal("ELF format does not support"
1240 " segment base references");
1242 if (wrt
== NO_SEG
) {
1243 elf_add_reloc(s
, segment
, 0, reltype
);
1245 nasm_nonfatal("Unsupported %d-bit ELF relocation", bytes
<< 3);
1248 elf_sect_writeaddr(s
, addr
, bytes
);
1252 addr
= *(int64_t *)data
- size
;
1253 if (segment
== segto
)
1254 nasm_panic("intra-segment OUT_REL4ADR");
1255 if (segment
!= NO_SEG
&& (segment
& 1)) {
1256 nasm_nonfatal("ELF format does not support"
1257 " segment base references");
1259 if (wrt
== NO_SEG
) {
1260 elf_add_reloc(s
, segment
, 0, R_386_PC32
);
1261 } else if (wrt
== elf_plt_sect
+ 1) {
1262 elf_add_reloc(s
, segment
, 0, R_386_PLT32
);
1263 } else if (wrt
== elf_gotpc_sect
+ 1 ||
1264 wrt
== elf_gotoff_sect
+ 1 ||
1265 wrt
== elf_got_sect
+ 1) {
1266 nasm_nonfatal("ELF format cannot produce PC-"
1267 "relative GOT references");
1269 nasm_nonfatal("ELF format does not support this"
1271 wrt
= NO_SEG
; /* we can at least _try_ to continue */
1274 elf_sect_writeaddr(s
, addr
, 4);
1278 nasm_nonfatal("32-bit ELF format does not support 64-bit relocations");
1280 elf_sect_writeaddr(s
, addr
, 8);
1287 static void elf64_out(int32_t segto
, const void *data
,
1288 enum out_type type
, uint64_t size
,
1289 int32_t segment
, int32_t wrt
)
1291 struct elf_section
*s
;
1294 static struct symlininfo sinfo
;
1297 * handle absolute-assembly (structure definitions)
1299 if (segto
== NO_SEG
) {
1300 if (type
!= OUT_RESERVE
)
1301 nasm_nonfatal("attempt to assemble code in [ABSOLUTE] space");
1305 s
= raa_read_ptr(section_by_index
, segto
>> 1);
1307 int tempint
; /* ignored */
1308 if (segto
!= elf_section_names(".text", &tempint
))
1309 nasm_panic("strange segment conditions in ELF driver");
1311 s
= sects
[nsects
- 1];
1314 /* again some stabs debugging stuff */
1315 sinfo
.offset
= s
->len
;
1316 /* Adjust to an index of the section table. */
1317 sinfo
.section
= s
->shndx
- 1;
1318 sinfo
.segto
= segto
;
1319 sinfo
.name
= s
->name
;
1320 dfmt
->debug_output(TY_DEBUGSYMLIN
, &sinfo
);
1321 /* end of debugging stuff */
1323 if (s
->type
== SHT_NOBITS
&& type
!= OUT_RESERVE
) {
1324 nasm_warn(WARN_OTHER
, "attempt to initialize memory in"
1325 " BSS section `%s': ignored", s
->name
);
1326 s
->len
+= realsize(type
, size
);
1332 if (s
->type
!= SHT_NOBITS
) {
1333 nasm_warn(WARN_ZEROING
, "uninitialized space declared in"
1334 " non-BSS section `%s': zeroing", s
->name
);
1335 elf_sect_write(s
, NULL
, size
);
1341 if (segment
!= NO_SEG
)
1342 nasm_panic("OUT_RAWDATA with other than NO_SEG");
1343 elf_sect_write(s
, data
, size
);
1348 int isize
= (int)size
;
1349 int asize
= abs((int)size
);
1351 addr
= *(int64_t *)data
;
1352 if (segment
== NO_SEG
) {
1354 } else if (segment
& 1) {
1355 nasm_nonfatal("ELF format does not support"
1356 " segment base references");
1358 if (wrt
== NO_SEG
) {
1362 elf_add_reloc(s
, segment
, addr
, R_X86_64_8
);
1366 elf_add_reloc(s
, segment
, addr
, R_X86_64_16
);
1369 elf_add_reloc(s
, segment
, addr
, R_X86_64_32
);
1372 elf_add_reloc(s
, segment
, addr
, R_X86_64_32S
);
1376 elf_add_reloc(s
, segment
, addr
, R_X86_64_64
);
1379 nasm_panic("internal error elf64-hpa-871");
1383 } else if (wrt
== elf_gotpc_sect
+ 1) {
1385 * The user will supply GOT relative to $$. ELF
1386 * will let us have GOT relative to $. So we
1387 * need to fix up the data item by $-$$.
1390 elf_add_reloc(s
, segment
, addr
, R_X86_64_GOTPC32
);
1392 } else if (wrt
== elf_gotoff_sect
+ 1) {
1394 nasm_nonfatal("ELF64 requires ..gotoff "
1395 "references to be qword");
1397 elf_add_reloc(s
, segment
, addr
, R_X86_64_GOTOFF64
);
1400 } else if (wrt
== elf_got_sect
+ 1) {
1403 elf_add_gsym_reloc(s
, segment
, addr
, 0,
1404 R_X86_64_GOT32
, true);
1408 elf_add_gsym_reloc(s
, segment
, addr
, 0,
1409 R_X86_64_GOT64
, true);
1413 nasm_nonfatal("invalid ..got reference");
1416 } else if (wrt
== elf_sym_sect
+ 1) {
1420 elf_add_gsym_reloc(s
, segment
, addr
, 0,
1426 elf_add_gsym_reloc(s
, segment
, addr
, 0,
1427 R_X86_64_16
, false);
1431 elf_add_gsym_reloc(s
, segment
, addr
, 0,
1432 R_X86_64_32
, false);
1436 elf_add_gsym_reloc(s
, segment
, addr
, 0,
1437 R_X86_64_32S
, false);
1442 elf_add_gsym_reloc(s
, segment
, addr
, 0,
1443 R_X86_64_64
, false);
1447 nasm_panic("internal error elf64-hpa-903");
1450 } else if (wrt
== elf_plt_sect
+ 1) {
1451 nasm_nonfatal("ELF format cannot produce non-PC-"
1452 "relative PLT references");
1454 nasm_nonfatal("ELF format does not support this"
1458 elf_sect_writeaddr(s
, addr
, asize
);
1463 reltype
= R_X86_64_PC8
;
1468 reltype
= R_X86_64_PC16
;
1473 addr
= *(int64_t *)data
- size
;
1474 if (segment
== segto
)
1475 nasm_panic("intra-segment OUT_REL1ADR");
1476 if (segment
== NO_SEG
) {
1478 } else if (segment
& 1) {
1479 nasm_nonfatal("ELF format does not support"
1480 " segment base references");
1482 if (wrt
== NO_SEG
) {
1483 elf_add_reloc(s
, segment
, addr
, reltype
);
1486 nasm_nonfatal("Unsupported %d-bit ELF relocation", bytes
<< 3);
1489 elf_sect_writeaddr(s
, addr
, bytes
);
1493 addr
= *(int64_t *)data
- size
;
1494 if (segment
== segto
)
1495 nasm_panic("intra-segment OUT_REL4ADR");
1496 if (segment
== NO_SEG
) {
1498 } else if (segment
& 1) {
1499 nasm_nonfatal("ELF64 format does not support"
1500 " segment base references");
1502 if (wrt
== NO_SEG
) {
1503 elf_add_reloc(s
, segment
, addr
, R_X86_64_PC32
);
1505 } else if (wrt
== elf_plt_sect
+ 1) {
1506 elf_add_gsym_reloc(s
, segment
, addr
+size
, size
,
1507 R_X86_64_PLT32
, true);
1509 } else if (wrt
== elf_gotpc_sect
+ 1 ||
1510 wrt
== elf_got_sect
+ 1) {
1511 elf_add_gsym_reloc(s
, segment
, addr
+size
, size
,
1512 R_X86_64_GOTPCREL
, true);
1514 } else if (wrt
== elf_gotoff_sect
+ 1 ||
1515 wrt
== elf_got_sect
+ 1) {
1516 nasm_nonfatal("ELF64 requires ..gotoff references to be "
1518 } else if (wrt
== elf_gottpoff_sect
+ 1) {
1519 elf_add_gsym_reloc(s
, segment
, addr
+size
, size
,
1520 R_X86_64_GOTTPOFF
, true);
1523 nasm_nonfatal("ELF64 format does not support this"
1527 elf_sect_writeaddr(s
, addr
, 4);
1531 addr
= *(int64_t *)data
- size
;
1532 if (segment
== segto
)
1533 nasm_panic("intra-segment OUT_REL8ADR");
1534 if (segment
== NO_SEG
) {
1536 } else if (segment
& 1) {
1537 nasm_nonfatal("ELF64 format does not support"
1538 " segment base references");
1540 if (wrt
== NO_SEG
) {
1541 elf_add_reloc(s
, segment
, addr
, R_X86_64_PC64
);
1543 } else if (wrt
== elf_gotpc_sect
+ 1 ||
1544 wrt
== elf_got_sect
+ 1) {
1545 elf_add_gsym_reloc(s
, segment
, addr
+size
, size
,
1546 R_X86_64_GOTPCREL64
, true);
1548 } else if (wrt
== elf_gotoff_sect
+ 1 ||
1549 wrt
== elf_got_sect
+ 1) {
1550 nasm_nonfatal("ELF64 requires ..gotoff references to be "
1552 } else if (wrt
== elf_gottpoff_sect
+ 1) {
1553 nasm_nonfatal("ELF64 requires ..gottpoff references to be "
1556 nasm_nonfatal("ELF64 format does not support this"
1560 elf_sect_writeaddr(s
, addr
, 8);
1568 static void elfx32_out(int32_t segto
, const void *data
,
1569 enum out_type type
, uint64_t size
,
1570 int32_t segment
, int32_t wrt
)
1572 struct elf_section
*s
;
1575 static struct symlininfo sinfo
;
1578 * handle absolute-assembly (structure definitions)
1580 if (segto
== NO_SEG
) {
1581 if (type
!= OUT_RESERVE
)
1582 nasm_nonfatal("attempt to assemble code in [ABSOLUTE] space");
1586 s
= raa_read_ptr(section_by_index
, segto
>> 1);
1588 int tempint
; /* ignored */
1589 if (segto
!= elf_section_names(".text", &tempint
))
1590 nasm_panic("strange segment conditions in ELF driver");
1592 s
= sects
[nsects
- 1];
1595 /* again some stabs debugging stuff */
1596 sinfo
.offset
= s
->len
;
1597 /* Adjust to an index of the section table. */
1598 sinfo
.section
= s
->shndx
- 1;
1599 sinfo
.segto
= segto
;
1600 sinfo
.name
= s
->name
;
1601 dfmt
->debug_output(TY_DEBUGSYMLIN
, &sinfo
);
1602 /* end of debugging stuff */
1604 if (s
->type
== SHT_NOBITS
&& type
!= OUT_RESERVE
) {
1605 nasm_warn(WARN_OTHER
, "attempt to initialize memory in"
1606 " BSS section `%s': ignored", s
->name
);
1607 s
->len
+= realsize(type
, size
);
1613 if (s
->type
!= SHT_NOBITS
) {
1614 nasm_warn(WARN_ZEROING
, "uninitialized space declared in"
1615 " non-BSS section `%s': zeroing", s
->name
);
1616 elf_sect_write(s
, NULL
, size
);
1622 if (segment
!= NO_SEG
)
1623 nasm_panic("OUT_RAWDATA with other than NO_SEG");
1624 elf_sect_write(s
, data
, size
);
1629 int isize
= (int)size
;
1630 int asize
= abs((int)size
);
1632 addr
= *(int64_t *)data
;
1633 if (segment
== NO_SEG
) {
1635 } else if (segment
& 1) {
1636 nasm_nonfatal("ELF format does not support"
1637 " segment base references");
1639 if (wrt
== NO_SEG
) {
1643 elf_add_reloc(s
, segment
, addr
, R_X86_64_8
);
1647 elf_add_reloc(s
, segment
, addr
, R_X86_64_16
);
1650 elf_add_reloc(s
, segment
, addr
, R_X86_64_32
);
1653 elf_add_reloc(s
, segment
, addr
, R_X86_64_32S
);
1657 elf_add_reloc(s
, segment
, addr
, R_X86_64_64
);
1660 nasm_panic("internal error elfx32-hpa-871");
1664 } else if (wrt
== elf_gotpc_sect
+ 1) {
1666 * The user will supply GOT relative to $$. ELF
1667 * will let us have GOT relative to $. So we
1668 * need to fix up the data item by $-$$.
1671 elf_add_reloc(s
, segment
, addr
, R_X86_64_GOTPC32
);
1673 } else if (wrt
== elf_gotoff_sect
+ 1) {
1674 nasm_nonfatal("ELFX32 doesn't support "
1675 "R_X86_64_GOTOFF64");
1676 } else if (wrt
== elf_got_sect
+ 1) {
1679 elf_add_gsym_reloc(s
, segment
, addr
, 0,
1680 R_X86_64_GOT32
, true);
1684 nasm_nonfatal("invalid ..got reference");
1687 } else if (wrt
== elf_sym_sect
+ 1) {
1691 elf_add_gsym_reloc(s
, segment
, addr
, 0,
1697 elf_add_gsym_reloc(s
, segment
, addr
, 0,
1698 R_X86_64_16
, false);
1702 elf_add_gsym_reloc(s
, segment
, addr
, 0,
1703 R_X86_64_32
, false);
1707 elf_add_gsym_reloc(s
, segment
, addr
, 0,
1708 R_X86_64_32S
, false);
1713 elf_add_gsym_reloc(s
, segment
, addr
, 0,
1714 R_X86_64_64
, false);
1718 nasm_panic("internal error elfx32-hpa-903");
1721 } else if (wrt
== elf_plt_sect
+ 1) {
1722 nasm_nonfatal("ELF format cannot produce non-PC-"
1723 "relative PLT references");
1725 nasm_nonfatal("ELF format does not support this"
1729 elf_sect_writeaddr(s
, addr
, asize
);
1734 reltype
= R_X86_64_PC8
;
1739 reltype
= R_X86_64_PC16
;
1744 addr
= *(int64_t *)data
- size
;
1745 if (segment
== segto
)
1746 nasm_panic("intra-segment OUT_REL1ADR");
1747 if (segment
== NO_SEG
) {
1749 } else if (segment
& 1) {
1750 nasm_nonfatal("ELF format does not support"
1751 " segment base references");
1753 if (wrt
== NO_SEG
) {
1754 elf_add_reloc(s
, segment
, addr
, reltype
);
1757 nasm_nonfatal("unsupported %d-bit ELF relocation", bytes
<< 3);
1760 elf_sect_writeaddr(s
, addr
, bytes
);
1764 addr
= *(int64_t *)data
- size
;
1765 if (segment
== segto
)
1766 nasm_panic("intra-segment OUT_REL4ADR");
1767 if (segment
== NO_SEG
) {
1769 } else if (segment
& 1) {
1770 nasm_nonfatal("ELFX32 format does not support"
1771 " segment base references");
1773 if (wrt
== NO_SEG
) {
1774 elf_add_reloc(s
, segment
, addr
, R_X86_64_PC32
);
1776 } else if (wrt
== elf_plt_sect
+ 1) {
1777 elf_add_gsym_reloc(s
, segment
, addr
+size
, size
,
1778 R_X86_64_PLT32
, true);
1780 } else if (wrt
== elf_gotpc_sect
+ 1 ||
1781 wrt
== elf_got_sect
+ 1) {
1782 elf_add_gsym_reloc(s
, segment
, addr
+size
, size
,
1783 R_X86_64_GOTPCREL
, true);
1785 } else if (wrt
== elf_gotoff_sect
+ 1 ||
1786 wrt
== elf_got_sect
+ 1) {
1787 nasm_nonfatal("invalid ..gotoff reference");
1788 } else if (wrt
== elf_gottpoff_sect
+ 1) {
1789 elf_add_gsym_reloc(s
, segment
, addr
+size
, size
,
1790 R_X86_64_GOTTPOFF
, true);
1793 nasm_nonfatal("ELFX32 format does not support this use of WRT");
1796 elf_sect_writeaddr(s
, addr
, 4);
1800 nasm_nonfatal("32-bit ELF format does not support 64-bit relocations");
1802 elf_sect_writeaddr(s
, addr
, 8);
1811 * Section index/count with a specified overflow value (usually SHN_INDEX,
1812 * but 0 for e_shnum.
1814 static inline uint16_t elf_shndx(int section
, uint16_t overflow
)
1816 return cpu_to_le16(section
< (int)SHN_LORESERVE
? section
: overflow
);
1819 struct ehdr_common
{
1820 uint8_t e_ident
[EI_NIDENT
];
1829 struct ehdr_common com
;
1832 static void elf_write(void)
1838 int sec_shstrtab
, sec_symtab
, sec_strtab
;
1842 * Add any sections we don't already have:
1843 * rel/rela sections for the user sections, debug sections, and
1844 * the ELF special sections.
1847 sec_debug
= nsections
;
1848 if (dfmt_is_stabs()) {
1849 /* in case the debug information is wanted, just add these three sections... */
1850 add_sectname("", ".stab");
1851 add_sectname("", ".stabstr");
1852 add_sectname(efmt
->relpfx
, ".stab");
1853 } else if (dfmt_is_dwarf()) {
1854 /* the dwarf debug standard specifies the following ten sections,
1855 not all of which are currently implemented,
1856 although all of them are defined. */
1857 add_sectname("", ".debug_aranges");
1858 add_sectname(".rela", ".debug_aranges");
1859 add_sectname("", ".debug_pubnames");
1860 add_sectname("", ".debug_info");
1861 add_sectname(".rela", ".debug_info");
1862 add_sectname("", ".debug_abbrev");
1863 add_sectname("", ".debug_line");
1864 add_sectname(".rela", ".debug_line");
1865 add_sectname("", ".debug_frame");
1866 add_sectname("", ".debug_loc");
1869 sec_shstrtab
= add_sectname("", ".shstrtab");
1870 sec_symtab
= add_sectname("", ".symtab");
1871 sec_strtab
= add_sectname("", ".strtab");
1874 * Build the symbol table and relocation tables.
1876 symtablocal
= elf_build_symtab();
1878 /* Do we need an .symtab_shndx section? */
1880 add_sectname("", ".symtab_shndx");
1882 for (i
= 0; i
< nsects
; i
++) {
1883 if (sects
[i
]->head
) {
1884 add_sectname(efmt
->relpfx
, sects
[i
]->name
);
1885 sects
[i
]->rel
= efmt
->elf_build_reltab(sects
[i
]->head
);
1890 * Output the ELF header.
1894 /* These fields are in the same place for 32 and 64 bits */
1895 memcpy(&ehdr
.com
.e_ident
[EI_MAG0
], ELFMAG
, SELFMAG
);
1896 ehdr
.com
.e_ident
[EI_CLASS
] = efmt
->ei_class
;
1897 ehdr
.com
.e_ident
[EI_DATA
] = ELFDATA2LSB
;
1898 ehdr
.com
.e_ident
[EI_VERSION
] = EV_CURRENT
;
1899 ehdr
.com
.e_ident
[EI_OSABI
] = elf_osabi
;
1900 ehdr
.com
.e_ident
[EI_ABIVERSION
] = elf_abiver
;
1901 ehdr
.com
.e_type
= cpu_to_le16(ET_REL
);
1902 ehdr
.com
.e_machine
= cpu_to_le16(efmt
->e_machine
);
1903 ehdr
.com
.e_version
= cpu_to_le16(EV_CURRENT
);
1906 ehdr
.ehdr32
.e_shoff
= cpu_to_le32(sizeof ehdr
);
1907 ehdr
.ehdr32
.e_ehsize
= cpu_to_le16(sizeof(Elf32_Ehdr
));
1908 ehdr
.ehdr32
.e_shentsize
= cpu_to_le16(sizeof(Elf32_Shdr
));
1909 ehdr
.ehdr32
.e_shnum
= elf_shndx(nsections
, 0);
1910 ehdr
.ehdr32
.e_shstrndx
= elf_shndx(sec_shstrtab
, SHN_XINDEX
);
1912 ehdr
.ehdr64
.e_shoff
= cpu_to_le64(sizeof ehdr
);
1913 ehdr
.ehdr64
.e_ehsize
= cpu_to_le16(sizeof(Elf64_Ehdr
));
1914 ehdr
.ehdr64
.e_shentsize
= cpu_to_le16(sizeof(Elf64_Shdr
));
1915 ehdr
.ehdr64
.e_shnum
= elf_shndx(nsections
, 0);
1916 ehdr
.ehdr64
.e_shstrndx
= elf_shndx(sec_shstrtab
, SHN_XINDEX
);
1919 nasm_write(&ehdr
, sizeof(ehdr
), ofile
);
1920 elf_foffs
= sizeof ehdr
+ efmt
->shdr_size
* nsections
;
1923 * Now output the section header table.
1925 align
= ALIGN(elf_foffs
, SEC_FILEALIGN
) - elf_foffs
;
1928 elf_sects
= nasm_malloc(sizeof(*elf_sects
) * nsections
);
1931 elf_section_header(0, SHT_NULL
, 0, NULL
, false,
1932 nsections
> (int)SHN_LORESERVE
? nsections
: 0,
1933 sec_shstrtab
>= (int)SHN_LORESERVE
? sec_shstrtab
: 0,
1937 /* The normal sections */
1938 for (i
= 0; i
< nsects
; i
++) {
1939 elf_section_header(p
- shstrtab
, sects
[i
]->type
, sects
[i
]->flags
,
1940 sects
[i
]->data
, true,
1941 sects
[i
]->len
, 0, 0,
1942 sects
[i
]->align
, sects
[i
]->entsize
);
1946 /* The debugging sections */
1947 if (dfmt_is_stabs()) {
1948 /* for debugging information, create the last three sections
1949 which are the .stab , .stabstr and .rel.stab sections respectively */
1951 /* this function call creates the stab sections in memory */
1954 if (stabbuf
&& stabstrbuf
&& stabrelbuf
) {
1955 elf_section_header(p
- shstrtab
, SHT_PROGBITS
, 0, stabbuf
, false,
1956 stablen
, sec_stabstr
, 0, 4, 12);
1959 elf_section_header(p
- shstrtab
, SHT_STRTAB
, 0, stabstrbuf
, false,
1960 stabstrlen
, 0, 0, 4, 0);
1963 /* link -> symtable info -> section to refer to */
1964 elf_section_header(p
- shstrtab
, efmt
->reltype
, 0,
1965 stabrelbuf
, false, stabrellen
,
1966 sec_symtab
, sec_stab
,
1967 efmt
->word
, efmt
->rel_size
);
1970 } else if (dfmt_is_dwarf()) {
1971 /* for dwarf debugging information, create the ten dwarf sections */
1973 /* this function call creates the dwarf sections in memory */
1977 elf_section_header(p
- shstrtab
, SHT_PROGBITS
, 0, arangesbuf
, false,
1978 arangeslen
, 0, 0, 1, 0);
1981 elf_section_header(p
- shstrtab
, SHT_RELA
, 0, arangesrelbuf
, false,
1982 arangesrellen
, sec_symtab
,
1984 efmt
->word
, efmt
->rela_size
);
1987 elf_section_header(p
- shstrtab
, SHT_PROGBITS
, 0, pubnamesbuf
,
1988 false, pubnameslen
, 0, 0, 1, 0);
1991 elf_section_header(p
- shstrtab
, SHT_PROGBITS
, 0, infobuf
, false,
1992 infolen
, 0, 0, 1, 0);
1995 elf_section_header(p
- shstrtab
, SHT_RELA
, 0, inforelbuf
, false,
1996 inforellen
, sec_symtab
,
1998 efmt
->word
, efmt
->rela_size
);
2001 elf_section_header(p
- shstrtab
, SHT_PROGBITS
, 0, abbrevbuf
, false,
2002 abbrevlen
, 0, 0, 1, 0);
2005 elf_section_header(p
- shstrtab
, SHT_PROGBITS
, 0, linebuf
, false,
2006 linelen
, 0, 0, 1, 0);
2009 elf_section_header(p
- shstrtab
, SHT_RELA
, 0, linerelbuf
, false,
2010 linerellen
, sec_symtab
,
2012 efmt
->word
, efmt
->rela_size
);
2015 elf_section_header(p
- shstrtab
, SHT_PROGBITS
, 0, framebuf
, false,
2016 framelen
, 0, 0, 8, 0);
2019 elf_section_header(p
- shstrtab
, SHT_PROGBITS
, 0, locbuf
, false,
2020 loclen
, 0, 0, 1, 0);
2025 elf_section_header(p
- shstrtab
, SHT_STRTAB
, 0, shstrtab
, false,
2026 shstrtablen
, 0, 0, 1, 0);
2030 elf_section_header(p
- shstrtab
, SHT_SYMTAB
, 0, symtab
, true,
2031 symtab
->datalen
, sec_strtab
, symtablocal
,
2032 efmt
->word
, efmt
->sym_size
);
2036 elf_section_header(p
- shstrtab
, SHT_STRTAB
, 0, strs
, true,
2037 strslen
, 0, 0, 1, 0);
2042 elf_section_header(p
- shstrtab
, SHT_SYMTAB_SHNDX
, 0,
2043 symtab_shndx
, true, symtab_shndx
->datalen
,
2044 sec_symtab
, 0, 1, 0);
2048 /* The relocation sections */
2049 for (i
= 0; i
< nsects
; i
++) {
2050 if (sects
[i
]->rel
) {
2051 elf_section_header(p
- shstrtab
, efmt
->reltype
, 0,
2052 sects
[i
]->rel
, true, sects
[i
]->rel
->datalen
,
2053 sec_symtab
, sects
[i
]->shndx
,
2054 efmt
->word
, efmt
->rel_size
);
2058 fwritezero(align
, ofile
);
2061 * Now output the sections.
2063 elf_write_sections();
2065 nasm_free(elf_sects
);
2068 saa_free(symtab_shndx
);
2071 static size_t nsyms
;
2073 static void elf_sym(const struct elf_symbol
*sym
)
2075 int shndx
= sym
->section
;
2078 * Careful here. This relies on sym->section being signed; for
2079 * special section indicies this value needs to be cast to
2080 * (int16_t) so that it sign-extends, however, here SHN_LORESERVE
2081 * is used as an unsigned constant.
2083 if (shndx
>= (int)SHN_LORESERVE
) {
2084 if (unlikely(!symtab_shndx
)) {
2085 /* Create symtab_shndx and fill previous entries with zero */
2086 symtab_shndx
= saa_init(1);
2087 saa_wbytes(symtab_shndx
, NULL
, nsyms
<< 2);
2090 shndx
= 0; /* Section index table always write zero */
2094 saa_write32(symtab_shndx
, shndx
);
2100 static void elf32_sym(const struct elf_symbol
*sym
)
2104 sym32
.st_name
= cpu_to_le32(sym
->strpos
);
2105 sym32
.st_value
= cpu_to_le32(sym
->symv
.key
);
2106 sym32
.st_size
= cpu_to_le32(sym
->size
);
2107 sym32
.st_info
= sym
->type
;
2108 sym32
.st_other
= sym
->other
;
2109 sym32
.st_shndx
= elf_shndx(sym
->section
, SHN_XINDEX
);
2110 saa_wbytes(symtab
, &sym32
, sizeof sym32
);
2113 static void elf64_sym(const struct elf_symbol
*sym
)
2117 sym64
.st_name
= cpu_to_le32(sym
->strpos
);
2118 sym64
.st_value
= cpu_to_le64(sym
->symv
.key
);
2119 sym64
.st_size
= cpu_to_le64(sym
->size
);
2120 sym64
.st_info
= sym
->type
;
2121 sym64
.st_other
= sym
->other
;
2122 sym64
.st_shndx
= elf_shndx(sym
->section
, SHN_XINDEX
);
2123 saa_wbytes(symtab
, &sym64
, sizeof sym64
);
2126 static size_t elf_build_symtab(void)
2128 struct elf_symbol
*sym
, xsym
;
2132 symtab
= saa_init(1);
2133 symtab_shndx
= NULL
;
2136 * Zero symbol first as required by spec.
2142 * Next, an entry for the file name.
2146 xsym
.type
= ELF32_ST_INFO(STB_LOCAL
, STT_FILE
);
2147 xsym
.section
= XSHN_ABS
;
2151 * Now some standard symbols defining the segments, for relocation
2155 for (i
= 1; i
<= nsects
; i
++) {
2156 xsym
.type
= ELF64_ST_INFO(STB_LOCAL
, STT_SECTION
);
2162 * dwarf needs symbols for debug sections
2163 * which are relocation targets.
2165 if (dfmt_is_dwarf()) {
2166 dwarf_infosym
= nsyms
;
2167 xsym
.section
= sec_debug_info
;
2170 dwarf_abbrevsym
= nsyms
;
2171 xsym
.section
= sec_debug_abbrev
;
2174 dwarf_linesym
= nsyms
;
2175 xsym
.section
= sec_debug_line
;
2180 * Now the other local symbols.
2183 while ((sym
= saa_rstruct(syms
))) {
2184 if (!sym_type_local(sym
->type
))
2193 * Now the global symbols.
2196 while ((sym
= saa_rstruct(syms
))) {
2197 if (sym_type_local(sym
->type
))
2206 static struct SAA
*elf32_build_reltab(const struct elf_reloc
*r
)
2209 int32_t global_offset
;
2218 * How to onvert from a global placeholder to a real symbol index;
2219 * the +2 refers to the two special entries, the null entry and
2220 * the filename entry.
2222 global_offset
= -GLOBAL_TEMP_BASE
+ nsects
+ nlocals
+ ndebugs
+ 2;
2225 int32_t sym
= r
->symbol
;
2227 if (sym
>= GLOBAL_TEMP_BASE
)
2228 sym
+= global_offset
;
2230 rel32
.r_offset
= cpu_to_le32(r
->address
);
2231 rel32
.r_info
= cpu_to_le32(ELF32_R_INFO(sym
, r
->type
));
2232 saa_wbytes(s
, &rel32
, sizeof rel32
);
2240 static struct SAA
*elfx32_build_reltab(const struct elf_reloc
*r
)
2243 int32_t global_offset
;
2252 * How to onvert from a global placeholder to a real symbol index;
2253 * the +2 refers to the two special entries, the null entry and
2254 * the filename entry.
2256 global_offset
= -GLOBAL_TEMP_BASE
+ nsects
+ nlocals
+ ndebugs
+ 2;
2259 int32_t sym
= r
->symbol
;
2261 if (sym
>= GLOBAL_TEMP_BASE
)
2262 sym
+= global_offset
;
2264 rela32
.r_offset
= cpu_to_le32(r
->address
);
2265 rela32
.r_info
= cpu_to_le32(ELF32_R_INFO(sym
, r
->type
));
2266 rela32
.r_addend
= cpu_to_le32(r
->offset
);
2267 saa_wbytes(s
, &rela32
, sizeof rela32
);
2275 static struct SAA
*elf64_build_reltab(const struct elf_reloc
*r
)
2278 int32_t global_offset
;
2287 * How to onvert from a global placeholder to a real symbol index;
2288 * the +2 refers to the two special entries, the null entry and
2289 * the filename entry.
2291 global_offset
= -GLOBAL_TEMP_BASE
+ nsects
+ nlocals
+ ndebugs
+ 2;
2294 int32_t sym
= r
->symbol
;
2296 if (sym
>= GLOBAL_TEMP_BASE
)
2297 sym
+= global_offset
;
2299 rela64
.r_offset
= cpu_to_le64(r
->address
);
2300 rela64
.r_info
= cpu_to_le64(ELF64_R_INFO(sym
, r
->type
));
2301 rela64
.r_addend
= cpu_to_le64(r
->offset
);
2302 saa_wbytes(s
, &rela64
, sizeof rela64
);
2310 static void elf_section_header(int name
, int type
, uint64_t flags
,
2311 void *data
, bool is_saa
, uint64_t datalen
,
2313 uint64_t align
, uint64_t entsize
)
2315 elf_sects
[elf_nsect
].data
= data
;
2316 elf_sects
[elf_nsect
].len
= datalen
;
2317 elf_sects
[elf_nsect
].is_saa
= is_saa
;
2323 shdr
.sh_name
= cpu_to_le32(name
);
2324 shdr
.sh_type
= cpu_to_le32(type
);
2325 shdr
.sh_flags
= cpu_to_le32(flags
);
2327 shdr
.sh_offset
= cpu_to_le32(type
== SHT_NULL
? 0 : elf_foffs
);
2328 shdr
.sh_size
= cpu_to_le32(datalen
);
2330 elf_foffs
+= ALIGN(datalen
, SEC_FILEALIGN
);
2331 shdr
.sh_link
= cpu_to_le32(link
);
2332 shdr
.sh_info
= cpu_to_le32(info
);
2333 shdr
.sh_addralign
= cpu_to_le32(align
);
2334 shdr
.sh_entsize
= cpu_to_le32(entsize
);
2336 nasm_write(&shdr
, sizeof shdr
, ofile
);
2340 shdr
.sh_name
= cpu_to_le32(name
);
2341 shdr
.sh_type
= cpu_to_le32(type
);
2342 shdr
.sh_flags
= cpu_to_le64(flags
);
2344 shdr
.sh_offset
= cpu_to_le64(type
== SHT_NULL
? 0 : elf_foffs
);
2345 shdr
.sh_size
= cpu_to_le64(datalen
);
2347 elf_foffs
+= ALIGN(datalen
, SEC_FILEALIGN
);
2348 shdr
.sh_link
= cpu_to_le32(link
);
2349 shdr
.sh_info
= cpu_to_le32(info
);
2350 shdr
.sh_addralign
= cpu_to_le64(align
);
2351 shdr
.sh_entsize
= cpu_to_le64(entsize
);
2353 nasm_write(&shdr
, sizeof shdr
, ofile
);
2357 static void elf_write_sections(void)
2360 for (i
= 0; i
< elf_nsect
; i
++)
2361 if (elf_sects
[i
].data
) {
2362 int32_t len
= elf_sects
[i
].len
;
2363 int32_t reallen
= ALIGN(len
, SEC_FILEALIGN
);
2364 int32_t align
= reallen
- len
;
2365 if (elf_sects
[i
].is_saa
)
2366 saa_fpwrite(elf_sects
[i
].data
, ofile
);
2368 nasm_write(elf_sects
[i
].data
, len
, ofile
);
2369 fwritezero(align
, ofile
);
2373 static void elf_sect_write(struct elf_section
*sect
, const void *data
, size_t len
)
2375 saa_wbytes(sect
->data
, data
, len
);
2379 static void elf_sect_writeaddr(struct elf_section
*sect
, int64_t data
, size_t len
)
2381 saa_writeaddr(sect
->data
, data
, len
);
2385 static void elf_sectalign(int32_t seg
, unsigned int value
)
2387 struct elf_section
*s
;
2389 s
= raa_read_ptr(section_by_index
, seg
>> 1);
2390 if (!s
|| !is_power2(value
))
2393 if (value
> s
->align
)
2397 extern macros_t elf_stdmac
[];
2399 /* Claim "elf" as a pragma namespace, for the future */
2400 static const struct pragma_facility elf_pragma_list
[] =
2403 { NULL
, NULL
} /* Implements the canonical output name */
2407 static const struct dfmt elf32_df_dwarf
= {
2408 "ELF32 (i386) dwarf (newer)",
2412 null_debug_deflabel
,
2413 null_debug_directive
,
2417 NULL
/* pragma list */
2420 static const struct dfmt elf32_df_stabs
= {
2421 "ELF32 (i386) stabs (older)",
2425 null_debug_deflabel
,
2426 null_debug_directive
,
2430 NULL
/* pragma list */
2433 static const struct dfmt
* const elf32_debugs_arr
[3] =
2434 { &elf32_df_dwarf
, &elf32_df_stabs
, NULL
};
2436 const struct ofmt of_elf32
= {
2437 "ELF32 (i386) (Linux, most Unix variants)",
2447 nasm_do_legacy_output
,
2459 static const struct dfmt elf64_df_dwarf
= {
2460 "ELF64 (x86-64) dwarf (newer)",
2464 null_debug_deflabel
,
2465 null_debug_directive
,
2469 NULL
/* pragma list */
2472 static const struct dfmt elf64_df_stabs
= {
2473 "ELF64 (x86-64) stabs (older)",
2477 null_debug_deflabel
,
2478 null_debug_directive
,
2482 NULL
/* pragma list */
2485 static const struct dfmt
* const elf64_debugs_arr
[3] =
2486 { &elf64_df_dwarf
, &elf64_df_stabs
, NULL
};
2488 const struct ofmt of_elf64
= {
2489 "ELF64 (x86-64) (Linux, most Unix variants)",
2499 nasm_do_legacy_output
,
2511 static const struct dfmt elfx32_df_dwarf
= {
2512 "ELFx32 (x86-64) dwarf (newer)",
2516 null_debug_deflabel
,
2517 null_debug_directive
,
2521 NULL
/* pragma list */
2524 static const struct dfmt elfx32_df_stabs
= {
2525 "ELFx32 (x86-64) stabs (older)",
2529 null_debug_deflabel
,
2530 null_debug_directive
,
2537 static const struct dfmt
* const elfx32_debugs_arr
[3] =
2538 { &elfx32_df_dwarf
, &elfx32_df_stabs
, NULL
};
2540 const struct ofmt of_elfx32
= {
2541 "ELFx32 (ELF32 for x86-64) (Linux)",
2551 nasm_do_legacy_output
,
2560 NULL
/* pragma list */
2563 static bool is_elf64(void)
2565 return ofmt
== &of_elf64
;
2568 static bool is_elf32(void)
2570 return ofmt
== &of_elf32
;
2573 static bool is_elfx32(void)
2575 return ofmt
== &of_elfx32
;
2578 static bool dfmt_is_stabs(void)
2580 return dfmt
== &elf32_df_stabs
||
2581 dfmt
== &elfx32_df_stabs
||
2582 dfmt
== &elf64_df_stabs
;
2585 static bool dfmt_is_dwarf(void)
2587 return dfmt
== &elf32_df_dwarf
||
2588 dfmt
== &elfx32_df_dwarf
||
2589 dfmt
== &elf64_df_dwarf
;
2592 /* common debugging routines */
2593 static void debug_typevalue(int32_t type
)
2595 int32_t stype
, ssize
;
2596 switch (TYM_TYPE(type
)) {
2643 stype
= STT_SECTION
;
2658 if (stype
== STT_OBJECT
&& lastsym
&& !lastsym
->type
) {
2659 lastsym
->size
= ssize
;
2660 lastsym
->type
= stype
;
2664 /* stabs debugging routines */
2666 static void stabs_linenum(const char *filename
, int32_t linenumber
, int32_t segto
)
2669 if (!stabs_filename
) {
2670 stabs_filename
= nasm_malloc(strlen(filename
) + 1);
2671 strcpy(stabs_filename
, filename
);
2673 if (strcmp(stabs_filename
, filename
)) {
2674 /* yep, a memory leak...this program is one-shot anyway, so who cares...
2675 in fact, this leak comes in quite handy to maintain a list of files
2676 encountered so far in the symbol lines... */
2678 /* why not nasm_free(stabs_filename); we're done with the old one */
2680 stabs_filename
= nasm_malloc(strlen(filename
) + 1);
2681 strcpy(stabs_filename
, filename
);
2685 currentline
= linenumber
;
2688 static void stabs_output(int type
, void *param
)
2690 struct symlininfo
*s
;
2691 struct linelist
*el
;
2692 if (type
== TY_DEBUGSYMLIN
) {
2693 if (debug_immcall
) {
2694 s
= (struct symlininfo
*)param
;
2695 if (!(sects
[s
->section
]->flags
& SHF_EXECINSTR
))
2696 return; /* line info is only collected for executable sections */
2698 el
= nasm_malloc(sizeof(struct linelist
));
2699 el
->info
.offset
= s
->offset
;
2700 el
->info
.section
= s
->section
;
2701 el
->info
.name
= s
->name
;
2702 el
->line
= currentline
;
2703 el
->filename
= stabs_filename
;
2706 stabslines
->last
->next
= el
;
2707 stabslines
->last
= el
;
2710 stabslines
->last
= el
;
2717 /* for creating the .stab , .stabstr and .rel.stab sections in memory */
2719 static void stabs_generate(void)
2721 int i
, numfiles
, strsize
, numstabs
= 0, currfile
, mainfileindex
;
2722 uint8_t *sbuf
, *ssbuf
, *rbuf
, *sptr
, *rptr
;
2726 struct linelist
*ptr
;
2730 allfiles
= nasm_zalloc(numlinestabs
* sizeof(char *));
2733 if (numfiles
== 0) {
2734 allfiles
[0] = ptr
->filename
;
2737 for (i
= 0; i
< numfiles
; i
++) {
2738 if (!strcmp(allfiles
[i
], ptr
->filename
))
2741 if (i
>= numfiles
) {
2742 allfiles
[i
] = ptr
->filename
;
2749 fileidx
= nasm_malloc(numfiles
* sizeof(int));
2750 for (i
= 0; i
< numfiles
; i
++) {
2751 fileidx
[i
] = strsize
;
2752 strsize
+= strlen(allfiles
[i
]) + 1;
2754 currfile
= mainfileindex
= 0;
2755 for (i
= 0; i
< numfiles
; i
++) {
2756 if (!strcmp(allfiles
[i
], elf_module
)) {
2757 currfile
= mainfileindex
= i
;
2763 * worst case size of the stab buffer would be:
2764 * the sourcefiles changes each line, which would mean 1 SOL, 1 SYMLIN per line
2765 * plus one "ending" entry
2767 sbuf
= nasm_malloc((numlinestabs
* 2 + 4) *
2768 sizeof(struct stabentry
));
2769 ssbuf
= nasm_malloc(strsize
);
2770 rbuf
= nasm_malloc(numlinestabs
* (is_elf64() ? 16 : 8) * (2 + 3));
2773 for (i
= 0; i
< numfiles
; i
++)
2774 strcpy((char *)ssbuf
+ fileidx
[i
], allfiles
[i
]);
2777 stabstrlen
= strsize
; /* set global variable for length of stab strings */
2785 * this is the first stab, its strx points to the filename of the
2786 * the source-file, the n_desc field should be set to the number
2787 * of remaining stabs
2789 WRITE_STAB(sptr
, fileidx
[0], 0, 0, 0, stabstrlen
);
2791 /* this is the stab for the main source file */
2792 WRITE_STAB(sptr
, fileidx
[mainfileindex
], N_SO
, 0, 0, 0);
2794 /* relocation table entry */
2797 * Since the symbol table has two entries before
2798 * the section symbols, the index in the info.section
2799 * member must be adjusted by adding 2
2803 WRITELONG(rptr
, (sptr
- sbuf
) - 4);
2804 WRITELONG(rptr
, ((ptr
->info
.section
+ 2) << 8) | R_386_32
);
2805 } else if (is_elfx32()) {
2806 WRITELONG(rptr
, (sptr
- sbuf
) - 4);
2807 WRITELONG(rptr
, ((ptr
->info
.section
+ 2) << 8) | R_X86_64_32
);
2810 nasm_assert(is_elf64());
2811 WRITEDLONG(rptr
, (int64_t)(sptr
- sbuf
) - 4);
2812 WRITELONG(rptr
, R_X86_64_32
);
2813 WRITELONG(rptr
, ptr
->info
.section
+ 2);
2814 WRITEDLONG(rptr
, 0);
2821 if (strcmp(allfiles
[currfile
], ptr
->filename
)) {
2822 /* oops file has changed... */
2823 for (i
= 0; i
< numfiles
; i
++)
2824 if (!strcmp(allfiles
[i
], ptr
->filename
))
2827 WRITE_STAB(sptr
, fileidx
[currfile
], N_SOL
, 0, 0,
2831 /* relocation table entry */
2832 WRITELONG(rptr
, (sptr
- sbuf
) - 4);
2833 WRITELONG(rptr
, ((ptr
->info
.section
+ 2) << 8) | R_386_32
);
2836 WRITE_STAB(sptr
, 0, N_SLINE
, 0, ptr
->line
, ptr
->info
.offset
);
2839 /* relocation table entry */
2840 WRITELONG(rptr
, (sptr
- sbuf
) - 4);
2841 WRITELONG(rptr
, ((ptr
->info
.section
+ 2) << 8) | R_386_32
);
2845 } else if (is_elfx32()) {
2847 if (strcmp(allfiles
[currfile
], ptr
->filename
)) {
2848 /* oops file has changed... */
2849 for (i
= 0; i
< numfiles
; i
++)
2850 if (!strcmp(allfiles
[i
], ptr
->filename
))
2853 WRITE_STAB(sptr
, fileidx
[currfile
], N_SOL
, 0, 0,
2857 /* relocation table entry */
2858 WRITELONG(rptr
, (sptr
- sbuf
) - 4);
2859 WRITELONG(rptr
, ((ptr
->info
.section
+ 2) << 8) | R_X86_64_32
);
2860 WRITELONG(rptr
, ptr
->info
.offset
);
2863 WRITE_STAB(sptr
, 0, N_SLINE
, 0, ptr
->line
, ptr
->info
.offset
);
2866 /* relocation table entry */
2867 WRITELONG(rptr
, (sptr
- sbuf
) - 4);
2868 WRITELONG(rptr
, ((ptr
->info
.section
+ 2) << 8) | R_X86_64_32
);
2869 WRITELONG(rptr
, ptr
->info
.offset
);
2874 nasm_assert(is_elf64());
2876 if (strcmp(allfiles
[currfile
], ptr
->filename
)) {
2877 /* oops file has changed... */
2878 for (i
= 0; i
< numfiles
; i
++)
2879 if (!strcmp(allfiles
[i
], ptr
->filename
))
2882 WRITE_STAB(sptr
, fileidx
[currfile
], N_SOL
, 0, 0,
2886 /* relocation table entry */
2887 WRITEDLONG(rptr
, (int64_t)(sptr
- sbuf
) - 4);
2888 WRITELONG(rptr
, R_X86_64_32
);
2889 WRITELONG(rptr
, ptr
->info
.section
+ 2);
2890 WRITEDLONG(rptr
, ptr
->info
.offset
);
2893 WRITE_STAB(sptr
, 0, N_SLINE
, 0, ptr
->line
, ptr
->info
.offset
);
2896 /* relocation table entry */
2897 WRITEDLONG(rptr
, (int64_t)(sptr
- sbuf
) - 4);
2898 WRITELONG(rptr
, R_X86_64_32
);
2899 WRITELONG(rptr
, ptr
->info
.section
+ 2);
2900 WRITEDLONG(rptr
, ptr
->info
.offset
);
2906 /* this is an "ending" token */
2907 WRITE_STAB(sptr
, 0, N_SO
, 0, 0, 0);
2910 ((struct stabentry
*)sbuf
)->n_desc
= numstabs
;
2912 nasm_free(allfiles
);
2915 stablen
= (sptr
- sbuf
);
2916 stabrellen
= (rptr
- rbuf
);
2922 static void stabs_cleanup(void)
2924 struct linelist
*ptr
, *del
;
2936 nasm_free(stabrelbuf
);
2937 nasm_free(stabstrbuf
);
2940 /* dwarf routines */
2942 static void dwarf_init(void)
2944 ndebugs
= 3; /* 3 debug symbols */
2947 static void dwarf_linenum(const char *filename
, int32_t linenumber
,
2951 dwarf_findfile(filename
);
2953 currentline
= linenumber
;
2956 /* called from elf_out with type == TY_DEBUGSYMLIN */
2957 static void dwarf_output(int type
, void *param
)
2959 int ln
, aa
, inx
, maxln
, soc
;
2960 struct symlininfo
*s
;
2965 s
= (struct symlininfo
*)param
;
2967 /* line number info is only gathered for executable sections */
2968 if (!(sects
[s
->section
]->flags
& SHF_EXECINSTR
))
2971 /* Check if section index has changed */
2972 if (!(dwarf_csect
&& (dwarf_csect
->section
) == (s
->section
)))
2973 dwarf_findsect(s
->section
);
2975 /* do nothing unless line or file has changed */
2979 ln
= currentline
- dwarf_csect
->line
;
2980 aa
= s
->offset
- dwarf_csect
->offset
;
2981 inx
= dwarf_clist
->line
;
2982 plinep
= dwarf_csect
->psaa
;
2983 /* check for file change */
2984 if (!(inx
== dwarf_csect
->file
)) {
2985 saa_write8(plinep
,DW_LNS_set_file
);
2986 saa_write8(plinep
,inx
);
2987 dwarf_csect
->file
= inx
;
2989 /* check for line change */
2991 /* test if in range of special op code */
2992 maxln
= line_base
+ line_range
;
2993 soc
= (ln
- line_base
) + (line_range
* aa
) + opcode_base
;
2994 if (ln
>= line_base
&& ln
< maxln
&& soc
< 256) {
2995 saa_write8(plinep
,soc
);
2997 saa_write8(plinep
,DW_LNS_advance_line
);
2998 saa_wleb128s(plinep
,ln
);
3000 saa_write8(plinep
,DW_LNS_advance_pc
);
3001 saa_wleb128u(plinep
,aa
);
3003 saa_write8(plinep
,DW_LNS_copy
);
3005 dwarf_csect
->line
= currentline
;
3006 dwarf_csect
->offset
= s
->offset
;
3009 /* show change handled */
3014 static void dwarf_generate(void)
3018 struct linelist
*ftentry
;
3019 struct SAA
*paranges
, *ppubnames
, *pinfo
, *pabbrev
, *plines
, *plinep
;
3020 struct SAA
*parangesrel
, *plinesrel
, *pinforel
;
3021 struct sectlist
*psect
;
3022 size_t saalen
, linepoff
, totlen
, highaddr
;
3025 /* write epilogues for each line program range */
3026 /* and build aranges section */
3027 paranges
= saa_init(1L);
3028 parangesrel
= saa_init(1L);
3029 saa_write16(paranges
,2); /* dwarf version */
3030 saa_write32(parangesrel
, paranges
->datalen
+4);
3031 saa_write32(parangesrel
, (dwarf_infosym
<< 8) + R_386_32
); /* reloc to info */
3032 saa_write32(parangesrel
, 0);
3033 saa_write32(paranges
,0); /* offset into info */
3034 saa_write8(paranges
,4); /* pointer size */
3035 saa_write8(paranges
,0); /* not segmented */
3036 saa_write32(paranges
,0); /* padding */
3037 /* iterate though sectlist entries */
3038 psect
= dwarf_fsect
;
3041 for (indx
= 0; indx
< dwarf_nsections
; indx
++) {
3042 plinep
= psect
->psaa
;
3043 /* Line Number Program Epilogue */
3044 saa_write8(plinep
,2); /* std op 2 */
3045 saa_write8(plinep
,(sects
[psect
->section
]->len
)-psect
->offset
);
3046 saa_write8(plinep
,DW_LNS_extended_op
);
3047 saa_write8(plinep
,1); /* operand length */
3048 saa_write8(plinep
,DW_LNE_end_sequence
);
3049 totlen
+= plinep
->datalen
;
3050 /* range table relocation entry */
3051 saa_write32(parangesrel
, paranges
->datalen
+ 4);
3052 saa_write32(parangesrel
, ((uint32_t) (psect
->section
+ 2) << 8) + R_386_32
);
3053 saa_write32(parangesrel
, (uint32_t) 0);
3054 /* range table entry */
3055 saa_write32(paranges
,0x0000); /* range start */
3056 saa_write32(paranges
,sects
[psect
->section
]->len
); /* range length */
3057 highaddr
+= sects
[psect
->section
]->len
;
3058 /* done with this entry */
3059 psect
= psect
->next
;
3061 saa_write32(paranges
,0); /* null address */
3062 saa_write32(paranges
,0); /* null length */
3063 saalen
= paranges
->datalen
;
3064 arangeslen
= saalen
+ 4;
3065 arangesbuf
= pbuf
= nasm_malloc(arangeslen
);
3066 WRITELONG(pbuf
,saalen
); /* initial length */
3067 saa_rnbytes(paranges
, pbuf
, saalen
);
3069 } else if (is_elfx32()) {
3070 /* write epilogues for each line program range */
3071 /* and build aranges section */
3072 paranges
= saa_init(1L);
3073 parangesrel
= saa_init(1L);
3074 saa_write16(paranges
,3); /* dwarf version */
3075 saa_write32(parangesrel
, paranges
->datalen
+4);
3076 saa_write32(parangesrel
, (dwarf_infosym
<< 8) + R_X86_64_32
); /* reloc to info */
3077 saa_write32(parangesrel
, 0);
3078 saa_write32(paranges
,0); /* offset into info */
3079 saa_write8(paranges
,4); /* pointer size */
3080 saa_write8(paranges
,0); /* not segmented */
3081 saa_write32(paranges
,0); /* padding */
3082 /* iterate though sectlist entries */
3083 psect
= dwarf_fsect
;
3086 for (indx
= 0; indx
< dwarf_nsections
; indx
++) {
3087 plinep
= psect
->psaa
;
3088 /* Line Number Program Epilogue */
3089 saa_write8(plinep
,2); /* std op 2 */
3090 saa_write8(plinep
,(sects
[psect
->section
]->len
)-psect
->offset
);
3091 saa_write8(plinep
,DW_LNS_extended_op
);
3092 saa_write8(plinep
,1); /* operand length */
3093 saa_write8(plinep
,DW_LNE_end_sequence
);
3094 totlen
+= plinep
->datalen
;
3095 /* range table relocation entry */
3096 saa_write32(parangesrel
, paranges
->datalen
+ 4);
3097 saa_write32(parangesrel
, ((uint32_t) (psect
->section
+ 2) << 8) + R_X86_64_32
);
3098 saa_write32(parangesrel
, (uint32_t) 0);
3099 /* range table entry */
3100 saa_write32(paranges
,0x0000); /* range start */
3101 saa_write32(paranges
,sects
[psect
->section
]->len
); /* range length */
3102 highaddr
+= sects
[psect
->section
]->len
;
3103 /* done with this entry */
3104 psect
= psect
->next
;
3106 saa_write32(paranges
,0); /* null address */
3107 saa_write32(paranges
,0); /* null length */
3108 saalen
= paranges
->datalen
;
3109 arangeslen
= saalen
+ 4;
3110 arangesbuf
= pbuf
= nasm_malloc(arangeslen
);
3111 WRITELONG(pbuf
,saalen
); /* initial length */
3112 saa_rnbytes(paranges
, pbuf
, saalen
);
3115 nasm_assert(is_elf64());
3116 /* write epilogues for each line program range */
3117 /* and build aranges section */
3118 paranges
= saa_init(1L);
3119 parangesrel
= saa_init(1L);
3120 saa_write16(paranges
,3); /* dwarf version */
3121 saa_write64(parangesrel
, paranges
->datalen
+4);
3122 saa_write64(parangesrel
, (dwarf_infosym
<< 32) + R_X86_64_32
); /* reloc to info */
3123 saa_write64(parangesrel
, 0);
3124 saa_write32(paranges
,0); /* offset into info */
3125 saa_write8(paranges
,8); /* pointer size */
3126 saa_write8(paranges
,0); /* not segmented */
3127 saa_write32(paranges
,0); /* padding */
3128 /* iterate though sectlist entries */
3129 psect
= dwarf_fsect
;
3132 for (indx
= 0; indx
< dwarf_nsections
; indx
++) {
3133 plinep
= psect
->psaa
;
3134 /* Line Number Program Epilogue */
3135 saa_write8(plinep
,2); /* std op 2 */
3136 saa_write8(plinep
,(sects
[psect
->section
]->len
)-psect
->offset
);
3137 saa_write8(plinep
,DW_LNS_extended_op
);
3138 saa_write8(plinep
,1); /* operand length */
3139 saa_write8(plinep
,DW_LNE_end_sequence
);
3140 totlen
+= plinep
->datalen
;
3141 /* range table relocation entry */
3142 saa_write64(parangesrel
, paranges
->datalen
+ 4);
3143 saa_write64(parangesrel
, ((uint64_t) (psect
->section
+ 2) << 32) + R_X86_64_64
);
3144 saa_write64(parangesrel
, (uint64_t) 0);
3145 /* range table entry */
3146 saa_write64(paranges
,0x0000); /* range start */
3147 saa_write64(paranges
,sects
[psect
->section
]->len
); /* range length */
3148 highaddr
+= sects
[psect
->section
]->len
;
3149 /* done with this entry */
3150 psect
= psect
->next
;
3152 saa_write64(paranges
,0); /* null address */
3153 saa_write64(paranges
,0); /* null length */
3154 saalen
= paranges
->datalen
;
3155 arangeslen
= saalen
+ 4;
3156 arangesbuf
= pbuf
= nasm_malloc(arangeslen
);
3157 WRITELONG(pbuf
,saalen
); /* initial length */
3158 saa_rnbytes(paranges
, pbuf
, saalen
);
3162 /* build rela.aranges section */
3163 arangesrellen
= saalen
= parangesrel
->datalen
;
3164 arangesrelbuf
= pbuf
= nasm_malloc(arangesrellen
);
3165 saa_rnbytes(parangesrel
, pbuf
, saalen
);
3166 saa_free(parangesrel
);
3168 /* build pubnames section */
3169 ppubnames
= saa_init(1L);
3170 saa_write16(ppubnames
,3); /* dwarf version */
3171 saa_write32(ppubnames
,0); /* offset into info */
3172 saa_write32(ppubnames
,0); /* space used in info */
3173 saa_write32(ppubnames
,0); /* end of list */
3174 saalen
= ppubnames
->datalen
;
3175 pubnameslen
= saalen
+ 4;
3176 pubnamesbuf
= pbuf
= nasm_malloc(pubnameslen
);
3177 WRITELONG(pbuf
,saalen
); /* initial length */
3178 saa_rnbytes(ppubnames
, pbuf
, saalen
);
3179 saa_free(ppubnames
);
3182 /* build info section */
3183 pinfo
= saa_init(1L);
3184 pinforel
= saa_init(1L);
3185 saa_write16(pinfo
,2); /* dwarf version */
3186 saa_write32(pinforel
, pinfo
->datalen
+ 4);
3187 saa_write32(pinforel
, (dwarf_abbrevsym
<< 8) + R_386_32
); /* reloc to abbrev */
3188 saa_write32(pinforel
, 0);
3189 saa_write32(pinfo
,0); /* offset into abbrev */
3190 saa_write8(pinfo
,4); /* pointer size */
3191 saa_write8(pinfo
,1); /* abbrviation number LEB128u */
3192 saa_write32(pinforel
, pinfo
->datalen
+ 4);
3193 saa_write32(pinforel
, ((dwarf_fsect
->section
+ 2) << 8) + R_386_32
);
3194 saa_write32(pinforel
, 0);
3195 saa_write32(pinfo
,0); /* DW_AT_low_pc */
3196 saa_write32(pinforel
, pinfo
->datalen
+ 4);
3197 saa_write32(pinforel
, ((dwarf_fsect
->section
+ 2) << 8) + R_386_32
);
3198 saa_write32(pinforel
, 0);
3199 saa_write32(pinfo
,highaddr
); /* DW_AT_high_pc */
3200 saa_write32(pinforel
, pinfo
->datalen
+ 4);
3201 saa_write32(pinforel
, (dwarf_linesym
<< 8) + R_386_32
); /* reloc to line */
3202 saa_write32(pinforel
, 0);
3203 saa_write32(pinfo
,0); /* DW_AT_stmt_list */
3204 saa_wbytes(pinfo
, elf_module
, strlen(elf_module
)+1);
3205 saa_wbytes(pinfo
, nasm_signature(), nasm_signature_len()+1);
3206 saa_write16(pinfo
,DW_LANG_Mips_Assembler
);
3207 saa_write8(pinfo
,2); /* abbrviation number LEB128u */
3208 saa_write32(pinforel
, pinfo
->datalen
+ 4);
3209 saa_write32(pinforel
, ((dwarf_fsect
->section
+ 2) << 8) + R_386_32
);
3210 saa_write32(pinforel
, 0);
3211 saa_write32(pinfo
,0); /* DW_AT_low_pc */
3212 saa_write32(pinfo
,0); /* DW_AT_frame_base */
3213 saa_write8(pinfo
,0); /* end of entries */
3214 saalen
= pinfo
->datalen
;
3215 infolen
= saalen
+ 4;
3216 infobuf
= pbuf
= nasm_malloc(infolen
);
3217 WRITELONG(pbuf
,saalen
); /* initial length */
3218 saa_rnbytes(pinfo
, pbuf
, saalen
);
3220 } else if (is_elfx32()) {
3221 /* build info section */
3222 pinfo
= saa_init(1L);
3223 pinforel
= saa_init(1L);
3224 saa_write16(pinfo
,3); /* dwarf version */
3225 saa_write32(pinforel
, pinfo
->datalen
+ 4);
3226 saa_write32(pinforel
, (dwarf_abbrevsym
<< 8) + R_X86_64_32
); /* reloc to abbrev */
3227 saa_write32(pinforel
, 0);
3228 saa_write32(pinfo
,0); /* offset into abbrev */
3229 saa_write8(pinfo
,4); /* pointer size */
3230 saa_write8(pinfo
,1); /* abbrviation number LEB128u */
3231 saa_write32(pinforel
, pinfo
->datalen
+ 4);
3232 saa_write32(pinforel
, ((dwarf_fsect
->section
+ 2) << 8) + R_X86_64_32
);
3233 saa_write32(pinforel
, 0);
3234 saa_write32(pinfo
,0); /* DW_AT_low_pc */
3235 saa_write32(pinforel
, pinfo
->datalen
+ 4);
3236 saa_write32(pinforel
, ((dwarf_fsect
->section
+ 2) << 8) + R_X86_64_32
);
3237 saa_write32(pinforel
, 0);
3238 saa_write32(pinfo
,highaddr
); /* DW_AT_high_pc */
3239 saa_write32(pinforel
, pinfo
->datalen
+ 4);
3240 saa_write32(pinforel
, (dwarf_linesym
<< 8) + R_X86_64_32
); /* reloc to line */
3241 saa_write32(pinforel
, 0);
3242 saa_write32(pinfo
,0); /* DW_AT_stmt_list */
3243 saa_wbytes(pinfo
, elf_module
, strlen(elf_module
)+1);
3244 saa_wbytes(pinfo
, nasm_signature(), nasm_signature_len()+1);
3245 saa_write16(pinfo
,DW_LANG_Mips_Assembler
);
3246 saa_write8(pinfo
,2); /* abbrviation number LEB128u */
3247 saa_write32(pinforel
, pinfo
->datalen
+ 4);
3248 saa_write32(pinforel
, ((dwarf_fsect
->section
+ 2) << 8) + R_X86_64_32
);
3249 saa_write32(pinforel
, 0);
3250 saa_write32(pinfo
,0); /* DW_AT_low_pc */
3251 saa_write32(pinfo
,0); /* DW_AT_frame_base */
3252 saa_write8(pinfo
,0); /* end of entries */
3253 saalen
= pinfo
->datalen
;
3254 infolen
= saalen
+ 4;
3255 infobuf
= pbuf
= nasm_malloc(infolen
);
3256 WRITELONG(pbuf
,saalen
); /* initial length */
3257 saa_rnbytes(pinfo
, pbuf
, saalen
);
3260 nasm_assert(is_elf64());
3261 /* build info section */
3262 pinfo
= saa_init(1L);
3263 pinforel
= saa_init(1L);
3264 saa_write16(pinfo
,3); /* dwarf version */
3265 saa_write64(pinforel
, pinfo
->datalen
+ 4);
3266 saa_write64(pinforel
, (dwarf_abbrevsym
<< 32) + R_X86_64_32
); /* reloc to abbrev */
3267 saa_write64(pinforel
, 0);
3268 saa_write32(pinfo
,0); /* offset into abbrev */
3269 saa_write8(pinfo
,8); /* pointer size */
3270 saa_write8(pinfo
,1); /* abbrviation number LEB128u */
3271 saa_write64(pinforel
, pinfo
->datalen
+ 4);
3272 saa_write64(pinforel
, ((uint64_t)(dwarf_fsect
->section
+ 2) << 32) + R_X86_64_64
);
3273 saa_write64(pinforel
, 0);
3274 saa_write64(pinfo
,0); /* DW_AT_low_pc */
3275 saa_write64(pinforel
, pinfo
->datalen
+ 4);
3276 saa_write64(pinforel
, ((uint64_t)(dwarf_fsect
->section
+ 2) << 32) + R_X86_64_64
);
3277 saa_write64(pinforel
, 0);
3278 saa_write64(pinfo
,highaddr
); /* DW_AT_high_pc */
3279 saa_write64(pinforel
, pinfo
->datalen
+ 4);
3280 saa_write64(pinforel
, (dwarf_linesym
<< 32) + R_X86_64_32
); /* reloc to line */
3281 saa_write64(pinforel
, 0);
3282 saa_write32(pinfo
,0); /* DW_AT_stmt_list */
3283 saa_wbytes(pinfo
, elf_module
, strlen(elf_module
)+1);
3284 saa_wbytes(pinfo
, nasm_signature(), nasm_signature_len()+1);
3285 saa_write16(pinfo
,DW_LANG_Mips_Assembler
);
3286 saa_write8(pinfo
,2); /* abbrviation number LEB128u */
3287 saa_write64(pinforel
, pinfo
->datalen
+ 4);
3288 saa_write64(pinforel
, ((uint64_t)(dwarf_fsect
->section
+ 2) << 32) + R_X86_64_64
);
3289 saa_write64(pinforel
, 0);
3290 saa_write64(pinfo
,0); /* DW_AT_low_pc */
3291 saa_write64(pinfo
,0); /* DW_AT_frame_base */
3292 saa_write8(pinfo
,0); /* end of entries */
3293 saalen
= pinfo
->datalen
;
3294 infolen
= saalen
+ 4;
3295 infobuf
= pbuf
= nasm_malloc(infolen
);
3296 WRITELONG(pbuf
,saalen
); /* initial length */
3297 saa_rnbytes(pinfo
, pbuf
, saalen
);
3301 /* build rela.info section */
3302 inforellen
= saalen
= pinforel
->datalen
;
3303 inforelbuf
= pbuf
= nasm_malloc(inforellen
);
3304 saa_rnbytes(pinforel
, pbuf
, saalen
);
3307 /* build abbrev section */
3308 pabbrev
= saa_init(1L);
3309 saa_write8(pabbrev
,1); /* entry number LEB128u */
3310 saa_write8(pabbrev
,DW_TAG_compile_unit
); /* tag LEB128u */
3311 saa_write8(pabbrev
,1); /* has children */
3312 /* the following attributes and forms are all LEB128u values */
3313 saa_write8(pabbrev
,DW_AT_low_pc
);
3314 saa_write8(pabbrev
,DW_FORM_addr
);
3315 saa_write8(pabbrev
,DW_AT_high_pc
);
3316 saa_write8(pabbrev
,DW_FORM_addr
);
3317 saa_write8(pabbrev
,DW_AT_stmt_list
);
3318 saa_write8(pabbrev
,DW_FORM_data4
);
3319 saa_write8(pabbrev
,DW_AT_name
);
3320 saa_write8(pabbrev
,DW_FORM_string
);
3321 saa_write8(pabbrev
,DW_AT_producer
);
3322 saa_write8(pabbrev
,DW_FORM_string
);
3323 saa_write8(pabbrev
,DW_AT_language
);
3324 saa_write8(pabbrev
,DW_FORM_data2
);
3325 saa_write16(pabbrev
,0); /* end of entry */
3326 /* LEB128u usage same as above */
3327 saa_write8(pabbrev
,2); /* entry number */
3328 saa_write8(pabbrev
,DW_TAG_subprogram
);
3329 saa_write8(pabbrev
,0); /* no children */
3330 saa_write8(pabbrev
,DW_AT_low_pc
);
3331 saa_write8(pabbrev
,DW_FORM_addr
);
3332 saa_write8(pabbrev
,DW_AT_frame_base
);
3333 saa_write8(pabbrev
,DW_FORM_data4
);
3334 saa_write16(pabbrev
,0); /* end of entry */
3335 /* Terminal zero entry */
3336 saa_write8(pabbrev
,0);
3337 abbrevlen
= saalen
= pabbrev
->datalen
;
3338 abbrevbuf
= pbuf
= nasm_malloc(saalen
);
3339 saa_rnbytes(pabbrev
, pbuf
, saalen
);
3342 /* build line section */
3344 plines
= saa_init(1L);
3345 saa_write8(plines
,1); /* Minimum Instruction Length */
3346 saa_write8(plines
,1); /* Initial value of 'is_stmt' */
3347 saa_write8(plines
,line_base
); /* Line Base */
3348 saa_write8(plines
,line_range
); /* Line Range */
3349 saa_write8(plines
,opcode_base
); /* Opcode Base */
3350 /* standard opcode lengths (# of LEB128u operands) */
3351 saa_write8(plines
,0); /* Std opcode 1 length */
3352 saa_write8(plines
,1); /* Std opcode 2 length */
3353 saa_write8(plines
,1); /* Std opcode 3 length */
3354 saa_write8(plines
,1); /* Std opcode 4 length */
3355 saa_write8(plines
,1); /* Std opcode 5 length */
3356 saa_write8(plines
,0); /* Std opcode 6 length */
3357 saa_write8(plines
,0); /* Std opcode 7 length */
3358 saa_write8(plines
,0); /* Std opcode 8 length */
3359 saa_write8(plines
,1); /* Std opcode 9 length */
3360 saa_write8(plines
,0); /* Std opcode 10 length */
3361 saa_write8(plines
,0); /* Std opcode 11 length */
3362 saa_write8(plines
,1); /* Std opcode 12 length */
3363 /* Directory Table */
3364 saa_write8(plines
,0); /* End of table */
3365 /* File Name Table */
3366 ftentry
= dwarf_flist
;
3367 for (indx
= 0; indx
< dwarf_numfiles
; indx
++) {
3368 saa_wbytes(plines
, ftentry
->filename
, (int32_t)(strlen(ftentry
->filename
) + 1));
3369 saa_write8(plines
,0); /* directory LEB128u */
3370 saa_write8(plines
,0); /* time LEB128u */
3371 saa_write8(plines
,0); /* size LEB128u */
3372 ftentry
= ftentry
->next
;
3374 saa_write8(plines
,0); /* End of table */
3375 linepoff
= plines
->datalen
;
3376 linelen
= linepoff
+ totlen
+ 10;
3377 linebuf
= pbuf
= nasm_malloc(linelen
);
3378 WRITELONG(pbuf
,linelen
-4); /* initial length */
3379 WRITESHORT(pbuf
,3); /* dwarf version */
3380 WRITELONG(pbuf
,linepoff
); /* offset to line number program */
3381 /* write line header */
3383 saa_rnbytes(plines
, pbuf
, saalen
); /* read a given no. of bytes */
3386 /* concatonate line program ranges */
3388 plinesrel
= saa_init(1L);
3389 psect
= dwarf_fsect
;
3391 for (indx
= 0; indx
< dwarf_nsections
; indx
++) {
3392 saa_write32(plinesrel
, linepoff
);
3393 saa_write32(plinesrel
, ((uint32_t) (psect
->section
+ 2) << 8) + R_386_32
);
3394 saa_write32(plinesrel
, (uint32_t) 0);
3395 plinep
= psect
->psaa
;
3396 saalen
= plinep
->datalen
;
3397 saa_rnbytes(plinep
, pbuf
, saalen
);
3401 /* done with this entry */
3402 psect
= psect
->next
;
3404 } else if (is_elfx32()) {
3405 for (indx
= 0; indx
< dwarf_nsections
; indx
++) {
3406 saa_write32(plinesrel
, linepoff
);
3407 saa_write32(plinesrel
, ((psect
->section
+ 2) << 8) + R_X86_64_32
);
3408 saa_write32(plinesrel
, 0);
3409 plinep
= psect
->psaa
;
3410 saalen
= plinep
->datalen
;
3411 saa_rnbytes(plinep
, pbuf
, saalen
);
3415 /* done with this entry */
3416 psect
= psect
->next
;
3419 nasm_assert(is_elf64());
3420 for (indx
= 0; indx
< dwarf_nsections
; indx
++) {
3421 saa_write64(plinesrel
, linepoff
);
3422 saa_write64(plinesrel
, ((uint64_t) (psect
->section
+ 2) << 32) + R_X86_64_64
);
3423 saa_write64(plinesrel
, (uint64_t) 0);
3424 plinep
= psect
->psaa
;
3425 saalen
= plinep
->datalen
;
3426 saa_rnbytes(plinep
, pbuf
, saalen
);
3430 /* done with this entry */
3431 psect
= psect
->next
;
3435 /* build rela.lines section */
3436 linerellen
=saalen
= plinesrel
->datalen
;
3437 linerelbuf
= pbuf
= nasm_malloc(linerellen
);
3438 saa_rnbytes(plinesrel
, pbuf
, saalen
);
3439 saa_free(plinesrel
);
3441 /* build frame section */
3443 /* This only applies if there is at least one frame defined */
3445 framebuf
= pbuf
= nasm_malloc(framelen
);
3446 WRITELONG(pbuf
,framelen
-4); /* initial length */
3451 /* build loc section */
3453 locbuf
= pbuf
= nasm_malloc(loclen
);
3455 WRITELONG(pbuf
,0); /* null beginning offset */
3456 WRITELONG(pbuf
,0); /* null ending offset */
3457 } else if (is_elfx32()) {
3458 WRITELONG(pbuf
,0); /* null beginning offset */
3459 WRITELONG(pbuf
,0); /* null ending offset */
3461 nasm_assert(is_elf64());
3462 WRITEDLONG(pbuf
,0); /* null beginning offset */
3463 WRITEDLONG(pbuf
,0); /* null ending offset */
3467 static void dwarf_cleanup(void)
3469 nasm_free(arangesbuf
);
3470 nasm_free(arangesrelbuf
);
3471 nasm_free(pubnamesbuf
);
3473 nasm_free(inforelbuf
);
3474 nasm_free(abbrevbuf
);
3476 nasm_free(linerelbuf
);
3477 nasm_free(framebuf
);
3481 static void dwarf_findfile(const char * fname
)
3484 struct linelist
*match
;
3486 /* return if fname is current file name */
3487 if (dwarf_clist
&& !(strcmp(fname
, dwarf_clist
->filename
)))
3490 /* search for match */
3493 match
= dwarf_flist
;
3494 for (finx
= 0; finx
< dwarf_numfiles
; finx
++) {
3495 if (!(strcmp(fname
, match
->filename
))) {
3496 dwarf_clist
= match
;
3499 match
= match
->next
;
3503 /* add file name to end of list */
3504 dwarf_clist
= nasm_malloc(sizeof(struct linelist
));
3506 dwarf_clist
->line
= dwarf_numfiles
;
3507 dwarf_clist
->filename
= nasm_malloc(strlen(fname
) + 1);
3508 strcpy(dwarf_clist
->filename
,fname
);
3509 dwarf_clist
->next
= 0;
3510 if (!dwarf_flist
) { /* if first entry */
3511 dwarf_flist
= dwarf_elist
= dwarf_clist
;
3512 dwarf_clist
->last
= 0;
3513 } else { /* chain to previous entry */
3514 dwarf_elist
->next
= dwarf_clist
;
3515 dwarf_elist
= dwarf_clist
;
3519 static void dwarf_findsect(const int index
)
3522 struct sectlist
*match
;
3525 /* return if index is current section index */
3526 if (dwarf_csect
&& (dwarf_csect
->section
== index
))
3529 /* search for match */
3532 match
= dwarf_fsect
;
3533 for (sinx
= 0; sinx
< dwarf_nsections
; sinx
++) {
3534 if (match
->section
== index
) {
3535 dwarf_csect
= match
;
3538 match
= match
->next
;
3542 /* add entry to end of list */
3543 dwarf_csect
= nasm_malloc(sizeof(struct sectlist
));
3545 dwarf_csect
->psaa
= plinep
= saa_init(1L);
3546 dwarf_csect
->line
= 1;
3547 dwarf_csect
->offset
= 0;
3548 dwarf_csect
->file
= 1;
3549 dwarf_csect
->section
= index
;
3550 dwarf_csect
->next
= 0;
3551 /* set relocatable address at start of line program */
3552 saa_write8(plinep
,DW_LNS_extended_op
);
3553 saa_write8(plinep
,is_elf64() ? 9 : 5); /* operand length */
3554 saa_write8(plinep
,DW_LNE_set_address
);
3556 saa_write64(plinep
,0); /* Start Address */
3558 saa_write32(plinep
,0); /* Start Address */
3560 if (!dwarf_fsect
) { /* if first entry */
3561 dwarf_fsect
= dwarf_esect
= dwarf_csect
;
3562 dwarf_csect
->last
= 0;
3563 } else { /* chain to previous entry */
3564 dwarf_esect
->next
= dwarf_csect
;
3565 dwarf_esect
= dwarf_csect
;
3569 #endif /* defined(OF_ELF32) || defined(OF_ELF64) || defined(OF_ELFX32) */