Missied a commit in order to support -v --help the same way as gcc does
[tinycc.git] / tccelf.c
blobd83cc30d33e1f32b618244699cff412791260e9a
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 tcc_add_library_err(s1, "c");
1421 #ifdef TCC_LIBGCC
1422 if (!s1->static_link) {
1423 if (TCC_LIBGCC[0] == '/')
1424 tcc_add_file(s1, TCC_LIBGCC);
1425 else
1426 tcc_add_dll(s1, TCC_LIBGCC, 0);
1428 #endif
1429 #ifdef CONFIG_TCC_BCHECK
1430 if (s1->do_bounds_check && s1->output_type != TCC_OUTPUT_DLL) {
1431 tcc_add_library_err(s1, "pthread");
1432 tcc_add_library_err(s1, "dl");
1433 tcc_add_support(s1, "bcheck.o");
1435 #endif
1436 #ifdef CONFIG_TCC_BACKTRACE
1437 if (s1->do_backtrace) {
1438 if (s1->output_type == TCC_OUTPUT_EXE)
1439 tcc_add_support(s1, "bt-exe.o");
1440 if (s1->output_type != TCC_OUTPUT_DLL)
1441 tcc_add_support(s1, "bt-log.o");
1442 if (s1->output_type != TCC_OUTPUT_MEMORY)
1443 tcc_add_btstub(s1);
1445 #endif
1446 tcc_add_support(s1, TCC_LIBTCC1);
1447 /* add crt end if not memory output */
1448 if (s1->output_type != TCC_OUTPUT_MEMORY)
1449 tcc_add_crt(s1, "crtn.o");
1452 #endif
1454 /* add various standard linker symbols (must be done after the
1455 sections are filled (for example after allocating common
1456 symbols)) */
1457 static void tcc_add_linker_symbols(TCCState *s1)
1459 char buf[1024];
1460 int i;
1461 Section *s;
1463 set_global_sym(s1, "_etext", text_section, -1);
1464 set_global_sym(s1, "_edata", data_section, -1);
1465 set_global_sym(s1, "_end", bss_section, -1);
1466 #ifdef TCC_TARGET_RISCV64
1467 /* XXX should be .sdata+0x800, not .data+0x800 */
1468 set_global_sym(s1, "__global_pointer$", data_section, 0x800);
1469 #endif
1470 /* horrible new standard ldscript defines */
1471 add_init_array_defines(s1, ".preinit_array");
1472 add_init_array_defines(s1, ".init_array");
1473 add_init_array_defines(s1, ".fini_array");
1474 /* add start and stop symbols for sections whose name can be
1475 expressed in C */
1476 for(i = 1; i < s1->nb_sections; i++) {
1477 s = s1->sections[i];
1478 if ((s->sh_flags & SHF_ALLOC)
1479 && (s->sh_type == SHT_PROGBITS
1480 || s->sh_type == SHT_STRTAB)) {
1481 const char *p;
1482 /* check if section name can be expressed in C */
1483 p = s->name;
1484 for(;;) {
1485 int c = *p;
1486 if (!c)
1487 break;
1488 if (!isid(c) && !isnum(c))
1489 goto next_sec;
1490 p++;
1492 snprintf(buf, sizeof(buf), "__start_%s", s->name);
1493 set_global_sym(s1, buf, s, 0);
1494 snprintf(buf, sizeof(buf), "__stop_%s", s->name);
1495 set_global_sym(s1, buf, s, -1);
1497 next_sec: ;
1501 ST_FUNC void resolve_common_syms(TCCState *s1)
1503 ElfW(Sym) *sym;
1505 /* Allocate common symbols in BSS. */
1506 for_each_elem(symtab_section, 1, sym, ElfW(Sym)) {
1507 if (sym->st_shndx == SHN_COMMON) {
1508 /* symbol alignment is in st_value for SHN_COMMONs */
1509 sym->st_value = section_add(bss_section, sym->st_size,
1510 sym->st_value);
1511 sym->st_shndx = bss_section->sh_num;
1515 /* Now assign linker provided symbols their value. */
1516 tcc_add_linker_symbols(s1);
1519 static void tcc_output_binary(TCCState *s1, FILE *f,
1520 const int *sec_order)
1522 Section *s;
1523 int i, offset, size;
1525 offset = 0;
1526 for(i=1;i<s1->nb_sections;i++) {
1527 s = s1->sections[sec_order[i]];
1528 if (s->sh_type != SHT_NOBITS &&
1529 (s->sh_flags & SHF_ALLOC)) {
1530 while (offset < s->sh_offset) {
1531 fputc(0, f);
1532 offset++;
1534 size = s->sh_size;
1535 fwrite(s->data, 1, size, f);
1536 offset += size;
1541 #ifndef ELF_OBJ_ONLY
1542 ST_FUNC void fill_got_entry(TCCState *s1, ElfW_Rel *rel)
1544 int sym_index = ELFW(R_SYM) (rel->r_info);
1545 ElfW(Sym) *sym = &((ElfW(Sym) *) symtab_section->data)[sym_index];
1546 struct sym_attr *attr = get_sym_attr(s1, sym_index, 0);
1547 unsigned offset = attr->got_offset;
1549 if (0 == offset)
1550 return;
1551 section_reserve(s1->got, offset + PTR_SIZE);
1552 #ifdef TCC_TARGET_X86_64
1553 write64le(s1->got->data + offset, sym->st_value);
1554 #else
1555 write32le(s1->got->data + offset, sym->st_value);
1556 #endif
1559 /* Perform relocation to GOT or PLT entries */
1560 ST_FUNC void fill_got(TCCState *s1)
1562 Section *s;
1563 ElfW_Rel *rel;
1564 int i;
1566 for(i = 1; i < s1->nb_sections; i++) {
1567 s = s1->sections[i];
1568 if (s->sh_type != SHT_RELX)
1569 continue;
1570 /* no need to handle got relocations */
1571 if (s->link != symtab_section)
1572 continue;
1573 for_each_elem(s, 0, rel, ElfW_Rel) {
1574 switch (ELFW(R_TYPE) (rel->r_info)) {
1575 case R_X86_64_GOT32:
1576 case R_X86_64_GOTPCREL:
1577 case R_X86_64_GOTPCRELX:
1578 case R_X86_64_REX_GOTPCRELX:
1579 case R_X86_64_PLT32:
1580 fill_got_entry(s1, rel);
1581 break;
1587 /* See put_got_entry for a description. This is the second stage
1588 where GOT references to local defined symbols are rewritten. */
1589 static void fill_local_got_entries(TCCState *s1)
1591 ElfW_Rel *rel;
1592 if (!s1->got->reloc)
1593 return;
1594 for_each_elem(s1->got->reloc, 0, rel, ElfW_Rel) {
1595 if (ELFW(R_TYPE)(rel->r_info) == R_RELATIVE) {
1596 int sym_index = ELFW(R_SYM) (rel->r_info);
1597 ElfW(Sym) *sym = &((ElfW(Sym) *) symtab_section->data)[sym_index];
1598 struct sym_attr *attr = get_sym_attr(s1, sym_index, 0);
1599 unsigned offset = attr->got_offset;
1600 if (offset != rel->r_offset - s1->got->sh_addr)
1601 tcc_error_noabort("huh");
1602 rel->r_info = ELFW(R_INFO)(0, R_RELATIVE);
1603 #if SHT_RELX == SHT_RELA
1604 rel->r_addend = sym->st_value;
1605 #else
1606 /* All our REL architectures also happen to be 32bit LE. */
1607 write32le(s1->got->data + offset, sym->st_value);
1608 #endif
1613 /* Bind symbols of executable: resolve undefined symbols from exported symbols
1614 in shared libraries and export non local defined symbols to shared libraries
1615 if -rdynamic switch was given on command line */
1616 static void bind_exe_dynsyms(TCCState *s1)
1618 const char *name;
1619 int sym_index, index;
1620 ElfW(Sym) *sym, *esym;
1621 int type;
1623 /* Resolve undefined symbols from dynamic symbols. When there is a match:
1624 - if STT_FUNC or STT_GNU_IFUNC symbol -> add it in PLT
1625 - if STT_OBJECT symbol -> add it in .bss section with suitable reloc */
1626 for_each_elem(symtab_section, 1, sym, ElfW(Sym)) {
1627 if (sym->st_shndx == SHN_UNDEF) {
1628 name = (char *) symtab_section->link->data + sym->st_name;
1629 sym_index = find_elf_sym(s1->dynsymtab_section, name);
1630 if (sym_index) {
1631 esym = &((ElfW(Sym) *)s1->dynsymtab_section->data)[sym_index];
1632 type = ELFW(ST_TYPE)(esym->st_info);
1633 if ((type == STT_FUNC) || (type == STT_GNU_IFUNC)) {
1634 /* Indirect functions shall have STT_FUNC type in executable
1635 * dynsym section. Indeed, a dlsym call following a lazy
1636 * resolution would pick the symbol value from the
1637 * executable dynsym entry which would contain the address
1638 * of the function wanted by the caller of dlsym instead of
1639 * the address of the function that would return that
1640 * address */
1641 int dynindex
1642 = put_elf_sym(s1->dynsym, 0, esym->st_size,
1643 ELFW(ST_INFO)(STB_GLOBAL,STT_FUNC), 0, 0,
1644 name);
1645 int index = sym - (ElfW(Sym) *) symtab_section->data;
1646 get_sym_attr(s1, index, 1)->dyn_index = dynindex;
1647 } else if (type == STT_OBJECT) {
1648 unsigned long offset;
1649 ElfW(Sym) *dynsym;
1650 offset = bss_section->data_offset;
1651 /* XXX: which alignment ? */
1652 offset = (offset + 16 - 1) & -16;
1653 set_elf_sym (s1->symtab, offset, esym->st_size,
1654 esym->st_info, 0, bss_section->sh_num, name);
1655 index = put_elf_sym(s1->dynsym, offset, esym->st_size,
1656 esym->st_info, 0, bss_section->sh_num,
1657 name);
1659 /* Ensure R_COPY works for weak symbol aliases */
1660 if (ELFW(ST_BIND)(esym->st_info) == STB_WEAK) {
1661 for_each_elem(s1->dynsymtab_section, 1, dynsym, ElfW(Sym)) {
1662 if ((dynsym->st_value == esym->st_value)
1663 && (ELFW(ST_BIND)(dynsym->st_info) == STB_GLOBAL)) {
1664 char *dynname = (char *) s1->dynsymtab_section->link->data
1665 + dynsym->st_name;
1666 put_elf_sym(s1->dynsym, offset, dynsym->st_size,
1667 dynsym->st_info, 0,
1668 bss_section->sh_num, dynname);
1669 break;
1674 put_elf_reloc(s1->dynsym, bss_section,
1675 offset, R_COPY, index);
1676 offset += esym->st_size;
1677 bss_section->data_offset = offset;
1679 } else {
1680 /* STB_WEAK undefined symbols are accepted */
1681 /* XXX: _fp_hw seems to be part of the ABI, so we ignore it */
1682 if (ELFW(ST_BIND)(sym->st_info) == STB_WEAK ||
1683 !strcmp(name, "_fp_hw")) {
1684 } else {
1685 tcc_error_noabort("undefined symbol '%s'", name);
1688 } else if (s1->rdynamic && ELFW(ST_BIND)(sym->st_info) != STB_LOCAL) {
1689 /* if -rdynamic option, then export all non local symbols */
1690 name = (char *) symtab_section->link->data + sym->st_name;
1691 set_elf_sym(s1->dynsym, sym->st_value, sym->st_size, sym->st_info,
1692 0, sym->st_shndx, name);
1697 /* Bind symbols of libraries: export all non local symbols of executable that
1698 are referenced by shared libraries. The reason is that the dynamic loader
1699 search symbol first in executable and then in libraries. Therefore a
1700 reference to a symbol already defined by a library can still be resolved by
1701 a symbol in the executable. */
1702 static void bind_libs_dynsyms(TCCState *s1)
1704 const char *name;
1705 int sym_index;
1706 ElfW(Sym) *sym, *esym;
1708 for_each_elem(s1->dynsymtab_section, 1, esym, ElfW(Sym)) {
1709 name = (char *) s1->dynsymtab_section->link->data + esym->st_name;
1710 sym_index = find_elf_sym(symtab_section, name);
1711 sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
1712 if (sym_index && sym->st_shndx != SHN_UNDEF
1713 && ELFW(ST_BIND)(sym->st_info) != STB_LOCAL) {
1714 set_elf_sym(s1->dynsym, sym->st_value, sym->st_size,
1715 sym->st_info, 0, sym->st_shndx, name);
1716 } else if (esym->st_shndx == SHN_UNDEF) {
1717 /* weak symbols can stay undefined */
1718 if (ELFW(ST_BIND)(esym->st_info) != STB_WEAK)
1719 tcc_warning("undefined dynamic symbol '%s'", name);
1724 /* Export all non local symbols. This is used by shared libraries so that the
1725 non local symbols they define can resolve a reference in another shared
1726 library or in the executable. Correspondingly, it allows undefined local
1727 symbols to be resolved by other shared libraries or by the executable. */
1728 static void export_global_syms(TCCState *s1)
1730 int dynindex, index;
1731 const char *name;
1732 ElfW(Sym) *sym;
1734 for_each_elem(symtab_section, 1, sym, ElfW(Sym)) {
1735 if (ELFW(ST_BIND)(sym->st_info) != STB_LOCAL) {
1736 name = (char *) symtab_section->link->data + sym->st_name;
1737 dynindex = put_elf_sym(s1->dynsym, sym->st_value, sym->st_size,
1738 sym->st_info, 0, sym->st_shndx, name);
1739 index = sym - (ElfW(Sym) *) symtab_section->data;
1740 get_sym_attr(s1, index, 1)->dyn_index = dynindex;
1744 #endif
1746 /* Allocate strings for section names and decide if an unallocated section
1747 should be output.
1748 NOTE: the strsec section comes last, so its size is also correct ! */
1749 static int alloc_sec_names(TCCState *s1, int file_type, Section *strsec)
1751 int i;
1752 Section *s;
1753 int textrel = 0;
1755 /* Allocate strings for section names */
1756 for(i = 1; i < s1->nb_sections; i++) {
1757 s = s1->sections[i];
1758 /* when generating a DLL, we include relocations but we may
1759 patch them */
1760 #ifndef ELF_OBJ_ONLY
1761 if (file_type == TCC_OUTPUT_DLL &&
1762 s->sh_type == SHT_RELX &&
1763 !(s->sh_flags & SHF_ALLOC) &&
1764 (s1->sections[s->sh_info]->sh_flags & SHF_ALLOC) &&
1765 prepare_dynamic_rel(s1, s)) {
1766 if (!(s1->sections[s->sh_info]->sh_flags & SHF_WRITE))
1767 textrel = 1;
1768 } else
1769 #endif
1770 if ((s1->do_debug && s->sh_type != SHT_RELX) ||
1771 file_type == TCC_OUTPUT_OBJ ||
1772 (s->sh_flags & SHF_ALLOC) ||
1773 i == (s1->nb_sections - 1)) {
1774 /* we output all sections if debug or object file */
1775 s->sh_size = s->data_offset;
1777 if (s->sh_size || (s->sh_flags & SHF_ALLOC))
1778 s->sh_name = put_elf_str(strsec, s->name);
1780 strsec->sh_size = strsec->data_offset;
1781 return textrel;
1784 /* Info to be copied in dynamic section */
1785 struct dyn_inf {
1786 Section *dynamic;
1787 Section *dynstr;
1788 unsigned long data_offset;
1789 addr_t rel_addr;
1790 addr_t rel_size;
1791 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
1792 addr_t bss_addr;
1793 addr_t bss_size;
1794 #endif
1797 /* Assign sections to segments and decide how are sections laid out when loaded
1798 in memory. This function also fills corresponding program headers. */
1799 static int layout_sections(TCCState *s1, ElfW(Phdr) *phdr, int phnum,
1800 Section *interp, Section* strsec,
1801 struct dyn_inf *dyninf, int *sec_order)
1803 int i, j, k, file_type, sh_order_index, file_offset;
1804 unsigned long s_align;
1805 long long tmp;
1806 addr_t addr;
1807 ElfW(Phdr) *ph;
1808 Section *s;
1810 file_type = s1->output_type;
1811 sh_order_index = 1;
1812 file_offset = 0;
1813 if (s1->output_format == TCC_OUTPUT_FORMAT_ELF)
1814 file_offset = sizeof(ElfW(Ehdr)) + phnum * sizeof(ElfW(Phdr));
1815 s_align = ELF_PAGE_SIZE;
1816 if (s1->section_align)
1817 s_align = s1->section_align;
1819 if (phnum > 0) {
1820 if (s1->has_text_addr) {
1821 int a_offset, p_offset;
1822 addr = s1->text_addr;
1823 /* we ensure that (addr % ELF_PAGE_SIZE) == file_offset %
1824 ELF_PAGE_SIZE */
1825 a_offset = (int) (addr & (s_align - 1));
1826 p_offset = file_offset & (s_align - 1);
1827 if (a_offset < p_offset)
1828 a_offset += s_align;
1829 file_offset += (a_offset - p_offset);
1830 } else {
1831 if (file_type == TCC_OUTPUT_DLL)
1832 addr = 0;
1833 else
1834 addr = ELF_START_ADDR;
1835 /* compute address after headers */
1836 addr += (file_offset & (s_align - 1));
1839 ph = &phdr[0];
1840 /* Leave one program headers for the program interpreter and one for
1841 the program header table itself if needed. These are done later as
1842 they require section layout to be done first. */
1843 if (interp)
1844 ph += 2;
1846 /* dynamic relocation table information, for .dynamic section */
1847 dyninf->rel_addr = dyninf->rel_size = 0;
1848 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
1849 dyninf->bss_addr = dyninf->bss_size = 0;
1850 #endif
1852 for(j = 0; j < 2; j++) {
1853 ph->p_type = PT_LOAD;
1854 if (j == 0)
1855 ph->p_flags = PF_R | PF_X;
1856 else
1857 ph->p_flags = PF_R | PF_W;
1858 ph->p_align = s_align;
1860 /* Decide the layout of sections loaded in memory. This must
1861 be done before program headers are filled since they contain
1862 info about the layout. We do the following ordering: interp,
1863 symbol tables, relocations, progbits, nobits */
1864 /* XXX: do faster and simpler sorting */
1865 for(k = 0; k < 5; k++) {
1866 for(i = 1; i < s1->nb_sections; i++) {
1867 s = s1->sections[i];
1868 /* compute if section should be included */
1869 if (j == 0) {
1870 if ((s->sh_flags & (SHF_ALLOC | SHF_WRITE)) !=
1871 SHF_ALLOC)
1872 continue;
1873 } else {
1874 if ((s->sh_flags & (SHF_ALLOC | SHF_WRITE)) !=
1875 (SHF_ALLOC | SHF_WRITE))
1876 continue;
1878 if (s == interp) {
1879 if (k != 0)
1880 continue;
1881 } else if ((s->sh_type == SHT_DYNSYM ||
1882 s->sh_type == SHT_STRTAB ||
1883 s->sh_type == SHT_HASH)
1884 && !strstr(s->name, ".stab")) {
1885 if (k != 1)
1886 continue;
1887 } else if (s->sh_type == SHT_RELX) {
1888 if (k != 2)
1889 continue;
1890 } else if (s->sh_type == SHT_NOBITS) {
1891 if (k != 4)
1892 continue;
1893 } else {
1894 if (k != 3)
1895 continue;
1897 sec_order[sh_order_index++] = i;
1899 /* section matches: we align it and add its size */
1900 tmp = addr;
1901 addr = (addr + s->sh_addralign - 1) &
1902 ~(s->sh_addralign - 1);
1903 file_offset += (int) ( addr - tmp );
1904 s->sh_offset = file_offset;
1905 s->sh_addr = addr;
1907 /* update program header infos */
1908 if (ph->p_offset == 0) {
1909 ph->p_offset = file_offset;
1910 ph->p_vaddr = addr;
1911 ph->p_paddr = ph->p_vaddr;
1913 /* update dynamic relocation infos */
1914 if (s->sh_type == SHT_RELX) {
1915 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
1916 if (!strcmp(strsec->data + s->sh_name, ".rel.got")) {
1917 dyninf->rel_addr = addr;
1918 dyninf->rel_size += s->sh_size; /* XXX only first rel. */
1920 if (!strcmp(strsec->data + s->sh_name, ".rel.bss")) {
1921 dyninf->bss_addr = addr;
1922 dyninf->bss_size = s->sh_size; /* XXX only first rel. */
1924 #else
1925 if (dyninf->rel_size == 0)
1926 dyninf->rel_addr = addr;
1927 dyninf->rel_size += s->sh_size;
1928 #endif
1930 addr += s->sh_size;
1931 if (s->sh_type != SHT_NOBITS)
1932 file_offset += s->sh_size;
1935 if (j == 0) {
1936 /* Make the first PT_LOAD segment include the program
1937 headers itself (and the ELF header as well), it'll
1938 come out with same memory use but will make various
1939 tools like binutils strip work better. */
1940 ph->p_offset &= ~(ph->p_align - 1);
1941 ph->p_vaddr &= ~(ph->p_align - 1);
1942 ph->p_paddr &= ~(ph->p_align - 1);
1944 ph->p_filesz = file_offset - ph->p_offset;
1945 ph->p_memsz = addr - ph->p_vaddr;
1946 ph++;
1947 if (j == 0) {
1948 if (s1->output_format == TCC_OUTPUT_FORMAT_ELF) {
1949 /* if in the middle of a page, we duplicate the page in
1950 memory so that one copy is RX and the other is RW */
1951 if ((addr & (s_align - 1)) != 0)
1952 addr += s_align;
1953 } else {
1954 addr = (addr + s_align - 1) & ~(s_align - 1);
1955 file_offset = (file_offset + s_align - 1) & ~(s_align - 1);
1961 /* all other sections come after */
1962 for(i = 1; i < s1->nb_sections; i++) {
1963 s = s1->sections[i];
1964 if (phnum > 0 && (s->sh_flags & SHF_ALLOC))
1965 continue;
1966 sec_order[sh_order_index++] = i;
1968 file_offset = (file_offset + s->sh_addralign - 1) &
1969 ~(s->sh_addralign - 1);
1970 s->sh_offset = file_offset;
1971 if (s->sh_type != SHT_NOBITS)
1972 file_offset += s->sh_size;
1975 return file_offset;
1978 #ifndef ELF_OBJ_ONLY
1979 static void fill_unloadable_phdr(ElfW(Phdr) *phdr, int phnum, Section *interp,
1980 Section *dynamic)
1982 ElfW(Phdr) *ph;
1984 /* if interpreter, then add corresponding program header */
1985 if (interp) {
1986 ph = &phdr[0];
1988 ph->p_type = PT_PHDR;
1989 ph->p_offset = sizeof(ElfW(Ehdr));
1990 ph->p_filesz = ph->p_memsz = phnum * sizeof(ElfW(Phdr));
1991 ph->p_vaddr = interp->sh_addr - ph->p_filesz;
1992 ph->p_paddr = ph->p_vaddr;
1993 ph->p_flags = PF_R | PF_X;
1994 ph->p_align = 4; /* interp->sh_addralign; */
1995 ph++;
1997 ph->p_type = PT_INTERP;
1998 ph->p_offset = interp->sh_offset;
1999 ph->p_vaddr = interp->sh_addr;
2000 ph->p_paddr = ph->p_vaddr;
2001 ph->p_filesz = interp->sh_size;
2002 ph->p_memsz = interp->sh_size;
2003 ph->p_flags = PF_R;
2004 ph->p_align = interp->sh_addralign;
2007 /* if dynamic section, then add corresponding program header */
2008 if (dynamic) {
2009 ph = &phdr[phnum - 1];
2011 ph->p_type = PT_DYNAMIC;
2012 ph->p_offset = dynamic->sh_offset;
2013 ph->p_vaddr = dynamic->sh_addr;
2014 ph->p_paddr = ph->p_vaddr;
2015 ph->p_filesz = dynamic->sh_size;
2016 ph->p_memsz = dynamic->sh_size;
2017 ph->p_flags = PF_R | PF_W;
2018 ph->p_align = dynamic->sh_addralign;
2022 /* Fill the dynamic section with tags describing the address and size of
2023 sections */
2024 static void fill_dynamic(TCCState *s1, struct dyn_inf *dyninf)
2026 Section *dynamic = dyninf->dynamic;
2027 Section *s;
2029 /* put dynamic section entries */
2030 put_dt(dynamic, DT_HASH, s1->dynsym->hash->sh_addr);
2031 put_dt(dynamic, DT_STRTAB, dyninf->dynstr->sh_addr);
2032 put_dt(dynamic, DT_SYMTAB, s1->dynsym->sh_addr);
2033 put_dt(dynamic, DT_STRSZ, dyninf->dynstr->data_offset);
2034 put_dt(dynamic, DT_SYMENT, sizeof(ElfW(Sym)));
2035 #if PTR_SIZE == 8
2036 put_dt(dynamic, DT_RELA, dyninf->rel_addr);
2037 put_dt(dynamic, DT_RELASZ, dyninf->rel_size);
2038 put_dt(dynamic, DT_RELAENT, sizeof(ElfW_Rel));
2039 #else
2040 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
2041 put_dt(dynamic, DT_PLTGOT, s1->got->sh_addr);
2042 put_dt(dynamic, DT_PLTRELSZ, dyninf->rel_size);
2043 put_dt(dynamic, DT_JMPREL, dyninf->rel_addr);
2044 put_dt(dynamic, DT_PLTREL, DT_REL);
2045 put_dt(dynamic, DT_REL, dyninf->bss_addr);
2046 put_dt(dynamic, DT_RELSZ, dyninf->bss_size);
2047 #else
2048 put_dt(dynamic, DT_REL, dyninf->rel_addr);
2049 put_dt(dynamic, DT_RELSZ, dyninf->rel_size);
2050 put_dt(dynamic, DT_RELENT, sizeof(ElfW_Rel));
2051 #endif
2052 #endif
2053 if (versym_section)
2054 put_dt(dynamic, DT_VERSYM, versym_section->sh_addr);
2055 if (verneed_section) {
2056 put_dt(dynamic, DT_VERNEED, verneed_section->sh_addr);
2057 put_dt(dynamic, DT_VERNEEDNUM, dt_verneednum);
2059 s = find_section_create (s1, ".preinit_array", 0);
2060 if (s && s->data_offset) {
2061 put_dt(dynamic, DT_PREINIT_ARRAY, s->sh_addr);
2062 put_dt(dynamic, DT_PREINIT_ARRAYSZ, s->data_offset);
2064 s = find_section_create (s1, ".init_array", 0);
2065 if (s && s->data_offset) {
2066 put_dt(dynamic, DT_INIT_ARRAY, s->sh_addr);
2067 put_dt(dynamic, DT_INIT_ARRAYSZ, s->data_offset);
2069 s = find_section_create (s1, ".fini_array", 0);
2070 if (s && s->data_offset) {
2071 put_dt(dynamic, DT_FINI_ARRAY, s->sh_addr);
2072 put_dt(dynamic, DT_FINI_ARRAYSZ, s->data_offset);
2074 s = find_section_create (s1, ".init", 0);
2075 if (s && s->data_offset) {
2076 put_dt(dynamic, DT_INIT, s->sh_addr);
2078 s = find_section_create (s1, ".fini", 0);
2079 if (s && s->data_offset) {
2080 put_dt(dynamic, DT_FINI, s->sh_addr);
2082 if (s1->do_debug)
2083 put_dt(dynamic, DT_DEBUG, 0);
2084 put_dt(dynamic, DT_NULL, 0);
2087 /* Relocate remaining sections and symbols (that is those not related to
2088 dynamic linking) */
2089 static int final_sections_reloc(TCCState *s1)
2091 int i;
2092 Section *s;
2094 relocate_syms(s1, s1->symtab, 0);
2096 if (s1->nb_errors != 0)
2097 return -1;
2099 /* relocate sections */
2100 /* XXX: ignore sections with allocated relocations ? */
2101 for(i = 1; i < s1->nb_sections; i++) {
2102 s = s1->sections[i];
2103 if (s->reloc && (s != s1->got || s1->static_link))
2104 relocate_section(s1, s);
2107 /* relocate relocation entries if the relocation tables are
2108 allocated in the executable */
2109 for(i = 1; i < s1->nb_sections; i++) {
2110 s = s1->sections[i];
2111 if ((s->sh_flags & SHF_ALLOC) &&
2112 s->sh_type == SHT_RELX) {
2113 relocate_rel(s1, s);
2116 return 0;
2118 #endif
2120 /* Create an ELF file on disk.
2121 This function handle ELF specific layout requirements */
2122 static void tcc_output_elf(TCCState *s1, FILE *f, int phnum, ElfW(Phdr) *phdr,
2123 int file_offset, int *sec_order)
2125 int i, shnum, offset, size, file_type;
2126 Section *s;
2127 ElfW(Ehdr) ehdr;
2128 ElfW(Shdr) shdr, *sh;
2130 file_type = s1->output_type;
2131 shnum = s1->nb_sections;
2133 memset(&ehdr, 0, sizeof(ehdr));
2135 if (phnum > 0) {
2136 ehdr.e_phentsize = sizeof(ElfW(Phdr));
2137 ehdr.e_phnum = phnum;
2138 ehdr.e_phoff = sizeof(ElfW(Ehdr));
2141 /* align to 4 */
2142 file_offset = (file_offset + 3) & -4;
2144 /* fill header */
2145 ehdr.e_ident[0] = ELFMAG0;
2146 ehdr.e_ident[1] = ELFMAG1;
2147 ehdr.e_ident[2] = ELFMAG2;
2148 ehdr.e_ident[3] = ELFMAG3;
2149 ehdr.e_ident[4] = ELFCLASSW;
2150 ehdr.e_ident[5] = ELFDATA2LSB;
2151 ehdr.e_ident[6] = EV_CURRENT;
2152 #if !defined(TCC_TARGET_PE) && (defined(__FreeBSD__) || defined(__FreeBSD_kernel__))
2153 /* FIXME: should set only for freebsd _target_, but we exclude only PE target */
2154 ehdr.e_ident[EI_OSABI] = ELFOSABI_FREEBSD;
2155 #endif
2156 #ifdef TCC_TARGET_ARM
2157 #ifdef TCC_ARM_EABI
2158 ehdr.e_ident[EI_OSABI] = 0;
2159 ehdr.e_flags = EF_ARM_EABI_VER4;
2160 if (file_type == TCC_OUTPUT_EXE || file_type == TCC_OUTPUT_DLL)
2161 ehdr.e_flags |= EF_ARM_HASENTRY;
2162 if (s1->float_abi == ARM_HARD_FLOAT)
2163 ehdr.e_flags |= EF_ARM_VFP_FLOAT;
2164 else
2165 ehdr.e_flags |= EF_ARM_SOFT_FLOAT;
2166 #else
2167 ehdr.e_ident[EI_OSABI] = ELFOSABI_ARM;
2168 #endif
2169 #elif defined TCC_TARGET_RISCV64
2170 ehdr.e_flags = EF_RISCV_FLOAT_ABI_DOUBLE;
2171 #endif
2172 switch(file_type) {
2173 default:
2174 case TCC_OUTPUT_EXE:
2175 ehdr.e_type = ET_EXEC;
2176 ehdr.e_entry = get_elf_sym_addr(s1, "_start", 1);
2177 break;
2178 case TCC_OUTPUT_DLL:
2179 ehdr.e_type = ET_DYN;
2180 ehdr.e_entry = text_section->sh_addr; /* XXX: is it correct ? */
2181 break;
2182 case TCC_OUTPUT_OBJ:
2183 ehdr.e_type = ET_REL;
2184 break;
2186 ehdr.e_machine = EM_TCC_TARGET;
2187 ehdr.e_version = EV_CURRENT;
2188 ehdr.e_shoff = file_offset;
2189 ehdr.e_ehsize = sizeof(ElfW(Ehdr));
2190 ehdr.e_shentsize = sizeof(ElfW(Shdr));
2191 ehdr.e_shnum = shnum;
2192 ehdr.e_shstrndx = shnum - 1;
2194 fwrite(&ehdr, 1, sizeof(ElfW(Ehdr)), f);
2195 fwrite(phdr, 1, phnum * sizeof(ElfW(Phdr)), f);
2196 offset = sizeof(ElfW(Ehdr)) + phnum * sizeof(ElfW(Phdr));
2198 sort_syms(s1, symtab_section);
2199 for(i = 1; i < s1->nb_sections; i++) {
2200 s = s1->sections[sec_order[i]];
2201 if (s->sh_type != SHT_NOBITS) {
2202 while (offset < s->sh_offset) {
2203 fputc(0, f);
2204 offset++;
2206 size = s->sh_size;
2207 if (size)
2208 fwrite(s->data, 1, size, f);
2209 offset += size;
2213 /* output section headers */
2214 while (offset < ehdr.e_shoff) {
2215 fputc(0, f);
2216 offset++;
2219 for(i = 0; i < s1->nb_sections; i++) {
2220 sh = &shdr;
2221 memset(sh, 0, sizeof(ElfW(Shdr)));
2222 s = s1->sections[i];
2223 if (s) {
2224 sh->sh_name = s->sh_name;
2225 sh->sh_type = s->sh_type;
2226 sh->sh_flags = s->sh_flags;
2227 sh->sh_entsize = s->sh_entsize;
2228 sh->sh_info = s->sh_info;
2229 if (s->link)
2230 sh->sh_link = s->link->sh_num;
2231 sh->sh_addralign = s->sh_addralign;
2232 sh->sh_addr = s->sh_addr;
2233 sh->sh_offset = s->sh_offset;
2234 sh->sh_size = s->sh_size;
2236 fwrite(sh, 1, sizeof(ElfW(Shdr)), f);
2240 /* Write an elf, coff or "binary" file */
2241 static int tcc_write_elf_file(TCCState *s1, const char *filename, int phnum,
2242 ElfW(Phdr) *phdr, int file_offset, int *sec_order)
2244 int fd, mode, file_type;
2245 FILE *f;
2247 file_type = s1->output_type;
2248 if (file_type == TCC_OUTPUT_OBJ)
2249 mode = 0666;
2250 else
2251 mode = 0777;
2252 unlink(filename);
2253 fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, mode);
2254 if (fd < 0) {
2255 tcc_error_noabort("could not write '%s'", filename);
2256 return -1;
2258 f = fdopen(fd, "wb");
2259 if (s1->verbose)
2260 printf("<- %s\n", filename);
2262 #ifdef TCC_TARGET_COFF
2263 if (s1->output_format == TCC_OUTPUT_FORMAT_COFF)
2264 tcc_output_coff(s1, f);
2265 else
2266 #endif
2267 if (s1->output_format == TCC_OUTPUT_FORMAT_ELF)
2268 tcc_output_elf(s1, f, phnum, phdr, file_offset, sec_order);
2269 else
2270 tcc_output_binary(s1, f, sec_order);
2271 fclose(f);
2273 return 0;
2276 #ifndef ELF_OBJ_ONLY
2277 /* Sort section headers by assigned sh_addr, remove sections
2278 that we aren't going to output. */
2279 static void tidy_section_headers(TCCState *s1, int *sec_order)
2281 int i, nnew, l, *backmap;
2282 Section **snew, *s;
2283 ElfW(Sym) *sym;
2285 snew = tcc_malloc(s1->nb_sections * sizeof(snew[0]));
2286 backmap = tcc_malloc(s1->nb_sections * sizeof(backmap[0]));
2287 for (i = 0, nnew = 0, l = s1->nb_sections; i < s1->nb_sections; i++) {
2288 s = s1->sections[sec_order[i]];
2289 if (!i || s->sh_name) {
2290 backmap[sec_order[i]] = nnew;
2291 snew[nnew] = s;
2292 ++nnew;
2293 } else {
2294 backmap[sec_order[i]] = 0;
2295 snew[--l] = s;
2298 for (i = 0; i < nnew; i++) {
2299 s = snew[i];
2300 if (s) {
2301 s->sh_num = i;
2302 if (s->sh_type == SHT_RELX)
2303 s->sh_info = backmap[s->sh_info];
2307 for_each_elem(symtab_section, 1, sym, ElfW(Sym))
2308 if (sym->st_shndx != SHN_UNDEF && sym->st_shndx < SHN_LORESERVE)
2309 sym->st_shndx = backmap[sym->st_shndx];
2310 if( !s1->static_link ) {
2311 for_each_elem(s1->dynsym, 1, sym, ElfW(Sym))
2312 if (sym->st_shndx != SHN_UNDEF && sym->st_shndx < SHN_LORESERVE)
2313 sym->st_shndx = backmap[sym->st_shndx];
2315 for (i = 0; i < s1->nb_sections; i++)
2316 sec_order[i] = i;
2317 tcc_free(s1->sections);
2318 s1->sections = snew;
2319 s1->nb_sections = nnew;
2320 tcc_free(backmap);
2322 #endif
2324 /* Output an elf, coff or binary file */
2325 /* XXX: suppress unneeded sections */
2326 static int elf_output_file(TCCState *s1, const char *filename)
2328 int ret, phnum, shnum, file_type, file_offset, *sec_order;
2329 struct dyn_inf dyninf = {0};
2330 ElfW(Phdr) *phdr;
2331 Section *strsec, *interp, *dynamic, *dynstr;
2333 file_type = s1->output_type;
2334 s1->nb_errors = 0;
2335 ret = -1;
2336 phdr = NULL;
2337 sec_order = NULL;
2338 interp = dynamic = dynstr = NULL; /* avoid warning */
2340 #ifndef ELF_OBJ_ONLY
2341 if (file_type != TCC_OUTPUT_OBJ) {
2342 /* if linking, also link in runtime libraries (libc, libgcc, etc.) */
2343 tcc_add_runtime(s1);
2344 resolve_common_syms(s1);
2346 if (!s1->static_link) {
2347 if (file_type == TCC_OUTPUT_EXE) {
2348 char *ptr;
2349 /* allow override the dynamic loader */
2350 const char *elfint = getenv("LD_SO");
2351 if (elfint == NULL)
2352 elfint = DEFAULT_ELFINTERP(s1);
2353 /* add interpreter section only if executable */
2354 interp = new_section(s1, ".interp", SHT_PROGBITS, SHF_ALLOC);
2355 interp->sh_addralign = 1;
2356 ptr = section_ptr_add(interp, 1 + strlen(elfint));
2357 strcpy(ptr, elfint);
2360 /* add dynamic symbol table */
2361 s1->dynsym = new_symtab(s1, ".dynsym", SHT_DYNSYM, SHF_ALLOC,
2362 ".dynstr",
2363 ".hash", SHF_ALLOC);
2364 dynstr = s1->dynsym->link;
2365 /* add dynamic section */
2366 dynamic = new_section(s1, ".dynamic", SHT_DYNAMIC,
2367 SHF_ALLOC | SHF_WRITE);
2368 dynamic->link = dynstr;
2369 dynamic->sh_entsize = sizeof(ElfW(Dyn));
2371 build_got(s1);
2373 if (file_type == TCC_OUTPUT_EXE) {
2374 bind_exe_dynsyms(s1);
2375 if (s1->nb_errors)
2376 goto the_end;
2377 bind_libs_dynsyms(s1);
2378 } else {
2379 /* shared library case: simply export all global symbols */
2380 export_global_syms(s1);
2383 build_got_entries(s1);
2384 version_add (s1);
2386 #endif
2388 /* we add a section for symbols */
2389 strsec = new_section(s1, ".shstrtab", SHT_STRTAB, 0);
2390 put_elf_str(strsec, "");
2392 /* Allocate strings for section names */
2393 ret = alloc_sec_names(s1, file_type, strsec);
2395 #ifndef ELF_OBJ_ONLY
2396 if (dynamic) {
2397 int i;
2398 /* add a list of needed dlls */
2399 for(i = 0; i < s1->nb_loaded_dlls; i++) {
2400 DLLReference *dllref = s1->loaded_dlls[i];
2401 if (dllref->level == 0)
2402 put_dt(dynamic, DT_NEEDED, put_elf_str(dynstr, dllref->name));
2405 if (s1->rpath)
2406 put_dt(dynamic, s1->enable_new_dtags ? DT_RUNPATH : DT_RPATH,
2407 put_elf_str(dynstr, s1->rpath));
2409 if (file_type == TCC_OUTPUT_DLL) {
2410 if (s1->soname)
2411 put_dt(dynamic, DT_SONAME, put_elf_str(dynstr, s1->soname));
2412 /* XXX: currently, since we do not handle PIC code, we
2413 must relocate the readonly segments */
2414 if (ret)
2415 put_dt(dynamic, DT_TEXTREL, 0);
2418 if (s1->symbolic)
2419 put_dt(dynamic, DT_SYMBOLIC, 0);
2421 dyninf.dynamic = dynamic;
2422 dyninf.dynstr = dynstr;
2423 /* remember offset and reserve space for 2nd call below */
2424 dyninf.data_offset = dynamic->data_offset;
2425 fill_dynamic(s1, &dyninf);
2426 dynamic->sh_size = dynamic->data_offset;
2427 dynstr->sh_size = dynstr->data_offset;
2429 #endif
2431 /* compute number of program headers */
2432 if (file_type == TCC_OUTPUT_OBJ)
2433 phnum = 0;
2434 else if (file_type == TCC_OUTPUT_DLL)
2435 phnum = 3;
2436 else if (s1->static_link)
2437 phnum = 2;
2438 else
2439 phnum = 5;
2441 /* allocate program segment headers */
2442 phdr = tcc_mallocz(phnum * sizeof(ElfW(Phdr)));
2444 /* compute number of sections */
2445 shnum = s1->nb_sections;
2447 /* this array is used to reorder sections in the output file */
2448 sec_order = tcc_malloc(sizeof(int) * shnum);
2449 sec_order[0] = 0;
2451 /* compute section to program header mapping */
2452 file_offset = layout_sections(s1, phdr, phnum, interp, strsec, &dyninf,
2453 sec_order);
2455 #ifndef ELF_OBJ_ONLY
2456 /* Fill remaining program header and finalize relocation related to dynamic
2457 linking. */
2458 if (file_type != TCC_OUTPUT_OBJ) {
2459 fill_unloadable_phdr(phdr, phnum, interp, dynamic);
2460 if (dynamic) {
2461 ElfW(Sym) *sym;
2462 dynamic->data_offset = dyninf.data_offset;
2463 fill_dynamic(s1, &dyninf);
2465 /* put in GOT the dynamic section address and relocate PLT */
2466 write32le(s1->got->data, dynamic->sh_addr);
2467 if (file_type == TCC_OUTPUT_EXE
2468 || (RELOCATE_DLLPLT && file_type == TCC_OUTPUT_DLL))
2469 relocate_plt(s1);
2471 /* relocate symbols in .dynsym now that final addresses are known */
2472 for_each_elem(s1->dynsym, 1, sym, ElfW(Sym)) {
2473 if (sym->st_shndx != SHN_UNDEF && sym->st_shndx < SHN_LORESERVE) {
2474 /* do symbol relocation */
2475 sym->st_value += s1->sections[sym->st_shndx]->sh_addr;
2480 /* if building executable or DLL, then relocate each section
2481 except the GOT which is already relocated */
2482 ret = final_sections_reloc(s1);
2483 if (ret)
2484 goto the_end;
2485 tidy_section_headers(s1, sec_order);
2487 /* Perform relocation to GOT or PLT entries */
2488 if (file_type == TCC_OUTPUT_EXE && s1->static_link)
2489 fill_got(s1);
2490 else if (s1->got)
2491 fill_local_got_entries(s1);
2493 #endif
2495 /* Create the ELF file with name 'filename' */
2496 ret = tcc_write_elf_file(s1, filename, phnum, phdr, file_offset, sec_order);
2497 s1->nb_sections = shnum;
2498 goto the_end;
2499 the_end:
2500 tcc_free(sec_order);
2501 tcc_free(phdr);
2502 return ret;
2505 LIBTCCAPI int tcc_output_file(TCCState *s, const char *filename)
2507 int ret;
2508 #ifdef TCC_TARGET_PE
2509 if (s->output_type != TCC_OUTPUT_OBJ) {
2510 ret = pe_output_file(s, filename);
2511 } else
2512 #endif
2513 ret = elf_output_file(s, filename);
2514 return ret;
2517 ssize_t full_read(int fd, void *buf, size_t count) {
2518 char *cbuf = buf;
2519 size_t rnum = 0;
2520 while (1) {
2521 ssize_t num = read(fd, cbuf, count-rnum);
2522 if (num < 0) return num;
2523 if (num == 0) return rnum;
2524 rnum += num;
2525 cbuf += num;
2529 static void *load_data(int fd, unsigned long file_offset, unsigned long size)
2531 void *data;
2533 data = tcc_malloc(size);
2534 lseek(fd, file_offset, SEEK_SET);
2535 full_read(fd, data, size);
2536 return data;
2539 typedef struct SectionMergeInfo {
2540 Section *s; /* corresponding existing section */
2541 unsigned long offset; /* offset of the new section in the existing section */
2542 uint8_t new_section; /* true if section 's' was added */
2543 uint8_t link_once; /* true if link once section */
2544 } SectionMergeInfo;
2546 ST_FUNC int tcc_object_type(int fd, ElfW(Ehdr) *h)
2548 int size = full_read(fd, h, sizeof *h);
2549 if (size == sizeof *h && 0 == memcmp(h, ELFMAG, 4)) {
2550 if (h->e_type == ET_REL)
2551 return AFF_BINTYPE_REL;
2552 if (h->e_type == ET_DYN)
2553 return AFF_BINTYPE_DYN;
2554 } else if (size >= 8) {
2555 if (0 == memcmp(h, ARMAG, 8))
2556 return AFF_BINTYPE_AR;
2557 #ifdef TCC_TARGET_COFF
2558 if (((struct filehdr*)h)->f_magic == COFF_C67_MAGIC)
2559 return AFF_BINTYPE_C67;
2560 #endif
2562 return 0;
2565 /* load an object file and merge it with current files */
2566 /* XXX: handle correctly stab (debug) info */
2567 ST_FUNC int tcc_load_object_file(TCCState *s1,
2568 int fd, unsigned long file_offset)
2570 ElfW(Ehdr) ehdr;
2571 ElfW(Shdr) *shdr, *sh;
2572 int size, i, j, offset, offseti, nb_syms, sym_index, ret, seencompressed;
2573 char *strsec, *strtab;
2574 int stab_index, stabstr_index;
2575 int *old_to_new_syms;
2576 char *sh_name, *name;
2577 SectionMergeInfo *sm_table, *sm;
2578 ElfW(Sym) *sym, *symtab;
2579 ElfW_Rel *rel;
2580 Section *s;
2582 lseek(fd, file_offset, SEEK_SET);
2583 if (tcc_object_type(fd, &ehdr) != AFF_BINTYPE_REL)
2584 goto fail1;
2585 /* test CPU specific stuff */
2586 if (ehdr.e_ident[5] != ELFDATA2LSB ||
2587 ehdr.e_machine != EM_TCC_TARGET) {
2588 fail1:
2589 tcc_error_noabort("invalid object file");
2590 return -1;
2592 /* read sections */
2593 shdr = load_data(fd, file_offset + ehdr.e_shoff,
2594 sizeof(ElfW(Shdr)) * ehdr.e_shnum);
2595 sm_table = tcc_mallocz(sizeof(SectionMergeInfo) * ehdr.e_shnum);
2597 /* load section names */
2598 sh = &shdr[ehdr.e_shstrndx];
2599 strsec = load_data(fd, file_offset + sh->sh_offset, sh->sh_size);
2601 /* load symtab and strtab */
2602 old_to_new_syms = NULL;
2603 symtab = NULL;
2604 strtab = NULL;
2605 nb_syms = 0;
2606 seencompressed = 0;
2607 stab_index = stabstr_index = 0;
2609 for(i = 1; i < ehdr.e_shnum; i++) {
2610 sh = &shdr[i];
2611 if (sh->sh_type == SHT_SYMTAB) {
2612 if (symtab) {
2613 tcc_error_noabort("object must contain only one symtab");
2614 fail:
2615 ret = -1;
2616 goto the_end;
2618 nb_syms = sh->sh_size / sizeof(ElfW(Sym));
2619 symtab = load_data(fd, file_offset + sh->sh_offset, sh->sh_size);
2620 sm_table[i].s = symtab_section;
2622 /* now load strtab */
2623 sh = &shdr[sh->sh_link];
2624 strtab = load_data(fd, file_offset + sh->sh_offset, sh->sh_size);
2626 if (sh->sh_flags & SHF_COMPRESSED)
2627 seencompressed = 1;
2630 /* now examine each section and try to merge its content with the
2631 ones in memory */
2632 for(i = 1; i < ehdr.e_shnum; i++) {
2633 /* no need to examine section name strtab */
2634 if (i == ehdr.e_shstrndx)
2635 continue;
2636 sh = &shdr[i];
2637 if (sh->sh_type == SHT_RELX)
2638 sh = &shdr[sh->sh_info];
2639 /* ignore sections types we do not handle (plus relocs to those) */
2640 if (sh->sh_type != SHT_PROGBITS &&
2641 #ifdef TCC_ARM_EABI
2642 sh->sh_type != SHT_ARM_EXIDX &&
2643 #endif
2644 sh->sh_type != SHT_NOBITS &&
2645 sh->sh_type != SHT_PREINIT_ARRAY &&
2646 sh->sh_type != SHT_INIT_ARRAY &&
2647 sh->sh_type != SHT_FINI_ARRAY &&
2648 strcmp(strsec + sh->sh_name, ".stabstr")
2650 continue;
2651 if (seencompressed
2652 && !strncmp(strsec + sh->sh_name, ".debug_", sizeof(".debug_")-1))
2653 continue;
2655 sh = &shdr[i];
2656 sh_name = strsec + sh->sh_name;
2657 if (sh->sh_addralign < 1)
2658 sh->sh_addralign = 1;
2659 /* find corresponding section, if any */
2660 for(j = 1; j < s1->nb_sections;j++) {
2661 s = s1->sections[j];
2662 if (!strcmp(s->name, sh_name)) {
2663 if (!strncmp(sh_name, ".gnu.linkonce",
2664 sizeof(".gnu.linkonce") - 1)) {
2665 /* if a 'linkonce' section is already present, we
2666 do not add it again. It is a little tricky as
2667 symbols can still be defined in
2668 it. */
2669 sm_table[i].link_once = 1;
2670 goto next;
2672 if (stab_section) {
2673 if (s == stab_section)
2674 stab_index = i;
2675 if (s == stab_section->link)
2676 stabstr_index = i;
2678 goto found;
2681 /* not found: create new section */
2682 s = new_section(s1, sh_name, sh->sh_type, sh->sh_flags & ~SHF_GROUP);
2683 /* take as much info as possible from the section. sh_link and
2684 sh_info will be updated later */
2685 s->sh_addralign = sh->sh_addralign;
2686 s->sh_entsize = sh->sh_entsize;
2687 sm_table[i].new_section = 1;
2688 found:
2689 if (sh->sh_type != s->sh_type) {
2690 tcc_error_noabort("invalid section type");
2691 goto fail;
2693 /* align start of section */
2694 s->data_offset += -s->data_offset & (sh->sh_addralign - 1);
2695 if (sh->sh_addralign > s->sh_addralign)
2696 s->sh_addralign = sh->sh_addralign;
2697 sm_table[i].offset = s->data_offset;
2698 sm_table[i].s = s;
2699 /* concatenate sections */
2700 size = sh->sh_size;
2701 if (sh->sh_type != SHT_NOBITS) {
2702 unsigned char *ptr;
2703 lseek(fd, file_offset + sh->sh_offset, SEEK_SET);
2704 ptr = section_ptr_add(s, size);
2705 full_read(fd, ptr, size);
2706 } else {
2707 s->data_offset += size;
2709 next: ;
2712 /* gr relocate stab strings */
2713 if (stab_index && stabstr_index) {
2714 Stab_Sym *a, *b;
2715 unsigned o;
2716 s = sm_table[stab_index].s;
2717 a = (Stab_Sym *)(s->data + sm_table[stab_index].offset);
2718 b = (Stab_Sym *)(s->data + s->data_offset);
2719 o = sm_table[stabstr_index].offset;
2720 while (a < b) {
2721 if (a->n_strx)
2722 a->n_strx += o;
2723 a++;
2727 /* second short pass to update sh_link and sh_info fields of new
2728 sections */
2729 for(i = 1; i < ehdr.e_shnum; i++) {
2730 s = sm_table[i].s;
2731 if (!s || !sm_table[i].new_section)
2732 continue;
2733 sh = &shdr[i];
2734 if (sh->sh_link > 0)
2735 s->link = sm_table[sh->sh_link].s;
2736 if (sh->sh_type == SHT_RELX) {
2737 s->sh_info = sm_table[sh->sh_info].s->sh_num;
2738 /* update backward link */
2739 s1->sections[s->sh_info]->reloc = s;
2743 /* resolve symbols */
2744 old_to_new_syms = tcc_mallocz(nb_syms * sizeof(int));
2746 sym = symtab + 1;
2747 for(i = 1; i < nb_syms; i++, sym++) {
2748 if (sym->st_shndx != SHN_UNDEF &&
2749 sym->st_shndx < SHN_LORESERVE) {
2750 sm = &sm_table[sym->st_shndx];
2751 if (sm->link_once) {
2752 /* if a symbol is in a link once section, we use the
2753 already defined symbol. It is very important to get
2754 correct relocations */
2755 if (ELFW(ST_BIND)(sym->st_info) != STB_LOCAL) {
2756 name = strtab + sym->st_name;
2757 sym_index = find_elf_sym(symtab_section, name);
2758 if (sym_index)
2759 old_to_new_syms[i] = sym_index;
2761 continue;
2763 /* if no corresponding section added, no need to add symbol */
2764 if (!sm->s)
2765 continue;
2766 /* convert section number */
2767 sym->st_shndx = sm->s->sh_num;
2768 /* offset value */
2769 sym->st_value += sm->offset;
2771 /* add symbol */
2772 name = strtab + sym->st_name;
2773 sym_index = set_elf_sym(symtab_section, sym->st_value, sym->st_size,
2774 sym->st_info, sym->st_other,
2775 sym->st_shndx, name);
2776 old_to_new_syms[i] = sym_index;
2779 /* third pass to patch relocation entries */
2780 for(i = 1; i < ehdr.e_shnum; i++) {
2781 s = sm_table[i].s;
2782 if (!s)
2783 continue;
2784 sh = &shdr[i];
2785 offset = sm_table[i].offset;
2786 switch(s->sh_type) {
2787 case SHT_RELX:
2788 /* take relocation offset information */
2789 offseti = sm_table[sh->sh_info].offset;
2790 for_each_elem(s, (offset / sizeof(*rel)), rel, ElfW_Rel) {
2791 int type;
2792 unsigned sym_index;
2793 /* convert symbol index */
2794 type = ELFW(R_TYPE)(rel->r_info);
2795 sym_index = ELFW(R_SYM)(rel->r_info);
2796 /* NOTE: only one symtab assumed */
2797 if (sym_index >= nb_syms)
2798 goto invalid_reloc;
2799 sym_index = old_to_new_syms[sym_index];
2800 /* ignore link_once in rel section. */
2801 if (!sym_index && !sm_table[sh->sh_info].link_once
2802 #ifdef TCC_TARGET_ARM
2803 && type != R_ARM_V4BX
2804 #elif defined TCC_TARGET_RISCV64
2805 && type != R_RISCV_ALIGN
2806 && type != R_RISCV_RELAX
2807 #endif
2809 invalid_reloc:
2810 tcc_error_noabort("Invalid relocation entry [%2d] '%s' @ %.8x",
2811 i, strsec + sh->sh_name, (int)rel->r_offset);
2812 goto fail;
2814 rel->r_info = ELFW(R_INFO)(sym_index, type);
2815 /* offset the relocation offset */
2816 rel->r_offset += offseti;
2817 #ifdef TCC_TARGET_ARM
2818 /* Jumps and branches from a Thumb code to a PLT entry need
2819 special handling since PLT entries are ARM code.
2820 Unconditional bl instructions referencing PLT entries are
2821 handled by converting these instructions into blx
2822 instructions. Other case of instructions referencing a PLT
2823 entry require to add a Thumb stub before the PLT entry to
2824 switch to ARM mode. We set bit plt_thumb_stub of the
2825 attribute of a symbol to indicate such a case. */
2826 if (type == R_ARM_THM_JUMP24)
2827 get_sym_attr(s1, sym_index, 1)->plt_thumb_stub = 1;
2828 #endif
2830 break;
2831 default:
2832 break;
2836 ret = 0;
2837 the_end:
2838 tcc_free(symtab);
2839 tcc_free(strtab);
2840 tcc_free(old_to_new_syms);
2841 tcc_free(sm_table);
2842 tcc_free(strsec);
2843 tcc_free(shdr);
2844 return ret;
2847 typedef struct ArchiveHeader {
2848 char ar_name[16]; /* name of this member */
2849 char ar_date[12]; /* file mtime */
2850 char ar_uid[6]; /* owner uid; printed as decimal */
2851 char ar_gid[6]; /* owner gid; printed as decimal */
2852 char ar_mode[8]; /* file mode, printed as octal */
2853 char ar_size[10]; /* file size, printed as decimal */
2854 char ar_fmag[2]; /* should contain ARFMAG */
2855 } ArchiveHeader;
2857 #define ARFMAG "`\n"
2859 static unsigned long long get_be(const uint8_t *b, int n)
2861 unsigned long long ret = 0;
2862 while (n)
2863 ret = (ret << 8) | *b++, --n;
2864 return ret;
2867 static int read_ar_header(int fd, int offset, ArchiveHeader *hdr)
2869 char *p, *e;
2870 int len;
2871 lseek(fd, offset, SEEK_SET);
2872 len = full_read(fd, hdr, sizeof(ArchiveHeader));
2873 if (len != sizeof(ArchiveHeader))
2874 return len ? -1 : 0;
2875 p = hdr->ar_name;
2876 for (e = p + sizeof hdr->ar_name; e > p && e[-1] == ' ';)
2877 --e;
2878 *e = '\0';
2879 hdr->ar_size[sizeof hdr->ar_size-1] = 0;
2880 return len;
2883 /* load only the objects which resolve undefined symbols */
2884 static int tcc_load_alacarte(TCCState *s1, int fd, int size, int entrysize)
2886 int i, bound, nsyms, sym_index, len, ret = -1;
2887 unsigned long long off;
2888 uint8_t *data;
2889 const char *ar_names, *p;
2890 const uint8_t *ar_index;
2891 ElfW(Sym) *sym;
2892 ArchiveHeader hdr;
2894 data = tcc_malloc(size);
2895 if (full_read(fd, data, size) != size)
2896 goto the_end;
2897 nsyms = get_be(data, entrysize);
2898 ar_index = data + entrysize;
2899 ar_names = (char *) ar_index + nsyms * entrysize;
2901 do {
2902 bound = 0;
2903 for (p = ar_names, i = 0; i < nsyms; i++, p += strlen(p)+1) {
2904 Section *s = symtab_section;
2905 sym_index = find_elf_sym(s, p);
2906 if (!sym_index)
2907 continue;
2908 sym = &((ElfW(Sym) *)s->data)[sym_index];
2909 if(sym->st_shndx != SHN_UNDEF)
2910 continue;
2911 off = get_be(ar_index + i * entrysize, entrysize);
2912 len = read_ar_header(fd, off, &hdr);
2913 if (len <= 0 || memcmp(hdr.ar_fmag, ARFMAG, 2)) {
2914 tcc_error_noabort("invalid archive");
2915 goto the_end;
2917 off += len;
2918 if (s1->verbose == 2)
2919 printf(" -> %s\n", hdr.ar_name);
2920 if (tcc_load_object_file(s1, fd, off) < 0)
2921 goto the_end;
2922 ++bound;
2924 } while(bound);
2925 ret = 0;
2926 the_end:
2927 tcc_free(data);
2928 return ret;
2931 /* load a '.a' file */
2932 ST_FUNC int tcc_load_archive(TCCState *s1, int fd, int alacarte)
2934 ArchiveHeader hdr;
2935 /* char magic[8]; */
2936 int size, len;
2937 unsigned long file_offset;
2938 ElfW(Ehdr) ehdr;
2940 /* skip magic which was already checked */
2941 /* full_read(fd, magic, sizeof(magic)); */
2942 file_offset = sizeof ARMAG - 1;
2944 for(;;) {
2945 len = read_ar_header(fd, file_offset, &hdr);
2946 if (len == 0)
2947 return 0;
2948 if (len < 0) {
2949 tcc_error_noabort("invalid archive");
2950 return -1;
2952 file_offset += len;
2953 size = strtol(hdr.ar_size, NULL, 0);
2954 /* align to even */
2955 size = (size + 1) & ~1;
2956 if (alacarte) {
2957 /* coff symbol table : we handle it */
2958 if (!strcmp(hdr.ar_name, "/"))
2959 return tcc_load_alacarte(s1, fd, size, 4);
2960 if (!strcmp(hdr.ar_name, "/SYM64/"))
2961 return tcc_load_alacarte(s1, fd, size, 8);
2962 } else if (tcc_object_type(fd, &ehdr) == AFF_BINTYPE_REL) {
2963 if (s1->verbose == 2)
2964 printf(" -> %s\n", hdr.ar_name);
2965 if (tcc_load_object_file(s1, fd, file_offset) < 0)
2966 return -1;
2968 file_offset += size;
2972 #ifndef ELF_OBJ_ONLY
2973 /* Set LV[I] to the global index of sym-version (LIB,VERSION). Maybe resizes
2974 LV, maybe create a new entry for (LIB,VERSION). */
2975 static void set_ver_to_ver(TCCState *s1, int *n, int **lv, int i, char *lib, char *version)
2977 while (i >= *n) {
2978 *lv = tcc_realloc(*lv, (*n + 1) * sizeof(**lv));
2979 (*lv)[(*n)++] = -1;
2981 if ((*lv)[i] == -1) {
2982 int v, prev_same_lib = -1;
2983 for (v = 0; v < nb_sym_versions; v++) {
2984 if (strcmp(sym_versions[v].lib, lib))
2985 continue;
2986 prev_same_lib = v;
2987 if (!strcmp(sym_versions[v].version, version))
2988 break;
2990 if (v == nb_sym_versions) {
2991 sym_versions = tcc_realloc (sym_versions,
2992 (v + 1) * sizeof(*sym_versions));
2993 sym_versions[v].lib = tcc_strdup(lib);
2994 sym_versions[v].version = tcc_strdup(version);
2995 sym_versions[v].out_index = 0;
2996 sym_versions[v].prev_same_lib = prev_same_lib;
2997 nb_sym_versions++;
2999 (*lv)[i] = v;
3003 /* Associates symbol SYM_INDEX (in dynsymtab) with sym-version index
3004 VERNDX. */
3005 static void
3006 set_sym_version(TCCState *s1, int sym_index, int verndx)
3008 if (sym_index >= nb_sym_to_version) {
3009 int newelems = sym_index ? sym_index * 2 : 1;
3010 sym_to_version = tcc_realloc(sym_to_version,
3011 newelems * sizeof(*sym_to_version));
3012 memset(sym_to_version + nb_sym_to_version, -1,
3013 (newelems - nb_sym_to_version) * sizeof(*sym_to_version));
3014 nb_sym_to_version = newelems;
3016 if (sym_to_version[sym_index] < 0)
3017 sym_to_version[sym_index] = verndx;
3020 struct versym_info {
3021 int nb_versyms;
3022 ElfW(Verdef) *verdef;
3023 ElfW(Verneed) *verneed;
3024 ElfW(Half) *versym;
3025 int nb_local_ver, *local_ver;
3029 static void store_version(TCCState *s1, struct versym_info *v, char *dynstr)
3031 char *lib, *version;
3032 uint32_t next;
3033 int i;
3035 #define DEBUG_VERSION 0
3037 if (v->versym && v->verdef) {
3038 ElfW(Verdef) *vdef = v->verdef;
3039 lib = NULL;
3040 do {
3041 ElfW(Verdaux) *verdaux =
3042 (ElfW(Verdaux) *) (((char *) vdef) + vdef->vd_aux);
3044 #if DEBUG_VERSION
3045 printf ("verdef: version:%u flags:%u index:%u, hash:%u\n",
3046 vdef->vd_version, vdef->vd_flags, vdef->vd_ndx,
3047 vdef->vd_hash);
3048 #endif
3049 if (vdef->vd_cnt) {
3050 version = dynstr + verdaux->vda_name;
3052 if (lib == NULL)
3053 lib = version;
3054 else
3055 set_ver_to_ver(s1, &v->nb_local_ver, &v->local_ver, vdef->vd_ndx,
3056 lib, version);
3057 #if DEBUG_VERSION
3058 printf (" verdaux(%u): %s\n", vdef->vd_ndx, version);
3059 #endif
3061 next = vdef->vd_next;
3062 vdef = (ElfW(Verdef) *) (((char *) vdef) + next);
3063 } while (next);
3065 if (v->versym && v->verneed) {
3066 ElfW(Verneed) *vneed = v->verneed;
3067 do {
3068 ElfW(Vernaux) *vernaux =
3069 (ElfW(Vernaux) *) (((char *) vneed) + vneed->vn_aux);
3071 lib = dynstr + vneed->vn_file;
3072 #if DEBUG_VERSION
3073 printf ("verneed: %u %s\n", vneed->vn_version, lib);
3074 #endif
3075 for (i = 0; i < vneed->vn_cnt; i++) {
3076 if ((vernaux->vna_other & 0x8000) == 0) { /* hidden */
3077 version = dynstr + vernaux->vna_name;
3078 set_ver_to_ver(s1, &v->nb_local_ver, &v->local_ver, vernaux->vna_other,
3079 lib, version);
3080 #if DEBUG_VERSION
3081 printf (" vernaux(%u): %u %u %s\n",
3082 vernaux->vna_other, vernaux->vna_hash,
3083 vernaux->vna_flags, version);
3084 #endif
3086 vernaux = (ElfW(Vernaux) *) (((char *) vernaux) + vernaux->vna_next);
3088 next = vneed->vn_next;
3089 vneed = (ElfW(Verneed) *) (((char *) vneed) + next);
3090 } while (next);
3093 #if DEBUG_VERSION
3094 for (i = 0; i < v->nb_local_ver; i++) {
3095 if (v->local_ver[i] > 0) {
3096 printf ("%d: lib: %s, version %s\n",
3097 i, sym_versions[v->local_ver[i]].lib,
3098 sym_versions[v->local_ver[i]].version);
3101 #endif
3104 /* load a DLL and all referenced DLLs. 'level = 0' means that the DLL
3105 is referenced by the user (so it should be added as DT_NEEDED in
3106 the generated ELF file) */
3107 ST_FUNC int tcc_load_dll(TCCState *s1, int fd, const char *filename, int level)
3109 ElfW(Ehdr) ehdr;
3110 ElfW(Shdr) *shdr, *sh, *sh1;
3111 int i, j, nb_syms, nb_dts, sym_bind, ret;
3112 ElfW(Sym) *sym, *dynsym;
3113 ElfW(Dyn) *dt, *dynamic;
3115 char *dynstr;
3116 int sym_index;
3117 const char *name, *soname;
3118 DLLReference *dllref;
3119 struct versym_info v;
3121 full_read(fd, &ehdr, sizeof(ehdr));
3123 /* test CPU specific stuff */
3124 if (ehdr.e_ident[5] != ELFDATA2LSB ||
3125 ehdr.e_machine != EM_TCC_TARGET) {
3126 tcc_error_noabort("bad architecture");
3127 return -1;
3130 /* read sections */
3131 shdr = load_data(fd, ehdr.e_shoff, sizeof(ElfW(Shdr)) * ehdr.e_shnum);
3133 /* load dynamic section and dynamic symbols */
3134 nb_syms = 0;
3135 nb_dts = 0;
3136 dynamic = NULL;
3137 dynsym = NULL; /* avoid warning */
3138 dynstr = NULL; /* avoid warning */
3139 memset(&v, 0, sizeof v);
3141 for(i = 0, sh = shdr; i < ehdr.e_shnum; i++, sh++) {
3142 switch(sh->sh_type) {
3143 case SHT_DYNAMIC:
3144 nb_dts = sh->sh_size / sizeof(ElfW(Dyn));
3145 dynamic = load_data(fd, sh->sh_offset, sh->sh_size);
3146 break;
3147 case SHT_DYNSYM:
3148 nb_syms = sh->sh_size / sizeof(ElfW(Sym));
3149 dynsym = load_data(fd, sh->sh_offset, sh->sh_size);
3150 sh1 = &shdr[sh->sh_link];
3151 dynstr = load_data(fd, sh1->sh_offset, sh1->sh_size);
3152 break;
3153 case SHT_GNU_verdef:
3154 v.verdef = load_data(fd, sh->sh_offset, sh->sh_size);
3155 break;
3156 case SHT_GNU_verneed:
3157 v.verneed = load_data(fd, sh->sh_offset, sh->sh_size);
3158 break;
3159 case SHT_GNU_versym:
3160 v.nb_versyms = sh->sh_size / sizeof(ElfW(Half));
3161 v.versym = load_data(fd, sh->sh_offset, sh->sh_size);
3162 break;
3163 default:
3164 break;
3168 /* compute the real library name */
3169 soname = tcc_basename(filename);
3171 for(i = 0, dt = dynamic; i < nb_dts; i++, dt++) {
3172 if (dt->d_tag == DT_SONAME) {
3173 soname = dynstr + dt->d_un.d_val;
3177 /* if the dll is already loaded, do not load it */
3178 for(i = 0; i < s1->nb_loaded_dlls; i++) {
3179 dllref = s1->loaded_dlls[i];
3180 if (!strcmp(soname, dllref->name)) {
3181 /* but update level if needed */
3182 if (level < dllref->level)
3183 dllref->level = level;
3184 ret = 0;
3185 goto the_end;
3189 if (v.nb_versyms != nb_syms)
3190 tcc_free (v.versym), v.versym = NULL;
3191 else
3192 store_version(s1, &v, dynstr);
3194 /* add the dll and its level */
3195 dllref = tcc_mallocz(sizeof(DLLReference) + strlen(soname));
3196 dllref->level = level;
3197 strcpy(dllref->name, soname);
3198 dynarray_add(&s1->loaded_dlls, &s1->nb_loaded_dlls, dllref);
3200 /* add dynamic symbols in dynsym_section */
3201 for(i = 1, sym = dynsym + 1; i < nb_syms; i++, sym++) {
3202 sym_bind = ELFW(ST_BIND)(sym->st_info);
3203 if (sym_bind == STB_LOCAL)
3204 continue;
3205 name = dynstr + sym->st_name;
3206 sym_index = set_elf_sym(s1->dynsymtab_section, sym->st_value, sym->st_size,
3207 sym->st_info, sym->st_other, sym->st_shndx, name);
3208 if (v.versym) {
3209 ElfW(Half) vsym = v.versym[i];
3210 if ((vsym & 0x8000) == 0 && vsym > 0 && vsym < v.nb_local_ver)
3211 set_sym_version(s1, sym_index, v.local_ver[vsym]);
3215 /* load all referenced DLLs */
3216 for(i = 0, dt = dynamic; i < nb_dts; i++, dt++) {
3217 switch(dt->d_tag) {
3218 case DT_NEEDED:
3219 name = dynstr + dt->d_un.d_val;
3220 for(j = 0; j < s1->nb_loaded_dlls; j++) {
3221 dllref = s1->loaded_dlls[j];
3222 if (!strcmp(name, dllref->name))
3223 goto already_loaded;
3225 if (tcc_add_dll(s1, name, AFF_REFERENCED_DLL) < 0) {
3226 tcc_error_noabort("referenced dll '%s' not found", name);
3227 ret = -1;
3228 goto the_end;
3230 already_loaded:
3231 break;
3234 ret = 0;
3235 the_end:
3236 tcc_free(dynstr);
3237 tcc_free(dynsym);
3238 tcc_free(dynamic);
3239 tcc_free(shdr);
3240 tcc_free(v.local_ver);
3241 tcc_free(v.verdef);
3242 tcc_free(v.verneed);
3243 tcc_free(v.versym);
3244 return ret;
3247 #define LD_TOK_NAME 256
3248 #define LD_TOK_EOF (-1)
3250 static int ld_inp(TCCState *s1)
3252 char b;
3253 if (s1->cc != -1) {
3254 int c = s1->cc;
3255 s1->cc = -1;
3256 return c;
3258 if (1 == read(s1->fd, &b, 1))
3259 return b;
3260 return CH_EOF;
3263 /* return next ld script token */
3264 static int ld_next(TCCState *s1, char *name, int name_size)
3266 int c, d, ch;
3267 char *q;
3269 redo:
3270 ch = ld_inp(s1);
3271 switch(ch) {
3272 case ' ':
3273 case '\t':
3274 case '\f':
3275 case '\v':
3276 case '\r':
3277 case '\n':
3278 goto redo;
3279 case '/':
3280 ch = ld_inp(s1);
3281 if (ch == '*') { /* comment */
3282 for (d = 0;; d = ch) {
3283 ch = ld_inp(s1);
3284 if (ch == CH_EOF || (ch == '/' && d == '*'))
3285 break;
3287 goto redo;
3288 } else {
3289 q = name;
3290 *q++ = '/';
3291 goto parse_name;
3293 break;
3294 case '\\':
3295 /* case 'a' ... 'z': */
3296 case 'a':
3297 case 'b':
3298 case 'c':
3299 case 'd':
3300 case 'e':
3301 case 'f':
3302 case 'g':
3303 case 'h':
3304 case 'i':
3305 case 'j':
3306 case 'k':
3307 case 'l':
3308 case 'm':
3309 case 'n':
3310 case 'o':
3311 case 'p':
3312 case 'q':
3313 case 'r':
3314 case 's':
3315 case 't':
3316 case 'u':
3317 case 'v':
3318 case 'w':
3319 case 'x':
3320 case 'y':
3321 case 'z':
3322 /* case 'A' ... 'z': */
3323 case 'A':
3324 case 'B':
3325 case 'C':
3326 case 'D':
3327 case 'E':
3328 case 'F':
3329 case 'G':
3330 case 'H':
3331 case 'I':
3332 case 'J':
3333 case 'K':
3334 case 'L':
3335 case 'M':
3336 case 'N':
3337 case 'O':
3338 case 'P':
3339 case 'Q':
3340 case 'R':
3341 case 'S':
3342 case 'T':
3343 case 'U':
3344 case 'V':
3345 case 'W':
3346 case 'X':
3347 case 'Y':
3348 case 'Z':
3349 case '_':
3350 case '.':
3351 case '$':
3352 case '~':
3353 q = name;
3354 parse_name:
3355 for(;;) {
3356 if (!((ch >= 'a' && ch <= 'z') ||
3357 (ch >= 'A' && ch <= 'Z') ||
3358 (ch >= '0' && ch <= '9') ||
3359 strchr("/.-_+=$:\\,~", ch)))
3360 break;
3361 if ((q - name) < name_size - 1) {
3362 *q++ = ch;
3364 ch = ld_inp(s1);
3366 s1->cc = ch;
3367 *q = '\0';
3368 c = LD_TOK_NAME;
3369 break;
3370 case CH_EOF:
3371 c = LD_TOK_EOF;
3372 break;
3373 default:
3374 c = ch;
3375 break;
3377 return c;
3380 static int ld_add_file(TCCState *s1, const char filename[])
3382 if (filename[0] == '/') {
3383 if (CONFIG_SYSROOT[0] == '\0'
3384 && tcc_add_file_internal(s1, filename, AFF_TYPE_BIN) == 0)
3385 return 0;
3386 filename = tcc_basename(filename);
3388 return tcc_add_dll(s1, filename, 0);
3391 static int ld_add_file_list(TCCState *s1, const char *cmd, int as_needed)
3393 char filename[1024], libname[1024];
3394 int t, group, nblibs = 0, ret = 0;
3395 char **libs = NULL;
3397 group = !strcmp(cmd, "GROUP");
3398 if (!as_needed)
3399 s1->new_undef_sym = 0;
3400 t = ld_next(s1, filename, sizeof(filename));
3401 if (t != '(') {
3402 tcc_error_noabort("( expected");
3403 ret = -1;
3404 goto lib_parse_error;
3406 t = ld_next(s1, filename, sizeof(filename));
3407 for(;;) {
3408 libname[0] = '\0';
3409 if (t == LD_TOK_EOF) {
3410 tcc_error_noabort("unexpected end of file");
3411 ret = -1;
3412 goto lib_parse_error;
3413 } else if (t == ')') {
3414 break;
3415 } else if (t == '-') {
3416 t = ld_next(s1, filename, sizeof(filename));
3417 if ((t != LD_TOK_NAME) || (filename[0] != 'l')) {
3418 tcc_error_noabort("library name expected");
3419 ret = -1;
3420 goto lib_parse_error;
3422 pstrcpy(libname, sizeof libname, &filename[1]);
3423 if (s1->static_link) {
3424 snprintf(filename, sizeof filename, "lib%s.a", libname);
3425 } else {
3426 snprintf(filename, sizeof filename, "lib%s.so", libname);
3428 } else if (t != LD_TOK_NAME) {
3429 tcc_error_noabort("filename expected");
3430 ret = -1;
3431 goto lib_parse_error;
3433 if (!strcmp(filename, "AS_NEEDED")) {
3434 ret = ld_add_file_list(s1, cmd, 1);
3435 if (ret)
3436 goto lib_parse_error;
3437 } else {
3438 /* TODO: Implement AS_NEEDED support. Ignore it for now */
3439 if (!as_needed) {
3440 ret = ld_add_file(s1, filename);
3441 if (ret)
3442 goto lib_parse_error;
3443 if (group) {
3444 /* Add the filename *and* the libname to avoid future conversions */
3445 dynarray_add(&libs, &nblibs, tcc_strdup(filename));
3446 if (libname[0] != '\0')
3447 dynarray_add(&libs, &nblibs, tcc_strdup(libname));
3451 t = ld_next(s1, filename, sizeof(filename));
3452 if (t == ',') {
3453 t = ld_next(s1, filename, sizeof(filename));
3456 if (group && !as_needed) {
3457 while (s1->new_undef_sym) {
3458 int i;
3459 s1->new_undef_sym = 0;
3460 for (i = 0; i < nblibs; i ++)
3461 ld_add_file(s1, libs[i]);
3464 lib_parse_error:
3465 dynarray_reset(&libs, &nblibs);
3466 return ret;
3469 /* interpret a subset of GNU ldscripts to handle the dummy libc.so
3470 files */
3471 ST_FUNC int tcc_load_ldscript(TCCState *s1, int fd)
3473 char cmd[64];
3474 char filename[1024];
3475 int t, ret;
3477 s1->fd = fd;
3478 s1->cc = -1;
3479 for(;;) {
3480 t = ld_next(s1, cmd, sizeof(cmd));
3481 if (t == LD_TOK_EOF)
3482 return 0;
3483 else if (t != LD_TOK_NAME)
3484 return -1;
3485 if (!strcmp(cmd, "INPUT") ||
3486 !strcmp(cmd, "GROUP")) {
3487 ret = ld_add_file_list(s1, cmd, 0);
3488 if (ret)
3489 return ret;
3490 } else if (!strcmp(cmd, "OUTPUT_FORMAT") ||
3491 !strcmp(cmd, "TARGET")) {
3492 /* ignore some commands */
3493 t = ld_next(s1, cmd, sizeof(cmd));
3494 if (t != '(') {
3495 tcc_error_noabort("( expected");
3496 return -1;
3498 for(;;) {
3499 t = ld_next(s1, filename, sizeof(filename));
3500 if (t == LD_TOK_EOF) {
3501 tcc_error_noabort("unexpected end of file");
3502 return -1;
3503 } else if (t == ')') {
3504 break;
3507 } else {
3508 return -1;
3511 return 0;
3513 #endif /* !ELF_OBJ_ONLY */