Generate PIC code so that we can create shared objects properly.
[tinycc/miki.git] / tccelf.c
blob56ee75a1b0e082392553188382d7cc73ad705261
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 int tcc_get_symbol(TCCState *s, unsigned long *pval, const char *name)
174 int sym_index;
175 ElfW(Sym) *sym;
177 sym_index = find_elf_sym(symtab_section, name);
178 if (!sym_index)
179 return -1;
180 sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
181 *pval = sym->st_value;
182 return 0;
185 void *tcc_get_symbol_err(TCCState *s, const char *name)
187 unsigned long val;
188 if (tcc_get_symbol(s, &val, name) < 0)
189 error("%s not defined", name);
190 return (void *)val;
193 /* add an elf symbol : check if it is already defined and patch
194 it. Return symbol index. NOTE that sh_num can be SHN_UNDEF. */
195 static int add_elf_sym(Section *s, unsigned long value, unsigned long size,
196 int info, int other, int sh_num, const char *name)
198 ElfW(Sym) *esym;
199 int sym_bind, sym_index, sym_type, esym_bind;
200 unsigned char sym_vis, esym_vis, new_vis;
202 sym_bind = ELFW(ST_BIND)(info);
203 sym_type = ELFW(ST_TYPE)(info);
204 sym_vis = ELFW(ST_VISIBILITY)(other);
206 if (sym_bind != STB_LOCAL) {
207 /* we search global or weak symbols */
208 sym_index = find_elf_sym(s, name);
209 if (!sym_index)
210 goto do_def;
211 esym = &((ElfW(Sym) *)s->data)[sym_index];
212 if (esym->st_shndx != SHN_UNDEF) {
213 esym_bind = ELFW(ST_BIND)(esym->st_info);
214 /* propagate the most constraining visibility */
215 /* STV_DEFAULT(0)<STV_PROTECTED(3)<STV_HIDDEN(2)<STV_INTERNAL(1) */
216 esym_vis = ELFW(ST_VISIBILITY)(esym->st_other);
217 if (esym_vis == STV_DEFAULT) {
218 new_vis = sym_vis;
219 } else if (sym_vis == STV_DEFAULT) {
220 new_vis = esym_vis;
221 } else {
222 new_vis = (esym_vis < sym_vis) ? esym_vis : sym_vis;
224 esym->st_other = (esym->st_other & ~ELFW(ST_VISIBILITY)(-1))
225 | new_vis;
226 other = esym->st_other; /* in case we have to patch esym */
227 if (sh_num == SHN_UNDEF) {
228 /* ignore adding of undefined symbol if the
229 corresponding symbol is already defined */
230 } else if (sym_bind == STB_GLOBAL && esym_bind == STB_WEAK) {
231 /* global overrides weak, so patch */
232 goto do_patch;
233 } else if (sym_bind == STB_WEAK && esym_bind == STB_GLOBAL) {
234 /* weak is ignored if already global */
235 } else if (sym_vis == STV_HIDDEN || sym_vis == STV_INTERNAL) {
236 /* ignore hidden symbols after */
237 } else if (esym->st_shndx == SHN_COMMON && sh_num < SHN_LORESERVE) {
238 /* gr: Happens with 'tcc ... -static tcctest.c' on e.g. Ubuntu 6.01
239 No idea if this is the correct solution ... */
240 goto do_patch;
241 } else if (s == tcc_state->dynsymtab_section) {
242 /* we accept that two DLL define the same symbol */
243 } else {
244 #if 1
245 printf("new_bind=%x new_shndx=%x new_vis=%x old_bind=%x old_shndx=%x old_vis=%x\n",
246 sym_bind, sh_num, new_vis, esym_bind, esym->st_shndx, esym_vis);
247 #endif
248 error_noabort("'%s' defined twice", name);
250 } else {
251 do_patch:
252 esym->st_info = ELFW(ST_INFO)(sym_bind, sym_type);
253 esym->st_shndx = sh_num;
254 esym->st_value = value;
255 esym->st_size = size;
256 esym->st_other = other;
258 } else {
259 do_def:
260 sym_index = put_elf_sym(s, value, size,
261 ELFW(ST_INFO)(sym_bind, sym_type), other,
262 sh_num, name);
264 return sym_index;
267 /* put relocation */
268 static void put_elf_reloc(Section *symtab, Section *s, unsigned long offset,
269 int type, int symbol)
271 char buf[256];
272 Section *sr;
273 ElfW_Rel *rel;
275 sr = s->reloc;
276 if (!sr) {
277 /* if no relocation section, create it */
278 snprintf(buf, sizeof(buf), REL_SECTION_FMT, s->name);
279 /* if the symtab is allocated, then we consider the relocation
280 are also */
281 sr = new_section(tcc_state, buf, SHT_RELX, symtab->sh_flags);
282 sr->sh_entsize = sizeof(ElfW_Rel);
283 sr->link = symtab;
284 sr->sh_info = s->sh_num;
285 s->reloc = sr;
287 rel = section_ptr_add(sr, sizeof(ElfW_Rel));
288 rel->r_offset = offset;
289 rel->r_info = ELFW(R_INFO)(symbol, type);
290 #ifdef TCC_TARGET_X86_64
291 rel->r_addend = 0;
292 #endif
295 /* put stab debug information */
297 typedef struct {
298 unsigned int n_strx; /* index into string table of name */
299 unsigned char n_type; /* type of symbol */
300 unsigned char n_other; /* misc info (usually empty) */
301 unsigned short n_desc; /* description field */
302 unsigned int n_value; /* value of symbol */
303 } Stab_Sym;
305 static void put_stabs(const char *str, int type, int other, int desc,
306 unsigned long value)
308 Stab_Sym *sym;
310 sym = section_ptr_add(stab_section, sizeof(Stab_Sym));
311 if (str) {
312 sym->n_strx = put_elf_str(stabstr_section, str);
313 } else {
314 sym->n_strx = 0;
316 sym->n_type = type;
317 sym->n_other = other;
318 sym->n_desc = desc;
319 sym->n_value = value;
322 static void put_stabs_r(const char *str, int type, int other, int desc,
323 unsigned long value, Section *sec, int sym_index)
325 put_stabs(str, type, other, desc, value);
326 put_elf_reloc(symtab_section, stab_section,
327 stab_section->data_offset - sizeof(unsigned int),
328 R_DATA_32, sym_index);
331 static void put_stabn(int type, int other, int desc, int value)
333 put_stabs(NULL, type, other, desc, value);
336 static void put_stabd(int type, int other, int desc)
338 put_stabs(NULL, type, other, desc, 0);
341 /* In an ELF file symbol table, the local symbols must appear below
342 the global and weak ones. Since TCC cannot sort it while generating
343 the code, we must do it after. All the relocation tables are also
344 modified to take into account the symbol table sorting */
345 static void sort_syms(TCCState *s1, Section *s)
347 int *old_to_new_syms;
348 ElfW(Sym) *new_syms;
349 int nb_syms, i;
350 ElfW(Sym) *p, *q;
351 ElfW_Rel *rel, *rel_end;
352 Section *sr;
353 int type, sym_index;
355 nb_syms = s->data_offset / sizeof(ElfW(Sym));
356 new_syms = tcc_malloc(nb_syms * sizeof(ElfW(Sym)));
357 old_to_new_syms = tcc_malloc(nb_syms * sizeof(int));
359 /* first pass for local symbols */
360 p = (ElfW(Sym) *)s->data;
361 q = new_syms;
362 for(i = 0; i < nb_syms; i++) {
363 if (ELFW(ST_BIND)(p->st_info) == STB_LOCAL) {
364 old_to_new_syms[i] = q - new_syms;
365 *q++ = *p;
367 p++;
369 /* save the number of local symbols in section header */
370 s->sh_info = q - new_syms;
372 /* then second pass for non local symbols */
373 p = (ElfW(Sym) *)s->data;
374 for(i = 0; i < nb_syms; i++) {
375 if (ELFW(ST_BIND)(p->st_info) != STB_LOCAL) {
376 old_to_new_syms[i] = q - new_syms;
377 *q++ = *p;
379 p++;
382 /* we copy the new symbols to the old */
383 memcpy(s->data, new_syms, nb_syms * sizeof(ElfW(Sym)));
384 tcc_free(new_syms);
386 /* now we modify all the relocations */
387 for(i = 1; i < s1->nb_sections; i++) {
388 sr = s1->sections[i];
389 if (sr->sh_type == SHT_RELX && sr->link == s) {
390 rel_end = (ElfW_Rel *)(sr->data + sr->data_offset);
391 for(rel = (ElfW_Rel *)sr->data;
392 rel < rel_end;
393 rel++) {
394 sym_index = ELFW(R_SYM)(rel->r_info);
395 type = ELFW(R_TYPE)(rel->r_info);
396 sym_index = old_to_new_syms[sym_index];
397 rel->r_info = ELFW(R_INFO)(sym_index, type);
402 tcc_free(old_to_new_syms);
405 /* relocate common symbols in the .bss section */
406 static void relocate_common_syms(void)
408 ElfW(Sym) *sym, *sym_end;
409 unsigned long offset, align;
411 sym_end = (ElfW(Sym) *)(symtab_section->data + symtab_section->data_offset);
412 for(sym = (ElfW(Sym) *)symtab_section->data + 1;
413 sym < sym_end;
414 sym++) {
415 if (sym->st_shndx == SHN_COMMON) {
416 /* align symbol */
417 align = sym->st_value;
418 offset = bss_section->data_offset;
419 offset = (offset + align - 1) & -align;
420 sym->st_value = offset;
421 sym->st_shndx = bss_section->sh_num;
422 offset += sym->st_size;
423 bss_section->data_offset = offset;
428 /* relocate symbol table, resolve undefined symbols if do_resolve is
429 true and output error if undefined symbol. */
430 static void relocate_syms(TCCState *s1, int do_resolve)
432 ElfW(Sym) *sym, *esym, *sym_end;
433 int sym_bind, sh_num, sym_index;
434 const char *name;
435 unsigned long addr;
437 sym_end = (ElfW(Sym) *)(symtab_section->data + symtab_section->data_offset);
438 for(sym = (ElfW(Sym) *)symtab_section->data + 1;
439 sym < sym_end;
440 sym++) {
441 sh_num = sym->st_shndx;
442 if (sh_num == SHN_UNDEF) {
443 name = strtab_section->data + sym->st_name;
444 if (do_resolve) {
445 name = symtab_section->link->data + sym->st_name;
446 addr = (unsigned long)resolve_sym(s1, name, ELFW(ST_TYPE)(sym->st_info));
447 if (addr) {
448 sym->st_value = addr;
449 goto found;
451 } else if (s1->dynsym) {
452 /* if dynamic symbol exist, then use it */
453 sym_index = find_elf_sym(s1->dynsym, name);
454 if (sym_index) {
455 esym = &((ElfW(Sym) *)s1->dynsym->data)[sym_index];
456 sym->st_value = esym->st_value;
457 goto found;
460 /* XXX: _fp_hw seems to be part of the ABI, so we ignore
461 it */
462 if (!strcmp(name, "_fp_hw"))
463 goto found;
464 /* only weak symbols are accepted to be undefined. Their
465 value is zero */
466 sym_bind = ELFW(ST_BIND)(sym->st_info);
467 if (sym_bind == STB_WEAK) {
468 sym->st_value = 0;
469 } else {
470 error_noabort("undefined symbol '%s'", name);
472 } else if (sh_num < SHN_LORESERVE) {
473 /* add section base */
474 sym->st_value += s1->sections[sym->st_shndx]->sh_addr;
476 found: ;
480 #ifdef TCC_TARGET_X86_64
481 #define JMP_TABLE_ENTRY_SIZE 14
482 #define JMP_TABLE_ENTRY_MAX_NUM 4096
483 static unsigned long add_jmp_table(TCCState *s1, unsigned long val)
485 char *p;
486 if (!s1->jmp_table) {
487 int size = JMP_TABLE_ENTRY_SIZE * JMP_TABLE_ENTRY_MAX_NUM;
488 s1->jmp_table_num = 0;
489 s1->jmp_table = (char *)tcc_malloc(size);
490 set_pages_executable(s1->jmp_table, size);
492 if (s1->jmp_table_num == JMP_TABLE_ENTRY_MAX_NUM) {
493 error("relocating >%d symbols are not supported",
494 JMP_TABLE_ENTRY_MAX_NUM);
496 p = s1->jmp_table + s1->jmp_table_num * JMP_TABLE_ENTRY_SIZE;
497 s1->jmp_table_num++;
498 /* jmp *0x0(%rip) */
499 p[0] = 0xff;
500 p[1] = 0x25;
501 *(int *)(p + 2) = 0;
502 *(unsigned long *)(p + 6) = val;
503 return (unsigned long)p;
506 #define GOT_TABLE_ENTRY_MAX_NUM 4096
507 static unsigned long add_got_table(TCCState *s1, unsigned long val)
509 unsigned long *p;
510 if (!s1->got_table) {
511 int size = sizeof(void *) * GOT_TABLE_ENTRY_MAX_NUM;
512 s1->got_table_num = 0;
513 s1->got_table = (char *)tcc_malloc(size);
515 if (s1->got_table_num == GOT_TABLE_ENTRY_MAX_NUM) {
516 error("relocating >%d symbols are not supported",
517 GOT_TABLE_ENTRY_MAX_NUM);
519 p = s1->got_table + s1->got_table_num;
520 s1->got_table_num++;
521 *p = val;
522 return (unsigned long)p;
524 #endif
526 /* relocate a given section (CPU dependent) */
527 static void relocate_section(TCCState *s1, Section *s)
529 Section *sr;
530 ElfW_Rel *rel, *rel_end, *qrel;
531 ElfW(Sym) *sym;
532 int type, sym_index;
533 unsigned char *ptr;
534 unsigned long val, addr;
535 int esym_index;
537 sr = s->reloc;
538 rel_end = (ElfW_Rel *)(sr->data + sr->data_offset);
539 qrel = (ElfW_Rel *)sr->data;
540 for(rel = qrel;
541 rel < rel_end;
542 rel++) {
543 ptr = s->data + rel->r_offset;
545 sym_index = ELFW(R_SYM)(rel->r_info);
546 sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
547 val = sym->st_value;
548 #ifdef TCC_TARGET_X86_64
549 /* XXX: not tested */
550 val += rel->r_addend;
551 #endif
552 type = ELFW(R_TYPE)(rel->r_info);
553 addr = s->sh_addr + rel->r_offset;
555 /* CPU specific */
556 switch(type) {
557 #if defined(TCC_TARGET_I386)
558 case R_386_32:
559 if (s1->output_type == TCC_OUTPUT_DLL) {
560 esym_index = s1->symtab_to_dynsym[sym_index];
561 qrel->r_offset = rel->r_offset;
562 if (esym_index) {
563 qrel->r_info = ELFW(R_INFO)(esym_index, R_386_32);
564 qrel++;
565 break;
566 } else {
567 qrel->r_info = ELFW(R_INFO)(0, R_386_RELATIVE);
568 qrel++;
571 *(int *)ptr += val;
572 break;
573 case R_386_PC32:
574 if (s1->output_type == TCC_OUTPUT_DLL) {
575 /* DLL relocation */
576 esym_index = s1->symtab_to_dynsym[sym_index];
577 if (esym_index) {
578 qrel->r_offset = rel->r_offset;
579 qrel->r_info = ELFW(R_INFO)(esym_index, R_386_PC32);
580 qrel++;
581 break;
584 *(int *)ptr += val - addr;
585 break;
586 case R_386_PLT32:
587 *(int *)ptr += val - addr;
588 break;
589 case R_386_GLOB_DAT:
590 case R_386_JMP_SLOT:
591 *(int *)ptr = val;
592 break;
593 case R_386_GOTPC:
594 *(int *)ptr += s1->got->sh_addr - addr;
595 break;
596 case R_386_GOTOFF:
597 *(int *)ptr += val - s1->got->sh_addr;
598 break;
599 case R_386_GOT32:
600 /* we load the got offset */
601 *(int *)ptr += s1->got_offsets[sym_index];
602 break;
603 #elif defined(TCC_TARGET_ARM)
604 case R_ARM_PC24:
605 case R_ARM_CALL:
606 case R_ARM_JUMP24:
607 case R_ARM_PLT32:
609 int x;
610 x = (*(int *)ptr)&0xffffff;
611 (*(int *)ptr) &= 0xff000000;
612 if (x & 0x800000)
613 x -= 0x1000000;
614 x *= 4;
615 x += val - addr;
616 if((x & 3) != 0 || x >= 0x4000000 || x < -0x4000000)
617 error("can't relocate value at %x",addr);
618 x >>= 2;
619 x &= 0xffffff;
620 (*(int *)ptr) |= x;
622 break;
623 case R_ARM_PREL31:
625 int x;
626 x = (*(int *)ptr) & 0x7fffffff;
627 (*(int *)ptr) &= 0x80000000;
628 x = (x * 2) / 2;
629 x += val - addr;
630 if((x^(x>>1))&0x40000000)
631 error("can't relocate value at %x",addr);
632 (*(int *)ptr) |= x & 0x7fffffff;
634 case R_ARM_ABS32:
635 *(int *)ptr += val;
636 break;
637 case R_ARM_BASE_PREL:
638 *(int *)ptr += s1->got->sh_addr - addr;
639 break;
640 case R_ARM_GOTOFF32:
641 *(int *)ptr += val - s1->got->sh_addr;
642 break;
643 case R_ARM_GOT_BREL:
644 /* we load the got offset */
645 *(int *)ptr += s1->got_offsets[sym_index];
646 break;
647 case R_ARM_COPY:
648 break;
649 default:
650 fprintf(stderr,"FIXME: handle reloc type %x at %lx [%.8x] to %lx\n",
651 type,addr,(unsigned int )ptr,val);
652 break;
653 #elif defined(TCC_TARGET_C67)
654 case R_C60_32:
655 *(int *)ptr += val;
656 break;
657 case R_C60LO16:
659 uint32_t orig;
661 /* put the low 16 bits of the absolute address */
662 // add to what is already there
664 orig = ((*(int *)(ptr )) >> 7) & 0xffff;
665 orig |= (((*(int *)(ptr+4)) >> 7) & 0xffff) << 16;
667 //patch both at once - assumes always in pairs Low - High
669 *(int *) ptr = (*(int *) ptr & (~(0xffff << 7)) ) | (((val+orig) & 0xffff) << 7);
670 *(int *)(ptr+4) = (*(int *)(ptr+4) & (~(0xffff << 7)) ) | ((((val+orig)>>16) & 0xffff) << 7);
672 break;
673 case R_C60HI16:
674 break;
675 default:
676 fprintf(stderr,"FIXME: handle reloc type %x at %lx [%.8x] to %lx\n",
677 type,addr,(unsigned int )ptr,val);
678 break;
679 #elif defined(TCC_TARGET_X86_64)
680 case R_X86_64_64:
681 if (s1->output_type == TCC_OUTPUT_DLL) {
682 qrel->r_info = ELFW(R_INFO)(0, R_X86_64_RELATIVE);
683 qrel->r_addend = *(long long *)ptr + val;
684 qrel++;
686 *(long long *)ptr += val;
687 break;
688 case R_X86_64_32:
689 case R_X86_64_32S:
690 if (s1->output_type == TCC_OUTPUT_DLL) {
691 /* XXX: this logic may depend on TCC's codegen
692 now TCC uses R_X86_64_32 even for a 64bit pointer */
693 qrel->r_info = ELFW(R_INFO)(0, R_X86_64_RELATIVE);
694 qrel->r_addend = *(int *)ptr + val;
695 qrel++;
697 *(int *)ptr += val;
698 break;
699 case R_X86_64_PC32: {
700 if (s1->output_type == TCC_OUTPUT_DLL) {
701 /* DLL relocation */
702 esym_index = s1->symtab_to_dynsym[sym_index];
703 if (esym_index) {
704 qrel->r_offset = rel->r_offset;
705 qrel->r_info = ELFW(R_INFO)(esym_index, R_X86_64_PC32);
706 qrel->r_addend = *(int *)ptr;
707 qrel++;
708 break;
711 long diff = val - addr;
712 if (diff < -2147483648 || diff > 2147483647) {
713 /* XXX: naive support for over 32bit jump */
714 if (s1->output_type == TCC_OUTPUT_MEMORY) {
715 val = add_jmp_table(s1, val);
716 diff = val - addr;
718 if (diff <= -2147483647 || diff > 2147483647) {
719 #if 0
720 /* output memory map to debug easily */
721 FILE* fp;
722 char buf[4096];
723 int size;
724 Dl_info di;
725 printf("%ld - %ld = %ld\n", val, addr, diff);
726 dladdr((void *)addr, &di);
727 printf("addr = %lx = %lx+%lx(%s) ptr=%p\n",
728 addr, s->sh_addr, rel->r_offset, di.dli_sname,
729 ptr);
730 fp = fopen("/proc/self/maps", "r");
731 size = fread(buf, 1, 4095, fp);
732 buf[size] = '\0';
733 printf("%s", buf);
734 #endif
735 error("internal error: relocation failed");
738 *(int *)ptr += diff;
740 break;
741 case R_X86_64_PLT32:
742 *(int *)ptr += val - addr;
743 break;
744 case R_X86_64_GLOB_DAT:
745 case R_X86_64_JUMP_SLOT:
746 *(int *)ptr = val;
747 break;
748 case R_X86_64_GOTPCREL:
749 if (s1->output_type == TCC_OUTPUT_MEMORY) {
750 val = add_got_table(s1, val - rel->r_addend) + rel->r_addend;
751 *(int *)ptr += val - addr;
752 break;
754 *(int *)ptr += (s1->got->sh_addr - addr +
755 s1->got_offsets[sym_index] - 4);
756 break;
757 case R_X86_64_GOTTPOFF:
758 *(int *)ptr += val - s1->got->sh_addr;
759 break;
760 case R_X86_64_GOT32:
761 /* we load the got offset */
762 *(int *)ptr += s1->got_offsets[sym_index];
763 break;
764 #else
765 #error unsupported processor
766 #endif
769 /* if the relocation is allocated, we change its symbol table */
770 if (sr->sh_flags & SHF_ALLOC)
771 sr->link = s1->dynsym;
774 /* relocate relocation table in 'sr' */
775 static void relocate_rel(TCCState *s1, Section *sr)
777 Section *s;
778 ElfW_Rel *rel, *rel_end;
780 s = s1->sections[sr->sh_info];
781 rel_end = (ElfW_Rel *)(sr->data + sr->data_offset);
782 for(rel = (ElfW_Rel *)sr->data;
783 rel < rel_end;
784 rel++) {
785 rel->r_offset += s->sh_addr;
789 /* count the number of dynamic relocations so that we can reserve
790 their space */
791 static int prepare_dynamic_rel(TCCState *s1, Section *sr)
793 ElfW_Rel *rel, *rel_end;
794 int sym_index, esym_index, type, count;
796 count = 0;
797 rel_end = (ElfW_Rel *)(sr->data + sr->data_offset);
798 for(rel = (ElfW_Rel *)sr->data; rel < rel_end; rel++) {
799 sym_index = ELFW(R_SYM)(rel->r_info);
800 type = ELFW(R_TYPE)(rel->r_info);
801 switch(type) {
802 #if defined(TCC_TARGET_I386)
803 case R_386_32:
804 #elif defined(TCC_TARGET_X86_64)
805 case R_X86_64_32:
806 case R_X86_64_32S:
807 case R_X86_64_64:
808 #endif
809 count++;
810 break;
811 #if defined(TCC_TARGET_I386)
812 case R_386_PC32:
813 #elif defined(TCC_TARGET_X86_64)
814 case R_X86_64_PC32:
815 #endif
816 esym_index = s1->symtab_to_dynsym[sym_index];
817 if (esym_index)
818 count++;
819 break;
820 default:
821 break;
824 if (count) {
825 /* allocate the section */
826 sr->sh_flags |= SHF_ALLOC;
827 sr->sh_size = count * sizeof(ElfW_Rel);
829 return count;
832 static void put_got_offset(TCCState *s1, int index, unsigned long val)
834 int n;
835 unsigned long *tab;
837 if (index >= s1->nb_got_offsets) {
838 /* find immediately bigger power of 2 and reallocate array */
839 n = 1;
840 while (index >= n)
841 n *= 2;
842 tab = tcc_realloc(s1->got_offsets, n * sizeof(unsigned long));
843 if (!tab)
844 error("memory full");
845 s1->got_offsets = tab;
846 memset(s1->got_offsets + s1->nb_got_offsets, 0,
847 (n - s1->nb_got_offsets) * sizeof(unsigned long));
848 s1->nb_got_offsets = n;
850 s1->got_offsets[index] = val;
853 /* XXX: suppress that */
854 static void put32(unsigned char *p, uint32_t val)
856 p[0] = val;
857 p[1] = val >> 8;
858 p[2] = val >> 16;
859 p[3] = val >> 24;
862 #if defined(TCC_TARGET_I386) || defined(TCC_TARGET_ARM) || \
863 defined(TCC_TARGET_X86_64)
864 static uint32_t get32(unsigned char *p)
866 return p[0] | (p[1] << 8) | (p[2] << 16) | (p[3] << 24);
868 #endif
870 static void build_got(TCCState *s1)
872 unsigned char *ptr;
874 /* if no got, then create it */
875 s1->got = new_section(s1, ".got", SHT_PROGBITS, SHF_ALLOC | SHF_WRITE);
876 s1->got->sh_entsize = 4;
877 add_elf_sym(symtab_section, 0, 4, ELFW(ST_INFO)(STB_GLOBAL, STT_OBJECT),
878 0, s1->got->sh_num, "_GLOBAL_OFFSET_TABLE_");
879 ptr = section_ptr_add(s1->got, 3 * PTR_SIZE);
880 #if PTR_SIZE == 4
881 /* keep space for _DYNAMIC pointer, if present */
882 put32(ptr, 0);
883 /* two dummy got entries */
884 put32(ptr + 4, 0);
885 put32(ptr + 8, 0);
886 #else
887 /* keep space for _DYNAMIC pointer, if present */
888 put32(ptr, 0);
889 put32(ptr + 4, 0);
890 /* two dummy got entries */
891 put32(ptr + 8, 0);
892 put32(ptr + 12, 0);
893 put32(ptr + 16, 0);
894 put32(ptr + 20, 0);
895 #endif
898 /* put a got entry corresponding to a symbol in symtab_section. 'size'
899 and 'info' can be modifed if more precise info comes from the DLL */
900 static void put_got_entry(TCCState *s1,
901 int reloc_type, unsigned long size, int info,
902 int sym_index)
904 int index;
905 const char *name;
906 ElfW(Sym) *sym;
907 unsigned long offset;
908 int *ptr;
910 if (!s1->got)
911 build_got(s1);
913 /* if a got entry already exists for that symbol, no need to add one */
914 if (sym_index < s1->nb_got_offsets &&
915 s1->got_offsets[sym_index] != 0)
916 return;
918 put_got_offset(s1, sym_index, s1->got->data_offset);
920 if (s1->dynsym) {
921 sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
922 name = symtab_section->link->data + sym->st_name;
923 offset = sym->st_value;
924 #if defined(TCC_TARGET_I386) || defined(TCC_TARGET_X86_64)
925 if (reloc_type ==
926 #ifdef TCC_TARGET_X86_64
927 R_X86_64_JUMP_SLOT
928 #else
929 R_386_JMP_SLOT
930 #endif
932 Section *plt;
933 uint8_t *p;
934 int modrm;
936 #if defined(TCC_OUTPUT_DLL_WITH_PLT)
937 modrm = 0x25;
938 #else
939 /* if we build a DLL, we add a %ebx offset */
940 if (s1->output_type == TCC_OUTPUT_DLL)
941 modrm = 0xa3;
942 else
943 modrm = 0x25;
944 #endif
946 /* add a PLT entry */
947 plt = s1->plt;
948 if (plt->data_offset == 0) {
949 /* first plt entry */
950 p = section_ptr_add(plt, 16);
951 p[0] = 0xff; /* pushl got + PTR_SIZE */
952 p[1] = modrm + 0x10;
953 put32(p + 2, PTR_SIZE);
954 p[6] = 0xff; /* jmp *(got + PTR_SIZE * 2) */
955 p[7] = modrm;
956 put32(p + 8, PTR_SIZE * 2);
959 p = section_ptr_add(plt, 16);
960 p[0] = 0xff; /* jmp *(got + x) */
961 p[1] = modrm;
962 put32(p + 2, s1->got->data_offset);
963 p[6] = 0x68; /* push $xxx */
964 put32(p + 7, (plt->data_offset - 32) >> 1);
965 p[11] = 0xe9; /* jmp plt_start */
966 put32(p + 12, -(plt->data_offset));
968 /* the symbol is modified so that it will be relocated to
969 the PLT */
970 #if !defined(TCC_OUTPUT_DLL_WITH_PLT)
971 if (s1->output_type == TCC_OUTPUT_EXE)
972 #endif
973 offset = plt->data_offset - 16;
975 #elif defined(TCC_TARGET_ARM)
976 if (reloc_type == R_ARM_JUMP_SLOT) {
977 Section *plt;
978 uint8_t *p;
980 /* if we build a DLL, we add a %ebx offset */
981 if (s1->output_type == TCC_OUTPUT_DLL)
982 error("DLLs unimplemented!");
984 /* add a PLT entry */
985 plt = s1->plt;
986 if (plt->data_offset == 0) {
987 /* first plt entry */
988 p = section_ptr_add(plt, 16);
989 put32(p , 0xe52de004);
990 put32(p + 4, 0xe59fe010);
991 put32(p + 8, 0xe08fe00e);
992 put32(p + 12, 0xe5bef008);
995 p = section_ptr_add(plt, 16);
996 put32(p , 0xe59fc004);
997 put32(p+4, 0xe08fc00c);
998 put32(p+8, 0xe59cf000);
999 put32(p+12, s1->got->data_offset);
1001 /* the symbol is modified so that it will be relocated to
1002 the PLT */
1003 if (s1->output_type == TCC_OUTPUT_EXE)
1004 offset = plt->data_offset - 16;
1006 #elif defined(TCC_TARGET_C67)
1007 error("C67 got not implemented");
1008 #else
1009 #error unsupported CPU
1010 #endif
1011 index = put_elf_sym(s1->dynsym, offset,
1012 size, info, 0, sym->st_shndx, name);
1013 /* put a got entry */
1014 put_elf_reloc(s1->dynsym, s1->got,
1015 s1->got->data_offset,
1016 reloc_type, index);
1018 ptr = section_ptr_add(s1->got, PTR_SIZE);
1019 *ptr = 0;
1022 /* build GOT and PLT entries */
1023 static void build_got_entries(TCCState *s1)
1025 Section *s, *symtab;
1026 ElfW_Rel *rel, *rel_end;
1027 ElfW(Sym) *sym;
1028 int i, type, reloc_type, sym_index;
1030 for(i = 1; i < s1->nb_sections; i++) {
1031 s = s1->sections[i];
1032 if (s->sh_type != SHT_RELX)
1033 continue;
1034 /* no need to handle got relocations */
1035 if (s->link != symtab_section)
1036 continue;
1037 symtab = s->link;
1038 rel_end = (ElfW_Rel *)(s->data + s->data_offset);
1039 for(rel = (ElfW_Rel *)s->data;
1040 rel < rel_end;
1041 rel++) {
1042 type = ELFW(R_TYPE)(rel->r_info);
1043 switch(type) {
1044 #if defined(TCC_TARGET_I386)
1045 case R_386_GOT32:
1046 case R_386_GOTOFF:
1047 case R_386_GOTPC:
1048 case R_386_PLT32:
1049 if (!s1->got)
1050 build_got(s1);
1051 if (type == R_386_GOT32 || type == R_386_PLT32) {
1052 sym_index = ELFW(R_SYM)(rel->r_info);
1053 sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
1054 /* look at the symbol got offset. If none, then add one */
1055 if (type == R_386_GOT32)
1056 reloc_type = R_386_GLOB_DAT;
1057 else
1058 reloc_type = R_386_JMP_SLOT;
1059 put_got_entry(s1, reloc_type, sym->st_size, sym->st_info,
1060 sym_index);
1062 break;
1063 #elif defined(TCC_TARGET_ARM)
1064 case R_ARM_GOT_BREL:
1065 case R_ARM_GOTOFF32:
1066 case R_ARM_BASE_PREL:
1067 case R_ARM_PLT32:
1068 if (!s1->got)
1069 build_got(s1);
1070 if (type == R_ARM_GOT_BREL || type == R_ARM_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_ARM_GOT_BREL)
1075 reloc_type = R_ARM_GLOB_DAT;
1076 else
1077 reloc_type = R_ARM_JUMP_SLOT;
1078 put_got_entry(s1, reloc_type, sym->st_size, sym->st_info,
1079 sym_index);
1081 break;
1082 #elif defined(TCC_TARGET_C67)
1083 case R_C60_GOT32:
1084 case R_C60_GOTOFF:
1085 case R_C60_GOTPC:
1086 case R_C60_PLT32:
1087 if (!s1->got)
1088 build_got(s1);
1089 if (type == R_C60_GOT32 || type == R_C60_PLT32) {
1090 sym_index = ELFW(R_SYM)(rel->r_info);
1091 sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
1092 /* look at the symbol got offset. If none, then add one */
1093 if (type == R_C60_GOT32)
1094 reloc_type = R_C60_GLOB_DAT;
1095 else
1096 reloc_type = R_C60_JMP_SLOT;
1097 put_got_entry(s1, reloc_type, sym->st_size, sym->st_info,
1098 sym_index);
1100 break;
1101 #elif defined(TCC_TARGET_X86_64)
1102 case R_X86_64_GOT32:
1103 case R_X86_64_GOTTPOFF:
1104 case R_X86_64_GOTPCREL:
1105 case R_X86_64_PLT32:
1106 if (!s1->got)
1107 build_got(s1);
1108 if (type == R_X86_64_GOT32 || type == R_X86_64_GOTPCREL ||
1109 type == R_X86_64_PLT32) {
1110 sym_index = ELFW(R_SYM)(rel->r_info);
1111 sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
1112 /* look at the symbol got offset. If none, then add one */
1113 if (type == R_X86_64_GOT32 || type == R_X86_64_GOTPCREL)
1114 reloc_type = R_X86_64_GLOB_DAT;
1115 else
1116 reloc_type = R_X86_64_JUMP_SLOT;
1117 put_got_entry(s1, reloc_type, sym->st_size, sym->st_info,
1118 sym_index);
1120 break;
1121 #else
1122 #error unsupported CPU
1123 #endif
1124 default:
1125 break;
1131 static Section *new_symtab(TCCState *s1,
1132 const char *symtab_name, int sh_type, int sh_flags,
1133 const char *strtab_name,
1134 const char *hash_name, int hash_sh_flags)
1136 Section *symtab, *strtab, *hash;
1137 int *ptr, nb_buckets;
1139 symtab = new_section(s1, symtab_name, sh_type, sh_flags);
1140 symtab->sh_entsize = sizeof(ElfW(Sym));
1141 strtab = new_section(s1, strtab_name, SHT_STRTAB, sh_flags);
1142 put_elf_str(strtab, "");
1143 symtab->link = strtab;
1144 put_elf_sym(symtab, 0, 0, 0, 0, 0, NULL);
1146 nb_buckets = 1;
1148 hash = new_section(s1, hash_name, SHT_HASH, hash_sh_flags);
1149 hash->sh_entsize = sizeof(int);
1150 symtab->hash = hash;
1151 hash->link = symtab;
1153 ptr = section_ptr_add(hash, (2 + nb_buckets + 1) * sizeof(int));
1154 ptr[0] = nb_buckets;
1155 ptr[1] = 1;
1156 memset(ptr + 2, 0, (nb_buckets + 1) * sizeof(int));
1157 return symtab;
1160 /* put dynamic tag */
1161 static void put_dt(Section *dynamic, int dt, unsigned long val)
1163 ElfW(Dyn) *dyn;
1164 dyn = section_ptr_add(dynamic, sizeof(ElfW(Dyn)));
1165 dyn->d_tag = dt;
1166 dyn->d_un.d_val = val;
1169 static void add_init_array_defines(TCCState *s1, const char *section_name)
1171 Section *s;
1172 long end_offset;
1173 char sym_start[1024];
1174 char sym_end[1024];
1176 snprintf(sym_start, sizeof(sym_start), "__%s_start", section_name + 1);
1177 snprintf(sym_end, sizeof(sym_end), "__%s_end", section_name + 1);
1179 s = find_section(s1, section_name);
1180 if (!s) {
1181 end_offset = 0;
1182 s = data_section;
1183 } else {
1184 end_offset = s->data_offset;
1187 add_elf_sym(symtab_section,
1188 0, 0,
1189 ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
1190 s->sh_num, sym_start);
1191 add_elf_sym(symtab_section,
1192 end_offset, 0,
1193 ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
1194 s->sh_num, sym_end);
1197 /* add tcc runtime libraries */
1198 static void tcc_add_runtime(TCCState *s1)
1200 #if defined(CONFIG_TCC_BCHECK) || !defined(CONFIG_USE_LIBGCC)
1201 char buf[1024];
1202 #endif
1204 #ifdef CONFIG_TCC_BCHECK
1205 if (do_bounds_check) {
1206 unsigned long *ptr;
1207 Section *init_section;
1208 unsigned char *pinit;
1209 int sym_index;
1211 /* XXX: add an object file to do that */
1212 ptr = section_ptr_add(bounds_section, sizeof(unsigned long));
1213 *ptr = 0;
1214 add_elf_sym(symtab_section, 0, 0,
1215 ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
1216 bounds_section->sh_num, "__bounds_start");
1217 /* add bound check code */
1218 snprintf(buf, sizeof(buf), "%s/%s", tcc_lib_path, "bcheck.o");
1219 tcc_add_file(s1, buf);
1220 #ifdef TCC_TARGET_I386
1221 if (s1->output_type != TCC_OUTPUT_MEMORY) {
1222 /* add 'call __bound_init()' in .init section */
1223 init_section = find_section(s1, ".init");
1224 pinit = section_ptr_add(init_section, 5);
1225 pinit[0] = 0xe8;
1226 put32(pinit + 1, -4);
1227 sym_index = find_elf_sym(symtab_section, "__bound_init");
1228 put_elf_reloc(symtab_section, init_section,
1229 init_section->data_offset - 4, R_386_PC32, sym_index);
1231 #endif
1233 #endif
1234 /* add libc */
1235 if (!s1->nostdlib) {
1236 tcc_add_library(s1, "c");
1238 #ifdef CONFIG_USE_LIBGCC
1239 tcc_add_file(s1, CONFIG_SYSROOT "/lib/libgcc_s.so.1");
1240 #else
1241 snprintf(buf, sizeof(buf), "%s/%s", tcc_lib_path, "libtcc1.a");
1242 tcc_add_file(s1, buf);
1243 #endif
1245 /* add crt end if not memory output */
1246 if (s1->output_type != TCC_OUTPUT_MEMORY && !s1->nostdlib) {
1247 tcc_add_file(s1, CONFIG_TCC_CRT_PREFIX "/crtn.o");
1251 /* add various standard linker symbols (must be done after the
1252 sections are filled (for example after allocating common
1253 symbols)) */
1254 static void tcc_add_linker_symbols(TCCState *s1)
1256 char buf[1024];
1257 int i;
1258 Section *s;
1260 add_elf_sym(symtab_section,
1261 text_section->data_offset, 0,
1262 ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
1263 text_section->sh_num, "_etext");
1264 add_elf_sym(symtab_section,
1265 data_section->data_offset, 0,
1266 ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
1267 data_section->sh_num, "_edata");
1268 add_elf_sym(symtab_section,
1269 bss_section->data_offset, 0,
1270 ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
1271 bss_section->sh_num, "_end");
1272 /* horrible new standard ldscript defines */
1273 add_init_array_defines(s1, ".preinit_array");
1274 add_init_array_defines(s1, ".init_array");
1275 add_init_array_defines(s1, ".fini_array");
1277 /* add start and stop symbols for sections whose name can be
1278 expressed in C */
1279 for(i = 1; i < s1->nb_sections; i++) {
1280 s = s1->sections[i];
1281 if (s->sh_type == SHT_PROGBITS &&
1282 (s->sh_flags & SHF_ALLOC)) {
1283 const char *p;
1284 int ch;
1286 /* check if section name can be expressed in C */
1287 p = s->name;
1288 for(;;) {
1289 ch = *p;
1290 if (!ch)
1291 break;
1292 if (!isid(ch) && !isnum(ch))
1293 goto next_sec;
1294 p++;
1296 snprintf(buf, sizeof(buf), "__start_%s", s->name);
1297 add_elf_sym(symtab_section,
1298 0, 0,
1299 ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
1300 s->sh_num, buf);
1301 snprintf(buf, sizeof(buf), "__stop_%s", s->name);
1302 add_elf_sym(symtab_section,
1303 s->data_offset, 0,
1304 ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
1305 s->sh_num, buf);
1307 next_sec: ;
1311 /* name of ELF interpreter */
1312 #ifdef __FreeBSD__
1313 static char elf_interp[] = "/usr/libexec/ld-elf.so.1";
1314 #else
1315 #ifdef TCC_ARM_EABI
1316 static char elf_interp[] = "/lib/ld-linux.so.3";
1317 #elif defined(TCC_TARGET_X86_64)
1318 static char elf_interp[] = "/lib/ld-linux-x86-64.so.2";
1319 #else
1320 static char elf_interp[] = "/lib/ld-linux.so.2";
1321 #endif
1322 #endif
1324 static void tcc_output_binary(TCCState *s1, FILE *f,
1325 const int *section_order)
1327 Section *s;
1328 int i, offset, size;
1330 offset = 0;
1331 for(i=1;i<s1->nb_sections;i++) {
1332 s = s1->sections[section_order[i]];
1333 if (s->sh_type != SHT_NOBITS &&
1334 (s->sh_flags & SHF_ALLOC)) {
1335 while (offset < s->sh_offset) {
1336 fputc(0, f);
1337 offset++;
1339 size = s->sh_size;
1340 fwrite(s->data, 1, size, f);
1341 offset += size;
1346 /* output an ELF file */
1347 /* XXX: suppress unneeded sections */
1348 int elf_output_file(TCCState *s1, const char *filename)
1350 ElfW(Ehdr) ehdr;
1351 FILE *f;
1352 int fd, mode, ret;
1353 int *section_order;
1354 int shnum, i, phnum, file_offset, offset, size, j, tmp, sh_order_index, k;
1355 unsigned long addr;
1356 Section *strsec, *s;
1357 ElfW(Shdr) shdr, *sh;
1358 ElfW(Phdr) *phdr, *ph;
1359 Section *interp, *dynamic, *dynstr;
1360 unsigned long saved_dynamic_data_offset;
1361 ElfW(Sym) *sym;
1362 int type, file_type;
1363 unsigned long rel_addr, rel_size;
1365 file_type = s1->output_type;
1366 s1->nb_errors = 0;
1368 if (file_type != TCC_OUTPUT_OBJ) {
1369 tcc_add_runtime(s1);
1372 phdr = NULL;
1373 section_order = NULL;
1374 interp = NULL;
1375 dynamic = NULL;
1376 dynstr = NULL; /* avoid warning */
1377 saved_dynamic_data_offset = 0; /* avoid warning */
1379 if (file_type != TCC_OUTPUT_OBJ) {
1380 relocate_common_syms();
1382 tcc_add_linker_symbols(s1);
1384 if (!s1->static_link) {
1385 const char *name;
1386 int sym_index, index;
1387 ElfW(Sym) *esym, *sym_end;
1389 if (file_type == TCC_OUTPUT_EXE) {
1390 char *ptr;
1391 /* add interpreter section only if executable */
1392 interp = new_section(s1, ".interp", SHT_PROGBITS, SHF_ALLOC);
1393 interp->sh_addralign = 1;
1394 ptr = section_ptr_add(interp, sizeof(elf_interp));
1395 strcpy(ptr, elf_interp);
1398 /* add dynamic symbol table */
1399 s1->dynsym = new_symtab(s1, ".dynsym", SHT_DYNSYM, SHF_ALLOC,
1400 ".dynstr",
1401 ".hash", SHF_ALLOC);
1402 dynstr = s1->dynsym->link;
1404 /* add dynamic section */
1405 dynamic = new_section(s1, ".dynamic", SHT_DYNAMIC,
1406 SHF_ALLOC | SHF_WRITE);
1407 dynamic->link = dynstr;
1408 dynamic->sh_entsize = sizeof(ElfW(Dyn));
1410 /* add PLT */
1411 s1->plt = new_section(s1, ".plt", SHT_PROGBITS,
1412 SHF_ALLOC | SHF_EXECINSTR);
1413 s1->plt->sh_entsize = 4;
1415 build_got(s1);
1417 /* scan for undefined symbols and see if they are in the
1418 dynamic symbols. If a symbol STT_FUNC is found, then we
1419 add it in the PLT. If a symbol STT_OBJECT is found, we
1420 add it in the .bss section with a suitable relocation */
1421 sym_end = (ElfW(Sym) *)(symtab_section->data +
1422 symtab_section->data_offset);
1423 if (file_type == TCC_OUTPUT_EXE) {
1424 for(sym = (ElfW(Sym) *)symtab_section->data + 1;
1425 sym < sym_end;
1426 sym++) {
1427 if (sym->st_shndx == SHN_UNDEF) {
1428 name = symtab_section->link->data + sym->st_name;
1429 sym_index = find_elf_sym(s1->dynsymtab_section, name);
1430 if (sym_index) {
1431 esym = &((ElfW(Sym) *)s1->dynsymtab_section->data)[sym_index];
1432 type = ELFW(ST_TYPE)(esym->st_info);
1433 if (type == STT_FUNC) {
1434 put_got_entry(s1, R_JMP_SLOT, esym->st_size,
1435 esym->st_info,
1436 sym - (ElfW(Sym) *)symtab_section->data);
1437 } else if (type == STT_OBJECT) {
1438 unsigned long offset;
1439 offset = bss_section->data_offset;
1440 /* XXX: which alignment ? */
1441 offset = (offset + 16 - 1) & -16;
1442 index = put_elf_sym(s1->dynsym, offset, esym->st_size,
1443 esym->st_info, 0,
1444 bss_section->sh_num, name);
1445 put_elf_reloc(s1->dynsym, bss_section,
1446 offset, R_COPY, index);
1447 offset += esym->st_size;
1448 bss_section->data_offset = offset;
1450 } else {
1451 /* STB_WEAK undefined symbols are accepted */
1452 /* XXX: _fp_hw seems to be part of the ABI, so we ignore
1453 it */
1454 if (ELFW(ST_BIND)(sym->st_info) == STB_WEAK ||
1455 !strcmp(name, "_fp_hw")) {
1456 } else {
1457 error_noabort("undefined symbol '%s'", name);
1460 } else if (s1->rdynamic &&
1461 ELFW(ST_BIND)(sym->st_info) != STB_LOCAL) {
1462 /* if -rdynamic option, then export all non
1463 local symbols */
1464 name = symtab_section->link->data + sym->st_name;
1465 put_elf_sym(s1->dynsym, sym->st_value, sym->st_size,
1466 sym->st_info, 0,
1467 sym->st_shndx, name);
1471 if (s1->nb_errors)
1472 goto fail;
1474 /* now look at unresolved dynamic symbols and export
1475 corresponding symbol */
1476 sym_end = (ElfW(Sym) *)(s1->dynsymtab_section->data +
1477 s1->dynsymtab_section->data_offset);
1478 for(esym = (ElfW(Sym) *)s1->dynsymtab_section->data + 1;
1479 esym < sym_end;
1480 esym++) {
1481 if (esym->st_shndx == SHN_UNDEF) {
1482 name = s1->dynsymtab_section->link->data + esym->st_name;
1483 sym_index = find_elf_sym(symtab_section, name);
1484 if (sym_index) {
1485 /* XXX: avoid adding a symbol if already
1486 present because of -rdynamic ? */
1487 sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
1488 put_elf_sym(s1->dynsym, sym->st_value, sym->st_size,
1489 sym->st_info, 0,
1490 sym->st_shndx, name);
1491 } else {
1492 if (ELFW(ST_BIND)(esym->st_info) == STB_WEAK) {
1493 /* weak symbols can stay undefined */
1494 } else {
1495 warning("undefined dynamic symbol '%s'", name);
1500 } else {
1501 int nb_syms;
1502 /* shared library case : we simply export all the global symbols */
1503 nb_syms = symtab_section->data_offset / sizeof(ElfW(Sym));
1504 s1->symtab_to_dynsym = tcc_mallocz(sizeof(int) * nb_syms);
1505 for(sym = (ElfW(Sym) *)symtab_section->data + 1;
1506 sym < sym_end;
1507 sym++) {
1508 if (ELFW(ST_BIND)(sym->st_info) != STB_LOCAL) {
1509 #if defined(TCC_OUTPUT_DLL_WITH_PLT)
1510 if (ELFW(ST_TYPE)(sym->st_info) == STT_FUNC &&
1511 sym->st_shndx == SHN_UNDEF) {
1512 put_got_entry(s1, R_JMP_SLOT, sym->st_size,
1513 sym->st_info,
1514 sym - (ElfW(Sym) *)symtab_section->data);
1516 else if (ELFW(ST_TYPE)(sym->st_info) == STT_OBJECT) {
1517 put_got_entry(s1, R_X86_64_GLOB_DAT, sym->st_size,
1518 sym->st_info,
1519 sym - (ElfW(Sym) *)symtab_section->data);
1521 else
1522 #endif
1524 name = symtab_section->link->data + sym->st_name;
1525 index = put_elf_sym(s1->dynsym, sym->st_value, sym->st_size,
1526 sym->st_info, 0,
1527 sym->st_shndx, name);
1528 s1->symtab_to_dynsym[sym -
1529 (ElfW(Sym) *)symtab_section->data] =
1530 index;
1536 build_got_entries(s1);
1538 /* add a list of needed dlls */
1539 for(i = 0; i < s1->nb_loaded_dlls; i++) {
1540 DLLReference *dllref = s1->loaded_dlls[i];
1541 if (dllref->level == 0)
1542 put_dt(dynamic, DT_NEEDED, put_elf_str(dynstr, dllref->name));
1544 /* XXX: currently, since we do not handle PIC code, we
1545 must relocate the readonly segments */
1546 if (file_type == TCC_OUTPUT_DLL) {
1547 if (s1->soname)
1548 put_dt(dynamic, DT_SONAME, put_elf_str(dynstr, s1->soname));
1549 put_dt(dynamic, DT_TEXTREL, 0);
1552 /* add necessary space for other entries */
1553 saved_dynamic_data_offset = dynamic->data_offset;
1554 dynamic->data_offset += sizeof(ElfW(Dyn)) * 9;
1555 } else {
1556 /* still need to build got entries in case of static link */
1557 build_got_entries(s1);
1561 memset(&ehdr, 0, sizeof(ehdr));
1563 /* we add a section for symbols */
1564 strsec = new_section(s1, ".shstrtab", SHT_STRTAB, 0);
1565 put_elf_str(strsec, "");
1567 /* compute number of sections */
1568 shnum = s1->nb_sections;
1570 /* this array is used to reorder sections in the output file */
1571 section_order = tcc_malloc(sizeof(int) * shnum);
1572 section_order[0] = 0;
1573 sh_order_index = 1;
1575 /* compute number of program headers */
1576 switch(file_type) {
1577 default:
1578 case TCC_OUTPUT_OBJ:
1579 phnum = 0;
1580 break;
1581 case TCC_OUTPUT_EXE:
1582 if (!s1->static_link)
1583 phnum = 4;
1584 else
1585 phnum = 2;
1586 break;
1587 case TCC_OUTPUT_DLL:
1588 phnum = 3;
1589 break;
1592 /* allocate strings for section names and decide if an unallocated
1593 section should be output */
1594 /* NOTE: the strsec section comes last, so its size is also
1595 correct ! */
1596 for(i = 1; i < s1->nb_sections; i++) {
1597 s = s1->sections[i];
1598 s->sh_name = put_elf_str(strsec, s->name);
1599 #if 0 //gr
1600 printf("section: f=%08x t=%08x i=%08x %s %s\n",
1601 s->sh_flags,
1602 s->sh_type,
1603 s->sh_info,
1604 s->name,
1605 s->reloc ? s->reloc->name : "n"
1607 #endif
1608 /* when generating a DLL, we include relocations but we may
1609 patch them */
1610 if (file_type == TCC_OUTPUT_DLL &&
1611 s->sh_type == SHT_RELX &&
1612 !(s->sh_flags & SHF_ALLOC)) {
1613 /* //gr: avoid bogus relocs for empty (debug) sections */
1614 if (s1->sections[s->sh_info]->sh_flags & SHF_ALLOC)
1615 prepare_dynamic_rel(s1, s);
1616 else if (do_debug)
1617 s->sh_size = s->data_offset;
1618 } else if (do_debug ||
1619 file_type == TCC_OUTPUT_OBJ ||
1620 (s->sh_flags & SHF_ALLOC) ||
1621 i == (s1->nb_sections - 1)) {
1622 /* we output all sections if debug or object file */
1623 s->sh_size = s->data_offset;
1627 /* allocate program segment headers */
1628 phdr = tcc_mallocz(phnum * sizeof(ElfW(Phdr)));
1630 if (s1->output_format == TCC_OUTPUT_FORMAT_ELF) {
1631 file_offset = sizeof(ElfW(Ehdr)) + phnum * sizeof(ElfW(Phdr));
1632 } else {
1633 file_offset = 0;
1635 if (phnum > 0) {
1636 /* compute section to program header mapping */
1637 if (s1->has_text_addr) {
1638 int a_offset, p_offset;
1639 addr = s1->text_addr;
1640 /* we ensure that (addr % ELF_PAGE_SIZE) == file_offset %
1641 ELF_PAGE_SIZE */
1642 a_offset = addr & (ELF_PAGE_SIZE - 1);
1643 p_offset = file_offset & (ELF_PAGE_SIZE - 1);
1644 if (a_offset < p_offset)
1645 a_offset += ELF_PAGE_SIZE;
1646 file_offset += (a_offset - p_offset);
1647 } else {
1648 if (file_type == TCC_OUTPUT_DLL)
1649 addr = 0;
1650 else
1651 addr = ELF_START_ADDR;
1652 /* compute address after headers */
1653 addr += (file_offset & (ELF_PAGE_SIZE - 1));
1656 /* dynamic relocation table information, for .dynamic section */
1657 rel_size = 0;
1658 rel_addr = 0;
1660 /* leave one program header for the program interpreter */
1661 ph = &phdr[0];
1662 if (interp)
1663 ph++;
1665 for(j = 0; j < 2; j++) {
1666 ph->p_type = PT_LOAD;
1667 if (j == 0)
1668 ph->p_flags = PF_R | PF_X;
1669 else
1670 ph->p_flags = PF_R | PF_W;
1671 ph->p_align = ELF_PAGE_SIZE;
1673 /* we do the following ordering: interp, symbol tables,
1674 relocations, progbits, nobits */
1675 /* XXX: do faster and simpler sorting */
1676 for(k = 0; k < 5; k++) {
1677 for(i = 1; i < s1->nb_sections; i++) {
1678 s = s1->sections[i];
1679 /* compute if section should be included */
1680 if (j == 0) {
1681 if ((s->sh_flags & (SHF_ALLOC | SHF_WRITE)) !=
1682 SHF_ALLOC)
1683 continue;
1684 } else {
1685 if ((s->sh_flags & (SHF_ALLOC | SHF_WRITE)) !=
1686 (SHF_ALLOC | SHF_WRITE))
1687 continue;
1689 if (s == interp) {
1690 if (k != 0)
1691 continue;
1692 } else if (s->sh_type == SHT_DYNSYM ||
1693 s->sh_type == SHT_STRTAB ||
1694 s->sh_type == SHT_HASH) {
1695 if (k != 1)
1696 continue;
1697 } else if (s->sh_type == SHT_RELX) {
1698 if (k != 2)
1699 continue;
1700 } else if (s->sh_type == SHT_NOBITS) {
1701 if (k != 4)
1702 continue;
1703 } else {
1704 if (k != 3)
1705 continue;
1707 section_order[sh_order_index++] = i;
1709 /* section matches: we align it and add its size */
1710 tmp = addr;
1711 addr = (addr + s->sh_addralign - 1) &
1712 ~(s->sh_addralign - 1);
1713 file_offset += addr - tmp;
1714 s->sh_offset = file_offset;
1715 s->sh_addr = addr;
1717 /* update program header infos */
1718 if (ph->p_offset == 0) {
1719 ph->p_offset = file_offset;
1720 ph->p_vaddr = addr;
1721 ph->p_paddr = ph->p_vaddr;
1723 /* update dynamic relocation infos */
1724 if (s->sh_type == SHT_RELX) {
1725 if (rel_size == 0)
1726 rel_addr = addr;
1727 rel_size += s->sh_size;
1729 addr += s->sh_size;
1730 if (s->sh_type != SHT_NOBITS)
1731 file_offset += s->sh_size;
1734 ph->p_filesz = file_offset - ph->p_offset;
1735 ph->p_memsz = addr - ph->p_vaddr;
1736 ph++;
1737 if (j == 0) {
1738 if (s1->output_format == TCC_OUTPUT_FORMAT_ELF) {
1739 /* if in the middle of a page, we duplicate the page in
1740 memory so that one copy is RX and the other is RW */
1741 if ((addr & (ELF_PAGE_SIZE - 1)) != 0)
1742 addr += ELF_PAGE_SIZE;
1743 } else {
1744 addr = (addr + ELF_PAGE_SIZE - 1) & ~(ELF_PAGE_SIZE - 1);
1745 file_offset = (file_offset + ELF_PAGE_SIZE - 1) &
1746 ~(ELF_PAGE_SIZE - 1);
1751 /* if interpreter, then add corresponing program header */
1752 if (interp) {
1753 ph = &phdr[0];
1755 ph->p_type = PT_INTERP;
1756 ph->p_offset = interp->sh_offset;
1757 ph->p_vaddr = interp->sh_addr;
1758 ph->p_paddr = ph->p_vaddr;
1759 ph->p_filesz = interp->sh_size;
1760 ph->p_memsz = interp->sh_size;
1761 ph->p_flags = PF_R;
1762 ph->p_align = interp->sh_addralign;
1765 /* if dynamic section, then add corresponing program header */
1766 if (dynamic) {
1767 ElfW(Sym) *sym_end;
1769 ph = &phdr[phnum - 1];
1771 ph->p_type = PT_DYNAMIC;
1772 ph->p_offset = dynamic->sh_offset;
1773 ph->p_vaddr = dynamic->sh_addr;
1774 ph->p_paddr = ph->p_vaddr;
1775 ph->p_filesz = dynamic->sh_size;
1776 ph->p_memsz = dynamic->sh_size;
1777 ph->p_flags = PF_R | PF_W;
1778 ph->p_align = dynamic->sh_addralign;
1780 /* put GOT dynamic section address */
1781 put32(s1->got->data, dynamic->sh_addr);
1783 /* relocate the PLT */
1784 if (file_type == TCC_OUTPUT_EXE
1785 #if defined(TCC_OUTPUT_DLL_WITH_PLT)
1786 || file_type == TCC_OUTPUT_DLL
1787 #endif
1789 uint8_t *p, *p_end;
1791 p = s1->plt->data;
1792 p_end = p + s1->plt->data_offset;
1793 if (p < p_end) {
1794 #if defined(TCC_TARGET_I386)
1795 put32(p + 2, get32(p + 2) + s1->got->sh_addr);
1796 put32(p + 8, get32(p + 8) + s1->got->sh_addr);
1797 p += 16;
1798 while (p < p_end) {
1799 put32(p + 2, get32(p + 2) + s1->got->sh_addr);
1800 p += 16;
1802 #elif defined(TCC_TARGET_X86_64)
1803 int x = s1->got->sh_addr - s1->plt->sh_addr - 6;
1804 put32(p + 2, get32(p + 2) + x);
1805 put32(p + 8, get32(p + 8) + x - 6);
1806 p += 16;
1807 while (p < p_end) {
1808 put32(p + 2, get32(p + 2) + x + s1->plt->data - p);
1809 p += 16;
1811 #elif defined(TCC_TARGET_ARM)
1812 int x;
1813 x=s1->got->sh_addr - s1->plt->sh_addr - 12;
1814 p +=16;
1815 while (p < p_end) {
1816 put32(p + 12, x + get32(p + 12) + s1->plt->data - p);
1817 p += 16;
1819 #elif defined(TCC_TARGET_C67)
1820 /* XXX: TODO */
1821 #else
1822 #error unsupported CPU
1823 #endif
1827 /* relocate symbols in .dynsym */
1828 sym_end = (ElfW(Sym) *)(s1->dynsym->data + s1->dynsym->data_offset);
1829 for(sym = (ElfW(Sym) *)s1->dynsym->data + 1;
1830 sym < sym_end;
1831 sym++) {
1832 if (sym->st_shndx == SHN_UNDEF) {
1833 /* relocate to the PLT if the symbol corresponds
1834 to a PLT entry */
1835 if (sym->st_value)
1836 sym->st_value += s1->plt->sh_addr;
1837 } else if (sym->st_shndx < SHN_LORESERVE) {
1838 /* do symbol relocation */
1839 sym->st_value += s1->sections[sym->st_shndx]->sh_addr;
1843 /* put dynamic section entries */
1844 dynamic->data_offset = saved_dynamic_data_offset;
1845 put_dt(dynamic, DT_HASH, s1->dynsym->hash->sh_addr);
1846 put_dt(dynamic, DT_STRTAB, dynstr->sh_addr);
1847 put_dt(dynamic, DT_SYMTAB, s1->dynsym->sh_addr);
1848 put_dt(dynamic, DT_STRSZ, dynstr->data_offset);
1849 put_dt(dynamic, DT_SYMENT, sizeof(ElfW(Sym)));
1850 #ifdef TCC_TARGET_X86_64
1851 put_dt(dynamic, DT_RELA, rel_addr);
1852 put_dt(dynamic, DT_RELASZ, rel_size);
1853 put_dt(dynamic, DT_RELAENT, sizeof(ElfW_Rel));
1854 #else
1855 put_dt(dynamic, DT_REL, rel_addr);
1856 put_dt(dynamic, DT_RELSZ, rel_size);
1857 put_dt(dynamic, DT_RELENT, sizeof(ElfW_Rel));
1858 #endif
1859 if (do_debug)
1860 put_dt(dynamic, DT_DEBUG, 0);
1861 put_dt(dynamic, DT_NULL, 0);
1864 ehdr.e_phentsize = sizeof(ElfW(Phdr));
1865 ehdr.e_phnum = phnum;
1866 ehdr.e_phoff = sizeof(ElfW(Ehdr));
1869 /* all other sections come after */
1870 for(i = 1; i < s1->nb_sections; i++) {
1871 s = s1->sections[i];
1872 if (phnum > 0 && (s->sh_flags & SHF_ALLOC))
1873 continue;
1874 section_order[sh_order_index++] = i;
1876 file_offset = (file_offset + s->sh_addralign - 1) &
1877 ~(s->sh_addralign - 1);
1878 s->sh_offset = file_offset;
1879 if (s->sh_type != SHT_NOBITS)
1880 file_offset += s->sh_size;
1883 /* if building executable or DLL, then relocate each section
1884 except the GOT which is already relocated */
1885 if (file_type != TCC_OUTPUT_OBJ) {
1886 relocate_syms(s1, 0);
1888 if (s1->nb_errors != 0) {
1889 fail:
1890 ret = -1;
1891 goto the_end;
1894 /* relocate sections */
1895 /* XXX: ignore sections with allocated relocations ? */
1896 for(i = 1; i < s1->nb_sections; i++) {
1897 s = s1->sections[i];
1898 if (s->reloc && s != s1->got && (s->sh_flags & SHF_ALLOC)) //gr
1899 relocate_section(s1, s);
1902 /* relocate relocation entries if the relocation tables are
1903 allocated in the executable */
1904 for(i = 1; i < s1->nb_sections; i++) {
1905 s = s1->sections[i];
1906 if ((s->sh_flags & SHF_ALLOC) &&
1907 s->sh_type == SHT_RELX) {
1908 relocate_rel(s1, s);
1912 /* get entry point address */
1913 if (file_type == TCC_OUTPUT_EXE)
1914 ehdr.e_entry = (unsigned long)tcc_get_symbol_err(s1, "_start");
1915 else
1916 ehdr.e_entry = text_section->sh_addr; /* XXX: is it correct ? */
1919 /* write elf file */
1920 if (file_type == TCC_OUTPUT_OBJ)
1921 mode = 0666;
1922 else
1923 mode = 0777;
1924 fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, mode);
1925 if (fd < 0) {
1926 error_noabort("could not write '%s'", filename);
1927 goto fail;
1929 f = fdopen(fd, "wb");
1930 if (verbose)
1931 printf("<- %s\n", filename);
1933 #ifdef TCC_TARGET_COFF
1934 if (s1->output_format == TCC_OUTPUT_FORMAT_COFF) {
1935 tcc_output_coff(s1, f);
1936 } else
1937 #endif
1938 if (s1->output_format == TCC_OUTPUT_FORMAT_ELF) {
1939 sort_syms(s1, symtab_section);
1941 /* align to 4 */
1942 file_offset = (file_offset + 3) & -4;
1944 /* fill header */
1945 ehdr.e_ident[0] = ELFMAG0;
1946 ehdr.e_ident[1] = ELFMAG1;
1947 ehdr.e_ident[2] = ELFMAG2;
1948 ehdr.e_ident[3] = ELFMAG3;
1949 ehdr.e_ident[4] = TCC_ELFCLASS;
1950 ehdr.e_ident[5] = ELFDATA2LSB;
1951 ehdr.e_ident[6] = EV_CURRENT;
1952 #ifdef __FreeBSD__
1953 ehdr.e_ident[EI_OSABI] = ELFOSABI_FREEBSD;
1954 #endif
1955 #ifdef TCC_TARGET_ARM
1956 #ifdef TCC_ARM_EABI
1957 ehdr.e_ident[EI_OSABI] = 0;
1958 ehdr.e_flags = 4 << 24;
1959 #else
1960 ehdr.e_ident[EI_OSABI] = ELFOSABI_ARM;
1961 #endif
1962 #endif
1963 switch(file_type) {
1964 default:
1965 case TCC_OUTPUT_EXE:
1966 ehdr.e_type = ET_EXEC;
1967 break;
1968 case TCC_OUTPUT_DLL:
1969 ehdr.e_type = ET_DYN;
1970 break;
1971 case TCC_OUTPUT_OBJ:
1972 ehdr.e_type = ET_REL;
1973 break;
1975 ehdr.e_machine = EM_TCC_TARGET;
1976 ehdr.e_version = EV_CURRENT;
1977 ehdr.e_shoff = file_offset;
1978 ehdr.e_ehsize = sizeof(ElfW(Ehdr));
1979 ehdr.e_shentsize = sizeof(ElfW(Shdr));
1980 ehdr.e_shnum = shnum;
1981 ehdr.e_shstrndx = shnum - 1;
1983 fwrite(&ehdr, 1, sizeof(ElfW(Ehdr)), f);
1984 fwrite(phdr, 1, phnum * sizeof(ElfW(Phdr)), f);
1985 offset = sizeof(ElfW(Ehdr)) + phnum * sizeof(ElfW(Phdr));
1987 for(i=1;i<s1->nb_sections;i++) {
1988 s = s1->sections[section_order[i]];
1989 if (s->sh_type != SHT_NOBITS) {
1990 while (offset < s->sh_offset) {
1991 fputc(0, f);
1992 offset++;
1994 size = s->sh_size;
1995 fwrite(s->data, 1, size, f);
1996 offset += size;
2000 /* output section headers */
2001 while (offset < ehdr.e_shoff) {
2002 fputc(0, f);
2003 offset++;
2006 for(i=0;i<s1->nb_sections;i++) {
2007 sh = &shdr;
2008 memset(sh, 0, sizeof(ElfW(Shdr)));
2009 s = s1->sections[i];
2010 if (s) {
2011 sh->sh_name = s->sh_name;
2012 sh->sh_type = s->sh_type;
2013 sh->sh_flags = s->sh_flags;
2014 sh->sh_entsize = s->sh_entsize;
2015 sh->sh_info = s->sh_info;
2016 if (s->link)
2017 sh->sh_link = s->link->sh_num;
2018 sh->sh_addralign = s->sh_addralign;
2019 sh->sh_addr = s->sh_addr;
2020 sh->sh_offset = s->sh_offset;
2021 sh->sh_size = s->sh_size;
2023 fwrite(sh, 1, sizeof(ElfW(Shdr)), f);
2025 } else {
2026 tcc_output_binary(s1, f, section_order);
2028 fclose(f);
2030 ret = 0;
2031 the_end:
2032 tcc_free(s1->symtab_to_dynsym);
2033 tcc_free(section_order);
2034 tcc_free(phdr);
2035 tcc_free(s1->got_offsets);
2036 return ret;
2039 int tcc_output_file(TCCState *s, const char *filename)
2041 int ret;
2042 #ifdef TCC_TARGET_PE
2043 if (s->output_type != TCC_OUTPUT_OBJ) {
2044 ret = pe_output_file(s, filename);
2045 } else
2046 #endif
2048 ret = elf_output_file(s, filename);
2050 return ret;
2053 static void *load_data(int fd, unsigned long file_offset, unsigned long size)
2055 void *data;
2057 data = tcc_malloc(size);
2058 lseek(fd, file_offset, SEEK_SET);
2059 read(fd, data, size);
2060 return data;
2063 typedef struct SectionMergeInfo {
2064 Section *s; /* corresponding existing section */
2065 unsigned long offset; /* offset of the new section in the existing section */
2066 uint8_t new_section; /* true if section 's' was added */
2067 uint8_t link_once; /* true if link once section */
2068 } SectionMergeInfo;
2070 /* load an object file and merge it with current files */
2071 /* XXX: handle correctly stab (debug) info */
2072 static int tcc_load_object_file(TCCState *s1,
2073 int fd, unsigned long file_offset)
2075 ElfW(Ehdr) ehdr;
2076 ElfW(Shdr) *shdr, *sh;
2077 int size, i, j, offset, offseti, nb_syms, sym_index, ret;
2078 unsigned char *strsec, *strtab;
2079 int *old_to_new_syms;
2080 char *sh_name, *name;
2081 SectionMergeInfo *sm_table, *sm;
2082 ElfW(Sym) *sym, *symtab;
2083 ElfW_Rel *rel, *rel_end;
2084 Section *s;
2086 int stab_index;
2087 int stabstr_index;
2089 stab_index = stabstr_index = 0;
2091 if (read(fd, &ehdr, sizeof(ehdr)) != sizeof(ehdr))
2092 goto fail1;
2093 if (ehdr.e_ident[0] != ELFMAG0 ||
2094 ehdr.e_ident[1] != ELFMAG1 ||
2095 ehdr.e_ident[2] != ELFMAG2 ||
2096 ehdr.e_ident[3] != ELFMAG3)
2097 goto fail1;
2098 /* test if object file */
2099 if (ehdr.e_type != ET_REL)
2100 goto fail1;
2101 /* test CPU specific stuff */
2102 if (ehdr.e_ident[5] != ELFDATA2LSB ||
2103 ehdr.e_machine != EM_TCC_TARGET) {
2104 fail1:
2105 error_noabort("invalid object file");
2106 return -1;
2108 /* read sections */
2109 shdr = load_data(fd, file_offset + ehdr.e_shoff,
2110 sizeof(ElfW(Shdr)) * ehdr.e_shnum);
2111 sm_table = tcc_mallocz(sizeof(SectionMergeInfo) * ehdr.e_shnum);
2113 /* load section names */
2114 sh = &shdr[ehdr.e_shstrndx];
2115 strsec = load_data(fd, file_offset + sh->sh_offset, sh->sh_size);
2117 /* load symtab and strtab */
2118 old_to_new_syms = NULL;
2119 symtab = NULL;
2120 strtab = NULL;
2121 nb_syms = 0;
2122 for(i = 1; i < ehdr.e_shnum; i++) {
2123 sh = &shdr[i];
2124 if (sh->sh_type == SHT_SYMTAB) {
2125 if (symtab) {
2126 error_noabort("object must contain only one symtab");
2127 fail:
2128 ret = -1;
2129 goto the_end;
2131 nb_syms = sh->sh_size / sizeof(ElfW(Sym));
2132 symtab = load_data(fd, file_offset + sh->sh_offset, sh->sh_size);
2133 sm_table[i].s = symtab_section;
2135 /* now load strtab */
2136 sh = &shdr[sh->sh_link];
2137 strtab = load_data(fd, file_offset + sh->sh_offset, sh->sh_size);
2141 /* now examine each section and try to merge its content with the
2142 ones in memory */
2143 for(i = 1; i < ehdr.e_shnum; i++) {
2144 /* no need to examine section name strtab */
2145 if (i == ehdr.e_shstrndx)
2146 continue;
2147 sh = &shdr[i];
2148 sh_name = strsec + sh->sh_name;
2149 /* ignore sections types we do not handle */
2150 if (sh->sh_type != SHT_PROGBITS &&
2151 sh->sh_type != SHT_RELX &&
2152 #ifdef TCC_ARM_EABI
2153 sh->sh_type != SHT_ARM_EXIDX &&
2154 #endif
2155 sh->sh_type != SHT_NOBITS &&
2156 strcmp(sh_name, ".stabstr")
2158 continue;
2159 if (sh->sh_addralign < 1)
2160 sh->sh_addralign = 1;
2161 /* find corresponding section, if any */
2162 for(j = 1; j < s1->nb_sections;j++) {
2163 s = s1->sections[j];
2164 if (!strcmp(s->name, sh_name)) {
2165 if (!strncmp(sh_name, ".gnu.linkonce",
2166 sizeof(".gnu.linkonce") - 1)) {
2167 /* if a 'linkonce' section is already present, we
2168 do not add it again. It is a little tricky as
2169 symbols can still be defined in
2170 it. */
2171 sm_table[i].link_once = 1;
2172 goto next;
2173 } else {
2174 goto found;
2178 /* not found: create new section */
2179 s = new_section(s1, sh_name, sh->sh_type, sh->sh_flags);
2180 /* take as much info as possible from the section. sh_link and
2181 sh_info will be updated later */
2182 s->sh_addralign = sh->sh_addralign;
2183 s->sh_entsize = sh->sh_entsize;
2184 sm_table[i].new_section = 1;
2185 found:
2186 if (sh->sh_type != s->sh_type) {
2187 error_noabort("invalid section type");
2188 goto fail;
2191 /* align start of section */
2192 offset = s->data_offset;
2194 if (0 == strcmp(sh_name, ".stab")) {
2195 stab_index = i;
2196 goto no_align;
2198 if (0 == strcmp(sh_name, ".stabstr")) {
2199 stabstr_index = i;
2200 goto no_align;
2203 size = sh->sh_addralign - 1;
2204 offset = (offset + size) & ~size;
2205 if (sh->sh_addralign > s->sh_addralign)
2206 s->sh_addralign = sh->sh_addralign;
2207 s->data_offset = offset;
2208 no_align:
2209 sm_table[i].offset = offset;
2210 sm_table[i].s = s;
2211 /* concatenate sections */
2212 size = sh->sh_size;
2213 if (sh->sh_type != SHT_NOBITS) {
2214 unsigned char *ptr;
2215 lseek(fd, file_offset + sh->sh_offset, SEEK_SET);
2216 ptr = section_ptr_add(s, size);
2217 read(fd, ptr, size);
2218 } else {
2219 s->data_offset += size;
2221 next: ;
2224 /* //gr relocate stab strings */
2225 if (stab_index && stabstr_index) {
2226 Stab_Sym *a, *b;
2227 unsigned o;
2228 s = sm_table[stab_index].s;
2229 a = (Stab_Sym *)(s->data + sm_table[stab_index].offset);
2230 b = (Stab_Sym *)(s->data + s->data_offset);
2231 o = sm_table[stabstr_index].offset;
2232 while (a < b)
2233 a->n_strx += o, a++;
2236 /* second short pass to update sh_link and sh_info fields of new
2237 sections */
2238 for(i = 1; i < ehdr.e_shnum; i++) {
2239 s = sm_table[i].s;
2240 if (!s || !sm_table[i].new_section)
2241 continue;
2242 sh = &shdr[i];
2243 if (sh->sh_link > 0)
2244 s->link = sm_table[sh->sh_link].s;
2245 if (sh->sh_type == SHT_RELX) {
2246 s->sh_info = sm_table[sh->sh_info].s->sh_num;
2247 /* update backward link */
2248 s1->sections[s->sh_info]->reloc = s;
2251 sm = sm_table;
2253 /* resolve symbols */
2254 old_to_new_syms = tcc_mallocz(nb_syms * sizeof(int));
2256 sym = symtab + 1;
2257 for(i = 1; i < nb_syms; i++, sym++) {
2258 if (sym->st_shndx != SHN_UNDEF &&
2259 sym->st_shndx < SHN_LORESERVE) {
2260 sm = &sm_table[sym->st_shndx];
2261 if (sm->link_once) {
2262 /* if a symbol is in a link once section, we use the
2263 already defined symbol. It is very important to get
2264 correct relocations */
2265 if (ELFW(ST_BIND)(sym->st_info) != STB_LOCAL) {
2266 name = strtab + sym->st_name;
2267 sym_index = find_elf_sym(symtab_section, name);
2268 if (sym_index)
2269 old_to_new_syms[i] = sym_index;
2271 continue;
2273 /* if no corresponding section added, no need to add symbol */
2274 if (!sm->s)
2275 continue;
2276 /* convert section number */
2277 sym->st_shndx = sm->s->sh_num;
2278 /* offset value */
2279 sym->st_value += sm->offset;
2281 /* add symbol */
2282 name = strtab + sym->st_name;
2283 sym_index = add_elf_sym(symtab_section, sym->st_value, sym->st_size,
2284 sym->st_info, sym->st_other,
2285 sym->st_shndx, name);
2286 old_to_new_syms[i] = sym_index;
2289 /* third pass to patch relocation entries */
2290 for(i = 1; i < ehdr.e_shnum; i++) {
2291 s = sm_table[i].s;
2292 if (!s)
2293 continue;
2294 sh = &shdr[i];
2295 offset = sm_table[i].offset;
2296 switch(s->sh_type) {
2297 case SHT_RELX:
2298 /* take relocation offset information */
2299 offseti = sm_table[sh->sh_info].offset;
2300 rel_end = (ElfW_Rel *)(s->data + s->data_offset);
2301 for(rel = (ElfW_Rel *)(s->data + offset);
2302 rel < rel_end;
2303 rel++) {
2304 int type;
2305 unsigned sym_index;
2306 /* convert symbol index */
2307 type = ELFW(R_TYPE)(rel->r_info);
2308 sym_index = ELFW(R_SYM)(rel->r_info);
2309 /* NOTE: only one symtab assumed */
2310 if (sym_index >= nb_syms)
2311 goto invalid_reloc;
2312 sym_index = old_to_new_syms[sym_index];
2313 /* ignore link_once in rel section. */
2314 if (!sym_index && !sm->link_once) {
2315 invalid_reloc:
2316 error_noabort("Invalid relocation entry [%2d] '%s' @ %.8x",
2317 i, strsec + sh->sh_name, rel->r_offset);
2318 goto fail;
2320 rel->r_info = ELFW(R_INFO)(sym_index, type);
2321 /* offset the relocation offset */
2322 rel->r_offset += offseti;
2324 break;
2325 default:
2326 break;
2330 ret = 0;
2331 the_end:
2332 tcc_free(symtab);
2333 tcc_free(strtab);
2334 tcc_free(old_to_new_syms);
2335 tcc_free(sm_table);
2336 tcc_free(strsec);
2337 tcc_free(shdr);
2338 return ret;
2341 #define ARMAG "!<arch>\012" /* For COFF and a.out archives */
2343 typedef struct ArchiveHeader {
2344 char ar_name[16]; /* name of this member */
2345 char ar_date[12]; /* file mtime */
2346 char ar_uid[6]; /* owner uid; printed as decimal */
2347 char ar_gid[6]; /* owner gid; printed as decimal */
2348 char ar_mode[8]; /* file mode, printed as octal */
2349 char ar_size[10]; /* file size, printed as decimal */
2350 char ar_fmag[2]; /* should contain ARFMAG */
2351 } ArchiveHeader;
2353 static int get_be32(const uint8_t *b)
2355 return b[3] | (b[2] << 8) | (b[1] << 16) | (b[0] << 24);
2358 /* load only the objects which resolve undefined symbols */
2359 static int tcc_load_alacarte(TCCState *s1, int fd, int size)
2361 int i, bound, nsyms, sym_index, off, ret;
2362 uint8_t *data;
2363 const char *ar_names, *p;
2364 const uint8_t *ar_index;
2365 ElfW(Sym) *sym;
2367 data = tcc_malloc(size);
2368 if (read(fd, data, size) != size)
2369 goto fail;
2370 nsyms = get_be32(data);
2371 ar_index = data + 4;
2372 ar_names = ar_index + nsyms * 4;
2374 do {
2375 bound = 0;
2376 for(p = ar_names, i = 0; i < nsyms; i++, p += strlen(p)+1) {
2377 sym_index = find_elf_sym(symtab_section, p);
2378 if(sym_index) {
2379 sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
2380 if(sym->st_shndx == SHN_UNDEF) {
2381 off = get_be32(ar_index + i * 4) + sizeof(ArchiveHeader);
2382 #if 0
2383 printf("%5d\t%s\t%08x\n", i, p, sym->st_shndx);
2384 #endif
2385 ++bound;
2386 lseek(fd, off, SEEK_SET);
2387 if(tcc_load_object_file(s1, fd, off) < 0) {
2388 fail:
2389 ret = -1;
2390 goto the_end;
2395 } while(bound);
2396 ret = 0;
2397 the_end:
2398 tcc_free(data);
2399 return ret;
2402 /* load a '.a' file */
2403 static int tcc_load_archive(TCCState *s1, int fd)
2405 ArchiveHeader hdr;
2406 char ar_size[11];
2407 char ar_name[17];
2408 char magic[8];
2409 int size, len, i;
2410 unsigned long file_offset;
2412 /* skip magic which was already checked */
2413 read(fd, magic, sizeof(magic));
2415 for(;;) {
2416 len = read(fd, &hdr, sizeof(hdr));
2417 if (len == 0)
2418 break;
2419 if (len != sizeof(hdr)) {
2420 error_noabort("invalid archive");
2421 return -1;
2423 memcpy(ar_size, hdr.ar_size, sizeof(hdr.ar_size));
2424 ar_size[sizeof(hdr.ar_size)] = '\0';
2425 size = strtol(ar_size, NULL, 0);
2426 memcpy(ar_name, hdr.ar_name, sizeof(hdr.ar_name));
2427 for(i = sizeof(hdr.ar_name) - 1; i >= 0; i--) {
2428 if (ar_name[i] != ' ')
2429 break;
2431 ar_name[i + 1] = '\0';
2432 // printf("name='%s' size=%d %s\n", ar_name, size, ar_size);
2433 file_offset = lseek(fd, 0, SEEK_CUR);
2434 /* align to even */
2435 size = (size + 1) & ~1;
2436 if (!strcmp(ar_name, "/")) {
2437 /* coff symbol table : we handle it */
2438 if(s1->alacarte_link)
2439 return tcc_load_alacarte(s1, fd, size);
2440 } else if (!strcmp(ar_name, "//") ||
2441 !strcmp(ar_name, "__.SYMDEF") ||
2442 !strcmp(ar_name, "__.SYMDEF/") ||
2443 !strcmp(ar_name, "ARFILENAMES/")) {
2444 /* skip symbol table or archive names */
2445 } else {
2446 if (tcc_load_object_file(s1, fd, file_offset) < 0)
2447 return -1;
2449 lseek(fd, file_offset + size, SEEK_SET);
2451 return 0;
2454 /* load a DLL and all referenced DLLs. 'level = 0' means that the DLL
2455 is referenced by the user (so it should be added as DT_NEEDED in
2456 the generated ELF file) */
2457 static int tcc_load_dll(TCCState *s1, int fd, const char *filename, int level)
2459 ElfW(Ehdr) ehdr;
2460 ElfW(Shdr) *shdr, *sh, *sh1;
2461 int i, j, nb_syms, nb_dts, sym_bind, ret;
2462 ElfW(Sym) *sym, *dynsym;
2463 ElfW(Dyn) *dt, *dynamic;
2464 unsigned char *dynstr;
2465 const char *name, *soname;
2466 DLLReference *dllref;
2468 read(fd, &ehdr, sizeof(ehdr));
2470 /* test CPU specific stuff */
2471 if (ehdr.e_ident[5] != ELFDATA2LSB ||
2472 ehdr.e_machine != EM_TCC_TARGET) {
2473 error_noabort("bad architecture");
2474 return -1;
2477 /* read sections */
2478 shdr = load_data(fd, ehdr.e_shoff, sizeof(ElfW(Shdr)) * ehdr.e_shnum);
2480 /* load dynamic section and dynamic symbols */
2481 nb_syms = 0;
2482 nb_dts = 0;
2483 dynamic = NULL;
2484 dynsym = NULL; /* avoid warning */
2485 dynstr = NULL; /* avoid warning */
2486 for(i = 0, sh = shdr; i < ehdr.e_shnum; i++, sh++) {
2487 switch(sh->sh_type) {
2488 case SHT_DYNAMIC:
2489 nb_dts = sh->sh_size / sizeof(ElfW(Dyn));
2490 dynamic = load_data(fd, sh->sh_offset, sh->sh_size);
2491 break;
2492 case SHT_DYNSYM:
2493 nb_syms = sh->sh_size / sizeof(ElfW(Sym));
2494 dynsym = load_data(fd, sh->sh_offset, sh->sh_size);
2495 sh1 = &shdr[sh->sh_link];
2496 dynstr = load_data(fd, sh1->sh_offset, sh1->sh_size);
2497 break;
2498 default:
2499 break;
2503 /* compute the real library name */
2504 soname = tcc_basename(filename);
2506 for(i = 0, dt = dynamic; i < nb_dts; i++, dt++) {
2507 if (dt->d_tag == DT_SONAME) {
2508 soname = dynstr + dt->d_un.d_val;
2512 /* if the dll is already loaded, do not load it */
2513 for(i = 0; i < s1->nb_loaded_dlls; i++) {
2514 dllref = s1->loaded_dlls[i];
2515 if (!strcmp(soname, dllref->name)) {
2516 /* but update level if needed */
2517 if (level < dllref->level)
2518 dllref->level = level;
2519 ret = 0;
2520 goto the_end;
2524 // printf("loading dll '%s'\n", soname);
2526 /* add the dll and its level */
2527 dllref = tcc_mallocz(sizeof(DLLReference) + strlen(soname));
2528 dllref->level = level;
2529 strcpy(dllref->name, soname);
2530 dynarray_add((void ***)&s1->loaded_dlls, &s1->nb_loaded_dlls, dllref);
2532 /* add dynamic symbols in dynsym_section */
2533 for(i = 1, sym = dynsym + 1; i < nb_syms; i++, sym++) {
2534 sym_bind = ELFW(ST_BIND)(sym->st_info);
2535 if (sym_bind == STB_LOCAL)
2536 continue;
2537 name = dynstr + sym->st_name;
2538 add_elf_sym(s1->dynsymtab_section, sym->st_value, sym->st_size,
2539 sym->st_info, sym->st_other, sym->st_shndx, name);
2542 /* load all referenced DLLs */
2543 for(i = 0, dt = dynamic; i < nb_dts; i++, dt++) {
2544 switch(dt->d_tag) {
2545 case DT_NEEDED:
2546 name = dynstr + dt->d_un.d_val;
2547 for(j = 0; j < s1->nb_loaded_dlls; j++) {
2548 dllref = s1->loaded_dlls[j];
2549 if (!strcmp(name, dllref->name))
2550 goto already_loaded;
2552 if (tcc_add_dll(s1, name, AFF_REFERENCED_DLL) < 0) {
2553 error_noabort("referenced dll '%s' not found", name);
2554 ret = -1;
2555 goto the_end;
2557 already_loaded:
2558 break;
2561 ret = 0;
2562 the_end:
2563 tcc_free(dynstr);
2564 tcc_free(dynsym);
2565 tcc_free(dynamic);
2566 tcc_free(shdr);
2567 return ret;
2570 #define LD_TOK_NAME 256
2571 #define LD_TOK_EOF (-1)
2573 /* return next ld script token */
2574 static int ld_next(TCCState *s1, char *name, int name_size)
2576 int c;
2577 char *q;
2579 redo:
2580 switch(ch) {
2581 case ' ':
2582 case '\t':
2583 case '\f':
2584 case '\v':
2585 case '\r':
2586 case '\n':
2587 inp();
2588 goto redo;
2589 case '/':
2590 minp();
2591 if (ch == '*') {
2592 file->buf_ptr = parse_comment(file->buf_ptr);
2593 ch = file->buf_ptr[0];
2594 goto redo;
2595 } else {
2596 q = name;
2597 *q++ = '/';
2598 goto parse_name;
2600 break;
2601 /* case 'a' ... 'z': */
2602 case 'a':
2603 case 'b':
2604 case 'c':
2605 case 'd':
2606 case 'e':
2607 case 'f':
2608 case 'g':
2609 case 'h':
2610 case 'i':
2611 case 'j':
2612 case 'k':
2613 case 'l':
2614 case 'm':
2615 case 'n':
2616 case 'o':
2617 case 'p':
2618 case 'q':
2619 case 'r':
2620 case 's':
2621 case 't':
2622 case 'u':
2623 case 'v':
2624 case 'w':
2625 case 'x':
2626 case 'y':
2627 case 'z':
2628 /* case 'A' ... 'z': */
2629 case 'A':
2630 case 'B':
2631 case 'C':
2632 case 'D':
2633 case 'E':
2634 case 'F':
2635 case 'G':
2636 case 'H':
2637 case 'I':
2638 case 'J':
2639 case 'K':
2640 case 'L':
2641 case 'M':
2642 case 'N':
2643 case 'O':
2644 case 'P':
2645 case 'Q':
2646 case 'R':
2647 case 'S':
2648 case 'T':
2649 case 'U':
2650 case 'V':
2651 case 'W':
2652 case 'X':
2653 case 'Y':
2654 case 'Z':
2655 case '_':
2656 case '\\':
2657 case '.':
2658 case '$':
2659 case '~':
2660 q = name;
2661 parse_name:
2662 for(;;) {
2663 if (!((ch >= 'a' && ch <= 'z') ||
2664 (ch >= 'A' && ch <= 'Z') ||
2665 (ch >= '0' && ch <= '9') ||
2666 strchr("/.-_+=$:\\,~", ch)))
2667 break;
2668 if ((q - name) < name_size - 1) {
2669 *q++ = ch;
2671 minp();
2673 *q = '\0';
2674 c = LD_TOK_NAME;
2675 break;
2676 case CH_EOF:
2677 c = LD_TOK_EOF;
2678 break;
2679 default:
2680 c = ch;
2681 inp();
2682 break;
2684 #if 0
2685 printf("tok=%c %d\n", c, c);
2686 if (c == LD_TOK_NAME)
2687 printf(" name=%s\n", name);
2688 #endif
2689 return c;
2692 static int ld_add_file_list(TCCState *s1, int as_needed)
2694 char filename[1024];
2695 int t, ret;
2697 t = ld_next(s1, filename, sizeof(filename));
2698 if (t != '(')
2699 expect("(");
2700 t = ld_next(s1, filename, sizeof(filename));
2701 for(;;) {
2702 if (t == LD_TOK_EOF) {
2703 error_noabort("unexpected end of file");
2704 return -1;
2705 } else if (t == ')') {
2706 break;
2707 } else if (t != LD_TOK_NAME) {
2708 error_noabort("filename expected");
2709 return -1;
2711 if (!strcmp(filename, "AS_NEEDED")) {
2712 ret = ld_add_file_list(s1, 1);
2713 if (ret)
2714 return ret;
2715 } else {
2716 /* TODO: Implement AS_NEEDED support. Ignore it for now */
2717 if (!as_needed)
2718 tcc_add_file(s1, filename);
2720 t = ld_next(s1, filename, sizeof(filename));
2721 if (t == ',') {
2722 t = ld_next(s1, filename, sizeof(filename));
2725 return 0;
2728 /* interpret a subset of GNU ldscripts to handle the dummy libc.so
2729 files */
2730 static int tcc_load_ldscript(TCCState *s1)
2732 char cmd[64];
2733 char filename[1024];
2734 int t, ret;
2736 ch = file->buf_ptr[0];
2737 ch = handle_eob();
2738 for(;;) {
2739 t = ld_next(s1, cmd, sizeof(cmd));
2740 if (t == LD_TOK_EOF)
2741 return 0;
2742 else if (t != LD_TOK_NAME)
2743 return -1;
2744 if (!strcmp(cmd, "INPUT") ||
2745 !strcmp(cmd, "GROUP")) {
2746 ret = ld_add_file_list(s1, 0);
2747 if (ret)
2748 return ret;
2749 } else if (!strcmp(cmd, "OUTPUT_FORMAT") ||
2750 !strcmp(cmd, "TARGET")) {
2751 /* ignore some commands */
2752 t = ld_next(s1, cmd, sizeof(cmd));
2753 if (t != '(')
2754 expect("(");
2755 for(;;) {
2756 t = ld_next(s1, filename, sizeof(filename));
2757 if (t == LD_TOK_EOF) {
2758 error_noabort("unexpected end of file");
2759 return -1;
2760 } else if (t == ')') {
2761 break;
2764 } else {
2765 return -1;
2768 return 0;