2 * ELF file handling for TCC
4 * Copyright (c) 2001-2004 Fabrice Bellard
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 static int put_elf_str(Section
*s
, const char *sym
)
26 len
= strlen(sym
) + 1;
27 offset
= s
->data_offset
;
28 ptr
= section_ptr_add(s
, len
);
29 memcpy(ptr
, sym
, len
);
33 /* elf symbol hashing function */
34 static unsigned long elf_hash(const unsigned char *name
)
36 unsigned long h
= 0, g
;
39 h
= (h
<< 4) + *name
++;
48 /* rebuild hash table of section s */
49 /* NOTE: we do factorize the hash table code to go faster */
50 static void rebuild_hash(Section
*s
, unsigned int nb_buckets
)
53 int *ptr
, *hash
, nb_syms
, sym_index
, h
;
56 strtab
= s
->link
->data
;
57 nb_syms
= s
->data_offset
/ sizeof(Elf32_Sym
);
59 s
->hash
->data_offset
= 0;
60 ptr
= section_ptr_add(s
->hash
, (2 + nb_buckets
+ nb_syms
) * sizeof(int));
65 memset(hash
, 0, (nb_buckets
+ 1) * sizeof(int));
66 ptr
+= nb_buckets
+ 1;
68 sym
= (Elf32_Sym
*)s
->data
+ 1;
69 for(sym_index
= 1; sym_index
< nb_syms
; sym_index
++) {
70 if (ELF32_ST_BIND(sym
->st_info
) != STB_LOCAL
) {
71 h
= elf_hash(strtab
+ sym
->st_name
) % nb_buckets
;
82 /* return the symbol number */
83 static int put_elf_sym(Section
*s
,
84 unsigned long value
, unsigned long size
,
85 int info
, int other
, int shndx
, const char *name
)
87 int name_offset
, sym_index
;
92 sym
= section_ptr_add(s
, sizeof(Elf32_Sym
));
94 name_offset
= put_elf_str(s
->link
, name
);
98 sym
->st_name
= name_offset
;
99 sym
->st_value
= value
;
102 sym
->st_other
= other
;
103 sym
->st_shndx
= shndx
;
104 sym_index
= sym
- (Elf32_Sym
*)s
->data
;
108 ptr
= section_ptr_add(hs
, sizeof(int));
109 base
= (int *)hs
->data
;
110 /* only add global or weak symbols */
111 if (ELF32_ST_BIND(info
) != STB_LOCAL
) {
112 /* add another hashing entry */
114 h
= elf_hash(name
) % nbuckets
;
116 base
[2 + h
] = sym_index
;
118 /* we resize the hash table */
119 hs
->nb_hashed_syms
++;
120 if (hs
->nb_hashed_syms
> 2 * nbuckets
) {
121 rebuild_hash(s
, 2 * nbuckets
);
131 /* find global ELF symbol 'name' and return its index. Return 0 if not
133 static int find_elf_sym(Section
*s
, const char *name
)
137 int nbuckets
, sym_index
, h
;
143 nbuckets
= ((int *)hs
->data
)[0];
144 h
= elf_hash(name
) % nbuckets
;
145 sym_index
= ((int *)hs
->data
)[2 + h
];
146 while (sym_index
!= 0) {
147 sym
= &((Elf32_Sym
*)s
->data
)[sym_index
];
148 name1
= s
->link
->data
+ sym
->st_name
;
149 if (!strcmp(name
, name1
))
151 sym_index
= ((int *)hs
->data
)[2 + nbuckets
+ sym_index
];
156 /* return elf symbol value or error */
157 int tcc_get_symbol(TCCState
*s
, unsigned long *pval
, const char *name
)
162 sym_index
= find_elf_sym(symtab_section
, name
);
165 sym
= &((Elf32_Sym
*)symtab_section
->data
)[sym_index
];
166 *pval
= sym
->st_value
;
170 void *tcc_get_symbol_err(TCCState
*s
, const char *name
)
173 if (tcc_get_symbol(s
, &val
, name
) < 0)
174 error("%s not defined", name
);
178 /* add an elf symbol : check if it is already defined and patch
179 it. Return symbol index. NOTE that sh_num can be SHN_UNDEF. */
180 static int add_elf_sym(Section
*s
, unsigned long value
, unsigned long size
,
181 int info
, int other
, int sh_num
, const char *name
)
184 int sym_bind
, sym_index
, sym_type
, esym_bind
;
185 unsigned char sym_vis
, esym_vis
, new_vis
;
187 sym_bind
= ELF32_ST_BIND(info
);
188 sym_type
= ELF32_ST_TYPE(info
);
189 sym_vis
= ELF32_ST_VISIBILITY(other
);
191 if (sym_bind
!= STB_LOCAL
) {
192 /* we search global or weak symbols */
193 sym_index
= find_elf_sym(s
, name
);
196 esym
= &((Elf32_Sym
*)s
->data
)[sym_index
];
197 if (esym
->st_shndx
!= SHN_UNDEF
) {
198 esym_bind
= ELF32_ST_BIND(esym
->st_info
);
199 /* propagate the most constraining visibility */
200 /* STV_DEFAULT(0)<STV_PROTECTED(3)<STV_HIDDEN(2)<STV_INTERNAL(1) */
201 esym_vis
= ELF32_ST_VISIBILITY(esym
->st_other
);
202 if (esym_vis
== STV_DEFAULT
) {
204 } else if (sym_vis
== STV_DEFAULT
) {
207 new_vis
= (esym_vis
< sym_vis
) ? esym_vis
: sym_vis
;
209 esym
->st_other
= (esym
->st_other
& ~ELF32_ST_VISIBILITY(-1))
211 other
= esym
->st_other
; /* in case we have to patch esym */
212 if (sh_num
== SHN_UNDEF
) {
213 /* ignore adding of undefined symbol if the
214 corresponding symbol is already defined */
215 } else if (sym_bind
== STB_GLOBAL
&& esym_bind
== STB_WEAK
) {
216 /* global overrides weak, so patch */
218 } else if (sym_bind
== STB_WEAK
&& esym_bind
== STB_GLOBAL
) {
219 /* weak is ignored if already global */
220 } else if (sym_vis
== STV_HIDDEN
|| sym_vis
== STV_INTERNAL
) {
221 /* ignore hidden symbols after */
222 } else if (esym
->st_shndx
== SHN_COMMON
&& sh_num
< SHN_LORESERVE
) {
223 /* gr: Happens with 'tcc ... -static tcctest.c' on e.g. Ubuntu 6.01
224 No idea if this is the correct solution ... */
226 } else if (s
== tcc_state
->dynsymtab_section
) {
227 /* we accept that two DLL define the same symbol */
230 printf("new_bind=%x new_shndx=%x new_vis=%x old_bind=%x old_shndx=%x old_vis=%x\n",
231 sym_bind
, sh_num
, new_vis
, esym_bind
, esym
->st_shndx
, esym_vis
);
233 error_noabort("'%s' defined twice", name
);
237 esym
->st_info
= ELF32_ST_INFO(sym_bind
, sym_type
);
238 esym
->st_shndx
= sh_num
;
239 esym
->st_value
= value
;
240 esym
->st_size
= size
;
241 esym
->st_other
= other
;
245 sym_index
= put_elf_sym(s
, value
, size
,
246 ELF32_ST_INFO(sym_bind
, sym_type
), other
,
253 static void put_elf_reloc(Section
*symtab
, Section
*s
, unsigned long offset
,
254 int type
, int symbol
)
262 /* if no relocation section, create it */
263 snprintf(buf
, sizeof(buf
), ".rel%s", s
->name
);
264 /* if the symtab is allocated, then we consider the relocation
266 sr
= new_section(tcc_state
, buf
, SHT_REL
, symtab
->sh_flags
);
267 sr
->sh_entsize
= sizeof(Elf32_Rel
);
269 sr
->sh_info
= s
->sh_num
;
272 rel
= section_ptr_add(sr
, sizeof(Elf32_Rel
));
273 rel
->r_offset
= offset
;
274 rel
->r_info
= ELF32_R_INFO(symbol
, type
);
277 /* put stab debug information */
280 unsigned long n_strx
; /* index into string table of name */
281 unsigned char n_type
; /* type of symbol */
282 unsigned char n_other
; /* misc info (usually empty) */
283 unsigned short n_desc
; /* description field */
284 unsigned long n_value
; /* value of symbol */
287 static void put_stabs(const char *str
, int type
, int other
, int desc
,
292 sym
= section_ptr_add(stab_section
, sizeof(Stab_Sym
));
294 sym
->n_strx
= put_elf_str(stabstr_section
, str
);
299 sym
->n_other
= other
;
301 sym
->n_value
= value
;
304 static void put_stabs_r(const char *str
, int type
, int other
, int desc
,
305 unsigned long value
, Section
*sec
, int sym_index
)
307 put_stabs(str
, type
, other
, desc
, value
);
308 put_elf_reloc(symtab_section
, stab_section
,
309 stab_section
->data_offset
- sizeof(unsigned long),
310 R_DATA_32
, sym_index
);
313 static void put_stabn(int type
, int other
, int desc
, int value
)
315 put_stabs(NULL
, type
, other
, desc
, value
);
318 static void put_stabd(int type
, int other
, int desc
)
320 put_stabs(NULL
, type
, other
, desc
, 0);
323 /* In an ELF file symbol table, the local symbols must appear below
324 the global and weak ones. Since TCC cannot sort it while generating
325 the code, we must do it after. All the relocation tables are also
326 modified to take into account the symbol table sorting */
327 static void sort_syms(TCCState
*s1
, Section
*s
)
329 int *old_to_new_syms
;
333 Elf32_Rel
*rel
, *rel_end
;
337 nb_syms
= s
->data_offset
/ sizeof(Elf32_Sym
);
338 new_syms
= tcc_malloc(nb_syms
* sizeof(Elf32_Sym
));
339 old_to_new_syms
= tcc_malloc(nb_syms
* sizeof(int));
341 /* first pass for local symbols */
342 p
= (Elf32_Sym
*)s
->data
;
344 for(i
= 0; i
< nb_syms
; i
++) {
345 if (ELF32_ST_BIND(p
->st_info
) == STB_LOCAL
) {
346 old_to_new_syms
[i
] = q
- new_syms
;
351 /* save the number of local symbols in section header */
352 s
->sh_info
= q
- new_syms
;
354 /* then second pass for non local symbols */
355 p
= (Elf32_Sym
*)s
->data
;
356 for(i
= 0; i
< nb_syms
; i
++) {
357 if (ELF32_ST_BIND(p
->st_info
) != STB_LOCAL
) {
358 old_to_new_syms
[i
] = q
- new_syms
;
364 /* we copy the new symbols to the old */
365 memcpy(s
->data
, new_syms
, nb_syms
* sizeof(Elf32_Sym
));
368 /* now we modify all the relocations */
369 for(i
= 1; i
< s1
->nb_sections
; i
++) {
370 sr
= s1
->sections
[i
];
371 if (sr
->sh_type
== SHT_REL
&& sr
->link
== s
) {
372 rel_end
= (Elf32_Rel
*)(sr
->data
+ sr
->data_offset
);
373 for(rel
= (Elf32_Rel
*)sr
->data
;
376 sym_index
= ELF32_R_SYM(rel
->r_info
);
377 type
= ELF32_R_TYPE(rel
->r_info
);
378 sym_index
= old_to_new_syms
[sym_index
];
379 rel
->r_info
= ELF32_R_INFO(sym_index
, type
);
384 tcc_free(old_to_new_syms
);
387 /* relocate common symbols in the .bss section */
388 static void relocate_common_syms(void)
390 Elf32_Sym
*sym
, *sym_end
;
391 unsigned long offset
, align
;
393 sym_end
= (Elf32_Sym
*)(symtab_section
->data
+ symtab_section
->data_offset
);
394 for(sym
= (Elf32_Sym
*)symtab_section
->data
+ 1;
397 if (sym
->st_shndx
== SHN_COMMON
) {
399 align
= sym
->st_value
;
400 offset
= bss_section
->data_offset
;
401 offset
= (offset
+ align
- 1) & -align
;
402 sym
->st_value
= offset
;
403 sym
->st_shndx
= bss_section
->sh_num
;
404 offset
+= sym
->st_size
;
405 bss_section
->data_offset
= offset
;
410 /* relocate symbol table, resolve undefined symbols if do_resolve is
411 true and output error if undefined symbol. */
412 static void relocate_syms(TCCState
*s1
, int do_resolve
)
414 Elf32_Sym
*sym
, *esym
, *sym_end
;
415 int sym_bind
, sh_num
, sym_index
;
419 sym_end
= (Elf32_Sym
*)(symtab_section
->data
+ symtab_section
->data_offset
);
420 for(sym
= (Elf32_Sym
*)symtab_section
->data
+ 1;
423 sh_num
= sym
->st_shndx
;
424 if (sh_num
== SHN_UNDEF
) {
425 name
= strtab_section
->data
+ sym
->st_name
;
427 name
= symtab_section
->link
->data
+ sym
->st_name
;
428 addr
= (unsigned long)resolve_sym(s1
, name
, ELF32_ST_TYPE(sym
->st_info
));
430 sym
->st_value
= addr
;
433 } else if (s1
->dynsym
) {
434 /* if dynamic symbol exist, then use it */
435 sym_index
= find_elf_sym(s1
->dynsym
, name
);
437 esym
= &((Elf32_Sym
*)s1
->dynsym
->data
)[sym_index
];
438 sym
->st_value
= esym
->st_value
;
442 /* XXX: _fp_hw seems to be part of the ABI, so we ignore
444 if (!strcmp(name
, "_fp_hw"))
446 /* only weak symbols are accepted to be undefined. Their
448 sym_bind
= ELF32_ST_BIND(sym
->st_info
);
449 if (sym_bind
== STB_WEAK
) {
452 error_noabort("undefined symbol '%s'", name
);
454 } else if (sh_num
< SHN_LORESERVE
) {
455 /* add section base */
456 sym
->st_value
+= s1
->sections
[sym
->st_shndx
]->sh_addr
;
462 /* relocate a given section (CPU dependent) */
463 static void relocate_section(TCCState
*s1
, Section
*s
)
466 Elf32_Rel
*rel
, *rel_end
, *qrel
;
470 unsigned long val
, addr
;
471 #if defined(TCC_TARGET_I386)
476 rel_end
= (Elf32_Rel
*)(sr
->data
+ sr
->data_offset
);
477 qrel
= (Elf32_Rel
*)sr
->data
;
481 ptr
= s
->data
+ rel
->r_offset
;
483 sym_index
= ELF32_R_SYM(rel
->r_info
);
484 sym
= &((Elf32_Sym
*)symtab_section
->data
)[sym_index
];
486 type
= ELF32_R_TYPE(rel
->r_info
);
487 addr
= s
->sh_addr
+ rel
->r_offset
;
491 #if defined(TCC_TARGET_I386)
493 if (s1
->output_type
== TCC_OUTPUT_DLL
) {
494 esym_index
= s1
->symtab_to_dynsym
[sym_index
];
495 qrel
->r_offset
= rel
->r_offset
;
497 qrel
->r_info
= ELF32_R_INFO(esym_index
, R_386_32
);
501 qrel
->r_info
= ELF32_R_INFO(0, R_386_RELATIVE
);
508 if (s1
->output_type
== TCC_OUTPUT_DLL
) {
510 esym_index
= s1
->symtab_to_dynsym
[sym_index
];
512 qrel
->r_offset
= rel
->r_offset
;
513 qrel
->r_info
= ELF32_R_INFO(esym_index
, R_386_PC32
);
518 *(int *)ptr
+= val
- addr
;
521 *(int *)ptr
+= val
- addr
;
528 *(int *)ptr
+= s1
->got
->sh_addr
- addr
;
531 *(int *)ptr
+= val
- s1
->got
->sh_addr
;
534 /* we load the got offset */
535 *(int *)ptr
+= s1
->got_offsets
[sym_index
];
537 #elif defined(TCC_TARGET_ARM)
544 x
= (*(int *)ptr
)&0xffffff;
545 (*(int *)ptr
) &= 0xff000000;
550 if((x
& 3) != 0 || x
>= 0x4000000 || x
< -0x4000000)
551 error("can't relocate value at %x",addr
);
560 x
= (*(int *)ptr
) & 0x7fffffff;
561 (*(int *)ptr
) &= 0x80000000;
564 if((x
^(x
>>1))&0x40000000)
565 error("can't relocate value at %x",addr
);
566 (*(int *)ptr
) |= x
& 0x7fffffff;
571 case R_ARM_BASE_PREL
:
572 *(int *)ptr
+= s1
->got
->sh_addr
- addr
;
575 *(int *)ptr
+= val
- s1
->got
->sh_addr
;
578 /* we load the got offset */
579 *(int *)ptr
+= s1
->got_offsets
[sym_index
];
584 fprintf(stderr
,"FIXME: handle reloc type %x at %lx [%.8x] to %lx\n",
585 type
,addr
,(unsigned int )ptr
,val
);
587 #elif defined(TCC_TARGET_C67)
595 /* put the low 16 bits of the absolute address */
596 // add to what is already there
598 orig
= ((*(int *)(ptr
)) >> 7) & 0xffff;
599 orig
|= (((*(int *)(ptr
+4)) >> 7) & 0xffff) << 16;
601 //patch both at once - assumes always in pairs Low - High
603 *(int *) ptr
= (*(int *) ptr
& (~(0xffff << 7)) ) | (((val
+orig
) & 0xffff) << 7);
604 *(int *)(ptr
+4) = (*(int *)(ptr
+4) & (~(0xffff << 7)) ) | ((((val
+orig
)>>16) & 0xffff) << 7);
610 fprintf(stderr
,"FIXME: handle reloc type %x at %lx [%.8x] to %lx\n",
611 type
,addr
,(unsigned int )ptr
,val
);
614 #error unsupported processor
618 /* if the relocation is allocated, we change its symbol table */
619 if (sr
->sh_flags
& SHF_ALLOC
)
620 sr
->link
= s1
->dynsym
;
623 /* relocate relocation table in 'sr' */
624 static void relocate_rel(TCCState
*s1
, Section
*sr
)
627 Elf32_Rel
*rel
, *rel_end
;
629 s
= s1
->sections
[sr
->sh_info
];
630 rel_end
= (Elf32_Rel
*)(sr
->data
+ sr
->data_offset
);
631 for(rel
= (Elf32_Rel
*)sr
->data
;
634 rel
->r_offset
+= s
->sh_addr
;
638 /* count the number of dynamic relocations so that we can reserve
640 static int prepare_dynamic_rel(TCCState
*s1
, Section
*sr
)
642 Elf32_Rel
*rel
, *rel_end
;
643 int sym_index
, esym_index
, type
, count
;
646 rel_end
= (Elf32_Rel
*)(sr
->data
+ sr
->data_offset
);
647 for(rel
= (Elf32_Rel
*)sr
->data
; rel
< rel_end
; rel
++) {
648 sym_index
= ELF32_R_SYM(rel
->r_info
);
649 type
= ELF32_R_TYPE(rel
->r_info
);
655 esym_index
= s1
->symtab_to_dynsym
[sym_index
];
664 /* allocate the section */
665 sr
->sh_flags
|= SHF_ALLOC
;
666 sr
->sh_size
= count
* sizeof(Elf32_Rel
);
671 static void put_got_offset(TCCState
*s1
, int index
, unsigned long val
)
676 if (index
>= s1
->nb_got_offsets
) {
677 /* find immediately bigger power of 2 and reallocate array */
681 tab
= tcc_realloc(s1
->got_offsets
, n
* sizeof(unsigned long));
683 error("memory full");
684 s1
->got_offsets
= tab
;
685 memset(s1
->got_offsets
+ s1
->nb_got_offsets
, 0,
686 (n
- s1
->nb_got_offsets
) * sizeof(unsigned long));
687 s1
->nb_got_offsets
= n
;
689 s1
->got_offsets
[index
] = val
;
692 /* XXX: suppress that */
693 static void put32(unsigned char *p
, uint32_t val
)
701 #if defined(TCC_TARGET_I386) || defined(TCC_TARGET_ARM)
702 static uint32_t get32(unsigned char *p
)
704 return p
[0] | (p
[1] << 8) | (p
[2] << 16) | (p
[3] << 24);
708 static void build_got(TCCState
*s1
)
712 /* if no got, then create it */
713 s1
->got
= new_section(s1
, ".got", SHT_PROGBITS
, SHF_ALLOC
| SHF_WRITE
);
714 s1
->got
->sh_entsize
= 4;
715 add_elf_sym(symtab_section
, 0, 4, ELF32_ST_INFO(STB_GLOBAL
, STT_OBJECT
),
716 0, s1
->got
->sh_num
, "_GLOBAL_OFFSET_TABLE_");
717 ptr
= section_ptr_add(s1
->got
, 3 * sizeof(int));
718 /* keep space for _DYNAMIC pointer, if present */
720 /* two dummy got entries */
725 /* put a got entry corresponding to a symbol in symtab_section. 'size'
726 and 'info' can be modifed if more precise info comes from the DLL */
727 static void put_got_entry(TCCState
*s1
,
728 int reloc_type
, unsigned long size
, int info
,
734 unsigned long offset
;
740 /* if a got entry already exists for that symbol, no need to add one */
741 if (sym_index
< s1
->nb_got_offsets
&&
742 s1
->got_offsets
[sym_index
] != 0)
745 put_got_offset(s1
, sym_index
, s1
->got
->data_offset
);
748 sym
= &((Elf32_Sym
*)symtab_section
->data
)[sym_index
];
749 name
= symtab_section
->link
->data
+ sym
->st_name
;
750 offset
= sym
->st_value
;
751 #ifdef TCC_TARGET_I386
752 if (reloc_type
== R_386_JMP_SLOT
) {
757 /* if we build a DLL, we add a %ebx offset */
758 if (s1
->output_type
== TCC_OUTPUT_DLL
)
763 /* add a PLT entry */
765 if (plt
->data_offset
== 0) {
766 /* first plt entry */
767 p
= section_ptr_add(plt
, 16);
768 p
[0] = 0xff; /* pushl got + 4 */
771 p
[6] = 0xff; /* jmp *(got + 8) */
776 p
= section_ptr_add(plt
, 16);
777 p
[0] = 0xff; /* jmp *(got + x) */
779 put32(p
+ 2, s1
->got
->data_offset
);
780 p
[6] = 0x68; /* push $xxx */
781 put32(p
+ 7, (plt
->data_offset
- 32) >> 1);
782 p
[11] = 0xe9; /* jmp plt_start */
783 put32(p
+ 12, -(plt
->data_offset
));
785 /* the symbol is modified so that it will be relocated to
787 if (s1
->output_type
== TCC_OUTPUT_EXE
)
788 offset
= plt
->data_offset
- 16;
790 #elif defined(TCC_TARGET_ARM)
791 if (reloc_type
== R_ARM_JUMP_SLOT
) {
795 /* if we build a DLL, we add a %ebx offset */
796 if (s1
->output_type
== TCC_OUTPUT_DLL
)
797 error("DLLs unimplemented!");
799 /* add a PLT entry */
801 if (plt
->data_offset
== 0) {
802 /* first plt entry */
803 p
= section_ptr_add(plt
, 16);
804 put32(p
, 0xe52de004);
805 put32(p
+ 4, 0xe59fe010);
806 put32(p
+ 8, 0xe08fe00e);
807 put32(p
+ 12, 0xe5bef008);
810 p
= section_ptr_add(plt
, 16);
811 put32(p
, 0xe59fc004);
812 put32(p
+4, 0xe08fc00c);
813 put32(p
+8, 0xe59cf000);
814 put32(p
+12, s1
->got
->data_offset
);
816 /* the symbol is modified so that it will be relocated to
818 if (s1
->output_type
== TCC_OUTPUT_EXE
)
819 offset
= plt
->data_offset
- 16;
821 #elif defined(TCC_TARGET_C67)
822 error("C67 got not implemented");
824 #error unsupported CPU
826 index
= put_elf_sym(s1
->dynsym
, offset
,
827 size
, info
, 0, sym
->st_shndx
, name
);
828 /* put a got entry */
829 put_elf_reloc(s1
->dynsym
, s1
->got
,
830 s1
->got
->data_offset
,
833 ptr
= section_ptr_add(s1
->got
, sizeof(int));
837 /* build GOT and PLT entries */
838 static void build_got_entries(TCCState
*s1
)
841 Elf32_Rel
*rel
, *rel_end
;
843 int i
, type
, reloc_type
, sym_index
;
845 for(i
= 1; i
< s1
->nb_sections
; i
++) {
847 if (s
->sh_type
!= SHT_REL
)
849 /* no need to handle got relocations */
850 if (s
->link
!= symtab_section
)
853 rel_end
= (Elf32_Rel
*)(s
->data
+ s
->data_offset
);
854 for(rel
= (Elf32_Rel
*)s
->data
;
857 type
= ELF32_R_TYPE(rel
->r_info
);
859 #if defined(TCC_TARGET_I386)
866 if (type
== R_386_GOT32
|| type
== R_386_PLT32
) {
867 sym_index
= ELF32_R_SYM(rel
->r_info
);
868 sym
= &((Elf32_Sym
*)symtab_section
->data
)[sym_index
];
869 /* look at the symbol got offset. If none, then add one */
870 if (type
== R_386_GOT32
)
871 reloc_type
= R_386_GLOB_DAT
;
873 reloc_type
= R_386_JMP_SLOT
;
874 put_got_entry(s1
, reloc_type
, sym
->st_size
, sym
->st_info
,
878 #elif defined(TCC_TARGET_ARM)
881 case R_ARM_BASE_PREL
:
885 if (type
== R_ARM_GOT_BREL
|| type
== R_ARM_PLT32
) {
886 sym_index
= ELF32_R_SYM(rel
->r_info
);
887 sym
= &((Elf32_Sym
*)symtab_section
->data
)[sym_index
];
888 /* look at the symbol got offset. If none, then add one */
889 if (type
== R_ARM_GOT_BREL
)
890 reloc_type
= R_ARM_GLOB_DAT
;
892 reloc_type
= R_ARM_JUMP_SLOT
;
893 put_got_entry(s1
, reloc_type
, sym
->st_size
, sym
->st_info
,
897 #elif defined(TCC_TARGET_C67)
904 if (type
== R_C60_GOT32
|| type
== R_C60_PLT32
) {
905 sym_index
= ELF32_R_SYM(rel
->r_info
);
906 sym
= &((Elf32_Sym
*)symtab_section
->data
)[sym_index
];
907 /* look at the symbol got offset. If none, then add one */
908 if (type
== R_C60_GOT32
)
909 reloc_type
= R_C60_GLOB_DAT
;
911 reloc_type
= R_C60_JMP_SLOT
;
912 put_got_entry(s1
, reloc_type
, sym
->st_size
, sym
->st_info
,
917 #error unsupported CPU
926 static Section
*new_symtab(TCCState
*s1
,
927 const char *symtab_name
, int sh_type
, int sh_flags
,
928 const char *strtab_name
,
929 const char *hash_name
, int hash_sh_flags
)
931 Section
*symtab
, *strtab
, *hash
;
932 int *ptr
, nb_buckets
;
934 symtab
= new_section(s1
, symtab_name
, sh_type
, sh_flags
);
935 symtab
->sh_entsize
= sizeof(Elf32_Sym
);
936 strtab
= new_section(s1
, strtab_name
, SHT_STRTAB
, sh_flags
);
937 put_elf_str(strtab
, "");
938 symtab
->link
= strtab
;
939 put_elf_sym(symtab
, 0, 0, 0, 0, 0, NULL
);
943 hash
= new_section(s1
, hash_name
, SHT_HASH
, hash_sh_flags
);
944 hash
->sh_entsize
= sizeof(int);
948 ptr
= section_ptr_add(hash
, (2 + nb_buckets
+ 1) * sizeof(int));
951 memset(ptr
+ 2, 0, (nb_buckets
+ 1) * sizeof(int));
955 /* put dynamic tag */
956 static void put_dt(Section
*dynamic
, int dt
, unsigned long val
)
959 dyn
= section_ptr_add(dynamic
, sizeof(Elf32_Dyn
));
961 dyn
->d_un
.d_val
= val
;
964 static void add_init_array_defines(TCCState
*s1
, const char *section_name
)
968 char sym_start
[1024];
971 snprintf(sym_start
, sizeof(sym_start
), "__%s_start", section_name
+ 1);
972 snprintf(sym_end
, sizeof(sym_end
), "__%s_end", section_name
+ 1);
974 s
= find_section(s1
, section_name
);
979 end_offset
= s
->data_offset
;
982 add_elf_sym(symtab_section
,
984 ELF32_ST_INFO(STB_GLOBAL
, STT_NOTYPE
), 0,
985 s
->sh_num
, sym_start
);
986 add_elf_sym(symtab_section
,
988 ELF32_ST_INFO(STB_GLOBAL
, STT_NOTYPE
), 0,
992 /* add tcc runtime libraries */
993 static void tcc_add_runtime(TCCState
*s1
)
997 #ifdef CONFIG_TCC_BCHECK
998 if (do_bounds_check
) {
1000 Section
*init_section
;
1001 unsigned char *pinit
;
1004 /* XXX: add an object file to do that */
1005 ptr
= section_ptr_add(bounds_section
, sizeof(unsigned long));
1007 add_elf_sym(symtab_section
, 0, 0,
1008 ELF32_ST_INFO(STB_GLOBAL
, STT_NOTYPE
), 0,
1009 bounds_section
->sh_num
, "__bounds_start");
1010 /* add bound check code */
1011 snprintf(buf
, sizeof(buf
), "%s/%s", tcc_lib_path
, "bcheck.o");
1012 tcc_add_file(s1
, buf
);
1013 #ifdef TCC_TARGET_I386
1014 if (s1
->output_type
!= TCC_OUTPUT_MEMORY
) {
1015 /* add 'call __bound_init()' in .init section */
1016 init_section
= find_section(s1
, ".init");
1017 pinit
= section_ptr_add(init_section
, 5);
1019 put32(pinit
+ 1, -4);
1020 sym_index
= find_elf_sym(symtab_section
, "__bound_init");
1021 put_elf_reloc(symtab_section
, init_section
,
1022 init_section
->data_offset
- 4, R_386_PC32
, sym_index
);
1028 if (!s1
->nostdlib
) {
1029 tcc_add_library(s1
, "c");
1031 snprintf(buf
, sizeof(buf
), "%s/%s", tcc_lib_path
, "libtcc1.a");
1032 tcc_add_file(s1
, buf
);
1034 /* add crt end if not memory output */
1035 if (s1
->output_type
!= TCC_OUTPUT_MEMORY
&& !s1
->nostdlib
) {
1036 tcc_add_file(s1
, CONFIG_TCC_CRT_PREFIX
"/crtn.o");
1040 /* add various standard linker symbols (must be done after the
1041 sections are filled (for example after allocating common
1043 static void tcc_add_linker_symbols(TCCState
*s1
)
1049 add_elf_sym(symtab_section
,
1050 text_section
->data_offset
, 0,
1051 ELF32_ST_INFO(STB_GLOBAL
, STT_NOTYPE
), 0,
1052 text_section
->sh_num
, "_etext");
1053 add_elf_sym(symtab_section
,
1054 data_section
->data_offset
, 0,
1055 ELF32_ST_INFO(STB_GLOBAL
, STT_NOTYPE
), 0,
1056 data_section
->sh_num
, "_edata");
1057 add_elf_sym(symtab_section
,
1058 bss_section
->data_offset
, 0,
1059 ELF32_ST_INFO(STB_GLOBAL
, STT_NOTYPE
), 0,
1060 bss_section
->sh_num
, "_end");
1061 /* horrible new standard ldscript defines */
1062 add_init_array_defines(s1
, ".preinit_array");
1063 add_init_array_defines(s1
, ".init_array");
1064 add_init_array_defines(s1
, ".fini_array");
1066 /* add start and stop symbols for sections whose name can be
1068 for(i
= 1; i
< s1
->nb_sections
; i
++) {
1069 s
= s1
->sections
[i
];
1070 if (s
->sh_type
== SHT_PROGBITS
&&
1071 (s
->sh_flags
& SHF_ALLOC
)) {
1075 /* check if section name can be expressed in C */
1081 if (!isid(ch
) && !isnum(ch
))
1085 snprintf(buf
, sizeof(buf
), "__start_%s", s
->name
);
1086 add_elf_sym(symtab_section
,
1088 ELF32_ST_INFO(STB_GLOBAL
, STT_NOTYPE
), 0,
1090 snprintf(buf
, sizeof(buf
), "__stop_%s", s
->name
);
1091 add_elf_sym(symtab_section
,
1093 ELF32_ST_INFO(STB_GLOBAL
, STT_NOTYPE
), 0,
1100 /* name of ELF interpreter */
1102 static char elf_interp
[] = "/usr/libexec/ld-elf.so.1";
1105 static char elf_interp
[] = "/lib/ld-linux.so.3";
1107 static char elf_interp
[] = "/lib/ld-linux.so.2";
1111 static void tcc_output_binary(TCCState
*s1
, FILE *f
,
1112 const int *section_order
)
1115 int i
, offset
, size
;
1118 for(i
=1;i
<s1
->nb_sections
;i
++) {
1119 s
= s1
->sections
[section_order
[i
]];
1120 if (s
->sh_type
!= SHT_NOBITS
&&
1121 (s
->sh_flags
& SHF_ALLOC
)) {
1122 while (offset
< s
->sh_offset
) {
1127 fwrite(s
->data
, 1, size
, f
);
1133 /* output an ELF file */
1134 /* XXX: suppress unneeded sections */
1135 int tcc_output_file(TCCState
*s1
, const char *filename
)
1141 int shnum
, i
, phnum
, file_offset
, offset
, size
, j
, tmp
, sh_order_index
, k
;
1143 Section
*strsec
, *s
;
1144 Elf32_Shdr shdr
, *sh
;
1145 Elf32_Phdr
*phdr
, *ph
;
1146 Section
*interp
, *dynamic
, *dynstr
;
1147 unsigned long saved_dynamic_data_offset
;
1149 int type
, file_type
;
1150 unsigned long rel_addr
, rel_size
;
1152 file_type
= s1
->output_type
;
1155 if (file_type
!= TCC_OUTPUT_OBJ
) {
1156 tcc_add_runtime(s1
);
1160 section_order
= NULL
;
1163 dynstr
= NULL
; /* avoid warning */
1164 saved_dynamic_data_offset
= 0; /* avoid warning */
1166 if (file_type
!= TCC_OUTPUT_OBJ
) {
1167 relocate_common_syms();
1169 tcc_add_linker_symbols(s1
);
1171 if (!s1
->static_link
) {
1173 int sym_index
, index
;
1174 Elf32_Sym
*esym
, *sym_end
;
1176 if (file_type
== TCC_OUTPUT_EXE
) {
1178 /* add interpreter section only if executable */
1179 interp
= new_section(s1
, ".interp", SHT_PROGBITS
, SHF_ALLOC
);
1180 interp
->sh_addralign
= 1;
1181 ptr
= section_ptr_add(interp
, sizeof(elf_interp
));
1182 strcpy(ptr
, elf_interp
);
1185 /* add dynamic symbol table */
1186 s1
->dynsym
= new_symtab(s1
, ".dynsym", SHT_DYNSYM
, SHF_ALLOC
,
1188 ".hash", SHF_ALLOC
);
1189 dynstr
= s1
->dynsym
->link
;
1191 /* add dynamic section */
1192 dynamic
= new_section(s1
, ".dynamic", SHT_DYNAMIC
,
1193 SHF_ALLOC
| SHF_WRITE
);
1194 dynamic
->link
= dynstr
;
1195 dynamic
->sh_entsize
= sizeof(Elf32_Dyn
);
1198 s1
->plt
= new_section(s1
, ".plt", SHT_PROGBITS
,
1199 SHF_ALLOC
| SHF_EXECINSTR
);
1200 s1
->plt
->sh_entsize
= 4;
1204 /* scan for undefined symbols and see if they are in the
1205 dynamic symbols. If a symbol STT_FUNC is found, then we
1206 add it in the PLT. If a symbol STT_OBJECT is found, we
1207 add it in the .bss section with a suitable relocation */
1208 sym_end
= (Elf32_Sym
*)(symtab_section
->data
+
1209 symtab_section
->data_offset
);
1210 if (file_type
== TCC_OUTPUT_EXE
) {
1211 for(sym
= (Elf32_Sym
*)symtab_section
->data
+ 1;
1214 if (sym
->st_shndx
== SHN_UNDEF
) {
1215 name
= symtab_section
->link
->data
+ sym
->st_name
;
1216 sym_index
= find_elf_sym(s1
->dynsymtab_section
, name
);
1218 esym
= &((Elf32_Sym
*)s1
->dynsymtab_section
->data
)[sym_index
];
1219 type
= ELF32_ST_TYPE(esym
->st_info
);
1220 if (type
== STT_FUNC
) {
1221 put_got_entry(s1
, R_JMP_SLOT
, esym
->st_size
,
1223 sym
- (Elf32_Sym
*)symtab_section
->data
);
1224 } else if (type
== STT_OBJECT
) {
1225 unsigned long offset
;
1226 offset
= bss_section
->data_offset
;
1227 /* XXX: which alignment ? */
1228 offset
= (offset
+ 16 - 1) & -16;
1229 index
= put_elf_sym(s1
->dynsym
, offset
, esym
->st_size
,
1231 bss_section
->sh_num
, name
);
1232 put_elf_reloc(s1
->dynsym
, bss_section
,
1233 offset
, R_COPY
, index
);
1234 offset
+= esym
->st_size
;
1235 bss_section
->data_offset
= offset
;
1238 /* STB_WEAK undefined symbols are accepted */
1239 /* XXX: _fp_hw seems to be part of the ABI, so we ignore
1241 if (ELF32_ST_BIND(sym
->st_info
) == STB_WEAK
||
1242 !strcmp(name
, "_fp_hw")) {
1244 error_noabort("undefined symbol '%s'", name
);
1247 } else if (s1
->rdynamic
&&
1248 ELF32_ST_BIND(sym
->st_info
) != STB_LOCAL
) {
1249 /* if -rdynamic option, then export all non
1251 name
= symtab_section
->link
->data
+ sym
->st_name
;
1252 put_elf_sym(s1
->dynsym
, sym
->st_value
, sym
->st_size
,
1254 sym
->st_shndx
, name
);
1261 /* now look at unresolved dynamic symbols and export
1262 corresponding symbol */
1263 sym_end
= (Elf32_Sym
*)(s1
->dynsymtab_section
->data
+
1264 s1
->dynsymtab_section
->data_offset
);
1265 for(esym
= (Elf32_Sym
*)s1
->dynsymtab_section
->data
+ 1;
1268 if (esym
->st_shndx
== SHN_UNDEF
) {
1269 name
= s1
->dynsymtab_section
->link
->data
+ esym
->st_name
;
1270 sym_index
= find_elf_sym(symtab_section
, name
);
1272 /* XXX: avoid adding a symbol if already
1273 present because of -rdynamic ? */
1274 sym
= &((Elf32_Sym
*)symtab_section
->data
)[sym_index
];
1275 put_elf_sym(s1
->dynsym
, sym
->st_value
, sym
->st_size
,
1277 sym
->st_shndx
, name
);
1279 if (ELF32_ST_BIND(esym
->st_info
) == STB_WEAK
) {
1280 /* weak symbols can stay undefined */
1282 warning("undefined dynamic symbol '%s'", name
);
1289 /* shared library case : we simply export all the global symbols */
1290 nb_syms
= symtab_section
->data_offset
/ sizeof(Elf32_Sym
);
1291 s1
->symtab_to_dynsym
= tcc_mallocz(sizeof(int) * nb_syms
);
1292 for(sym
= (Elf32_Sym
*)symtab_section
->data
+ 1;
1295 if (ELF32_ST_BIND(sym
->st_info
) != STB_LOCAL
) {
1296 name
= symtab_section
->link
->data
+ sym
->st_name
;
1297 index
= put_elf_sym(s1
->dynsym
, sym
->st_value
, sym
->st_size
,
1299 sym
->st_shndx
, name
);
1300 s1
->symtab_to_dynsym
[sym
-
1301 (Elf32_Sym
*)symtab_section
->data
] =
1307 build_got_entries(s1
);
1309 /* add a list of needed dlls */
1310 for(i
= 0; i
< s1
->nb_loaded_dlls
; i
++) {
1311 DLLReference
*dllref
= s1
->loaded_dlls
[i
];
1312 if (dllref
->level
== 0)
1313 put_dt(dynamic
, DT_NEEDED
, put_elf_str(dynstr
, dllref
->name
));
1315 /* XXX: currently, since we do not handle PIC code, we
1316 must relocate the readonly segments */
1317 if (file_type
== TCC_OUTPUT_DLL
) {
1319 put_dt(dynamic
, DT_SONAME
, put_elf_str(dynstr
, s1
->soname
));
1320 put_dt(dynamic
, DT_TEXTREL
, 0);
1323 /* add necessary space for other entries */
1324 saved_dynamic_data_offset
= dynamic
->data_offset
;
1325 dynamic
->data_offset
+= 8 * 9;
1327 /* still need to build got entries in case of static link */
1328 build_got_entries(s1
);
1332 memset(&ehdr
, 0, sizeof(ehdr
));
1334 /* we add a section for symbols */
1335 strsec
= new_section(s1
, ".shstrtab", SHT_STRTAB
, 0);
1336 put_elf_str(strsec
, "");
1338 /* compute number of sections */
1339 shnum
= s1
->nb_sections
;
1341 /* this array is used to reorder sections in the output file */
1342 section_order
= tcc_malloc(sizeof(int) * shnum
);
1343 section_order
[0] = 0;
1346 /* compute number of program headers */
1349 case TCC_OUTPUT_OBJ
:
1352 case TCC_OUTPUT_EXE
:
1353 if (!s1
->static_link
)
1358 case TCC_OUTPUT_DLL
:
1363 /* allocate strings for section names and decide if an unallocated
1364 section should be output */
1365 /* NOTE: the strsec section comes last, so its size is also
1367 for(i
= 1; i
< s1
->nb_sections
; i
++) {
1368 s
= s1
->sections
[i
];
1369 s
->sh_name
= put_elf_str(strsec
, s
->name
);
1370 /* when generating a DLL, we include relocations but we may
1372 if (file_type
== TCC_OUTPUT_DLL
&&
1373 s
->sh_type
== SHT_REL
&&
1374 !(s
->sh_flags
& SHF_ALLOC
)) {
1375 prepare_dynamic_rel(s1
, s
);
1376 } else if (do_debug
||
1377 file_type
== TCC_OUTPUT_OBJ
||
1378 (s
->sh_flags
& SHF_ALLOC
) ||
1379 i
== (s1
->nb_sections
- 1)) {
1380 /* we output all sections if debug or object file */
1381 s
->sh_size
= s
->data_offset
;
1385 /* allocate program segment headers */
1386 phdr
= tcc_mallocz(phnum
* sizeof(Elf32_Phdr
));
1388 if (s1
->output_format
== TCC_OUTPUT_FORMAT_ELF
) {
1389 file_offset
= sizeof(Elf32_Ehdr
) + phnum
* sizeof(Elf32_Phdr
);
1394 /* compute section to program header mapping */
1395 if (s1
->has_text_addr
) {
1396 int a_offset
, p_offset
;
1397 addr
= s1
->text_addr
;
1398 /* we ensure that (addr % ELF_PAGE_SIZE) == file_offset %
1400 a_offset
= addr
& (ELF_PAGE_SIZE
- 1);
1401 p_offset
= file_offset
& (ELF_PAGE_SIZE
- 1);
1402 if (a_offset
< p_offset
)
1403 a_offset
+= ELF_PAGE_SIZE
;
1404 file_offset
+= (a_offset
- p_offset
);
1406 if (file_type
== TCC_OUTPUT_DLL
)
1409 addr
= ELF_START_ADDR
;
1410 /* compute address after headers */
1411 addr
+= (file_offset
& (ELF_PAGE_SIZE
- 1));
1414 /* dynamic relocation table information, for .dynamic section */
1418 /* leave one program header for the program interpreter */
1423 for(j
= 0; j
< 2; j
++) {
1424 ph
->p_type
= PT_LOAD
;
1426 ph
->p_flags
= PF_R
| PF_X
;
1428 ph
->p_flags
= PF_R
| PF_W
;
1429 ph
->p_align
= ELF_PAGE_SIZE
;
1431 /* we do the following ordering: interp, symbol tables,
1432 relocations, progbits, nobits */
1433 /* XXX: do faster and simpler sorting */
1434 for(k
= 0; k
< 5; k
++) {
1435 for(i
= 1; i
< s1
->nb_sections
; i
++) {
1436 s
= s1
->sections
[i
];
1437 /* compute if section should be included */
1439 if ((s
->sh_flags
& (SHF_ALLOC
| SHF_WRITE
)) !=
1443 if ((s
->sh_flags
& (SHF_ALLOC
| SHF_WRITE
)) !=
1444 (SHF_ALLOC
| SHF_WRITE
))
1450 } else if (s
->sh_type
== SHT_DYNSYM
||
1451 s
->sh_type
== SHT_STRTAB
||
1452 s
->sh_type
== SHT_HASH
) {
1455 } else if (s
->sh_type
== SHT_REL
) {
1458 } else if (s
->sh_type
== SHT_NOBITS
) {
1465 section_order
[sh_order_index
++] = i
;
1467 /* section matches: we align it and add its size */
1469 addr
= (addr
+ s
->sh_addralign
- 1) &
1470 ~(s
->sh_addralign
- 1);
1471 file_offset
+= addr
- tmp
;
1472 s
->sh_offset
= file_offset
;
1475 /* update program header infos */
1476 if (ph
->p_offset
== 0) {
1477 ph
->p_offset
= file_offset
;
1479 ph
->p_paddr
= ph
->p_vaddr
;
1481 /* update dynamic relocation infos */
1482 if (s
->sh_type
== SHT_REL
) {
1485 rel_size
+= s
->sh_size
;
1488 if (s
->sh_type
!= SHT_NOBITS
)
1489 file_offset
+= s
->sh_size
;
1492 ph
->p_filesz
= file_offset
- ph
->p_offset
;
1493 ph
->p_memsz
= addr
- ph
->p_vaddr
;
1496 if (s1
->output_format
== TCC_OUTPUT_FORMAT_ELF
) {
1497 /* if in the middle of a page, we duplicate the page in
1498 memory so that one copy is RX and the other is RW */
1499 if ((addr
& (ELF_PAGE_SIZE
- 1)) != 0)
1500 addr
+= ELF_PAGE_SIZE
;
1502 addr
= (addr
+ ELF_PAGE_SIZE
- 1) & ~(ELF_PAGE_SIZE
- 1);
1503 file_offset
= (file_offset
+ ELF_PAGE_SIZE
- 1) &
1504 ~(ELF_PAGE_SIZE
- 1);
1509 /* if interpreter, then add corresponing program header */
1513 ph
->p_type
= PT_INTERP
;
1514 ph
->p_offset
= interp
->sh_offset
;
1515 ph
->p_vaddr
= interp
->sh_addr
;
1516 ph
->p_paddr
= ph
->p_vaddr
;
1517 ph
->p_filesz
= interp
->sh_size
;
1518 ph
->p_memsz
= interp
->sh_size
;
1520 ph
->p_align
= interp
->sh_addralign
;
1523 /* if dynamic section, then add corresponing program header */
1527 ph
= &phdr
[phnum
- 1];
1529 ph
->p_type
= PT_DYNAMIC
;
1530 ph
->p_offset
= dynamic
->sh_offset
;
1531 ph
->p_vaddr
= dynamic
->sh_addr
;
1532 ph
->p_paddr
= ph
->p_vaddr
;
1533 ph
->p_filesz
= dynamic
->sh_size
;
1534 ph
->p_memsz
= dynamic
->sh_size
;
1535 ph
->p_flags
= PF_R
| PF_W
;
1536 ph
->p_align
= dynamic
->sh_addralign
;
1538 /* put GOT dynamic section address */
1539 put32(s1
->got
->data
, dynamic
->sh_addr
);
1541 /* relocate the PLT */
1542 if (file_type
== TCC_OUTPUT_EXE
) {
1546 p_end
= p
+ s1
->plt
->data_offset
;
1548 #if defined(TCC_TARGET_I386)
1549 put32(p
+ 2, get32(p
+ 2) + s1
->got
->sh_addr
);
1550 put32(p
+ 8, get32(p
+ 8) + s1
->got
->sh_addr
);
1553 put32(p
+ 2, get32(p
+ 2) + s1
->got
->sh_addr
);
1556 #elif defined(TCC_TARGET_ARM)
1558 x
=s1
->got
->sh_addr
- s1
->plt
->sh_addr
- 12;
1561 put32(p
+ 12, x
+ get32(p
+ 12) + s1
->plt
->data
- p
);
1564 #elif defined(TCC_TARGET_C67)
1567 #error unsupported CPU
1572 /* relocate symbols in .dynsym */
1573 sym_end
= (Elf32_Sym
*)(s1
->dynsym
->data
+ s1
->dynsym
->data_offset
);
1574 for(sym
= (Elf32_Sym
*)s1
->dynsym
->data
+ 1;
1577 if (sym
->st_shndx
== SHN_UNDEF
) {
1578 /* relocate to the PLT if the symbol corresponds
1581 sym
->st_value
+= s1
->plt
->sh_addr
;
1582 } else if (sym
->st_shndx
< SHN_LORESERVE
) {
1583 /* do symbol relocation */
1584 sym
->st_value
+= s1
->sections
[sym
->st_shndx
]->sh_addr
;
1588 /* put dynamic section entries */
1589 dynamic
->data_offset
= saved_dynamic_data_offset
;
1590 put_dt(dynamic
, DT_HASH
, s1
->dynsym
->hash
->sh_addr
);
1591 put_dt(dynamic
, DT_STRTAB
, dynstr
->sh_addr
);
1592 put_dt(dynamic
, DT_SYMTAB
, s1
->dynsym
->sh_addr
);
1593 put_dt(dynamic
, DT_STRSZ
, dynstr
->data_offset
);
1594 put_dt(dynamic
, DT_SYMENT
, sizeof(Elf32_Sym
));
1595 put_dt(dynamic
, DT_REL
, rel_addr
);
1596 put_dt(dynamic
, DT_RELSZ
, rel_size
);
1597 put_dt(dynamic
, DT_RELENT
, sizeof(Elf32_Rel
));
1598 put_dt(dynamic
, DT_NULL
, 0);
1601 ehdr
.e_phentsize
= sizeof(Elf32_Phdr
);
1602 ehdr
.e_phnum
= phnum
;
1603 ehdr
.e_phoff
= sizeof(Elf32_Ehdr
);
1606 /* all other sections come after */
1607 for(i
= 1; i
< s1
->nb_sections
; i
++) {
1608 s
= s1
->sections
[i
];
1609 if (phnum
> 0 && (s
->sh_flags
& SHF_ALLOC
))
1611 section_order
[sh_order_index
++] = i
;
1613 file_offset
= (file_offset
+ s
->sh_addralign
- 1) &
1614 ~(s
->sh_addralign
- 1);
1615 s
->sh_offset
= file_offset
;
1616 if (s
->sh_type
!= SHT_NOBITS
)
1617 file_offset
+= s
->sh_size
;
1620 /* if building executable or DLL, then relocate each section
1621 except the GOT which is already relocated */
1622 if (file_type
!= TCC_OUTPUT_OBJ
) {
1623 relocate_syms(s1
, 0);
1625 if (s1
->nb_errors
!= 0) {
1631 /* relocate sections */
1632 /* XXX: ignore sections with allocated relocations ? */
1633 for(i
= 1; i
< s1
->nb_sections
; i
++) {
1634 s
= s1
->sections
[i
];
1635 if (s
->reloc
&& s
!= s1
->got
)
1636 relocate_section(s1
, s
);
1639 /* relocate relocation entries if the relocation tables are
1640 allocated in the executable */
1641 for(i
= 1; i
< s1
->nb_sections
; i
++) {
1642 s
= s1
->sections
[i
];
1643 if ((s
->sh_flags
& SHF_ALLOC
) &&
1644 s
->sh_type
== SHT_REL
) {
1645 relocate_rel(s1
, s
);
1649 /* get entry point address */
1650 if (file_type
== TCC_OUTPUT_EXE
)
1651 ehdr
.e_entry
= (unsigned long)tcc_get_symbol_err(s1
, "_start");
1653 ehdr
.e_entry
= text_section
->sh_addr
; /* XXX: is it correct ? */
1656 /* write elf file */
1657 if (file_type
== TCC_OUTPUT_OBJ
)
1661 fd
= open(filename
, O_WRONLY
| O_CREAT
| O_TRUNC
| O_BINARY
, mode
);
1663 error_noabort("could not write '%s'", filename
);
1666 f
= fdopen(fd
, "wb");
1668 #ifdef TCC_TARGET_COFF
1669 if (s1
->output_format
== TCC_OUTPUT_FORMAT_COFF
) {
1670 tcc_output_coff(s1
, f
);
1673 if (s1
->output_format
== TCC_OUTPUT_FORMAT_ELF
) {
1674 sort_syms(s1
, symtab_section
);
1677 file_offset
= (file_offset
+ 3) & -4;
1680 ehdr
.e_ident
[0] = ELFMAG0
;
1681 ehdr
.e_ident
[1] = ELFMAG1
;
1682 ehdr
.e_ident
[2] = ELFMAG2
;
1683 ehdr
.e_ident
[3] = ELFMAG3
;
1684 ehdr
.e_ident
[4] = ELFCLASS32
;
1685 ehdr
.e_ident
[5] = ELFDATA2LSB
;
1686 ehdr
.e_ident
[6] = EV_CURRENT
;
1688 ehdr
.e_ident
[EI_OSABI
] = ELFOSABI_FREEBSD
;
1690 #ifdef TCC_TARGET_ARM
1692 ehdr
.e_ident
[EI_OSABI
] = 0;
1693 ehdr
.e_flags
= 4 << 24;
1695 ehdr
.e_ident
[EI_OSABI
] = ELFOSABI_ARM
;
1700 case TCC_OUTPUT_EXE
:
1701 ehdr
.e_type
= ET_EXEC
;
1703 case TCC_OUTPUT_DLL
:
1704 ehdr
.e_type
= ET_DYN
;
1706 case TCC_OUTPUT_OBJ
:
1707 ehdr
.e_type
= ET_REL
;
1710 ehdr
.e_machine
= EM_TCC_TARGET
;
1711 ehdr
.e_version
= EV_CURRENT
;
1712 ehdr
.e_shoff
= file_offset
;
1713 ehdr
.e_ehsize
= sizeof(Elf32_Ehdr
);
1714 ehdr
.e_shentsize
= sizeof(Elf32_Shdr
);
1715 ehdr
.e_shnum
= shnum
;
1716 ehdr
.e_shstrndx
= shnum
- 1;
1718 fwrite(&ehdr
, 1, sizeof(Elf32_Ehdr
), f
);
1719 fwrite(phdr
, 1, phnum
* sizeof(Elf32_Phdr
), f
);
1720 offset
= sizeof(Elf32_Ehdr
) + phnum
* sizeof(Elf32_Phdr
);
1722 for(i
=1;i
<s1
->nb_sections
;i
++) {
1723 s
= s1
->sections
[section_order
[i
]];
1724 if (s
->sh_type
!= SHT_NOBITS
) {
1725 while (offset
< s
->sh_offset
) {
1730 fwrite(s
->data
, 1, size
, f
);
1735 /* output section headers */
1736 while (offset
< ehdr
.e_shoff
) {
1741 for(i
=0;i
<s1
->nb_sections
;i
++) {
1743 memset(sh
, 0, sizeof(Elf32_Shdr
));
1744 s
= s1
->sections
[i
];
1746 sh
->sh_name
= s
->sh_name
;
1747 sh
->sh_type
= s
->sh_type
;
1748 sh
->sh_flags
= s
->sh_flags
;
1749 sh
->sh_entsize
= s
->sh_entsize
;
1750 sh
->sh_info
= s
->sh_info
;
1752 sh
->sh_link
= s
->link
->sh_num
;
1753 sh
->sh_addralign
= s
->sh_addralign
;
1754 sh
->sh_addr
= s
->sh_addr
;
1755 sh
->sh_offset
= s
->sh_offset
;
1756 sh
->sh_size
= s
->sh_size
;
1758 fwrite(sh
, 1, sizeof(Elf32_Shdr
), f
);
1761 tcc_output_binary(s1
, f
, section_order
);
1767 tcc_free(s1
->symtab_to_dynsym
);
1768 tcc_free(section_order
);
1770 tcc_free(s1
->got_offsets
);
1774 static void *load_data(int fd
, unsigned long file_offset
, unsigned long size
)
1778 data
= tcc_malloc(size
);
1779 lseek(fd
, file_offset
, SEEK_SET
);
1780 read(fd
, data
, size
);
1784 typedef struct SectionMergeInfo
{
1785 Section
*s
; /* corresponding existing section */
1786 unsigned long offset
; /* offset of the new section in the existing section */
1787 uint8_t new_section
; /* true if section 's' was added */
1788 uint8_t link_once
; /* true if link once section */
1791 /* load an object file and merge it with current files */
1792 /* XXX: handle correctly stab (debug) info */
1793 static int tcc_load_object_file(TCCState
*s1
,
1794 int fd
, unsigned long file_offset
)
1797 Elf32_Shdr
*shdr
, *sh
;
1798 int size
, i
, j
, offset
, offseti
, nb_syms
, sym_index
, ret
;
1799 unsigned char *strsec
, *strtab
;
1800 int *old_to_new_syms
;
1801 char *sh_name
, *name
;
1802 SectionMergeInfo
*sm_table
, *sm
;
1803 Elf32_Sym
*sym
, *symtab
;
1804 Elf32_Rel
*rel
, *rel_end
;
1807 if (read(fd
, &ehdr
, sizeof(ehdr
)) != sizeof(ehdr
))
1809 if (ehdr
.e_ident
[0] != ELFMAG0
||
1810 ehdr
.e_ident
[1] != ELFMAG1
||
1811 ehdr
.e_ident
[2] != ELFMAG2
||
1812 ehdr
.e_ident
[3] != ELFMAG3
)
1814 /* test if object file */
1815 if (ehdr
.e_type
!= ET_REL
)
1817 /* test CPU specific stuff */
1818 if (ehdr
.e_ident
[5] != ELFDATA2LSB
||
1819 ehdr
.e_machine
!= EM_TCC_TARGET
) {
1821 error_noabort("invalid object file");
1825 shdr
= load_data(fd
, file_offset
+ ehdr
.e_shoff
,
1826 sizeof(Elf32_Shdr
) * ehdr
.e_shnum
);
1827 sm_table
= tcc_mallocz(sizeof(SectionMergeInfo
) * ehdr
.e_shnum
);
1829 /* load section names */
1830 sh
= &shdr
[ehdr
.e_shstrndx
];
1831 strsec
= load_data(fd
, file_offset
+ sh
->sh_offset
, sh
->sh_size
);
1833 /* load symtab and strtab */
1834 old_to_new_syms
= NULL
;
1838 for(i
= 1; i
< ehdr
.e_shnum
; i
++) {
1840 if (sh
->sh_type
== SHT_SYMTAB
) {
1842 error_noabort("object must contain only one symtab");
1847 nb_syms
= sh
->sh_size
/ sizeof(Elf32_Sym
);
1848 symtab
= load_data(fd
, file_offset
+ sh
->sh_offset
, sh
->sh_size
);
1849 sm_table
[i
].s
= symtab_section
;
1851 /* now load strtab */
1852 sh
= &shdr
[sh
->sh_link
];
1853 strtab
= load_data(fd
, file_offset
+ sh
->sh_offset
, sh
->sh_size
);
1857 /* now examine each section and try to merge its content with the
1859 for(i
= 1; i
< ehdr
.e_shnum
; i
++) {
1860 /* no need to examine section name strtab */
1861 if (i
== ehdr
.e_shstrndx
)
1864 sh_name
= strsec
+ sh
->sh_name
;
1865 /* ignore sections types we do not handle */
1866 if (sh
->sh_type
!= SHT_PROGBITS
&&
1867 sh
->sh_type
!= SHT_REL
&&
1869 sh
->sh_type
!= SHT_ARM_EXIDX
&&
1871 sh
->sh_type
!= SHT_NOBITS
)
1873 if (sh
->sh_addralign
< 1)
1874 sh
->sh_addralign
= 1;
1875 /* find corresponding section, if any */
1876 for(j
= 1; j
< s1
->nb_sections
;j
++) {
1877 s
= s1
->sections
[j
];
1878 if (!strcmp(s
->name
, sh_name
)) {
1879 if (!strncmp(sh_name
, ".gnu.linkonce",
1880 sizeof(".gnu.linkonce") - 1)) {
1881 /* if a 'linkonce' section is already present, we
1882 do not add it again. It is a little tricky as
1883 symbols can still be defined in
1885 sm_table
[i
].link_once
= 1;
1892 /* not found: create new section */
1893 s
= new_section(s1
, sh_name
, sh
->sh_type
, sh
->sh_flags
);
1894 /* take as much info as possible from the section. sh_link and
1895 sh_info will be updated later */
1896 s
->sh_addralign
= sh
->sh_addralign
;
1897 s
->sh_entsize
= sh
->sh_entsize
;
1898 sm_table
[i
].new_section
= 1;
1900 if (sh
->sh_type
!= s
->sh_type
) {
1901 error_noabort("invalid section type");
1905 /* align start of section */
1906 offset
= s
->data_offset
;
1907 size
= sh
->sh_addralign
- 1;
1908 offset
= (offset
+ size
) & ~size
;
1909 if (sh
->sh_addralign
> s
->sh_addralign
)
1910 s
->sh_addralign
= sh
->sh_addralign
;
1911 s
->data_offset
= offset
;
1912 sm_table
[i
].offset
= offset
;
1914 /* concatenate sections */
1916 if (sh
->sh_type
!= SHT_NOBITS
) {
1918 lseek(fd
, file_offset
+ sh
->sh_offset
, SEEK_SET
);
1919 ptr
= section_ptr_add(s
, size
);
1920 read(fd
, ptr
, size
);
1922 s
->data_offset
+= size
;
1927 /* second short pass to update sh_link and sh_info fields of new
1929 for(i
= 1; i
< ehdr
.e_shnum
; i
++) {
1931 if (!s
|| !sm_table
[i
].new_section
)
1934 if (sh
->sh_link
> 0)
1935 s
->link
= sm_table
[sh
->sh_link
].s
;
1936 if (sh
->sh_type
== SHT_REL
) {
1937 s
->sh_info
= sm_table
[sh
->sh_info
].s
->sh_num
;
1938 /* update backward link */
1939 s1
->sections
[s
->sh_info
]->reloc
= s
;
1944 /* resolve symbols */
1945 old_to_new_syms
= tcc_mallocz(nb_syms
* sizeof(int));
1948 for(i
= 1; i
< nb_syms
; i
++, sym
++) {
1949 if (sym
->st_shndx
!= SHN_UNDEF
&&
1950 sym
->st_shndx
< SHN_LORESERVE
) {
1951 sm
= &sm_table
[sym
->st_shndx
];
1952 if (sm
->link_once
) {
1953 /* if a symbol is in a link once section, we use the
1954 already defined symbol. It is very important to get
1955 correct relocations */
1956 if (ELF32_ST_BIND(sym
->st_info
) != STB_LOCAL
) {
1957 name
= strtab
+ sym
->st_name
;
1958 sym_index
= find_elf_sym(symtab_section
, name
);
1960 old_to_new_syms
[i
] = sym_index
;
1964 /* if no corresponding section added, no need to add symbol */
1967 /* convert section number */
1968 sym
->st_shndx
= sm
->s
->sh_num
;
1970 sym
->st_value
+= sm
->offset
;
1973 name
= strtab
+ sym
->st_name
;
1974 sym_index
= add_elf_sym(symtab_section
, sym
->st_value
, sym
->st_size
,
1975 sym
->st_info
, sym
->st_other
,
1976 sym
->st_shndx
, name
);
1977 old_to_new_syms
[i
] = sym_index
;
1980 /* third pass to patch relocation entries */
1981 for(i
= 1; i
< ehdr
.e_shnum
; i
++) {
1986 offset
= sm_table
[i
].offset
;
1987 switch(s
->sh_type
) {
1989 /* take relocation offset information */
1990 offseti
= sm_table
[sh
->sh_info
].offset
;
1991 rel_end
= (Elf32_Rel
*)(s
->data
+ s
->data_offset
);
1992 for(rel
= (Elf32_Rel
*)(s
->data
+ offset
);
1997 /* convert symbol index */
1998 type
= ELF32_R_TYPE(rel
->r_info
);
1999 sym_index
= ELF32_R_SYM(rel
->r_info
);
2000 /* NOTE: only one symtab assumed */
2001 if (sym_index
>= nb_syms
)
2003 sym_index
= old_to_new_syms
[sym_index
];
2004 /* ignore link_once in rel section. */
2005 if (!sym_index
&& !sm
->link_once
) {
2007 error_noabort("Invalid relocation entry [%2d] '%s' @ %.8x",
2008 i
, strsec
+ sh
->sh_name
, rel
->r_offset
);
2011 rel
->r_info
= ELF32_R_INFO(sym_index
, type
);
2012 /* offset the relocation offset */
2013 rel
->r_offset
+= offseti
;
2025 tcc_free(old_to_new_syms
);
2032 #define ARMAG "!<arch>\012" /* For COFF and a.out archives */
2034 typedef struct ArchiveHeader
{
2035 char ar_name
[16]; /* name of this member */
2036 char ar_date
[12]; /* file mtime */
2037 char ar_uid
[6]; /* owner uid; printed as decimal */
2038 char ar_gid
[6]; /* owner gid; printed as decimal */
2039 char ar_mode
[8]; /* file mode, printed as octal */
2040 char ar_size
[10]; /* file size, printed as decimal */
2041 char ar_fmag
[2]; /* should contain ARFMAG */
2044 static int get_be32(const uint8_t *b
)
2046 return b
[3] | (b
[2] << 8) | (b
[1] << 16) | (b
[0] << 24);
2049 /* load only the objects which resolve undefined symbols */
2050 static int tcc_load_alacarte(TCCState
*s1
, int fd
, int size
)
2052 int i
, bound
, nsyms
, sym_index
, off
, ret
;
2054 const char *ar_names
, *p
;
2055 const uint8_t *ar_index
;
2058 data
= tcc_malloc(size
);
2059 if (read(fd
, data
, size
) != size
)
2061 nsyms
= get_be32(data
);
2062 ar_index
= data
+ 4;
2063 ar_names
= ar_index
+ nsyms
* 4;
2067 for(p
= ar_names
, i
= 0; i
< nsyms
; i
++, p
+= strlen(p
)+1) {
2068 sym_index
= find_elf_sym(symtab_section
, p
);
2070 sym
= &((Elf32_Sym
*)symtab_section
->data
)[sym_index
];
2071 if(sym
->st_shndx
== SHN_UNDEF
) {
2072 off
= get_be32(ar_index
+ i
* 4) + sizeof(ArchiveHeader
);
2074 printf("%5d\t%s\t%08x\n", i
, p
, sym
->st_shndx
);
2077 lseek(fd
, off
, SEEK_SET
);
2078 if(tcc_load_object_file(s1
, fd
, off
) < 0) {
2093 /* load a '.a' file */
2094 static int tcc_load_archive(TCCState
*s1
, int fd
)
2101 unsigned long file_offset
;
2103 /* skip magic which was already checked */
2104 read(fd
, magic
, sizeof(magic
));
2107 len
= read(fd
, &hdr
, sizeof(hdr
));
2110 if (len
!= sizeof(hdr
)) {
2111 error_noabort("invalid archive");
2114 memcpy(ar_size
, hdr
.ar_size
, sizeof(hdr
.ar_size
));
2115 ar_size
[sizeof(hdr
.ar_size
)] = '\0';
2116 size
= strtol(ar_size
, NULL
, 0);
2117 memcpy(ar_name
, hdr
.ar_name
, sizeof(hdr
.ar_name
));
2118 for(i
= sizeof(hdr
.ar_name
) - 1; i
>= 0; i
--) {
2119 if (ar_name
[i
] != ' ')
2122 ar_name
[i
+ 1] = '\0';
2123 // printf("name='%s' size=%d %s\n", ar_name, size, ar_size);
2124 file_offset
= lseek(fd
, 0, SEEK_CUR
);
2126 size
= (size
+ 1) & ~1;
2127 if (!strcmp(ar_name
, "/")) {
2128 /* coff symbol table : we handle it */
2129 if(s1
->alacarte_link
)
2130 return tcc_load_alacarte(s1
, fd
, size
);
2131 } else if (!strcmp(ar_name
, "//") ||
2132 !strcmp(ar_name
, "__.SYMDEF") ||
2133 !strcmp(ar_name
, "__.SYMDEF/") ||
2134 !strcmp(ar_name
, "ARFILENAMES/")) {
2135 /* skip symbol table or archive names */
2137 if (tcc_load_object_file(s1
, fd
, file_offset
) < 0)
2140 lseek(fd
, file_offset
+ size
, SEEK_SET
);
2145 /* load a DLL and all referenced DLLs. 'level = 0' means that the DLL
2146 is referenced by the user (so it should be added as DT_NEEDED in
2147 the generated ELF file) */
2148 static int tcc_load_dll(TCCState
*s1
, int fd
, const char *filename
, int level
)
2151 Elf32_Shdr
*shdr
, *sh
, *sh1
;
2152 int i
, j
, nb_syms
, nb_dts
, sym_bind
, ret
;
2153 Elf32_Sym
*sym
, *dynsym
;
2154 Elf32_Dyn
*dt
, *dynamic
;
2155 unsigned char *dynstr
;
2156 const char *name
, *soname
;
2157 DLLReference
*dllref
;
2159 read(fd
, &ehdr
, sizeof(ehdr
));
2161 /* test CPU specific stuff */
2162 if (ehdr
.e_ident
[5] != ELFDATA2LSB
||
2163 ehdr
.e_machine
!= EM_TCC_TARGET
) {
2164 error_noabort("bad architecture");
2169 shdr
= load_data(fd
, ehdr
.e_shoff
, sizeof(Elf32_Shdr
) * ehdr
.e_shnum
);
2171 /* load dynamic section and dynamic symbols */
2175 dynsym
= NULL
; /* avoid warning */
2176 dynstr
= NULL
; /* avoid warning */
2177 for(i
= 0, sh
= shdr
; i
< ehdr
.e_shnum
; i
++, sh
++) {
2178 switch(sh
->sh_type
) {
2180 nb_dts
= sh
->sh_size
/ sizeof(Elf32_Dyn
);
2181 dynamic
= load_data(fd
, sh
->sh_offset
, sh
->sh_size
);
2184 nb_syms
= sh
->sh_size
/ sizeof(Elf32_Sym
);
2185 dynsym
= load_data(fd
, sh
->sh_offset
, sh
->sh_size
);
2186 sh1
= &shdr
[sh
->sh_link
];
2187 dynstr
= load_data(fd
, sh1
->sh_offset
, sh1
->sh_size
);
2194 /* compute the real library name */
2195 soname
= tcc_basename(filename
);
2197 for(i
= 0, dt
= dynamic
; i
< nb_dts
; i
++, dt
++) {
2198 if (dt
->d_tag
== DT_SONAME
) {
2199 soname
= dynstr
+ dt
->d_un
.d_val
;
2203 /* if the dll is already loaded, do not load it */
2204 for(i
= 0; i
< s1
->nb_loaded_dlls
; i
++) {
2205 dllref
= s1
->loaded_dlls
[i
];
2206 if (!strcmp(soname
, dllref
->name
)) {
2207 /* but update level if needed */
2208 if (level
< dllref
->level
)
2209 dllref
->level
= level
;
2215 // printf("loading dll '%s'\n", soname);
2217 /* add the dll and its level */
2218 dllref
= tcc_malloc(sizeof(DLLReference
) + strlen(soname
));
2219 dllref
->level
= level
;
2220 strcpy(dllref
->name
, soname
);
2221 dynarray_add((void ***)&s1
->loaded_dlls
, &s1
->nb_loaded_dlls
, dllref
);
2223 /* add dynamic symbols in dynsym_section */
2224 for(i
= 1, sym
= dynsym
+ 1; i
< nb_syms
; i
++, sym
++) {
2225 sym_bind
= ELF32_ST_BIND(sym
->st_info
);
2226 if (sym_bind
== STB_LOCAL
)
2228 name
= dynstr
+ sym
->st_name
;
2229 add_elf_sym(s1
->dynsymtab_section
, sym
->st_value
, sym
->st_size
,
2230 sym
->st_info
, sym
->st_other
, sym
->st_shndx
, name
);
2233 /* load all referenced DLLs */
2234 for(i
= 0, dt
= dynamic
; i
< nb_dts
; i
++, dt
++) {
2237 name
= dynstr
+ dt
->d_un
.d_val
;
2238 for(j
= 0; j
< s1
->nb_loaded_dlls
; j
++) {
2239 dllref
= s1
->loaded_dlls
[j
];
2240 if (!strcmp(name
, dllref
->name
))
2241 goto already_loaded
;
2243 if (tcc_add_dll(s1
, name
, AFF_REFERENCED_DLL
) < 0) {
2244 error_noabort("referenced dll '%s' not found", name
);
2261 #define LD_TOK_NAME 256
2262 #define LD_TOK_EOF (-1)
2264 /* return next ld script token */
2265 static int ld_next(TCCState
*s1
, char *name
, int name_size
)
2283 file
->buf_ptr
= parse_comment(file
->buf_ptr
);
2284 ch
= file
->buf_ptr
[0];
2292 /* case 'a' ... 'z': */
2319 /* case 'A' ... 'z': */
2354 if (!((ch
>= 'a' && ch
<= 'z') ||
2355 (ch
>= 'A' && ch
<= 'Z') ||
2356 (ch
>= '0' && ch
<= '9') ||
2357 strchr("/.-_+=$:\\,~", ch
)))
2359 if ((q
- name
) < name_size
- 1) {
2376 printf("tok=%c %d\n", c
, c
);
2377 if (c
== LD_TOK_NAME
)
2378 printf(" name=%s\n", name
);
2383 static int ld_add_file_list(TCCState
*s1
, int as_needed
)
2385 char filename
[1024];
2388 t
= ld_next(s1
, filename
, sizeof(filename
));
2391 t
= ld_next(s1
, filename
, sizeof(filename
));
2393 if (t
== LD_TOK_EOF
) {
2394 error_noabort("unexpected end of file");
2396 } else if (t
== ')') {
2398 } else if (t
!= LD_TOK_NAME
) {
2399 error_noabort("filename expected");
2402 if (!strcmp(filename
, "AS_NEEDED")) {
2403 ret
= ld_add_file_list(s1
, 1);
2407 /* TODO: Implement AS_NEEDED support. Ignore it for now */
2409 tcc_add_file(s1
, filename
);
2411 t
= ld_next(s1
, filename
, sizeof(filename
));
2413 t
= ld_next(s1
, filename
, sizeof(filename
));
2419 /* interpret a subset of GNU ldscripts to handle the dummy libc.so
2421 static int tcc_load_ldscript(TCCState
*s1
)
2424 char filename
[1024];
2427 ch
= file
->buf_ptr
[0];
2430 t
= ld_next(s1
, cmd
, sizeof(cmd
));
2431 if (t
== LD_TOK_EOF
)
2433 else if (t
!= LD_TOK_NAME
)
2435 if (!strcmp(cmd
, "INPUT") ||
2436 !strcmp(cmd
, "GROUP")) {
2437 ret
= ld_add_file_list(s1
, 0);
2440 } else if (!strcmp(cmd
, "OUTPUT_FORMAT") ||
2441 !strcmp(cmd
, "TARGET")) {
2442 /* ignore some commands */
2443 t
= ld_next(s1
, cmd
, sizeof(cmd
));
2447 t
= ld_next(s1
, filename
, sizeof(filename
));
2448 if (t
== LD_TOK_EOF
) {
2449 error_noabort("unexpected end of file");
2451 } else if (t
== ')') {