Fix some string literal expressions in initializers
[tinycc.git] / tccelf.c
blob558846c16e5caffe0c82d8084e68300c1cd76b7f
1 /*
2 * ELF file handling for TCC
4 * Copyright (c) 2001-2004 Fabrice Bellard
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 #include "tcc.h"
23 /* Define this to get some debug output during relocation processing. */
24 #undef DEBUG_RELOC
26 /********************************************************/
27 /* global variables */
29 /* elf version information */
30 struct sym_version {
31 char *lib;
32 char *version;
33 int out_index;
34 int prev_same_lib;
37 #define nb_sym_versions s1->nb_sym_versions
38 #define sym_versions s1->sym_versions
39 #define nb_sym_to_version s1->nb_sym_to_version
40 #define sym_to_version s1->sym_to_version
41 #define dt_verneednum s1->dt_verneednum
42 #define versym_section s1->versym_section
43 #define verneed_section s1->verneed_section
45 /* special flag to indicate that the section should not be linked to the other ones */
46 #define SHF_PRIVATE 0x80000000
47 /* section is dynsymtab_section */
48 #define SHF_DYNSYM 0x40000000
50 /* ------------------------------------------------------------------------- */
52 ST_FUNC void tccelf_new(TCCState *s)
54 TCCState *s1 = s;
55 /* no section zero */
56 dynarray_add(&s->sections, &s->nb_sections, NULL);
58 /* create standard sections */
59 text_section = new_section(s, ".text", SHT_PROGBITS, SHF_ALLOC | SHF_EXECINSTR);
60 data_section = new_section(s, ".data", SHT_PROGBITS, SHF_ALLOC | SHF_WRITE);
61 bss_section = new_section(s, ".bss", SHT_NOBITS, SHF_ALLOC | SHF_WRITE);
62 common_section = new_section(s, ".common", SHT_NOBITS, SHF_PRIVATE);
63 common_section->sh_num = SHN_COMMON;
65 /* symbols are always generated for linking stage */
66 symtab_section = new_symtab(s, ".symtab", SHT_SYMTAB, 0,
67 ".strtab",
68 ".hashtab", SHF_PRIVATE);
69 s->symtab = symtab_section;
71 /* private symbol table for dynamic symbols */
72 s->dynsymtab_section = new_symtab(s, ".dynsymtab", SHT_SYMTAB, SHF_PRIVATE|SHF_DYNSYM,
73 ".dynstrtab",
74 ".dynhashtab", SHF_PRIVATE);
75 get_sym_attr(s, 0, 1);
78 #ifdef CONFIG_TCC_BCHECK
79 ST_FUNC void tccelf_bounds_new(TCCState *s)
81 TCCState *s1 = s;
82 /* create bounds sections */
83 bounds_section = new_section(s, ".bounds",
84 SHT_PROGBITS, SHF_ALLOC);
85 lbounds_section = new_section(s, ".lbounds",
86 SHT_PROGBITS, SHF_ALLOC);
88 #endif
90 ST_FUNC void tccelf_stab_new(TCCState *s)
92 TCCState *s1 = s;
93 int shf = 0;
94 #ifdef CONFIG_TCC_BACKTRACE
95 /* include stab info with standalone backtrace support */
96 if (s->do_backtrace && s->output_type != TCC_OUTPUT_MEMORY)
97 shf = SHF_ALLOC;
98 #endif
99 stab_section = new_section(s, ".stab", SHT_PROGBITS, shf);
100 stab_section->sh_entsize = sizeof(Stab_Sym);
101 stab_section->sh_addralign = sizeof ((Stab_Sym*)0)->n_value;
102 stab_section->link = new_section(s, ".stabstr", SHT_STRTAB, shf);
103 /* put first entry */
104 put_stabs(s, "", 0, 0, 0, 0);
107 static void free_section(Section *s)
109 tcc_free(s->data);
112 ST_FUNC void tccelf_delete(TCCState *s1)
114 int i;
116 #ifndef ELF_OBJ_ONLY
117 /* free symbol versions */
118 for (i = 0; i < nb_sym_versions; i++) {
119 tcc_free(sym_versions[i].version);
120 tcc_free(sym_versions[i].lib);
122 tcc_free(sym_versions);
123 tcc_free(sym_to_version);
124 #endif
126 /* free all sections */
127 for(i = 1; i < s1->nb_sections; i++)
128 free_section(s1->sections[i]);
129 dynarray_reset(&s1->sections, &s1->nb_sections);
131 for(i = 0; i < s1->nb_priv_sections; i++)
132 free_section(s1->priv_sections[i]);
133 dynarray_reset(&s1->priv_sections, &s1->nb_priv_sections);
135 /* free any loaded DLLs */
136 #ifdef TCC_IS_NATIVE
137 for ( i = 0; i < s1->nb_loaded_dlls; i++) {
138 DLLReference *ref = s1->loaded_dlls[i];
139 if ( ref->handle )
140 # ifdef _WIN32
141 FreeLibrary((HMODULE)ref->handle);
142 # else
143 dlclose(ref->handle);
144 # endif
146 #endif
147 /* free loaded dlls array */
148 dynarray_reset(&s1->loaded_dlls, &s1->nb_loaded_dlls);
149 tcc_free(s1->sym_attrs);
151 symtab_section = NULL; /* for tccrun.c:rt_printline() */
154 /* save section data state */
155 ST_FUNC void tccelf_begin_file(TCCState *s1)
157 Section *s; int i;
158 for (i = 1; i < s1->nb_sections; i++) {
159 s = s1->sections[i];
160 s->sh_offset = s->data_offset;
162 /* disable symbol hashing during compilation */
163 s = s1->symtab, s->reloc = s->hash, s->hash = NULL;
164 #if defined TCC_TARGET_X86_64 && defined TCC_TARGET_PE
165 s1->uw_sym = 0;
166 #endif
169 /* At the end of compilation, convert any UNDEF syms to global, and merge
170 with previously existing symbols */
171 ST_FUNC void tccelf_end_file(TCCState *s1)
173 Section *s = s1->symtab;
174 int first_sym, nb_syms, *tr, i;
176 first_sym = s->sh_offset / sizeof (ElfSym);
177 nb_syms = s->data_offset / sizeof (ElfSym) - first_sym;
178 s->data_offset = s->sh_offset;
179 s->link->data_offset = s->link->sh_offset;
180 s->hash = s->reloc, s->reloc = NULL;
181 tr = tcc_mallocz(nb_syms * sizeof *tr);
183 for (i = 0; i < nb_syms; ++i) {
184 ElfSym *sym = (ElfSym*)s->data + first_sym + i;
185 if (sym->st_shndx == SHN_UNDEF
186 && ELFW(ST_BIND)(sym->st_info) == STB_LOCAL)
187 sym->st_info = ELFW(ST_INFO)(STB_GLOBAL, ELFW(ST_TYPE)(sym->st_info));
188 tr[i] = set_elf_sym(s, sym->st_value, sym->st_size, sym->st_info,
189 sym->st_other, sym->st_shndx, (char*)s->link->data + sym->st_name);
191 /* now update relocations */
192 for (i = 1; i < s1->nb_sections; i++) {
193 Section *sr = s1->sections[i];
194 if (sr->sh_type == SHT_RELX && sr->link == s) {
195 ElfW_Rel *rel = (ElfW_Rel*)(sr->data + sr->sh_offset);
196 ElfW_Rel *rel_end = (ElfW_Rel*)(sr->data + sr->data_offset);
197 for (; rel < rel_end; ++rel) {
198 int n = ELFW(R_SYM)(rel->r_info) - first_sym;
199 //if (n < 0) tcc_error("internal: invalid symbol index in relocation");
200 rel->r_info = ELFW(R_INFO)(tr[n], ELFW(R_TYPE)(rel->r_info));
204 tcc_free(tr);
207 ST_FUNC Section *new_section(TCCState *s1, const char *name, int sh_type, int sh_flags)
209 Section *sec;
211 sec = tcc_mallocz(sizeof(Section) + strlen(name));
212 sec->s1 = s1;
213 strcpy(sec->name, name);
214 sec->sh_type = sh_type;
215 sec->sh_flags = sh_flags;
216 switch(sh_type) {
217 case SHT_GNU_versym:
218 sec->sh_addralign = 2;
219 break;
220 case SHT_HASH:
221 case SHT_REL:
222 case SHT_RELA:
223 case SHT_DYNSYM:
224 case SHT_SYMTAB:
225 case SHT_DYNAMIC:
226 case SHT_GNU_verneed:
227 case SHT_GNU_verdef:
228 sec->sh_addralign = PTR_SIZE;
229 break;
230 case SHT_STRTAB:
231 sec->sh_addralign = 1;
232 break;
233 default:
234 sec->sh_addralign = PTR_SIZE; /* gcc/pcc default alignment */
235 break;
238 if (sh_flags & SHF_PRIVATE) {
239 dynarray_add(&s1->priv_sections, &s1->nb_priv_sections, sec);
240 } else {
241 sec->sh_num = s1->nb_sections;
242 dynarray_add(&s1->sections, &s1->nb_sections, sec);
245 return sec;
248 ST_FUNC Section *new_symtab(TCCState *s1,
249 const char *symtab_name, int sh_type, int sh_flags,
250 const char *strtab_name,
251 const char *hash_name, int hash_sh_flags)
253 Section *symtab, *strtab, *hash;
254 int *ptr, nb_buckets;
256 symtab = new_section(s1, symtab_name, sh_type, sh_flags);
257 symtab->sh_entsize = sizeof(ElfW(Sym));
258 strtab = new_section(s1, strtab_name, SHT_STRTAB, sh_flags);
259 put_elf_str(strtab, "");
260 symtab->link = strtab;
261 put_elf_sym(symtab, 0, 0, 0, 0, 0, NULL);
263 nb_buckets = 1;
265 hash = new_section(s1, hash_name, SHT_HASH, hash_sh_flags);
266 hash->sh_entsize = sizeof(int);
267 symtab->hash = hash;
268 hash->link = symtab;
270 ptr = section_ptr_add(hash, (2 + nb_buckets + 1) * sizeof(int));
271 ptr[0] = nb_buckets;
272 ptr[1] = 1;
273 memset(ptr + 2, 0, (nb_buckets + 1) * sizeof(int));
274 return symtab;
277 /* realloc section and set its content to zero */
278 ST_FUNC void section_realloc(Section *sec, unsigned long new_size)
280 unsigned long size;
281 unsigned char *data;
283 size = sec->data_allocated;
284 if (size == 0)
285 size = 1;
286 while (size < new_size)
287 size = size * 2;
288 data = tcc_realloc(sec->data, size);
289 memset(data + sec->data_allocated, 0, size - sec->data_allocated);
290 sec->data = data;
291 sec->data_allocated = size;
294 /* reserve at least 'size' bytes aligned per 'align' in section
295 'sec' from current offset, and return the aligned offset */
296 ST_FUNC size_t section_add(Section *sec, addr_t size, int align)
298 size_t offset, offset1;
300 offset = (sec->data_offset + align - 1) & -align;
301 offset1 = offset + size;
302 if (sec->sh_type != SHT_NOBITS && offset1 > sec->data_allocated)
303 section_realloc(sec, offset1);
304 sec->data_offset = offset1;
305 if (align > sec->sh_addralign)
306 sec->sh_addralign = align;
307 return offset;
310 /* reserve at least 'size' bytes in section 'sec' from
311 sec->data_offset. */
312 ST_FUNC void *section_ptr_add(Section *sec, addr_t size)
314 size_t offset = section_add(sec, size, 1);
315 return sec->data + offset;
318 /* reserve at least 'size' bytes from section start */
319 ST_FUNC void section_reserve(Section *sec, unsigned long size)
321 if (size > sec->data_allocated)
322 section_realloc(sec, size);
323 if (size > sec->data_offset)
324 sec->data_offset = size;
327 static Section *find_section_create (TCCState *s1, const char *name, int create)
329 Section *sec;
330 int i;
331 for(i = 1; i < s1->nb_sections; i++) {
332 sec = s1->sections[i];
333 if (!strcmp(name, sec->name))
334 return sec;
336 /* sections are created as PROGBITS */
337 return create ? new_section(s1, name, SHT_PROGBITS, SHF_ALLOC) : NULL;
340 /* return a reference to a section, and create it if it does not
341 exists */
342 ST_FUNC Section *find_section(TCCState *s1, const char *name)
344 return find_section_create (s1, name, 1);
347 /* ------------------------------------------------------------------------- */
349 ST_FUNC int put_elf_str(Section *s, const char *sym)
351 int offset, len;
352 char *ptr;
354 len = strlen(sym) + 1;
355 offset = s->data_offset;
356 ptr = section_ptr_add(s, len);
357 memmove(ptr, sym, len);
358 return offset;
361 /* elf symbol hashing function */
362 static unsigned long elf_hash(const unsigned char *name)
364 unsigned long h = 0, g;
366 while (*name) {
367 h = (h << 4) + *name++;
368 g = h & 0xf0000000;
369 if (g)
370 h ^= g >> 24;
371 h &= ~g;
373 return h;
376 /* rebuild hash table of section s */
377 /* NOTE: we do factorize the hash table code to go faster */
378 static void rebuild_hash(Section *s, unsigned int nb_buckets)
380 ElfW(Sym) *sym;
381 int *ptr, *hash, nb_syms, sym_index, h;
382 unsigned char *strtab;
384 strtab = s->link->data;
385 nb_syms = s->data_offset / sizeof(ElfW(Sym));
387 if (!nb_buckets)
388 nb_buckets = ((int*)s->hash->data)[0];
390 s->hash->data_offset = 0;
391 ptr = section_ptr_add(s->hash, (2 + nb_buckets + nb_syms) * sizeof(int));
392 ptr[0] = nb_buckets;
393 ptr[1] = nb_syms;
394 ptr += 2;
395 hash = ptr;
396 memset(hash, 0, (nb_buckets + 1) * sizeof(int));
397 ptr += nb_buckets + 1;
399 sym = (ElfW(Sym) *)s->data + 1;
400 for(sym_index = 1; sym_index < nb_syms; sym_index++) {
401 if (ELFW(ST_BIND)(sym->st_info) != STB_LOCAL) {
402 h = elf_hash(strtab + sym->st_name) % nb_buckets;
403 *ptr = hash[h];
404 hash[h] = sym_index;
405 } else {
406 *ptr = 0;
408 ptr++;
409 sym++;
413 /* return the symbol number */
414 ST_FUNC int put_elf_sym(Section *s, addr_t value, unsigned long size,
415 int info, int other, int shndx, const char *name)
417 int name_offset, sym_index;
418 int nbuckets, h;
419 ElfW(Sym) *sym;
420 Section *hs;
422 sym = section_ptr_add(s, sizeof(ElfW(Sym)));
423 if (name && name[0])
424 name_offset = put_elf_str(s->link, name);
425 else
426 name_offset = 0;
427 /* XXX: endianness */
428 sym->st_name = name_offset;
429 sym->st_value = value;
430 sym->st_size = size;
431 sym->st_info = info;
432 sym->st_other = other;
433 sym->st_shndx = shndx;
434 sym_index = sym - (ElfW(Sym) *)s->data;
435 hs = s->hash;
436 if (hs) {
437 int *ptr, *base;
438 ptr = section_ptr_add(hs, sizeof(int));
439 base = (int *)hs->data;
440 /* only add global or weak symbols. */
441 if (ELFW(ST_BIND)(info) != STB_LOCAL) {
442 /* add another hashing entry */
443 nbuckets = base[0];
444 h = elf_hash((unsigned char *)s->link->data + name_offset) % nbuckets;
445 *ptr = base[2 + h];
446 base[2 + h] = sym_index;
447 base[1]++;
448 /* we resize the hash table */
449 hs->nb_hashed_syms++;
450 if (hs->nb_hashed_syms > 2 * nbuckets) {
451 rebuild_hash(s, 2 * nbuckets);
453 } else {
454 *ptr = 0;
455 base[1]++;
458 return sym_index;
461 ST_FUNC int find_elf_sym(Section *s, const char *name)
463 ElfW(Sym) *sym;
464 Section *hs;
465 int nbuckets, sym_index, h;
466 const char *name1;
468 hs = s->hash;
469 if (!hs)
470 return 0;
471 nbuckets = ((int *)hs->data)[0];
472 h = elf_hash((unsigned char *) name) % nbuckets;
473 sym_index = ((int *)hs->data)[2 + h];
474 while (sym_index != 0) {
475 sym = &((ElfW(Sym) *)s->data)[sym_index];
476 name1 = (char *) s->link->data + sym->st_name;
477 if (!strcmp(name, name1))
478 return sym_index;
479 sym_index = ((int *)hs->data)[2 + nbuckets + sym_index];
481 return 0;
484 /* return elf symbol value, signal error if 'err' is nonzero */
485 ST_FUNC addr_t get_elf_sym_addr(TCCState *s1, const char *name, int err)
487 int sym_index;
488 ElfW(Sym) *sym;
490 sym_index = find_elf_sym(s1->symtab, name);
491 sym = &((ElfW(Sym) *)s1->symtab->data)[sym_index];
492 if (!sym_index || sym->st_shndx == SHN_UNDEF) {
493 if (err)
494 tcc_error("%s not defined", name);
495 return 0;
497 return sym->st_value;
500 /* list elf symbol names and values */
501 ST_FUNC void list_elf_symbols(TCCState *s, void *ctx,
502 void (*symbol_cb)(void *ctx, const char *name, const void *val))
504 ElfW(Sym) *sym;
505 Section *symtab;
506 int sym_index, end_sym;
507 const char *name;
508 unsigned char sym_vis, sym_bind;
510 symtab = s->symtab;
511 end_sym = symtab->data_offset / sizeof (ElfSym);
512 for (sym_index = 0; sym_index < end_sym; ++sym_index) {
513 sym = &((ElfW(Sym) *)symtab->data)[sym_index];
514 if (sym->st_value) {
515 name = (char *) symtab->link->data + sym->st_name;
516 sym_bind = ELFW(ST_BIND)(sym->st_info);
517 sym_vis = ELFW(ST_VISIBILITY)(sym->st_other);
518 if (sym_bind == STB_GLOBAL && sym_vis == STV_DEFAULT)
519 symbol_cb(ctx, name, (void*)(uintptr_t)sym->st_value);
524 /* return elf symbol value */
525 LIBTCCAPI void *tcc_get_symbol(TCCState *s, const char *name)
527 return (void*)(uintptr_t)get_elf_sym_addr(s, name, 0);
530 /* list elf symbol names and values */
531 LIBTCCAPI void tcc_list_symbols(TCCState *s, void *ctx,
532 void (*symbol_cb)(void *ctx, const char *name, const void *val))
534 list_elf_symbols(s, ctx, symbol_cb);
537 #if defined TCC_IS_NATIVE || defined TCC_TARGET_PE
538 /* return elf symbol value or error */
539 ST_FUNC void* tcc_get_symbol_err(TCCState *s, const char *name)
541 return (void*)(uintptr_t)get_elf_sym_addr(s, name, 1);
543 #endif
545 #ifndef ELF_OBJ_ONLY
546 static void
547 version_add (TCCState *s1)
549 int i;
550 ElfW(Sym) *sym;
551 ElfW(Verneed) *vn = NULL;
552 Section *symtab;
553 int sym_index, end_sym, nb_versions = 2, nb_entries = 0;
554 ElfW(Half) *versym;
555 const char *name;
557 if (0 == nb_sym_versions)
558 return;
559 versym_section = new_section(s1, ".gnu.version", SHT_GNU_versym, SHF_ALLOC);
560 versym_section->sh_entsize = sizeof(ElfW(Half));
561 versym_section->link = s1->dynsym;
563 /* add needed symbols */
564 symtab = s1->dynsym;
565 end_sym = symtab->data_offset / sizeof (ElfSym);
566 versym = section_ptr_add(versym_section, end_sym * sizeof(ElfW(Half)));
567 for (sym_index = 0; sym_index < end_sym; ++sym_index) {
568 int dllindex, verndx;
569 sym = &((ElfW(Sym) *)symtab->data)[sym_index];
570 name = (char *) symtab->link->data + sym->st_name;
571 dllindex = find_elf_sym(s1->dynsymtab_section, name);
572 verndx = (dllindex && dllindex < nb_sym_to_version)
573 ? sym_to_version[dllindex] : -1;
574 if (verndx >= 0) {
575 if (!sym_versions[verndx].out_index)
576 sym_versions[verndx].out_index = nb_versions++;
577 versym[sym_index] = sym_versions[verndx].out_index;
578 } else
579 versym[sym_index] = 0;
581 /* generate verneed section, but not when it will be empty. Some
582 dynamic linkers look at their contents even when DTVERNEEDNUM and
583 section size is zero. */
584 if (nb_versions > 2) {
585 verneed_section = new_section(s1, ".gnu.version_r",
586 SHT_GNU_verneed, SHF_ALLOC);
587 verneed_section->link = s1->dynsym->link;
588 for (i = nb_sym_versions; i-- > 0;) {
589 struct sym_version *sv = &sym_versions[i];
590 int n_same_libs = 0, prev;
591 size_t vnofs;
592 ElfW(Vernaux) *vna = 0;
593 if (sv->out_index < 1)
594 continue;
595 vnofs = section_add(verneed_section, sizeof(*vn), 1);
596 vn = (ElfW(Verneed)*)(verneed_section->data + vnofs);
597 vn->vn_version = 1;
598 vn->vn_file = put_elf_str(verneed_section->link, sv->lib);
599 vn->vn_aux = sizeof (*vn);
600 do {
601 prev = sv->prev_same_lib;
602 if (sv->out_index > 0) {
603 vna = section_ptr_add(verneed_section, sizeof(*vna));
604 vna->vna_hash = elf_hash ((const unsigned char *)sv->version);
605 vna->vna_flags = 0;
606 vna->vna_other = sv->out_index;
607 sv->out_index = -2;
608 vna->vna_name = put_elf_str(verneed_section->link, sv->version);
609 vna->vna_next = sizeof (*vna);
610 n_same_libs++;
612 if (prev >= 0)
613 sv = &sym_versions[prev];
614 } while(prev >= 0);
615 vna->vna_next = 0;
616 vn = (ElfW(Verneed)*)(verneed_section->data + vnofs);
617 vn->vn_cnt = n_same_libs;
618 vn->vn_next = sizeof(*vn) + n_same_libs * sizeof(*vna);
619 nb_entries++;
621 if (vn)
622 vn->vn_next = 0;
623 verneed_section->sh_info = nb_entries;
625 dt_verneednum = nb_entries;
627 #endif
629 /* add an elf symbol : check if it is already defined and patch
630 it. Return symbol index. NOTE that sh_num can be SHN_UNDEF. */
631 ST_FUNC int set_elf_sym(Section *s, addr_t value, unsigned long size,
632 int info, int other, int shndx, const char *name)
634 TCCState *s1 = s->s1;
635 ElfW(Sym) *esym;
636 int sym_bind, sym_index, sym_type, esym_bind;
637 unsigned char sym_vis, esym_vis, new_vis;
639 sym_bind = ELFW(ST_BIND)(info);
640 sym_type = ELFW(ST_TYPE)(info);
641 sym_vis = ELFW(ST_VISIBILITY)(other);
643 if (sym_bind != STB_LOCAL) {
644 /* we search global or weak symbols */
645 sym_index = find_elf_sym(s, name);
646 if (!sym_index)
647 goto do_def;
648 esym = &((ElfW(Sym) *)s->data)[sym_index];
649 if (esym->st_value == value && esym->st_size == size && esym->st_info == info
650 && esym->st_other == other && esym->st_shndx == shndx)
651 return sym_index;
652 if (esym->st_shndx != SHN_UNDEF) {
653 esym_bind = ELFW(ST_BIND)(esym->st_info);
654 /* propagate the most constraining visibility */
655 /* STV_DEFAULT(0)<STV_PROTECTED(3)<STV_HIDDEN(2)<STV_INTERNAL(1) */
656 esym_vis = ELFW(ST_VISIBILITY)(esym->st_other);
657 if (esym_vis == STV_DEFAULT) {
658 new_vis = sym_vis;
659 } else if (sym_vis == STV_DEFAULT) {
660 new_vis = esym_vis;
661 } else {
662 new_vis = (esym_vis < sym_vis) ? esym_vis : sym_vis;
664 esym->st_other = (esym->st_other & ~ELFW(ST_VISIBILITY)(-1))
665 | new_vis;
666 other = esym->st_other; /* in case we have to patch esym */
667 if (shndx == SHN_UNDEF) {
668 /* ignore adding of undefined symbol if the
669 corresponding symbol is already defined */
670 } else if (sym_bind == STB_GLOBAL && esym_bind == STB_WEAK) {
671 /* global overrides weak, so patch */
672 goto do_patch;
673 } else if (sym_bind == STB_WEAK && esym_bind == STB_GLOBAL) {
674 /* weak is ignored if already global */
675 } else if (sym_bind == STB_WEAK && esym_bind == STB_WEAK) {
676 /* keep first-found weak definition, ignore subsequents */
677 } else if (sym_vis == STV_HIDDEN || sym_vis == STV_INTERNAL) {
678 /* ignore hidden symbols after */
679 } else if ((esym->st_shndx == SHN_COMMON
680 || esym->st_shndx == bss_section->sh_num)
681 && (shndx < SHN_LORESERVE
682 && shndx != bss_section->sh_num)) {
683 /* data symbol gets precedence over common/bss */
684 goto do_patch;
685 } else if (shndx == SHN_COMMON || shndx == bss_section->sh_num) {
686 /* data symbol keeps precedence over common/bss */
687 } else if (s->sh_flags & SHF_DYNSYM) {
688 /* we accept that two DLL define the same symbol */
689 } else if (esym->st_other & ST_ASM_SET) {
690 /* If the existing symbol came from an asm .set
691 we can override. */
692 goto do_patch;
693 } else {
694 #if 0
695 printf("new_bind=%x new_shndx=%x new_vis=%x old_bind=%x old_shndx=%x old_vis=%x\n",
696 sym_bind, shndx, new_vis, esym_bind, esym->st_shndx, esym_vis);
697 #endif
698 tcc_error_noabort("'%s' defined twice", name);
700 } else {
701 do_patch:
702 esym->st_info = ELFW(ST_INFO)(sym_bind, sym_type);
703 esym->st_shndx = shndx;
704 s1->new_undef_sym = 1;
705 esym->st_value = value;
706 esym->st_size = size;
707 esym->st_other = other;
709 } else {
710 do_def:
711 sym_index = put_elf_sym(s, value, size,
712 ELFW(ST_INFO)(sym_bind, sym_type), other,
713 shndx, name);
715 return sym_index;
718 /* put relocation */
719 ST_FUNC void put_elf_reloca(Section *symtab, Section *s, unsigned long offset,
720 int type, int symbol, addr_t addend)
722 TCCState *s1 = s->s1;
723 char buf[256];
724 Section *sr;
725 ElfW_Rel *rel;
727 sr = s->reloc;
728 if (!sr) {
729 /* if no relocation section, create it */
730 snprintf(buf, sizeof(buf), REL_SECTION_FMT, s->name);
731 /* if the symtab is allocated, then we consider the relocation
732 are also */
733 sr = new_section(s->s1, buf, SHT_RELX, symtab->sh_flags);
734 sr->sh_entsize = sizeof(ElfW_Rel);
735 sr->link = symtab;
736 sr->sh_info = s->sh_num;
737 s->reloc = sr;
739 rel = section_ptr_add(sr, sizeof(ElfW_Rel));
740 rel->r_offset = offset;
741 rel->r_info = ELFW(R_INFO)(symbol, type);
742 #if SHT_RELX == SHT_RELA
743 rel->r_addend = addend;
744 #endif
745 if (SHT_RELX != SHT_RELA && addend)
746 tcc_error("non-zero addend on REL architecture");
749 ST_FUNC void put_elf_reloc(Section *symtab, Section *s, unsigned long offset,
750 int type, int symbol)
752 put_elf_reloca(symtab, s, offset, type, symbol, 0);
755 /* Remove relocations for section S->reloc starting at oldrelocoffset
756 that are to the same place, retaining the last of them. As side effect
757 the relocations are sorted. Possibly reduces the number of relocs. */
758 ST_FUNC void squeeze_multi_relocs(Section *s, size_t oldrelocoffset)
760 Section *sr = s->reloc;
761 ElfW_Rel *r, *dest;
762 ssize_t a;
763 ElfW(Addr) addr;
765 if (oldrelocoffset + sizeof(*r) >= sr->data_offset)
766 return;
767 /* The relocs we're dealing with are the result of initializer parsing.
768 So they will be mostly in order and there aren't many of them.
769 Secondly we need a stable sort (which qsort isn't). We use
770 a simple insertion sort. */
771 for (a = oldrelocoffset + sizeof(*r); a < sr->data_offset; a += sizeof(*r)) {
772 ssize_t i = a - sizeof(*r);
773 addr = ((ElfW_Rel*)(sr->data + a))->r_offset;
774 for (; i >= (ssize_t)oldrelocoffset &&
775 ((ElfW_Rel*)(sr->data + i))->r_offset > addr; i -= sizeof(*r)) {
776 ElfW_Rel tmp = *(ElfW_Rel*)(sr->data + a);
777 *(ElfW_Rel*)(sr->data + a) = *(ElfW_Rel*)(sr->data + i);
778 *(ElfW_Rel*)(sr->data + i) = tmp;
782 r = (ElfW_Rel*)(sr->data + oldrelocoffset);
783 dest = r;
784 for (; r < (ElfW_Rel*)(sr->data + sr->data_offset); r++) {
785 if (dest->r_offset != r->r_offset)
786 dest++;
787 *dest = *r;
789 sr->data_offset = (unsigned char*)dest - sr->data + sizeof(*r);
792 /* put stab debug information */
794 ST_FUNC void put_stabs(TCCState *s1, const char *str, int type, int other, int desc,
795 unsigned long value)
797 Stab_Sym *sym;
799 unsigned offset;
800 if (type == N_SLINE
801 && (offset = stab_section->data_offset)
802 && (sym = (Stab_Sym*)(stab_section->data + offset) - 1)
803 && sym->n_type == type
804 && sym->n_value == value) {
805 /* just update line_number in previous entry */
806 sym->n_desc = desc;
807 return;
810 sym = section_ptr_add(stab_section, sizeof(Stab_Sym));
811 if (str) {
812 sym->n_strx = put_elf_str(stab_section->link, str);
813 } else {
814 sym->n_strx = 0;
816 sym->n_type = type;
817 sym->n_other = other;
818 sym->n_desc = desc;
819 sym->n_value = value;
822 ST_FUNC void put_stabs_r(TCCState *s1, const char *str, int type, int other, int desc,
823 unsigned long value, Section *sec, int sym_index)
825 put_elf_reloc(symtab_section, stab_section,
826 stab_section->data_offset + 8,
827 sizeof ((Stab_Sym*)0)->n_value == PTR_SIZE ? R_DATA_PTR : R_DATA_32,
828 sym_index);
829 put_stabs(s1, str, type, other, desc, value);
832 ST_FUNC void put_stabn(TCCState *s1, int type, int other, int desc, int value)
834 put_stabs(s1, NULL, type, other, desc, value);
837 ST_FUNC struct sym_attr *get_sym_attr(TCCState *s1, int index, int alloc)
839 int n;
840 struct sym_attr *tab;
842 if (index >= s1->nb_sym_attrs) {
843 if (!alloc)
844 return s1->sym_attrs;
845 /* find immediately bigger power of 2 and reallocate array */
846 n = 1;
847 while (index >= n)
848 n *= 2;
849 tab = tcc_realloc(s1->sym_attrs, n * sizeof(*s1->sym_attrs));
850 s1->sym_attrs = tab;
851 memset(s1->sym_attrs + s1->nb_sym_attrs, 0,
852 (n - s1->nb_sym_attrs) * sizeof(*s1->sym_attrs));
853 s1->nb_sym_attrs = n;
855 return &s1->sym_attrs[index];
858 /* Browse each elem of type <type> in section <sec> starting at elem <startoff>
859 using variable <elem> */
860 #define for_each_elem(sec, startoff, elem, type) \
861 for (elem = (type *) sec->data + startoff; \
862 elem < (type *) (sec->data + sec->data_offset); elem++)
864 /* In an ELF file symbol table, the local symbols must appear below
865 the global and weak ones. Since TCC cannot sort it while generating
866 the code, we must do it after. All the relocation tables are also
867 modified to take into account the symbol table sorting */
868 static void sort_syms(TCCState *s1, Section *s)
870 int *old_to_new_syms;
871 ElfW(Sym) *new_syms;
872 int nb_syms, i;
873 ElfW(Sym) *p, *q;
874 ElfW_Rel *rel;
875 Section *sr;
876 int type, sym_index;
878 nb_syms = s->data_offset / sizeof(ElfW(Sym));
879 new_syms = tcc_malloc(nb_syms * sizeof(ElfW(Sym)));
880 old_to_new_syms = tcc_malloc(nb_syms * sizeof(int));
882 /* first pass for local symbols */
883 p = (ElfW(Sym) *)s->data;
884 q = new_syms;
885 for(i = 0; i < nb_syms; i++) {
886 if (ELFW(ST_BIND)(p->st_info) == STB_LOCAL) {
887 old_to_new_syms[i] = q - new_syms;
888 *q++ = *p;
890 p++;
892 /* save the number of local symbols in section header */
893 if( s->sh_size ) /* this 'if' makes IDA happy */
894 s->sh_info = q - new_syms;
896 /* then second pass for non local symbols */
897 p = (ElfW(Sym) *)s->data;
898 for(i = 0; i < nb_syms; i++) {
899 if (ELFW(ST_BIND)(p->st_info) != STB_LOCAL) {
900 old_to_new_syms[i] = q - new_syms;
901 *q++ = *p;
903 p++;
906 /* we copy the new symbols to the old */
907 memcpy(s->data, new_syms, nb_syms * sizeof(ElfW(Sym)));
908 tcc_free(new_syms);
910 /* now we modify all the relocations */
911 for(i = 1; i < s1->nb_sections; i++) {
912 sr = s1->sections[i];
913 if (sr->sh_type == SHT_RELX && sr->link == s) {
914 for_each_elem(sr, 0, rel, ElfW_Rel) {
915 sym_index = ELFW(R_SYM)(rel->r_info);
916 type = ELFW(R_TYPE)(rel->r_info);
917 sym_index = old_to_new_syms[sym_index];
918 rel->r_info = ELFW(R_INFO)(sym_index, type);
923 tcc_free(old_to_new_syms);
926 /* relocate symbol table, resolve undefined symbols if do_resolve is
927 true and output error if undefined symbol. */
928 ST_FUNC void relocate_syms(TCCState *s1, Section *symtab, int do_resolve)
930 ElfW(Sym) *sym;
931 int sym_bind, sh_num;
932 const char *name;
934 for_each_elem(symtab, 1, sym, ElfW(Sym)) {
935 sh_num = sym->st_shndx;
936 if (sh_num == SHN_UNDEF) {
937 name = (char *) s1->symtab->link->data + sym->st_name;
938 /* Use ld.so to resolve symbol for us (for tcc -run) */
939 if (do_resolve) {
940 #if defined TCC_IS_NATIVE && !defined TCC_TARGET_PE
941 void *addr = dlsym(RTLD_DEFAULT, name);
942 if (addr) {
943 sym->st_value = (addr_t) addr;
944 #ifdef DEBUG_RELOC
945 printf ("relocate_sym: %s -> 0x%lx\n", name, sym->st_value);
946 #endif
947 goto found;
949 #endif
950 /* if dynamic symbol exist, it will be used in relocate_section */
951 } else if (s1->dynsym && find_elf_sym(s1->dynsym, name))
952 goto found;
953 /* XXX: _fp_hw seems to be part of the ABI, so we ignore
954 it */
955 if (!strcmp(name, "_fp_hw"))
956 goto found;
957 /* only weak symbols are accepted to be undefined. Their
958 value is zero */
959 sym_bind = ELFW(ST_BIND)(sym->st_info);
960 if (sym_bind == STB_WEAK)
961 sym->st_value = 0;
962 else
963 tcc_error_noabort("undefined symbol '%s'", name);
964 } else if (sh_num < SHN_LORESERVE) {
965 /* add section base */
966 sym->st_value += s1->sections[sym->st_shndx]->sh_addr;
968 found: ;
972 /* relocate a given section (CPU dependent) by applying the relocations
973 in the associated relocation section */
974 ST_FUNC void relocate_section(TCCState *s1, Section *s)
976 Section *sr = s->reloc;
977 ElfW_Rel *rel;
978 ElfW(Sym) *sym;
979 int type, sym_index;
980 unsigned char *ptr;
981 addr_t tgt, addr;
983 qrel = (ElfW_Rel *)sr->data;
985 for_each_elem(sr, 0, rel, ElfW_Rel) {
986 ptr = s->data + rel->r_offset;
987 sym_index = ELFW(R_SYM)(rel->r_info);
988 sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
989 type = ELFW(R_TYPE)(rel->r_info);
990 tgt = sym->st_value;
991 #if SHT_RELX == SHT_RELA
992 tgt += rel->r_addend;
993 #endif
994 addr = s->sh_addr + rel->r_offset;
995 relocate(s1, rel, type, ptr, addr, tgt);
997 /* if the relocation is allocated, we change its symbol table */
998 if (sr->sh_flags & SHF_ALLOC) {
999 sr->link = s1->dynsym;
1000 if (s1->output_type == TCC_OUTPUT_DLL) {
1001 size_t r = (uint8_t*)qrel - sr->data;
1002 if (sizeof ((Stab_Sym*)0)->n_value < PTR_SIZE
1003 && 0 == strcmp(s->name, ".stab"))
1004 r = 0; /* cannot apply 64bit relocation to 32bit value */
1005 sr->data_offset = sr->sh_size = r;
1010 #ifndef ELF_OBJ_ONLY
1011 /* relocate relocation table in 'sr' */
1012 static void relocate_rel(TCCState *s1, Section *sr)
1014 Section *s;
1015 ElfW_Rel *rel;
1017 s = s1->sections[sr->sh_info];
1018 for_each_elem(sr, 0, rel, ElfW_Rel)
1019 rel->r_offset += s->sh_addr;
1022 /* count the number of dynamic relocations so that we can reserve
1023 their space */
1024 static int prepare_dynamic_rel(TCCState *s1, Section *sr)
1026 int count = 0;
1027 #if defined(TCC_TARGET_I386) || defined(TCC_TARGET_X86_64)
1028 ElfW_Rel *rel;
1029 for_each_elem(sr, 0, rel, ElfW_Rel) {
1030 int sym_index = ELFW(R_SYM)(rel->r_info);
1031 int type = ELFW(R_TYPE)(rel->r_info);
1032 switch(type) {
1033 #if defined(TCC_TARGET_I386)
1034 case R_386_32:
1035 if (!get_sym_attr(s1, sym_index, 0)->dyn_index
1036 && ((ElfW(Sym)*)symtab_section->data + sym_index)->st_shndx == SHN_UNDEF) {
1037 /* don't fixup unresolved (weak) symbols */
1038 rel->r_info = ELFW(R_INFO)(sym_index, R_386_RELATIVE);
1039 break;
1041 #elif defined(TCC_TARGET_X86_64)
1042 case R_X86_64_32:
1043 case R_X86_64_32S:
1044 case R_X86_64_64:
1045 #endif
1046 count++;
1047 break;
1048 #if defined(TCC_TARGET_I386)
1049 case R_386_PC32:
1050 #elif defined(TCC_TARGET_X86_64)
1051 case R_X86_64_PC32:
1052 #endif
1053 if (get_sym_attr(s1, sym_index, 0)->dyn_index)
1054 count++;
1055 break;
1056 default:
1057 break;
1060 if (count) {
1061 /* allocate the section */
1062 sr->sh_flags |= SHF_ALLOC;
1063 sr->sh_size = count * sizeof(ElfW_Rel);
1065 #endif
1066 return count;
1069 static void build_got(TCCState *s1)
1071 /* if no got, then create it */
1072 s1->got = new_section(s1, ".got", SHT_PROGBITS, SHF_ALLOC | SHF_WRITE);
1073 s1->got->sh_entsize = 4;
1074 set_elf_sym(symtab_section, 0, 4, ELFW(ST_INFO)(STB_GLOBAL, STT_OBJECT),
1075 0, s1->got->sh_num, "_GLOBAL_OFFSET_TABLE_");
1076 /* keep space for _DYNAMIC pointer and two dummy got entries */
1077 section_ptr_add(s1->got, 3 * PTR_SIZE);
1080 /* Create a GOT and (for function call) a PLT entry corresponding to a symbol
1081 in s1->symtab. When creating the dynamic symbol table entry for the GOT
1082 relocation, use 'size' and 'info' for the corresponding symbol metadata.
1083 Returns the offset of the GOT or (if any) PLT entry. */
1084 static struct sym_attr * put_got_entry(TCCState *s1, int dyn_reloc_type,
1085 int sym_index)
1087 int need_plt_entry;
1088 const char *name;
1089 ElfW(Sym) *sym;
1090 struct sym_attr *attr;
1091 unsigned got_offset;
1092 char plt_name[100];
1093 int len;
1095 need_plt_entry = (dyn_reloc_type == R_JMP_SLOT);
1096 attr = get_sym_attr(s1, sym_index, 1);
1098 /* In case a function is both called and its address taken 2 GOT entries
1099 are created, one for taking the address (GOT) and the other for the PLT
1100 entry (PLTGOT). */
1101 if (need_plt_entry ? attr->plt_offset : attr->got_offset)
1102 return attr;
1104 /* create the GOT entry */
1105 got_offset = s1->got->data_offset;
1106 section_ptr_add(s1->got, PTR_SIZE);
1108 /* Create the GOT relocation that will insert the address of the object or
1109 function of interest in the GOT entry. This is a static relocation for
1110 memory output (dlsym will give us the address of symbols) and dynamic
1111 relocation otherwise (executable and DLLs). The relocation should be
1112 done lazily for GOT entry with *_JUMP_SLOT relocation type (the one
1113 associated to a PLT entry) but is currently done at load time for an
1114 unknown reason. */
1116 sym = &((ElfW(Sym) *) symtab_section->data)[sym_index];
1117 name = (char *) symtab_section->link->data + sym->st_name;
1119 if (s1->dynsym) {
1120 if (ELFW(ST_BIND)(sym->st_info) == STB_LOCAL) {
1121 /* Hack alarm. We don't want to emit dynamic symbols
1122 and symbol based relocs for STB_LOCAL symbols, but rather
1123 want to resolve them directly. At this point the symbol
1124 values aren't final yet, so we must defer this. We will later
1125 have to create a RELATIVE reloc anyway, so we misuse the
1126 relocation slot to smuggle the symbol reference until
1127 fill_local_got_entries. Not that the sym_index is
1128 relative to symtab_section, not s1->dynsym! Nevertheless
1129 we use s1->dyn_sym so that if this is the first call
1130 that got->reloc is correctly created. Also note that
1131 RELATIVE relocs are not normally created for the .got,
1132 so the types serves as a marker for later (and is retained
1133 also for the final output, which is okay because then the
1134 got is just normal data). */
1135 put_elf_reloc(s1->dynsym, s1->got, got_offset, R_RELATIVE,
1136 sym_index);
1137 } else {
1138 if (0 == attr->dyn_index)
1139 attr->dyn_index = set_elf_sym(s1->dynsym, sym->st_value,
1140 sym->st_size, sym->st_info, 0,
1141 sym->st_shndx, name);
1142 put_elf_reloc(s1->dynsym, s1->got, got_offset, dyn_reloc_type,
1143 attr->dyn_index);
1145 } else {
1146 put_elf_reloc(symtab_section, s1->got, got_offset, dyn_reloc_type,
1147 sym_index);
1150 if (need_plt_entry) {
1151 if (!s1->plt) {
1152 s1->plt = new_section(s1, ".plt", SHT_PROGBITS,
1153 SHF_ALLOC | SHF_EXECINSTR);
1154 s1->plt->sh_entsize = 4;
1157 attr->plt_offset = create_plt_entry(s1, got_offset, attr);
1159 /* create a symbol 'sym@plt' for the PLT jump vector */
1160 len = strlen(name);
1161 if (len > sizeof plt_name - 5)
1162 len = sizeof plt_name - 5;
1163 memcpy(plt_name, name, len);
1164 strcpy(plt_name + len, "@plt");
1165 attr->plt_sym = put_elf_sym(s1->symtab, attr->plt_offset, sym->st_size,
1166 ELFW(ST_INFO)(STB_GLOBAL, STT_FUNC), 0, s1->plt->sh_num, plt_name);
1168 } else {
1169 attr->got_offset = got_offset;
1172 return attr;
1175 /* build GOT and PLT entries */
1176 ST_FUNC void build_got_entries(TCCState *s1)
1178 Section *s;
1179 ElfW_Rel *rel;
1180 ElfW(Sym) *sym;
1181 int i, type, gotplt_entry, reloc_type, sym_index;
1182 struct sym_attr *attr;
1184 for(i = 1; i < s1->nb_sections; i++) {
1185 s = s1->sections[i];
1186 if (s->sh_type != SHT_RELX)
1187 continue;
1188 /* no need to handle got relocations */
1189 if (s->link != symtab_section)
1190 continue;
1191 for_each_elem(s, 0, rel, ElfW_Rel) {
1192 type = ELFW(R_TYPE)(rel->r_info);
1193 gotplt_entry = gotplt_entry_type(type);
1194 if (gotplt_entry == -1)
1195 tcc_error ("Unknown relocation type for got: %d", type);
1196 sym_index = ELFW(R_SYM)(rel->r_info);
1197 sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
1199 if (gotplt_entry == NO_GOTPLT_ENTRY) {
1200 continue;
1203 /* Automatically create PLT/GOT [entry] if it is an undefined
1204 reference (resolved at runtime), or the symbol is absolute,
1205 probably created by tcc_add_symbol, and thus on 64-bit
1206 targets might be too far from application code. */
1207 if (gotplt_entry == AUTO_GOTPLT_ENTRY) {
1208 if (sym->st_shndx == SHN_UNDEF) {
1209 ElfW(Sym) *esym;
1210 int dynindex;
1211 if (s1->output_type == TCC_OUTPUT_DLL && ! PCRELATIVE_DLLPLT)
1212 continue;
1213 /* Relocations for UNDEF symbols would normally need
1214 to be transferred into the executable or shared object.
1215 If that were done AUTO_GOTPLT_ENTRY wouldn't exist.
1216 But TCC doesn't do that (at least for exes), so we
1217 need to resolve all such relocs locally. And that
1218 means PLT slots for functions in DLLs and COPY relocs for
1219 data symbols. COPY relocs were generated in
1220 bind_exe_dynsyms (and the symbol adjusted to be defined),
1221 and for functions we were generated a dynamic symbol
1222 of function type. */
1223 if (s1->dynsym) {
1224 /* dynsym isn't set for -run :-/ */
1225 dynindex = get_sym_attr(s1, sym_index, 0)->dyn_index;
1226 esym = (ElfW(Sym) *)s1->dynsym->data + dynindex;
1227 if (dynindex
1228 && (ELFW(ST_TYPE)(esym->st_info) == STT_FUNC
1229 || (ELFW(ST_TYPE)(esym->st_info) == STT_NOTYPE
1230 && ELFW(ST_TYPE)(sym->st_info) == STT_FUNC)))
1231 goto jmp_slot;
1233 } else if (!(sym->st_shndx == SHN_ABS
1234 #ifndef TCC_TARGET_ARM
1235 && PTR_SIZE == 8
1236 #endif
1238 continue;
1241 #ifdef TCC_TARGET_X86_64
1242 if ((type == R_X86_64_PLT32 || type == R_X86_64_PC32) &&
1243 sym->st_shndx != SHN_UNDEF &&
1244 (ELFW(ST_VISIBILITY)(sym->st_other) != STV_DEFAULT ||
1245 ELFW(ST_BIND)(sym->st_info) == STB_LOCAL ||
1246 s1->output_type == TCC_OUTPUT_EXE)) {
1247 rel->r_info = ELFW(R_INFO)(sym_index, R_X86_64_PC32);
1248 continue;
1250 #endif
1251 reloc_type = code_reloc(type);
1252 if (reloc_type == -1)
1253 tcc_error ("Unknown relocation type: %d", type);
1254 else if (reloc_type != 0) {
1255 jmp_slot:
1256 reloc_type = R_JMP_SLOT;
1257 } else
1258 reloc_type = R_GLOB_DAT;
1260 if (!s1->got)
1261 build_got(s1);
1263 if (gotplt_entry == BUILD_GOT_ONLY)
1264 continue;
1266 attr = put_got_entry(s1, reloc_type, sym_index);
1268 if (reloc_type == R_JMP_SLOT)
1269 rel->r_info = ELFW(R_INFO)(attr->plt_sym, type);
1274 /* put dynamic tag */
1275 static void put_dt(Section *dynamic, int dt, addr_t val)
1277 ElfW(Dyn) *dyn;
1278 dyn = section_ptr_add(dynamic, sizeof(ElfW(Dyn)));
1279 dyn->d_tag = dt;
1280 dyn->d_un.d_val = val;
1282 #endif
1284 ST_FUNC int set_global_sym(TCCState *s1, const char *name, Section *sec, long offs)
1286 int shn = sec ? sec->sh_num : offs ? SHN_ABS : SHN_UNDEF;
1287 if (sec && offs == -1)
1288 offs = sec->data_offset;
1289 return set_elf_sym(symtab_section, offs, 0,
1290 ELFW(ST_INFO)(name ? STB_GLOBAL : STB_LOCAL, STT_NOTYPE), 0, shn, name);
1293 static void add_init_array_defines(TCCState *s1, const char *section_name)
1295 Section *s;
1296 long end_offset;
1297 char buf[1024];
1298 s = find_section(s1, section_name);
1299 if (!s) {
1300 end_offset = 0;
1301 s = data_section;
1302 } else {
1303 end_offset = s->data_offset;
1305 snprintf(buf, sizeof(buf), "__%s_start", section_name + 1);
1306 set_global_sym(s1, buf, s, 0);
1307 snprintf(buf, sizeof(buf), "__%s_end", section_name + 1);
1308 set_global_sym(s1, buf, s, end_offset);
1311 #ifndef TCC_TARGET_PE
1312 static int tcc_add_support(TCCState *s1, const char *filename)
1314 char buf[1024];
1315 snprintf(buf, sizeof(buf), "%s/%s", s1->tcc_lib_path, filename);
1316 return tcc_add_file(s1, buf);
1318 #endif
1320 ST_FUNC void add_array (TCCState *s1, const char *sec, int c)
1322 Section *s;
1323 s = find_section(s1, sec);
1324 s->sh_flags |= SHF_WRITE;
1325 #ifndef TCC_TARGET_PE
1326 s->sh_type = sec[1] == 'i' ? SHT_INIT_ARRAY : SHT_FINI_ARRAY;
1327 #endif
1328 put_elf_reloc (s1->symtab, s, s->data_offset, R_DATA_PTR, c);
1329 section_ptr_add(s, PTR_SIZE);
1332 #ifdef CONFIG_TCC_BCHECK
1333 ST_FUNC void tcc_add_bcheck(TCCState *s1)
1335 if (0 == s1->do_bounds_check)
1336 return;
1337 section_ptr_add(bounds_section, sizeof(addr_t));
1339 #endif
1341 #ifdef CONFIG_TCC_BACKTRACE
1342 static void put_ptr(TCCState *s1, Section *s, int offs)
1344 int c;
1345 c = set_global_sym(s1, NULL, s, offs);
1346 s = data_section;
1347 put_elf_reloc (s1->symtab, s, s->data_offset, R_DATA_PTR, c);
1348 section_ptr_add(s, PTR_SIZE);
1351 /* set symbol to STB_LOCAL and resolve. The point is to not export it as
1352 a dynamic symbol to allow so's to have one each with a different value. */
1353 static void set_local_sym(TCCState *s1, const char *name, Section *s, int offset)
1355 int c = find_elf_sym(s1->symtab, name);
1356 if (c) {
1357 ElfW(Sym) *esym = (ElfW(Sym)*)s1->symtab->data + c;
1358 esym->st_info = ELFW(ST_INFO)(STB_LOCAL, STT_NOTYPE);
1359 esym->st_value = offset;
1360 esym->st_shndx = s->sh_num;
1364 ST_FUNC void tcc_add_btstub(TCCState *s1)
1366 Section *s;
1367 int n, o;
1368 CString cstr;
1370 s = data_section;
1371 o = s->data_offset;
1372 /* create (part of) a struct rt_context (see tccrun.c) */
1373 put_ptr(s1, stab_section, 0);
1374 put_ptr(s1, stab_section, -1);
1375 put_ptr(s1, stab_section->link, 0);
1376 section_ptr_add(s, 3 * PTR_SIZE);
1377 /* prog_base */
1378 put_elf_reloc(s1->symtab, s, s->data_offset, R_DATA_PTR, 0);
1379 section_ptr_add(s, PTR_SIZE);
1380 n = 2 * PTR_SIZE;
1381 #ifdef CONFIG_TCC_BCHECK
1382 if (s1->do_bounds_check) {
1383 put_ptr(s1, bounds_section, 0);
1384 n -= PTR_SIZE;
1386 #endif
1387 section_ptr_add(s, n);
1389 cstr_new(&cstr);
1390 cstr_printf(&cstr,
1391 " extern void __bt_init(),*__rt_info[],__bt_init_dll();"
1392 "__attribute__((constructor)) static void __bt_init_rt(){");
1393 #ifdef TCC_TARGET_PE
1394 if (s1->output_type == TCC_OUTPUT_DLL)
1395 #ifdef CONFIG_TCC_BCHECK
1396 cstr_printf(&cstr, "__bt_init_dll(%d);", s1->do_bounds_check);
1397 #else
1398 cstr_printf(&cstr, "__bt_init_dll(0);");
1399 #endif
1400 #endif
1401 cstr_printf(&cstr, "__bt_init(__rt_info,%d);}",
1402 s1->output_type == TCC_OUTPUT_DLL ? 0 : s1->rt_num_callers + 1);
1403 tcc_compile_string(s1, cstr.data);
1404 cstr_free(&cstr);
1405 set_local_sym(s1, "__rt_info", s, o);
1407 #endif
1409 #ifndef TCC_TARGET_PE
1410 /* add tcc runtime libraries */
1411 ST_FUNC void tcc_add_runtime(TCCState *s1)
1413 s1->filetype = 0;
1414 #ifdef CONFIG_TCC_BCHECK
1415 tcc_add_bcheck(s1);
1416 #endif
1417 tcc_add_pragma_libs(s1);
1418 /* add libc */
1419 if (!s1->nostdlib) {
1420 if (s1->option_pthread)
1421 tcc_add_library_err(s1, "pthread");
1422 tcc_add_library_err(s1, "c");
1423 #ifdef TCC_LIBGCC
1424 if (!s1->static_link) {
1425 if (TCC_LIBGCC[0] == '/')
1426 tcc_add_file(s1, TCC_LIBGCC);
1427 else
1428 tcc_add_dll(s1, TCC_LIBGCC, 0);
1430 #endif
1431 #ifdef CONFIG_TCC_BCHECK
1432 if (s1->do_bounds_check && s1->output_type != TCC_OUTPUT_DLL) {
1433 tcc_add_library_err(s1, "pthread");
1434 tcc_add_library_err(s1, "dl");
1435 tcc_add_support(s1, "bcheck.o");
1437 #endif
1438 #ifdef CONFIG_TCC_BACKTRACE
1439 if (s1->do_backtrace) {
1440 if (s1->output_type == TCC_OUTPUT_EXE)
1441 tcc_add_support(s1, "bt-exe.o");
1442 if (s1->output_type != TCC_OUTPUT_DLL)
1443 tcc_add_support(s1, "bt-log.o");
1444 if (s1->output_type != TCC_OUTPUT_MEMORY)
1445 tcc_add_btstub(s1);
1447 #endif
1448 tcc_add_support(s1, TCC_LIBTCC1);
1449 /* add crt end if not memory output */
1450 if (s1->output_type != TCC_OUTPUT_MEMORY)
1451 tcc_add_crt(s1, "crtn.o");
1454 #endif
1456 /* add various standard linker symbols (must be done after the
1457 sections are filled (for example after allocating common
1458 symbols)) */
1459 static void tcc_add_linker_symbols(TCCState *s1)
1461 char buf[1024];
1462 int i;
1463 Section *s;
1465 set_global_sym(s1, "_etext", text_section, -1);
1466 set_global_sym(s1, "_edata", data_section, -1);
1467 set_global_sym(s1, "_end", bss_section, -1);
1468 #ifdef TCC_TARGET_RISCV64
1469 /* XXX should be .sdata+0x800, not .data+0x800 */
1470 set_global_sym(s1, "__global_pointer$", data_section, 0x800);
1471 #endif
1472 /* horrible new standard ldscript defines */
1473 add_init_array_defines(s1, ".preinit_array");
1474 add_init_array_defines(s1, ".init_array");
1475 add_init_array_defines(s1, ".fini_array");
1476 /* add start and stop symbols for sections whose name can be
1477 expressed in C */
1478 for(i = 1; i < s1->nb_sections; i++) {
1479 s = s1->sections[i];
1480 if ((s->sh_flags & SHF_ALLOC)
1481 && (s->sh_type == SHT_PROGBITS
1482 || s->sh_type == SHT_STRTAB)) {
1483 const char *p;
1484 /* check if section name can be expressed in C */
1485 p = s->name;
1486 for(;;) {
1487 int c = *p;
1488 if (!c)
1489 break;
1490 if (!isid(c) && !isnum(c))
1491 goto next_sec;
1492 p++;
1494 snprintf(buf, sizeof(buf), "__start_%s", s->name);
1495 set_global_sym(s1, buf, s, 0);
1496 snprintf(buf, sizeof(buf), "__stop_%s", s->name);
1497 set_global_sym(s1, buf, s, -1);
1499 next_sec: ;
1503 ST_FUNC void resolve_common_syms(TCCState *s1)
1505 ElfW(Sym) *sym;
1507 /* Allocate common symbols in BSS. */
1508 for_each_elem(symtab_section, 1, sym, ElfW(Sym)) {
1509 if (sym->st_shndx == SHN_COMMON) {
1510 /* symbol alignment is in st_value for SHN_COMMONs */
1511 sym->st_value = section_add(bss_section, sym->st_size,
1512 sym->st_value);
1513 sym->st_shndx = bss_section->sh_num;
1517 /* Now assign linker provided symbols their value. */
1518 tcc_add_linker_symbols(s1);
1521 static void tcc_output_binary(TCCState *s1, FILE *f,
1522 const int *sec_order)
1524 Section *s;
1525 int i, offset, size;
1527 offset = 0;
1528 for(i=1;i<s1->nb_sections;i++) {
1529 s = s1->sections[sec_order[i]];
1530 if (s->sh_type != SHT_NOBITS &&
1531 (s->sh_flags & SHF_ALLOC)) {
1532 while (offset < s->sh_offset) {
1533 fputc(0, f);
1534 offset++;
1536 size = s->sh_size;
1537 fwrite(s->data, 1, size, f);
1538 offset += size;
1543 #ifndef ELF_OBJ_ONLY
1544 ST_FUNC void fill_got_entry(TCCState *s1, ElfW_Rel *rel)
1546 int sym_index = ELFW(R_SYM) (rel->r_info);
1547 ElfW(Sym) *sym = &((ElfW(Sym) *) symtab_section->data)[sym_index];
1548 struct sym_attr *attr = get_sym_attr(s1, sym_index, 0);
1549 unsigned offset = attr->got_offset;
1551 if (0 == offset)
1552 return;
1553 section_reserve(s1->got, offset + PTR_SIZE);
1554 #ifdef TCC_TARGET_X86_64
1555 write64le(s1->got->data + offset, sym->st_value);
1556 #else
1557 write32le(s1->got->data + offset, sym->st_value);
1558 #endif
1561 /* Perform relocation to GOT or PLT entries */
1562 ST_FUNC void fill_got(TCCState *s1)
1564 Section *s;
1565 ElfW_Rel *rel;
1566 int i;
1568 for(i = 1; i < s1->nb_sections; i++) {
1569 s = s1->sections[i];
1570 if (s->sh_type != SHT_RELX)
1571 continue;
1572 /* no need to handle got relocations */
1573 if (s->link != symtab_section)
1574 continue;
1575 for_each_elem(s, 0, rel, ElfW_Rel) {
1576 switch (ELFW(R_TYPE) (rel->r_info)) {
1577 case R_X86_64_GOT32:
1578 case R_X86_64_GOTPCREL:
1579 case R_X86_64_GOTPCRELX:
1580 case R_X86_64_REX_GOTPCRELX:
1581 case R_X86_64_PLT32:
1582 fill_got_entry(s1, rel);
1583 break;
1589 /* See put_got_entry for a description. This is the second stage
1590 where GOT references to local defined symbols are rewritten. */
1591 static void fill_local_got_entries(TCCState *s1)
1593 ElfW_Rel *rel;
1594 if (!s1->got->reloc)
1595 return;
1596 for_each_elem(s1->got->reloc, 0, rel, ElfW_Rel) {
1597 if (ELFW(R_TYPE)(rel->r_info) == R_RELATIVE) {
1598 int sym_index = ELFW(R_SYM) (rel->r_info);
1599 ElfW(Sym) *sym = &((ElfW(Sym) *) symtab_section->data)[sym_index];
1600 struct sym_attr *attr = get_sym_attr(s1, sym_index, 0);
1601 unsigned offset = attr->got_offset;
1602 if (offset != rel->r_offset - s1->got->sh_addr)
1603 tcc_error_noabort("huh");
1604 rel->r_info = ELFW(R_INFO)(0, R_RELATIVE);
1605 #if SHT_RELX == SHT_RELA
1606 rel->r_addend = sym->st_value;
1607 #else
1608 /* All our REL architectures also happen to be 32bit LE. */
1609 write32le(s1->got->data + offset, sym->st_value);
1610 #endif
1615 /* Bind symbols of executable: resolve undefined symbols from exported symbols
1616 in shared libraries and export non local defined symbols to shared libraries
1617 if -rdynamic switch was given on command line */
1618 static void bind_exe_dynsyms(TCCState *s1)
1620 const char *name;
1621 int sym_index, index;
1622 ElfW(Sym) *sym, *esym;
1623 int type;
1625 /* Resolve undefined symbols from dynamic symbols. When there is a match:
1626 - if STT_FUNC or STT_GNU_IFUNC symbol -> add it in PLT
1627 - if STT_OBJECT symbol -> add it in .bss section with suitable reloc */
1628 for_each_elem(symtab_section, 1, sym, ElfW(Sym)) {
1629 if (sym->st_shndx == SHN_UNDEF) {
1630 name = (char *) symtab_section->link->data + sym->st_name;
1631 sym_index = find_elf_sym(s1->dynsymtab_section, name);
1632 if (sym_index) {
1633 esym = &((ElfW(Sym) *)s1->dynsymtab_section->data)[sym_index];
1634 type = ELFW(ST_TYPE)(esym->st_info);
1635 if ((type == STT_FUNC) || (type == STT_GNU_IFUNC)) {
1636 /* Indirect functions shall have STT_FUNC type in executable
1637 * dynsym section. Indeed, a dlsym call following a lazy
1638 * resolution would pick the symbol value from the
1639 * executable dynsym entry which would contain the address
1640 * of the function wanted by the caller of dlsym instead of
1641 * the address of the function that would return that
1642 * address */
1643 int dynindex
1644 = put_elf_sym(s1->dynsym, 0, esym->st_size,
1645 ELFW(ST_INFO)(STB_GLOBAL,STT_FUNC), 0, 0,
1646 name);
1647 int index = sym - (ElfW(Sym) *) symtab_section->data;
1648 get_sym_attr(s1, index, 1)->dyn_index = dynindex;
1649 } else if (type == STT_OBJECT) {
1650 unsigned long offset;
1651 ElfW(Sym) *dynsym;
1652 offset = bss_section->data_offset;
1653 /* XXX: which alignment ? */
1654 offset = (offset + 16 - 1) & -16;
1655 set_elf_sym (s1->symtab, offset, esym->st_size,
1656 esym->st_info, 0, bss_section->sh_num, name);
1657 index = put_elf_sym(s1->dynsym, offset, esym->st_size,
1658 esym->st_info, 0, bss_section->sh_num,
1659 name);
1661 /* Ensure R_COPY works for weak symbol aliases */
1662 if (ELFW(ST_BIND)(esym->st_info) == STB_WEAK) {
1663 for_each_elem(s1->dynsymtab_section, 1, dynsym, ElfW(Sym)) {
1664 if ((dynsym->st_value == esym->st_value)
1665 && (ELFW(ST_BIND)(dynsym->st_info) == STB_GLOBAL)) {
1666 char *dynname = (char *) s1->dynsymtab_section->link->data
1667 + dynsym->st_name;
1668 put_elf_sym(s1->dynsym, offset, dynsym->st_size,
1669 dynsym->st_info, 0,
1670 bss_section->sh_num, dynname);
1671 break;
1676 put_elf_reloc(s1->dynsym, bss_section,
1677 offset, R_COPY, index);
1678 offset += esym->st_size;
1679 bss_section->data_offset = offset;
1681 } else {
1682 /* STB_WEAK undefined symbols are accepted */
1683 /* XXX: _fp_hw seems to be part of the ABI, so we ignore it */
1684 if (ELFW(ST_BIND)(sym->st_info) == STB_WEAK ||
1685 !strcmp(name, "_fp_hw")) {
1686 } else {
1687 tcc_error_noabort("undefined symbol '%s'", name);
1690 } else if (s1->rdynamic && ELFW(ST_BIND)(sym->st_info) != STB_LOCAL) {
1691 /* if -rdynamic option, then export all non local symbols */
1692 name = (char *) symtab_section->link->data + sym->st_name;
1693 set_elf_sym(s1->dynsym, sym->st_value, sym->st_size, sym->st_info,
1694 0, sym->st_shndx, name);
1699 /* Bind symbols of libraries: export all non local symbols of executable that
1700 are referenced by shared libraries. The reason is that the dynamic loader
1701 search symbol first in executable and then in libraries. Therefore a
1702 reference to a symbol already defined by a library can still be resolved by
1703 a symbol in the executable. */
1704 static void bind_libs_dynsyms(TCCState *s1)
1706 const char *name;
1707 int sym_index;
1708 ElfW(Sym) *sym, *esym;
1710 for_each_elem(s1->dynsymtab_section, 1, esym, ElfW(Sym)) {
1711 name = (char *) s1->dynsymtab_section->link->data + esym->st_name;
1712 sym_index = find_elf_sym(symtab_section, name);
1713 sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
1714 if (sym_index && sym->st_shndx != SHN_UNDEF
1715 && ELFW(ST_BIND)(sym->st_info) != STB_LOCAL) {
1716 set_elf_sym(s1->dynsym, sym->st_value, sym->st_size,
1717 sym->st_info, 0, sym->st_shndx, name);
1718 } else if (esym->st_shndx == SHN_UNDEF) {
1719 /* weak symbols can stay undefined */
1720 if (ELFW(ST_BIND)(esym->st_info) != STB_WEAK)
1721 tcc_warning("undefined dynamic symbol '%s'", name);
1726 /* Export all non local symbols. This is used by shared libraries so that the
1727 non local symbols they define can resolve a reference in another shared
1728 library or in the executable. Correspondingly, it allows undefined local
1729 symbols to be resolved by other shared libraries or by the executable. */
1730 static void export_global_syms(TCCState *s1)
1732 int dynindex, index;
1733 const char *name;
1734 ElfW(Sym) *sym;
1736 for_each_elem(symtab_section, 1, sym, ElfW(Sym)) {
1737 if (ELFW(ST_BIND)(sym->st_info) != STB_LOCAL) {
1738 name = (char *) symtab_section->link->data + sym->st_name;
1739 dynindex = put_elf_sym(s1->dynsym, sym->st_value, sym->st_size,
1740 sym->st_info, 0, sym->st_shndx, name);
1741 index = sym - (ElfW(Sym) *) symtab_section->data;
1742 get_sym_attr(s1, index, 1)->dyn_index = dynindex;
1746 #endif
1748 /* Allocate strings for section names and decide if an unallocated section
1749 should be output.
1750 NOTE: the strsec section comes last, so its size is also correct ! */
1751 static int alloc_sec_names(TCCState *s1, int file_type, Section *strsec)
1753 int i;
1754 Section *s;
1755 int textrel = 0;
1757 /* Allocate strings for section names */
1758 for(i = 1; i < s1->nb_sections; i++) {
1759 s = s1->sections[i];
1760 /* when generating a DLL, we include relocations but we may
1761 patch them */
1762 #ifndef ELF_OBJ_ONLY
1763 if (file_type == TCC_OUTPUT_DLL &&
1764 s->sh_type == SHT_RELX &&
1765 !(s->sh_flags & SHF_ALLOC) &&
1766 (s1->sections[s->sh_info]->sh_flags & SHF_ALLOC) &&
1767 prepare_dynamic_rel(s1, s)) {
1768 if (!(s1->sections[s->sh_info]->sh_flags & SHF_WRITE))
1769 textrel = 1;
1770 } else
1771 #endif
1772 if ((s1->do_debug && s->sh_type != SHT_RELX) ||
1773 file_type == TCC_OUTPUT_OBJ ||
1774 (s->sh_flags & SHF_ALLOC) ||
1775 i == (s1->nb_sections - 1)) {
1776 /* we output all sections if debug or object file */
1777 s->sh_size = s->data_offset;
1779 if (s->sh_size || (s->sh_flags & SHF_ALLOC))
1780 s->sh_name = put_elf_str(strsec, s->name);
1782 strsec->sh_size = strsec->data_offset;
1783 return textrel;
1786 /* Info to be copied in dynamic section */
1787 struct dyn_inf {
1788 Section *dynamic;
1789 Section *dynstr;
1790 unsigned long data_offset;
1791 addr_t rel_addr;
1792 addr_t rel_size;
1793 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
1794 addr_t bss_addr;
1795 addr_t bss_size;
1796 #endif
1799 /* Assign sections to segments and decide how are sections laid out when loaded
1800 in memory. This function also fills corresponding program headers. */
1801 static int layout_sections(TCCState *s1, ElfW(Phdr) *phdr, int phnum,
1802 Section *interp, Section* strsec,
1803 struct dyn_inf *dyninf, int *sec_order)
1805 int i, j, k, file_type, sh_order_index, file_offset;
1806 unsigned long s_align;
1807 long long tmp;
1808 addr_t addr;
1809 ElfW(Phdr) *ph;
1810 Section *s;
1812 file_type = s1->output_type;
1813 sh_order_index = 1;
1814 file_offset = 0;
1815 if (s1->output_format == TCC_OUTPUT_FORMAT_ELF)
1816 file_offset = sizeof(ElfW(Ehdr)) + phnum * sizeof(ElfW(Phdr));
1817 s_align = ELF_PAGE_SIZE;
1818 if (s1->section_align)
1819 s_align = s1->section_align;
1821 if (phnum > 0) {
1822 if (s1->has_text_addr) {
1823 int a_offset, p_offset;
1824 addr = s1->text_addr;
1825 /* we ensure that (addr % ELF_PAGE_SIZE) == file_offset %
1826 ELF_PAGE_SIZE */
1827 a_offset = (int) (addr & (s_align - 1));
1828 p_offset = file_offset & (s_align - 1);
1829 if (a_offset < p_offset)
1830 a_offset += s_align;
1831 file_offset += (a_offset - p_offset);
1832 } else {
1833 if (file_type == TCC_OUTPUT_DLL)
1834 addr = 0;
1835 else
1836 addr = ELF_START_ADDR;
1837 /* compute address after headers */
1838 addr += (file_offset & (s_align - 1));
1841 ph = &phdr[0];
1842 /* Leave one program headers for the program interpreter and one for
1843 the program header table itself if needed. These are done later as
1844 they require section layout to be done first. */
1845 if (interp)
1846 ph += 2;
1848 /* dynamic relocation table information, for .dynamic section */
1849 dyninf->rel_addr = dyninf->rel_size = 0;
1850 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
1851 dyninf->bss_addr = dyninf->bss_size = 0;
1852 #endif
1854 for(j = 0; j < 2; j++) {
1855 ph->p_type = PT_LOAD;
1856 if (j == 0)
1857 ph->p_flags = PF_R | PF_X;
1858 else
1859 ph->p_flags = PF_R | PF_W;
1860 ph->p_align = s_align;
1862 /* Decide the layout of sections loaded in memory. This must
1863 be done before program headers are filled since they contain
1864 info about the layout. We do the following ordering: interp,
1865 symbol tables, relocations, progbits, nobits */
1866 /* XXX: do faster and simpler sorting */
1867 for(k = 0; k < 5; k++) {
1868 for(i = 1; i < s1->nb_sections; i++) {
1869 s = s1->sections[i];
1870 /* compute if section should be included */
1871 if (j == 0) {
1872 if ((s->sh_flags & (SHF_ALLOC | SHF_WRITE)) !=
1873 SHF_ALLOC)
1874 continue;
1875 } else {
1876 if ((s->sh_flags & (SHF_ALLOC | SHF_WRITE)) !=
1877 (SHF_ALLOC | SHF_WRITE))
1878 continue;
1880 if (s == interp) {
1881 if (k != 0)
1882 continue;
1883 } else if ((s->sh_type == SHT_DYNSYM ||
1884 s->sh_type == SHT_STRTAB ||
1885 s->sh_type == SHT_HASH)
1886 && !strstr(s->name, ".stab")) {
1887 if (k != 1)
1888 continue;
1889 } else if (s->sh_type == SHT_RELX) {
1890 if (k != 2)
1891 continue;
1892 } else if (s->sh_type == SHT_NOBITS) {
1893 if (k != 4)
1894 continue;
1895 } else {
1896 if (k != 3)
1897 continue;
1899 sec_order[sh_order_index++] = i;
1901 /* section matches: we align it and add its size */
1902 tmp = addr;
1903 addr = (addr + s->sh_addralign - 1) &
1904 ~(s->sh_addralign - 1);
1905 file_offset += (int) ( addr - tmp );
1906 s->sh_offset = file_offset;
1907 s->sh_addr = addr;
1909 /* update program header infos */
1910 if (ph->p_offset == 0) {
1911 ph->p_offset = file_offset;
1912 ph->p_vaddr = addr;
1913 ph->p_paddr = ph->p_vaddr;
1915 /* update dynamic relocation infos */
1916 if (s->sh_type == SHT_RELX) {
1917 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
1918 if (!strcmp(strsec->data + s->sh_name, ".rel.got")) {
1919 dyninf->rel_addr = addr;
1920 dyninf->rel_size += s->sh_size; /* XXX only first rel. */
1922 if (!strcmp(strsec->data + s->sh_name, ".rel.bss")) {
1923 dyninf->bss_addr = addr;
1924 dyninf->bss_size = s->sh_size; /* XXX only first rel. */
1926 #else
1927 if (dyninf->rel_size == 0)
1928 dyninf->rel_addr = addr;
1929 dyninf->rel_size += s->sh_size;
1930 #endif
1932 addr += s->sh_size;
1933 if (s->sh_type != SHT_NOBITS)
1934 file_offset += s->sh_size;
1937 if (j == 0) {
1938 /* Make the first PT_LOAD segment include the program
1939 headers itself (and the ELF header as well), it'll
1940 come out with same memory use but will make various
1941 tools like binutils strip work better. */
1942 ph->p_offset &= ~(ph->p_align - 1);
1943 ph->p_vaddr &= ~(ph->p_align - 1);
1944 ph->p_paddr &= ~(ph->p_align - 1);
1946 ph->p_filesz = file_offset - ph->p_offset;
1947 ph->p_memsz = addr - ph->p_vaddr;
1948 ph++;
1949 if (j == 0) {
1950 if (s1->output_format == TCC_OUTPUT_FORMAT_ELF) {
1951 /* if in the middle of a page, we duplicate the page in
1952 memory so that one copy is RX and the other is RW */
1953 if ((addr & (s_align - 1)) != 0)
1954 addr += s_align;
1955 } else {
1956 addr = (addr + s_align - 1) & ~(s_align - 1);
1957 file_offset = (file_offset + s_align - 1) & ~(s_align - 1);
1963 /* all other sections come after */
1964 for(i = 1; i < s1->nb_sections; i++) {
1965 s = s1->sections[i];
1966 if (phnum > 0 && (s->sh_flags & SHF_ALLOC))
1967 continue;
1968 sec_order[sh_order_index++] = i;
1970 file_offset = (file_offset + s->sh_addralign - 1) &
1971 ~(s->sh_addralign - 1);
1972 s->sh_offset = file_offset;
1973 if (s->sh_type != SHT_NOBITS)
1974 file_offset += s->sh_size;
1977 return file_offset;
1980 #ifndef ELF_OBJ_ONLY
1981 static void fill_unloadable_phdr(ElfW(Phdr) *phdr, int phnum, Section *interp,
1982 Section *dynamic)
1984 ElfW(Phdr) *ph;
1986 /* if interpreter, then add corresponding program header */
1987 if (interp) {
1988 ph = &phdr[0];
1990 ph->p_type = PT_PHDR;
1991 ph->p_offset = sizeof(ElfW(Ehdr));
1992 ph->p_filesz = ph->p_memsz = phnum * sizeof(ElfW(Phdr));
1993 ph->p_vaddr = interp->sh_addr - ph->p_filesz;
1994 ph->p_paddr = ph->p_vaddr;
1995 ph->p_flags = PF_R | PF_X;
1996 ph->p_align = 4; /* interp->sh_addralign; */
1997 ph++;
1999 ph->p_type = PT_INTERP;
2000 ph->p_offset = interp->sh_offset;
2001 ph->p_vaddr = interp->sh_addr;
2002 ph->p_paddr = ph->p_vaddr;
2003 ph->p_filesz = interp->sh_size;
2004 ph->p_memsz = interp->sh_size;
2005 ph->p_flags = PF_R;
2006 ph->p_align = interp->sh_addralign;
2009 /* if dynamic section, then add corresponding program header */
2010 if (dynamic) {
2011 ph = &phdr[phnum - 1];
2013 ph->p_type = PT_DYNAMIC;
2014 ph->p_offset = dynamic->sh_offset;
2015 ph->p_vaddr = dynamic->sh_addr;
2016 ph->p_paddr = ph->p_vaddr;
2017 ph->p_filesz = dynamic->sh_size;
2018 ph->p_memsz = dynamic->sh_size;
2019 ph->p_flags = PF_R | PF_W;
2020 ph->p_align = dynamic->sh_addralign;
2024 /* Fill the dynamic section with tags describing the address and size of
2025 sections */
2026 static void fill_dynamic(TCCState *s1, struct dyn_inf *dyninf)
2028 Section *dynamic = dyninf->dynamic;
2029 Section *s;
2031 /* put dynamic section entries */
2032 put_dt(dynamic, DT_HASH, s1->dynsym->hash->sh_addr);
2033 put_dt(dynamic, DT_STRTAB, dyninf->dynstr->sh_addr);
2034 put_dt(dynamic, DT_SYMTAB, s1->dynsym->sh_addr);
2035 put_dt(dynamic, DT_STRSZ, dyninf->dynstr->data_offset);
2036 put_dt(dynamic, DT_SYMENT, sizeof(ElfW(Sym)));
2037 #if PTR_SIZE == 8
2038 put_dt(dynamic, DT_RELA, dyninf->rel_addr);
2039 put_dt(dynamic, DT_RELASZ, dyninf->rel_size);
2040 put_dt(dynamic, DT_RELAENT, sizeof(ElfW_Rel));
2041 #else
2042 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
2043 put_dt(dynamic, DT_PLTGOT, s1->got->sh_addr);
2044 put_dt(dynamic, DT_PLTRELSZ, dyninf->rel_size);
2045 put_dt(dynamic, DT_JMPREL, dyninf->rel_addr);
2046 put_dt(dynamic, DT_PLTREL, DT_REL);
2047 put_dt(dynamic, DT_REL, dyninf->bss_addr);
2048 put_dt(dynamic, DT_RELSZ, dyninf->bss_size);
2049 #else
2050 put_dt(dynamic, DT_REL, dyninf->rel_addr);
2051 put_dt(dynamic, DT_RELSZ, dyninf->rel_size);
2052 put_dt(dynamic, DT_RELENT, sizeof(ElfW_Rel));
2053 #endif
2054 #endif
2055 if (versym_section)
2056 put_dt(dynamic, DT_VERSYM, versym_section->sh_addr);
2057 if (verneed_section) {
2058 put_dt(dynamic, DT_VERNEED, verneed_section->sh_addr);
2059 put_dt(dynamic, DT_VERNEEDNUM, dt_verneednum);
2061 s = find_section_create (s1, ".preinit_array", 0);
2062 if (s && s->data_offset) {
2063 put_dt(dynamic, DT_PREINIT_ARRAY, s->sh_addr);
2064 put_dt(dynamic, DT_PREINIT_ARRAYSZ, s->data_offset);
2066 s = find_section_create (s1, ".init_array", 0);
2067 if (s && s->data_offset) {
2068 put_dt(dynamic, DT_INIT_ARRAY, s->sh_addr);
2069 put_dt(dynamic, DT_INIT_ARRAYSZ, s->data_offset);
2071 s = find_section_create (s1, ".fini_array", 0);
2072 if (s && s->data_offset) {
2073 put_dt(dynamic, DT_FINI_ARRAY, s->sh_addr);
2074 put_dt(dynamic, DT_FINI_ARRAYSZ, s->data_offset);
2076 s = find_section_create (s1, ".init", 0);
2077 if (s && s->data_offset) {
2078 put_dt(dynamic, DT_INIT, s->sh_addr);
2080 s = find_section_create (s1, ".fini", 0);
2081 if (s && s->data_offset) {
2082 put_dt(dynamic, DT_FINI, s->sh_addr);
2084 if (s1->do_debug)
2085 put_dt(dynamic, DT_DEBUG, 0);
2086 put_dt(dynamic, DT_NULL, 0);
2089 /* Relocate remaining sections and symbols (that is those not related to
2090 dynamic linking) */
2091 static int final_sections_reloc(TCCState *s1)
2093 int i;
2094 Section *s;
2096 relocate_syms(s1, s1->symtab, 0);
2098 if (s1->nb_errors != 0)
2099 return -1;
2101 /* relocate sections */
2102 /* XXX: ignore sections with allocated relocations ? */
2103 for(i = 1; i < s1->nb_sections; i++) {
2104 s = s1->sections[i];
2105 if (s->reloc && (s != s1->got || s1->static_link))
2106 relocate_section(s1, s);
2109 /* relocate relocation entries if the relocation tables are
2110 allocated in the executable */
2111 for(i = 1; i < s1->nb_sections; i++) {
2112 s = s1->sections[i];
2113 if ((s->sh_flags & SHF_ALLOC) &&
2114 s->sh_type == SHT_RELX) {
2115 relocate_rel(s1, s);
2118 return 0;
2120 #endif
2122 /* Create an ELF file on disk.
2123 This function handle ELF specific layout requirements */
2124 static void tcc_output_elf(TCCState *s1, FILE *f, int phnum, ElfW(Phdr) *phdr,
2125 int file_offset, int *sec_order)
2127 int i, shnum, offset, size, file_type;
2128 Section *s;
2129 ElfW(Ehdr) ehdr;
2130 ElfW(Shdr) shdr, *sh;
2132 file_type = s1->output_type;
2133 shnum = s1->nb_sections;
2135 memset(&ehdr, 0, sizeof(ehdr));
2137 if (phnum > 0) {
2138 ehdr.e_phentsize = sizeof(ElfW(Phdr));
2139 ehdr.e_phnum = phnum;
2140 ehdr.e_phoff = sizeof(ElfW(Ehdr));
2143 /* align to 4 */
2144 file_offset = (file_offset + 3) & -4;
2146 /* fill header */
2147 ehdr.e_ident[0] = ELFMAG0;
2148 ehdr.e_ident[1] = ELFMAG1;
2149 ehdr.e_ident[2] = ELFMAG2;
2150 ehdr.e_ident[3] = ELFMAG3;
2151 ehdr.e_ident[4] = ELFCLASSW;
2152 ehdr.e_ident[5] = ELFDATA2LSB;
2153 ehdr.e_ident[6] = EV_CURRENT;
2154 #if !defined(TCC_TARGET_PE) && (defined(__FreeBSD__) || defined(__FreeBSD_kernel__))
2155 /* FIXME: should set only for freebsd _target_, but we exclude only PE target */
2156 ehdr.e_ident[EI_OSABI] = ELFOSABI_FREEBSD;
2157 #endif
2158 #ifdef TCC_TARGET_ARM
2159 #ifdef TCC_ARM_EABI
2160 ehdr.e_ident[EI_OSABI] = 0;
2161 ehdr.e_flags = EF_ARM_EABI_VER4;
2162 if (file_type == TCC_OUTPUT_EXE || file_type == TCC_OUTPUT_DLL)
2163 ehdr.e_flags |= EF_ARM_HASENTRY;
2164 if (s1->float_abi == ARM_HARD_FLOAT)
2165 ehdr.e_flags |= EF_ARM_VFP_FLOAT;
2166 else
2167 ehdr.e_flags |= EF_ARM_SOFT_FLOAT;
2168 #else
2169 ehdr.e_ident[EI_OSABI] = ELFOSABI_ARM;
2170 #endif
2171 #elif defined TCC_TARGET_RISCV64
2172 ehdr.e_flags = EF_RISCV_FLOAT_ABI_DOUBLE;
2173 #endif
2174 switch(file_type) {
2175 default:
2176 case TCC_OUTPUT_EXE:
2177 ehdr.e_type = ET_EXEC;
2178 ehdr.e_entry = get_elf_sym_addr(s1, "_start", 1);
2179 break;
2180 case TCC_OUTPUT_DLL:
2181 ehdr.e_type = ET_DYN;
2182 ehdr.e_entry = text_section->sh_addr; /* XXX: is it correct ? */
2183 break;
2184 case TCC_OUTPUT_OBJ:
2185 ehdr.e_type = ET_REL;
2186 break;
2188 ehdr.e_machine = EM_TCC_TARGET;
2189 ehdr.e_version = EV_CURRENT;
2190 ehdr.e_shoff = file_offset;
2191 ehdr.e_ehsize = sizeof(ElfW(Ehdr));
2192 ehdr.e_shentsize = sizeof(ElfW(Shdr));
2193 ehdr.e_shnum = shnum;
2194 ehdr.e_shstrndx = shnum - 1;
2196 fwrite(&ehdr, 1, sizeof(ElfW(Ehdr)), f);
2197 fwrite(phdr, 1, phnum * sizeof(ElfW(Phdr)), f);
2198 offset = sizeof(ElfW(Ehdr)) + phnum * sizeof(ElfW(Phdr));
2200 sort_syms(s1, symtab_section);
2201 for(i = 1; i < s1->nb_sections; i++) {
2202 s = s1->sections[sec_order[i]];
2203 if (s->sh_type != SHT_NOBITS) {
2204 while (offset < s->sh_offset) {
2205 fputc(0, f);
2206 offset++;
2208 size = s->sh_size;
2209 if (size)
2210 fwrite(s->data, 1, size, f);
2211 offset += size;
2215 /* output section headers */
2216 while (offset < ehdr.e_shoff) {
2217 fputc(0, f);
2218 offset++;
2221 for(i = 0; i < s1->nb_sections; i++) {
2222 sh = &shdr;
2223 memset(sh, 0, sizeof(ElfW(Shdr)));
2224 s = s1->sections[i];
2225 if (s) {
2226 sh->sh_name = s->sh_name;
2227 sh->sh_type = s->sh_type;
2228 sh->sh_flags = s->sh_flags;
2229 sh->sh_entsize = s->sh_entsize;
2230 sh->sh_info = s->sh_info;
2231 if (s->link)
2232 sh->sh_link = s->link->sh_num;
2233 sh->sh_addralign = s->sh_addralign;
2234 sh->sh_addr = s->sh_addr;
2235 sh->sh_offset = s->sh_offset;
2236 sh->sh_size = s->sh_size;
2238 fwrite(sh, 1, sizeof(ElfW(Shdr)), f);
2242 /* Write an elf, coff or "binary" file */
2243 static int tcc_write_elf_file(TCCState *s1, const char *filename, int phnum,
2244 ElfW(Phdr) *phdr, int file_offset, int *sec_order)
2246 int fd, mode, file_type;
2247 FILE *f;
2249 file_type = s1->output_type;
2250 if (file_type == TCC_OUTPUT_OBJ)
2251 mode = 0666;
2252 else
2253 mode = 0777;
2254 unlink(filename);
2255 fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, mode);
2256 if (fd < 0) {
2257 tcc_error_noabort("could not write '%s'", filename);
2258 return -1;
2260 f = fdopen(fd, "wb");
2261 if (s1->verbose)
2262 printf("<- %s\n", filename);
2264 #ifdef TCC_TARGET_COFF
2265 if (s1->output_format == TCC_OUTPUT_FORMAT_COFF)
2266 tcc_output_coff(s1, f);
2267 else
2268 #endif
2269 if (s1->output_format == TCC_OUTPUT_FORMAT_ELF)
2270 tcc_output_elf(s1, f, phnum, phdr, file_offset, sec_order);
2271 else
2272 tcc_output_binary(s1, f, sec_order);
2273 fclose(f);
2275 return 0;
2278 #ifndef ELF_OBJ_ONLY
2279 /* Sort section headers by assigned sh_addr, remove sections
2280 that we aren't going to output. */
2281 static void tidy_section_headers(TCCState *s1, int *sec_order)
2283 int i, nnew, l, *backmap;
2284 Section **snew, *s;
2285 ElfW(Sym) *sym;
2287 snew = tcc_malloc(s1->nb_sections * sizeof(snew[0]));
2288 backmap = tcc_malloc(s1->nb_sections * sizeof(backmap[0]));
2289 for (i = 0, nnew = 0, l = s1->nb_sections; i < s1->nb_sections; i++) {
2290 s = s1->sections[sec_order[i]];
2291 if (!i || s->sh_name) {
2292 backmap[sec_order[i]] = nnew;
2293 snew[nnew] = s;
2294 ++nnew;
2295 } else {
2296 backmap[sec_order[i]] = 0;
2297 snew[--l] = s;
2300 for (i = 0; i < nnew; i++) {
2301 s = snew[i];
2302 if (s) {
2303 s->sh_num = i;
2304 if (s->sh_type == SHT_RELX)
2305 s->sh_info = backmap[s->sh_info];
2309 for_each_elem(symtab_section, 1, sym, ElfW(Sym))
2310 if (sym->st_shndx != SHN_UNDEF && sym->st_shndx < SHN_LORESERVE)
2311 sym->st_shndx = backmap[sym->st_shndx];
2312 if( !s1->static_link ) {
2313 for_each_elem(s1->dynsym, 1, sym, ElfW(Sym))
2314 if (sym->st_shndx != SHN_UNDEF && sym->st_shndx < SHN_LORESERVE)
2315 sym->st_shndx = backmap[sym->st_shndx];
2317 for (i = 0; i < s1->nb_sections; i++)
2318 sec_order[i] = i;
2319 tcc_free(s1->sections);
2320 s1->sections = snew;
2321 s1->nb_sections = nnew;
2322 tcc_free(backmap);
2324 #endif
2326 /* Output an elf, coff or binary file */
2327 /* XXX: suppress unneeded sections */
2328 static int elf_output_file(TCCState *s1, const char *filename)
2330 int ret, phnum, shnum, file_type, file_offset, *sec_order;
2331 struct dyn_inf dyninf = {0};
2332 ElfW(Phdr) *phdr;
2333 Section *strsec, *interp, *dynamic, *dynstr;
2335 file_type = s1->output_type;
2336 s1->nb_errors = 0;
2337 ret = -1;
2338 phdr = NULL;
2339 sec_order = NULL;
2340 interp = dynamic = dynstr = NULL; /* avoid warning */
2342 #ifndef ELF_OBJ_ONLY
2343 if (file_type != TCC_OUTPUT_OBJ) {
2344 /* if linking, also link in runtime libraries (libc, libgcc, etc.) */
2345 tcc_add_runtime(s1);
2346 resolve_common_syms(s1);
2348 if (!s1->static_link) {
2349 if (file_type == TCC_OUTPUT_EXE) {
2350 char *ptr;
2351 /* allow override the dynamic loader */
2352 const char *elfint = getenv("LD_SO");
2353 if (elfint == NULL)
2354 elfint = DEFAULT_ELFINTERP(s1);
2355 /* add interpreter section only if executable */
2356 interp = new_section(s1, ".interp", SHT_PROGBITS, SHF_ALLOC);
2357 interp->sh_addralign = 1;
2358 ptr = section_ptr_add(interp, 1 + strlen(elfint));
2359 strcpy(ptr, elfint);
2362 /* add dynamic symbol table */
2363 s1->dynsym = new_symtab(s1, ".dynsym", SHT_DYNSYM, SHF_ALLOC,
2364 ".dynstr",
2365 ".hash", SHF_ALLOC);
2366 dynstr = s1->dynsym->link;
2367 /* add dynamic section */
2368 dynamic = new_section(s1, ".dynamic", SHT_DYNAMIC,
2369 SHF_ALLOC | SHF_WRITE);
2370 dynamic->link = dynstr;
2371 dynamic->sh_entsize = sizeof(ElfW(Dyn));
2373 build_got(s1);
2375 if (file_type == TCC_OUTPUT_EXE) {
2376 bind_exe_dynsyms(s1);
2377 if (s1->nb_errors)
2378 goto the_end;
2379 bind_libs_dynsyms(s1);
2380 } else {
2381 /* shared library case: simply export all global symbols */
2382 export_global_syms(s1);
2385 build_got_entries(s1);
2386 version_add (s1);
2388 #endif
2390 /* we add a section for symbols */
2391 strsec = new_section(s1, ".shstrtab", SHT_STRTAB, 0);
2392 put_elf_str(strsec, "");
2394 /* Allocate strings for section names */
2395 ret = alloc_sec_names(s1, file_type, strsec);
2397 #ifndef ELF_OBJ_ONLY
2398 if (dynamic) {
2399 int i;
2400 /* add a list of needed dlls */
2401 for(i = 0; i < s1->nb_loaded_dlls; i++) {
2402 DLLReference *dllref = s1->loaded_dlls[i];
2403 if (dllref->level == 0)
2404 put_dt(dynamic, DT_NEEDED, put_elf_str(dynstr, dllref->name));
2407 if (s1->rpath)
2408 put_dt(dynamic, s1->enable_new_dtags ? DT_RUNPATH : DT_RPATH,
2409 put_elf_str(dynstr, s1->rpath));
2411 if (file_type == TCC_OUTPUT_DLL) {
2412 if (s1->soname)
2413 put_dt(dynamic, DT_SONAME, put_elf_str(dynstr, s1->soname));
2414 /* XXX: currently, since we do not handle PIC code, we
2415 must relocate the readonly segments */
2416 if (ret)
2417 put_dt(dynamic, DT_TEXTREL, 0);
2420 if (s1->symbolic)
2421 put_dt(dynamic, DT_SYMBOLIC, 0);
2423 dyninf.dynamic = dynamic;
2424 dyninf.dynstr = dynstr;
2425 /* remember offset and reserve space for 2nd call below */
2426 dyninf.data_offset = dynamic->data_offset;
2427 fill_dynamic(s1, &dyninf);
2428 dynamic->sh_size = dynamic->data_offset;
2429 dynstr->sh_size = dynstr->data_offset;
2431 #endif
2433 /* compute number of program headers */
2434 if (file_type == TCC_OUTPUT_OBJ)
2435 phnum = 0;
2436 else if (file_type == TCC_OUTPUT_DLL)
2437 phnum = 3;
2438 else if (s1->static_link)
2439 phnum = 2;
2440 else
2441 phnum = 5;
2443 /* allocate program segment headers */
2444 phdr = tcc_mallocz(phnum * sizeof(ElfW(Phdr)));
2446 /* compute number of sections */
2447 shnum = s1->nb_sections;
2449 /* this array is used to reorder sections in the output file */
2450 sec_order = tcc_malloc(sizeof(int) * shnum);
2451 sec_order[0] = 0;
2453 /* compute section to program header mapping */
2454 file_offset = layout_sections(s1, phdr, phnum, interp, strsec, &dyninf,
2455 sec_order);
2457 #ifndef ELF_OBJ_ONLY
2458 /* Fill remaining program header and finalize relocation related to dynamic
2459 linking. */
2460 if (file_type != TCC_OUTPUT_OBJ) {
2461 fill_unloadable_phdr(phdr, phnum, interp, dynamic);
2462 if (dynamic) {
2463 ElfW(Sym) *sym;
2464 dynamic->data_offset = dyninf.data_offset;
2465 fill_dynamic(s1, &dyninf);
2467 /* put in GOT the dynamic section address and relocate PLT */
2468 write32le(s1->got->data, dynamic->sh_addr);
2469 if (file_type == TCC_OUTPUT_EXE
2470 || (RELOCATE_DLLPLT && file_type == TCC_OUTPUT_DLL))
2471 relocate_plt(s1);
2473 /* relocate symbols in .dynsym now that final addresses are known */
2474 for_each_elem(s1->dynsym, 1, sym, ElfW(Sym)) {
2475 if (sym->st_shndx != SHN_UNDEF && sym->st_shndx < SHN_LORESERVE) {
2476 /* do symbol relocation */
2477 sym->st_value += s1->sections[sym->st_shndx]->sh_addr;
2482 /* if building executable or DLL, then relocate each section
2483 except the GOT which is already relocated */
2484 ret = final_sections_reloc(s1);
2485 if (ret)
2486 goto the_end;
2487 tidy_section_headers(s1, sec_order);
2489 /* Perform relocation to GOT or PLT entries */
2490 if (file_type == TCC_OUTPUT_EXE && s1->static_link)
2491 fill_got(s1);
2492 else if (s1->got)
2493 fill_local_got_entries(s1);
2495 #endif
2497 /* Create the ELF file with name 'filename' */
2498 ret = tcc_write_elf_file(s1, filename, phnum, phdr, file_offset, sec_order);
2499 s1->nb_sections = shnum;
2500 goto the_end;
2501 the_end:
2502 tcc_free(sec_order);
2503 tcc_free(phdr);
2504 return ret;
2507 LIBTCCAPI int tcc_output_file(TCCState *s, const char *filename)
2509 int ret;
2510 #ifdef TCC_TARGET_PE
2511 if (s->output_type != TCC_OUTPUT_OBJ) {
2512 ret = pe_output_file(s, filename);
2513 } else
2514 #endif
2515 ret = elf_output_file(s, filename);
2516 return ret;
2519 ssize_t full_read(int fd, void *buf, size_t count) {
2520 char *cbuf = buf;
2521 size_t rnum = 0;
2522 while (1) {
2523 ssize_t num = read(fd, cbuf, count-rnum);
2524 if (num < 0) return num;
2525 if (num == 0) return rnum;
2526 rnum += num;
2527 cbuf += num;
2531 static void *load_data(int fd, unsigned long file_offset, unsigned long size)
2533 void *data;
2535 data = tcc_malloc(size);
2536 lseek(fd, file_offset, SEEK_SET);
2537 full_read(fd, data, size);
2538 return data;
2541 typedef struct SectionMergeInfo {
2542 Section *s; /* corresponding existing section */
2543 unsigned long offset; /* offset of the new section in the existing section */
2544 uint8_t new_section; /* true if section 's' was added */
2545 uint8_t link_once; /* true if link once section */
2546 } SectionMergeInfo;
2548 ST_FUNC int tcc_object_type(int fd, ElfW(Ehdr) *h)
2550 int size = full_read(fd, h, sizeof *h);
2551 if (size == sizeof *h && 0 == memcmp(h, ELFMAG, 4)) {
2552 if (h->e_type == ET_REL)
2553 return AFF_BINTYPE_REL;
2554 if (h->e_type == ET_DYN)
2555 return AFF_BINTYPE_DYN;
2556 } else if (size >= 8) {
2557 if (0 == memcmp(h, ARMAG, 8))
2558 return AFF_BINTYPE_AR;
2559 #ifdef TCC_TARGET_COFF
2560 if (((struct filehdr*)h)->f_magic == COFF_C67_MAGIC)
2561 return AFF_BINTYPE_C67;
2562 #endif
2564 return 0;
2567 /* load an object file and merge it with current files */
2568 /* XXX: handle correctly stab (debug) info */
2569 ST_FUNC int tcc_load_object_file(TCCState *s1,
2570 int fd, unsigned long file_offset)
2572 ElfW(Ehdr) ehdr;
2573 ElfW(Shdr) *shdr, *sh;
2574 int size, i, j, offset, offseti, nb_syms, sym_index, ret, seencompressed;
2575 char *strsec, *strtab;
2576 int stab_index, stabstr_index;
2577 int *old_to_new_syms;
2578 char *sh_name, *name;
2579 SectionMergeInfo *sm_table, *sm;
2580 ElfW(Sym) *sym, *symtab;
2581 ElfW_Rel *rel;
2582 Section *s;
2584 lseek(fd, file_offset, SEEK_SET);
2585 if (tcc_object_type(fd, &ehdr) != AFF_BINTYPE_REL)
2586 goto fail1;
2587 /* test CPU specific stuff */
2588 if (ehdr.e_ident[5] != ELFDATA2LSB ||
2589 ehdr.e_machine != EM_TCC_TARGET) {
2590 fail1:
2591 tcc_error_noabort("invalid object file");
2592 return -1;
2594 /* read sections */
2595 shdr = load_data(fd, file_offset + ehdr.e_shoff,
2596 sizeof(ElfW(Shdr)) * ehdr.e_shnum);
2597 sm_table = tcc_mallocz(sizeof(SectionMergeInfo) * ehdr.e_shnum);
2599 /* load section names */
2600 sh = &shdr[ehdr.e_shstrndx];
2601 strsec = load_data(fd, file_offset + sh->sh_offset, sh->sh_size);
2603 /* load symtab and strtab */
2604 old_to_new_syms = NULL;
2605 symtab = NULL;
2606 strtab = NULL;
2607 nb_syms = 0;
2608 seencompressed = 0;
2609 stab_index = stabstr_index = 0;
2611 for(i = 1; i < ehdr.e_shnum; i++) {
2612 sh = &shdr[i];
2613 if (sh->sh_type == SHT_SYMTAB) {
2614 if (symtab) {
2615 tcc_error_noabort("object must contain only one symtab");
2616 fail:
2617 ret = -1;
2618 goto the_end;
2620 nb_syms = sh->sh_size / sizeof(ElfW(Sym));
2621 symtab = load_data(fd, file_offset + sh->sh_offset, sh->sh_size);
2622 sm_table[i].s = symtab_section;
2624 /* now load strtab */
2625 sh = &shdr[sh->sh_link];
2626 strtab = load_data(fd, file_offset + sh->sh_offset, sh->sh_size);
2628 if (sh->sh_flags & SHF_COMPRESSED)
2629 seencompressed = 1;
2632 /* now examine each section and try to merge its content with the
2633 ones in memory */
2634 for(i = 1; i < ehdr.e_shnum; i++) {
2635 /* no need to examine section name strtab */
2636 if (i == ehdr.e_shstrndx)
2637 continue;
2638 sh = &shdr[i];
2639 if (sh->sh_type == SHT_RELX)
2640 sh = &shdr[sh->sh_info];
2641 /* ignore sections types we do not handle (plus relocs to those) */
2642 if (sh->sh_type != SHT_PROGBITS &&
2643 #ifdef TCC_ARM_EABI
2644 sh->sh_type != SHT_ARM_EXIDX &&
2645 #endif
2646 sh->sh_type != SHT_NOBITS &&
2647 sh->sh_type != SHT_PREINIT_ARRAY &&
2648 sh->sh_type != SHT_INIT_ARRAY &&
2649 sh->sh_type != SHT_FINI_ARRAY &&
2650 strcmp(strsec + sh->sh_name, ".stabstr")
2652 continue;
2653 if (seencompressed
2654 && !strncmp(strsec + sh->sh_name, ".debug_", sizeof(".debug_")-1))
2655 continue;
2657 sh = &shdr[i];
2658 sh_name = strsec + sh->sh_name;
2659 if (sh->sh_addralign < 1)
2660 sh->sh_addralign = 1;
2661 /* find corresponding section, if any */
2662 for(j = 1; j < s1->nb_sections;j++) {
2663 s = s1->sections[j];
2664 if (!strcmp(s->name, sh_name)) {
2665 if (!strncmp(sh_name, ".gnu.linkonce",
2666 sizeof(".gnu.linkonce") - 1)) {
2667 /* if a 'linkonce' section is already present, we
2668 do not add it again. It is a little tricky as
2669 symbols can still be defined in
2670 it. */
2671 sm_table[i].link_once = 1;
2672 goto next;
2674 if (stab_section) {
2675 if (s == stab_section)
2676 stab_index = i;
2677 if (s == stab_section->link)
2678 stabstr_index = i;
2680 goto found;
2683 /* not found: create new section */
2684 s = new_section(s1, sh_name, sh->sh_type, sh->sh_flags & ~SHF_GROUP);
2685 /* take as much info as possible from the section. sh_link and
2686 sh_info will be updated later */
2687 s->sh_addralign = sh->sh_addralign;
2688 s->sh_entsize = sh->sh_entsize;
2689 sm_table[i].new_section = 1;
2690 found:
2691 if (sh->sh_type != s->sh_type) {
2692 tcc_error_noabort("invalid section type");
2693 goto fail;
2695 /* align start of section */
2696 s->data_offset += -s->data_offset & (sh->sh_addralign - 1);
2697 if (sh->sh_addralign > s->sh_addralign)
2698 s->sh_addralign = sh->sh_addralign;
2699 sm_table[i].offset = s->data_offset;
2700 sm_table[i].s = s;
2701 /* concatenate sections */
2702 size = sh->sh_size;
2703 if (sh->sh_type != SHT_NOBITS) {
2704 unsigned char *ptr;
2705 lseek(fd, file_offset + sh->sh_offset, SEEK_SET);
2706 ptr = section_ptr_add(s, size);
2707 full_read(fd, ptr, size);
2708 } else {
2709 s->data_offset += size;
2711 next: ;
2714 /* gr relocate stab strings */
2715 if (stab_index && stabstr_index) {
2716 Stab_Sym *a, *b;
2717 unsigned o;
2718 s = sm_table[stab_index].s;
2719 a = (Stab_Sym *)(s->data + sm_table[stab_index].offset);
2720 b = (Stab_Sym *)(s->data + s->data_offset);
2721 o = sm_table[stabstr_index].offset;
2722 while (a < b) {
2723 if (a->n_strx)
2724 a->n_strx += o;
2725 a++;
2729 /* second short pass to update sh_link and sh_info fields of new
2730 sections */
2731 for(i = 1; i < ehdr.e_shnum; i++) {
2732 s = sm_table[i].s;
2733 if (!s || !sm_table[i].new_section)
2734 continue;
2735 sh = &shdr[i];
2736 if (sh->sh_link > 0)
2737 s->link = sm_table[sh->sh_link].s;
2738 if (sh->sh_type == SHT_RELX) {
2739 s->sh_info = sm_table[sh->sh_info].s->sh_num;
2740 /* update backward link */
2741 s1->sections[s->sh_info]->reloc = s;
2745 /* resolve symbols */
2746 old_to_new_syms = tcc_mallocz(nb_syms * sizeof(int));
2748 sym = symtab + 1;
2749 for(i = 1; i < nb_syms; i++, sym++) {
2750 if (sym->st_shndx != SHN_UNDEF &&
2751 sym->st_shndx < SHN_LORESERVE) {
2752 sm = &sm_table[sym->st_shndx];
2753 if (sm->link_once) {
2754 /* if a symbol is in a link once section, we use the
2755 already defined symbol. It is very important to get
2756 correct relocations */
2757 if (ELFW(ST_BIND)(sym->st_info) != STB_LOCAL) {
2758 name = strtab + sym->st_name;
2759 sym_index = find_elf_sym(symtab_section, name);
2760 if (sym_index)
2761 old_to_new_syms[i] = sym_index;
2763 continue;
2765 /* if no corresponding section added, no need to add symbol */
2766 if (!sm->s)
2767 continue;
2768 /* convert section number */
2769 sym->st_shndx = sm->s->sh_num;
2770 /* offset value */
2771 sym->st_value += sm->offset;
2773 /* add symbol */
2774 name = strtab + sym->st_name;
2775 sym_index = set_elf_sym(symtab_section, sym->st_value, sym->st_size,
2776 sym->st_info, sym->st_other,
2777 sym->st_shndx, name);
2778 old_to_new_syms[i] = sym_index;
2781 /* third pass to patch relocation entries */
2782 for(i = 1; i < ehdr.e_shnum; i++) {
2783 s = sm_table[i].s;
2784 if (!s)
2785 continue;
2786 sh = &shdr[i];
2787 offset = sm_table[i].offset;
2788 switch(s->sh_type) {
2789 case SHT_RELX:
2790 /* take relocation offset information */
2791 offseti = sm_table[sh->sh_info].offset;
2792 for_each_elem(s, (offset / sizeof(*rel)), rel, ElfW_Rel) {
2793 int type;
2794 unsigned sym_index;
2795 /* convert symbol index */
2796 type = ELFW(R_TYPE)(rel->r_info);
2797 sym_index = ELFW(R_SYM)(rel->r_info);
2798 /* NOTE: only one symtab assumed */
2799 if (sym_index >= nb_syms)
2800 goto invalid_reloc;
2801 sym_index = old_to_new_syms[sym_index];
2802 /* ignore link_once in rel section. */
2803 if (!sym_index && !sm_table[sh->sh_info].link_once
2804 #ifdef TCC_TARGET_ARM
2805 && type != R_ARM_V4BX
2806 #elif defined TCC_TARGET_RISCV64
2807 && type != R_RISCV_ALIGN
2808 && type != R_RISCV_RELAX
2809 #endif
2811 invalid_reloc:
2812 tcc_error_noabort("Invalid relocation entry [%2d] '%s' @ %.8x",
2813 i, strsec + sh->sh_name, (int)rel->r_offset);
2814 goto fail;
2816 rel->r_info = ELFW(R_INFO)(sym_index, type);
2817 /* offset the relocation offset */
2818 rel->r_offset += offseti;
2819 #ifdef TCC_TARGET_ARM
2820 /* Jumps and branches from a Thumb code to a PLT entry need
2821 special handling since PLT entries are ARM code.
2822 Unconditional bl instructions referencing PLT entries are
2823 handled by converting these instructions into blx
2824 instructions. Other case of instructions referencing a PLT
2825 entry require to add a Thumb stub before the PLT entry to
2826 switch to ARM mode. We set bit plt_thumb_stub of the
2827 attribute of a symbol to indicate such a case. */
2828 if (type == R_ARM_THM_JUMP24)
2829 get_sym_attr(s1, sym_index, 1)->plt_thumb_stub = 1;
2830 #endif
2832 break;
2833 default:
2834 break;
2838 ret = 0;
2839 the_end:
2840 tcc_free(symtab);
2841 tcc_free(strtab);
2842 tcc_free(old_to_new_syms);
2843 tcc_free(sm_table);
2844 tcc_free(strsec);
2845 tcc_free(shdr);
2846 return ret;
2849 typedef struct ArchiveHeader {
2850 char ar_name[16]; /* name of this member */
2851 char ar_date[12]; /* file mtime */
2852 char ar_uid[6]; /* owner uid; printed as decimal */
2853 char ar_gid[6]; /* owner gid; printed as decimal */
2854 char ar_mode[8]; /* file mode, printed as octal */
2855 char ar_size[10]; /* file size, printed as decimal */
2856 char ar_fmag[2]; /* should contain ARFMAG */
2857 } ArchiveHeader;
2859 #define ARFMAG "`\n"
2861 static unsigned long long get_be(const uint8_t *b, int n)
2863 unsigned long long ret = 0;
2864 while (n)
2865 ret = (ret << 8) | *b++, --n;
2866 return ret;
2869 static int read_ar_header(int fd, int offset, ArchiveHeader *hdr)
2871 char *p, *e;
2872 int len;
2873 lseek(fd, offset, SEEK_SET);
2874 len = full_read(fd, hdr, sizeof(ArchiveHeader));
2875 if (len != sizeof(ArchiveHeader))
2876 return len ? -1 : 0;
2877 p = hdr->ar_name;
2878 for (e = p + sizeof hdr->ar_name; e > p && e[-1] == ' ';)
2879 --e;
2880 *e = '\0';
2881 hdr->ar_size[sizeof hdr->ar_size-1] = 0;
2882 return len;
2885 /* load only the objects which resolve undefined symbols */
2886 static int tcc_load_alacarte(TCCState *s1, int fd, int size, int entrysize)
2888 int i, bound, nsyms, sym_index, len, ret = -1;
2889 unsigned long long off;
2890 uint8_t *data;
2891 const char *ar_names, *p;
2892 const uint8_t *ar_index;
2893 ElfW(Sym) *sym;
2894 ArchiveHeader hdr;
2896 data = tcc_malloc(size);
2897 if (full_read(fd, data, size) != size)
2898 goto the_end;
2899 nsyms = get_be(data, entrysize);
2900 ar_index = data + entrysize;
2901 ar_names = (char *) ar_index + nsyms * entrysize;
2903 do {
2904 bound = 0;
2905 for (p = ar_names, i = 0; i < nsyms; i++, p += strlen(p)+1) {
2906 Section *s = symtab_section;
2907 sym_index = find_elf_sym(s, p);
2908 if (!sym_index)
2909 continue;
2910 sym = &((ElfW(Sym) *)s->data)[sym_index];
2911 if(sym->st_shndx != SHN_UNDEF)
2912 continue;
2913 off = get_be(ar_index + i * entrysize, entrysize);
2914 len = read_ar_header(fd, off, &hdr);
2915 if (len <= 0 || memcmp(hdr.ar_fmag, ARFMAG, 2)) {
2916 tcc_error_noabort("invalid archive");
2917 goto the_end;
2919 off += len;
2920 if (s1->verbose == 2)
2921 printf(" -> %s\n", hdr.ar_name);
2922 if (tcc_load_object_file(s1, fd, off) < 0)
2923 goto the_end;
2924 ++bound;
2926 } while(bound);
2927 ret = 0;
2928 the_end:
2929 tcc_free(data);
2930 return ret;
2933 /* load a '.a' file */
2934 ST_FUNC int tcc_load_archive(TCCState *s1, int fd, int alacarte)
2936 ArchiveHeader hdr;
2937 /* char magic[8]; */
2938 int size, len;
2939 unsigned long file_offset;
2940 ElfW(Ehdr) ehdr;
2942 /* skip magic which was already checked */
2943 /* full_read(fd, magic, sizeof(magic)); */
2944 file_offset = sizeof ARMAG - 1;
2946 for(;;) {
2947 len = read_ar_header(fd, file_offset, &hdr);
2948 if (len == 0)
2949 return 0;
2950 if (len < 0) {
2951 tcc_error_noabort("invalid archive");
2952 return -1;
2954 file_offset += len;
2955 size = strtol(hdr.ar_size, NULL, 0);
2956 /* align to even */
2957 size = (size + 1) & ~1;
2958 if (alacarte) {
2959 /* coff symbol table : we handle it */
2960 if (!strcmp(hdr.ar_name, "/"))
2961 return tcc_load_alacarte(s1, fd, size, 4);
2962 if (!strcmp(hdr.ar_name, "/SYM64/"))
2963 return tcc_load_alacarte(s1, fd, size, 8);
2964 } else if (tcc_object_type(fd, &ehdr) == AFF_BINTYPE_REL) {
2965 if (s1->verbose == 2)
2966 printf(" -> %s\n", hdr.ar_name);
2967 if (tcc_load_object_file(s1, fd, file_offset) < 0)
2968 return -1;
2970 file_offset += size;
2974 #ifndef ELF_OBJ_ONLY
2975 /* Set LV[I] to the global index of sym-version (LIB,VERSION). Maybe resizes
2976 LV, maybe create a new entry for (LIB,VERSION). */
2977 static void set_ver_to_ver(TCCState *s1, int *n, int **lv, int i, char *lib, char *version)
2979 while (i >= *n) {
2980 *lv = tcc_realloc(*lv, (*n + 1) * sizeof(**lv));
2981 (*lv)[(*n)++] = -1;
2983 if ((*lv)[i] == -1) {
2984 int v, prev_same_lib = -1;
2985 for (v = 0; v < nb_sym_versions; v++) {
2986 if (strcmp(sym_versions[v].lib, lib))
2987 continue;
2988 prev_same_lib = v;
2989 if (!strcmp(sym_versions[v].version, version))
2990 break;
2992 if (v == nb_sym_versions) {
2993 sym_versions = tcc_realloc (sym_versions,
2994 (v + 1) * sizeof(*sym_versions));
2995 sym_versions[v].lib = tcc_strdup(lib);
2996 sym_versions[v].version = tcc_strdup(version);
2997 sym_versions[v].out_index = 0;
2998 sym_versions[v].prev_same_lib = prev_same_lib;
2999 nb_sym_versions++;
3001 (*lv)[i] = v;
3005 /* Associates symbol SYM_INDEX (in dynsymtab) with sym-version index
3006 VERNDX. */
3007 static void
3008 set_sym_version(TCCState *s1, int sym_index, int verndx)
3010 if (sym_index >= nb_sym_to_version) {
3011 int newelems = sym_index ? sym_index * 2 : 1;
3012 sym_to_version = tcc_realloc(sym_to_version,
3013 newelems * sizeof(*sym_to_version));
3014 memset(sym_to_version + nb_sym_to_version, -1,
3015 (newelems - nb_sym_to_version) * sizeof(*sym_to_version));
3016 nb_sym_to_version = newelems;
3018 if (sym_to_version[sym_index] < 0)
3019 sym_to_version[sym_index] = verndx;
3022 struct versym_info {
3023 int nb_versyms;
3024 ElfW(Verdef) *verdef;
3025 ElfW(Verneed) *verneed;
3026 ElfW(Half) *versym;
3027 int nb_local_ver, *local_ver;
3031 static void store_version(TCCState *s1, struct versym_info *v, char *dynstr)
3033 char *lib, *version;
3034 uint32_t next;
3035 int i;
3037 #define DEBUG_VERSION 0
3039 if (v->versym && v->verdef) {
3040 ElfW(Verdef) *vdef = v->verdef;
3041 lib = NULL;
3042 do {
3043 ElfW(Verdaux) *verdaux =
3044 (ElfW(Verdaux) *) (((char *) vdef) + vdef->vd_aux);
3046 #if DEBUG_VERSION
3047 printf ("verdef: version:%u flags:%u index:%u, hash:%u\n",
3048 vdef->vd_version, vdef->vd_flags, vdef->vd_ndx,
3049 vdef->vd_hash);
3050 #endif
3051 if (vdef->vd_cnt) {
3052 version = dynstr + verdaux->vda_name;
3054 if (lib == NULL)
3055 lib = version;
3056 else
3057 set_ver_to_ver(s1, &v->nb_local_ver, &v->local_ver, vdef->vd_ndx,
3058 lib, version);
3059 #if DEBUG_VERSION
3060 printf (" verdaux(%u): %s\n", vdef->vd_ndx, version);
3061 #endif
3063 next = vdef->vd_next;
3064 vdef = (ElfW(Verdef) *) (((char *) vdef) + next);
3065 } while (next);
3067 if (v->versym && v->verneed) {
3068 ElfW(Verneed) *vneed = v->verneed;
3069 do {
3070 ElfW(Vernaux) *vernaux =
3071 (ElfW(Vernaux) *) (((char *) vneed) + vneed->vn_aux);
3073 lib = dynstr + vneed->vn_file;
3074 #if DEBUG_VERSION
3075 printf ("verneed: %u %s\n", vneed->vn_version, lib);
3076 #endif
3077 for (i = 0; i < vneed->vn_cnt; i++) {
3078 if ((vernaux->vna_other & 0x8000) == 0) { /* hidden */
3079 version = dynstr + vernaux->vna_name;
3080 set_ver_to_ver(s1, &v->nb_local_ver, &v->local_ver, vernaux->vna_other,
3081 lib, version);
3082 #if DEBUG_VERSION
3083 printf (" vernaux(%u): %u %u %s\n",
3084 vernaux->vna_other, vernaux->vna_hash,
3085 vernaux->vna_flags, version);
3086 #endif
3088 vernaux = (ElfW(Vernaux) *) (((char *) vernaux) + vernaux->vna_next);
3090 next = vneed->vn_next;
3091 vneed = (ElfW(Verneed) *) (((char *) vneed) + next);
3092 } while (next);
3095 #if DEBUG_VERSION
3096 for (i = 0; i < v->nb_local_ver; i++) {
3097 if (v->local_ver[i] > 0) {
3098 printf ("%d: lib: %s, version %s\n",
3099 i, sym_versions[v->local_ver[i]].lib,
3100 sym_versions[v->local_ver[i]].version);
3103 #endif
3106 /* load a DLL and all referenced DLLs. 'level = 0' means that the DLL
3107 is referenced by the user (so it should be added as DT_NEEDED in
3108 the generated ELF file) */
3109 ST_FUNC int tcc_load_dll(TCCState *s1, int fd, const char *filename, int level)
3111 ElfW(Ehdr) ehdr;
3112 ElfW(Shdr) *shdr, *sh, *sh1;
3113 int i, j, nb_syms, nb_dts, sym_bind, ret;
3114 ElfW(Sym) *sym, *dynsym;
3115 ElfW(Dyn) *dt, *dynamic;
3117 char *dynstr;
3118 int sym_index;
3119 const char *name, *soname;
3120 DLLReference *dllref;
3121 struct versym_info v;
3123 full_read(fd, &ehdr, sizeof(ehdr));
3125 /* test CPU specific stuff */
3126 if (ehdr.e_ident[5] != ELFDATA2LSB ||
3127 ehdr.e_machine != EM_TCC_TARGET) {
3128 tcc_error_noabort("bad architecture");
3129 return -1;
3132 /* read sections */
3133 shdr = load_data(fd, ehdr.e_shoff, sizeof(ElfW(Shdr)) * ehdr.e_shnum);
3135 /* load dynamic section and dynamic symbols */
3136 nb_syms = 0;
3137 nb_dts = 0;
3138 dynamic = NULL;
3139 dynsym = NULL; /* avoid warning */
3140 dynstr = NULL; /* avoid warning */
3141 memset(&v, 0, sizeof v);
3143 for(i = 0, sh = shdr; i < ehdr.e_shnum; i++, sh++) {
3144 switch(sh->sh_type) {
3145 case SHT_DYNAMIC:
3146 nb_dts = sh->sh_size / sizeof(ElfW(Dyn));
3147 dynamic = load_data(fd, sh->sh_offset, sh->sh_size);
3148 break;
3149 case SHT_DYNSYM:
3150 nb_syms = sh->sh_size / sizeof(ElfW(Sym));
3151 dynsym = load_data(fd, sh->sh_offset, sh->sh_size);
3152 sh1 = &shdr[sh->sh_link];
3153 dynstr = load_data(fd, sh1->sh_offset, sh1->sh_size);
3154 break;
3155 case SHT_GNU_verdef:
3156 v.verdef = load_data(fd, sh->sh_offset, sh->sh_size);
3157 break;
3158 case SHT_GNU_verneed:
3159 v.verneed = load_data(fd, sh->sh_offset, sh->sh_size);
3160 break;
3161 case SHT_GNU_versym:
3162 v.nb_versyms = sh->sh_size / sizeof(ElfW(Half));
3163 v.versym = load_data(fd, sh->sh_offset, sh->sh_size);
3164 break;
3165 default:
3166 break;
3170 /* compute the real library name */
3171 soname = tcc_basename(filename);
3173 for(i = 0, dt = dynamic; i < nb_dts; i++, dt++) {
3174 if (dt->d_tag == DT_SONAME) {
3175 soname = dynstr + dt->d_un.d_val;
3179 /* if the dll is already loaded, do not load it */
3180 for(i = 0; i < s1->nb_loaded_dlls; i++) {
3181 dllref = s1->loaded_dlls[i];
3182 if (!strcmp(soname, dllref->name)) {
3183 /* but update level if needed */
3184 if (level < dllref->level)
3185 dllref->level = level;
3186 ret = 0;
3187 goto the_end;
3191 if (v.nb_versyms != nb_syms)
3192 tcc_free (v.versym), v.versym = NULL;
3193 else
3194 store_version(s1, &v, dynstr);
3196 /* add the dll and its level */
3197 dllref = tcc_mallocz(sizeof(DLLReference) + strlen(soname));
3198 dllref->level = level;
3199 strcpy(dllref->name, soname);
3200 dynarray_add(&s1->loaded_dlls, &s1->nb_loaded_dlls, dllref);
3202 /* add dynamic symbols in dynsym_section */
3203 for(i = 1, sym = dynsym + 1; i < nb_syms; i++, sym++) {
3204 sym_bind = ELFW(ST_BIND)(sym->st_info);
3205 if (sym_bind == STB_LOCAL)
3206 continue;
3207 name = dynstr + sym->st_name;
3208 sym_index = set_elf_sym(s1->dynsymtab_section, sym->st_value, sym->st_size,
3209 sym->st_info, sym->st_other, sym->st_shndx, name);
3210 if (v.versym) {
3211 ElfW(Half) vsym = v.versym[i];
3212 if ((vsym & 0x8000) == 0 && vsym > 0 && vsym < v.nb_local_ver)
3213 set_sym_version(s1, sym_index, v.local_ver[vsym]);
3217 /* load all referenced DLLs */
3218 for(i = 0, dt = dynamic; i < nb_dts; i++, dt++) {
3219 switch(dt->d_tag) {
3220 case DT_NEEDED:
3221 name = dynstr + dt->d_un.d_val;
3222 for(j = 0; j < s1->nb_loaded_dlls; j++) {
3223 dllref = s1->loaded_dlls[j];
3224 if (!strcmp(name, dllref->name))
3225 goto already_loaded;
3227 if (tcc_add_dll(s1, name, AFF_REFERENCED_DLL) < 0) {
3228 tcc_error_noabort("referenced dll '%s' not found", name);
3229 ret = -1;
3230 goto the_end;
3232 already_loaded:
3233 break;
3236 ret = 0;
3237 the_end:
3238 tcc_free(dynstr);
3239 tcc_free(dynsym);
3240 tcc_free(dynamic);
3241 tcc_free(shdr);
3242 tcc_free(v.local_ver);
3243 tcc_free(v.verdef);
3244 tcc_free(v.verneed);
3245 tcc_free(v.versym);
3246 return ret;
3249 #define LD_TOK_NAME 256
3250 #define LD_TOK_EOF (-1)
3252 static int ld_inp(TCCState *s1)
3254 char b;
3255 if (s1->cc != -1) {
3256 int c = s1->cc;
3257 s1->cc = -1;
3258 return c;
3260 if (1 == read(s1->fd, &b, 1))
3261 return b;
3262 return CH_EOF;
3265 /* return next ld script token */
3266 static int ld_next(TCCState *s1, char *name, int name_size)
3268 int c, d, ch;
3269 char *q;
3271 redo:
3272 ch = ld_inp(s1);
3273 switch(ch) {
3274 case ' ':
3275 case '\t':
3276 case '\f':
3277 case '\v':
3278 case '\r':
3279 case '\n':
3280 goto redo;
3281 case '/':
3282 ch = ld_inp(s1);
3283 if (ch == '*') { /* comment */
3284 for (d = 0;; d = ch) {
3285 ch = ld_inp(s1);
3286 if (ch == CH_EOF || (ch == '/' && d == '*'))
3287 break;
3289 goto redo;
3290 } else {
3291 q = name;
3292 *q++ = '/';
3293 goto parse_name;
3295 break;
3296 case '\\':
3297 /* case 'a' ... 'z': */
3298 case 'a':
3299 case 'b':
3300 case 'c':
3301 case 'd':
3302 case 'e':
3303 case 'f':
3304 case 'g':
3305 case 'h':
3306 case 'i':
3307 case 'j':
3308 case 'k':
3309 case 'l':
3310 case 'm':
3311 case 'n':
3312 case 'o':
3313 case 'p':
3314 case 'q':
3315 case 'r':
3316 case 's':
3317 case 't':
3318 case 'u':
3319 case 'v':
3320 case 'w':
3321 case 'x':
3322 case 'y':
3323 case 'z':
3324 /* case 'A' ... 'z': */
3325 case 'A':
3326 case 'B':
3327 case 'C':
3328 case 'D':
3329 case 'E':
3330 case 'F':
3331 case 'G':
3332 case 'H':
3333 case 'I':
3334 case 'J':
3335 case 'K':
3336 case 'L':
3337 case 'M':
3338 case 'N':
3339 case 'O':
3340 case 'P':
3341 case 'Q':
3342 case 'R':
3343 case 'S':
3344 case 'T':
3345 case 'U':
3346 case 'V':
3347 case 'W':
3348 case 'X':
3349 case 'Y':
3350 case 'Z':
3351 case '_':
3352 case '.':
3353 case '$':
3354 case '~':
3355 q = name;
3356 parse_name:
3357 for(;;) {
3358 if (!((ch >= 'a' && ch <= 'z') ||
3359 (ch >= 'A' && ch <= 'Z') ||
3360 (ch >= '0' && ch <= '9') ||
3361 strchr("/.-_+=$:\\,~", ch)))
3362 break;
3363 if ((q - name) < name_size - 1) {
3364 *q++ = ch;
3366 ch = ld_inp(s1);
3368 s1->cc = ch;
3369 *q = '\0';
3370 c = LD_TOK_NAME;
3371 break;
3372 case CH_EOF:
3373 c = LD_TOK_EOF;
3374 break;
3375 default:
3376 c = ch;
3377 break;
3379 return c;
3382 static int ld_add_file(TCCState *s1, const char filename[])
3384 if (filename[0] == '/') {
3385 if (CONFIG_SYSROOT[0] == '\0'
3386 && tcc_add_file_internal(s1, filename, AFF_TYPE_BIN) == 0)
3387 return 0;
3388 filename = tcc_basename(filename);
3390 return tcc_add_dll(s1, filename, 0);
3393 static int ld_add_file_list(TCCState *s1, const char *cmd, int as_needed)
3395 char filename[1024], libname[1024];
3396 int t, group, nblibs = 0, ret = 0;
3397 char **libs = NULL;
3399 group = !strcmp(cmd, "GROUP");
3400 if (!as_needed)
3401 s1->new_undef_sym = 0;
3402 t = ld_next(s1, filename, sizeof(filename));
3403 if (t != '(') {
3404 tcc_error_noabort("( expected");
3405 ret = -1;
3406 goto lib_parse_error;
3408 t = ld_next(s1, filename, sizeof(filename));
3409 for(;;) {
3410 libname[0] = '\0';
3411 if (t == LD_TOK_EOF) {
3412 tcc_error_noabort("unexpected end of file");
3413 ret = -1;
3414 goto lib_parse_error;
3415 } else if (t == ')') {
3416 break;
3417 } else if (t == '-') {
3418 t = ld_next(s1, filename, sizeof(filename));
3419 if ((t != LD_TOK_NAME) || (filename[0] != 'l')) {
3420 tcc_error_noabort("library name expected");
3421 ret = -1;
3422 goto lib_parse_error;
3424 pstrcpy(libname, sizeof libname, &filename[1]);
3425 if (s1->static_link) {
3426 snprintf(filename, sizeof filename, "lib%s.a", libname);
3427 } else {
3428 snprintf(filename, sizeof filename, "lib%s.so", libname);
3430 } else if (t != LD_TOK_NAME) {
3431 tcc_error_noabort("filename expected");
3432 ret = -1;
3433 goto lib_parse_error;
3435 if (!strcmp(filename, "AS_NEEDED")) {
3436 ret = ld_add_file_list(s1, cmd, 1);
3437 if (ret)
3438 goto lib_parse_error;
3439 } else {
3440 /* TODO: Implement AS_NEEDED support. Ignore it for now */
3441 if (!as_needed) {
3442 ret = ld_add_file(s1, filename);
3443 if (ret)
3444 goto lib_parse_error;
3445 if (group) {
3446 /* Add the filename *and* the libname to avoid future conversions */
3447 dynarray_add(&libs, &nblibs, tcc_strdup(filename));
3448 if (libname[0] != '\0')
3449 dynarray_add(&libs, &nblibs, tcc_strdup(libname));
3453 t = ld_next(s1, filename, sizeof(filename));
3454 if (t == ',') {
3455 t = ld_next(s1, filename, sizeof(filename));
3458 if (group && !as_needed) {
3459 while (s1->new_undef_sym) {
3460 int i;
3461 s1->new_undef_sym = 0;
3462 for (i = 0; i < nblibs; i ++)
3463 ld_add_file(s1, libs[i]);
3466 lib_parse_error:
3467 dynarray_reset(&libs, &nblibs);
3468 return ret;
3471 /* interpret a subset of GNU ldscripts to handle the dummy libc.so
3472 files */
3473 ST_FUNC int tcc_load_ldscript(TCCState *s1, int fd)
3475 char cmd[64];
3476 char filename[1024];
3477 int t, ret;
3479 s1->fd = fd;
3480 s1->cc = -1;
3481 for(;;) {
3482 t = ld_next(s1, cmd, sizeof(cmd));
3483 if (t == LD_TOK_EOF)
3484 return 0;
3485 else if (t != LD_TOK_NAME)
3486 return -1;
3487 if (!strcmp(cmd, "INPUT") ||
3488 !strcmp(cmd, "GROUP")) {
3489 ret = ld_add_file_list(s1, cmd, 0);
3490 if (ret)
3491 return ret;
3492 } else if (!strcmp(cmd, "OUTPUT_FORMAT") ||
3493 !strcmp(cmd, "TARGET")) {
3494 /* ignore some commands */
3495 t = ld_next(s1, cmd, sizeof(cmd));
3496 if (t != '(') {
3497 tcc_error_noabort("( expected");
3498 return -1;
3500 for(;;) {
3501 t = ld_next(s1, filename, sizeof(filename));
3502 if (t == LD_TOK_EOF) {
3503 tcc_error_noabort("unexpected end of file");
3504 return -1;
3505 } else if (t == ')') {
3506 break;
3509 } else {
3510 return -1;
3513 return 0;
3515 #endif /* !ELF_OBJ_ONLY */