tcc_relocate: return error and remove unused code
[tinycc.git] / tccelf.c
blob11bb82c7529c1a18879a4139f688b65e3c3e53eb
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 or error */
172 void *tcc_get_symbol(TCCState *s, const char *name)
174 int sym_index;
175 ElfW(Sym) *sym;
176 sym_index = find_elf_sym(symtab_section, name);
177 if (!sym_index)
178 return NULL;
179 sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
180 return (void*)sym->st_value;
183 void *tcc_get_symbol_err(TCCState *s, const char *name)
185 void *sym;
186 sym = tcc_get_symbol(s, name);
187 if (!sym)
188 error("%s not defined", name);
189 return sym;
192 /* add an elf symbol : check if it is already defined and patch
193 it. Return symbol index. NOTE that sh_num can be SHN_UNDEF. */
194 static int add_elf_sym(Section *s, unsigned long value, unsigned long size,
195 int info, int other, int sh_num, const char *name)
197 ElfW(Sym) *esym;
198 int sym_bind, sym_index, sym_type, esym_bind;
199 unsigned char sym_vis, esym_vis, new_vis;
201 sym_bind = ELFW(ST_BIND)(info);
202 sym_type = ELFW(ST_TYPE)(info);
203 sym_vis = ELFW(ST_VISIBILITY)(other);
205 if (sym_bind != STB_LOCAL) {
206 /* we search global or weak symbols */
207 sym_index = find_elf_sym(s, name);
208 if (!sym_index)
209 goto do_def;
210 esym = &((ElfW(Sym) *)s->data)[sym_index];
211 if (esym->st_shndx != SHN_UNDEF) {
212 esym_bind = ELFW(ST_BIND)(esym->st_info);
213 /* propagate the most constraining visibility */
214 /* STV_DEFAULT(0)<STV_PROTECTED(3)<STV_HIDDEN(2)<STV_INTERNAL(1) */
215 esym_vis = ELFW(ST_VISIBILITY)(esym->st_other);
216 if (esym_vis == STV_DEFAULT) {
217 new_vis = sym_vis;
218 } else if (sym_vis == STV_DEFAULT) {
219 new_vis = esym_vis;
220 } else {
221 new_vis = (esym_vis < sym_vis) ? esym_vis : sym_vis;
223 esym->st_other = (esym->st_other & ~ELFW(ST_VISIBILITY)(-1))
224 | new_vis;
225 other = esym->st_other; /* in case we have to patch esym */
226 if (sh_num == SHN_UNDEF) {
227 /* ignore adding of undefined symbol if the
228 corresponding symbol is already defined */
229 } else if (sym_bind == STB_GLOBAL && esym_bind == STB_WEAK) {
230 /* global overrides weak, so patch */
231 goto do_patch;
232 } else if (sym_bind == STB_WEAK && esym_bind == STB_GLOBAL) {
233 /* weak is ignored if already global */
234 } else if (sym_vis == STV_HIDDEN || sym_vis == STV_INTERNAL) {
235 /* ignore hidden symbols after */
236 } else if (esym->st_shndx == SHN_COMMON && sh_num < SHN_LORESERVE) {
237 /* gr: Happens with 'tcc ... -static tcctest.c' on e.g. Ubuntu 6.01
238 No idea if this is the correct solution ... */
239 goto do_patch;
240 } else if (s == tcc_state->dynsymtab_section) {
241 /* we accept that two DLL define the same symbol */
242 } else {
243 #if 1
244 printf("new_bind=%x new_shndx=%x new_vis=%x old_bind=%x old_shndx=%x old_vis=%x\n",
245 sym_bind, sh_num, new_vis, esym_bind, esym->st_shndx, esym_vis);
246 #endif
247 error_noabort("'%s' defined twice", name);
249 } else {
250 do_patch:
251 esym->st_info = ELFW(ST_INFO)(sym_bind, sym_type);
252 esym->st_shndx = sh_num;
253 esym->st_value = value;
254 esym->st_size = size;
255 esym->st_other = other;
257 } else {
258 do_def:
259 sym_index = put_elf_sym(s, value, size,
260 ELFW(ST_INFO)(sym_bind, sym_type), other,
261 sh_num, name);
263 return sym_index;
266 /* put relocation */
267 static void put_elf_reloc(Section *symtab, Section *s, unsigned long offset,
268 int type, int symbol)
270 char buf[256];
271 Section *sr;
272 ElfW_Rel *rel;
274 sr = s->reloc;
275 if (!sr) {
276 /* if no relocation section, create it */
277 snprintf(buf, sizeof(buf), REL_SECTION_FMT, s->name);
278 /* if the symtab is allocated, then we consider the relocation
279 are also */
280 sr = new_section(tcc_state, buf, SHT_RELX, symtab->sh_flags);
281 sr->sh_entsize = sizeof(ElfW_Rel);
282 sr->link = symtab;
283 sr->sh_info = s->sh_num;
284 s->reloc = sr;
286 rel = section_ptr_add(sr, sizeof(ElfW_Rel));
287 rel->r_offset = offset;
288 rel->r_info = ELFW(R_INFO)(symbol, type);
289 #ifdef TCC_TARGET_X86_64
290 rel->r_addend = 0;
291 #endif
294 /* put stab debug information */
296 typedef struct {
297 unsigned int n_strx; /* index into string table of name */
298 unsigned char n_type; /* type of symbol */
299 unsigned char n_other; /* misc info (usually empty) */
300 unsigned short n_desc; /* description field */
301 unsigned int n_value; /* value of symbol */
302 } Stab_Sym;
304 static void put_stabs(const char *str, int type, int other, int desc,
305 unsigned long value)
307 Stab_Sym *sym;
309 sym = section_ptr_add(stab_section, sizeof(Stab_Sym));
310 if (str) {
311 sym->n_strx = put_elf_str(stabstr_section, str);
312 } else {
313 sym->n_strx = 0;
315 sym->n_type = type;
316 sym->n_other = other;
317 sym->n_desc = desc;
318 sym->n_value = value;
321 static void put_stabs_r(const char *str, int type, int other, int desc,
322 unsigned long value, Section *sec, int sym_index)
324 put_stabs(str, type, other, desc, value);
325 put_elf_reloc(symtab_section, stab_section,
326 stab_section->data_offset - sizeof(unsigned int),
327 R_DATA_32, sym_index);
330 static void put_stabn(int type, int other, int desc, int value)
332 put_stabs(NULL, type, other, desc, value);
335 static void put_stabd(int type, int other, int desc)
337 put_stabs(NULL, type, other, desc, 0);
340 /* In an ELF file symbol table, the local symbols must appear below
341 the global and weak ones. Since TCC cannot sort it while generating
342 the code, we must do it after. All the relocation tables are also
343 modified to take into account the symbol table sorting */
344 static void sort_syms(TCCState *s1, Section *s)
346 int *old_to_new_syms;
347 ElfW(Sym) *new_syms;
348 int nb_syms, i;
349 ElfW(Sym) *p, *q;
350 ElfW_Rel *rel, *rel_end;
351 Section *sr;
352 int type, sym_index;
354 nb_syms = s->data_offset / sizeof(ElfW(Sym));
355 new_syms = tcc_malloc(nb_syms * sizeof(ElfW(Sym)));
356 old_to_new_syms = tcc_malloc(nb_syms * sizeof(int));
358 /* first pass for local symbols */
359 p = (ElfW(Sym) *)s->data;
360 q = new_syms;
361 for(i = 0; i < nb_syms; i++) {
362 if (ELFW(ST_BIND)(p->st_info) == STB_LOCAL) {
363 old_to_new_syms[i] = q - new_syms;
364 *q++ = *p;
366 p++;
368 /* save the number of local symbols in section header */
369 s->sh_info = q - new_syms;
371 /* then second pass for non local symbols */
372 p = (ElfW(Sym) *)s->data;
373 for(i = 0; i < nb_syms; i++) {
374 if (ELFW(ST_BIND)(p->st_info) != STB_LOCAL) {
375 old_to_new_syms[i] = q - new_syms;
376 *q++ = *p;
378 p++;
381 /* we copy the new symbols to the old */
382 memcpy(s->data, new_syms, nb_syms * sizeof(ElfW(Sym)));
383 tcc_free(new_syms);
385 /* now we modify all the relocations */
386 for(i = 1; i < s1->nb_sections; i++) {
387 sr = s1->sections[i];
388 if (sr->sh_type == SHT_RELX && sr->link == s) {
389 rel_end = (ElfW_Rel *)(sr->data + sr->data_offset);
390 for(rel = (ElfW_Rel *)sr->data;
391 rel < rel_end;
392 rel++) {
393 sym_index = ELFW(R_SYM)(rel->r_info);
394 type = ELFW(R_TYPE)(rel->r_info);
395 sym_index = old_to_new_syms[sym_index];
396 rel->r_info = ELFW(R_INFO)(sym_index, type);
401 tcc_free(old_to_new_syms);
404 /* relocate common symbols in the .bss section */
405 static void relocate_common_syms(void)
407 ElfW(Sym) *sym, *sym_end;
408 unsigned long offset, align;
410 sym_end = (ElfW(Sym) *)(symtab_section->data + symtab_section->data_offset);
411 for(sym = (ElfW(Sym) *)symtab_section->data + 1;
412 sym < sym_end;
413 sym++) {
414 if (sym->st_shndx == SHN_COMMON) {
415 /* align symbol */
416 align = sym->st_value;
417 offset = bss_section->data_offset;
418 offset = (offset + align - 1) & -align;
419 sym->st_value = offset;
420 sym->st_shndx = bss_section->sh_num;
421 offset += sym->st_size;
422 bss_section->data_offset = offset;
427 /* relocate symbol table, resolve undefined symbols if do_resolve is
428 true and output error if undefined symbol. */
429 static void relocate_syms(TCCState *s1, int do_resolve)
431 ElfW(Sym) *sym, *esym, *sym_end;
432 int sym_bind, sh_num, sym_index;
433 const char *name;
434 unsigned long addr;
436 sym_end = (ElfW(Sym) *)(symtab_section->data + symtab_section->data_offset);
437 for(sym = (ElfW(Sym) *)symtab_section->data + 1;
438 sym < sym_end;
439 sym++) {
440 sh_num = sym->st_shndx;
441 if (sh_num == SHN_UNDEF) {
442 name = strtab_section->data + sym->st_name;
443 if (do_resolve) {
444 name = symtab_section->link->data + sym->st_name;
445 addr = (unsigned long)resolve_sym(s1, name, ELFW(ST_TYPE)(sym->st_info));
446 if (addr) {
447 sym->st_value = addr;
448 goto found;
450 } else if (s1->dynsym) {
451 /* if dynamic symbol exist, then use it */
452 sym_index = find_elf_sym(s1->dynsym, name);
453 if (sym_index) {
454 esym = &((ElfW(Sym) *)s1->dynsym->data)[sym_index];
455 sym->st_value = esym->st_value;
456 goto found;
459 /* XXX: _fp_hw seems to be part of the ABI, so we ignore
460 it */
461 if (!strcmp(name, "_fp_hw"))
462 goto found;
463 /* only weak symbols are accepted to be undefined. Their
464 value is zero */
465 sym_bind = ELFW(ST_BIND)(sym->st_info);
466 if (sym_bind == STB_WEAK) {
467 sym->st_value = 0;
468 } else {
469 error_noabort("undefined symbol '%s'", name);
471 } else if (sh_num < SHN_LORESERVE) {
472 /* add section base */
473 sym->st_value += s1->sections[sym->st_shndx]->sh_addr;
475 found: ;
479 #ifdef TCC_TARGET_X86_64
480 #define JMP_TABLE_ENTRY_SIZE 14
481 static unsigned long add_jmp_table(TCCState *s1, unsigned long val)
483 char *p = s1->runtime_plt_and_got + s1->runtime_plt_and_got_offset;
484 s1->runtime_plt_and_got_offset += JMP_TABLE_ENTRY_SIZE;
485 /* jmp *0x0(%rip) */
486 p[0] = 0xff;
487 p[1] = 0x25;
488 *(int *)(p + 2) = 0;
489 *(unsigned long *)(p + 6) = val;
490 return (unsigned long)p;
493 static unsigned long add_got_table(TCCState *s1, unsigned long val)
495 unsigned long *p =(unsigned long *)(s1->runtime_plt_and_got +
496 s1->runtime_plt_and_got_offset);
497 s1->runtime_plt_and_got_offset += sizeof(void *);
498 *p = val;
499 return (unsigned long)p;
501 #endif
503 /* relocate a given section (CPU dependent) */
504 static void relocate_section(TCCState *s1, Section *s)
506 Section *sr;
507 ElfW_Rel *rel, *rel_end, *qrel;
508 ElfW(Sym) *sym;
509 int type, sym_index;
510 unsigned char *ptr;
511 unsigned long val, addr;
512 int esym_index;
514 sr = s->reloc;
515 rel_end = (ElfW_Rel *)(sr->data + sr->data_offset);
516 qrel = (ElfW_Rel *)sr->data;
517 for(rel = qrel;
518 rel < rel_end;
519 rel++) {
520 ptr = s->data + rel->r_offset;
522 sym_index = ELFW(R_SYM)(rel->r_info);
523 sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
524 val = sym->st_value;
525 #ifdef TCC_TARGET_X86_64
526 /* XXX: not tested */
527 val += rel->r_addend;
528 #endif
529 type = ELFW(R_TYPE)(rel->r_info);
530 addr = s->sh_addr + rel->r_offset;
532 /* CPU specific */
533 switch(type) {
534 #if defined(TCC_TARGET_I386)
535 case R_386_32:
536 if (s1->output_type == TCC_OUTPUT_DLL) {
537 esym_index = s1->symtab_to_dynsym[sym_index];
538 qrel->r_offset = rel->r_offset;
539 if (esym_index) {
540 qrel->r_info = ELFW(R_INFO)(esym_index, R_386_32);
541 qrel++;
542 break;
543 } else {
544 qrel->r_info = ELFW(R_INFO)(0, R_386_RELATIVE);
545 qrel++;
548 *(int *)ptr += val;
549 break;
550 case R_386_PC32:
551 if (s1->output_type == TCC_OUTPUT_DLL) {
552 /* DLL relocation */
553 esym_index = s1->symtab_to_dynsym[sym_index];
554 if (esym_index) {
555 qrel->r_offset = rel->r_offset;
556 qrel->r_info = ELFW(R_INFO)(esym_index, R_386_PC32);
557 qrel++;
558 break;
561 *(int *)ptr += val - addr;
562 break;
563 case R_386_PLT32:
564 *(int *)ptr += val - addr;
565 break;
566 case R_386_GLOB_DAT:
567 case R_386_JMP_SLOT:
568 *(int *)ptr = val;
569 break;
570 case R_386_GOTPC:
571 *(int *)ptr += s1->got->sh_addr - addr;
572 break;
573 case R_386_GOTOFF:
574 *(int *)ptr += val - s1->got->sh_addr;
575 break;
576 case R_386_GOT32:
577 /* we load the got offset */
578 *(int *)ptr += s1->got_offsets[sym_index];
579 break;
580 #elif defined(TCC_TARGET_ARM)
581 case R_ARM_PC24:
582 case R_ARM_CALL:
583 case R_ARM_JUMP24:
584 case R_ARM_PLT32:
586 int x;
587 x = (*(int *)ptr)&0xffffff;
588 (*(int *)ptr) &= 0xff000000;
589 if (x & 0x800000)
590 x -= 0x1000000;
591 x *= 4;
592 x += val - addr;
593 if((x & 3) != 0 || x >= 0x4000000 || x < -0x4000000)
594 error("can't relocate value at %x",addr);
595 x >>= 2;
596 x &= 0xffffff;
597 (*(int *)ptr) |= x;
599 break;
600 case R_ARM_PREL31:
602 int x;
603 x = (*(int *)ptr) & 0x7fffffff;
604 (*(int *)ptr) &= 0x80000000;
605 x = (x * 2) / 2;
606 x += val - addr;
607 if((x^(x>>1))&0x40000000)
608 error("can't relocate value at %x",addr);
609 (*(int *)ptr) |= x & 0x7fffffff;
611 case R_ARM_ABS32:
612 *(int *)ptr += val;
613 break;
614 case R_ARM_BASE_PREL:
615 *(int *)ptr += s1->got->sh_addr - addr;
616 break;
617 case R_ARM_GOTOFF32:
618 *(int *)ptr += val - s1->got->sh_addr;
619 break;
620 case R_ARM_GOT_BREL:
621 /* we load the got offset */
622 *(int *)ptr += s1->got_offsets[sym_index];
623 break;
624 case R_ARM_COPY:
625 break;
626 default:
627 fprintf(stderr,"FIXME: handle reloc type %x at %lx [%.8x] to %lx\n",
628 type,addr,(unsigned int )ptr,val);
629 break;
630 #elif defined(TCC_TARGET_C67)
631 case R_C60_32:
632 *(int *)ptr += val;
633 break;
634 case R_C60LO16:
636 uint32_t orig;
638 /* put the low 16 bits of the absolute address */
639 // add to what is already there
641 orig = ((*(int *)(ptr )) >> 7) & 0xffff;
642 orig |= (((*(int *)(ptr+4)) >> 7) & 0xffff) << 16;
644 //patch both at once - assumes always in pairs Low - High
646 *(int *) ptr = (*(int *) ptr & (~(0xffff << 7)) ) | (((val+orig) & 0xffff) << 7);
647 *(int *)(ptr+4) = (*(int *)(ptr+4) & (~(0xffff << 7)) ) | ((((val+orig)>>16) & 0xffff) << 7);
649 break;
650 case R_C60HI16:
651 break;
652 default:
653 fprintf(stderr,"FIXME: handle reloc type %x at %lx [%.8x] to %lx\n",
654 type,addr,(unsigned int )ptr,val);
655 break;
656 #elif defined(TCC_TARGET_X86_64)
657 case R_X86_64_64:
658 if (s1->output_type == TCC_OUTPUT_DLL) {
659 qrel->r_info = ELFW(R_INFO)(0, R_X86_64_RELATIVE);
660 qrel->r_addend = *(long long *)ptr + val;
661 qrel++;
663 *(long long *)ptr += val;
664 break;
665 case R_X86_64_32:
666 case R_X86_64_32S:
667 if (s1->output_type == TCC_OUTPUT_DLL) {
668 /* XXX: this logic may depend on TCC's codegen
669 now TCC uses R_X86_64_32 even for a 64bit pointer */
670 qrel->r_info = ELFW(R_INFO)(0, R_X86_64_RELATIVE);
671 qrel->r_addend = *(int *)ptr + val;
672 qrel++;
674 *(int *)ptr += val;
675 break;
676 case R_X86_64_PC32: {
677 if (s1->output_type == TCC_OUTPUT_DLL) {
678 /* DLL relocation */
679 esym_index = s1->symtab_to_dynsym[sym_index];
680 if (esym_index) {
681 qrel->r_offset = rel->r_offset;
682 qrel->r_info = ELFW(R_INFO)(esym_index, R_X86_64_PC32);
683 qrel->r_addend = *(int *)ptr;
684 qrel++;
685 break;
688 long diff = val - addr;
689 if (diff <= -2147483647 || diff > 2147483647) {
690 /* XXX: naive support for over 32bit jump */
691 if (s1->output_type == TCC_OUTPUT_MEMORY) {
692 val = add_jmp_table(s1, val);
693 diff = val - addr;
695 if (diff <= -2147483647 || diff > 2147483647) {
696 error("internal error: relocation failed");
699 *(int *)ptr += diff;
701 break;
702 case R_X86_64_PLT32:
703 *(int *)ptr += val - addr;
704 break;
705 case R_X86_64_GLOB_DAT:
706 case R_X86_64_JUMP_SLOT:
707 *(int *)ptr = val;
708 break;
709 case R_X86_64_GOTPCREL:
710 if (s1->output_type == TCC_OUTPUT_MEMORY) {
711 val = add_got_table(s1, val - rel->r_addend) + rel->r_addend;
712 *(int *)ptr += val - addr;
713 break;
715 *(int *)ptr += (s1->got->sh_addr - addr +
716 s1->got_offsets[sym_index] - 4);
717 break;
718 case R_X86_64_GOTTPOFF:
719 *(int *)ptr += val - s1->got->sh_addr;
720 break;
721 case R_X86_64_GOT32:
722 /* we load the got offset */
723 *(int *)ptr += s1->got_offsets[sym_index];
724 break;
725 #else
726 #error unsupported processor
727 #endif
730 /* if the relocation is allocated, we change its symbol table */
731 if (sr->sh_flags & SHF_ALLOC)
732 sr->link = s1->dynsym;
735 /* relocate relocation table in 'sr' */
736 static void relocate_rel(TCCState *s1, Section *sr)
738 Section *s;
739 ElfW_Rel *rel, *rel_end;
741 s = s1->sections[sr->sh_info];
742 rel_end = (ElfW_Rel *)(sr->data + sr->data_offset);
743 for(rel = (ElfW_Rel *)sr->data;
744 rel < rel_end;
745 rel++) {
746 rel->r_offset += s->sh_addr;
750 /* count the number of dynamic relocations so that we can reserve
751 their space */
752 static int prepare_dynamic_rel(TCCState *s1, Section *sr)
754 ElfW_Rel *rel, *rel_end;
755 int sym_index, esym_index, type, count;
757 count = 0;
758 rel_end = (ElfW_Rel *)(sr->data + sr->data_offset);
759 for(rel = (ElfW_Rel *)sr->data; rel < rel_end; rel++) {
760 sym_index = ELFW(R_SYM)(rel->r_info);
761 type = ELFW(R_TYPE)(rel->r_info);
762 switch(type) {
763 #if defined(TCC_TARGET_I386)
764 case R_386_32:
765 #elif defined(TCC_TARGET_X86_64)
766 case R_X86_64_32:
767 case R_X86_64_32S:
768 case R_X86_64_64:
769 #endif
770 count++;
771 break;
772 #if defined(TCC_TARGET_I386)
773 case R_386_PC32:
774 #elif defined(TCC_TARGET_X86_64)
775 case R_X86_64_PC32:
776 #endif
777 esym_index = s1->symtab_to_dynsym[sym_index];
778 if (esym_index)
779 count++;
780 break;
781 default:
782 break;
785 if (count) {
786 /* allocate the section */
787 sr->sh_flags |= SHF_ALLOC;
788 sr->sh_size = count * sizeof(ElfW_Rel);
790 return count;
793 static void put_got_offset(TCCState *s1, int index, unsigned long val)
795 int n;
796 unsigned long *tab;
798 if (index >= s1->nb_got_offsets) {
799 /* find immediately bigger power of 2 and reallocate array */
800 n = 1;
801 while (index >= n)
802 n *= 2;
803 tab = tcc_realloc(s1->got_offsets, n * sizeof(unsigned long));
804 if (!tab)
805 error("memory full");
806 s1->got_offsets = tab;
807 memset(s1->got_offsets + s1->nb_got_offsets, 0,
808 (n - s1->nb_got_offsets) * sizeof(unsigned long));
809 s1->nb_got_offsets = n;
811 s1->got_offsets[index] = val;
814 /* XXX: suppress that */
815 static void put32(unsigned char *p, uint32_t val)
817 p[0] = val;
818 p[1] = val >> 8;
819 p[2] = val >> 16;
820 p[3] = val >> 24;
823 #if defined(TCC_TARGET_I386) || defined(TCC_TARGET_ARM) || \
824 defined(TCC_TARGET_X86_64)
825 static uint32_t get32(unsigned char *p)
827 return p[0] | (p[1] << 8) | (p[2] << 16) | (p[3] << 24);
829 #endif
831 static void build_got(TCCState *s1)
833 unsigned char *ptr;
835 /* if no got, then create it */
836 s1->got = new_section(s1, ".got", SHT_PROGBITS, SHF_ALLOC | SHF_WRITE);
837 s1->got->sh_entsize = 4;
838 add_elf_sym(symtab_section, 0, 4, ELFW(ST_INFO)(STB_GLOBAL, STT_OBJECT),
839 0, s1->got->sh_num, "_GLOBAL_OFFSET_TABLE_");
840 ptr = section_ptr_add(s1->got, 3 * PTR_SIZE);
841 #if PTR_SIZE == 4
842 /* keep space for _DYNAMIC pointer, if present */
843 put32(ptr, 0);
844 /* two dummy got entries */
845 put32(ptr + 4, 0);
846 put32(ptr + 8, 0);
847 #else
848 /* keep space for _DYNAMIC pointer, if present */
849 put32(ptr, 0);
850 put32(ptr + 4, 0);
851 /* two dummy got entries */
852 put32(ptr + 8, 0);
853 put32(ptr + 12, 0);
854 put32(ptr + 16, 0);
855 put32(ptr + 20, 0);
856 #endif
859 /* put a got entry corresponding to a symbol in symtab_section. 'size'
860 and 'info' can be modifed if more precise info comes from the DLL */
861 static void put_got_entry(TCCState *s1,
862 int reloc_type, unsigned long size, int info,
863 int sym_index)
865 int index;
866 const char *name;
867 ElfW(Sym) *sym;
868 unsigned long offset;
869 int *ptr;
871 if (!s1->got)
872 build_got(s1);
874 /* if a got entry already exists for that symbol, no need to add one */
875 if (sym_index < s1->nb_got_offsets &&
876 s1->got_offsets[sym_index] != 0)
877 return;
879 put_got_offset(s1, sym_index, s1->got->data_offset);
881 if (s1->dynsym) {
882 sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
883 name = symtab_section->link->data + sym->st_name;
884 offset = sym->st_value;
885 #if defined(TCC_TARGET_I386) || defined(TCC_TARGET_X86_64)
886 if (reloc_type ==
887 #ifdef TCC_TARGET_X86_64
888 R_X86_64_JUMP_SLOT
889 #else
890 R_386_JMP_SLOT
891 #endif
893 Section *plt;
894 uint8_t *p;
895 int modrm;
897 #if defined(TCC_OUTPUT_DLL_WITH_PLT)
898 modrm = 0x25;
899 #else
900 /* if we build a DLL, we add a %ebx offset */
901 if (s1->output_type == TCC_OUTPUT_DLL)
902 modrm = 0xa3;
903 else
904 modrm = 0x25;
905 #endif
907 /* add a PLT entry */
908 plt = s1->plt;
909 if (plt->data_offset == 0) {
910 /* first plt entry */
911 p = section_ptr_add(plt, 16);
912 p[0] = 0xff; /* pushl got + PTR_SIZE */
913 p[1] = modrm + 0x10;
914 put32(p + 2, PTR_SIZE);
915 p[6] = 0xff; /* jmp *(got + PTR_SIZE * 2) */
916 p[7] = modrm;
917 put32(p + 8, PTR_SIZE * 2);
920 p = section_ptr_add(plt, 16);
921 p[0] = 0xff; /* jmp *(got + x) */
922 p[1] = modrm;
923 put32(p + 2, s1->got->data_offset);
924 p[6] = 0x68; /* push $xxx */
925 put32(p + 7, (plt->data_offset - 32) >> 1);
926 p[11] = 0xe9; /* jmp plt_start */
927 put32(p + 12, -(plt->data_offset));
929 /* the symbol is modified so that it will be relocated to
930 the PLT */
931 #if !defined(TCC_OUTPUT_DLL_WITH_PLT)
932 if (s1->output_type == TCC_OUTPUT_EXE)
933 #endif
934 offset = plt->data_offset - 16;
936 #elif defined(TCC_TARGET_ARM)
937 if (reloc_type == R_ARM_JUMP_SLOT) {
938 Section *plt;
939 uint8_t *p;
941 /* if we build a DLL, we add a %ebx offset */
942 if (s1->output_type == TCC_OUTPUT_DLL)
943 error("DLLs unimplemented!");
945 /* add a PLT entry */
946 plt = s1->plt;
947 if (plt->data_offset == 0) {
948 /* first plt entry */
949 p = section_ptr_add(plt, 16);
950 put32(p , 0xe52de004);
951 put32(p + 4, 0xe59fe010);
952 put32(p + 8, 0xe08fe00e);
953 put32(p + 12, 0xe5bef008);
956 p = section_ptr_add(plt, 16);
957 put32(p , 0xe59fc004);
958 put32(p+4, 0xe08fc00c);
959 put32(p+8, 0xe59cf000);
960 put32(p+12, s1->got->data_offset);
962 /* the symbol is modified so that it will be relocated to
963 the PLT */
964 if (s1->output_type == TCC_OUTPUT_EXE)
965 offset = plt->data_offset - 16;
967 #elif defined(TCC_TARGET_C67)
968 error("C67 got not implemented");
969 #else
970 #error unsupported CPU
971 #endif
972 index = put_elf_sym(s1->dynsym, offset,
973 size, info, 0, sym->st_shndx, name);
974 /* put a got entry */
975 put_elf_reloc(s1->dynsym, s1->got,
976 s1->got->data_offset,
977 reloc_type, index);
979 ptr = section_ptr_add(s1->got, PTR_SIZE);
980 *ptr = 0;
983 /* build GOT and PLT entries */
984 static void build_got_entries(TCCState *s1)
986 Section *s, *symtab;
987 ElfW_Rel *rel, *rel_end;
988 ElfW(Sym) *sym;
989 int i, type, reloc_type, sym_index;
991 for(i = 1; i < s1->nb_sections; i++) {
992 s = s1->sections[i];
993 if (s->sh_type != SHT_RELX)
994 continue;
995 /* no need to handle got relocations */
996 if (s->link != symtab_section)
997 continue;
998 symtab = s->link;
999 rel_end = (ElfW_Rel *)(s->data + s->data_offset);
1000 for(rel = (ElfW_Rel *)s->data;
1001 rel < rel_end;
1002 rel++) {
1003 type = ELFW(R_TYPE)(rel->r_info);
1004 switch(type) {
1005 #if defined(TCC_TARGET_I386)
1006 case R_386_GOT32:
1007 case R_386_GOTOFF:
1008 case R_386_GOTPC:
1009 case R_386_PLT32:
1010 if (!s1->got)
1011 build_got(s1);
1012 if (type == R_386_GOT32 || type == R_386_PLT32) {
1013 sym_index = ELFW(R_SYM)(rel->r_info);
1014 sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
1015 /* look at the symbol got offset. If none, then add one */
1016 if (type == R_386_GOT32)
1017 reloc_type = R_386_GLOB_DAT;
1018 else
1019 reloc_type = R_386_JMP_SLOT;
1020 put_got_entry(s1, reloc_type, sym->st_size, sym->st_info,
1021 sym_index);
1023 break;
1024 #elif defined(TCC_TARGET_ARM)
1025 case R_ARM_GOT_BREL:
1026 case R_ARM_GOTOFF32:
1027 case R_ARM_BASE_PREL:
1028 case R_ARM_PLT32:
1029 if (!s1->got)
1030 build_got(s1);
1031 if (type == R_ARM_GOT_BREL || type == R_ARM_PLT32) {
1032 sym_index = ELFW(R_SYM)(rel->r_info);
1033 sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
1034 /* look at the symbol got offset. If none, then add one */
1035 if (type == R_ARM_GOT_BREL)
1036 reloc_type = R_ARM_GLOB_DAT;
1037 else
1038 reloc_type = R_ARM_JUMP_SLOT;
1039 put_got_entry(s1, reloc_type, sym->st_size, sym->st_info,
1040 sym_index);
1042 break;
1043 #elif defined(TCC_TARGET_C67)
1044 case R_C60_GOT32:
1045 case R_C60_GOTOFF:
1046 case R_C60_GOTPC:
1047 case R_C60_PLT32:
1048 if (!s1->got)
1049 build_got(s1);
1050 if (type == R_C60_GOT32 || type == R_C60_PLT32) {
1051 sym_index = ELFW(R_SYM)(rel->r_info);
1052 sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
1053 /* look at the symbol got offset. If none, then add one */
1054 if (type == R_C60_GOT32)
1055 reloc_type = R_C60_GLOB_DAT;
1056 else
1057 reloc_type = R_C60_JMP_SLOT;
1058 put_got_entry(s1, reloc_type, sym->st_size, sym->st_info,
1059 sym_index);
1061 break;
1062 #elif defined(TCC_TARGET_X86_64)
1063 case R_X86_64_GOT32:
1064 case R_X86_64_GOTTPOFF:
1065 case R_X86_64_GOTPCREL:
1066 case R_X86_64_PLT32:
1067 if (!s1->got)
1068 build_got(s1);
1069 if (type == R_X86_64_GOT32 || type == R_X86_64_GOTPCREL ||
1070 type == R_X86_64_PLT32) {
1071 sym_index = ELFW(R_SYM)(rel->r_info);
1072 sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
1073 /* look at the symbol got offset. If none, then add one */
1074 if (type == R_X86_64_GOT32 || type == R_X86_64_GOTPCREL)
1075 reloc_type = R_X86_64_GLOB_DAT;
1076 else
1077 reloc_type = R_X86_64_JUMP_SLOT;
1078 put_got_entry(s1, reloc_type, sym->st_size, sym->st_info,
1079 sym_index);
1081 break;
1082 #else
1083 #error unsupported CPU
1084 #endif
1085 default:
1086 break;
1092 static Section *new_symtab(TCCState *s1,
1093 const char *symtab_name, int sh_type, int sh_flags,
1094 const char *strtab_name,
1095 const char *hash_name, int hash_sh_flags)
1097 Section *symtab, *strtab, *hash;
1098 int *ptr, nb_buckets;
1100 symtab = new_section(s1, symtab_name, sh_type, sh_flags);
1101 symtab->sh_entsize = sizeof(ElfW(Sym));
1102 strtab = new_section(s1, strtab_name, SHT_STRTAB, sh_flags);
1103 put_elf_str(strtab, "");
1104 symtab->link = strtab;
1105 put_elf_sym(symtab, 0, 0, 0, 0, 0, NULL);
1107 nb_buckets = 1;
1109 hash = new_section(s1, hash_name, SHT_HASH, hash_sh_flags);
1110 hash->sh_entsize = sizeof(int);
1111 symtab->hash = hash;
1112 hash->link = symtab;
1114 ptr = section_ptr_add(hash, (2 + nb_buckets + 1) * sizeof(int));
1115 ptr[0] = nb_buckets;
1116 ptr[1] = 1;
1117 memset(ptr + 2, 0, (nb_buckets + 1) * sizeof(int));
1118 return symtab;
1121 /* put dynamic tag */
1122 static void put_dt(Section *dynamic, int dt, unsigned long val)
1124 ElfW(Dyn) *dyn;
1125 dyn = section_ptr_add(dynamic, sizeof(ElfW(Dyn)));
1126 dyn->d_tag = dt;
1127 dyn->d_un.d_val = val;
1130 static void add_init_array_defines(TCCState *s1, const char *section_name)
1132 Section *s;
1133 long end_offset;
1134 char sym_start[1024];
1135 char sym_end[1024];
1137 snprintf(sym_start, sizeof(sym_start), "__%s_start", section_name + 1);
1138 snprintf(sym_end, sizeof(sym_end), "__%s_end", section_name + 1);
1140 s = find_section(s1, section_name);
1141 if (!s) {
1142 end_offset = 0;
1143 s = data_section;
1144 } else {
1145 end_offset = s->data_offset;
1148 add_elf_sym(symtab_section,
1149 0, 0,
1150 ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
1151 s->sh_num, sym_start);
1152 add_elf_sym(symtab_section,
1153 end_offset, 0,
1154 ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
1155 s->sh_num, sym_end);
1158 /* add tcc runtime libraries */
1159 static void tcc_add_runtime(TCCState *s1)
1161 #if defined(CONFIG_TCC_BCHECK) || !defined(CONFIG_USE_LIBGCC)
1162 char buf[1024];
1163 #endif
1165 #ifdef CONFIG_TCC_BCHECK
1166 if (do_bounds_check) {
1167 unsigned long *ptr;
1168 Section *init_section;
1169 unsigned char *pinit;
1170 int sym_index;
1172 /* XXX: add an object file to do that */
1173 ptr = section_ptr_add(bounds_section, sizeof(unsigned long));
1174 *ptr = 0;
1175 add_elf_sym(symtab_section, 0, 0,
1176 ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
1177 bounds_section->sh_num, "__bounds_start");
1178 /* add bound check code */
1179 snprintf(buf, sizeof(buf), "%s/%s", tcc_lib_path, "bcheck.o");
1180 tcc_add_file(s1, buf);
1181 #ifdef TCC_TARGET_I386
1182 if (s1->output_type != TCC_OUTPUT_MEMORY) {
1183 /* add 'call __bound_init()' in .init section */
1184 init_section = find_section(s1, ".init");
1185 pinit = section_ptr_add(init_section, 5);
1186 pinit[0] = 0xe8;
1187 put32(pinit + 1, -4);
1188 sym_index = find_elf_sym(symtab_section, "__bound_init");
1189 put_elf_reloc(symtab_section, init_section,
1190 init_section->data_offset - 4, R_386_PC32, sym_index);
1192 #endif
1194 #endif
1195 /* add libc */
1196 if (!s1->nostdlib) {
1197 tcc_add_library(s1, "c");
1199 #ifdef CONFIG_USE_LIBGCC
1200 tcc_add_file(s1, CONFIG_SYSROOT "/lib/libgcc_s.so.1");
1201 #else
1202 snprintf(buf, sizeof(buf), "%s/%s", tcc_lib_path, "libtcc1.a");
1203 tcc_add_file(s1, buf);
1204 #endif
1206 /* add crt end if not memory output */
1207 if (s1->output_type != TCC_OUTPUT_MEMORY && !s1->nostdlib) {
1208 tcc_add_file(s1, CONFIG_TCC_CRT_PREFIX "/crtn.o");
1212 /* add various standard linker symbols (must be done after the
1213 sections are filled (for example after allocating common
1214 symbols)) */
1215 static void tcc_add_linker_symbols(TCCState *s1)
1217 char buf[1024];
1218 int i;
1219 Section *s;
1221 add_elf_sym(symtab_section,
1222 text_section->data_offset, 0,
1223 ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
1224 text_section->sh_num, "_etext");
1225 add_elf_sym(symtab_section,
1226 data_section->data_offset, 0,
1227 ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
1228 data_section->sh_num, "_edata");
1229 add_elf_sym(symtab_section,
1230 bss_section->data_offset, 0,
1231 ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
1232 bss_section->sh_num, "_end");
1233 /* horrible new standard ldscript defines */
1234 add_init_array_defines(s1, ".preinit_array");
1235 add_init_array_defines(s1, ".init_array");
1236 add_init_array_defines(s1, ".fini_array");
1238 /* add start and stop symbols for sections whose name can be
1239 expressed in C */
1240 for(i = 1; i < s1->nb_sections; i++) {
1241 s = s1->sections[i];
1242 if (s->sh_type == SHT_PROGBITS &&
1243 (s->sh_flags & SHF_ALLOC)) {
1244 const char *p;
1245 int ch;
1247 /* check if section name can be expressed in C */
1248 p = s->name;
1249 for(;;) {
1250 ch = *p;
1251 if (!ch)
1252 break;
1253 if (!isid(ch) && !isnum(ch))
1254 goto next_sec;
1255 p++;
1257 snprintf(buf, sizeof(buf), "__start_%s", s->name);
1258 add_elf_sym(symtab_section,
1259 0, 0,
1260 ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
1261 s->sh_num, buf);
1262 snprintf(buf, sizeof(buf), "__stop_%s", s->name);
1263 add_elf_sym(symtab_section,
1264 s->data_offset, 0,
1265 ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
1266 s->sh_num, buf);
1268 next_sec: ;
1272 /* name of ELF interpreter */
1273 #ifdef __FreeBSD__
1274 static char elf_interp[] = "/usr/libexec/ld-elf.so.1";
1275 #else
1276 #ifdef TCC_ARM_EABI
1277 static char elf_interp[] = "/lib/ld-linux.so.3";
1278 #elif defined(TCC_TARGET_X86_64)
1279 static char elf_interp[] = "/lib/ld-linux-x86-64.so.2";
1280 #else
1281 static char elf_interp[] = "/lib/ld-linux.so.2";
1282 #endif
1283 #endif
1285 static void tcc_output_binary(TCCState *s1, FILE *f,
1286 const int *section_order)
1288 Section *s;
1289 int i, offset, size;
1291 offset = 0;
1292 for(i=1;i<s1->nb_sections;i++) {
1293 s = s1->sections[section_order[i]];
1294 if (s->sh_type != SHT_NOBITS &&
1295 (s->sh_flags & SHF_ALLOC)) {
1296 while (offset < s->sh_offset) {
1297 fputc(0, f);
1298 offset++;
1300 size = s->sh_size;
1301 fwrite(s->data, 1, size, f);
1302 offset += size;
1307 /* output an ELF file */
1308 /* XXX: suppress unneeded sections */
1309 int elf_output_file(TCCState *s1, const char *filename)
1311 ElfW(Ehdr) ehdr;
1312 FILE *f;
1313 int fd, mode, ret;
1314 int *section_order;
1315 int shnum, i, phnum, file_offset, offset, size, j, tmp, sh_order_index, k;
1316 unsigned long addr;
1317 Section *strsec, *s;
1318 ElfW(Shdr) shdr, *sh;
1319 ElfW(Phdr) *phdr, *ph;
1320 Section *interp, *dynamic, *dynstr;
1321 unsigned long saved_dynamic_data_offset;
1322 ElfW(Sym) *sym;
1323 int type, file_type;
1324 unsigned long rel_addr, rel_size;
1326 file_type = s1->output_type;
1327 s1->nb_errors = 0;
1329 if (file_type != TCC_OUTPUT_OBJ) {
1330 tcc_add_runtime(s1);
1333 phdr = NULL;
1334 section_order = NULL;
1335 interp = NULL;
1336 dynamic = NULL;
1337 dynstr = NULL; /* avoid warning */
1338 saved_dynamic_data_offset = 0; /* avoid warning */
1340 if (file_type != TCC_OUTPUT_OBJ) {
1341 relocate_common_syms();
1343 tcc_add_linker_symbols(s1);
1345 if (!s1->static_link) {
1346 const char *name;
1347 int sym_index, index;
1348 ElfW(Sym) *esym, *sym_end;
1350 if (file_type == TCC_OUTPUT_EXE) {
1351 char *ptr;
1352 /* add interpreter section only if executable */
1353 interp = new_section(s1, ".interp", SHT_PROGBITS, SHF_ALLOC);
1354 interp->sh_addralign = 1;
1355 ptr = section_ptr_add(interp, sizeof(elf_interp));
1356 strcpy(ptr, elf_interp);
1359 /* add dynamic symbol table */
1360 s1->dynsym = new_symtab(s1, ".dynsym", SHT_DYNSYM, SHF_ALLOC,
1361 ".dynstr",
1362 ".hash", SHF_ALLOC);
1363 dynstr = s1->dynsym->link;
1365 /* add dynamic section */
1366 dynamic = new_section(s1, ".dynamic", SHT_DYNAMIC,
1367 SHF_ALLOC | SHF_WRITE);
1368 dynamic->link = dynstr;
1369 dynamic->sh_entsize = sizeof(ElfW(Dyn));
1371 /* add PLT */
1372 s1->plt = new_section(s1, ".plt", SHT_PROGBITS,
1373 SHF_ALLOC | SHF_EXECINSTR);
1374 s1->plt->sh_entsize = 4;
1376 build_got(s1);
1378 /* scan for undefined symbols and see if they are in the
1379 dynamic symbols. If a symbol STT_FUNC is found, then we
1380 add it in the PLT. If a symbol STT_OBJECT is found, we
1381 add it in the .bss section with a suitable relocation */
1382 sym_end = (ElfW(Sym) *)(symtab_section->data +
1383 symtab_section->data_offset);
1384 if (file_type == TCC_OUTPUT_EXE) {
1385 for(sym = (ElfW(Sym) *)symtab_section->data + 1;
1386 sym < sym_end;
1387 sym++) {
1388 if (sym->st_shndx == SHN_UNDEF) {
1389 name = symtab_section->link->data + sym->st_name;
1390 sym_index = find_elf_sym(s1->dynsymtab_section, name);
1391 if (sym_index) {
1392 esym = &((ElfW(Sym) *)s1->dynsymtab_section->data)[sym_index];
1393 type = ELFW(ST_TYPE)(esym->st_info);
1394 if (type == STT_FUNC) {
1395 put_got_entry(s1, R_JMP_SLOT, esym->st_size,
1396 esym->st_info,
1397 sym - (ElfW(Sym) *)symtab_section->data);
1398 } else if (type == STT_OBJECT) {
1399 unsigned long offset;
1400 offset = bss_section->data_offset;
1401 /* XXX: which alignment ? */
1402 offset = (offset + 16 - 1) & -16;
1403 index = put_elf_sym(s1->dynsym, offset, esym->st_size,
1404 esym->st_info, 0,
1405 bss_section->sh_num, name);
1406 put_elf_reloc(s1->dynsym, bss_section,
1407 offset, R_COPY, index);
1408 offset += esym->st_size;
1409 bss_section->data_offset = offset;
1411 } else {
1412 /* STB_WEAK undefined symbols are accepted */
1413 /* XXX: _fp_hw seems to be part of the ABI, so we ignore
1414 it */
1415 if (ELFW(ST_BIND)(sym->st_info) == STB_WEAK ||
1416 !strcmp(name, "_fp_hw")) {
1417 } else {
1418 error_noabort("undefined symbol '%s'", name);
1421 } else if (s1->rdynamic &&
1422 ELFW(ST_BIND)(sym->st_info) != STB_LOCAL) {
1423 /* if -rdynamic option, then export all non
1424 local symbols */
1425 name = symtab_section->link->data + sym->st_name;
1426 put_elf_sym(s1->dynsym, sym->st_value, sym->st_size,
1427 sym->st_info, 0,
1428 sym->st_shndx, name);
1432 if (s1->nb_errors)
1433 goto fail;
1435 /* now look at unresolved dynamic symbols and export
1436 corresponding symbol */
1437 sym_end = (ElfW(Sym) *)(s1->dynsymtab_section->data +
1438 s1->dynsymtab_section->data_offset);
1439 for(esym = (ElfW(Sym) *)s1->dynsymtab_section->data + 1;
1440 esym < sym_end;
1441 esym++) {
1442 if (esym->st_shndx == SHN_UNDEF) {
1443 name = s1->dynsymtab_section->link->data + esym->st_name;
1444 sym_index = find_elf_sym(symtab_section, name);
1445 if (sym_index) {
1446 /* XXX: avoid adding a symbol if already
1447 present because of -rdynamic ? */
1448 sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
1449 put_elf_sym(s1->dynsym, sym->st_value, sym->st_size,
1450 sym->st_info, 0,
1451 sym->st_shndx, name);
1452 } else {
1453 if (ELFW(ST_BIND)(esym->st_info) == STB_WEAK) {
1454 /* weak symbols can stay undefined */
1455 } else {
1456 warning("undefined dynamic symbol '%s'", name);
1461 } else {
1462 int nb_syms;
1463 /* shared library case : we simply export all the global symbols */
1464 nb_syms = symtab_section->data_offset / sizeof(ElfW(Sym));
1465 s1->symtab_to_dynsym = tcc_mallocz(sizeof(int) * nb_syms);
1466 for(sym = (ElfW(Sym) *)symtab_section->data + 1;
1467 sym < sym_end;
1468 sym++) {
1469 if (ELFW(ST_BIND)(sym->st_info) != STB_LOCAL) {
1470 #if defined(TCC_OUTPUT_DLL_WITH_PLT)
1471 if (ELFW(ST_TYPE)(sym->st_info) == STT_FUNC &&
1472 sym->st_shndx == SHN_UNDEF) {
1473 put_got_entry(s1, R_JMP_SLOT, sym->st_size,
1474 sym->st_info,
1475 sym - (ElfW(Sym) *)symtab_section->data);
1477 else if (ELFW(ST_TYPE)(sym->st_info) == STT_OBJECT) {
1478 put_got_entry(s1, R_X86_64_GLOB_DAT, sym->st_size,
1479 sym->st_info,
1480 sym - (ElfW(Sym) *)symtab_section->data);
1482 else
1483 #endif
1485 name = symtab_section->link->data + sym->st_name;
1486 index = put_elf_sym(s1->dynsym, sym->st_value, sym->st_size,
1487 sym->st_info, 0,
1488 sym->st_shndx, name);
1489 s1->symtab_to_dynsym[sym -
1490 (ElfW(Sym) *)symtab_section->data] =
1491 index;
1497 build_got_entries(s1);
1499 /* add a list of needed dlls */
1500 for(i = 0; i < s1->nb_loaded_dlls; i++) {
1501 DLLReference *dllref = s1->loaded_dlls[i];
1502 if (dllref->level == 0)
1503 put_dt(dynamic, DT_NEEDED, put_elf_str(dynstr, dllref->name));
1505 /* XXX: currently, since we do not handle PIC code, we
1506 must relocate the readonly segments */
1507 if (file_type == TCC_OUTPUT_DLL) {
1508 if (s1->soname)
1509 put_dt(dynamic, DT_SONAME, put_elf_str(dynstr, s1->soname));
1510 put_dt(dynamic, DT_TEXTREL, 0);
1513 /* add necessary space for other entries */
1514 saved_dynamic_data_offset = dynamic->data_offset;
1515 dynamic->data_offset += sizeof(ElfW(Dyn)) * 9;
1516 } else {
1517 /* still need to build got entries in case of static link */
1518 build_got_entries(s1);
1522 memset(&ehdr, 0, sizeof(ehdr));
1524 /* we add a section for symbols */
1525 strsec = new_section(s1, ".shstrtab", SHT_STRTAB, 0);
1526 put_elf_str(strsec, "");
1528 /* compute number of sections */
1529 shnum = s1->nb_sections;
1531 /* this array is used to reorder sections in the output file */
1532 section_order = tcc_malloc(sizeof(int) * shnum);
1533 section_order[0] = 0;
1534 sh_order_index = 1;
1536 /* compute number of program headers */
1537 switch(file_type) {
1538 default:
1539 case TCC_OUTPUT_OBJ:
1540 phnum = 0;
1541 break;
1542 case TCC_OUTPUT_EXE:
1543 if (!s1->static_link)
1544 phnum = 4;
1545 else
1546 phnum = 2;
1547 break;
1548 case TCC_OUTPUT_DLL:
1549 phnum = 3;
1550 break;
1553 /* allocate strings for section names and decide if an unallocated
1554 section should be output */
1555 /* NOTE: the strsec section comes last, so its size is also
1556 correct ! */
1557 for(i = 1; i < s1->nb_sections; i++) {
1558 s = s1->sections[i];
1559 s->sh_name = put_elf_str(strsec, s->name);
1560 #if 0 //gr
1561 printf("section: f=%08x t=%08x i=%08x %s %s\n",
1562 s->sh_flags,
1563 s->sh_type,
1564 s->sh_info,
1565 s->name,
1566 s->reloc ? s->reloc->name : "n"
1568 #endif
1569 /* when generating a DLL, we include relocations but we may
1570 patch them */
1571 if (file_type == TCC_OUTPUT_DLL &&
1572 s->sh_type == SHT_RELX &&
1573 !(s->sh_flags & SHF_ALLOC)) {
1574 /* //gr: avoid bogus relocs for empty (debug) sections */
1575 if (s1->sections[s->sh_info]->sh_flags & SHF_ALLOC)
1576 prepare_dynamic_rel(s1, s);
1577 else if (do_debug)
1578 s->sh_size = s->data_offset;
1579 } else if (do_debug ||
1580 file_type == TCC_OUTPUT_OBJ ||
1581 (s->sh_flags & SHF_ALLOC) ||
1582 i == (s1->nb_sections - 1)) {
1583 /* we output all sections if debug or object file */
1584 s->sh_size = s->data_offset;
1588 /* allocate program segment headers */
1589 phdr = tcc_mallocz(phnum * sizeof(ElfW(Phdr)));
1591 if (s1->output_format == TCC_OUTPUT_FORMAT_ELF) {
1592 file_offset = sizeof(ElfW(Ehdr)) + phnum * sizeof(ElfW(Phdr));
1593 } else {
1594 file_offset = 0;
1596 if (phnum > 0) {
1597 /* compute section to program header mapping */
1598 if (s1->has_text_addr) {
1599 int a_offset, p_offset;
1600 addr = s1->text_addr;
1601 /* we ensure that (addr % ELF_PAGE_SIZE) == file_offset %
1602 ELF_PAGE_SIZE */
1603 a_offset = addr & (ELF_PAGE_SIZE - 1);
1604 p_offset = file_offset & (ELF_PAGE_SIZE - 1);
1605 if (a_offset < p_offset)
1606 a_offset += ELF_PAGE_SIZE;
1607 file_offset += (a_offset - p_offset);
1608 } else {
1609 if (file_type == TCC_OUTPUT_DLL)
1610 addr = 0;
1611 else
1612 addr = ELF_START_ADDR;
1613 /* compute address after headers */
1614 addr += (file_offset & (ELF_PAGE_SIZE - 1));
1617 /* dynamic relocation table information, for .dynamic section */
1618 rel_size = 0;
1619 rel_addr = 0;
1621 /* leave one program header for the program interpreter */
1622 ph = &phdr[0];
1623 if (interp)
1624 ph++;
1626 for(j = 0; j < 2; j++) {
1627 ph->p_type = PT_LOAD;
1628 if (j == 0)
1629 ph->p_flags = PF_R | PF_X;
1630 else
1631 ph->p_flags = PF_R | PF_W;
1632 ph->p_align = ELF_PAGE_SIZE;
1634 /* we do the following ordering: interp, symbol tables,
1635 relocations, progbits, nobits */
1636 /* XXX: do faster and simpler sorting */
1637 for(k = 0; k < 5; k++) {
1638 for(i = 1; i < s1->nb_sections; i++) {
1639 s = s1->sections[i];
1640 /* compute if section should be included */
1641 if (j == 0) {
1642 if ((s->sh_flags & (SHF_ALLOC | SHF_WRITE)) !=
1643 SHF_ALLOC)
1644 continue;
1645 } else {
1646 if ((s->sh_flags & (SHF_ALLOC | SHF_WRITE)) !=
1647 (SHF_ALLOC | SHF_WRITE))
1648 continue;
1650 if (s == interp) {
1651 if (k != 0)
1652 continue;
1653 } else if (s->sh_type == SHT_DYNSYM ||
1654 s->sh_type == SHT_STRTAB ||
1655 s->sh_type == SHT_HASH) {
1656 if (k != 1)
1657 continue;
1658 } else if (s->sh_type == SHT_RELX) {
1659 if (k != 2)
1660 continue;
1661 } else if (s->sh_type == SHT_NOBITS) {
1662 if (k != 4)
1663 continue;
1664 } else {
1665 if (k != 3)
1666 continue;
1668 section_order[sh_order_index++] = i;
1670 /* section matches: we align it and add its size */
1671 tmp = addr;
1672 addr = (addr + s->sh_addralign - 1) &
1673 ~(s->sh_addralign - 1);
1674 file_offset += addr - tmp;
1675 s->sh_offset = file_offset;
1676 s->sh_addr = addr;
1678 /* update program header infos */
1679 if (ph->p_offset == 0) {
1680 ph->p_offset = file_offset;
1681 ph->p_vaddr = addr;
1682 ph->p_paddr = ph->p_vaddr;
1684 /* update dynamic relocation infos */
1685 if (s->sh_type == SHT_RELX) {
1686 if (rel_size == 0)
1687 rel_addr = addr;
1688 rel_size += s->sh_size;
1690 addr += s->sh_size;
1691 if (s->sh_type != SHT_NOBITS)
1692 file_offset += s->sh_size;
1695 ph->p_filesz = file_offset - ph->p_offset;
1696 ph->p_memsz = addr - ph->p_vaddr;
1697 ph++;
1698 if (j == 0) {
1699 if (s1->output_format == TCC_OUTPUT_FORMAT_ELF) {
1700 /* if in the middle of a page, we duplicate the page in
1701 memory so that one copy is RX and the other is RW */
1702 if ((addr & (ELF_PAGE_SIZE - 1)) != 0)
1703 addr += ELF_PAGE_SIZE;
1704 } else {
1705 addr = (addr + ELF_PAGE_SIZE - 1) & ~(ELF_PAGE_SIZE - 1);
1706 file_offset = (file_offset + ELF_PAGE_SIZE - 1) &
1707 ~(ELF_PAGE_SIZE - 1);
1712 /* if interpreter, then add corresponing program header */
1713 if (interp) {
1714 ph = &phdr[0];
1716 ph->p_type = PT_INTERP;
1717 ph->p_offset = interp->sh_offset;
1718 ph->p_vaddr = interp->sh_addr;
1719 ph->p_paddr = ph->p_vaddr;
1720 ph->p_filesz = interp->sh_size;
1721 ph->p_memsz = interp->sh_size;
1722 ph->p_flags = PF_R;
1723 ph->p_align = interp->sh_addralign;
1726 /* if dynamic section, then add corresponing program header */
1727 if (dynamic) {
1728 ElfW(Sym) *sym_end;
1730 ph = &phdr[phnum - 1];
1732 ph->p_type = PT_DYNAMIC;
1733 ph->p_offset = dynamic->sh_offset;
1734 ph->p_vaddr = dynamic->sh_addr;
1735 ph->p_paddr = ph->p_vaddr;
1736 ph->p_filesz = dynamic->sh_size;
1737 ph->p_memsz = dynamic->sh_size;
1738 ph->p_flags = PF_R | PF_W;
1739 ph->p_align = dynamic->sh_addralign;
1741 /* put GOT dynamic section address */
1742 put32(s1->got->data, dynamic->sh_addr);
1744 /* relocate the PLT */
1745 if (file_type == TCC_OUTPUT_EXE
1746 #if defined(TCC_OUTPUT_DLL_WITH_PLT)
1747 || file_type == TCC_OUTPUT_DLL
1748 #endif
1750 uint8_t *p, *p_end;
1752 p = s1->plt->data;
1753 p_end = p + s1->plt->data_offset;
1754 if (p < p_end) {
1755 #if defined(TCC_TARGET_I386)
1756 put32(p + 2, get32(p + 2) + s1->got->sh_addr);
1757 put32(p + 8, get32(p + 8) + s1->got->sh_addr);
1758 p += 16;
1759 while (p < p_end) {
1760 put32(p + 2, get32(p + 2) + s1->got->sh_addr);
1761 p += 16;
1763 #elif defined(TCC_TARGET_X86_64)
1764 int x = s1->got->sh_addr - s1->plt->sh_addr - 6;
1765 put32(p + 2, get32(p + 2) + x);
1766 put32(p + 8, get32(p + 8) + x - 6);
1767 p += 16;
1768 while (p < p_end) {
1769 put32(p + 2, get32(p + 2) + x + s1->plt->data - p);
1770 p += 16;
1772 #elif defined(TCC_TARGET_ARM)
1773 int x;
1774 x=s1->got->sh_addr - s1->plt->sh_addr - 12;
1775 p +=16;
1776 while (p < p_end) {
1777 put32(p + 12, x + get32(p + 12) + s1->plt->data - p);
1778 p += 16;
1780 #elif defined(TCC_TARGET_C67)
1781 /* XXX: TODO */
1782 #else
1783 #error unsupported CPU
1784 #endif
1788 /* relocate symbols in .dynsym */
1789 sym_end = (ElfW(Sym) *)(s1->dynsym->data + s1->dynsym->data_offset);
1790 for(sym = (ElfW(Sym) *)s1->dynsym->data + 1;
1791 sym < sym_end;
1792 sym++) {
1793 if (sym->st_shndx == SHN_UNDEF) {
1794 /* relocate to the PLT if the symbol corresponds
1795 to a PLT entry */
1796 if (sym->st_value)
1797 sym->st_value += s1->plt->sh_addr;
1798 } else if (sym->st_shndx < SHN_LORESERVE) {
1799 /* do symbol relocation */
1800 sym->st_value += s1->sections[sym->st_shndx]->sh_addr;
1804 /* put dynamic section entries */
1805 dynamic->data_offset = saved_dynamic_data_offset;
1806 put_dt(dynamic, DT_HASH, s1->dynsym->hash->sh_addr);
1807 put_dt(dynamic, DT_STRTAB, dynstr->sh_addr);
1808 put_dt(dynamic, DT_SYMTAB, s1->dynsym->sh_addr);
1809 put_dt(dynamic, DT_STRSZ, dynstr->data_offset);
1810 put_dt(dynamic, DT_SYMENT, sizeof(ElfW(Sym)));
1811 #ifdef TCC_TARGET_X86_64
1812 put_dt(dynamic, DT_RELA, rel_addr);
1813 put_dt(dynamic, DT_RELASZ, rel_size);
1814 put_dt(dynamic, DT_RELAENT, sizeof(ElfW_Rel));
1815 #else
1816 put_dt(dynamic, DT_REL, rel_addr);
1817 put_dt(dynamic, DT_RELSZ, rel_size);
1818 put_dt(dynamic, DT_RELENT, sizeof(ElfW_Rel));
1819 #endif
1820 if (do_debug)
1821 put_dt(dynamic, DT_DEBUG, 0);
1822 put_dt(dynamic, DT_NULL, 0);
1825 ehdr.e_phentsize = sizeof(ElfW(Phdr));
1826 ehdr.e_phnum = phnum;
1827 ehdr.e_phoff = sizeof(ElfW(Ehdr));
1830 /* all other sections come after */
1831 for(i = 1; i < s1->nb_sections; i++) {
1832 s = s1->sections[i];
1833 if (phnum > 0 && (s->sh_flags & SHF_ALLOC))
1834 continue;
1835 section_order[sh_order_index++] = i;
1837 file_offset = (file_offset + s->sh_addralign - 1) &
1838 ~(s->sh_addralign - 1);
1839 s->sh_offset = file_offset;
1840 if (s->sh_type != SHT_NOBITS)
1841 file_offset += s->sh_size;
1844 /* if building executable or DLL, then relocate each section
1845 except the GOT which is already relocated */
1846 if (file_type != TCC_OUTPUT_OBJ) {
1847 relocate_syms(s1, 0);
1849 if (s1->nb_errors != 0) {
1850 fail:
1851 ret = -1;
1852 goto the_end;
1855 /* relocate sections */
1856 /* XXX: ignore sections with allocated relocations ? */
1857 for(i = 1; i < s1->nb_sections; i++) {
1858 s = s1->sections[i];
1859 if (s->reloc && s != s1->got && (s->sh_flags & SHF_ALLOC)) //gr
1860 relocate_section(s1, s);
1863 /* relocate relocation entries if the relocation tables are
1864 allocated in the executable */
1865 for(i = 1; i < s1->nb_sections; i++) {
1866 s = s1->sections[i];
1867 if ((s->sh_flags & SHF_ALLOC) &&
1868 s->sh_type == SHT_RELX) {
1869 relocate_rel(s1, s);
1873 /* get entry point address */
1874 if (file_type == TCC_OUTPUT_EXE)
1875 ehdr.e_entry = (unsigned long)tcc_get_symbol_err(s1, "_start");
1876 else
1877 ehdr.e_entry = text_section->sh_addr; /* XXX: is it correct ? */
1880 /* write elf file */
1881 if (file_type == TCC_OUTPUT_OBJ)
1882 mode = 0666;
1883 else
1884 mode = 0777;
1885 fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, mode);
1886 if (fd < 0) {
1887 error_noabort("could not write '%s'", filename);
1888 goto fail;
1890 f = fdopen(fd, "wb");
1891 if (verbose)
1892 printf("<- %s\n", filename);
1894 #ifdef TCC_TARGET_COFF
1895 if (s1->output_format == TCC_OUTPUT_FORMAT_COFF) {
1896 tcc_output_coff(s1, f);
1897 } else
1898 #endif
1899 if (s1->output_format == TCC_OUTPUT_FORMAT_ELF) {
1900 sort_syms(s1, symtab_section);
1902 /* align to 4 */
1903 file_offset = (file_offset + 3) & -4;
1905 /* fill header */
1906 ehdr.e_ident[0] = ELFMAG0;
1907 ehdr.e_ident[1] = ELFMAG1;
1908 ehdr.e_ident[2] = ELFMAG2;
1909 ehdr.e_ident[3] = ELFMAG3;
1910 ehdr.e_ident[4] = TCC_ELFCLASS;
1911 ehdr.e_ident[5] = ELFDATA2LSB;
1912 ehdr.e_ident[6] = EV_CURRENT;
1913 #ifdef __FreeBSD__
1914 ehdr.e_ident[EI_OSABI] = ELFOSABI_FREEBSD;
1915 #endif
1916 #ifdef TCC_TARGET_ARM
1917 #ifdef TCC_ARM_EABI
1918 ehdr.e_ident[EI_OSABI] = 0;
1919 ehdr.e_flags = 4 << 24;
1920 #else
1921 ehdr.e_ident[EI_OSABI] = ELFOSABI_ARM;
1922 #endif
1923 #endif
1924 switch(file_type) {
1925 default:
1926 case TCC_OUTPUT_EXE:
1927 ehdr.e_type = ET_EXEC;
1928 break;
1929 case TCC_OUTPUT_DLL:
1930 ehdr.e_type = ET_DYN;
1931 break;
1932 case TCC_OUTPUT_OBJ:
1933 ehdr.e_type = ET_REL;
1934 break;
1936 ehdr.e_machine = EM_TCC_TARGET;
1937 ehdr.e_version = EV_CURRENT;
1938 ehdr.e_shoff = file_offset;
1939 ehdr.e_ehsize = sizeof(ElfW(Ehdr));
1940 ehdr.e_shentsize = sizeof(ElfW(Shdr));
1941 ehdr.e_shnum = shnum;
1942 ehdr.e_shstrndx = shnum - 1;
1944 fwrite(&ehdr, 1, sizeof(ElfW(Ehdr)), f);
1945 fwrite(phdr, 1, phnum * sizeof(ElfW(Phdr)), f);
1946 offset = sizeof(ElfW(Ehdr)) + phnum * sizeof(ElfW(Phdr));
1948 for(i=1;i<s1->nb_sections;i++) {
1949 s = s1->sections[section_order[i]];
1950 if (s->sh_type != SHT_NOBITS) {
1951 while (offset < s->sh_offset) {
1952 fputc(0, f);
1953 offset++;
1955 size = s->sh_size;
1956 fwrite(s->data, 1, size, f);
1957 offset += size;
1961 /* output section headers */
1962 while (offset < ehdr.e_shoff) {
1963 fputc(0, f);
1964 offset++;
1967 for(i=0;i<s1->nb_sections;i++) {
1968 sh = &shdr;
1969 memset(sh, 0, sizeof(ElfW(Shdr)));
1970 s = s1->sections[i];
1971 if (s) {
1972 sh->sh_name = s->sh_name;
1973 sh->sh_type = s->sh_type;
1974 sh->sh_flags = s->sh_flags;
1975 sh->sh_entsize = s->sh_entsize;
1976 sh->sh_info = s->sh_info;
1977 if (s->link)
1978 sh->sh_link = s->link->sh_num;
1979 sh->sh_addralign = s->sh_addralign;
1980 sh->sh_addr = s->sh_addr;
1981 sh->sh_offset = s->sh_offset;
1982 sh->sh_size = s->sh_size;
1984 fwrite(sh, 1, sizeof(ElfW(Shdr)), f);
1986 } else {
1987 tcc_output_binary(s1, f, section_order);
1989 fclose(f);
1991 ret = 0;
1992 the_end:
1993 tcc_free(s1->symtab_to_dynsym);
1994 tcc_free(section_order);
1995 tcc_free(phdr);
1996 tcc_free(s1->got_offsets);
1997 return ret;
2000 int tcc_output_file(TCCState *s, const char *filename)
2002 int ret;
2003 #ifdef TCC_TARGET_PE
2004 if (s->output_type != TCC_OUTPUT_OBJ) {
2005 ret = pe_output_file(s, filename);
2006 } else
2007 #endif
2009 ret = elf_output_file(s, filename);
2011 return ret;
2014 static void *load_data(int fd, unsigned long file_offset, unsigned long size)
2016 void *data;
2018 data = tcc_malloc(size);
2019 lseek(fd, file_offset, SEEK_SET);
2020 read(fd, data, size);
2021 return data;
2024 typedef struct SectionMergeInfo {
2025 Section *s; /* corresponding existing section */
2026 unsigned long offset; /* offset of the new section in the existing section */
2027 uint8_t new_section; /* true if section 's' was added */
2028 uint8_t link_once; /* true if link once section */
2029 } SectionMergeInfo;
2031 /* load an object file and merge it with current files */
2032 /* XXX: handle correctly stab (debug) info */
2033 static int tcc_load_object_file(TCCState *s1,
2034 int fd, unsigned long file_offset)
2036 ElfW(Ehdr) ehdr;
2037 ElfW(Shdr) *shdr, *sh;
2038 int size, i, j, offset, offseti, nb_syms, sym_index, ret;
2039 unsigned char *strsec, *strtab;
2040 int *old_to_new_syms;
2041 char *sh_name, *name;
2042 SectionMergeInfo *sm_table, *sm;
2043 ElfW(Sym) *sym, *symtab;
2044 ElfW_Rel *rel, *rel_end;
2045 Section *s;
2047 int stab_index;
2048 int stabstr_index;
2050 stab_index = stabstr_index = 0;
2052 if (read(fd, &ehdr, sizeof(ehdr)) != sizeof(ehdr))
2053 goto fail1;
2054 if (ehdr.e_ident[0] != ELFMAG0 ||
2055 ehdr.e_ident[1] != ELFMAG1 ||
2056 ehdr.e_ident[2] != ELFMAG2 ||
2057 ehdr.e_ident[3] != ELFMAG3)
2058 goto fail1;
2059 /* test if object file */
2060 if (ehdr.e_type != ET_REL)
2061 goto fail1;
2062 /* test CPU specific stuff */
2063 if (ehdr.e_ident[5] != ELFDATA2LSB ||
2064 ehdr.e_machine != EM_TCC_TARGET) {
2065 fail1:
2066 error_noabort("invalid object file");
2067 return -1;
2069 /* read sections */
2070 shdr = load_data(fd, file_offset + ehdr.e_shoff,
2071 sizeof(ElfW(Shdr)) * ehdr.e_shnum);
2072 sm_table = tcc_mallocz(sizeof(SectionMergeInfo) * ehdr.e_shnum);
2074 /* load section names */
2075 sh = &shdr[ehdr.e_shstrndx];
2076 strsec = load_data(fd, file_offset + sh->sh_offset, sh->sh_size);
2078 /* load symtab and strtab */
2079 old_to_new_syms = NULL;
2080 symtab = NULL;
2081 strtab = NULL;
2082 nb_syms = 0;
2083 for(i = 1; i < ehdr.e_shnum; i++) {
2084 sh = &shdr[i];
2085 if (sh->sh_type == SHT_SYMTAB) {
2086 if (symtab) {
2087 error_noabort("object must contain only one symtab");
2088 fail:
2089 ret = -1;
2090 goto the_end;
2092 nb_syms = sh->sh_size / sizeof(ElfW(Sym));
2093 symtab = load_data(fd, file_offset + sh->sh_offset, sh->sh_size);
2094 sm_table[i].s = symtab_section;
2096 /* now load strtab */
2097 sh = &shdr[sh->sh_link];
2098 strtab = load_data(fd, file_offset + sh->sh_offset, sh->sh_size);
2102 /* now examine each section and try to merge its content with the
2103 ones in memory */
2104 for(i = 1; i < ehdr.e_shnum; i++) {
2105 /* no need to examine section name strtab */
2106 if (i == ehdr.e_shstrndx)
2107 continue;
2108 sh = &shdr[i];
2109 sh_name = strsec + sh->sh_name;
2110 /* ignore sections types we do not handle */
2111 if (sh->sh_type != SHT_PROGBITS &&
2112 sh->sh_type != SHT_RELX &&
2113 #ifdef TCC_ARM_EABI
2114 sh->sh_type != SHT_ARM_EXIDX &&
2115 #endif
2116 sh->sh_type != SHT_NOBITS &&
2117 strcmp(sh_name, ".stabstr")
2119 continue;
2120 if (sh->sh_addralign < 1)
2121 sh->sh_addralign = 1;
2122 /* find corresponding section, if any */
2123 for(j = 1; j < s1->nb_sections;j++) {
2124 s = s1->sections[j];
2125 if (!strcmp(s->name, sh_name)) {
2126 if (!strncmp(sh_name, ".gnu.linkonce",
2127 sizeof(".gnu.linkonce") - 1)) {
2128 /* if a 'linkonce' section is already present, we
2129 do not add it again. It is a little tricky as
2130 symbols can still be defined in
2131 it. */
2132 sm_table[i].link_once = 1;
2133 goto next;
2134 } else {
2135 goto found;
2139 /* not found: create new section */
2140 s = new_section(s1, sh_name, sh->sh_type, sh->sh_flags);
2141 /* take as much info as possible from the section. sh_link and
2142 sh_info will be updated later */
2143 s->sh_addralign = sh->sh_addralign;
2144 s->sh_entsize = sh->sh_entsize;
2145 sm_table[i].new_section = 1;
2146 found:
2147 if (sh->sh_type != s->sh_type) {
2148 error_noabort("invalid section type");
2149 goto fail;
2152 /* align start of section */
2153 offset = s->data_offset;
2155 if (0 == strcmp(sh_name, ".stab")) {
2156 stab_index = i;
2157 goto no_align;
2159 if (0 == strcmp(sh_name, ".stabstr")) {
2160 stabstr_index = i;
2161 goto no_align;
2164 size = sh->sh_addralign - 1;
2165 offset = (offset + size) & ~size;
2166 if (sh->sh_addralign > s->sh_addralign)
2167 s->sh_addralign = sh->sh_addralign;
2168 s->data_offset = offset;
2169 no_align:
2170 sm_table[i].offset = offset;
2171 sm_table[i].s = s;
2172 /* concatenate sections */
2173 size = sh->sh_size;
2174 if (sh->sh_type != SHT_NOBITS) {
2175 unsigned char *ptr;
2176 lseek(fd, file_offset + sh->sh_offset, SEEK_SET);
2177 ptr = section_ptr_add(s, size);
2178 read(fd, ptr, size);
2179 } else {
2180 s->data_offset += size;
2182 next: ;
2185 /* //gr relocate stab strings */
2186 if (stab_index && stabstr_index) {
2187 Stab_Sym *a, *b;
2188 unsigned o;
2189 s = sm_table[stab_index].s;
2190 a = (Stab_Sym *)(s->data + sm_table[stab_index].offset);
2191 b = (Stab_Sym *)(s->data + s->data_offset);
2192 o = sm_table[stabstr_index].offset;
2193 while (a < b)
2194 a->n_strx += o, a++;
2197 /* second short pass to update sh_link and sh_info fields of new
2198 sections */
2199 for(i = 1; i < ehdr.e_shnum; i++) {
2200 s = sm_table[i].s;
2201 if (!s || !sm_table[i].new_section)
2202 continue;
2203 sh = &shdr[i];
2204 if (sh->sh_link > 0)
2205 s->link = sm_table[sh->sh_link].s;
2206 if (sh->sh_type == SHT_RELX) {
2207 s->sh_info = sm_table[sh->sh_info].s->sh_num;
2208 /* update backward link */
2209 s1->sections[s->sh_info]->reloc = s;
2212 sm = sm_table;
2214 /* resolve symbols */
2215 old_to_new_syms = tcc_mallocz(nb_syms * sizeof(int));
2217 sym = symtab + 1;
2218 for(i = 1; i < nb_syms; i++, sym++) {
2219 if (sym->st_shndx != SHN_UNDEF &&
2220 sym->st_shndx < SHN_LORESERVE) {
2221 sm = &sm_table[sym->st_shndx];
2222 if (sm->link_once) {
2223 /* if a symbol is in a link once section, we use the
2224 already defined symbol. It is very important to get
2225 correct relocations */
2226 if (ELFW(ST_BIND)(sym->st_info) != STB_LOCAL) {
2227 name = strtab + sym->st_name;
2228 sym_index = find_elf_sym(symtab_section, name);
2229 if (sym_index)
2230 old_to_new_syms[i] = sym_index;
2232 continue;
2234 /* if no corresponding section added, no need to add symbol */
2235 if (!sm->s)
2236 continue;
2237 /* convert section number */
2238 sym->st_shndx = sm->s->sh_num;
2239 /* offset value */
2240 sym->st_value += sm->offset;
2242 /* add symbol */
2243 name = strtab + sym->st_name;
2244 sym_index = add_elf_sym(symtab_section, sym->st_value, sym->st_size,
2245 sym->st_info, sym->st_other,
2246 sym->st_shndx, name);
2247 old_to_new_syms[i] = sym_index;
2250 /* third pass to patch relocation entries */
2251 for(i = 1; i < ehdr.e_shnum; i++) {
2252 s = sm_table[i].s;
2253 if (!s)
2254 continue;
2255 sh = &shdr[i];
2256 offset = sm_table[i].offset;
2257 switch(s->sh_type) {
2258 case SHT_RELX:
2259 /* take relocation offset information */
2260 offseti = sm_table[sh->sh_info].offset;
2261 rel_end = (ElfW_Rel *)(s->data + s->data_offset);
2262 for(rel = (ElfW_Rel *)(s->data + offset);
2263 rel < rel_end;
2264 rel++) {
2265 int type;
2266 unsigned sym_index;
2267 /* convert symbol index */
2268 type = ELFW(R_TYPE)(rel->r_info);
2269 sym_index = ELFW(R_SYM)(rel->r_info);
2270 /* NOTE: only one symtab assumed */
2271 if (sym_index >= nb_syms)
2272 goto invalid_reloc;
2273 sym_index = old_to_new_syms[sym_index];
2274 /* ignore link_once in rel section. */
2275 if (!sym_index && !sm->link_once) {
2276 invalid_reloc:
2277 error_noabort("Invalid relocation entry [%2d] '%s' @ %.8x",
2278 i, strsec + sh->sh_name, rel->r_offset);
2279 goto fail;
2281 rel->r_info = ELFW(R_INFO)(sym_index, type);
2282 /* offset the relocation offset */
2283 rel->r_offset += offseti;
2285 break;
2286 default:
2287 break;
2291 ret = 0;
2292 the_end:
2293 tcc_free(symtab);
2294 tcc_free(strtab);
2295 tcc_free(old_to_new_syms);
2296 tcc_free(sm_table);
2297 tcc_free(strsec);
2298 tcc_free(shdr);
2299 return ret;
2302 #define ARMAG "!<arch>\012" /* For COFF and a.out archives */
2304 typedef struct ArchiveHeader {
2305 char ar_name[16]; /* name of this member */
2306 char ar_date[12]; /* file mtime */
2307 char ar_uid[6]; /* owner uid; printed as decimal */
2308 char ar_gid[6]; /* owner gid; printed as decimal */
2309 char ar_mode[8]; /* file mode, printed as octal */
2310 char ar_size[10]; /* file size, printed as decimal */
2311 char ar_fmag[2]; /* should contain ARFMAG */
2312 } ArchiveHeader;
2314 static int get_be32(const uint8_t *b)
2316 return b[3] | (b[2] << 8) | (b[1] << 16) | (b[0] << 24);
2319 /* load only the objects which resolve undefined symbols */
2320 static int tcc_load_alacarte(TCCState *s1, int fd, int size)
2322 int i, bound, nsyms, sym_index, off, ret;
2323 uint8_t *data;
2324 const char *ar_names, *p;
2325 const uint8_t *ar_index;
2326 ElfW(Sym) *sym;
2328 data = tcc_malloc(size);
2329 if (read(fd, data, size) != size)
2330 goto fail;
2331 nsyms = get_be32(data);
2332 ar_index = data + 4;
2333 ar_names = ar_index + nsyms * 4;
2335 do {
2336 bound = 0;
2337 for(p = ar_names, i = 0; i < nsyms; i++, p += strlen(p)+1) {
2338 sym_index = find_elf_sym(symtab_section, p);
2339 if(sym_index) {
2340 sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
2341 if(sym->st_shndx == SHN_UNDEF) {
2342 off = get_be32(ar_index + i * 4) + sizeof(ArchiveHeader);
2343 #if 0
2344 printf("%5d\t%s\t%08x\n", i, p, sym->st_shndx);
2345 #endif
2346 ++bound;
2347 lseek(fd, off, SEEK_SET);
2348 if(tcc_load_object_file(s1, fd, off) < 0) {
2349 fail:
2350 ret = -1;
2351 goto the_end;
2356 } while(bound);
2357 ret = 0;
2358 the_end:
2359 tcc_free(data);
2360 return ret;
2363 /* load a '.a' file */
2364 static int tcc_load_archive(TCCState *s1, int fd)
2366 ArchiveHeader hdr;
2367 char ar_size[11];
2368 char ar_name[17];
2369 char magic[8];
2370 int size, len, i;
2371 unsigned long file_offset;
2373 /* skip magic which was already checked */
2374 read(fd, magic, sizeof(magic));
2376 for(;;) {
2377 len = read(fd, &hdr, sizeof(hdr));
2378 if (len == 0)
2379 break;
2380 if (len != sizeof(hdr)) {
2381 error_noabort("invalid archive");
2382 return -1;
2384 memcpy(ar_size, hdr.ar_size, sizeof(hdr.ar_size));
2385 ar_size[sizeof(hdr.ar_size)] = '\0';
2386 size = strtol(ar_size, NULL, 0);
2387 memcpy(ar_name, hdr.ar_name, sizeof(hdr.ar_name));
2388 for(i = sizeof(hdr.ar_name) - 1; i >= 0; i--) {
2389 if (ar_name[i] != ' ')
2390 break;
2392 ar_name[i + 1] = '\0';
2393 // printf("name='%s' size=%d %s\n", ar_name, size, ar_size);
2394 file_offset = lseek(fd, 0, SEEK_CUR);
2395 /* align to even */
2396 size = (size + 1) & ~1;
2397 if (!strcmp(ar_name, "/")) {
2398 /* coff symbol table : we handle it */
2399 if(s1->alacarte_link)
2400 return tcc_load_alacarte(s1, fd, size);
2401 } else if (!strcmp(ar_name, "//") ||
2402 !strcmp(ar_name, "__.SYMDEF") ||
2403 !strcmp(ar_name, "__.SYMDEF/") ||
2404 !strcmp(ar_name, "ARFILENAMES/")) {
2405 /* skip symbol table or archive names */
2406 } else {
2407 if (tcc_load_object_file(s1, fd, file_offset) < 0)
2408 return -1;
2410 lseek(fd, file_offset + size, SEEK_SET);
2412 return 0;
2415 /* load a DLL and all referenced DLLs. 'level = 0' means that the DLL
2416 is referenced by the user (so it should be added as DT_NEEDED in
2417 the generated ELF file) */
2418 static int tcc_load_dll(TCCState *s1, int fd, const char *filename, int level)
2420 ElfW(Ehdr) ehdr;
2421 ElfW(Shdr) *shdr, *sh, *sh1;
2422 int i, j, nb_syms, nb_dts, sym_bind, ret;
2423 ElfW(Sym) *sym, *dynsym;
2424 ElfW(Dyn) *dt, *dynamic;
2425 unsigned char *dynstr;
2426 const char *name, *soname;
2427 DLLReference *dllref;
2429 read(fd, &ehdr, sizeof(ehdr));
2431 /* test CPU specific stuff */
2432 if (ehdr.e_ident[5] != ELFDATA2LSB ||
2433 ehdr.e_machine != EM_TCC_TARGET) {
2434 error_noabort("bad architecture");
2435 return -1;
2438 /* read sections */
2439 shdr = load_data(fd, ehdr.e_shoff, sizeof(ElfW(Shdr)) * ehdr.e_shnum);
2441 /* load dynamic section and dynamic symbols */
2442 nb_syms = 0;
2443 nb_dts = 0;
2444 dynamic = NULL;
2445 dynsym = NULL; /* avoid warning */
2446 dynstr = NULL; /* avoid warning */
2447 for(i = 0, sh = shdr; i < ehdr.e_shnum; i++, sh++) {
2448 switch(sh->sh_type) {
2449 case SHT_DYNAMIC:
2450 nb_dts = sh->sh_size / sizeof(ElfW(Dyn));
2451 dynamic = load_data(fd, sh->sh_offset, sh->sh_size);
2452 break;
2453 case SHT_DYNSYM:
2454 nb_syms = sh->sh_size / sizeof(ElfW(Sym));
2455 dynsym = load_data(fd, sh->sh_offset, sh->sh_size);
2456 sh1 = &shdr[sh->sh_link];
2457 dynstr = load_data(fd, sh1->sh_offset, sh1->sh_size);
2458 break;
2459 default:
2460 break;
2464 /* compute the real library name */
2465 soname = tcc_basename(filename);
2467 for(i = 0, dt = dynamic; i < nb_dts; i++, dt++) {
2468 if (dt->d_tag == DT_SONAME) {
2469 soname = dynstr + dt->d_un.d_val;
2473 /* if the dll is already loaded, do not load it */
2474 for(i = 0; i < s1->nb_loaded_dlls; i++) {
2475 dllref = s1->loaded_dlls[i];
2476 if (!strcmp(soname, dllref->name)) {
2477 /* but update level if needed */
2478 if (level < dllref->level)
2479 dllref->level = level;
2480 ret = 0;
2481 goto the_end;
2485 // printf("loading dll '%s'\n", soname);
2487 /* add the dll and its level */
2488 dllref = tcc_mallocz(sizeof(DLLReference) + strlen(soname));
2489 dllref->level = level;
2490 strcpy(dllref->name, soname);
2491 dynarray_add((void ***)&s1->loaded_dlls, &s1->nb_loaded_dlls, dllref);
2493 /* add dynamic symbols in dynsym_section */
2494 for(i = 1, sym = dynsym + 1; i < nb_syms; i++, sym++) {
2495 sym_bind = ELFW(ST_BIND)(sym->st_info);
2496 if (sym_bind == STB_LOCAL)
2497 continue;
2498 name = dynstr + sym->st_name;
2499 add_elf_sym(s1->dynsymtab_section, sym->st_value, sym->st_size,
2500 sym->st_info, sym->st_other, sym->st_shndx, name);
2503 /* load all referenced DLLs */
2504 for(i = 0, dt = dynamic; i < nb_dts; i++, dt++) {
2505 switch(dt->d_tag) {
2506 case DT_NEEDED:
2507 name = dynstr + dt->d_un.d_val;
2508 for(j = 0; j < s1->nb_loaded_dlls; j++) {
2509 dllref = s1->loaded_dlls[j];
2510 if (!strcmp(name, dllref->name))
2511 goto already_loaded;
2513 if (tcc_add_dll(s1, name, AFF_REFERENCED_DLL) < 0) {
2514 error_noabort("referenced dll '%s' not found", name);
2515 ret = -1;
2516 goto the_end;
2518 already_loaded:
2519 break;
2522 ret = 0;
2523 the_end:
2524 tcc_free(dynstr);
2525 tcc_free(dynsym);
2526 tcc_free(dynamic);
2527 tcc_free(shdr);
2528 return ret;
2531 #define LD_TOK_NAME 256
2532 #define LD_TOK_EOF (-1)
2534 /* return next ld script token */
2535 static int ld_next(TCCState *s1, char *name, int name_size)
2537 int c;
2538 char *q;
2540 redo:
2541 switch(ch) {
2542 case ' ':
2543 case '\t':
2544 case '\f':
2545 case '\v':
2546 case '\r':
2547 case '\n':
2548 inp();
2549 goto redo;
2550 case '/':
2551 minp();
2552 if (ch == '*') {
2553 file->buf_ptr = parse_comment(file->buf_ptr);
2554 ch = file->buf_ptr[0];
2555 goto redo;
2556 } else {
2557 q = name;
2558 *q++ = '/';
2559 goto parse_name;
2561 break;
2562 /* case 'a' ... 'z': */
2563 case 'a':
2564 case 'b':
2565 case 'c':
2566 case 'd':
2567 case 'e':
2568 case 'f':
2569 case 'g':
2570 case 'h':
2571 case 'i':
2572 case 'j':
2573 case 'k':
2574 case 'l':
2575 case 'm':
2576 case 'n':
2577 case 'o':
2578 case 'p':
2579 case 'q':
2580 case 'r':
2581 case 's':
2582 case 't':
2583 case 'u':
2584 case 'v':
2585 case 'w':
2586 case 'x':
2587 case 'y':
2588 case 'z':
2589 /* case 'A' ... 'z': */
2590 case 'A':
2591 case 'B':
2592 case 'C':
2593 case 'D':
2594 case 'E':
2595 case 'F':
2596 case 'G':
2597 case 'H':
2598 case 'I':
2599 case 'J':
2600 case 'K':
2601 case 'L':
2602 case 'M':
2603 case 'N':
2604 case 'O':
2605 case 'P':
2606 case 'Q':
2607 case 'R':
2608 case 'S':
2609 case 'T':
2610 case 'U':
2611 case 'V':
2612 case 'W':
2613 case 'X':
2614 case 'Y':
2615 case 'Z':
2616 case '_':
2617 case '\\':
2618 case '.':
2619 case '$':
2620 case '~':
2621 q = name;
2622 parse_name:
2623 for(;;) {
2624 if (!((ch >= 'a' && ch <= 'z') ||
2625 (ch >= 'A' && ch <= 'Z') ||
2626 (ch >= '0' && ch <= '9') ||
2627 strchr("/.-_+=$:\\,~", ch)))
2628 break;
2629 if ((q - name) < name_size - 1) {
2630 *q++ = ch;
2632 minp();
2634 *q = '\0';
2635 c = LD_TOK_NAME;
2636 break;
2637 case CH_EOF:
2638 c = LD_TOK_EOF;
2639 break;
2640 default:
2641 c = ch;
2642 inp();
2643 break;
2645 #if 0
2646 printf("tok=%c %d\n", c, c);
2647 if (c == LD_TOK_NAME)
2648 printf(" name=%s\n", name);
2649 #endif
2650 return c;
2653 static int ld_add_file_list(TCCState *s1, int as_needed)
2655 char filename[1024];
2656 int t, ret;
2658 t = ld_next(s1, filename, sizeof(filename));
2659 if (t != '(')
2660 expect("(");
2661 t = ld_next(s1, filename, sizeof(filename));
2662 for(;;) {
2663 if (t == LD_TOK_EOF) {
2664 error_noabort("unexpected end of file");
2665 return -1;
2666 } else if (t == ')') {
2667 break;
2668 } else if (t != LD_TOK_NAME) {
2669 error_noabort("filename expected");
2670 return -1;
2672 if (!strcmp(filename, "AS_NEEDED")) {
2673 ret = ld_add_file_list(s1, 1);
2674 if (ret)
2675 return ret;
2676 } else {
2677 /* TODO: Implement AS_NEEDED support. Ignore it for now */
2678 if (!as_needed)
2679 tcc_add_file(s1, filename);
2681 t = ld_next(s1, filename, sizeof(filename));
2682 if (t == ',') {
2683 t = ld_next(s1, filename, sizeof(filename));
2686 return 0;
2689 /* interpret a subset of GNU ldscripts to handle the dummy libc.so
2690 files */
2691 static int tcc_load_ldscript(TCCState *s1)
2693 char cmd[64];
2694 char filename[1024];
2695 int t, ret;
2697 ch = file->buf_ptr[0];
2698 ch = handle_eob();
2699 for(;;) {
2700 t = ld_next(s1, cmd, sizeof(cmd));
2701 if (t == LD_TOK_EOF)
2702 return 0;
2703 else if (t != LD_TOK_NAME)
2704 return -1;
2705 if (!strcmp(cmd, "INPUT") ||
2706 !strcmp(cmd, "GROUP")) {
2707 ret = ld_add_file_list(s1, 0);
2708 if (ret)
2709 return ret;
2710 } else if (!strcmp(cmd, "OUTPUT_FORMAT") ||
2711 !strcmp(cmd, "TARGET")) {
2712 /* ignore some commands */
2713 t = ld_next(s1, cmd, sizeof(cmd));
2714 if (t != '(')
2715 expect("(");
2716 for(;;) {
2717 t = ld_next(s1, filename, sizeof(filename));
2718 if (t == LD_TOK_EOF) {
2719 error_noabort("unexpected end of file");
2720 return -1;
2721 } else if (t == ')') {
2722 break;
2725 } else {
2726 return -1;
2729 return 0;