x86-asm: Correct register size for pointer ops
[tinycc.git] / tccelf.c
blobc97d742389a358d523e0471da9495145d21a086f
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 ST_DATA Section *text_section, *data_section, *bss_section; /* predefined sections */
30 ST_DATA Section *cur_text_section; /* current section where function code is generated */
31 #ifdef CONFIG_TCC_ASM
32 ST_DATA Section *last_text_section; /* to handle .previous asm directive */
33 #endif
34 #ifdef CONFIG_TCC_BCHECK
35 /* bound check related sections */
36 ST_DATA Section *bounds_section; /* contains global data bound description */
37 ST_DATA Section *lbounds_section; /* contains local data bound description */
38 #endif
39 /* symbol sections */
40 ST_DATA Section *symtab_section, *strtab_section;
41 /* debug sections */
42 ST_DATA Section *stab_section, *stabstr_section;
44 /* XXX: avoid static variable */
45 static int new_undef_sym = 0; /* Is there a new undefined sym since last new_undef_sym() */
47 /* ------------------------------------------------------------------------- */
49 ST_FUNC void tccelf_new(TCCState *s)
51 /* no section zero */
52 dynarray_add((void ***)&s->sections, &s->nb_sections, NULL);
54 /* create standard sections */
55 text_section = new_section(s, ".text", SHT_PROGBITS, SHF_ALLOC | SHF_EXECINSTR);
56 data_section = new_section(s, ".data", SHT_PROGBITS, SHF_ALLOC | SHF_WRITE);
57 bss_section = new_section(s, ".bss", SHT_NOBITS, SHF_ALLOC | SHF_WRITE);
59 /* symbols are always generated for linking stage */
60 symtab_section = new_symtab(s, ".symtab", SHT_SYMTAB, 0,
61 ".strtab",
62 ".hashtab", SHF_PRIVATE);
63 strtab_section = symtab_section->link;
64 s->symtab = symtab_section;
66 /* private symbol table for dynamic symbols */
67 s->dynsymtab_section = new_symtab(s, ".dynsymtab", SHT_SYMTAB, SHF_PRIVATE,
68 ".dynstrtab",
69 ".dynhashtab", SHF_PRIVATE);
70 get_sym_attr(s, 0, 1);
73 #ifdef CONFIG_TCC_BCHECK
74 ST_FUNC void tccelf_bounds_new(TCCState *s)
76 /* create bounds sections */
77 bounds_section = new_section(s, ".bounds",
78 SHT_PROGBITS, SHF_ALLOC);
79 lbounds_section = new_section(s, ".lbounds",
80 SHT_PROGBITS, SHF_ALLOC);
82 #endif
84 ST_FUNC void tccelf_stab_new(TCCState *s)
86 stab_section = new_section(s, ".stab", SHT_PROGBITS, 0);
87 stab_section->sh_entsize = sizeof(Stab_Sym);
88 stabstr_section = new_section(s, ".stabstr", SHT_STRTAB, 0);
89 put_elf_str(stabstr_section, "");
90 stab_section->link = stabstr_section;
91 /* put first entry */
92 put_stabs("", 0, 0, 0, 0);
95 static void free_section(Section *s)
97 tcc_free(s->data);
100 ST_FUNC void tccelf_delete(TCCState *s1)
102 int i;
104 /* free all sections */
105 for(i = 1; i < s1->nb_sections; i++)
106 free_section(s1->sections[i]);
107 dynarray_reset(&s1->sections, &s1->nb_sections);
109 for(i = 0; i < s1->nb_priv_sections; i++)
110 free_section(s1->priv_sections[i]);
111 dynarray_reset(&s1->priv_sections, &s1->nb_priv_sections);
113 /* free any loaded DLLs */
114 #ifdef TCC_IS_NATIVE
115 for ( i = 0; i < s1->nb_loaded_dlls; i++) {
116 DLLReference *ref = s1->loaded_dlls[i];
117 if ( ref->handle )
118 # ifdef _WIN32
119 FreeLibrary((HMODULE)ref->handle);
120 # else
121 dlclose(ref->handle);
122 # endif
124 #endif
125 /* free loaded dlls array */
126 dynarray_reset(&s1->loaded_dlls, &s1->nb_loaded_dlls);
127 tcc_free(s1->sym_attrs);
130 ST_FUNC Section *new_section(TCCState *s1, const char *name, int sh_type, int sh_flags)
132 Section *sec;
134 sec = tcc_mallocz(sizeof(Section) + strlen(name));
135 strcpy(sec->name, name);
136 sec->sh_type = sh_type;
137 sec->sh_flags = sh_flags;
138 switch(sh_type) {
139 case SHT_HASH:
140 case SHT_REL:
141 case SHT_RELA:
142 case SHT_DYNSYM:
143 case SHT_SYMTAB:
144 case SHT_DYNAMIC:
145 sec->sh_addralign = 4;
146 break;
147 case SHT_STRTAB:
148 sec->sh_addralign = 1;
149 break;
150 default:
151 sec->sh_addralign = PTR_SIZE; /* gcc/pcc default aligment */
152 break;
155 if (sh_flags & SHF_PRIVATE) {
156 dynarray_add((void ***)&s1->priv_sections, &s1->nb_priv_sections, sec);
157 } else {
158 sec->sh_num = s1->nb_sections;
159 dynarray_add((void ***)&s1->sections, &s1->nb_sections, sec);
162 return sec;
165 ST_FUNC Section *new_symtab(TCCState *s1,
166 const char *symtab_name, int sh_type, int sh_flags,
167 const char *strtab_name,
168 const char *hash_name, int hash_sh_flags)
170 Section *symtab, *strtab, *hash;
171 int *ptr, nb_buckets;
173 symtab = new_section(s1, symtab_name, sh_type, sh_flags);
174 symtab->sh_entsize = sizeof(ElfW(Sym));
175 strtab = new_section(s1, strtab_name, SHT_STRTAB, sh_flags);
176 put_elf_str(strtab, "");
177 symtab->link = strtab;
178 put_elf_sym(symtab, 0, 0, 0, 0, 0, NULL);
180 nb_buckets = 1;
182 hash = new_section(s1, hash_name, SHT_HASH, hash_sh_flags);
183 hash->sh_entsize = sizeof(int);
184 symtab->hash = hash;
185 hash->link = symtab;
187 ptr = section_ptr_add(hash, (2 + nb_buckets + 1) * sizeof(int));
188 ptr[0] = nb_buckets;
189 ptr[1] = 1;
190 memset(ptr + 2, 0, (nb_buckets + 1) * sizeof(int));
191 return symtab;
194 /* realloc section and set its content to zero */
195 ST_FUNC void section_realloc(Section *sec, unsigned long new_size)
197 unsigned long size;
198 unsigned char *data;
200 size = sec->data_allocated;
201 if (size == 0)
202 size = 1;
203 while (size < new_size)
204 size = size * 2;
205 data = tcc_realloc(sec->data, size);
206 memset(data + sec->data_allocated, 0, size - sec->data_allocated);
207 sec->data = data;
208 sec->data_allocated = size;
211 /* reserve at least 'size' bytes in section 'sec' from
212 sec->data_offset. */
213 ST_FUNC void *section_ptr_add(Section *sec, addr_t size)
215 size_t offset, offset1;
217 offset = sec->data_offset;
218 offset1 = offset + size;
219 if (offset1 > sec->data_allocated)
220 section_realloc(sec, offset1);
221 sec->data_offset = offset1;
222 return sec->data + offset;
225 /* reserve at least 'size' bytes from section start */
226 ST_FUNC void section_reserve(Section *sec, unsigned long size)
228 if (size > sec->data_allocated)
229 section_realloc(sec, size);
230 if (size > sec->data_offset)
231 sec->data_offset = size;
234 /* return a reference to a section, and create it if it does not
235 exists */
236 ST_FUNC Section *find_section(TCCState *s1, const char *name)
238 Section *sec;
239 int i;
240 for(i = 1; i < s1->nb_sections; i++) {
241 sec = s1->sections[i];
242 if (!strcmp(name, sec->name))
243 return sec;
245 /* sections are created as PROGBITS */
246 return new_section(s1, name, SHT_PROGBITS, SHF_ALLOC);
249 /* ------------------------------------------------------------------------- */
251 ST_FUNC int put_elf_str(Section *s, const char *sym)
253 int offset, len;
254 char *ptr;
256 len = strlen(sym) + 1;
257 offset = s->data_offset;
258 ptr = section_ptr_add(s, len);
259 memcpy(ptr, sym, len);
260 return offset;
263 /* elf symbol hashing function */
264 static unsigned long elf_hash(const unsigned char *name)
266 unsigned long h = 0, g;
268 while (*name) {
269 h = (h << 4) + *name++;
270 g = h & 0xf0000000;
271 if (g)
272 h ^= g >> 24;
273 h &= ~g;
275 return h;
278 /* rebuild hash table of section s */
279 /* NOTE: we do factorize the hash table code to go faster */
280 static void rebuild_hash(Section *s, unsigned int nb_buckets)
282 ElfW(Sym) *sym;
283 int *ptr, *hash, nb_syms, sym_index, h;
284 unsigned char *strtab;
286 strtab = s->link->data;
287 nb_syms = s->data_offset / sizeof(ElfW(Sym));
289 s->hash->data_offset = 0;
290 ptr = section_ptr_add(s->hash, (2 + nb_buckets + nb_syms) * sizeof(int));
291 ptr[0] = nb_buckets;
292 ptr[1] = nb_syms;
293 ptr += 2;
294 hash = ptr;
295 memset(hash, 0, (nb_buckets + 1) * sizeof(int));
296 ptr += nb_buckets + 1;
298 sym = (ElfW(Sym) *)s->data + 1;
299 for(sym_index = 1; sym_index < nb_syms; sym_index++) {
300 if (ELFW(ST_BIND)(sym->st_info) != STB_LOCAL) {
301 h = elf_hash(strtab + sym->st_name) % nb_buckets;
302 *ptr = hash[h];
303 hash[h] = sym_index;
304 } else {
305 *ptr = 0;
307 ptr++;
308 sym++;
312 /* return the symbol number */
313 ST_FUNC int put_elf_sym(Section *s, addr_t value, unsigned long size,
314 int info, int other, int shndx, const char *name)
316 int name_offset, sym_index;
317 int nbuckets, h;
318 ElfW(Sym) *sym;
319 Section *hs;
321 sym = section_ptr_add(s, sizeof(ElfW(Sym)));
322 if (name)
323 name_offset = put_elf_str(s->link, name);
324 else
325 name_offset = 0;
326 /* XXX: endianness */
327 sym->st_name = name_offset;
328 sym->st_value = value;
329 sym->st_size = size;
330 sym->st_info = info;
331 sym->st_other = other;
332 sym->st_shndx = shndx;
333 sym_index = sym - (ElfW(Sym) *)s->data;
334 hs = s->hash;
335 if (hs) {
336 int *ptr, *base;
337 ptr = section_ptr_add(hs, sizeof(int));
338 base = (int *)hs->data;
339 /* only add global or weak symbols */
340 if (ELFW(ST_BIND)(info) != STB_LOCAL) {
341 /* add another hashing entry */
342 nbuckets = base[0];
343 h = elf_hash((unsigned char *) name) % nbuckets;
344 *ptr = base[2 + h];
345 base[2 + h] = sym_index;
346 base[1]++;
347 /* we resize the hash table */
348 hs->nb_hashed_syms++;
349 if (hs->nb_hashed_syms > 2 * nbuckets) {
350 rebuild_hash(s, 2 * nbuckets);
352 } else {
353 *ptr = 0;
354 base[1]++;
357 return sym_index;
360 /* find global ELF symbol 'name' and return its index. Return 0 if not
361 found. */
362 ST_FUNC int find_elf_sym(Section *s, const char *name)
364 ElfW(Sym) *sym;
365 Section *hs;
366 int nbuckets, sym_index, h;
367 const char *name1;
369 hs = s->hash;
370 if (!hs)
371 return 0;
372 nbuckets = ((int *)hs->data)[0];
373 h = elf_hash((unsigned char *) name) % nbuckets;
374 sym_index = ((int *)hs->data)[2 + h];
375 while (sym_index != 0) {
376 sym = &((ElfW(Sym) *)s->data)[sym_index];
377 name1 = (char *) s->link->data + sym->st_name;
378 if (!strcmp(name, name1))
379 return sym_index;
380 sym_index = ((int *)hs->data)[2 + nbuckets + sym_index];
382 return 0;
385 /* return elf symbol value, signal error if 'err' is nonzero */
386 ST_FUNC addr_t get_elf_sym_addr(TCCState *s, const char *name, int err)
388 int sym_index;
389 ElfW(Sym) *sym;
391 sym_index = find_elf_sym(s->symtab, name);
392 sym = &((ElfW(Sym) *)s->symtab->data)[sym_index];
393 if (!sym_index || sym->st_shndx == SHN_UNDEF) {
394 if (err)
395 tcc_error("%s not defined", name);
396 return 0;
398 return sym->st_value;
401 /* return elf symbol value */
402 LIBTCCAPI void *tcc_get_symbol(TCCState *s, const char *name)
404 return (void*)(uintptr_t)get_elf_sym_addr(s, name, 0);
407 #if defined TCC_IS_NATIVE || defined TCC_TARGET_PE
408 /* return elf symbol value or error */
409 ST_FUNC void* tcc_get_symbol_err(TCCState *s, const char *name)
411 return (void*)(uintptr_t)get_elf_sym_addr(s, name, 1);
413 #endif
415 /* add an elf symbol : check if it is already defined and patch
416 it. Return symbol index. NOTE that sh_num can be SHN_UNDEF. */
417 ST_FUNC int set_elf_sym(Section *s, addr_t value, unsigned long size,
418 int info, int other, int shndx, const char *name)
420 ElfW(Sym) *esym;
421 int sym_bind, sym_index, sym_type, esym_bind;
422 unsigned char sym_vis, esym_vis, new_vis;
424 sym_bind = ELFW(ST_BIND)(info);
425 sym_type = ELFW(ST_TYPE)(info);
426 sym_vis = ELFW(ST_VISIBILITY)(other);
428 sym_index = find_elf_sym(s, name);
429 esym = &((ElfW(Sym) *)s->data)[sym_index];
430 if (sym_index && esym->st_value == value && esym->st_size == size
431 && esym->st_info == info && esym->st_other == other
432 && esym->st_shndx == shndx)
433 return sym_index;
435 if (sym_bind != STB_LOCAL) {
436 /* we search global or weak symbols */
437 if (!sym_index)
438 goto do_def;
439 if (esym->st_shndx != SHN_UNDEF) {
440 esym_bind = ELFW(ST_BIND)(esym->st_info);
441 /* propagate the most constraining visibility */
442 /* STV_DEFAULT(0)<STV_PROTECTED(3)<STV_HIDDEN(2)<STV_INTERNAL(1) */
443 esym_vis = ELFW(ST_VISIBILITY)(esym->st_other);
444 if (esym_vis == STV_DEFAULT) {
445 new_vis = sym_vis;
446 } else if (sym_vis == STV_DEFAULT) {
447 new_vis = esym_vis;
448 } else {
449 new_vis = (esym_vis < sym_vis) ? esym_vis : sym_vis;
451 esym->st_other = (esym->st_other & ~ELFW(ST_VISIBILITY)(-1))
452 | new_vis;
453 other = esym->st_other; /* in case we have to patch esym */
454 if (shndx == SHN_UNDEF) {
455 /* ignore adding of undefined symbol if the
456 corresponding symbol is already defined */
457 } else if (sym_bind == STB_GLOBAL && esym_bind == STB_WEAK) {
458 /* global overrides weak, so patch */
459 goto do_patch;
460 } else if (sym_bind == STB_WEAK && esym_bind == STB_GLOBAL) {
461 /* weak is ignored if already global */
462 } else if (sym_bind == STB_WEAK && esym_bind == STB_WEAK) {
463 /* keep first-found weak definition, ignore subsequents */
464 } else if (sym_vis == STV_HIDDEN || sym_vis == STV_INTERNAL) {
465 /* ignore hidden symbols after */
466 } else if ((esym->st_shndx == SHN_COMMON
467 || esym->st_shndx == bss_section->sh_num)
468 && (shndx < SHN_LORESERVE
469 && shndx != bss_section->sh_num)) {
470 /* data symbol gets precedence over common/bss */
471 goto do_patch;
472 } else if (shndx == SHN_COMMON || shndx == bss_section->sh_num) {
473 /* data symbol keeps precedence over common/bss */
474 } else if (s == tcc_state->dynsymtab_section) {
475 /* we accept that two DLL define the same symbol */
476 } else {
477 #if 0
478 printf("new_bind=%x new_shndx=%x new_vis=%x old_bind=%x old_shndx=%x old_vis=%x\n",
479 sym_bind, shndx, new_vis, esym_bind, esym->st_shndx, esym_vis);
480 #endif
481 tcc_error_noabort("'%s' defined twice", name);
483 } else {
484 do_patch:
485 esym->st_info = ELFW(ST_INFO)(sym_bind, sym_type);
486 esym->st_shndx = shndx;
487 new_undef_sym = 1;
488 esym->st_value = value;
489 esym->st_size = size;
490 esym->st_other = other;
492 } else {
493 do_def:
494 sym_index = put_elf_sym(s, value, size,
495 ELFW(ST_INFO)(sym_bind, sym_type), other,
496 shndx, name);
498 return sym_index;
501 /* put relocation */
502 ST_FUNC void put_elf_reloca(Section *symtab, Section *s, unsigned long offset,
503 int type, int symbol, addr_t addend)
505 char buf[256];
506 Section *sr;
507 ElfW_Rel *rel;
509 sr = s->reloc;
510 if (!sr) {
511 /* if no relocation section, create it */
512 snprintf(buf, sizeof(buf), REL_SECTION_FMT, s->name);
513 /* if the symtab is allocated, then we consider the relocation
514 are also */
515 sr = new_section(tcc_state, buf, SHT_RELX, symtab->sh_flags);
516 sr->sh_entsize = sizeof(ElfW_Rel);
517 sr->link = symtab;
518 sr->sh_info = s->sh_num;
519 s->reloc = sr;
521 rel = section_ptr_add(sr, sizeof(ElfW_Rel));
522 rel->r_offset = offset;
523 rel->r_info = ELFW(R_INFO)(symbol, type);
524 #if SHT_RELX == SHT_RELA
525 rel->r_addend = addend;
526 #else
527 if (addend)
528 tcc_error("non-zero addend on REL architecture");
529 #endif
532 ST_FUNC void put_elf_reloc(Section *symtab, Section *s, unsigned long offset,
533 int type, int symbol)
535 put_elf_reloca(symtab, s, offset, type, symbol, 0);
538 /* put stab debug information */
540 ST_FUNC void put_stabs(const char *str, int type, int other, int desc,
541 unsigned long value)
543 Stab_Sym *sym;
545 sym = section_ptr_add(stab_section, sizeof(Stab_Sym));
546 if (str) {
547 sym->n_strx = put_elf_str(stabstr_section, str);
548 } else {
549 sym->n_strx = 0;
551 sym->n_type = type;
552 sym->n_other = other;
553 sym->n_desc = desc;
554 sym->n_value = value;
557 ST_FUNC void put_stabs_r(const char *str, int type, int other, int desc,
558 unsigned long value, Section *sec, int sym_index)
560 put_stabs(str, type, other, desc, value);
561 put_elf_reloc(symtab_section, stab_section,
562 stab_section->data_offset - sizeof(unsigned int),
563 R_DATA_32, sym_index);
566 ST_FUNC void put_stabn(int type, int other, int desc, int value)
568 put_stabs(NULL, type, other, desc, value);
571 ST_FUNC void put_stabd(int type, int other, int desc)
573 put_stabs(NULL, type, other, desc, 0);
576 ST_FUNC struct sym_attr *get_sym_attr(TCCState *s1, int index, int alloc)
578 int n;
579 struct sym_attr *tab;
581 if (index >= s1->nb_sym_attrs) {
582 if (!alloc)
583 return s1->sym_attrs;
584 /* find immediately bigger power of 2 and reallocate array */
585 n = 1;
586 while (index >= n)
587 n *= 2;
588 tab = tcc_realloc(s1->sym_attrs, n * sizeof(*s1->sym_attrs));
589 s1->sym_attrs = tab;
590 memset(s1->sym_attrs + s1->nb_sym_attrs, 0,
591 (n - s1->nb_sym_attrs) * sizeof(*s1->sym_attrs));
592 s1->nb_sym_attrs = n;
594 return &s1->sym_attrs[index];
597 /* Browse each elem of type <type> in section <sec> starting at elem <startoff>
598 using variable <elem> */
599 #define for_each_elem(sec, startoff, elem, type) \
600 for (elem = (type *) sec->data + startoff; \
601 elem < (type *) (sec->data + sec->data_offset); elem++)
603 /* In an ELF file symbol table, the local symbols must appear below
604 the global and weak ones. Since TCC cannot sort it while generating
605 the code, we must do it after. All the relocation tables are also
606 modified to take into account the symbol table sorting */
607 static void sort_syms(TCCState *s1, Section *s)
609 int *old_to_new_syms;
610 ElfW(Sym) *new_syms;
611 int nb_syms, i;
612 ElfW(Sym) *p, *q;
613 ElfW_Rel *rel;
614 Section *sr;
615 int type, sym_index;
617 nb_syms = s->data_offset / sizeof(ElfW(Sym));
618 new_syms = tcc_malloc(nb_syms * sizeof(ElfW(Sym)));
619 old_to_new_syms = tcc_malloc(nb_syms * sizeof(int));
621 /* first pass for local symbols */
622 p = (ElfW(Sym) *)s->data;
623 q = new_syms;
624 for(i = 0; i < nb_syms; i++) {
625 if (ELFW(ST_BIND)(p->st_info) == STB_LOCAL) {
626 old_to_new_syms[i] = q - new_syms;
627 *q++ = *p;
629 p++;
631 /* save the number of local symbols in section header */
632 s->sh_info = q - new_syms;
634 /* then second pass for non local symbols */
635 p = (ElfW(Sym) *)s->data;
636 for(i = 0; i < nb_syms; i++) {
637 if (ELFW(ST_BIND)(p->st_info) != STB_LOCAL) {
638 old_to_new_syms[i] = q - new_syms;
639 *q++ = *p;
641 p++;
644 /* we copy the new symbols to the old */
645 memcpy(s->data, new_syms, nb_syms * sizeof(ElfW(Sym)));
646 tcc_free(new_syms);
648 /* now we modify all the relocations */
649 for(i = 1; i < s1->nb_sections; i++) {
650 sr = s1->sections[i];
651 if (sr->sh_type == SHT_RELX && sr->link == s) {
652 for_each_elem(sr, 0, rel, ElfW_Rel) {
653 sym_index = ELFW(R_SYM)(rel->r_info);
654 type = ELFW(R_TYPE)(rel->r_info);
655 sym_index = old_to_new_syms[sym_index];
656 rel->r_info = ELFW(R_INFO)(sym_index, type);
661 tcc_free(old_to_new_syms);
664 /* relocate common symbols in the .bss section */
665 ST_FUNC void relocate_common_syms(void)
667 ElfW(Sym) *sym;
668 unsigned long offset, align;
670 for_each_elem(symtab_section, 1, sym, ElfW(Sym)) {
671 if (sym->st_shndx == SHN_COMMON) {
672 /* align symbol */
673 align = sym->st_value;
674 offset = bss_section->data_offset;
675 offset = (offset + align - 1) & -align;
676 sym->st_value = offset;
677 sym->st_shndx = bss_section->sh_num;
678 offset += sym->st_size;
679 bss_section->data_offset = offset;
684 /* relocate symbol table, resolve undefined symbols if do_resolve is
685 true and output error if undefined symbol. */
686 ST_FUNC void relocate_syms(TCCState *s1, Section *symtab, int do_resolve)
688 ElfW(Sym) *sym;
689 int sym_bind, sh_num;
690 const char *name;
692 for_each_elem(symtab, 1, sym, ElfW(Sym)) {
693 sh_num = sym->st_shndx;
694 if (sh_num == SHN_UNDEF) {
695 name = (char *) strtab_section->data + sym->st_name;
696 /* Use ld.so to resolve symbol for us (for tcc -run) */
697 if (do_resolve) {
698 #if defined TCC_IS_NATIVE && !defined TCC_TARGET_PE
699 void *addr = dlsym(RTLD_DEFAULT, name);
700 if (addr) {
701 sym->st_value = (addr_t) addr;
702 #ifdef DEBUG_RELOC
703 printf ("relocate_sym: %s -> 0x%lx\n", name, sym->st_value);
704 #endif
705 goto found;
707 #endif
708 /* if dynamic symbol exist, it will be used in relocate_section */
709 } else if (s1->dynsym && find_elf_sym(s1->dynsym, name))
710 goto found;
711 /* XXX: _fp_hw seems to be part of the ABI, so we ignore
712 it */
713 if (!strcmp(name, "_fp_hw"))
714 goto found;
715 /* only weak symbols are accepted to be undefined. Their
716 value is zero */
717 sym_bind = ELFW(ST_BIND)(sym->st_info);
718 if (sym_bind == STB_WEAK)
719 sym->st_value = 0;
720 else
721 tcc_error_noabort("undefined symbol '%s'", name);
722 } else if (sh_num < SHN_LORESERVE) {
723 /* add section base */
724 sym->st_value += s1->sections[sym->st_shndx]->sh_addr;
726 found: ;
730 /* relocate a given section (CPU dependent) by applying the relocations
731 in the associated relocation section */
732 ST_FUNC void relocate_section(TCCState *s1, Section *s)
734 Section *sr = s->reloc;
735 ElfW_Rel *rel;
736 ElfW(Sym) *sym;
737 int type, sym_index;
738 unsigned char *ptr;
739 addr_t tgt, addr;
741 relocate_init(sr);
743 for_each_elem(sr, 0, rel, ElfW_Rel) {
744 ptr = s->data + rel->r_offset;
745 sym_index = ELFW(R_SYM)(rel->r_info);
746 sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
747 type = ELFW(R_TYPE)(rel->r_info);
748 tgt = sym->st_value;
749 #if SHT_RELX == SHT_RELA
750 tgt += rel->r_addend;
751 #endif
752 addr = s->sh_addr + rel->r_offset;
753 relocate(s1, rel, type, ptr, addr, tgt);
755 /* if the relocation is allocated, we change its symbol table */
756 if (sr->sh_flags & SHF_ALLOC)
757 sr->link = s1->dynsym;
760 /* relocate relocation table in 'sr' */
761 static void relocate_rel(TCCState *s1, Section *sr)
763 Section *s;
764 ElfW_Rel *rel;
766 s = s1->sections[sr->sh_info];
767 for_each_elem(sr, 0, rel, ElfW_Rel)
768 rel->r_offset += s->sh_addr;
771 /* count the number of dynamic relocations so that we can reserve
772 their space */
773 static int prepare_dynamic_rel(TCCState *s1, Section *sr)
775 ElfW_Rel *rel;
776 int sym_index, type, count;
778 count = 0;
779 for_each_elem(sr, 0, rel, ElfW_Rel) {
780 sym_index = ELFW(R_SYM)(rel->r_info);
781 type = ELFW(R_TYPE)(rel->r_info);
782 switch(type) {
783 #if defined(TCC_TARGET_I386)
784 case R_386_32:
785 #elif defined(TCC_TARGET_X86_64)
786 case R_X86_64_32:
787 case R_X86_64_32S:
788 case R_X86_64_64:
789 #endif
790 count++;
791 break;
792 #if defined(TCC_TARGET_I386)
793 case R_386_PC32:
794 #elif defined(TCC_TARGET_X86_64)
795 case R_X86_64_PC32:
796 #endif
797 if (get_sym_attr(s1, sym_index, 0)->dyn_index)
798 count++;
799 break;
800 default:
801 break;
804 if (count) {
805 /* allocate the section */
806 sr->sh_flags |= SHF_ALLOC;
807 sr->sh_size = count * sizeof(ElfW_Rel);
809 return count;
812 static void build_got(TCCState *s1)
814 /* if no got, then create it */
815 s1->got = new_section(s1, ".got", SHT_PROGBITS, SHF_ALLOC | SHF_WRITE);
816 s1->got->sh_entsize = 4;
817 set_elf_sym(symtab_section, 0, 4, ELFW(ST_INFO)(STB_GLOBAL, STT_OBJECT),
818 0, s1->got->sh_num, "_GLOBAL_OFFSET_TABLE_");
819 /* keep space for _DYNAMIC pointer and two dummy got entries */
820 section_ptr_add(s1->got, 3 * PTR_SIZE);
823 /* Create a GOT and (for function call) a PLT entry corresponding to a symbol
824 in s1->symtab. When creating the dynamic symbol table entry for the GOT
825 relocation, use 'size' and 'info' for the corresponding symbol metadata.
826 Returns the offset of the GOT or (if any) PLT entry. */
827 static struct sym_attr * put_got_entry(TCCState *s1, int dyn_reloc_type,
828 int reloc_type, unsigned long size,
829 int info, int sym_index)
831 int need_plt_entry;
832 const char *name;
833 ElfW(Sym) *sym;
834 struct sym_attr *attr;
835 unsigned got_offset;
836 char plt_name[100];
837 int len;
839 need_plt_entry = (dyn_reloc_type == R_JMP_SLOT);
840 attr = get_sym_attr(s1, sym_index, 1);
842 /* In case a function is both called and its address taken 2 GOT entries
843 are created, one for taking the address (GOT) and the other for the PLT
844 entry (PLTGOT). */
845 if (need_plt_entry ? attr->plt_offset : attr->got_offset)
846 return attr;
848 /* create the GOT entry */
849 got_offset = s1->got->data_offset;
850 section_ptr_add(s1->got, PTR_SIZE);
852 /* Create the GOT relocation that will insert the address of the object or
853 function of interest in the GOT entry. This is a static relocation for
854 memory output (dlsym will give us the address of symbols) and dynamic
855 relocation otherwise (executable and DLLs). The relocation should be
856 done lazily for GOT entry with *_JUMP_SLOT relocation type (the one
857 associated to a PLT entry) but is currently done at load time for an
858 unknown reason. */
860 sym = &((ElfW(Sym) *) symtab_section->data)[sym_index];
861 name = (char *) symtab_section->link->data + sym->st_name;
863 if (s1->dynsym) {
864 if (0 == attr->dyn_index)
865 attr->dyn_index = set_elf_sym(s1->dynsym, sym->st_value, size,
866 info, 0, sym->st_shndx, name);
867 put_elf_reloc(s1->dynsym, s1->got, got_offset, dyn_reloc_type,
868 attr->dyn_index);
869 } else {
870 put_elf_reloc(symtab_section, s1->got, got_offset, dyn_reloc_type,
871 sym_index);
874 if (need_plt_entry) {
875 if (!s1->plt) {
876 s1->plt = new_section(s1, ".plt", SHT_PROGBITS,
877 SHF_ALLOC | SHF_EXECINSTR);
878 s1->plt->sh_entsize = 4;
881 attr->plt_offset = create_plt_entry(s1, got_offset, attr);
883 /* create a symbol 'sym@plt' for the PLT jump vector */
884 len = strlen(name);
885 if (len > sizeof plt_name - 5)
886 len = sizeof plt_name - 5;
887 memcpy(plt_name, name, len);
888 strcpy(plt_name + len, "@plt");
889 attr->plt_sym = put_elf_sym(s1->symtab, attr->plt_offset, sym->st_size,
890 ELFW(ST_INFO)(STB_GLOBAL, STT_FUNC), 0, s1->plt->sh_num, plt_name);
892 } else {
893 attr->got_offset = got_offset;
896 return attr;
899 /* build GOT and PLT entries */
900 ST_FUNC void build_got_entries(TCCState *s1)
902 Section *s;
903 ElfW_Rel *rel;
904 ElfW(Sym) *sym;
905 int i, type, gotplt_entry, reloc_type, sym_index;
906 struct sym_attr *attr;
908 for(i = 1; i < s1->nb_sections; i++) {
909 s = s1->sections[i];
910 if (s->sh_type != SHT_RELX)
911 continue;
912 /* no need to handle got relocations */
913 if (s->link != symtab_section)
914 continue;
915 for_each_elem(s, 0, rel, ElfW_Rel) {
916 type = ELFW(R_TYPE)(rel->r_info);
917 gotplt_entry = gotplt_entry_type(type);
918 sym_index = ELFW(R_SYM)(rel->r_info);
919 sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
921 if (gotplt_entry == NO_GOTPLT_ENTRY) {
922 #ifdef TCC_TARGET_I386
923 if (type == R_386_32 && sym->st_shndx == SHN_UNDEF) {
924 /* the i386 generator uses the plt address for function
925 pointers into .so. This may break pointer equality
926 but helps to keep it simple */
927 char *name = (char *)symtab_section->link->data + sym->st_name;
928 int index = find_elf_sym(s1->dynsymtab_section, name);
929 ElfW(Sym) *esym = (ElfW(Sym) *)s1->dynsymtab_section->data + index;
930 if (index
931 && (ELFW(ST_TYPE)(esym->st_info) == STT_FUNC
932 || (ELFW(ST_TYPE)(esym->st_info) == STT_NOTYPE
933 && ELFW(ST_TYPE)(sym->st_info) == STT_FUNC)))
934 goto jmp_slot;
936 #endif
937 continue;
940 /* Automatically create PLT/GOT [entry] it is an undefined reference
941 (resolved at runtime), or the symbol is absolute, probably created
942 by tcc_add_symbol, and thus on 64-bit targets might be too far
943 from application code */
944 if (gotplt_entry == AUTO_GOTPLT_ENTRY) {
945 if (sym->st_shndx == SHN_UNDEF) {
946 if (s1->output_type == TCC_OUTPUT_DLL && ! PCRELATIVE_DLLPLT)
947 continue;
948 } else if (!(sym->st_shndx == SHN_ABS && PTR_SIZE == 8))
949 continue;
952 #ifdef TCC_TARGET_X86_64
953 if (type == R_X86_64_PLT32 &&
954 ELFW(ST_VISIBILITY)(sym->st_other) != STV_DEFAULT) {
955 rel->r_info = ELFW(R_INFO)(sym_index, R_X86_64_PC32);
956 continue;
958 #endif
959 if (code_reloc(type)) {
960 #ifdef TCC_TARGET_I386
961 jmp_slot:
962 #endif
963 reloc_type = R_JMP_SLOT;
964 } else
965 reloc_type = R_GLOB_DAT;
967 if (!s1->got)
968 build_got(s1);
970 if (gotplt_entry == BUILD_GOT_ONLY)
971 continue;
973 attr = put_got_entry(s1, reloc_type, type, sym->st_size, sym->st_info,
974 sym_index);
976 if (reloc_type == R_JMP_SLOT)
977 rel->r_info = ELFW(R_INFO)(attr->plt_sym, type);
982 /* put dynamic tag */
983 static void put_dt(Section *dynamic, int dt, addr_t val)
985 ElfW(Dyn) *dyn;
986 dyn = section_ptr_add(dynamic, sizeof(ElfW(Dyn)));
987 dyn->d_tag = dt;
988 dyn->d_un.d_val = val;
991 #ifndef TCC_TARGET_PE
992 static void add_init_array_defines(TCCState *s1, const char *section_name)
994 Section *s;
995 long end_offset;
996 char sym_start[1024];
997 char sym_end[1024];
999 snprintf(sym_start, sizeof(sym_start), "__%s_start", section_name + 1);
1000 snprintf(sym_end, sizeof(sym_end), "__%s_end", section_name + 1);
1002 s = find_section(s1, section_name);
1003 if (!s) {
1004 end_offset = 0;
1005 s = data_section;
1006 } else {
1007 end_offset = s->data_offset;
1010 set_elf_sym(symtab_section,
1011 0, 0,
1012 ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
1013 s->sh_num, sym_start);
1014 set_elf_sym(symtab_section,
1015 end_offset, 0,
1016 ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
1017 s->sh_num, sym_end);
1019 #endif
1021 static int tcc_add_support(TCCState *s1, const char *filename)
1023 char buf[1024];
1024 snprintf(buf, sizeof(buf), "%s/"TCC_ARCH_DIR"%s", s1->tcc_lib_path, filename);
1025 return tcc_add_file(s1, buf);
1028 ST_FUNC void tcc_add_bcheck(TCCState *s1)
1030 #ifdef CONFIG_TCC_BCHECK
1031 addr_t *ptr;
1032 int sym_index;
1034 if (0 == s1->do_bounds_check)
1035 return;
1036 /* XXX: add an object file to do that */
1037 ptr = section_ptr_add(bounds_section, sizeof(*ptr));
1038 *ptr = 0;
1039 set_elf_sym(symtab_section, 0, 0,
1040 ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
1041 bounds_section->sh_num, "__bounds_start");
1042 /* pull bcheck.o from libtcc1.a */
1043 sym_index = set_elf_sym(symtab_section, 0, 0,
1044 ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
1045 SHN_UNDEF, "__bound_init");
1046 if (s1->output_type != TCC_OUTPUT_MEMORY) {
1047 /* add 'call __bound_init()' in .init section */
1048 Section *init_section = find_section(s1, ".init");
1049 unsigned char *pinit = section_ptr_add(init_section, 5);
1050 pinit[0] = 0xe8;
1051 write32le(pinit + 1, -4);
1052 put_elf_reloc(symtab_section, init_section,
1053 init_section->data_offset - 4, R_386_PC32, sym_index);
1054 /* R_386_PC32 = R_X86_64_PC32 = 2 */
1056 #endif
1059 /* add tcc runtime libraries */
1060 ST_FUNC void tcc_add_runtime(TCCState *s1)
1062 tcc_add_bcheck(s1);
1063 tcc_add_pragma_libs(s1);
1064 /* add libc */
1065 if (!s1->nostdlib) {
1066 tcc_add_library_err(s1, "c");
1067 #ifdef CONFIG_USE_LIBGCC
1068 if (!s1->static_link) {
1069 tcc_add_file(s1, TCC_LIBGCC);
1071 #endif
1072 tcc_add_support(s1, "libtcc1.a");
1073 /* add crt end if not memory output */
1074 if (s1->output_type != TCC_OUTPUT_MEMORY)
1075 tcc_add_crt(s1, "crtn.o");
1079 /* add various standard linker symbols (must be done after the
1080 sections are filled (for example after allocating common
1081 symbols)) */
1082 ST_FUNC void tcc_add_linker_symbols(TCCState *s1)
1084 char buf[1024];
1085 int i;
1086 Section *s;
1088 set_elf_sym(symtab_section,
1089 text_section->data_offset, 0,
1090 ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
1091 text_section->sh_num, "_etext");
1092 set_elf_sym(symtab_section,
1093 data_section->data_offset, 0,
1094 ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
1095 data_section->sh_num, "_edata");
1096 set_elf_sym(symtab_section,
1097 bss_section->data_offset, 0,
1098 ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
1099 bss_section->sh_num, "_end");
1100 #ifndef TCC_TARGET_PE
1101 /* horrible new standard ldscript defines */
1102 add_init_array_defines(s1, ".preinit_array");
1103 add_init_array_defines(s1, ".init_array");
1104 add_init_array_defines(s1, ".fini_array");
1105 #endif
1107 /* add start and stop symbols for sections whose name can be
1108 expressed in C */
1109 for(i = 1; i < s1->nb_sections; i++) {
1110 s = s1->sections[i];
1111 if (s->sh_type == SHT_PROGBITS &&
1112 (s->sh_flags & SHF_ALLOC)) {
1113 const char *p;
1114 int ch;
1116 /* check if section name can be expressed in C */
1117 p = s->name;
1118 for(;;) {
1119 ch = *p;
1120 if (!ch)
1121 break;
1122 if (!isid(ch) && !isnum(ch))
1123 goto next_sec;
1124 p++;
1126 snprintf(buf, sizeof(buf), "__start_%s", s->name);
1127 set_elf_sym(symtab_section,
1128 0, 0,
1129 ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
1130 s->sh_num, buf);
1131 snprintf(buf, sizeof(buf), "__stop_%s", s->name);
1132 set_elf_sym(symtab_section,
1133 s->data_offset, 0,
1134 ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
1135 s->sh_num, buf);
1137 next_sec: ;
1141 static void tcc_output_binary(TCCState *s1, FILE *f,
1142 const int *sec_order)
1144 Section *s;
1145 int i, offset, size;
1147 offset = 0;
1148 for(i=1;i<s1->nb_sections;i++) {
1149 s = s1->sections[sec_order[i]];
1150 if (s->sh_type != SHT_NOBITS &&
1151 (s->sh_flags & SHF_ALLOC)) {
1152 while (offset < s->sh_offset) {
1153 fputc(0, f);
1154 offset++;
1156 size = s->sh_size;
1157 fwrite(s->data, 1, size, f);
1158 offset += size;
1163 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
1164 #define HAVE_PHDR 1
1165 #define EXTRA_RELITEMS 14
1166 #else
1167 #define HAVE_PHDR 1
1168 #define EXTRA_RELITEMS 9
1169 #endif
1171 ST_FUNC void fill_got_entry(TCCState *s1, ElfW_Rel *rel)
1173 int sym_index = ELFW(R_SYM) (rel->r_info);
1174 ElfW(Sym) *sym = &((ElfW(Sym) *) symtab_section->data)[sym_index];
1175 struct sym_attr *attr = get_sym_attr(s1, sym_index, 0);
1176 unsigned offset = attr->got_offset;
1178 if (0 == offset)
1179 return;
1180 section_reserve(s1->got, offset + PTR_SIZE);
1181 #ifdef TCC_TARGET_X86_64
1182 write64le(s1->got->data + offset, sym->st_value);
1183 #else
1184 write32le(s1->got->data + offset, sym->st_value);
1185 #endif
1188 /* Perform relocation to GOT or PLT entries */
1189 ST_FUNC void fill_got(TCCState *s1)
1191 Section *s;
1192 ElfW_Rel *rel;
1193 int i;
1195 for(i = 1; i < s1->nb_sections; i++) {
1196 s = s1->sections[i];
1197 if (s->sh_type != SHT_RELX)
1198 continue;
1199 /* no need to handle got relocations */
1200 if (s->link != symtab_section)
1201 continue;
1202 for_each_elem(s, 0, rel, ElfW_Rel) {
1203 switch (ELFW(R_TYPE) (rel->r_info)) {
1204 case R_X86_64_GOT32:
1205 case R_X86_64_GOTPCREL:
1206 case R_X86_64_GOTPCRELX:
1207 case R_X86_64_REX_GOTPCRELX:
1208 case R_X86_64_PLT32:
1209 fill_got_entry(s1, rel);
1210 break;
1216 /* Bind symbols of executable: resolve undefined symbols from exported symbols
1217 in shared libraries and export non local defined symbols to shared libraries
1218 if -rdynamic switch was given on command line */
1219 static void bind_exe_dynsyms(TCCState *s1)
1221 const char *name;
1222 int sym_index, index;
1223 ElfW(Sym) *sym, *esym;
1224 int type;
1226 /* Resolve undefined symbols from dynamic symbols. When there is a match:
1227 - if STT_FUNC or STT_GNU_IFUNC symbol -> add it in PLT
1228 - if STT_OBJECT symbol -> add it in .bss section with suitable reloc */
1229 for_each_elem(symtab_section, 1, sym, ElfW(Sym)) {
1230 if (sym->st_shndx == SHN_UNDEF) {
1231 name = (char *) symtab_section->link->data + sym->st_name;
1232 sym_index = find_elf_sym(s1->dynsymtab_section, name);
1233 if (sym_index) {
1234 esym = &((ElfW(Sym) *)s1->dynsymtab_section->data)[sym_index];
1235 type = ELFW(ST_TYPE)(esym->st_info);
1236 if ((type == STT_FUNC) || (type == STT_GNU_IFUNC)) {
1237 /* Indirect functions shall have STT_FUNC type in executable
1238 * dynsym section. Indeed, a dlsym call following a lazy
1239 * resolution would pick the symbol value from the
1240 * executable dynsym entry which would contain the address
1241 * of the function wanted by the caller of dlsym instead of
1242 * the address of the function that would return that
1243 * address */
1244 put_elf_sym(s1->dynsym, 0, esym->st_size,
1245 ELFW(ST_INFO)(STB_GLOBAL,STT_FUNC), 0, 0,
1246 name);
1247 } else if (type == STT_OBJECT) {
1248 unsigned long offset;
1249 ElfW(Sym) *dynsym;
1250 offset = bss_section->data_offset;
1251 /* XXX: which alignment ? */
1252 offset = (offset + 16 - 1) & -16;
1253 set_elf_sym (s1->symtab, offset, esym->st_size,
1254 esym->st_info, 0, bss_section->sh_num, name);
1255 index = put_elf_sym(s1->dynsym, offset, esym->st_size,
1256 esym->st_info, 0, bss_section->sh_num,
1257 name);
1259 /* Ensure R_COPY works for weak symbol aliases */
1260 if (ELFW(ST_BIND)(esym->st_info) == STB_WEAK) {
1261 for_each_elem(s1->dynsymtab_section, 1, dynsym, ElfW(Sym)) {
1262 if ((dynsym->st_value == esym->st_value)
1263 && (ELFW(ST_BIND)(dynsym->st_info) == STB_GLOBAL)) {
1264 char *dynname = (char *) s1->dynsymtab_section->link->data
1265 + dynsym->st_name;
1266 put_elf_sym(s1->dynsym, offset, dynsym->st_size,
1267 dynsym->st_info, 0,
1268 bss_section->sh_num, dynname);
1269 break;
1274 put_elf_reloc(s1->dynsym, bss_section,
1275 offset, R_COPY, index);
1276 offset += esym->st_size;
1277 bss_section->data_offset = offset;
1279 } else {
1280 /* STB_WEAK undefined symbols are accepted */
1281 /* XXX: _fp_hw seems to be part of the ABI, so we ignore it */
1282 if (ELFW(ST_BIND)(sym->st_info) == STB_WEAK ||
1283 !strcmp(name, "_fp_hw")) {
1284 } else {
1285 tcc_error_noabort("undefined symbol '%s'", name);
1288 } else if (s1->rdynamic && ELFW(ST_BIND)(sym->st_info) != STB_LOCAL) {
1289 /* if -rdynamic option, then export all non local symbols */
1290 name = (char *) symtab_section->link->data + sym->st_name;
1291 set_elf_sym(s1->dynsym, sym->st_value, sym->st_size, sym->st_info,
1292 0, sym->st_shndx, name);
1297 /* Bind symbols of libraries: export all non local symbols of executable that
1298 are referenced by shared libraries. The reason is that the dynamic loader
1299 search symbol first in executable and then in libraries. Therefore a
1300 reference to a symbol already defined by a library can still be resolved by
1301 a symbol in the executable. */
1302 static void bind_libs_dynsyms(TCCState *s1)
1304 const char *name;
1305 int sym_index;
1306 ElfW(Sym) *sym, *esym;
1308 for_each_elem(s1->dynsymtab_section, 1, esym, ElfW(Sym)) {
1309 name = (char *) s1->dynsymtab_section->link->data + esym->st_name;
1310 sym_index = find_elf_sym(symtab_section, name);
1311 /* XXX: avoid adding a symbol if already present because of
1312 -rdynamic ? */
1313 sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
1314 if (sym_index && sym->st_shndx != SHN_UNDEF)
1315 set_elf_sym(s1->dynsym, sym->st_value, sym->st_size, sym->st_info,
1316 0, sym->st_shndx, name);
1317 else if (esym->st_shndx == SHN_UNDEF) {
1318 /* weak symbols can stay undefined */
1319 if (ELFW(ST_BIND)(esym->st_info) != STB_WEAK)
1320 tcc_warning("undefined dynamic symbol '%s'", name);
1325 /* Export all non local symbols. This is used by shared libraries so that the
1326 non local symbols they define can resolve a reference in another shared
1327 library or in the executable. Correspondingly, it allows undefined local
1328 symbols to be resolved by other shared libraries or by the executable. */
1329 static void export_global_syms(TCCState *s1)
1331 int dynindex, index;
1332 const char *name;
1333 ElfW(Sym) *sym;
1335 for_each_elem(symtab_section, 1, sym, ElfW(Sym)) {
1336 if (ELFW(ST_BIND)(sym->st_info) != STB_LOCAL) {
1337 name = (char *) symtab_section->link->data + sym->st_name;
1338 dynindex = put_elf_sym(s1->dynsym, sym->st_value, sym->st_size,
1339 sym->st_info, 0, sym->st_shndx, name);
1340 index = sym - (ElfW(Sym) *) symtab_section->data;
1341 get_sym_attr(s1, index, 1)->dyn_index = dynindex;
1346 /* Allocate strings for section names and decide if an unallocated section
1347 should be output.
1348 NOTE: the strsec section comes last, so its size is also correct ! */
1349 static void alloc_sec_names(TCCState *s1, int file_type, Section *strsec)
1351 int i;
1352 Section *s;
1354 /* Allocate strings for section names */
1355 for(i = 1; i < s1->nb_sections; i++) {
1356 s = s1->sections[i];
1357 s->sh_name = put_elf_str(strsec, s->name);
1358 /* when generating a DLL, we include relocations but we may
1359 patch them */
1360 if (file_type == TCC_OUTPUT_DLL &&
1361 s->sh_type == SHT_RELX &&
1362 !(s->sh_flags & SHF_ALLOC)) {
1363 /* gr: avoid bogus relocs for empty (debug) sections */
1364 if (s1->sections[s->sh_info]->sh_flags & SHF_ALLOC)
1365 prepare_dynamic_rel(s1, s);
1366 else if (s1->do_debug)
1367 s->sh_size = s->data_offset;
1368 } else if (s1->do_debug ||
1369 file_type == TCC_OUTPUT_OBJ ||
1370 (s->sh_flags & SHF_ALLOC) ||
1371 i == (s1->nb_sections - 1)) {
1372 /* we output all sections if debug or object file */
1373 s->sh_size = s->data_offset;
1378 /* Info to be copied in dynamic section */
1379 struct dyn_inf {
1380 Section *dynamic;
1381 Section *dynstr;
1382 unsigned long dyn_rel_off;
1383 addr_t rel_addr;
1384 addr_t rel_size;
1385 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
1386 addr_t bss_addr;
1387 addr_t bss_size;
1388 #endif
1391 /* Assign sections to segments and decide how are sections laid out when loaded
1392 in memory. This function also fills corresponding program headers. */
1393 static int layout_sections(TCCState *s1, ElfW(Phdr) *phdr, int phnum,
1394 Section *interp, Section* strsec,
1395 struct dyn_inf *dyninf, int *sec_order)
1397 int i, j, k, file_type, sh_order_index, file_offset;
1398 unsigned long s_align;
1399 long long tmp;
1400 addr_t addr;
1401 ElfW(Phdr) *ph;
1402 Section *s;
1404 file_type = s1->output_type;
1405 sh_order_index = 1;
1406 file_offset = 0;
1407 if (s1->output_format == TCC_OUTPUT_FORMAT_ELF)
1408 file_offset = sizeof(ElfW(Ehdr)) + phnum * sizeof(ElfW(Phdr));
1409 s_align = ELF_PAGE_SIZE;
1410 if (s1->section_align)
1411 s_align = s1->section_align;
1413 if (phnum > 0) {
1414 if (s1->has_text_addr) {
1415 int a_offset, p_offset;
1416 addr = s1->text_addr;
1417 /* we ensure that (addr % ELF_PAGE_SIZE) == file_offset %
1418 ELF_PAGE_SIZE */
1419 a_offset = (int) (addr & (s_align - 1));
1420 p_offset = file_offset & (s_align - 1);
1421 if (a_offset < p_offset)
1422 a_offset += s_align;
1423 file_offset += (a_offset - p_offset);
1424 } else {
1425 if (file_type == TCC_OUTPUT_DLL)
1426 addr = 0;
1427 else
1428 addr = ELF_START_ADDR;
1429 /* compute address after headers */
1430 addr += (file_offset & (s_align - 1));
1433 ph = &phdr[0];
1434 /* Leave one program headers for the program interpreter and one for
1435 the program header table itself if needed. These are done later as
1436 they require section layout to be done first. */
1437 if (interp)
1438 ph += 1 + HAVE_PHDR;
1440 /* dynamic relocation table information, for .dynamic section */
1441 dyninf->rel_addr = dyninf->rel_size = 0;
1442 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
1443 dyninf->bss_addr = dyninf->bss_size = 0;
1444 #endif
1446 for(j = 0; j < 2; j++) {
1447 ph->p_type = PT_LOAD;
1448 if (j == 0)
1449 ph->p_flags = PF_R | PF_X;
1450 else
1451 ph->p_flags = PF_R | PF_W;
1452 ph->p_align = s_align;
1454 /* Decide the layout of sections loaded in memory. This must
1455 be done before program headers are filled since they contain
1456 info about the layout. We do the following ordering: interp,
1457 symbol tables, relocations, progbits, nobits */
1458 /* XXX: do faster and simpler sorting */
1459 for(k = 0; k < 5; k++) {
1460 for(i = 1; i < s1->nb_sections; i++) {
1461 s = s1->sections[i];
1462 /* compute if section should be included */
1463 if (j == 0) {
1464 if ((s->sh_flags & (SHF_ALLOC | SHF_WRITE)) !=
1465 SHF_ALLOC)
1466 continue;
1467 } else {
1468 if ((s->sh_flags & (SHF_ALLOC | SHF_WRITE)) !=
1469 (SHF_ALLOC | SHF_WRITE))
1470 continue;
1472 if (s == interp) {
1473 if (k != 0)
1474 continue;
1475 } else if (s->sh_type == SHT_DYNSYM ||
1476 s->sh_type == SHT_STRTAB ||
1477 s->sh_type == SHT_HASH) {
1478 if (k != 1)
1479 continue;
1480 } else if (s->sh_type == SHT_RELX) {
1481 if (k != 2)
1482 continue;
1483 } else if (s->sh_type == SHT_NOBITS) {
1484 if (k != 4)
1485 continue;
1486 } else {
1487 if (k != 3)
1488 continue;
1490 sec_order[sh_order_index++] = i;
1492 /* section matches: we align it and add its size */
1493 tmp = addr;
1494 addr = (addr + s->sh_addralign - 1) &
1495 ~(s->sh_addralign - 1);
1496 file_offset += (int) ( addr - tmp );
1497 s->sh_offset = file_offset;
1498 s->sh_addr = addr;
1500 /* update program header infos */
1501 if (ph->p_offset == 0) {
1502 ph->p_offset = file_offset;
1503 ph->p_vaddr = addr;
1504 ph->p_paddr = ph->p_vaddr;
1506 /* update dynamic relocation infos */
1507 if (s->sh_type == SHT_RELX) {
1508 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
1509 if (!strcmp(strsec->data + s->sh_name, ".rel.got")) {
1510 dyninf->rel_addr = addr;
1511 dyninf->rel_size += s->sh_size; /* XXX only first rel. */
1513 if (!strcmp(strsec->data + s->sh_name, ".rel.bss")) {
1514 dyninf->bss_addr = addr;
1515 dyninf->bss_size = s->sh_size; /* XXX only first rel. */
1517 #else
1518 if (dyninf->rel_size == 0)
1519 dyninf->rel_addr = addr;
1520 dyninf->rel_size += s->sh_size;
1521 #endif
1523 addr += s->sh_size;
1524 if (s->sh_type != SHT_NOBITS)
1525 file_offset += s->sh_size;
1528 if (j == 0) {
1529 /* Make the first PT_LOAD segment include the program
1530 headers itself (and the ELF header as well), it'll
1531 come out with same memory use but will make various
1532 tools like binutils strip work better. */
1533 ph->p_offset &= ~(ph->p_align - 1);
1534 ph->p_vaddr &= ~(ph->p_align - 1);
1535 ph->p_paddr &= ~(ph->p_align - 1);
1537 ph->p_filesz = file_offset - ph->p_offset;
1538 ph->p_memsz = addr - ph->p_vaddr;
1539 ph++;
1540 if (j == 0) {
1541 if (s1->output_format == TCC_OUTPUT_FORMAT_ELF) {
1542 /* if in the middle of a page, we duplicate the page in
1543 memory so that one copy is RX and the other is RW */
1544 if ((addr & (s_align - 1)) != 0)
1545 addr += s_align;
1546 } else {
1547 addr = (addr + s_align - 1) & ~(s_align - 1);
1548 file_offset = (file_offset + s_align - 1) & ~(s_align - 1);
1554 /* all other sections come after */
1555 for(i = 1; i < s1->nb_sections; i++) {
1556 s = s1->sections[i];
1557 if (phnum > 0 && (s->sh_flags & SHF_ALLOC))
1558 continue;
1559 sec_order[sh_order_index++] = i;
1561 file_offset = (file_offset + s->sh_addralign - 1) &
1562 ~(s->sh_addralign - 1);
1563 s->sh_offset = file_offset;
1564 if (s->sh_type != SHT_NOBITS)
1565 file_offset += s->sh_size;
1568 return file_offset;
1571 static void fill_unloadable_phdr(ElfW(Phdr) *phdr, int phnum, Section *interp,
1572 Section *dynamic)
1574 ElfW(Phdr) *ph;
1576 /* if interpreter, then add corresponding program header */
1577 if (interp) {
1578 ph = &phdr[0];
1580 if (HAVE_PHDR)
1582 int len = phnum * sizeof(ElfW(Phdr));
1584 ph->p_type = PT_PHDR;
1585 ph->p_offset = sizeof(ElfW(Ehdr));
1586 ph->p_vaddr = interp->sh_addr - len;
1587 ph->p_paddr = ph->p_vaddr;
1588 ph->p_filesz = ph->p_memsz = len;
1589 ph->p_flags = PF_R | PF_X;
1590 ph->p_align = 4; /* interp->sh_addralign; */
1591 ph++;
1594 ph->p_type = PT_INTERP;
1595 ph->p_offset = interp->sh_offset;
1596 ph->p_vaddr = interp->sh_addr;
1597 ph->p_paddr = ph->p_vaddr;
1598 ph->p_filesz = interp->sh_size;
1599 ph->p_memsz = interp->sh_size;
1600 ph->p_flags = PF_R;
1601 ph->p_align = interp->sh_addralign;
1604 /* if dynamic section, then add corresponding program header */
1605 if (dynamic) {
1606 ph = &phdr[phnum - 1];
1608 ph->p_type = PT_DYNAMIC;
1609 ph->p_offset = dynamic->sh_offset;
1610 ph->p_vaddr = dynamic->sh_addr;
1611 ph->p_paddr = ph->p_vaddr;
1612 ph->p_filesz = dynamic->sh_size;
1613 ph->p_memsz = dynamic->sh_size;
1614 ph->p_flags = PF_R | PF_W;
1615 ph->p_align = dynamic->sh_addralign;
1619 /* Fill the dynamic section with tags describing the address and size of
1620 sections */
1621 static void fill_dynamic(TCCState *s1, struct dyn_inf *dyninf)
1623 Section *dynamic;
1625 dynamic = dyninf->dynamic;
1627 /* put dynamic section entries */
1628 dynamic->data_offset = dyninf->dyn_rel_off;
1629 put_dt(dynamic, DT_HASH, s1->dynsym->hash->sh_addr);
1630 put_dt(dynamic, DT_STRTAB, dyninf->dynstr->sh_addr);
1631 put_dt(dynamic, DT_SYMTAB, s1->dynsym->sh_addr);
1632 put_dt(dynamic, DT_STRSZ, dyninf->dynstr->data_offset);
1633 put_dt(dynamic, DT_SYMENT, sizeof(ElfW(Sym)));
1634 #if defined(TCC_TARGET_ARM64) || defined(TCC_TARGET_X86_64)
1635 put_dt(dynamic, DT_RELA, dyninf->rel_addr);
1636 put_dt(dynamic, DT_RELASZ, dyninf->rel_size);
1637 put_dt(dynamic, DT_RELAENT, sizeof(ElfW_Rel));
1638 #else
1639 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
1640 put_dt(dynamic, DT_PLTGOT, s1->got->sh_addr);
1641 put_dt(dynamic, DT_PLTRELSZ, dyninf->rel_size);
1642 put_dt(dynamic, DT_JMPREL, dyninf->rel_addr);
1643 put_dt(dynamic, DT_PLTREL, DT_REL);
1644 put_dt(dynamic, DT_REL, dyninf->bss_addr);
1645 put_dt(dynamic, DT_RELSZ, dyninf->bss_size);
1646 #else
1647 put_dt(dynamic, DT_REL, dyninf->rel_addr);
1648 put_dt(dynamic, DT_RELSZ, dyninf->rel_size);
1649 put_dt(dynamic, DT_RELENT, sizeof(ElfW_Rel));
1650 #endif
1651 #endif
1652 if (s1->do_debug)
1653 put_dt(dynamic, DT_DEBUG, 0);
1654 put_dt(dynamic, DT_NULL, 0);
1657 /* Relocate remaining sections and symbols (that is those not related to
1658 dynamic linking) */
1659 static int final_sections_reloc(TCCState *s1)
1661 int i;
1662 Section *s;
1664 relocate_syms(s1, s1->symtab, 0);
1666 if (s1->nb_errors != 0)
1667 return -1;
1669 /* relocate sections */
1670 /* XXX: ignore sections with allocated relocations ? */
1671 for(i = 1; i < s1->nb_sections; i++) {
1672 s = s1->sections[i];
1673 #ifdef TCC_TARGET_I386
1674 if (s->reloc && s != s1->got && (s->sh_flags & SHF_ALLOC)) //gr
1675 /* On X86 gdb 7.3 works in any case but gdb 6.6 will crash if SHF_ALLOC
1676 checking is removed */
1677 #else
1678 if (s->reloc && s != s1->got)
1679 /* On X86_64 gdb 7.3 will crash if SHF_ALLOC checking is present */
1680 #endif
1681 relocate_section(s1, s);
1684 /* relocate relocation entries if the relocation tables are
1685 allocated in the executable */
1686 for(i = 1; i < s1->nb_sections; i++) {
1687 s = s1->sections[i];
1688 if ((s->sh_flags & SHF_ALLOC) &&
1689 s->sh_type == SHT_RELX) {
1690 relocate_rel(s1, s);
1693 return 0;
1696 /* Create an ELF file on disk.
1697 This function handle ELF specific layout requirements */
1698 static void tcc_output_elf(TCCState *s1, FILE *f, int phnum, ElfW(Phdr) *phdr,
1699 int file_offset, int *sec_order)
1701 int i, shnum, offset, size, file_type;
1702 Section *s;
1703 ElfW(Ehdr) ehdr;
1704 ElfW(Shdr) shdr, *sh;
1706 file_type = s1->output_type;
1707 shnum = s1->nb_sections;
1709 memset(&ehdr, 0, sizeof(ehdr));
1711 if (phnum > 0) {
1712 ehdr.e_phentsize = sizeof(ElfW(Phdr));
1713 ehdr.e_phnum = phnum;
1714 ehdr.e_phoff = sizeof(ElfW(Ehdr));
1717 /* align to 4 */
1718 file_offset = (file_offset + 3) & -4;
1720 /* fill header */
1721 ehdr.e_ident[0] = ELFMAG0;
1722 ehdr.e_ident[1] = ELFMAG1;
1723 ehdr.e_ident[2] = ELFMAG2;
1724 ehdr.e_ident[3] = ELFMAG3;
1725 ehdr.e_ident[4] = ELFCLASSW;
1726 ehdr.e_ident[5] = ELFDATA2LSB;
1727 ehdr.e_ident[6] = EV_CURRENT;
1728 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
1729 ehdr.e_ident[EI_OSABI] = ELFOSABI_FREEBSD;
1730 #endif
1731 #ifdef TCC_TARGET_ARM
1732 #ifdef TCC_ARM_EABI
1733 ehdr.e_ident[EI_OSABI] = 0;
1734 ehdr.e_flags = EF_ARM_EABI_VER4;
1735 if (file_type == TCC_OUTPUT_EXE || file_type == TCC_OUTPUT_DLL)
1736 ehdr.e_flags |= EF_ARM_HASENTRY;
1737 if (s1->float_abi == ARM_HARD_FLOAT)
1738 ehdr.e_flags |= EF_ARM_VFP_FLOAT;
1739 else
1740 ehdr.e_flags |= EF_ARM_SOFT_FLOAT;
1741 #else
1742 ehdr.e_ident[EI_OSABI] = ELFOSABI_ARM;
1743 #endif
1744 #endif
1745 switch(file_type) {
1746 default:
1747 case TCC_OUTPUT_EXE:
1748 ehdr.e_type = ET_EXEC;
1749 ehdr.e_entry = get_elf_sym_addr(s1, "_start", 1);
1750 break;
1751 case TCC_OUTPUT_DLL:
1752 ehdr.e_type = ET_DYN;
1753 ehdr.e_entry = text_section->sh_addr; /* XXX: is it correct ? */
1754 break;
1755 case TCC_OUTPUT_OBJ:
1756 ehdr.e_type = ET_REL;
1757 break;
1759 ehdr.e_machine = EM_TCC_TARGET;
1760 ehdr.e_version = EV_CURRENT;
1761 ehdr.e_shoff = file_offset;
1762 ehdr.e_ehsize = sizeof(ElfW(Ehdr));
1763 ehdr.e_shentsize = sizeof(ElfW(Shdr));
1764 ehdr.e_shnum = shnum;
1765 ehdr.e_shstrndx = shnum - 1;
1767 fwrite(&ehdr, 1, sizeof(ElfW(Ehdr)), f);
1768 fwrite(phdr, 1, phnum * sizeof(ElfW(Phdr)), f);
1769 offset = sizeof(ElfW(Ehdr)) + phnum * sizeof(ElfW(Phdr));
1771 sort_syms(s1, symtab_section);
1772 for(i = 1; i < s1->nb_sections; i++) {
1773 s = s1->sections[sec_order[i]];
1774 if (s->sh_type != SHT_NOBITS) {
1775 while (offset < s->sh_offset) {
1776 fputc(0, f);
1777 offset++;
1779 size = s->sh_size;
1780 if (size)
1781 fwrite(s->data, 1, size, f);
1782 offset += size;
1786 /* output section headers */
1787 while (offset < ehdr.e_shoff) {
1788 fputc(0, f);
1789 offset++;
1792 for(i = 0; i < s1->nb_sections; i++) {
1793 sh = &shdr;
1794 memset(sh, 0, sizeof(ElfW(Shdr)));
1795 s = s1->sections[i];
1796 if (s) {
1797 sh->sh_name = s->sh_name;
1798 sh->sh_type = s->sh_type;
1799 sh->sh_flags = s->sh_flags;
1800 sh->sh_entsize = s->sh_entsize;
1801 sh->sh_info = s->sh_info;
1802 if (s->link)
1803 sh->sh_link = s->link->sh_num;
1804 sh->sh_addralign = s->sh_addralign;
1805 sh->sh_addr = s->sh_addr;
1806 sh->sh_offset = s->sh_offset;
1807 sh->sh_size = s->sh_size;
1809 fwrite(sh, 1, sizeof(ElfW(Shdr)), f);
1813 /* Write an elf, coff or "binary" file */
1814 static int tcc_write_elf_file(TCCState *s1, const char *filename, int phnum,
1815 ElfW(Phdr) *phdr, int file_offset, int *sec_order)
1817 int fd, mode, file_type;
1818 FILE *f;
1820 file_type = s1->output_type;
1821 if (file_type == TCC_OUTPUT_OBJ)
1822 mode = 0666;
1823 else
1824 mode = 0777;
1825 unlink(filename);
1826 fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, mode);
1827 if (fd < 0) {
1828 tcc_error_noabort("could not write '%s'", filename);
1829 return -1;
1831 f = fdopen(fd, "wb");
1832 if (s1->verbose)
1833 printf("<- %s\n", filename);
1835 #ifdef TCC_TARGET_COFF
1836 if (s1->output_format == TCC_OUTPUT_FORMAT_COFF)
1837 tcc_output_coff(s1, f);
1838 else
1839 #endif
1840 if (s1->output_format == TCC_OUTPUT_FORMAT_ELF)
1841 tcc_output_elf(s1, f, phnum, phdr, file_offset, sec_order);
1842 else
1843 tcc_output_binary(s1, f, sec_order);
1844 fclose(f);
1846 return 0;
1849 /* Output an elf, coff or binary file */
1850 /* XXX: suppress unneeded sections */
1851 static int elf_output_file(TCCState *s1, const char *filename)
1853 int i, ret, phnum, shnum, file_type, file_offset, *sec_order;
1854 struct dyn_inf dyninf;
1855 ElfW(Phdr) *phdr;
1856 ElfW(Sym) *sym;
1857 Section *strsec, *interp, *dynamic, *dynstr;
1859 file_type = s1->output_type;
1860 s1->nb_errors = 0;
1862 /* if linking, also link in runtime libraries (libc, libgcc, etc.) */
1863 if (file_type != TCC_OUTPUT_OBJ) {
1864 tcc_add_runtime(s1);
1867 phdr = NULL;
1868 sec_order = NULL;
1869 interp = dynamic = dynstr = NULL; /* avoid warning */
1870 dyninf.dyn_rel_off = 0; /* avoid warning */
1872 if (file_type != TCC_OUTPUT_OBJ) {
1873 relocate_common_syms();
1875 tcc_add_linker_symbols(s1);
1877 if (!s1->static_link) {
1878 if (file_type == TCC_OUTPUT_EXE) {
1879 char *ptr;
1880 /* allow override the dynamic loader */
1881 const char *elfint = getenv("LD_SO");
1882 if (elfint == NULL)
1883 elfint = DEFAULT_ELFINTERP(s1);
1884 /* add interpreter section only if executable */
1885 interp = new_section(s1, ".interp", SHT_PROGBITS, SHF_ALLOC);
1886 interp->sh_addralign = 1;
1887 ptr = section_ptr_add(interp, 1 + strlen(elfint));
1888 strcpy(ptr, elfint);
1891 /* add dynamic symbol table */
1892 s1->dynsym = new_symtab(s1, ".dynsym", SHT_DYNSYM, SHF_ALLOC,
1893 ".dynstr",
1894 ".hash", SHF_ALLOC);
1895 dynstr = s1->dynsym->link;
1897 /* add dynamic section */
1898 dynamic = new_section(s1, ".dynamic", SHT_DYNAMIC,
1899 SHF_ALLOC | SHF_WRITE);
1900 dynamic->link = dynstr;
1901 dynamic->sh_entsize = sizeof(ElfW(Dyn));
1903 build_got(s1);
1905 if (file_type == TCC_OUTPUT_EXE) {
1906 bind_exe_dynsyms(s1);
1908 if (s1->nb_errors) {
1909 ret = -1;
1910 goto the_end;
1913 bind_libs_dynsyms(s1);
1914 } else /* shared library case: simply export all global symbols */
1915 export_global_syms(s1);
1917 build_got_entries(s1);
1919 /* add a list of needed dlls */
1920 for(i = 0; i < s1->nb_loaded_dlls; i++) {
1921 DLLReference *dllref = s1->loaded_dlls[i];
1922 if (dllref->level == 0)
1923 put_dt(dynamic, DT_NEEDED, put_elf_str(dynstr, dllref->name));
1926 if (s1->rpath)
1927 put_dt(dynamic, DT_RPATH, put_elf_str(dynstr, s1->rpath));
1929 /* XXX: currently, since we do not handle PIC code, we
1930 must relocate the readonly segments */
1931 if (file_type == TCC_OUTPUT_DLL) {
1932 if (s1->soname)
1933 put_dt(dynamic, DT_SONAME, put_elf_str(dynstr, s1->soname));
1934 put_dt(dynamic, DT_TEXTREL, 0);
1937 if (s1->symbolic)
1938 put_dt(dynamic, DT_SYMBOLIC, 0);
1940 /* add necessary space for other entries */
1941 dyninf.dyn_rel_off = dynamic->data_offset;
1942 dynamic->data_offset += sizeof(ElfW(Dyn)) * EXTRA_RELITEMS;
1943 } else {
1944 /* still need to build got entries in case of static link */
1945 build_got_entries(s1);
1949 /* we add a section for symbols */
1950 strsec = new_section(s1, ".shstrtab", SHT_STRTAB, 0);
1951 put_elf_str(strsec, "");
1953 /* compute number of sections */
1954 shnum = s1->nb_sections;
1956 /* this array is used to reorder sections in the output file */
1957 sec_order = tcc_malloc(sizeof(int) * shnum);
1958 sec_order[0] = 0;
1960 /* compute number of program headers */
1961 switch(file_type) {
1962 default:
1963 case TCC_OUTPUT_OBJ:
1964 phnum = 0;
1965 break;
1966 case TCC_OUTPUT_EXE:
1967 if (!s1->static_link)
1968 phnum = 4 + HAVE_PHDR;
1969 else
1970 phnum = 2;
1971 break;
1972 case TCC_OUTPUT_DLL:
1973 phnum = 3;
1974 break;
1977 /* Allocate strings for section names */
1978 alloc_sec_names(s1, file_type, strsec);
1980 /* allocate program segment headers */
1981 phdr = tcc_mallocz(phnum * sizeof(ElfW(Phdr)));
1983 /* compute section to program header mapping */
1984 file_offset = layout_sections(s1, phdr, phnum, interp, strsec, &dyninf,
1985 sec_order);
1987 /* Fill remaining program header and finalize relocation related to dynamic
1988 linking. */
1989 if (phnum > 0) {
1990 fill_unloadable_phdr(phdr, phnum, interp, dynamic);
1991 if (dynamic) {
1992 dyninf.dynamic = dynamic;
1993 dyninf.dynstr = dynstr;
1995 fill_dynamic(s1, &dyninf);
1997 /* put in GOT the dynamic section address and relocate PLT */
1998 write32le(s1->got->data, dynamic->sh_addr);
1999 if (file_type == TCC_OUTPUT_EXE
2000 || (RELOCATE_DLLPLT && file_type == TCC_OUTPUT_DLL))
2001 relocate_plt(s1);
2003 /* relocate symbols in .dynsym now that final addresses are known */
2004 for_each_elem(s1->dynsym, 1, sym, ElfW(Sym)) {
2005 if (sym->st_shndx != SHN_UNDEF && sym->st_shndx < SHN_LORESERVE) {
2006 /* do symbol relocation */
2007 sym->st_value += s1->sections[sym->st_shndx]->sh_addr;
2013 /* if building executable or DLL, then relocate each section
2014 except the GOT which is already relocated */
2015 if (file_type != TCC_OUTPUT_OBJ) {
2016 ret = final_sections_reloc(s1);
2017 if (ret)
2018 goto the_end;
2021 /* Perform relocation to GOT or PLT entries */
2022 if (file_type == TCC_OUTPUT_EXE && s1->static_link)
2023 fill_got(s1);
2025 /* Create the ELF file with name 'filename' */
2026 ret = tcc_write_elf_file(s1, filename, phnum, phdr, file_offset, sec_order);
2027 the_end:
2028 tcc_free(sec_order);
2029 tcc_free(phdr);
2030 return ret;
2033 LIBTCCAPI int tcc_output_file(TCCState *s, const char *filename)
2035 int ret;
2036 #ifdef TCC_TARGET_PE
2037 if (s->output_type != TCC_OUTPUT_OBJ) {
2038 ret = pe_output_file(s, filename);
2039 } else
2040 #endif
2041 ret = elf_output_file(s, filename);
2042 return ret;
2045 static void *load_data(int fd, unsigned long file_offset, unsigned long size)
2047 void *data;
2049 data = tcc_malloc(size);
2050 lseek(fd, file_offset, SEEK_SET);
2051 read(fd, data, size);
2052 return data;
2055 typedef struct SectionMergeInfo {
2056 Section *s; /* corresponding existing section */
2057 unsigned long offset; /* offset of the new section in the existing section */
2058 uint8_t new_section; /* true if section 's' was added */
2059 uint8_t link_once; /* true if link once section */
2060 } SectionMergeInfo;
2062 ST_FUNC int tcc_object_type(int fd, ElfW(Ehdr) *h)
2064 int size = read(fd, h, sizeof *h);
2065 if (size == sizeof *h && 0 == memcmp(h, ELFMAG, 4)) {
2066 if (h->e_type == ET_REL)
2067 return AFF_BINTYPE_REL;
2068 if (h->e_type == ET_DYN)
2069 return AFF_BINTYPE_DYN;
2070 } else if (size >= 8) {
2071 if (0 == memcmp(h, ARMAG, 8))
2072 return AFF_BINTYPE_AR;
2073 #ifdef TCC_TARGET_COFF
2074 if (((struct filehdr*)h)->f_magic == COFF_C67_MAGIC)
2075 return AFF_BINTYPE_C67;
2076 #endif
2078 return 0;
2081 /* load an object file and merge it with current files */
2082 /* XXX: handle correctly stab (debug) info */
2083 ST_FUNC int tcc_load_object_file(TCCState *s1,
2084 int fd, unsigned long file_offset)
2086 ElfW(Ehdr) ehdr;
2087 ElfW(Shdr) *shdr, *sh;
2088 int size, i, j, offset, offseti, nb_syms, sym_index, ret;
2089 unsigned char *strsec, *strtab;
2090 int *old_to_new_syms;
2091 char *sh_name, *name;
2092 SectionMergeInfo *sm_table, *sm;
2093 ElfW(Sym) *sym, *symtab;
2094 ElfW_Rel *rel;
2095 Section *s;
2097 int stab_index;
2098 int stabstr_index;
2100 stab_index = stabstr_index = 0;
2102 lseek(fd, file_offset, SEEK_SET);
2103 if (tcc_object_type(fd, &ehdr) != AFF_BINTYPE_REL)
2104 goto fail1;
2105 /* test CPU specific stuff */
2106 if (ehdr.e_ident[5] != ELFDATA2LSB ||
2107 ehdr.e_machine != EM_TCC_TARGET) {
2108 fail1:
2109 tcc_error_noabort("invalid object file");
2110 return -1;
2112 /* read sections */
2113 shdr = load_data(fd, file_offset + ehdr.e_shoff,
2114 sizeof(ElfW(Shdr)) * ehdr.e_shnum);
2115 sm_table = tcc_mallocz(sizeof(SectionMergeInfo) * ehdr.e_shnum);
2117 /* load section names */
2118 sh = &shdr[ehdr.e_shstrndx];
2119 strsec = load_data(fd, file_offset + sh->sh_offset, sh->sh_size);
2121 /* load symtab and strtab */
2122 old_to_new_syms = NULL;
2123 symtab = NULL;
2124 strtab = NULL;
2125 nb_syms = 0;
2126 for(i = 1; i < ehdr.e_shnum; i++) {
2127 sh = &shdr[i];
2128 if (sh->sh_type == SHT_SYMTAB) {
2129 if (symtab) {
2130 tcc_error_noabort("object must contain only one symtab");
2131 fail:
2132 ret = -1;
2133 goto the_end;
2135 nb_syms = sh->sh_size / sizeof(ElfW(Sym));
2136 symtab = load_data(fd, file_offset + sh->sh_offset, sh->sh_size);
2137 sm_table[i].s = symtab_section;
2139 /* now load strtab */
2140 sh = &shdr[sh->sh_link];
2141 strtab = load_data(fd, file_offset + sh->sh_offset, sh->sh_size);
2145 /* now examine each section and try to merge its content with the
2146 ones in memory */
2147 for(i = 1; i < ehdr.e_shnum; i++) {
2148 /* no need to examine section name strtab */
2149 if (i == ehdr.e_shstrndx)
2150 continue;
2151 sh = &shdr[i];
2152 sh_name = (char *) strsec + sh->sh_name;
2153 /* ignore sections types we do not handle */
2154 if (sh->sh_type != SHT_PROGBITS &&
2155 sh->sh_type != SHT_RELX &&
2156 #ifdef TCC_ARM_EABI
2157 sh->sh_type != SHT_ARM_EXIDX &&
2158 #endif
2159 sh->sh_type != SHT_NOBITS &&
2160 sh->sh_type != SHT_PREINIT_ARRAY &&
2161 sh->sh_type != SHT_INIT_ARRAY &&
2162 sh->sh_type != SHT_FINI_ARRAY &&
2163 strcmp(sh_name, ".stabstr")
2165 continue;
2166 if (sh->sh_addralign < 1)
2167 sh->sh_addralign = 1;
2168 /* find corresponding section, if any */
2169 for(j = 1; j < s1->nb_sections;j++) {
2170 s = s1->sections[j];
2171 if (!strcmp(s->name, sh_name)) {
2172 if (!strncmp(sh_name, ".gnu.linkonce",
2173 sizeof(".gnu.linkonce") - 1)) {
2174 /* if a 'linkonce' section is already present, we
2175 do not add it again. It is a little tricky as
2176 symbols can still be defined in
2177 it. */
2178 sm_table[i].link_once = 1;
2179 goto next;
2180 } else {
2181 goto found;
2185 /* not found: create new section */
2186 s = new_section(s1, sh_name, sh->sh_type, sh->sh_flags & ~SHF_GROUP);
2187 /* take as much info as possible from the section. sh_link and
2188 sh_info will be updated later */
2189 s->sh_addralign = sh->sh_addralign;
2190 s->sh_entsize = sh->sh_entsize;
2191 sm_table[i].new_section = 1;
2192 found:
2193 if (sh->sh_type != s->sh_type) {
2194 tcc_error_noabort("invalid section type");
2195 goto fail;
2198 /* align start of section */
2199 offset = s->data_offset;
2201 if (0 == strcmp(sh_name, ".stab")) {
2202 stab_index = i;
2203 goto no_align;
2205 if (0 == strcmp(sh_name, ".stabstr")) {
2206 stabstr_index = i;
2207 goto no_align;
2210 size = sh->sh_addralign - 1;
2211 offset = (offset + size) & ~size;
2212 if (sh->sh_addralign > s->sh_addralign)
2213 s->sh_addralign = sh->sh_addralign;
2214 s->data_offset = offset;
2215 no_align:
2216 sm_table[i].offset = offset;
2217 sm_table[i].s = s;
2218 /* concatenate sections */
2219 size = sh->sh_size;
2220 if (sh->sh_type != SHT_NOBITS) {
2221 unsigned char *ptr;
2222 lseek(fd, file_offset + sh->sh_offset, SEEK_SET);
2223 ptr = section_ptr_add(s, size);
2224 read(fd, ptr, size);
2225 } else {
2226 s->data_offset += size;
2228 next: ;
2231 /* gr relocate stab strings */
2232 if (stab_index && stabstr_index) {
2233 Stab_Sym *a, *b;
2234 unsigned o;
2235 s = sm_table[stab_index].s;
2236 a = (Stab_Sym *)(s->data + sm_table[stab_index].offset);
2237 b = (Stab_Sym *)(s->data + s->data_offset);
2238 o = sm_table[stabstr_index].offset;
2239 while (a < b)
2240 a->n_strx += o, a++;
2243 /* second short pass to update sh_link and sh_info fields of new
2244 sections */
2245 for(i = 1; i < ehdr.e_shnum; i++) {
2246 s = sm_table[i].s;
2247 if (!s || !sm_table[i].new_section)
2248 continue;
2249 sh = &shdr[i];
2250 if (sh->sh_link > 0)
2251 s->link = sm_table[sh->sh_link].s;
2252 if (sh->sh_type == SHT_RELX) {
2253 s->sh_info = sm_table[sh->sh_info].s->sh_num;
2254 /* update backward link */
2255 s1->sections[s->sh_info]->reloc = s;
2258 sm = sm_table;
2260 /* resolve symbols */
2261 old_to_new_syms = tcc_mallocz(nb_syms * sizeof(int));
2263 sym = symtab + 1;
2264 for(i = 1; i < nb_syms; i++, sym++) {
2265 if (sym->st_shndx != SHN_UNDEF &&
2266 sym->st_shndx < SHN_LORESERVE) {
2267 sm = &sm_table[sym->st_shndx];
2268 if (sm->link_once) {
2269 /* if a symbol is in a link once section, we use the
2270 already defined symbol. It is very important to get
2271 correct relocations */
2272 if (ELFW(ST_BIND)(sym->st_info) != STB_LOCAL) {
2273 name = (char *) strtab + sym->st_name;
2274 sym_index = find_elf_sym(symtab_section, name);
2275 if (sym_index)
2276 old_to_new_syms[i] = sym_index;
2278 continue;
2280 /* if no corresponding section added, no need to add symbol */
2281 if (!sm->s)
2282 continue;
2283 /* convert section number */
2284 sym->st_shndx = sm->s->sh_num;
2285 /* offset value */
2286 sym->st_value += sm->offset;
2288 /* add symbol */
2289 name = (char *) strtab + sym->st_name;
2290 sym_index = set_elf_sym(symtab_section, sym->st_value, sym->st_size,
2291 sym->st_info, sym->st_other,
2292 sym->st_shndx, name);
2293 old_to_new_syms[i] = sym_index;
2296 /* third pass to patch relocation entries */
2297 for(i = 1; i < ehdr.e_shnum; i++) {
2298 s = sm_table[i].s;
2299 if (!s)
2300 continue;
2301 sh = &shdr[i];
2302 offset = sm_table[i].offset;
2303 switch(s->sh_type) {
2304 case SHT_RELX:
2305 /* take relocation offset information */
2306 offseti = sm_table[sh->sh_info].offset;
2307 for_each_elem(s, (offset / sizeof(*rel)), rel, ElfW_Rel) {
2308 int type;
2309 unsigned sym_index;
2310 /* convert symbol index */
2311 type = ELFW(R_TYPE)(rel->r_info);
2312 sym_index = ELFW(R_SYM)(rel->r_info);
2313 /* NOTE: only one symtab assumed */
2314 if (sym_index >= nb_syms)
2315 goto invalid_reloc;
2316 sym_index = old_to_new_syms[sym_index];
2317 /* ignore link_once in rel section. */
2318 if (!sym_index && !sm->link_once
2319 #ifdef TCC_TARGET_ARM
2320 && type != R_ARM_V4BX
2321 #endif
2323 invalid_reloc:
2324 tcc_error_noabort("Invalid relocation entry [%2d] '%s' @ %.8x",
2325 i, strsec + sh->sh_name, rel->r_offset);
2326 goto fail;
2328 rel->r_info = ELFW(R_INFO)(sym_index, type);
2329 /* offset the relocation offset */
2330 rel->r_offset += offseti;
2331 #ifdef TCC_TARGET_ARM
2332 /* Jumps and branches from a Thumb code to a PLT entry need
2333 special handling since PLT entries are ARM code.
2334 Unconditional bl instructions referencing PLT entries are
2335 handled by converting these instructions into blx
2336 instructions. Other case of instructions referencing a PLT
2337 entry require to add a Thumb stub before the PLT entry to
2338 switch to ARM mode. We set bit plt_thumb_stub of the
2339 attribute of a symbol to indicate such a case. */
2340 if (type == R_ARM_THM_JUMP24)
2341 get_sym_attr(s1, sym_index, 1)->plt_thumb_stub = 1;
2342 #endif
2344 break;
2345 default:
2346 break;
2350 ret = 0;
2351 the_end:
2352 tcc_free(symtab);
2353 tcc_free(strtab);
2354 tcc_free(old_to_new_syms);
2355 tcc_free(sm_table);
2356 tcc_free(strsec);
2357 tcc_free(shdr);
2358 return ret;
2361 typedef struct ArchiveHeader {
2362 char ar_name[16]; /* name of this member */
2363 char ar_date[12]; /* file mtime */
2364 char ar_uid[6]; /* owner uid; printed as decimal */
2365 char ar_gid[6]; /* owner gid; printed as decimal */
2366 char ar_mode[8]; /* file mode, printed as octal */
2367 char ar_size[10]; /* file size, printed as decimal */
2368 char ar_fmag[2]; /* should contain ARFMAG */
2369 } ArchiveHeader;
2371 static int get_be32(const uint8_t *b)
2373 return b[3] | (b[2] << 8) | (b[1] << 16) | (b[0] << 24);
2376 static long get_be64(const uint8_t *b)
2378 long long ret = get_be32(b);
2379 ret = (ret << 32) | (unsigned)get_be32(b+4);
2380 return (long)ret;
2383 /* load only the objects which resolve undefined symbols */
2384 static int tcc_load_alacarte(TCCState *s1, int fd, int size, int entrysize)
2386 long i, bound, nsyms, sym_index, off, ret;
2387 uint8_t *data;
2388 const char *ar_names, *p;
2389 const uint8_t *ar_index;
2390 ElfW(Sym) *sym;
2392 data = tcc_malloc(size);
2393 if (read(fd, data, size) != size)
2394 goto fail;
2395 nsyms = entrysize == 4 ? get_be32(data) : get_be64(data);
2396 ar_index = data + entrysize;
2397 ar_names = (char *) ar_index + nsyms * entrysize;
2399 do {
2400 bound = 0;
2401 for(p = ar_names, i = 0; i < nsyms; i++, p += strlen(p)+1) {
2402 sym_index = find_elf_sym(symtab_section, p);
2403 if(sym_index) {
2404 sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
2405 if(sym->st_shndx == SHN_UNDEF) {
2406 off = (entrysize == 4
2407 ? get_be32(ar_index + i * 4)
2408 : get_be64(ar_index + i * 8))
2409 + sizeof(ArchiveHeader);
2410 ++bound;
2411 if(tcc_load_object_file(s1, fd, off) < 0) {
2412 fail:
2413 ret = -1;
2414 goto the_end;
2419 } while(bound);
2420 ret = 0;
2421 the_end:
2422 tcc_free(data);
2423 return ret;
2426 /* load a '.a' file */
2427 ST_FUNC int tcc_load_archive(TCCState *s1, int fd)
2429 ArchiveHeader hdr;
2430 char ar_size[11];
2431 char ar_name[17];
2432 char magic[8];
2433 int size, len, i;
2434 unsigned long file_offset;
2436 /* skip magic which was already checked */
2437 read(fd, magic, sizeof(magic));
2439 for(;;) {
2440 len = read(fd, &hdr, sizeof(hdr));
2441 if (len == 0)
2442 break;
2443 if (len != sizeof(hdr)) {
2444 tcc_error_noabort("invalid archive");
2445 return -1;
2447 memcpy(ar_size, hdr.ar_size, sizeof(hdr.ar_size));
2448 ar_size[sizeof(hdr.ar_size)] = '\0';
2449 size = strtol(ar_size, NULL, 0);
2450 memcpy(ar_name, hdr.ar_name, sizeof(hdr.ar_name));
2451 for(i = sizeof(hdr.ar_name) - 1; i >= 0; i--) {
2452 if (ar_name[i] != ' ')
2453 break;
2455 ar_name[i + 1] = '\0';
2456 file_offset = lseek(fd, 0, SEEK_CUR);
2457 /* align to even */
2458 size = (size + 1) & ~1;
2459 if (!strcmp(ar_name, "/")) {
2460 /* coff symbol table : we handle it */
2461 if(s1->alacarte_link)
2462 return tcc_load_alacarte(s1, fd, size, 4);
2463 } else if (!strcmp(ar_name, "/SYM64/")) {
2464 if(s1->alacarte_link)
2465 return tcc_load_alacarte(s1, fd, size, 8);
2466 } else {
2467 ElfW(Ehdr) ehdr;
2468 if (tcc_object_type(fd, &ehdr) == AFF_BINTYPE_REL) {
2469 if (tcc_load_object_file(s1, fd, file_offset) < 0)
2470 return -1;
2473 lseek(fd, file_offset + size, SEEK_SET);
2475 return 0;
2478 #ifndef TCC_TARGET_PE
2479 /* load a DLL and all referenced DLLs. 'level = 0' means that the DLL
2480 is referenced by the user (so it should be added as DT_NEEDED in
2481 the generated ELF file) */
2482 ST_FUNC int tcc_load_dll(TCCState *s1, int fd, const char *filename, int level)
2484 ElfW(Ehdr) ehdr;
2485 ElfW(Shdr) *shdr, *sh, *sh1;
2486 int i, j, nb_syms, nb_dts, sym_bind, ret;
2487 ElfW(Sym) *sym, *dynsym;
2488 ElfW(Dyn) *dt, *dynamic;
2489 unsigned char *dynstr;
2490 const char *name, *soname;
2491 DLLReference *dllref;
2493 read(fd, &ehdr, sizeof(ehdr));
2495 /* test CPU specific stuff */
2496 if (ehdr.e_ident[5] != ELFDATA2LSB ||
2497 ehdr.e_machine != EM_TCC_TARGET) {
2498 tcc_error_noabort("bad architecture");
2499 return -1;
2502 /* read sections */
2503 shdr = load_data(fd, ehdr.e_shoff, sizeof(ElfW(Shdr)) * ehdr.e_shnum);
2505 /* load dynamic section and dynamic symbols */
2506 nb_syms = 0;
2507 nb_dts = 0;
2508 dynamic = NULL;
2509 dynsym = NULL; /* avoid warning */
2510 dynstr = NULL; /* avoid warning */
2511 for(i = 0, sh = shdr; i < ehdr.e_shnum; i++, sh++) {
2512 switch(sh->sh_type) {
2513 case SHT_DYNAMIC:
2514 nb_dts = sh->sh_size / sizeof(ElfW(Dyn));
2515 dynamic = load_data(fd, sh->sh_offset, sh->sh_size);
2516 break;
2517 case SHT_DYNSYM:
2518 nb_syms = sh->sh_size / sizeof(ElfW(Sym));
2519 dynsym = load_data(fd, sh->sh_offset, sh->sh_size);
2520 sh1 = &shdr[sh->sh_link];
2521 dynstr = load_data(fd, sh1->sh_offset, sh1->sh_size);
2522 break;
2523 default:
2524 break;
2528 /* compute the real library name */
2529 soname = tcc_basename(filename);
2531 for(i = 0, dt = dynamic; i < nb_dts; i++, dt++) {
2532 if (dt->d_tag == DT_SONAME) {
2533 soname = (char *) dynstr + dt->d_un.d_val;
2537 /* if the dll is already loaded, do not load it */
2538 for(i = 0; i < s1->nb_loaded_dlls; i++) {
2539 dllref = s1->loaded_dlls[i];
2540 if (!strcmp(soname, dllref->name)) {
2541 /* but update level if needed */
2542 if (level < dllref->level)
2543 dllref->level = level;
2544 ret = 0;
2545 goto the_end;
2549 /* add the dll and its level */
2550 dllref = tcc_mallocz(sizeof(DLLReference) + strlen(soname));
2551 dllref->level = level;
2552 strcpy(dllref->name, soname);
2553 dynarray_add((void ***)&s1->loaded_dlls, &s1->nb_loaded_dlls, dllref);
2555 /* add dynamic symbols in dynsym_section */
2556 for(i = 1, sym = dynsym + 1; i < nb_syms; i++, sym++) {
2557 sym_bind = ELFW(ST_BIND)(sym->st_info);
2558 if (sym_bind == STB_LOCAL)
2559 continue;
2560 name = (char *) dynstr + sym->st_name;
2561 set_elf_sym(s1->dynsymtab_section, sym->st_value, sym->st_size,
2562 sym->st_info, sym->st_other, sym->st_shndx, name);
2565 /* load all referenced DLLs */
2566 for(i = 0, dt = dynamic; i < nb_dts; i++, dt++) {
2567 switch(dt->d_tag) {
2568 case DT_NEEDED:
2569 name = (char *) dynstr + dt->d_un.d_val;
2570 for(j = 0; j < s1->nb_loaded_dlls; j++) {
2571 dllref = s1->loaded_dlls[j];
2572 if (!strcmp(name, dllref->name))
2573 goto already_loaded;
2575 if (tcc_add_dll(s1, name, AFF_REFERENCED_DLL) < 0) {
2576 tcc_error_noabort("referenced dll '%s' not found", name);
2577 ret = -1;
2578 goto the_end;
2580 already_loaded:
2581 break;
2584 ret = 0;
2585 the_end:
2586 tcc_free(dynstr);
2587 tcc_free(dynsym);
2588 tcc_free(dynamic);
2589 tcc_free(shdr);
2590 return ret;
2593 #define LD_TOK_NAME 256
2594 #define LD_TOK_EOF (-1)
2596 /* return next ld script token */
2597 static int ld_next(TCCState *s1, char *name, int name_size)
2599 int c;
2600 char *q;
2602 redo:
2603 switch(ch) {
2604 case ' ':
2605 case '\t':
2606 case '\f':
2607 case '\v':
2608 case '\r':
2609 case '\n':
2610 inp();
2611 goto redo;
2612 case '/':
2613 minp();
2614 if (ch == '*') {
2615 file->buf_ptr = parse_comment(file->buf_ptr);
2616 ch = file->buf_ptr[0];
2617 goto redo;
2618 } else {
2619 q = name;
2620 *q++ = '/';
2621 goto parse_name;
2623 break;
2624 case '\\':
2625 ch = handle_eob();
2626 if (ch != '\\')
2627 goto redo;
2628 /* fall through */
2629 /* case 'a' ... 'z': */
2630 case 'a':
2631 case 'b':
2632 case 'c':
2633 case 'd':
2634 case 'e':
2635 case 'f':
2636 case 'g':
2637 case 'h':
2638 case 'i':
2639 case 'j':
2640 case 'k':
2641 case 'l':
2642 case 'm':
2643 case 'n':
2644 case 'o':
2645 case 'p':
2646 case 'q':
2647 case 'r':
2648 case 's':
2649 case 't':
2650 case 'u':
2651 case 'v':
2652 case 'w':
2653 case 'x':
2654 case 'y':
2655 case 'z':
2656 /* case 'A' ... 'z': */
2657 case 'A':
2658 case 'B':
2659 case 'C':
2660 case 'D':
2661 case 'E':
2662 case 'F':
2663 case 'G':
2664 case 'H':
2665 case 'I':
2666 case 'J':
2667 case 'K':
2668 case 'L':
2669 case 'M':
2670 case 'N':
2671 case 'O':
2672 case 'P':
2673 case 'Q':
2674 case 'R':
2675 case 'S':
2676 case 'T':
2677 case 'U':
2678 case 'V':
2679 case 'W':
2680 case 'X':
2681 case 'Y':
2682 case 'Z':
2683 case '_':
2684 case '.':
2685 case '$':
2686 case '~':
2687 q = name;
2688 parse_name:
2689 for(;;) {
2690 if (!((ch >= 'a' && ch <= 'z') ||
2691 (ch >= 'A' && ch <= 'Z') ||
2692 (ch >= '0' && ch <= '9') ||
2693 strchr("/.-_+=$:\\,~", ch)))
2694 break;
2695 if ((q - name) < name_size - 1) {
2696 *q++ = ch;
2698 minp();
2700 *q = '\0';
2701 c = LD_TOK_NAME;
2702 break;
2703 case CH_EOF:
2704 c = LD_TOK_EOF;
2705 break;
2706 default:
2707 c = ch;
2708 inp();
2709 break;
2711 return c;
2714 static int ld_add_file(TCCState *s1, const char filename[])
2716 int ret;
2718 ret = tcc_add_file_internal(s1, filename, AFF_TYPE_BIN);
2719 if (ret)
2720 ret = tcc_add_dll(s1, filename, 0);
2721 return ret;
2724 static inline int new_undef_syms(void)
2726 int ret = 0;
2727 ret = new_undef_sym;
2728 new_undef_sym = 0;
2729 return ret;
2732 static int ld_add_file_list(TCCState *s1, const char *cmd, int as_needed)
2734 char filename[1024], libname[1024];
2735 int t, group, nblibs = 0, ret = 0;
2736 char **libs = NULL;
2738 group = !strcmp(cmd, "GROUP");
2739 if (!as_needed)
2740 new_undef_syms();
2741 t = ld_next(s1, filename, sizeof(filename));
2742 if (t != '(')
2743 expect("(");
2744 t = ld_next(s1, filename, sizeof(filename));
2745 for(;;) {
2746 libname[0] = '\0';
2747 if (t == LD_TOK_EOF) {
2748 tcc_error_noabort("unexpected end of file");
2749 ret = -1;
2750 goto lib_parse_error;
2751 } else if (t == ')') {
2752 break;
2753 } else if (t == '-') {
2754 t = ld_next(s1, filename, sizeof(filename));
2755 if ((t != LD_TOK_NAME) || (filename[0] != 'l')) {
2756 tcc_error_noabort("library name expected");
2757 ret = -1;
2758 goto lib_parse_error;
2760 pstrcpy(libname, sizeof libname, &filename[1]);
2761 if (s1->static_link) {
2762 snprintf(filename, sizeof filename, "lib%s.a", libname);
2763 } else {
2764 snprintf(filename, sizeof filename, "lib%s.so", libname);
2766 } else if (t != LD_TOK_NAME) {
2767 tcc_error_noabort("filename expected");
2768 ret = -1;
2769 goto lib_parse_error;
2771 if (!strcmp(filename, "AS_NEEDED")) {
2772 ret = ld_add_file_list(s1, cmd, 1);
2773 if (ret)
2774 goto lib_parse_error;
2775 } else {
2776 /* TODO: Implement AS_NEEDED support. Ignore it for now */
2777 if (!as_needed) {
2778 ret = ld_add_file(s1, filename);
2779 if (ret)
2780 goto lib_parse_error;
2781 if (group) {
2782 /* Add the filename *and* the libname to avoid future conversions */
2783 dynarray_add((void ***) &libs, &nblibs, tcc_strdup(filename));
2784 if (libname[0] != '\0')
2785 dynarray_add((void ***) &libs, &nblibs, tcc_strdup(libname));
2789 t = ld_next(s1, filename, sizeof(filename));
2790 if (t == ',') {
2791 t = ld_next(s1, filename, sizeof(filename));
2794 if (group && !as_needed) {
2795 while (new_undef_syms()) {
2796 int i;
2798 for (i = 0; i < nblibs; i ++)
2799 ld_add_file(s1, libs[i]);
2802 lib_parse_error:
2803 dynarray_reset(&libs, &nblibs);
2804 return ret;
2807 /* interpret a subset of GNU ldscripts to handle the dummy libc.so
2808 files */
2809 ST_FUNC int tcc_load_ldscript(TCCState *s1)
2811 char cmd[64];
2812 char filename[1024];
2813 int t, ret;
2815 ch = handle_eob();
2816 for(;;) {
2817 t = ld_next(s1, cmd, sizeof(cmd));
2818 if (t == LD_TOK_EOF)
2819 return 0;
2820 else if (t != LD_TOK_NAME)
2821 return -1;
2822 if (!strcmp(cmd, "INPUT") ||
2823 !strcmp(cmd, "GROUP")) {
2824 ret = ld_add_file_list(s1, cmd, 0);
2825 if (ret)
2826 return ret;
2827 } else if (!strcmp(cmd, "OUTPUT_FORMAT") ||
2828 !strcmp(cmd, "TARGET")) {
2829 /* ignore some commands */
2830 t = ld_next(s1, cmd, sizeof(cmd));
2831 if (t != '(')
2832 expect("(");
2833 for(;;) {
2834 t = ld_next(s1, filename, sizeof(filename));
2835 if (t == LD_TOK_EOF) {
2836 tcc_error_noabort("unexpected end of file");
2837 return -1;
2838 } else if (t == ')') {
2839 break;
2842 } else {
2843 return -1;
2846 return 0;
2848 #endif /* !TCC_TARGET_PE */