Only create GOT or GOT entry when needed
[tinycc.git] / tccelf.c
blob63e81116884dca87aa365bd6b179220e7eb01167
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 sym_index = ELFW(R_SYM)(rel->r_info);
1036 sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
1037 switch(type) {
1038 #if defined(TCC_TARGET_I386)
1039 case R_386_PC16:
1040 case R_386_PC32:
1041 case R_386_GOT32:
1042 case R_386_GOT32X:
1043 case R_386_GOTOFF:
1044 case R_386_GOTPC:
1045 case R_386_PLT32:
1046 if (sym->st_shndx != SHN_UNDEF && type != R_386_GOT32 &&
1047 type != R_386_GOT32X && type != R_386_GOTOFF &&
1048 type != R_386_GOTPC && type != R_386_PLT32)
1049 break;
1051 if (!s1->got)
1052 build_got(s1);
1054 if (type != R_386_GOTOFF && type != R_386_GOTPC) {
1055 /* look at the symbol got offset. If none, then add one */
1056 if (type == R_386_GOT32 || type == R_386_GOT32X)
1057 reloc_type = R_386_GLOB_DAT;
1058 else
1059 reloc_type = R_386_JMP_SLOT;
1060 put_got_entry(s1, reloc_type, sym->st_size, sym->st_info,
1061 sym_index);
1063 break;
1064 #elif defined(TCC_TARGET_ARM)
1065 case R_ARM_PC24:
1066 case R_ARM_CALL:
1067 case R_ARM_JUMP24:
1068 case R_ARM_PLT32:
1069 case R_ARM_THM_PC22:
1070 case R_ARM_MOVT_ABS:
1071 case R_ARM_MOVW_ABS_NC:
1072 case R_ARM_THM_MOVT_ABS:
1073 case R_ARM_THM_MOVW_ABS_NC:
1074 case R_ARM_PREL31:
1075 case R_ARM_REL32:
1076 case R_ARM_GOTPC:
1077 case R_ARM_GOTOFF:
1078 case R_ARM_GOT32:
1079 case R_ARM_V4BX:
1080 if (sym->st_shndx != SHN_UNDEF && type != R_ARM_GOT32 &&
1081 type != R_ARM_GOTOFF && type != R_ARM_GOTPC &&
1082 type != R_ARM_PLT32)
1083 break;
1085 if (!s1->got)
1086 build_got(s1);
1087 if (type != R_ARM_GOTOFF && type != R_ARM_GOTPC
1088 && (sym->st_shndx == SHN_UNDEF
1089 || s1->output_type == TCC_OUTPUT_MEMORY)) {
1090 unsigned long ofs;
1091 /* look at the symbol got offset. If none, then add one */
1092 if (type == R_ARM_GOT32 || type == R_ARM_MOVT_ABS ||
1093 type == R_ARM_MOVW_ABS_NC ||
1094 type == R_ARM_THM_MOVT_ABS ||
1095 type == R_ARM_THM_MOVW_ABS_NC || type == R_ARM_ABS32 ||
1096 type == R_ARM_REL32)
1097 reloc_type = R_ARM_GLOB_DAT;
1098 else
1099 reloc_type = R_ARM_JUMP_SLOT;
1100 ofs = put_got_entry(s1, reloc_type, sym->st_size,
1101 sym->st_info, sym_index);
1102 #ifdef DEBUG_RELOC
1103 printf ("maybegot: %s, %d, %d --> ofs=0x%x\n",
1104 (char *) symtab_section->link->data + sym->st_name,
1105 type, sym->st_shndx, ofs);
1106 #endif
1107 if (type == R_ARM_PC24 || type == R_ARM_CALL ||
1108 type == R_ARM_JUMP24 || type == R_ARM_PLT32) {
1109 addr_t *ptr = (addr_t*)(s1->sections[s->sh_info]->data
1110 + rel->r_offset);
1111 /* x must be signed! */
1112 int x = *ptr & 0xffffff;
1113 x = (x << 8) >> 8;
1114 x <<= 2;
1115 x += ofs;
1116 x >>= 2;
1117 #ifdef DEBUG_RELOC
1118 printf ("insn=0x%x --> 0x%x (x==0x%x)\n", *ptr,
1119 (*ptr & 0xff000000) | x, x);
1120 #endif
1121 *ptr = (*ptr & 0xff000000) | x;
1124 break;
1125 case R_ARM_THM_JUMP24:
1126 sym_index = ELFW(R_SYM)(rel->r_info);
1127 sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
1128 /* We are relocating a jump from thumb code to arm code */
1129 if (sym->st_shndx != SHN_UNDEF && !(sym->st_value & 1)) {
1130 int index;
1131 uint8_t *p;
1132 char *name, buf[1024];
1133 Section *text_section;
1135 name = (char *) symtab_section->link->data + sym->st_name;
1136 text_section = s1->sections[sym->st_shndx];
1137 /* Modify reloc to target a thumb stub to switch to ARM */
1138 snprintf(buf, sizeof(buf), "%s_from_thumb", name);
1139 index = put_elf_sym(symtab_section,
1140 text_section->data_offset + 1,
1141 sym->st_size, sym->st_info, 0,
1142 sym->st_shndx, buf);
1143 rel->r_info = ELFW(R_INFO)(index, type);
1144 /* Create a thumb stub fonction to switch to ARM mode */
1145 put_elf_reloc(symtab_section, text_section,
1146 text_section->data_offset + 4, R_ARM_JUMP24,
1147 sym_index);
1148 p = section_ptr_add(text_section, 8);
1149 write32le(p, 0x4778); /* bx pc */
1150 write32le(p+2, 0x46c0); /* nop */
1151 write32le(p+4, 0xeafffffe); /* b $sym */
1153 #elif defined(TCC_TARGET_ARM64)
1154 //xx Other cases may be required here:
1155 case R_AARCH64_ADR_GOT_PAGE:
1156 case R_AARCH64_LD64_GOT_LO12_NC:
1157 if (!s1->got)
1158 build_got(s1);
1159 sym_index = ELFW(R_SYM)(rel->r_info);
1160 sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
1161 reloc_type = R_AARCH64_GLOB_DAT;
1162 put_got_entry(s1, reloc_type, sym->st_size, sym->st_info,
1163 sym_index);
1164 break;
1166 case R_AARCH64_JUMP26:
1167 case R_AARCH64_CALL26:
1168 if (!s1->got)
1169 build_got(s1);
1170 sym_index = ELFW(R_SYM)(rel->r_info);
1171 sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
1172 if (sym->st_shndx == SHN_UNDEF ||
1173 s1->output_type == TCC_OUTPUT_MEMORY) {
1174 unsigned long ofs;
1175 reloc_type = R_AARCH64_JUMP_SLOT;
1176 ofs = put_got_entry(s1, reloc_type, sym->st_size,
1177 sym->st_info, sym_index);
1178 /* We store the place of the generated PLT slot
1179 in our addend. */
1180 rel->r_addend += ofs;
1182 break;
1183 #elif defined(TCC_TARGET_C67)
1184 case R_C60_GOT32:
1185 case R_C60_GOTOFF:
1186 case R_C60_GOTPC:
1187 case R_C60_PLT32:
1188 if (!s1->got)
1189 build_got(s1);
1190 if (type == R_C60_GOT32 || type == R_C60_PLT32) {
1191 sym_index = ELFW(R_SYM)(rel->r_info);
1192 sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
1193 /* look at the symbol got offset. If none, then add one */
1194 if (type == R_C60_GOT32)
1195 reloc_type = R_C60_GLOB_DAT;
1196 else
1197 reloc_type = R_C60_JMP_SLOT;
1198 put_got_entry(s1, reloc_type, sym->st_size, sym->st_info,
1199 sym_index);
1201 break;
1202 #elif defined(TCC_TARGET_X86_64)
1203 case R_X86_64_32:
1204 case R_X86_64_32S:
1205 case R_X86_64_64:
1206 case R_X86_64_PC32:
1207 case R_X86_64_GOT32:
1208 case R_X86_64_GOTTPOFF:
1209 case R_X86_64_GOTPCREL:
1210 case R_X86_64_GOTPCRELX:
1211 case R_X86_64_REX_GOTPCRELX:
1212 case R_X86_64_PLT32:
1213 sym_index = ELFW(R_SYM)(rel->r_info);
1214 sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
1215 if ((type == R_X86_64_32 || type == R_X86_64_32S ||
1216 type == R_X86_64_64 || type == R_X86_64_PC32) &&
1217 sym->st_shndx != SHN_UNDEF)
1218 break;
1220 if (type == R_X86_64_PLT32 &&
1221 ELFW(ST_VISIBILITY)(sym->st_other) != STV_DEFAULT) {
1222 rel->r_info = ELFW(R_INFO)(sym_index, R_X86_64_PC32);
1223 break;
1226 if (!s1->got)
1227 build_got(s1);
1228 if (type != R_X86_64_GOTTPOFF) {
1229 unsigned long ofs;
1230 /* look at the symbol got offset. If none, then add one */
1231 if (type == R_X86_64_GOT32 || type == R_X86_64_GOTPCREL ||
1232 type == R_X86_64_GOTPCRELX ||
1233 type == R_X86_64_REX_GOTPCRELX ||
1234 type == R_X86_64_32 || type == R_X86_64_32S ||
1235 type == R_X86_64_64)
1236 reloc_type = R_X86_64_GLOB_DAT;
1237 else
1238 reloc_type = R_X86_64_JUMP_SLOT;
1239 ofs = put_got_entry(s1, reloc_type, sym->st_size,
1240 sym->st_info, sym_index);
1241 if (type == R_X86_64_PLT32)
1242 /* We store the place of the generated PLT slot
1243 in our addend. */
1244 rel->r_addend += ofs;
1246 break;
1247 #else
1248 #error unsupported CPU
1249 #endif
1250 default:
1251 break;
1257 ST_FUNC Section *new_symtab(TCCState *s1,
1258 const char *symtab_name, int sh_type, int sh_flags,
1259 const char *strtab_name,
1260 const char *hash_name, int hash_sh_flags)
1262 Section *symtab, *strtab, *hash;
1263 int *ptr, nb_buckets;
1265 symtab = new_section(s1, symtab_name, sh_type, sh_flags);
1266 symtab->sh_entsize = sizeof(ElfW(Sym));
1267 strtab = new_section(s1, strtab_name, SHT_STRTAB, sh_flags);
1268 put_elf_str(strtab, "");
1269 symtab->link = strtab;
1270 put_elf_sym(symtab, 0, 0, 0, 0, 0, NULL);
1272 nb_buckets = 1;
1274 hash = new_section(s1, hash_name, SHT_HASH, hash_sh_flags);
1275 hash->sh_entsize = sizeof(int);
1276 symtab->hash = hash;
1277 hash->link = symtab;
1279 ptr = section_ptr_add(hash, (2 + nb_buckets + 1) * sizeof(int));
1280 ptr[0] = nb_buckets;
1281 ptr[1] = 1;
1282 memset(ptr + 2, 0, (nb_buckets + 1) * sizeof(int));
1283 return symtab;
1286 /* put dynamic tag */
1287 static void put_dt(Section *dynamic, int dt, addr_t val)
1289 ElfW(Dyn) *dyn;
1290 dyn = section_ptr_add(dynamic, sizeof(ElfW(Dyn)));
1291 dyn->d_tag = dt;
1292 dyn->d_un.d_val = val;
1295 #ifndef TCC_TARGET_PE
1296 static void add_init_array_defines(TCCState *s1, const char *section_name)
1298 Section *s;
1299 long end_offset;
1300 char sym_start[1024];
1301 char sym_end[1024];
1303 snprintf(sym_start, sizeof(sym_start), "__%s_start", section_name + 1);
1304 snprintf(sym_end, sizeof(sym_end), "__%s_end", section_name + 1);
1306 s = find_section(s1, section_name);
1307 if (!s) {
1308 end_offset = 0;
1309 s = data_section;
1310 } else {
1311 end_offset = s->data_offset;
1314 set_elf_sym(symtab_section,
1315 0, 0,
1316 ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
1317 s->sh_num, sym_start);
1318 set_elf_sym(symtab_section,
1319 end_offset, 0,
1320 ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
1321 s->sh_num, sym_end);
1323 #endif
1325 static int tcc_add_support(TCCState *s1, const char *filename)
1327 char buf[1024];
1328 snprintf(buf, sizeof(buf), "%s/"TCC_ARCH_DIR"%s", s1->tcc_lib_path, filename);
1329 return tcc_add_file(s1, buf);
1332 ST_FUNC void tcc_add_bcheck(TCCState *s1)
1334 #ifdef CONFIG_TCC_BCHECK
1335 addr_t *ptr;
1336 int sym_index;
1338 if (0 == s1->do_bounds_check)
1339 return;
1340 /* XXX: add an object file to do that */
1341 ptr = section_ptr_add(bounds_section, sizeof(*ptr));
1342 *ptr = 0;
1343 set_elf_sym(symtab_section, 0, 0,
1344 ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
1345 bounds_section->sh_num, "__bounds_start");
1346 /* pull bcheck.o from libtcc1.a */
1347 sym_index = set_elf_sym(symtab_section, 0, 0,
1348 ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
1349 SHN_UNDEF, "__bound_init");
1350 if (s1->output_type != TCC_OUTPUT_MEMORY) {
1351 /* add 'call __bound_init()' in .init section */
1352 Section *init_section = find_section(s1, ".init");
1353 unsigned char *pinit = section_ptr_add(init_section, 5);
1354 pinit[0] = 0xe8;
1355 write32le(pinit + 1, -4);
1356 put_elf_reloc(symtab_section, init_section,
1357 init_section->data_offset - 4, R_386_PC32, sym_index);
1358 /* R_386_PC32 = R_X86_64_PC32 = 2 */
1360 #endif
1363 /* add tcc runtime libraries */
1364 ST_FUNC void tcc_add_runtime(TCCState *s1)
1366 tcc_add_bcheck(s1);
1367 tcc_add_pragma_libs(s1);
1368 /* add libc */
1369 if (!s1->nostdlib) {
1370 tcc_add_library_err(s1, "c");
1371 #ifdef CONFIG_USE_LIBGCC
1372 if (!s1->static_link) {
1373 tcc_add_file(s1, TCC_LIBGCC);
1375 #endif
1376 tcc_add_support(s1, "libtcc1.a");
1377 /* add crt end if not memory output */
1378 if (s1->output_type != TCC_OUTPUT_MEMORY)
1379 tcc_add_crt(s1, "crtn.o");
1383 /* add various standard linker symbols (must be done after the
1384 sections are filled (for example after allocating common
1385 symbols)) */
1386 ST_FUNC void tcc_add_linker_symbols(TCCState *s1)
1388 char buf[1024];
1389 int i;
1390 Section *s;
1392 set_elf_sym(symtab_section,
1393 text_section->data_offset, 0,
1394 ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
1395 text_section->sh_num, "_etext");
1396 set_elf_sym(symtab_section,
1397 data_section->data_offset, 0,
1398 ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
1399 data_section->sh_num, "_edata");
1400 set_elf_sym(symtab_section,
1401 bss_section->data_offset, 0,
1402 ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
1403 bss_section->sh_num, "_end");
1404 #ifndef TCC_TARGET_PE
1405 /* horrible new standard ldscript defines */
1406 add_init_array_defines(s1, ".preinit_array");
1407 add_init_array_defines(s1, ".init_array");
1408 add_init_array_defines(s1, ".fini_array");
1409 #endif
1411 /* add start and stop symbols for sections whose name can be
1412 expressed in C */
1413 for(i = 1; i < s1->nb_sections; i++) {
1414 s = s1->sections[i];
1415 if (s->sh_type == SHT_PROGBITS &&
1416 (s->sh_flags & SHF_ALLOC)) {
1417 const char *p;
1418 int ch;
1420 /* check if section name can be expressed in C */
1421 p = s->name;
1422 for(;;) {
1423 ch = *p;
1424 if (!ch)
1425 break;
1426 if (!isid(ch) && !isnum(ch))
1427 goto next_sec;
1428 p++;
1430 snprintf(buf, sizeof(buf), "__start_%s", s->name);
1431 set_elf_sym(symtab_section,
1432 0, 0,
1433 ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
1434 s->sh_num, buf);
1435 snprintf(buf, sizeof(buf), "__stop_%s", s->name);
1436 set_elf_sym(symtab_section,
1437 s->data_offset, 0,
1438 ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
1439 s->sh_num, buf);
1441 next_sec: ;
1445 static void tcc_output_binary(TCCState *s1, FILE *f,
1446 const int *sec_order)
1448 Section *s;
1449 int i, offset, size;
1451 offset = 0;
1452 for(i=1;i<s1->nb_sections;i++) {
1453 s = s1->sections[sec_order[i]];
1454 if (s->sh_type != SHT_NOBITS &&
1455 (s->sh_flags & SHF_ALLOC)) {
1456 while (offset < s->sh_offset) {
1457 fputc(0, f);
1458 offset++;
1460 size = s->sh_size;
1461 fwrite(s->data, 1, size, f);
1462 offset += size;
1467 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
1468 #define HAVE_PHDR 1
1469 #define EXTRA_RELITEMS 14
1471 /* move the relocation value from .dynsym to .got */
1472 static void patch_dynsym_undef(TCCState *s1, Section *s)
1474 uint32_t *gotd = (void *)s1->got->data;
1475 ElfW(Sym) *sym;
1477 gotd += 3; /* dummy entries in .got */
1478 /* relocate symbols in .dynsym */
1479 for_each_elem(s, 1, sym, ElfW(Sym)) {
1480 if (sym->st_shndx == SHN_UNDEF) {
1481 *gotd++ = sym->st_value + 6; /* XXX 6 is magic ? */
1482 sym->st_value = 0;
1486 #else
1487 #define HAVE_PHDR 1
1488 #define EXTRA_RELITEMS 9
1490 /* zero plt offsets of weak symbols in .dynsym */
1491 static void patch_dynsym_undef(TCCState *s1, Section *s)
1493 ElfW(Sym) *sym;
1495 for_each_elem(s, 1, sym, ElfW(Sym))
1496 if (sym->st_shndx == SHN_UNDEF && ELFW(ST_BIND)(sym->st_info) == STB_WEAK)
1497 sym->st_value = 0;
1499 #endif
1501 ST_FUNC void fill_got_entry(TCCState *s1, ElfW_Rel *rel)
1503 int sym_index = ELFW(R_SYM) (rel->r_info);
1504 ElfW(Sym) *sym = &((ElfW(Sym) *) symtab_section->data)[sym_index];
1505 unsigned long offset;
1507 if (sym_index >= s1->nb_sym_attrs)
1508 return;
1509 offset = s1->sym_attrs[sym_index].got_offset;
1510 section_reserve(s1->got, offset + PTR_SIZE);
1511 #ifdef TCC_TARGET_X86_64
1512 /* only works for x86-64 */
1513 write32le(s1->got->data + offset + 4, sym->st_value >> 32);
1514 #endif
1515 write32le(s1->got->data + offset, sym->st_value & 0xffffffff);
1518 /* Perform relocation to GOT or PLT entries */
1519 ST_FUNC void fill_got(TCCState *s1)
1521 Section *s;
1522 ElfW_Rel *rel;
1523 int i;
1525 for(i = 1; i < s1->nb_sections; i++) {
1526 s = s1->sections[i];
1527 if (s->sh_type != SHT_RELX)
1528 continue;
1529 /* no need to handle got relocations */
1530 if (s->link != symtab_section)
1531 continue;
1532 for_each_elem(s, 0, rel, ElfW_Rel) {
1533 switch (ELFW(R_TYPE) (rel->r_info)) {
1534 case R_X86_64_GOT32:
1535 case R_X86_64_GOTPCREL:
1536 case R_X86_64_GOTPCRELX:
1537 case R_X86_64_REX_GOTPCRELX:
1538 case R_X86_64_PLT32:
1539 fill_got_entry(s1, rel);
1540 break;
1546 /* Bind symbols of executable: resolve undefined symbols from exported symbols
1547 in shared libraries and export non local defined symbols to shared libraries
1548 if -rdynamic switch was given on command line */
1549 static void bind_exe_dynsyms(TCCState *s1)
1551 const char *name;
1552 int sym_index, index;
1553 ElfW(Sym) *sym, *esym;
1554 int type;
1556 /* Resolve undefined symbols from dynamic symbols. When there is a match:
1557 - if STT_FUNC or STT_GNU_IFUNC symbol -> add it in PLT
1558 - if STT_OBJECT symbol -> add it in .bss section with suitable reloc */
1559 for_each_elem(symtab_section, 1, sym, ElfW(Sym)) {
1560 if (sym->st_shndx == SHN_UNDEF) {
1561 name = (char *) symtab_section->link->data + sym->st_name;
1562 sym_index = find_elf_sym(s1->dynsymtab_section, name);
1563 if (sym_index) {
1564 esym = &((ElfW(Sym) *)s1->dynsymtab_section->data)[sym_index];
1565 type = ELFW(ST_TYPE)(esym->st_info);
1566 if ((type == STT_FUNC) || (type == STT_GNU_IFUNC)) {
1567 /* Indirect functions shall have STT_FUNC type in executable
1568 * dynsym section. Indeed, a dlsym call following a lazy
1569 * resolution would pick the symbol value from the
1570 * executable dynsym entry which would contain the address
1571 * of the function wanted by the caller of dlsym instead of
1572 * the address of the function that would return that
1573 * address */
1574 put_got_entry(s1, R_JMP_SLOT, esym->st_size,
1575 ELFW(ST_INFO)(STB_GLOBAL,STT_FUNC),
1576 sym - (ElfW(Sym) *)symtab_section->data);
1577 } else if (type == STT_OBJECT) {
1578 unsigned long offset;
1579 ElfW(Sym) *dynsym;
1580 offset = bss_section->data_offset;
1581 /* XXX: which alignment ? */
1582 offset = (offset + 16 - 1) & -16;
1583 index = put_elf_sym(s1->dynsym, offset, esym->st_size,
1584 esym->st_info, 0, bss_section->sh_num,
1585 name);
1586 /* Ensure R_COPY works for weak symbol aliases */
1587 if (ELFW(ST_BIND)(esym->st_info) == STB_WEAK) {
1588 for_each_elem(s1->dynsymtab_section, 1, dynsym, ElfW(Sym)) {
1589 if ((dynsym->st_value == esym->st_value)
1590 && (ELFW(ST_BIND)(dynsym->st_info) == STB_GLOBAL)) {
1591 char *dynname = (char *) s1->dynsymtab_section->link->data
1592 + dynsym->st_name;
1593 put_elf_sym(s1->dynsym, offset, dynsym->st_size,
1594 dynsym->st_info, 0,
1595 bss_section->sh_num, dynname);
1596 break;
1600 put_elf_reloc(s1->dynsym, bss_section,
1601 offset, R_COPY, index);
1602 offset += esym->st_size;
1603 bss_section->data_offset = offset;
1605 } else {
1606 /* STB_WEAK undefined symbols are accepted */
1607 /* XXX: _fp_hw seems to be part of the ABI, so we ignore it */
1608 if (ELFW(ST_BIND)(sym->st_info) == STB_WEAK ||
1609 !strcmp(name, "_fp_hw")) {
1610 } else {
1611 tcc_error_noabort("undefined symbol '%s'", name);
1614 } else if (s1->rdynamic && ELFW(ST_BIND)(sym->st_info) != STB_LOCAL) {
1615 /* if -rdynamic option, then export all non local symbols */
1616 name = (char *) symtab_section->link->data + sym->st_name;
1617 set_elf_sym(s1->dynsym, sym->st_value, sym->st_size, sym->st_info,
1618 0, sym->st_shndx, name);
1623 /* Bind symbols of libraries: export all non local symbols of executable that
1624 are referenced by shared libraries. The reason is that the dynamic loader
1625 search symbol first in executable and then in libraries. Therefore a
1626 reference to a symbol already defined by a library can still be resolved by
1627 a symbol in the executable. */
1628 static void bind_libs_dynsyms(TCCState *s1)
1630 const char *name;
1631 int sym_index;
1632 ElfW(Sym) *sym, *esym;
1634 for_each_elem(s1->dynsymtab_section, 1, esym, ElfW(Sym)) {
1635 name = (char *) s1->dynsymtab_section->link->data + esym->st_name;
1636 sym_index = find_elf_sym(symtab_section, name);
1637 /* XXX: avoid adding a symbol if already present because of
1638 -rdynamic ? */
1639 sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
1640 if (sym_index && sym->st_shndx != SHN_UNDEF)
1641 set_elf_sym(s1->dynsym, sym->st_value, sym->st_size, sym->st_info,
1642 0, sym->st_shndx, name);
1643 else if (esym->st_shndx == SHN_UNDEF) {
1644 /* weak symbols can stay undefined */
1645 if (ELFW(ST_BIND)(esym->st_info) != STB_WEAK)
1646 tcc_warning("undefined dynamic symbol '%s'", name);
1651 /* Export all non local symbols. This is used by shared libraries so that the
1652 non local symbols they define can resolve a reference in another shared
1653 library or in the executable. Correspondingly, it allows undefined local
1654 symbols to be resolved by other shared libraries or by the executable. */
1655 static void export_global_syms(TCCState *s1)
1657 int nb_syms, dynindex, index;
1658 const char *name;
1659 ElfW(Sym) *sym;
1661 nb_syms = symtab_section->data_offset / sizeof(ElfW(Sym));
1662 s1->symtab_to_dynsym = tcc_mallocz(sizeof(int) * nb_syms);
1663 for_each_elem(symtab_section, 1, sym, ElfW(Sym)) {
1664 if (ELFW(ST_BIND)(sym->st_info) != STB_LOCAL) {
1665 name = (char *) symtab_section->link->data + sym->st_name;
1666 dynindex = put_elf_sym(s1->dynsym, sym->st_value, sym->st_size,
1667 sym->st_info, 0, sym->st_shndx, name);
1668 index = sym - (ElfW(Sym) *) symtab_section->data;
1669 s1->symtab_to_dynsym[index] = dynindex;
1674 /* relocate the PLT: compute addresses and offsets in the PLT now that final
1675 address for PLT and GOT are known (see fill_program_header) */
1676 ST_FUNC void relocate_plt(TCCState *s1)
1678 uint8_t *p, *p_end;
1680 if (!s1->plt)
1681 return;
1683 p = s1->plt->data;
1684 p_end = p + s1->plt->data_offset;
1685 if (p < p_end) {
1686 #if defined(TCC_TARGET_I386)
1687 add32le(p + 2, s1->got->sh_addr);
1688 add32le(p + 8, s1->got->sh_addr);
1689 p += 16;
1690 while (p < p_end) {
1691 add32le(p + 2, s1->got->sh_addr);
1692 p += 16;
1694 #elif defined(TCC_TARGET_X86_64)
1695 int x = s1->got->sh_addr - s1->plt->sh_addr - 6;
1696 add32le(p + 2, x);
1697 add32le(p + 8, x - 6);
1698 p += 16;
1699 while (p < p_end) {
1700 add32le(p + 2, x + s1->plt->data - p);
1701 p += 16;
1703 #elif defined(TCC_TARGET_ARM)
1704 int x = s1->got->sh_addr - s1->plt->sh_addr - 12;
1705 write32le(s1->plt->data + 16, x - 16);
1706 p += 20;
1707 while (p < p_end) {
1708 if (read32le(p) == 0x46c04778) /* PLT Thumb stub present */
1709 p += 4;
1710 add32le(p + 12, x + s1->plt->data - p);
1711 p += 16;
1713 #elif defined(TCC_TARGET_ARM64)
1714 uint64_t plt = s1->plt->sh_addr;
1715 uint64_t got = s1->got->sh_addr;
1716 uint64_t off = (got >> 12) - (plt >> 12);
1717 if ((off + ((uint32_t)1 << 20)) >> 21)
1718 tcc_error("Failed relocating PLT (off=0x%lx, got=0x%lx, plt=0x%lx)", off, got, plt);
1719 write32le(p, 0xa9bf7bf0); // stp x16,x30,[sp,#-16]!
1720 write32le(p + 4, (0x90000010 | // adrp x16,...
1721 (off & 0x1ffffc) << 3 | (off & 3) << 29));
1722 write32le(p + 8, (0xf9400211 | // ldr x17,[x16,#...]
1723 (got & 0xff8) << 7));
1724 write32le(p + 12, (0x91000210 | // add x16,x16,#...
1725 (got & 0xfff) << 10));
1726 write32le(p + 16, 0xd61f0220); // br x17
1727 write32le(p + 20, 0xd503201f); // nop
1728 write32le(p + 24, 0xd503201f); // nop
1729 write32le(p + 28, 0xd503201f); // nop
1730 p += 32;
1731 while (p < p_end) {
1732 uint64_t pc = plt + (p - s1->plt->data);
1733 uint64_t addr = got + read64le(p);
1734 uint64_t off = (addr >> 12) - (pc >> 12);
1735 if ((off + ((uint32_t)1 << 20)) >> 21)
1736 tcc_error("Failed relocating PLT (off=0x%lx, addr=0x%lx, pc=0x%lx)", off, addr, pc);
1737 write32le(p, (0x90000010 | // adrp x16,...
1738 (off & 0x1ffffc) << 3 | (off & 3) << 29));
1739 write32le(p + 4, (0xf9400211 | // ldr x17,[x16,#...]
1740 (addr & 0xff8) << 7));
1741 write32le(p + 8, (0x91000210 | // add x16,x16,#...
1742 (addr & 0xfff) << 10));
1743 write32le(p + 12, 0xd61f0220); // br x17
1744 p += 16;
1746 #elif defined(TCC_TARGET_C67)
1747 /* XXX: TODO */
1748 #else
1749 #error unsupported CPU
1750 #endif
1754 /* Allocate strings for section names and decide if an unallocated section
1755 should be output.
1757 NOTE: the strsec section comes last, so its size is also correct ! */
1758 static void alloc_sec_names(TCCState *s1, int file_type, Section *strsec)
1760 int i;
1761 Section *s;
1763 /* Allocate strings for section names */
1764 for(i = 1; i < s1->nb_sections; i++) {
1765 s = s1->sections[i];
1766 s->sh_name = put_elf_str(strsec, s->name);
1767 /* when generating a DLL, we include relocations but we may
1768 patch them */
1769 if (file_type == TCC_OUTPUT_DLL &&
1770 s->sh_type == SHT_RELX &&
1771 !(s->sh_flags & SHF_ALLOC)) {
1772 /* gr: avoid bogus relocs for empty (debug) sections */
1773 if (s1->sections[s->sh_info]->sh_flags & SHF_ALLOC)
1774 prepare_dynamic_rel(s1, s);
1775 else if (s1->do_debug)
1776 s->sh_size = s->data_offset;
1777 } else if (s1->do_debug ||
1778 file_type == TCC_OUTPUT_OBJ ||
1779 (s->sh_flags & SHF_ALLOC) ||
1780 i == (s1->nb_sections - 1)) {
1781 /* we output all sections if debug or object file */
1782 s->sh_size = s->data_offset;
1787 /* Info to be copied in dynamic section */
1788 struct dyn_inf {
1789 Section *dynamic;
1790 Section *dynstr;
1791 unsigned long dyn_rel_off;
1792 addr_t rel_addr;
1793 addr_t rel_size;
1794 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
1795 addr_t bss_addr;
1796 addr_t bss_size;
1797 #endif
1800 /* Assign sections to segments and decide how are sections laid out when loaded
1801 in memory. This function also fills corresponding program headers. */
1802 static int layout_sections(TCCState *s1, ElfW(Phdr) *phdr, int phnum,
1803 Section *interp, Section* strsec,
1804 struct dyn_inf *dyninf, int *sec_order)
1806 int i, j, k, file_type, sh_order_index, file_offset;
1807 unsigned long s_align;
1808 long long tmp;
1809 addr_t addr;
1810 ElfW(Phdr) *ph;
1811 Section *s;
1813 file_type = s1->output_type;
1814 sh_order_index = 1;
1815 file_offset = 0;
1816 if (s1->output_format == TCC_OUTPUT_FORMAT_ELF)
1817 file_offset = sizeof(ElfW(Ehdr)) + phnum * sizeof(ElfW(Phdr));
1818 s_align = ELF_PAGE_SIZE;
1819 if (s1->section_align)
1820 s_align = s1->section_align;
1822 if (phnum > 0) {
1823 if (s1->has_text_addr) {
1824 int a_offset, p_offset;
1825 addr = s1->text_addr;
1826 /* we ensure that (addr % ELF_PAGE_SIZE) == file_offset %
1827 ELF_PAGE_SIZE */
1828 a_offset = (int) (addr & (s_align - 1));
1829 p_offset = file_offset & (s_align - 1);
1830 if (a_offset < p_offset)
1831 a_offset += s_align;
1832 file_offset += (a_offset - p_offset);
1833 } else {
1834 if (file_type == TCC_OUTPUT_DLL)
1835 addr = 0;
1836 else
1837 addr = ELF_START_ADDR;
1838 /* compute address after headers */
1839 addr += (file_offset & (s_align - 1));
1842 ph = &phdr[0];
1843 /* Leave one program headers for the program interpreter and one for
1844 the program header table itself if needed. These are done later as
1845 they require section layout to be done first. */
1846 if (interp)
1847 ph += 1 + HAVE_PHDR;
1849 /* dynamic relocation table information, for .dynamic section */
1850 dyninf->rel_addr = dyninf->rel_size = 0;
1851 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
1852 dyninf->bss_addr = dyninf->bss_size = 0;
1853 #endif
1855 for(j = 0; j < 2; j++) {
1856 ph->p_type = PT_LOAD;
1857 if (j == 0)
1858 ph->p_flags = PF_R | PF_X;
1859 else
1860 ph->p_flags = PF_R | PF_W;
1861 ph->p_align = s_align;
1863 /* Decide the layout of sections loaded in memory. This must
1864 be done before program headers are filled since they contain
1865 info about the layout. We do the following ordering: interp,
1866 symbol tables, relocations, progbits, nobits */
1867 /* XXX: do faster and simpler sorting */
1868 for(k = 0; k < 5; k++) {
1869 for(i = 1; i < s1->nb_sections; i++) {
1870 s = s1->sections[i];
1871 /* compute if section should be included */
1872 if (j == 0) {
1873 if ((s->sh_flags & (SHF_ALLOC | SHF_WRITE)) !=
1874 SHF_ALLOC)
1875 continue;
1876 } else {
1877 if ((s->sh_flags & (SHF_ALLOC | SHF_WRITE)) !=
1878 (SHF_ALLOC | SHF_WRITE))
1879 continue;
1881 if (s == interp) {
1882 if (k != 0)
1883 continue;
1884 } else if (s->sh_type == SHT_DYNSYM ||
1885 s->sh_type == SHT_STRTAB ||
1886 s->sh_type == SHT_HASH) {
1887 if (k != 1)
1888 continue;
1889 } else if (s->sh_type == SHT_RELX) {
1890 if (k != 2)
1891 continue;
1892 } else if (s->sh_type == SHT_NOBITS) {
1893 if (k != 4)
1894 continue;
1895 } else {
1896 if (k != 3)
1897 continue;
1899 sec_order[sh_order_index++] = i;
1901 /* section matches: we align it and add its size */
1902 tmp = addr;
1903 addr = (addr + s->sh_addralign - 1) &
1904 ~(s->sh_addralign - 1);
1905 file_offset += (int) ( addr - tmp );
1906 s->sh_offset = file_offset;
1907 s->sh_addr = addr;
1909 /* update program header infos */
1910 if (ph->p_offset == 0) {
1911 ph->p_offset = file_offset;
1912 ph->p_vaddr = addr;
1913 ph->p_paddr = ph->p_vaddr;
1915 /* update dynamic relocation infos */
1916 if (s->sh_type == SHT_RELX) {
1917 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
1918 if (!strcmp(strsec->data + s->sh_name, ".rel.got")) {
1919 dyninf->rel_addr = addr;
1920 dyninf->rel_size += s->sh_size; /* XXX only first rel. */
1922 if (!strcmp(strsec->data + s->sh_name, ".rel.bss")) {
1923 dyninf->bss_addr = addr;
1924 dyninf->bss_size = s->sh_size; /* XXX only first rel. */
1926 #else
1927 if (dyninf->rel_size == 0)
1928 dyninf->rel_addr = addr;
1929 dyninf->rel_size += s->sh_size;
1930 #endif
1932 addr += s->sh_size;
1933 if (s->sh_type != SHT_NOBITS)
1934 file_offset += s->sh_size;
1937 if (j == 0) {
1938 /* Make the first PT_LOAD segment include the program
1939 headers itself (and the ELF header as well), it'll
1940 come out with same memory use but will make various
1941 tools like binutils strip work better. */
1942 ph->p_offset &= ~(ph->p_align - 1);
1943 ph->p_vaddr &= ~(ph->p_align - 1);
1944 ph->p_paddr &= ~(ph->p_align - 1);
1946 ph->p_filesz = file_offset - ph->p_offset;
1947 ph->p_memsz = addr - ph->p_vaddr;
1948 ph++;
1949 if (j == 0) {
1950 if (s1->output_format == TCC_OUTPUT_FORMAT_ELF) {
1951 /* if in the middle of a page, we duplicate the page in
1952 memory so that one copy is RX and the other is RW */
1953 if ((addr & (s_align - 1)) != 0)
1954 addr += s_align;
1955 } else {
1956 addr = (addr + s_align - 1) & ~(s_align - 1);
1957 file_offset = (file_offset + s_align - 1) & ~(s_align - 1);
1963 /* all other sections come after */
1964 for(i = 1; i < s1->nb_sections; i++) {
1965 s = s1->sections[i];
1966 if (phnum > 0 && (s->sh_flags & SHF_ALLOC))
1967 continue;
1968 sec_order[sh_order_index++] = i;
1970 file_offset = (file_offset + s->sh_addralign - 1) &
1971 ~(s->sh_addralign - 1);
1972 s->sh_offset = file_offset;
1973 if (s->sh_type != SHT_NOBITS)
1974 file_offset += s->sh_size;
1977 return file_offset;
1980 static void fill_unloadable_phdr(ElfW(Phdr) *phdr, int phnum, Section *interp,
1981 Section *dynamic)
1983 ElfW(Phdr) *ph;
1985 /* if interpreter, then add corresponding program header */
1986 if (interp) {
1987 ph = &phdr[0];
1989 if (HAVE_PHDR)
1991 int len = phnum * sizeof(ElfW(Phdr));
1993 ph->p_type = PT_PHDR;
1994 ph->p_offset = sizeof(ElfW(Ehdr));
1995 ph->p_vaddr = interp->sh_addr - len;
1996 ph->p_paddr = ph->p_vaddr;
1997 ph->p_filesz = ph->p_memsz = len;
1998 ph->p_flags = PF_R | PF_X;
1999 ph->p_align = 4; /* interp->sh_addralign; */
2000 ph++;
2003 ph->p_type = PT_INTERP;
2004 ph->p_offset = interp->sh_offset;
2005 ph->p_vaddr = interp->sh_addr;
2006 ph->p_paddr = ph->p_vaddr;
2007 ph->p_filesz = interp->sh_size;
2008 ph->p_memsz = interp->sh_size;
2009 ph->p_flags = PF_R;
2010 ph->p_align = interp->sh_addralign;
2013 /* if dynamic section, then add corresponding program header */
2014 if (dynamic) {
2015 ph = &phdr[phnum - 1];
2017 ph->p_type = PT_DYNAMIC;
2018 ph->p_offset = dynamic->sh_offset;
2019 ph->p_vaddr = dynamic->sh_addr;
2020 ph->p_paddr = ph->p_vaddr;
2021 ph->p_filesz = dynamic->sh_size;
2022 ph->p_memsz = dynamic->sh_size;
2023 ph->p_flags = PF_R | PF_W;
2024 ph->p_align = dynamic->sh_addralign;
2028 /* Fill the dynamic section with tags describing the address and size of
2029 sections */
2030 static void fill_dynamic(TCCState *s1, struct dyn_inf *dyninf)
2032 Section *dynamic;
2034 dynamic = dyninf->dynamic;
2036 /* put dynamic section entries */
2037 dynamic->data_offset = dyninf->dyn_rel_off;
2038 put_dt(dynamic, DT_HASH, s1->dynsym->hash->sh_addr);
2039 put_dt(dynamic, DT_STRTAB, dyninf->dynstr->sh_addr);
2040 put_dt(dynamic, DT_SYMTAB, s1->dynsym->sh_addr);
2041 put_dt(dynamic, DT_STRSZ, dyninf->dynstr->data_offset);
2042 put_dt(dynamic, DT_SYMENT, sizeof(ElfW(Sym)));
2043 #if defined(TCC_TARGET_ARM64) || defined(TCC_TARGET_X86_64)
2044 put_dt(dynamic, DT_RELA, dyninf->rel_addr);
2045 put_dt(dynamic, DT_RELASZ, dyninf->rel_size);
2046 put_dt(dynamic, DT_RELAENT, sizeof(ElfW_Rel));
2047 #else
2048 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
2049 put_dt(dynamic, DT_PLTGOT, s1->got->sh_addr);
2050 put_dt(dynamic, DT_PLTRELSZ, dyninf->rel_size);
2051 put_dt(dynamic, DT_JMPREL, dyninf->rel_addr);
2052 put_dt(dynamic, DT_PLTREL, DT_REL);
2053 put_dt(dynamic, DT_REL, dyninf->bss_addr);
2054 put_dt(dynamic, DT_RELSZ, dyninf->bss_size);
2055 #else
2056 put_dt(dynamic, DT_REL, dyninf->rel_addr);
2057 put_dt(dynamic, DT_RELSZ, dyninf->rel_size);
2058 put_dt(dynamic, DT_RELENT, sizeof(ElfW_Rel));
2059 #endif
2060 #endif
2061 if (s1->do_debug)
2062 put_dt(dynamic, DT_DEBUG, 0);
2063 put_dt(dynamic, DT_NULL, 0);
2066 /* Relocate remaining sections and symbols (that is those not related to
2067 dynamic linking) */
2068 static int final_sections_reloc(TCCState *s1)
2070 int i;
2071 Section *s;
2073 relocate_syms(s1, 0);
2075 if (s1->nb_errors != 0)
2076 return -1;
2078 /* relocate sections */
2079 /* XXX: ignore sections with allocated relocations ? */
2080 for(i = 1; i < s1->nb_sections; i++) {
2081 s = s1->sections[i];
2082 #ifdef TCC_TARGET_I386
2083 if (s->reloc && s != s1->got && (s->sh_flags & SHF_ALLOC)) //gr
2084 /* On X86 gdb 7.3 works in any case but gdb 6.6 will crash if SHF_ALLOC
2085 checking is removed */
2086 #else
2087 if (s->reloc && s != s1->got)
2088 /* On X86_64 gdb 7.3 will crash if SHF_ALLOC checking is present */
2089 #endif
2090 relocate_section(s1, s);
2093 /* relocate relocation entries if the relocation tables are
2094 allocated in the executable */
2095 for(i = 1; i < s1->nb_sections; i++) {
2096 s = s1->sections[i];
2097 if ((s->sh_flags & SHF_ALLOC) &&
2098 s->sh_type == SHT_RELX) {
2099 relocate_rel(s1, s);
2102 return 0;
2105 /* Create an ELF file on disk.
2106 This function handle ELF specific layout requirements */
2107 static void tcc_output_elf(TCCState *s1, FILE *f, int phnum, ElfW(Phdr) *phdr,
2108 int file_offset, int *sec_order)
2110 int i, shnum, offset, size, file_type;
2111 Section *s;
2112 ElfW(Ehdr) ehdr;
2113 ElfW(Shdr) shdr, *sh;
2115 file_type = s1->output_type;
2116 shnum = s1->nb_sections;
2118 memset(&ehdr, 0, sizeof(ehdr));
2120 if (phnum > 0) {
2121 ehdr.e_phentsize = sizeof(ElfW(Phdr));
2122 ehdr.e_phnum = phnum;
2123 ehdr.e_phoff = sizeof(ElfW(Ehdr));
2126 /* align to 4 */
2127 file_offset = (file_offset + 3) & -4;
2129 /* fill header */
2130 ehdr.e_ident[0] = ELFMAG0;
2131 ehdr.e_ident[1] = ELFMAG1;
2132 ehdr.e_ident[2] = ELFMAG2;
2133 ehdr.e_ident[3] = ELFMAG3;
2134 ehdr.e_ident[4] = ELFCLASSW;
2135 ehdr.e_ident[5] = ELFDATA2LSB;
2136 ehdr.e_ident[6] = EV_CURRENT;
2137 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
2138 ehdr.e_ident[EI_OSABI] = ELFOSABI_FREEBSD;
2139 #endif
2140 #ifdef TCC_TARGET_ARM
2141 #ifdef TCC_ARM_EABI
2142 ehdr.e_ident[EI_OSABI] = 0;
2143 ehdr.e_flags = EF_ARM_EABI_VER4;
2144 if (file_type == TCC_OUTPUT_EXE || file_type == TCC_OUTPUT_DLL)
2145 ehdr.e_flags |= EF_ARM_HASENTRY;
2146 if (s1->float_abi == ARM_HARD_FLOAT)
2147 ehdr.e_flags |= EF_ARM_VFP_FLOAT;
2148 else
2149 ehdr.e_flags |= EF_ARM_SOFT_FLOAT;
2150 #else
2151 ehdr.e_ident[EI_OSABI] = ELFOSABI_ARM;
2152 #endif
2153 #endif
2154 switch(file_type) {
2155 default:
2156 case TCC_OUTPUT_EXE:
2157 ehdr.e_type = ET_EXEC;
2158 ehdr.e_entry = get_elf_sym_addr(s1, "_start", 1);
2159 break;
2160 case TCC_OUTPUT_DLL:
2161 ehdr.e_type = ET_DYN;
2162 ehdr.e_entry = text_section->sh_addr; /* XXX: is it correct ? */
2163 break;
2164 case TCC_OUTPUT_OBJ:
2165 ehdr.e_type = ET_REL;
2166 break;
2168 ehdr.e_machine = EM_TCC_TARGET;
2169 ehdr.e_version = EV_CURRENT;
2170 ehdr.e_shoff = file_offset;
2171 ehdr.e_ehsize = sizeof(ElfW(Ehdr));
2172 ehdr.e_shentsize = sizeof(ElfW(Shdr));
2173 ehdr.e_shnum = shnum;
2174 ehdr.e_shstrndx = shnum - 1;
2176 fwrite(&ehdr, 1, sizeof(ElfW(Ehdr)), f);
2177 fwrite(phdr, 1, phnum * sizeof(ElfW(Phdr)), f);
2178 offset = sizeof(ElfW(Ehdr)) + phnum * sizeof(ElfW(Phdr));
2180 sort_syms(s1, symtab_section);
2181 for(i = 1; i < s1->nb_sections; i++) {
2182 s = s1->sections[sec_order[i]];
2183 if (s->sh_type != SHT_NOBITS) {
2184 if (s->sh_type == SHT_DYNSYM)
2185 patch_dynsym_undef(s1, s);
2186 while (offset < s->sh_offset) {
2187 fputc(0, f);
2188 offset++;
2190 size = s->sh_size;
2191 if (size)
2192 fwrite(s->data, 1, size, f);
2193 offset += size;
2197 /* output section headers */
2198 while (offset < ehdr.e_shoff) {
2199 fputc(0, f);
2200 offset++;
2203 for(i = 0; i < s1->nb_sections; i++) {
2204 sh = &shdr;
2205 memset(sh, 0, sizeof(ElfW(Shdr)));
2206 s = s1->sections[i];
2207 if (s) {
2208 sh->sh_name = s->sh_name;
2209 sh->sh_type = s->sh_type;
2210 sh->sh_flags = s->sh_flags;
2211 sh->sh_entsize = s->sh_entsize;
2212 sh->sh_info = s->sh_info;
2213 if (s->link)
2214 sh->sh_link = s->link->sh_num;
2215 sh->sh_addralign = s->sh_addralign;
2216 sh->sh_addr = s->sh_addr;
2217 sh->sh_offset = s->sh_offset;
2218 sh->sh_size = s->sh_size;
2220 fwrite(sh, 1, sizeof(ElfW(Shdr)), f);
2224 /* Write an elf, coff or "binary" file */
2225 static int tcc_write_elf_file(TCCState *s1, const char *filename, int phnum,
2226 ElfW(Phdr) *phdr, int file_offset, int *sec_order)
2228 int fd, mode, file_type;
2229 FILE *f;
2231 file_type = s1->output_type;
2232 if (file_type == TCC_OUTPUT_OBJ)
2233 mode = 0666;
2234 else
2235 mode = 0777;
2236 unlink(filename);
2237 fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, mode);
2238 if (fd < 0) {
2239 tcc_error_noabort("could not write '%s'", filename);
2240 return -1;
2242 f = fdopen(fd, "wb");
2243 if (s1->verbose)
2244 printf("<- %s\n", filename);
2246 #ifdef TCC_TARGET_COFF
2247 if (s1->output_format == TCC_OUTPUT_FORMAT_COFF)
2248 tcc_output_coff(s1, f);
2249 else
2250 #endif
2251 if (s1->output_format == TCC_OUTPUT_FORMAT_ELF)
2252 tcc_output_elf(s1, f, phnum, phdr, file_offset, sec_order);
2253 else
2254 tcc_output_binary(s1, f, sec_order);
2255 fclose(f);
2257 return 0;
2260 /* Output an elf, coff or binary file */
2261 /* XXX: suppress unneeded sections */
2262 static int elf_output_file(TCCState *s1, const char *filename)
2264 int i, ret, phnum, shnum, file_type, file_offset, *sec_order;
2265 struct dyn_inf dyninf;
2266 ElfW(Phdr) *phdr;
2267 ElfW(Sym) *sym;
2268 Section *strsec, *interp, *dynamic, *dynstr;
2270 file_type = s1->output_type;
2271 s1->nb_errors = 0;
2273 /* if linking, also link in runtime libraries (libc, libgcc, etc.) */
2274 if (file_type != TCC_OUTPUT_OBJ) {
2275 tcc_add_runtime(s1);
2278 phdr = NULL;
2279 sec_order = NULL;
2280 interp = dynamic = dynstr = NULL; /* avoid warning */
2281 dyninf.dyn_rel_off = 0; /* avoid warning */
2283 if (file_type != TCC_OUTPUT_OBJ) {
2284 relocate_common_syms();
2286 tcc_add_linker_symbols(s1);
2288 if (!s1->static_link) {
2289 if (file_type == TCC_OUTPUT_EXE) {
2290 char *ptr;
2291 /* allow override the dynamic loader */
2292 const char *elfint = getenv("LD_SO");
2293 if (elfint == NULL)
2294 elfint = DEFAULT_ELFINTERP(s1);
2295 /* add interpreter section only if executable */
2296 interp = new_section(s1, ".interp", SHT_PROGBITS, SHF_ALLOC);
2297 interp->sh_addralign = 1;
2298 ptr = section_ptr_add(interp, 1 + strlen(elfint));
2299 strcpy(ptr, elfint);
2302 /* add dynamic symbol table */
2303 s1->dynsym = new_symtab(s1, ".dynsym", SHT_DYNSYM, SHF_ALLOC,
2304 ".dynstr",
2305 ".hash", SHF_ALLOC);
2306 dynstr = s1->dynsym->link;
2308 /* add dynamic section */
2309 dynamic = new_section(s1, ".dynamic", SHT_DYNAMIC,
2310 SHF_ALLOC | SHF_WRITE);
2311 dynamic->link = dynstr;
2312 dynamic->sh_entsize = sizeof(ElfW(Dyn));
2314 build_got(s1);
2316 if (file_type == TCC_OUTPUT_EXE) {
2317 bind_exe_dynsyms(s1);
2319 if (s1->nb_errors) {
2320 ret = -1;
2321 goto the_end;
2324 bind_libs_dynsyms(s1);
2325 } else /* shared library case: simply export all global symbols */
2326 export_global_syms(s1);
2328 build_got_entries(s1);
2330 /* add a list of needed dlls */
2331 for(i = 0; i < s1->nb_loaded_dlls; i++) {
2332 DLLReference *dllref = s1->loaded_dlls[i];
2333 if (dllref->level == 0)
2334 put_dt(dynamic, DT_NEEDED, put_elf_str(dynstr, dllref->name));
2337 if (s1->rpath)
2338 put_dt(dynamic, DT_RPATH, put_elf_str(dynstr, s1->rpath));
2340 /* XXX: currently, since we do not handle PIC code, we
2341 must relocate the readonly segments */
2342 if (file_type == TCC_OUTPUT_DLL) {
2343 if (s1->soname)
2344 put_dt(dynamic, DT_SONAME, put_elf_str(dynstr, s1->soname));
2345 put_dt(dynamic, DT_TEXTREL, 0);
2348 if (s1->symbolic)
2349 put_dt(dynamic, DT_SYMBOLIC, 0);
2351 /* add necessary space for other entries */
2352 dyninf.dyn_rel_off = dynamic->data_offset;
2353 dynamic->data_offset += sizeof(ElfW(Dyn)) * EXTRA_RELITEMS;
2354 } else {
2355 /* still need to build got entries in case of static link */
2356 build_got_entries(s1);
2360 /* we add a section for symbols */
2361 strsec = new_section(s1, ".shstrtab", SHT_STRTAB, 0);
2362 put_elf_str(strsec, "");
2364 /* compute number of sections */
2365 shnum = s1->nb_sections;
2367 /* this array is used to reorder sections in the output file */
2368 sec_order = tcc_malloc(sizeof(int) * shnum);
2369 sec_order[0] = 0;
2371 /* compute number of program headers */
2372 switch(file_type) {
2373 default:
2374 case TCC_OUTPUT_OBJ:
2375 phnum = 0;
2376 break;
2377 case TCC_OUTPUT_EXE:
2378 if (!s1->static_link)
2379 phnum = 4 + HAVE_PHDR;
2380 else
2381 phnum = 2;
2382 break;
2383 case TCC_OUTPUT_DLL:
2384 phnum = 3;
2385 break;
2388 /* Allocate strings for section names */
2389 alloc_sec_names(s1, file_type, strsec);
2391 /* allocate program segment headers */
2392 phdr = tcc_mallocz(phnum * sizeof(ElfW(Phdr)));
2394 /* compute section to program header mapping */
2395 file_offset = layout_sections(s1, phdr, phnum, interp, strsec, &dyninf,
2396 sec_order);
2398 /* Fill remaining program header and finalize relocation related to dynamic
2399 linking. */
2400 if (phnum > 0) {
2401 fill_unloadable_phdr(phdr, phnum, interp, dynamic);
2402 if (dynamic) {
2403 dyninf.dynamic = dynamic;
2404 dyninf.dynstr = dynstr;
2406 fill_dynamic(s1, &dyninf);
2408 /* put in GOT the dynamic section address and relocate PLT */
2409 write32le(s1->got->data, dynamic->sh_addr);
2410 if (file_type == TCC_OUTPUT_EXE
2411 #if defined(TCC_OUTPUT_DLL_WITH_PLT)
2412 || file_type == TCC_OUTPUT_DLL
2413 #endif
2415 relocate_plt(s1);
2417 /* relocate symbols in .dynsym now that final addresses are known */
2418 for_each_elem(s1->dynsym, 1, sym, ElfW(Sym)) {
2419 if (sym->st_shndx == SHN_UNDEF) {
2420 /* relocate to PLT if symbol corresponds to a PLT entry,
2421 but not if it's a weak symbol */
2422 if (ELFW(ST_BIND)(sym->st_info) == STB_WEAK)
2423 sym->st_value = 0;
2424 else if (sym->st_value)
2425 sym->st_value += s1->plt->sh_addr;
2426 } else if (sym->st_shndx < SHN_LORESERVE) {
2427 /* do symbol relocation */
2428 sym->st_value += s1->sections[sym->st_shndx]->sh_addr;
2434 /* if building executable or DLL, then relocate each section
2435 except the GOT which is already relocated */
2436 if (file_type != TCC_OUTPUT_OBJ) {
2437 ret = final_sections_reloc(s1);
2438 if (ret)
2439 goto the_end;
2442 /* Perform relocation to GOT or PLT entries */
2443 if (file_type == TCC_OUTPUT_EXE && s1->static_link)
2444 fill_got(s1);
2446 /* Create the ELF file with name 'filename' */
2447 ret = tcc_write_elf_file(s1, filename, phnum, phdr, file_offset, sec_order);
2448 the_end:
2449 tcc_free(s1->symtab_to_dynsym);
2450 tcc_free(sec_order);
2451 tcc_free(phdr);
2452 tcc_free(s1->sym_attrs);
2453 s1->sym_attrs = NULL;
2454 return ret;
2457 LIBTCCAPI int tcc_output_file(TCCState *s, const char *filename)
2459 int ret;
2460 #ifdef TCC_TARGET_PE
2461 if (s->output_type != TCC_OUTPUT_OBJ) {
2462 ret = pe_output_file(s, filename);
2463 } else
2464 #endif
2465 ret = elf_output_file(s, filename);
2466 return ret;
2469 static void *load_data(int fd, unsigned long file_offset, unsigned long size)
2471 void *data;
2473 data = tcc_malloc(size);
2474 lseek(fd, file_offset, SEEK_SET);
2475 read(fd, data, size);
2476 return data;
2479 typedef struct SectionMergeInfo {
2480 Section *s; /* corresponding existing section */
2481 unsigned long offset; /* offset of the new section in the existing section */
2482 uint8_t new_section; /* true if section 's' was added */
2483 uint8_t link_once; /* true if link once section */
2484 } SectionMergeInfo;
2486 ST_FUNC int tcc_object_type(int fd, ElfW(Ehdr) *h)
2488 int size = read(fd, h, sizeof *h);
2489 if (size == sizeof *h && 0 == memcmp(h, ELFMAG, 4)) {
2490 if (h->e_type == ET_REL)
2491 return AFF_BINTYPE_REL;
2492 if (h->e_type == ET_DYN)
2493 return AFF_BINTYPE_DYN;
2494 } else if (size >= 8) {
2495 if (0 == memcmp(h, ARMAG, 8))
2496 return AFF_BINTYPE_AR;
2497 #ifdef TCC_TARGET_COFF
2498 if (((struct filehdr*)h)->f_magic == COFF_C67_MAGIC)
2499 return AFF_BINTYPE_C67;
2500 #endif
2502 return 0;
2505 /* load an object file and merge it with current files */
2506 /* XXX: handle correctly stab (debug) info */
2507 ST_FUNC int tcc_load_object_file(TCCState *s1,
2508 int fd, unsigned long file_offset)
2510 ElfW(Ehdr) ehdr;
2511 ElfW(Shdr) *shdr, *sh;
2512 int size, i, j, offset, offseti, nb_syms, sym_index, ret;
2513 unsigned char *strsec, *strtab;
2514 int *old_to_new_syms;
2515 char *sh_name, *name;
2516 SectionMergeInfo *sm_table, *sm;
2517 ElfW(Sym) *sym, *symtab;
2518 ElfW_Rel *rel;
2519 Section *s;
2521 int stab_index;
2522 int stabstr_index;
2524 stab_index = stabstr_index = 0;
2526 lseek(fd, file_offset, SEEK_SET);
2527 if (tcc_object_type(fd, &ehdr) != AFF_BINTYPE_REL)
2528 goto fail1;
2529 /* test CPU specific stuff */
2530 if (ehdr.e_ident[5] != ELFDATA2LSB ||
2531 ehdr.e_machine != EM_TCC_TARGET) {
2532 fail1:
2533 tcc_error_noabort("invalid object file");
2534 return -1;
2536 /* read sections */
2537 shdr = load_data(fd, file_offset + ehdr.e_shoff,
2538 sizeof(ElfW(Shdr)) * ehdr.e_shnum);
2539 sm_table = tcc_mallocz(sizeof(SectionMergeInfo) * ehdr.e_shnum);
2541 /* load section names */
2542 sh = &shdr[ehdr.e_shstrndx];
2543 strsec = load_data(fd, file_offset + sh->sh_offset, sh->sh_size);
2545 /* load symtab and strtab */
2546 old_to_new_syms = NULL;
2547 symtab = NULL;
2548 strtab = NULL;
2549 nb_syms = 0;
2550 for(i = 1; i < ehdr.e_shnum; i++) {
2551 sh = &shdr[i];
2552 if (sh->sh_type == SHT_SYMTAB) {
2553 if (symtab) {
2554 tcc_error_noabort("object must contain only one symtab");
2555 fail:
2556 ret = -1;
2557 goto the_end;
2559 nb_syms = sh->sh_size / sizeof(ElfW(Sym));
2560 symtab = load_data(fd, file_offset + sh->sh_offset, sh->sh_size);
2561 sm_table[i].s = symtab_section;
2563 /* now load strtab */
2564 sh = &shdr[sh->sh_link];
2565 strtab = load_data(fd, file_offset + sh->sh_offset, sh->sh_size);
2569 /* now examine each section and try to merge its content with the
2570 ones in memory */
2571 for(i = 1; i < ehdr.e_shnum; i++) {
2572 /* no need to examine section name strtab */
2573 if (i == ehdr.e_shstrndx)
2574 continue;
2575 sh = &shdr[i];
2576 sh_name = (char *) strsec + sh->sh_name;
2577 /* ignore sections types we do not handle */
2578 if (sh->sh_type != SHT_PROGBITS &&
2579 sh->sh_type != SHT_RELX &&
2580 #ifdef TCC_ARM_EABI
2581 sh->sh_type != SHT_ARM_EXIDX &&
2582 #endif
2583 sh->sh_type != SHT_NOBITS &&
2584 sh->sh_type != SHT_PREINIT_ARRAY &&
2585 sh->sh_type != SHT_INIT_ARRAY &&
2586 sh->sh_type != SHT_FINI_ARRAY &&
2587 strcmp(sh_name, ".stabstr")
2589 continue;
2590 if (sh->sh_addralign < 1)
2591 sh->sh_addralign = 1;
2592 /* find corresponding section, if any */
2593 for(j = 1; j < s1->nb_sections;j++) {
2594 s = s1->sections[j];
2595 if (!strcmp(s->name, sh_name)) {
2596 if (!strncmp(sh_name, ".gnu.linkonce",
2597 sizeof(".gnu.linkonce") - 1)) {
2598 /* if a 'linkonce' section is already present, we
2599 do not add it again. It is a little tricky as
2600 symbols can still be defined in
2601 it. */
2602 sm_table[i].link_once = 1;
2603 goto next;
2604 } else {
2605 goto found;
2609 /* not found: create new section */
2610 s = new_section(s1, sh_name, sh->sh_type, sh->sh_flags & ~SHF_GROUP);
2611 /* take as much info as possible from the section. sh_link and
2612 sh_info will be updated later */
2613 s->sh_addralign = sh->sh_addralign;
2614 s->sh_entsize = sh->sh_entsize;
2615 sm_table[i].new_section = 1;
2616 found:
2617 if (sh->sh_type != s->sh_type) {
2618 tcc_error_noabort("invalid section type");
2619 goto fail;
2622 /* align start of section */
2623 offset = s->data_offset;
2625 if (0 == strcmp(sh_name, ".stab")) {
2626 stab_index = i;
2627 goto no_align;
2629 if (0 == strcmp(sh_name, ".stabstr")) {
2630 stabstr_index = i;
2631 goto no_align;
2634 size = sh->sh_addralign - 1;
2635 offset = (offset + size) & ~size;
2636 if (sh->sh_addralign > s->sh_addralign)
2637 s->sh_addralign = sh->sh_addralign;
2638 s->data_offset = offset;
2639 no_align:
2640 sm_table[i].offset = offset;
2641 sm_table[i].s = s;
2642 /* concatenate sections */
2643 size = sh->sh_size;
2644 if (sh->sh_type != SHT_NOBITS) {
2645 unsigned char *ptr;
2646 lseek(fd, file_offset + sh->sh_offset, SEEK_SET);
2647 ptr = section_ptr_add(s, size);
2648 read(fd, ptr, size);
2649 } else {
2650 s->data_offset += size;
2652 next: ;
2655 /* gr relocate stab strings */
2656 if (stab_index && stabstr_index) {
2657 Stab_Sym *a, *b;
2658 unsigned o;
2659 s = sm_table[stab_index].s;
2660 a = (Stab_Sym *)(s->data + sm_table[stab_index].offset);
2661 b = (Stab_Sym *)(s->data + s->data_offset);
2662 o = sm_table[stabstr_index].offset;
2663 while (a < b)
2664 a->n_strx += o, a++;
2667 /* second short pass to update sh_link and sh_info fields of new
2668 sections */
2669 for(i = 1; i < ehdr.e_shnum; i++) {
2670 s = sm_table[i].s;
2671 if (!s || !sm_table[i].new_section)
2672 continue;
2673 sh = &shdr[i];
2674 if (sh->sh_link > 0)
2675 s->link = sm_table[sh->sh_link].s;
2676 if (sh->sh_type == SHT_RELX) {
2677 s->sh_info = sm_table[sh->sh_info].s->sh_num;
2678 /* update backward link */
2679 s1->sections[s->sh_info]->reloc = s;
2682 sm = sm_table;
2684 /* resolve symbols */
2685 old_to_new_syms = tcc_mallocz(nb_syms * sizeof(int));
2687 sym = symtab + 1;
2688 for(i = 1; i < nb_syms; i++, sym++) {
2689 if (sym->st_shndx != SHN_UNDEF &&
2690 sym->st_shndx < SHN_LORESERVE) {
2691 sm = &sm_table[sym->st_shndx];
2692 if (sm->link_once) {
2693 /* if a symbol is in a link once section, we use the
2694 already defined symbol. It is very important to get
2695 correct relocations */
2696 if (ELFW(ST_BIND)(sym->st_info) != STB_LOCAL) {
2697 name = (char *) strtab + sym->st_name;
2698 sym_index = find_elf_sym(symtab_section, name);
2699 if (sym_index)
2700 old_to_new_syms[i] = sym_index;
2702 continue;
2704 /* if no corresponding section added, no need to add symbol */
2705 if (!sm->s)
2706 continue;
2707 /* convert section number */
2708 sym->st_shndx = sm->s->sh_num;
2709 /* offset value */
2710 sym->st_value += sm->offset;
2712 /* add symbol */
2713 name = (char *) strtab + sym->st_name;
2714 sym_index = set_elf_sym(symtab_section, sym->st_value, sym->st_size,
2715 sym->st_info, sym->st_other,
2716 sym->st_shndx, name);
2717 old_to_new_syms[i] = sym_index;
2720 /* third pass to patch relocation entries */
2721 for(i = 1; i < ehdr.e_shnum; i++) {
2722 s = sm_table[i].s;
2723 if (!s)
2724 continue;
2725 sh = &shdr[i];
2726 offset = sm_table[i].offset;
2727 switch(s->sh_type) {
2728 case SHT_RELX:
2729 /* take relocation offset information */
2730 offseti = sm_table[sh->sh_info].offset;
2731 for_each_elem(s, (offset / sizeof(*rel)), rel, ElfW_Rel) {
2732 int type;
2733 unsigned sym_index;
2734 /* convert symbol index */
2735 type = ELFW(R_TYPE)(rel->r_info);
2736 sym_index = ELFW(R_SYM)(rel->r_info);
2737 /* NOTE: only one symtab assumed */
2738 if (sym_index >= nb_syms)
2739 goto invalid_reloc;
2740 sym_index = old_to_new_syms[sym_index];
2741 /* ignore link_once in rel section. */
2742 if (!sym_index && !sm->link_once
2743 #ifdef TCC_TARGET_ARM
2744 && type != R_ARM_V4BX
2745 #endif
2747 invalid_reloc:
2748 tcc_error_noabort("Invalid relocation entry [%2d] '%s' @ %.8x",
2749 i, strsec + sh->sh_name, rel->r_offset);
2750 goto fail;
2752 rel->r_info = ELFW(R_INFO)(sym_index, type);
2753 /* offset the relocation offset */
2754 rel->r_offset += offseti;
2755 #ifdef TCC_TARGET_ARM
2756 /* Jumps and branches from a Thumb code to a PLT entry need
2757 special handling since PLT entries are ARM code.
2758 Unconditional bl instructions referencing PLT entries are
2759 handled by converting these instructions into blx
2760 instructions. Other case of instructions referencing a PLT
2761 entry require to add a Thumb stub before the PLT entry to
2762 switch to ARM mode. We set bit plt_thumb_stub of the
2763 attribute of a symbol to indicate such a case. */
2764 if (type == R_ARM_THM_JUMP24)
2765 alloc_sym_attr(s1, sym_index)->plt_thumb_stub = 1;
2766 #endif
2768 break;
2769 default:
2770 break;
2774 ret = 0;
2775 the_end:
2776 tcc_free(symtab);
2777 tcc_free(strtab);
2778 tcc_free(old_to_new_syms);
2779 tcc_free(sm_table);
2780 tcc_free(strsec);
2781 tcc_free(shdr);
2782 return ret;
2785 typedef struct ArchiveHeader {
2786 char ar_name[16]; /* name of this member */
2787 char ar_date[12]; /* file mtime */
2788 char ar_uid[6]; /* owner uid; printed as decimal */
2789 char ar_gid[6]; /* owner gid; printed as decimal */
2790 char ar_mode[8]; /* file mode, printed as octal */
2791 char ar_size[10]; /* file size, printed as decimal */
2792 char ar_fmag[2]; /* should contain ARFMAG */
2793 } ArchiveHeader;
2795 static int get_be32(const uint8_t *b)
2797 return b[3] | (b[2] << 8) | (b[1] << 16) | (b[0] << 24);
2800 static long get_be64(const uint8_t *b)
2802 long long ret = get_be32(b);
2803 ret = (ret << 32) | (unsigned)get_be32(b+4);
2804 return (long)ret;
2807 /* load only the objects which resolve undefined symbols */
2808 static int tcc_load_alacarte(TCCState *s1, int fd, int size, int entrysize)
2810 long i, bound, nsyms, sym_index, off, ret;
2811 uint8_t *data;
2812 const char *ar_names, *p;
2813 const uint8_t *ar_index;
2814 ElfW(Sym) *sym;
2816 data = tcc_malloc(size);
2817 if (read(fd, data, size) != size)
2818 goto fail;
2819 nsyms = entrysize == 4 ? get_be32(data) : get_be64(data);
2820 ar_index = data + entrysize;
2821 ar_names = (char *) ar_index + nsyms * entrysize;
2823 do {
2824 bound = 0;
2825 for(p = ar_names, i = 0; i < nsyms; i++, p += strlen(p)+1) {
2826 sym_index = find_elf_sym(symtab_section, p);
2827 if(sym_index) {
2828 sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
2829 if(sym->st_shndx == SHN_UNDEF) {
2830 off = (entrysize == 4
2831 ? get_be32(ar_index + i * 4)
2832 : get_be64(ar_index + i * 8))
2833 + sizeof(ArchiveHeader);
2834 ++bound;
2835 if(tcc_load_object_file(s1, fd, off) < 0) {
2836 fail:
2837 ret = -1;
2838 goto the_end;
2843 } while(bound);
2844 ret = 0;
2845 the_end:
2846 tcc_free(data);
2847 return ret;
2850 /* load a '.a' file */
2851 ST_FUNC int tcc_load_archive(TCCState *s1, int fd)
2853 ArchiveHeader hdr;
2854 char ar_size[11];
2855 char ar_name[17];
2856 char magic[8];
2857 int size, len, i;
2858 unsigned long file_offset;
2860 /* skip magic which was already checked */
2861 read(fd, magic, sizeof(magic));
2863 for(;;) {
2864 len = read(fd, &hdr, sizeof(hdr));
2865 if (len == 0)
2866 break;
2867 if (len != sizeof(hdr)) {
2868 tcc_error_noabort("invalid archive");
2869 return -1;
2871 memcpy(ar_size, hdr.ar_size, sizeof(hdr.ar_size));
2872 ar_size[sizeof(hdr.ar_size)] = '\0';
2873 size = strtol(ar_size, NULL, 0);
2874 memcpy(ar_name, hdr.ar_name, sizeof(hdr.ar_name));
2875 for(i = sizeof(hdr.ar_name) - 1; i >= 0; i--) {
2876 if (ar_name[i] != ' ')
2877 break;
2879 ar_name[i + 1] = '\0';
2880 file_offset = lseek(fd, 0, SEEK_CUR);
2881 /* align to even */
2882 size = (size + 1) & ~1;
2883 if (!strcmp(ar_name, "/")) {
2884 /* coff symbol table : we handle it */
2885 if(s1->alacarte_link)
2886 return tcc_load_alacarte(s1, fd, size, 4);
2887 } else if (!strcmp(ar_name, "/SYM64/")) {
2888 if(s1->alacarte_link)
2889 return tcc_load_alacarte(s1, fd, size, 8);
2890 } else {
2891 ElfW(Ehdr) ehdr;
2892 if (tcc_object_type(fd, &ehdr) == AFF_BINTYPE_REL) {
2893 if (tcc_load_object_file(s1, fd, file_offset) < 0)
2894 return -1;
2897 lseek(fd, file_offset + size, SEEK_SET);
2899 return 0;
2902 #ifndef TCC_TARGET_PE
2903 /* load a DLL and all referenced DLLs. 'level = 0' means that the DLL
2904 is referenced by the user (so it should be added as DT_NEEDED in
2905 the generated ELF file) */
2906 ST_FUNC int tcc_load_dll(TCCState *s1, int fd, const char *filename, int level)
2908 ElfW(Ehdr) ehdr;
2909 ElfW(Shdr) *shdr, *sh, *sh1;
2910 int i, j, nb_syms, nb_dts, sym_bind, ret;
2911 ElfW(Sym) *sym, *dynsym;
2912 ElfW(Dyn) *dt, *dynamic;
2913 unsigned char *dynstr;
2914 const char *name, *soname;
2915 DLLReference *dllref;
2917 read(fd, &ehdr, sizeof(ehdr));
2919 /* test CPU specific stuff */
2920 if (ehdr.e_ident[5] != ELFDATA2LSB ||
2921 ehdr.e_machine != EM_TCC_TARGET) {
2922 tcc_error_noabort("bad architecture");
2923 return -1;
2926 /* read sections */
2927 shdr = load_data(fd, ehdr.e_shoff, sizeof(ElfW(Shdr)) * ehdr.e_shnum);
2929 /* load dynamic section and dynamic symbols */
2930 nb_syms = 0;
2931 nb_dts = 0;
2932 dynamic = NULL;
2933 dynsym = NULL; /* avoid warning */
2934 dynstr = NULL; /* avoid warning */
2935 for(i = 0, sh = shdr; i < ehdr.e_shnum; i++, sh++) {
2936 switch(sh->sh_type) {
2937 case SHT_DYNAMIC:
2938 nb_dts = sh->sh_size / sizeof(ElfW(Dyn));
2939 dynamic = load_data(fd, sh->sh_offset, sh->sh_size);
2940 break;
2941 case SHT_DYNSYM:
2942 nb_syms = sh->sh_size / sizeof(ElfW(Sym));
2943 dynsym = load_data(fd, sh->sh_offset, sh->sh_size);
2944 sh1 = &shdr[sh->sh_link];
2945 dynstr = load_data(fd, sh1->sh_offset, sh1->sh_size);
2946 break;
2947 default:
2948 break;
2952 /* compute the real library name */
2953 soname = tcc_basename(filename);
2955 for(i = 0, dt = dynamic; i < nb_dts; i++, dt++) {
2956 if (dt->d_tag == DT_SONAME) {
2957 soname = (char *) dynstr + dt->d_un.d_val;
2961 /* if the dll is already loaded, do not load it */
2962 for(i = 0; i < s1->nb_loaded_dlls; i++) {
2963 dllref = s1->loaded_dlls[i];
2964 if (!strcmp(soname, dllref->name)) {
2965 /* but update level if needed */
2966 if (level < dllref->level)
2967 dllref->level = level;
2968 ret = 0;
2969 goto the_end;
2973 /* add the dll and its level */
2974 dllref = tcc_mallocz(sizeof(DLLReference) + strlen(soname));
2975 dllref->level = level;
2976 strcpy(dllref->name, soname);
2977 dynarray_add((void ***)&s1->loaded_dlls, &s1->nb_loaded_dlls, dllref);
2979 /* add dynamic symbols in dynsym_section */
2980 for(i = 1, sym = dynsym + 1; i < nb_syms; i++, sym++) {
2981 sym_bind = ELFW(ST_BIND)(sym->st_info);
2982 if (sym_bind == STB_LOCAL)
2983 continue;
2984 name = (char *) dynstr + sym->st_name;
2985 set_elf_sym(s1->dynsymtab_section, sym->st_value, sym->st_size,
2986 sym->st_info, sym->st_other, sym->st_shndx, name);
2989 /* load all referenced DLLs */
2990 for(i = 0, dt = dynamic; i < nb_dts; i++, dt++) {
2991 switch(dt->d_tag) {
2992 case DT_NEEDED:
2993 name = (char *) dynstr + dt->d_un.d_val;
2994 for(j = 0; j < s1->nb_loaded_dlls; j++) {
2995 dllref = s1->loaded_dlls[j];
2996 if (!strcmp(name, dllref->name))
2997 goto already_loaded;
2999 if (tcc_add_dll(s1, name, AFF_REFERENCED_DLL) < 0) {
3000 tcc_error_noabort("referenced dll '%s' not found", name);
3001 ret = -1;
3002 goto the_end;
3004 already_loaded:
3005 break;
3008 ret = 0;
3009 the_end:
3010 tcc_free(dynstr);
3011 tcc_free(dynsym);
3012 tcc_free(dynamic);
3013 tcc_free(shdr);
3014 return ret;
3017 #define LD_TOK_NAME 256
3018 #define LD_TOK_EOF (-1)
3020 /* return next ld script token */
3021 static int ld_next(TCCState *s1, char *name, int name_size)
3023 int c;
3024 char *q;
3026 redo:
3027 switch(ch) {
3028 case ' ':
3029 case '\t':
3030 case '\f':
3031 case '\v':
3032 case '\r':
3033 case '\n':
3034 inp();
3035 goto redo;
3036 case '/':
3037 minp();
3038 if (ch == '*') {
3039 file->buf_ptr = parse_comment(file->buf_ptr);
3040 ch = file->buf_ptr[0];
3041 goto redo;
3042 } else {
3043 q = name;
3044 *q++ = '/';
3045 goto parse_name;
3047 break;
3048 case '\\':
3049 ch = handle_eob();
3050 if (ch != '\\')
3051 goto redo;
3052 /* fall through */
3053 /* case 'a' ... 'z': */
3054 case 'a':
3055 case 'b':
3056 case 'c':
3057 case 'd':
3058 case 'e':
3059 case 'f':
3060 case 'g':
3061 case 'h':
3062 case 'i':
3063 case 'j':
3064 case 'k':
3065 case 'l':
3066 case 'm':
3067 case 'n':
3068 case 'o':
3069 case 'p':
3070 case 'q':
3071 case 'r':
3072 case 's':
3073 case 't':
3074 case 'u':
3075 case 'v':
3076 case 'w':
3077 case 'x':
3078 case 'y':
3079 case 'z':
3080 /* case 'A' ... 'z': */
3081 case 'A':
3082 case 'B':
3083 case 'C':
3084 case 'D':
3085 case 'E':
3086 case 'F':
3087 case 'G':
3088 case 'H':
3089 case 'I':
3090 case 'J':
3091 case 'K':
3092 case 'L':
3093 case 'M':
3094 case 'N':
3095 case 'O':
3096 case 'P':
3097 case 'Q':
3098 case 'R':
3099 case 'S':
3100 case 'T':
3101 case 'U':
3102 case 'V':
3103 case 'W':
3104 case 'X':
3105 case 'Y':
3106 case 'Z':
3107 case '_':
3108 case '.':
3109 case '$':
3110 case '~':
3111 q = name;
3112 parse_name:
3113 for(;;) {
3114 if (!((ch >= 'a' && ch <= 'z') ||
3115 (ch >= 'A' && ch <= 'Z') ||
3116 (ch >= '0' && ch <= '9') ||
3117 strchr("/.-_+=$:\\,~", ch)))
3118 break;
3119 if ((q - name) < name_size - 1) {
3120 *q++ = ch;
3122 minp();
3124 *q = '\0';
3125 c = LD_TOK_NAME;
3126 break;
3127 case CH_EOF:
3128 c = LD_TOK_EOF;
3129 break;
3130 default:
3131 c = ch;
3132 inp();
3133 break;
3135 return c;
3138 static int ld_add_file(TCCState *s1, const char filename[])
3140 int ret;
3142 ret = tcc_add_file_internal(s1, filename, AFF_TYPE_BIN);
3143 if (ret)
3144 ret = tcc_add_dll(s1, filename, 0);
3145 return ret;
3148 static inline int new_undef_syms(void)
3150 int ret = 0;
3151 ret = new_undef_sym;
3152 new_undef_sym = 0;
3153 return ret;
3156 static int ld_add_file_list(TCCState *s1, const char *cmd, int as_needed)
3158 char filename[1024], libname[1024];
3159 int t, group, nblibs = 0, ret = 0;
3160 char **libs = NULL;
3162 group = !strcmp(cmd, "GROUP");
3163 if (!as_needed)
3164 new_undef_syms();
3165 t = ld_next(s1, filename, sizeof(filename));
3166 if (t != '(')
3167 expect("(");
3168 t = ld_next(s1, filename, sizeof(filename));
3169 for(;;) {
3170 libname[0] = '\0';
3171 if (t == LD_TOK_EOF) {
3172 tcc_error_noabort("unexpected end of file");
3173 ret = -1;
3174 goto lib_parse_error;
3175 } else if (t == ')') {
3176 break;
3177 } else if (t == '-') {
3178 t = ld_next(s1, filename, sizeof(filename));
3179 if ((t != LD_TOK_NAME) || (filename[0] != 'l')) {
3180 tcc_error_noabort("library name expected");
3181 ret = -1;
3182 goto lib_parse_error;
3184 pstrcpy(libname, sizeof libname, &filename[1]);
3185 if (s1->static_link) {
3186 snprintf(filename, sizeof filename, "lib%s.a", libname);
3187 } else {
3188 snprintf(filename, sizeof filename, "lib%s.so", libname);
3190 } else if (t != LD_TOK_NAME) {
3191 tcc_error_noabort("filename expected");
3192 ret = -1;
3193 goto lib_parse_error;
3195 if (!strcmp(filename, "AS_NEEDED")) {
3196 ret = ld_add_file_list(s1, cmd, 1);
3197 if (ret)
3198 goto lib_parse_error;
3199 } else {
3200 /* TODO: Implement AS_NEEDED support. Ignore it for now */
3201 if (!as_needed) {
3202 ret = ld_add_file(s1, filename);
3203 if (ret)
3204 goto lib_parse_error;
3205 if (group) {
3206 /* Add the filename *and* the libname to avoid future conversions */
3207 dynarray_add((void ***) &libs, &nblibs, tcc_strdup(filename));
3208 if (libname[0] != '\0')
3209 dynarray_add((void ***) &libs, &nblibs, tcc_strdup(libname));
3213 t = ld_next(s1, filename, sizeof(filename));
3214 if (t == ',') {
3215 t = ld_next(s1, filename, sizeof(filename));
3218 if (group && !as_needed) {
3219 while (new_undef_syms()) {
3220 int i;
3222 for (i = 0; i < nblibs; i ++)
3223 ld_add_file(s1, libs[i]);
3226 lib_parse_error:
3227 dynarray_reset(&libs, &nblibs);
3228 return ret;
3231 /* interpret a subset of GNU ldscripts to handle the dummy libc.so
3232 files */
3233 ST_FUNC int tcc_load_ldscript(TCCState *s1)
3235 char cmd[64];
3236 char filename[1024];
3237 int t, ret;
3239 ch = handle_eob();
3240 for(;;) {
3241 t = ld_next(s1, cmd, sizeof(cmd));
3242 if (t == LD_TOK_EOF)
3243 return 0;
3244 else if (t != LD_TOK_NAME)
3245 return -1;
3246 if (!strcmp(cmd, "INPUT") ||
3247 !strcmp(cmd, "GROUP")) {
3248 ret = ld_add_file_list(s1, cmd, 0);
3249 if (ret)
3250 return ret;
3251 } else if (!strcmp(cmd, "OUTPUT_FORMAT") ||
3252 !strcmp(cmd, "TARGET")) {
3253 /* ignore some commands */
3254 t = ld_next(s1, cmd, sizeof(cmd));
3255 if (t != '(')
3256 expect("(");
3257 for(;;) {
3258 t = ld_next(s1, filename, sizeof(filename));
3259 if (t == LD_TOK_EOF) {
3260 tcc_error_noabort("unexpected end of file");
3261 return -1;
3262 } else if (t == ')') {
3263 break;
3266 } else {
3267 return -1;
3270 return 0;
3272 #endif /* !TCC_TARGET_PE */