Define __ARM_PCS_VFP in hardfloat compilation mode
[tinycc.git] / tccelf.c
1 /*
2  *  ELF file handling for TCC
3  * 
4  *  Copyright (c) 2001-2004 Fabrice Bellard
5  *
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.
10  *
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.
15  *
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
19  */
20
21 #include "tcc.h"
22
23 static int new_undef_sym = 0; /* Is there a new undefined sym since last new_undef_sym() */
24
25 ST_FUNC int put_elf_str(Section *s, const char *sym)
26 {
27     int offset, len;
28     char *ptr;
29
30     len = strlen(sym) + 1;
31     offset = s->data_offset;
32     ptr = section_ptr_add(s, len);
33     memcpy(ptr, sym, len);
34     return offset;
35 }
36
37 /* elf symbol hashing function */
38 static unsigned long elf_hash(const unsigned char *name)
39 {
40     unsigned long h = 0, g;
41     
42     while (*name) {
43         h = (h << 4) + *name++;
44         g = h & 0xf0000000;
45         if (g)
46             h ^= g >> 24;
47         h &= ~g;
48     }
49     return h;
50 }
51
52 /* rebuild hash table of section s */
53 /* NOTE: we do factorize the hash table code to go faster */
54 static void rebuild_hash(Section *s, unsigned int nb_buckets)
55 {
56     ElfW(Sym) *sym;
57     int *ptr, *hash, nb_syms, sym_index, h;
58     char *strtab;
59
60     strtab = s->link->data;
61     nb_syms = s->data_offset / sizeof(ElfW(Sym));
62
63     s->hash->data_offset = 0;
64     ptr = section_ptr_add(s->hash, (2 + nb_buckets + nb_syms) * sizeof(int));
65     ptr[0] = nb_buckets;
66     ptr[1] = nb_syms;
67     ptr += 2;
68     hash = ptr;
69     memset(hash, 0, (nb_buckets + 1) * sizeof(int));
70     ptr += nb_buckets + 1;
71
72     sym = (ElfW(Sym) *)s->data + 1;
73     for(sym_index = 1; sym_index < nb_syms; sym_index++) {
74         if (ELFW(ST_BIND)(sym->st_info) != STB_LOCAL) {
75             h = elf_hash(strtab + sym->st_name) % nb_buckets;
76             *ptr = hash[h];
77             hash[h] = sym_index;
78         } else {
79             *ptr = 0;
80         }
81         ptr++;
82         sym++;
83     }
84 }
85
86 /* return the symbol number */
87 ST_FUNC int put_elf_sym(Section *s, addr_t value, unsigned long size,
88     int info, int other, int shndx, const char *name)
89 {
90     int name_offset, sym_index;
91     int nbuckets, h;
92     ElfW(Sym) *sym;
93     Section *hs;
94     
95     sym = section_ptr_add(s, sizeof(ElfW(Sym)));
96     if (name)
97         name_offset = put_elf_str(s->link, name);
98     else
99         name_offset = 0;
100     /* XXX: endianness */
101     sym->st_name = name_offset;
102     sym->st_value = value;
103     sym->st_size = size;
104     sym->st_info = info;
105     sym->st_other = other;
106     sym->st_shndx = shndx;
107     sym_index = sym - (ElfW(Sym) *)s->data;
108     hs = s->hash;
109     if (hs) {
110         int *ptr, *base;
111         ptr = section_ptr_add(hs, sizeof(int));
112         base = (int *)hs->data;
113         /* only add global or weak symbols */
114         if (ELFW(ST_BIND)(info) != STB_LOCAL) {
115             /* add another hashing entry */
116             nbuckets = base[0];
117             h = elf_hash(name) % nbuckets;
118             *ptr = base[2 + h];
119             base[2 + h] = sym_index;
120             base[1]++;
121             /* we resize the hash table */
122             hs->nb_hashed_syms++;
123             if (hs->nb_hashed_syms > 2 * nbuckets) {
124                 rebuild_hash(s, 2 * nbuckets);
125             }
126         } else {
127             *ptr = 0;
128             base[1]++;
129         }
130     }
131     return sym_index;
132 }
133
134 /* find global ELF symbol 'name' and return its index. Return 0 if not
135    found. */
136 ST_FUNC int find_elf_sym(Section *s, const char *name)
137 {
138     ElfW(Sym) *sym;
139     Section *hs;
140     int nbuckets, sym_index, h;
141     const char *name1;
142     
143     hs = s->hash;
144     if (!hs)
145         return 0;
146     nbuckets = ((int *)hs->data)[0];
147     h = elf_hash(name) % nbuckets;
148     sym_index = ((int *)hs->data)[2 + h];
149     while (sym_index != 0) {
150         sym = &((ElfW(Sym) *)s->data)[sym_index];
151         name1 = s->link->data + sym->st_name;
152         if (!strcmp(name, name1))
153             return sym_index;
154         sym_index = ((int *)hs->data)[2 + nbuckets + sym_index];
155     }
156     return 0;
157 }
158
159 /* return elf symbol value, signal error if 'err' is nonzero */
160 ST_FUNC addr_t get_elf_sym_addr(TCCState *s, const char *name, int err)
161 {
162     int sym_index;
163     ElfW(Sym) *sym;
164
165     sym_index = find_elf_sym(s->symtab, name);
166     sym = &((ElfW(Sym) *)s->symtab->data)[sym_index];
167     if (!sym_index || sym->st_shndx == SHN_UNDEF) {
168         if (err)
169             tcc_error("%s not defined", name);
170         return 0;
171     }
172     return sym->st_value;
173 }
174
175 /* return elf symbol value */
176 LIBTCCAPI void *tcc_get_symbol(TCCState *s, const char *name)
177 {
178     return (void*)(uintptr_t)get_elf_sym_addr(s, name, 0);
179 }
180
181 #ifdef TCC_IS_NATIVE
182 /* return elf symbol value or error */
183 ST_FUNC void* tcc_get_symbol_err(TCCState *s, const char *name)
184 {
185     return (void*)get_elf_sym_addr(s, name, 1);
186 }
187 #endif
188
189 /* add an elf symbol : check if it is already defined and patch
190    it. Return symbol index. NOTE that sh_num can be SHN_UNDEF. */
191 ST_FUNC int add_elf_sym(Section *s, addr_t value, unsigned long size,
192                        int info, int other, int sh_num, const char *name)
193 {
194     ElfW(Sym) *esym;
195     int sym_bind, sym_index, sym_type, esym_bind;
196     unsigned char sym_vis, esym_vis, new_vis;
197
198     sym_bind = ELFW(ST_BIND)(info);
199     sym_type = ELFW(ST_TYPE)(info);
200     sym_vis = ELFW(ST_VISIBILITY)(other);
201         
202     if (sym_bind != STB_LOCAL) {
203         /* we search global or weak symbols */
204         sym_index = find_elf_sym(s, name);
205         if (!sym_index)
206             goto do_def;
207         esym = &((ElfW(Sym) *)s->data)[sym_index];
208         if (esym->st_shndx != SHN_UNDEF) {
209             esym_bind = ELFW(ST_BIND)(esym->st_info);
210             /* propagate the most constraining visibility */
211             /* STV_DEFAULT(0)<STV_PROTECTED(3)<STV_HIDDEN(2)<STV_INTERNAL(1) */
212             esym_vis = ELFW(ST_VISIBILITY)(esym->st_other);
213             if (esym_vis == STV_DEFAULT) {
214                 new_vis = sym_vis;
215             } else if (sym_vis == STV_DEFAULT) {
216                 new_vis = esym_vis;
217             } else {
218                 new_vis = (esym_vis < sym_vis) ? esym_vis : sym_vis;
219             }
220             esym->st_other = (esym->st_other & ~ELFW(ST_VISIBILITY)(-1))
221                              | new_vis;
222             other = esym->st_other; /* in case we have to patch esym */
223             if (sh_num == SHN_UNDEF) {
224                 /* ignore adding of undefined symbol if the
225                    corresponding symbol is already defined */
226             } else if (sym_bind == STB_GLOBAL && esym_bind == STB_WEAK) {
227                 /* global overrides weak, so patch */
228                 goto do_patch;
229             } else if (sym_bind == STB_WEAK && esym_bind == STB_GLOBAL) {
230                 /* weak is ignored if already global */
231             } else if (sym_bind == STB_WEAK && esym_bind == STB_WEAK) {
232                 /* keep first-found weak definition, ignore subsequents */
233             } else if (sym_vis == STV_HIDDEN || sym_vis == STV_INTERNAL) {
234                 /* ignore hidden symbols after */
235             } else if (esym->st_shndx == SHN_COMMON
236                     && (sh_num < SHN_LORESERVE || sh_num == SHN_COMMON)) {
237                 /* gr: Happens with 'tcc ... -static tcctest.c' on e.g. Ubuntu 6.01
238                    No idea if this is the correct solution ... */
239                 goto do_patch;
240             } else if (s == tcc_state->dynsymtab_section) {
241                 /* we accept that two DLL define the same symbol */
242             } else {
243 #if 0
244                 printf("new_bind=%x new_shndx=%x new_vis=%x old_bind=%x old_shndx=%x old_vis=%x\n",
245                        sym_bind, sh_num, new_vis, esym_bind, esym->st_shndx, esym_vis);
246 #endif
247                 tcc_error_noabort("'%s' defined twice", name);
248             }
249         } else {
250         do_patch:
251             esym->st_info = ELFW(ST_INFO)(sym_bind, sym_type);
252             esym->st_shndx = sh_num;
253             new_undef_sym = 1;
254             esym->st_value = value;
255             esym->st_size = size;
256             esym->st_other = other;
257         }
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);
263     }
264     return sym_index;
265 }
266
267 /* put relocation */
268 ST_FUNC void put_elf_reloc(Section *symtab, Section *s, unsigned long offset,
269                           int type, int symbol)
270 {
271     char buf[256];
272     Section *sr;
273     ElfW_Rel *rel;
274
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;
286     }
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
293 }
294
295 /* put stab debug information */
296
297 ST_FUNC void put_stabs(const char *str, int type, int other, int desc,
298                       unsigned long value)
299 {
300     Stab_Sym *sym;
301
302     sym = section_ptr_add(stab_section, sizeof(Stab_Sym));
303     if (str) {
304         sym->n_strx = put_elf_str(stabstr_section, str);
305     } else {
306         sym->n_strx = 0;
307     }
308     sym->n_type = type;
309     sym->n_other = other;
310     sym->n_desc = desc;
311     sym->n_value = value;
312 }
313
314 ST_FUNC void put_stabs_r(const char *str, int type, int other, int desc, 
315                         unsigned long value, Section *sec, int sym_index)
316 {
317     put_stabs(str, type, other, desc, value);
318     put_elf_reloc(symtab_section, stab_section, 
319                   stab_section->data_offset - sizeof(unsigned int),
320                   R_DATA_32, sym_index);
321 }
322
323 ST_FUNC void put_stabn(int type, int other, int desc, int value)
324 {
325     put_stabs(NULL, type, other, desc, value);
326 }
327
328 ST_FUNC void put_stabd(int type, int other, int desc)
329 {
330     put_stabs(NULL, type, other, desc, 0);
331 }
332
333 /* In an ELF file symbol table, the local symbols must appear below
334    the global and weak ones. Since TCC cannot sort it while generating
335    the code, we must do it after. All the relocation tables are also
336    modified to take into account the symbol table sorting */
337 static void sort_syms(TCCState *s1, Section *s)
338 {
339     int *old_to_new_syms;
340     ElfW(Sym) *new_syms;
341     int nb_syms, i;
342     ElfW(Sym) *p, *q;
343     ElfW_Rel *rel, *rel_end;
344     Section *sr;
345     int type, sym_index;
346
347     nb_syms = s->data_offset / sizeof(ElfW(Sym));
348     new_syms = tcc_malloc(nb_syms * sizeof(ElfW(Sym)));
349     old_to_new_syms = tcc_malloc(nb_syms * sizeof(int));
350
351     /* first pass for local symbols */
352     p = (ElfW(Sym) *)s->data;
353     q = new_syms;
354     for(i = 0; i < nb_syms; i++) {
355         if (ELFW(ST_BIND)(p->st_info) == STB_LOCAL) {
356             old_to_new_syms[i] = q - new_syms;
357             *q++ = *p;
358         }
359         p++;
360     }
361     /* save the number of local symbols in section header */
362     s->sh_info = q - new_syms;
363
364     /* then second pass for non local symbols */
365     p = (ElfW(Sym) *)s->data;
366     for(i = 0; i < nb_syms; i++) {
367         if (ELFW(ST_BIND)(p->st_info) != STB_LOCAL) {
368             old_to_new_syms[i] = q - new_syms;
369             *q++ = *p;
370         }
371         p++;
372     }
373     
374     /* we copy the new symbols to the old */
375     memcpy(s->data, new_syms, nb_syms * sizeof(ElfW(Sym)));
376     tcc_free(new_syms);
377
378     /* now we modify all the relocations */
379     for(i = 1; i < s1->nb_sections; i++) {
380         sr = s1->sections[i];
381         if (sr->sh_type == SHT_RELX && sr->link == s) {
382             rel_end = (ElfW_Rel *)(sr->data + sr->data_offset);
383             for(rel = (ElfW_Rel *)sr->data;
384                 rel < rel_end;
385                 rel++) {
386                 sym_index = ELFW(R_SYM)(rel->r_info);
387                 type = ELFW(R_TYPE)(rel->r_info);
388                 sym_index = old_to_new_syms[sym_index];
389                 rel->r_info = ELFW(R_INFO)(sym_index, type);
390             }
391         }
392     }
393     
394     tcc_free(old_to_new_syms);
395 }
396
397 /* relocate common symbols in the .bss section */
398 ST_FUNC void relocate_common_syms(void)
399 {
400     ElfW(Sym) *sym, *sym_end;
401     unsigned long offset, align;
402     
403     sym_end = (ElfW(Sym) *)(symtab_section->data + symtab_section->data_offset);
404     for(sym = (ElfW(Sym) *)symtab_section->data + 1; 
405         sym < sym_end;
406         sym++) {
407         if (sym->st_shndx == SHN_COMMON) {
408             /* align symbol */
409             align = sym->st_value;
410             offset = bss_section->data_offset;
411             offset = (offset + align - 1) & -align;
412             sym->st_value = offset;
413             sym->st_shndx = bss_section->sh_num;
414             offset += sym->st_size;
415             bss_section->data_offset = offset;
416         }
417     }
418 }
419
420 /* relocate symbol table, resolve undefined symbols if do_resolve is
421    true and output error if undefined symbol. */
422 ST_FUNC void relocate_syms(TCCState *s1, int do_resolve)
423 {
424     ElfW(Sym) *sym, *esym, *sym_end;
425     int sym_bind, sh_num, sym_index;
426     const char *name;
427
428     sym_end = (ElfW(Sym) *)(symtab_section->data + symtab_section->data_offset);
429     for(sym = (ElfW(Sym) *)symtab_section->data + 1; 
430         sym < sym_end;
431         sym++) {
432         sh_num = sym->st_shndx;
433         if (sh_num == SHN_UNDEF) {
434             name = strtab_section->data + sym->st_name;
435             if (do_resolve) {
436 #if defined TCC_IS_NATIVE && !defined _WIN32
437                 void *addr;
438                 name = symtab_section->link->data + sym->st_name;
439                 addr = resolve_sym(s1, name);
440                 if (addr) {
441                     sym->st_value = (addr_t)addr;
442                     goto found;
443                 }
444 #endif
445             } else if (s1->dynsym) {
446                 /* if dynamic symbol exist, then use it */
447                 sym_index = find_elf_sym(s1->dynsym, name);
448                 if (sym_index) {
449                     esym = &((ElfW(Sym) *)s1->dynsym->data)[sym_index];
450                     sym->st_value = esym->st_value;
451                     goto found;
452                 }
453             }
454             /* XXX: _fp_hw seems to be part of the ABI, so we ignore
455                it */
456             if (!strcmp(name, "_fp_hw"))
457                 goto found;
458             /* only weak symbols are accepted to be undefined. Their
459                value is zero */
460             sym_bind = ELFW(ST_BIND)(sym->st_info);
461             if (sym_bind == STB_WEAK) {
462                 sym->st_value = 0;
463             } else {
464                 tcc_error_noabort("undefined symbol '%s'", name);
465             }
466         } else if (sh_num < SHN_LORESERVE) {
467             /* add section base */
468             sym->st_value += s1->sections[sym->st_shndx]->sh_addr;
469         }
470     found: ;
471     }
472 }
473
474 #ifdef TCC_HAS_RUNTIME_PLTGOT
475 #ifdef TCC_TARGET_X86_64
476 #define JMP_TABLE_ENTRY_SIZE 14
477 static addr_t add_jmp_table(TCCState *s1, addr_t val)
478 {
479     char *p = s1->runtime_plt_and_got + s1->runtime_plt_and_got_offset;
480     s1->runtime_plt_and_got_offset += JMP_TABLE_ENTRY_SIZE;
481     /* jmp *0x0(%rip) */
482     p[0] = 0xff;
483     p[1] = 0x25;
484     *(int *)(p + 2) = 0;
485     *(addr_t *)(p + 6) = val;
486     return (addr_t)p;
487 }
488
489 static addr_t add_got_table(TCCState *s1, addr_t val)
490 {
491     addr_t *p = (addr_t *)(s1->runtime_plt_and_got + s1->runtime_plt_and_got_offset);
492     s1->runtime_plt_and_got_offset += sizeof(addr_t);
493     *p = val;
494     return (addr_t)p;
495 }
496 #elif defined TCC_TARGET_ARM
497 #define JMP_TABLE_ENTRY_SIZE 8
498 static addr_t add_jmp_table(TCCState *s1, int val)
499 {
500     uint32_t *p = (uint32_t *)(s1->runtime_plt_and_got + s1->runtime_plt_and_got_offset);
501     s1->runtime_plt_and_got_offset += JMP_TABLE_ENTRY_SIZE;
502     /* ldr pc, [pc, #-4] */
503     p[0] = 0xE51FF004;
504     p[1] = val;
505     return (addr_t)p;
506 }
507 #endif
508 #endif /* def TCC_HAS_RUNTIME_PLTGOT */
509
510 /* relocate a given section (CPU dependent) */
511 ST_FUNC void relocate_section(TCCState *s1, Section *s)
512 {
513     Section *sr;
514     ElfW_Rel *rel, *rel_end, *qrel;
515     ElfW(Sym) *sym;
516     int type, sym_index;
517     unsigned char *ptr;
518     addr_t val, addr;
519 #if defined TCC_TARGET_I386 || defined TCC_TARGET_X86_64
520     int esym_index;
521 #endif
522
523     sr = s->reloc;
524     rel_end = (ElfW_Rel *)(sr->data + sr->data_offset);
525     qrel = (ElfW_Rel *)sr->data;
526     for(rel = qrel;
527         rel < rel_end;
528         rel++) {
529         ptr = s->data + rel->r_offset;
530
531         sym_index = ELFW(R_SYM)(rel->r_info);
532         sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
533         val = sym->st_value;
534 #ifdef TCC_TARGET_X86_64
535         val += rel->r_addend;
536 #endif
537         type = ELFW(R_TYPE)(rel->r_info);
538         addr = s->sh_addr + rel->r_offset;
539
540         /* CPU specific */
541         switch(type) {
542 #if defined(TCC_TARGET_I386)
543         case R_386_32:
544             if (s1->output_type == TCC_OUTPUT_DLL) {
545                 esym_index = s1->symtab_to_dynsym[sym_index];
546                 qrel->r_offset = rel->r_offset;
547                 if (esym_index) {
548                     qrel->r_info = ELFW(R_INFO)(esym_index, R_386_32);
549                     qrel++;
550                     break;
551                 } else {
552                     qrel->r_info = ELFW(R_INFO)(0, R_386_RELATIVE);
553                     qrel++;
554                 }
555             }
556             *(int *)ptr += val;
557             break;
558         case R_386_PC32:
559             if (s1->output_type == TCC_OUTPUT_DLL) {
560                 /* DLL relocation */
561                 esym_index = s1->symtab_to_dynsym[sym_index];
562                 if (esym_index) {
563                     qrel->r_offset = rel->r_offset;
564                     qrel->r_info = ELFW(R_INFO)(esym_index, R_386_PC32);
565                     qrel++;
566                     break;
567                 }
568             }
569             *(int *)ptr += val - addr;
570             break;
571         case R_386_PLT32:
572             *(int *)ptr += val - addr;
573             break;
574         case R_386_GLOB_DAT:
575         case R_386_JMP_SLOT:
576             *(int *)ptr = val;
577             break;
578         case R_386_GOTPC:
579             *(int *)ptr += s1->got->sh_addr - addr;
580             break;
581         case R_386_GOTOFF:
582             *(int *)ptr += val - s1->got->sh_addr;
583             break;
584         case R_386_GOT32:
585             /* we load the got offset */
586             *(int *)ptr += s1->sym_attrs[sym_index].got_offset;
587             break;
588         case R_386_16:
589             if (s1->output_format != TCC_OUTPUT_FORMAT_BINARY) {
590             output_file:
591                 tcc_error("can only produce 16-bit binary files");
592             }
593             *(short *)ptr += val;
594             break;
595         case R_386_PC16:
596             if (s1->output_format != TCC_OUTPUT_FORMAT_BINARY)
597                 goto output_file;
598             *(short *)ptr += val - addr;
599             break;
600 #elif defined(TCC_TARGET_ARM)
601         case R_ARM_PC24:
602         case R_ARM_CALL:
603         case R_ARM_JUMP24:
604         case R_ARM_PLT32:
605             {
606                 int x, is_thumb, is_call, h, blx_avail;
607                 x = (*(int *)ptr)&0xffffff;
608                 (*(int *)ptr) &= 0xff000000;
609                 if (x & 0x800000)
610                     x -= 0x1000000;
611                 x <<= 2;
612                 blx_avail = (TCC_ARM_VERSION >= 5);
613                 is_thumb = val & 1;
614                 is_call = (type == R_ARM_CALL);
615                 x += val - addr;
616                 h = x & 2;
617 #ifdef TCC_HAS_RUNTIME_PLTGOT
618                 if (s1->output_type == TCC_OUTPUT_MEMORY) {
619                     if ((x & 3) || x >= 0x2000000 || x < -0x2000000)
620                         if (!(x & 3) || !blx_avail || !is_call) {
621                             x += add_jmp_table(s1, val) - val; /* add veneer */
622                             is_thumb = 0; /* Veneer uses ARM instructions */
623                         }
624                 }
625 #endif
626                 if ((x & 3) || x >= 0x2000000 || x < -0x2000000)
627                     if (!(x & 3) || !blx_avail || !is_call)
628                         tcc_error("can't relocate value at %x",addr);
629                 x >>= 2;
630                 x &= 0xffffff;
631                 /* Only reached if blx is avail and it is a call */
632                 if (is_thumb) {
633                     x |= h << 24;
634                     (*(int *)ptr) = 0xfa << 24; /* bl -> blx */
635                 }
636                 (*(int *)ptr) |= x;
637             }
638             break;
639         /* Since these relocations only concern Thumb-2 and blx instruction was
640            introduced before Thumb-2, we can assume blx is available and not
641            guard its use */
642         case R_ARM_THM_CALL:
643         case R_ARM_THM_JUMP24:
644             {
645                 int x, hi, lo, s, j1, j2, i1, i2, imm10, imm11;
646                 int to_thumb, is_call, to_plt, blx_bit = 1 << 12;
647                 Section *plt;
648
649                 /* weak reference */
650                 if (sym->st_shndx == SHN_UNDEF &&
651                     ELFW(ST_BIND)(sym->st_info) == STB_WEAK)
652                     break;
653
654                 /* Get initial offset */
655                 hi = (*(uint16_t *)ptr);
656                 lo = (*(uint16_t *)(ptr+2));
657                 s = (hi >> 10) & 1;
658                 j1 = (lo >> 13) & 1;
659                 j2 = (lo >> 11) & 1;
660                 i1 = (j1 ^ s) ^ 1;
661                 i2 = (j2 ^ s) ^ 1;
662                 imm10 = hi & 0x3ff;
663                 imm11 = lo & 0x7ff;
664                 x = (s << 24) | (i1 << 23) | (i2 << 22) |
665                     (imm10 << 12) | (imm11 << 1);
666                 if (x & 0x01000000)
667                     x -= 0x02000000;
668
669                 /* Relocation infos */
670                 to_thumb = val & 1;
671                 plt = s1->plt;
672                 to_plt = (val >= plt->sh_addr) &&
673                          (val < plt->sh_addr + plt->data_offset);
674                 is_call = (type == R_ARM_THM_CALL);
675
676                 /* Compute final offset */
677                 if (to_plt && !is_call) /* Point to 1st instr of Thumb stub */
678                     x -= 4;
679                 x += val - addr;
680                 if (!to_thumb && is_call) {
681                     blx_bit = 0; /* bl -> blx */
682                     x = (x + 3) & -4; /* Compute offset from aligned PC */
683                 }
684
685                 /* Check that relocation is possible
686                    * offset must not be out of range
687                    * if target is to be entered in arm mode:
688                      - bit 1 must not set
689                      - instruction must be a call (bl) or a jump to PLT */
690                 if (!to_thumb || x >= 0x1000000 || x < -0x1000000)
691                     if (to_thumb || (val & 2) || (!is_call && !to_plt))
692                         tcc_error("can't relocate value at %x",addr);
693
694                 /* Compute and store final offset */
695                 s = (x >> 24) & 1;
696                 i1 = (x >> 23) & 1;
697                 i2 = (x >> 22) & 1;
698                 j1 = s ^ (i1 ^ 1);
699                 j2 = s ^ (i2 ^ 1);
700                 imm10 = (x >> 12) & 0x3ff;
701                 imm11 = (x >> 1) & 0x7ff;
702                 (*(uint16_t *)ptr) = (uint16_t) ((hi & 0xf800) |
703                                      (s << 10) | imm10);
704                 (*(uint16_t *)(ptr+2)) = (uint16_t) ((lo & 0xc000) |
705                                 (j1 << 13) | blx_bit | (j2 << 11) |
706                                 imm11);
707             }
708             break;
709         case R_ARM_MOVT_ABS:
710         case R_ARM_MOVW_ABS_NC:
711             {
712                 int x, imm4, imm12;
713                 if (type == R_ARM_MOVT_ABS)
714                     val >>= 16;
715                 imm12 = val & 0xfff;
716                 imm4 = (val >> 12) & 0xf;
717                 x = (imm4 << 16) | imm12;
718                 if (type == R_ARM_THM_MOVT_ABS)
719                     *(int *)ptr |= x;
720                 else
721                     *(int *)ptr += x;
722             }
723             break;
724         case R_ARM_THM_MOVT_ABS:
725         case R_ARM_THM_MOVW_ABS_NC:
726             {
727                 int x, i, imm4, imm3, imm8;
728                 if (type == R_ARM_THM_MOVT_ABS)
729                     val >>= 16;
730                 imm8 = val & 0xff;
731                 imm3 = (val >> 8) & 0x7;
732                 i = (val >> 11) & 1;
733                 imm4 = (val >> 12) & 0xf;
734                 x = (imm3 << 28) | (imm8 << 16) | (i << 10) | imm4;
735                 if (type == R_ARM_THM_MOVT_ABS)
736                     *(int *)ptr |= x;
737                 else
738                     *(int *)ptr += x;
739             }
740             break;
741         case R_ARM_PREL31:
742             {
743                 int x;
744                 x = (*(int *)ptr) & 0x7fffffff;
745                 (*(int *)ptr) &= 0x80000000;
746                 x = (x * 2) / 2;
747                 x += val - addr;
748                 if((x^(x>>1))&0x40000000)
749                     tcc_error("can't relocate value at %x",addr);
750                 (*(int *)ptr) |= x & 0x7fffffff;
751             }
752         case R_ARM_ABS32:
753             *(int *)ptr += val;
754             break;
755         case R_ARM_REL32:
756             *(int *)ptr += val - addr;
757             break;
758         case R_ARM_BASE_PREL:
759             *(int *)ptr += s1->got->sh_addr - addr;
760             break;
761         case R_ARM_GOTOFF32:
762             *(int *)ptr += val - s1->got->sh_addr;
763             break;
764         case R_ARM_GOT_BREL:
765             /* we load the got offset */
766             *(int *)ptr += s1->sym_attrs[sym_index].got_offset;
767             break;
768         case R_ARM_COPY:
769             break;
770         case R_ARM_V4BX:
771             /* trade Thumb support for ARMv4 support */
772             if ((0x0ffffff0 & *(int*)ptr) == 0x012FFF10)
773                 *(int*)ptr ^= 0xE12FFF10 ^ 0xE1A0F000; /* BX Rm -> MOV PC, Rm */
774             break;
775         default:
776             fprintf(stderr,"FIXME: handle reloc type %x at %x [%p] to %x\n",
777                 type, (unsigned)addr, ptr, (unsigned)val);
778             break;
779 #elif defined(TCC_TARGET_C67)
780         case R_C60_32:
781             *(int *)ptr += val;
782             break;
783         case R_C60LO16:
784             {
785                 uint32_t orig;
786                 
787                 /* put the low 16 bits of the absolute address */
788                 // add to what is already there
789                 
790                 orig  =   ((*(int *)(ptr  )) >> 7) & 0xffff;
791                 orig |=  (((*(int *)(ptr+4)) >> 7) & 0xffff) << 16;
792                 
793                 //patch both at once - assumes always in pairs Low - High
794                 
795                 *(int *) ptr    = (*(int *) ptr    & (~(0xffff << 7)) ) |  (((val+orig)      & 0xffff) << 7);
796                 *(int *)(ptr+4) = (*(int *)(ptr+4) & (~(0xffff << 7)) ) | ((((val+orig)>>16) & 0xffff) << 7);
797             }
798             break;
799         case R_C60HI16:
800             break;
801         default:
802             fprintf(stderr,"FIXME: handle reloc type %x at %x [%p] to %x\n",
803                 type, (unsigned)addr, ptr, (unsigned)val);
804             break;
805 #elif defined(TCC_TARGET_X86_64)
806         case R_X86_64_64:
807             if (s1->output_type == TCC_OUTPUT_DLL) {
808                 qrel->r_info = ELFW(R_INFO)(0, R_X86_64_RELATIVE);
809                 qrel->r_addend = *(long long *)ptr + val;
810                 qrel++;
811             }
812             *(long long *)ptr += val;
813             break;
814         case R_X86_64_32:
815         case R_X86_64_32S:
816             if (s1->output_type == TCC_OUTPUT_DLL) {
817                 /* XXX: this logic may depend on TCC's codegen
818                    now TCC uses R_X86_64_32 even for a 64bit pointer */
819                 qrel->r_info = ELFW(R_INFO)(0, R_X86_64_RELATIVE);
820                 qrel->r_addend = *(int *)ptr + val;
821                 qrel++;
822             }
823             *(int *)ptr += val;
824             break;
825
826         case R_X86_64_PC32:
827             if (s1->output_type == TCC_OUTPUT_DLL) {
828                 /* DLL relocation */
829                 esym_index = s1->symtab_to_dynsym[sym_index];
830                 if (esym_index) {
831                     qrel->r_offset = rel->r_offset;
832                     qrel->r_info = ELFW(R_INFO)(esym_index, R_X86_64_PC32);
833                     qrel->r_addend = *(int *)ptr;
834                     qrel++;
835                     break;
836                 }
837             }
838             /* fall through */
839         case R_X86_64_PLT32: {
840             long long diff;
841             diff = (long long)val - addr;
842             if (diff <= -2147483647 || diff > 2147483647) {
843 #ifdef TCC_HAS_RUNTIME_PLTGOT
844                 /* XXX: naive support for over 32bit jump */
845                 if (s1->output_type == TCC_OUTPUT_MEMORY) {
846                     val = (add_jmp_table(s1, val - rel->r_addend) +
847                            rel->r_addend);
848                     diff = val - addr;
849                 }
850 #endif
851                 if (diff <= -2147483647 || diff > 2147483647) {
852                     tcc_error("internal error: relocation failed");
853                 }
854             }
855             *(int *)ptr += diff;
856         }
857             break;
858         case R_X86_64_GLOB_DAT:
859         case R_X86_64_JUMP_SLOT:
860             /* They don't need addend */
861             *(int *)ptr = val - rel->r_addend;
862             break;
863         case R_X86_64_GOTPCREL:
864 #ifdef TCC_HAS_RUNTIME_PLTGOT
865             if (s1->output_type == TCC_OUTPUT_MEMORY) {
866                 val = add_got_table(s1, val - rel->r_addend) + rel->r_addend;
867                 *(int *)ptr += val - addr;
868                 break;
869             }
870 #endif
871             *(int *)ptr += (s1->got->sh_addr - addr +
872                             s1->sym_attrs[sym_index].got_offset - 4);
873             break;
874         case R_X86_64_GOTTPOFF:
875             *(int *)ptr += val - s1->got->sh_addr;
876             break;
877         case R_X86_64_GOT32:
878             /* we load the got offset */
879             *(int *)ptr += s1->sym_attrs[sym_index].got_offset;
880             break;
881 #else
882 #error unsupported processor
883 #endif
884         }
885     }
886     /* if the relocation is allocated, we change its symbol table */
887     if (sr->sh_flags & SHF_ALLOC)
888         sr->link = s1->dynsym;
889 }
890
891 /* relocate relocation table in 'sr' */
892 static void relocate_rel(TCCState *s1, Section *sr)
893 {
894     Section *s;
895     ElfW_Rel *rel, *rel_end;
896     
897     s = s1->sections[sr->sh_info];
898     rel_end = (ElfW_Rel *)(sr->data + sr->data_offset);
899     for(rel = (ElfW_Rel *)sr->data;
900         rel < rel_end;
901         rel++) {
902         rel->r_offset += s->sh_addr;
903     }
904 }
905
906 /* count the number of dynamic relocations so that we can reserve
907    their space */
908 static int prepare_dynamic_rel(TCCState *s1, Section *sr)
909 {
910     ElfW_Rel *rel, *rel_end;
911     int sym_index, esym_index, type, count;
912
913     count = 0;
914     rel_end = (ElfW_Rel *)(sr->data + sr->data_offset);
915     for(rel = (ElfW_Rel *)sr->data; rel < rel_end; rel++) {
916         sym_index = ELFW(R_SYM)(rel->r_info);
917         type = ELFW(R_TYPE)(rel->r_info);
918         switch(type) {
919 #if defined(TCC_TARGET_I386)
920         case R_386_32:
921 #elif defined(TCC_TARGET_X86_64)
922         case R_X86_64_32:
923         case R_X86_64_32S:
924         case R_X86_64_64:
925 #endif
926             count++;
927             break;
928 #if defined(TCC_TARGET_I386)
929         case R_386_PC32:
930 #elif defined(TCC_TARGET_X86_64)
931         case R_X86_64_PC32:
932 #endif
933             esym_index = s1->symtab_to_dynsym[sym_index];
934             if (esym_index)
935                 count++;
936             break;
937         default:
938             break;
939         }
940     }
941     if (count) {
942         /* allocate the section */
943         sr->sh_flags |= SHF_ALLOC;
944         sr->sh_size = count * sizeof(ElfW_Rel);
945     }
946     return count;
947 }
948
949 static struct sym_attr *alloc_sym_attr(TCCState *s1, int index)
950 {
951     int n;
952     struct sym_attr *tab;
953
954     if (index >= s1->nb_sym_attrs) {
955         /* find immediately bigger power of 2 and reallocate array */
956         n = 1;
957         while (index >= n)
958             n *= 2;
959         tab = tcc_realloc(s1->sym_attrs, n * sizeof(*s1->sym_attrs));
960         s1->sym_attrs = tab;
961         memset(s1->sym_attrs + s1->nb_sym_attrs, 0,
962                (n - s1->nb_sym_attrs) * sizeof(*s1->sym_attrs));
963         s1->nb_sym_attrs = n;
964     }
965     return &s1->sym_attrs[index];
966 }
967
968 /* XXX: suppress that */
969 static void put32(unsigned char *p, uint32_t val)
970 {
971     p[0] = val;
972     p[1] = val >> 8;
973     p[2] = val >> 16;
974     p[3] = val >> 24;
975 }
976
977 #if defined(TCC_TARGET_I386) || defined(TCC_TARGET_ARM) || \
978     defined(TCC_TARGET_X86_64)
979 static uint32_t get32(unsigned char *p)
980 {
981     return p[0] | (p[1] << 8) | (p[2] << 16) | (p[3] << 24);
982 }
983 #endif
984
985 static void build_got(TCCState *s1)
986 {
987     unsigned char *ptr;
988
989     /* if no got, then create it */
990     s1->got = new_section(s1, ".got", SHT_PROGBITS, SHF_ALLOC | SHF_WRITE);
991     s1->got->sh_entsize = 4;
992     add_elf_sym(symtab_section, 0, 4, ELFW(ST_INFO)(STB_GLOBAL, STT_OBJECT), 
993                 0, s1->got->sh_num, "_GLOBAL_OFFSET_TABLE_");
994     ptr = section_ptr_add(s1->got, 3 * PTR_SIZE);
995 #if PTR_SIZE == 4
996     /* keep space for _DYNAMIC pointer, if present */
997     put32(ptr, 0);
998     /* two dummy got entries */
999     put32(ptr + 4, 0);
1000     put32(ptr + 8, 0);
1001 #else
1002     /* keep space for _DYNAMIC pointer, if present */
1003     put32(ptr, 0);
1004     put32(ptr + 4, 0);
1005     /* two dummy got entries */
1006     put32(ptr + 8, 0);
1007     put32(ptr + 12, 0);
1008     put32(ptr + 16, 0);
1009     put32(ptr + 20, 0);
1010 #endif
1011 }
1012
1013 /* put a got entry corresponding to a symbol in symtab_section. 'size'
1014    and 'info' can be modifed if more precise info comes from the DLL */
1015 static void put_got_entry(TCCState *s1,
1016                           int reloc_type, unsigned long size, int info, 
1017                           int sym_index)
1018 {
1019     int index;
1020     const char *name;
1021     ElfW(Sym) *sym;
1022     unsigned long offset;
1023     int *ptr;
1024
1025     if (!s1->got)
1026         build_got(s1);
1027
1028     /* if a got entry already exists for that symbol, no need to add one */
1029     if (sym_index < s1->nb_sym_attrs &&
1030         s1->sym_attrs[sym_index].got_offset)
1031         return;
1032
1033     alloc_sym_attr(s1, sym_index)->got_offset = s1->got->data_offset;
1034
1035     if (s1->dynsym) {
1036         sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
1037         name = symtab_section->link->data + sym->st_name;
1038         offset = sym->st_value;
1039 #if defined(TCC_TARGET_I386) || defined(TCC_TARGET_X86_64)
1040         if (reloc_type ==
1041 #ifdef TCC_TARGET_X86_64
1042             R_X86_64_JUMP_SLOT
1043 #else
1044             R_386_JMP_SLOT
1045 #endif
1046             ) {
1047             Section *plt;
1048             uint8_t *p;
1049             int modrm;
1050
1051 #if defined(TCC_OUTPUT_DLL_WITH_PLT)
1052             modrm = 0x25;
1053 #else
1054             /* if we build a DLL, we add a %ebx offset */
1055             if (s1->output_type == TCC_OUTPUT_DLL)
1056                 modrm = 0xa3;
1057             else
1058                 modrm = 0x25;
1059 #endif
1060
1061             /* add a PLT entry */
1062             plt = s1->plt;
1063             if (plt->data_offset == 0) {
1064                 /* first plt entry */
1065                 p = section_ptr_add(plt, 16);
1066                 p[0] = 0xff; /* pushl got + PTR_SIZE */
1067                 p[1] = modrm + 0x10;
1068                 put32(p + 2, PTR_SIZE);
1069                 p[6] = 0xff; /* jmp *(got + PTR_SIZE * 2) */
1070                 p[7] = modrm;
1071                 put32(p + 8, PTR_SIZE * 2);
1072             }
1073
1074             p = section_ptr_add(plt, 16);
1075             p[0] = 0xff; /* jmp *(got + x) */
1076             p[1] = modrm;
1077             put32(p + 2, s1->got->data_offset);
1078             p[6] = 0x68; /* push $xxx */
1079             put32(p + 7, (plt->data_offset - 32) >> 1);
1080             p[11] = 0xe9; /* jmp plt_start */
1081             put32(p + 12, -(plt->data_offset));
1082
1083             /* the symbol is modified so that it will be relocated to
1084                the PLT */
1085 #if !defined(TCC_OUTPUT_DLL_WITH_PLT)
1086             if (s1->output_type == TCC_OUTPUT_EXE)
1087 #endif
1088                 offset = plt->data_offset - 16;
1089         }
1090 #elif defined(TCC_TARGET_ARM)
1091         if (reloc_type == R_ARM_JUMP_SLOT) {
1092             Section *plt;
1093             uint8_t *p;
1094             
1095             /* if we build a DLL, we add a %ebx offset */
1096             if (s1->output_type == TCC_OUTPUT_DLL)
1097                 tcc_error("DLLs unimplemented!");
1098
1099             /* add a PLT entry */
1100             plt = s1->plt;
1101             if (plt->data_offset == 0) {
1102                 /* first plt entry */
1103                 p = section_ptr_add(plt, 16);
1104                 put32(p     , 0xe52de004);
1105                 put32(p +  4, 0xe59fe010);
1106                 put32(p +  8, 0xe08fe00e);
1107                 put32(p + 12, 0xe5bef008);
1108             }
1109
1110             if (s1->sym_attrs[sym_index].plt_thumb_stub) {
1111                 p = section_ptr_add(plt, 20);
1112                 put32(p  , 0x4778); // bx pc
1113                 put32(p+2, 0x46c0); // nop
1114                 p += 4;
1115             } else
1116                 p = section_ptr_add(plt, 16);
1117             put32(p  , 0xe59fc004); // ldr ip, [pc, #4] // offset in GOT
1118             put32(p+4, 0xe08fc00c); // add ip, pc, ip // absolute address or offset
1119             put32(p+8, 0xe59cf000); // ldr pc, [ip] // load absolute address or load offset
1120             put32(p+12, s1->got->data_offset);
1121
1122             /* the symbol is modified so that it will be relocated to
1123                the PLT */
1124             if (s1->output_type == TCC_OUTPUT_EXE)
1125                 offset = plt->data_offset - 16;
1126         }
1127 #elif defined(TCC_TARGET_C67)
1128         tcc_error("C67 got not implemented");
1129 #else
1130 #error unsupported CPU
1131 #endif
1132         index = put_elf_sym(s1->dynsym, offset, 
1133                             size, info, 0, sym->st_shndx, name);
1134         /* put a got entry */
1135         put_elf_reloc(s1->dynsym, s1->got, 
1136                       s1->got->data_offset, 
1137                       reloc_type, index);
1138     }
1139     ptr = section_ptr_add(s1->got, PTR_SIZE);
1140     *ptr = 0;
1141 }
1142
1143 /* build GOT and PLT entries */
1144 ST_FUNC void build_got_entries(TCCState *s1)
1145 {
1146     Section *s;
1147     ElfW_Rel *rel, *rel_end;
1148     ElfW(Sym) *sym;
1149     int i, type, reloc_type, sym_index;
1150
1151     for(i = 1; i < s1->nb_sections; i++) {
1152         s = s1->sections[i];
1153         if (s->sh_type != SHT_RELX)
1154             continue;
1155         /* no need to handle got relocations */
1156         if (s->link != symtab_section)
1157             continue;
1158         rel_end = (ElfW_Rel *)(s->data + s->data_offset);
1159         for(rel = (ElfW_Rel *)s->data;
1160             rel < rel_end;
1161             rel++) {
1162             type = ELFW(R_TYPE)(rel->r_info);
1163             switch(type) {
1164 #if defined(TCC_TARGET_I386)
1165             case R_386_GOT32:
1166             case R_386_GOTOFF:
1167             case R_386_GOTPC:
1168             case R_386_PLT32:
1169                 if (!s1->got)
1170                     build_got(s1);
1171                 if (type == R_386_GOT32 || type == R_386_PLT32) {
1172                     sym_index = ELFW(R_SYM)(rel->r_info);
1173                     sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
1174                     /* look at the symbol got offset. If none, then add one */
1175                     if (type == R_386_GOT32)
1176                         reloc_type = R_386_GLOB_DAT;
1177                     else
1178                         reloc_type = R_386_JMP_SLOT;
1179                     put_got_entry(s1, reloc_type, sym->st_size, sym->st_info, 
1180                                   sym_index);
1181                 }
1182                 break;
1183 #elif defined(TCC_TARGET_ARM)
1184             case R_ARM_GOT_BREL:
1185             case R_ARM_GOTOFF32:
1186             case R_ARM_BASE_PREL:
1187             case R_ARM_PLT32:
1188                 if (!s1->got)
1189                     build_got(s1);
1190                 if (type == R_ARM_GOT_BREL || type == R_ARM_PLT32) {
1191                     sym_index = ELFW(R_SYM)(rel->r_info);
1192                     sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
1193                     /* look at the symbol got offset. If none, then add one */
1194                     if (type == R_ARM_GOT_BREL)
1195                         reloc_type = R_ARM_GLOB_DAT;
1196                     else
1197                         reloc_type = R_ARM_JUMP_SLOT;
1198                     put_got_entry(s1, reloc_type, sym->st_size, sym->st_info, 
1199                                   sym_index);
1200                 }
1201                 break;
1202 #elif defined(TCC_TARGET_C67)
1203             case R_C60_GOT32:
1204             case R_C60_GOTOFF:
1205             case R_C60_GOTPC:
1206             case R_C60_PLT32:
1207                 if (!s1->got)
1208                     build_got(s1);
1209                 if (type == R_C60_GOT32 || type == R_C60_PLT32) {
1210                     sym_index = ELFW(R_SYM)(rel->r_info);
1211                     sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
1212                     /* look at the symbol got offset. If none, then add one */
1213                     if (type == R_C60_GOT32)
1214                         reloc_type = R_C60_GLOB_DAT;
1215                     else
1216                         reloc_type = R_C60_JMP_SLOT;
1217                     put_got_entry(s1, reloc_type, sym->st_size, sym->st_info, 
1218                                   sym_index);
1219                 }
1220                 break;
1221 #elif defined(TCC_TARGET_X86_64)
1222             case R_X86_64_GOT32:
1223             case R_X86_64_GOTTPOFF:
1224             case R_X86_64_GOTPCREL:
1225             case R_X86_64_PLT32:
1226                 if (!s1->got)
1227                     build_got(s1);
1228                 if (type == R_X86_64_GOT32 || type == R_X86_64_GOTPCREL ||
1229                     type == R_X86_64_PLT32) {
1230                     sym_index = ELFW(R_SYM)(rel->r_info);
1231                     sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
1232                     /* look at the symbol got offset. If none, then add one */
1233                     if (type == R_X86_64_GOT32 || type == R_X86_64_GOTPCREL)
1234                         reloc_type = R_X86_64_GLOB_DAT;
1235                     else
1236                         reloc_type = R_X86_64_JUMP_SLOT;
1237                     put_got_entry(s1, reloc_type, sym->st_size, sym->st_info, 
1238                                   sym_index);
1239                 }
1240                 break;
1241 #else
1242 #error unsupported CPU
1243 #endif
1244             default:
1245                 break;
1246             }
1247         }
1248     }
1249 }
1250
1251 ST_FUNC Section *new_symtab(TCCState *s1,
1252                            const char *symtab_name, int sh_type, int sh_flags,
1253                            const char *strtab_name, 
1254                            const char *hash_name, int hash_sh_flags)
1255 {
1256     Section *symtab, *strtab, *hash;
1257     int *ptr, nb_buckets;
1258
1259     symtab = new_section(s1, symtab_name, sh_type, sh_flags);
1260     symtab->sh_entsize = sizeof(ElfW(Sym));
1261     strtab = new_section(s1, strtab_name, SHT_STRTAB, sh_flags);
1262     put_elf_str(strtab, "");
1263     symtab->link = strtab;
1264     put_elf_sym(symtab, 0, 0, 0, 0, 0, NULL);
1265     
1266     nb_buckets = 1;
1267
1268     hash = new_section(s1, hash_name, SHT_HASH, hash_sh_flags);
1269     hash->sh_entsize = sizeof(int);
1270     symtab->hash = hash;
1271     hash->link = symtab;
1272
1273     ptr = section_ptr_add(hash, (2 + nb_buckets + 1) * sizeof(int));
1274     ptr[0] = nb_buckets;
1275     ptr[1] = 1;
1276     memset(ptr + 2, 0, (nb_buckets + 1) * sizeof(int));
1277     return symtab;
1278 }
1279
1280 /* put dynamic tag */
1281 static void put_dt(Section *dynamic, int dt, addr_t val)
1282 {
1283     ElfW(Dyn) *dyn;
1284     dyn = section_ptr_add(dynamic, sizeof(ElfW(Dyn)));
1285     dyn->d_tag = dt;
1286     dyn->d_un.d_val = val;
1287 }
1288
1289 static void add_init_array_defines(TCCState *s1, const char *section_name)
1290 {
1291     Section *s;
1292     long end_offset;
1293     char sym_start[1024];
1294     char sym_end[1024];
1295     
1296     snprintf(sym_start, sizeof(sym_start), "__%s_start", section_name + 1);
1297     snprintf(sym_end, sizeof(sym_end), "__%s_end", section_name + 1);
1298
1299     s = find_section(s1, section_name);
1300     if (!s) {
1301         end_offset = 0;
1302         s = data_section;
1303     } else {
1304         end_offset = s->data_offset;
1305     }
1306
1307     add_elf_sym(symtab_section, 
1308                 0, 0,
1309                 ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
1310                 s->sh_num, sym_start);
1311     add_elf_sym(symtab_section, 
1312                 end_offset, 0,
1313                 ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
1314                 s->sh_num, sym_end);
1315 }
1316
1317 ST_FUNC void tcc_add_bcheck(TCCState *s1)
1318 {
1319 #ifdef CONFIG_TCC_BCHECK
1320     unsigned long *ptr;
1321     Section *init_section;
1322     unsigned char *pinit;
1323     int sym_index;
1324
1325     if (0 == s1->do_bounds_check)
1326         return;
1327
1328     /* XXX: add an object file to do that */
1329     ptr = section_ptr_add(bounds_section, sizeof(unsigned long));
1330     *ptr = 0;
1331     add_elf_sym(symtab_section, 0, 0,
1332                 ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
1333                 bounds_section->sh_num, "__bounds_start");
1334 #ifdef TCC_TARGET_I386
1335     if (s1->output_type != TCC_OUTPUT_MEMORY) {
1336         /* add 'call __bound_init()' in .init section */
1337         init_section = find_section(s1, ".init");
1338         pinit = section_ptr_add(init_section, 5);
1339         pinit[0] = 0xe8;
1340         put32(pinit + 1, -4);
1341         sym_index = find_elf_sym(symtab_section, "__bound_init");
1342         put_elf_reloc(symtab_section, init_section,
1343                       init_section->data_offset - 4, R_386_PC32, sym_index);
1344     }
1345 #endif
1346 #endif
1347 }
1348
1349 static inline int tcc_add_support(TCCState *s1, const char *filename)
1350 {
1351     char buf[1024];
1352     snprintf(buf, sizeof(buf), "%s/%s", s1->tcc_lib_path, filename);
1353     return tcc_add_file(s1, buf);
1354 }
1355
1356 /* add tcc runtime libraries */
1357 ST_FUNC void tcc_add_runtime(TCCState *s1)
1358 {
1359     tcc_add_bcheck(s1);
1360
1361     /* add libc */
1362     if (!s1->nostdlib) {
1363         tcc_add_library(s1, "c");
1364 #ifdef CONFIG_USE_LIBGCC
1365         tcc_add_file(s1, TCC_LIBGCC);
1366 #elif !defined WITHOUT_LIBTCC
1367         tcc_add_support(s1, "libtcc1.a");
1368 #endif
1369         /* add crt end if not memory output */
1370         if (s1->output_type != TCC_OUTPUT_MEMORY)
1371             tcc_add_crt(s1, "crtn.o");
1372     }
1373 }
1374
1375 /* add various standard linker symbols (must be done after the
1376    sections are filled (for example after allocating common
1377    symbols)) */
1378 ST_FUNC void tcc_add_linker_symbols(TCCState *s1)
1379 {
1380     char buf[1024];
1381     int i;
1382     Section *s;
1383
1384     add_elf_sym(symtab_section, 
1385                 text_section->data_offset, 0,
1386                 ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
1387                 text_section->sh_num, "_etext");
1388     add_elf_sym(symtab_section, 
1389                 data_section->data_offset, 0,
1390                 ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
1391                 data_section->sh_num, "_edata");
1392     add_elf_sym(symtab_section, 
1393                 bss_section->data_offset, 0,
1394                 ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
1395                 bss_section->sh_num, "_end");
1396     /* horrible new standard ldscript defines */
1397     add_init_array_defines(s1, ".preinit_array");
1398     add_init_array_defines(s1, ".init_array");
1399     add_init_array_defines(s1, ".fini_array");
1400     
1401     /* add start and stop symbols for sections whose name can be
1402        expressed in C */
1403     for(i = 1; i < s1->nb_sections; i++) {
1404         s = s1->sections[i];
1405         if (s->sh_type == SHT_PROGBITS &&
1406             (s->sh_flags & SHF_ALLOC)) {
1407             const char *p;
1408             int ch;
1409
1410             /* check if section name can be expressed in C */
1411             p = s->name;
1412             for(;;) {
1413                 ch = *p;
1414                 if (!ch)
1415                     break;
1416                 if (!isid(ch) && !isnum(ch))
1417                     goto next_sec;
1418                 p++;
1419             }
1420             snprintf(buf, sizeof(buf), "__start_%s", s->name);
1421             add_elf_sym(symtab_section, 
1422                         0, 0,
1423                         ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
1424                         s->sh_num, buf);
1425             snprintf(buf, sizeof(buf), "__stop_%s", s->name);
1426             add_elf_sym(symtab_section,
1427                         s->data_offset, 0,
1428                         ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
1429                         s->sh_num, buf);
1430         }
1431     next_sec: ;
1432     }
1433 }
1434
1435 static void tcc_output_binary(TCCState *s1, FILE *f,
1436                               const int *section_order)
1437 {
1438     Section *s;
1439     int i, offset, size;
1440
1441     offset = 0;
1442     for(i=1;i<s1->nb_sections;i++) {
1443         s = s1->sections[section_order[i]];
1444         if (s->sh_type != SHT_NOBITS &&
1445             (s->sh_flags & SHF_ALLOC)) {
1446             while (offset < s->sh_offset) {
1447                 fputc(0, f);
1448                 offset++;
1449             }
1450             size = s->sh_size;
1451             fwrite(s->data, 1, size, f);
1452             offset += size;
1453         }
1454     }
1455 }
1456
1457 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
1458 #define HAVE_PHDR       1
1459 #define EXTRA_RELITEMS  14
1460
1461 /* move the relocation value from .dynsym to .got */
1462 void patch_dynsym_undef(TCCState *s1, Section *s)
1463 {
1464     uint32_t *gotd = (void *)s1->got->data;
1465     ElfW(Sym) *sym, *sym_end;
1466
1467     gotd += 3;  // dummy entries in .got
1468     /* relocate symbols in .dynsym */
1469     sym_end = (ElfW(Sym) *)(s->data + s->data_offset);
1470     for (sym = (ElfW(Sym) *)s->data + 1; sym < sym_end; sym++) {
1471         if (sym->st_shndx == SHN_UNDEF) {
1472             *gotd++ = sym->st_value + 6; // XXX 6 is magic ?
1473             sym->st_value = 0;
1474         }
1475     }
1476 }
1477 #else
1478 #define HAVE_PHDR       0
1479 #define EXTRA_RELITEMS  9
1480
1481 /* zero plt offsets of weak symbols in .dynsym */
1482 void patch_dynsym_undef(TCCState *s1, Section *s)
1483 {
1484     ElfW(Sym) *sym, *sym_end;
1485
1486     sym_end = (ElfW(Sym) *)(s->data + s->data_offset);
1487     for (sym = (ElfW(Sym) *)s->data + 1; sym < sym_end; sym++)
1488         if (sym->st_shndx == SHN_UNDEF && ELFW(ST_BIND)(sym->st_info) == STB_WEAK)
1489             sym->st_value = 0;
1490 }
1491 #endif
1492
1493 ST_FUNC void fill_got_entry(TCCState *s1, ElfW_Rel *rel)
1494 {
1495         int sym_index = ELFW(R_SYM) (rel->r_info);
1496         ElfW(Sym) *sym = &((ElfW(Sym) *) symtab_section->data)[sym_index];
1497         unsigned long offset;
1498
1499         if (sym_index >= s1->nb_sym_attrs)
1500                 return;
1501         offset = s1->sym_attrs[sym_index].got_offset;
1502         section_reserve(s1->got, offset + PTR_SIZE);
1503 #ifdef TCC_TARGET_X86_64
1504         /* only works for x86-64 */
1505         put32(s1->got->data + offset + 4, sym->st_value >> 32);
1506 #endif
1507         put32(s1->got->data + offset, sym->st_value & 0xffffffff);
1508 }
1509
1510 ST_FUNC void fill_got(TCCState *s1)
1511 {
1512         Section *s;
1513         ElfW_Rel *rel, *rel_end;
1514         int i;
1515
1516         for(i = 1; i < s1->nb_sections; i++) {
1517                 s = s1->sections[i];
1518                 if (s->sh_type != SHT_RELX)
1519                         continue;
1520                 /* no need to handle got relocations */
1521                 if (s->link != symtab_section)
1522                         continue;
1523                 rel_end = (ElfW_Rel *) (s->data + s->data_offset);
1524                 for(rel = (ElfW_Rel *) s->data; rel < rel_end; rel++) {
1525                         switch (ELFW(R_TYPE) (rel->r_info)) {
1526                         case R_X86_64_GOT32:
1527                         case R_X86_64_GOTPCREL:
1528                         case R_X86_64_PLT32:
1529                                 fill_got_entry(s1, rel);
1530                                 break;
1531                         }
1532                 }
1533         }
1534 }
1535
1536
1537 /* output an ELF file */
1538 /* XXX: suppress unneeded sections */
1539 static int elf_output_file(TCCState *s1, const char *filename)
1540 {
1541     ElfW(Ehdr) ehdr;
1542     FILE *f;
1543     int fd, mode, ret;
1544     int *section_order;
1545     int shnum, i, phnum, file_offset, offset, size, j, sh_order_index, k;
1546     long long tmp;
1547     addr_t addr;
1548     Section *strsec, *s;
1549     ElfW(Shdr) shdr, *sh;
1550     ElfW(Phdr) *phdr, *ph;
1551     Section *interp, *dynamic, *dynstr;
1552     unsigned long saved_dynamic_data_offset;
1553     ElfW(Sym) *sym;
1554     int type, file_type;
1555     addr_t rel_addr, rel_size;
1556 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
1557     addr_t bss_addr, bss_size;
1558 #endif
1559
1560     file_type = s1->output_type;
1561     s1->nb_errors = 0;
1562
1563     if (file_type != TCC_OUTPUT_OBJ) {
1564         tcc_add_runtime(s1);
1565     }
1566
1567     phdr = NULL;
1568     section_order = NULL;
1569     interp = NULL;
1570     dynamic = NULL;
1571     dynstr = NULL; /* avoid warning */
1572     saved_dynamic_data_offset = 0; /* avoid warning */
1573     
1574     if (file_type != TCC_OUTPUT_OBJ) {
1575         relocate_common_syms();
1576
1577         tcc_add_linker_symbols(s1);
1578
1579         if (!s1->static_link) {
1580             const char *name;
1581             int sym_index, index;
1582             ElfW(Sym) *esym, *sym_end;
1583
1584             if (file_type == TCC_OUTPUT_EXE) {
1585                 char *ptr;
1586                 /* allow override the dynamic loader */
1587                 const char *elfint = getenv("LD_SO");
1588                 if (elfint == NULL)
1589                     elfint = CONFIG_TCC_ELFINTERP;
1590                 /* add interpreter section only if executable */
1591                 interp = new_section(s1, ".interp", SHT_PROGBITS, SHF_ALLOC);
1592                 interp->sh_addralign = 1;
1593                 ptr = section_ptr_add(interp, 1+strlen(elfint));
1594                 strcpy(ptr, elfint);
1595             }
1596
1597             /* add dynamic symbol table */
1598             s1->dynsym = new_symtab(s1, ".dynsym", SHT_DYNSYM, SHF_ALLOC,
1599                                     ".dynstr", 
1600                                     ".hash", SHF_ALLOC);
1601             dynstr = s1->dynsym->link;
1602             
1603             /* add dynamic section */
1604             dynamic = new_section(s1, ".dynamic", SHT_DYNAMIC, 
1605                                   SHF_ALLOC | SHF_WRITE);
1606             dynamic->link = dynstr;
1607             dynamic->sh_entsize = sizeof(ElfW(Dyn));
1608         
1609             /* add PLT */
1610             s1->plt = new_section(s1, ".plt", SHT_PROGBITS, 
1611                                   SHF_ALLOC | SHF_EXECINSTR);
1612             s1->plt->sh_entsize = 4;
1613
1614             build_got(s1);
1615
1616             /* scan for undefined symbols and see if they are in the
1617                dynamic symbols. If a symbol STT_FUNC or STT_GNU_IFUNC
1618                is found, then we add it in the PLT. If a symbol
1619                STT_OBJECT is found, we add it in the .bss section with
1620                a suitable relocation */
1621             sym_end = (ElfW(Sym) *)(symtab_section->data + 
1622                                     symtab_section->data_offset);
1623             if (file_type == TCC_OUTPUT_EXE) {
1624                 for(sym = (ElfW(Sym) *)symtab_section->data + 1; 
1625                     sym < sym_end;
1626                     sym++) {
1627                     if (sym->st_shndx == SHN_UNDEF) {
1628                         name = symtab_section->link->data + sym->st_name;
1629                         sym_index = find_elf_sym(s1->dynsymtab_section, name);
1630                         if (sym_index) {
1631                             esym = &((ElfW(Sym) *)s1->dynsymtab_section->data)[sym_index];
1632                             type = ELFW(ST_TYPE)(esym->st_info);
1633                             if ((type == STT_FUNC) || (type == STT_GNU_IFUNC)) {
1634                                 /* Indirect functions shall have STT_FUNC type
1635                                  * in executable dynsym section. Indeed, a dlsym
1636                                  * call following a lazy resolution would pick
1637                                  * the symbol value from the executable dynsym
1638                                  * entry which would contain the address of the
1639                                  * function wanted by the caller of dlsym
1640                                  * instead of the address of the function that
1641                                  * would return that address */
1642                                 put_got_entry(s1, R_JMP_SLOT, esym->st_size, 
1643                                               ELFW(ST_INFO)(STB_GLOBAL,STT_FUNC),
1644                                               sym - (ElfW(Sym) *)symtab_section->data);
1645                             } else if (type == STT_OBJECT) {
1646                                 unsigned long offset;
1647                                 ElfW(Sym) *dynsym, *dynsym_end;
1648                                 offset = bss_section->data_offset;
1649                                 /* XXX: which alignment ? */
1650                                 offset = (offset + 16 - 1) & -16;
1651                                 index = put_elf_sym(s1->dynsym, offset, esym->st_size, 
1652                                                     esym->st_info, 0, 
1653                                                     bss_section->sh_num, name);
1654                                 // Ensure R_COPY works for weak symbol aliases
1655                                 if (ELFW(ST_BIND)(esym->st_info) == STB_WEAK) {
1656                                     dynsym_end = (ElfW(Sym) *)
1657                                                  (s1->dynsymtab_section->data +
1658                                                   s1->dynsymtab_section->data_offset);
1659                                     for(dynsym = (ElfW(Sym) *)s1->dynsymtab_section->data + 1;
1660                                         dynsym < dynsym_end; dynsym++) {
1661                                         if ((dynsym->st_value == esym->st_value)
1662                                            && (ELFW(ST_BIND)(dynsym->st_info) == STB_GLOBAL)) {
1663                                             char *dynname;
1664                                             dynname = s1->dynsymtab_section->link->data
1665                                                       + dynsym->st_name;
1666                                             put_elf_sym(s1->dynsym, offset,
1667                                                         dynsym->st_size,
1668                                                         dynsym->st_info, 0,
1669                                                         bss_section->sh_num,
1670                                                         dynname);
1671                                             break;
1672                                         }
1673                                     }
1674                                 }
1675                                 put_elf_reloc(s1->dynsym, bss_section, 
1676                                               offset, R_COPY, index);
1677                                 offset += esym->st_size;
1678                                 bss_section->data_offset = offset;
1679                             }
1680                         } else {
1681                                 /* STB_WEAK undefined symbols are accepted */
1682                                 /* XXX: _fp_hw seems to be part of the ABI, so we ignore
1683                                    it */
1684                             if (ELFW(ST_BIND)(sym->st_info) == STB_WEAK ||
1685                                 !strcmp(name, "_fp_hw")) {
1686                             } else {
1687                                 tcc_error_noabort("undefined symbol '%s'", name);
1688                             }
1689                         }
1690                     } else if (s1->rdynamic && 
1691                                ELFW(ST_BIND)(sym->st_info) != STB_LOCAL) {
1692                         /* if -rdynamic option, then export all non
1693                            local symbols */
1694                         name = symtab_section->link->data + sym->st_name;
1695                         put_elf_sym(s1->dynsym, sym->st_value, sym->st_size, 
1696                                     sym->st_info, 0, 
1697                                     sym->st_shndx, name);
1698                     }
1699                 }
1700             
1701                 if (s1->nb_errors)
1702                     goto fail;
1703
1704                 /* now look at unresolved dynamic symbols and export
1705                    corresponding symbol */
1706                 sym_end = (ElfW(Sym) *)(s1->dynsymtab_section->data + 
1707                                         s1->dynsymtab_section->data_offset);
1708                 for(esym = (ElfW(Sym) *)s1->dynsymtab_section->data + 1; 
1709                     esym < sym_end;
1710                     esym++) {
1711                     if (esym->st_shndx == SHN_UNDEF) {
1712                         name = s1->dynsymtab_section->link->data + esym->st_name;
1713                         sym_index = find_elf_sym(symtab_section, name);
1714                         if (sym_index) {
1715                             /* XXX: avoid adding a symbol if already
1716                                present because of -rdynamic ? */
1717                             sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
1718                             put_elf_sym(s1->dynsym, sym->st_value, sym->st_size, 
1719                                         sym->st_info, 0, 
1720                                         sym->st_shndx, name);
1721                         } else {
1722                             if (ELFW(ST_BIND)(esym->st_info) == STB_WEAK) {
1723                                 /* weak symbols can stay undefined */
1724                             } else {
1725                                 tcc_warning("undefined dynamic symbol '%s'", name);
1726                             }
1727                         }
1728                     }
1729                 }
1730             } else {
1731                 int nb_syms;
1732                 /* shared library case : we simply export all the global symbols */
1733                 nb_syms = symtab_section->data_offset / sizeof(ElfW(Sym));
1734                 s1->symtab_to_dynsym = tcc_mallocz(sizeof(int) * nb_syms);
1735                 for(sym = (ElfW(Sym) *)symtab_section->data + 1; 
1736                     sym < sym_end;
1737                     sym++) {
1738                     if (ELFW(ST_BIND)(sym->st_info) != STB_LOCAL) {
1739 #if defined(TCC_OUTPUT_DLL_WITH_PLT)
1740                         if ((ELFW(ST_TYPE)(sym->st_info) == STT_FUNC ||
1741                             ELFW(ST_TYPE)(sym->st_info) == STT_GNU_IFUNC)
1742                             && sym->st_shndx == SHN_UNDEF) {
1743                             int visibility = ELFW(ST_BIND)(sym->st_info);
1744                             put_got_entry(s1, R_JMP_SLOT, sym->st_size, 
1745                                           ELFW(ST_INFO)(visibility,STT_FUNC),
1746                                           sym - (ElfW(Sym) *)symtab_section->data);
1747                         }
1748                         else if (ELFW(ST_TYPE)(sym->st_info) == STT_OBJECT) {
1749                             put_got_entry(s1, R_X86_64_GLOB_DAT, sym->st_size, 
1750                                           sym->st_info, 
1751                                           sym - (ElfW(Sym) *)symtab_section->data);
1752                         }
1753                         else
1754 #endif
1755                         {
1756                             name = symtab_section->link->data + sym->st_name;
1757                             index = put_elf_sym(s1->dynsym, sym->st_value, sym->st_size, 
1758                                                 sym->st_info, 0, 
1759                                                 sym->st_shndx, name);
1760                             s1->symtab_to_dynsym[sym - 
1761                                                  (ElfW(Sym) *)symtab_section->data] = 
1762                                 index;
1763                         }
1764                     }
1765                 }
1766             }
1767
1768             build_got_entries(s1);
1769         
1770             /* add a list of needed dlls */
1771             for(i = 0; i < s1->nb_loaded_dlls; i++) {
1772                 DLLReference *dllref = s1->loaded_dlls[i];
1773                 if (dllref->level == 0)
1774                     put_dt(dynamic, DT_NEEDED, put_elf_str(dynstr, dllref->name));
1775             }
1776
1777             if (s1->rpath)
1778                 put_dt(dynamic, DT_RPATH, put_elf_str(dynstr, s1->rpath));
1779
1780             /* XXX: currently, since we do not handle PIC code, we
1781                must relocate the readonly segments */
1782             if (file_type == TCC_OUTPUT_DLL) {
1783                 if (s1->soname)
1784                     put_dt(dynamic, DT_SONAME, put_elf_str(dynstr, s1->soname));
1785                 put_dt(dynamic, DT_TEXTREL, 0);
1786             }
1787
1788             if (s1->symbolic)
1789                 put_dt(dynamic, DT_SYMBOLIC, 0);
1790
1791             /* add necessary space for other entries */
1792             saved_dynamic_data_offset = dynamic->data_offset;
1793             dynamic->data_offset += sizeof(ElfW(Dyn)) * EXTRA_RELITEMS;
1794         } else {
1795             /* still need to build got entries in case of static link */
1796             build_got_entries(s1);
1797         }
1798     }
1799
1800     memset(&ehdr, 0, sizeof(ehdr));
1801
1802     /* we add a section for symbols */
1803     strsec = new_section(s1, ".shstrtab", SHT_STRTAB, 0);
1804     put_elf_str(strsec, "");
1805     
1806     /* compute number of sections */
1807     shnum = s1->nb_sections;
1808
1809     /* this array is used to reorder sections in the output file */
1810     section_order = tcc_malloc(sizeof(int) * shnum);
1811     section_order[0] = 0;
1812     sh_order_index = 1;
1813     
1814     /* compute number of program headers */
1815     switch(file_type) {
1816     default:
1817     case TCC_OUTPUT_OBJ:
1818         phnum = 0;
1819         break;
1820     case TCC_OUTPUT_EXE:
1821         if (!s1->static_link)
1822             phnum = 4 + HAVE_PHDR;
1823         else
1824             phnum = 2;
1825         break;
1826     case TCC_OUTPUT_DLL:
1827         phnum = 3;
1828         break;
1829     }
1830
1831     /* allocate strings for section names and decide if an unallocated
1832        section should be output */
1833     /* NOTE: the strsec section comes last, so its size is also
1834        correct ! */
1835     for(i = 1; i < s1->nb_sections; i++) {
1836         s = s1->sections[i];
1837         s->sh_name = put_elf_str(strsec, s->name);
1838 #if 0 /* gr */
1839         printf("section: f=%08x t=%08x i=%08x %s %s\n", 
1840                s->sh_flags, 
1841                s->sh_type, 
1842                s->sh_info, 
1843                s->name, 
1844                s->reloc ? s->reloc->name : "n"
1845                ); 
1846 #endif
1847         /* when generating a DLL, we include relocations but we may
1848            patch them */
1849         if (file_type == TCC_OUTPUT_DLL && 
1850             s->sh_type == SHT_RELX && 
1851             !(s->sh_flags & SHF_ALLOC)) {
1852             /* //gr: avoid bogus relocs for empty (debug) sections */
1853             if (s1->sections[s->sh_info]->sh_flags & SHF_ALLOC)
1854                 prepare_dynamic_rel(s1, s);
1855             else if (s1->do_debug)
1856                 s->sh_size = s->data_offset;
1857         } else if (s1->do_debug ||
1858             file_type == TCC_OUTPUT_OBJ || 
1859             (s->sh_flags & SHF_ALLOC) ||
1860             i == (s1->nb_sections - 1)) {
1861             /* we output all sections if debug or object file */
1862             s->sh_size = s->data_offset;
1863         }
1864     }
1865
1866     /* allocate program segment headers */
1867     phdr = tcc_mallocz(phnum * sizeof(ElfW(Phdr)));
1868         
1869     if (s1->output_format == TCC_OUTPUT_FORMAT_ELF) {
1870         file_offset = sizeof(ElfW(Ehdr)) + phnum * sizeof(ElfW(Phdr));
1871     } else {
1872         file_offset = 0;
1873     }
1874     if (phnum > 0) {
1875         /* compute section to program header mapping */
1876         if (s1->has_text_addr) { 
1877             int a_offset, p_offset;
1878             addr = s1->text_addr;
1879             /* we ensure that (addr % ELF_PAGE_SIZE) == file_offset %
1880                ELF_PAGE_SIZE */
1881             a_offset = (int) (addr & (s1->section_align - 1));
1882             p_offset = file_offset & (s1->section_align - 1);
1883             if (a_offset < p_offset) 
1884                 a_offset += s1->section_align;
1885             file_offset += (a_offset - p_offset);
1886         } else {
1887             if (file_type == TCC_OUTPUT_DLL)
1888                 addr = 0;
1889             else
1890                 addr = ELF_START_ADDR;
1891             /* compute address after headers */
1892             addr += (file_offset & (s1->section_align - 1));
1893         }
1894         
1895         /* dynamic relocation table information, for .dynamic section */
1896         rel_size = 0;
1897         rel_addr = 0;
1898
1899 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
1900         bss_addr = bss_size = 0;
1901 #endif
1902         /* leave one program header for the program interpreter */
1903         ph = &phdr[0];
1904         if (interp)
1905             ph += 1 + HAVE_PHDR;
1906
1907         for(j = 0; j < 2; j++) {
1908             ph->p_type = PT_LOAD;
1909             if (j == 0)
1910                 ph->p_flags = PF_R | PF_X;
1911             else
1912                 ph->p_flags = PF_R | PF_W;
1913             ph->p_align = s1->section_align;
1914             
1915             /* we do the following ordering: interp, symbol tables,
1916                relocations, progbits, nobits */
1917             /* XXX: do faster and simpler sorting */
1918             for(k = 0; k < 5; k++) {
1919                 for(i = 1; i < s1->nb_sections; i++) {
1920                     s = s1->sections[i];
1921                     /* compute if section should be included */
1922                     if (j == 0) {
1923                         if ((s->sh_flags & (SHF_ALLOC | SHF_WRITE)) != 
1924                             SHF_ALLOC)
1925                             continue;
1926                     } else {
1927                         if ((s->sh_flags & (SHF_ALLOC | SHF_WRITE)) != 
1928                             (SHF_ALLOC | SHF_WRITE))
1929                             continue;
1930                     }
1931                     if (s == interp) {
1932                         if (k != 0)
1933                             continue;
1934                     } else if (s->sh_type == SHT_DYNSYM ||
1935                                s->sh_type == SHT_STRTAB ||
1936                                s->sh_type == SHT_HASH) {
1937                         if (k != 1)
1938                             continue;
1939                     } else if (s->sh_type == SHT_RELX) {
1940                         if (k != 2)
1941                             continue;
1942                     } else if (s->sh_type == SHT_NOBITS) {
1943                         if (k != 4)
1944                             continue;
1945                     } else {
1946                         if (k != 3)
1947                             continue;
1948                     }
1949                     section_order[sh_order_index++] = i;
1950
1951                     /* section matches: we align it and add its size */
1952                     tmp = addr;
1953                     addr = (addr + s->sh_addralign - 1) & 
1954                         ~(s->sh_addralign - 1);
1955                     file_offset += (int) ( addr - tmp );
1956                     s->sh_offset = file_offset;
1957                     s->sh_addr = addr;
1958                     
1959                     /* update program header infos */
1960                     if (ph->p_offset == 0) {
1961                         ph->p_offset = file_offset;
1962                         ph->p_vaddr = addr;
1963                         ph->p_paddr = ph->p_vaddr;
1964                     }
1965                     /* update dynamic relocation infos */
1966                     if (s->sh_type == SHT_RELX) {
1967 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
1968                         if (!strcmp(strsec->data + s->sh_name, ".rel.got")) { // rel_size == 0) {
1969                             rel_addr = addr;
1970                             rel_size += s->sh_size;     // XXX only first rel.
1971                         }
1972                         if (!strcmp(strsec->data + s->sh_name, ".rel.bss")) { // rel_size == 0) {
1973                             bss_addr = addr;
1974                             bss_size = s->sh_size;      // XXX only first rel.
1975                         }
1976 #else
1977                         if (rel_size == 0)
1978                             rel_addr = addr;
1979                         rel_size += s->sh_size;
1980 #endif
1981                     }
1982                     addr += s->sh_size;
1983                     if (s->sh_type != SHT_NOBITS)
1984                         file_offset += s->sh_size;
1985                 }
1986             }
1987             ph->p_filesz = file_offset - ph->p_offset;
1988             ph->p_memsz = addr - ph->p_vaddr;
1989             ph++;
1990             if (j == 0) {
1991                 if (s1->output_format == TCC_OUTPUT_FORMAT_ELF) {
1992                     /* if in the middle of a page, we duplicate the page in
1993                        memory so that one copy is RX and the other is RW */
1994                     if ((addr & (s1->section_align - 1)) != 0)
1995                         addr += s1->section_align;
1996                 } else {
1997                     addr = (addr + s1->section_align - 1) & ~(s1->section_align - 1);
1998                     file_offset = (file_offset + s1->section_align - 1) &
1999                         ~(s1->section_align - 1);
2000                 }
2001             }
2002         }
2003
2004         /* if interpreter, then add corresponing program header */
2005         if (interp) {
2006             ph = &phdr[0];
2007
2008 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
2009             {
2010                 int len = phnum * sizeof(ElfW(Phdr));
2011
2012                 ph->p_type = PT_PHDR;
2013                 ph->p_offset = sizeof(ElfW(Ehdr));
2014                 ph->p_vaddr = interp->sh_addr - len;
2015                 ph->p_paddr = ph->p_vaddr;
2016                 ph->p_filesz = ph->p_memsz = len;
2017                 ph->p_flags = PF_R | PF_X;
2018                 ph->p_align = 4; // interp->sh_addralign;
2019                 ph++;
2020             }
2021 #endif
2022
2023             ph->p_type = PT_INTERP;
2024             ph->p_offset = interp->sh_offset;
2025             ph->p_vaddr = interp->sh_addr;
2026             ph->p_paddr = ph->p_vaddr;
2027             ph->p_filesz = interp->sh_size;
2028             ph->p_memsz = interp->sh_size;
2029             ph->p_flags = PF_R;
2030             ph->p_align = interp->sh_addralign;
2031         }
2032         
2033         /* if dynamic section, then add corresponing program header */
2034         if (dynamic) {
2035             ElfW(Sym) *sym_end;
2036
2037             ph = &phdr[phnum - 1];
2038             
2039             ph->p_type = PT_DYNAMIC;
2040             ph->p_offset = dynamic->sh_offset;
2041             ph->p_vaddr = dynamic->sh_addr;
2042             ph->p_paddr = ph->p_vaddr;
2043             ph->p_filesz = dynamic->sh_size;
2044             ph->p_memsz = dynamic->sh_size;
2045             ph->p_flags = PF_R | PF_W;
2046             ph->p_align = dynamic->sh_addralign;
2047
2048             /* put GOT dynamic section address */
2049             put32(s1->got->data, dynamic->sh_addr);
2050
2051             /* relocate the PLT */
2052             if (file_type == TCC_OUTPUT_EXE
2053 #if defined(TCC_OUTPUT_DLL_WITH_PLT)
2054                 || file_type == TCC_OUTPUT_DLL
2055 #endif
2056                 ) {
2057                 uint8_t *p, *p_end;
2058
2059                 p = s1->plt->data;
2060                 p_end = p + s1->plt->data_offset;
2061                 if (p < p_end) {
2062 #if defined(TCC_TARGET_I386)
2063                     put32(p + 2, get32(p + 2) + s1->got->sh_addr);
2064                     put32(p + 8, get32(p + 8) + s1->got->sh_addr);
2065                     p += 16;
2066                     while (p < p_end) {
2067                         put32(p + 2, get32(p + 2) + s1->got->sh_addr);
2068                         p += 16;
2069                     }
2070 #elif defined(TCC_TARGET_X86_64)
2071                     int x = s1->got->sh_addr - s1->plt->sh_addr - 6;
2072                     put32(p + 2, get32(p + 2) + x);
2073                     put32(p + 8, get32(p + 8) + x - 6);
2074                     p += 16;
2075                     while (p < p_end) {
2076                         put32(p + 2, get32(p + 2) + x + s1->plt->data - p);
2077                         p += 16;
2078                     }
2079 #elif defined(TCC_TARGET_ARM)
2080                     int x;
2081                     x=s1->got->sh_addr - s1->plt->sh_addr - 12;
2082                     p += 16;
2083                     while (p < p_end) {
2084                         if (get32(p) == 0x46c04778) /* PLT Thumb stub present */
2085                             p += 4;
2086                         put32(p + 12, x + get32(p + 12) + s1->plt->data - p);
2087                         p += 16;
2088                     }
2089 #elif defined(TCC_TARGET_C67)
2090                     /* XXX: TODO */
2091 #else
2092 #error unsupported CPU
2093 #endif
2094                 }
2095             }
2096
2097             /* relocate symbols in .dynsym */
2098             sym_end = (ElfW(Sym) *)(s1->dynsym->data + s1->dynsym->data_offset);
2099             for(sym = (ElfW(Sym) *)s1->dynsym->data + 1; 
2100                 sym < sym_end;
2101                 sym++) {
2102                 if (sym->st_shndx == SHN_UNDEF) {
2103                     /* relocate to the PLT if the symbol corresponds
2104                        to a PLT entry */
2105                     if (sym->st_value)
2106                         sym->st_value += s1->plt->sh_addr;
2107                 } else if (sym->st_shndx < SHN_LORESERVE) {
2108                     /* do symbol relocation */
2109                     sym->st_value += s1->sections[sym->st_shndx]->sh_addr;
2110                 }
2111             }
2112
2113             /* put dynamic section entries */
2114             dynamic->data_offset = saved_dynamic_data_offset;
2115             put_dt(dynamic, DT_HASH, s1->dynsym->hash->sh_addr);
2116             put_dt(dynamic, DT_STRTAB, dynstr->sh_addr);
2117             put_dt(dynamic, DT_SYMTAB, s1->dynsym->sh_addr);
2118             put_dt(dynamic, DT_STRSZ, dynstr->data_offset);
2119             put_dt(dynamic, DT_SYMENT, sizeof(ElfW(Sym)));
2120 #ifdef TCC_TARGET_X86_64
2121             put_dt(dynamic, DT_RELA, rel_addr);
2122             put_dt(dynamic, DT_RELASZ, rel_size);
2123             put_dt(dynamic, DT_RELAENT, sizeof(ElfW_Rel));
2124 #else
2125 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
2126             put_dt(dynamic, DT_PLTGOT, s1->got->sh_addr);
2127             put_dt(dynamic, DT_PLTRELSZ, rel_size);
2128             put_dt(dynamic, DT_JMPREL, rel_addr);
2129             put_dt(dynamic, DT_PLTREL, DT_REL);
2130             put_dt(dynamic, DT_REL, bss_addr);
2131             put_dt(dynamic, DT_RELSZ, bss_size);
2132 #else
2133             put_dt(dynamic, DT_REL, rel_addr);
2134             put_dt(dynamic, DT_RELSZ, rel_size);
2135             put_dt(dynamic, DT_RELENT, sizeof(ElfW_Rel));
2136 #endif
2137 #endif
2138             if (s1->do_debug)
2139                 put_dt(dynamic, DT_DEBUG, 0);
2140             put_dt(dynamic, DT_NULL, 0);
2141         }
2142
2143         ehdr.e_phentsize = sizeof(ElfW(Phdr));
2144         ehdr.e_phnum = phnum;
2145         ehdr.e_phoff = sizeof(ElfW(Ehdr));
2146     }
2147
2148     /* all other sections come after */
2149     for(i = 1; i < s1->nb_sections; i++) {
2150         s = s1->sections[i];
2151         if (phnum > 0 && (s->sh_flags & SHF_ALLOC))
2152             continue;
2153         section_order[sh_order_index++] = i;
2154         
2155         file_offset = (file_offset + s->sh_addralign - 1) & 
2156             ~(s->sh_addralign - 1);
2157         s->sh_offset = file_offset;
2158         if (s->sh_type != SHT_NOBITS)
2159             file_offset += s->sh_size;
2160     }
2161     
2162     /* if building executable or DLL, then relocate each section
2163        except the GOT which is already relocated */
2164     if (file_type != TCC_OUTPUT_OBJ) {
2165         relocate_syms(s1, 0);
2166
2167         if (s1->nb_errors != 0) {
2168         fail:
2169             ret = -1;
2170             goto the_end;
2171         }
2172
2173         /* relocate sections */
2174         /* XXX: ignore sections with allocated relocations ? */
2175         for(i = 1; i < s1->nb_sections; i++) {
2176             s = s1->sections[i];
2177             if (s->reloc && s != s1->got)
2178                 relocate_section(s1, s);
2179         }
2180
2181         /* relocate relocation entries if the relocation tables are
2182            allocated in the executable */
2183         for(i = 1; i < s1->nb_sections; i++) {
2184             s = s1->sections[i];
2185             if ((s->sh_flags & SHF_ALLOC) &&
2186                 s->sh_type == SHT_RELX) {
2187                 relocate_rel(s1, s);
2188             }
2189         }
2190
2191         /* get entry point address */
2192         if (file_type == TCC_OUTPUT_EXE)
2193             ehdr.e_entry = get_elf_sym_addr(s1, "_start", 1);
2194         else
2195             ehdr.e_entry = text_section->sh_addr; /* XXX: is it correct ? */
2196     }
2197     if (file_type == TCC_OUTPUT_EXE && s1->static_link)
2198         fill_got(s1);
2199
2200     /* write elf file */
2201     if (file_type == TCC_OUTPUT_OBJ)
2202         mode = 0666;
2203     else
2204         mode = 0777;
2205     unlink(filename);
2206     fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, mode); 
2207     if (fd < 0) {
2208         tcc_error_noabort("could not write '%s'", filename);
2209         goto fail;
2210     }
2211     f = fdopen(fd, "wb");
2212     if (s1->verbose)
2213         printf("<- %s\n", filename);
2214
2215 #ifdef TCC_TARGET_COFF
2216     if (s1->output_format == TCC_OUTPUT_FORMAT_COFF) {
2217         tcc_output_coff(s1, f);
2218     } else
2219 #endif
2220     if (s1->output_format == TCC_OUTPUT_FORMAT_ELF) {
2221         sort_syms(s1, symtab_section);
2222         
2223         /* align to 4 */
2224         file_offset = (file_offset + 3) & -4;
2225     
2226         /* fill header */
2227         ehdr.e_ident[0] = ELFMAG0;
2228         ehdr.e_ident[1] = ELFMAG1;
2229         ehdr.e_ident[2] = ELFMAG2;
2230         ehdr.e_ident[3] = ELFMAG3;
2231         ehdr.e_ident[4] = ELFCLASSW;
2232         ehdr.e_ident[5] = ELFDATA2LSB;
2233         ehdr.e_ident[6] = EV_CURRENT;
2234 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
2235         ehdr.e_ident[EI_OSABI] = ELFOSABI_FREEBSD;
2236 #endif
2237 #ifdef TCC_TARGET_ARM
2238 #ifdef TCC_ARM_EABI
2239         ehdr.e_ident[EI_OSABI] = 0;
2240         ehdr.e_flags = 4 << 24;
2241 #else
2242         ehdr.e_ident[EI_OSABI] = ELFOSABI_ARM;
2243 #endif
2244 #endif
2245         switch(file_type) {
2246         default:
2247         case TCC_OUTPUT_EXE:
2248             ehdr.e_type = ET_EXEC;
2249             break;
2250         case TCC_OUTPUT_DLL:
2251             ehdr.e_type = ET_DYN;
2252             break;
2253         case TCC_OUTPUT_OBJ:
2254             ehdr.e_type = ET_REL;
2255             break;
2256         }
2257         ehdr.e_machine = EM_TCC_TARGET;
2258         ehdr.e_version = EV_CURRENT;
2259         ehdr.e_shoff = file_offset;
2260         ehdr.e_ehsize = sizeof(ElfW(Ehdr));
2261         ehdr.e_shentsize = sizeof(ElfW(Shdr));
2262         ehdr.e_shnum = shnum;
2263         ehdr.e_shstrndx = shnum - 1;
2264         
2265         fwrite(&ehdr, 1, sizeof(ElfW(Ehdr)), f);
2266         fwrite(phdr, 1, phnum * sizeof(ElfW(Phdr)), f);
2267         offset = sizeof(ElfW(Ehdr)) + phnum * sizeof(ElfW(Phdr));
2268
2269         for(i=1;i<s1->nb_sections;i++) {
2270             s = s1->sections[section_order[i]];
2271             if (s->sh_type != SHT_NOBITS) {
2272                 if (s->sh_type == SHT_DYNSYM)
2273                     patch_dynsym_undef(s1, s);
2274                 while (offset < s->sh_offset) {
2275                     fputc(0, f);
2276                     offset++;
2277                 }
2278                 size = s->sh_size;
2279                 fwrite(s->data, 1, size, f);
2280                 offset += size;
2281             }
2282         }
2283
2284         /* output section headers */
2285         while (offset < ehdr.e_shoff) {
2286             fputc(0, f);
2287             offset++;
2288         }
2289     
2290         for(i=0;i<s1->nb_sections;i++) {
2291             sh = &shdr;
2292             memset(sh, 0, sizeof(ElfW(Shdr)));
2293             s = s1->sections[i];
2294             if (s) {
2295                 sh->sh_name = s->sh_name;
2296                 sh->sh_type = s->sh_type;
2297                 sh->sh_flags = s->sh_flags;
2298                 sh->sh_entsize = s->sh_entsize;
2299                 sh->sh_info = s->sh_info;
2300                 if (s->link)
2301                     sh->sh_link = s->link->sh_num;
2302                 sh->sh_addralign = s->sh_addralign;
2303                 sh->sh_addr = s->sh_addr;
2304                 sh->sh_offset = s->sh_offset;
2305                 sh->sh_size = s->sh_size;
2306             }
2307             fwrite(sh, 1, sizeof(ElfW(Shdr)), f);
2308         }
2309     } else {
2310         tcc_output_binary(s1, f, section_order);
2311     }
2312     fclose(f);
2313
2314     ret = 0;
2315  the_end:
2316     tcc_free(s1->symtab_to_dynsym);
2317     tcc_free(section_order);
2318     tcc_free(phdr);
2319     tcc_free(s1->sym_attrs);
2320     return ret;
2321 }
2322
2323 LIBTCCAPI int tcc_output_file(TCCState *s, const char *filename)
2324 {
2325     int ret;
2326 #ifdef TCC_TARGET_PE
2327     if (s->output_type != TCC_OUTPUT_OBJ) {
2328         ret = pe_output_file(s, filename);
2329     } else
2330 #endif
2331     {
2332         ret = elf_output_file(s, filename);
2333     }
2334     return ret;
2335 }
2336
2337 static void *load_data(int fd, unsigned long file_offset, unsigned long size)
2338 {
2339     void *data;
2340
2341     data = tcc_malloc(size);
2342     lseek(fd, file_offset, SEEK_SET);
2343     read(fd, data, size);
2344     return data;
2345 }
2346
2347 typedef struct SectionMergeInfo {
2348     Section *s;            /* corresponding existing section */
2349     unsigned long offset;  /* offset of the new section in the existing section */
2350     uint8_t new_section;       /* true if section 's' was added */
2351     uint8_t link_once;         /* true if link once section */
2352 } SectionMergeInfo;
2353
2354 /* load an object file and merge it with current files */
2355 /* XXX: handle correctly stab (debug) info */
2356 ST_FUNC int tcc_load_object_file(TCCState *s1, 
2357                                 int fd, unsigned long file_offset)
2358
2359     ElfW(Ehdr) ehdr;
2360     ElfW(Shdr) *shdr, *sh;
2361     int size, i, j, offset, offseti, nb_syms, sym_index, ret;
2362     unsigned char *strsec, *strtab;
2363     int *old_to_new_syms;
2364     char *sh_name, *name;
2365     SectionMergeInfo *sm_table, *sm;
2366     ElfW(Sym) *sym, *symtab;
2367     ElfW_Rel *rel, *rel_end;
2368     Section *s;
2369
2370     int stab_index;
2371     int stabstr_index;
2372
2373     stab_index = stabstr_index = 0;
2374
2375     if (read(fd, &ehdr, sizeof(ehdr)) != sizeof(ehdr))
2376         goto fail1;
2377     if (ehdr.e_ident[0] != ELFMAG0 ||
2378         ehdr.e_ident[1] != ELFMAG1 ||
2379         ehdr.e_ident[2] != ELFMAG2 ||
2380         ehdr.e_ident[3] != ELFMAG3)
2381         goto fail1;
2382     /* test if object file */
2383     if (ehdr.e_type != ET_REL)
2384         goto fail1;
2385     /* test CPU specific stuff */
2386     if (ehdr.e_ident[5] != ELFDATA2LSB ||
2387         ehdr.e_machine != EM_TCC_TARGET) {
2388     fail1:
2389         tcc_error_noabort("invalid object file");
2390         return -1;
2391     }
2392     /* read sections */
2393     shdr = load_data(fd, file_offset + ehdr.e_shoff, 
2394                      sizeof(ElfW(Shdr)) * ehdr.e_shnum);
2395     sm_table = tcc_mallocz(sizeof(SectionMergeInfo) * ehdr.e_shnum);
2396     
2397     /* load section names */
2398     sh = &shdr[ehdr.e_shstrndx];
2399     strsec = load_data(fd, file_offset + sh->sh_offset, sh->sh_size);
2400
2401     /* load symtab and strtab */
2402     old_to_new_syms = NULL;
2403     symtab = NULL;
2404     strtab = NULL;
2405     nb_syms = 0;
2406     for(i = 1; i < ehdr.e_shnum; i++) {
2407         sh = &shdr[i];
2408         if (sh->sh_type == SHT_SYMTAB) {
2409             if (symtab) {
2410                 tcc_error_noabort("object must contain only one symtab");
2411             fail:
2412                 ret = -1;
2413                 goto the_end;
2414             }
2415             nb_syms = sh->sh_size / sizeof(ElfW(Sym));
2416             symtab = load_data(fd, file_offset + sh->sh_offset, sh->sh_size);
2417             sm_table[i].s = symtab_section;
2418
2419             /* now load strtab */
2420             sh = &shdr[sh->sh_link];
2421             strtab = load_data(fd, file_offset + sh->sh_offset, sh->sh_size);
2422         }
2423     }
2424         
2425     /* now examine each section and try to merge its content with the
2426        ones in memory */
2427     for(i = 1; i < ehdr.e_shnum; i++) {
2428         /* no need to examine section name strtab */
2429         if (i == ehdr.e_shstrndx)
2430             continue;
2431         sh = &shdr[i];
2432         sh_name = strsec + sh->sh_name;
2433         /* ignore sections types we do not handle */
2434         if (sh->sh_type != SHT_PROGBITS &&
2435             sh->sh_type != SHT_RELX && 
2436 #ifdef TCC_ARM_EABI
2437             sh->sh_type != SHT_ARM_EXIDX &&
2438 #endif
2439             sh->sh_type != SHT_NOBITS && 
2440             sh->sh_type != SHT_PREINIT_ARRAY &&
2441             sh->sh_type != SHT_INIT_ARRAY &&
2442             sh->sh_type != SHT_FINI_ARRAY &&
2443             strcmp(sh_name, ".stabstr")
2444             )
2445             continue;
2446         if (sh->sh_addralign < 1)
2447             sh->sh_addralign = 1;
2448         /* find corresponding section, if any */
2449         for(j = 1; j < s1->nb_sections;j++) {
2450             s = s1->sections[j];
2451             if (!strcmp(s->name, sh_name)) {
2452                 if (!strncmp(sh_name, ".gnu.linkonce", 
2453                              sizeof(".gnu.linkonce") - 1)) {
2454                     /* if a 'linkonce' section is already present, we
2455                        do not add it again. It is a little tricky as
2456                        symbols can still be defined in
2457                        it. */
2458                     sm_table[i].link_once = 1;
2459                     goto next;
2460                 } else {
2461                     goto found;
2462                 }
2463             }
2464         }
2465         /* not found: create new section */
2466         s = new_section(s1, sh_name, sh->sh_type, sh->sh_flags);
2467         /* take as much info as possible from the section. sh_link and
2468            sh_info will be updated later */
2469         s->sh_addralign = sh->sh_addralign;
2470         s->sh_entsize = sh->sh_entsize;
2471         sm_table[i].new_section = 1;
2472     found:
2473         if (sh->sh_type != s->sh_type) {
2474             tcc_error_noabort("invalid section type");
2475             goto fail;
2476         }
2477
2478         /* align start of section */
2479         offset = s->data_offset;
2480
2481         if (0 == strcmp(sh_name, ".stab")) {
2482             stab_index = i;
2483             goto no_align;
2484         }
2485         if (0 == strcmp(sh_name, ".stabstr")) {
2486             stabstr_index = i;
2487             goto no_align;
2488         }
2489
2490         size = sh->sh_addralign - 1;
2491         offset = (offset + size) & ~size;
2492         if (sh->sh_addralign > s->sh_addralign)
2493             s->sh_addralign = sh->sh_addralign;
2494         s->data_offset = offset;
2495     no_align:
2496         sm_table[i].offset = offset;
2497         sm_table[i].s = s;
2498         /* concatenate sections */
2499         size = sh->sh_size;
2500         if (sh->sh_type != SHT_NOBITS) {
2501             unsigned char *ptr;
2502             lseek(fd, file_offset + sh->sh_offset, SEEK_SET);
2503             ptr = section_ptr_add(s, size);
2504             read(fd, ptr, size);
2505         } else {
2506             s->data_offset += size;
2507         }
2508     next: ;
2509     }
2510
2511     /* //gr relocate stab strings */
2512     if (stab_index && stabstr_index) {
2513         Stab_Sym *a, *b;
2514         unsigned o;
2515         s = sm_table[stab_index].s;
2516         a = (Stab_Sym *)(s->data + sm_table[stab_index].offset);
2517         b = (Stab_Sym *)(s->data + s->data_offset);
2518         o = sm_table[stabstr_index].offset;
2519         while (a < b) 
2520             a->n_strx += o, a++;
2521     }
2522
2523     /* second short pass to update sh_link and sh_info fields of new
2524        sections */
2525     for(i = 1; i < ehdr.e_shnum; i++) {
2526         s = sm_table[i].s;
2527         if (!s || !sm_table[i].new_section)
2528             continue;
2529         sh = &shdr[i];
2530         if (sh->sh_link > 0)
2531             s->link = sm_table[sh->sh_link].s;
2532         if (sh->sh_type == SHT_RELX) {
2533             s->sh_info = sm_table[sh->sh_info].s->sh_num;
2534             /* update backward link */
2535             s1->sections[s->sh_info]->reloc = s;
2536         }
2537     }
2538     sm = sm_table;
2539
2540     /* resolve symbols */
2541     old_to_new_syms = tcc_mallocz(nb_syms * sizeof(int));
2542
2543     sym = symtab + 1;
2544     for(i = 1; i < nb_syms; i++, sym++) {
2545         if (sym->st_shndx != SHN_UNDEF &&
2546             sym->st_shndx < SHN_LORESERVE) {
2547             sm = &sm_table[sym->st_shndx];
2548             if (sm->link_once) {
2549                 /* if a symbol is in a link once section, we use the
2550                    already defined symbol. It is very important to get
2551                    correct relocations */
2552                 if (ELFW(ST_BIND)(sym->st_info) != STB_LOCAL) {
2553                     name = strtab + sym->st_name;
2554                     sym_index = find_elf_sym(symtab_section, name);
2555                     if (sym_index)
2556                         old_to_new_syms[i] = sym_index;
2557                 }
2558                 continue;
2559             }
2560             /* if no corresponding section added, no need to add symbol */
2561             if (!sm->s)
2562                 continue;
2563             /* convert section number */
2564             sym->st_shndx = sm->s->sh_num;
2565             /* offset value */
2566             sym->st_value += sm->offset;
2567         }
2568         /* add symbol */
2569         name = strtab + sym->st_name;
2570         sym_index = add_elf_sym(symtab_section, sym->st_value, sym->st_size, 
2571                                 sym->st_info, sym->st_other, 
2572                                 sym->st_shndx, name);
2573         old_to_new_syms[i] = sym_index;
2574     }
2575
2576     /* third pass to patch relocation entries */
2577     for(i = 1; i < ehdr.e_shnum; i++) {
2578         s = sm_table[i].s;
2579         if (!s)
2580             continue;
2581         sh = &shdr[i];
2582         offset = sm_table[i].offset;
2583         switch(s->sh_type) {
2584         case SHT_RELX:
2585             /* take relocation offset information */
2586             offseti = sm_table[sh->sh_info].offset;
2587             rel_end = (ElfW_Rel *)(s->data + s->data_offset);
2588             for(rel = (ElfW_Rel *)(s->data + offset);
2589                 rel < rel_end;
2590                 rel++) {
2591                 int type;
2592                 unsigned sym_index;
2593                 /* convert symbol index */
2594                 type = ELFW(R_TYPE)(rel->r_info);
2595                 sym_index = ELFW(R_SYM)(rel->r_info);
2596                 /* NOTE: only one symtab assumed */
2597                 if (sym_index >= nb_syms)
2598                     goto invalid_reloc;
2599                 sym_index = old_to_new_syms[sym_index];
2600                 /* ignore link_once in rel section. */
2601                 if (!sym_index && !sm->link_once
2602 #ifdef TCC_TARGET_ARM
2603                     && type != R_ARM_V4BX
2604 #endif
2605                    ) {
2606                 invalid_reloc:
2607                     tcc_error_noabort("Invalid relocation entry [%2d] '%s' @ %.8x",
2608                         i, strsec + sh->sh_name, rel->r_offset);
2609                     goto fail;
2610                 }
2611                 rel->r_info = ELFW(R_INFO)(sym_index, type);
2612                 /* offset the relocation offset */
2613                 rel->r_offset += offseti;
2614 #ifdef TCC_TARGET_ARM
2615                 /* Jumps and branches from a Thumb code to a PLT entry need
2616                    special handling since PLT entries are ARM code.
2617                    Unconditional bl instructions referencing PLT entries are
2618                    handled by converting these instructions into blx
2619                    instructions. Other case of instructions referencing a PLT
2620                    entry require to add a Thumb stub before the PLT entry to
2621                    switch to ARM mode. We set bit 0 of the got offset of a
2622                    symbol to indicate such a case. */
2623                 if (type == R_ARM_THM_JUMP24)
2624                     alloc_sym_attr(s1, sym_index)->plt_thumb_stub = 1;
2625 #endif
2626             }
2627             break;
2628         default:
2629             break;
2630         }
2631     }
2632     
2633     ret = 0;
2634  the_end:
2635     tcc_free(symtab);
2636     tcc_free(strtab);
2637     tcc_free(old_to_new_syms);
2638     tcc_free(sm_table);
2639     tcc_free(strsec);
2640     tcc_free(shdr);
2641     return ret;
2642 }
2643
2644 typedef struct ArchiveHeader {
2645     char ar_name[16];           /* name of this member */
2646     char ar_date[12];           /* file mtime */
2647     char ar_uid[6];             /* owner uid; printed as decimal */
2648     char ar_gid[6];             /* owner gid; printed as decimal */
2649     char ar_mode[8];            /* file mode, printed as octal   */
2650     char ar_size[10];           /* file size, printed as decimal */
2651     char ar_fmag[2];            /* should contain ARFMAG */
2652 } ArchiveHeader;
2653
2654 static int get_be32(const uint8_t *b)
2655 {
2656     return b[3] | (b[2] << 8) | (b[1] << 16) | (b[0] << 24);
2657 }
2658
2659 /* load only the objects which resolve undefined symbols */
2660 static int tcc_load_alacarte(TCCState *s1, int fd, int size)
2661 {
2662     int i, bound, nsyms, sym_index, off, ret;
2663     uint8_t *data;
2664     const char *ar_names, *p;
2665     const uint8_t *ar_index;
2666     ElfW(Sym) *sym;
2667
2668     data = tcc_malloc(size);
2669     if (read(fd, data, size) != size)
2670         goto fail;
2671     nsyms = get_be32(data);
2672     ar_index = data + 4;
2673     ar_names = ar_index + nsyms * 4;
2674
2675     do {
2676         bound = 0;
2677         for(p = ar_names, i = 0; i < nsyms; i++, p += strlen(p)+1) {
2678             sym_index = find_elf_sym(symtab_section, p);
2679             if(sym_index) {
2680                 sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
2681                 if(sym->st_shndx == SHN_UNDEF) {
2682                     off = get_be32(ar_index + i * 4) + sizeof(ArchiveHeader);
2683 #if 0
2684                     printf("%5d\t%s\t%08x\n", i, p, sym->st_shndx);
2685 #endif
2686                     ++bound;
2687                     lseek(fd, off, SEEK_SET);
2688                     if(tcc_load_object_file(s1, fd, off) < 0) {
2689                     fail:
2690                         ret = -1;
2691                         goto the_end;
2692                     }
2693                 }
2694             }
2695         }
2696     } while(bound);
2697     ret = 0;
2698  the_end:
2699     tcc_free(data);
2700     return ret;
2701 }
2702
2703 /* load a '.a' file */
2704 ST_FUNC int tcc_load_archive(TCCState *s1, int fd)
2705 {
2706     ArchiveHeader hdr;
2707     char ar_size[11];
2708     char ar_name[17];
2709     char magic[8];
2710     int size, len, i;
2711     unsigned long file_offset;
2712
2713     /* skip magic which was already checked */
2714     read(fd, magic, sizeof(magic));
2715     
2716     for(;;) {
2717         len = read(fd, &hdr, sizeof(hdr));
2718         if (len == 0)
2719             break;
2720         if (len != sizeof(hdr)) {
2721             tcc_error_noabort("invalid archive");
2722             return -1;
2723         }
2724         memcpy(ar_size, hdr.ar_size, sizeof(hdr.ar_size));
2725         ar_size[sizeof(hdr.ar_size)] = '\0';
2726         size = strtol(ar_size, NULL, 0);
2727         memcpy(ar_name, hdr.ar_name, sizeof(hdr.ar_name));
2728         for(i = sizeof(hdr.ar_name) - 1; i >= 0; i--) {
2729             if (ar_name[i] != ' ')
2730                 break;
2731         }
2732         ar_name[i + 1] = '\0';
2733         //        printf("name='%s' size=%d %s\n", ar_name, size, ar_size);
2734         file_offset = lseek(fd, 0, SEEK_CUR);
2735         /* align to even */
2736         size = (size + 1) & ~1;
2737         if (!strcmp(ar_name, "/")) {
2738             /* coff symbol table : we handle it */
2739             if(s1->alacarte_link)
2740                 return tcc_load_alacarte(s1, fd, size);
2741         } else if (!strcmp(ar_name, "//") ||
2742                    !strcmp(ar_name, "__.SYMDEF") ||
2743                    !strcmp(ar_name, "__.SYMDEF/") ||
2744                    !strcmp(ar_name, "ARFILENAMES/")) {
2745             /* skip symbol table or archive names */
2746         } else {
2747             if (tcc_load_object_file(s1, fd, file_offset) < 0)
2748                 return -1;
2749         }
2750         lseek(fd, file_offset + size, SEEK_SET);
2751     }
2752     return 0;
2753 }
2754
2755 #ifndef TCC_TARGET_PE
2756 /* load a DLL and all referenced DLLs. 'level = 0' means that the DLL
2757    is referenced by the user (so it should be added as DT_NEEDED in
2758    the generated ELF file) */
2759 ST_FUNC int tcc_load_dll(TCCState *s1, int fd, const char *filename, int level)
2760
2761     ElfW(Ehdr) ehdr;
2762     ElfW(Shdr) *shdr, *sh, *sh1;
2763     int i, j, nb_syms, nb_dts, sym_bind, ret;
2764     ElfW(Sym) *sym, *dynsym;
2765     ElfW(Dyn) *dt, *dynamic;
2766     unsigned char *dynstr;
2767     const char *name, *soname;
2768     DLLReference *dllref;
2769     
2770     read(fd, &ehdr, sizeof(ehdr));
2771
2772     /* test CPU specific stuff */
2773     if (ehdr.e_ident[5] != ELFDATA2LSB ||
2774         ehdr.e_machine != EM_TCC_TARGET) {
2775         tcc_error_noabort("bad architecture");
2776         return -1;
2777     }
2778
2779     /* read sections */
2780     shdr = load_data(fd, ehdr.e_shoff, sizeof(ElfW(Shdr)) * ehdr.e_shnum);
2781
2782     /* load dynamic section and dynamic symbols */
2783     nb_syms = 0;
2784     nb_dts = 0;
2785     dynamic = NULL;
2786     dynsym = NULL; /* avoid warning */
2787     dynstr = NULL; /* avoid warning */
2788     for(i = 0, sh = shdr; i < ehdr.e_shnum; i++, sh++) {
2789         switch(sh->sh_type) {
2790         case SHT_DYNAMIC:
2791             nb_dts = sh->sh_size / sizeof(ElfW(Dyn));
2792             dynamic = load_data(fd, sh->sh_offset, sh->sh_size);
2793             break;
2794         case SHT_DYNSYM:
2795             nb_syms = sh->sh_size / sizeof(ElfW(Sym));
2796             dynsym = load_data(fd, sh->sh_offset, sh->sh_size);
2797             sh1 = &shdr[sh->sh_link];
2798             dynstr = load_data(fd, sh1->sh_offset, sh1->sh_size);
2799             break;
2800         default:
2801             break;
2802         }
2803     }
2804     
2805     /* compute the real library name */
2806     soname = tcc_basename(filename);
2807         
2808     for(i = 0, dt = dynamic; i < nb_dts; i++, dt++) {
2809         if (dt->d_tag == DT_SONAME) {
2810             soname = dynstr + dt->d_un.d_val;
2811         }
2812     }
2813
2814     /* if the dll is already loaded, do not load it */
2815     for(i = 0; i < s1->nb_loaded_dlls; i++) {
2816         dllref = s1->loaded_dlls[i];
2817         if (!strcmp(soname, dllref->name)) {
2818             /* but update level if needed */
2819             if (level < dllref->level)
2820                 dllref->level = level;
2821             ret = 0;
2822             goto the_end;
2823         }
2824     }
2825     
2826     //    printf("loading dll '%s'\n", soname);
2827
2828     /* add the dll and its level */
2829     dllref = tcc_mallocz(sizeof(DLLReference) + strlen(soname));
2830     dllref->level = level;
2831     strcpy(dllref->name, soname);
2832     dynarray_add((void ***)&s1->loaded_dlls, &s1->nb_loaded_dlls, dllref);
2833
2834     /* add dynamic symbols in dynsym_section */
2835     for(i = 1, sym = dynsym + 1; i < nb_syms; i++, sym++) {
2836         sym_bind = ELFW(ST_BIND)(sym->st_info);
2837         if (sym_bind == STB_LOCAL)
2838             continue;
2839         name = dynstr + sym->st_name;
2840         add_elf_sym(s1->dynsymtab_section, sym->st_value, sym->st_size,
2841                     sym->st_info, sym->st_other, sym->st_shndx, name);
2842     }
2843
2844     /* load all referenced DLLs */
2845     for(i = 0, dt = dynamic; i < nb_dts; i++, dt++) {
2846         switch(dt->d_tag) {
2847         case DT_NEEDED:
2848             name = dynstr + dt->d_un.d_val;
2849             for(j = 0; j < s1->nb_loaded_dlls; j++) {
2850                 dllref = s1->loaded_dlls[j];
2851                 if (!strcmp(name, dllref->name))
2852                     goto already_loaded;
2853             }
2854             if (tcc_add_dll(s1, name, AFF_REFERENCED_DLL) < 0) {
2855                 tcc_error_noabort("referenced dll '%s' not found", name);
2856                 ret = -1;
2857                 goto the_end;
2858             }
2859         already_loaded:
2860             break;
2861         }
2862     }
2863     ret = 0;
2864  the_end:
2865     tcc_free(dynstr);
2866     tcc_free(dynsym);
2867     tcc_free(dynamic);
2868     tcc_free(shdr);
2869     return ret;
2870 }
2871
2872 #define LD_TOK_NAME 256
2873 #define LD_TOK_EOF  (-1)
2874
2875 /* return next ld script token */
2876 static int ld_next(TCCState *s1, char *name, int name_size)
2877 {
2878     int c;
2879     char *q;
2880
2881  redo:
2882     switch(ch) {
2883     case ' ':
2884     case '\t':
2885     case '\f':
2886     case '\v':
2887     case '\r':
2888     case '\n':
2889         inp();
2890         goto redo;
2891     case '/':
2892         minp();
2893         if (ch == '*') {
2894             file->buf_ptr = parse_comment(file->buf_ptr);
2895             ch = file->buf_ptr[0];
2896             goto redo;
2897         } else {
2898             q = name;
2899             *q++ = '/';
2900             goto parse_name;
2901         }
2902         break;
2903     /* case 'a' ... 'z': */
2904     case 'a':
2905        case 'b':
2906        case 'c':
2907        case 'd':
2908        case 'e':
2909        case 'f':
2910        case 'g':
2911        case 'h':
2912        case 'i':
2913        case 'j':
2914        case 'k':
2915        case 'l':
2916        case 'm':
2917        case 'n':
2918        case 'o':
2919        case 'p':
2920        case 'q':
2921        case 'r':
2922        case 's':
2923        case 't':
2924        case 'u':
2925        case 'v':
2926        case 'w':
2927        case 'x':
2928        case 'y':
2929        case 'z':
2930     /* case 'A' ... 'z': */
2931     case 'A':
2932        case 'B':
2933        case 'C':
2934        case 'D':
2935        case 'E':
2936        case 'F':
2937        case 'G':
2938        case 'H':
2939        case 'I':
2940        case 'J':
2941        case 'K':
2942        case 'L':
2943        case 'M':
2944        case 'N':
2945        case 'O':
2946        case 'P':
2947        case 'Q':
2948        case 'R':
2949        case 'S':
2950        case 'T':
2951        case 'U':
2952        case 'V':
2953        case 'W':
2954        case 'X':
2955        case 'Y':
2956        case 'Z':
2957     case '_':
2958     case '\\':
2959     case '.':
2960     case '$':
2961     case '~':
2962         q = name;
2963     parse_name:
2964         for(;;) {
2965             if (!((ch >= 'a' && ch <= 'z') ||
2966                   (ch >= 'A' && ch <= 'Z') ||
2967                   (ch >= '0' && ch <= '9') ||
2968                   strchr("/.-_+=$:\\,~", ch)))
2969                 break;
2970             if ((q - name) < name_size - 1) {
2971                 *q++ = ch;
2972             }
2973             minp();
2974         }
2975         *q = '\0';
2976         c = LD_TOK_NAME;
2977         break;
2978     case CH_EOF:
2979         c = LD_TOK_EOF;
2980         break;
2981     default:
2982         c = ch;
2983         inp();
2984         break;
2985     }
2986 #if 0
2987     printf("tok=%c %d\n", c, c);
2988     if (c == LD_TOK_NAME)
2989         printf("  name=%s\n", name);
2990 #endif
2991     return c;
2992 }
2993
2994 static int ld_add_file(TCCState *s1, const char filename[])
2995 {
2996     int ret;
2997
2998     ret = tcc_add_file_internal(s1, filename, 0);
2999     if (ret)
3000         ret = tcc_add_dll(s1, filename, 0);
3001     return ret;
3002 }
3003
3004 static inline int new_undef_syms(void)
3005 {
3006     int ret = 0;
3007     ret = new_undef_sym;
3008     new_undef_sym = 0;
3009     return ret;
3010 }
3011
3012 static int ld_add_file_list(TCCState *s1, const char *cmd, int as_needed)
3013 {
3014     char filename[1024], libname[1024];
3015     int t, group, nblibs = 0, ret = 0;
3016     char **libs = NULL;
3017
3018     group = !strcmp(cmd, "GROUP");
3019     if (!as_needed)
3020         new_undef_syms();
3021     t = ld_next(s1, filename, sizeof(filename));
3022     if (t != '(')
3023         expect("(");
3024     t = ld_next(s1, filename, sizeof(filename));
3025     for(;;) {
3026         libname[0] = '\0';
3027         if (t == LD_TOK_EOF) {
3028             tcc_error_noabort("unexpected end of file");
3029             ret = -1;
3030             goto lib_parse_error;
3031         } else if (t == ')') {
3032             break;
3033         } else if (t == '-') {
3034             t = ld_next(s1, filename, sizeof(filename));
3035             if ((t != LD_TOK_NAME) || (filename[0] != 'l')) {
3036                 tcc_error_noabort("library name expected");
3037                 ret = -1;
3038                 goto lib_parse_error;
3039             }
3040             pstrcpy(libname, sizeof libname, &filename[1]);
3041             if (s1->static_link) {
3042                 snprintf(filename, sizeof filename, "lib%s.a", libname);
3043             } else {
3044                 snprintf(filename, sizeof filename, "lib%s.so", libname);
3045             }
3046         } else if (t != LD_TOK_NAME) {
3047             tcc_error_noabort("filename expected");
3048             ret = -1;
3049             goto lib_parse_error;
3050         }
3051         if (!strcmp(filename, "AS_NEEDED")) {
3052             ret = ld_add_file_list(s1, cmd, 1);
3053             if (ret)
3054                 goto lib_parse_error;
3055         } else {
3056             /* TODO: Implement AS_NEEDED support. Ignore it for now */
3057             if (!as_needed) {
3058                 ret = ld_add_file(s1, filename);
3059                 if (ret)
3060                     goto lib_parse_error;
3061                 if (group) {
3062                     /* Add the filename *and* the libname to avoid future conversions */
3063                     dynarray_add((void ***) &libs, &nblibs, tcc_strdup(filename));
3064                     if (libname[0] != '\0')
3065                         dynarray_add((void ***) &libs, &nblibs, tcc_strdup(libname));
3066                 }
3067             }
3068         }
3069         t = ld_next(s1, filename, sizeof(filename));
3070         if (t == ',') {
3071             t = ld_next(s1, filename, sizeof(filename));
3072         }
3073     }
3074     if (group && !as_needed) {
3075         while (new_undef_syms()) {
3076             int i;
3077
3078             for (i = 0; i < nblibs; i ++)
3079                 ld_add_file(s1, libs[i]);
3080         }
3081     }
3082 lib_parse_error:
3083     dynarray_reset(&libs, &nblibs);
3084     return ret;
3085 }
3086
3087 /* interpret a subset of GNU ldscripts to handle the dummy libc.so
3088    files */
3089 ST_FUNC int tcc_load_ldscript(TCCState *s1)
3090 {
3091     char cmd[64];
3092     char filename[1024];
3093     int t, ret;
3094     
3095     ch = file->buf_ptr[0];
3096     ch = handle_eob();
3097     for(;;) {
3098         t = ld_next(s1, cmd, sizeof(cmd));
3099         if (t == LD_TOK_EOF)
3100             return 0;
3101         else if (t != LD_TOK_NAME)
3102             return -1;
3103         if (!strcmp(cmd, "INPUT") ||
3104             !strcmp(cmd, "GROUP")) {
3105             ret = ld_add_file_list(s1, cmd, 0);
3106             if (ret)
3107                 return ret;
3108         } else if (!strcmp(cmd, "OUTPUT_FORMAT") ||
3109                    !strcmp(cmd, "TARGET")) {
3110             /* ignore some commands */
3111             t = ld_next(s1, cmd, sizeof(cmd));
3112             if (t != '(')
3113                 expect("(");
3114             for(;;) {
3115                 t = ld_next(s1, filename, sizeof(filename));
3116                 if (t == LD_TOK_EOF) {
3117                     tcc_error_noabort("unexpected end of file");
3118                     return -1;
3119                 } else if (t == ')') {
3120                     break;
3121                 }
3122             }
3123         } else {
3124             return -1;
3125         }
3126     }
3127     return 0;
3128 }
3129 #endif /* ndef TCC_TARGET_PE */