Subversion Repositories Kolibri OS

Rev

Rev 647 | Go to most recent revision | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed

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