Recognize more relocations as needing GOT/PLT entry
[tinycc.git] / tccelf.c
blobe0eaea524387975498cf9ab834027ac5c3ab512d
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);
72 #ifdef CONFIG_TCC_BCHECK
73 ST_FUNC void tccelf_bounds_new(TCCState *s)
75 /* create bounds sections */
76 bounds_section = new_section(s, ".bounds",
77 SHT_PROGBITS, SHF_ALLOC);
78 lbounds_section = new_section(s, ".lbounds",
79 SHT_PROGBITS, SHF_ALLOC);
81 #endif
83 ST_FUNC void tccelf_stab_new(TCCState *s)
85 stab_section = new_section(s, ".stab", SHT_PROGBITS, 0);
86 stab_section->sh_entsize = sizeof(Stab_Sym);
87 stabstr_section = new_section(s, ".stabstr", SHT_STRTAB, 0);
88 put_elf_str(stabstr_section, "");
89 stab_section->link = stabstr_section;
90 /* put first entry */
91 put_stabs("", 0, 0, 0, 0);
94 static void free_section(Section *s)
96 tcc_free(s->data);
99 ST_FUNC void tccelf_delete(TCCState *s1)
101 int i;
103 /* free all sections */
104 for(i = 1; i < s1->nb_sections; i++)
105 free_section(s1->sections[i]);
106 dynarray_reset(&s1->sections, &s1->nb_sections);
108 for(i = 0; i < s1->nb_priv_sections; i++)
109 free_section(s1->priv_sections[i]);
110 dynarray_reset(&s1->priv_sections, &s1->nb_priv_sections);
112 /* free any loaded DLLs */
113 #ifdef TCC_IS_NATIVE
114 for ( i = 0; i < s1->nb_loaded_dlls; i++) {
115 DLLReference *ref = s1->loaded_dlls[i];
116 if ( ref->handle )
117 # ifdef _WIN32
118 FreeLibrary((HMODULE)ref->handle);
119 # else
120 dlclose(ref->handle);
121 # endif
123 #endif
124 /* free loaded dlls array */
125 dynarray_reset(&s1->loaded_dlls, &s1->nb_loaded_dlls);
128 ST_FUNC Section *new_section(TCCState *s1, const char *name, int sh_type, int sh_flags)
130 Section *sec;
132 sec = tcc_mallocz(sizeof(Section) + strlen(name));
133 strcpy(sec->name, name);
134 sec->sh_type = sh_type;
135 sec->sh_flags = sh_flags;
136 switch(sh_type) {
137 case SHT_HASH:
138 case SHT_REL:
139 case SHT_RELA:
140 case SHT_DYNSYM:
141 case SHT_SYMTAB:
142 case SHT_DYNAMIC:
143 sec->sh_addralign = 4;
144 break;
145 case SHT_STRTAB:
146 sec->sh_addralign = 1;
147 break;
148 default:
149 sec->sh_addralign = PTR_SIZE; /* gcc/pcc default aligment */
150 break;
153 if (sh_flags & SHF_PRIVATE) {
154 dynarray_add((void ***)&s1->priv_sections, &s1->nb_priv_sections, sec);
155 } else {
156 sec->sh_num = s1->nb_sections;
157 dynarray_add((void ***)&s1->sections, &s1->nb_sections, sec);
160 return sec;
163 /* realloc section and set its content to zero */
164 ST_FUNC void section_realloc(Section *sec, unsigned long new_size)
166 unsigned long size;
167 unsigned char *data;
169 size = sec->data_allocated;
170 if (size == 0)
171 size = 1;
172 while (size < new_size)
173 size = size * 2;
174 data = tcc_realloc(sec->data, size);
175 memset(data + sec->data_allocated, 0, size - sec->data_allocated);
176 sec->data = data;
177 sec->data_allocated = size;
180 /* reserve at least 'size' bytes in section 'sec' from
181 sec->data_offset. */
182 ST_FUNC void *section_ptr_add(Section *sec, addr_t size)
184 size_t offset, offset1;
186 offset = sec->data_offset;
187 offset1 = offset + size;
188 if (offset1 > sec->data_allocated)
189 section_realloc(sec, offset1);
190 sec->data_offset = offset1;
191 return sec->data + offset;
194 /* reserve at least 'size' bytes from section start */
195 ST_FUNC void section_reserve(Section *sec, unsigned long size)
197 if (size > sec->data_allocated)
198 section_realloc(sec, size);
199 if (size > sec->data_offset)
200 sec->data_offset = size;
203 /* return a reference to a section, and create it if it does not
204 exists */
205 ST_FUNC Section *find_section(TCCState *s1, const char *name)
207 Section *sec;
208 int i;
209 for(i = 1; i < s1->nb_sections; i++) {
210 sec = s1->sections[i];
211 if (!strcmp(name, sec->name))
212 return sec;
214 /* sections are created as PROGBITS */
215 return new_section(s1, name, SHT_PROGBITS, SHF_ALLOC);
218 /* ------------------------------------------------------------------------- */
220 ST_FUNC int put_elf_str(Section *s, const char *sym)
222 int offset, len;
223 char *ptr;
225 len = strlen(sym) + 1;
226 offset = s->data_offset;
227 ptr = section_ptr_add(s, len);
228 memcpy(ptr, sym, len);
229 return offset;
232 /* elf symbol hashing function */
233 static unsigned long elf_hash(const unsigned char *name)
235 unsigned long h = 0, g;
237 while (*name) {
238 h = (h << 4) + *name++;
239 g = h & 0xf0000000;
240 if (g)
241 h ^= g >> 24;
242 h &= ~g;
244 return h;
247 /* rebuild hash table of section s */
248 /* NOTE: we do factorize the hash table code to go faster */
249 static void rebuild_hash(Section *s, unsigned int nb_buckets)
251 ElfW(Sym) *sym;
252 int *ptr, *hash, nb_syms, sym_index, h;
253 unsigned char *strtab;
255 strtab = s->link->data;
256 nb_syms = s->data_offset / sizeof(ElfW(Sym));
258 s->hash->data_offset = 0;
259 ptr = section_ptr_add(s->hash, (2 + nb_buckets + nb_syms) * sizeof(int));
260 ptr[0] = nb_buckets;
261 ptr[1] = nb_syms;
262 ptr += 2;
263 hash = ptr;
264 memset(hash, 0, (nb_buckets + 1) * sizeof(int));
265 ptr += nb_buckets + 1;
267 sym = (ElfW(Sym) *)s->data + 1;
268 for(sym_index = 1; sym_index < nb_syms; sym_index++) {
269 if (ELFW(ST_BIND)(sym->st_info) != STB_LOCAL) {
270 h = elf_hash(strtab + sym->st_name) % nb_buckets;
271 *ptr = hash[h];
272 hash[h] = sym_index;
273 } else {
274 *ptr = 0;
276 ptr++;
277 sym++;
281 /* return the symbol number */
282 ST_FUNC int put_elf_sym(Section *s, addr_t value, unsigned long size,
283 int info, int other, int shndx, const char *name)
285 int name_offset, sym_index;
286 int nbuckets, h;
287 ElfW(Sym) *sym;
288 Section *hs;
290 sym = section_ptr_add(s, sizeof(ElfW(Sym)));
291 if (name)
292 name_offset = put_elf_str(s->link, name);
293 else
294 name_offset = 0;
295 /* XXX: endianness */
296 sym->st_name = name_offset;
297 sym->st_value = value;
298 sym->st_size = size;
299 sym->st_info = info;
300 sym->st_other = other;
301 sym->st_shndx = shndx;
302 sym_index = sym - (ElfW(Sym) *)s->data;
303 hs = s->hash;
304 if (hs) {
305 int *ptr, *base;
306 ptr = section_ptr_add(hs, sizeof(int));
307 base = (int *)hs->data;
308 /* only add global or weak symbols */
309 if (ELFW(ST_BIND)(info) != STB_LOCAL) {
310 /* add another hashing entry */
311 nbuckets = base[0];
312 h = elf_hash((unsigned char *) name) % nbuckets;
313 *ptr = base[2 + h];
314 base[2 + h] = sym_index;
315 base[1]++;
316 /* we resize the hash table */
317 hs->nb_hashed_syms++;
318 if (hs->nb_hashed_syms > 2 * nbuckets) {
319 rebuild_hash(s, 2 * nbuckets);
321 } else {
322 *ptr = 0;
323 base[1]++;
326 return sym_index;
329 /* find global ELF symbol 'name' and return its index. Return 0 if not
330 found. */
331 ST_FUNC int find_elf_sym(Section *s, const char *name)
333 ElfW(Sym) *sym;
334 Section *hs;
335 int nbuckets, sym_index, h;
336 const char *name1;
338 hs = s->hash;
339 if (!hs)
340 return 0;
341 nbuckets = ((int *)hs->data)[0];
342 h = elf_hash((unsigned char *) name) % nbuckets;
343 sym_index = ((int *)hs->data)[2 + h];
344 while (sym_index != 0) {
345 sym = &((ElfW(Sym) *)s->data)[sym_index];
346 name1 = (char *) s->link->data + sym->st_name;
347 if (!strcmp(name, name1))
348 return sym_index;
349 sym_index = ((int *)hs->data)[2 + nbuckets + sym_index];
351 return 0;
354 /* return elf symbol value, signal error if 'err' is nonzero */
355 ST_FUNC addr_t get_elf_sym_addr(TCCState *s, const char *name, int err)
357 int sym_index;
358 ElfW(Sym) *sym;
360 sym_index = find_elf_sym(s->symtab, name);
361 sym = &((ElfW(Sym) *)s->symtab->data)[sym_index];
362 if (!sym_index || sym->st_shndx == SHN_UNDEF) {
363 if (err)
364 tcc_error("%s not defined", name);
365 return 0;
367 return sym->st_value;
370 /* return elf symbol value */
371 LIBTCCAPI void *tcc_get_symbol(TCCState *s, const char *name)
373 return (void*)(uintptr_t)get_elf_sym_addr(s, name, 0);
376 #if defined TCC_IS_NATIVE || defined TCC_TARGET_PE
377 /* return elf symbol value or error */
378 ST_FUNC void* tcc_get_symbol_err(TCCState *s, const char *name)
380 return (void*)(uintptr_t)get_elf_sym_addr(s, name, 1);
382 #endif
384 /* add an elf symbol : check if it is already defined and patch
385 it. Return symbol index. NOTE that sh_num can be SHN_UNDEF. */
386 ST_FUNC int set_elf_sym(Section *s, addr_t value, unsigned long size,
387 int info, int other, int shndx, const char *name)
389 ElfW(Sym) *esym;
390 int sym_bind, sym_index, sym_type, esym_bind;
391 unsigned char sym_vis, esym_vis, new_vis;
393 sym_bind = ELFW(ST_BIND)(info);
394 sym_type = ELFW(ST_TYPE)(info);
395 sym_vis = ELFW(ST_VISIBILITY)(other);
397 sym_index = find_elf_sym(s, name);
398 esym = &((ElfW(Sym) *)s->data)[sym_index];
399 if (sym_index && esym->st_value == value && esym->st_size == size
400 && esym->st_info == info && esym->st_other == other
401 && esym->st_shndx == shndx)
402 return sym_index;
404 if (sym_bind != STB_LOCAL) {
405 /* we search global or weak symbols */
406 if (!sym_index)
407 goto do_def;
408 if (esym->st_shndx != SHN_UNDEF) {
409 esym_bind = ELFW(ST_BIND)(esym->st_info);
410 /* propagate the most constraining visibility */
411 /* STV_DEFAULT(0)<STV_PROTECTED(3)<STV_HIDDEN(2)<STV_INTERNAL(1) */
412 esym_vis = ELFW(ST_VISIBILITY)(esym->st_other);
413 if (esym_vis == STV_DEFAULT) {
414 new_vis = sym_vis;
415 } else if (sym_vis == STV_DEFAULT) {
416 new_vis = esym_vis;
417 } else {
418 new_vis = (esym_vis < sym_vis) ? esym_vis : sym_vis;
420 esym->st_other = (esym->st_other & ~ELFW(ST_VISIBILITY)(-1))
421 | new_vis;
422 other = esym->st_other; /* in case we have to patch esym */
423 if (shndx == SHN_UNDEF) {
424 /* ignore adding of undefined symbol if the
425 corresponding symbol is already defined */
426 } else if (sym_bind == STB_GLOBAL && esym_bind == STB_WEAK) {
427 /* global overrides weak, so patch */
428 goto do_patch;
429 } else if (sym_bind == STB_WEAK && esym_bind == STB_GLOBAL) {
430 /* weak is ignored if already global */
431 } else if (sym_bind == STB_WEAK && esym_bind == STB_WEAK) {
432 /* keep first-found weak definition, ignore subsequents */
433 } else if (sym_vis == STV_HIDDEN || sym_vis == STV_INTERNAL) {
434 /* ignore hidden symbols after */
435 } else if ((esym->st_shndx == SHN_COMMON
436 || esym->st_shndx == bss_section->sh_num)
437 && (shndx < SHN_LORESERVE
438 && shndx != bss_section->sh_num)) {
439 /* data symbol gets precedence over common/bss */
440 goto do_patch;
441 } else if (shndx == SHN_COMMON || shndx == bss_section->sh_num) {
442 /* data symbol keeps precedence over common/bss */
443 } else if (s == tcc_state->dynsymtab_section) {
444 /* we accept that two DLL define the same symbol */
445 } else {
446 #if 0
447 printf("new_bind=%x new_shndx=%x new_vis=%x old_bind=%x old_shndx=%x old_vis=%x\n",
448 sym_bind, shndx, new_vis, esym_bind, esym->st_shndx, esym_vis);
449 #endif
450 tcc_error_noabort("'%s' defined twice", name);
452 } else {
453 do_patch:
454 esym->st_info = ELFW(ST_INFO)(sym_bind, sym_type);
455 esym->st_shndx = shndx;
456 new_undef_sym = 1;
457 esym->st_value = value;
458 esym->st_size = size;
459 esym->st_other = other;
461 } else {
462 do_def:
463 sym_index = put_elf_sym(s, value, size,
464 ELFW(ST_INFO)(sym_bind, sym_type), other,
465 shndx, name);
467 return sym_index;
470 /* put relocation */
471 ST_FUNC void put_elf_reloca(Section *symtab, Section *s, unsigned long offset,
472 int type, int symbol, addr_t addend)
474 char buf[256];
475 Section *sr;
476 ElfW_Rel *rel;
478 sr = s->reloc;
479 if (!sr) {
480 /* if no relocation section, create it */
481 snprintf(buf, sizeof(buf), REL_SECTION_FMT, s->name);
482 /* if the symtab is allocated, then we consider the relocation
483 are also */
484 sr = new_section(tcc_state, buf, SHT_RELX, symtab->sh_flags);
485 sr->sh_entsize = sizeof(ElfW_Rel);
486 sr->link = symtab;
487 sr->sh_info = s->sh_num;
488 s->reloc = sr;
490 rel = section_ptr_add(sr, sizeof(ElfW_Rel));
491 rel->r_offset = offset;
492 rel->r_info = ELFW(R_INFO)(symbol, type);
493 #if defined(TCC_TARGET_ARM64) || defined(TCC_TARGET_X86_64)
494 rel->r_addend = addend;
495 #else
496 if (addend)
497 tcc_error("non-zero addend on REL architecture");
498 #endif
501 ST_FUNC void put_elf_reloc(Section *symtab, Section *s, unsigned long offset,
502 int type, int symbol)
504 put_elf_reloca(symtab, s, offset, type, symbol, 0);
507 /* put stab debug information */
509 ST_FUNC void put_stabs(const char *str, int type, int other, int desc,
510 unsigned long value)
512 Stab_Sym *sym;
514 sym = section_ptr_add(stab_section, sizeof(Stab_Sym));
515 if (str) {
516 sym->n_strx = put_elf_str(stabstr_section, str);
517 } else {
518 sym->n_strx = 0;
520 sym->n_type = type;
521 sym->n_other = other;
522 sym->n_desc = desc;
523 sym->n_value = value;
526 ST_FUNC void put_stabs_r(const char *str, int type, int other, int desc,
527 unsigned long value, Section *sec, int sym_index)
529 put_stabs(str, type, other, desc, value);
530 put_elf_reloc(symtab_section, stab_section,
531 stab_section->data_offset - sizeof(unsigned int),
532 R_DATA_32, sym_index);
535 ST_FUNC void put_stabn(int type, int other, int desc, int value)
537 put_stabs(NULL, type, other, desc, value);
540 ST_FUNC void put_stabd(int type, int other, int desc)
542 put_stabs(NULL, type, other, desc, 0);
545 /* Browse each elem of type <type> in section <sec> starting at elem <startoff>
546 using variable <elem> */
547 #define for_each_elem(sec, startoff, elem, type) \
548 for (elem = (type *) sec->data + startoff; \
549 elem < (type *) (sec->data + sec->data_offset); elem++)
551 /* In an ELF file symbol table, the local symbols must appear below
552 the global and weak ones. Since TCC cannot sort it while generating
553 the code, we must do it after. All the relocation tables are also
554 modified to take into account the symbol table sorting */
555 static void sort_syms(TCCState *s1, Section *s)
557 int *old_to_new_syms;
558 ElfW(Sym) *new_syms;
559 int nb_syms, i;
560 ElfW(Sym) *p, *q;
561 ElfW_Rel *rel;
562 Section *sr;
563 int type, sym_index;
565 nb_syms = s->data_offset / sizeof(ElfW(Sym));
566 new_syms = tcc_malloc(nb_syms * sizeof(ElfW(Sym)));
567 old_to_new_syms = tcc_malloc(nb_syms * sizeof(int));
569 /* first pass for local symbols */
570 p = (ElfW(Sym) *)s->data;
571 q = new_syms;
572 for(i = 0; i < nb_syms; i++) {
573 if (ELFW(ST_BIND)(p->st_info) == STB_LOCAL) {
574 old_to_new_syms[i] = q - new_syms;
575 *q++ = *p;
577 p++;
579 /* save the number of local symbols in section header */
580 s->sh_info = q - new_syms;
582 /* then second pass for non local symbols */
583 p = (ElfW(Sym) *)s->data;
584 for(i = 0; i < nb_syms; i++) {
585 if (ELFW(ST_BIND)(p->st_info) != STB_LOCAL) {
586 old_to_new_syms[i] = q - new_syms;
587 *q++ = *p;
589 p++;
592 /* we copy the new symbols to the old */
593 memcpy(s->data, new_syms, nb_syms * sizeof(ElfW(Sym)));
594 tcc_free(new_syms);
596 /* now we modify all the relocations */
597 for(i = 1; i < s1->nb_sections; i++) {
598 sr = s1->sections[i];
599 if (sr->sh_type == SHT_RELX && sr->link == s) {
600 for_each_elem(sr, 0, rel, ElfW_Rel) {
601 sym_index = ELFW(R_SYM)(rel->r_info);
602 type = ELFW(R_TYPE)(rel->r_info);
603 sym_index = old_to_new_syms[sym_index];
604 rel->r_info = ELFW(R_INFO)(sym_index, type);
609 tcc_free(old_to_new_syms);
612 /* relocate common symbols in the .bss section */
613 ST_FUNC void relocate_common_syms(void)
615 ElfW(Sym) *sym;
616 unsigned long offset, align;
618 for_each_elem(symtab_section, 1, sym, ElfW(Sym)) {
619 if (sym->st_shndx == SHN_COMMON) {
620 /* align symbol */
621 align = sym->st_value;
622 offset = bss_section->data_offset;
623 offset = (offset + align - 1) & -align;
624 sym->st_value = offset;
625 sym->st_shndx = bss_section->sh_num;
626 offset += sym->st_size;
627 bss_section->data_offset = offset;
632 /* relocate symbol table, resolve undefined symbols if do_resolve is
633 true and output error if undefined symbol. */
634 ST_FUNC void relocate_syms(TCCState *s1, int do_resolve)
636 ElfW(Sym) *sym, *esym;
637 int sym_bind, sh_num, sym_index;
638 const char *name;
640 for_each_elem(symtab_section, 1, sym, ElfW(Sym)) {
641 sh_num = sym->st_shndx;
642 if (sh_num == SHN_UNDEF) {
643 name = (char *) strtab_section->data + sym->st_name;
644 /* Use ld.so to resolve symbol for us (for tcc -run) */
645 if (do_resolve) {
646 #if defined TCC_IS_NATIVE && !defined TCC_TARGET_PE
647 void *addr;
648 name = (char *) symtab_section->link->data + sym->st_name;
649 addr = dlsym(RTLD_DEFAULT, name);
650 if (addr) {
651 sym->st_value = (addr_t)addr;
652 #ifdef DEBUG_RELOC
653 printf ("relocate_sym: %s -> 0x%lx\n", name, sym->st_value);
654 #endif
655 goto found;
657 #endif
658 } else if (s1->dynsym) {
659 /* if dynamic symbol exist, then use it */
660 sym_index = find_elf_sym(s1->dynsym, name);
661 if (sym_index) {
662 esym = &((ElfW(Sym) *)s1->dynsym->data)[sym_index];
663 sym->st_value = esym->st_value;
664 goto found;
667 /* XXX: _fp_hw seems to be part of the ABI, so we ignore
668 it */
669 if (!strcmp(name, "_fp_hw"))
670 goto found;
671 /* only weak symbols are accepted to be undefined. Their
672 value is zero */
673 sym_bind = ELFW(ST_BIND)(sym->st_info);
674 if (sym_bind == STB_WEAK) {
675 sym->st_value = 0;
676 } else {
677 tcc_error_noabort("undefined symbol '%s'", name);
679 } else if (sh_num < SHN_LORESERVE) {
680 /* add section base */
681 sym->st_value += s1->sections[sym->st_shndx]->sh_addr;
683 found: ;
687 /* relocate a given section (CPU dependent) by applying the relocations
688 in the associated relocation section */
689 ST_FUNC void relocate_section(TCCState *s1, Section *s)
691 Section *sr = s->reloc;
692 ElfW_Rel *rel;
693 ElfW(Sym) *sym;
694 int type, sym_index;
695 unsigned char *ptr;
696 addr_t val, addr;
698 relocate_init(sr);
699 for_each_elem(sr, 0, rel, ElfW_Rel) {
700 ptr = s->data + rel->r_offset;
702 sym_index = ELFW(R_SYM)(rel->r_info);
703 sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
704 val = sym->st_value;
705 #if defined(TCC_TARGET_ARM64) || defined(TCC_TARGET_X86_64)
706 val += rel->r_addend;
707 #endif
708 type = ELFW(R_TYPE)(rel->r_info);
709 addr = s->sh_addr + rel->r_offset;
711 relocate(s1, rel, type, ptr, addr, val);
713 /* if the relocation is allocated, we change its symbol table */
714 if (sr->sh_flags & SHF_ALLOC)
715 sr->link = s1->dynsym;
718 /* relocate relocation table in 'sr' */
719 static void relocate_rel(TCCState *s1, Section *sr)
721 Section *s;
722 ElfW_Rel *rel;
724 s = s1->sections[sr->sh_info];
725 for_each_elem(sr, 0, rel, ElfW_Rel)
726 rel->r_offset += s->sh_addr;
729 /* count the number of dynamic relocations so that we can reserve
730 their space */
731 static int prepare_dynamic_rel(TCCState *s1, Section *sr)
733 ElfW_Rel *rel;
734 int sym_index, esym_index, type, count;
736 count = 0;
737 for_each_elem(sr, 0, rel, ElfW_Rel) {
738 sym_index = ELFW(R_SYM)(rel->r_info);
739 type = ELFW(R_TYPE)(rel->r_info);
740 switch(type) {
741 #if defined(TCC_TARGET_I386)
742 case R_386_32:
743 #elif defined(TCC_TARGET_X86_64)
744 case R_X86_64_32:
745 case R_X86_64_32S:
746 case R_X86_64_64:
747 #endif
748 count++;
749 break;
750 #if defined(TCC_TARGET_I386)
751 case R_386_PC32:
752 #elif defined(TCC_TARGET_X86_64)
753 case R_X86_64_PC32:
754 #endif
755 esym_index = s1->symtab_to_dynsym[sym_index];
756 if (esym_index)
757 count++;
758 break;
759 default:
760 break;
763 if (count) {
764 /* allocate the section */
765 sr->sh_flags |= SHF_ALLOC;
766 sr->sh_size = count * sizeof(ElfW_Rel);
768 return count;
771 static struct sym_attr *alloc_sym_attr(TCCState *s1, int index)
773 int n;
774 struct sym_attr *tab;
776 if (index >= s1->nb_sym_attrs) {
777 /* find immediately bigger power of 2 and reallocate array */
778 n = 1;
779 while (index >= n)
780 n *= 2;
781 tab = tcc_realloc(s1->sym_attrs, n * sizeof(*s1->sym_attrs));
782 s1->sym_attrs = tab;
783 memset(s1->sym_attrs + s1->nb_sym_attrs, 0,
784 (n - s1->nb_sym_attrs) * sizeof(*s1->sym_attrs));
785 s1->nb_sym_attrs = n;
787 return &s1->sym_attrs[index];
790 static void build_got(TCCState *s1)
792 unsigned char *ptr;
794 /* if no got, then create it */
795 s1->got = new_section(s1, ".got", SHT_PROGBITS, SHF_ALLOC | SHF_WRITE);
796 s1->got->sh_entsize = 4;
797 set_elf_sym(symtab_section, 0, 4, ELFW(ST_INFO)(STB_GLOBAL, STT_OBJECT),
798 0, s1->got->sh_num, "_GLOBAL_OFFSET_TABLE_");
799 ptr = section_ptr_add(s1->got, 3 * PTR_SIZE);
800 #if PTR_SIZE == 4
801 /* keep space for _DYNAMIC pointer, if present */
802 write32le(ptr, 0);
803 /* two dummy got entries */
804 write32le(ptr + 4, 0);
805 write32le(ptr + 8, 0);
806 #else
807 /* keep space for _DYNAMIC pointer, if present */
808 write32le(ptr, 0);
809 write32le(ptr + 4, 0);
810 /* two dummy got entries */
811 write32le(ptr + 8, 0);
812 write32le(ptr + 12, 0);
813 write32le(ptr + 16, 0);
814 write32le(ptr + 20, 0);
815 #endif
818 /* Create a GOT and (for function call) a PLT entry corresponding to a symbol
819 in s1->symtab. When creating the dynamic symbol table entry for the GOT
820 relocation, use 'size' and 'info' for the corresponding symbol metadata.
821 Returns the offset of the GOT or (if any) PLT entry. */
822 static unsigned long put_got_entry(TCCState *s1,
823 int reloc_type, unsigned long size, int info,
824 int sym_index)
826 int index, need_plt_entry = 0;
827 const char *name;
828 ElfW(Sym) *sym;
829 unsigned long offset;
830 int *ptr;
831 size_t got_offset;
832 struct sym_attr *symattr;
834 need_plt_entry = (reloc_type == R_JMP_SLOT);
836 if (!s1->got)
837 build_got(s1);
839 /* create PLT if needed */
840 if (need_plt_entry && !s1->plt) {
841 s1->plt = new_section(s1, ".plt", SHT_PROGBITS,
842 SHF_ALLOC | SHF_EXECINSTR);
843 s1->plt->sh_entsize = 4;
846 /* already a GOT and/or PLT entry, no need to add one */
847 if (sym_index < s1->nb_sym_attrs) {
848 if (need_plt_entry && s1->sym_attrs[sym_index].plt_offset)
849 return s1->sym_attrs[sym_index].plt_offset;
850 else if (!need_plt_entry && s1->sym_attrs[sym_index].got_offset)
851 return s1->sym_attrs[sym_index].got_offset;
854 symattr = alloc_sym_attr(s1, sym_index);
856 /* create the GOT entry */
857 ptr = section_ptr_add(s1->got, PTR_SIZE);
858 *ptr = 0;
859 got_offset = OFFSET_FROM_SECTION_START (s1->got, ptr);
861 /* In case a function is both called and its address taken 2 GOT entries
862 are created, one for taking the address (GOT) and the other for the PLT
863 entry (PLTGOT). We don't record the offset of the PLTGOT entry in the
864 got_offset field since it might overwrite the offset of a GOT entry.
865 Besides, for PLT entry the static relocation is against the PLT entry
866 and the dynamic relocation for PLTGOT is created in this function. */
867 if (!need_plt_entry)
868 symattr->got_offset = got_offset;
870 sym = &((ElfW(Sym) *) symtab_section->data)[sym_index];
871 name = (char *) symtab_section->link->data + sym->st_name;
872 offset = sym->st_value;
874 /* create PLT entry */
875 if (need_plt_entry) {
876 #if defined(TCC_TARGET_I386) || defined(TCC_TARGET_X86_64)
877 Section *plt;
878 uint8_t *p;
879 int modrm;
880 unsigned long relofs;
882 #if defined(TCC_OUTPUT_DLL_WITH_PLT)
883 modrm = 0x25;
884 #else
885 /* if we build a DLL, we add a %ebx offset */
886 if (s1->output_type == TCC_OUTPUT_DLL)
887 modrm = 0xa3;
888 else
889 modrm = 0x25;
890 #endif
892 plt = s1->plt;
893 /* empty PLT: create PLT0 entry that pushes the library indentifier
894 (GOT + PTR_SIZE) and jumps to ld.so resolution routine
895 (GOT + 2 * PTR_SIZE) */
896 if (plt->data_offset == 0) {
897 p = section_ptr_add(plt, 16);
898 p[0] = 0xff; /* pushl got + PTR_SIZE */
899 p[1] = modrm + 0x10;
900 write32le(p + 2, PTR_SIZE);
901 p[6] = 0xff; /* jmp *(got + PTR_SIZE * 2) */
902 p[7] = modrm;
903 write32le(p + 8, PTR_SIZE * 2);
906 /* The PLT slot refers to the relocation entry it needs via offset.
907 The reloc entry is created below, so its offset is the current
908 data_offset */
909 relofs = s1->got->reloc ? s1->got->reloc->data_offset : 0;
910 symattr->plt_offset = plt->data_offset;
912 /* Jump to GOT entry where ld.so initially put the address of ip + 4 */
913 p = section_ptr_add(plt, 16);
914 p[0] = 0xff; /* jmp *(got + x) */
915 p[1] = modrm;
916 write32le(p + 2, got_offset);
917 p[6] = 0x68; /* push $xxx */
918 #ifdef TCC_TARGET_X86_64
919 /* On x86-64, the relocation is referred to by _index_ */
920 write32le(p + 7, relofs / sizeof (ElfW_Rel));
921 #else
922 write32le(p + 7, relofs);
923 #endif
924 p[11] = 0xe9; /* jmp plt_start */
925 write32le(p + 12, -(plt->data_offset));
927 /* If this was an UNDEF symbol set the offset in the dynsymtab to the
928 PLT slot, so that PC32 relocs to it can be resolved */
929 if (sym->st_shndx == SHN_UNDEF)
930 offset = plt->data_offset - 16;
931 #elif defined(TCC_TARGET_ARM)
932 Section *plt;
933 uint8_t *p;
935 /* when building a DLL, GOT entry accesses must be done relative to
936 start of GOT (see x86_64 examble above) */
937 if (s1->output_type == TCC_OUTPUT_DLL)
938 tcc_error("DLLs unimplemented!");
940 plt = s1->plt;
941 /* empty PLT: create PLT0 entry that push address of call site and
942 jump to ld.so resolution routine (GOT + 8) */
943 if (plt->data_offset == 0) {
944 p = section_ptr_add(plt, 20);
945 write32le(p, 0xe52de004); /* push {lr} */
946 write32le(p+4, 0xe59fe004); /* ldr lr, [pc, #4] */
947 write32le(p+8, 0xe08fe00e); /* add lr, pc, lr */
948 write32le(p+12, 0xe5bef008); /* ldr pc, [lr, #8]! */
949 /* p+16 is set in relocate_plt */
952 symattr->plt_offset = plt->data_offset;
953 if (symattr->plt_thumb_stub) {
954 p = section_ptr_add(plt, 4);
955 write32le(p, 0x4778); /* bx pc */
956 write32le(p+2, 0x46c0); /* nop */
958 p = section_ptr_add(plt, 16);
959 /* Jump to GOT entry where ld.so initially put address of PLT0 */
960 write32le(p, 0xe59fc004); /* ldr ip, [pc, #4] */
961 write32le(p+4, 0xe08fc00c); /* add ip, pc, ip */
962 write32le(p+8, 0xe59cf000); /* ldr pc, [ip] */
963 /* p + 12 contains offset to GOT entry once patched by relocate_plt */
964 write32le(p+12, got_offset);
966 /* the symbol is modified so that it will be relocated to the PLT */
967 if (sym->st_shndx == SHN_UNDEF)
968 offset = plt->data_offset - 16;
969 #elif defined(TCC_TARGET_ARM64)
970 Section *plt;
971 uint8_t *p;
973 if (s1->output_type == TCC_OUTPUT_DLL)
974 tcc_error("DLLs unimplemented!");
976 plt = s1->plt;
977 if (plt->data_offset == 0)
978 section_ptr_add(plt, 32);
979 symattr->plt_offset = plt->data_offset;
980 p = section_ptr_add(plt, 16);
981 write32le(p, got_offset);
982 write32le(p + 4, (uint64_t) got_offset >> 32);
984 if (sym->st_shndx == SHN_UNDEF)
985 offset = plt->data_offset - 16;
986 #elif defined(TCC_TARGET_C67)
987 tcc_error("C67 got not implemented");
988 #else
989 #error unsupported CPU
990 #endif
993 /* Create the GOT relocation that will insert the address of the object or
994 function of interest in the GOT entry. This is a static relocation for
995 memory output (dlsym will give us the address of symbols) and dynamic
996 relocation otherwise (executable and DLLs). The relocation should be
997 done lazily for GOT entry with *_JUMP_SLOT relocation type (the one
998 associated to a PLT entry) but is currently done at load time for an
999 unknown reason. */
1000 if (s1->dynsym) {
1001 /* create the dynamic symbol table entry that the relocation refers to
1002 in its r_info field to identify the symbol */
1003 /* XXX This might generate multiple syms for name. */
1004 index = put_elf_sym(s1->dynsym, offset, size, info, 0, sym->st_shndx,
1005 name);
1006 put_elf_reloc(s1->dynsym, s1->got, got_offset, reloc_type, index);
1007 } else {
1008 put_elf_reloc(symtab_section, s1->got, got_offset, reloc_type,
1009 sym_index);
1012 if (need_plt_entry)
1013 return symattr->plt_offset;
1014 else
1015 return symattr->got_offset;
1018 /* build GOT and PLT entries */
1019 ST_FUNC void build_got_entries(TCCState *s1)
1021 Section *s;
1022 ElfW_Rel *rel;
1023 ElfW(Sym) *sym;
1024 int i, type, reloc_type, sym_index;
1026 for(i = 1; i < s1->nb_sections; i++) {
1027 s = s1->sections[i];
1028 if (s->sh_type != SHT_RELX)
1029 continue;
1030 /* no need to handle got relocations */
1031 if (s->link != symtab_section)
1032 continue;
1033 for_each_elem(s, 0, rel, ElfW_Rel) {
1034 type = ELFW(R_TYPE)(rel->r_info);
1035 switch(type) {
1036 #if defined(TCC_TARGET_I386)
1037 case R_386_PC16:
1038 case R_386_PC32:
1039 case R_386_GOT32:
1040 case R_386_GOT32X:
1041 case R_386_GOTOFF:
1042 case R_386_GOTPC:
1043 case R_386_PLT32:
1044 if (!s1->got)
1045 build_got(s1);
1046 if (type == R_386_GOT32 || type == R_386_GOT32X ||
1047 type == R_386_PLT32) {
1048 sym_index = ELFW(R_SYM)(rel->r_info);
1049 sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
1050 /* look at the symbol got offset. If none, then add one */
1051 if (type == R_386_GOT32 || type == R_386_GOT32X ||
1052 type == R_386_16 || type == R_386_32)
1053 reloc_type = R_386_GLOB_DAT;
1054 else
1055 reloc_type = R_386_JMP_SLOT;
1056 put_got_entry(s1, reloc_type, sym->st_size, sym->st_info,
1057 sym_index);
1059 break;
1060 #elif defined(TCC_TARGET_ARM)
1061 case R_ARM_PC24:
1062 case R_ARM_CALL:
1063 case R_ARM_JUMP24:
1064 case R_ARM_PLT32:
1065 case R_ARM_THM_PC22:
1066 case R_ARM_MOVT_ABS:
1067 case R_ARM_MOVW_ABS_NC:
1068 case R_ARM_THM_MOVT_ABS:
1069 case R_ARM_THM_MOVW_ABS_NC:
1070 case R_ARM_PREL31:
1071 case R_ARM_REL32:
1072 case R_ARM_GOTPC:
1073 case R_ARM_GOTOFF:
1074 case R_ARM_GOT32:
1075 case R_ARM_V4BX:
1077 if (!s1->got)
1078 build_got(s1);
1079 sym_index = ELFW(R_SYM)(rel->r_info);
1080 sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
1081 if (type != R_ARM_GOTOFF && type != R_ARM_GOTPC
1082 && (sym->st_shndx == SHN_UNDEF
1083 || s1->output_type == TCC_OUTPUT_MEMORY)) {
1084 unsigned long ofs;
1085 /* look at the symbol got offset. If none, then add one */
1086 if (type == R_ARM_GOT32 || type == R_ARM_MOVT_ABS ||
1087 type == R_ARM_MOVW_ABS_NC ||
1088 type == R_ARM_THM_MOVT_ABS ||
1089 type == R_ARM_THM_MOVW_ABS_NC || type == R_ARM_ABS32 ||
1090 type == R_ARM_REL32)
1091 reloc_type = R_ARM_GLOB_DAT;
1092 else
1093 reloc_type = R_ARM_JUMP_SLOT;
1094 ofs = put_got_entry(s1, reloc_type, sym->st_size,
1095 sym->st_info, sym_index);
1096 #ifdef DEBUG_RELOC
1097 printf ("maybegot: %s, %d, %d --> ofs=0x%x\n",
1098 (char *) symtab_section->link->data + sym->st_name,
1099 type, sym->st_shndx, ofs);
1100 #endif
1101 if (type == R_ARM_PC24 || type == R_ARM_CALL ||
1102 type == R_ARM_JUMP24 || type == R_ARM_PLT32) {
1103 addr_t *ptr = (addr_t*)(s1->sections[s->sh_info]->data
1104 + rel->r_offset);
1105 /* x must be signed! */
1106 int x = *ptr & 0xffffff;
1107 x = (x << 8) >> 8;
1108 x <<= 2;
1109 x += ofs;
1110 x >>= 2;
1111 #ifdef DEBUG_RELOC
1112 printf ("insn=0x%x --> 0x%x (x==0x%x)\n", *ptr,
1113 (*ptr & 0xff000000) | x, x);
1114 #endif
1115 *ptr = (*ptr & 0xff000000) | x;
1118 break;
1119 case R_ARM_THM_JUMP24:
1120 sym_index = ELFW(R_SYM)(rel->r_info);
1121 sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
1122 /* We are relocating a jump from thumb code to arm code */
1123 if (sym->st_shndx != SHN_UNDEF && !(sym->st_value & 1)) {
1124 int index;
1125 uint8_t *p;
1126 char *name, buf[1024];
1127 Section *text_section;
1129 name = (char *) symtab_section->link->data + sym->st_name;
1130 text_section = s1->sections[sym->st_shndx];
1131 /* Modify reloc to target a thumb stub to switch to ARM */
1132 snprintf(buf, sizeof(buf), "%s_from_thumb", name);
1133 index = put_elf_sym(symtab_section,
1134 text_section->data_offset + 1,
1135 sym->st_size, sym->st_info, 0,
1136 sym->st_shndx, buf);
1137 rel->r_info = ELFW(R_INFO)(index, type);
1138 /* Create a thumb stub fonction to switch to ARM mode */
1139 put_elf_reloc(symtab_section, text_section,
1140 text_section->data_offset + 4, R_ARM_JUMP24,
1141 sym_index);
1142 p = section_ptr_add(text_section, 8);
1143 write32le(p, 0x4778); /* bx pc */
1144 write32le(p+2, 0x46c0); /* nop */
1145 write32le(p+4, 0xeafffffe); /* b $sym */
1147 #elif defined(TCC_TARGET_ARM64)
1148 //xx Other cases may be required here:
1149 case R_AARCH64_ADR_GOT_PAGE:
1150 case R_AARCH64_LD64_GOT_LO12_NC:
1151 if (!s1->got)
1152 build_got(s1);
1153 sym_index = ELFW(R_SYM)(rel->r_info);
1154 sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
1155 reloc_type = R_AARCH64_GLOB_DAT;
1156 put_got_entry(s1, reloc_type, sym->st_size, sym->st_info,
1157 sym_index);
1158 break;
1160 case R_AARCH64_JUMP26:
1161 case R_AARCH64_CALL26:
1162 if (!s1->got)
1163 build_got(s1);
1164 sym_index = ELFW(R_SYM)(rel->r_info);
1165 sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
1166 if (sym->st_shndx == SHN_UNDEF ||
1167 s1->output_type == TCC_OUTPUT_MEMORY) {
1168 unsigned long ofs;
1169 reloc_type = R_AARCH64_JUMP_SLOT;
1170 ofs = put_got_entry(s1, reloc_type, sym->st_size,
1171 sym->st_info, sym_index);
1172 /* We store the place of the generated PLT slot
1173 in our addend. */
1174 rel->r_addend += ofs;
1176 break;
1177 #elif defined(TCC_TARGET_C67)
1178 case R_C60_GOT32:
1179 case R_C60_GOTOFF:
1180 case R_C60_GOTPC:
1181 case R_C60_PLT32:
1182 if (!s1->got)
1183 build_got(s1);
1184 if (type == R_C60_GOT32 || type == R_C60_PLT32) {
1185 sym_index = ELFW(R_SYM)(rel->r_info);
1186 sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
1187 /* look at the symbol got offset. If none, then add one */
1188 if (type == R_C60_GOT32)
1189 reloc_type = R_C60_GLOB_DAT;
1190 else
1191 reloc_type = R_C60_JMP_SLOT;
1192 put_got_entry(s1, reloc_type, sym->st_size, sym->st_info,
1193 sym_index);
1195 break;
1196 #elif defined(TCC_TARGET_X86_64)
1197 case R_X86_64_32:
1198 case R_X86_64_32S:
1199 case R_X86_64_64:
1200 case R_X86_64_PC32:
1201 case R_X86_64_GOT32:
1202 case R_X86_64_GOTTPOFF:
1203 case R_X86_64_GOTPCREL:
1204 case R_X86_64_GOTPCRELX:
1205 case R_X86_64_REX_GOTPCRELX:
1206 case R_X86_64_PLT32:
1207 sym_index = ELFW(R_SYM)(rel->r_info);
1208 sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
1209 if (type == R_X86_64_PLT32 &&
1210 ELFW(ST_VISIBILITY)(sym->st_other) != STV_DEFAULT)
1212 rel->r_info = ELFW(R_INFO)(sym_index, R_X86_64_PC32);
1213 break;
1216 if (!s1->got) {
1217 build_got(s1);
1218 sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
1220 if (type == R_X86_64_GOT32 || type == R_X86_64_GOTPCREL ||
1221 type == R_X86_64_GOTPCRELX ||
1222 type == R_X86_64_REX_GOTPCRELX ||
1223 type == R_X86_64_PLT32) {
1224 unsigned long ofs;
1225 /* look at the symbol got offset. If none, then add one */
1226 if (type == R_X86_64_GOT32 || type == R_X86_64_GOTPCREL ||
1227 type == R_X86_64_GOTPCRELX ||
1228 type == R_X86_64_REX_GOTPCRELX ||
1229 type == R_X86_64_32 || type == R_X86_64_32S ||
1230 type == R_X86_64_64)
1231 reloc_type = R_X86_64_GLOB_DAT;
1232 else
1233 reloc_type = R_X86_64_JUMP_SLOT;
1234 ofs = put_got_entry(s1, reloc_type, sym->st_size,
1235 sym->st_info, sym_index);
1236 if (type == R_X86_64_PLT32)
1237 /* We store the place of the generated PLT slot
1238 in our addend. */
1239 rel->r_addend += ofs;
1241 break;
1242 #else
1243 #error unsupported CPU
1244 #endif
1245 default:
1246 break;
1252 ST_FUNC Section *new_symtab(TCCState *s1,
1253 const char *symtab_name, int sh_type, int sh_flags,
1254 const char *strtab_name,
1255 const char *hash_name, int hash_sh_flags)
1257 Section *symtab, *strtab, *hash;
1258 int *ptr, nb_buckets;
1260 symtab = new_section(s1, symtab_name, sh_type, sh_flags);
1261 symtab->sh_entsize = sizeof(ElfW(Sym));
1262 strtab = new_section(s1, strtab_name, SHT_STRTAB, sh_flags);
1263 put_elf_str(strtab, "");
1264 symtab->link = strtab;
1265 put_elf_sym(symtab, 0, 0, 0, 0, 0, NULL);
1267 nb_buckets = 1;
1269 hash = new_section(s1, hash_name, SHT_HASH, hash_sh_flags);
1270 hash->sh_entsize = sizeof(int);
1271 symtab->hash = hash;
1272 hash->link = symtab;
1274 ptr = section_ptr_add(hash, (2 + nb_buckets + 1) * sizeof(int));
1275 ptr[0] = nb_buckets;
1276 ptr[1] = 1;
1277 memset(ptr + 2, 0, (nb_buckets + 1) * sizeof(int));
1278 return symtab;
1281 /* put dynamic tag */
1282 static void put_dt(Section *dynamic, int dt, addr_t val)
1284 ElfW(Dyn) *dyn;
1285 dyn = section_ptr_add(dynamic, sizeof(ElfW(Dyn)));
1286 dyn->d_tag = dt;
1287 dyn->d_un.d_val = val;
1290 #ifndef TCC_TARGET_PE
1291 static void add_init_array_defines(TCCState *s1, const char *section_name)
1293 Section *s;
1294 long end_offset;
1295 char sym_start[1024];
1296 char sym_end[1024];
1298 snprintf(sym_start, sizeof(sym_start), "__%s_start", section_name + 1);
1299 snprintf(sym_end, sizeof(sym_end), "__%s_end", section_name + 1);
1301 s = find_section(s1, section_name);
1302 if (!s) {
1303 end_offset = 0;
1304 s = data_section;
1305 } else {
1306 end_offset = s->data_offset;
1309 set_elf_sym(symtab_section,
1310 0, 0,
1311 ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
1312 s->sh_num, sym_start);
1313 set_elf_sym(symtab_section,
1314 end_offset, 0,
1315 ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
1316 s->sh_num, sym_end);
1318 #endif
1320 static int tcc_add_support(TCCState *s1, const char *filename)
1322 char buf[1024];
1323 snprintf(buf, sizeof(buf), "%s/"TCC_ARCH_DIR"%s", s1->tcc_lib_path, filename);
1324 return tcc_add_file(s1, buf);
1327 ST_FUNC void tcc_add_bcheck(TCCState *s1)
1329 #ifdef CONFIG_TCC_BCHECK
1330 addr_t *ptr;
1331 int sym_index;
1333 if (0 == s1->do_bounds_check)
1334 return;
1335 /* XXX: add an object file to do that */
1336 ptr = section_ptr_add(bounds_section, sizeof(*ptr));
1337 *ptr = 0;
1338 set_elf_sym(symtab_section, 0, 0,
1339 ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
1340 bounds_section->sh_num, "__bounds_start");
1341 /* pull bcheck.o from libtcc1.a */
1342 sym_index = set_elf_sym(symtab_section, 0, 0,
1343 ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
1344 SHN_UNDEF, "__bound_init");
1345 if (s1->output_type != TCC_OUTPUT_MEMORY) {
1346 /* add 'call __bound_init()' in .init section */
1347 Section *init_section = find_section(s1, ".init");
1348 unsigned char *pinit = section_ptr_add(init_section, 5);
1349 pinit[0] = 0xe8;
1350 write32le(pinit + 1, -4);
1351 put_elf_reloc(symtab_section, init_section,
1352 init_section->data_offset - 4, R_386_PC32, sym_index);
1353 /* R_386_PC32 = R_X86_64_PC32 = 2 */
1355 #endif
1358 /* add tcc runtime libraries */
1359 ST_FUNC void tcc_add_runtime(TCCState *s1)
1361 tcc_add_bcheck(s1);
1362 tcc_add_pragma_libs(s1);
1363 /* add libc */
1364 if (!s1->nostdlib) {
1365 tcc_add_library_err(s1, "c");
1366 #ifdef CONFIG_USE_LIBGCC
1367 if (!s1->static_link) {
1368 tcc_add_file(s1, TCC_LIBGCC);
1370 #endif
1371 tcc_add_support(s1, "libtcc1.a");
1372 /* add crt end if not memory output */
1373 if (s1->output_type != TCC_OUTPUT_MEMORY)
1374 tcc_add_crt(s1, "crtn.o");
1378 /* add various standard linker symbols (must be done after the
1379 sections are filled (for example after allocating common
1380 symbols)) */
1381 ST_FUNC void tcc_add_linker_symbols(TCCState *s1)
1383 char buf[1024];
1384 int i;
1385 Section *s;
1387 set_elf_sym(symtab_section,
1388 text_section->data_offset, 0,
1389 ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
1390 text_section->sh_num, "_etext");
1391 set_elf_sym(symtab_section,
1392 data_section->data_offset, 0,
1393 ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
1394 data_section->sh_num, "_edata");
1395 set_elf_sym(symtab_section,
1396 bss_section->data_offset, 0,
1397 ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
1398 bss_section->sh_num, "_end");
1399 #ifndef TCC_TARGET_PE
1400 /* horrible new standard ldscript defines */
1401 add_init_array_defines(s1, ".preinit_array");
1402 add_init_array_defines(s1, ".init_array");
1403 add_init_array_defines(s1, ".fini_array");
1404 #endif
1406 /* add start and stop symbols for sections whose name can be
1407 expressed in C */
1408 for(i = 1; i < s1->nb_sections; i++) {
1409 s = s1->sections[i];
1410 if (s->sh_type == SHT_PROGBITS &&
1411 (s->sh_flags & SHF_ALLOC)) {
1412 const char *p;
1413 int ch;
1415 /* check if section name can be expressed in C */
1416 p = s->name;
1417 for(;;) {
1418 ch = *p;
1419 if (!ch)
1420 break;
1421 if (!isid(ch) && !isnum(ch))
1422 goto next_sec;
1423 p++;
1425 snprintf(buf, sizeof(buf), "__start_%s", s->name);
1426 set_elf_sym(symtab_section,
1427 0, 0,
1428 ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
1429 s->sh_num, buf);
1430 snprintf(buf, sizeof(buf), "__stop_%s", s->name);
1431 set_elf_sym(symtab_section,
1432 s->data_offset, 0,
1433 ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
1434 s->sh_num, buf);
1436 next_sec: ;
1440 static void tcc_output_binary(TCCState *s1, FILE *f,
1441 const int *sec_order)
1443 Section *s;
1444 int i, offset, size;
1446 offset = 0;
1447 for(i=1;i<s1->nb_sections;i++) {
1448 s = s1->sections[sec_order[i]];
1449 if (s->sh_type != SHT_NOBITS &&
1450 (s->sh_flags & SHF_ALLOC)) {
1451 while (offset < s->sh_offset) {
1452 fputc(0, f);
1453 offset++;
1455 size = s->sh_size;
1456 fwrite(s->data, 1, size, f);
1457 offset += size;
1462 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
1463 #define HAVE_PHDR 1
1464 #define EXTRA_RELITEMS 14
1466 /* move the relocation value from .dynsym to .got */
1467 static void patch_dynsym_undef(TCCState *s1, Section *s)
1469 uint32_t *gotd = (void *)s1->got->data;
1470 ElfW(Sym) *sym;
1472 gotd += 3; /* dummy entries in .got */
1473 /* relocate symbols in .dynsym */
1474 for_each_elem(s, 1, sym, ElfW(Sym)) {
1475 if (sym->st_shndx == SHN_UNDEF) {
1476 *gotd++ = sym->st_value + 6; /* XXX 6 is magic ? */
1477 sym->st_value = 0;
1481 #else
1482 #define HAVE_PHDR 1
1483 #define EXTRA_RELITEMS 9
1485 /* zero plt offsets of weak symbols in .dynsym */
1486 static void patch_dynsym_undef(TCCState *s1, Section *s)
1488 ElfW(Sym) *sym;
1490 for_each_elem(s, 1, sym, ElfW(Sym))
1491 if (sym->st_shndx == SHN_UNDEF && ELFW(ST_BIND)(sym->st_info) == STB_WEAK)
1492 sym->st_value = 0;
1494 #endif
1496 ST_FUNC void fill_got_entry(TCCState *s1, ElfW_Rel *rel)
1498 int sym_index = ELFW(R_SYM) (rel->r_info);
1499 ElfW(Sym) *sym = &((ElfW(Sym) *) symtab_section->data)[sym_index];
1500 unsigned long offset;
1502 if (sym_index >= s1->nb_sym_attrs)
1503 return;
1504 offset = s1->sym_attrs[sym_index].got_offset;
1505 section_reserve(s1->got, offset + PTR_SIZE);
1506 #ifdef TCC_TARGET_X86_64
1507 /* only works for x86-64 */
1508 write32le(s1->got->data + offset + 4, sym->st_value >> 32);
1509 #endif
1510 write32le(s1->got->data + offset, sym->st_value & 0xffffffff);
1513 /* Perform relocation to GOT or PLT entries */
1514 ST_FUNC void fill_got(TCCState *s1)
1516 Section *s;
1517 ElfW_Rel *rel;
1518 int i;
1520 for(i = 1; i < s1->nb_sections; i++) {
1521 s = s1->sections[i];
1522 if (s->sh_type != SHT_RELX)
1523 continue;
1524 /* no need to handle got relocations */
1525 if (s->link != symtab_section)
1526 continue;
1527 for_each_elem(s, 0, rel, ElfW_Rel) {
1528 switch (ELFW(R_TYPE) (rel->r_info)) {
1529 case R_X86_64_GOT32:
1530 case R_X86_64_GOTPCREL:
1531 case R_X86_64_GOTPCRELX:
1532 case R_X86_64_REX_GOTPCRELX:
1533 case R_X86_64_PLT32:
1534 fill_got_entry(s1, rel);
1535 break;
1541 /* Bind symbols of executable: resolve undefined symbols from exported symbols
1542 in shared libraries and export non local defined symbols to shared libraries
1543 if -rdynamic switch was given on command line */
1544 static void bind_exe_dynsyms(TCCState *s1)
1546 const char *name;
1547 int sym_index, index;
1548 ElfW(Sym) *sym, *esym;
1549 int type;
1551 /* Resolve undefined symbols from dynamic symbols. When there is a match:
1552 - if STT_FUNC or STT_GNU_IFUNC symbol -> add it in PLT
1553 - if STT_OBJECT symbol -> add it in .bss section with suitable reloc */
1554 for_each_elem(symtab_section, 1, sym, ElfW(Sym)) {
1555 if (sym->st_shndx == SHN_UNDEF) {
1556 name = (char *) symtab_section->link->data + sym->st_name;
1557 sym_index = find_elf_sym(s1->dynsymtab_section, name);
1558 if (sym_index) {
1559 esym = &((ElfW(Sym) *)s1->dynsymtab_section->data)[sym_index];
1560 type = ELFW(ST_TYPE)(esym->st_info);
1561 if ((type == STT_FUNC) || (type == STT_GNU_IFUNC)) {
1562 /* Indirect functions shall have STT_FUNC type in executable
1563 * dynsym section. Indeed, a dlsym call following a lazy
1564 * resolution would pick the symbol value from the
1565 * executable dynsym entry which would contain the address
1566 * of the function wanted by the caller of dlsym instead of
1567 * the address of the function that would return that
1568 * address */
1569 put_got_entry(s1, R_JMP_SLOT, esym->st_size,
1570 ELFW(ST_INFO)(STB_GLOBAL,STT_FUNC),
1571 sym - (ElfW(Sym) *)symtab_section->data);
1572 } else if (type == STT_OBJECT) {
1573 unsigned long offset;
1574 ElfW(Sym) *dynsym;
1575 offset = bss_section->data_offset;
1576 /* XXX: which alignment ? */
1577 offset = (offset + 16 - 1) & -16;
1578 index = put_elf_sym(s1->dynsym, offset, esym->st_size,
1579 esym->st_info, 0, bss_section->sh_num,
1580 name);
1581 /* Ensure R_COPY works for weak symbol aliases */
1582 if (ELFW(ST_BIND)(esym->st_info) == STB_WEAK) {
1583 for_each_elem(s1->dynsymtab_section, 1, dynsym, ElfW(Sym)) {
1584 if ((dynsym->st_value == esym->st_value)
1585 && (ELFW(ST_BIND)(dynsym->st_info) == STB_GLOBAL)) {
1586 char *dynname = (char *) s1->dynsymtab_section->link->data
1587 + dynsym->st_name;
1588 put_elf_sym(s1->dynsym, offset, dynsym->st_size,
1589 dynsym->st_info, 0,
1590 bss_section->sh_num, dynname);
1591 break;
1595 put_elf_reloc(s1->dynsym, bss_section,
1596 offset, R_COPY, index);
1597 offset += esym->st_size;
1598 bss_section->data_offset = offset;
1600 } else {
1601 /* STB_WEAK undefined symbols are accepted */
1602 /* XXX: _fp_hw seems to be part of the ABI, so we ignore it */
1603 if (ELFW(ST_BIND)(sym->st_info) == STB_WEAK ||
1604 !strcmp(name, "_fp_hw")) {
1605 } else {
1606 tcc_error_noabort("undefined symbol '%s'", name);
1609 } else if (s1->rdynamic && ELFW(ST_BIND)(sym->st_info) != STB_LOCAL) {
1610 /* if -rdynamic option, then export all non local symbols */
1611 name = (char *) symtab_section->link->data + sym->st_name;
1612 set_elf_sym(s1->dynsym, sym->st_value, sym->st_size, sym->st_info,
1613 0, sym->st_shndx, name);
1618 /* Bind symbols of libraries: export all non local symbols of executable that
1619 are referenced by shared libraries. The reason is that the dynamic loader
1620 search symbol first in executable and then in libraries. Therefore a
1621 reference to a symbol already defined by a library can still be resolved by
1622 a symbol in the executable. */
1623 static void bind_libs_dynsyms(TCCState *s1)
1625 const char *name;
1626 int sym_index;
1627 ElfW(Sym) *sym, *esym;
1629 for_each_elem(s1->dynsymtab_section, 1, esym, ElfW(Sym)) {
1630 name = (char *) s1->dynsymtab_section->link->data + esym->st_name;
1631 sym_index = find_elf_sym(symtab_section, name);
1632 /* XXX: avoid adding a symbol if already present because of
1633 -rdynamic ? */
1634 sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
1635 if (sym_index && sym->st_shndx != SHN_UNDEF)
1636 set_elf_sym(s1->dynsym, sym->st_value, sym->st_size, sym->st_info,
1637 0, sym->st_shndx, name);
1638 else if (esym->st_shndx == SHN_UNDEF) {
1639 /* weak symbols can stay undefined */
1640 if (ELFW(ST_BIND)(esym->st_info) != STB_WEAK)
1641 tcc_warning("undefined dynamic symbol '%s'", name);
1646 /* Export all non local symbols. This is used by shared libraries so that the
1647 non local symbols they define can resolve a reference in another shared
1648 library or in the executable. Correspondingly, it allows undefined local
1649 symbols to be resolved by other shared libraries or by the executable. */
1650 static void export_global_syms(TCCState *s1)
1652 int nb_syms, dynindex, index;
1653 const char *name;
1654 ElfW(Sym) *sym;
1656 nb_syms = symtab_section->data_offset / sizeof(ElfW(Sym));
1657 s1->symtab_to_dynsym = tcc_mallocz(sizeof(int) * nb_syms);
1658 for_each_elem(symtab_section, 1, sym, ElfW(Sym)) {
1659 if (ELFW(ST_BIND)(sym->st_info) != STB_LOCAL) {
1660 name = (char *) symtab_section->link->data + sym->st_name;
1661 dynindex = put_elf_sym(s1->dynsym, sym->st_value, sym->st_size,
1662 sym->st_info, 0, sym->st_shndx, name);
1663 index = sym - (ElfW(Sym) *) symtab_section->data;
1664 s1->symtab_to_dynsym[index] = dynindex;
1669 /* relocate the PLT: compute addresses and offsets in the PLT now that final
1670 address for PLT and GOT are known (see fill_program_header) */
1671 ST_FUNC void relocate_plt(TCCState *s1)
1673 uint8_t *p, *p_end;
1675 if (!s1->plt)
1676 return;
1678 p = s1->plt->data;
1679 p_end = p + s1->plt->data_offset;
1680 if (p < p_end) {
1681 #if defined(TCC_TARGET_I386)
1682 add32le(p + 2, s1->got->sh_addr);
1683 add32le(p + 8, s1->got->sh_addr);
1684 p += 16;
1685 while (p < p_end) {
1686 add32le(p + 2, s1->got->sh_addr);
1687 p += 16;
1689 #elif defined(TCC_TARGET_X86_64)
1690 int x = s1->got->sh_addr - s1->plt->sh_addr - 6;
1691 add32le(p + 2, x);
1692 add32le(p + 8, x - 6);
1693 p += 16;
1694 while (p < p_end) {
1695 add32le(p + 2, x + s1->plt->data - p);
1696 p += 16;
1698 #elif defined(TCC_TARGET_ARM)
1699 int x = s1->got->sh_addr - s1->plt->sh_addr - 12;
1700 write32le(s1->plt->data + 16, x - 16);
1701 p += 20;
1702 while (p < p_end) {
1703 if (read32le(p) == 0x46c04778) /* PLT Thumb stub present */
1704 p += 4;
1705 add32le(p + 12, x + s1->plt->data - p);
1706 p += 16;
1708 #elif defined(TCC_TARGET_ARM64)
1709 uint64_t plt = s1->plt->sh_addr;
1710 uint64_t got = s1->got->sh_addr;
1711 uint64_t off = (got >> 12) - (plt >> 12);
1712 if ((off + ((uint32_t)1 << 20)) >> 21)
1713 tcc_error("Failed relocating PLT (off=0x%lx, got=0x%lx, plt=0x%lx)", off, got, plt);
1714 write32le(p, 0xa9bf7bf0); // stp x16,x30,[sp,#-16]!
1715 write32le(p + 4, (0x90000010 | // adrp x16,...
1716 (off & 0x1ffffc) << 3 | (off & 3) << 29));
1717 write32le(p + 8, (0xf9400211 | // ldr x17,[x16,#...]
1718 (got & 0xff8) << 7));
1719 write32le(p + 12, (0x91000210 | // add x16,x16,#...
1720 (got & 0xfff) << 10));
1721 write32le(p + 16, 0xd61f0220); // br x17
1722 write32le(p + 20, 0xd503201f); // nop
1723 write32le(p + 24, 0xd503201f); // nop
1724 write32le(p + 28, 0xd503201f); // nop
1725 p += 32;
1726 while (p < p_end) {
1727 uint64_t pc = plt + (p - s1->plt->data);
1728 uint64_t addr = got + read64le(p);
1729 uint64_t off = (addr >> 12) - (pc >> 12);
1730 if ((off + ((uint32_t)1 << 20)) >> 21)
1731 tcc_error("Failed relocating PLT (off=0x%lx, addr=0x%lx, pc=0x%lx)", off, addr, pc);
1732 write32le(p, (0x90000010 | // adrp x16,...
1733 (off & 0x1ffffc) << 3 | (off & 3) << 29));
1734 write32le(p + 4, (0xf9400211 | // ldr x17,[x16,#...]
1735 (addr & 0xff8) << 7));
1736 write32le(p + 8, (0x91000210 | // add x16,x16,#...
1737 (addr & 0xfff) << 10));
1738 write32le(p + 12, 0xd61f0220); // br x17
1739 p += 16;
1741 #elif defined(TCC_TARGET_C67)
1742 /* XXX: TODO */
1743 #else
1744 #error unsupported CPU
1745 #endif
1749 /* Allocate strings for section names and decide if an unallocated section
1750 should be output.
1752 NOTE: the strsec section comes last, so its size is also correct ! */
1753 static void alloc_sec_names(TCCState *s1, int file_type, Section *strsec)
1755 int i;
1756 Section *s;
1758 /* Allocate strings for section names */
1759 for(i = 1; i < s1->nb_sections; i++) {
1760 s = s1->sections[i];
1761 s->sh_name = put_elf_str(strsec, s->name);
1762 /* when generating a DLL, we include relocations but we may
1763 patch them */
1764 if (file_type == TCC_OUTPUT_DLL &&
1765 s->sh_type == SHT_RELX &&
1766 !(s->sh_flags & SHF_ALLOC)) {
1767 /* gr: avoid bogus relocs for empty (debug) sections */
1768 if (s1->sections[s->sh_info]->sh_flags & SHF_ALLOC)
1769 prepare_dynamic_rel(s1, s);
1770 else if (s1->do_debug)
1771 s->sh_size = s->data_offset;
1772 } else if (s1->do_debug ||
1773 file_type == TCC_OUTPUT_OBJ ||
1774 (s->sh_flags & SHF_ALLOC) ||
1775 i == (s1->nb_sections - 1)) {
1776 /* we output all sections if debug or object file */
1777 s->sh_size = s->data_offset;
1782 /* Info to be copied in dynamic section */
1783 struct dyn_inf {
1784 Section *dynamic;
1785 Section *dynstr;
1786 unsigned long dyn_rel_off;
1787 addr_t rel_addr;
1788 addr_t rel_size;
1789 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
1790 addr_t bss_addr;
1791 addr_t bss_size;
1792 #endif
1795 /* Assign sections to segments and decide how are sections laid out when loaded
1796 in memory. This function also fills corresponding program headers. */
1797 static int layout_sections(TCCState *s1, ElfW(Phdr) *phdr, int phnum,
1798 Section *interp, Section* strsec,
1799 struct dyn_inf *dyninf, int *sec_order)
1801 int i, j, k, file_type, sh_order_index, file_offset;
1802 unsigned long s_align;
1803 long long tmp;
1804 addr_t addr;
1805 ElfW(Phdr) *ph;
1806 Section *s;
1808 file_type = s1->output_type;
1809 sh_order_index = 1;
1810 file_offset = 0;
1811 if (s1->output_format == TCC_OUTPUT_FORMAT_ELF)
1812 file_offset = sizeof(ElfW(Ehdr)) + phnum * sizeof(ElfW(Phdr));
1813 s_align = ELF_PAGE_SIZE;
1814 if (s1->section_align)
1815 s_align = s1->section_align;
1817 if (phnum > 0) {
1818 if (s1->has_text_addr) {
1819 int a_offset, p_offset;
1820 addr = s1->text_addr;
1821 /* we ensure that (addr % ELF_PAGE_SIZE) == file_offset %
1822 ELF_PAGE_SIZE */
1823 a_offset = (int) (addr & (s_align - 1));
1824 p_offset = file_offset & (s_align - 1);
1825 if (a_offset < p_offset)
1826 a_offset += s_align;
1827 file_offset += (a_offset - p_offset);
1828 } else {
1829 if (file_type == TCC_OUTPUT_DLL)
1830 addr = 0;
1831 else
1832 addr = ELF_START_ADDR;
1833 /* compute address after headers */
1834 addr += (file_offset & (s_align - 1));
1837 ph = &phdr[0];
1838 /* Leave one program headers for the program interpreter and one for
1839 the program header table itself if needed. These are done later as
1840 they require section layout to be done first. */
1841 if (interp)
1842 ph += 1 + HAVE_PHDR;
1844 /* dynamic relocation table information, for .dynamic section */
1845 dyninf->rel_addr = dyninf->rel_size = 0;
1846 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
1847 dyninf->bss_addr = dyninf->bss_size = 0;
1848 #endif
1850 for(j = 0; j < 2; j++) {
1851 ph->p_type = PT_LOAD;
1852 if (j == 0)
1853 ph->p_flags = PF_R | PF_X;
1854 else
1855 ph->p_flags = PF_R | PF_W;
1856 ph->p_align = s_align;
1858 /* Decide the layout of sections loaded in memory. This must
1859 be done before program headers are filled since they contain
1860 info about the layout. We do the following ordering: interp,
1861 symbol tables, relocations, progbits, nobits */
1862 /* XXX: do faster and simpler sorting */
1863 for(k = 0; k < 5; k++) {
1864 for(i = 1; i < s1->nb_sections; i++) {
1865 s = s1->sections[i];
1866 /* compute if section should be included */
1867 if (j == 0) {
1868 if ((s->sh_flags & (SHF_ALLOC | SHF_WRITE)) !=
1869 SHF_ALLOC)
1870 continue;
1871 } else {
1872 if ((s->sh_flags & (SHF_ALLOC | SHF_WRITE)) !=
1873 (SHF_ALLOC | SHF_WRITE))
1874 continue;
1876 if (s == interp) {
1877 if (k != 0)
1878 continue;
1879 } else if (s->sh_type == SHT_DYNSYM ||
1880 s->sh_type == SHT_STRTAB ||
1881 s->sh_type == SHT_HASH) {
1882 if (k != 1)
1883 continue;
1884 } else if (s->sh_type == SHT_RELX) {
1885 if (k != 2)
1886 continue;
1887 } else if (s->sh_type == SHT_NOBITS) {
1888 if (k != 4)
1889 continue;
1890 } else {
1891 if (k != 3)
1892 continue;
1894 sec_order[sh_order_index++] = i;
1896 /* section matches: we align it and add its size */
1897 tmp = addr;
1898 addr = (addr + s->sh_addralign - 1) &
1899 ~(s->sh_addralign - 1);
1900 file_offset += (int) ( addr - tmp );
1901 s->sh_offset = file_offset;
1902 s->sh_addr = addr;
1904 /* update program header infos */
1905 if (ph->p_offset == 0) {
1906 ph->p_offset = file_offset;
1907 ph->p_vaddr = addr;
1908 ph->p_paddr = ph->p_vaddr;
1910 /* update dynamic relocation infos */
1911 if (s->sh_type == SHT_RELX) {
1912 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
1913 if (!strcmp(strsec->data + s->sh_name, ".rel.got")) {
1914 dyninf->rel_addr = addr;
1915 dyninf->rel_size += s->sh_size; /* XXX only first rel. */
1917 if (!strcmp(strsec->data + s->sh_name, ".rel.bss")) {
1918 dyninf->bss_addr = addr;
1919 dyninf->bss_size = s->sh_size; /* XXX only first rel. */
1921 #else
1922 if (dyninf->rel_size == 0)
1923 dyninf->rel_addr = addr;
1924 dyninf->rel_size += s->sh_size;
1925 #endif
1927 addr += s->sh_size;
1928 if (s->sh_type != SHT_NOBITS)
1929 file_offset += s->sh_size;
1932 if (j == 0) {
1933 /* Make the first PT_LOAD segment include the program
1934 headers itself (and the ELF header as well), it'll
1935 come out with same memory use but will make various
1936 tools like binutils strip work better. */
1937 ph->p_offset &= ~(ph->p_align - 1);
1938 ph->p_vaddr &= ~(ph->p_align - 1);
1939 ph->p_paddr &= ~(ph->p_align - 1);
1941 ph->p_filesz = file_offset - ph->p_offset;
1942 ph->p_memsz = addr - ph->p_vaddr;
1943 ph++;
1944 if (j == 0) {
1945 if (s1->output_format == TCC_OUTPUT_FORMAT_ELF) {
1946 /* if in the middle of a page, we duplicate the page in
1947 memory so that one copy is RX and the other is RW */
1948 if ((addr & (s_align - 1)) != 0)
1949 addr += s_align;
1950 } else {
1951 addr = (addr + s_align - 1) & ~(s_align - 1);
1952 file_offset = (file_offset + s_align - 1) & ~(s_align - 1);
1958 /* all other sections come after */
1959 for(i = 1; i < s1->nb_sections; i++) {
1960 s = s1->sections[i];
1961 if (phnum > 0 && (s->sh_flags & SHF_ALLOC))
1962 continue;
1963 sec_order[sh_order_index++] = i;
1965 file_offset = (file_offset + s->sh_addralign - 1) &
1966 ~(s->sh_addralign - 1);
1967 s->sh_offset = file_offset;
1968 if (s->sh_type != SHT_NOBITS)
1969 file_offset += s->sh_size;
1972 return file_offset;
1975 static void fill_unloadable_phdr(ElfW(Phdr) *phdr, int phnum, Section *interp,
1976 Section *dynamic)
1978 ElfW(Phdr) *ph;
1980 /* if interpreter, then add corresponding program header */
1981 if (interp) {
1982 ph = &phdr[0];
1984 if (HAVE_PHDR)
1986 int len = phnum * sizeof(ElfW(Phdr));
1988 ph->p_type = PT_PHDR;
1989 ph->p_offset = sizeof(ElfW(Ehdr));
1990 ph->p_vaddr = interp->sh_addr - len;
1991 ph->p_paddr = ph->p_vaddr;
1992 ph->p_filesz = ph->p_memsz = len;
1993 ph->p_flags = PF_R | PF_X;
1994 ph->p_align = 4; /* interp->sh_addralign; */
1995 ph++;
1998 ph->p_type = PT_INTERP;
1999 ph->p_offset = interp->sh_offset;
2000 ph->p_vaddr = interp->sh_addr;
2001 ph->p_paddr = ph->p_vaddr;
2002 ph->p_filesz = interp->sh_size;
2003 ph->p_memsz = interp->sh_size;
2004 ph->p_flags = PF_R;
2005 ph->p_align = interp->sh_addralign;
2008 /* if dynamic section, then add corresponding program header */
2009 if (dynamic) {
2010 ph = &phdr[phnum - 1];
2012 ph->p_type = PT_DYNAMIC;
2013 ph->p_offset = dynamic->sh_offset;
2014 ph->p_vaddr = dynamic->sh_addr;
2015 ph->p_paddr = ph->p_vaddr;
2016 ph->p_filesz = dynamic->sh_size;
2017 ph->p_memsz = dynamic->sh_size;
2018 ph->p_flags = PF_R | PF_W;
2019 ph->p_align = dynamic->sh_addralign;
2023 /* Fill the dynamic section with tags describing the address and size of
2024 sections */
2025 static void fill_dynamic(TCCState *s1, struct dyn_inf *dyninf)
2027 Section *dynamic;
2029 dynamic = dyninf->dynamic;
2031 /* put dynamic section entries */
2032 dynamic->data_offset = dyninf->dyn_rel_off;
2033 put_dt(dynamic, DT_HASH, s1->dynsym->hash->sh_addr);
2034 put_dt(dynamic, DT_STRTAB, dyninf->dynstr->sh_addr);
2035 put_dt(dynamic, DT_SYMTAB, s1->dynsym->sh_addr);
2036 put_dt(dynamic, DT_STRSZ, dyninf->dynstr->data_offset);
2037 put_dt(dynamic, DT_SYMENT, sizeof(ElfW(Sym)));
2038 #if defined(TCC_TARGET_ARM64) || defined(TCC_TARGET_X86_64)
2039 put_dt(dynamic, DT_RELA, dyninf->rel_addr);
2040 put_dt(dynamic, DT_RELASZ, dyninf->rel_size);
2041 put_dt(dynamic, DT_RELAENT, sizeof(ElfW_Rel));
2042 #else
2043 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
2044 put_dt(dynamic, DT_PLTGOT, s1->got->sh_addr);
2045 put_dt(dynamic, DT_PLTRELSZ, dyninf->rel_size);
2046 put_dt(dynamic, DT_JMPREL, dyninf->rel_addr);
2047 put_dt(dynamic, DT_PLTREL, DT_REL);
2048 put_dt(dynamic, DT_REL, dyninf->bss_addr);
2049 put_dt(dynamic, DT_RELSZ, dyninf->bss_size);
2050 #else
2051 put_dt(dynamic, DT_REL, dyninf->rel_addr);
2052 put_dt(dynamic, DT_RELSZ, dyninf->rel_size);
2053 put_dt(dynamic, DT_RELENT, sizeof(ElfW_Rel));
2054 #endif
2055 #endif
2056 if (s1->do_debug)
2057 put_dt(dynamic, DT_DEBUG, 0);
2058 put_dt(dynamic, DT_NULL, 0);
2061 /* Relocate remaining sections and symbols (that is those not related to
2062 dynamic linking) */
2063 static int final_sections_reloc(TCCState *s1)
2065 int i;
2066 Section *s;
2068 relocate_syms(s1, 0);
2070 if (s1->nb_errors != 0)
2071 return -1;
2073 /* relocate sections */
2074 /* XXX: ignore sections with allocated relocations ? */
2075 for(i = 1; i < s1->nb_sections; i++) {
2076 s = s1->sections[i];
2077 #ifdef TCC_TARGET_I386
2078 if (s->reloc && s != s1->got && (s->sh_flags & SHF_ALLOC)) //gr
2079 /* On X86 gdb 7.3 works in any case but gdb 6.6 will crash if SHF_ALLOC
2080 checking is removed */
2081 #else
2082 if (s->reloc && s != s1->got)
2083 /* On X86_64 gdb 7.3 will crash if SHF_ALLOC checking is present */
2084 #endif
2085 relocate_section(s1, s);
2088 /* relocate relocation entries if the relocation tables are
2089 allocated in the executable */
2090 for(i = 1; i < s1->nb_sections; i++) {
2091 s = s1->sections[i];
2092 if ((s->sh_flags & SHF_ALLOC) &&
2093 s->sh_type == SHT_RELX) {
2094 relocate_rel(s1, s);
2097 return 0;
2100 /* Create an ELF file on disk.
2101 This function handle ELF specific layout requirements */
2102 static void tcc_output_elf(TCCState *s1, FILE *f, int phnum, ElfW(Phdr) *phdr,
2103 int file_offset, int *sec_order)
2105 int i, shnum, offset, size, file_type;
2106 Section *s;
2107 ElfW(Ehdr) ehdr;
2108 ElfW(Shdr) shdr, *sh;
2110 file_type = s1->output_type;
2111 shnum = s1->nb_sections;
2113 memset(&ehdr, 0, sizeof(ehdr));
2115 if (phnum > 0) {
2116 ehdr.e_phentsize = sizeof(ElfW(Phdr));
2117 ehdr.e_phnum = phnum;
2118 ehdr.e_phoff = sizeof(ElfW(Ehdr));
2121 /* align to 4 */
2122 file_offset = (file_offset + 3) & -4;
2124 /* fill header */
2125 ehdr.e_ident[0] = ELFMAG0;
2126 ehdr.e_ident[1] = ELFMAG1;
2127 ehdr.e_ident[2] = ELFMAG2;
2128 ehdr.e_ident[3] = ELFMAG3;
2129 ehdr.e_ident[4] = ELFCLASSW;
2130 ehdr.e_ident[5] = ELFDATA2LSB;
2131 ehdr.e_ident[6] = EV_CURRENT;
2132 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
2133 ehdr.e_ident[EI_OSABI] = ELFOSABI_FREEBSD;
2134 #endif
2135 #ifdef TCC_TARGET_ARM
2136 #ifdef TCC_ARM_EABI
2137 ehdr.e_ident[EI_OSABI] = 0;
2138 ehdr.e_flags = EF_ARM_EABI_VER4;
2139 if (file_type == TCC_OUTPUT_EXE || file_type == TCC_OUTPUT_DLL)
2140 ehdr.e_flags |= EF_ARM_HASENTRY;
2141 if (s1->float_abi == ARM_HARD_FLOAT)
2142 ehdr.e_flags |= EF_ARM_VFP_FLOAT;
2143 else
2144 ehdr.e_flags |= EF_ARM_SOFT_FLOAT;
2145 #else
2146 ehdr.e_ident[EI_OSABI] = ELFOSABI_ARM;
2147 #endif
2148 #endif
2149 switch(file_type) {
2150 default:
2151 case TCC_OUTPUT_EXE:
2152 ehdr.e_type = ET_EXEC;
2153 ehdr.e_entry = get_elf_sym_addr(s1, "_start", 1);
2154 break;
2155 case TCC_OUTPUT_DLL:
2156 ehdr.e_type = ET_DYN;
2157 ehdr.e_entry = text_section->sh_addr; /* XXX: is it correct ? */
2158 break;
2159 case TCC_OUTPUT_OBJ:
2160 ehdr.e_type = ET_REL;
2161 break;
2163 ehdr.e_machine = EM_TCC_TARGET;
2164 ehdr.e_version = EV_CURRENT;
2165 ehdr.e_shoff = file_offset;
2166 ehdr.e_ehsize = sizeof(ElfW(Ehdr));
2167 ehdr.e_shentsize = sizeof(ElfW(Shdr));
2168 ehdr.e_shnum = shnum;
2169 ehdr.e_shstrndx = shnum - 1;
2171 fwrite(&ehdr, 1, sizeof(ElfW(Ehdr)), f);
2172 fwrite(phdr, 1, phnum * sizeof(ElfW(Phdr)), f);
2173 offset = sizeof(ElfW(Ehdr)) + phnum * sizeof(ElfW(Phdr));
2175 sort_syms(s1, symtab_section);
2176 for(i = 1; i < s1->nb_sections; i++) {
2177 s = s1->sections[sec_order[i]];
2178 if (s->sh_type != SHT_NOBITS) {
2179 if (s->sh_type == SHT_DYNSYM)
2180 patch_dynsym_undef(s1, s);
2181 while (offset < s->sh_offset) {
2182 fputc(0, f);
2183 offset++;
2185 size = s->sh_size;
2186 if (size)
2187 fwrite(s->data, 1, size, f);
2188 offset += size;
2192 /* output section headers */
2193 while (offset < ehdr.e_shoff) {
2194 fputc(0, f);
2195 offset++;
2198 for(i = 0; i < s1->nb_sections; i++) {
2199 sh = &shdr;
2200 memset(sh, 0, sizeof(ElfW(Shdr)));
2201 s = s1->sections[i];
2202 if (s) {
2203 sh->sh_name = s->sh_name;
2204 sh->sh_type = s->sh_type;
2205 sh->sh_flags = s->sh_flags;
2206 sh->sh_entsize = s->sh_entsize;
2207 sh->sh_info = s->sh_info;
2208 if (s->link)
2209 sh->sh_link = s->link->sh_num;
2210 sh->sh_addralign = s->sh_addralign;
2211 sh->sh_addr = s->sh_addr;
2212 sh->sh_offset = s->sh_offset;
2213 sh->sh_size = s->sh_size;
2215 fwrite(sh, 1, sizeof(ElfW(Shdr)), f);
2219 /* Write an elf, coff or "binary" file */
2220 static int tcc_write_elf_file(TCCState *s1, const char *filename, int phnum,
2221 ElfW(Phdr) *phdr, int file_offset, int *sec_order)
2223 int fd, mode, file_type;
2224 FILE *f;
2226 file_type = s1->output_type;
2227 if (file_type == TCC_OUTPUT_OBJ)
2228 mode = 0666;
2229 else
2230 mode = 0777;
2231 unlink(filename);
2232 fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, mode);
2233 if (fd < 0) {
2234 tcc_error_noabort("could not write '%s'", filename);
2235 return -1;
2237 f = fdopen(fd, "wb");
2238 if (s1->verbose)
2239 printf("<- %s\n", filename);
2241 #ifdef TCC_TARGET_COFF
2242 if (s1->output_format == TCC_OUTPUT_FORMAT_COFF)
2243 tcc_output_coff(s1, f);
2244 else
2245 #endif
2246 if (s1->output_format == TCC_OUTPUT_FORMAT_ELF)
2247 tcc_output_elf(s1, f, phnum, phdr, file_offset, sec_order);
2248 else
2249 tcc_output_binary(s1, f, sec_order);
2250 fclose(f);
2252 return 0;
2255 /* Output an elf, coff or binary file */
2256 /* XXX: suppress unneeded sections */
2257 static int elf_output_file(TCCState *s1, const char *filename)
2259 int i, ret, phnum, shnum, file_type, file_offset, *sec_order;
2260 struct dyn_inf dyninf;
2261 ElfW(Phdr) *phdr;
2262 ElfW(Sym) *sym;
2263 Section *strsec, *interp, *dynamic, *dynstr;
2265 file_type = s1->output_type;
2266 s1->nb_errors = 0;
2268 /* if linking, also link in runtime libraries (libc, libgcc, etc.) */
2269 if (file_type != TCC_OUTPUT_OBJ) {
2270 tcc_add_runtime(s1);
2273 phdr = NULL;
2274 sec_order = NULL;
2275 interp = dynamic = dynstr = NULL; /* avoid warning */
2276 dyninf.dyn_rel_off = 0; /* avoid warning */
2278 if (file_type != TCC_OUTPUT_OBJ) {
2279 relocate_common_syms();
2281 tcc_add_linker_symbols(s1);
2283 if (!s1->static_link) {
2284 if (file_type == TCC_OUTPUT_EXE) {
2285 char *ptr;
2286 /* allow override the dynamic loader */
2287 const char *elfint = getenv("LD_SO");
2288 if (elfint == NULL)
2289 elfint = DEFAULT_ELFINTERP(s1);
2290 /* add interpreter section only if executable */
2291 interp = new_section(s1, ".interp", SHT_PROGBITS, SHF_ALLOC);
2292 interp->sh_addralign = 1;
2293 ptr = section_ptr_add(interp, 1 + strlen(elfint));
2294 strcpy(ptr, elfint);
2297 /* add dynamic symbol table */
2298 s1->dynsym = new_symtab(s1, ".dynsym", SHT_DYNSYM, SHF_ALLOC,
2299 ".dynstr",
2300 ".hash", SHF_ALLOC);
2301 dynstr = s1->dynsym->link;
2303 /* add dynamic section */
2304 dynamic = new_section(s1, ".dynamic", SHT_DYNAMIC,
2305 SHF_ALLOC | SHF_WRITE);
2306 dynamic->link = dynstr;
2307 dynamic->sh_entsize = sizeof(ElfW(Dyn));
2309 build_got(s1);
2311 if (file_type == TCC_OUTPUT_EXE) {
2312 bind_exe_dynsyms(s1);
2314 if (s1->nb_errors) {
2315 ret = -1;
2316 goto the_end;
2319 bind_libs_dynsyms(s1);
2320 } else /* shared library case: simply export all global symbols */
2321 export_global_syms(s1);
2323 build_got_entries(s1);
2325 /* add a list of needed dlls */
2326 for(i = 0; i < s1->nb_loaded_dlls; i++) {
2327 DLLReference *dllref = s1->loaded_dlls[i];
2328 if (dllref->level == 0)
2329 put_dt(dynamic, DT_NEEDED, put_elf_str(dynstr, dllref->name));
2332 if (s1->rpath)
2333 put_dt(dynamic, DT_RPATH, put_elf_str(dynstr, s1->rpath));
2335 /* XXX: currently, since we do not handle PIC code, we
2336 must relocate the readonly segments */
2337 if (file_type == TCC_OUTPUT_DLL) {
2338 if (s1->soname)
2339 put_dt(dynamic, DT_SONAME, put_elf_str(dynstr, s1->soname));
2340 put_dt(dynamic, DT_TEXTREL, 0);
2343 if (s1->symbolic)
2344 put_dt(dynamic, DT_SYMBOLIC, 0);
2346 /* add necessary space for other entries */
2347 dyninf.dyn_rel_off = dynamic->data_offset;
2348 dynamic->data_offset += sizeof(ElfW(Dyn)) * EXTRA_RELITEMS;
2349 } else {
2350 /* still need to build got entries in case of static link */
2351 build_got_entries(s1);
2355 /* we add a section for symbols */
2356 strsec = new_section(s1, ".shstrtab", SHT_STRTAB, 0);
2357 put_elf_str(strsec, "");
2359 /* compute number of sections */
2360 shnum = s1->nb_sections;
2362 /* this array is used to reorder sections in the output file */
2363 sec_order = tcc_malloc(sizeof(int) * shnum);
2364 sec_order[0] = 0;
2366 /* compute number of program headers */
2367 switch(file_type) {
2368 default:
2369 case TCC_OUTPUT_OBJ:
2370 phnum = 0;
2371 break;
2372 case TCC_OUTPUT_EXE:
2373 if (!s1->static_link)
2374 phnum = 4 + HAVE_PHDR;
2375 else
2376 phnum = 2;
2377 break;
2378 case TCC_OUTPUT_DLL:
2379 phnum = 3;
2380 break;
2383 /* Allocate strings for section names */
2384 alloc_sec_names(s1, file_type, strsec);
2386 /* allocate program segment headers */
2387 phdr = tcc_mallocz(phnum * sizeof(ElfW(Phdr)));
2389 /* compute section to program header mapping */
2390 file_offset = layout_sections(s1, phdr, phnum, interp, strsec, &dyninf,
2391 sec_order);
2393 /* Fill remaining program header and finalize relocation related to dynamic
2394 linking. */
2395 if (phnum > 0) {
2396 fill_unloadable_phdr(phdr, phnum, interp, dynamic);
2397 if (dynamic) {
2398 dyninf.dynamic = dynamic;
2399 dyninf.dynstr = dynstr;
2401 fill_dynamic(s1, &dyninf);
2403 /* put in GOT the dynamic section address and relocate PLT */
2404 write32le(s1->got->data, dynamic->sh_addr);
2405 if (file_type == TCC_OUTPUT_EXE
2406 #if defined(TCC_OUTPUT_DLL_WITH_PLT)
2407 || file_type == TCC_OUTPUT_DLL
2408 #endif
2410 relocate_plt(s1);
2412 /* relocate symbols in .dynsym now that final addresses are known */
2413 for_each_elem(s1->dynsym, 1, sym, ElfW(Sym)) {
2414 if (sym->st_shndx == SHN_UNDEF) {
2415 /* relocate to PLT if symbol corresponds to a PLT entry,
2416 but not if it's a weak symbol */
2417 if (ELFW(ST_BIND)(sym->st_info) == STB_WEAK)
2418 sym->st_value = 0;
2419 else if (sym->st_value)
2420 sym->st_value += s1->plt->sh_addr;
2421 } else if (sym->st_shndx < SHN_LORESERVE) {
2422 /* do symbol relocation */
2423 sym->st_value += s1->sections[sym->st_shndx]->sh_addr;
2429 /* if building executable or DLL, then relocate each section
2430 except the GOT which is already relocated */
2431 if (file_type != TCC_OUTPUT_OBJ) {
2432 ret = final_sections_reloc(s1);
2433 if (ret)
2434 goto the_end;
2437 /* Perform relocation to GOT or PLT entries */
2438 if (file_type == TCC_OUTPUT_EXE && s1->static_link)
2439 fill_got(s1);
2441 /* Create the ELF file with name 'filename' */
2442 ret = tcc_write_elf_file(s1, filename, phnum, phdr, file_offset, sec_order);
2443 the_end:
2444 tcc_free(s1->symtab_to_dynsym);
2445 tcc_free(sec_order);
2446 tcc_free(phdr);
2447 tcc_free(s1->sym_attrs);
2448 s1->sym_attrs = NULL;
2449 return ret;
2452 LIBTCCAPI int tcc_output_file(TCCState *s, const char *filename)
2454 int ret;
2455 #ifdef TCC_TARGET_PE
2456 if (s->output_type != TCC_OUTPUT_OBJ) {
2457 ret = pe_output_file(s, filename);
2458 } else
2459 #endif
2460 ret = elf_output_file(s, filename);
2461 return ret;
2464 static void *load_data(int fd, unsigned long file_offset, unsigned long size)
2466 void *data;
2468 data = tcc_malloc(size);
2469 lseek(fd, file_offset, SEEK_SET);
2470 read(fd, data, size);
2471 return data;
2474 typedef struct SectionMergeInfo {
2475 Section *s; /* corresponding existing section */
2476 unsigned long offset; /* offset of the new section in the existing section */
2477 uint8_t new_section; /* true if section 's' was added */
2478 uint8_t link_once; /* true if link once section */
2479 } SectionMergeInfo;
2481 ST_FUNC int tcc_object_type(int fd, ElfW(Ehdr) *h)
2483 int size = read(fd, h, sizeof *h);
2484 if (size == sizeof *h && 0 == memcmp(h, ELFMAG, 4)) {
2485 if (h->e_type == ET_REL)
2486 return AFF_BINTYPE_REL;
2487 if (h->e_type == ET_DYN)
2488 return AFF_BINTYPE_DYN;
2489 } else if (size >= 8) {
2490 if (0 == memcmp(h, ARMAG, 8))
2491 return AFF_BINTYPE_AR;
2492 #ifdef TCC_TARGET_COFF
2493 if (((struct filehdr*)h)->f_magic == COFF_C67_MAGIC)
2494 return AFF_BINTYPE_C67;
2495 #endif
2497 return 0;
2500 /* load an object file and merge it with current files */
2501 /* XXX: handle correctly stab (debug) info */
2502 ST_FUNC int tcc_load_object_file(TCCState *s1,
2503 int fd, unsigned long file_offset)
2505 ElfW(Ehdr) ehdr;
2506 ElfW(Shdr) *shdr, *sh;
2507 int size, i, j, offset, offseti, nb_syms, sym_index, ret;
2508 unsigned char *strsec, *strtab;
2509 int *old_to_new_syms;
2510 char *sh_name, *name;
2511 SectionMergeInfo *sm_table, *sm;
2512 ElfW(Sym) *sym, *symtab;
2513 ElfW_Rel *rel;
2514 Section *s;
2516 int stab_index;
2517 int stabstr_index;
2519 stab_index = stabstr_index = 0;
2521 lseek(fd, file_offset, SEEK_SET);
2522 if (tcc_object_type(fd, &ehdr) != AFF_BINTYPE_REL)
2523 goto fail1;
2524 /* test CPU specific stuff */
2525 if (ehdr.e_ident[5] != ELFDATA2LSB ||
2526 ehdr.e_machine != EM_TCC_TARGET) {
2527 fail1:
2528 tcc_error_noabort("invalid object file");
2529 return -1;
2531 /* read sections */
2532 shdr = load_data(fd, file_offset + ehdr.e_shoff,
2533 sizeof(ElfW(Shdr)) * ehdr.e_shnum);
2534 sm_table = tcc_mallocz(sizeof(SectionMergeInfo) * ehdr.e_shnum);
2536 /* load section names */
2537 sh = &shdr[ehdr.e_shstrndx];
2538 strsec = load_data(fd, file_offset + sh->sh_offset, sh->sh_size);
2540 /* load symtab and strtab */
2541 old_to_new_syms = NULL;
2542 symtab = NULL;
2543 strtab = NULL;
2544 nb_syms = 0;
2545 for(i = 1; i < ehdr.e_shnum; i++) {
2546 sh = &shdr[i];
2547 if (sh->sh_type == SHT_SYMTAB) {
2548 if (symtab) {
2549 tcc_error_noabort("object must contain only one symtab");
2550 fail:
2551 ret = -1;
2552 goto the_end;
2554 nb_syms = sh->sh_size / sizeof(ElfW(Sym));
2555 symtab = load_data(fd, file_offset + sh->sh_offset, sh->sh_size);
2556 sm_table[i].s = symtab_section;
2558 /* now load strtab */
2559 sh = &shdr[sh->sh_link];
2560 strtab = load_data(fd, file_offset + sh->sh_offset, sh->sh_size);
2564 /* now examine each section and try to merge its content with the
2565 ones in memory */
2566 for(i = 1; i < ehdr.e_shnum; i++) {
2567 /* no need to examine section name strtab */
2568 if (i == ehdr.e_shstrndx)
2569 continue;
2570 sh = &shdr[i];
2571 sh_name = (char *) strsec + sh->sh_name;
2572 /* ignore sections types we do not handle */
2573 if (sh->sh_type != SHT_PROGBITS &&
2574 sh->sh_type != SHT_RELX &&
2575 #ifdef TCC_ARM_EABI
2576 sh->sh_type != SHT_ARM_EXIDX &&
2577 #endif
2578 sh->sh_type != SHT_NOBITS &&
2579 sh->sh_type != SHT_PREINIT_ARRAY &&
2580 sh->sh_type != SHT_INIT_ARRAY &&
2581 sh->sh_type != SHT_FINI_ARRAY &&
2582 strcmp(sh_name, ".stabstr")
2584 continue;
2585 if (sh->sh_addralign < 1)
2586 sh->sh_addralign = 1;
2587 /* find corresponding section, if any */
2588 for(j = 1; j < s1->nb_sections;j++) {
2589 s = s1->sections[j];
2590 if (!strcmp(s->name, sh_name)) {
2591 if (!strncmp(sh_name, ".gnu.linkonce",
2592 sizeof(".gnu.linkonce") - 1)) {
2593 /* if a 'linkonce' section is already present, we
2594 do not add it again. It is a little tricky as
2595 symbols can still be defined in
2596 it. */
2597 sm_table[i].link_once = 1;
2598 goto next;
2599 } else {
2600 goto found;
2604 /* not found: create new section */
2605 s = new_section(s1, sh_name, sh->sh_type, sh->sh_flags & ~SHF_GROUP);
2606 /* take as much info as possible from the section. sh_link and
2607 sh_info will be updated later */
2608 s->sh_addralign = sh->sh_addralign;
2609 s->sh_entsize = sh->sh_entsize;
2610 sm_table[i].new_section = 1;
2611 found:
2612 if (sh->sh_type != s->sh_type) {
2613 tcc_error_noabort("invalid section type");
2614 goto fail;
2617 /* align start of section */
2618 offset = s->data_offset;
2620 if (0 == strcmp(sh_name, ".stab")) {
2621 stab_index = i;
2622 goto no_align;
2624 if (0 == strcmp(sh_name, ".stabstr")) {
2625 stabstr_index = i;
2626 goto no_align;
2629 size = sh->sh_addralign - 1;
2630 offset = (offset + size) & ~size;
2631 if (sh->sh_addralign > s->sh_addralign)
2632 s->sh_addralign = sh->sh_addralign;
2633 s->data_offset = offset;
2634 no_align:
2635 sm_table[i].offset = offset;
2636 sm_table[i].s = s;
2637 /* concatenate sections */
2638 size = sh->sh_size;
2639 if (sh->sh_type != SHT_NOBITS) {
2640 unsigned char *ptr;
2641 lseek(fd, file_offset + sh->sh_offset, SEEK_SET);
2642 ptr = section_ptr_add(s, size);
2643 read(fd, ptr, size);
2644 } else {
2645 s->data_offset += size;
2647 next: ;
2650 /* gr relocate stab strings */
2651 if (stab_index && stabstr_index) {
2652 Stab_Sym *a, *b;
2653 unsigned o;
2654 s = sm_table[stab_index].s;
2655 a = (Stab_Sym *)(s->data + sm_table[stab_index].offset);
2656 b = (Stab_Sym *)(s->data + s->data_offset);
2657 o = sm_table[stabstr_index].offset;
2658 while (a < b)
2659 a->n_strx += o, a++;
2662 /* second short pass to update sh_link and sh_info fields of new
2663 sections */
2664 for(i = 1; i < ehdr.e_shnum; i++) {
2665 s = sm_table[i].s;
2666 if (!s || !sm_table[i].new_section)
2667 continue;
2668 sh = &shdr[i];
2669 if (sh->sh_link > 0)
2670 s->link = sm_table[sh->sh_link].s;
2671 if (sh->sh_type == SHT_RELX) {
2672 s->sh_info = sm_table[sh->sh_info].s->sh_num;
2673 /* update backward link */
2674 s1->sections[s->sh_info]->reloc = s;
2677 sm = sm_table;
2679 /* resolve symbols */
2680 old_to_new_syms = tcc_mallocz(nb_syms * sizeof(int));
2682 sym = symtab + 1;
2683 for(i = 1; i < nb_syms; i++, sym++) {
2684 if (sym->st_shndx != SHN_UNDEF &&
2685 sym->st_shndx < SHN_LORESERVE) {
2686 sm = &sm_table[sym->st_shndx];
2687 if (sm->link_once) {
2688 /* if a symbol is in a link once section, we use the
2689 already defined symbol. It is very important to get
2690 correct relocations */
2691 if (ELFW(ST_BIND)(sym->st_info) != STB_LOCAL) {
2692 name = (char *) strtab + sym->st_name;
2693 sym_index = find_elf_sym(symtab_section, name);
2694 if (sym_index)
2695 old_to_new_syms[i] = sym_index;
2697 continue;
2699 /* if no corresponding section added, no need to add symbol */
2700 if (!sm->s)
2701 continue;
2702 /* convert section number */
2703 sym->st_shndx = sm->s->sh_num;
2704 /* offset value */
2705 sym->st_value += sm->offset;
2707 /* add symbol */
2708 name = (char *) strtab + sym->st_name;
2709 sym_index = set_elf_sym(symtab_section, sym->st_value, sym->st_size,
2710 sym->st_info, sym->st_other,
2711 sym->st_shndx, name);
2712 old_to_new_syms[i] = sym_index;
2715 /* third pass to patch relocation entries */
2716 for(i = 1; i < ehdr.e_shnum; i++) {
2717 s = sm_table[i].s;
2718 if (!s)
2719 continue;
2720 sh = &shdr[i];
2721 offset = sm_table[i].offset;
2722 switch(s->sh_type) {
2723 case SHT_RELX:
2724 /* take relocation offset information */
2725 offseti = sm_table[sh->sh_info].offset;
2726 for_each_elem(s, (offset / sizeof(*rel)), rel, ElfW_Rel) {
2727 int type;
2728 unsigned sym_index;
2729 /* convert symbol index */
2730 type = ELFW(R_TYPE)(rel->r_info);
2731 sym_index = ELFW(R_SYM)(rel->r_info);
2732 /* NOTE: only one symtab assumed */
2733 if (sym_index >= nb_syms)
2734 goto invalid_reloc;
2735 sym_index = old_to_new_syms[sym_index];
2736 /* ignore link_once in rel section. */
2737 if (!sym_index && !sm->link_once
2738 #ifdef TCC_TARGET_ARM
2739 && type != R_ARM_V4BX
2740 #endif
2742 invalid_reloc:
2743 tcc_error_noabort("Invalid relocation entry [%2d] '%s' @ %.8x",
2744 i, strsec + sh->sh_name, rel->r_offset);
2745 goto fail;
2747 rel->r_info = ELFW(R_INFO)(sym_index, type);
2748 /* offset the relocation offset */
2749 rel->r_offset += offseti;
2750 #ifdef TCC_TARGET_ARM
2751 /* Jumps and branches from a Thumb code to a PLT entry need
2752 special handling since PLT entries are ARM code.
2753 Unconditional bl instructions referencing PLT entries are
2754 handled by converting these instructions into blx
2755 instructions. Other case of instructions referencing a PLT
2756 entry require to add a Thumb stub before the PLT entry to
2757 switch to ARM mode. We set bit plt_thumb_stub of the
2758 attribute of a symbol to indicate such a case. */
2759 if (type == R_ARM_THM_JUMP24)
2760 alloc_sym_attr(s1, sym_index)->plt_thumb_stub = 1;
2761 #endif
2763 break;
2764 default:
2765 break;
2769 ret = 0;
2770 the_end:
2771 tcc_free(symtab);
2772 tcc_free(strtab);
2773 tcc_free(old_to_new_syms);
2774 tcc_free(sm_table);
2775 tcc_free(strsec);
2776 tcc_free(shdr);
2777 return ret;
2780 typedef struct ArchiveHeader {
2781 char ar_name[16]; /* name of this member */
2782 char ar_date[12]; /* file mtime */
2783 char ar_uid[6]; /* owner uid; printed as decimal */
2784 char ar_gid[6]; /* owner gid; printed as decimal */
2785 char ar_mode[8]; /* file mode, printed as octal */
2786 char ar_size[10]; /* file size, printed as decimal */
2787 char ar_fmag[2]; /* should contain ARFMAG */
2788 } ArchiveHeader;
2790 static int get_be32(const uint8_t *b)
2792 return b[3] | (b[2] << 8) | (b[1] << 16) | (b[0] << 24);
2795 static long get_be64(const uint8_t *b)
2797 long long ret = get_be32(b);
2798 ret = (ret << 32) | (unsigned)get_be32(b+4);
2799 return (long)ret;
2802 /* load only the objects which resolve undefined symbols */
2803 static int tcc_load_alacarte(TCCState *s1, int fd, int size, int entrysize)
2805 long i, bound, nsyms, sym_index, off, ret;
2806 uint8_t *data;
2807 const char *ar_names, *p;
2808 const uint8_t *ar_index;
2809 ElfW(Sym) *sym;
2811 data = tcc_malloc(size);
2812 if (read(fd, data, size) != size)
2813 goto fail;
2814 nsyms = entrysize == 4 ? get_be32(data) : get_be64(data);
2815 ar_index = data + entrysize;
2816 ar_names = (char *) ar_index + nsyms * entrysize;
2818 do {
2819 bound = 0;
2820 for(p = ar_names, i = 0; i < nsyms; i++, p += strlen(p)+1) {
2821 sym_index = find_elf_sym(symtab_section, p);
2822 if(sym_index) {
2823 sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
2824 if(sym->st_shndx == SHN_UNDEF) {
2825 off = (entrysize == 4
2826 ? get_be32(ar_index + i * 4)
2827 : get_be64(ar_index + i * 8))
2828 + sizeof(ArchiveHeader);
2829 ++bound;
2830 if(tcc_load_object_file(s1, fd, off) < 0) {
2831 fail:
2832 ret = -1;
2833 goto the_end;
2838 } while(bound);
2839 ret = 0;
2840 the_end:
2841 tcc_free(data);
2842 return ret;
2845 /* load a '.a' file */
2846 ST_FUNC int tcc_load_archive(TCCState *s1, int fd)
2848 ArchiveHeader hdr;
2849 char ar_size[11];
2850 char ar_name[17];
2851 char magic[8];
2852 int size, len, i;
2853 unsigned long file_offset;
2855 /* skip magic which was already checked */
2856 read(fd, magic, sizeof(magic));
2858 for(;;) {
2859 len = read(fd, &hdr, sizeof(hdr));
2860 if (len == 0)
2861 break;
2862 if (len != sizeof(hdr)) {
2863 tcc_error_noabort("invalid archive");
2864 return -1;
2866 memcpy(ar_size, hdr.ar_size, sizeof(hdr.ar_size));
2867 ar_size[sizeof(hdr.ar_size)] = '\0';
2868 size = strtol(ar_size, NULL, 0);
2869 memcpy(ar_name, hdr.ar_name, sizeof(hdr.ar_name));
2870 for(i = sizeof(hdr.ar_name) - 1; i >= 0; i--) {
2871 if (ar_name[i] != ' ')
2872 break;
2874 ar_name[i + 1] = '\0';
2875 file_offset = lseek(fd, 0, SEEK_CUR);
2876 /* align to even */
2877 size = (size + 1) & ~1;
2878 if (!strcmp(ar_name, "/")) {
2879 /* coff symbol table : we handle it */
2880 if(s1->alacarte_link)
2881 return tcc_load_alacarte(s1, fd, size, 4);
2882 } else if (!strcmp(ar_name, "/SYM64/")) {
2883 if(s1->alacarte_link)
2884 return tcc_load_alacarte(s1, fd, size, 8);
2885 } else {
2886 ElfW(Ehdr) ehdr;
2887 if (tcc_object_type(fd, &ehdr) == AFF_BINTYPE_REL) {
2888 if (tcc_load_object_file(s1, fd, file_offset) < 0)
2889 return -1;
2892 lseek(fd, file_offset + size, SEEK_SET);
2894 return 0;
2897 #ifndef TCC_TARGET_PE
2898 /* load a DLL and all referenced DLLs. 'level = 0' means that the DLL
2899 is referenced by the user (so it should be added as DT_NEEDED in
2900 the generated ELF file) */
2901 ST_FUNC int tcc_load_dll(TCCState *s1, int fd, const char *filename, int level)
2903 ElfW(Ehdr) ehdr;
2904 ElfW(Shdr) *shdr, *sh, *sh1;
2905 int i, j, nb_syms, nb_dts, sym_bind, ret;
2906 ElfW(Sym) *sym, *dynsym;
2907 ElfW(Dyn) *dt, *dynamic;
2908 unsigned char *dynstr;
2909 const char *name, *soname;
2910 DLLReference *dllref;
2912 read(fd, &ehdr, sizeof(ehdr));
2914 /* test CPU specific stuff */
2915 if (ehdr.e_ident[5] != ELFDATA2LSB ||
2916 ehdr.e_machine != EM_TCC_TARGET) {
2917 tcc_error_noabort("bad architecture");
2918 return -1;
2921 /* read sections */
2922 shdr = load_data(fd, ehdr.e_shoff, sizeof(ElfW(Shdr)) * ehdr.e_shnum);
2924 /* load dynamic section and dynamic symbols */
2925 nb_syms = 0;
2926 nb_dts = 0;
2927 dynamic = NULL;
2928 dynsym = NULL; /* avoid warning */
2929 dynstr = NULL; /* avoid warning */
2930 for(i = 0, sh = shdr; i < ehdr.e_shnum; i++, sh++) {
2931 switch(sh->sh_type) {
2932 case SHT_DYNAMIC:
2933 nb_dts = sh->sh_size / sizeof(ElfW(Dyn));
2934 dynamic = load_data(fd, sh->sh_offset, sh->sh_size);
2935 break;
2936 case SHT_DYNSYM:
2937 nb_syms = sh->sh_size / sizeof(ElfW(Sym));
2938 dynsym = load_data(fd, sh->sh_offset, sh->sh_size);
2939 sh1 = &shdr[sh->sh_link];
2940 dynstr = load_data(fd, sh1->sh_offset, sh1->sh_size);
2941 break;
2942 default:
2943 break;
2947 /* compute the real library name */
2948 soname = tcc_basename(filename);
2950 for(i = 0, dt = dynamic; i < nb_dts; i++, dt++) {
2951 if (dt->d_tag == DT_SONAME) {
2952 soname = (char *) dynstr + dt->d_un.d_val;
2956 /* if the dll is already loaded, do not load it */
2957 for(i = 0; i < s1->nb_loaded_dlls; i++) {
2958 dllref = s1->loaded_dlls[i];
2959 if (!strcmp(soname, dllref->name)) {
2960 /* but update level if needed */
2961 if (level < dllref->level)
2962 dllref->level = level;
2963 ret = 0;
2964 goto the_end;
2968 /* add the dll and its level */
2969 dllref = tcc_mallocz(sizeof(DLLReference) + strlen(soname));
2970 dllref->level = level;
2971 strcpy(dllref->name, soname);
2972 dynarray_add((void ***)&s1->loaded_dlls, &s1->nb_loaded_dlls, dllref);
2974 /* add dynamic symbols in dynsym_section */
2975 for(i = 1, sym = dynsym + 1; i < nb_syms; i++, sym++) {
2976 sym_bind = ELFW(ST_BIND)(sym->st_info);
2977 if (sym_bind == STB_LOCAL)
2978 continue;
2979 name = (char *) dynstr + sym->st_name;
2980 set_elf_sym(s1->dynsymtab_section, sym->st_value, sym->st_size,
2981 sym->st_info, sym->st_other, sym->st_shndx, name);
2984 /* load all referenced DLLs */
2985 for(i = 0, dt = dynamic; i < nb_dts; i++, dt++) {
2986 switch(dt->d_tag) {
2987 case DT_NEEDED:
2988 name = (char *) dynstr + dt->d_un.d_val;
2989 for(j = 0; j < s1->nb_loaded_dlls; j++) {
2990 dllref = s1->loaded_dlls[j];
2991 if (!strcmp(name, dllref->name))
2992 goto already_loaded;
2994 if (tcc_add_dll(s1, name, AFF_REFERENCED_DLL) < 0) {
2995 tcc_error_noabort("referenced dll '%s' not found", name);
2996 ret = -1;
2997 goto the_end;
2999 already_loaded:
3000 break;
3003 ret = 0;
3004 the_end:
3005 tcc_free(dynstr);
3006 tcc_free(dynsym);
3007 tcc_free(dynamic);
3008 tcc_free(shdr);
3009 return ret;
3012 #define LD_TOK_NAME 256
3013 #define LD_TOK_EOF (-1)
3015 /* return next ld script token */
3016 static int ld_next(TCCState *s1, char *name, int name_size)
3018 int c;
3019 char *q;
3021 redo:
3022 switch(ch) {
3023 case ' ':
3024 case '\t':
3025 case '\f':
3026 case '\v':
3027 case '\r':
3028 case '\n':
3029 inp();
3030 goto redo;
3031 case '/':
3032 minp();
3033 if (ch == '*') {
3034 file->buf_ptr = parse_comment(file->buf_ptr);
3035 ch = file->buf_ptr[0];
3036 goto redo;
3037 } else {
3038 q = name;
3039 *q++ = '/';
3040 goto parse_name;
3042 break;
3043 case '\\':
3044 ch = handle_eob();
3045 if (ch != '\\')
3046 goto redo;
3047 /* fall through */
3048 /* case 'a' ... 'z': */
3049 case 'a':
3050 case 'b':
3051 case 'c':
3052 case 'd':
3053 case 'e':
3054 case 'f':
3055 case 'g':
3056 case 'h':
3057 case 'i':
3058 case 'j':
3059 case 'k':
3060 case 'l':
3061 case 'm':
3062 case 'n':
3063 case 'o':
3064 case 'p':
3065 case 'q':
3066 case 'r':
3067 case 's':
3068 case 't':
3069 case 'u':
3070 case 'v':
3071 case 'w':
3072 case 'x':
3073 case 'y':
3074 case 'z':
3075 /* case 'A' ... 'z': */
3076 case 'A':
3077 case 'B':
3078 case 'C':
3079 case 'D':
3080 case 'E':
3081 case 'F':
3082 case 'G':
3083 case 'H':
3084 case 'I':
3085 case 'J':
3086 case 'K':
3087 case 'L':
3088 case 'M':
3089 case 'N':
3090 case 'O':
3091 case 'P':
3092 case 'Q':
3093 case 'R':
3094 case 'S':
3095 case 'T':
3096 case 'U':
3097 case 'V':
3098 case 'W':
3099 case 'X':
3100 case 'Y':
3101 case 'Z':
3102 case '_':
3103 case '.':
3104 case '$':
3105 case '~':
3106 q = name;
3107 parse_name:
3108 for(;;) {
3109 if (!((ch >= 'a' && ch <= 'z') ||
3110 (ch >= 'A' && ch <= 'Z') ||
3111 (ch >= '0' && ch <= '9') ||
3112 strchr("/.-_+=$:\\,~", ch)))
3113 break;
3114 if ((q - name) < name_size - 1) {
3115 *q++ = ch;
3117 minp();
3119 *q = '\0';
3120 c = LD_TOK_NAME;
3121 break;
3122 case CH_EOF:
3123 c = LD_TOK_EOF;
3124 break;
3125 default:
3126 c = ch;
3127 inp();
3128 break;
3130 return c;
3133 static int ld_add_file(TCCState *s1, const char filename[])
3135 int ret;
3137 ret = tcc_add_file_internal(s1, filename, AFF_TYPE_BIN);
3138 if (ret)
3139 ret = tcc_add_dll(s1, filename, 0);
3140 return ret;
3143 static inline int new_undef_syms(void)
3145 int ret = 0;
3146 ret = new_undef_sym;
3147 new_undef_sym = 0;
3148 return ret;
3151 static int ld_add_file_list(TCCState *s1, const char *cmd, int as_needed)
3153 char filename[1024], libname[1024];
3154 int t, group, nblibs = 0, ret = 0;
3155 char **libs = NULL;
3157 group = !strcmp(cmd, "GROUP");
3158 if (!as_needed)
3159 new_undef_syms();
3160 t = ld_next(s1, filename, sizeof(filename));
3161 if (t != '(')
3162 expect("(");
3163 t = ld_next(s1, filename, sizeof(filename));
3164 for(;;) {
3165 libname[0] = '\0';
3166 if (t == LD_TOK_EOF) {
3167 tcc_error_noabort("unexpected end of file");
3168 ret = -1;
3169 goto lib_parse_error;
3170 } else if (t == ')') {
3171 break;
3172 } else if (t == '-') {
3173 t = ld_next(s1, filename, sizeof(filename));
3174 if ((t != LD_TOK_NAME) || (filename[0] != 'l')) {
3175 tcc_error_noabort("library name expected");
3176 ret = -1;
3177 goto lib_parse_error;
3179 pstrcpy(libname, sizeof libname, &filename[1]);
3180 if (s1->static_link) {
3181 snprintf(filename, sizeof filename, "lib%s.a", libname);
3182 } else {
3183 snprintf(filename, sizeof filename, "lib%s.so", libname);
3185 } else if (t != LD_TOK_NAME) {
3186 tcc_error_noabort("filename expected");
3187 ret = -1;
3188 goto lib_parse_error;
3190 if (!strcmp(filename, "AS_NEEDED")) {
3191 ret = ld_add_file_list(s1, cmd, 1);
3192 if (ret)
3193 goto lib_parse_error;
3194 } else {
3195 /* TODO: Implement AS_NEEDED support. Ignore it for now */
3196 if (!as_needed) {
3197 ret = ld_add_file(s1, filename);
3198 if (ret)
3199 goto lib_parse_error;
3200 if (group) {
3201 /* Add the filename *and* the libname to avoid future conversions */
3202 dynarray_add((void ***) &libs, &nblibs, tcc_strdup(filename));
3203 if (libname[0] != '\0')
3204 dynarray_add((void ***) &libs, &nblibs, tcc_strdup(libname));
3208 t = ld_next(s1, filename, sizeof(filename));
3209 if (t == ',') {
3210 t = ld_next(s1, filename, sizeof(filename));
3213 if (group && !as_needed) {
3214 while (new_undef_syms()) {
3215 int i;
3217 for (i = 0; i < nblibs; i ++)
3218 ld_add_file(s1, libs[i]);
3221 lib_parse_error:
3222 dynarray_reset(&libs, &nblibs);
3223 return ret;
3226 /* interpret a subset of GNU ldscripts to handle the dummy libc.so
3227 files */
3228 ST_FUNC int tcc_load_ldscript(TCCState *s1)
3230 char cmd[64];
3231 char filename[1024];
3232 int t, ret;
3234 ch = handle_eob();
3235 for(;;) {
3236 t = ld_next(s1, cmd, sizeof(cmd));
3237 if (t == LD_TOK_EOF)
3238 return 0;
3239 else if (t != LD_TOK_NAME)
3240 return -1;
3241 if (!strcmp(cmd, "INPUT") ||
3242 !strcmp(cmd, "GROUP")) {
3243 ret = ld_add_file_list(s1, cmd, 0);
3244 if (ret)
3245 return ret;
3246 } else if (!strcmp(cmd, "OUTPUT_FORMAT") ||
3247 !strcmp(cmd, "TARGET")) {
3248 /* ignore some commands */
3249 t = ld_next(s1, cmd, sizeof(cmd));
3250 if (t != '(')
3251 expect("(");
3252 for(;;) {
3253 t = ld_next(s1, filename, sizeof(filename));
3254 if (t == LD_TOK_EOF) {
3255 tcc_error_noabort("unexpected end of file");
3256 return -1;
3257 } else if (t == ')') {
3258 break;
3261 } else {
3262 return -1;
3265 return 0;
3267 #endif /* !TCC_TARGET_PE */