asm 32/64: replace (long)sym->next by sym->jnext
[tinycc/kirr.git] / tccelf.c
blob3b881b00d1e91d8c6a579c84c965a24cc15ef9e8
1 /*
2 * ELF file handling for TCC
3 *
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 #ifdef TCC_TARGET_X86_64
22 #define ElfW_Rel ElfW(Rela)
23 #define SHT_RELX SHT_RELA
24 #define REL_SECTION_FMT ".rela%s"
25 /* x86-64 requires PLT for DLLs */
26 #define TCC_OUTPUT_DLL_WITH_PLT
27 #else
28 #define ElfW_Rel ElfW(Rel)
29 #define SHT_RELX SHT_REL
30 #define REL_SECTION_FMT ".rel%s"
31 #endif
33 /* XXX: DLL with PLT would only work with x86-64 for now */
34 //#define TCC_OUTPUT_DLL_WITH_PLT
36 static int put_elf_str(Section *s, const char *sym)
38 int offset, len;
39 char *ptr;
41 len = strlen(sym) + 1;
42 offset = s->data_offset;
43 ptr = section_ptr_add(s, len);
44 memcpy(ptr, sym, len);
45 return offset;
48 /* elf symbol hashing function */
49 static unsigned long elf_hash(const unsigned char *name)
51 unsigned long h = 0, g;
53 while (*name) {
54 h = (h << 4) + *name++;
55 g = h & 0xf0000000;
56 if (g)
57 h ^= g >> 24;
58 h &= ~g;
60 return h;
63 /* rebuild hash table of section s */
64 /* NOTE: we do factorize the hash table code to go faster */
65 static void rebuild_hash(Section *s, unsigned int nb_buckets)
67 ElfW(Sym) *sym;
68 int *ptr, *hash, nb_syms, sym_index, h;
69 char *strtab;
71 strtab = s->link->data;
72 nb_syms = s->data_offset / sizeof(ElfW(Sym));
74 s->hash->data_offset = 0;
75 ptr = section_ptr_add(s->hash, (2 + nb_buckets + nb_syms) * sizeof(int));
76 ptr[0] = nb_buckets;
77 ptr[1] = nb_syms;
78 ptr += 2;
79 hash = ptr;
80 memset(hash, 0, (nb_buckets + 1) * sizeof(int));
81 ptr += nb_buckets + 1;
83 sym = (ElfW(Sym) *)s->data + 1;
84 for(sym_index = 1; sym_index < nb_syms; sym_index++) {
85 if (ELFW(ST_BIND)(sym->st_info) != STB_LOCAL) {
86 h = elf_hash(strtab + sym->st_name) % nb_buckets;
87 *ptr = hash[h];
88 hash[h] = sym_index;
89 } else {
90 *ptr = 0;
92 ptr++;
93 sym++;
97 /* return the symbol number */
98 static int put_elf_sym(Section *s,
99 unsigned long value, unsigned long size,
100 int info, int other, int shndx, const char *name)
102 int name_offset, sym_index;
103 int nbuckets, h;
104 ElfW(Sym) *sym;
105 Section *hs;
107 sym = section_ptr_add(s, sizeof(ElfW(Sym)));
108 if (name)
109 name_offset = put_elf_str(s->link, name);
110 else
111 name_offset = 0;
112 /* XXX: endianness */
113 sym->st_name = name_offset;
114 sym->st_value = value;
115 sym->st_size = size;
116 sym->st_info = info;
117 sym->st_other = other;
118 sym->st_shndx = shndx;
119 sym_index = sym - (ElfW(Sym) *)s->data;
120 hs = s->hash;
121 if (hs) {
122 int *ptr, *base;
123 ptr = section_ptr_add(hs, sizeof(int));
124 base = (int *)hs->data;
125 /* only add global or weak symbols */
126 if (ELFW(ST_BIND)(info) != STB_LOCAL) {
127 /* add another hashing entry */
128 nbuckets = base[0];
129 h = elf_hash(name) % nbuckets;
130 *ptr = base[2 + h];
131 base[2 + h] = sym_index;
132 base[1]++;
133 /* we resize the hash table */
134 hs->nb_hashed_syms++;
135 if (hs->nb_hashed_syms > 2 * nbuckets) {
136 rebuild_hash(s, 2 * nbuckets);
138 } else {
139 *ptr = 0;
140 base[1]++;
143 return sym_index;
146 /* find global ELF symbol 'name' and return its index. Return 0 if not
147 found. */
148 static int find_elf_sym(Section *s, const char *name)
150 ElfW(Sym) *sym;
151 Section *hs;
152 int nbuckets, sym_index, h;
153 const char *name1;
155 hs = s->hash;
156 if (!hs)
157 return 0;
158 nbuckets = ((int *)hs->data)[0];
159 h = elf_hash(name) % nbuckets;
160 sym_index = ((int *)hs->data)[2 + h];
161 while (sym_index != 0) {
162 sym = &((ElfW(Sym) *)s->data)[sym_index];
163 name1 = s->link->data + sym->st_name;
164 if (!strcmp(name, name1))
165 return sym_index;
166 sym_index = ((int *)hs->data)[2 + nbuckets + sym_index];
168 return 0;
171 /* return elf symbol value, signal error if 'err' is nonzero */
172 static void *get_elf_sym_addr(TCCState *s, const char *name, int err)
174 int sym_index;
175 ElfW(Sym) *sym;
177 sym_index = find_elf_sym(symtab_section, name);
178 sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
179 if (!sym_index || sym->st_shndx == SHN_UNDEF) {
180 if (err)
181 error("%s not defined", name);
182 return NULL;
184 return (void*)(uplong)sym->st_value;
187 /* return elf symbol value */
188 void *tcc_get_symbol(TCCState *s, const char *name)
190 return get_elf_sym_addr(s, name, 0);
193 /* return elf symbol value or error */
194 void *tcc_get_symbol_err(TCCState *s, const char *name)
196 return get_elf_sym_addr(s, name, 1);
199 /* add an elf symbol : check if it is already defined and patch
200 it. Return symbol index. NOTE that sh_num can be SHN_UNDEF. */
201 static int add_elf_sym(Section *s, uplong value, unsigned long size,
202 int info, int other, int sh_num, const char *name)
204 ElfW(Sym) *esym;
205 int sym_bind, sym_index, sym_type, esym_bind;
206 unsigned char sym_vis, esym_vis, new_vis;
208 sym_bind = ELFW(ST_BIND)(info);
209 sym_type = ELFW(ST_TYPE)(info);
210 sym_vis = ELFW(ST_VISIBILITY)(other);
212 if (sym_bind != STB_LOCAL) {
213 /* we search global or weak symbols */
214 sym_index = find_elf_sym(s, name);
215 if (!sym_index)
216 goto do_def;
217 esym = &((ElfW(Sym) *)s->data)[sym_index];
218 if (esym->st_shndx != SHN_UNDEF) {
219 esym_bind = ELFW(ST_BIND)(esym->st_info);
220 /* propagate the most constraining visibility */
221 /* STV_DEFAULT(0)<STV_PROTECTED(3)<STV_HIDDEN(2)<STV_INTERNAL(1) */
222 esym_vis = ELFW(ST_VISIBILITY)(esym->st_other);
223 if (esym_vis == STV_DEFAULT) {
224 new_vis = sym_vis;
225 } else if (sym_vis == STV_DEFAULT) {
226 new_vis = esym_vis;
227 } else {
228 new_vis = (esym_vis < sym_vis) ? esym_vis : sym_vis;
230 esym->st_other = (esym->st_other & ~ELFW(ST_VISIBILITY)(-1))
231 | new_vis;
232 other = esym->st_other; /* in case we have to patch esym */
233 if (sh_num == SHN_UNDEF) {
234 /* ignore adding of undefined symbol if the
235 corresponding symbol is already defined */
236 } else if (sym_bind == STB_GLOBAL && esym_bind == STB_WEAK) {
237 /* global overrides weak, so patch */
238 goto do_patch;
239 } else if (sym_bind == STB_WEAK && esym_bind == STB_GLOBAL) {
240 /* weak is ignored if already global */
241 } else if (sym_vis == STV_HIDDEN || sym_vis == STV_INTERNAL) {
242 /* ignore hidden symbols after */
243 } else if (esym->st_shndx == SHN_COMMON
244 && (sh_num < SHN_LORESERVE || sh_num == SHN_COMMON)) {
245 /* gr: Happens with 'tcc ... -static tcctest.c' on e.g. Ubuntu 6.01
246 No idea if this is the correct solution ... */
247 goto do_patch;
248 } else if (s == tcc_state->dynsymtab_section) {
249 /* we accept that two DLL define the same symbol */
250 } else {
251 #if 1
252 printf("new_bind=%x new_shndx=%x new_vis=%x old_bind=%x old_shndx=%x old_vis=%x\n",
253 sym_bind, sh_num, new_vis, esym_bind, esym->st_shndx, esym_vis);
254 #endif
255 error_noabort("'%s' defined twice", name);
257 } else {
258 do_patch:
259 esym->st_info = ELFW(ST_INFO)(sym_bind, sym_type);
260 esym->st_shndx = sh_num;
261 esym->st_value = value;
262 esym->st_size = size;
263 esym->st_other = other;
265 } else {
266 do_def:
267 sym_index = put_elf_sym(s, value, size,
268 ELFW(ST_INFO)(sym_bind, sym_type), other,
269 sh_num, name);
271 return sym_index;
274 /* put relocation */
275 static void put_elf_reloc(Section *symtab, Section *s, unsigned long offset,
276 int type, int symbol)
278 char buf[256];
279 Section *sr;
280 ElfW_Rel *rel;
282 sr = s->reloc;
283 if (!sr) {
284 /* if no relocation section, create it */
285 snprintf(buf, sizeof(buf), REL_SECTION_FMT, s->name);
286 /* if the symtab is allocated, then we consider the relocation
287 are also */
288 sr = new_section(tcc_state, buf, SHT_RELX, symtab->sh_flags);
289 sr->sh_entsize = sizeof(ElfW_Rel);
290 sr->link = symtab;
291 sr->sh_info = s->sh_num;
292 s->reloc = sr;
294 rel = section_ptr_add(sr, sizeof(ElfW_Rel));
295 rel->r_offset = offset;
296 rel->r_info = ELFW(R_INFO)(symbol, type);
297 #ifdef TCC_TARGET_X86_64
298 rel->r_addend = 0;
299 #endif
302 /* put stab debug information */
304 typedef struct {
305 unsigned int n_strx; /* index into string table of name */
306 unsigned char n_type; /* type of symbol */
307 unsigned char n_other; /* misc info (usually empty) */
308 unsigned short n_desc; /* description field */
309 unsigned int n_value; /* value of symbol */
310 } Stab_Sym;
312 static void put_stabs(const char *str, int type, int other, int desc,
313 unsigned long value)
315 Stab_Sym *sym;
317 sym = section_ptr_add(stab_section, sizeof(Stab_Sym));
318 if (str) {
319 sym->n_strx = put_elf_str(stabstr_section, str);
320 } else {
321 sym->n_strx = 0;
323 sym->n_type = type;
324 sym->n_other = other;
325 sym->n_desc = desc;
326 sym->n_value = value;
329 static void put_stabs_r(const char *str, int type, int other, int desc,
330 unsigned long value, Section *sec, int sym_index)
332 put_stabs(str, type, other, desc, value);
333 put_elf_reloc(symtab_section, stab_section,
334 stab_section->data_offset - sizeof(unsigned int),
335 R_DATA_32, sym_index);
338 static void put_stabn(int type, int other, int desc, int value)
340 put_stabs(NULL, type, other, desc, value);
343 static void put_stabd(int type, int other, int desc)
345 put_stabs(NULL, type, other, desc, 0);
348 /* In an ELF file symbol table, the local symbols must appear below
349 the global and weak ones. Since TCC cannot sort it while generating
350 the code, we must do it after. All the relocation tables are also
351 modified to take into account the symbol table sorting */
352 static void sort_syms(TCCState *s1, Section *s)
354 int *old_to_new_syms;
355 ElfW(Sym) *new_syms;
356 int nb_syms, i;
357 ElfW(Sym) *p, *q;
358 ElfW_Rel *rel, *rel_end;
359 Section *sr;
360 int type, sym_index;
362 nb_syms = s->data_offset / sizeof(ElfW(Sym));
363 new_syms = tcc_malloc(nb_syms * sizeof(ElfW(Sym)));
364 old_to_new_syms = tcc_malloc(nb_syms * sizeof(int));
366 /* first pass for local symbols */
367 p = (ElfW(Sym) *)s->data;
368 q = new_syms;
369 for(i = 0; i < nb_syms; i++) {
370 if (ELFW(ST_BIND)(p->st_info) == STB_LOCAL) {
371 old_to_new_syms[i] = q - new_syms;
372 *q++ = *p;
374 p++;
376 /* save the number of local symbols in section header */
377 s->sh_info = q - new_syms;
379 /* then second pass for non local symbols */
380 p = (ElfW(Sym) *)s->data;
381 for(i = 0; i < nb_syms; i++) {
382 if (ELFW(ST_BIND)(p->st_info) != STB_LOCAL) {
383 old_to_new_syms[i] = q - new_syms;
384 *q++ = *p;
386 p++;
389 /* we copy the new symbols to the old */
390 memcpy(s->data, new_syms, nb_syms * sizeof(ElfW(Sym)));
391 tcc_free(new_syms);
393 /* now we modify all the relocations */
394 for(i = 1; i < s1->nb_sections; i++) {
395 sr = s1->sections[i];
396 if (sr->sh_type == SHT_RELX && sr->link == s) {
397 rel_end = (ElfW_Rel *)(sr->data + sr->data_offset);
398 for(rel = (ElfW_Rel *)sr->data;
399 rel < rel_end;
400 rel++) {
401 sym_index = ELFW(R_SYM)(rel->r_info);
402 type = ELFW(R_TYPE)(rel->r_info);
403 sym_index = old_to_new_syms[sym_index];
404 rel->r_info = ELFW(R_INFO)(sym_index, type);
409 tcc_free(old_to_new_syms);
412 /* relocate common symbols in the .bss section */
413 static void relocate_common_syms(void)
415 ElfW(Sym) *sym, *sym_end;
416 unsigned long offset, align;
418 sym_end = (ElfW(Sym) *)(symtab_section->data + symtab_section->data_offset);
419 for(sym = (ElfW(Sym) *)symtab_section->data + 1;
420 sym < sym_end;
421 sym++) {
422 if (sym->st_shndx == SHN_COMMON) {
423 /* align symbol */
424 align = sym->st_value;
425 offset = bss_section->data_offset;
426 offset = (offset + align - 1) & -align;
427 sym->st_value = offset;
428 sym->st_shndx = bss_section->sh_num;
429 offset += sym->st_size;
430 bss_section->data_offset = offset;
435 /* relocate symbol table, resolve undefined symbols if do_resolve is
436 true and output error if undefined symbol. */
437 static void relocate_syms(TCCState *s1, int do_resolve)
439 ElfW(Sym) *sym, *esym, *sym_end;
440 int sym_bind, sh_num, sym_index;
441 const char *name;
443 sym_end = (ElfW(Sym) *)(symtab_section->data + symtab_section->data_offset);
444 for(sym = (ElfW(Sym) *)symtab_section->data + 1;
445 sym < sym_end;
446 sym++) {
447 sh_num = sym->st_shndx;
448 if (sh_num == SHN_UNDEF) {
449 name = strtab_section->data + sym->st_name;
450 if (do_resolve) {
451 #ifndef _WIN32
452 void *addr;
453 name = symtab_section->link->data + sym->st_name;
454 addr = resolve_sym(s1, name);
455 if (addr) {
456 sym->st_value = (uplong)addr;
457 goto found;
459 #endif
460 } else if (s1->dynsym) {
461 /* if dynamic symbol exist, then use it */
462 sym_index = find_elf_sym(s1->dynsym, name);
463 if (sym_index) {
464 esym = &((ElfW(Sym) *)s1->dynsym->data)[sym_index];
465 sym->st_value = esym->st_value;
466 goto found;
469 /* XXX: _fp_hw seems to be part of the ABI, so we ignore
470 it */
471 if (!strcmp(name, "_fp_hw"))
472 goto found;
473 /* only weak symbols are accepted to be undefined. Their
474 value is zero */
475 sym_bind = ELFW(ST_BIND)(sym->st_info);
476 if (sym_bind == STB_WEAK) {
477 sym->st_value = 0;
478 } else {
479 error_noabort("undefined symbol '%s'", name);
481 } else if (sh_num < SHN_LORESERVE) {
482 /* add section base */
483 sym->st_value += s1->sections[sym->st_shndx]->sh_addr;
485 found: ;
489 #ifndef TCC_TARGET_PE
490 #ifdef TCC_TARGET_X86_64
491 #define JMP_TABLE_ENTRY_SIZE 14
492 static unsigned long add_jmp_table(TCCState *s1, unsigned long val)
494 char *p = s1->runtime_plt_and_got + s1->runtime_plt_and_got_offset;
495 s1->runtime_plt_and_got_offset += JMP_TABLE_ENTRY_SIZE;
496 /* jmp *0x0(%rip) */
497 p[0] = 0xff;
498 p[1] = 0x25;
499 *(int *)(p + 2) = 0;
500 *(unsigned long *)(p + 6) = val;
501 return (unsigned long)p;
504 static unsigned long add_got_table(TCCState *s1, unsigned long val)
506 unsigned long *p =(unsigned long *)(s1->runtime_plt_and_got +
507 s1->runtime_plt_and_got_offset);
508 s1->runtime_plt_and_got_offset += sizeof(void *);
509 *p = val;
510 return (unsigned long)p;
512 #endif
513 #endif
515 /* relocate a given section (CPU dependent) */
516 static void relocate_section(TCCState *s1, Section *s)
518 Section *sr;
519 ElfW_Rel *rel, *rel_end, *qrel;
520 ElfW(Sym) *sym;
521 int type, sym_index;
522 unsigned char *ptr;
523 unsigned long val, addr;
524 #if defined TCC_TARGET_I386 || defined TCC_TARGET_X86_64
525 int esym_index;
526 #endif
528 sr = s->reloc;
529 rel_end = (ElfW_Rel *)(sr->data + sr->data_offset);
530 qrel = (ElfW_Rel *)sr->data;
531 for(rel = qrel;
532 rel < rel_end;
533 rel++) {
534 ptr = s->data + rel->r_offset;
536 sym_index = ELFW(R_SYM)(rel->r_info);
537 sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
538 val = sym->st_value;
539 #ifdef TCC_TARGET_X86_64
540 /* XXX: not tested */
541 val += rel->r_addend;
542 #endif
543 type = ELFW(R_TYPE)(rel->r_info);
544 addr = s->sh_addr + rel->r_offset;
546 /* CPU specific */
547 switch(type) {
548 #if defined(TCC_TARGET_I386)
549 case R_386_32:
550 if (s1->output_type == TCC_OUTPUT_DLL) {
551 esym_index = s1->symtab_to_dynsym[sym_index];
552 qrel->r_offset = rel->r_offset;
553 if (esym_index) {
554 qrel->r_info = ELFW(R_INFO)(esym_index, R_386_32);
555 qrel++;
556 break;
557 } else {
558 qrel->r_info = ELFW(R_INFO)(0, R_386_RELATIVE);
559 qrel++;
562 *(int *)ptr += val;
563 break;
564 case R_386_PC32:
565 if (s1->output_type == TCC_OUTPUT_DLL) {
566 /* DLL relocation */
567 esym_index = s1->symtab_to_dynsym[sym_index];
568 if (esym_index) {
569 qrel->r_offset = rel->r_offset;
570 qrel->r_info = ELFW(R_INFO)(esym_index, R_386_PC32);
571 qrel++;
572 break;
575 *(int *)ptr += val - addr;
576 break;
577 case R_386_PLT32:
578 *(int *)ptr += val - addr;
579 break;
580 case R_386_GLOB_DAT:
581 case R_386_JMP_SLOT:
582 *(int *)ptr = val;
583 break;
584 case R_386_GOTPC:
585 *(int *)ptr += s1->got->sh_addr - addr;
586 break;
587 case R_386_GOTOFF:
588 *(int *)ptr += val - s1->got->sh_addr;
589 break;
590 case R_386_GOT32:
591 /* we load the got offset */
592 *(int *)ptr += s1->got_offsets[sym_index];
593 break;
594 case R_386_16:
595 if (s1->output_format != TCC_OUTPUT_FORMAT_BINARY) {
596 output_file:
597 error("can only produce 16-bit binary files");
599 *(short *)ptr += val;
600 break;
601 case R_386_PC16:
602 if (s1->output_format != TCC_OUTPUT_FORMAT_BINARY)
603 goto output_file;
604 *(short *)ptr += val - addr;
605 break;
606 #elif defined(TCC_TARGET_ARM)
607 case R_ARM_PC24:
608 case R_ARM_CALL:
609 case R_ARM_JUMP24:
610 case R_ARM_PLT32:
612 int x;
613 x = (*(int *)ptr)&0xffffff;
614 (*(int *)ptr) &= 0xff000000;
615 if (x & 0x800000)
616 x -= 0x1000000;
617 x *= 4;
618 x += val - addr;
619 if((x & 3) != 0 || x >= 0x4000000 || x < -0x4000000)
620 error("can't relocate value at %x",addr);
621 x >>= 2;
622 x &= 0xffffff;
623 (*(int *)ptr) |= x;
625 break;
626 case R_ARM_PREL31:
628 int x;
629 x = (*(int *)ptr) & 0x7fffffff;
630 (*(int *)ptr) &= 0x80000000;
631 x = (x * 2) / 2;
632 x += val - addr;
633 if((x^(x>>1))&0x40000000)
634 error("can't relocate value at %x",addr);
635 (*(int *)ptr) |= x & 0x7fffffff;
637 case R_ARM_ABS32:
638 *(int *)ptr += val;
639 break;
640 case R_ARM_BASE_PREL:
641 *(int *)ptr += s1->got->sh_addr - addr;
642 break;
643 case R_ARM_GOTOFF32:
644 *(int *)ptr += val - s1->got->sh_addr;
645 break;
646 case R_ARM_GOT_BREL:
647 /* we load the got offset */
648 *(int *)ptr += s1->got_offsets[sym_index];
649 break;
650 case R_ARM_COPY:
651 break;
652 default:
653 fprintf(stderr,"FIXME: handle reloc type %x at %lx [%.8x] to %lx\n",
654 type,addr,(unsigned int)(long)ptr,val);
655 break;
656 #elif defined(TCC_TARGET_C67)
657 case R_C60_32:
658 *(int *)ptr += val;
659 break;
660 case R_C60LO16:
662 uint32_t orig;
664 /* put the low 16 bits of the absolute address */
665 // add to what is already there
667 orig = ((*(int *)(ptr )) >> 7) & 0xffff;
668 orig |= (((*(int *)(ptr+4)) >> 7) & 0xffff) << 16;
670 //patch both at once - assumes always in pairs Low - High
672 *(int *) ptr = (*(int *) ptr & (~(0xffff << 7)) ) | (((val+orig) & 0xffff) << 7);
673 *(int *)(ptr+4) = (*(int *)(ptr+4) & (~(0xffff << 7)) ) | ((((val+orig)>>16) & 0xffff) << 7);
675 break;
676 case R_C60HI16:
677 break;
678 default:
679 fprintf(stderr,"FIXME: handle reloc type %x at %lx [%.8x] to %lx\n",
680 type,addr,(unsigned int)(long)ptr, val);
681 break;
682 #elif defined(TCC_TARGET_X86_64)
683 case R_X86_64_64:
684 if (s1->output_type == TCC_OUTPUT_DLL) {
685 qrel->r_info = ELFW(R_INFO)(0, R_X86_64_RELATIVE);
686 qrel->r_addend = *(long long *)ptr + val;
687 qrel++;
689 *(long long *)ptr += val;
690 break;
691 case R_X86_64_32:
692 case R_X86_64_32S:
693 if (s1->output_type == TCC_OUTPUT_DLL) {
694 /* XXX: this logic may depend on TCC's codegen
695 now TCC uses R_X86_64_32 even for a 64bit pointer */
696 qrel->r_info = ELFW(R_INFO)(0, R_X86_64_RELATIVE);
697 qrel->r_addend = *(int *)ptr + val;
698 qrel++;
700 *(int *)ptr += val;
701 break;
702 case R_X86_64_PC32: {
703 long long diff;
704 if (s1->output_type == TCC_OUTPUT_DLL) {
705 /* DLL relocation */
706 esym_index = s1->symtab_to_dynsym[sym_index];
707 if (esym_index) {
708 qrel->r_offset = rel->r_offset;
709 qrel->r_info = ELFW(R_INFO)(esym_index, R_X86_64_PC32);
710 qrel->r_addend = *(int *)ptr;
711 qrel++;
712 break;
715 diff = (long long)val - addr;
716 if (diff <= -2147483647 || diff > 2147483647) {
717 #ifndef TCC_TARGET_PE
718 /* XXX: naive support for over 32bit jump */
719 if (s1->output_type == TCC_OUTPUT_MEMORY) {
720 val = add_jmp_table(s1, val);
721 diff = val - addr;
723 #endif
724 if (diff <= -2147483647 || diff > 2147483647) {
725 error("internal error: relocation failed");
728 *(int *)ptr += diff;
730 break;
731 case R_X86_64_PLT32:
732 *(int *)ptr += val - addr;
733 break;
734 case R_X86_64_GLOB_DAT:
735 case R_X86_64_JUMP_SLOT:
736 *(int *)ptr = val;
737 break;
738 case R_X86_64_GOTPCREL:
739 #ifndef TCC_TARGET_PE
740 if (s1->output_type == TCC_OUTPUT_MEMORY) {
741 val = add_got_table(s1, val - rel->r_addend) + rel->r_addend;
742 *(int *)ptr += val - addr;
743 break;
745 #endif
746 *(int *)ptr += (s1->got->sh_addr - addr +
747 s1->got_offsets[sym_index] - 4);
748 break;
749 case R_X86_64_GOTTPOFF:
750 *(int *)ptr += val - s1->got->sh_addr;
751 break;
752 case R_X86_64_GOT32:
753 /* we load the got offset */
754 *(int *)ptr += s1->got_offsets[sym_index];
755 break;
756 #else
757 #error unsupported processor
758 #endif
761 /* if the relocation is allocated, we change its symbol table */
762 if (sr->sh_flags & SHF_ALLOC)
763 sr->link = s1->dynsym;
766 /* relocate relocation table in 'sr' */
767 static void relocate_rel(TCCState *s1, Section *sr)
769 Section *s;
770 ElfW_Rel *rel, *rel_end;
772 s = s1->sections[sr->sh_info];
773 rel_end = (ElfW_Rel *)(sr->data + sr->data_offset);
774 for(rel = (ElfW_Rel *)sr->data;
775 rel < rel_end;
776 rel++) {
777 rel->r_offset += s->sh_addr;
781 /* count the number of dynamic relocations so that we can reserve
782 their space */
783 static int prepare_dynamic_rel(TCCState *s1, Section *sr)
785 ElfW_Rel *rel, *rel_end;
786 int sym_index, esym_index, type, count;
788 count = 0;
789 rel_end = (ElfW_Rel *)(sr->data + sr->data_offset);
790 for(rel = (ElfW_Rel *)sr->data; rel < rel_end; rel++) {
791 sym_index = ELFW(R_SYM)(rel->r_info);
792 type = ELFW(R_TYPE)(rel->r_info);
793 switch(type) {
794 #if defined(TCC_TARGET_I386)
795 case R_386_32:
796 #elif defined(TCC_TARGET_X86_64)
797 case R_X86_64_32:
798 case R_X86_64_32S:
799 case R_X86_64_64:
800 #endif
801 count++;
802 break;
803 #if defined(TCC_TARGET_I386)
804 case R_386_PC32:
805 #elif defined(TCC_TARGET_X86_64)
806 case R_X86_64_PC32:
807 #endif
808 esym_index = s1->symtab_to_dynsym[sym_index];
809 if (esym_index)
810 count++;
811 break;
812 default:
813 break;
816 if (count) {
817 /* allocate the section */
818 sr->sh_flags |= SHF_ALLOC;
819 sr->sh_size = count * sizeof(ElfW_Rel);
821 return count;
824 static void put_got_offset(TCCState *s1, int index, unsigned long val)
826 int n;
827 unsigned long *tab;
829 if (index >= s1->nb_got_offsets) {
830 /* find immediately bigger power of 2 and reallocate array */
831 n = 1;
832 while (index >= n)
833 n *= 2;
834 tab = tcc_realloc(s1->got_offsets, n * sizeof(unsigned long));
835 if (!tab)
836 error("memory full");
837 s1->got_offsets = tab;
838 memset(s1->got_offsets + s1->nb_got_offsets, 0,
839 (n - s1->nb_got_offsets) * sizeof(unsigned long));
840 s1->nb_got_offsets = n;
842 s1->got_offsets[index] = val;
845 /* XXX: suppress that */
846 static void put32(unsigned char *p, uint32_t val)
848 p[0] = val;
849 p[1] = val >> 8;
850 p[2] = val >> 16;
851 p[3] = val >> 24;
854 #if defined(TCC_TARGET_I386) || defined(TCC_TARGET_ARM) || \
855 defined(TCC_TARGET_X86_64)
856 static uint32_t get32(unsigned char *p)
858 return p[0] | (p[1] << 8) | (p[2] << 16) | (p[3] << 24);
860 #endif
862 static void build_got(TCCState *s1)
864 unsigned char *ptr;
866 /* if no got, then create it */
867 s1->got = new_section(s1, ".got", SHT_PROGBITS, SHF_ALLOC | SHF_WRITE);
868 s1->got->sh_entsize = 4;
869 add_elf_sym(symtab_section, 0, 4, ELFW(ST_INFO)(STB_GLOBAL, STT_OBJECT),
870 0, s1->got->sh_num, "_GLOBAL_OFFSET_TABLE_");
871 ptr = section_ptr_add(s1->got, 3 * PTR_SIZE);
872 #if PTR_SIZE == 4
873 /* keep space for _DYNAMIC pointer, if present */
874 put32(ptr, 0);
875 /* two dummy got entries */
876 put32(ptr + 4, 0);
877 put32(ptr + 8, 0);
878 #else
879 /* keep space for _DYNAMIC pointer, if present */
880 put32(ptr, 0);
881 put32(ptr + 4, 0);
882 /* two dummy got entries */
883 put32(ptr + 8, 0);
884 put32(ptr + 12, 0);
885 put32(ptr + 16, 0);
886 put32(ptr + 20, 0);
887 #endif
890 /* put a got entry corresponding to a symbol in symtab_section. 'size'
891 and 'info' can be modifed if more precise info comes from the DLL */
892 static void put_got_entry(TCCState *s1,
893 int reloc_type, unsigned long size, int info,
894 int sym_index)
896 int index;
897 const char *name;
898 ElfW(Sym) *sym;
899 unsigned long offset;
900 int *ptr;
902 if (!s1->got)
903 build_got(s1);
905 /* if a got entry already exists for that symbol, no need to add one */
906 if (sym_index < s1->nb_got_offsets &&
907 s1->got_offsets[sym_index] != 0)
908 return;
910 put_got_offset(s1, sym_index, s1->got->data_offset);
912 if (s1->dynsym) {
913 sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
914 name = symtab_section->link->data + sym->st_name;
915 offset = sym->st_value;
916 #if defined(TCC_TARGET_I386) || defined(TCC_TARGET_X86_64)
917 if (reloc_type ==
918 #ifdef TCC_TARGET_X86_64
919 R_X86_64_JUMP_SLOT
920 #else
921 R_386_JMP_SLOT
922 #endif
924 Section *plt;
925 uint8_t *p;
926 int modrm;
928 #if defined(TCC_OUTPUT_DLL_WITH_PLT)
929 modrm = 0x25;
930 #else
931 /* if we build a DLL, we add a %ebx offset */
932 if (s1->output_type == TCC_OUTPUT_DLL)
933 modrm = 0xa3;
934 else
935 modrm = 0x25;
936 #endif
938 /* add a PLT entry */
939 plt = s1->plt;
940 if (plt->data_offset == 0) {
941 /* first plt entry */
942 p = section_ptr_add(plt, 16);
943 p[0] = 0xff; /* pushl got + PTR_SIZE */
944 p[1] = modrm + 0x10;
945 put32(p + 2, PTR_SIZE);
946 p[6] = 0xff; /* jmp *(got + PTR_SIZE * 2) */
947 p[7] = modrm;
948 put32(p + 8, PTR_SIZE * 2);
951 p = section_ptr_add(plt, 16);
952 p[0] = 0xff; /* jmp *(got + x) */
953 p[1] = modrm;
954 put32(p + 2, s1->got->data_offset);
955 p[6] = 0x68; /* push $xxx */
956 put32(p + 7, (plt->data_offset - 32) >> 1);
957 p[11] = 0xe9; /* jmp plt_start */
958 put32(p + 12, -(plt->data_offset));
960 /* the symbol is modified so that it will be relocated to
961 the PLT */
962 #if !defined(TCC_OUTPUT_DLL_WITH_PLT)
963 if (s1->output_type == TCC_OUTPUT_EXE)
964 #endif
965 offset = plt->data_offset - 16;
967 #elif defined(TCC_TARGET_ARM)
968 if (reloc_type == R_ARM_JUMP_SLOT) {
969 Section *plt;
970 uint8_t *p;
972 /* if we build a DLL, we add a %ebx offset */
973 if (s1->output_type == TCC_OUTPUT_DLL)
974 error("DLLs unimplemented!");
976 /* add a PLT entry */
977 plt = s1->plt;
978 if (plt->data_offset == 0) {
979 /* first plt entry */
980 p = section_ptr_add(plt, 16);
981 put32(p , 0xe52de004);
982 put32(p + 4, 0xe59fe010);
983 put32(p + 8, 0xe08fe00e);
984 put32(p + 12, 0xe5bef008);
987 p = section_ptr_add(plt, 16);
988 put32(p , 0xe59fc004);
989 put32(p+4, 0xe08fc00c);
990 put32(p+8, 0xe59cf000);
991 put32(p+12, s1->got->data_offset);
993 /* the symbol is modified so that it will be relocated to
994 the PLT */
995 if (s1->output_type == TCC_OUTPUT_EXE)
996 offset = plt->data_offset - 16;
998 #elif defined(TCC_TARGET_C67)
999 error("C67 got not implemented");
1000 #else
1001 #error unsupported CPU
1002 #endif
1003 index = put_elf_sym(s1->dynsym, offset,
1004 size, info, 0, sym->st_shndx, name);
1005 /* put a got entry */
1006 put_elf_reloc(s1->dynsym, s1->got,
1007 s1->got->data_offset,
1008 reloc_type, index);
1010 ptr = section_ptr_add(s1->got, PTR_SIZE);
1011 *ptr = 0;
1014 /* build GOT and PLT entries */
1015 static void build_got_entries(TCCState *s1)
1017 Section *s, *symtab;
1018 ElfW_Rel *rel, *rel_end;
1019 ElfW(Sym) *sym;
1020 int i, type, reloc_type, sym_index;
1022 for(i = 1; i < s1->nb_sections; i++) {
1023 s = s1->sections[i];
1024 if (s->sh_type != SHT_RELX)
1025 continue;
1026 /* no need to handle got relocations */
1027 if (s->link != symtab_section)
1028 continue;
1029 symtab = s->link;
1030 rel_end = (ElfW_Rel *)(s->data + s->data_offset);
1031 for(rel = (ElfW_Rel *)s->data;
1032 rel < rel_end;
1033 rel++) {
1034 type = ELFW(R_TYPE)(rel->r_info);
1035 switch(type) {
1036 #if defined(TCC_TARGET_I386)
1037 case R_386_GOT32:
1038 case R_386_GOTOFF:
1039 case R_386_GOTPC:
1040 case R_386_PLT32:
1041 if (!s1->got)
1042 build_got(s1);
1043 if (type == R_386_GOT32 || type == R_386_PLT32) {
1044 sym_index = ELFW(R_SYM)(rel->r_info);
1045 sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
1046 /* look at the symbol got offset. If none, then add one */
1047 if (type == R_386_GOT32)
1048 reloc_type = R_386_GLOB_DAT;
1049 else
1050 reloc_type = R_386_JMP_SLOT;
1051 put_got_entry(s1, reloc_type, sym->st_size, sym->st_info,
1052 sym_index);
1054 break;
1055 #elif defined(TCC_TARGET_ARM)
1056 case R_ARM_GOT_BREL:
1057 case R_ARM_GOTOFF32:
1058 case R_ARM_BASE_PREL:
1059 case R_ARM_PLT32:
1060 if (!s1->got)
1061 build_got(s1);
1062 if (type == R_ARM_GOT_BREL || type == R_ARM_PLT32) {
1063 sym_index = ELFW(R_SYM)(rel->r_info);
1064 sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
1065 /* look at the symbol got offset. If none, then add one */
1066 if (type == R_ARM_GOT_BREL)
1067 reloc_type = R_ARM_GLOB_DAT;
1068 else
1069 reloc_type = R_ARM_JUMP_SLOT;
1070 put_got_entry(s1, reloc_type, sym->st_size, sym->st_info,
1071 sym_index);
1073 break;
1074 #elif defined(TCC_TARGET_C67)
1075 case R_C60_GOT32:
1076 case R_C60_GOTOFF:
1077 case R_C60_GOTPC:
1078 case R_C60_PLT32:
1079 if (!s1->got)
1080 build_got(s1);
1081 if (type == R_C60_GOT32 || type == R_C60_PLT32) {
1082 sym_index = ELFW(R_SYM)(rel->r_info);
1083 sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
1084 /* look at the symbol got offset. If none, then add one */
1085 if (type == R_C60_GOT32)
1086 reloc_type = R_C60_GLOB_DAT;
1087 else
1088 reloc_type = R_C60_JMP_SLOT;
1089 put_got_entry(s1, reloc_type, sym->st_size, sym->st_info,
1090 sym_index);
1092 break;
1093 #elif defined(TCC_TARGET_X86_64)
1094 case R_X86_64_GOT32:
1095 case R_X86_64_GOTTPOFF:
1096 case R_X86_64_GOTPCREL:
1097 case R_X86_64_PLT32:
1098 if (!s1->got)
1099 build_got(s1);
1100 if (type == R_X86_64_GOT32 || type == R_X86_64_GOTPCREL ||
1101 type == R_X86_64_PLT32) {
1102 sym_index = ELFW(R_SYM)(rel->r_info);
1103 sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
1104 /* look at the symbol got offset. If none, then add one */
1105 if (type == R_X86_64_GOT32 || type == R_X86_64_GOTPCREL)
1106 reloc_type = R_X86_64_GLOB_DAT;
1107 else
1108 reloc_type = R_X86_64_JUMP_SLOT;
1109 put_got_entry(s1, reloc_type, sym->st_size, sym->st_info,
1110 sym_index);
1112 break;
1113 #else
1114 #error unsupported CPU
1115 #endif
1116 default:
1117 break;
1123 static Section *new_symtab(TCCState *s1,
1124 const char *symtab_name, int sh_type, int sh_flags,
1125 const char *strtab_name,
1126 const char *hash_name, int hash_sh_flags)
1128 Section *symtab, *strtab, *hash;
1129 int *ptr, nb_buckets;
1131 symtab = new_section(s1, symtab_name, sh_type, sh_flags);
1132 symtab->sh_entsize = sizeof(ElfW(Sym));
1133 strtab = new_section(s1, strtab_name, SHT_STRTAB, sh_flags);
1134 put_elf_str(strtab, "");
1135 symtab->link = strtab;
1136 put_elf_sym(symtab, 0, 0, 0, 0, 0, NULL);
1138 nb_buckets = 1;
1140 hash = new_section(s1, hash_name, SHT_HASH, hash_sh_flags);
1141 hash->sh_entsize = sizeof(int);
1142 symtab->hash = hash;
1143 hash->link = symtab;
1145 ptr = section_ptr_add(hash, (2 + nb_buckets + 1) * sizeof(int));
1146 ptr[0] = nb_buckets;
1147 ptr[1] = 1;
1148 memset(ptr + 2, 0, (nb_buckets + 1) * sizeof(int));
1149 return symtab;
1152 /* put dynamic tag */
1153 static void put_dt(Section *dynamic, int dt, unsigned long val)
1155 ElfW(Dyn) *dyn;
1156 dyn = section_ptr_add(dynamic, sizeof(ElfW(Dyn)));
1157 dyn->d_tag = dt;
1158 dyn->d_un.d_val = val;
1161 static void add_init_array_defines(TCCState *s1, const char *section_name)
1163 Section *s;
1164 long end_offset;
1165 char sym_start[1024];
1166 char sym_end[1024];
1168 snprintf(sym_start, sizeof(sym_start), "__%s_start", section_name + 1);
1169 snprintf(sym_end, sizeof(sym_end), "__%s_end", section_name + 1);
1171 s = find_section(s1, section_name);
1172 if (!s) {
1173 end_offset = 0;
1174 s = data_section;
1175 } else {
1176 end_offset = s->data_offset;
1179 add_elf_sym(symtab_section,
1180 0, 0,
1181 ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
1182 s->sh_num, sym_start);
1183 add_elf_sym(symtab_section,
1184 end_offset, 0,
1185 ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
1186 s->sh_num, sym_end);
1189 /* add tcc runtime libraries */
1190 static void tcc_add_runtime(TCCState *s1)
1192 #if defined(CONFIG_TCC_BCHECK) || !defined(CONFIG_USE_LIBGCC)
1193 char buf[1024];
1194 #endif
1196 #ifdef CONFIG_TCC_BCHECK
1197 if (s1->do_bounds_check) {
1198 unsigned long *ptr;
1199 Section *init_section;
1200 unsigned char *pinit;
1201 int sym_index;
1203 /* XXX: add an object file to do that */
1204 ptr = section_ptr_add(bounds_section, sizeof(unsigned long));
1205 *ptr = 0;
1206 add_elf_sym(symtab_section, 0, 0,
1207 ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
1208 bounds_section->sh_num, "__bounds_start");
1209 /* add bound check code */
1210 snprintf(buf, sizeof(buf), "%s/%s", s1->tcc_lib_path, "bcheck.o");
1211 tcc_add_file(s1, buf);
1212 #ifdef TCC_TARGET_I386
1213 if (s1->output_type != TCC_OUTPUT_MEMORY) {
1214 /* add 'call __bound_init()' in .init section */
1215 init_section = find_section(s1, ".init");
1216 pinit = section_ptr_add(init_section, 5);
1217 pinit[0] = 0xe8;
1218 put32(pinit + 1, -4);
1219 sym_index = find_elf_sym(symtab_section, "__bound_init");
1220 put_elf_reloc(symtab_section, init_section,
1221 init_section->data_offset - 4, R_386_PC32, sym_index);
1223 #endif
1225 #endif
1226 /* add libc */
1227 if (!s1->nostdlib) {
1228 tcc_add_library(s1, "c");
1230 #ifdef CONFIG_USE_LIBGCC
1231 tcc_add_file(s1, CONFIG_SYSROOT "/lib/libgcc_s.so.1");
1232 #else
1233 snprintf(buf, sizeof(buf), "%s/%s", s1->tcc_lib_path, "libtcc1.a");
1234 tcc_add_file(s1, buf);
1235 #endif
1237 /* add crt end if not memory output */
1238 if (s1->output_type != TCC_OUTPUT_MEMORY && !s1->nostdlib) {
1239 tcc_add_file(s1, CONFIG_TCC_CRT_PREFIX "/crtn.o");
1243 /* add various standard linker symbols (must be done after the
1244 sections are filled (for example after allocating common
1245 symbols)) */
1246 static void tcc_add_linker_symbols(TCCState *s1)
1248 char buf[1024];
1249 int i;
1250 Section *s;
1252 add_elf_sym(symtab_section,
1253 text_section->data_offset, 0,
1254 ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
1255 text_section->sh_num, "_etext");
1256 add_elf_sym(symtab_section,
1257 data_section->data_offset, 0,
1258 ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
1259 data_section->sh_num, "_edata");
1260 add_elf_sym(symtab_section,
1261 bss_section->data_offset, 0,
1262 ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
1263 bss_section->sh_num, "_end");
1264 /* horrible new standard ldscript defines */
1265 add_init_array_defines(s1, ".preinit_array");
1266 add_init_array_defines(s1, ".init_array");
1267 add_init_array_defines(s1, ".fini_array");
1269 /* add start and stop symbols for sections whose name can be
1270 expressed in C */
1271 for(i = 1; i < s1->nb_sections; i++) {
1272 s = s1->sections[i];
1273 if (s->sh_type == SHT_PROGBITS &&
1274 (s->sh_flags & SHF_ALLOC)) {
1275 const char *p;
1276 int ch;
1278 /* check if section name can be expressed in C */
1279 p = s->name;
1280 for(;;) {
1281 ch = *p;
1282 if (!ch)
1283 break;
1284 if (!isid(ch) && !isnum(ch))
1285 goto next_sec;
1286 p++;
1288 snprintf(buf, sizeof(buf), "__start_%s", s->name);
1289 add_elf_sym(symtab_section,
1290 0, 0,
1291 ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
1292 s->sh_num, buf);
1293 snprintf(buf, sizeof(buf), "__stop_%s", s->name);
1294 add_elf_sym(symtab_section,
1295 s->data_offset, 0,
1296 ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
1297 s->sh_num, buf);
1299 next_sec: ;
1303 /* name of ELF interpreter */
1304 #if defined __FreeBSD__
1305 static const char elf_interp[] = "/usr/libexec/ld-elf.so.1";
1306 #elif defined TCC_ARM_EABI
1307 static const char elf_interp[] = "/lib/ld-linux.so.3";
1308 #elif defined(TCC_TARGET_X86_64)
1309 static const char elf_interp[] = "/lib/ld-linux-x86-64.so.2";
1310 #elif defined(TCC_UCLIBC)
1311 static const char elf_interp[] = "/lib/ld-uClibc.so.0";
1312 #else
1313 static const char elf_interp[] = "/lib/ld-linux.so.2";
1314 #endif
1316 static void tcc_output_binary(TCCState *s1, FILE *f,
1317 const int *section_order)
1319 Section *s;
1320 int i, offset, size;
1322 offset = 0;
1323 for(i=1;i<s1->nb_sections;i++) {
1324 s = s1->sections[section_order[i]];
1325 if (s->sh_type != SHT_NOBITS &&
1326 (s->sh_flags & SHF_ALLOC)) {
1327 while (offset < s->sh_offset) {
1328 fputc(0, f);
1329 offset++;
1331 size = s->sh_size;
1332 fwrite(s->data, 1, size, f);
1333 offset += size;
1338 /* output an ELF file */
1339 /* XXX: suppress unneeded sections */
1340 int elf_output_file(TCCState *s1, const char *filename)
1342 ElfW(Ehdr) ehdr;
1343 FILE *f;
1344 int fd, mode, ret;
1345 int *section_order;
1346 int shnum, i, phnum, file_offset, offset, size, j, tmp, sh_order_index, k;
1347 unsigned long addr;
1348 Section *strsec, *s;
1349 ElfW(Shdr) shdr, *sh;
1350 ElfW(Phdr) *phdr, *ph;
1351 Section *interp, *dynamic, *dynstr;
1352 unsigned long saved_dynamic_data_offset;
1353 ElfW(Sym) *sym;
1354 int type, file_type;
1355 unsigned long rel_addr, rel_size;
1357 file_type = s1->output_type;
1358 s1->nb_errors = 0;
1360 if (file_type != TCC_OUTPUT_OBJ) {
1361 tcc_add_runtime(s1);
1364 phdr = NULL;
1365 section_order = NULL;
1366 interp = NULL;
1367 dynamic = NULL;
1368 dynstr = NULL; /* avoid warning */
1369 saved_dynamic_data_offset = 0; /* avoid warning */
1371 if (file_type != TCC_OUTPUT_OBJ) {
1372 relocate_common_syms();
1374 tcc_add_linker_symbols(s1);
1376 if (!s1->static_link) {
1377 const char *name;
1378 int sym_index, index;
1379 ElfW(Sym) *esym, *sym_end;
1381 if (file_type == TCC_OUTPUT_EXE) {
1382 char *ptr;
1383 /* add interpreter section only if executable */
1384 interp = new_section(s1, ".interp", SHT_PROGBITS, SHF_ALLOC);
1385 interp->sh_addralign = 1;
1386 ptr = section_ptr_add(interp, sizeof(elf_interp));
1387 strcpy(ptr, elf_interp);
1390 /* add dynamic symbol table */
1391 s1->dynsym = new_symtab(s1, ".dynsym", SHT_DYNSYM, SHF_ALLOC,
1392 ".dynstr",
1393 ".hash", SHF_ALLOC);
1394 dynstr = s1->dynsym->link;
1396 /* add dynamic section */
1397 dynamic = new_section(s1, ".dynamic", SHT_DYNAMIC,
1398 SHF_ALLOC | SHF_WRITE);
1399 dynamic->link = dynstr;
1400 dynamic->sh_entsize = sizeof(ElfW(Dyn));
1402 /* add PLT */
1403 s1->plt = new_section(s1, ".plt", SHT_PROGBITS,
1404 SHF_ALLOC | SHF_EXECINSTR);
1405 s1->plt->sh_entsize = 4;
1407 build_got(s1);
1409 /* scan for undefined symbols and see if they are in the
1410 dynamic symbols. If a symbol STT_FUNC is found, then we
1411 add it in the PLT. If a symbol STT_OBJECT is found, we
1412 add it in the .bss section with a suitable relocation */
1413 sym_end = (ElfW(Sym) *)(symtab_section->data +
1414 symtab_section->data_offset);
1415 if (file_type == TCC_OUTPUT_EXE) {
1416 for(sym = (ElfW(Sym) *)symtab_section->data + 1;
1417 sym < sym_end;
1418 sym++) {
1419 if (sym->st_shndx == SHN_UNDEF) {
1420 name = symtab_section->link->data + sym->st_name;
1421 sym_index = find_elf_sym(s1->dynsymtab_section, name);
1422 if (sym_index) {
1423 esym = &((ElfW(Sym) *)s1->dynsymtab_section->data)[sym_index];
1424 type = ELFW(ST_TYPE)(esym->st_info);
1425 if (type == STT_FUNC) {
1426 put_got_entry(s1, R_JMP_SLOT, esym->st_size,
1427 esym->st_info,
1428 sym - (ElfW(Sym) *)symtab_section->data);
1429 } else if (type == STT_OBJECT) {
1430 unsigned long offset;
1431 offset = bss_section->data_offset;
1432 /* XXX: which alignment ? */
1433 offset = (offset + 16 - 1) & -16;
1434 index = put_elf_sym(s1->dynsym, offset, esym->st_size,
1435 esym->st_info, 0,
1436 bss_section->sh_num, name);
1437 put_elf_reloc(s1->dynsym, bss_section,
1438 offset, R_COPY, index);
1439 offset += esym->st_size;
1440 bss_section->data_offset = offset;
1442 } else {
1443 /* STB_WEAK undefined symbols are accepted */
1444 /* XXX: _fp_hw seems to be part of the ABI, so we ignore
1445 it */
1446 if (ELFW(ST_BIND)(sym->st_info) == STB_WEAK ||
1447 !strcmp(name, "_fp_hw")) {
1448 } else {
1449 error_noabort("undefined symbol '%s'", name);
1452 } else if (s1->rdynamic &&
1453 ELFW(ST_BIND)(sym->st_info) != STB_LOCAL) {
1454 /* if -rdynamic option, then export all non
1455 local symbols */
1456 name = symtab_section->link->data + sym->st_name;
1457 put_elf_sym(s1->dynsym, sym->st_value, sym->st_size,
1458 sym->st_info, 0,
1459 sym->st_shndx, name);
1463 if (s1->nb_errors)
1464 goto fail;
1466 /* now look at unresolved dynamic symbols and export
1467 corresponding symbol */
1468 sym_end = (ElfW(Sym) *)(s1->dynsymtab_section->data +
1469 s1->dynsymtab_section->data_offset);
1470 for(esym = (ElfW(Sym) *)s1->dynsymtab_section->data + 1;
1471 esym < sym_end;
1472 esym++) {
1473 if (esym->st_shndx == SHN_UNDEF) {
1474 name = s1->dynsymtab_section->link->data + esym->st_name;
1475 sym_index = find_elf_sym(symtab_section, name);
1476 if (sym_index) {
1477 /* XXX: avoid adding a symbol if already
1478 present because of -rdynamic ? */
1479 sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
1480 put_elf_sym(s1->dynsym, sym->st_value, sym->st_size,
1481 sym->st_info, 0,
1482 sym->st_shndx, name);
1483 } else {
1484 if (ELFW(ST_BIND)(esym->st_info) == STB_WEAK) {
1485 /* weak symbols can stay undefined */
1486 } else {
1487 warning("undefined dynamic symbol '%s'", name);
1492 } else {
1493 int nb_syms;
1494 /* shared library case : we simply export all the global symbols */
1495 nb_syms = symtab_section->data_offset / sizeof(ElfW(Sym));
1496 s1->symtab_to_dynsym = tcc_mallocz(sizeof(int) * nb_syms);
1497 for(sym = (ElfW(Sym) *)symtab_section->data + 1;
1498 sym < sym_end;
1499 sym++) {
1500 if (ELFW(ST_BIND)(sym->st_info) != STB_LOCAL) {
1501 #if defined(TCC_OUTPUT_DLL_WITH_PLT)
1502 if (ELFW(ST_TYPE)(sym->st_info) == STT_FUNC &&
1503 sym->st_shndx == SHN_UNDEF) {
1504 put_got_entry(s1, R_JMP_SLOT, sym->st_size,
1505 sym->st_info,
1506 sym - (ElfW(Sym) *)symtab_section->data);
1508 else if (ELFW(ST_TYPE)(sym->st_info) == STT_OBJECT) {
1509 put_got_entry(s1, R_X86_64_GLOB_DAT, sym->st_size,
1510 sym->st_info,
1511 sym - (ElfW(Sym) *)symtab_section->data);
1513 else
1514 #endif
1516 name = symtab_section->link->data + sym->st_name;
1517 index = put_elf_sym(s1->dynsym, sym->st_value, sym->st_size,
1518 sym->st_info, 0,
1519 sym->st_shndx, name);
1520 s1->symtab_to_dynsym[sym -
1521 (ElfW(Sym) *)symtab_section->data] =
1522 index;
1528 build_got_entries(s1);
1530 /* add a list of needed dlls */
1531 for(i = 0; i < s1->nb_loaded_dlls; i++) {
1532 DLLReference *dllref = s1->loaded_dlls[i];
1533 if (dllref->level == 0)
1534 put_dt(dynamic, DT_NEEDED, put_elf_str(dynstr, dllref->name));
1536 /* XXX: currently, since we do not handle PIC code, we
1537 must relocate the readonly segments */
1538 if (file_type == TCC_OUTPUT_DLL) {
1539 if (s1->soname)
1540 put_dt(dynamic, DT_SONAME, put_elf_str(dynstr, s1->soname));
1541 put_dt(dynamic, DT_TEXTREL, 0);
1544 /* add necessary space for other entries */
1545 saved_dynamic_data_offset = dynamic->data_offset;
1546 dynamic->data_offset += sizeof(ElfW(Dyn)) * 9;
1547 } else {
1548 /* still need to build got entries in case of static link */
1549 build_got_entries(s1);
1553 memset(&ehdr, 0, sizeof(ehdr));
1555 /* we add a section for symbols */
1556 strsec = new_section(s1, ".shstrtab", SHT_STRTAB, 0);
1557 put_elf_str(strsec, "");
1559 /* compute number of sections */
1560 shnum = s1->nb_sections;
1562 /* this array is used to reorder sections in the output file */
1563 section_order = tcc_malloc(sizeof(int) * shnum);
1564 section_order[0] = 0;
1565 sh_order_index = 1;
1567 /* compute number of program headers */
1568 switch(file_type) {
1569 default:
1570 case TCC_OUTPUT_OBJ:
1571 phnum = 0;
1572 break;
1573 case TCC_OUTPUT_EXE:
1574 if (!s1->static_link)
1575 phnum = 4;
1576 else
1577 phnum = 2;
1578 break;
1579 case TCC_OUTPUT_DLL:
1580 phnum = 3;
1581 break;
1584 /* allocate strings for section names and decide if an unallocated
1585 section should be output */
1586 /* NOTE: the strsec section comes last, so its size is also
1587 correct ! */
1588 for(i = 1; i < s1->nb_sections; i++) {
1589 s = s1->sections[i];
1590 s->sh_name = put_elf_str(strsec, s->name);
1591 #if 0 //gr
1592 printf("section: f=%08x t=%08x i=%08x %s %s\n",
1593 s->sh_flags,
1594 s->sh_type,
1595 s->sh_info,
1596 s->name,
1597 s->reloc ? s->reloc->name : "n"
1599 #endif
1600 /* when generating a DLL, we include relocations but we may
1601 patch them */
1602 if (file_type == TCC_OUTPUT_DLL &&
1603 s->sh_type == SHT_RELX &&
1604 !(s->sh_flags & SHF_ALLOC)) {
1605 /* //gr: avoid bogus relocs for empty (debug) sections */
1606 if (s1->sections[s->sh_info]->sh_flags & SHF_ALLOC)
1607 prepare_dynamic_rel(s1, s);
1608 else if (s1->do_debug)
1609 s->sh_size = s->data_offset;
1610 } else if (s1->do_debug ||
1611 file_type == TCC_OUTPUT_OBJ ||
1612 (s->sh_flags & SHF_ALLOC) ||
1613 i == (s1->nb_sections - 1)) {
1614 /* we output all sections if debug or object file */
1615 s->sh_size = s->data_offset;
1619 /* allocate program segment headers */
1620 phdr = tcc_mallocz(phnum * sizeof(ElfW(Phdr)));
1622 if (s1->output_format == TCC_OUTPUT_FORMAT_ELF) {
1623 file_offset = sizeof(ElfW(Ehdr)) + phnum * sizeof(ElfW(Phdr));
1624 } else {
1625 file_offset = 0;
1627 if (phnum > 0) {
1628 /* compute section to program header mapping */
1629 if (s1->has_text_addr) {
1630 int a_offset, p_offset;
1631 addr = s1->text_addr;
1632 /* we ensure that (addr % ELF_PAGE_SIZE) == file_offset %
1633 ELF_PAGE_SIZE */
1634 a_offset = addr & (s1->section_align - 1);
1635 p_offset = file_offset & (s1->section_align - 1);
1636 if (a_offset < p_offset)
1637 a_offset += s1->section_align;
1638 file_offset += (a_offset - p_offset);
1639 } else {
1640 if (file_type == TCC_OUTPUT_DLL)
1641 addr = 0;
1642 else
1643 addr = ELF_START_ADDR;
1644 /* compute address after headers */
1645 addr += (file_offset & (s1->section_align - 1));
1648 /* dynamic relocation table information, for .dynamic section */
1649 rel_size = 0;
1650 rel_addr = 0;
1652 /* leave one program header for the program interpreter */
1653 ph = &phdr[0];
1654 if (interp)
1655 ph++;
1657 for(j = 0; j < 2; j++) {
1658 ph->p_type = PT_LOAD;
1659 if (j == 0)
1660 ph->p_flags = PF_R | PF_X;
1661 else
1662 ph->p_flags = PF_R | PF_W;
1663 ph->p_align = s1->section_align;
1665 /* we do the following ordering: interp, symbol tables,
1666 relocations, progbits, nobits */
1667 /* XXX: do faster and simpler sorting */
1668 for(k = 0; k < 5; k++) {
1669 for(i = 1; i < s1->nb_sections; i++) {
1670 s = s1->sections[i];
1671 /* compute if section should be included */
1672 if (j == 0) {
1673 if ((s->sh_flags & (SHF_ALLOC | SHF_WRITE)) !=
1674 SHF_ALLOC)
1675 continue;
1676 } else {
1677 if ((s->sh_flags & (SHF_ALLOC | SHF_WRITE)) !=
1678 (SHF_ALLOC | SHF_WRITE))
1679 continue;
1681 if (s == interp) {
1682 if (k != 0)
1683 continue;
1684 } else if (s->sh_type == SHT_DYNSYM ||
1685 s->sh_type == SHT_STRTAB ||
1686 s->sh_type == SHT_HASH) {
1687 if (k != 1)
1688 continue;
1689 } else if (s->sh_type == SHT_RELX) {
1690 if (k != 2)
1691 continue;
1692 } else if (s->sh_type == SHT_NOBITS) {
1693 if (k != 4)
1694 continue;
1695 } else {
1696 if (k != 3)
1697 continue;
1699 section_order[sh_order_index++] = i;
1701 /* section matches: we align it and add its size */
1702 tmp = addr;
1703 addr = (addr + s->sh_addralign - 1) &
1704 ~(s->sh_addralign - 1);
1705 file_offset += addr - tmp;
1706 s->sh_offset = file_offset;
1707 s->sh_addr = addr;
1709 /* update program header infos */
1710 if (ph->p_offset == 0) {
1711 ph->p_offset = file_offset;
1712 ph->p_vaddr = addr;
1713 ph->p_paddr = ph->p_vaddr;
1715 /* update dynamic relocation infos */
1716 if (s->sh_type == SHT_RELX) {
1717 if (rel_size == 0)
1718 rel_addr = addr;
1719 rel_size += s->sh_size;
1721 addr += s->sh_size;
1722 if (s->sh_type != SHT_NOBITS)
1723 file_offset += s->sh_size;
1726 ph->p_filesz = file_offset - ph->p_offset;
1727 ph->p_memsz = addr - ph->p_vaddr;
1728 ph++;
1729 if (j == 0) {
1730 if (s1->output_format == TCC_OUTPUT_FORMAT_ELF) {
1731 /* if in the middle of a page, we duplicate the page in
1732 memory so that one copy is RX and the other is RW */
1733 if ((addr & (s1->section_align - 1)) != 0)
1734 addr += s1->section_align;
1735 } else {
1736 addr = (addr + s1->section_align - 1) & ~(s1->section_align - 1);
1737 file_offset = (file_offset + s1->section_align - 1) &
1738 ~(s1->section_align - 1);
1743 /* if interpreter, then add corresponing program header */
1744 if (interp) {
1745 ph = &phdr[0];
1747 ph->p_type = PT_INTERP;
1748 ph->p_offset = interp->sh_offset;
1749 ph->p_vaddr = interp->sh_addr;
1750 ph->p_paddr = ph->p_vaddr;
1751 ph->p_filesz = interp->sh_size;
1752 ph->p_memsz = interp->sh_size;
1753 ph->p_flags = PF_R;
1754 ph->p_align = interp->sh_addralign;
1757 /* if dynamic section, then add corresponing program header */
1758 if (dynamic) {
1759 ElfW(Sym) *sym_end;
1761 ph = &phdr[phnum - 1];
1763 ph->p_type = PT_DYNAMIC;
1764 ph->p_offset = dynamic->sh_offset;
1765 ph->p_vaddr = dynamic->sh_addr;
1766 ph->p_paddr = ph->p_vaddr;
1767 ph->p_filesz = dynamic->sh_size;
1768 ph->p_memsz = dynamic->sh_size;
1769 ph->p_flags = PF_R | PF_W;
1770 ph->p_align = dynamic->sh_addralign;
1772 /* put GOT dynamic section address */
1773 put32(s1->got->data, dynamic->sh_addr);
1775 /* relocate the PLT */
1776 if (file_type == TCC_OUTPUT_EXE
1777 #if defined(TCC_OUTPUT_DLL_WITH_PLT)
1778 || file_type == TCC_OUTPUT_DLL
1779 #endif
1781 uint8_t *p, *p_end;
1783 p = s1->plt->data;
1784 p_end = p + s1->plt->data_offset;
1785 if (p < p_end) {
1786 #if defined(TCC_TARGET_I386)
1787 put32(p + 2, get32(p + 2) + s1->got->sh_addr);
1788 put32(p + 8, get32(p + 8) + s1->got->sh_addr);
1789 p += 16;
1790 while (p < p_end) {
1791 put32(p + 2, get32(p + 2) + s1->got->sh_addr);
1792 p += 16;
1794 #elif defined(TCC_TARGET_X86_64)
1795 int x = s1->got->sh_addr - s1->plt->sh_addr - 6;
1796 put32(p + 2, get32(p + 2) + x);
1797 put32(p + 8, get32(p + 8) + x - 6);
1798 p += 16;
1799 while (p < p_end) {
1800 put32(p + 2, get32(p + 2) + x + s1->plt->data - p);
1801 p += 16;
1803 #elif defined(TCC_TARGET_ARM)
1804 int x;
1805 x=s1->got->sh_addr - s1->plt->sh_addr - 12;
1806 p +=16;
1807 while (p < p_end) {
1808 put32(p + 12, x + get32(p + 12) + s1->plt->data - p);
1809 p += 16;
1811 #elif defined(TCC_TARGET_C67)
1812 /* XXX: TODO */
1813 #else
1814 #error unsupported CPU
1815 #endif
1819 /* relocate symbols in .dynsym */
1820 sym_end = (ElfW(Sym) *)(s1->dynsym->data + s1->dynsym->data_offset);
1821 for(sym = (ElfW(Sym) *)s1->dynsym->data + 1;
1822 sym < sym_end;
1823 sym++) {
1824 if (sym->st_shndx == SHN_UNDEF) {
1825 /* relocate to the PLT if the symbol corresponds
1826 to a PLT entry */
1827 if (sym->st_value)
1828 sym->st_value += s1->plt->sh_addr;
1829 } else if (sym->st_shndx < SHN_LORESERVE) {
1830 /* do symbol relocation */
1831 sym->st_value += s1->sections[sym->st_shndx]->sh_addr;
1835 /* put dynamic section entries */
1836 dynamic->data_offset = saved_dynamic_data_offset;
1837 put_dt(dynamic, DT_HASH, s1->dynsym->hash->sh_addr);
1838 put_dt(dynamic, DT_STRTAB, dynstr->sh_addr);
1839 put_dt(dynamic, DT_SYMTAB, s1->dynsym->sh_addr);
1840 put_dt(dynamic, DT_STRSZ, dynstr->data_offset);
1841 put_dt(dynamic, DT_SYMENT, sizeof(ElfW(Sym)));
1842 #ifdef TCC_TARGET_X86_64
1843 put_dt(dynamic, DT_RELA, rel_addr);
1844 put_dt(dynamic, DT_RELASZ, rel_size);
1845 put_dt(dynamic, DT_RELAENT, sizeof(ElfW_Rel));
1846 #else
1847 put_dt(dynamic, DT_REL, rel_addr);
1848 put_dt(dynamic, DT_RELSZ, rel_size);
1849 put_dt(dynamic, DT_RELENT, sizeof(ElfW_Rel));
1850 #endif
1851 if (s1->do_debug)
1852 put_dt(dynamic, DT_DEBUG, 0);
1853 put_dt(dynamic, DT_NULL, 0);
1856 ehdr.e_phentsize = sizeof(ElfW(Phdr));
1857 ehdr.e_phnum = phnum;
1858 ehdr.e_phoff = sizeof(ElfW(Ehdr));
1861 /* all other sections come after */
1862 for(i = 1; i < s1->nb_sections; i++) {
1863 s = s1->sections[i];
1864 if (phnum > 0 && (s->sh_flags & SHF_ALLOC))
1865 continue;
1866 section_order[sh_order_index++] = i;
1868 file_offset = (file_offset + s->sh_addralign - 1) &
1869 ~(s->sh_addralign - 1);
1870 s->sh_offset = file_offset;
1871 if (s->sh_type != SHT_NOBITS)
1872 file_offset += s->sh_size;
1875 /* if building executable or DLL, then relocate each section
1876 except the GOT which is already relocated */
1877 if (file_type != TCC_OUTPUT_OBJ) {
1878 relocate_syms(s1, 0);
1880 if (s1->nb_errors != 0) {
1881 fail:
1882 ret = -1;
1883 goto the_end;
1886 /* relocate sections */
1887 /* XXX: ignore sections with allocated relocations ? */
1888 for(i = 1; i < s1->nb_sections; i++) {
1889 s = s1->sections[i];
1890 if (s->reloc && s != s1->got && (s->sh_flags & SHF_ALLOC)) //gr
1891 relocate_section(s1, s);
1894 /* relocate relocation entries if the relocation tables are
1895 allocated in the executable */
1896 for(i = 1; i < s1->nb_sections; i++) {
1897 s = s1->sections[i];
1898 if ((s->sh_flags & SHF_ALLOC) &&
1899 s->sh_type == SHT_RELX) {
1900 relocate_rel(s1, s);
1904 /* get entry point address */
1905 if (file_type == TCC_OUTPUT_EXE)
1906 ehdr.e_entry = (uplong)tcc_get_symbol_err(s1, "_start");
1907 else
1908 ehdr.e_entry = text_section->sh_addr; /* XXX: is it correct ? */
1911 /* write elf file */
1912 if (file_type == TCC_OUTPUT_OBJ)
1913 mode = 0666;
1914 else
1915 mode = 0777;
1916 fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, mode);
1917 if (fd < 0) {
1918 error_noabort("could not write '%s'", filename);
1919 goto fail;
1921 f = fdopen(fd, "wb");
1922 if (s1->verbose)
1923 printf("<- %s\n", filename);
1925 #ifdef TCC_TARGET_COFF
1926 if (s1->output_format == TCC_OUTPUT_FORMAT_COFF) {
1927 tcc_output_coff(s1, f);
1928 } else
1929 #endif
1930 if (s1->output_format == TCC_OUTPUT_FORMAT_ELF) {
1931 sort_syms(s1, symtab_section);
1933 /* align to 4 */
1934 file_offset = (file_offset + 3) & -4;
1936 /* fill header */
1937 ehdr.e_ident[0] = ELFMAG0;
1938 ehdr.e_ident[1] = ELFMAG1;
1939 ehdr.e_ident[2] = ELFMAG2;
1940 ehdr.e_ident[3] = ELFMAG3;
1941 ehdr.e_ident[4] = TCC_ELFCLASS;
1942 ehdr.e_ident[5] = ELFDATA2LSB;
1943 ehdr.e_ident[6] = EV_CURRENT;
1944 #ifdef __FreeBSD__
1945 ehdr.e_ident[EI_OSABI] = ELFOSABI_FREEBSD;
1946 #endif
1947 #ifdef TCC_TARGET_ARM
1948 #ifdef TCC_ARM_EABI
1949 ehdr.e_ident[EI_OSABI] = 0;
1950 ehdr.e_flags = 4 << 24;
1951 #else
1952 ehdr.e_ident[EI_OSABI] = ELFOSABI_ARM;
1953 #endif
1954 #endif
1955 switch(file_type) {
1956 default:
1957 case TCC_OUTPUT_EXE:
1958 ehdr.e_type = ET_EXEC;
1959 break;
1960 case TCC_OUTPUT_DLL:
1961 ehdr.e_type = ET_DYN;
1962 break;
1963 case TCC_OUTPUT_OBJ:
1964 ehdr.e_type = ET_REL;
1965 break;
1967 ehdr.e_machine = EM_TCC_TARGET;
1968 ehdr.e_version = EV_CURRENT;
1969 ehdr.e_shoff = file_offset;
1970 ehdr.e_ehsize = sizeof(ElfW(Ehdr));
1971 ehdr.e_shentsize = sizeof(ElfW(Shdr));
1972 ehdr.e_shnum = shnum;
1973 ehdr.e_shstrndx = shnum - 1;
1975 fwrite(&ehdr, 1, sizeof(ElfW(Ehdr)), f);
1976 fwrite(phdr, 1, phnum * sizeof(ElfW(Phdr)), f);
1977 offset = sizeof(ElfW(Ehdr)) + phnum * sizeof(ElfW(Phdr));
1979 for(i=1;i<s1->nb_sections;i++) {
1980 s = s1->sections[section_order[i]];
1981 if (s->sh_type != SHT_NOBITS) {
1982 while (offset < s->sh_offset) {
1983 fputc(0, f);
1984 offset++;
1986 size = s->sh_size;
1987 fwrite(s->data, 1, size, f);
1988 offset += size;
1992 /* output section headers */
1993 while (offset < ehdr.e_shoff) {
1994 fputc(0, f);
1995 offset++;
1998 for(i=0;i<s1->nb_sections;i++) {
1999 sh = &shdr;
2000 memset(sh, 0, sizeof(ElfW(Shdr)));
2001 s = s1->sections[i];
2002 if (s) {
2003 sh->sh_name = s->sh_name;
2004 sh->sh_type = s->sh_type;
2005 sh->sh_flags = s->sh_flags;
2006 sh->sh_entsize = s->sh_entsize;
2007 sh->sh_info = s->sh_info;
2008 if (s->link)
2009 sh->sh_link = s->link->sh_num;
2010 sh->sh_addralign = s->sh_addralign;
2011 sh->sh_addr = s->sh_addr;
2012 sh->sh_offset = s->sh_offset;
2013 sh->sh_size = s->sh_size;
2015 fwrite(sh, 1, sizeof(ElfW(Shdr)), f);
2017 } else {
2018 tcc_output_binary(s1, f, section_order);
2020 fclose(f);
2022 ret = 0;
2023 the_end:
2024 tcc_free(s1->symtab_to_dynsym);
2025 tcc_free(section_order);
2026 tcc_free(phdr);
2027 tcc_free(s1->got_offsets);
2028 return ret;
2031 int tcc_output_file(TCCState *s, const char *filename)
2033 int ret;
2034 #ifdef TCC_TARGET_PE
2035 if (s->output_type != TCC_OUTPUT_OBJ) {
2036 ret = pe_output_file(s, filename);
2037 } else
2038 #endif
2040 ret = elf_output_file(s, filename);
2042 return ret;
2045 static void *load_data(int fd, unsigned long file_offset, unsigned long size)
2047 void *data;
2049 data = tcc_malloc(size);
2050 lseek(fd, file_offset, SEEK_SET);
2051 read(fd, data, size);
2052 return data;
2055 typedef struct SectionMergeInfo {
2056 Section *s; /* corresponding existing section */
2057 unsigned long offset; /* offset of the new section in the existing section */
2058 uint8_t new_section; /* true if section 's' was added */
2059 uint8_t link_once; /* true if link once section */
2060 } SectionMergeInfo;
2062 /* load an object file and merge it with current files */
2063 /* XXX: handle correctly stab (debug) info */
2064 static int tcc_load_object_file(TCCState *s1,
2065 int fd, unsigned long file_offset)
2067 ElfW(Ehdr) ehdr;
2068 ElfW(Shdr) *shdr, *sh;
2069 int size, i, j, offset, offseti, nb_syms, sym_index, ret;
2070 unsigned char *strsec, *strtab;
2071 int *old_to_new_syms;
2072 char *sh_name, *name;
2073 SectionMergeInfo *sm_table, *sm;
2074 ElfW(Sym) *sym, *symtab;
2075 ElfW_Rel *rel, *rel_end;
2076 Section *s;
2078 int stab_index;
2079 int stabstr_index;
2081 stab_index = stabstr_index = 0;
2083 if (read(fd, &ehdr, sizeof(ehdr)) != sizeof(ehdr))
2084 goto fail1;
2085 if (ehdr.e_ident[0] != ELFMAG0 ||
2086 ehdr.e_ident[1] != ELFMAG1 ||
2087 ehdr.e_ident[2] != ELFMAG2 ||
2088 ehdr.e_ident[3] != ELFMAG3)
2089 goto fail1;
2090 /* test if object file */
2091 if (ehdr.e_type != ET_REL)
2092 goto fail1;
2093 /* test CPU specific stuff */
2094 if (ehdr.e_ident[5] != ELFDATA2LSB ||
2095 ehdr.e_machine != EM_TCC_TARGET) {
2096 fail1:
2097 error_noabort("invalid object file");
2098 return -1;
2100 /* read sections */
2101 shdr = load_data(fd, file_offset + ehdr.e_shoff,
2102 sizeof(ElfW(Shdr)) * ehdr.e_shnum);
2103 sm_table = tcc_mallocz(sizeof(SectionMergeInfo) * ehdr.e_shnum);
2105 /* load section names */
2106 sh = &shdr[ehdr.e_shstrndx];
2107 strsec = load_data(fd, file_offset + sh->sh_offset, sh->sh_size);
2109 /* load symtab and strtab */
2110 old_to_new_syms = NULL;
2111 symtab = NULL;
2112 strtab = NULL;
2113 nb_syms = 0;
2114 for(i = 1; i < ehdr.e_shnum; i++) {
2115 sh = &shdr[i];
2116 if (sh->sh_type == SHT_SYMTAB) {
2117 if (symtab) {
2118 error_noabort("object must contain only one symtab");
2119 fail:
2120 ret = -1;
2121 goto the_end;
2123 nb_syms = sh->sh_size / sizeof(ElfW(Sym));
2124 symtab = load_data(fd, file_offset + sh->sh_offset, sh->sh_size);
2125 sm_table[i].s = symtab_section;
2127 /* now load strtab */
2128 sh = &shdr[sh->sh_link];
2129 strtab = load_data(fd, file_offset + sh->sh_offset, sh->sh_size);
2133 /* now examine each section and try to merge its content with the
2134 ones in memory */
2135 for(i = 1; i < ehdr.e_shnum; i++) {
2136 /* no need to examine section name strtab */
2137 if (i == ehdr.e_shstrndx)
2138 continue;
2139 sh = &shdr[i];
2140 sh_name = strsec + sh->sh_name;
2141 /* ignore sections types we do not handle */
2142 if (sh->sh_type != SHT_PROGBITS &&
2143 sh->sh_type != SHT_RELX &&
2144 #ifdef TCC_ARM_EABI
2145 sh->sh_type != SHT_ARM_EXIDX &&
2146 #endif
2147 sh->sh_type != SHT_NOBITS &&
2148 strcmp(sh_name, ".stabstr")
2150 continue;
2151 if (sh->sh_addralign < 1)
2152 sh->sh_addralign = 1;
2153 /* find corresponding section, if any */
2154 for(j = 1; j < s1->nb_sections;j++) {
2155 s = s1->sections[j];
2156 if (!strcmp(s->name, sh_name)) {
2157 if (!strncmp(sh_name, ".gnu.linkonce",
2158 sizeof(".gnu.linkonce") - 1)) {
2159 /* if a 'linkonce' section is already present, we
2160 do not add it again. It is a little tricky as
2161 symbols can still be defined in
2162 it. */
2163 sm_table[i].link_once = 1;
2164 goto next;
2165 } else {
2166 goto found;
2170 /* not found: create new section */
2171 s = new_section(s1, sh_name, sh->sh_type, sh->sh_flags);
2172 /* take as much info as possible from the section. sh_link and
2173 sh_info will be updated later */
2174 s->sh_addralign = sh->sh_addralign;
2175 s->sh_entsize = sh->sh_entsize;
2176 sm_table[i].new_section = 1;
2177 found:
2178 if (sh->sh_type != s->sh_type) {
2179 error_noabort("invalid section type");
2180 goto fail;
2183 /* align start of section */
2184 offset = s->data_offset;
2186 if (0 == strcmp(sh_name, ".stab")) {
2187 stab_index = i;
2188 goto no_align;
2190 if (0 == strcmp(sh_name, ".stabstr")) {
2191 stabstr_index = i;
2192 goto no_align;
2195 size = sh->sh_addralign - 1;
2196 offset = (offset + size) & ~size;
2197 if (sh->sh_addralign > s->sh_addralign)
2198 s->sh_addralign = sh->sh_addralign;
2199 s->data_offset = offset;
2200 no_align:
2201 sm_table[i].offset = offset;
2202 sm_table[i].s = s;
2203 /* concatenate sections */
2204 size = sh->sh_size;
2205 if (sh->sh_type != SHT_NOBITS) {
2206 unsigned char *ptr;
2207 lseek(fd, file_offset + sh->sh_offset, SEEK_SET);
2208 ptr = section_ptr_add(s, size);
2209 read(fd, ptr, size);
2210 } else {
2211 s->data_offset += size;
2213 next: ;
2216 /* //gr relocate stab strings */
2217 if (stab_index && stabstr_index) {
2218 Stab_Sym *a, *b;
2219 unsigned o;
2220 s = sm_table[stab_index].s;
2221 a = (Stab_Sym *)(s->data + sm_table[stab_index].offset);
2222 b = (Stab_Sym *)(s->data + s->data_offset);
2223 o = sm_table[stabstr_index].offset;
2224 while (a < b)
2225 a->n_strx += o, a++;
2228 /* second short pass to update sh_link and sh_info fields of new
2229 sections */
2230 for(i = 1; i < ehdr.e_shnum; i++) {
2231 s = sm_table[i].s;
2232 if (!s || !sm_table[i].new_section)
2233 continue;
2234 sh = &shdr[i];
2235 if (sh->sh_link > 0)
2236 s->link = sm_table[sh->sh_link].s;
2237 if (sh->sh_type == SHT_RELX) {
2238 s->sh_info = sm_table[sh->sh_info].s->sh_num;
2239 /* update backward link */
2240 s1->sections[s->sh_info]->reloc = s;
2243 sm = sm_table;
2245 /* resolve symbols */
2246 old_to_new_syms = tcc_mallocz(nb_syms * sizeof(int));
2248 sym = symtab + 1;
2249 for(i = 1; i < nb_syms; i++, sym++) {
2250 if (sym->st_shndx != SHN_UNDEF &&
2251 sym->st_shndx < SHN_LORESERVE) {
2252 sm = &sm_table[sym->st_shndx];
2253 if (sm->link_once) {
2254 /* if a symbol is in a link once section, we use the
2255 already defined symbol. It is very important to get
2256 correct relocations */
2257 if (ELFW(ST_BIND)(sym->st_info) != STB_LOCAL) {
2258 name = strtab + sym->st_name;
2259 sym_index = find_elf_sym(symtab_section, name);
2260 if (sym_index)
2261 old_to_new_syms[i] = sym_index;
2263 continue;
2265 /* if no corresponding section added, no need to add symbol */
2266 if (!sm->s)
2267 continue;
2268 /* convert section number */
2269 sym->st_shndx = sm->s->sh_num;
2270 /* offset value */
2271 sym->st_value += sm->offset;
2273 /* add symbol */
2274 name = strtab + sym->st_name;
2275 sym_index = add_elf_sym(symtab_section, sym->st_value, sym->st_size,
2276 sym->st_info, sym->st_other,
2277 sym->st_shndx, name);
2278 old_to_new_syms[i] = sym_index;
2281 /* third pass to patch relocation entries */
2282 for(i = 1; i < ehdr.e_shnum; i++) {
2283 s = sm_table[i].s;
2284 if (!s)
2285 continue;
2286 sh = &shdr[i];
2287 offset = sm_table[i].offset;
2288 switch(s->sh_type) {
2289 case SHT_RELX:
2290 /* take relocation offset information */
2291 offseti = sm_table[sh->sh_info].offset;
2292 rel_end = (ElfW_Rel *)(s->data + s->data_offset);
2293 for(rel = (ElfW_Rel *)(s->data + offset);
2294 rel < rel_end;
2295 rel++) {
2296 int type;
2297 unsigned sym_index;
2298 /* convert symbol index */
2299 type = ELFW(R_TYPE)(rel->r_info);
2300 sym_index = ELFW(R_SYM)(rel->r_info);
2301 /* NOTE: only one symtab assumed */
2302 if (sym_index >= nb_syms)
2303 goto invalid_reloc;
2304 sym_index = old_to_new_syms[sym_index];
2305 /* ignore link_once in rel section. */
2306 if (!sym_index && !sm->link_once) {
2307 invalid_reloc:
2308 error_noabort("Invalid relocation entry [%2d] '%s' @ %.8x",
2309 i, strsec + sh->sh_name, rel->r_offset);
2310 goto fail;
2312 rel->r_info = ELFW(R_INFO)(sym_index, type);
2313 /* offset the relocation offset */
2314 rel->r_offset += offseti;
2316 break;
2317 default:
2318 break;
2322 ret = 0;
2323 the_end:
2324 tcc_free(symtab);
2325 tcc_free(strtab);
2326 tcc_free(old_to_new_syms);
2327 tcc_free(sm_table);
2328 tcc_free(strsec);
2329 tcc_free(shdr);
2330 return ret;
2333 #define ARMAG "!<arch>\012" /* For COFF and a.out archives */
2335 typedef struct ArchiveHeader {
2336 char ar_name[16]; /* name of this member */
2337 char ar_date[12]; /* file mtime */
2338 char ar_uid[6]; /* owner uid; printed as decimal */
2339 char ar_gid[6]; /* owner gid; printed as decimal */
2340 char ar_mode[8]; /* file mode, printed as octal */
2341 char ar_size[10]; /* file size, printed as decimal */
2342 char ar_fmag[2]; /* should contain ARFMAG */
2343 } ArchiveHeader;
2345 static int get_be32(const uint8_t *b)
2347 return b[3] | (b[2] << 8) | (b[1] << 16) | (b[0] << 24);
2350 /* load only the objects which resolve undefined symbols */
2351 static int tcc_load_alacarte(TCCState *s1, int fd, int size)
2353 int i, bound, nsyms, sym_index, off, ret;
2354 uint8_t *data;
2355 const char *ar_names, *p;
2356 const uint8_t *ar_index;
2357 ElfW(Sym) *sym;
2359 data = tcc_malloc(size);
2360 if (read(fd, data, size) != size)
2361 goto fail;
2362 nsyms = get_be32(data);
2363 ar_index = data + 4;
2364 ar_names = ar_index + nsyms * 4;
2366 do {
2367 bound = 0;
2368 for(p = ar_names, i = 0; i < nsyms; i++, p += strlen(p)+1) {
2369 sym_index = find_elf_sym(symtab_section, p);
2370 if(sym_index) {
2371 sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
2372 if(sym->st_shndx == SHN_UNDEF) {
2373 off = get_be32(ar_index + i * 4) + sizeof(ArchiveHeader);
2374 #if 0
2375 printf("%5d\t%s\t%08x\n", i, p, sym->st_shndx);
2376 #endif
2377 ++bound;
2378 lseek(fd, off, SEEK_SET);
2379 if(tcc_load_object_file(s1, fd, off) < 0) {
2380 fail:
2381 ret = -1;
2382 goto the_end;
2387 } while(bound);
2388 ret = 0;
2389 the_end:
2390 tcc_free(data);
2391 return ret;
2394 /* load a '.a' file */
2395 static int tcc_load_archive(TCCState *s1, int fd)
2397 ArchiveHeader hdr;
2398 char ar_size[11];
2399 char ar_name[17];
2400 char magic[8];
2401 int size, len, i;
2402 unsigned long file_offset;
2404 /* skip magic which was already checked */
2405 read(fd, magic, sizeof(magic));
2407 for(;;) {
2408 len = read(fd, &hdr, sizeof(hdr));
2409 if (len == 0)
2410 break;
2411 if (len != sizeof(hdr)) {
2412 error_noabort("invalid archive");
2413 return -1;
2415 memcpy(ar_size, hdr.ar_size, sizeof(hdr.ar_size));
2416 ar_size[sizeof(hdr.ar_size)] = '\0';
2417 size = strtol(ar_size, NULL, 0);
2418 memcpy(ar_name, hdr.ar_name, sizeof(hdr.ar_name));
2419 for(i = sizeof(hdr.ar_name) - 1; i >= 0; i--) {
2420 if (ar_name[i] != ' ')
2421 break;
2423 ar_name[i + 1] = '\0';
2424 // printf("name='%s' size=%d %s\n", ar_name, size, ar_size);
2425 file_offset = lseek(fd, 0, SEEK_CUR);
2426 /* align to even */
2427 size = (size + 1) & ~1;
2428 if (!strcmp(ar_name, "/")) {
2429 /* coff symbol table : we handle it */
2430 if(s1->alacarte_link)
2431 return tcc_load_alacarte(s1, fd, size);
2432 } else if (!strcmp(ar_name, "//") ||
2433 !strcmp(ar_name, "__.SYMDEF") ||
2434 !strcmp(ar_name, "__.SYMDEF/") ||
2435 !strcmp(ar_name, "ARFILENAMES/")) {
2436 /* skip symbol table or archive names */
2437 } else {
2438 if (tcc_load_object_file(s1, fd, file_offset) < 0)
2439 return -1;
2441 lseek(fd, file_offset + size, SEEK_SET);
2443 return 0;
2446 #ifndef TCC_TARGET_PE
2447 /* load a DLL and all referenced DLLs. 'level = 0' means that the DLL
2448 is referenced by the user (so it should be added as DT_NEEDED in
2449 the generated ELF file) */
2450 static int tcc_load_dll(TCCState *s1, int fd, const char *filename, int level)
2452 ElfW(Ehdr) ehdr;
2453 ElfW(Shdr) *shdr, *sh, *sh1;
2454 int i, j, nb_syms, nb_dts, sym_bind, ret;
2455 ElfW(Sym) *sym, *dynsym;
2456 ElfW(Dyn) *dt, *dynamic;
2457 unsigned char *dynstr;
2458 const char *name, *soname;
2459 DLLReference *dllref;
2461 read(fd, &ehdr, sizeof(ehdr));
2463 /* test CPU specific stuff */
2464 if (ehdr.e_ident[5] != ELFDATA2LSB ||
2465 ehdr.e_machine != EM_TCC_TARGET) {
2466 error_noabort("bad architecture");
2467 return -1;
2470 /* read sections */
2471 shdr = load_data(fd, ehdr.e_shoff, sizeof(ElfW(Shdr)) * ehdr.e_shnum);
2473 /* load dynamic section and dynamic symbols */
2474 nb_syms = 0;
2475 nb_dts = 0;
2476 dynamic = NULL;
2477 dynsym = NULL; /* avoid warning */
2478 dynstr = NULL; /* avoid warning */
2479 for(i = 0, sh = shdr; i < ehdr.e_shnum; i++, sh++) {
2480 switch(sh->sh_type) {
2481 case SHT_DYNAMIC:
2482 nb_dts = sh->sh_size / sizeof(ElfW(Dyn));
2483 dynamic = load_data(fd, sh->sh_offset, sh->sh_size);
2484 break;
2485 case SHT_DYNSYM:
2486 nb_syms = sh->sh_size / sizeof(ElfW(Sym));
2487 dynsym = load_data(fd, sh->sh_offset, sh->sh_size);
2488 sh1 = &shdr[sh->sh_link];
2489 dynstr = load_data(fd, sh1->sh_offset, sh1->sh_size);
2490 break;
2491 default:
2492 break;
2496 /* compute the real library name */
2497 soname = tcc_basename(filename);
2499 for(i = 0, dt = dynamic; i < nb_dts; i++, dt++) {
2500 if (dt->d_tag == DT_SONAME) {
2501 soname = dynstr + dt->d_un.d_val;
2505 /* if the dll is already loaded, do not load it */
2506 for(i = 0; i < s1->nb_loaded_dlls; i++) {
2507 dllref = s1->loaded_dlls[i];
2508 if (!strcmp(soname, dllref->name)) {
2509 /* but update level if needed */
2510 if (level < dllref->level)
2511 dllref->level = level;
2512 ret = 0;
2513 goto the_end;
2517 // printf("loading dll '%s'\n", soname);
2519 /* add the dll and its level */
2520 dllref = tcc_mallocz(sizeof(DLLReference) + strlen(soname));
2521 dllref->level = level;
2522 strcpy(dllref->name, soname);
2523 dynarray_add((void ***)&s1->loaded_dlls, &s1->nb_loaded_dlls, dllref);
2525 /* add dynamic symbols in dynsym_section */
2526 for(i = 1, sym = dynsym + 1; i < nb_syms; i++, sym++) {
2527 sym_bind = ELFW(ST_BIND)(sym->st_info);
2528 if (sym_bind == STB_LOCAL)
2529 continue;
2530 name = dynstr + sym->st_name;
2531 add_elf_sym(s1->dynsymtab_section, sym->st_value, sym->st_size,
2532 sym->st_info, sym->st_other, sym->st_shndx, name);
2535 /* load all referenced DLLs */
2536 for(i = 0, dt = dynamic; i < nb_dts; i++, dt++) {
2537 switch(dt->d_tag) {
2538 case DT_NEEDED:
2539 name = dynstr + dt->d_un.d_val;
2540 for(j = 0; j < s1->nb_loaded_dlls; j++) {
2541 dllref = s1->loaded_dlls[j];
2542 if (!strcmp(name, dllref->name))
2543 goto already_loaded;
2545 if (tcc_add_dll(s1, name, AFF_REFERENCED_DLL) < 0) {
2546 error_noabort("referenced dll '%s' not found", name);
2547 ret = -1;
2548 goto the_end;
2550 already_loaded:
2551 break;
2554 ret = 0;
2555 the_end:
2556 tcc_free(dynstr);
2557 tcc_free(dynsym);
2558 tcc_free(dynamic);
2559 tcc_free(shdr);
2560 return ret;
2563 #define LD_TOK_NAME 256
2564 #define LD_TOK_EOF (-1)
2566 /* return next ld script token */
2567 static int ld_next(TCCState *s1, char *name, int name_size)
2569 int c;
2570 char *q;
2572 redo:
2573 switch(ch) {
2574 case ' ':
2575 case '\t':
2576 case '\f':
2577 case '\v':
2578 case '\r':
2579 case '\n':
2580 inp();
2581 goto redo;
2582 case '/':
2583 minp();
2584 if (ch == '*') {
2585 file->buf_ptr = parse_comment(file->buf_ptr);
2586 ch = file->buf_ptr[0];
2587 goto redo;
2588 } else {
2589 q = name;
2590 *q++ = '/';
2591 goto parse_name;
2593 break;
2594 /* case 'a' ... 'z': */
2595 case 'a':
2596 case 'b':
2597 case 'c':
2598 case 'd':
2599 case 'e':
2600 case 'f':
2601 case 'g':
2602 case 'h':
2603 case 'i':
2604 case 'j':
2605 case 'k':
2606 case 'l':
2607 case 'm':
2608 case 'n':
2609 case 'o':
2610 case 'p':
2611 case 'q':
2612 case 'r':
2613 case 's':
2614 case 't':
2615 case 'u':
2616 case 'v':
2617 case 'w':
2618 case 'x':
2619 case 'y':
2620 case 'z':
2621 /* case 'A' ... 'z': */
2622 case 'A':
2623 case 'B':
2624 case 'C':
2625 case 'D':
2626 case 'E':
2627 case 'F':
2628 case 'G':
2629 case 'H':
2630 case 'I':
2631 case 'J':
2632 case 'K':
2633 case 'L':
2634 case 'M':
2635 case 'N':
2636 case 'O':
2637 case 'P':
2638 case 'Q':
2639 case 'R':
2640 case 'S':
2641 case 'T':
2642 case 'U':
2643 case 'V':
2644 case 'W':
2645 case 'X':
2646 case 'Y':
2647 case 'Z':
2648 case '_':
2649 case '\\':
2650 case '.':
2651 case '$':
2652 case '~':
2653 q = name;
2654 parse_name:
2655 for(;;) {
2656 if (!((ch >= 'a' && ch <= 'z') ||
2657 (ch >= 'A' && ch <= 'Z') ||
2658 (ch >= '0' && ch <= '9') ||
2659 strchr("/.-_+=$:\\,~", ch)))
2660 break;
2661 if ((q - name) < name_size - 1) {
2662 *q++ = ch;
2664 minp();
2666 *q = '\0';
2667 c = LD_TOK_NAME;
2668 break;
2669 case CH_EOF:
2670 c = LD_TOK_EOF;
2671 break;
2672 default:
2673 c = ch;
2674 inp();
2675 break;
2677 #if 0
2678 printf("tok=%c %d\n", c, c);
2679 if (c == LD_TOK_NAME)
2680 printf(" name=%s\n", name);
2681 #endif
2682 return c;
2685 static int ld_add_file_list(TCCState *s1, int as_needed)
2687 char filename[1024];
2688 int t, ret;
2690 t = ld_next(s1, filename, sizeof(filename));
2691 if (t != '(')
2692 expect("(");
2693 t = ld_next(s1, filename, sizeof(filename));
2694 for(;;) {
2695 if (t == LD_TOK_EOF) {
2696 error_noabort("unexpected end of file");
2697 return -1;
2698 } else if (t == ')') {
2699 break;
2700 } else if (t != LD_TOK_NAME) {
2701 error_noabort("filename expected");
2702 return -1;
2704 if (!strcmp(filename, "AS_NEEDED")) {
2705 ret = ld_add_file_list(s1, 1);
2706 if (ret)
2707 return ret;
2708 } else {
2709 /* TODO: Implement AS_NEEDED support. Ignore it for now */
2710 if (!as_needed)
2711 tcc_add_file(s1, filename);
2713 t = ld_next(s1, filename, sizeof(filename));
2714 if (t == ',') {
2715 t = ld_next(s1, filename, sizeof(filename));
2718 return 0;
2721 /* interpret a subset of GNU ldscripts to handle the dummy libc.so
2722 files */
2723 static int tcc_load_ldscript(TCCState *s1)
2725 char cmd[64];
2726 char filename[1024];
2727 int t, ret;
2729 ch = file->buf_ptr[0];
2730 ch = handle_eob();
2731 for(;;) {
2732 t = ld_next(s1, cmd, sizeof(cmd));
2733 if (t == LD_TOK_EOF)
2734 return 0;
2735 else if (t != LD_TOK_NAME)
2736 return -1;
2737 if (!strcmp(cmd, "INPUT") ||
2738 !strcmp(cmd, "GROUP")) {
2739 ret = ld_add_file_list(s1, 0);
2740 if (ret)
2741 return ret;
2742 } else if (!strcmp(cmd, "OUTPUT_FORMAT") ||
2743 !strcmp(cmd, "TARGET")) {
2744 /* ignore some commands */
2745 t = ld_next(s1, cmd, sizeof(cmd));
2746 if (t != '(')
2747 expect("(");
2748 for(;;) {
2749 t = ld_next(s1, filename, sizeof(filename));
2750 if (t == LD_TOK_EOF) {
2751 error_noabort("unexpected end of file");
2752 return -1;
2753 } else if (t == ')') {
2754 break;
2757 } else {
2758 return -1;
2761 return 0;
2763 #endif