Subversion Repositories Kolibri OS

Rev

Rev 145 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
145 halyavin 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
static int put_elf_str(Section *s, const char *sym)
22
{
23
    int offset, len;
24
    char *ptr;
25
 
26
    len = strlen(sym) + 1;
27
    offset = s->data_offset;
28
    ptr = section_ptr_add(s, len);
29
    memcpy(ptr, sym, len);
30
    return offset;
31
}
32
 
33
/* elf symbol hashing function */
34
static unsigned long elf_hash(const unsigned char *name)
35
{
36
    unsigned long h = 0, g;
37
 
38
    while (*name) {
39
        h = (h << 4) + *name++;
40
        g = h & 0xf0000000;
41
        if (g)
42
            h ^= g >> 24;
43
        h &= ~g;
44
    }
45
    return h;
46
}
47
 
48
/* rebuild hash table of section s */
49
/* NOTE: we do factorize the hash table code to go faster */
50
static void rebuild_hash(Section *s, unsigned int nb_buckets)
51
{
52
    Elf32_Sym *sym;
53
    int *ptr, *hash, nb_syms, sym_index, h;
54
    char *strtab;
55
 
56
    strtab = s->link->data;
57
    nb_syms = s->data_offset / sizeof(Elf32_Sym);
58
 
59
    s->hash->data_offset = 0;
60
    ptr = section_ptr_add(s->hash, (2 + nb_buckets + nb_syms) * sizeof(int));
61
    ptr[0] = nb_buckets;
62
    ptr[1] = nb_syms;
63
    ptr += 2;
64
    hash = ptr;
65
    memset(hash, 0, (nb_buckets + 1) * sizeof(int));
66
    ptr += nb_buckets + 1;
67
 
68
    sym = (Elf32_Sym *)s->data + 1;
69
    for(sym_index = 1; sym_index < nb_syms; sym_index++) {
70
        if (ELF32_ST_BIND(sym->st_info) != STB_LOCAL) {
71
            h = elf_hash(strtab + sym->st_name) % nb_buckets;
72
            *ptr = hash[h];
73
            hash[h] = sym_index;
74
        } else {
75
            *ptr = 0;
76
        }
77
        ptr++;
78
        sym++;
79
    }
80
}
81
 
82
/* return the symbol number */
83
static int put_elf_sym(Section *s,
84
                       unsigned long value, unsigned long size,
85
                       int info, int other, int shndx, const char *name)
86
{
87
    int name_offset, sym_index;
88
    int nbuckets, h;
89
    Elf32_Sym *sym;
90
    Section *hs;
91
 
92
    sym = section_ptr_add(s, sizeof(Elf32_Sym));
93
    if (name)
94
        name_offset = put_elf_str(s->link, name);
95
    else
96
        name_offset = 0;
97
    /* XXX: endianness */
98
    sym->st_name = name_offset;
99
    sym->st_value = value;
100
    sym->st_size = size;
101
    sym->st_info = info;
102
    sym->st_other = other;
103
    sym->st_shndx = shndx;
104
    sym_index = sym - (Elf32_Sym *)s->data;
105
    hs = s->hash;
106
    if (hs) {
107
        int *ptr, *base;
108
        ptr = section_ptr_add(hs, sizeof(int));
109
        base = (int *)hs->data;
110
        /* only add global or weak symbols */
111
        if (ELF32_ST_BIND(info) != STB_LOCAL) {
112
            /* add another hashing entry */
113
            nbuckets = base[0];
114
            h = elf_hash(name) % nbuckets;
115
            *ptr = base[2 + h];
116
            base[2 + h] = sym_index;
117
            base[1]++;
118
            /* we resize the hash table */
119
            hs->nb_hashed_syms++;
120
            if (hs->nb_hashed_syms > 2 * nbuckets) {
121
                rebuild_hash(s, 2 * nbuckets);
122
            }
123
        } else {
124
            *ptr = 0;
125
            base[1]++;
126
        }
127
    }
128
    return sym_index;
129
}
130
 
131
/* find global ELF symbol 'name' and return its index. Return 0 if not
132
   found. */
133
static int find_elf_sym(Section *s, const char *name)
134
{
135
    Elf32_Sym *sym;
136
    Section *hs;
137
    int nbuckets, sym_index, h;
138
    const char *name1;
139
 
140
    hs = s->hash;
141
    if (!hs)
142
        return 0;
143
    nbuckets = ((int *)hs->data)[0];
144
    h = elf_hash(name) % nbuckets;
145
    sym_index = ((int *)hs->data)[2 + h];
146
    while (sym_index != 0) {
147
        sym = &((Elf32_Sym *)s->data)[sym_index];
148
        name1 = s->link->data + sym->st_name;
149
        if (!strcmp(name, name1))
150
            return sym_index;
151
        sym_index = ((int *)hs->data)[2 + nbuckets + sym_index];
152
    }
153
    return 0;
154
}
155
 
156
/* return elf symbol value or error */
157
int tcc_get_symbol(TCCState *s, unsigned long *pval, const char *name)
158
{
159
    int sym_index;
160
    Elf32_Sym *sym;
161
 
162
    sym_index = find_elf_sym(symtab_section, name);
163
    if (!sym_index)
164
        return -1;
165
    sym = &((Elf32_Sym *)symtab_section->data)[sym_index];
166
    *pval = sym->st_value;
167
    return 0;
168
}
169
 
170
void *tcc_get_symbol_err(TCCState *s, const char *name)
171
{
172
    unsigned long val;
173
    if (tcc_get_symbol(s, &val, name) < 0)
174
        error("%s not defined", name);
175
    return (void *)val;
176
}
177
 
178
/* add an elf symbol : check if it is already defined and patch
179
   it. Return symbol index. NOTE that sh_num can be SHN_UNDEF. */
180
static int add_elf_sym(Section *s, unsigned long value, unsigned long size,
181
                       int info, int other, int sh_num, const char *name)
182
{
183
    Elf32_Sym *esym;
184
    int sym_bind, sym_index, sym_type, esym_bind;
185
 
186
    sym_bind = ELF32_ST_BIND(info);
187
    sym_type = ELF32_ST_TYPE(info);
188
 
189
    if (sym_bind != STB_LOCAL) {
190
        /* we search global or weak symbols */
191
        sym_index = find_elf_sym(s, name);
192
        if (!sym_index)
193
            goto do_def;
194
        esym = &((Elf32_Sym *)s->data)[sym_index];
195
        if (esym->st_shndx != SHN_UNDEF) {
196
            esym_bind = ELF32_ST_BIND(esym->st_info);
197
            if (sh_num == SHN_UNDEF) {
198
                /* ignore adding of undefined symbol if the
199
                   corresponding symbol is already defined */
200
            } else if (sym_bind == STB_GLOBAL && esym_bind == STB_WEAK) {
201
                /* global overrides weak, so patch */
202
                goto do_patch;
203
            } else if (sym_bind == STB_WEAK && esym_bind == STB_GLOBAL) {
204
                /* weak is ignored if already global */
205
            } else {
206
#if 0
207
                printf("new_bind=%d new_shndx=%d last_bind=%d old_shndx=%d\n",
208
                       sym_bind, sh_num, esym_bind, esym->st_shndx);
209
#endif
210
                /* NOTE: we accept that two DLL define the same symbol */
211
                if (s != tcc_state->dynsymtab_section)
212
                    error_noabort("'%s' defined twice", name);
213
            }
214
        } else {
215
        do_patch:
216
            esym->st_info = ELF32_ST_INFO(sym_bind, sym_type);
217
            esym->st_shndx = sh_num;
218
            esym->st_value = value;
219
            esym->st_size = size;
220
            esym->st_other = other;
221
        }
222
    } else {
223
    do_def:
224
        sym_index = put_elf_sym(s, value, size,
225
                                ELF32_ST_INFO(sym_bind, sym_type), other,
226
                                sh_num, name);
227
    }
228
    return sym_index;
229
}
230
 
231
/* put relocation */
232
static void put_elf_reloc(Section *symtab, Section *s, unsigned long offset,
233
                          int type, int symbol)
234
{
235
    char buf[256];
236
    Section *sr;
237
    Elf32_Rel *rel;
238
 
239
    sr = s->reloc;
240
    if (!sr) {
241
        /* if no relocation section, create it */
242
        snprintf(buf, sizeof(buf), ".rel%s", s->name);
243
        /* if the symtab is allocated, then we consider the relocation
244
           are also */
245
        sr = new_section(tcc_state, buf, SHT_REL, symtab->sh_flags);
246
        sr->sh_entsize = sizeof(Elf32_Rel);
247
        sr->link = symtab;
248
        sr->sh_info = s->sh_num;
249
        s->reloc = sr;
250
    }
251
    rel = section_ptr_add(sr, sizeof(Elf32_Rel));
252
    rel->r_offset = offset;
253
    rel->r_info = ELF32_R_INFO(symbol, type);
254
}
255
 
256
/* put stab debug information */
257
 
258
typedef struct {
259
    unsigned long n_strx;         /* index into string table of name */
260
    unsigned char n_type;         /* type of symbol */
261
    unsigned char n_other;        /* misc info (usually empty) */
262
    unsigned short n_desc;        /* description field */
263
    unsigned long n_value;        /* value of symbol */
264
} Stab_Sym;
265
 
266
static void put_stabs(const char *str, int type, int other, int desc,
267
                      unsigned long value)
268
{
269
    Stab_Sym *sym;
270
 
271
    sym = section_ptr_add(stab_section, sizeof(Stab_Sym));
272
    if (str) {
273
        sym->n_strx = put_elf_str(stabstr_section, str);
274
    } else {
275
        sym->n_strx = 0;
276
    }
277
    sym->n_type = type;
278
    sym->n_other = other;
279
    sym->n_desc = desc;
280
    sym->n_value = value;
281
}
282
 
283
static void put_stabs_r(const char *str, int type, int other, int desc,
284
                        unsigned long value, Section *sec, int sym_index)
285
{
286
    put_stabs(str, type, other, desc, value);
287
    put_elf_reloc(symtab_section, stab_section,
288
                  stab_section->data_offset - sizeof(unsigned long),
289
                  R_DATA_32, sym_index);
290
}
291
 
292
static void put_stabn(int type, int other, int desc, int value)
293
{
294
    put_stabs(NULL, type, other, desc, value);
295
}
296
 
297
static void put_stabd(int type, int other, int desc)
298
{
299
    put_stabs(NULL, type, other, desc, 0);
300
}
301
 
302
/* In an ELF file symbol table, the local symbols must appear below
303
   the global and weak ones. Since TCC cannot sort it while generating
304
   the code, we must do it after. All the relocation tables are also
305
   modified to take into account the symbol table sorting */
306
static void sort_syms(TCCState *s1, Section *s)
307
{
308
    int *old_to_new_syms;
309
    Elf32_Sym *new_syms;
310
    int nb_syms, i;
311
    Elf32_Sym *p, *q;
312
    Elf32_Rel *rel, *rel_end;
313
    Section *sr;
314
    int type, sym_index;
315
 
316
    nb_syms = s->data_offset / sizeof(Elf32_Sym);
317
    new_syms = tcc_malloc(nb_syms * sizeof(Elf32_Sym));
318
    old_to_new_syms = tcc_malloc(nb_syms * sizeof(int));
319
 
320
    /* first pass for local symbols */
321
    p = (Elf32_Sym *)s->data;
322
    q = new_syms;
323
    for(i = 0; i < nb_syms; i++) {
324
        if (ELF32_ST_BIND(p->st_info) == STB_LOCAL) {
325
            old_to_new_syms[i] = q - new_syms;
326
            *q++ = *p;
327
        }
328
        p++;
329
    }
330
    /* save the number of local symbols in section header */
331
    s->sh_info = q - new_syms;
332
 
333
    /* then second pass for non local symbols */
334
    p = (Elf32_Sym *)s->data;
335
    for(i = 0; i < nb_syms; i++) {
336
        if (ELF32_ST_BIND(p->st_info) != STB_LOCAL) {
337
            old_to_new_syms[i] = q - new_syms;
338
            *q++ = *p;
339
        }
340
        p++;
341
    }
342
 
343
    /* we copy the new symbols to the old */
344
    memcpy(s->data, new_syms, nb_syms * sizeof(Elf32_Sym));
345
    tcc_free(new_syms);
346
 
347
    /* now we modify all the relocations */
348
    for(i = 1; i < s1->nb_sections; i++) {
349
        sr = s1->sections[i];
350
        if (sr->sh_type == SHT_REL && sr->link == s) {
351
            rel_end = (Elf32_Rel *)(sr->data + sr->data_offset);
352
            for(rel = (Elf32_Rel *)sr->data;
353
                rel < rel_end;
354
                rel++) {
355
                sym_index = ELF32_R_SYM(rel->r_info);
356
                type = ELF32_R_TYPE(rel->r_info);
357
                sym_index = old_to_new_syms[sym_index];
358
                rel->r_info = ELF32_R_INFO(sym_index, type);
359
            }
360
        }
361
    }
362
 
363
    tcc_free(old_to_new_syms);
364
}
365
 
366
/* relocate common symbols in the .bss section */
367
static void relocate_common_syms(void)
368
{
369
    Elf32_Sym *sym, *sym_end;
370
    unsigned long offset, align;
371
 
372
    sym_end = (Elf32_Sym *)(symtab_section->data + symtab_section->data_offset);
373
    for(sym = (Elf32_Sym *)symtab_section->data + 1;
374
        sym < sym_end;
375
        sym++) {
376
        if (sym->st_shndx == SHN_COMMON) {
377
            /* align symbol */
378
            align = sym->st_value;
379
            offset = bss_section->data_offset;
380
            offset = (offset + align - 1) & -align;
381
            sym->st_value = offset;
382
            sym->st_shndx = bss_section->sh_num;
383
            offset += sym->st_size;
384
            bss_section->data_offset = offset;
385
        }
386
    }
387
}
388
 
389
/* relocate symbol table, resolve undefined symbols if do_resolve is
390
   true and output error if undefined symbol. */
391
static void relocate_syms(TCCState *s1, int do_resolve)
392
{
393
    Elf32_Sym *sym, *esym, *sym_end;
394
    int sym_bind, sh_num, sym_index;
395
    const char *name;
396
    unsigned long addr;
397
 
398
    sym_end = (Elf32_Sym *)(symtab_section->data + symtab_section->data_offset);
399
    for(sym = (Elf32_Sym *)symtab_section->data + 1;
400
        sym < sym_end;
401
        sym++) {
402
        sh_num = sym->st_shndx;
403
        if (sh_num == SHN_UNDEF) {
404
            name = strtab_section->data + sym->st_name;
405
            if (do_resolve) {
406
                name = symtab_section->link->data + sym->st_name;
407
                addr = (unsigned long)resolve_sym(s1, name, ELF32_ST_TYPE(sym->st_info));
408
                if (addr) {
409
                    sym->st_value = addr;
410
                    goto found;
411
                }
412
            } else if (s1->dynsym) {
413
                /* if dynamic symbol exist, then use it */
414
                sym_index = find_elf_sym(s1->dynsym, name);
415
                if (sym_index) {
416
                    esym = &((Elf32_Sym *)s1->dynsym->data)[sym_index];
417
                    sym->st_value = esym->st_value;
418
                    goto found;
419
                }
420
            }
421
            /* XXX: _fp_hw seems to be part of the ABI, so we ignore
422
               it */
423
            if (!strcmp(name, "_fp_hw"))
424
                goto found;
425
            /* only weak symbols are accepted to be undefined. Their
426
               value is zero */
427
            sym_bind = ELF32_ST_BIND(sym->st_info);
428
            if (sym_bind == STB_WEAK) {
429
                sym->st_value = 0;
430
            } else {
431
                error_noabort("undefined symbol '%s'", name);
432
            }
433
        } else if (sh_num < SHN_LORESERVE) {
434
            /* add section base */
435
            sym->st_value += s1->sections[sym->st_shndx]->sh_addr;
436
        }
437
    found: ;
438
    }
439
}
440
 
441
/* relocate a given section (CPU dependent) */
442
static void relocate_section(TCCState *s1, Section *s)
443
{
444
    Section *sr;
445
    Elf32_Rel *rel, *rel_end, *qrel;
446
    Elf32_Sym *sym;
447
    int type, sym_index;
448
    unsigned char *ptr;
449
    unsigned long val, addr;
450
#if defined(TCC_TARGET_I386)
451
    int esym_index;
452
#endif
453
 
454
    sr = s->reloc;
455
    rel_end = (Elf32_Rel *)(sr->data + sr->data_offset);
456
    qrel = (Elf32_Rel *)sr->data;
457
    for(rel = qrel;
458
        rel < rel_end;
459
        rel++) {
460
        ptr = s->data + rel->r_offset;
461
 
462
        sym_index = ELF32_R_SYM(rel->r_info);
463
        sym = &((Elf32_Sym *)symtab_section->data)[sym_index];
464
        val = sym->st_value;
465
        type = ELF32_R_TYPE(rel->r_info);
466
        addr = s->sh_addr + rel->r_offset;
467
 
468
        /* CPU specific */
469
        switch(type) {
470
#if defined(TCC_TARGET_I386)
471
        case R_386_32:
472
            if (s1->output_type == TCC_OUTPUT_DLL) {
473
                esym_index = s1->symtab_to_dynsym[sym_index];
474
                qrel->r_offset = rel->r_offset;
475
                if (esym_index) {
476
                    qrel->r_info = ELF32_R_INFO(esym_index, R_386_32);
477
                    qrel++;
478
                    break;
479
                } else {
480
                    qrel->r_info = ELF32_R_INFO(0, R_386_RELATIVE);
481
                    qrel++;
482
                }
483
            }
484
            *(int *)ptr += val;
485
            break;
486
        case R_386_PC32:
487
            if (s1->output_type == TCC_OUTPUT_DLL) {
488
                /* DLL relocation */
489
                esym_index = s1->symtab_to_dynsym[sym_index];
490
                if (esym_index) {
491
                    qrel->r_offset = rel->r_offset;
492
                    qrel->r_info = ELF32_R_INFO(esym_index, R_386_PC32);
493
                    qrel++;
494
                    break;
495
                }
496
            }
497
            *(int *)ptr += val - addr;
498
            break;
499
        case R_386_PLT32:
500
            *(int *)ptr += val - addr;
501
            break;
502
        case R_386_GLOB_DAT:
503
        case R_386_JMP_SLOT:
504
            *(int *)ptr = val;
505
            break;
506
        case R_386_GOTPC:
507
            *(int *)ptr += s1->got->sh_addr - addr;
508
            break;
509
        case R_386_GOTOFF:
510
            *(int *)ptr += val - s1->got->sh_addr;
511
            break;
512
        case R_386_GOT32:
513
            /* we load the got offset */
514
            *(int *)ptr += s1->got_offsets[sym_index];
515
            break;
516
#elif defined(TCC_TARGET_ARM)
517
	case R_ARM_PC24:
518
	case R_ARM_PLT32:
519
	    {
520
                int x;
521
                x = (*(int *)ptr)&0xffffff;
522
                (*(int *)ptr) &= 0xff000000;
523
                if (x & 0x800000)
524
                    x -= 0x1000000;
525
                x *= 4;
526
                x += val - addr;
527
                if((x & 3) != 0 || x >= 0x4000000 || x < -0x4000000)
528
                    error("can't relocate value at %x",addr);
529
                x >>= 2;
530
                x &= 0xffffff;
531
                (*(int *)ptr) |= x;
532
	    }
533
	    break;
534
	case R_ARM_ABS32:
535
	    *(int *)ptr += val;
536
	    break;
537
	case R_ARM_GOTPC:
538
	    *(int *)ptr += s1->got->sh_addr - addr;
539
	    break;
540
        case R_ARM_GOT32:
541
            /* we load the got offset */
542
            *(int *)ptr += s1->got_offsets[sym_index];
543
            break;
544
	case R_ARM_COPY:
545
            break;
546
	default:
547
	    fprintf(stderr,"FIXME: handle reloc type %x at %lx [%.8x] to %lx\n",
548
                    type,addr,(unsigned int )ptr,val);
549
            break;
550
#elif defined(TCC_TARGET_C67)
551
	case R_C60_32:
552
	    *(int *)ptr += val;
553
	    break;
554
        case R_C60LO16:
555
            {
556
                uint32_t orig;
557
 
558
                /* put the low 16 bits of the absolute address */
559
                // add to what is already there
560
 
561
                orig  =   ((*(int *)(ptr  )) >> 7) & 0xffff;
562
                orig |=  (((*(int *)(ptr+4)) >> 7) & 0xffff) << 16;
563
 
564
                //patch both at once - assumes always in pairs Low - High
565
 
566
                *(int *) ptr    = (*(int *) ptr    & (~(0xffff << 7)) ) |  (((val+orig)      & 0xffff) << 7);
567
                *(int *)(ptr+4) = (*(int *)(ptr+4) & (~(0xffff << 7)) ) | ((((val+orig)>>16) & 0xffff) << 7);
568
            }
569
            break;
570
        case R_C60HI16:
571
            break;
572
        default:
573
	    fprintf(stderr,"FIXME: handle reloc type %x at %lx [%.8x] to %lx\n",
574
                    type,addr,(unsigned int )ptr,val);
575
            break;
576
#else
577
#error unsupported processor
578
#endif
579
        }
580
    }
581
    /* if the relocation is allocated, we change its symbol table */
582
    if (sr->sh_flags & SHF_ALLOC)
583
        sr->link = s1->dynsym;
584
}
585
 
586
/* relocate relocation table in 'sr' */
587
static void relocate_rel(TCCState *s1, Section *sr)
588
{
589
    Section *s;
590
    Elf32_Rel *rel, *rel_end;
591
 
592
    s = s1->sections[sr->sh_info];
593
    rel_end = (Elf32_Rel *)(sr->data + sr->data_offset);
594
    for(rel = (Elf32_Rel *)sr->data;
595
        rel < rel_end;
596
        rel++) {
597
        rel->r_offset += s->sh_addr;
598
    }
599
}
600
 
601
/* count the number of dynamic relocations so that we can reserve
602
   their space */
603
static int prepare_dynamic_rel(TCCState *s1, Section *sr)
604
{
605
    Elf32_Rel *rel, *rel_end;
606
    int sym_index, esym_index, type, count;
607
 
608
    count = 0;
609
    rel_end = (Elf32_Rel *)(sr->data + sr->data_offset);
610
    for(rel = (Elf32_Rel *)sr->data; rel < rel_end; rel++) {
611
        sym_index = ELF32_R_SYM(rel->r_info);
612
        type = ELF32_R_TYPE(rel->r_info);
613
        switch(type) {
614
        case R_386_32:
615
            count++;
616
            break;
617
        case R_386_PC32:
618
            esym_index = s1->symtab_to_dynsym[sym_index];
619
            if (esym_index)
620
                count++;
621
            break;
622
        default:
623
            break;
624
        }
625
    }
626
    if (count) {
627
        /* allocate the section */
628
        sr->sh_flags |= SHF_ALLOC;
629
        sr->sh_size = count * sizeof(Elf32_Rel);
630
    }
631
    return count;
632
}
633
 
634
static void put_got_offset(TCCState *s1, int index, unsigned long val)
635
{
636
    int n;
637
    unsigned long *tab;
638
 
639
    if (index >= s1->nb_got_offsets) {
640
        /* find immediately bigger power of 2 and reallocate array */
641
        n = 1;
642
        while (index >= n)
643
            n *= 2;
644
        tab = tcc_realloc(s1->got_offsets, n * sizeof(unsigned long));
645
        if (!tab)
646
            error("memory full");
647
        s1->got_offsets = tab;
648
        memset(s1->got_offsets + s1->nb_got_offsets, 0,
649
               (n - s1->nb_got_offsets) * sizeof(unsigned long));
650
        s1->nb_got_offsets = n;
651
    }
652
    s1->got_offsets[index] = val;
653
}
654
 
655
/* XXX: suppress that */
656
static void put32(unsigned char *p, uint32_t val)
657
{
658
    p[0] = val;
659
    p[1] = val >> 8;
660
    p[2] = val >> 16;
661
    p[3] = val >> 24;
662
}
663
 
664
#if defined(TCC_TARGET_I386) || defined(TCC_TARGET_ARM)
665
static uint32_t get32(unsigned char *p)
666
{
667
    return p[0] | (p[1] << 8) | (p[2] << 16) | (p[3] << 24);
668
}
669
#endif
670
 
671
static void build_got(TCCState *s1)
672
{
673
    unsigned char *ptr;
674
 
675
    /* if no got, then create it */
676
    s1->got = new_section(s1, ".got", SHT_PROGBITS, SHF_ALLOC | SHF_WRITE);
677
    s1->got->sh_entsize = 4;
678
    add_elf_sym(symtab_section, 0, 4, ELF32_ST_INFO(STB_GLOBAL, STT_OBJECT),
679
                0, s1->got->sh_num, "_GLOBAL_OFFSET_TABLE_");
680
    ptr = section_ptr_add(s1->got, 3 * sizeof(int));
681
    /* keep space for _DYNAMIC pointer, if present */
682
    put32(ptr, 0);
683
    /* two dummy got entries */
684
    put32(ptr + 4, 0);
685
    put32(ptr + 8, 0);
686
}
687
 
688
/* put a got entry corresponding to a symbol in symtab_section. 'size'
689
   and 'info' can be modifed if more precise info comes from the DLL */
690
static void put_got_entry(TCCState *s1,
691
                          int reloc_type, unsigned long size, int info,
692
                          int sym_index)
693
{
694
    int index;
695
    const char *name;
696
    Elf32_Sym *sym;
697
    unsigned long offset;
698
    int *ptr;
699
 
700
    if (!s1->got)
701
        build_got(s1);
702
 
703
    /* if a got entry already exists for that symbol, no need to add one */
704
    if (sym_index < s1->nb_got_offsets &&
705
        s1->got_offsets[sym_index] != 0)
706
        return;
707
 
708
    put_got_offset(s1, sym_index, s1->got->data_offset);
709
 
710
    if (s1->dynsym) {
711
        sym = &((Elf32_Sym *)symtab_section->data)[sym_index];
712
        name = symtab_section->link->data + sym->st_name;
713
        offset = sym->st_value;
714
#ifdef TCC_TARGET_I386
715
        if (reloc_type == R_386_JMP_SLOT) {
716
            Section *plt;
717
            uint8_t *p;
718
            int modrm;
719
 
720
            /* if we build a DLL, we add a %ebx offset */
721
            if (s1->output_type == TCC_OUTPUT_DLL)
722
                modrm = 0xa3;
723
            else
724
                modrm = 0x25;
725
 
726
            /* add a PLT entry */
727
            plt = s1->plt;
728
            if (plt->data_offset == 0) {
729
                /* first plt entry */
730
                p = section_ptr_add(plt, 16);
731
                p[0] = 0xff; /* pushl got + 4 */
732
                p[1] = modrm + 0x10;
733
                put32(p + 2, 4);
734
                p[6] = 0xff; /* jmp *(got + 8) */
735
                p[7] = modrm;
736
                put32(p + 8, 8);
737
            }
738
 
739
            p = section_ptr_add(plt, 16);
740
            p[0] = 0xff; /* jmp *(got + x) */
741
            p[1] = modrm;
742
            put32(p + 2, s1->got->data_offset);
743
            p[6] = 0x68; /* push $xxx */
744
            put32(p + 7, (plt->data_offset - 32) >> 1);
745
            p[11] = 0xe9; /* jmp plt_start */
746
            put32(p + 12, -(plt->data_offset));
747
 
748
            /* the symbol is modified so that it will be relocated to
749
               the PLT */
750
            if (s1->output_type == TCC_OUTPUT_EXE)
751
                offset = plt->data_offset - 16;
752
        }
753
#elif defined(TCC_TARGET_ARM)
754
	if (reloc_type == R_ARM_JUMP_SLOT) {
755
            Section *plt;
756
            uint8_t *p;
757
 
758
            /* if we build a DLL, we add a %ebx offset */
759
            if (s1->output_type == TCC_OUTPUT_DLL)
760
                error("DLLs unimplemented!");
761
 
762
            /* add a PLT entry */
763
            plt = s1->plt;
764
            if (plt->data_offset == 0) {
765
                /* first plt entry */
766
                p = section_ptr_add(plt, 16);
767
		put32(p     , 0xe52de004);
768
		put32(p +  4, 0xe59fe010);
769
		put32(p +  8, 0xe08fe00e);
770
		put32(p + 12, 0xe5bef008);
771
            }
772
 
773
            p = section_ptr_add(plt, 16);
774
	    put32(p  , 0xe59fc004);
775
	    put32(p+4, 0xe08fc00c);
776
	    put32(p+8, 0xe59cf000);
777
	    put32(p+12, s1->got->data_offset);
778
 
779
            /* the symbol is modified so that it will be relocated to
780
               the PLT */
781
            if (s1->output_type == TCC_OUTPUT_EXE)
782
                offset = plt->data_offset - 16;
783
        }
784
#elif defined(TCC_TARGET_C67)
785
        error("C67 got not implemented");
786
#else
787
#error unsupported CPU
788
#endif
789
        index = put_elf_sym(s1->dynsym, offset,
790
                            size, info, 0, sym->st_shndx, name);
791
        /* put a got entry */
792
        put_elf_reloc(s1->dynsym, s1->got,
793
                      s1->got->data_offset,
794
                      reloc_type, index);
795
    }
796
    ptr = section_ptr_add(s1->got, sizeof(int));
797
    *ptr = 0;
798
}
799
 
800
/* build GOT and PLT entries */
801
static void build_got_entries(TCCState *s1)
802
{
803
    Section *s, *symtab;
804
    Elf32_Rel *rel, *rel_end;
805
    Elf32_Sym *sym;
806
    int i, type, reloc_type, sym_index;
807
 
808
    for(i = 1; i < s1->nb_sections; i++) {
809
        s = s1->sections[i];
810
        if (s->sh_type != SHT_REL)
811
            continue;
812
        /* no need to handle got relocations */
813
        if (s->link != symtab_section)
814
            continue;
815
        symtab = s->link;
816
        rel_end = (Elf32_Rel *)(s->data + s->data_offset);
817
        for(rel = (Elf32_Rel *)s->data;
818
            rel < rel_end;
819
            rel++) {
820
            type = ELF32_R_TYPE(rel->r_info);
821
            switch(type) {
822
#if defined(TCC_TARGET_I386)
823
            case R_386_GOT32:
824
            case R_386_GOTOFF:
825
            case R_386_GOTPC:
826
            case R_386_PLT32:
827
                if (!s1->got)
828
                    build_got(s1);
829
                if (type == R_386_GOT32 || type == R_386_PLT32) {
830
                    sym_index = ELF32_R_SYM(rel->r_info);
831
                    sym = &((Elf32_Sym *)symtab_section->data)[sym_index];
832
                    /* look at the symbol got offset. If none, then add one */
833
                    if (type == R_386_GOT32)
834
                        reloc_type = R_386_GLOB_DAT;
835
                    else
836
                        reloc_type = R_386_JMP_SLOT;
837
                    put_got_entry(s1, reloc_type, sym->st_size, sym->st_info,
838
                                  sym_index);
839
                }
840
                break;
841
#elif defined(TCC_TARGET_ARM)
842
	    case R_ARM_GOT32:
843
            case R_ARM_GOTOFF:
844
            case R_ARM_GOTPC:
845
            case R_ARM_PLT32:
846
                if (!s1->got)
847
                    build_got(s1);
848
                if (type == R_ARM_GOT32 || type == R_ARM_PLT32) {
849
                    sym_index = ELF32_R_SYM(rel->r_info);
850
                    sym = &((Elf32_Sym *)symtab_section->data)[sym_index];
851
                    /* look at the symbol got offset. If none, then add one */
852
                    if (type == R_ARM_GOT32)
853
                        reloc_type = R_ARM_GLOB_DAT;
854
                    else
855
                        reloc_type = R_ARM_JUMP_SLOT;
856
                    put_got_entry(s1, reloc_type, sym->st_size, sym->st_info,
857
                                  sym_index);
858
                }
859
                break;
860
#elif defined(TCC_TARGET_C67)
861
	    case R_C60_GOT32:
862
            case R_C60_GOTOFF:
863
            case R_C60_GOTPC:
864
            case R_C60_PLT32:
865
                if (!s1->got)
866
                    build_got(s1);
867
                if (type == R_C60_GOT32 || type == R_C60_PLT32) {
868
                    sym_index = ELF32_R_SYM(rel->r_info);
869
                    sym = &((Elf32_Sym *)symtab_section->data)[sym_index];
870
                    /* look at the symbol got offset. If none, then add one */
871
                    if (type == R_C60_GOT32)
872
                        reloc_type = R_C60_GLOB_DAT;
873
                    else
874
                        reloc_type = R_C60_JMP_SLOT;
875
                    put_got_entry(s1, reloc_type, sym->st_size, sym->st_info,
876
                                  sym_index);
877
                }
878
                break;
879
#else
880
#error unsupported CPU
881
#endif
882
            default:
883
                break;
884
            }
885
        }
886
    }
887
}
888
 
889
static Section *new_symtab(TCCState *s1,
890
                           const char *symtab_name, int sh_type, int sh_flags,
891
                           const char *strtab_name,
892
                           const char *hash_name, int hash_sh_flags)
893
{
894
    Section *symtab, *strtab, *hash;
895
    int *ptr, nb_buckets;
896
 
897
    symtab = new_section(s1, symtab_name, sh_type, sh_flags);
898
    symtab->sh_entsize = sizeof(Elf32_Sym);
899
    strtab = new_section(s1, strtab_name, SHT_STRTAB, sh_flags);
900
    put_elf_str(strtab, "");
901
    symtab->link = strtab;
902
    put_elf_sym(symtab, 0, 0, 0, 0, 0, NULL);
903
 
904
    nb_buckets = 1;
905
 
906
    hash = new_section(s1, hash_name, SHT_HASH, hash_sh_flags);
907
    hash->sh_entsize = sizeof(int);
908
    symtab->hash = hash;
909
    hash->link = symtab;
910
 
911
    ptr = section_ptr_add(hash, (2 + nb_buckets + 1) * sizeof(int));
912
    ptr[0] = nb_buckets;
913
    ptr[1] = 1;
914
    memset(ptr + 2, 0, (nb_buckets + 1) * sizeof(int));
915
    return symtab;
916
}
917
 
918
/* put dynamic tag */
919
static void put_dt(Section *dynamic, int dt, unsigned long val)
920
{
921
    Elf32_Dyn *dyn;
922
    dyn = section_ptr_add(dynamic, sizeof(Elf32_Dyn));
923
    dyn->d_tag = dt;
924
    dyn->d_un.d_val = val;
925
}
926
 
927
static void add_init_array_defines(TCCState *s1, const char *section_name)
928
{
929
    Section *s;
930
    long end_offset;
931
    char sym_start[1024];
932
    char sym_end[1024];
933
 
934
    snprintf(sym_start, sizeof(sym_start), "__%s_start", section_name + 1);
935
    snprintf(sym_end, sizeof(sym_end), "__%s_end", section_name + 1);
936
 
937
    s = find_section(s1, section_name);
938
    if (!s) {
939
        end_offset = 0;
940
        s = data_section;
941
    } else {
942
        end_offset = s->data_offset;
943
    }
944
 
945
    add_elf_sym(symtab_section,
946
                0, 0,
947
                ELF32_ST_INFO(STB_GLOBAL, STT_NOTYPE), 0,
948
                s->sh_num, sym_start);
949
    add_elf_sym(symtab_section,
950
                end_offset, 0,
951
                ELF32_ST_INFO(STB_GLOBAL, STT_NOTYPE), 0,
952
                s->sh_num, sym_end);
953
}
954
 
955
/* add tcc runtime libraries */
956
static void tcc_add_runtime(TCCState *s1)
957
{
958
    char buf[1024];
959
 
960
#ifdef CONFIG_TCC_BCHECK
961
    if (do_bounds_check) {
962
        unsigned long *ptr;
963
        Section *init_section;
964
        unsigned char *pinit;
965
        int sym_index;
966
 
967
        /* XXX: add an object file to do that */
968
        ptr = section_ptr_add(bounds_section, sizeof(unsigned long));
969
        *ptr = 0;
970
        add_elf_sym(symtab_section, 0, 0,
971
                    ELF32_ST_INFO(STB_GLOBAL, STT_NOTYPE), 0,
972
                    bounds_section->sh_num, "__bounds_start");
973
        /* add bound check code */
974
        snprintf(buf, sizeof(buf), "%s/%s", tcc_lib_path, "bcheck.o");
975
        tcc_add_file(s1, buf);
976
#ifdef TCC_TARGET_I386
977
        if (s1->output_type != TCC_OUTPUT_MEMORY) {
978
            /* add 'call __bound_init()' in .init section */
979
            init_section = find_section(s1, ".init");
980
            pinit = section_ptr_add(init_section, 5);
981
            pinit[0] = 0xe8;
982
            put32(pinit + 1, -4);
983
            sym_index = find_elf_sym(symtab_section, "__bound_init");
984
            put_elf_reloc(symtab_section, init_section,
985
                          init_section->data_offset - 4, R_386_PC32, sym_index);
986
        }
987
#endif
988
    }
989
#endif
990
    /* add libc */
991
    if (!s1->nostdlib) {
992
        tcc_add_library(s1, "c");
993
 
994
        snprintf(buf, sizeof(buf), "%s/%s", tcc_lib_path, "libtcc1.a");
995
        tcc_add_file(s1, buf);
996
    }
997
    /* add crt end if not memory output */
998
    if (s1->output_type != TCC_OUTPUT_MEMORY && !s1->nostdlib) {
999
        tcc_add_file(s1, CONFIG_TCC_CRT_PREFIX "/crtn.o");
1000
    }
1001
}
1002
 
1003
/* add various standard linker symbols (must be done after the
1004
   sections are filled (for example after allocating common
1005
   symbols)) */
1006
static void tcc_add_linker_symbols(TCCState *s1)
1007
{
1008
    char buf[1024];
1009
    int i;
1010
    Section *s;
1011
 
1012
    add_elf_sym(symtab_section,
1013
                text_section->data_offset, 0,
1014
                ELF32_ST_INFO(STB_GLOBAL, STT_NOTYPE), 0,
1015
                text_section->sh_num, "_etext");
1016
    add_elf_sym(symtab_section,
1017
                data_section->data_offset, 0,
1018
                ELF32_ST_INFO(STB_GLOBAL, STT_NOTYPE), 0,
1019
                data_section->sh_num, "_edata");
1020
    add_elf_sym(symtab_section,
1021
                bss_section->data_offset, 0,
1022
                ELF32_ST_INFO(STB_GLOBAL, STT_NOTYPE), 0,
1023
                bss_section->sh_num, "_end");
1024
    /* horrible new standard ldscript defines */
1025
    add_init_array_defines(s1, ".preinit_array");
1026
    add_init_array_defines(s1, ".init_array");
1027
    add_init_array_defines(s1, ".fini_array");
1028
 
1029
    /* add start and stop symbols for sections whose name can be
1030
       expressed in C */
1031
    for(i = 1; i < s1->nb_sections; i++) {
1032
        s = s1->sections[i];
1033
        if (s->sh_type == SHT_PROGBITS &&
1034
            (s->sh_flags & SHF_ALLOC)) {
1035
            const char *p;
1036
            int ch;
1037
 
1038
            /* check if section name can be expressed in C */
1039
            p = s->name;
1040
            for(;;) {
1041
                ch = *p;
1042
                if (!ch)
1043
                    break;
1044
                if (!isid(ch) && !isnum(ch))
1045
                    goto next_sec;
1046
                p++;
1047
            }
1048
            snprintf(buf, sizeof(buf), "__start_%s", s->name);
1049
            add_elf_sym(symtab_section,
1050
                        0, 0,
1051
                        ELF32_ST_INFO(STB_GLOBAL, STT_NOTYPE), 0,
1052
                        s->sh_num, buf);
1053
            snprintf(buf, sizeof(buf), "__stop_%s", s->name);
1054
            add_elf_sym(symtab_section,
1055
                        s->data_offset, 0,
1056
                        ELF32_ST_INFO(STB_GLOBAL, STT_NOTYPE), 0,
1057
                        s->sh_num, buf);
1058
        }
1059
    next_sec: ;
1060
    }
1061
}
1062
 
1063
/* name of ELF interpreter */
1064
#ifdef __FreeBSD__
1065
static char elf_interp[] = "/usr/libexec/ld-elf.so.1";
1066
#else
1067
static char elf_interp[] = "/lib/ld-linux.so.2";
1068
#endif
1069
 
1070
static void tcc_output_binary(TCCState *s1, FILE *f,
1071
                              const int *section_order)
1072
{
1073
    Section *s;
1074
    int i, offset, size;
1075
 
1076
    offset = 0;
1077
    for(i=1;inb_sections;i++) {
1078
        s = s1->sections[section_order[i]];
1079
        if (s->sh_type != SHT_NOBITS &&
1080
            (s->sh_flags & SHF_ALLOC)) {
1081
            while (offset < s->sh_offset) {
1082
                fputc(0, f);
1083
                offset++;
1084
            }
1085
            size = s->sh_size;
1086
            fwrite(s->data, 1, size, f);
1087
            offset += size;
1088
        }
1089
    }
1090
}
1091
 
1092
/* output an ELF file */
1093
/* XXX: suppress unneeded sections */
1094
int tcc_output_file(TCCState *s1, const char *filename)
1095
{
1096
    Elf32_Ehdr ehdr;
1097
    FILE *f;
1098
    int fd, mode, ret;
1099
    int *section_order;
1100
    int shnum, i, phnum, file_offset, offset, size, j, tmp, sh_order_index, k;
1101
    unsigned long addr;
1102
    Section *strsec, *s;
1103
    Elf32_Shdr shdr, *sh;
1104
    Elf32_Phdr *phdr, *ph;
1105
    Section *interp, *dynamic, *dynstr;
1106
    unsigned long saved_dynamic_data_offset;
1107
    Elf32_Sym *sym;
1108
    int type, file_type;
1109
    unsigned long rel_addr, rel_size;
1110
 
1111
    file_type = s1->output_type;
1112
    s1->nb_errors = 0;
1113
 
1114
    if (file_type != TCC_OUTPUT_OBJ) {
1115
        tcc_add_runtime(s1);
1116
    }
1117
 
1118
    phdr = NULL;
1119
    section_order = NULL;
1120
    interp = NULL;
1121
    dynamic = NULL;
1122
    dynstr = NULL; /* avoid warning */
1123
    saved_dynamic_data_offset = 0; /* avoid warning */
1124
 
1125
    if (file_type != TCC_OUTPUT_OBJ) {
1126
        relocate_common_syms();
1127
 
1128
        tcc_add_linker_symbols(s1);
1129
 
1130
        if (!s1->static_link) {
1131
            const char *name;
1132
            int sym_index, index;
1133
            Elf32_Sym *esym, *sym_end;
1134
 
1135
            if (file_type == TCC_OUTPUT_EXE) {
1136
                char *ptr;
1137
                /* add interpreter section only if executable */
1138
                interp = new_section(s1, ".interp", SHT_PROGBITS, SHF_ALLOC);
1139
                interp->sh_addralign = 1;
1140
                ptr = section_ptr_add(interp, sizeof(elf_interp));
1141
                strcpy(ptr, elf_interp);
1142
            }
1143
 
1144
            /* add dynamic symbol table */
1145
            s1->dynsym = new_symtab(s1, ".dynsym", SHT_DYNSYM, SHF_ALLOC,
1146
                                    ".dynstr",
1147
                                    ".hash", SHF_ALLOC);
1148
            dynstr = s1->dynsym->link;
1149
 
1150
            /* add dynamic section */
1151
            dynamic = new_section(s1, ".dynamic", SHT_DYNAMIC,
1152
                                  SHF_ALLOC | SHF_WRITE);
1153
            dynamic->link = dynstr;
1154
            dynamic->sh_entsize = sizeof(Elf32_Dyn);
1155
 
1156
            /* add PLT */
1157
            s1->plt = new_section(s1, ".plt", SHT_PROGBITS,
1158
                                  SHF_ALLOC | SHF_EXECINSTR);
1159
            s1->plt->sh_entsize = 4;
1160
 
1161
            build_got(s1);
1162
 
1163
            /* scan for undefined symbols and see if they are in the
1164
               dynamic symbols. If a symbol STT_FUNC is found, then we
1165
               add it in the PLT. If a symbol STT_OBJECT is found, we
1166
               add it in the .bss section with a suitable relocation */
1167
            sym_end = (Elf32_Sym *)(symtab_section->data +
1168
                                    symtab_section->data_offset);
1169
            if (file_type == TCC_OUTPUT_EXE) {
1170
                for(sym = (Elf32_Sym *)symtab_section->data + 1;
1171
                    sym < sym_end;
1172
                    sym++) {
1173
                    if (sym->st_shndx == SHN_UNDEF) {
1174
                        name = symtab_section->link->data + sym->st_name;
1175
                        sym_index = find_elf_sym(s1->dynsymtab_section, name);
1176
                        if (sym_index) {
1177
                            esym = &((Elf32_Sym *)s1->dynsymtab_section->data)[sym_index];
1178
                            type = ELF32_ST_TYPE(esym->st_info);
1179
                            if (type == STT_FUNC) {
1180
                                put_got_entry(s1, R_JMP_SLOT, esym->st_size,
1181
                                              esym->st_info,
1182
                                              sym - (Elf32_Sym *)symtab_section->data);
1183
                            } else if (type == STT_OBJECT) {
1184
                                unsigned long offset;
1185
                                offset = bss_section->data_offset;
1186
                                /* XXX: which alignment ? */
1187
                                offset = (offset + 16 - 1) & -16;
1188
                                index = put_elf_sym(s1->dynsym, offset, esym->st_size,
1189
                                                    esym->st_info, 0,
1190
                                                    bss_section->sh_num, name);
1191
                                put_elf_reloc(s1->dynsym, bss_section,
1192
                                              offset, R_COPY, index);
1193
                                offset += esym->st_size;
1194
                                bss_section->data_offset = offset;
1195
                            }
1196
                        } else {
1197
                                /* STB_WEAK undefined symbols are accepted */
1198
                                /* XXX: _fp_hw seems to be part of the ABI, so we ignore
1199
                                   it */
1200
                            if (ELF32_ST_BIND(sym->st_info) == STB_WEAK ||
1201
                                !strcmp(name, "_fp_hw")) {
1202
                            } else {
1203
                                error_noabort("undefined symbol '%s'", name);
1204
                            }
1205
                        }
1206
                    } else if (s1->rdynamic &&
1207
                               ELF32_ST_BIND(sym->st_info) != STB_LOCAL) {
1208
                        /* if -rdynamic option, then export all non
1209
                           local symbols */
1210
                        name = symtab_section->link->data + sym->st_name;
1211
                        put_elf_sym(s1->dynsym, sym->st_value, sym->st_size,
1212
                                    sym->st_info, 0,
1213
                                    sym->st_shndx, name);
1214
                    }
1215
                }
1216
 
1217
                if (s1->nb_errors)
1218
                    goto fail;
1219
 
1220
                /* now look at unresolved dynamic symbols and export
1221
                   corresponding symbol */
1222
                sym_end = (Elf32_Sym *)(s1->dynsymtab_section->data +
1223
                                        s1->dynsymtab_section->data_offset);
1224
                for(esym = (Elf32_Sym *)s1->dynsymtab_section->data + 1;
1225
                    esym < sym_end;
1226
                    esym++) {
1227
                    if (esym->st_shndx == SHN_UNDEF) {
1228
                        name = s1->dynsymtab_section->link->data + esym->st_name;
1229
                        sym_index = find_elf_sym(symtab_section, name);
1230
                        if (sym_index) {
1231
                            /* XXX: avoid adding a symbol if already
1232
                               present because of -rdynamic ? */
1233
                            sym = &((Elf32_Sym *)symtab_section->data)[sym_index];
1234
                            put_elf_sym(s1->dynsym, sym->st_value, sym->st_size,
1235
                                        sym->st_info, 0,
1236
                                        sym->st_shndx, name);
1237
                        } else {
1238
                            if (ELF32_ST_BIND(esym->st_info) == STB_WEAK) {
1239
                                /* weak symbols can stay undefined */
1240
                            } else {
1241
                                warning("undefined dynamic symbol '%s'", name);
1242
                            }
1243
                        }
1244
                    }
1245
                }
1246
            } else {
1247
                int nb_syms;
1248
                /* shared library case : we simply export all the global symbols */
1249
                nb_syms = symtab_section->data_offset / sizeof(Elf32_Sym);
1250
                s1->symtab_to_dynsym = tcc_mallocz(sizeof(int) * nb_syms);
1251
                for(sym = (Elf32_Sym *)symtab_section->data + 1;
1252
                    sym < sym_end;
1253
                    sym++) {
1254
                    if (ELF32_ST_BIND(sym->st_info) != STB_LOCAL) {
1255
                        name = symtab_section->link->data + sym->st_name;
1256
                        index = put_elf_sym(s1->dynsym, sym->st_value, sym->st_size,
1257
                                            sym->st_info, 0,
1258
                                            sym->st_shndx, name);
1259
                        s1->symtab_to_dynsym[sym -
1260
                                            (Elf32_Sym *)symtab_section->data] =
1261
                            index;
1262
                    }
1263
                }
1264
            }
1265
 
1266
            build_got_entries(s1);
1267
 
1268
            /* add a list of needed dlls */
1269
            for(i = 0; i < s1->nb_loaded_dlls; i++) {
1270
                DLLReference *dllref = s1->loaded_dlls[i];
1271
                if (dllref->level == 0)
1272
                    put_dt(dynamic, DT_NEEDED, put_elf_str(dynstr, dllref->name));
1273
            }
1274
            /* XXX: currently, since we do not handle PIC code, we
1275
               must relocate the readonly segments */
1276
            if (file_type == TCC_OUTPUT_DLL)
1277
                put_dt(dynamic, DT_TEXTREL, 0);
1278
 
1279
            /* add necessary space for other entries */
1280
            saved_dynamic_data_offset = dynamic->data_offset;
1281
            dynamic->data_offset += 8 * 9;
1282
        } else {
1283
            /* still need to build got entries in case of static link */
1284
            build_got_entries(s1);
1285
        }
1286
    }
1287
 
1288
    memset(&ehdr, 0, sizeof(ehdr));
1289
 
1290
    /* we add a section for symbols */
1291
    strsec = new_section(s1, ".shstrtab", SHT_STRTAB, 0);
1292
    put_elf_str(strsec, "");
1293
 
1294
    /* compute number of sections */
1295
    shnum = s1->nb_sections;
1296
 
1297
    /* this array is used to reorder sections in the output file */
1298
    section_order = tcc_malloc(sizeof(int) * shnum);
1299
    section_order[0] = 0;
1300
    sh_order_index = 1;
1301
 
1302
    /* compute number of program headers */
1303
    switch(file_type) {
1304
    default:
1305
    case TCC_OUTPUT_OBJ:
1306
        phnum = 0;
1307
        break;
1308
    case TCC_OUTPUT_EXE:
1309
        if (!s1->static_link)
1310
            phnum = 4;
1311
        else
1312
            phnum = 2;
1313
        break;
1314
    case TCC_OUTPUT_DLL:
1315
        phnum = 3;
1316
        break;
1317
    }
1318
 
1319
    /* allocate strings for section names and decide if an unallocated
1320
       section should be output */
1321
    /* NOTE: the strsec section comes last, so its size is also
1322
       correct ! */
1323
    for(i = 1; i < s1->nb_sections; i++) {
1324
        s = s1->sections[i];
1325
        s->sh_name = put_elf_str(strsec, s->name);
1326
        /* when generating a DLL, we include relocations but we may
1327
           patch them */
1328
        if (file_type == TCC_OUTPUT_DLL &&
1329
            s->sh_type == SHT_REL &&
1330
            !(s->sh_flags & SHF_ALLOC)) {
1331
            prepare_dynamic_rel(s1, s);
1332
        } else if (do_debug ||
1333
            file_type == TCC_OUTPUT_OBJ ||
1334
            (s->sh_flags & SHF_ALLOC) ||
1335
            i == (s1->nb_sections - 1)) {
1336
            /* we output all sections if debug or object file */
1337
            s->sh_size = s->data_offset;
1338
        }
1339
    }
1340
 
1341
    /* allocate program segment headers */
1342
    phdr = tcc_mallocz(phnum * sizeof(Elf32_Phdr));
1343
 
1344
    if (s1->output_format == TCC_OUTPUT_FORMAT_ELF) {
1345
        file_offset = sizeof(Elf32_Ehdr) + phnum * sizeof(Elf32_Phdr);
1346
    } else {
1347
        file_offset = 0;
1348
    }
1349
    if (phnum > 0) {
1350
        /* compute section to program header mapping */
1351
        if (s1->has_text_addr) {
1352
            int a_offset, p_offset;
1353
            addr = s1->text_addr;
1354
            /* we ensure that (addr % ELF_PAGE_SIZE) == file_offset %
1355
               ELF_PAGE_SIZE */
1356
            a_offset = addr & (ELF_PAGE_SIZE - 1);
1357
            p_offset = file_offset & (ELF_PAGE_SIZE - 1);
1358
            if (a_offset < p_offset)
1359
                a_offset += ELF_PAGE_SIZE;
1360
            file_offset += (a_offset - p_offset);
1361
        } else {
1362
            if (file_type == TCC_OUTPUT_DLL)
1363
                addr = 0;
1364
            else
1365
                addr = ELF_START_ADDR;
1366
            /* compute address after headers */
1367
            addr += (file_offset & (ELF_PAGE_SIZE - 1));
1368
        }
1369
 
1370
        /* dynamic relocation table information, for .dynamic section */
1371
        rel_size = 0;
1372
        rel_addr = 0;
1373
 
1374
        /* leave one program header for the program interpreter */
1375
        ph = &phdr[0];
1376
        if (interp)
1377
            ph++;
1378
 
1379
        for(j = 0; j < 2; j++) {
1380
            ph->p_type = PT_LOAD;
1381
            if (j == 0)
1382
                ph->p_flags = PF_R | PF_X;
1383
            else
1384
                ph->p_flags = PF_R | PF_W;
1385
            ph->p_align = ELF_PAGE_SIZE;
1386
 
1387
            /* we do the following ordering: interp, symbol tables,
1388
               relocations, progbits, nobits */
1389
            /* XXX: do faster and simpler sorting */
1390
            for(k = 0; k < 5; k++) {
1391
                for(i = 1; i < s1->nb_sections; i++) {
1392
                    s = s1->sections[i];
1393
                    /* compute if section should be included */
1394
                    if (j == 0) {
1395
                        if ((s->sh_flags & (SHF_ALLOC | SHF_WRITE)) !=
1396
                            SHF_ALLOC)
1397
                            continue;
1398
                    } else {
1399
                        if ((s->sh_flags & (SHF_ALLOC | SHF_WRITE)) !=
1400
                            (SHF_ALLOC | SHF_WRITE))
1401
                            continue;
1402
                    }
1403
                    if (s == interp) {
1404
                        if (k != 0)
1405
                            continue;
1406
                    } else if (s->sh_type == SHT_DYNSYM ||
1407
                               s->sh_type == SHT_STRTAB ||
1408
                               s->sh_type == SHT_HASH) {
1409
                        if (k != 1)
1410
                            continue;
1411
                    } else if (s->sh_type == SHT_REL) {
1412
                        if (k != 2)
1413
                            continue;
1414
                    } else if (s->sh_type == SHT_NOBITS) {
1415
                        if (k != 4)
1416
                            continue;
1417
                    } else {
1418
                        if (k != 3)
1419
                            continue;
1420
                    }
1421
                    section_order[sh_order_index++] = i;
1422
 
1423
                    /* section matches: we align it and add its size */
1424
                    tmp = addr;
1425
                    addr = (addr + s->sh_addralign - 1) &
1426
                        ~(s->sh_addralign - 1);
1427
                    file_offset += addr - tmp;
1428
                    s->sh_offset = file_offset;
1429
                    s->sh_addr = addr;
1430
 
1431
                    /* update program header infos */
1432
                    if (ph->p_offset == 0) {
1433
                        ph->p_offset = file_offset;
1434
                        ph->p_vaddr = addr;
1435
                        ph->p_paddr = ph->p_vaddr;
1436
                    }
1437
                    /* update dynamic relocation infos */
1438
                    if (s->sh_type == SHT_REL) {
1439
                        if (rel_size == 0)
1440
                            rel_addr = addr;
1441
                        rel_size += s->sh_size;
1442
                    }
1443
                    addr += s->sh_size;
1444
                    if (s->sh_type != SHT_NOBITS)
1445
                        file_offset += s->sh_size;
1446
                }
1447
            }
1448
            ph->p_filesz = file_offset - ph->p_offset;
1449
            ph->p_memsz = addr - ph->p_vaddr;
1450
            ph++;
1451
            if (j == 0) {
1452
                if (s1->output_format == TCC_OUTPUT_FORMAT_ELF) {
1453
                    /* if in the middle of a page, we duplicate the page in
1454
                       memory so that one copy is RX and the other is RW */
1455
                    if ((addr & (ELF_PAGE_SIZE - 1)) != 0)
1456
                        addr += ELF_PAGE_SIZE;
1457
                } else {
1458
                    addr = (addr + ELF_PAGE_SIZE - 1) & ~(ELF_PAGE_SIZE - 1);
1459
                    file_offset = (file_offset + ELF_PAGE_SIZE - 1) &
1460
                        ~(ELF_PAGE_SIZE - 1);
1461
                }
1462
            }
1463
        }
1464
 
1465
        /* if interpreter, then add corresponing program header */
1466
        if (interp) {
1467
            ph = &phdr[0];
1468
 
1469
            ph->p_type = PT_INTERP;
1470
            ph->p_offset = interp->sh_offset;
1471
            ph->p_vaddr = interp->sh_addr;
1472
            ph->p_paddr = ph->p_vaddr;
1473
            ph->p_filesz = interp->sh_size;
1474
            ph->p_memsz = interp->sh_size;
1475
            ph->p_flags = PF_R;
1476
            ph->p_align = interp->sh_addralign;
1477
        }
1478
 
1479
        /* if dynamic section, then add corresponing program header */
1480
        if (dynamic) {
1481
            Elf32_Sym *sym_end;
1482
 
1483
            ph = &phdr[phnum - 1];
1484
 
1485
            ph->p_type = PT_DYNAMIC;
1486
            ph->p_offset = dynamic->sh_offset;
1487
            ph->p_vaddr = dynamic->sh_addr;
1488
            ph->p_paddr = ph->p_vaddr;
1489
            ph->p_filesz = dynamic->sh_size;
1490
            ph->p_memsz = dynamic->sh_size;
1491
            ph->p_flags = PF_R | PF_W;
1492
            ph->p_align = dynamic->sh_addralign;
1493
 
1494
            /* put GOT dynamic section address */
1495
            put32(s1->got->data, dynamic->sh_addr);
1496
 
1497
            /* relocate the PLT */
1498
            if (file_type == TCC_OUTPUT_EXE) {
1499
                uint8_t *p, *p_end;
1500
 
1501
                p = s1->plt->data;
1502
                p_end = p + s1->plt->data_offset;
1503
                if (p < p_end) {
1504
#if defined(TCC_TARGET_I386)
1505
                    put32(p + 2, get32(p + 2) + s1->got->sh_addr);
1506
                    put32(p + 8, get32(p + 8) + s1->got->sh_addr);
1507
                    p += 16;
1508
                    while (p < p_end) {
1509
                        put32(p + 2, get32(p + 2) + s1->got->sh_addr);
1510
                        p += 16;
1511
                    }
1512
#elif defined(TCC_TARGET_ARM)
1513
		    int x;
1514
		    x=s1->got->sh_addr - s1->plt->sh_addr - 12;
1515
		    p +=16;
1516
		    while (p < p_end) {
1517
		        put32(p + 12, x + get32(p + 12) + s1->plt->data - p);
1518
			p += 16;
1519
		    }
1520
#elif defined(TCC_TARGET_C67)
1521
                    /* XXX: TODO */
1522
#else
1523
#error unsupported CPU
1524
#endif
1525
                }
1526
            }
1527
 
1528
            /* relocate symbols in .dynsym */
1529
            sym_end = (Elf32_Sym *)(s1->dynsym->data + s1->dynsym->data_offset);
1530
            for(sym = (Elf32_Sym *)s1->dynsym->data + 1;
1531
                sym < sym_end;
1532
                sym++) {
1533
                if (sym->st_shndx == SHN_UNDEF) {
1534
                    /* relocate to the PLT if the symbol corresponds
1535
                       to a PLT entry */
1536
                    if (sym->st_value)
1537
                        sym->st_value += s1->plt->sh_addr;
1538
                } else if (sym->st_shndx < SHN_LORESERVE) {
1539
                    /* do symbol relocation */
1540
                    sym->st_value += s1->sections[sym->st_shndx]->sh_addr;
1541
                }
1542
            }
1543
 
1544
            /* put dynamic section entries */
1545
            dynamic->data_offset = saved_dynamic_data_offset;
1546
            put_dt(dynamic, DT_HASH, s1->dynsym->hash->sh_addr);
1547
            put_dt(dynamic, DT_STRTAB, dynstr->sh_addr);
1548
            put_dt(dynamic, DT_SYMTAB, s1->dynsym->sh_addr);
1549
            put_dt(dynamic, DT_STRSZ, dynstr->data_offset);
1550
            put_dt(dynamic, DT_SYMENT, sizeof(Elf32_Sym));
1551
            put_dt(dynamic, DT_REL, rel_addr);
1552
            put_dt(dynamic, DT_RELSZ, rel_size);
1553
            put_dt(dynamic, DT_RELENT, sizeof(Elf32_Rel));
1554
            put_dt(dynamic, DT_NULL, 0);
1555
        }
1556
 
1557
        ehdr.e_phentsize = sizeof(Elf32_Phdr);
1558
        ehdr.e_phnum = phnum;
1559
        ehdr.e_phoff = sizeof(Elf32_Ehdr);
1560
    }
1561
 
1562
    /* all other sections come after */
1563
    for(i = 1; i < s1->nb_sections; i++) {
1564
        s = s1->sections[i];
1565
        if (phnum > 0 && (s->sh_flags & SHF_ALLOC))
1566
            continue;
1567
        section_order[sh_order_index++] = i;
1568
 
1569
        file_offset = (file_offset + s->sh_addralign - 1) &
1570
            ~(s->sh_addralign - 1);
1571
        s->sh_offset = file_offset;
1572
        if (s->sh_type != SHT_NOBITS)
1573
            file_offset += s->sh_size;
1574
    }
1575
 
1576
    /* if building executable or DLL, then relocate each section
1577
       except the GOT which is already relocated */
1578
    if (file_type != TCC_OUTPUT_OBJ) {
1579
        relocate_syms(s1, 0);
1580
 
1581
        if (s1->nb_errors != 0) {
1582
        fail:
1583
            ret = -1;
1584
            goto the_end;
1585
        }
1586
 
1587
        /* relocate sections */
1588
        /* XXX: ignore sections with allocated relocations ? */
1589
        for(i = 1; i < s1->nb_sections; i++) {
1590
            s = s1->sections[i];
1591
            if (s->reloc && s != s1->got)
1592
                relocate_section(s1, s);
1593
        }
1594
 
1595
        /* relocate relocation entries if the relocation tables are
1596
           allocated in the executable */
1597
        for(i = 1; i < s1->nb_sections; i++) {
1598
            s = s1->sections[i];
1599
            if ((s->sh_flags & SHF_ALLOC) &&
1600
                s->sh_type == SHT_REL) {
1601
                relocate_rel(s1, s);
1602
            }
1603
        }
1604
 
1605
        /* get entry point address */
1606
        if (file_type == TCC_OUTPUT_EXE)
1607
            ehdr.e_entry = (unsigned long)tcc_get_symbol_err(s1, "_start");
1608
        else
1609
            ehdr.e_entry = text_section->sh_addr; /* XXX: is it correct ? */
1610
    }
1611
 
1612
    /* write elf file */
1613
    if (file_type == TCC_OUTPUT_OBJ)
1614
        mode = 0666;
1615
    else
1616
        mode = 0777;
1617
    fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, mode);
1618
    if (fd < 0) {
1619
        error_noabort("could not write '%s'", filename);
1620
        goto fail;
1621
    }
1622
    f = fdopen(fd, "wb");
1623
 
1624
#ifdef TCC_TARGET_COFF
1625
    if (s1->output_format == TCC_OUTPUT_FORMAT_COFF) {
1626
        tcc_output_coff(s1, f);
1627
    } else
1628
#endif
1629
    if (s1->output_format == TCC_OUTPUT_FORMAT_ELF) {
1630
        sort_syms(s1, symtab_section);
1631
 
1632
        /* align to 4 */
1633
        file_offset = (file_offset + 3) & -4;
1634
 
1635
        /* fill header */
1636
        ehdr.e_ident[0] = ELFMAG0;
1637
        ehdr.e_ident[1] = ELFMAG1;
1638
        ehdr.e_ident[2] = ELFMAG2;
1639
        ehdr.e_ident[3] = ELFMAG3;
1640
        ehdr.e_ident[4] = ELFCLASS32;
1641
        ehdr.e_ident[5] = ELFDATA2LSB;
1642
        ehdr.e_ident[6] = EV_CURRENT;
1643
#ifdef __FreeBSD__
1644
        ehdr.e_ident[EI_OSABI] = ELFOSABI_FREEBSD;
1645
#endif
1646
#ifdef TCC_TARGET_ARM
1647
        ehdr.e_ident[EI_OSABI] = ELFOSABI_ARM;
1648
#endif
1649
        switch(file_type) {
1650
        default:
1651
        case TCC_OUTPUT_EXE:
1652
            ehdr.e_type = ET_EXEC;
1653
            break;
1654
        case TCC_OUTPUT_DLL:
1655
            ehdr.e_type = ET_DYN;
1656
            break;
1657
        case TCC_OUTPUT_OBJ:
1658
            ehdr.e_type = ET_REL;
1659
            break;
1660
        }
1661
        ehdr.e_machine = EM_TCC_TARGET;
1662
        ehdr.e_version = EV_CURRENT;
1663
        ehdr.e_shoff = file_offset;
1664
        ehdr.e_ehsize = sizeof(Elf32_Ehdr);
1665
        ehdr.e_shentsize = sizeof(Elf32_Shdr);
1666
        ehdr.e_shnum = shnum;
1667
        ehdr.e_shstrndx = shnum - 1;
1668
 
1669
        fwrite(&ehdr, 1, sizeof(Elf32_Ehdr), f);
1670
        fwrite(phdr, 1, phnum * sizeof(Elf32_Phdr), f);
1671
        offset = sizeof(Elf32_Ehdr) + phnum * sizeof(Elf32_Phdr);
1672
 
1673
        for(i=1;inb_sections;i++) {
1674
            s = s1->sections[section_order[i]];
1675
            if (s->sh_type != SHT_NOBITS) {
1676
                while (offset < s->sh_offset) {
1677
                    fputc(0, f);
1678
                    offset++;
1679
                }
1680
                size = s->sh_size;
1681
                fwrite(s->data, 1, size, f);
1682
                offset += size;
1683
            }
1684
        }
1685
 
1686
        /* output section headers */
1687
        while (offset < ehdr.e_shoff) {
1688
            fputc(0, f);
1689
            offset++;
1690
        }
1691
 
1692
        for(i=0;inb_sections;i++) {
1693
            sh = &shdr;
1694
            memset(sh, 0, sizeof(Elf32_Shdr));
1695
            s = s1->sections[i];
1696
            if (s) {
1697
                sh->sh_name = s->sh_name;
1698
                sh->sh_type = s->sh_type;
1699
                sh->sh_flags = s->sh_flags;
1700
                sh->sh_entsize = s->sh_entsize;
1701
                sh->sh_info = s->sh_info;
1702
                if (s->link)
1703
                    sh->sh_link = s->link->sh_num;
1704
                sh->sh_addralign = s->sh_addralign;
1705
                sh->sh_addr = s->sh_addr;
1706
                sh->sh_offset = s->sh_offset;
1707
                sh->sh_size = s->sh_size;
1708
            }
1709
            fwrite(sh, 1, sizeof(Elf32_Shdr), f);
1710
        }
1711
    } else {
1712
        tcc_output_binary(s1, f, section_order);
1713
    }
1714
    fclose(f);
1715
 
1716
    ret = 0;
1717
 the_end:
1718
    tcc_free(s1->symtab_to_dynsym);
1719
    tcc_free(section_order);
1720
    tcc_free(phdr);
1721
    tcc_free(s1->got_offsets);
1722
    return ret;
1723
}
1724
 
1725
static void *load_data(int fd, unsigned long file_offset, unsigned long size)
1726
{
1727
    void *data;
1728
 
1729
    data = tcc_malloc(size);
1730
    lseek(fd, file_offset, SEEK_SET);
1731
    read(fd, data, size);
1732
    return data;
1733
}
1734
 
1735
typedef struct SectionMergeInfo {
1736
    Section *s;            /* corresponding existing section */
1737
    unsigned long offset;  /* offset of the new section in the existing section */
1738
    uint8_t new_section;       /* true if section 's' was added */
1739
    uint8_t link_once;         /* true if link once section */
1740
} SectionMergeInfo;
1741
 
1742
/* load an object file and merge it with current files */
1743
/* XXX: handle correctly stab (debug) info */
1744
static int tcc_load_object_file(TCCState *s1,
1745
                                int fd, unsigned long file_offset)
1746
{
1747
    Elf32_Ehdr ehdr;
1748
    Elf32_Shdr *shdr, *sh;
1749
    int size, i, j, offset, offseti, nb_syms, sym_index, ret;
1750
    unsigned char *strsec, *strtab;
1751
    int *old_to_new_syms;
1752
    char *sh_name, *name;
1753
    SectionMergeInfo *sm_table, *sm;
1754
    Elf32_Sym *sym, *symtab;
1755
    Elf32_Rel *rel, *rel_end;
1756
    Section *s;
1757
 
1758
    if (read(fd, &ehdr, sizeof(ehdr)) != sizeof(ehdr))
1759
        goto fail1;
1760
    if (ehdr.e_ident[0] != ELFMAG0 ||
1761
        ehdr.e_ident[1] != ELFMAG1 ||
1762
        ehdr.e_ident[2] != ELFMAG2 ||
1763
        ehdr.e_ident[3] != ELFMAG3)
1764
        goto fail1;
1765
    /* test if object file */
1766
    if (ehdr.e_type != ET_REL)
1767
        goto fail1;
1768
    /* test CPU specific stuff */
1769
    if (ehdr.e_ident[5] != ELFDATA2LSB ||
1770
        ehdr.e_machine != EM_TCC_TARGET) {
1771
    fail1:
1772
        error_noabort("invalid object file");
1773
        return -1;
1774
    }
1775
    /* read sections */
1776
    shdr = load_data(fd, file_offset + ehdr.e_shoff,
1777
                     sizeof(Elf32_Shdr) * ehdr.e_shnum);
1778
    sm_table = tcc_mallocz(sizeof(SectionMergeInfo) * ehdr.e_shnum);
1779
 
1780
    /* load section names */
1781
    sh = &shdr[ehdr.e_shstrndx];
1782
    strsec = load_data(fd, file_offset + sh->sh_offset, sh->sh_size);
1783
 
1784
    /* load symtab and strtab */
1785
    old_to_new_syms = NULL;
1786
    symtab = NULL;
1787
    strtab = NULL;
1788
    nb_syms = 0;
1789
    for(i = 1; i < ehdr.e_shnum; i++) {
1790
        sh = &shdr[i];
1791
        if (sh->sh_type == SHT_SYMTAB) {
1792
            if (symtab) {
1793
                error_noabort("object must contain only one symtab");
1794
            fail:
1795
                ret = -1;
1796
                goto the_end;
1797
            }
1798
            nb_syms = sh->sh_size / sizeof(Elf32_Sym);
1799
            symtab = load_data(fd, file_offset + sh->sh_offset, sh->sh_size);
1800
            sm_table[i].s = symtab_section;
1801
 
1802
            /* now load strtab */
1803
            sh = &shdr[sh->sh_link];
1804
            strtab = load_data(fd, file_offset + sh->sh_offset, sh->sh_size);
1805
        }
1806
    }
1807
 
1808
    /* now examine each section and try to merge its content with the
1809
       ones in memory */
1810
    for(i = 1; i < ehdr.e_shnum; i++) {
1811
        /* no need to examine section name strtab */
1812
        if (i == ehdr.e_shstrndx)
1813
            continue;
1814
        sh = &shdr[i];
1815
        sh_name = strsec + sh->sh_name;
1816
        /* ignore sections types we do not handle */
1817
        if (sh->sh_type != SHT_PROGBITS &&
1818
            sh->sh_type != SHT_REL &&
1819
            sh->sh_type != SHT_NOBITS)
1820
            continue;
1821
        if (sh->sh_addralign < 1)
1822
            sh->sh_addralign = 1;
1823
        /* find corresponding section, if any */
1824
        for(j = 1; j < s1->nb_sections;j++) {
1825
            s = s1->sections[j];
1826
            if (!strcmp(s->name, sh_name)) {
1827
                if (!strncmp(sh_name, ".gnu.linkonce",
1828
                             sizeof(".gnu.linkonce") - 1)) {
1829
                    /* if a 'linkonce' section is already present, we
1830
                       do not add it again. It is a little tricky as
1831
                       symbols can still be defined in
1832
                       it. */
1833
                    sm_table[i].link_once = 1;
1834
                    goto next;
1835
                } else {
1836
                    goto found;
1837
                }
1838
            }
1839
        }
1840
        /* not found: create new section */
1841
        s = new_section(s1, sh_name, sh->sh_type, sh->sh_flags);
1842
        /* take as much info as possible from the section. sh_link and
1843
           sh_info will be updated later */
1844
        s->sh_addralign = sh->sh_addralign;
1845
        s->sh_entsize = sh->sh_entsize;
1846
        sm_table[i].new_section = 1;
1847
    found:
1848
        if (sh->sh_type != s->sh_type) {
1849
            error_noabort("invalid section type");
1850
            goto fail;
1851
        }
1852
 
1853
        /* align start of section */
1854
        offset = s->data_offset;
1855
        size = sh->sh_addralign - 1;
1856
        offset = (offset + size) & ~size;
1857
        if (sh->sh_addralign > s->sh_addralign)
1858
            s->sh_addralign = sh->sh_addralign;
1859
        s->data_offset = offset;
1860
        sm_table[i].offset = offset;
1861
        sm_table[i].s = s;
1862
        /* concatenate sections */
1863
        size = sh->sh_size;
1864
        if (sh->sh_type != SHT_NOBITS) {
1865
            unsigned char *ptr;
1866
            lseek(fd, file_offset + sh->sh_offset, SEEK_SET);
1867
            ptr = section_ptr_add(s, size);
1868
            read(fd, ptr, size);
1869
        } else {
1870
            s->data_offset += size;
1871
        }
1872
    next: ;
1873
    }
1874
 
1875
    /* second short pass to update sh_link and sh_info fields of new
1876
       sections */
1877
    sm = sm_table;
1878
    for(i = 1; i < ehdr.e_shnum; i++) {
1879
        s = sm_table[i].s;
1880
        if (!s || !sm_table[i].new_section)
1881
            continue;
1882
        sh = &shdr[i];
1883
        if (sh->sh_link > 0)
1884
            s->link = sm_table[sh->sh_link].s;
1885
        if (sh->sh_type == SHT_REL) {
1886
            s->sh_info = sm_table[sh->sh_info].s->sh_num;
1887
            /* update backward link */
1888
            s1->sections[s->sh_info]->reloc = s;
1889
        }
1890
    }
1891
 
1892
    /* resolve symbols */
1893
    old_to_new_syms = tcc_mallocz(nb_syms * sizeof(int));
1894
 
1895
    sym = symtab + 1;
1896
    for(i = 1; i < nb_syms; i++, sym++) {
1897
        if (sym->st_shndx != SHN_UNDEF &&
1898
            sym->st_shndx < SHN_LORESERVE) {
1899
            sm = &sm_table[sym->st_shndx];
1900
            if (sm->link_once) {
1901
                /* if a symbol is in a link once section, we use the
1902
                   already defined symbol. It is very important to get
1903
                   correct relocations */
1904
                if (ELF32_ST_BIND(sym->st_info) != STB_LOCAL) {
1905
                    name = strtab + sym->st_name;
1906
                    sym_index = find_elf_sym(symtab_section, name);
1907
                    if (sym_index)
1908
                        old_to_new_syms[i] = sym_index;
1909
                }
1910
                continue;
1911
            }
1912
            /* if no corresponding section added, no need to add symbol */
1913
            if (!sm->s)
1914
                continue;
1915
            /* convert section number */
1916
            sym->st_shndx = sm->s->sh_num;
1917
            /* offset value */
1918
            sym->st_value += sm->offset;
1919
        }
1920
        /* add symbol */
1921
        name = strtab + sym->st_name;
1922
        sym_index = add_elf_sym(symtab_section, sym->st_value, sym->st_size,
1923
                                sym->st_info, sym->st_other,
1924
                                sym->st_shndx, name);
1925
        old_to_new_syms[i] = sym_index;
1926
    }
1927
 
1928
    /* third pass to patch relocation entries */
1929
    for(i = 1; i < ehdr.e_shnum; i++) {
1930
        s = sm_table[i].s;
1931
        if (!s)
1932
            continue;
1933
        sh = &shdr[i];
1934
        offset = sm_table[i].offset;
1935
        switch(s->sh_type) {
1936
        case SHT_REL:
1937
            /* take relocation offset information */
1938
            offseti = sm_table[sh->sh_info].offset;
1939
            rel_end = (Elf32_Rel *)(s->data + s->data_offset);
1940
            for(rel = (Elf32_Rel *)(s->data + offset);
1941
                rel < rel_end;
1942
                rel++) {
1943
                int type;
1944
                unsigned sym_index;
1945
                /* convert symbol index */
1946
                type = ELF32_R_TYPE(rel->r_info);
1947
                sym_index = ELF32_R_SYM(rel->r_info);
1948
                /* NOTE: only one symtab assumed */
1949
                if (sym_index >= nb_syms)
1950
                    goto invalid_reloc;
1951
                sym_index = old_to_new_syms[sym_index];
1952
                if (!sym_index) {
1953
                invalid_reloc:
1954
                    error_noabort("Invalid relocation entry");
1955
                    goto fail;
1956
                }
1957
                rel->r_info = ELF32_R_INFO(sym_index, type);
1958
                /* offset the relocation offset */
1959
                rel->r_offset += offseti;
1960
            }
1961
            break;
1962
        default:
1963
            break;
1964
        }
1965
    }
1966
 
1967
    ret = 0;
1968
 the_end:
1969
    tcc_free(symtab);
1970
    tcc_free(strtab);
1971
    tcc_free(old_to_new_syms);
1972
    tcc_free(sm_table);
1973
    tcc_free(strsec);
1974
    tcc_free(shdr);
1975
    return ret;
1976
}
1977
 
1978
#define ARMAG  "!\012"	/* For COFF and a.out archives */
1979
 
1980
typedef struct ArchiveHeader {
1981
    char ar_name[16];		/* name of this member */
1982
    char ar_date[12];		/* file mtime */
1983
    char ar_uid[6];		/* owner uid; printed as decimal */
1984
    char ar_gid[6];		/* owner gid; printed as decimal */
1985
    char ar_mode[8];		/* file mode, printed as octal   */
1986
    char ar_size[10];		/* file size, printed as decimal */
1987
    char ar_fmag[2];		/* should contain ARFMAG */
1988
} ArchiveHeader;
1989
 
1990
static int get_be32(const uint8_t *b)
1991
{
1992
    return b[3] | (b[2] << 8) | (b[1] << 16) | (b[0] << 24);
1993
}
1994
 
1995
/* load only the objects which resolve undefined symbols */
1996
static int tcc_load_alacarte(TCCState *s1, int fd, int size)
1997
{
1998
    int i, bound, nsyms, sym_index, off, ret;
1999
    uint8_t *data;
2000
    const char *ar_names, *p;
2001
    const uint8_t *ar_index;
2002
    Elf32_Sym *sym;
2003
 
2004
    data = tcc_malloc(size);
2005
    if (read(fd, data, size) != size)
2006
        goto fail;
2007
    nsyms = get_be32(data);
2008
    ar_index = data + 4;
2009
    ar_names = ar_index + nsyms * 4;
2010
 
2011
    do {
2012
	bound = 0;
2013
	for(p = ar_names, i = 0; i < nsyms; i++, p += strlen(p)+1) {
2014
	    sym_index = find_elf_sym(symtab_section, p);
2015
	    if(sym_index) {
2016
		sym = &((Elf32_Sym *)symtab_section->data)[sym_index];
2017
		if(sym->st_shndx == SHN_UNDEF) {
2018
		    off = get_be32(ar_index + i * 4) + sizeof(ArchiveHeader);
2019
#if 0
2020
		    printf("%5d\t%s\t%08x\n", i, p, sym->st_shndx);
2021
#endif
2022
		    ++bound;
2023
		    lseek(fd, off, SEEK_SET);
2024
		    if(tcc_load_object_file(s1, fd, off) < 0) {
2025
                    fail:
2026
                        ret = -1;
2027
                        goto the_end;
2028
                    }
2029
		}
2030
	    }
2031
	}
2032
    } while(bound);
2033
    ret = 0;
2034
 the_end:
2035
    tcc_free(data);
2036
    return ret;
2037
}
2038
 
2039
/* load a '.a' file */
2040
static int tcc_load_archive(TCCState *s1, int fd)
2041
{
2042
    ArchiveHeader hdr;
2043
    char ar_size[11];
2044
    char ar_name[17];
2045
    char magic[8];
2046
    int size, len, i;
2047
    unsigned long file_offset;
2048
 
2049
    /* skip magic which was already checked */
2050
    read(fd, magic, sizeof(magic));
2051
 
2052
    for(;;) {
2053
        len = read(fd, &hdr, sizeof(hdr));
2054
        if (len == 0)
2055
            break;
2056
        if (len != sizeof(hdr)) {
2057
            error_noabort("invalid archive");
2058
            return -1;
2059
        }
2060
        memcpy(ar_size, hdr.ar_size, sizeof(hdr.ar_size));
2061
        ar_size[sizeof(hdr.ar_size)] = '\0';
2062
        size = strtol(ar_size, NULL, 0);
2063
        memcpy(ar_name, hdr.ar_name, sizeof(hdr.ar_name));
2064
        for(i = sizeof(hdr.ar_name) - 1; i >= 0; i--) {
2065
            if (ar_name[i] != ' ')
2066
                break;
2067
        }
2068
        ar_name[i + 1] = '\0';
2069
        //        printf("name='%s' size=%d %s\n", ar_name, size, ar_size);
2070
        file_offset = lseek(fd, 0, SEEK_CUR);
2071
        /* align to even */
2072
        size = (size + 1) & ~1;
2073
        if (!strcmp(ar_name, "/")) {
2074
            /* coff symbol table : we handle it */
2075
	    if(s1->alacarte_link)
2076
		return tcc_load_alacarte(s1, fd, size);
2077
        } else if (!strcmp(ar_name, "//") ||
2078
                   !strcmp(ar_name, "__.SYMDEF") ||
2079
                   !strcmp(ar_name, "__.SYMDEF/") ||
2080
                   !strcmp(ar_name, "ARFILENAMES/")) {
2081
            /* skip symbol table or archive names */
2082
        } else {
2083
            if (tcc_load_object_file(s1, fd, file_offset) < 0)
2084
                return -1;
2085
        }
2086
        lseek(fd, file_offset + size, SEEK_SET);
2087
    }
2088
    return 0;
2089
}
2090
 
2091
/* load a DLL and all referenced DLLs. 'level = 0' means that the DLL
2092
   is referenced by the user (so it should be added as DT_NEEDED in
2093
   the generated ELF file) */
2094
static int tcc_load_dll(TCCState *s1, int fd, const char *filename, int level)
2095
{
2096
    Elf32_Ehdr ehdr;
2097
    Elf32_Shdr *shdr, *sh, *sh1;
2098
    int i, nb_syms, nb_dts, sym_bind, ret;
2099
    Elf32_Sym *sym, *dynsym;
2100
    Elf32_Dyn *dt, *dynamic;
2101
    unsigned char *dynstr;
2102
    const char *name, *soname, *p;
2103
    DLLReference *dllref;
2104
 
2105
    read(fd, &ehdr, sizeof(ehdr));
2106
 
2107
    /* test CPU specific stuff */
2108
    if (ehdr.e_ident[5] != ELFDATA2LSB ||
2109
        ehdr.e_machine != EM_TCC_TARGET) {
2110
        error_noabort("bad architecture");
2111
        return -1;
2112
    }
2113
 
2114
    /* read sections */
2115
    shdr = load_data(fd, ehdr.e_shoff, sizeof(Elf32_Shdr) * ehdr.e_shnum);
2116
 
2117
    /* load dynamic section and dynamic symbols */
2118
    nb_syms = 0;
2119
    nb_dts = 0;
2120
    dynamic = NULL;
2121
    dynsym = NULL; /* avoid warning */
2122
    dynstr = NULL; /* avoid warning */
2123
    for(i = 0, sh = shdr; i < ehdr.e_shnum; i++, sh++) {
2124
        switch(sh->sh_type) {
2125
        case SHT_DYNAMIC:
2126
            nb_dts = sh->sh_size / sizeof(Elf32_Dyn);
2127
            dynamic = load_data(fd, sh->sh_offset, sh->sh_size);
2128
            break;
2129
        case SHT_DYNSYM:
2130
            nb_syms = sh->sh_size / sizeof(Elf32_Sym);
2131
            dynsym = load_data(fd, sh->sh_offset, sh->sh_size);
2132
            sh1 = &shdr[sh->sh_link];
2133
            dynstr = load_data(fd, sh1->sh_offset, sh1->sh_size);
2134
            break;
2135
        default:
2136
            break;
2137
        }
2138
    }
2139
 
2140
    /* compute the real library name */
2141
    soname = filename;
2142
    p = strrchr(soname, '/');
2143
    if (p)
2144
        soname = p + 1;
2145
 
2146
    for(i = 0, dt = dynamic; i < nb_dts; i++, dt++) {
2147
        if (dt->d_tag == DT_SONAME) {
2148
            soname = dynstr + dt->d_un.d_val;
2149
        }
2150
    }
2151
 
2152
    /* if the dll is already loaded, do not load it */
2153
    for(i = 0; i < s1->nb_loaded_dlls; i++) {
2154
        dllref = s1->loaded_dlls[i];
2155
        if (!strcmp(soname, dllref->name)) {
2156
            /* but update level if needed */
2157
            if (level < dllref->level)
2158
                dllref->level = level;
2159
            ret = 0;
2160
            goto the_end;
2161
        }
2162
    }
2163
 
2164
    //    printf("loading dll '%s'\n", soname);
2165
 
2166
    /* add the dll and its level */
2167
    dllref = tcc_malloc(sizeof(DLLReference) + strlen(soname));
2168
    dllref->level = level;
2169
    strcpy(dllref->name, soname);
2170
    dynarray_add((void ***)&s1->loaded_dlls, &s1->nb_loaded_dlls, dllref);
2171
 
2172
    /* add dynamic symbols in dynsym_section */
2173
    for(i = 1, sym = dynsym + 1; i < nb_syms; i++, sym++) {
2174
        sym_bind = ELF32_ST_BIND(sym->st_info);
2175
        if (sym_bind == STB_LOCAL)
2176
            continue;
2177
        name = dynstr + sym->st_name;
2178
        add_elf_sym(s1->dynsymtab_section, sym->st_value, sym->st_size,
2179
                    sym->st_info, sym->st_other, sym->st_shndx, name);
2180
    }
2181
 
2182
    /* load all referenced DLLs */
2183
    for(i = 0, dt = dynamic; i < nb_dts; i++, dt++) {
2184
        switch(dt->d_tag) {
2185
        case DT_NEEDED:
2186
            name = dynstr + dt->d_un.d_val;
2187
            for(i = 0; i < s1->nb_loaded_dlls; i++) {
2188
                dllref = s1->loaded_dlls[i];
2189
                if (!strcmp(name, dllref->name))
2190
                    goto already_loaded;
2191
            }
2192
            if (tcc_add_dll(s1, name, AFF_REFERENCED_DLL) < 0) {
2193
                error_noabort("referenced dll '%s' not found", name);
2194
                ret = -1;
2195
                goto the_end;
2196
            }
2197
        already_loaded:
2198
            break;
2199
        }
2200
    }
2201
    ret = 0;
2202
 the_end:
2203
    tcc_free(dynstr);
2204
    tcc_free(dynsym);
2205
    tcc_free(dynamic);
2206
    tcc_free(shdr);
2207
    return ret;
2208
}
2209
 
2210
#define LD_TOK_NAME 256
2211
#define LD_TOK_EOF  (-1)
2212
 
2213
/* return next ld script token */
2214
static int ld_next(TCCState *s1, char *name, int name_size)
2215
{
2216
    int c;
2217
    char *q;
2218
 
2219
 redo:
2220
    switch(ch) {
2221
    case ' ':
2222
    case '\t':
2223
    case '\f':
2224
    case '\v':
2225
    case '\r':
2226
    case '\n':
609 andrew_pro 2227
        input();
145 halyavin 2228
        goto redo;
2229
    case '/':
2230
        minp();
2231
        if (ch == '*') {
2232
            file->buf_ptr = parse_comment(file->buf_ptr);
2233
            ch = file->buf_ptr[0];
2234
            goto redo;
2235
        } else {
2236
            q = name;
2237
            *q++ = '/';
2238
            goto parse_name;
2239
        }
2240
        break;
2241
    case 'a' ... 'z':
2242
    case 'A' ... 'Z':
2243
    case '_':
2244
    case '\\':
2245
    case '.':
2246
    case '$':
2247
    case '~':
2248
        q = name;
2249
    parse_name:
2250
        for(;;) {
2251
            if (!((ch >= 'a' && ch <= 'z') ||
2252
                  (ch >= 'A' && ch <= 'Z') ||
2253
                  (ch >= '0' && ch <= '9') ||
2254
                  strchr("/.-_+=$:\\,~", ch)))
2255
                break;
2256
            if ((q - name) < name_size - 1) {
2257
                *q++ = ch;
2258
            }
2259
            minp();
2260
        }
2261
        *q = '\0';
2262
        c = LD_TOK_NAME;
2263
        break;
2264
    case CH_EOF:
2265
        c = LD_TOK_EOF;
2266
        break;
2267
    default:
2268
        c = ch;
609 andrew_pro 2269
        input();
145 halyavin 2270
        break;
2271
    }
2272
#if 0
2273
    printf("tok=%c %d\n", c, c);
2274
    if (c == LD_TOK_NAME)
2275
        printf("  name=%s\n", name);
2276
#endif
2277
    return c;
2278
}
2279
 
2280
/* interpret a subset of GNU ldscripts to handle the dummy libc.so
2281
   files */
2282
static int tcc_load_ldscript(TCCState *s1)
2283
{
2284
    char cmd[64];
2285
    char filename[1024];
2286
    int t;
2287
 
2288
    ch = file->buf_ptr[0];
2289
    ch = handle_eob();
2290
    for(;;) {
2291
        t = ld_next(s1, cmd, sizeof(cmd));
2292
        if (t == LD_TOK_EOF)
2293
            return 0;
2294
        else if (t != LD_TOK_NAME)
2295
            return -1;
2296
        if (!strcmp(cmd, "INPUT") ||
2297
            !strcmp(cmd, "GROUP")) {
2298
            t = ld_next(s1, cmd, sizeof(cmd));
2299
            if (t != '(')
2300
                expect("(");
2301
            t = ld_next(s1, filename, sizeof(filename));
2302
            for(;;) {
2303
                if (t == LD_TOK_EOF) {
2304
                    error_noabort("unexpected end of file");
2305
                    return -1;
2306
                } else if (t == ')') {
2307
                    break;
2308
                } else if (t != LD_TOK_NAME) {
2309
                    error_noabort("filename expected");
2310
                    return -1;
2311
                }
2312
                tcc_add_file(s1, filename);
2313
                t = ld_next(s1, filename, sizeof(filename));
2314
                if (t == ',') {
2315
                    t = ld_next(s1, filename, sizeof(filename));
2316
                }
2317
            }
2318
        } else if (!strcmp(cmd, "OUTPUT_FORMAT") ||
2319
                   !strcmp(cmd, "TARGET")) {
2320
            /* ignore some commands */
2321
            t = ld_next(s1, cmd, sizeof(cmd));
2322
            if (t != '(')
2323
                expect("(");
2324
            for(;;) {
2325
                t = ld_next(s1, filename, sizeof(filename));
2326
                if (t == LD_TOK_EOF) {
2327
                    error_noabort("unexpected end of file");
2328
                    return -1;
2329
                } else if (t == ')') {
2330
                    break;
2331
                }
2332
            }
2333
        } else {
2334
            return -1;
2335
        }
2336
    }
2337
    return 0;
2338
}