macos: don't like in crt startup code
[tinycc.git] / tccelf.c
blob99effb6b1230be3f1331ae10fc3d864575616c27
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 /* In an ELF file symbol table, the local symbols must appear below
859 the global and weak ones. Since TCC cannot sort it while generating
860 the code, we must do it after. All the relocation tables are also
861 modified to take into account the symbol table sorting */
862 static void sort_syms(TCCState *s1, Section *s)
864 int *old_to_new_syms;
865 ElfW(Sym) *new_syms;
866 int nb_syms, i;
867 ElfW(Sym) *p, *q;
868 ElfW_Rel *rel;
869 Section *sr;
870 int type, sym_index;
872 nb_syms = s->data_offset / sizeof(ElfW(Sym));
873 new_syms = tcc_malloc(nb_syms * sizeof(ElfW(Sym)));
874 old_to_new_syms = tcc_malloc(nb_syms * sizeof(int));
876 /* first pass for local symbols */
877 p = (ElfW(Sym) *)s->data;
878 q = new_syms;
879 for(i = 0; i < nb_syms; i++) {
880 if (ELFW(ST_BIND)(p->st_info) == STB_LOCAL) {
881 old_to_new_syms[i] = q - new_syms;
882 *q++ = *p;
884 p++;
886 /* save the number of local symbols in section header */
887 if( s->sh_size ) /* this 'if' makes IDA happy */
888 s->sh_info = q - new_syms;
890 /* then second pass for non local symbols */
891 p = (ElfW(Sym) *)s->data;
892 for(i = 0; i < nb_syms; i++) {
893 if (ELFW(ST_BIND)(p->st_info) != STB_LOCAL) {
894 old_to_new_syms[i] = q - new_syms;
895 *q++ = *p;
897 p++;
900 /* we copy the new symbols to the old */
901 memcpy(s->data, new_syms, nb_syms * sizeof(ElfW(Sym)));
902 tcc_free(new_syms);
904 /* now we modify all the relocations */
905 for(i = 1; i < s1->nb_sections; i++) {
906 sr = s1->sections[i];
907 if (sr->sh_type == SHT_RELX && sr->link == s) {
908 for_each_elem(sr, 0, rel, ElfW_Rel) {
909 sym_index = ELFW(R_SYM)(rel->r_info);
910 type = ELFW(R_TYPE)(rel->r_info);
911 sym_index = old_to_new_syms[sym_index];
912 rel->r_info = ELFW(R_INFO)(sym_index, type);
917 tcc_free(old_to_new_syms);
920 /* relocate symbol table, resolve undefined symbols if do_resolve is
921 true and output error if undefined symbol. */
922 ST_FUNC void relocate_syms(TCCState *s1, Section *symtab, int do_resolve)
924 ElfW(Sym) *sym;
925 int sym_bind, sh_num;
926 const char *name;
928 for_each_elem(symtab, 1, sym, ElfW(Sym)) {
929 sh_num = sym->st_shndx;
930 if (sh_num == SHN_UNDEF) {
931 name = (char *) s1->symtab->link->data + sym->st_name;
932 /* Use ld.so to resolve symbol for us (for tcc -run) */
933 if (do_resolve) {
934 #if defined TCC_IS_NATIVE && !defined TCC_TARGET_PE
935 #ifdef TCC_TARGET_MACHO
936 /* The symbols in the symtables have a prepended '_'
937 but dlsym() needs the undecorated name. */
938 void *addr = dlsym(RTLD_DEFAULT, name + 1);
939 #else
940 void *addr = dlsym(RTLD_DEFAULT, name);
941 #endif
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;
1068 #endif
1070 #if !defined(ELF_OBJ_ONLY) || defined(TCC_TARGET_MACHO)
1071 static void build_got(TCCState *s1)
1073 /* if no got, then create it */
1074 s1->got = new_section(s1, ".got", SHT_PROGBITS, SHF_ALLOC | SHF_WRITE);
1075 s1->got->sh_entsize = 4;
1076 set_elf_sym(symtab_section, 0, 4, ELFW(ST_INFO)(STB_GLOBAL, STT_OBJECT),
1077 0, s1->got->sh_num, "_GLOBAL_OFFSET_TABLE_");
1078 /* keep space for _DYNAMIC pointer and two dummy got entries */
1079 section_ptr_add(s1->got, 3 * PTR_SIZE);
1082 /* Create a GOT and (for function call) a PLT entry corresponding to a symbol
1083 in s1->symtab. When creating the dynamic symbol table entry for the GOT
1084 relocation, use 'size' and 'info' for the corresponding symbol metadata.
1085 Returns the offset of the GOT or (if any) PLT entry. */
1086 static struct sym_attr * put_got_entry(TCCState *s1, int dyn_reloc_type,
1087 int sym_index)
1089 int need_plt_entry;
1090 const char *name;
1091 ElfW(Sym) *sym;
1092 struct sym_attr *attr;
1093 unsigned got_offset;
1094 char plt_name[100];
1095 int len;
1097 need_plt_entry = (dyn_reloc_type == R_JMP_SLOT);
1098 attr = get_sym_attr(s1, sym_index, 1);
1100 /* In case a function is both called and its address taken 2 GOT entries
1101 are created, one for taking the address (GOT) and the other for the PLT
1102 entry (PLTGOT). */
1103 if (need_plt_entry ? attr->plt_offset : attr->got_offset)
1104 return attr;
1106 /* create the GOT entry */
1107 got_offset = s1->got->data_offset;
1108 section_ptr_add(s1->got, PTR_SIZE);
1110 /* Create the GOT relocation that will insert the address of the object or
1111 function of interest in the GOT entry. This is a static relocation for
1112 memory output (dlsym will give us the address of symbols) and dynamic
1113 relocation otherwise (executable and DLLs). The relocation should be
1114 done lazily for GOT entry with *_JUMP_SLOT relocation type (the one
1115 associated to a PLT entry) but is currently done at load time for an
1116 unknown reason. */
1118 sym = &((ElfW(Sym) *) symtab_section->data)[sym_index];
1119 name = (char *) symtab_section->link->data + sym->st_name;
1121 if (s1->dynsym) {
1122 if (ELFW(ST_BIND)(sym->st_info) == STB_LOCAL) {
1123 /* Hack alarm. We don't want to emit dynamic symbols
1124 and symbol based relocs for STB_LOCAL symbols, but rather
1125 want to resolve them directly. At this point the symbol
1126 values aren't final yet, so we must defer this. We will later
1127 have to create a RELATIVE reloc anyway, so we misuse the
1128 relocation slot to smuggle the symbol reference until
1129 fill_local_got_entries. Not that the sym_index is
1130 relative to symtab_section, not s1->dynsym! Nevertheless
1131 we use s1->dyn_sym so that if this is the first call
1132 that got->reloc is correctly created. Also note that
1133 RELATIVE relocs are not normally created for the .got,
1134 so the types serves as a marker for later (and is retained
1135 also for the final output, which is okay because then the
1136 got is just normal data). */
1137 put_elf_reloc(s1->dynsym, s1->got, got_offset, R_RELATIVE,
1138 sym_index);
1139 } else {
1140 if (0 == attr->dyn_index)
1141 attr->dyn_index = set_elf_sym(s1->dynsym, sym->st_value,
1142 sym->st_size, sym->st_info, 0,
1143 sym->st_shndx, name);
1144 put_elf_reloc(s1->dynsym, s1->got, got_offset, dyn_reloc_type,
1145 attr->dyn_index);
1147 } else {
1148 put_elf_reloc(symtab_section, s1->got, got_offset, dyn_reloc_type,
1149 sym_index);
1152 if (need_plt_entry) {
1153 if (!s1->plt) {
1154 s1->plt = new_section(s1, ".plt", SHT_PROGBITS,
1155 SHF_ALLOC | SHF_EXECINSTR);
1156 s1->plt->sh_entsize = 4;
1159 attr->plt_offset = create_plt_entry(s1, got_offset, attr);
1161 /* create a symbol 'sym@plt' for the PLT jump vector */
1162 len = strlen(name);
1163 if (len > sizeof plt_name - 5)
1164 len = sizeof plt_name - 5;
1165 memcpy(plt_name, name, len);
1166 strcpy(plt_name + len, "@plt");
1167 attr->plt_sym = put_elf_sym(s1->symtab, attr->plt_offset, sym->st_size,
1168 ELFW(ST_INFO)(STB_GLOBAL, STT_FUNC), 0, s1->plt->sh_num, plt_name);
1170 } else {
1171 attr->got_offset = got_offset;
1174 return attr;
1177 /* build GOT and PLT entries */
1178 ST_FUNC void build_got_entries(TCCState *s1)
1180 Section *s;
1181 ElfW_Rel *rel;
1182 ElfW(Sym) *sym;
1183 int i, type, gotplt_entry, reloc_type, sym_index;
1184 struct sym_attr *attr;
1186 for(i = 1; i < s1->nb_sections; i++) {
1187 s = s1->sections[i];
1188 if (s->sh_type != SHT_RELX)
1189 continue;
1190 /* no need to handle got relocations */
1191 if (s->link != symtab_section)
1192 continue;
1193 for_each_elem(s, 0, rel, ElfW_Rel) {
1194 type = ELFW(R_TYPE)(rel->r_info);
1195 gotplt_entry = gotplt_entry_type(type);
1196 if (gotplt_entry == -1)
1197 tcc_error ("Unknown relocation type for got: %d", type);
1198 sym_index = ELFW(R_SYM)(rel->r_info);
1199 sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
1201 if (gotplt_entry == NO_GOTPLT_ENTRY) {
1202 continue;
1205 /* Automatically create PLT/GOT [entry] if it is an undefined
1206 reference (resolved at runtime), or the symbol is absolute,
1207 probably created by tcc_add_symbol, and thus on 64-bit
1208 targets might be too far from application code. */
1209 if (gotplt_entry == AUTO_GOTPLT_ENTRY) {
1210 if (sym->st_shndx == SHN_UNDEF) {
1211 ElfW(Sym) *esym;
1212 int dynindex;
1213 if (s1->output_type == TCC_OUTPUT_DLL && ! PCRELATIVE_DLLPLT)
1214 continue;
1215 /* Relocations for UNDEF symbols would normally need
1216 to be transferred into the executable or shared object.
1217 If that were done AUTO_GOTPLT_ENTRY wouldn't exist.
1218 But TCC doesn't do that (at least for exes), so we
1219 need to resolve all such relocs locally. And that
1220 means PLT slots for functions in DLLs and COPY relocs for
1221 data symbols. COPY relocs were generated in
1222 bind_exe_dynsyms (and the symbol adjusted to be defined),
1223 and for functions we were generated a dynamic symbol
1224 of function type. */
1225 if (s1->dynsym) {
1226 /* dynsym isn't set for -run :-/ */
1227 dynindex = get_sym_attr(s1, sym_index, 0)->dyn_index;
1228 esym = (ElfW(Sym) *)s1->dynsym->data + dynindex;
1229 if (dynindex
1230 && (ELFW(ST_TYPE)(esym->st_info) == STT_FUNC
1231 || (ELFW(ST_TYPE)(esym->st_info) == STT_NOTYPE
1232 && ELFW(ST_TYPE)(sym->st_info) == STT_FUNC)))
1233 goto jmp_slot;
1235 } else if (!(sym->st_shndx == SHN_ABS
1236 #ifndef TCC_TARGET_ARM
1237 && PTR_SIZE == 8
1238 #endif
1240 continue;
1243 #ifdef TCC_TARGET_X86_64
1244 if ((type == R_X86_64_PLT32 || type == R_X86_64_PC32) &&
1245 sym->st_shndx != SHN_UNDEF &&
1246 (ELFW(ST_VISIBILITY)(sym->st_other) != STV_DEFAULT ||
1247 ELFW(ST_BIND)(sym->st_info) == STB_LOCAL ||
1248 s1->output_type == TCC_OUTPUT_EXE)) {
1249 rel->r_info = ELFW(R_INFO)(sym_index, R_X86_64_PC32);
1250 continue;
1252 #endif
1253 reloc_type = code_reloc(type);
1254 if (reloc_type == -1)
1255 tcc_error ("Unknown relocation type: %d", type);
1256 else if (reloc_type != 0) {
1257 jmp_slot:
1258 reloc_type = R_JMP_SLOT;
1259 } else
1260 reloc_type = R_GLOB_DAT;
1262 if (!s1->got)
1263 build_got(s1);
1265 if (gotplt_entry == BUILD_GOT_ONLY)
1266 continue;
1268 attr = put_got_entry(s1, reloc_type, sym_index);
1270 if (reloc_type == R_JMP_SLOT)
1271 rel->r_info = ELFW(R_INFO)(attr->plt_sym, type);
1275 #endif
1277 ST_FUNC int set_global_sym(TCCState *s1, const char *name, Section *sec, long offs)
1279 int shn = sec ? sec->sh_num : offs ? SHN_ABS : SHN_UNDEF;
1280 if (sec && offs == -1)
1281 offs = sec->data_offset;
1282 return set_elf_sym(symtab_section, offs, 0,
1283 ELFW(ST_INFO)(name ? STB_GLOBAL : STB_LOCAL, STT_NOTYPE), 0, shn, name);
1286 static void add_init_array_defines(TCCState *s1, const char *section_name)
1288 Section *s;
1289 long end_offset;
1290 char buf[1024];
1291 s = find_section(s1, section_name);
1292 if (!s) {
1293 end_offset = 0;
1294 s = data_section;
1295 } else {
1296 end_offset = s->data_offset;
1298 snprintf(buf, sizeof(buf), "__%s_start", section_name + 1);
1299 set_global_sym(s1, buf, s, 0);
1300 snprintf(buf, sizeof(buf), "__%s_end", section_name + 1);
1301 set_global_sym(s1, buf, s, end_offset);
1304 #ifndef TCC_TARGET_PE
1305 static int tcc_add_support(TCCState *s1, const char *filename)
1307 char buf[1024];
1308 snprintf(buf, sizeof(buf), "%s/%s", s1->tcc_lib_path, filename);
1309 return tcc_add_file(s1, buf);
1311 #endif
1313 ST_FUNC void add_array (TCCState *s1, const char *sec, int c)
1315 Section *s;
1316 s = find_section(s1, sec);
1317 s->sh_flags |= SHF_WRITE;
1318 #ifndef TCC_TARGET_PE
1319 s->sh_type = sec[1] == 'i' ? SHT_INIT_ARRAY : SHT_FINI_ARRAY;
1320 #endif
1321 put_elf_reloc (s1->symtab, s, s->data_offset, R_DATA_PTR, c);
1322 section_ptr_add(s, PTR_SIZE);
1325 #ifdef CONFIG_TCC_BCHECK
1326 ST_FUNC void tcc_add_bcheck(TCCState *s1)
1328 if (0 == s1->do_bounds_check)
1329 return;
1330 section_ptr_add(bounds_section, sizeof(addr_t));
1332 #endif
1334 #ifdef CONFIG_TCC_BACKTRACE
1335 static void put_ptr(TCCState *s1, Section *s, int offs)
1337 int c;
1338 c = set_global_sym(s1, NULL, s, offs);
1339 s = data_section;
1340 put_elf_reloc (s1->symtab, s, s->data_offset, R_DATA_PTR, c);
1341 section_ptr_add(s, PTR_SIZE);
1344 /* set symbol to STB_LOCAL and resolve. The point is to not export it as
1345 a dynamic symbol to allow so's to have one each with a different value. */
1346 static void set_local_sym(TCCState *s1, const char *name, Section *s, int offset)
1348 int c = find_elf_sym(s1->symtab, name);
1349 if (c) {
1350 ElfW(Sym) *esym = (ElfW(Sym)*)s1->symtab->data + c;
1351 esym->st_info = ELFW(ST_INFO)(STB_LOCAL, STT_NOTYPE);
1352 esym->st_value = offset;
1353 esym->st_shndx = s->sh_num;
1357 ST_FUNC void tcc_add_btstub(TCCState *s1)
1359 Section *s;
1360 int n, o;
1361 CString cstr;
1363 s = data_section;
1364 o = s->data_offset;
1365 /* create (part of) a struct rt_context (see tccrun.c) */
1366 put_ptr(s1, stab_section, 0);
1367 put_ptr(s1, stab_section, -1);
1368 put_ptr(s1, stab_section->link, 0);
1369 section_ptr_add(s, 3 * PTR_SIZE);
1370 /* prog_base */
1371 put_elf_reloc(s1->symtab, s, s->data_offset, R_DATA_PTR, 0);
1372 section_ptr_add(s, PTR_SIZE);
1373 n = 2 * PTR_SIZE;
1374 #ifdef CONFIG_TCC_BCHECK
1375 if (s1->do_bounds_check) {
1376 put_ptr(s1, bounds_section, 0);
1377 n -= PTR_SIZE;
1379 #endif
1380 section_ptr_add(s, n);
1382 cstr_new(&cstr);
1383 cstr_printf(&cstr,
1384 " extern void __bt_init(),*__rt_info[],__bt_init_dll();"
1385 "__attribute__((constructor)) static void __bt_init_rt(){");
1386 #ifdef TCC_TARGET_PE
1387 if (s1->output_type == TCC_OUTPUT_DLL)
1388 #ifdef CONFIG_TCC_BCHECK
1389 cstr_printf(&cstr, "__bt_init_dll(%d);", s1->do_bounds_check);
1390 #else
1391 cstr_printf(&cstr, "__bt_init_dll(0);");
1392 #endif
1393 #endif
1394 cstr_printf(&cstr, "__bt_init(__rt_info,%d);}",
1395 s1->output_type == TCC_OUTPUT_DLL ? 0 : s1->rt_num_callers + 1);
1396 tcc_compile_string(s1, cstr.data);
1397 cstr_free(&cstr);
1398 set_local_sym(s1, "__rt_info", s, o);
1400 #endif
1402 #ifndef TCC_TARGET_PE
1403 /* add tcc runtime libraries */
1404 ST_FUNC void tcc_add_runtime(TCCState *s1)
1406 s1->filetype = 0;
1407 #ifdef CONFIG_TCC_BCHECK
1408 tcc_add_bcheck(s1);
1409 #endif
1410 tcc_add_pragma_libs(s1);
1411 /* add libc */
1412 if (!s1->nostdlib) {
1413 if (s1->option_pthread)
1414 tcc_add_library_err(s1, "pthread");
1415 tcc_add_library_err(s1, "c");
1416 #ifdef TCC_LIBGCC
1417 if (!s1->static_link) {
1418 if (TCC_LIBGCC[0] == '/')
1419 tcc_add_file(s1, TCC_LIBGCC);
1420 else
1421 tcc_add_dll(s1, TCC_LIBGCC, 0);
1423 #endif
1424 #ifdef CONFIG_TCC_BCHECK
1425 if (s1->do_bounds_check && s1->output_type != TCC_OUTPUT_DLL) {
1426 tcc_add_library_err(s1, "pthread");
1427 tcc_add_library_err(s1, "dl");
1428 tcc_add_support(s1, "bcheck.o");
1430 #endif
1431 #ifdef CONFIG_TCC_BACKTRACE
1432 if (s1->do_backtrace) {
1433 if (s1->output_type == TCC_OUTPUT_EXE)
1434 tcc_add_support(s1, "bt-exe.o");
1435 if (s1->output_type != TCC_OUTPUT_DLL)
1436 tcc_add_support(s1, "bt-log.o");
1437 if (s1->output_type != TCC_OUTPUT_MEMORY)
1438 tcc_add_btstub(s1);
1440 #endif
1441 tcc_add_support(s1, TCC_LIBTCC1);
1442 /* add crt end if not memory output */
1443 if (s1->output_type != TCC_OUTPUT_MEMORY)
1444 tcc_add_crt(s1, "crtn.o");
1447 #endif
1449 /* add various standard linker symbols (must be done after the
1450 sections are filled (for example after allocating common
1451 symbols)) */
1452 static void tcc_add_linker_symbols(TCCState *s1)
1454 char buf[1024];
1455 int i;
1456 Section *s;
1458 set_global_sym(s1, "_etext", text_section, -1);
1459 set_global_sym(s1, "_edata", data_section, -1);
1460 set_global_sym(s1, "_end", bss_section, -1);
1461 #ifdef TCC_TARGET_RISCV64
1462 /* XXX should be .sdata+0x800, not .data+0x800 */
1463 set_global_sym(s1, "__global_pointer$", data_section, 0x800);
1464 #endif
1465 /* horrible new standard ldscript defines */
1466 add_init_array_defines(s1, ".preinit_array");
1467 add_init_array_defines(s1, ".init_array");
1468 add_init_array_defines(s1, ".fini_array");
1469 /* add start and stop symbols for sections whose name can be
1470 expressed in C */
1471 for(i = 1; i < s1->nb_sections; i++) {
1472 s = s1->sections[i];
1473 if ((s->sh_flags & SHF_ALLOC)
1474 && (s->sh_type == SHT_PROGBITS
1475 || s->sh_type == SHT_STRTAB)) {
1476 const char *p;
1477 /* check if section name can be expressed in C */
1478 p = s->name;
1479 for(;;) {
1480 int c = *p;
1481 if (!c)
1482 break;
1483 if (!isid(c) && !isnum(c))
1484 goto next_sec;
1485 p++;
1487 snprintf(buf, sizeof(buf), "__start_%s", s->name);
1488 set_global_sym(s1, buf, s, 0);
1489 snprintf(buf, sizeof(buf), "__stop_%s", s->name);
1490 set_global_sym(s1, buf, s, -1);
1492 next_sec: ;
1496 ST_FUNC void resolve_common_syms(TCCState *s1)
1498 ElfW(Sym) *sym;
1500 /* Allocate common symbols in BSS. */
1501 for_each_elem(symtab_section, 1, sym, ElfW(Sym)) {
1502 if (sym->st_shndx == SHN_COMMON) {
1503 /* symbol alignment is in st_value for SHN_COMMONs */
1504 sym->st_value = section_add(bss_section, sym->st_size,
1505 sym->st_value);
1506 sym->st_shndx = bss_section->sh_num;
1510 /* Now assign linker provided symbols their value. */
1511 tcc_add_linker_symbols(s1);
1514 static void tcc_output_binary(TCCState *s1, FILE *f,
1515 const int *sec_order)
1517 Section *s;
1518 int i, offset, size;
1520 offset = 0;
1521 for(i=1;i<s1->nb_sections;i++) {
1522 s = s1->sections[sec_order[i]];
1523 if (s->sh_type != SHT_NOBITS &&
1524 (s->sh_flags & SHF_ALLOC)) {
1525 while (offset < s->sh_offset) {
1526 fputc(0, f);
1527 offset++;
1529 size = s->sh_size;
1530 fwrite(s->data, 1, size, f);
1531 offset += size;
1536 #ifndef ELF_OBJ_ONLY
1537 ST_FUNC void fill_got_entry(TCCState *s1, ElfW_Rel *rel)
1539 int sym_index = ELFW(R_SYM) (rel->r_info);
1540 ElfW(Sym) *sym = &((ElfW(Sym) *) symtab_section->data)[sym_index];
1541 struct sym_attr *attr = get_sym_attr(s1, sym_index, 0);
1542 unsigned offset = attr->got_offset;
1544 if (0 == offset)
1545 return;
1546 section_reserve(s1->got, offset + PTR_SIZE);
1547 #ifdef TCC_TARGET_X86_64
1548 write64le(s1->got->data + offset, sym->st_value);
1549 #else
1550 write32le(s1->got->data + offset, sym->st_value);
1551 #endif
1554 /* Perform relocation to GOT or PLT entries */
1555 ST_FUNC void fill_got(TCCState *s1)
1557 Section *s;
1558 ElfW_Rel *rel;
1559 int i;
1561 for(i = 1; i < s1->nb_sections; i++) {
1562 s = s1->sections[i];
1563 if (s->sh_type != SHT_RELX)
1564 continue;
1565 /* no need to handle got relocations */
1566 if (s->link != symtab_section)
1567 continue;
1568 for_each_elem(s, 0, rel, ElfW_Rel) {
1569 switch (ELFW(R_TYPE) (rel->r_info)) {
1570 case R_X86_64_GOT32:
1571 case R_X86_64_GOTPCREL:
1572 case R_X86_64_GOTPCRELX:
1573 case R_X86_64_REX_GOTPCRELX:
1574 case R_X86_64_PLT32:
1575 fill_got_entry(s1, rel);
1576 break;
1582 /* See put_got_entry for a description. This is the second stage
1583 where GOT references to local defined symbols are rewritten. */
1584 static void fill_local_got_entries(TCCState *s1)
1586 ElfW_Rel *rel;
1587 if (!s1->got->reloc)
1588 return;
1589 for_each_elem(s1->got->reloc, 0, rel, ElfW_Rel) {
1590 if (ELFW(R_TYPE)(rel->r_info) == R_RELATIVE) {
1591 int sym_index = ELFW(R_SYM) (rel->r_info);
1592 ElfW(Sym) *sym = &((ElfW(Sym) *) symtab_section->data)[sym_index];
1593 struct sym_attr *attr = get_sym_attr(s1, sym_index, 0);
1594 unsigned offset = attr->got_offset;
1595 if (offset != rel->r_offset - s1->got->sh_addr)
1596 tcc_error_noabort("huh");
1597 rel->r_info = ELFW(R_INFO)(0, R_RELATIVE);
1598 #if SHT_RELX == SHT_RELA
1599 rel->r_addend = sym->st_value;
1600 #else
1601 /* All our REL architectures also happen to be 32bit LE. */
1602 write32le(s1->got->data + offset, sym->st_value);
1603 #endif
1608 /* Bind symbols of executable: resolve undefined symbols from exported symbols
1609 in shared libraries and export non local defined symbols to shared libraries
1610 if -rdynamic switch was given on command line */
1611 static void bind_exe_dynsyms(TCCState *s1)
1613 const char *name;
1614 int sym_index, index;
1615 ElfW(Sym) *sym, *esym;
1616 int type;
1618 /* Resolve undefined symbols from dynamic symbols. When there is a match:
1619 - if STT_FUNC or STT_GNU_IFUNC symbol -> add it in PLT
1620 - if STT_OBJECT symbol -> add it in .bss section with suitable reloc */
1621 for_each_elem(symtab_section, 1, sym, ElfW(Sym)) {
1622 if (sym->st_shndx == SHN_UNDEF) {
1623 name = (char *) symtab_section->link->data + sym->st_name;
1624 sym_index = find_elf_sym(s1->dynsymtab_section, name);
1625 if (sym_index) {
1626 esym = &((ElfW(Sym) *)s1->dynsymtab_section->data)[sym_index];
1627 type = ELFW(ST_TYPE)(esym->st_info);
1628 if ((type == STT_FUNC) || (type == STT_GNU_IFUNC)) {
1629 /* Indirect functions shall have STT_FUNC type in executable
1630 * dynsym section. Indeed, a dlsym call following a lazy
1631 * resolution would pick the symbol value from the
1632 * executable dynsym entry which would contain the address
1633 * of the function wanted by the caller of dlsym instead of
1634 * the address of the function that would return that
1635 * address */
1636 int dynindex
1637 = put_elf_sym(s1->dynsym, 0, esym->st_size,
1638 ELFW(ST_INFO)(STB_GLOBAL,STT_FUNC), 0, 0,
1639 name);
1640 int index = sym - (ElfW(Sym) *) symtab_section->data;
1641 get_sym_attr(s1, index, 1)->dyn_index = dynindex;
1642 } else if (type == STT_OBJECT) {
1643 unsigned long offset;
1644 ElfW(Sym) *dynsym;
1645 offset = bss_section->data_offset;
1646 /* XXX: which alignment ? */
1647 offset = (offset + 16 - 1) & -16;
1648 set_elf_sym (s1->symtab, offset, esym->st_size,
1649 esym->st_info, 0, bss_section->sh_num, name);
1650 index = put_elf_sym(s1->dynsym, offset, esym->st_size,
1651 esym->st_info, 0, bss_section->sh_num,
1652 name);
1654 /* Ensure R_COPY works for weak symbol aliases */
1655 if (ELFW(ST_BIND)(esym->st_info) == STB_WEAK) {
1656 for_each_elem(s1->dynsymtab_section, 1, dynsym, ElfW(Sym)) {
1657 if ((dynsym->st_value == esym->st_value)
1658 && (ELFW(ST_BIND)(dynsym->st_info) == STB_GLOBAL)) {
1659 char *dynname = (char *) s1->dynsymtab_section->link->data
1660 + dynsym->st_name;
1661 put_elf_sym(s1->dynsym, offset, dynsym->st_size,
1662 dynsym->st_info, 0,
1663 bss_section->sh_num, dynname);
1664 break;
1669 put_elf_reloc(s1->dynsym, bss_section,
1670 offset, R_COPY, index);
1671 offset += esym->st_size;
1672 bss_section->data_offset = offset;
1674 } else {
1675 /* STB_WEAK undefined symbols are accepted */
1676 /* XXX: _fp_hw seems to be part of the ABI, so we ignore it */
1677 if (ELFW(ST_BIND)(sym->st_info) == STB_WEAK ||
1678 !strcmp(name, "_fp_hw")) {
1679 } else {
1680 tcc_error_noabort("undefined symbol '%s'", name);
1683 } else if (s1->rdynamic && ELFW(ST_BIND)(sym->st_info) != STB_LOCAL) {
1684 /* if -rdynamic option, then export all non local symbols */
1685 name = (char *) symtab_section->link->data + sym->st_name;
1686 set_elf_sym(s1->dynsym, sym->st_value, sym->st_size, sym->st_info,
1687 0, sym->st_shndx, name);
1692 /* Bind symbols of libraries: export all non local symbols of executable that
1693 are referenced by shared libraries. The reason is that the dynamic loader
1694 search symbol first in executable and then in libraries. Therefore a
1695 reference to a symbol already defined by a library can still be resolved by
1696 a symbol in the executable. */
1697 static void bind_libs_dynsyms(TCCState *s1)
1699 const char *name;
1700 int sym_index;
1701 ElfW(Sym) *sym, *esym;
1703 for_each_elem(s1->dynsymtab_section, 1, esym, ElfW(Sym)) {
1704 name = (char *) s1->dynsymtab_section->link->data + esym->st_name;
1705 sym_index = find_elf_sym(symtab_section, name);
1706 sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
1707 if (sym_index && sym->st_shndx != SHN_UNDEF
1708 && ELFW(ST_BIND)(sym->st_info) != STB_LOCAL) {
1709 set_elf_sym(s1->dynsym, sym->st_value, sym->st_size,
1710 sym->st_info, 0, sym->st_shndx, name);
1711 } else if (esym->st_shndx == SHN_UNDEF) {
1712 /* weak symbols can stay undefined */
1713 if (ELFW(ST_BIND)(esym->st_info) != STB_WEAK)
1714 tcc_warning("undefined dynamic symbol '%s'", name);
1719 /* Export all non local symbols. This is used by shared libraries so that the
1720 non local symbols they define can resolve a reference in another shared
1721 library or in the executable. Correspondingly, it allows undefined local
1722 symbols to be resolved by other shared libraries or by the executable. */
1723 static void export_global_syms(TCCState *s1)
1725 int dynindex, index;
1726 const char *name;
1727 ElfW(Sym) *sym;
1729 for_each_elem(symtab_section, 1, sym, ElfW(Sym)) {
1730 if (ELFW(ST_BIND)(sym->st_info) != STB_LOCAL) {
1731 name = (char *) symtab_section->link->data + sym->st_name;
1732 dynindex = put_elf_sym(s1->dynsym, sym->st_value, sym->st_size,
1733 sym->st_info, 0, sym->st_shndx, name);
1734 index = sym - (ElfW(Sym) *) symtab_section->data;
1735 get_sym_attr(s1, index, 1)->dyn_index = dynindex;
1739 #endif
1741 /* Allocate strings for section names and decide if an unallocated section
1742 should be output.
1743 NOTE: the strsec section comes last, so its size is also correct ! */
1744 static int alloc_sec_names(TCCState *s1, int file_type, Section *strsec)
1746 int i;
1747 Section *s;
1748 int textrel = 0;
1750 /* Allocate strings for section names */
1751 for(i = 1; i < s1->nb_sections; i++) {
1752 s = s1->sections[i];
1753 /* when generating a DLL, we include relocations but we may
1754 patch them */
1755 #ifndef ELF_OBJ_ONLY
1756 if (file_type == TCC_OUTPUT_DLL &&
1757 s->sh_type == SHT_RELX &&
1758 !(s->sh_flags & SHF_ALLOC) &&
1759 (s1->sections[s->sh_info]->sh_flags & SHF_ALLOC) &&
1760 prepare_dynamic_rel(s1, s)) {
1761 if (!(s1->sections[s->sh_info]->sh_flags & SHF_WRITE))
1762 textrel = 1;
1763 } else
1764 #endif
1765 if ((s1->do_debug && s->sh_type != SHT_RELX) ||
1766 file_type == TCC_OUTPUT_OBJ ||
1767 (s->sh_flags & SHF_ALLOC) ||
1768 i == (s1->nb_sections - 1)) {
1769 /* we output all sections if debug or object file */
1770 s->sh_size = s->data_offset;
1772 if (s->sh_size || (s->sh_flags & SHF_ALLOC))
1773 s->sh_name = put_elf_str(strsec, s->name);
1775 strsec->sh_size = strsec->data_offset;
1776 return textrel;
1779 /* Info to be copied in dynamic section */
1780 struct dyn_inf {
1781 Section *dynamic;
1782 Section *dynstr;
1783 unsigned long data_offset;
1784 addr_t rel_addr;
1785 addr_t rel_size;
1786 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
1787 addr_t bss_addr;
1788 addr_t bss_size;
1789 #endif
1792 /* Assign sections to segments and decide how are sections laid out when loaded
1793 in memory. This function also fills corresponding program headers. */
1794 static int layout_sections(TCCState *s1, ElfW(Phdr) *phdr, int phnum,
1795 Section *interp, Section* strsec,
1796 struct dyn_inf *dyninf, int *sec_order)
1798 int i, j, k, file_type, sh_order_index, file_offset;
1799 unsigned long s_align;
1800 long long tmp;
1801 addr_t addr;
1802 ElfW(Phdr) *ph;
1803 Section *s;
1805 file_type = s1->output_type;
1806 sh_order_index = 1;
1807 file_offset = 0;
1808 if (s1->output_format == TCC_OUTPUT_FORMAT_ELF)
1809 file_offset = sizeof(ElfW(Ehdr)) + phnum * sizeof(ElfW(Phdr));
1810 s_align = ELF_PAGE_SIZE;
1811 if (s1->section_align)
1812 s_align = s1->section_align;
1814 if (phnum > 0) {
1815 if (s1->has_text_addr) {
1816 int a_offset, p_offset;
1817 addr = s1->text_addr;
1818 /* we ensure that (addr % ELF_PAGE_SIZE) == file_offset %
1819 ELF_PAGE_SIZE */
1820 a_offset = (int) (addr & (s_align - 1));
1821 p_offset = file_offset & (s_align - 1);
1822 if (a_offset < p_offset)
1823 a_offset += s_align;
1824 file_offset += (a_offset - p_offset);
1825 } else {
1826 if (file_type == TCC_OUTPUT_DLL)
1827 addr = 0;
1828 else
1829 addr = ELF_START_ADDR;
1830 /* compute address after headers */
1831 addr += (file_offset & (s_align - 1));
1834 ph = &phdr[0];
1835 /* Leave one program headers for the program interpreter and one for
1836 the program header table itself if needed. These are done later as
1837 they require section layout to be done first. */
1838 if (interp)
1839 ph += 2;
1841 /* dynamic relocation table information, for .dynamic section */
1842 dyninf->rel_addr = dyninf->rel_size = 0;
1843 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
1844 dyninf->bss_addr = dyninf->bss_size = 0;
1845 #endif
1847 for(j = 0; j < 2; j++) {
1848 ph->p_type = PT_LOAD;
1849 if (j == 0)
1850 ph->p_flags = PF_R | PF_X;
1851 else
1852 ph->p_flags = PF_R | PF_W;
1853 ph->p_align = s_align;
1855 /* Decide the layout of sections loaded in memory. This must
1856 be done before program headers are filled since they contain
1857 info about the layout. We do the following ordering: interp,
1858 symbol tables, relocations, progbits, nobits */
1859 /* XXX: do faster and simpler sorting */
1860 for(k = 0; k < 5; k++) {
1861 for(i = 1; i < s1->nb_sections; i++) {
1862 s = s1->sections[i];
1863 /* compute if section should be included */
1864 if (j == 0) {
1865 if ((s->sh_flags & (SHF_ALLOC | SHF_WRITE)) !=
1866 SHF_ALLOC)
1867 continue;
1868 } else {
1869 if ((s->sh_flags & (SHF_ALLOC | SHF_WRITE)) !=
1870 (SHF_ALLOC | SHF_WRITE))
1871 continue;
1873 if (s == interp) {
1874 if (k != 0)
1875 continue;
1876 } else if ((s->sh_type == SHT_DYNSYM ||
1877 s->sh_type == SHT_STRTAB ||
1878 s->sh_type == SHT_HASH)
1879 && !strstr(s->name, ".stab")) {
1880 if (k != 1)
1881 continue;
1882 } else if (s->sh_type == SHT_RELX) {
1883 if (k != 2)
1884 continue;
1885 } else if (s->sh_type == SHT_NOBITS) {
1886 if (k != 4)
1887 continue;
1888 } else {
1889 if (k != 3)
1890 continue;
1892 sec_order[sh_order_index++] = i;
1894 /* section matches: we align it and add its size */
1895 tmp = addr;
1896 addr = (addr + s->sh_addralign - 1) &
1897 ~(s->sh_addralign - 1);
1898 file_offset += (int) ( addr - tmp );
1899 s->sh_offset = file_offset;
1900 s->sh_addr = addr;
1902 /* update program header infos */
1903 if (ph->p_offset == 0) {
1904 ph->p_offset = file_offset;
1905 ph->p_vaddr = addr;
1906 ph->p_paddr = ph->p_vaddr;
1908 /* update dynamic relocation infos */
1909 if (s->sh_type == SHT_RELX) {
1910 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
1911 if (!strcmp(strsec->data + s->sh_name, ".rel.got")) {
1912 dyninf->rel_addr = addr;
1913 dyninf->rel_size += s->sh_size; /* XXX only first rel. */
1915 if (!strcmp(strsec->data + s->sh_name, ".rel.bss")) {
1916 dyninf->bss_addr = addr;
1917 dyninf->bss_size = s->sh_size; /* XXX only first rel. */
1919 #else
1920 if (dyninf->rel_size == 0)
1921 dyninf->rel_addr = addr;
1922 dyninf->rel_size += s->sh_size;
1923 #endif
1925 addr += s->sh_size;
1926 if (s->sh_type != SHT_NOBITS)
1927 file_offset += s->sh_size;
1930 if (j == 0) {
1931 /* Make the first PT_LOAD segment include the program
1932 headers itself (and the ELF header as well), it'll
1933 come out with same memory use but will make various
1934 tools like binutils strip work better. */
1935 ph->p_offset &= ~(ph->p_align - 1);
1936 ph->p_vaddr &= ~(ph->p_align - 1);
1937 ph->p_paddr &= ~(ph->p_align - 1);
1939 ph->p_filesz = file_offset - ph->p_offset;
1940 ph->p_memsz = addr - ph->p_vaddr;
1941 ph++;
1942 if (j == 0) {
1943 if (s1->output_format == TCC_OUTPUT_FORMAT_ELF) {
1944 /* if in the middle of a page, we duplicate the page in
1945 memory so that one copy is RX and the other is RW */
1946 if ((addr & (s_align - 1)) != 0)
1947 addr += s_align;
1948 } else {
1949 addr = (addr + s_align - 1) & ~(s_align - 1);
1950 file_offset = (file_offset + s_align - 1) & ~(s_align - 1);
1956 /* all other sections come after */
1957 for(i = 1; i < s1->nb_sections; i++) {
1958 s = s1->sections[i];
1959 if (phnum > 0 && (s->sh_flags & SHF_ALLOC))
1960 continue;
1961 sec_order[sh_order_index++] = i;
1963 file_offset = (file_offset + s->sh_addralign - 1) &
1964 ~(s->sh_addralign - 1);
1965 s->sh_offset = file_offset;
1966 if (s->sh_type != SHT_NOBITS)
1967 file_offset += s->sh_size;
1970 return file_offset;
1973 #ifndef ELF_OBJ_ONLY
1974 /* put dynamic tag */
1975 static void put_dt(Section *dynamic, int dt, addr_t val)
1977 ElfW(Dyn) *dyn;
1978 dyn = section_ptr_add(dynamic, sizeof(ElfW(Dyn)));
1979 dyn->d_tag = dt;
1980 dyn->d_un.d_val = val;
1983 static void fill_unloadable_phdr(ElfW(Phdr) *phdr, int phnum, Section *interp,
1984 Section *dynamic)
1986 ElfW(Phdr) *ph;
1988 /* if interpreter, then add corresponding program header */
1989 if (interp) {
1990 ph = &phdr[0];
1992 ph->p_type = PT_PHDR;
1993 ph->p_offset = sizeof(ElfW(Ehdr));
1994 ph->p_filesz = ph->p_memsz = phnum * sizeof(ElfW(Phdr));
1995 ph->p_vaddr = interp->sh_addr - ph->p_filesz;
1996 ph->p_paddr = ph->p_vaddr;
1997 ph->p_flags = PF_R | PF_X;
1998 ph->p_align = 4; /* interp->sh_addralign; */
1999 ph++;
2001 ph->p_type = PT_INTERP;
2002 ph->p_offset = interp->sh_offset;
2003 ph->p_vaddr = interp->sh_addr;
2004 ph->p_paddr = ph->p_vaddr;
2005 ph->p_filesz = interp->sh_size;
2006 ph->p_memsz = interp->sh_size;
2007 ph->p_flags = PF_R;
2008 ph->p_align = interp->sh_addralign;
2011 /* if dynamic section, then add corresponding program header */
2012 if (dynamic) {
2013 ph = &phdr[phnum - 1];
2015 ph->p_type = PT_DYNAMIC;
2016 ph->p_offset = dynamic->sh_offset;
2017 ph->p_vaddr = dynamic->sh_addr;
2018 ph->p_paddr = ph->p_vaddr;
2019 ph->p_filesz = dynamic->sh_size;
2020 ph->p_memsz = dynamic->sh_size;
2021 ph->p_flags = PF_R | PF_W;
2022 ph->p_align = dynamic->sh_addralign;
2026 /* Fill the dynamic section with tags describing the address and size of
2027 sections */
2028 static void fill_dynamic(TCCState *s1, struct dyn_inf *dyninf)
2030 Section *dynamic = dyninf->dynamic;
2031 Section *s;
2033 /* put dynamic section entries */
2034 put_dt(dynamic, DT_HASH, s1->dynsym->hash->sh_addr);
2035 put_dt(dynamic, DT_STRTAB, dyninf->dynstr->sh_addr);
2036 put_dt(dynamic, DT_SYMTAB, s1->dynsym->sh_addr);
2037 put_dt(dynamic, DT_STRSZ, dyninf->dynstr->data_offset);
2038 put_dt(dynamic, DT_SYMENT, sizeof(ElfW(Sym)));
2039 #if PTR_SIZE == 8
2040 put_dt(dynamic, DT_RELA, dyninf->rel_addr);
2041 put_dt(dynamic, DT_RELASZ, dyninf->rel_size);
2042 put_dt(dynamic, DT_RELAENT, sizeof(ElfW_Rel));
2043 #else
2044 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
2045 put_dt(dynamic, DT_PLTGOT, s1->got->sh_addr);
2046 put_dt(dynamic, DT_PLTRELSZ, dyninf->rel_size);
2047 put_dt(dynamic, DT_JMPREL, dyninf->rel_addr);
2048 put_dt(dynamic, DT_PLTREL, DT_REL);
2049 put_dt(dynamic, DT_REL, dyninf->bss_addr);
2050 put_dt(dynamic, DT_RELSZ, dyninf->bss_size);
2051 #else
2052 put_dt(dynamic, DT_REL, dyninf->rel_addr);
2053 put_dt(dynamic, DT_RELSZ, dyninf->rel_size);
2054 put_dt(dynamic, DT_RELENT, sizeof(ElfW_Rel));
2055 #endif
2056 #endif
2057 if (versym_section)
2058 put_dt(dynamic, DT_VERSYM, versym_section->sh_addr);
2059 if (verneed_section) {
2060 put_dt(dynamic, DT_VERNEED, verneed_section->sh_addr);
2061 put_dt(dynamic, DT_VERNEEDNUM, dt_verneednum);
2063 s = find_section_create (s1, ".preinit_array", 0);
2064 if (s && s->data_offset) {
2065 put_dt(dynamic, DT_PREINIT_ARRAY, s->sh_addr);
2066 put_dt(dynamic, DT_PREINIT_ARRAYSZ, s->data_offset);
2068 s = find_section_create (s1, ".init_array", 0);
2069 if (s && s->data_offset) {
2070 put_dt(dynamic, DT_INIT_ARRAY, s->sh_addr);
2071 put_dt(dynamic, DT_INIT_ARRAYSZ, s->data_offset);
2073 s = find_section_create (s1, ".fini_array", 0);
2074 if (s && s->data_offset) {
2075 put_dt(dynamic, DT_FINI_ARRAY, s->sh_addr);
2076 put_dt(dynamic, DT_FINI_ARRAYSZ, s->data_offset);
2078 s = find_section_create (s1, ".init", 0);
2079 if (s && s->data_offset) {
2080 put_dt(dynamic, DT_INIT, s->sh_addr);
2082 s = find_section_create (s1, ".fini", 0);
2083 if (s && s->data_offset) {
2084 put_dt(dynamic, DT_FINI, s->sh_addr);
2086 if (s1->do_debug)
2087 put_dt(dynamic, DT_DEBUG, 0);
2088 put_dt(dynamic, DT_NULL, 0);
2091 /* Relocate remaining sections and symbols (that is those not related to
2092 dynamic linking) */
2093 static int final_sections_reloc(TCCState *s1)
2095 int i;
2096 Section *s;
2098 relocate_syms(s1, s1->symtab, 0);
2100 if (s1->nb_errors != 0)
2101 return -1;
2103 /* relocate sections */
2104 /* XXX: ignore sections with allocated relocations ? */
2105 for(i = 1; i < s1->nb_sections; i++) {
2106 s = s1->sections[i];
2107 if (s->reloc && (s != s1->got || s1->static_link))
2108 relocate_section(s1, s);
2111 /* relocate relocation entries if the relocation tables are
2112 allocated in the executable */
2113 for(i = 1; i < s1->nb_sections; i++) {
2114 s = s1->sections[i];
2115 if ((s->sh_flags & SHF_ALLOC) &&
2116 s->sh_type == SHT_RELX) {
2117 relocate_rel(s1, s);
2120 return 0;
2122 #endif
2124 /* Create an ELF file on disk.
2125 This function handle ELF specific layout requirements */
2126 static void tcc_output_elf(TCCState *s1, FILE *f, int phnum, ElfW(Phdr) *phdr,
2127 int file_offset, int *sec_order)
2129 int i, shnum, offset, size, file_type;
2130 Section *s;
2131 ElfW(Ehdr) ehdr;
2132 ElfW(Shdr) shdr, *sh;
2134 file_type = s1->output_type;
2135 shnum = s1->nb_sections;
2137 memset(&ehdr, 0, sizeof(ehdr));
2139 if (phnum > 0) {
2140 ehdr.e_phentsize = sizeof(ElfW(Phdr));
2141 ehdr.e_phnum = phnum;
2142 ehdr.e_phoff = sizeof(ElfW(Ehdr));
2145 /* align to 4 */
2146 file_offset = (file_offset + 3) & -4;
2148 /* fill header */
2149 ehdr.e_ident[0] = ELFMAG0;
2150 ehdr.e_ident[1] = ELFMAG1;
2151 ehdr.e_ident[2] = ELFMAG2;
2152 ehdr.e_ident[3] = ELFMAG3;
2153 ehdr.e_ident[4] = ELFCLASSW;
2154 ehdr.e_ident[5] = ELFDATA2LSB;
2155 ehdr.e_ident[6] = EV_CURRENT;
2156 #if !defined(TCC_TARGET_PE) && (defined(__FreeBSD__) || defined(__FreeBSD_kernel__))
2157 /* FIXME: should set only for freebsd _target_, but we exclude only PE target */
2158 ehdr.e_ident[EI_OSABI] = ELFOSABI_FREEBSD;
2159 #endif
2160 #ifdef TCC_TARGET_ARM
2161 #ifdef TCC_ARM_EABI
2162 ehdr.e_ident[EI_OSABI] = 0;
2163 ehdr.e_flags = EF_ARM_EABI_VER4;
2164 if (file_type == TCC_OUTPUT_EXE || file_type == TCC_OUTPUT_DLL)
2165 ehdr.e_flags |= EF_ARM_HASENTRY;
2166 if (s1->float_abi == ARM_HARD_FLOAT)
2167 ehdr.e_flags |= EF_ARM_VFP_FLOAT;
2168 else
2169 ehdr.e_flags |= EF_ARM_SOFT_FLOAT;
2170 #else
2171 ehdr.e_ident[EI_OSABI] = ELFOSABI_ARM;
2172 #endif
2173 #elif defined TCC_TARGET_RISCV64
2174 ehdr.e_flags = EF_RISCV_FLOAT_ABI_DOUBLE;
2175 #endif
2176 switch(file_type) {
2177 default:
2178 case TCC_OUTPUT_EXE:
2179 ehdr.e_type = ET_EXEC;
2180 ehdr.e_entry = get_elf_sym_addr(s1, "_start", 1);
2181 break;
2182 case TCC_OUTPUT_DLL:
2183 ehdr.e_type = ET_DYN;
2184 ehdr.e_entry = text_section->sh_addr; /* XXX: is it correct ? */
2185 break;
2186 case TCC_OUTPUT_OBJ:
2187 ehdr.e_type = ET_REL;
2188 break;
2190 ehdr.e_machine = EM_TCC_TARGET;
2191 ehdr.e_version = EV_CURRENT;
2192 ehdr.e_shoff = file_offset;
2193 ehdr.e_ehsize = sizeof(ElfW(Ehdr));
2194 ehdr.e_shentsize = sizeof(ElfW(Shdr));
2195 ehdr.e_shnum = shnum;
2196 ehdr.e_shstrndx = shnum - 1;
2198 fwrite(&ehdr, 1, sizeof(ElfW(Ehdr)), f);
2199 fwrite(phdr, 1, phnum * sizeof(ElfW(Phdr)), f);
2200 offset = sizeof(ElfW(Ehdr)) + phnum * sizeof(ElfW(Phdr));
2202 sort_syms(s1, symtab_section);
2203 for(i = 1; i < s1->nb_sections; i++) {
2204 s = s1->sections[sec_order[i]];
2205 if (s->sh_type != SHT_NOBITS) {
2206 while (offset < s->sh_offset) {
2207 fputc(0, f);
2208 offset++;
2210 size = s->sh_size;
2211 if (size)
2212 fwrite(s->data, 1, size, f);
2213 offset += size;
2217 /* output section headers */
2218 while (offset < ehdr.e_shoff) {
2219 fputc(0, f);
2220 offset++;
2223 for(i = 0; i < s1->nb_sections; i++) {
2224 sh = &shdr;
2225 memset(sh, 0, sizeof(ElfW(Shdr)));
2226 s = s1->sections[i];
2227 if (s) {
2228 sh->sh_name = s->sh_name;
2229 sh->sh_type = s->sh_type;
2230 sh->sh_flags = s->sh_flags;
2231 sh->sh_entsize = s->sh_entsize;
2232 sh->sh_info = s->sh_info;
2233 if (s->link)
2234 sh->sh_link = s->link->sh_num;
2235 sh->sh_addralign = s->sh_addralign;
2236 sh->sh_addr = s->sh_addr;
2237 sh->sh_offset = s->sh_offset;
2238 sh->sh_size = s->sh_size;
2240 fwrite(sh, 1, sizeof(ElfW(Shdr)), f);
2244 /* Write an elf, coff or "binary" file */
2245 static int tcc_write_elf_file(TCCState *s1, const char *filename, int phnum,
2246 ElfW(Phdr) *phdr, int file_offset, int *sec_order)
2248 int fd, mode, file_type;
2249 FILE *f;
2251 file_type = s1->output_type;
2252 if (file_type == TCC_OUTPUT_OBJ)
2253 mode = 0666;
2254 else
2255 mode = 0777;
2256 unlink(filename);
2257 fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, mode);
2258 if (fd < 0) {
2259 tcc_error_noabort("could not write '%s'", filename);
2260 return -1;
2262 f = fdopen(fd, "wb");
2263 if (s1->verbose)
2264 printf("<- %s\n", filename);
2266 #ifdef TCC_TARGET_COFF
2267 if (s1->output_format == TCC_OUTPUT_FORMAT_COFF)
2268 tcc_output_coff(s1, f);
2269 else
2270 #endif
2271 if (s1->output_format == TCC_OUTPUT_FORMAT_ELF)
2272 tcc_output_elf(s1, f, phnum, phdr, file_offset, sec_order);
2273 else
2274 tcc_output_binary(s1, f, sec_order);
2275 fclose(f);
2277 return 0;
2280 #ifndef ELF_OBJ_ONLY
2281 /* Sort section headers by assigned sh_addr, remove sections
2282 that we aren't going to output. */
2283 static void tidy_section_headers(TCCState *s1, int *sec_order)
2285 int i, nnew, l, *backmap;
2286 Section **snew, *s;
2287 ElfW(Sym) *sym;
2289 snew = tcc_malloc(s1->nb_sections * sizeof(snew[0]));
2290 backmap = tcc_malloc(s1->nb_sections * sizeof(backmap[0]));
2291 for (i = 0, nnew = 0, l = s1->nb_sections; i < s1->nb_sections; i++) {
2292 s = s1->sections[sec_order[i]];
2293 if (!i || s->sh_name) {
2294 backmap[sec_order[i]] = nnew;
2295 snew[nnew] = s;
2296 ++nnew;
2297 } else {
2298 backmap[sec_order[i]] = 0;
2299 snew[--l] = s;
2302 for (i = 0; i < nnew; i++) {
2303 s = snew[i];
2304 if (s) {
2305 s->sh_num = i;
2306 if (s->sh_type == SHT_RELX)
2307 s->sh_info = backmap[s->sh_info];
2311 for_each_elem(symtab_section, 1, sym, ElfW(Sym))
2312 if (sym->st_shndx != SHN_UNDEF && sym->st_shndx < SHN_LORESERVE)
2313 sym->st_shndx = backmap[sym->st_shndx];
2314 if( !s1->static_link ) {
2315 for_each_elem(s1->dynsym, 1, sym, ElfW(Sym))
2316 if (sym->st_shndx != SHN_UNDEF && sym->st_shndx < SHN_LORESERVE)
2317 sym->st_shndx = backmap[sym->st_shndx];
2319 for (i = 0; i < s1->nb_sections; i++)
2320 sec_order[i] = i;
2321 tcc_free(s1->sections);
2322 s1->sections = snew;
2323 s1->nb_sections = nnew;
2324 tcc_free(backmap);
2326 #endif
2328 /* Output an elf, coff or binary file */
2329 /* XXX: suppress unneeded sections */
2330 static int elf_output_file(TCCState *s1, const char *filename)
2332 int ret, phnum, shnum, file_type, file_offset, *sec_order;
2333 struct dyn_inf dyninf = {0};
2334 ElfW(Phdr) *phdr;
2335 Section *strsec, *interp, *dynamic, *dynstr;
2337 file_type = s1->output_type;
2338 s1->nb_errors = 0;
2339 ret = -1;
2340 phdr = NULL;
2341 sec_order = NULL;
2342 interp = dynamic = dynstr = NULL; /* avoid warning */
2344 #ifndef ELF_OBJ_ONLY
2345 if (file_type != TCC_OUTPUT_OBJ) {
2346 /* if linking, also link in runtime libraries (libc, libgcc, etc.) */
2347 tcc_add_runtime(s1);
2348 resolve_common_syms(s1);
2350 if (!s1->static_link) {
2351 if (file_type == TCC_OUTPUT_EXE) {
2352 char *ptr;
2353 /* allow override the dynamic loader */
2354 const char *elfint = getenv("LD_SO");
2355 if (elfint == NULL)
2356 elfint = DEFAULT_ELFINTERP(s1);
2357 /* add interpreter section only if executable */
2358 interp = new_section(s1, ".interp", SHT_PROGBITS, SHF_ALLOC);
2359 interp->sh_addralign = 1;
2360 ptr = section_ptr_add(interp, 1 + strlen(elfint));
2361 strcpy(ptr, elfint);
2364 /* add dynamic symbol table */
2365 s1->dynsym = new_symtab(s1, ".dynsym", SHT_DYNSYM, SHF_ALLOC,
2366 ".dynstr",
2367 ".hash", SHF_ALLOC);
2368 dynstr = s1->dynsym->link;
2369 /* add dynamic section */
2370 dynamic = new_section(s1, ".dynamic", SHT_DYNAMIC,
2371 SHF_ALLOC | SHF_WRITE);
2372 dynamic->link = dynstr;
2373 dynamic->sh_entsize = sizeof(ElfW(Dyn));
2375 build_got(s1);
2377 if (file_type == TCC_OUTPUT_EXE) {
2378 bind_exe_dynsyms(s1);
2379 if (s1->nb_errors)
2380 goto the_end;
2381 bind_libs_dynsyms(s1);
2382 } else {
2383 /* shared library case: simply export all global symbols */
2384 export_global_syms(s1);
2387 build_got_entries(s1);
2388 version_add (s1);
2390 #endif
2392 /* we add a section for symbols */
2393 strsec = new_section(s1, ".shstrtab", SHT_STRTAB, 0);
2394 put_elf_str(strsec, "");
2396 /* Allocate strings for section names */
2397 ret = alloc_sec_names(s1, file_type, strsec);
2399 #ifndef ELF_OBJ_ONLY
2400 if (dynamic) {
2401 int i;
2402 /* add a list of needed dlls */
2403 for(i = 0; i < s1->nb_loaded_dlls; i++) {
2404 DLLReference *dllref = s1->loaded_dlls[i];
2405 if (dllref->level == 0)
2406 put_dt(dynamic, DT_NEEDED, put_elf_str(dynstr, dllref->name));
2409 if (s1->rpath)
2410 put_dt(dynamic, s1->enable_new_dtags ? DT_RUNPATH : DT_RPATH,
2411 put_elf_str(dynstr, s1->rpath));
2413 if (file_type == TCC_OUTPUT_DLL) {
2414 if (s1->soname)
2415 put_dt(dynamic, DT_SONAME, put_elf_str(dynstr, s1->soname));
2416 /* XXX: currently, since we do not handle PIC code, we
2417 must relocate the readonly segments */
2418 if (ret)
2419 put_dt(dynamic, DT_TEXTREL, 0);
2422 if (s1->symbolic)
2423 put_dt(dynamic, DT_SYMBOLIC, 0);
2425 dyninf.dynamic = dynamic;
2426 dyninf.dynstr = dynstr;
2427 /* remember offset and reserve space for 2nd call below */
2428 dyninf.data_offset = dynamic->data_offset;
2429 fill_dynamic(s1, &dyninf);
2430 dynamic->sh_size = dynamic->data_offset;
2431 dynstr->sh_size = dynstr->data_offset;
2433 #endif
2435 /* compute number of program headers */
2436 if (file_type == TCC_OUTPUT_OBJ)
2437 phnum = 0;
2438 else if (file_type == TCC_OUTPUT_DLL)
2439 phnum = 3;
2440 else if (s1->static_link)
2441 phnum = 2;
2442 else
2443 phnum = 5;
2445 /* allocate program segment headers */
2446 phdr = tcc_mallocz(phnum * sizeof(ElfW(Phdr)));
2448 /* compute number of sections */
2449 shnum = s1->nb_sections;
2451 /* this array is used to reorder sections in the output file */
2452 sec_order = tcc_malloc(sizeof(int) * shnum);
2453 sec_order[0] = 0;
2455 /* compute section to program header mapping */
2456 file_offset = layout_sections(s1, phdr, phnum, interp, strsec, &dyninf,
2457 sec_order);
2459 #ifndef ELF_OBJ_ONLY
2460 /* Fill remaining program header and finalize relocation related to dynamic
2461 linking. */
2462 if (file_type != TCC_OUTPUT_OBJ) {
2463 fill_unloadable_phdr(phdr, phnum, interp, dynamic);
2464 if (dynamic) {
2465 ElfW(Sym) *sym;
2466 dynamic->data_offset = dyninf.data_offset;
2467 fill_dynamic(s1, &dyninf);
2469 /* put in GOT the dynamic section address and relocate PLT */
2470 write32le(s1->got->data, dynamic->sh_addr);
2471 if (file_type == TCC_OUTPUT_EXE
2472 || (RELOCATE_DLLPLT && file_type == TCC_OUTPUT_DLL))
2473 relocate_plt(s1);
2475 /* relocate symbols in .dynsym now that final addresses are known */
2476 for_each_elem(s1->dynsym, 1, sym, ElfW(Sym)) {
2477 if (sym->st_shndx != SHN_UNDEF && sym->st_shndx < SHN_LORESERVE) {
2478 /* do symbol relocation */
2479 sym->st_value += s1->sections[sym->st_shndx]->sh_addr;
2484 /* if building executable or DLL, then relocate each section
2485 except the GOT which is already relocated */
2486 ret = final_sections_reloc(s1);
2487 if (ret)
2488 goto the_end;
2489 tidy_section_headers(s1, sec_order);
2491 /* Perform relocation to GOT or PLT entries */
2492 if (file_type == TCC_OUTPUT_EXE && s1->static_link)
2493 fill_got(s1);
2494 else if (s1->got)
2495 fill_local_got_entries(s1);
2497 #endif
2499 /* Create the ELF file with name 'filename' */
2500 ret = tcc_write_elf_file(s1, filename, phnum, phdr, file_offset, sec_order);
2501 s1->nb_sections = shnum;
2502 goto the_end;
2503 the_end:
2504 tcc_free(sec_order);
2505 tcc_free(phdr);
2506 return ret;
2509 LIBTCCAPI int tcc_output_file(TCCState *s, const char *filename)
2511 int ret;
2512 #ifdef TCC_TARGET_PE
2513 if (s->output_type != TCC_OUTPUT_OBJ) {
2514 ret = pe_output_file(s, filename);
2515 } else
2516 #elif TCC_TARGET_MACHO
2517 if (s->output_type != TCC_OUTPUT_OBJ) {
2518 ret = macho_output_file(s, filename);
2519 } else
2520 #endif
2521 ret = elf_output_file(s, filename);
2522 return ret;
2525 ssize_t full_read(int fd, void *buf, size_t count) {
2526 char *cbuf = buf;
2527 size_t rnum = 0;
2528 while (1) {
2529 ssize_t num = read(fd, cbuf, count-rnum);
2530 if (num < 0) return num;
2531 if (num == 0) return rnum;
2532 rnum += num;
2533 cbuf += num;
2537 static void *load_data(int fd, unsigned long file_offset, unsigned long size)
2539 void *data;
2541 data = tcc_malloc(size);
2542 lseek(fd, file_offset, SEEK_SET);
2543 full_read(fd, data, size);
2544 return data;
2547 typedef struct SectionMergeInfo {
2548 Section *s; /* corresponding existing section */
2549 unsigned long offset; /* offset of the new section in the existing section */
2550 uint8_t new_section; /* true if section 's' was added */
2551 uint8_t link_once; /* true if link once section */
2552 } SectionMergeInfo;
2554 ST_FUNC int tcc_object_type(int fd, ElfW(Ehdr) *h)
2556 int size = full_read(fd, h, sizeof *h);
2557 if (size == sizeof *h && 0 == memcmp(h, ELFMAG, 4)) {
2558 if (h->e_type == ET_REL)
2559 return AFF_BINTYPE_REL;
2560 if (h->e_type == ET_DYN)
2561 return AFF_BINTYPE_DYN;
2562 } else if (size >= 8) {
2563 if (0 == memcmp(h, ARMAG, 8))
2564 return AFF_BINTYPE_AR;
2565 #ifdef TCC_TARGET_COFF
2566 if (((struct filehdr*)h)->f_magic == COFF_C67_MAGIC)
2567 return AFF_BINTYPE_C67;
2568 #endif
2570 return 0;
2573 /* load an object file and merge it with current files */
2574 /* XXX: handle correctly stab (debug) info */
2575 ST_FUNC int tcc_load_object_file(TCCState *s1,
2576 int fd, unsigned long file_offset)
2578 ElfW(Ehdr) ehdr;
2579 ElfW(Shdr) *shdr, *sh;
2580 int size, i, j, offset, offseti, nb_syms, sym_index, ret, seencompressed;
2581 char *strsec, *strtab;
2582 int stab_index, stabstr_index;
2583 int *old_to_new_syms;
2584 char *sh_name, *name;
2585 SectionMergeInfo *sm_table, *sm;
2586 ElfW(Sym) *sym, *symtab;
2587 ElfW_Rel *rel;
2588 Section *s;
2590 lseek(fd, file_offset, SEEK_SET);
2591 if (tcc_object_type(fd, &ehdr) != AFF_BINTYPE_REL)
2592 goto fail1;
2593 /* test CPU specific stuff */
2594 if (ehdr.e_ident[5] != ELFDATA2LSB ||
2595 ehdr.e_machine != EM_TCC_TARGET) {
2596 fail1:
2597 tcc_error_noabort("invalid object file");
2598 return -1;
2600 /* read sections */
2601 shdr = load_data(fd, file_offset + ehdr.e_shoff,
2602 sizeof(ElfW(Shdr)) * ehdr.e_shnum);
2603 sm_table = tcc_mallocz(sizeof(SectionMergeInfo) * ehdr.e_shnum);
2605 /* load section names */
2606 sh = &shdr[ehdr.e_shstrndx];
2607 strsec = load_data(fd, file_offset + sh->sh_offset, sh->sh_size);
2609 /* load symtab and strtab */
2610 old_to_new_syms = NULL;
2611 symtab = NULL;
2612 strtab = NULL;
2613 nb_syms = 0;
2614 seencompressed = 0;
2615 stab_index = stabstr_index = 0;
2617 for(i = 1; i < ehdr.e_shnum; i++) {
2618 sh = &shdr[i];
2619 if (sh->sh_type == SHT_SYMTAB) {
2620 if (symtab) {
2621 tcc_error_noabort("object must contain only one symtab");
2622 fail:
2623 ret = -1;
2624 goto the_end;
2626 nb_syms = sh->sh_size / sizeof(ElfW(Sym));
2627 symtab = load_data(fd, file_offset + sh->sh_offset, sh->sh_size);
2628 sm_table[i].s = symtab_section;
2630 /* now load strtab */
2631 sh = &shdr[sh->sh_link];
2632 strtab = load_data(fd, file_offset + sh->sh_offset, sh->sh_size);
2634 if (sh->sh_flags & SHF_COMPRESSED)
2635 seencompressed = 1;
2638 /* now examine each section and try to merge its content with the
2639 ones in memory */
2640 for(i = 1; i < ehdr.e_shnum; i++) {
2641 /* no need to examine section name strtab */
2642 if (i == ehdr.e_shstrndx)
2643 continue;
2644 sh = &shdr[i];
2645 if (sh->sh_type == SHT_RELX)
2646 sh = &shdr[sh->sh_info];
2647 /* ignore sections types we do not handle (plus relocs to those) */
2648 if (sh->sh_type != SHT_PROGBITS &&
2649 #ifdef TCC_ARM_EABI
2650 sh->sh_type != SHT_ARM_EXIDX &&
2651 #endif
2652 sh->sh_type != SHT_NOBITS &&
2653 sh->sh_type != SHT_PREINIT_ARRAY &&
2654 sh->sh_type != SHT_INIT_ARRAY &&
2655 sh->sh_type != SHT_FINI_ARRAY &&
2656 strcmp(strsec + sh->sh_name, ".stabstr")
2658 continue;
2659 if (seencompressed
2660 && !strncmp(strsec + sh->sh_name, ".debug_", sizeof(".debug_")-1))
2661 continue;
2663 sh = &shdr[i];
2664 sh_name = strsec + sh->sh_name;
2665 if (sh->sh_addralign < 1)
2666 sh->sh_addralign = 1;
2667 /* find corresponding section, if any */
2668 for(j = 1; j < s1->nb_sections;j++) {
2669 s = s1->sections[j];
2670 if (!strcmp(s->name, sh_name)) {
2671 if (!strncmp(sh_name, ".gnu.linkonce",
2672 sizeof(".gnu.linkonce") - 1)) {
2673 /* if a 'linkonce' section is already present, we
2674 do not add it again. It is a little tricky as
2675 symbols can still be defined in
2676 it. */
2677 sm_table[i].link_once = 1;
2678 goto next;
2680 if (stab_section) {
2681 if (s == stab_section)
2682 stab_index = i;
2683 if (s == stab_section->link)
2684 stabstr_index = i;
2686 goto found;
2689 /* not found: create new section */
2690 s = new_section(s1, sh_name, sh->sh_type, sh->sh_flags & ~SHF_GROUP);
2691 /* take as much info as possible from the section. sh_link and
2692 sh_info will be updated later */
2693 s->sh_addralign = sh->sh_addralign;
2694 s->sh_entsize = sh->sh_entsize;
2695 sm_table[i].new_section = 1;
2696 found:
2697 if (sh->sh_type != s->sh_type) {
2698 tcc_error_noabort("invalid section type");
2699 goto fail;
2701 /* align start of section */
2702 s->data_offset += -s->data_offset & (sh->sh_addralign - 1);
2703 if (sh->sh_addralign > s->sh_addralign)
2704 s->sh_addralign = sh->sh_addralign;
2705 sm_table[i].offset = s->data_offset;
2706 sm_table[i].s = s;
2707 /* concatenate sections */
2708 size = sh->sh_size;
2709 if (sh->sh_type != SHT_NOBITS) {
2710 unsigned char *ptr;
2711 lseek(fd, file_offset + sh->sh_offset, SEEK_SET);
2712 ptr = section_ptr_add(s, size);
2713 full_read(fd, ptr, size);
2714 } else {
2715 s->data_offset += size;
2717 next: ;
2720 /* gr relocate stab strings */
2721 if (stab_index && stabstr_index) {
2722 Stab_Sym *a, *b;
2723 unsigned o;
2724 s = sm_table[stab_index].s;
2725 a = (Stab_Sym *)(s->data + sm_table[stab_index].offset);
2726 b = (Stab_Sym *)(s->data + s->data_offset);
2727 o = sm_table[stabstr_index].offset;
2728 while (a < b) {
2729 if (a->n_strx)
2730 a->n_strx += o;
2731 a++;
2735 /* second short pass to update sh_link and sh_info fields of new
2736 sections */
2737 for(i = 1; i < ehdr.e_shnum; i++) {
2738 s = sm_table[i].s;
2739 if (!s || !sm_table[i].new_section)
2740 continue;
2741 sh = &shdr[i];
2742 if (sh->sh_link > 0)
2743 s->link = sm_table[sh->sh_link].s;
2744 if (sh->sh_type == SHT_RELX) {
2745 s->sh_info = sm_table[sh->sh_info].s->sh_num;
2746 /* update backward link */
2747 s1->sections[s->sh_info]->reloc = s;
2751 /* resolve symbols */
2752 old_to_new_syms = tcc_mallocz(nb_syms * sizeof(int));
2754 sym = symtab + 1;
2755 for(i = 1; i < nb_syms; i++, sym++) {
2756 if (sym->st_shndx != SHN_UNDEF &&
2757 sym->st_shndx < SHN_LORESERVE) {
2758 sm = &sm_table[sym->st_shndx];
2759 if (sm->link_once) {
2760 /* if a symbol is in a link once section, we use the
2761 already defined symbol. It is very important to get
2762 correct relocations */
2763 if (ELFW(ST_BIND)(sym->st_info) != STB_LOCAL) {
2764 name = strtab + sym->st_name;
2765 sym_index = find_elf_sym(symtab_section, name);
2766 if (sym_index)
2767 old_to_new_syms[i] = sym_index;
2769 continue;
2771 /* if no corresponding section added, no need to add symbol */
2772 if (!sm->s)
2773 continue;
2774 /* convert section number */
2775 sym->st_shndx = sm->s->sh_num;
2776 /* offset value */
2777 sym->st_value += sm->offset;
2779 /* add symbol */
2780 name = strtab + sym->st_name;
2781 sym_index = set_elf_sym(symtab_section, sym->st_value, sym->st_size,
2782 sym->st_info, sym->st_other,
2783 sym->st_shndx, name);
2784 old_to_new_syms[i] = sym_index;
2787 /* third pass to patch relocation entries */
2788 for(i = 1; i < ehdr.e_shnum; i++) {
2789 s = sm_table[i].s;
2790 if (!s)
2791 continue;
2792 sh = &shdr[i];
2793 offset = sm_table[i].offset;
2794 switch(s->sh_type) {
2795 case SHT_RELX:
2796 /* take relocation offset information */
2797 offseti = sm_table[sh->sh_info].offset;
2798 for_each_elem(s, (offset / sizeof(*rel)), rel, ElfW_Rel) {
2799 int type;
2800 unsigned sym_index;
2801 /* convert symbol index */
2802 type = ELFW(R_TYPE)(rel->r_info);
2803 sym_index = ELFW(R_SYM)(rel->r_info);
2804 /* NOTE: only one symtab assumed */
2805 if (sym_index >= nb_syms)
2806 goto invalid_reloc;
2807 sym_index = old_to_new_syms[sym_index];
2808 /* ignore link_once in rel section. */
2809 if (!sym_index && !sm_table[sh->sh_info].link_once
2810 #ifdef TCC_TARGET_ARM
2811 && type != R_ARM_V4BX
2812 #elif defined TCC_TARGET_RISCV64
2813 && type != R_RISCV_ALIGN
2814 && type != R_RISCV_RELAX
2815 #endif
2817 invalid_reloc:
2818 tcc_error_noabort("Invalid relocation entry [%2d] '%s' @ %.8x",
2819 i, strsec + sh->sh_name, (int)rel->r_offset);
2820 goto fail;
2822 rel->r_info = ELFW(R_INFO)(sym_index, type);
2823 /* offset the relocation offset */
2824 rel->r_offset += offseti;
2825 #ifdef TCC_TARGET_ARM
2826 /* Jumps and branches from a Thumb code to a PLT entry need
2827 special handling since PLT entries are ARM code.
2828 Unconditional bl instructions referencing PLT entries are
2829 handled by converting these instructions into blx
2830 instructions. Other case of instructions referencing a PLT
2831 entry require to add a Thumb stub before the PLT entry to
2832 switch to ARM mode. We set bit plt_thumb_stub of the
2833 attribute of a symbol to indicate such a case. */
2834 if (type == R_ARM_THM_JUMP24)
2835 get_sym_attr(s1, sym_index, 1)->plt_thumb_stub = 1;
2836 #endif
2838 break;
2839 default:
2840 break;
2844 ret = 0;
2845 the_end:
2846 tcc_free(symtab);
2847 tcc_free(strtab);
2848 tcc_free(old_to_new_syms);
2849 tcc_free(sm_table);
2850 tcc_free(strsec);
2851 tcc_free(shdr);
2852 return ret;
2855 typedef struct ArchiveHeader {
2856 char ar_name[16]; /* name of this member */
2857 char ar_date[12]; /* file mtime */
2858 char ar_uid[6]; /* owner uid; printed as decimal */
2859 char ar_gid[6]; /* owner gid; printed as decimal */
2860 char ar_mode[8]; /* file mode, printed as octal */
2861 char ar_size[10]; /* file size, printed as decimal */
2862 char ar_fmag[2]; /* should contain ARFMAG */
2863 } ArchiveHeader;
2865 #define ARFMAG "`\n"
2867 static unsigned long long get_be(const uint8_t *b, int n)
2869 unsigned long long ret = 0;
2870 while (n)
2871 ret = (ret << 8) | *b++, --n;
2872 return ret;
2875 static int read_ar_header(int fd, int offset, ArchiveHeader *hdr)
2877 char *p, *e;
2878 int len;
2879 lseek(fd, offset, SEEK_SET);
2880 len = full_read(fd, hdr, sizeof(ArchiveHeader));
2881 if (len != sizeof(ArchiveHeader))
2882 return len ? -1 : 0;
2883 p = hdr->ar_name;
2884 for (e = p + sizeof hdr->ar_name; e > p && e[-1] == ' ';)
2885 --e;
2886 *e = '\0';
2887 hdr->ar_size[sizeof hdr->ar_size-1] = 0;
2888 return len;
2891 /* load only the objects which resolve undefined symbols */
2892 static int tcc_load_alacarte(TCCState *s1, int fd, int size, int entrysize)
2894 int i, bound, nsyms, sym_index, len, ret = -1;
2895 unsigned long long off;
2896 uint8_t *data;
2897 const char *ar_names, *p;
2898 const uint8_t *ar_index;
2899 ElfW(Sym) *sym;
2900 ArchiveHeader hdr;
2902 data = tcc_malloc(size);
2903 if (full_read(fd, data, size) != size)
2904 goto the_end;
2905 nsyms = get_be(data, entrysize);
2906 ar_index = data + entrysize;
2907 ar_names = (char *) ar_index + nsyms * entrysize;
2909 do {
2910 bound = 0;
2911 for (p = ar_names, i = 0; i < nsyms; i++, p += strlen(p)+1) {
2912 Section *s = symtab_section;
2913 sym_index = find_elf_sym(s, p);
2914 if (!sym_index)
2915 continue;
2916 sym = &((ElfW(Sym) *)s->data)[sym_index];
2917 if(sym->st_shndx != SHN_UNDEF)
2918 continue;
2919 off = get_be(ar_index + i * entrysize, entrysize);
2920 len = read_ar_header(fd, off, &hdr);
2921 if (len <= 0 || memcmp(hdr.ar_fmag, ARFMAG, 2)) {
2922 tcc_error_noabort("invalid archive");
2923 goto the_end;
2925 off += len;
2926 if (s1->verbose == 2)
2927 printf(" -> %s\n", hdr.ar_name);
2928 if (tcc_load_object_file(s1, fd, off) < 0)
2929 goto the_end;
2930 ++bound;
2932 } while(bound);
2933 ret = 0;
2934 the_end:
2935 tcc_free(data);
2936 return ret;
2939 /* load a '.a' file */
2940 ST_FUNC int tcc_load_archive(TCCState *s1, int fd, int alacarte)
2942 ArchiveHeader hdr;
2943 /* char magic[8]; */
2944 int size, len;
2945 unsigned long file_offset;
2946 ElfW(Ehdr) ehdr;
2948 /* skip magic which was already checked */
2949 /* full_read(fd, magic, sizeof(magic)); */
2950 file_offset = sizeof ARMAG - 1;
2952 for(;;) {
2953 len = read_ar_header(fd, file_offset, &hdr);
2954 if (len == 0)
2955 return 0;
2956 if (len < 0) {
2957 tcc_error_noabort("invalid archive");
2958 return -1;
2960 file_offset += len;
2961 size = strtol(hdr.ar_size, NULL, 0);
2962 /* align to even */
2963 size = (size + 1) & ~1;
2964 if (alacarte) {
2965 /* coff symbol table : we handle it */
2966 if (!strcmp(hdr.ar_name, "/"))
2967 return tcc_load_alacarte(s1, fd, size, 4);
2968 if (!strcmp(hdr.ar_name, "/SYM64/"))
2969 return tcc_load_alacarte(s1, fd, size, 8);
2970 } else if (tcc_object_type(fd, &ehdr) == AFF_BINTYPE_REL) {
2971 if (s1->verbose == 2)
2972 printf(" -> %s\n", hdr.ar_name);
2973 if (tcc_load_object_file(s1, fd, file_offset) < 0)
2974 return -1;
2976 file_offset += size;
2980 #ifndef ELF_OBJ_ONLY
2981 /* Set LV[I] to the global index of sym-version (LIB,VERSION). Maybe resizes
2982 LV, maybe create a new entry for (LIB,VERSION). */
2983 static void set_ver_to_ver(TCCState *s1, int *n, int **lv, int i, char *lib, char *version)
2985 while (i >= *n) {
2986 *lv = tcc_realloc(*lv, (*n + 1) * sizeof(**lv));
2987 (*lv)[(*n)++] = -1;
2989 if ((*lv)[i] == -1) {
2990 int v, prev_same_lib = -1;
2991 for (v = 0; v < nb_sym_versions; v++) {
2992 if (strcmp(sym_versions[v].lib, lib))
2993 continue;
2994 prev_same_lib = v;
2995 if (!strcmp(sym_versions[v].version, version))
2996 break;
2998 if (v == nb_sym_versions) {
2999 sym_versions = tcc_realloc (sym_versions,
3000 (v + 1) * sizeof(*sym_versions));
3001 sym_versions[v].lib = tcc_strdup(lib);
3002 sym_versions[v].version = tcc_strdup(version);
3003 sym_versions[v].out_index = 0;
3004 sym_versions[v].prev_same_lib = prev_same_lib;
3005 nb_sym_versions++;
3007 (*lv)[i] = v;
3011 /* Associates symbol SYM_INDEX (in dynsymtab) with sym-version index
3012 VERNDX. */
3013 static void
3014 set_sym_version(TCCState *s1, int sym_index, int verndx)
3016 if (sym_index >= nb_sym_to_version) {
3017 int newelems = sym_index ? sym_index * 2 : 1;
3018 sym_to_version = tcc_realloc(sym_to_version,
3019 newelems * sizeof(*sym_to_version));
3020 memset(sym_to_version + nb_sym_to_version, -1,
3021 (newelems - nb_sym_to_version) * sizeof(*sym_to_version));
3022 nb_sym_to_version = newelems;
3024 if (sym_to_version[sym_index] < 0)
3025 sym_to_version[sym_index] = verndx;
3028 struct versym_info {
3029 int nb_versyms;
3030 ElfW(Verdef) *verdef;
3031 ElfW(Verneed) *verneed;
3032 ElfW(Half) *versym;
3033 int nb_local_ver, *local_ver;
3037 static void store_version(TCCState *s1, struct versym_info *v, char *dynstr)
3039 char *lib, *version;
3040 uint32_t next;
3041 int i;
3043 #define DEBUG_VERSION 0
3045 if (v->versym && v->verdef) {
3046 ElfW(Verdef) *vdef = v->verdef;
3047 lib = NULL;
3048 do {
3049 ElfW(Verdaux) *verdaux =
3050 (ElfW(Verdaux) *) (((char *) vdef) + vdef->vd_aux);
3052 #if DEBUG_VERSION
3053 printf ("verdef: version:%u flags:%u index:%u, hash:%u\n",
3054 vdef->vd_version, vdef->vd_flags, vdef->vd_ndx,
3055 vdef->vd_hash);
3056 #endif
3057 if (vdef->vd_cnt) {
3058 version = dynstr + verdaux->vda_name;
3060 if (lib == NULL)
3061 lib = version;
3062 else
3063 set_ver_to_ver(s1, &v->nb_local_ver, &v->local_ver, vdef->vd_ndx,
3064 lib, version);
3065 #if DEBUG_VERSION
3066 printf (" verdaux(%u): %s\n", vdef->vd_ndx, version);
3067 #endif
3069 next = vdef->vd_next;
3070 vdef = (ElfW(Verdef) *) (((char *) vdef) + next);
3071 } while (next);
3073 if (v->versym && v->verneed) {
3074 ElfW(Verneed) *vneed = v->verneed;
3075 do {
3076 ElfW(Vernaux) *vernaux =
3077 (ElfW(Vernaux) *) (((char *) vneed) + vneed->vn_aux);
3079 lib = dynstr + vneed->vn_file;
3080 #if DEBUG_VERSION
3081 printf ("verneed: %u %s\n", vneed->vn_version, lib);
3082 #endif
3083 for (i = 0; i < vneed->vn_cnt; i++) {
3084 if ((vernaux->vna_other & 0x8000) == 0) { /* hidden */
3085 version = dynstr + vernaux->vna_name;
3086 set_ver_to_ver(s1, &v->nb_local_ver, &v->local_ver, vernaux->vna_other,
3087 lib, version);
3088 #if DEBUG_VERSION
3089 printf (" vernaux(%u): %u %u %s\n",
3090 vernaux->vna_other, vernaux->vna_hash,
3091 vernaux->vna_flags, version);
3092 #endif
3094 vernaux = (ElfW(Vernaux) *) (((char *) vernaux) + vernaux->vna_next);
3096 next = vneed->vn_next;
3097 vneed = (ElfW(Verneed) *) (((char *) vneed) + next);
3098 } while (next);
3101 #if DEBUG_VERSION
3102 for (i = 0; i < v->nb_local_ver; i++) {
3103 if (v->local_ver[i] > 0) {
3104 printf ("%d: lib: %s, version %s\n",
3105 i, sym_versions[v->local_ver[i]].lib,
3106 sym_versions[v->local_ver[i]].version);
3109 #endif
3112 /* load a DLL and all referenced DLLs. 'level = 0' means that the DLL
3113 is referenced by the user (so it should be added as DT_NEEDED in
3114 the generated ELF file) */
3115 ST_FUNC int tcc_load_dll(TCCState *s1, int fd, const char *filename, int level)
3117 ElfW(Ehdr) ehdr;
3118 ElfW(Shdr) *shdr, *sh, *sh1;
3119 int i, j, nb_syms, nb_dts, sym_bind, ret;
3120 ElfW(Sym) *sym, *dynsym;
3121 ElfW(Dyn) *dt, *dynamic;
3123 char *dynstr;
3124 int sym_index;
3125 const char *name, *soname;
3126 DLLReference *dllref;
3127 struct versym_info v;
3129 full_read(fd, &ehdr, sizeof(ehdr));
3131 /* test CPU specific stuff */
3132 if (ehdr.e_ident[5] != ELFDATA2LSB ||
3133 ehdr.e_machine != EM_TCC_TARGET) {
3134 tcc_error_noabort("bad architecture");
3135 return -1;
3138 /* read sections */
3139 shdr = load_data(fd, ehdr.e_shoff, sizeof(ElfW(Shdr)) * ehdr.e_shnum);
3141 /* load dynamic section and dynamic symbols */
3142 nb_syms = 0;
3143 nb_dts = 0;
3144 dynamic = NULL;
3145 dynsym = NULL; /* avoid warning */
3146 dynstr = NULL; /* avoid warning */
3147 memset(&v, 0, sizeof v);
3149 for(i = 0, sh = shdr; i < ehdr.e_shnum; i++, sh++) {
3150 switch(sh->sh_type) {
3151 case SHT_DYNAMIC:
3152 nb_dts = sh->sh_size / sizeof(ElfW(Dyn));
3153 dynamic = load_data(fd, sh->sh_offset, sh->sh_size);
3154 break;
3155 case SHT_DYNSYM:
3156 nb_syms = sh->sh_size / sizeof(ElfW(Sym));
3157 dynsym = load_data(fd, sh->sh_offset, sh->sh_size);
3158 sh1 = &shdr[sh->sh_link];
3159 dynstr = load_data(fd, sh1->sh_offset, sh1->sh_size);
3160 break;
3161 case SHT_GNU_verdef:
3162 v.verdef = load_data(fd, sh->sh_offset, sh->sh_size);
3163 break;
3164 case SHT_GNU_verneed:
3165 v.verneed = load_data(fd, sh->sh_offset, sh->sh_size);
3166 break;
3167 case SHT_GNU_versym:
3168 v.nb_versyms = sh->sh_size / sizeof(ElfW(Half));
3169 v.versym = load_data(fd, sh->sh_offset, sh->sh_size);
3170 break;
3171 default:
3172 break;
3176 /* compute the real library name */
3177 soname = tcc_basename(filename);
3179 for(i = 0, dt = dynamic; i < nb_dts; i++, dt++) {
3180 if (dt->d_tag == DT_SONAME) {
3181 soname = dynstr + dt->d_un.d_val;
3185 /* if the dll is already loaded, do not load it */
3186 for(i = 0; i < s1->nb_loaded_dlls; i++) {
3187 dllref = s1->loaded_dlls[i];
3188 if (!strcmp(soname, dllref->name)) {
3189 /* but update level if needed */
3190 if (level < dllref->level)
3191 dllref->level = level;
3192 ret = 0;
3193 goto the_end;
3197 if (v.nb_versyms != nb_syms)
3198 tcc_free (v.versym), v.versym = NULL;
3199 else
3200 store_version(s1, &v, dynstr);
3202 /* add the dll and its level */
3203 dllref = tcc_mallocz(sizeof(DLLReference) + strlen(soname));
3204 dllref->level = level;
3205 strcpy(dllref->name, soname);
3206 dynarray_add(&s1->loaded_dlls, &s1->nb_loaded_dlls, dllref);
3208 /* add dynamic symbols in dynsym_section */
3209 for(i = 1, sym = dynsym + 1; i < nb_syms; i++, sym++) {
3210 sym_bind = ELFW(ST_BIND)(sym->st_info);
3211 if (sym_bind == STB_LOCAL)
3212 continue;
3213 name = dynstr + sym->st_name;
3214 sym_index = set_elf_sym(s1->dynsymtab_section, sym->st_value, sym->st_size,
3215 sym->st_info, sym->st_other, sym->st_shndx, name);
3216 if (v.versym) {
3217 ElfW(Half) vsym = v.versym[i];
3218 if ((vsym & 0x8000) == 0 && vsym > 0 && vsym < v.nb_local_ver)
3219 set_sym_version(s1, sym_index, v.local_ver[vsym]);
3223 /* load all referenced DLLs */
3224 for(i = 0, dt = dynamic; i < nb_dts; i++, dt++) {
3225 switch(dt->d_tag) {
3226 case DT_NEEDED:
3227 name = dynstr + dt->d_un.d_val;
3228 for(j = 0; j < s1->nb_loaded_dlls; j++) {
3229 dllref = s1->loaded_dlls[j];
3230 if (!strcmp(name, dllref->name))
3231 goto already_loaded;
3233 if (tcc_add_dll(s1, name, AFF_REFERENCED_DLL) < 0) {
3234 tcc_error_noabort("referenced dll '%s' not found", name);
3235 ret = -1;
3236 goto the_end;
3238 already_loaded:
3239 break;
3242 ret = 0;
3243 the_end:
3244 tcc_free(dynstr);
3245 tcc_free(dynsym);
3246 tcc_free(dynamic);
3247 tcc_free(shdr);
3248 tcc_free(v.local_ver);
3249 tcc_free(v.verdef);
3250 tcc_free(v.verneed);
3251 tcc_free(v.versym);
3252 return ret;
3255 #define LD_TOK_NAME 256
3256 #define LD_TOK_EOF (-1)
3258 static int ld_inp(TCCState *s1)
3260 char b;
3261 if (s1->cc != -1) {
3262 int c = s1->cc;
3263 s1->cc = -1;
3264 return c;
3266 if (1 == read(s1->fd, &b, 1))
3267 return b;
3268 return CH_EOF;
3271 /* return next ld script token */
3272 static int ld_next(TCCState *s1, char *name, int name_size)
3274 int c, d, ch;
3275 char *q;
3277 redo:
3278 ch = ld_inp(s1);
3279 switch(ch) {
3280 case ' ':
3281 case '\t':
3282 case '\f':
3283 case '\v':
3284 case '\r':
3285 case '\n':
3286 goto redo;
3287 case '/':
3288 ch = ld_inp(s1);
3289 if (ch == '*') { /* comment */
3290 for (d = 0;; d = ch) {
3291 ch = ld_inp(s1);
3292 if (ch == CH_EOF || (ch == '/' && d == '*'))
3293 break;
3295 goto redo;
3296 } else {
3297 q = name;
3298 *q++ = '/';
3299 goto parse_name;
3301 break;
3302 case '\\':
3303 /* case 'a' ... 'z': */
3304 case 'a':
3305 case 'b':
3306 case 'c':
3307 case 'd':
3308 case 'e':
3309 case 'f':
3310 case 'g':
3311 case 'h':
3312 case 'i':
3313 case 'j':
3314 case 'k':
3315 case 'l':
3316 case 'm':
3317 case 'n':
3318 case 'o':
3319 case 'p':
3320 case 'q':
3321 case 'r':
3322 case 's':
3323 case 't':
3324 case 'u':
3325 case 'v':
3326 case 'w':
3327 case 'x':
3328 case 'y':
3329 case 'z':
3330 /* case 'A' ... 'z': */
3331 case 'A':
3332 case 'B':
3333 case 'C':
3334 case 'D':
3335 case 'E':
3336 case 'F':
3337 case 'G':
3338 case 'H':
3339 case 'I':
3340 case 'J':
3341 case 'K':
3342 case 'L':
3343 case 'M':
3344 case 'N':
3345 case 'O':
3346 case 'P':
3347 case 'Q':
3348 case 'R':
3349 case 'S':
3350 case 'T':
3351 case 'U':
3352 case 'V':
3353 case 'W':
3354 case 'X':
3355 case 'Y':
3356 case 'Z':
3357 case '_':
3358 case '.':
3359 case '$':
3360 case '~':
3361 q = name;
3362 parse_name:
3363 for(;;) {
3364 if (!((ch >= 'a' && ch <= 'z') ||
3365 (ch >= 'A' && ch <= 'Z') ||
3366 (ch >= '0' && ch <= '9') ||
3367 strchr("/.-_+=$:\\,~", ch)))
3368 break;
3369 if ((q - name) < name_size - 1) {
3370 *q++ = ch;
3372 ch = ld_inp(s1);
3374 s1->cc = ch;
3375 *q = '\0';
3376 c = LD_TOK_NAME;
3377 break;
3378 case CH_EOF:
3379 c = LD_TOK_EOF;
3380 break;
3381 default:
3382 c = ch;
3383 break;
3385 return c;
3388 static int ld_add_file(TCCState *s1, const char filename[])
3390 if (filename[0] == '/') {
3391 if (CONFIG_SYSROOT[0] == '\0'
3392 && tcc_add_file_internal(s1, filename, AFF_TYPE_BIN) == 0)
3393 return 0;
3394 filename = tcc_basename(filename);
3396 return tcc_add_dll(s1, filename, 0);
3399 static int ld_add_file_list(TCCState *s1, const char *cmd, int as_needed)
3401 char filename[1024], libname[1024];
3402 int t, group, nblibs = 0, ret = 0;
3403 char **libs = NULL;
3405 group = !strcmp(cmd, "GROUP");
3406 if (!as_needed)
3407 s1->new_undef_sym = 0;
3408 t = ld_next(s1, filename, sizeof(filename));
3409 if (t != '(') {
3410 tcc_error_noabort("( expected");
3411 ret = -1;
3412 goto lib_parse_error;
3414 t = ld_next(s1, filename, sizeof(filename));
3415 for(;;) {
3416 libname[0] = '\0';
3417 if (t == LD_TOK_EOF) {
3418 tcc_error_noabort("unexpected end of file");
3419 ret = -1;
3420 goto lib_parse_error;
3421 } else if (t == ')') {
3422 break;
3423 } else if (t == '-') {
3424 t = ld_next(s1, filename, sizeof(filename));
3425 if ((t != LD_TOK_NAME) || (filename[0] != 'l')) {
3426 tcc_error_noabort("library name expected");
3427 ret = -1;
3428 goto lib_parse_error;
3430 pstrcpy(libname, sizeof libname, &filename[1]);
3431 if (s1->static_link) {
3432 snprintf(filename, sizeof filename, "lib%s.a", libname);
3433 } else {
3434 snprintf(filename, sizeof filename, "lib%s.so", libname);
3436 } else if (t != LD_TOK_NAME) {
3437 tcc_error_noabort("filename expected");
3438 ret = -1;
3439 goto lib_parse_error;
3441 if (!strcmp(filename, "AS_NEEDED")) {
3442 ret = ld_add_file_list(s1, cmd, 1);
3443 if (ret)
3444 goto lib_parse_error;
3445 } else {
3446 /* TODO: Implement AS_NEEDED support. Ignore it for now */
3447 if (!as_needed) {
3448 ret = ld_add_file(s1, filename);
3449 if (ret)
3450 goto lib_parse_error;
3451 if (group) {
3452 /* Add the filename *and* the libname to avoid future conversions */
3453 dynarray_add(&libs, &nblibs, tcc_strdup(filename));
3454 if (libname[0] != '\0')
3455 dynarray_add(&libs, &nblibs, tcc_strdup(libname));
3459 t = ld_next(s1, filename, sizeof(filename));
3460 if (t == ',') {
3461 t = ld_next(s1, filename, sizeof(filename));
3464 if (group && !as_needed) {
3465 while (s1->new_undef_sym) {
3466 int i;
3467 s1->new_undef_sym = 0;
3468 for (i = 0; i < nblibs; i ++)
3469 ld_add_file(s1, libs[i]);
3472 lib_parse_error:
3473 dynarray_reset(&libs, &nblibs);
3474 return ret;
3477 /* interpret a subset of GNU ldscripts to handle the dummy libc.so
3478 files */
3479 ST_FUNC int tcc_load_ldscript(TCCState *s1, int fd)
3481 char cmd[64];
3482 char filename[1024];
3483 int t, ret;
3485 s1->fd = fd;
3486 s1->cc = -1;
3487 for(;;) {
3488 t = ld_next(s1, cmd, sizeof(cmd));
3489 if (t == LD_TOK_EOF)
3490 return 0;
3491 else if (t != LD_TOK_NAME)
3492 return -1;
3493 if (!strcmp(cmd, "INPUT") ||
3494 !strcmp(cmd, "GROUP")) {
3495 ret = ld_add_file_list(s1, cmd, 0);
3496 if (ret)
3497 return ret;
3498 } else if (!strcmp(cmd, "OUTPUT_FORMAT") ||
3499 !strcmp(cmd, "TARGET")) {
3500 /* ignore some commands */
3501 t = ld_next(s1, cmd, sizeof(cmd));
3502 if (t != '(') {
3503 tcc_error_noabort("( expected");
3504 return -1;
3506 for(;;) {
3507 t = ld_next(s1, filename, sizeof(filename));
3508 if (t == LD_TOK_EOF) {
3509 tcc_error_noabort("unexpected end of file");
3510 return -1;
3511 } else if (t == ')') {
3512 break;
3515 } else {
3516 return -1;
3519 return 0;
3521 #endif /* !ELF_OBJ_ONLY */