1/*
2 * ELF file handling for TCC
3 *
4 * Copyright (c) 2001-2004 Fabrice Bellard
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 */
20
21#include "tcc.h"
22
23/* Define this to get some debug output during relocation processing. */
24#undef DEBUG_RELOC
25
26/********************************************************/
27/* global variables */
28
29/* elf version information */
30struct sym_version {
31 char *lib;
32 char *version;
33 int out_index;
34 int prev_same_lib;
35};
36
37#define nb_sym_versions s1->nb_sym_versions
38#define sym_versions s1->sym_versions
39#define nb_sym_to_version s1->nb_sym_to_version
40#define sym_to_version s1->sym_to_version
41#define dt_verneednum s1->dt_verneednum
42#define versym_section s1->versym_section
43#define verneed_section s1->verneed_section
44
45/* special flag to indicate that the section should not be linked to the other ones */
46#define SHF_PRIVATE 0x80000000
47/* section is dynsymtab_section */
48#define SHF_DYNSYM 0x40000000
49
50/* ------------------------------------------------------------------------- */
51
52ST_FUNC void tccelf_new(TCCState *s)
53{
54 TCCState *s1 = s;
55 /* no section zero */
56 dynarray_add(&s->sections, &s->nb_sections, NULL);
57
58 /* create standard sections */
59 text_section = new_section(s, ".text", SHT_PROGBITS, SHF_ALLOC | SHF_EXECINSTR);
60 data_section = new_section(s, ".data", SHT_PROGBITS, SHF_ALLOC | SHF_WRITE);
61 bss_section = new_section(s, ".bss", SHT_NOBITS, SHF_ALLOC | SHF_WRITE);
62 common_section = new_section(s, ".common", SHT_NOBITS, SHF_PRIVATE);
63 common_section->sh_num = SHN_COMMON;
64
65 /* symbols are always generated for linking stage */
66 symtab_section = new_symtab(s, ".symtab", SHT_SYMTAB, 0,
67 ".strtab",
68 ".hashtab", SHF_PRIVATE);
69 s->symtab = symtab_section;
70
71 /* private symbol table for dynamic symbols */
72 s->dynsymtab_section = new_symtab(s, ".dynsymtab", SHT_SYMTAB, SHF_PRIVATE|SHF_DYNSYM,
73 ".dynstrtab",
74 ".dynhashtab", SHF_PRIVATE);
75 get_sym_attr(s, 0, 1);
76}
77
78#ifdef CONFIG_TCC_BCHECK
79ST_FUNC void tccelf_bounds_new(TCCState *s)
80{
81 TCCState *s1 = s;
82 /* create bounds sections */
83 bounds_section = new_section(s, ".bounds",
84 SHT_PROGBITS, SHF_ALLOC);
85 lbounds_section = new_section(s, ".lbounds",
86 SHT_PROGBITS, SHF_ALLOC);
87}
88#endif
89
90ST_FUNC void tccelf_stab_new(TCCState *s)
91{
92 TCCState *s1 = s;
93 int shf = 0;
94#ifdef CONFIG_TCC_BACKTRACE
95 /* include stab info with standalone backtrace support */
96 if (s->do_backtrace && s->output_type != TCC_OUTPUT_MEMORY)
97 shf = SHF_ALLOC;
98#endif
99 stab_section = new_section(s, ".stab", SHT_PROGBITS, shf);
100 stab_section->sh_entsize = sizeof(Stab_Sym);
101 stab_section->sh_addralign = sizeof ((Stab_Sym*)0)->n_value;
102 stab_section->link = new_section(s, ".stabstr", SHT_STRTAB, shf);
103 /* put first entry */
104 put_stabs(s, "", 0, 0, 0, 0);
105}
106
107static void free_section(Section *s)
108{
109 tcc_free(s->data);
110}
111
112ST_FUNC void tccelf_delete(TCCState *s1)
113{
114 int i;
115
116#ifndef ELF_OBJ_ONLY
117 /* free symbol versions */
118 for (i = 0; i < nb_sym_versions; i++) {
119 tcc_free(sym_versions[i].version);
120 tcc_free(sym_versions[i].lib);
121 }
122 tcc_free(sym_versions);
123 tcc_free(sym_to_version);
124#endif
125
126 /* free all sections */
127 for(i = 1; i < s1->nb_sections; i++)
128 free_section(s1->sections[i]);
129 dynarray_reset(&s1->sections, &s1->nb_sections);
130
131 for(i = 0; i < s1->nb_priv_sections; i++)
132 free_section(s1->priv_sections[i]);
133 dynarray_reset(&s1->priv_sections, &s1->nb_priv_sections);
134
135 /* free any loaded DLLs */
136#ifdef TCC_IS_NATIVE
137 for ( i = 0; i < s1->nb_loaded_dlls; i++) {
138 DLLReference *ref = s1->loaded_dlls[i];
139 if ( ref->handle )
140# ifdef _WIN32
141 FreeLibrary((HMODULE)ref->handle);
142# else
143 dlclose(ref->handle);
144# endif
145 }
146#endif
147 /* free loaded dlls array */
148 dynarray_reset(&s1->loaded_dlls, &s1->nb_loaded_dlls);
149 tcc_free(s1->sym_attrs);
150
151 symtab_section = NULL; /* for tccrun.c:rt_printline() */
152}
153
154/* save section data state */
155ST_FUNC void tccelf_begin_file(TCCState *s1)
156{
157 Section *s; int i;
158 for (i = 1; i < s1->nb_sections; i++) {
159 s = s1->sections[i];
160 s->sh_offset = s->data_offset;
161 }
162 /* disable symbol hashing during compilation */
163 s = s1->symtab, s->reloc = s->hash, s->hash = NULL;
164#if defined TCC_TARGET_X86_64 && defined TCC_TARGET_PE
165 s1->uw_sym = 0;
166#endif
167}
168
169/* At the end of compilation, convert any UNDEF syms to global, and merge
170 with previously existing symbols */
171ST_FUNC void tccelf_end_file(TCCState *s1)
172{
173 Section *s = s1->symtab;
174 int first_sym, nb_syms, *tr, i;
175
176 first_sym = s->sh_offset / sizeof (ElfSym);
177 nb_syms = s->data_offset / sizeof (ElfSym) - first_sym;
178 s->data_offset = s->sh_offset;
179 s->link->data_offset = s->link->sh_offset;
180 s->hash = s->reloc, s->reloc = NULL;
181 tr = tcc_mallocz(nb_syms * sizeof *tr);
182
183 for (i = 0; i < nb_syms; ++i) {
184 ElfSym *sym = (ElfSym*)s->data + first_sym + i;
185 if (sym->st_shndx == SHN_UNDEF
186 && ELFW(ST_BIND)(sym->st_info) == STB_LOCAL)
187 sym->st_info = ELFW(ST_INFO)(STB_GLOBAL, ELFW(ST_TYPE)(sym->st_info));
188 tr[i] = set_elf_sym(s, sym->st_value, sym->st_size, sym->st_info,
189 sym->st_other, sym->st_shndx, (char*)s->link->data + sym->st_name);
190 }
191 /* now update relocations */
192 for (i = 1; i < s1->nb_sections; i++) {
193 Section *sr = s1->sections[i];
194 if (sr->sh_type == SHT_RELX && sr->link == s) {
195 ElfW_Rel *rel = (ElfW_Rel*)(sr->data + sr->sh_offset);
196 ElfW_Rel *rel_end = (ElfW_Rel*)(sr->data + sr->data_offset);
197 for (; rel < rel_end; ++rel) {
198 int n = ELFW(R_SYM)(rel->r_info) - first_sym;
199 //if (n < 0) tcc_error("internal: invalid symbol index in relocation");
200 rel->r_info = ELFW(R_INFO)(tr[n], ELFW(R_TYPE)(rel->r_info));
201 }
202 }
203 }
204 tcc_free(tr);
205
206 /* record text/data/bss output for -bench info */
207 for (i = 0; i < 3; ++i) {
208 s = s1->sections[i + 1];
209 s1->total_output[i] += s->data_offset - s->sh_offset;
210 }
211}
212
213ST_FUNC Section *new_section(TCCState *s1, const char *name, int sh_type, int sh_flags)
214{
215 Section *sec;
216
217 sec = tcc_mallocz(sizeof(Section) + strlen(name));
218 sec->s1 = s1;
219 strcpy(sec->name, name);
220 sec->sh_type = sh_type;
221 sec->sh_flags = sh_flags;
222 switch(sh_type) {
223 case SHT_GNU_versym:
224 sec->sh_addralign = 2;
225 break;
226 case SHT_HASH:
227 case SHT_REL:
228 case SHT_RELA:
229 case SHT_DYNSYM:
230 case SHT_SYMTAB:
231 case SHT_DYNAMIC:
232 case SHT_GNU_verneed:
233 case SHT_GNU_verdef:
234 sec->sh_addralign = PTR_SIZE;
235 break;
236 case SHT_STRTAB:
237 sec->sh_addralign = 1;
238 break;
239 default:
240 sec->sh_addralign = PTR_SIZE; /* gcc/pcc default alignment */
241 break;
242 }
243
244 if (sh_flags & SHF_PRIVATE) {
245 dynarray_add(&s1->priv_sections, &s1->nb_priv_sections, sec);
246 } else {
247 sec->sh_num = s1->nb_sections;
248 dynarray_add(&s1->sections, &s1->nb_sections, sec);
249 }
250
251 return sec;
252}
253
254ST_FUNC Section *new_symtab(TCCState *s1,
255 const char *symtab_name, int sh_type, int sh_flags,
256 const char *strtab_name,
257 const char *hash_name, int hash_sh_flags)
258{
259 Section *symtab, *strtab, *hash;
260 int *ptr, nb_buckets;
261
262 symtab = new_section(s1, symtab_name, sh_type, sh_flags);
263 symtab->sh_entsize = sizeof(ElfW(Sym));
264 strtab = new_section(s1, strtab_name, SHT_STRTAB, sh_flags);
265 put_elf_str(strtab, "");
266 symtab->link = strtab;
267 put_elf_sym(symtab, 0, 0, 0, 0, 0, NULL);
268
269 nb_buckets = 1;
270
271 hash = new_section(s1, hash_name, SHT_HASH, hash_sh_flags);
272 hash->sh_entsize = sizeof(int);
273 symtab->hash = hash;
274 hash->link = symtab;
275
276 ptr = section_ptr_add(hash, (2 + nb_buckets + 1) * sizeof(int));
277 ptr[0] = nb_buckets;
278 ptr[1] = 1;
279 memset(ptr + 2, 0, (nb_buckets + 1) * sizeof(int));
280 return symtab;
281}
282
283/* realloc section and set its content to zero */
284ST_FUNC void section_realloc(Section *sec, unsigned long new_size)
285{
286 unsigned long size;
287 unsigned char *data;
288
289 size = sec->data_allocated;
290 if (size == 0)
291 size = 1;
292 while (size < new_size)
293 size = size * 2;
294 data = tcc_realloc(sec->data, size);
295 memset(data + sec->data_allocated, 0, size - sec->data_allocated);
296 sec->data = data;
297 sec->data_allocated = size;
298}
299
300/* reserve at least 'size' bytes aligned per 'align' in section
301 'sec' from current offset, and return the aligned offset */
302ST_FUNC size_t section_add(Section *sec, addr_t size, int align)
303{
304 size_t offset, offset1;
305
306 offset = (sec->data_offset + align - 1) & -align;
307 offset1 = offset + size;
308 if (sec->sh_type != SHT_NOBITS && offset1 > sec->data_allocated)
309 section_realloc(sec, offset1);
310 sec->data_offset = offset1;
311 if (align > sec->sh_addralign)
312 sec->sh_addralign = align;
313 return offset;
314}
315
316/* reserve at least 'size' bytes in section 'sec' from
317 sec->data_offset. */
318ST_FUNC void *section_ptr_add(Section *sec, addr_t size)
319{
320 size_t offset = section_add(sec, size, 1);
321 return sec->data + offset;
322}
323
324#ifndef ELF_OBJ_ONLY
325/* reserve at least 'size' bytes from section start */
326static void section_reserve(Section *sec, unsigned long size)
327{
328 if (size > sec->data_allocated)
329 section_realloc(sec, size);
330 if (size > sec->data_offset)
331 sec->data_offset = size;
332}
333#endif
334
335static Section *find_section_create (TCCState *s1, const char *name, int create)
336{
337 Section *sec;
338 int i;
339 for(i = 1; i < s1->nb_sections; i++) {
340 sec = s1->sections[i];
341 if (!strcmp(name, sec->name))
342 return sec;
343 }
344 /* sections are created as PROGBITS */
345 return create ? new_section(s1, name, SHT_PROGBITS, SHF_ALLOC) : NULL;
346}
347
348/* return a reference to a section, and create it if it does not
349 exists */
350ST_FUNC Section *find_section(TCCState *s1, const char *name)
351{
352 return find_section_create (s1, name, 1);
353}
354
355/* ------------------------------------------------------------------------- */
356
357ST_FUNC int put_elf_str(Section *s, const char *sym)
358{
359 int offset, len;
360 char *ptr;
361
362 len = strlen(sym) + 1;
363 offset = s->data_offset;
364 ptr = section_ptr_add(s, len);
365 memmove(ptr, sym, len);
366 return offset;
367}
368
369/* elf symbol hashing function */
370static unsigned long elf_hash(const unsigned char *name)
371{
372 unsigned long h = 0, g;
373
374 while (*name) {
375 h = (h << 4) + *name++;
376 g = h & 0xf0000000;
377 if (g)
378 h ^= g >> 24;
379 h &= ~g;
380 }
381 return h;
382}
383
384/* rebuild hash table of section s */
385/* NOTE: we do factorize the hash table code to go faster */
386static void rebuild_hash(Section *s, unsigned int nb_buckets)
387{
388 ElfW(Sym) *sym;
389 int *ptr, *hash, nb_syms, sym_index, h;
390 unsigned char *strtab;
391
392 strtab = s->link->data;
393 nb_syms = s->data_offset / sizeof(ElfW(Sym));
394
395 if (!nb_buckets)
396 nb_buckets = ((int*)s->hash->data)[0];
397
398 s->hash->data_offset = 0;
399 ptr = section_ptr_add(s->hash, (2 + nb_buckets + nb_syms) * sizeof(int));
400 ptr[0] = nb_buckets;
401 ptr[1] = nb_syms;
402 ptr += 2;
403 hash = ptr;
404 memset(hash, 0, (nb_buckets + 1) * sizeof(int));
405 ptr += nb_buckets + 1;
406
407 sym = (ElfW(Sym) *)s->data + 1;
408 for(sym_index = 1; sym_index < nb_syms; sym_index++) {
409 if (ELFW(ST_BIND)(sym->st_info) != STB_LOCAL) {
410 h = elf_hash(strtab + sym->st_name) % nb_buckets;
411 *ptr = hash[h];
412 hash[h] = sym_index;
413 } else {
414 *ptr = 0;
415 }
416 ptr++;
417 sym++;
418 }
419}
420
421/* return the symbol number */
422ST_FUNC int put_elf_sym(Section *s, addr_t value, unsigned long size,
423 int info, int other, int shndx, const char *name)
424{
425 int name_offset, sym_index;
426 int nbuckets, h;
427 ElfW(Sym) *sym;
428 Section *hs;
429
430 sym = section_ptr_add(s, sizeof(ElfW(Sym)));
431 if (name && name[0])
432 name_offset = put_elf_str(s->link, name);
433 else
434 name_offset = 0;
435 /* XXX: endianness */
436 sym->st_name = name_offset;
437 sym->st_value = value;
438 sym->st_size = size;
439 sym->st_info = info;
440 sym->st_other = other;
441 sym->st_shndx = shndx;
442 sym_index = sym - (ElfW(Sym) *)s->data;
443 hs = s->hash;
444 if (hs) {
445 int *ptr, *base;
446 ptr = section_ptr_add(hs, sizeof(int));
447 base = (int *)hs->data;
448 /* only add global or weak symbols. */
449 if (ELFW(ST_BIND)(info) != STB_LOCAL) {
450 /* add another hashing entry */
451 nbuckets = base[0];
452 h = elf_hash((unsigned char *)s->link->data + name_offset) % nbuckets;
453 *ptr = base[2 + h];
454 base[2 + h] = sym_index;
455 base[1]++;
456 /* we resize the hash table */
457 hs->nb_hashed_syms++;
458 if (hs->nb_hashed_syms > 2 * nbuckets) {
459 rebuild_hash(s, 2 * nbuckets);
460 }
461 } else {
462 *ptr = 0;
463 base[1]++;
464 }
465 }
466 return sym_index;
467}
468
469ST_FUNC int find_elf_sym(Section *s, const char *name)
470{
471 ElfW(Sym) *sym;
472 Section *hs;
473 int nbuckets, sym_index, h;
474 const char *name1;
475
476 hs = s->hash;
477 if (!hs)
478 return 0;
479 nbuckets = ((int *)hs->data)[0];
480 h = elf_hash((unsigned char *) name) % nbuckets;
481 sym_index = ((int *)hs->data)[2 + h];
482 while (sym_index != 0) {
483 sym = &((ElfW(Sym) *)s->data)[sym_index];
484 name1 = (char *) s->link->data + sym->st_name;
485 if (!strcmp(name, name1))
486 return sym_index;
487 sym_index = ((int *)hs->data)[2 + nbuckets + sym_index];
488 }
489 return 0;
490}
491
492/* return elf symbol value, signal error if 'err' is nonzero, decorate
493 name if FORC */
494ST_FUNC addr_t get_sym_addr(TCCState *s1, const char *name, int err, int forc)
495{
496 int sym_index;
497 ElfW(Sym) *sym;
498 char buf[256];
499 if (forc && s1->leading_underscore
500#ifdef TCC_TARGET_PE
501 /* win32-32bit stdcall symbols always have _ already */
502 && !strchr(name, '@')
503#endif
504 ) {
505 buf[0] = '_';
506 pstrcpy(buf + 1, sizeof(buf) - 1, name);
507 name = buf;
508 }
509 sym_index = find_elf_sym(s1->symtab, name);
510 sym = &((ElfW(Sym) *)s1->symtab->data)[sym_index];
511 if (!sym_index || sym->st_shndx == SHN_UNDEF) {
512 if (err)
513 tcc_error("%s not defined", name);
514 return (addr_t)-1;
515 }
516 return sym->st_value;
517}
518
519/* return elf symbol value */
520LIBTCCAPI void *tcc_get_symbol(TCCState *s, const char *name)
521{
522 addr_t addr = get_sym_addr(s, name, 0, 1);
523 return addr == -1 ? NULL : (void*)(uintptr_t)addr;
524}
525
526/* list elf symbol names and values */
527ST_FUNC void list_elf_symbols(TCCState *s, void *ctx,
528 void (*symbol_cb)(void *ctx, const char *name, const void *val))
529{
530 ElfW(Sym) *sym;
531 Section *symtab;
532 int sym_index, end_sym;
533 const char *name;
534 unsigned char sym_vis, sym_bind;
535
536 symtab = s->symtab;
537 end_sym = symtab->data_offset / sizeof (ElfSym);
538 for (sym_index = 0; sym_index < end_sym; ++sym_index) {
539 sym = &((ElfW(Sym) *)symtab->data)[sym_index];
540 if (sym->st_value) {
541 name = (char *) symtab->link->data + sym->st_name;
542 sym_bind = ELFW(ST_BIND)(sym->st_info);
543 sym_vis = ELFW(ST_VISIBILITY)(sym->st_other);
544 if (sym_bind == STB_GLOBAL && sym_vis == STV_DEFAULT)
545 symbol_cb(ctx, name, (void*)(uintptr_t)sym->st_value);
546 }
547 }
548}
549
550/* list elf symbol names and values */
551LIBTCCAPI void tcc_list_symbols(TCCState *s, void *ctx,
552 void (*symbol_cb)(void *ctx, const char *name, const void *val))
553{
554 list_elf_symbols(s, ctx, symbol_cb);
555}
556
557#ifndef ELF_OBJ_ONLY
558static void
559version_add (TCCState *s1)
560{
561 int i;
562 ElfW(Sym) *sym;
563 ElfW(Verneed) *vn = NULL;
564 Section *symtab;
565 int sym_index, end_sym, nb_versions = 2, nb_entries = 0;
566 ElfW(Half) *versym;
567 const char *name;
568
569 if (0 == nb_sym_versions)
570 return;
571 versym_section = new_section(s1, ".gnu.version", SHT_GNU_versym, SHF_ALLOC);
572 versym_section->sh_entsize = sizeof(ElfW(Half));
573 versym_section->link = s1->dynsym;
574
575 /* add needed symbols */
576 symtab = s1->dynsym;
577 end_sym = symtab->data_offset / sizeof (ElfSym);
578 versym = section_ptr_add(versym_section, end_sym * sizeof(ElfW(Half)));
579 for (sym_index = 0; sym_index < end_sym; ++sym_index) {
580 int dllindex, verndx;
581 sym = &((ElfW(Sym) *)symtab->data)[sym_index];
582 name = (char *) symtab->link->data + sym->st_name;
583 dllindex = find_elf_sym(s1->dynsymtab_section, name);
584 verndx = (dllindex && dllindex < nb_sym_to_version)
585 ? sym_to_version[dllindex] : -1;
586 if (verndx >= 0) {
587 if (!sym_versions[verndx].out_index)
588 sym_versions[verndx].out_index = nb_versions++;
589 versym[sym_index] = sym_versions[verndx].out_index;
590 } else
591 versym[sym_index] = 0;
592 }
593 /* generate verneed section, but not when it will be empty. Some
594 dynamic linkers look at their contents even when DTVERNEEDNUM and
595 section size is zero. */
596 if (nb_versions > 2) {
597 verneed_section = new_section(s1, ".gnu.version_r",
598 SHT_GNU_verneed, SHF_ALLOC);
599 verneed_section->link = s1->dynsym->link;
600 for (i = nb_sym_versions; i-- > 0;) {
601 struct sym_version *sv = &sym_versions[i];
602 int n_same_libs = 0, prev;
603 size_t vnofs;
604 ElfW(Vernaux) *vna = 0;
605 if (sv->out_index < 1)
606 continue;
607 vnofs = section_add(verneed_section, sizeof(*vn), 1);
608 vn = (ElfW(Verneed)*)(verneed_section->data + vnofs);
609 vn->vn_version = 1;
610 vn->vn_file = put_elf_str(verneed_section->link, sv->lib);
611 vn->vn_aux = sizeof (*vn);
612 do {
613 prev = sv->prev_same_lib;
614 if (sv->out_index > 0) {
615 vna = section_ptr_add(verneed_section, sizeof(*vna));
616 vna->vna_hash = elf_hash ((const unsigned char *)sv->version);
617 vna->vna_flags = 0;
618 vna->vna_other = sv->out_index;
619 sv->out_index = -2;
620 vna->vna_name = put_elf_str(verneed_section->link, sv->version);
621 vna->vna_next = sizeof (*vna);
622 n_same_libs++;
623 }
624 if (prev >= 0)
625 sv = &sym_versions[prev];
626 } while(prev >= 0);
627 vna->vna_next = 0;
628 vn = (ElfW(Verneed)*)(verneed_section->data + vnofs);
629 vn->vn_cnt = n_same_libs;
630 vn->vn_next = sizeof(*vn) + n_same_libs * sizeof(*vna);
631 nb_entries++;
632 }
633 if (vn)
634 vn->vn_next = 0;
635 verneed_section->sh_info = nb_entries;
636 }
637 dt_verneednum = nb_entries;
638}
639#endif
640
641/* add an elf symbol : check if it is already defined and patch
642 it. Return symbol index. NOTE that sh_num can be SHN_UNDEF. */
643ST_FUNC int set_elf_sym(Section *s, addr_t value, unsigned long size,
644 int info, int other, int shndx, const char *name)
645{
646 TCCState *s1 = s->s1;
647 ElfW(Sym) *esym;
648 int sym_bind, sym_index, sym_type, esym_bind;
649 unsigned char sym_vis, esym_vis, new_vis;
650
651 sym_bind = ELFW(ST_BIND)(info);
652 sym_type = ELFW(ST_TYPE)(info);
653 sym_vis = ELFW(ST_VISIBILITY)(other);
654
655 if (sym_bind != STB_LOCAL) {
656 /* we search global or weak symbols */
657 sym_index = find_elf_sym(s, name);
658 if (!sym_index)
659 goto do_def;
660 esym = &((ElfW(Sym) *)s->data)[sym_index];
661 if (esym->st_value == value && esym->st_size == size && esym->st_info == info
662 && esym->st_other == other && esym->st_shndx == shndx)
663 return sym_index;
664 if (esym->st_shndx != SHN_UNDEF) {
665 esym_bind = ELFW(ST_BIND)(esym->st_info);
666 /* propagate the most constraining visibility */
667 /* STV_DEFAULT(0)<STV_PROTECTED(3)<STV_HIDDEN(2)<STV_INTERNAL(1) */
668 esym_vis = ELFW(ST_VISIBILITY)(esym->st_other);
669 if (esym_vis == STV_DEFAULT) {
670 new_vis = sym_vis;
671 } else if (sym_vis == STV_DEFAULT) {
672 new_vis = esym_vis;
673 } else {
674 new_vis = (esym_vis < sym_vis) ? esym_vis : sym_vis;
675 }
676 esym->st_other = (esym->st_other & ~ELFW(ST_VISIBILITY)(-1))
677 | new_vis;
678 other = esym->st_other; /* in case we have to patch esym */
679 if (shndx == SHN_UNDEF) {
680 /* ignore adding of undefined symbol if the
681 corresponding symbol is already defined */
682 } else if (sym_bind == STB_GLOBAL && esym_bind == STB_WEAK) {
683 /* global overrides weak, so patch */
684 goto do_patch;
685 } else if (sym_bind == STB_WEAK && esym_bind == STB_GLOBAL) {
686 /* weak is ignored if already global */
687 } else if (sym_bind == STB_WEAK && esym_bind == STB_WEAK) {
688 /* keep first-found weak definition, ignore subsequents */
689 } else if (sym_vis == STV_HIDDEN || sym_vis == STV_INTERNAL) {
690 /* ignore hidden symbols after */
691 } else if ((esym->st_shndx == SHN_COMMON
692 || esym->st_shndx == bss_section->sh_num)
693 && (shndx < SHN_LORESERVE
694 && shndx != bss_section->sh_num)) {
695 /* data symbol gets precedence over common/bss */
696 goto do_patch;
697 } else if (shndx == SHN_COMMON || shndx == bss_section->sh_num) {
698 /* data symbol keeps precedence over common/bss */
699 } else if (s->sh_flags & SHF_DYNSYM) {
700 /* we accept that two DLL define the same symbol */
701 } else if (esym->st_other & ST_ASM_SET) {
702 /* If the existing symbol came from an asm .set
703 we can override. */
704 goto do_patch;
705 } else {
706#if 0
707 printf("new_bind=%x new_shndx=%x new_vis=%x old_bind=%x old_shndx=%x old_vis=%x\n",
708 sym_bind, shndx, new_vis, esym_bind, esym->st_shndx, esym_vis);
709#endif
710 tcc_error_noabort("'%s' defined twice", name);
711 }
712 } else {
713 do_patch:
714 esym->st_info = ELFW(ST_INFO)(sym_bind, sym_type);
715 esym->st_shndx = shndx;
716 s1->new_undef_sym = 1;
717 esym->st_value = value;
718 esym->st_size = size;
719 esym->st_other = other;
720 }
721 } else {
722 do_def:
723 sym_index = put_elf_sym(s, value, size,
724 ELFW(ST_INFO)(sym_bind, sym_type), other,
725 shndx, name);
726 }
727 return sym_index;
728}
729
730/* put relocation */
731ST_FUNC void put_elf_reloca(Section *symtab, Section *s, unsigned long offset,
732 int type, int symbol, addr_t addend)
733{
734 TCCState *s1 = s->s1;
735 char buf[256];
736 Section *sr;
737 ElfW_Rel *rel;
738
739 sr = s->reloc;
740 if (!sr) {
741 /* if no relocation section, create it */
742 snprintf(buf, sizeof(buf), REL_SECTION_FMT, s->name);
743 /* if the symtab is allocated, then we consider the relocation
744 are also */
745 sr = new_section(s->s1, buf, SHT_RELX, symtab->sh_flags);
746 sr->sh_entsize = sizeof(ElfW_Rel);
747 sr->link = symtab;
748 sr->sh_info = s->sh_num;
749 s->reloc = sr;
750 }
751 rel = section_ptr_add(sr, sizeof(ElfW_Rel));
752 rel->r_offset = offset;
753 rel->r_info = ELFW(R_INFO)(symbol, type);
754#if SHT_RELX == SHT_RELA
755 rel->r_addend = addend;
756#endif
757 if (SHT_RELX != SHT_RELA && addend)
758 tcc_error("non-zero addend on REL architecture");
759}
760
761ST_FUNC void put_elf_reloc(Section *symtab, Section *s, unsigned long offset,
762 int type, int symbol)
763{
764 put_elf_reloca(symtab, s, offset, type, symbol, 0);
765}
766
767/* put stab debug information */
768ST_FUNC void put_stabs(TCCState *s1, const char *str, int type, int other, int desc,
769 unsigned long value)
770{
771 Stab_Sym *sym;
772
773 unsigned offset;
774 if (type == N_SLINE
775 && (offset = stab_section->data_offset)
776 && (sym = (Stab_Sym*)(stab_section->data + offset) - 1)
777 && sym->n_type == type
778 && sym->n_value == value) {
779 /* just update line_number in previous entry */
780 sym->n_desc = desc;
781 return;
782 }
783
784 sym = section_ptr_add(stab_section, sizeof(Stab_Sym));
785 if (str) {
786 sym->n_strx = put_elf_str(stab_section->link, str);
787 } else {
788 sym->n_strx = 0;
789 }
790 sym->n_type = type;
791 sym->n_other = other;
792 sym->n_desc = desc;
793 sym->n_value = value;
794}
795
796ST_FUNC void put_stabs_r(TCCState *s1, const char *str, int type, int other, int desc,
797 unsigned long value, Section *sec, int sym_index)
798{
799 put_elf_reloc(symtab_section, stab_section,
800 stab_section->data_offset + 8,
801 sizeof ((Stab_Sym*)0)->n_value == PTR_SIZE ? R_DATA_PTR : R_DATA_32,
802 sym_index);
803 put_stabs(s1, str, type, other, desc, value);
804}
805
806ST_FUNC void put_stabn(TCCState *s1, int type, int other, int desc, int value)
807{
808 put_stabs(s1, NULL, type, other, desc, value);
809}
810
811ST_FUNC struct sym_attr *get_sym_attr(TCCState *s1, int index, int alloc)
812{
813 int n;
814 struct sym_attr *tab;
815
816 if (index >= s1->nb_sym_attrs) {
817 if (!alloc)
818 return s1->sym_attrs;
819 /* find immediately bigger power of 2 and reallocate array */
820 n = 1;
821 while (index >= n)
822 n *= 2;
823 tab = tcc_realloc(s1->sym_attrs, n * sizeof(*s1->sym_attrs));
824 s1->sym_attrs = tab;
825 memset(s1->sym_attrs + s1->nb_sym_attrs, 0,
826 (n - s1->nb_sym_attrs) * sizeof(*s1->sym_attrs));
827 s1->nb_sym_attrs = n;
828 }
829 return &s1->sym_attrs[index];
830}
831
832/* In an ELF file symbol table, the local symbols must appear below
833 the global and weak ones. Since TCC cannot sort it while generating
834 the code, we must do it after. All the relocation tables are also
835 modified to take into account the symbol table sorting */
836static void sort_syms(TCCState *s1, Section *s)
837{
838 int *old_to_new_syms;
839 ElfW(Sym) *new_syms;
840 int nb_syms, i;
841 ElfW(Sym) *p, *q;
842 ElfW_Rel *rel;
843 Section *sr;
844 int type, sym_index;
845
846 nb_syms = s->data_offset / sizeof(ElfW(Sym));
847 new_syms = tcc_malloc(nb_syms * sizeof(ElfW(Sym)));
848 old_to_new_syms = tcc_malloc(nb_syms * sizeof(int));
849
850 /* first pass for local symbols */
851 p = (ElfW(Sym) *)s->data;
852 q = new_syms;
853 for(i = 0; i < nb_syms; i++) {
854 if (ELFW(ST_BIND)(p->st_info) == STB_LOCAL) {
855 old_to_new_syms[i] = q - new_syms;
856 *q++ = *p;
857 }
858 p++;
859 }
860 /* save the number of local symbols in section header */
861 if( s->sh_size ) /* this 'if' makes IDA happy */
862 s->sh_info = q - new_syms;
863
864 /* then second pass for non local symbols */
865 p = (ElfW(Sym) *)s->data;
866 for(i = 0; i < nb_syms; i++) {
867 if (ELFW(ST_BIND)(p->st_info) != STB_LOCAL) {
868 old_to_new_syms[i] = q - new_syms;
869 *q++ = *p;
870 }
871 p++;
872 }
873
874 /* we copy the new symbols to the old */
875 memcpy(s->data, new_syms, nb_syms * sizeof(ElfW(Sym)));
876 tcc_free(new_syms);
877
878 /* now we modify all the relocations */
879 for(i = 1; i < s1->nb_sections; i++) {
880 sr = s1->sections[i];
881 if (sr->sh_type == SHT_RELX && sr->link == s) {
882 for_each_elem(sr, 0, rel, ElfW_Rel) {
883 sym_index = ELFW(R_SYM)(rel->r_info);
884 type = ELFW(R_TYPE)(rel->r_info);
885 sym_index = old_to_new_syms[sym_index];
886 rel->r_info = ELFW(R_INFO)(sym_index, type);
887 }
888 }
889 }
890
891 tcc_free(old_to_new_syms);
892}
893
894/* relocate symbol table, resolve undefined symbols if do_resolve is
895 true and output error if undefined symbol. */
896ST_FUNC void relocate_syms(TCCState *s1, Section *symtab, int do_resolve)
897{
898 ElfW(Sym) *sym;
899 int sym_bind, sh_num;
900 const char *name;
901
902 for_each_elem(symtab, 1, sym, ElfW(Sym)) {
903 sh_num = sym->st_shndx;
904 if (sh_num == SHN_UNDEF) {
905 name = (char *) s1->symtab->link->data + sym->st_name;
906 /* Use ld.so to resolve symbol for us (for tcc -run) */
907 if (do_resolve) {
908#if defined TCC_IS_NATIVE && !defined TCC_TARGET_PE
909#ifdef TCC_TARGET_MACHO
910 /* The symbols in the symtables have a prepended '_'
911 but dlsym() needs the undecorated name. */
912 void *addr = dlsym(RTLD_DEFAULT, name + 1);
913#else
914 void *addr = dlsym(RTLD_DEFAULT, name);
915#endif
916 if (addr) {
917 sym->st_value = (addr_t) addr;
918#ifdef DEBUG_RELOC
919 printf ("relocate_sym: %s -> 0x%lx\n", name, sym->st_value);
920#endif
921 goto found;
922 }
923#endif
924 /* if dynamic symbol exist, it will be used in relocate_section */
925 } else if (s1->dynsym && find_elf_sym(s1->dynsym, name))
926 goto found;
927 /* XXX: _fp_hw seems to be part of the ABI, so we ignore
928 it */
929 if (!strcmp(name, "_fp_hw"))
930 goto found;
931 /* only weak symbols are accepted to be undefined. Their
932 value is zero */
933 sym_bind = ELFW(ST_BIND)(sym->st_info);
934 if (sym_bind == STB_WEAK)
935 sym->st_value = 0;
936 else
937 tcc_error_noabort("undefined symbol '%s'", name);
938 } else if (sh_num < SHN_LORESERVE) {
939 /* add section base */
940 sym->st_value += s1->sections[sym->st_shndx]->sh_addr;
941 }
942 found: ;
943 }
944}
945
946/* relocate a given section (CPU dependent) by applying the relocations
947 in the associated relocation section */
948ST_FUNC void relocate_section(TCCState *s1, Section *s)
949{
950 Section *sr = s->reloc;
951 ElfW_Rel *rel;
952 ElfW(Sym) *sym;
953 int type, sym_index;
954 unsigned char *ptr;
955 addr_t tgt, addr;
956
957 qrel = (ElfW_Rel *)sr->data;
958
959 for_each_elem(sr, 0, rel, ElfW_Rel) {
960 ptr = s->data + rel->r_offset;
961 sym_index = ELFW(R_SYM)(rel->r_info);
962 sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
963 type = ELFW(R_TYPE)(rel->r_info);
964 tgt = sym->st_value;
965#if SHT_RELX == SHT_RELA
966 tgt += rel->r_addend;
967#endif
968 addr = s->sh_addr + rel->r_offset;
969 relocate(s1, rel, type, ptr, addr, tgt);
970 }
971 /* if the relocation is allocated, we change its symbol table */
972 if (sr->sh_flags & SHF_ALLOC) {
973 sr->link = s1->dynsym;
974 if (s1->output_type == TCC_OUTPUT_DLL) {
975 size_t r = (uint8_t*)qrel - sr->data;
976 if (sizeof ((Stab_Sym*)0)->n_value < PTR_SIZE
977 && 0 == strcmp(s->name, ".stab"))
978 r = 0; /* cannot apply 64bit relocation to 32bit value */
979 sr->data_offset = sr->sh_size = r;
980 }
981 }
982}
983
984#ifndef ELF_OBJ_ONLY
985/* relocate relocation table in 'sr' */
986static void relocate_rel(TCCState *s1, Section *sr)
987{
988 Section *s;
989 ElfW_Rel *rel;
990
991 s = s1->sections[sr->sh_info];
992 for_each_elem(sr, 0, rel, ElfW_Rel)
993 rel->r_offset += s->sh_addr;
994}
995
996/* count the number of dynamic relocations so that we can reserve
997 their space */
998static int prepare_dynamic_rel(TCCState *s1, Section *sr)
999{
1000 int count = 0;
1001#if defined(TCC_TARGET_I386) || defined(TCC_TARGET_X86_64) || \
1002 defined(TCC_TARGET_ARM) || defined(TCC_TARGET_ARM64) || \
1003 defined(TCC_TARGET_RISCV64)
1004 ElfW_Rel *rel;
1005 for_each_elem(sr, 0, rel, ElfW_Rel) {
1006 int sym_index = ELFW(R_SYM)(rel->r_info);
1007 int type = ELFW(R_TYPE)(rel->r_info);
1008 switch(type) {
1009#if defined(TCC_TARGET_I386)
1010 case R_386_32:
1011 if (!get_sym_attr(s1, sym_index, 0)->dyn_index
1012 && ((ElfW(Sym)*)symtab_section->data + sym_index)->st_shndx == SHN_UNDEF) {
1013 /* don't fixup unresolved (weak) symbols */
1014 rel->r_info = ELFW(R_INFO)(sym_index, R_386_RELATIVE);
1015 break;
1016 }
1017#elif defined(TCC_TARGET_X86_64)
1018 case R_X86_64_32:
1019 case R_X86_64_32S:
1020 case R_X86_64_64:
1021#elif defined(TCC_TARGET_ARM)
1022 case R_ARM_ABS32:
1023#elif defined(TCC_TARGET_ARM64)
1024 case R_AARCH64_ABS32:
1025 case R_AARCH64_ABS64:
1026#elif defined(TCC_TARGET_RISCV64)
1027 case R_RISCV_32:
1028 case R_RISCV_64:
1029#endif
1030 count++;
1031 break;
1032#if defined(TCC_TARGET_I386)
1033 case R_386_PC32:
1034#elif defined(TCC_TARGET_X86_64)
1035 case R_X86_64_PC32:
1036#elif defined(TCC_TARGET_ARM64)
1037 case R_AARCH64_PREL32:
1038#endif
1039 if (get_sym_attr(s1, sym_index, 0)->dyn_index)
1040 count++;
1041 break;
1042 default:
1043 break;
1044 }
1045 }
1046 if (count) {
1047 /* allocate the section */
1048 sr->sh_flags |= SHF_ALLOC;
1049 sr->sh_size = count * sizeof(ElfW_Rel);
1050 }
1051#endif
1052 return count;
1053}
1054#endif
1055
1056#if !defined(ELF_OBJ_ONLY) || (defined(TCC_TARGET_MACHO) && defined TCC_IS_NATIVE)
1057static void build_got(TCCState *s1)
1058{
1059 /* if no got, then create it */
1060 s1->got = new_section(s1, ".got", SHT_PROGBITS, SHF_ALLOC | SHF_WRITE);
1061 s1->got->sh_entsize = 4;
1062 set_elf_sym(symtab_section, 0, 4, ELFW(ST_INFO)(STB_GLOBAL, STT_OBJECT),
1063 0, s1->got->sh_num, "_GLOBAL_OFFSET_TABLE_");
1064 /* keep space for _DYNAMIC pointer and two dummy got entries */
1065 section_ptr_add(s1->got, 3 * PTR_SIZE);
1066}
1067
1068/* Create a GOT and (for function call) a PLT entry corresponding to a symbol
1069 in s1->symtab. When creating the dynamic symbol table entry for the GOT
1070 relocation, use 'size' and 'info' for the corresponding symbol metadata.
1071 Returns the offset of the GOT or (if any) PLT entry. */
1072static struct sym_attr * put_got_entry(TCCState *s1, int dyn_reloc_type,
1073 int sym_index)
1074{
1075 int need_plt_entry;
1076 const char *name;
1077 ElfW(Sym) *sym;
1078 struct sym_attr *attr;
1079 unsigned got_offset;
1080 char plt_name[100];
1081 int len;
1082
1083 need_plt_entry = (dyn_reloc_type == R_JMP_SLOT);
1084 attr = get_sym_attr(s1, sym_index, 1);
1085
1086 /* In case a function is both called and its address taken 2 GOT entries
1087 are created, one for taking the address (GOT) and the other for the PLT
1088 entry (PLTGOT). */
1089 if (need_plt_entry ? attr->plt_offset : attr->got_offset)
1090 return attr;
1091
1092 /* create the GOT entry */
1093 got_offset = s1->got->data_offset;
1094 section_ptr_add(s1->got, PTR_SIZE);
1095
1096 /* Create the GOT relocation that will insert the address of the object or
1097 function of interest in the GOT entry. This is a static relocation for
1098 memory output (dlsym will give us the address of symbols) and dynamic
1099 relocation otherwise (executable and DLLs). The relocation should be
1100 done lazily for GOT entry with *_JUMP_SLOT relocation type (the one
1101 associated to a PLT entry) but is currently done at load time for an
1102 unknown reason. */
1103
1104 sym = &((ElfW(Sym) *) symtab_section->data)[sym_index];
1105 name = (char *) symtab_section->link->data + sym->st_name;
1106
1107 if (s1->dynsym) {
1108 if (ELFW(ST_BIND)(sym->st_info) == STB_LOCAL) {
1109 /* Hack alarm. We don't want to emit dynamic symbols
1110 and symbol based relocs for STB_LOCAL symbols, but rather
1111 want to resolve them directly. At this point the symbol
1112 values aren't final yet, so we must defer this. We will later
1113 have to create a RELATIVE reloc anyway, so we misuse the
1114 relocation slot to smuggle the symbol reference until
1115 fill_local_got_entries. Not that the sym_index is
1116 relative to symtab_section, not s1->dynsym! Nevertheless
1117 we use s1->dyn_sym so that if this is the first call
1118 that got->reloc is correctly created. Also note that
1119 RELATIVE relocs are not normally created for the .got,
1120 so the types serves as a marker for later (and is retained
1121 also for the final output, which is okay because then the
1122 got is just normal data). */
1123 put_elf_reloc(s1->dynsym, s1->got, got_offset, R_RELATIVE,
1124 sym_index);
1125 } else {
1126 if (0 == attr->dyn_index)
1127 attr->dyn_index = set_elf_sym(s1->dynsym, sym->st_value,
1128 sym->st_size, sym->st_info, 0,
1129 sym->st_shndx, name);
1130 put_elf_reloc(s1->dynsym, s1->got, got_offset, dyn_reloc_type,
1131 attr->dyn_index);
1132 }
1133 } else {
1134 put_elf_reloc(symtab_section, s1->got, got_offset, dyn_reloc_type,
1135 sym_index);
1136 }
1137
1138 if (need_plt_entry) {
1139 if (!s1->plt) {
1140 s1->plt = new_section(s1, ".plt", SHT_PROGBITS,
1141 SHF_ALLOC | SHF_EXECINSTR);
1142 s1->plt->sh_entsize = 4;
1143 }
1144
1145 attr->plt_offset = create_plt_entry(s1, got_offset, attr);
1146
1147 /* create a symbol 'sym@plt' for the PLT jump vector */
1148 len = strlen(name);
1149 if (len > sizeof plt_name - 5)
1150 len = sizeof plt_name - 5;
1151 memcpy(plt_name, name, len);
1152 strcpy(plt_name + len, "@plt");
1153 attr->plt_sym = put_elf_sym(s1->symtab, attr->plt_offset, sym->st_size,
1154 ELFW(ST_INFO)(STB_GLOBAL, STT_FUNC), 0, s1->plt->sh_num, plt_name);
1155
1156 } else {
1157 attr->got_offset = got_offset;
1158 }
1159
1160 return attr;
1161}
1162
1163/* build GOT and PLT entries */
1164ST_FUNC void build_got_entries(TCCState *s1)
1165{
1166 Section *s;
1167 ElfW_Rel *rel;
1168 ElfW(Sym) *sym;
1169 int i, type, gotplt_entry, reloc_type, sym_index;
1170 struct sym_attr *attr;
1171
1172 for(i = 1; i < s1->nb_sections; i++) {
1173 s = s1->sections[i];
1174 if (s->sh_type != SHT_RELX)
1175 continue;
1176 /* no need to handle got relocations */
1177 if (s->link != symtab_section)
1178 continue;
1179 for_each_elem(s, 0, rel, ElfW_Rel) {
1180 type = ELFW(R_TYPE)(rel->r_info);
1181 gotplt_entry = gotplt_entry_type(type);
1182 if (gotplt_entry == -1)
1183 tcc_error ("Unknown relocation type for got: %d", type);
1184 sym_index = ELFW(R_SYM)(rel->r_info);
1185 sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
1186
1187 if (gotplt_entry == NO_GOTPLT_ENTRY) {
1188 continue;
1189 }
1190
1191 /* Automatically create PLT/GOT [entry] if it is an undefined
1192 reference (resolved at runtime), or the symbol is absolute,
1193 probably created by tcc_add_symbol, and thus on 64-bit
1194 targets might be too far from application code. */
1195 if (gotplt_entry == AUTO_GOTPLT_ENTRY) {
1196 if (sym->st_shndx == SHN_UNDEF) {
1197 ElfW(Sym) *esym;
1198 int dynindex;
1199 if (s1->output_type == TCC_OUTPUT_DLL && ! PCRELATIVE_DLLPLT)
1200 continue;
1201 /* Relocations for UNDEF symbols would normally need
1202 to be transferred into the executable or shared object.
1203 If that were done AUTO_GOTPLT_ENTRY wouldn't exist.
1204 But TCC doesn't do that (at least for exes), so we
1205 need to resolve all such relocs locally. And that
1206 means PLT slots for functions in DLLs and COPY relocs for
1207 data symbols. COPY relocs were generated in
1208 bind_exe_dynsyms (and the symbol adjusted to be defined),
1209 and for functions we were generated a dynamic symbol
1210 of function type. */
1211 if (s1->dynsym) {
1212 /* dynsym isn't set for -run :-/ */
1213 dynindex = get_sym_attr(s1, sym_index, 0)->dyn_index;
1214 esym = (ElfW(Sym) *)s1->dynsym->data + dynindex;
1215 if (dynindex
1216 && (ELFW(ST_TYPE)(esym->st_info) == STT_FUNC
1217 || (ELFW(ST_TYPE)(esym->st_info) == STT_NOTYPE
1218 && ELFW(ST_TYPE)(sym->st_info) == STT_FUNC)))
1219 goto jmp_slot;
1220 }
1221 } else if (!(sym->st_shndx == SHN_ABS
1222#ifndef TCC_TARGET_ARM
1223 && PTR_SIZE == 8
1224#endif
1225 ))
1226 continue;
1227 }
1228
1229#ifdef TCC_TARGET_X86_64
1230 if ((type == R_X86_64_PLT32 || type == R_X86_64_PC32) &&
1231 sym->st_shndx != SHN_UNDEF &&
1232 (ELFW(ST_VISIBILITY)(sym->st_other) != STV_DEFAULT ||
1233 ELFW(ST_BIND)(sym->st_info) == STB_LOCAL ||
1234 s1->output_type == TCC_OUTPUT_EXE)) {
1235 rel->r_info = ELFW(R_INFO)(sym_index, R_X86_64_PC32);
1236 continue;
1237 }
1238#endif
1239 reloc_type = code_reloc(type);
1240 if (reloc_type == -1)
1241 tcc_error ("Unknown relocation type: %d", type);
1242 else if (reloc_type != 0) {
1243 jmp_slot:
1244 reloc_type = R_JMP_SLOT;
1245 } else
1246 reloc_type = R_GLOB_DAT;
1247
1248 if (!s1->got)
1249 build_got(s1);
1250
1251 if (gotplt_entry == BUILD_GOT_ONLY)
1252 continue;
1253
1254 attr = put_got_entry(s1, reloc_type, sym_index);
1255
1256 if (reloc_type == R_JMP_SLOT)
1257 rel->r_info = ELFW(R_INFO)(attr->plt_sym, type);
1258 }
1259 }
1260}
1261#endif
1262
1263ST_FUNC int set_global_sym(TCCState *s1, const char *name, Section *sec, addr_t offs)
1264{
1265 int shn = sec ? sec->sh_num : offs ? SHN_ABS : SHN_UNDEF;
1266 if (sec && offs == -1)
1267 offs = sec->data_offset;
1268 return set_elf_sym(symtab_section, offs, 0,
1269 ELFW(ST_INFO)(name ? STB_GLOBAL : STB_LOCAL, STT_NOTYPE), 0, shn, name);
1270}
1271
1272static void add_init_array_defines(TCCState *s1, const char *section_name)
1273{
1274 Section *s;
1275 addr_t end_offset;
1276 char buf[1024];
1277 s = find_section(s1, section_name);
1278 if (!s) {
1279 end_offset = 0;
1280 s = data_section;
1281 } else {
1282 end_offset = s->data_offset;
1283 }
1284 snprintf(buf, sizeof(buf), "__%s_start", section_name + 1);
1285 set_global_sym(s1, buf, s, 0);
1286 snprintf(buf, sizeof(buf), "__%s_end", section_name + 1);
1287 set_global_sym(s1, buf, s, end_offset);
1288}
1289
1290#ifndef TCC_TARGET_PE
1291static void tcc_add_support(TCCState *s1, const char *filename)
1292{
1293 char buf[1024];
1294 snprintf(buf, sizeof(buf), "%s/%s", s1->tcc_lib_path, filename);
1295 tcc_add_file(s1, buf);
1296}
1297#endif
1298
1299ST_FUNC void add_array (TCCState *s1, const char *sec, int c)
1300{
1301 Section *s;
1302 s = find_section(s1, sec);
1303 s->sh_flags |= SHF_WRITE;
1304#ifndef TCC_TARGET_PE
1305 s->sh_type = sec[1] == 'i' ? SHT_INIT_ARRAY : SHT_FINI_ARRAY;
1306#endif
1307 put_elf_reloc (s1->symtab, s, s->data_offset, R_DATA_PTR, c);
1308 section_ptr_add(s, PTR_SIZE);
1309}
1310
1311#ifdef CONFIG_TCC_BCHECK
1312ST_FUNC void tcc_add_bcheck(TCCState *s1)
1313{
1314 if (0 == s1->do_bounds_check)
1315 return;
1316 section_ptr_add(bounds_section, sizeof(addr_t));
1317}
1318#endif
1319
1320#ifdef CONFIG_TCC_BACKTRACE
1321static void put_ptr(TCCState *s1, Section *s, int offs)
1322{
1323 int c;
1324 c = set_global_sym(s1, NULL, s, offs);
1325 s = data_section;
1326 put_elf_reloc (s1->symtab, s, s->data_offset, R_DATA_PTR, c);
1327 section_ptr_add(s, PTR_SIZE);
1328}
1329
1330/* set symbol to STB_LOCAL and resolve. The point is to not export it as
1331 a dynamic symbol to allow so's to have one each with a different value. */
1332static void set_local_sym(TCCState *s1, const char *name, Section *s, int offset)
1333{
1334 int c = find_elf_sym(s1->symtab, name);
1335 if (c) {
1336 ElfW(Sym) *esym = (ElfW(Sym)*)s1->symtab->data + c;
1337 esym->st_info = ELFW(ST_INFO)(STB_LOCAL, STT_NOTYPE);
1338 esym->st_value = offset;
1339 esym->st_shndx = s->sh_num;
1340 }
1341}
1342
1343ST_FUNC void tcc_add_btstub(TCCState *s1)
1344{
1345 Section *s;
1346 int n, o;
1347 CString cstr;
1348
1349 s = data_section;
1350 o = s->data_offset;
1351 /* create (part of) a struct rt_context (see tccrun.c) */
1352 put_ptr(s1, stab_section, 0);
1353 put_ptr(s1, stab_section, -1);
1354 put_ptr(s1, stab_section->link, 0);
1355 section_ptr_add(s, 3 * PTR_SIZE);
1356 /* prog_base */
1357#ifndef TCC_TARGET_MACHO
1358 /* XXX this relocation is wrong, it uses sym-index 0 (local,undef) */
1359 put_elf_reloc(s1->symtab, s, s->data_offset, R_DATA_PTR, 0);
1360#endif
1361 section_ptr_add(s, PTR_SIZE);
1362 n = 2 * PTR_SIZE;
1363#ifdef CONFIG_TCC_BCHECK
1364 if (s1->do_bounds_check) {
1365 put_ptr(s1, bounds_section, 0);
1366 n -= PTR_SIZE;
1367 }
1368#endif
1369 section_ptr_add(s, n);
1370
1371 cstr_new(&cstr);
1372 cstr_printf(&cstr,
1373 " extern void __bt_init(),*__rt_info[],__bt_init_dll();"
1374 "__attribute__((constructor)) static void __bt_init_rt(){");
1375#ifdef TCC_TARGET_PE
1376 if (s1->output_type == TCC_OUTPUT_DLL)
1377#ifdef CONFIG_TCC_BCHECK
1378 cstr_printf(&cstr, "__bt_init_dll(%d);", s1->do_bounds_check);
1379#else
1380 cstr_printf(&cstr, "__bt_init_dll(0);");
1381#endif
1382#endif
1383 cstr_printf(&cstr, "__bt_init(__rt_info,%d, 0);}",
1384 s1->output_type == TCC_OUTPUT_DLL ? 0 : s1->rt_num_callers + 1);
1385 tcc_compile_string(s1, cstr.data);
1386 cstr_free(&cstr);
1387 set_local_sym(s1, &"___rt_info"[!s1->leading_underscore], s, o);
1388}
1389#endif
1390
1391#ifndef TCC_TARGET_PE
1392/* add tcc runtime libraries */
1393ST_FUNC void tcc_add_runtime(TCCState *s1)
1394{
1395 s1->filetype = 0;
1396#ifdef CONFIG_TCC_BCHECK
1397 tcc_add_bcheck(s1);
1398#endif
1399 tcc_add_pragma_libs(s1);
1400 /* add libc */
1401 if (!s1->nostdlib) {
1402 if (s1->option_pthread)
1403 tcc_add_library_err(s1, "pthread");
1404 tcc_add_library_err(s1, "c");
1405#ifdef TCC_LIBGCC
1406 if (!s1->static_link) {
1407 if (TCC_LIBGCC[0] == '/')
1408 tcc_add_file(s1, TCC_LIBGCC);
1409 else
1410 tcc_add_dll(s1, TCC_LIBGCC, 0);
1411 }
1412#endif
1413#ifdef CONFIG_TCC_BCHECK
1414 if (s1->do_bounds_check && s1->output_type != TCC_OUTPUT_DLL) {
1415 tcc_add_library_err(s1, "pthread");
1416 tcc_add_library_err(s1, "dl");
1417 tcc_add_support(s1, "bcheck.o");
1418 }
1419#endif
1420#ifdef CONFIG_TCC_BACKTRACE
1421 if (s1->do_backtrace) {
1422 if (s1->output_type == TCC_OUTPUT_EXE)
1423 tcc_add_support(s1, "bt-exe.o");
1424 if (s1->output_type != TCC_OUTPUT_DLL)
1425 tcc_add_support(s1, "bt-log.o");
1426 if (s1->output_type != TCC_OUTPUT_MEMORY)
1427 tcc_add_btstub(s1);
1428 }
1429#endif
1430 if (strlen(TCC_LIBTCC1) > 0)
1431 tcc_add_support(s1, TCC_LIBTCC1);
1432#ifndef TCC_TARGET_MACHO
1433 /* add crt end if not memory output */
1434 if (s1->output_type != TCC_OUTPUT_MEMORY)
1435 tcc_add_crt(s1, "crtn.o");
1436#endif
1437 }
1438}
1439#endif
1440
1441/* add various standard linker symbols (must be done after the
1442 sections are filled (for example after allocating common
1443 symbols)) */
1444static void tcc_add_linker_symbols(TCCState *s1)
1445{
1446 char buf[1024];
1447 int i;
1448 Section *s;
1449
1450 set_global_sym(s1, "_etext", text_section, -1);
1451 set_global_sym(s1, "_edata", data_section, -1);
1452 set_global_sym(s1, "_end", bss_section, -1);
1453#ifdef TCC_TARGET_RISCV64
1454 /* XXX should be .sdata+0x800, not .data+0x800 */
1455 set_global_sym(s1, "__global_pointer$", data_section, 0x800);
1456#endif
1457 /* horrible new standard ldscript defines */
1458 add_init_array_defines(s1, ".preinit_array");
1459 add_init_array_defines(s1, ".init_array");
1460 add_init_array_defines(s1, ".fini_array");
1461 /* add start and stop symbols for sections whose name can be
1462 expressed in C */
1463 for(i = 1; i < s1->nb_sections; i++) {
1464 s = s1->sections[i];
1465 if ((s->sh_flags & SHF_ALLOC)
1466 && (s->sh_type == SHT_PROGBITS
1467 || s->sh_type == SHT_STRTAB)) {
1468 const char *p;
1469 /* check if section name can be expressed in C */
1470 p = s->name;
1471 for(;;) {
1472 int c = *p;
1473 if (!c)
1474 break;
1475 if (!isid(c) && !isnum(c))
1476 goto next_sec;
1477 p++;
1478 }
1479 snprintf(buf, sizeof(buf), "__start_%s", s->name);
1480 set_global_sym(s1, buf, s, 0);
1481 snprintf(buf, sizeof(buf), "__stop_%s", s->name);
1482 set_global_sym(s1, buf, s, -1);
1483 }
1484 next_sec: ;
1485 }
1486}
1487
1488ST_FUNC void resolve_common_syms(TCCState *s1)
1489{
1490 ElfW(Sym) *sym;
1491
1492 /* Allocate common symbols in BSS. */
1493 for_each_elem(symtab_section, 1, sym, ElfW(Sym)) {
1494 if (sym->st_shndx == SHN_COMMON) {
1495 /* symbol alignment is in st_value for SHN_COMMONs */
1496 sym->st_value = section_add(bss_section, sym->st_size,
1497 sym->st_value);
1498 sym->st_shndx = bss_section->sh_num;
1499 }
1500 }
1501
1502 /* Now assign linker provided symbols their value. */
1503 tcc_add_linker_symbols(s1);
1504}
1505
1506static void tcc_output_binary(TCCState *s1, FILE *f,
1507 const int *sec_order)
1508{
1509 Section *s;
1510 int i, offset, size;
1511
1512 offset = 0;
1513 for(i=1;i<s1->nb_sections;i++) {
1514 s = s1->sections[sec_order[i]];
1515 if (s->sh_type != SHT_NOBITS &&
1516 (s->sh_flags & SHF_ALLOC)) {
1517 while (offset < s->sh_offset) {
1518 fputc(0, f);
1519 offset++;
1520 }
1521 size = s->sh_size;
1522 fwrite(s->data, 1, size, f);
1523 offset += size;
1524 }
1525 }
1526}
1527
1528#ifndef ELF_OBJ_ONLY
1529ST_FUNC void fill_got_entry(TCCState *s1, ElfW_Rel *rel)
1530{
1531 int sym_index = ELFW(R_SYM) (rel->r_info);
1532 ElfW(Sym) *sym = &((ElfW(Sym) *) symtab_section->data)[sym_index];
1533 struct sym_attr *attr = get_sym_attr(s1, sym_index, 0);
1534 unsigned offset = attr->got_offset;
1535
1536 if (0 == offset)
1537 return;
1538 section_reserve(s1->got, offset + PTR_SIZE);
1539#if PTR_SIZE == 8
1540 write64le(s1->got->data + offset, sym->st_value);
1541#else
1542 write32le(s1->got->data + offset, sym->st_value);
1543#endif
1544}
1545
1546/* Perform relocation to GOT or PLT entries */
1547ST_FUNC void fill_got(TCCState *s1)
1548{
1549 Section *s;
1550 ElfW_Rel *rel;
1551 int i;
1552
1553 for(i = 1; i < s1->nb_sections; i++) {
1554 s = s1->sections[i];
1555 if (s->sh_type != SHT_RELX)
1556 continue;
1557 /* no need to handle got relocations */
1558 if (s->link != symtab_section)
1559 continue;
1560 for_each_elem(s, 0, rel, ElfW_Rel) {
1561 switch (ELFW(R_TYPE) (rel->r_info)) {
1562 case R_X86_64_GOT32:
1563 case R_X86_64_GOTPCREL:
1564 case R_X86_64_GOTPCRELX:
1565 case R_X86_64_REX_GOTPCRELX:
1566 case R_X86_64_PLT32:
1567 fill_got_entry(s1, rel);
1568 break;
1569 }
1570 }
1571 }
1572}
1573
1574/* See put_got_entry for a description. This is the second stage
1575 where GOT references to local defined symbols are rewritten. */
1576static void fill_local_got_entries(TCCState *s1)
1577{
1578 ElfW_Rel *rel;
1579 if (!s1->got->reloc)
1580 return;
1581 for_each_elem(s1->got->reloc, 0, rel, ElfW_Rel) {
1582 if (ELFW(R_TYPE)(rel->r_info) == R_RELATIVE) {
1583 int sym_index = ELFW(R_SYM) (rel->r_info);
1584 ElfW(Sym) *sym = &((ElfW(Sym) *) symtab_section->data)[sym_index];
1585 struct sym_attr *attr = get_sym_attr(s1, sym_index, 0);
1586 unsigned offset = attr->got_offset;
1587 if (offset != rel->r_offset - s1->got->sh_addr)
1588 tcc_error_noabort("huh");
1589 rel->r_info = ELFW(R_INFO)(0, R_RELATIVE);
1590#if SHT_RELX == SHT_RELA
1591 rel->r_addend = sym->st_value;
1592#else
1593 /* All our REL architectures also happen to be 32bit LE. */
1594 write32le(s1->got->data + offset, sym->st_value);
1595#endif
1596 }
1597 }
1598}
1599
1600/* Bind symbols of executable: resolve undefined symbols from exported symbols
1601 in shared libraries and export non local defined symbols to shared libraries
1602 if -rdynamic switch was given on command line */
1603static void bind_exe_dynsyms(TCCState *s1)
1604{
1605 const char *name;
1606 int sym_index, index;
1607 ElfW(Sym) *sym, *esym;
1608 int type;
1609
1610 /* Resolve undefined symbols from dynamic symbols. When there is a match:
1611 - if STT_FUNC or STT_GNU_IFUNC symbol -> add it in PLT
1612 - if STT_OBJECT symbol -> add it in .bss section with suitable reloc */
1613 for_each_elem(symtab_section, 1, sym, ElfW(Sym)) {
1614 if (sym->st_shndx == SHN_UNDEF) {
1615 name = (char *) symtab_section->link->data + sym->st_name;
1616 sym_index = find_elf_sym(s1->dynsymtab_section, name);
1617 if (sym_index) {
1618 esym = &((ElfW(Sym) *)s1->dynsymtab_section->data)[sym_index];
1619 type = ELFW(ST_TYPE)(esym->st_info);
1620 if ((type == STT_FUNC) || (type == STT_GNU_IFUNC)) {
1621 /* Indirect functions shall have STT_FUNC type in executable
1622 * dynsym section. Indeed, a dlsym call following a lazy
1623 * resolution would pick the symbol value from the
1624 * executable dynsym entry which would contain the address
1625 * of the function wanted by the caller of dlsym instead of
1626 * the address of the function that would return that
1627 * address */
1628 int dynindex
1629 = put_elf_sym(s1->dynsym, 0, esym->st_size,
1630 ELFW(ST_INFO)(STB_GLOBAL,STT_FUNC), 0, 0,
1631 name);
1632 int index = sym - (ElfW(Sym) *) symtab_section->data;
1633 get_sym_attr(s1, index, 1)->dyn_index = dynindex;
1634 } else if (type == STT_OBJECT) {
1635 unsigned long offset;
1636 ElfW(Sym) *dynsym;
1637 offset = bss_section->data_offset;
1638 /* XXX: which alignment ? */
1639 offset = (offset + 16 - 1) & -16;
1640 set_elf_sym (s1->symtab, offset, esym->st_size,
1641 esym->st_info, 0, bss_section->sh_num, name);
1642 index = put_elf_sym(s1->dynsym, offset, esym->st_size,
1643 esym->st_info, 0, bss_section->sh_num,
1644 name);
1645
1646 /* Ensure R_COPY works for weak symbol aliases */
1647 if (ELFW(ST_BIND)(esym->st_info) == STB_WEAK) {
1648 for_each_elem(s1->dynsymtab_section, 1, dynsym, ElfW(Sym)) {
1649 if ((dynsym->st_value == esym->st_value)
1650 && (ELFW(ST_BIND)(dynsym->st_info) == STB_GLOBAL)) {
1651 char *dynname = (char *) s1->dynsymtab_section->link->data
1652 + dynsym->st_name;
1653 put_elf_sym(s1->dynsym, offset, dynsym->st_size,
1654 dynsym->st_info, 0,
1655 bss_section->sh_num, dynname);
1656 break;
1657 }
1658 }
1659 }
1660
1661 put_elf_reloc(s1->dynsym, bss_section,
1662 offset, R_COPY, index);
1663 offset += esym->st_size;
1664 bss_section->data_offset = offset;
1665 }
1666 } else {
1667 /* STB_WEAK undefined symbols are accepted */
1668 /* XXX: _fp_hw seems to be part of the ABI, so we ignore it */
1669 if (ELFW(ST_BIND)(sym->st_info) == STB_WEAK ||
1670 !strcmp(name, "_fp_hw")) {
1671 } else {
1672 tcc_error_noabort("undefined symbol '%s'", name);
1673 }
1674 }
1675 } else if (s1->rdynamic && ELFW(ST_BIND)(sym->st_info) != STB_LOCAL) {
1676 /* if -rdynamic option, then export all non local symbols */
1677 name = (char *) symtab_section->link->data + sym->st_name;
1678 set_elf_sym(s1->dynsym, sym->st_value, sym->st_size, sym->st_info,
1679 0, sym->st_shndx, name);
1680 }
1681 }
1682}
1683
1684/* Bind symbols of libraries: export all non local symbols of executable that
1685 are referenced by shared libraries. The reason is that the dynamic loader
1686 search symbol first in executable and then in libraries. Therefore a
1687 reference to a symbol already defined by a library can still be resolved by
1688 a symbol in the executable. */
1689static void bind_libs_dynsyms(TCCState *s1)
1690{
1691 const char *name;
1692 int sym_index;
1693 ElfW(Sym) *sym, *esym;
1694
1695 for_each_elem(s1->dynsymtab_section, 1, esym, ElfW(Sym)) {
1696 name = (char *) s1->dynsymtab_section->link->data + esym->st_name;
1697 sym_index = find_elf_sym(symtab_section, name);
1698 sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
1699 if (sym_index && sym->st_shndx != SHN_UNDEF
1700 && ELFW(ST_BIND)(sym->st_info) != STB_LOCAL) {
1701 set_elf_sym(s1->dynsym, sym->st_value, sym->st_size,
1702 sym->st_info, 0, sym->st_shndx, name);
1703 } else if (esym->st_shndx == SHN_UNDEF) {
1704 /* weak symbols can stay undefined */
1705 if (ELFW(ST_BIND)(esym->st_info) != STB_WEAK)
1706 tcc_warning("undefined dynamic symbol '%s'", name);
1707 }
1708 }
1709}
1710
1711/* Export all non local symbols. This is used by shared libraries so that the
1712 non local symbols they define can resolve a reference in another shared
1713 library or in the executable. Correspondingly, it allows undefined local
1714 symbols to be resolved by other shared libraries or by the executable. */
1715static void export_global_syms(TCCState *s1)
1716{
1717 int dynindex, index;
1718 const char *name;
1719 ElfW(Sym) *sym;
1720
1721 for_each_elem(symtab_section, 1, sym, ElfW(Sym)) {
1722 if (ELFW(ST_BIND)(sym->st_info) != STB_LOCAL) {
1723 name = (char *) symtab_section->link->data + sym->st_name;
1724 dynindex = put_elf_sym(s1->dynsym, sym->st_value, sym->st_size,
1725 sym->st_info, 0, sym->st_shndx, name);
1726 index = sym - (ElfW(Sym) *) symtab_section->data;
1727 get_sym_attr(s1, index, 1)->dyn_index = dynindex;
1728 }
1729 }
1730}
1731#endif
1732
1733/* Allocate strings for section names and decide if an unallocated section
1734 should be output.
1735 NOTE: the strsec section comes last, so its size is also correct ! */
1736static int alloc_sec_names(TCCState *s1, int file_type, Section *strsec)
1737{
1738 int i;
1739 Section *s;
1740 int textrel = 0;
1741
1742 /* Allocate strings for section names */
1743 for(i = 1; i < s1->nb_sections; i++) {
1744 s = s1->sections[i];
1745 /* when generating a DLL, we include relocations but we may
1746 patch them */
1747#ifndef ELF_OBJ_ONLY
1748 if (file_type == TCC_OUTPUT_DLL &&
1749 s->sh_type == SHT_RELX &&
1750 !(s->sh_flags & SHF_ALLOC) &&
1751 (s1->sections[s->sh_info]->sh_flags & SHF_ALLOC) &&
1752 prepare_dynamic_rel(s1, s)) {
1753 if (!(s1->sections[s->sh_info]->sh_flags & SHF_WRITE))
1754 textrel = 1;
1755 } else
1756#endif
1757 if ((s1->do_debug && s->sh_type != SHT_RELX) ||
1758 file_type == TCC_OUTPUT_OBJ ||
1759 (s->sh_flags & SHF_ALLOC) ||
1760 i == (s1->nb_sections - 1)
1761#ifdef TCC_TARGET_ARM
1762 || s->sh_type == SHT_ARM_ATTRIBUTES
1763#endif
1764 ) {
1765 /* we output all sections if debug or object file */
1766 s->sh_size = s->data_offset;
1767 }
1768#ifdef TCC_TARGET_ARM
1769 /* XXX: Suppress stack unwinding section. */
1770 if (s->sh_type == SHT_ARM_EXIDX) {
1771 s->sh_flags = 0;
1772 s->sh_size = 0;
1773 }
1774#endif
1775 if (s->sh_size || (s->sh_flags & SHF_ALLOC))
1776 s->sh_name = put_elf_str(strsec, s->name);
1777 }
1778 strsec->sh_size = strsec->data_offset;
1779 return textrel;
1780}
1781
1782/* Info to be copied in dynamic section */
1783struct dyn_inf {
1784 Section *dynamic;
1785 Section *dynstr;
1786 unsigned long data_offset;
1787 addr_t rel_addr;
1788 addr_t rel_size;
1789#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
1790 addr_t bss_addr;
1791 addr_t bss_size;
1792#endif
1793};
1794
1795/* Assign sections to segments and decide how are sections laid out when loaded
1796 in memory. This function also fills corresponding program headers. */
1797static int layout_sections(TCCState *s1, ElfW(Phdr) *phdr, int phnum,
1798 Section *interp, Section* strsec,
1799 struct dyn_inf *dyninf, int *sec_order)
1800{
1801 int i, j, k, file_type, sh_order_index, file_offset;
1802 unsigned long s_align;
1803 long long tmp;
1804 addr_t addr;
1805 ElfW(Phdr) *ph;
1806 Section *s;
1807
1808 file_type = s1->output_type;
1809 sh_order_index = 1;
1810 file_offset = 0;
1811 if (s1->output_format == TCC_OUTPUT_FORMAT_ELF)
1812 file_offset = sizeof(ElfW(Ehdr)) + phnum * sizeof(ElfW(Phdr));
1813 s_align = ELF_PAGE_SIZE;
1814 if (s1->section_align)
1815 s_align = s1->section_align;
1816
1817 if (phnum > 0) {
1818 if (s1->has_text_addr) {
1819 int a_offset, p_offset;
1820 addr = s1->text_addr;
1821 /* we ensure that (addr % ELF_PAGE_SIZE) == file_offset %
1822 ELF_PAGE_SIZE */
1823 a_offset = (int) (addr & (s_align - 1));
1824 p_offset = file_offset & (s_align - 1);
1825 if (a_offset < p_offset)
1826 a_offset += s_align;
1827 file_offset += (a_offset - p_offset);
1828 } else {
1829 if (file_type == TCC_OUTPUT_DLL)
1830 addr = 0;
1831 else
1832 addr = ELF_START_ADDR;
1833 /* compute address after headers */
1834 addr += (file_offset & (s_align - 1));
1835 }
1836
1837 ph = &phdr[0];
1838 /* Leave one program headers for the program interpreter and one for
1839 the program header table itself if needed. These are done later as
1840 they require section layout to be done first. */
1841 if (interp)
1842 ph += 2;
1843
1844 /* dynamic relocation table information, for .dynamic section */
1845 dyninf->rel_addr = dyninf->rel_size = 0;
1846#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
1847 dyninf->bss_addr = dyninf->bss_size = 0;
1848#endif
1849
1850 for(j = 0; j < (phnum == 6 ? 3 : 2); j++) {
1851 ph->p_type = j == 2 ? PT_TLS : PT_LOAD;
1852 if (j == 0)
1853 ph->p_flags = PF_R | PF_X;
1854 else
1855 ph->p_flags = PF_R | PF_W;
1856 ph->p_align = j == 2 ? 4 : s_align;
1857
1858 /* Decide the layout of sections loaded in memory. This must
1859 be done before program headers are filled since they contain
1860 info about the layout. We do the following ordering: interp,
1861 symbol tables, relocations, progbits, nobits */
1862 /* XXX: do faster and simpler sorting */
1863 for(k = 0; k < 5; k++) {
1864 for(i = 1; i < s1->nb_sections; i++) {
1865 s = s1->sections[i];
1866 /* compute if section should be included */
1867 if (j == 0) {
1868 if ((s->sh_flags & (SHF_ALLOC | SHF_WRITE | SHF_TLS)) !=
1869 SHF_ALLOC)
1870 continue;
1871 } else if (j == 1) {
1872 if ((s->sh_flags & (SHF_ALLOC | SHF_WRITE | SHF_TLS)) !=
1873 (SHF_ALLOC | SHF_WRITE))
1874 continue;
1875 } else {
1876 if ((s->sh_flags & (SHF_ALLOC | SHF_WRITE | SHF_TLS)) !=
1877 (SHF_ALLOC | SHF_WRITE | SHF_TLS))
1878 continue;
1879 }
1880 if (s == interp) {
1881 if (k != 0)
1882 continue;
1883 } else if ((s->sh_type == SHT_DYNSYM ||
1884 s->sh_type == SHT_STRTAB ||
1885 s->sh_type == SHT_HASH)
1886 && !strstr(s->name, ".stab")) {
1887 if (k != 1)
1888 continue;
1889 } else if (s->sh_type == SHT_RELX) {
1890 if (k != 2)
1891 continue;
1892 } else if (s->sh_type == SHT_NOBITS) {
1893 if (k != 4)
1894 continue;
1895 } else {
1896 if (k != 3)
1897 continue;
1898 }
1899 sec_order[sh_order_index++] = i;
1900
1901 /* section matches: we align it and add its size */
1902 tmp = addr;
1903 addr = (addr + s->sh_addralign - 1) &
1904 ~(s->sh_addralign - 1);
1905 file_offset += (int) ( addr - tmp );
1906 s->sh_offset = file_offset;
1907 s->sh_addr = addr;
1908
1909 /* update program header infos */
1910 if (ph->p_offset == 0) {
1911 ph->p_offset = file_offset;
1912 ph->p_vaddr = addr;
1913 ph->p_paddr = ph->p_vaddr;
1914 }
1915 /* update dynamic relocation infos */
1916 if (s->sh_type == SHT_RELX) {
1917#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
1918 if (!strcmp(strsec->data + s->sh_name, ".rel.got")) {
1919 dyninf->rel_addr = addr;
1920 dyninf->rel_size += s->sh_size; /* XXX only first rel. */
1921 }
1922 if (!strcmp(strsec->data + s->sh_name, ".rel.bss")) {
1923 dyninf->bss_addr = addr;
1924 dyninf->bss_size = s->sh_size; /* XXX only first rel. */
1925 }
1926#else
1927 if (dyninf->rel_size == 0)
1928 dyninf->rel_addr = addr;
1929 dyninf->rel_size += s->sh_size;
1930#endif
1931 }
1932 addr += s->sh_size;
1933 if (s->sh_type != SHT_NOBITS)
1934 file_offset += s->sh_size;
1935 }
1936 }
1937 if (j == 0) {
1938 /* Make the first PT_LOAD segment include the program
1939 headers itself (and the ELF header as well), it'll
1940 come out with same memory use but will make various
1941 tools like binutils strip work better. */
1942 ph->p_offset &= ~(ph->p_align - 1);
1943 ph->p_vaddr &= ~(ph->p_align - 1);
1944 ph->p_paddr &= ~(ph->p_align - 1);
1945 }
1946 ph->p_filesz = file_offset - ph->p_offset;
1947 ph->p_memsz = addr - ph->p_vaddr;
1948 ph++;
1949 if (j == 0) {
1950 if (s1->output_format == TCC_OUTPUT_FORMAT_ELF) {
1951 /* if in the middle of a page, we duplicate the page in
1952 memory so that one copy is RX and the other is RW */
1953 if ((addr & (s_align - 1)) != 0)
1954 addr += s_align;
1955 } else {
1956 addr = (addr + s_align - 1) & ~(s_align - 1);
1957 file_offset = (file_offset + s_align - 1) & ~(s_align - 1);
1958 }
1959 }
1960 }
1961 }
1962
1963 /* all other sections come after */
1964 for(i = 1; i < s1->nb_sections; i++) {
1965 s = s1->sections[i];
1966 if (phnum > 0 && (s->sh_flags & SHF_ALLOC))
1967 continue;
1968 sec_order[sh_order_index++] = i;
1969
1970 file_offset = (file_offset + s->sh_addralign - 1) &
1971 ~(s->sh_addralign - 1);
1972 s->sh_offset = file_offset;
1973 if (s->sh_type != SHT_NOBITS)
1974 file_offset += s->sh_size;
1975 }
1976
1977 return file_offset;
1978}
1979
1980#ifndef ELF_OBJ_ONLY
1981/* put dynamic tag */
1982static void put_dt(Section *dynamic, int dt, addr_t val)
1983{
1984 ElfW(Dyn) *dyn;
1985 dyn = section_ptr_add(dynamic, sizeof(ElfW(Dyn)));
1986 dyn->d_tag = dt;
1987 dyn->d_un.d_val = val;
1988}
1989
1990static void fill_unloadable_phdr(ElfW(Phdr) *phdr, int phnum, Section *interp,
1991 Section *dynamic)
1992{
1993 ElfW(Phdr) *ph;
1994
1995 /* if interpreter, then add corresponding program header */
1996 if (interp) {
1997 ph = &phdr[0];
1998
1999 ph->p_type = PT_PHDR;
2000 ph->p_offset = sizeof(ElfW(Ehdr));
2001 ph->p_filesz = ph->p_memsz = phnum * sizeof(ElfW(Phdr));
2002 ph->p_vaddr = interp->sh_addr - ph->p_filesz;
2003 ph->p_paddr = ph->p_vaddr;
2004 ph->p_flags = PF_R | PF_X;
2005 ph->p_align = 4; /* interp->sh_addralign; */
2006 ph++;
2007
2008 ph->p_type = PT_INTERP;
2009 ph->p_offset = interp->sh_offset;
2010 ph->p_vaddr = interp->sh_addr;
2011 ph->p_paddr = ph->p_vaddr;
2012 ph->p_filesz = interp->sh_size;
2013 ph->p_memsz = interp->sh_size;
2014 ph->p_flags = PF_R;
2015 ph->p_align = interp->sh_addralign;
2016 }
2017
2018 /* if dynamic section, then add corresponding program header */
2019 if (dynamic) {
2020 ph = &phdr[phnum - 1];
2021
2022 ph->p_type = PT_DYNAMIC;
2023 ph->p_offset = dynamic->sh_offset;
2024 ph->p_vaddr = dynamic->sh_addr;
2025 ph->p_paddr = ph->p_vaddr;
2026 ph->p_filesz = dynamic->sh_size;
2027 ph->p_memsz = dynamic->sh_size;
2028 ph->p_flags = PF_R | PF_W;
2029 ph->p_align = dynamic->sh_addralign;
2030 }
2031}
2032
2033/* Fill the dynamic section with tags describing the address and size of
2034 sections */
2035static void fill_dynamic(TCCState *s1, struct dyn_inf *dyninf)
2036{
2037 Section *dynamic = dyninf->dynamic;
2038 Section *s;
2039
2040 /* put dynamic section entries */
2041 put_dt(dynamic, DT_HASH, s1->dynsym->hash->sh_addr);
2042 put_dt(dynamic, DT_STRTAB, dyninf->dynstr->sh_addr);
2043 put_dt(dynamic, DT_SYMTAB, s1->dynsym->sh_addr);
2044 put_dt(dynamic, DT_STRSZ, dyninf->dynstr->data_offset);
2045 put_dt(dynamic, DT_SYMENT, sizeof(ElfW(Sym)));
2046#if PTR_SIZE == 8
2047 put_dt(dynamic, DT_RELA, dyninf->rel_addr);
2048 put_dt(dynamic, DT_RELASZ, dyninf->rel_size);
2049 put_dt(dynamic, DT_RELAENT, sizeof(ElfW_Rel));
2050#else
2051#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
2052 put_dt(dynamic, DT_PLTGOT, s1->got->sh_addr);
2053 put_dt(dynamic, DT_PLTRELSZ, dyninf->rel_size);
2054 put_dt(dynamic, DT_JMPREL, dyninf->rel_addr);
2055 put_dt(dynamic, DT_PLTREL, DT_REL);
2056 put_dt(dynamic, DT_REL, dyninf->bss_addr);
2057 put_dt(dynamic, DT_RELSZ, dyninf->bss_size);
2058#else
2059 put_dt(dynamic, DT_REL, dyninf->rel_addr);
2060 put_dt(dynamic, DT_RELSZ, dyninf->rel_size);
2061 put_dt(dynamic, DT_RELENT, sizeof(ElfW_Rel));
2062#endif
2063#endif
2064 if (versym_section)
2065 put_dt(dynamic, DT_VERSYM, versym_section->sh_addr);
2066 if (verneed_section) {
2067 put_dt(dynamic, DT_VERNEED, verneed_section->sh_addr);
2068 put_dt(dynamic, DT_VERNEEDNUM, dt_verneednum);
2069 }
2070 s = find_section_create (s1, ".preinit_array", 0);
2071 if (s && s->data_offset) {
2072 put_dt(dynamic, DT_PREINIT_ARRAY, s->sh_addr);
2073 put_dt(dynamic, DT_PREINIT_ARRAYSZ, s->data_offset);
2074 }
2075 s = find_section_create (s1, ".init_array", 0);
2076 if (s && s->data_offset) {
2077 put_dt(dynamic, DT_INIT_ARRAY, s->sh_addr);
2078 put_dt(dynamic, DT_INIT_ARRAYSZ, s->data_offset);
2079 }
2080 s = find_section_create (s1, ".fini_array", 0);
2081 if (s && s->data_offset) {
2082 put_dt(dynamic, DT_FINI_ARRAY, s->sh_addr);
2083 put_dt(dynamic, DT_FINI_ARRAYSZ, s->data_offset);
2084 }
2085 s = find_section_create (s1, ".init", 0);
2086 if (s && s->data_offset) {
2087 put_dt(dynamic, DT_INIT, s->sh_addr);
2088 }
2089 s = find_section_create (s1, ".fini", 0);
2090 if (s && s->data_offset) {
2091 put_dt(dynamic, DT_FINI, s->sh_addr);
2092 }
2093 if (s1->do_debug)
2094 put_dt(dynamic, DT_DEBUG, 0);
2095 put_dt(dynamic, DT_NULL, 0);
2096}
2097
2098/* Relocate remaining sections and symbols (that is those not related to
2099 dynamic linking) */
2100static int final_sections_reloc(TCCState *s1)
2101{
2102 int i;
2103 Section *s;
2104
2105 relocate_syms(s1, s1->symtab, 0);
2106
2107 if (s1->nb_errors != 0)
2108 return -1;
2109
2110 /* relocate sections */
2111 /* XXX: ignore sections with allocated relocations ? */
2112 for(i = 1; i < s1->nb_sections; i++) {
2113 s = s1->sections[i];
2114 if (s->reloc && (s != s1->got || s1->static_link))
2115 relocate_section(s1, s);
2116 }
2117
2118 /* relocate relocation entries if the relocation tables are
2119 allocated in the executable */
2120 for(i = 1; i < s1->nb_sections; i++) {
2121 s = s1->sections[i];
2122 if ((s->sh_flags & SHF_ALLOC) &&
2123 s->sh_type == SHT_RELX) {
2124 relocate_rel(s1, s);
2125 }
2126 }
2127 return 0;
2128}
2129#endif
2130
2131/* Create an ELF file on disk.
2132 This function handle ELF specific layout requirements */
2133static void tcc_output_elf(TCCState *s1, FILE *f, int phnum, ElfW(Phdr) *phdr,
2134 int file_offset, int *sec_order)
2135{
2136 int i, shnum, offset, size, file_type;
2137 Section *s;
2138 ElfW(Ehdr) ehdr;
2139 ElfW(Shdr) shdr, *sh;
2140
2141 file_type = s1->output_type;
2142 shnum = s1->nb_sections;
2143
2144 memset(&ehdr, 0, sizeof(ehdr));
2145
2146 if (phnum > 0) {
2147 ehdr.e_phentsize = sizeof(ElfW(Phdr));
2148 ehdr.e_phnum = phnum;
2149 ehdr.e_phoff = sizeof(ElfW(Ehdr));
2150 }
2151
2152 /* align to 4 */
2153 file_offset = (file_offset + 3) & -4;
2154
2155 /* fill header */
2156 ehdr.e_ident[0] = ELFMAG0;
2157 ehdr.e_ident[1] = ELFMAG1;
2158 ehdr.e_ident[2] = ELFMAG2;
2159 ehdr.e_ident[3] = ELFMAG3;
2160 ehdr.e_ident[4] = ELFCLASSW;
2161 ehdr.e_ident[5] = ELFDATA2LSB;
2162 ehdr.e_ident[6] = EV_CURRENT;
2163#if !defined(TCC_TARGET_PE) && (defined(__FreeBSD__) || defined(__FreeBSD_kernel__))
2164 /* FIXME: should set only for freebsd _target_, but we exclude only PE target */
2165 ehdr.e_ident[EI_OSABI] = ELFOSABI_FREEBSD;
2166#endif
2167#ifdef TCC_TARGET_ARM
2168#ifdef TCC_ARM_EABI
2169 ehdr.e_ident[EI_OSABI] = 0;
2170 ehdr.e_flags = EF_ARM_EABI_VER4;
2171 if (file_type == TCC_OUTPUT_EXE || file_type == TCC_OUTPUT_DLL)
2172 ehdr.e_flags |= EF_ARM_HASENTRY;
2173 if (s1->float_abi == ARM_HARD_FLOAT)
2174 ehdr.e_flags |= EF_ARM_VFP_FLOAT;
2175 else
2176 ehdr.e_flags |= EF_ARM_SOFT_FLOAT;
2177#else
2178 ehdr.e_ident[EI_OSABI] = ELFOSABI_ARM;
2179#endif
2180#elif defined TCC_TARGET_RISCV64
2181 ehdr.e_flags = EF_RISCV_FLOAT_ABI_DOUBLE;
2182#endif
2183 switch(file_type) {
2184 default:
2185 case TCC_OUTPUT_EXE:
2186 ehdr.e_type = ET_EXEC;
2187 ehdr.e_entry = get_sym_addr(s1, "_start", 1, 0);
2188 break;
2189 case TCC_OUTPUT_DLL:
2190 ehdr.e_type = ET_DYN;
2191 ehdr.e_entry = text_section->sh_addr; /* XXX: is it correct ? */
2192 break;
2193 case TCC_OUTPUT_OBJ:
2194 ehdr.e_type = ET_REL;
2195 break;
2196 }
2197 ehdr.e_machine = EM_TCC_TARGET;
2198 ehdr.e_version = EV_CURRENT;
2199 ehdr.e_shoff = file_offset;
2200 ehdr.e_ehsize = sizeof(ElfW(Ehdr));
2201 ehdr.e_shentsize = sizeof(ElfW(Shdr));
2202 ehdr.e_shnum = shnum;
2203 ehdr.e_shstrndx = shnum - 1;
2204
2205 fwrite(&ehdr, 1, sizeof(ElfW(Ehdr)), f);
2206 fwrite(phdr, 1, phnum * sizeof(ElfW(Phdr)), f);
2207 offset = sizeof(ElfW(Ehdr)) + phnum * sizeof(ElfW(Phdr));
2208
2209 sort_syms(s1, symtab_section);
2210 for(i = 1; i < s1->nb_sections; i++) {
2211 s = s1->sections[sec_order[i]];
2212 if (s->sh_type != SHT_NOBITS) {
2213 while (offset < s->sh_offset) {
2214 fputc(0, f);
2215 offset++;
2216 }
2217 size = s->sh_size;
2218 if (size)
2219 fwrite(s->data, 1, size, f);
2220 offset += size;
2221 }
2222 }
2223
2224 /* output section headers */
2225 while (offset < ehdr.e_shoff) {
2226 fputc(0, f);
2227 offset++;
2228 }
2229
2230 for(i = 0; i < s1->nb_sections; i++) {
2231 sh = &shdr;
2232 memset(sh, 0, sizeof(ElfW(Shdr)));
2233 s = s1->sections[i];
2234 if (s) {
2235 sh->sh_name = s->sh_name;
2236 sh->sh_type = s->sh_type;
2237 sh->sh_flags = s->sh_flags;
2238 sh->sh_entsize = s->sh_entsize;
2239 sh->sh_info = s->sh_info;
2240 if (s->link)
2241 sh->sh_link = s->link->sh_num;
2242 sh->sh_addralign = s->sh_addralign;
2243 sh->sh_addr = s->sh_addr;
2244 sh->sh_offset = s->sh_offset;
2245 sh->sh_size = s->sh_size;
2246 }
2247 fwrite(sh, 1, sizeof(ElfW(Shdr)), f);
2248 }
2249}
2250
2251/* Write an elf, coff or "binary" file */
2252static int tcc_write_elf_file(TCCState *s1, const char *filename, int phnum,
2253 ElfW(Phdr) *phdr, int file_offset, int *sec_order)
2254{
2255 int fd, mode, file_type;
2256 FILE *f;
2257
2258 file_type = s1->output_type;
2259 if (file_type == TCC_OUTPUT_OBJ)
2260 mode = 0666;
2261 else
2262 mode = 0777;
2263 unlink(filename);
2264 fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, mode);
2265 if (fd < 0) {
2266 tcc_error_noabort("could not write '%s'", filename);
2267 return -1;
2268 }
2269 f = fdopen(fd, "wb");
2270 if (s1->verbose)
2271 printf("<- %s\n", filename);
2272
2273#ifdef TCC_TARGET_COFF
2274 if (s1->output_format == TCC_OUTPUT_FORMAT_COFF)
2275 tcc_output_coff(s1, f);
2276 else
2277#endif
2278 if (s1->output_format == TCC_OUTPUT_FORMAT_ELF)
2279 tcc_output_elf(s1, f, phnum, phdr, file_offset, sec_order);
2280 else
2281 tcc_output_binary(s1, f, sec_order);
2282 fclose(f);
2283
2284 return 0;
2285}
2286
2287#ifndef ELF_OBJ_ONLY
2288/* Sort section headers by assigned sh_addr, remove sections
2289 that we aren't going to output. */
2290static void tidy_section_headers(TCCState *s1, int *sec_order)
2291{
2292 int i, nnew, l, *backmap;
2293 Section **snew, *s;
2294 ElfW(Sym) *sym;
2295
2296 snew = tcc_malloc(s1->nb_sections * sizeof(snew[0]));
2297 backmap = tcc_malloc(s1->nb_sections * sizeof(backmap[0]));
2298 for (i = 0, nnew = 0, l = s1->nb_sections; i < s1->nb_sections; i++) {
2299 s = s1->sections[sec_order[i]];
2300 if (!i || s->sh_name) {
2301 backmap[sec_order[i]] = nnew;
2302 snew[nnew] = s;
2303 ++nnew;
2304 } else {
2305 backmap[sec_order[i]] = 0;
2306 snew[--l] = s;
2307 }
2308 }
2309 for (i = 0; i < nnew; i++) {
2310 s = snew[i];
2311 if (s) {
2312 s->sh_num = i;
2313 if (s->sh_type == SHT_RELX)
2314 s->sh_info = backmap[s->sh_info];
2315 }
2316 }
2317
2318 for_each_elem(symtab_section, 1, sym, ElfW(Sym))
2319 if (sym->st_shndx != SHN_UNDEF && sym->st_shndx < SHN_LORESERVE)
2320 sym->st_shndx = backmap[sym->st_shndx];
2321 if ( !s1->static_link ) {
2322 for_each_elem(s1->dynsym, 1, sym, ElfW(Sym))
2323 if (sym->st_shndx != SHN_UNDEF && sym->st_shndx < SHN_LORESERVE)
2324 sym->st_shndx = backmap[sym->st_shndx];
2325 }
2326 for (i = 0; i < s1->nb_sections; i++)
2327 sec_order[i] = i;
2328 tcc_free(s1->sections);
2329 s1->sections = snew;
2330 s1->nb_sections = nnew;
2331 tcc_free(backmap);
2332}
2333#endif
2334
2335#ifdef TCC_TARGET_ARM
2336static void create_arm_attribute_section(TCCState *s1)
2337{
2338 // Needed for DLL support.
2339 static const unsigned char arm_attr[] = {
2340 0x41, // 'A'
2341 0x2c, 0x00, 0x00, 0x00, // size 0x2c
2342 'a', 'e', 'a', 'b', 'i', 0x00, // "aeabi"
2343 0x01, 0x22, 0x00, 0x00, 0x00, // 'File Attributes', size 0x22
2344 0x05, 0x36, 0x00, // 'CPU_name', "6"
2345 0x06, 0x06, // 'CPU_arch', 'v6'
2346 0x08, 0x01, // 'ARM_ISA_use', 'Yes'
2347 0x09, 0x01, // 'THUMB_ISA_use', 'Thumb-1'
2348 0x0a, 0x02, // 'FP_arch', 'VFPv2'
2349 0x12, 0x04, // 'ABI_PCS_wchar_t', 4
2350 0x14, 0x01, // 'ABI_FP_denormal', 'Needed'
2351 0x15, 0x01, // 'ABI_FP_exceptions', 'Needed'
2352 0x17, 0x03, // 'ABI_FP_number_model', 'IEEE 754'
2353 0x18, 0x01, // 'ABI_align_needed', '8-byte'
2354 0x19, 0x01, // 'ABI_align_preserved', '8-byte, except leaf SP'
2355 0x1a, 0x02, // 'ABI_enum_size', 'int'
2356 0x1c, 0x01, // 'ABI_VFP_args', 'VFP registers'
2357 0x22, 0x01 // 'CPU_unaligned_access', 'v6'
2358 };
2359 Section *attr = new_section(s1, ".ARM.attributes", SHT_ARM_ATTRIBUTES, 0);
2360 unsigned char *ptr = section_ptr_add(attr, sizeof(arm_attr));
2361 attr->sh_addralign = 1;
2362 memcpy(ptr, arm_attr, sizeof(arm_attr));
2363 if (s1->float_abi != ARM_HARD_FLOAT) {
2364 ptr[26] = 0x00; // 'FP_arch', 'No'
2365 ptr[41] = 0x1e; // 'ABI_optimization_goals'
2366 ptr[42] = 0x06; // 'Aggressive Debug'
2367 }
2368}
2369#endif
2370
2371/* Output an elf, coff or binary file */
2372/* XXX: suppress unneeded sections */
2373static int elf_output_file(TCCState *s1, const char *filename)
2374{
2375 int ret, phnum, shnum, file_type, file_offset, *sec_order;
2376 struct dyn_inf dyninf = {0};
2377 ElfW(Phdr) *phdr;
2378 Section *strsec, *interp, *dynamic, *dynstr;
2379
2380#ifdef TCC_TARGET_ARM
2381 create_arm_attribute_section (s1);
2382#endif
2383
2384 file_type = s1->output_type;
2385 s1->nb_errors = 0;
2386 ret = -1;
2387 phdr = NULL;
2388 sec_order = NULL;
2389 interp = dynamic = dynstr = NULL; /* avoid warning */
2390
2391#ifndef ELF_OBJ_ONLY
2392 if (file_type != TCC_OUTPUT_OBJ) {
2393 /* if linking, also link in runtime libraries (libc, libgcc, etc.) */
2394 tcc_add_runtime(s1);
2395 resolve_common_syms(s1);
2396
2397 if (!s1->static_link) {
2398 if (file_type == TCC_OUTPUT_EXE) {
2399 char *ptr;
2400 /* allow override the dynamic loader */
2401 const char *elfint = getenv("LD_SO");
2402 if (elfint == NULL)
2403 elfint = DEFAULT_ELFINTERP(s1);
2404 /* add interpreter section only if executable */
2405 interp = new_section(s1, ".interp", SHT_PROGBITS, SHF_ALLOC);
2406 interp->sh_addralign = 1;
2407 ptr = section_ptr_add(interp, 1 + strlen(elfint));
2408 strcpy(ptr, elfint);
2409 }
2410
2411 /* add dynamic symbol table */
2412 s1->dynsym = new_symtab(s1, ".dynsym", SHT_DYNSYM, SHF_ALLOC,
2413 ".dynstr",
2414 ".hash", SHF_ALLOC);
2415 dynstr = s1->dynsym->link;
2416 /* add dynamic section */
2417 dynamic = new_section(s1, ".dynamic", SHT_DYNAMIC,
2418 SHF_ALLOC | SHF_WRITE);
2419 dynamic->link = dynstr;
2420 dynamic->sh_entsize = sizeof(ElfW(Dyn));
2421
2422 build_got(s1);
2423
2424 if (file_type == TCC_OUTPUT_EXE) {
2425 bind_exe_dynsyms(s1);
2426 if (s1->nb_errors)
2427 goto the_end;
2428 bind_libs_dynsyms(s1);
2429 } else {
2430 /* shared library case: simply export all global symbols */
2431 export_global_syms(s1);
2432 }
2433 }
2434 build_got_entries(s1);
2435 version_add (s1);
2436 }
2437#endif
2438
2439 /* we add a section for symbols */
2440 strsec = new_section(s1, ".shstrtab", SHT_STRTAB, 0);
2441 put_elf_str(strsec, "");
2442
2443 /* Allocate strings for section names */
2444 ret = alloc_sec_names(s1, file_type, strsec);
2445
2446#ifndef ELF_OBJ_ONLY
2447 if (dynamic) {
2448 int i;
2449 /* add a list of needed dlls */
2450 for(i = 0; i < s1->nb_loaded_dlls; i++) {
2451 DLLReference *dllref = s1->loaded_dlls[i];
2452 if (dllref->level == 0)
2453 put_dt(dynamic, DT_NEEDED, put_elf_str(dynstr, dllref->name));
2454 }
2455
2456 if (s1->rpath)
2457 put_dt(dynamic, s1->enable_new_dtags ? DT_RUNPATH : DT_RPATH,
2458 put_elf_str(dynstr, s1->rpath));
2459
2460 if (file_type == TCC_OUTPUT_DLL) {
2461 if (s1->soname)
2462 put_dt(dynamic, DT_SONAME, put_elf_str(dynstr, s1->soname));
2463 /* XXX: currently, since we do not handle PIC code, we
2464 must relocate the readonly segments */
2465 if (ret)
2466 put_dt(dynamic, DT_TEXTREL, 0);
2467 }
2468
2469 if (s1->symbolic)
2470 put_dt(dynamic, DT_SYMBOLIC, 0);
2471
2472 dyninf.dynamic = dynamic;
2473 dyninf.dynstr = dynstr;
2474 /* remember offset and reserve space for 2nd call below */
2475 dyninf.data_offset = dynamic->data_offset;
2476 fill_dynamic(s1, &dyninf);
2477 dynamic->sh_size = dynamic->data_offset;
2478 dynstr->sh_size = dynstr->data_offset;
2479 }
2480#endif
2481
2482 /* compute number of program headers */
2483 if (file_type == TCC_OUTPUT_OBJ)
2484 phnum = 0;
2485 else if (file_type == TCC_OUTPUT_DLL)
2486 phnum = 3;
2487 else if (s1->static_link)
2488 phnum = 2;
2489 else {
2490 int i;
2491 for (i = 1; i < s1->nb_sections &&
2492 !(s1->sections[i]->sh_flags & SHF_TLS); i++);
2493 phnum = i < s1->nb_sections ? 6 : 5;
2494 }
2495
2496 /* allocate program segment headers */
2497 phdr = tcc_mallocz(phnum * sizeof(ElfW(Phdr)));
2498
2499 /* compute number of sections */
2500 shnum = s1->nb_sections;
2501
2502 /* this array is used to reorder sections in the output file */
2503 sec_order = tcc_malloc(sizeof(int) * shnum);
2504 sec_order[0] = 0;
2505
2506 /* compute section to program header mapping */
2507 file_offset = layout_sections(s1, phdr, phnum, interp, strsec, &dyninf,
2508 sec_order);
2509
2510#ifndef ELF_OBJ_ONLY
2511 /* Fill remaining program header and finalize relocation related to dynamic
2512 linking. */
2513 if (file_type != TCC_OUTPUT_OBJ) {
2514 fill_unloadable_phdr(phdr, phnum, interp, dynamic);
2515 if (dynamic) {
2516 ElfW(Sym) *sym;
2517 dynamic->data_offset = dyninf.data_offset;
2518 fill_dynamic(s1, &dyninf);
2519
2520 /* put in GOT the dynamic section address and relocate PLT */
2521 write32le(s1->got->data, dynamic->sh_addr);
2522 if (file_type == TCC_OUTPUT_EXE
2523 || (RELOCATE_DLLPLT && file_type == TCC_OUTPUT_DLL))
2524 relocate_plt(s1);
2525
2526 /* relocate symbols in .dynsym now that final addresses are known */
2527 for_each_elem(s1->dynsym, 1, sym, ElfW(Sym)) {
2528 if (sym->st_shndx != SHN_UNDEF && sym->st_shndx < SHN_LORESERVE) {
2529 /* do symbol relocation */
2530 sym->st_value += s1->sections[sym->st_shndx]->sh_addr;
2531 }
2532 }
2533 }
2534
2535 /* if building executable or DLL, then relocate each section
2536 except the GOT which is already relocated */
2537 ret = final_sections_reloc(s1);
2538 if (ret)
2539 goto the_end;
2540 tidy_section_headers(s1, sec_order);
2541
2542 /* Perform relocation to GOT or PLT entries */
2543 if (file_type == TCC_OUTPUT_EXE && s1->static_link)
2544 fill_got(s1);
2545 else if (s1->got)
2546 fill_local_got_entries(s1);
2547 }
2548#endif
2549
2550 /* Create the ELF file with name 'filename' */
2551 ret = tcc_write_elf_file(s1, filename, phnum, phdr, file_offset, sec_order);
2552 s1->nb_sections = shnum;
2553 goto the_end;
2554 the_end:
2555 tcc_free(sec_order);
2556 tcc_free(phdr);
2557 return ret;
2558}
2559
2560LIBTCCAPI int tcc_output_file(TCCState *s, const char *filename)
2561{
2562 int ret;
2563#ifdef TCC_TARGET_PE
2564 if (s->output_type != TCC_OUTPUT_OBJ) {
2565 ret = pe_output_file(s, filename);
2566 } else
2567#elif TCC_TARGET_MACHO
2568 if (s->output_type != TCC_OUTPUT_OBJ) {
2569 ret = macho_output_file(s, filename);
2570 } else
2571#endif
2572 ret = elf_output_file(s, filename);
2573 return ret;
2574}
2575
2576ST_FUNC ssize_t full_read(int fd, void *buf, size_t count) {
2577 char *cbuf = buf;
2578 size_t rnum = 0;
2579 while (1) {
2580 ssize_t num = read(fd, cbuf, count-rnum);
2581 if (num < 0) return num;
2582 if (num == 0) return rnum;
2583 rnum += num;
2584 cbuf += num;
2585 }
2586}
2587
2588ST_FUNC void *load_data(int fd, unsigned long file_offset, unsigned long size)
2589{
2590 void *data;
2591
2592 data = tcc_malloc(size);
2593 lseek(fd, file_offset, SEEK_SET);
2594 full_read(fd, data, size);
2595 return data;
2596}
2597
2598typedef struct SectionMergeInfo {
2599 Section *s; /* corresponding existing section */
2600 unsigned long offset; /* offset of the new section in the existing section */
2601 uint8_t new_section; /* true if section 's' was added */
2602 uint8_t link_once; /* true if link once section */
2603} SectionMergeInfo;
2604
2605ST_FUNC int tcc_object_type(int fd, ElfW(Ehdr) *h)
2606{
2607 int size = full_read(fd, h, sizeof *h);
2608 if (size == sizeof *h && 0 == memcmp(h, ELFMAG, 4)) {
2609 if (h->e_type == ET_REL)
2610 return AFF_BINTYPE_REL;
2611 if (h->e_type == ET_DYN)
2612 return AFF_BINTYPE_DYN;
2613 } else if (size >= 8) {
2614 if (0 == memcmp(h, ARMAG, 8))
2615 return AFF_BINTYPE_AR;
2616#ifdef TCC_TARGET_COFF
2617 if (((struct filehdr*)h)->f_magic == COFF_C67_MAGIC)
2618 return AFF_BINTYPE_C67;
2619#endif
2620 }
2621 return 0;
2622}
2623
2624/* load an object file and merge it with current files */
2625/* XXX: handle correctly stab (debug) info */
2626ST_FUNC int tcc_load_object_file(TCCState *s1,
2627 int fd, unsigned long file_offset)
2628{
2629 ElfW(Ehdr) ehdr;
2630 ElfW(Shdr) *shdr, *sh;
2631 int size, i, j, offset, offseti, nb_syms, sym_index, ret, seencompressed;
2632 char *strsec, *strtab;
2633 int stab_index, stabstr_index;
2634 int *old_to_new_syms;
2635 char *sh_name, *name;
2636 SectionMergeInfo *sm_table, *sm;
2637 ElfW(Sym) *sym, *symtab;
2638 ElfW_Rel *rel;
2639 Section *s;
2640
2641 lseek(fd, file_offset, SEEK_SET);
2642 if (tcc_object_type(fd, &ehdr) != AFF_BINTYPE_REL)
2643 goto fail1;
2644 /* test CPU specific stuff */
2645 if (ehdr.e_ident[5] != ELFDATA2LSB ||
2646 ehdr.e_machine != EM_TCC_TARGET) {
2647 fail1:
2648 tcc_error_noabort("invalid object file");
2649 return -1;
2650 }
2651 /* read sections */
2652 shdr = load_data(fd, file_offset + ehdr.e_shoff,
2653 sizeof(ElfW(Shdr)) * ehdr.e_shnum);
2654 sm_table = tcc_mallocz(sizeof(SectionMergeInfo) * ehdr.e_shnum);
2655
2656 /* load section names */
2657 sh = &shdr[ehdr.e_shstrndx];
2658 strsec = load_data(fd, file_offset + sh->sh_offset, sh->sh_size);
2659
2660 /* load symtab and strtab */
2661 old_to_new_syms = NULL;
2662 symtab = NULL;
2663 strtab = NULL;
2664 nb_syms = 0;
2665 seencompressed = 0;
2666 stab_index = stabstr_index = 0;
2667
2668 for(i = 1; i < ehdr.e_shnum; i++) {
2669 sh = &shdr[i];
2670 if (sh->sh_type == SHT_SYMTAB) {
2671 if (symtab) {
2672 tcc_error_noabort("object must contain only one symtab");
2673 fail:
2674 ret = -1;
2675 goto the_end;
2676 }
2677 nb_syms = sh->sh_size / sizeof(ElfW(Sym));
2678 symtab = load_data(fd, file_offset + sh->sh_offset, sh->sh_size);
2679 sm_table[i].s = symtab_section;
2680
2681 /* now load strtab */
2682 sh = &shdr[sh->sh_link];
2683 strtab = load_data(fd, file_offset + sh->sh_offset, sh->sh_size);
2684 }
2685 if (sh->sh_flags & SHF_COMPRESSED)
2686 seencompressed = 1;
2687 }
2688
2689 /* now examine each section and try to merge its content with the
2690 ones in memory */
2691 for(i = 1; i < ehdr.e_shnum; i++) {
2692 /* no need to examine section name strtab */
2693 if (i == ehdr.e_shstrndx)
2694 continue;
2695 sh = &shdr[i];
2696 if (sh->sh_type == SHT_RELX)
2697 sh = &shdr[sh->sh_info];
2698 /* ignore sections types we do not handle (plus relocs to those) */
2699 if (sh->sh_type != SHT_PROGBITS &&
2700#ifdef TCC_ARM_EABI
2701 sh->sh_type != SHT_ARM_EXIDX &&
2702#endif
2703 sh->sh_type != SHT_NOBITS &&
2704 sh->sh_type != SHT_PREINIT_ARRAY &&
2705 sh->sh_type != SHT_INIT_ARRAY &&
2706 sh->sh_type != SHT_FINI_ARRAY &&
2707 strcmp(strsec + sh->sh_name, ".stabstr")
2708 )
2709 continue;
2710 if (seencompressed
2711 && !strncmp(strsec + sh->sh_name, ".debug_", sizeof(".debug_")-1))
2712 continue;
2713
2714 sh = &shdr[i];
2715 sh_name = strsec + sh->sh_name;
2716 if (sh->sh_addralign < 1)
2717 sh->sh_addralign = 1;
2718 /* find corresponding section, if any */
2719 for(j = 1; j < s1->nb_sections;j++) {
2720 s = s1->sections[j];
2721 if (!strcmp(s->name, sh_name)) {
2722 if (!strncmp(sh_name, ".gnu.linkonce",
2723 sizeof(".gnu.linkonce") - 1)) {
2724 /* if a 'linkonce' section is already present, we
2725 do not add it again. It is a little tricky as
2726 symbols can still be defined in
2727 it. */
2728 sm_table[i].link_once = 1;
2729 goto next;
2730 }
2731 if (stab_section) {
2732 if (s == stab_section)
2733 stab_index = i;
2734 if (s == stab_section->link)
2735 stabstr_index = i;
2736 }
2737 goto found;
2738 }
2739 }
2740 /* not found: create new section */
2741 s = new_section(s1, sh_name, sh->sh_type, sh->sh_flags & ~SHF_GROUP);
2742 /* take as much info as possible from the section. sh_link and
2743 sh_info will be updated later */
2744 s->sh_addralign = sh->sh_addralign;
2745 s->sh_entsize = sh->sh_entsize;
2746 sm_table[i].new_section = 1;
2747 found:
2748 if (sh->sh_type != s->sh_type) {
2749 tcc_error_noabort("invalid section type");
2750 goto fail;
2751 }
2752 /* align start of section */
2753 s->data_offset += -s->data_offset & (sh->sh_addralign - 1);
2754 if (sh->sh_addralign > s->sh_addralign)
2755 s->sh_addralign = sh->sh_addralign;
2756 sm_table[i].offset = s->data_offset;
2757 sm_table[i].s = s;
2758 /* concatenate sections */
2759 size = sh->sh_size;
2760 if (sh->sh_type != SHT_NOBITS) {
2761 unsigned char *ptr;
2762 lseek(fd, file_offset + sh->sh_offset, SEEK_SET);
2763 ptr = section_ptr_add(s, size);
2764 full_read(fd, ptr, size);
2765 } else {
2766 s->data_offset += size;
2767 }
2768 next: ;
2769 }
2770
2771 /* gr relocate stab strings */
2772 if (stab_index && stabstr_index) {
2773 Stab_Sym *a, *b;
2774 unsigned o;
2775 s = sm_table[stab_index].s;
2776 a = (Stab_Sym *)(s->data + sm_table[stab_index].offset);
2777 b = (Stab_Sym *)(s->data + s->data_offset);
2778 o = sm_table[stabstr_index].offset;
2779 while (a < b) {
2780 if (a->n_strx)
2781 a->n_strx += o;
2782 a++;
2783 }
2784 }
2785
2786 /* second short pass to update sh_link and sh_info fields of new
2787 sections */
2788 for(i = 1; i < ehdr.e_shnum; i++) {
2789 s = sm_table[i].s;
2790 if (!s || !sm_table[i].new_section)
2791 continue;
2792 sh = &shdr[i];
2793 if (sh->sh_link > 0)
2794 s->link = sm_table[sh->sh_link].s;
2795 if (sh->sh_type == SHT_RELX) {
2796 s->sh_info = sm_table[sh->sh_info].s->sh_num;
2797 /* update backward link */
2798 s1->sections[s->sh_info]->reloc = s;
2799 }
2800 }
2801
2802 /* resolve symbols */
2803 old_to_new_syms = tcc_mallocz(nb_syms * sizeof(int));
2804
2805 sym = symtab + 1;
2806 for(i = 1; i < nb_syms; i++, sym++) {
2807 if (sym->st_shndx != SHN_UNDEF &&
2808 sym->st_shndx < SHN_LORESERVE) {
2809 sm = &sm_table[sym->st_shndx];
2810 if (sm->link_once) {
2811 /* if a symbol is in a link once section, we use the
2812 already defined symbol. It is very important to get
2813 correct relocations */
2814 if (ELFW(ST_BIND)(sym->st_info) != STB_LOCAL) {
2815 name = strtab + sym->st_name;
2816 sym_index = find_elf_sym(symtab_section, name);
2817 if (sym_index)
2818 old_to_new_syms[i] = sym_index;
2819 }
2820 continue;
2821 }
2822 /* if no corresponding section added, no need to add symbol */
2823 if (!sm->s)
2824 continue;
2825 /* convert section number */
2826 sym->st_shndx = sm->s->sh_num;
2827 /* offset value */
2828 sym->st_value += sm->offset;
2829 }
2830 /* add symbol */
2831 name = strtab + sym->st_name;
2832 sym_index = set_elf_sym(symtab_section, sym->st_value, sym->st_size,
2833 sym->st_info, sym->st_other,
2834 sym->st_shndx, name);
2835 old_to_new_syms[i] = sym_index;
2836 }
2837
2838 /* third pass to patch relocation entries */
2839 for(i = 1; i < ehdr.e_shnum; i++) {
2840 s = sm_table[i].s;
2841 if (!s)
2842 continue;
2843 sh = &shdr[i];
2844 offset = sm_table[i].offset;
2845 switch(s->sh_type) {
2846 case SHT_RELX:
2847 /* take relocation offset information */
2848 offseti = sm_table[sh->sh_info].offset;
2849 for_each_elem(s, (offset / sizeof(*rel)), rel, ElfW_Rel) {
2850 int type;
2851 unsigned sym_index;
2852 /* convert symbol index */
2853 type = ELFW(R_TYPE)(rel->r_info);
2854 sym_index = ELFW(R_SYM)(rel->r_info);
2855 /* NOTE: only one symtab assumed */
2856 if (sym_index >= nb_syms)
2857 goto invalid_reloc;
2858 sym_index = old_to_new_syms[sym_index];
2859 /* ignore link_once in rel section. */
2860 if (!sym_index && !sm_table[sh->sh_info].link_once
2861#ifdef TCC_TARGET_ARM
2862 && type != R_ARM_V4BX
2863#elif defined TCC_TARGET_RISCV64
2864 && type != R_RISCV_ALIGN
2865 && type != R_RISCV_RELAX
2866#endif
2867 ) {
2868 invalid_reloc:
2869 tcc_error_noabort("Invalid relocation entry [%2d] '%s' @ %.8x",
2870 i, strsec + sh->sh_name, (int)rel->r_offset);
2871 goto fail;
2872 }
2873 rel->r_info = ELFW(R_INFO)(sym_index, type);
2874 /* offset the relocation offset */
2875 rel->r_offset += offseti;
2876#ifdef TCC_TARGET_ARM
2877 /* Jumps and branches from a Thumb code to a PLT entry need
2878 special handling since PLT entries are ARM code.
2879 Unconditional bl instructions referencing PLT entries are
2880 handled by converting these instructions into blx
2881 instructions. Other case of instructions referencing a PLT
2882 entry require to add a Thumb stub before the PLT entry to
2883 switch to ARM mode. We set bit plt_thumb_stub of the
2884 attribute of a symbol to indicate such a case. */
2885 if (type == R_ARM_THM_JUMP24)
2886 get_sym_attr(s1, sym_index, 1)->plt_thumb_stub = 1;
2887#endif
2888 }
2889 break;
2890 default:
2891 break;
2892 }
2893 }
2894
2895 ret = 0;
2896 the_end:
2897 tcc_free(symtab);
2898 tcc_free(strtab);
2899 tcc_free(old_to_new_syms);
2900 tcc_free(sm_table);
2901 tcc_free(strsec);
2902 tcc_free(shdr);
2903 return ret;
2904}
2905
2906typedef struct ArchiveHeader {
2907 char ar_name[16]; /* name of this member */
2908 char ar_date[12]; /* file mtime */
2909 char ar_uid[6]; /* owner uid; printed as decimal */
2910 char ar_gid[6]; /* owner gid; printed as decimal */
2911 char ar_mode[8]; /* file mode, printed as octal */
2912 char ar_size[10]; /* file size, printed as decimal */
2913 char ar_fmag[2]; /* should contain ARFMAG */
2914} ArchiveHeader;
2915
2916#define ARFMAG "`\n"
2917
2918static unsigned long long get_be(const uint8_t *b, int n)
2919{
2920 unsigned long long ret = 0;
2921 while (n)
2922 ret = (ret << 8) | *b++, --n;
2923 return ret;
2924}
2925
2926static int read_ar_header(int fd, int offset, ArchiveHeader *hdr)
2927{
2928 char *p, *e;
2929 int len;
2930 lseek(fd, offset, SEEK_SET);
2931 len = full_read(fd, hdr, sizeof(ArchiveHeader));
2932 if (len != sizeof(ArchiveHeader))
2933 return len ? -1 : 0;
2934 p = hdr->ar_name;
2935 for (e = p + sizeof hdr->ar_name; e > p && e[-1] == ' ';)
2936 --e;
2937 *e = '\0';
2938 hdr->ar_size[sizeof hdr->ar_size-1] = 0;
2939 return len;
2940}
2941
2942/* load only the objects which resolve undefined symbols */
2943static int tcc_load_alacarte(TCCState *s1, int fd, int size, int entrysize)
2944{
2945 int i, bound, nsyms, sym_index, len, ret = -1;
2946 unsigned long long off;
2947 uint8_t *data;
2948 const char *ar_names, *p;
2949 const uint8_t *ar_index;
2950 ElfW(Sym) *sym;
2951 ArchiveHeader hdr;
2952
2953 data = tcc_malloc(size);
2954 if (full_read(fd, data, size) != size)
2955 goto the_end;
2956 nsyms = get_be(data, entrysize);
2957 ar_index = data + entrysize;
2958 ar_names = (char *) ar_index + nsyms * entrysize;
2959
2960 do {
2961 bound = 0;
2962 for (p = ar_names, i = 0; i < nsyms; i++, p += strlen(p)+1) {
2963 Section *s = symtab_section;
2964 sym_index = find_elf_sym(s, p);
2965 if (!sym_index)
2966 continue;
2967 sym = &((ElfW(Sym) *)s->data)[sym_index];
2968 if(sym->st_shndx != SHN_UNDEF)
2969 continue;
2970 off = get_be(ar_index + i * entrysize, entrysize);
2971 len = read_ar_header(fd, off, &hdr);
2972 if (len <= 0 || memcmp(hdr.ar_fmag, ARFMAG, 2)) {
2973 tcc_error_noabort("invalid archive");
2974 goto the_end;
2975 }
2976 off += len;
2977 if (s1->verbose == 2)
2978 printf(" -> %s\n", hdr.ar_name);
2979 if (tcc_load_object_file(s1, fd, off) < 0)
2980 goto the_end;
2981 ++bound;
2982 }
2983 } while(bound);
2984 ret = 0;
2985 the_end:
2986 tcc_free(data);
2987 return ret;
2988}
2989
2990/* load a '.a' file */
2991ST_FUNC int tcc_load_archive(TCCState *s1, int fd, int alacarte)
2992{
2993 ArchiveHeader hdr;
2994 /* char magic[8]; */
2995 int size, len;
2996 unsigned long file_offset;
2997 ElfW(Ehdr) ehdr;
2998
2999 /* skip magic which was already checked */
3000 /* full_read(fd, magic, sizeof(magic)); */
3001 file_offset = sizeof ARMAG - 1;
3002
3003 for(;;) {
3004 len = read_ar_header(fd, file_offset, &hdr);
3005 if (len == 0)
3006 return 0;
3007 if (len < 0) {
3008 tcc_error_noabort("invalid archive");
3009 return -1;
3010 }
3011 file_offset += len;
3012 size = strtol(hdr.ar_size, NULL, 0);
3013 /* align to even */
3014 size = (size + 1) & ~1;
3015 if (alacarte) {
3016 /* coff symbol table : we handle it */
3017 if (!strcmp(hdr.ar_name, "/"))
3018 return tcc_load_alacarte(s1, fd, size, 4);
3019 if (!strcmp(hdr.ar_name, "/SYM64/"))
3020 return tcc_load_alacarte(s1, fd, size, 8);
3021 } else if (tcc_object_type(fd, &ehdr) == AFF_BINTYPE_REL) {
3022 if (s1->verbose == 2)
3023 printf(" -> %s\n", hdr.ar_name);
3024 if (tcc_load_object_file(s1, fd, file_offset) < 0)
3025 return -1;
3026 }
3027 file_offset += size;
3028 }
3029}
3030
3031#ifndef ELF_OBJ_ONLY
3032/* Set LV[I] to the global index of sym-version (LIB,VERSION). Maybe resizes
3033 LV, maybe create a new entry for (LIB,VERSION). */
3034static void set_ver_to_ver(TCCState *s1, int *n, int **lv, int i, char *lib, char *version)
3035{
3036 while (i >= *n) {
3037 *lv = tcc_realloc(*lv, (*n + 1) * sizeof(**lv));
3038 (*lv)[(*n)++] = -1;
3039 }
3040 if ((*lv)[i] == -1) {
3041 int v, prev_same_lib = -1;
3042 for (v = 0; v < nb_sym_versions; v++) {
3043 if (strcmp(sym_versions[v].lib, lib))
3044 continue;
3045 prev_same_lib = v;
3046 if (!strcmp(sym_versions[v].version, version))
3047 break;
3048 }
3049 if (v == nb_sym_versions) {
3050 sym_versions = tcc_realloc (sym_versions,
3051 (v + 1) * sizeof(*sym_versions));
3052 sym_versions[v].lib = tcc_strdup(lib);
3053 sym_versions[v].version = tcc_strdup(version);
3054 sym_versions[v].out_index = 0;
3055 sym_versions[v].prev_same_lib = prev_same_lib;
3056 nb_sym_versions++;
3057 }
3058 (*lv)[i] = v;
3059 }
3060}
3061
3062/* Associates symbol SYM_INDEX (in dynsymtab) with sym-version index
3063 VERNDX. */
3064static void
3065set_sym_version(TCCState *s1, int sym_index, int verndx)
3066{
3067 if (sym_index >= nb_sym_to_version) {
3068 int newelems = sym_index ? sym_index * 2 : 1;
3069 sym_to_version = tcc_realloc(sym_to_version,
3070 newelems * sizeof(*sym_to_version));
3071 memset(sym_to_version + nb_sym_to_version, -1,
3072 (newelems - nb_sym_to_version) * sizeof(*sym_to_version));
3073 nb_sym_to_version = newelems;
3074 }
3075 if (sym_to_version[sym_index] < 0)
3076 sym_to_version[sym_index] = verndx;
3077}
3078
3079struct versym_info {
3080 int nb_versyms;
3081 ElfW(Verdef) *verdef;
3082 ElfW(Verneed) *verneed;
3083 ElfW(Half) *versym;
3084 int nb_local_ver, *local_ver;
3085};
3086
3087
3088static void store_version(TCCState *s1, struct versym_info *v, char *dynstr)
3089{
3090 char *lib, *version;
3091 uint32_t next;
3092 int i;
3093
3094#define DEBUG_VERSION 0
3095
3096 if (v->versym && v->verdef) {
3097 ElfW(Verdef) *vdef = v->verdef;
3098 lib = NULL;
3099 do {
3100 ElfW(Verdaux) *verdaux =
3101 (ElfW(Verdaux) *) (((char *) vdef) + vdef->vd_aux);
3102
3103#if DEBUG_VERSION
3104 printf ("verdef: version:%u flags:%u index:%u, hash:%u\n",
3105 vdef->vd_version, vdef->vd_flags, vdef->vd_ndx,
3106 vdef->vd_hash);
3107#endif
3108 if (vdef->vd_cnt) {
3109 version = dynstr + verdaux->vda_name;
3110
3111 if (lib == NULL)
3112 lib = version;
3113 else
3114 set_ver_to_ver(s1, &v->nb_local_ver, &v->local_ver, vdef->vd_ndx,
3115 lib, version);
3116#if DEBUG_VERSION
3117 printf (" verdaux(%u): %s\n", vdef->vd_ndx, version);
3118#endif
3119 }
3120 next = vdef->vd_next;
3121 vdef = (ElfW(Verdef) *) (((char *) vdef) + next);
3122 } while (next);
3123 }
3124 if (v->versym && v->verneed) {
3125 ElfW(Verneed) *vneed = v->verneed;
3126 do {
3127 ElfW(Vernaux) *vernaux =
3128 (ElfW(Vernaux) *) (((char *) vneed) + vneed->vn_aux);
3129
3130 lib = dynstr + vneed->vn_file;
3131#if DEBUG_VERSION
3132 printf ("verneed: %u %s\n", vneed->vn_version, lib);
3133#endif
3134 for (i = 0; i < vneed->vn_cnt; i++) {
3135 if ((vernaux->vna_other & 0x8000) == 0) { /* hidden */
3136 version = dynstr + vernaux->vna_name;
3137 set_ver_to_ver(s1, &v->nb_local_ver, &v->local_ver, vernaux->vna_other,
3138 lib, version);
3139#if DEBUG_VERSION
3140 printf (" vernaux(%u): %u %u %s\n",
3141 vernaux->vna_other, vernaux->vna_hash,
3142 vernaux->vna_flags, version);
3143#endif
3144 }
3145 vernaux = (ElfW(Vernaux) *) (((char *) vernaux) + vernaux->vna_next);
3146 }
3147 next = vneed->vn_next;
3148 vneed = (ElfW(Verneed) *) (((char *) vneed) + next);
3149 } while (next);
3150 }
3151
3152#if DEBUG_VERSION
3153 for (i = 0; i < v->nb_local_ver; i++) {
3154 if (v->local_ver[i] > 0) {
3155 printf ("%d: lib: %s, version %s\n",
3156 i, sym_versions[v->local_ver[i]].lib,
3157 sym_versions[v->local_ver[i]].version);
3158 }
3159 }
3160#endif
3161}
3162
3163/* load a DLL and all referenced DLLs. 'level = 0' means that the DLL
3164 is referenced by the user (so it should be added as DT_NEEDED in
3165 the generated ELF file) */
3166ST_FUNC int tcc_load_dll(TCCState *s1, int fd, const char *filename, int level)
3167{
3168 ElfW(Ehdr) ehdr;
3169 ElfW(Shdr) *shdr, *sh, *sh1;
3170 int i, j, nb_syms, nb_dts, sym_bind, ret;
3171 ElfW(Sym) *sym, *dynsym;
3172 ElfW(Dyn) *dt, *dynamic;
3173
3174 char *dynstr;
3175 int sym_index;
3176 const char *name, *soname;
3177 DLLReference *dllref;
3178 struct versym_info v;
3179
3180 full_read(fd, &ehdr, sizeof(ehdr));
3181
3182 /* test CPU specific stuff */
3183 if (ehdr.e_ident[5] != ELFDATA2LSB ||
3184 ehdr.e_machine != EM_TCC_TARGET) {
3185 tcc_error_noabort("bad architecture");
3186 return -1;
3187 }
3188
3189 /* read sections */
3190 shdr = load_data(fd, ehdr.e_shoff, sizeof(ElfW(Shdr)) * ehdr.e_shnum);
3191
3192 /* load dynamic section and dynamic symbols */
3193 nb_syms = 0;
3194 nb_dts = 0;
3195 dynamic = NULL;
3196 dynsym = NULL; /* avoid warning */
3197 dynstr = NULL; /* avoid warning */
3198 memset(&v, 0, sizeof v);
3199
3200 for(i = 0, sh = shdr; i < ehdr.e_shnum; i++, sh++) {
3201 switch(sh->sh_type) {
3202 case SHT_DYNAMIC:
3203 nb_dts = sh->sh_size / sizeof(ElfW(Dyn));
3204 dynamic = load_data(fd, sh->sh_offset, sh->sh_size);
3205 break;
3206 case SHT_DYNSYM:
3207 nb_syms = sh->sh_size / sizeof(ElfW(Sym));
3208 dynsym = load_data(fd, sh->sh_offset, sh->sh_size);
3209 sh1 = &shdr[sh->sh_link];
3210 dynstr = load_data(fd, sh1->sh_offset, sh1->sh_size);
3211 break;
3212 case SHT_GNU_verdef:
3213 v.verdef = load_data(fd, sh->sh_offset, sh->sh_size);
3214 break;
3215 case SHT_GNU_verneed:
3216 v.verneed = load_data(fd, sh->sh_offset, sh->sh_size);
3217 break;
3218 case SHT_GNU_versym:
3219 v.nb_versyms = sh->sh_size / sizeof(ElfW(Half));
3220 v.versym = load_data(fd, sh->sh_offset, sh->sh_size);
3221 break;
3222 default:
3223 break;
3224 }
3225 }
3226
3227 /* compute the real library name */
3228 soname = tcc_basename(filename);
3229
3230 for(i = 0, dt = dynamic; i < nb_dts; i++, dt++) {
3231 if (dt->d_tag == DT_SONAME) {
3232 soname = dynstr + dt->d_un.d_val;
3233 }
3234 }
3235
3236 /* if the dll is already loaded, do not load it */
3237 for(i = 0; i < s1->nb_loaded_dlls; i++) {
3238 dllref = s1->loaded_dlls[i];
3239 if (!strcmp(soname, dllref->name)) {
3240 /* but update level if needed */
3241 if (level < dllref->level)
3242 dllref->level = level;
3243 ret = 0;
3244 goto the_end;
3245 }
3246 }
3247
3248 if (v.nb_versyms != nb_syms)
3249 tcc_free (v.versym), v.versym = NULL;
3250 else
3251 store_version(s1, &v, dynstr);
3252
3253 /* add the dll and its level */
3254 dllref = tcc_mallocz(sizeof(DLLReference) + strlen(soname));
3255 dllref->level = level;
3256 strcpy(dllref->name, soname);
3257 dynarray_add(&s1->loaded_dlls, &s1->nb_loaded_dlls, dllref);
3258
3259 /* add dynamic symbols in dynsym_section */
3260 for(i = 1, sym = dynsym + 1; i < nb_syms; i++, sym++) {
3261 sym_bind = ELFW(ST_BIND)(sym->st_info);
3262 if (sym_bind == STB_LOCAL)
3263 continue;
3264 name = dynstr + sym->st_name;
3265 sym_index = set_elf_sym(s1->dynsymtab_section, sym->st_value, sym->st_size,
3266 sym->st_info, sym->st_other, sym->st_shndx, name);
3267 if (v.versym) {
3268 ElfW(Half) vsym = v.versym[i];
3269 if ((vsym & 0x8000) == 0 && vsym > 0 && vsym < v.nb_local_ver)
3270 set_sym_version(s1, sym_index, v.local_ver[vsym]);
3271 }
3272 }
3273
3274 /* load all referenced DLLs */
3275 for(i = 0, dt = dynamic; i < nb_dts; i++, dt++) {
3276 switch(dt->d_tag) {
3277 case DT_NEEDED:
3278 name = dynstr + dt->d_un.d_val;
3279 for(j = 0; j < s1->nb_loaded_dlls; j++) {
3280 dllref = s1->loaded_dlls[j];
3281 if (!strcmp(name, dllref->name))
3282 goto already_loaded;
3283 }
3284 if (tcc_add_dll(s1, name, AFF_REFERENCED_DLL) < 0) {
3285 tcc_error_noabort("referenced dll '%s' not found", name);
3286 ret = -1;
3287 goto the_end;
3288 }
3289 already_loaded:
3290 break;
3291 }
3292 }
3293 ret = 0;
3294 the_end:
3295 tcc_free(dynstr);
3296 tcc_free(dynsym);
3297 tcc_free(dynamic);
3298 tcc_free(shdr);
3299 tcc_free(v.local_ver);
3300 tcc_free(v.verdef);
3301 tcc_free(v.verneed);
3302 tcc_free(v.versym);
3303 return ret;
3304}
3305
3306#define LD_TOK_NAME 256
3307#define LD_TOK_EOF (-1)
3308
3309static int ld_inp(TCCState *s1)
3310{
3311 char b;
3312 if (s1->cc != -1) {
3313 int c = s1->cc;
3314 s1->cc = -1;
3315 return c;
3316 }
3317 if (1 == read(s1->fd, &b, 1))
3318 return b;
3319 return CH_EOF;
3320}
3321
3322/* return next ld script token */
3323static int ld_next(TCCState *s1, char *name, int name_size)
3324{
3325 int c, d, ch;
3326 char *q;
3327
3328 redo:
3329 ch = ld_inp(s1);
3330 switch(ch) {
3331 case ' ':
3332 case '\t':
3333 case '\f':
3334 case '\v':
3335 case '\r':
3336 case '\n':
3337 goto redo;
3338 case '/':
3339 ch = ld_inp(s1);
3340 if (ch == '*') { /* comment */
3341 for (d = 0;; d = ch) {
3342 ch = ld_inp(s1);
3343 if (ch == CH_EOF || (ch == '/' && d == '*'))
3344 break;
3345 }
3346 goto redo;
3347 } else {
3348 q = name;
3349 *q++ = '/';
3350 goto parse_name;
3351 }
3352 break;
3353 case '\\':
3354 /* case 'a' ... 'z': */
3355 case 'a':
3356 case 'b':
3357 case 'c':
3358 case 'd':
3359 case 'e':
3360 case 'f':
3361 case 'g':
3362 case 'h':
3363 case 'i':
3364 case 'j':
3365 case 'k':
3366 case 'l':
3367 case 'm':
3368 case 'n':
3369 case 'o':
3370 case 'p':
3371 case 'q':
3372 case 'r':
3373 case 's':
3374 case 't':
3375 case 'u':
3376 case 'v':
3377 case 'w':
3378 case 'x':
3379 case 'y':
3380 case 'z':
3381 /* case 'A' ... 'z': */
3382 case 'A':
3383 case 'B':
3384 case 'C':
3385 case 'D':
3386 case 'E':
3387 case 'F':
3388 case 'G':
3389 case 'H':
3390 case 'I':
3391 case 'J':
3392 case 'K':
3393 case 'L':
3394 case 'M':
3395 case 'N':
3396 case 'O':
3397 case 'P':
3398 case 'Q':
3399 case 'R':
3400 case 'S':
3401 case 'T':
3402 case 'U':
3403 case 'V':
3404 case 'W':
3405 case 'X':
3406 case 'Y':
3407 case 'Z':
3408 case '_':
3409 case '.':
3410 case '$':
3411 case '~':
3412 q = name;
3413 parse_name:
3414 for(;;) {
3415 if (!((ch >= 'a' && ch <= 'z') ||
3416 (ch >= 'A' && ch <= 'Z') ||
3417 (ch >= '0' && ch <= '9') ||
3418 strchr("/.-_+=$:\\,~", ch)))
3419 break;
3420 if ((q - name) < name_size - 1) {
3421 *q++ = ch;
3422 }
3423 ch = ld_inp(s1);
3424 }
3425 s1->cc = ch;
3426 *q = '\0';
3427 c = LD_TOK_NAME;
3428 break;
3429 case CH_EOF:
3430 c = LD_TOK_EOF;
3431 break;
3432 default:
3433 c = ch;
3434 break;
3435 }
3436 return c;
3437}
3438
3439static int ld_add_file(TCCState *s1, const char filename[])
3440{
3441 if (filename[0] == '/') {
3442 if (CONFIG_SYSROOT[0] == '\0'
3443 && tcc_add_file_internal(s1, filename, AFF_TYPE_BIN) == 0)
3444 return 0;
3445 filename = tcc_basename(filename);
3446 }
3447 return tcc_add_dll(s1, filename, 0);
3448}
3449
3450static int ld_add_file_list(TCCState *s1, const char *cmd, int as_needed)
3451{
3452 char filename[1024], libname[1024];
3453 int t, group, nblibs = 0, ret = 0;
3454 char **libs = NULL;
3455
3456 group = !strcmp(cmd, "GROUP");
3457 if (!as_needed)
3458 s1->new_undef_sym = 0;
3459 t = ld_next(s1, filename, sizeof(filename));
3460 if (t != '(') {
3461 tcc_error_noabort("( expected");
3462 ret = -1;
3463 goto lib_parse_error;
3464 }
3465 t = ld_next(s1, filename, sizeof(filename));
3466 for(;;) {
3467 libname[0] = '\0';
3468 if (t == LD_TOK_EOF) {
3469 tcc_error_noabort("unexpected end of file");
3470 ret = -1;
3471 goto lib_parse_error;
3472 } else if (t == ')') {
3473 break;
3474 } else if (t == '-') {
3475 t = ld_next(s1, filename, sizeof(filename));
3476 if ((t != LD_TOK_NAME) || (filename[0] != 'l')) {
3477 tcc_error_noabort("library name expected");
3478 ret = -1;
3479 goto lib_parse_error;
3480 }
3481 pstrcpy(libname, sizeof libname, &filename[1]);
3482 if (s1->static_link) {
3483 snprintf(filename, sizeof filename, "lib%s.a", libname);
3484 } else {
3485 snprintf(filename, sizeof filename, "lib%s.so", libname);
3486 }
3487 } else if (t != LD_TOK_NAME) {
3488 tcc_error_noabort("filename expected");
3489 ret = -1;
3490 goto lib_parse_error;
3491 }
3492 if (!strcmp(filename, "AS_NEEDED")) {
3493 ret = ld_add_file_list(s1, cmd, 1);
3494 if (ret)
3495 goto lib_parse_error;
3496 } else {
3497 /* TODO: Implement AS_NEEDED support. Ignore it for now */
3498 if (!as_needed) {
3499 ret = ld_add_file(s1, filename);
3500 if (ret)
3501 goto lib_parse_error;
3502 if (group) {
3503 /* Add the filename *and* the libname to avoid future conversions */
3504 dynarray_add(&libs, &nblibs, tcc_strdup(filename));
3505 if (libname[0] != '\0')
3506 dynarray_add(&libs, &nblibs, tcc_strdup(libname));
3507 }
3508 }
3509 }
3510 t = ld_next(s1, filename, sizeof(filename));
3511 if (t == ',') {
3512 t = ld_next(s1, filename, sizeof(filename));
3513 }
3514 }
3515 if (group && !as_needed) {
3516 while (s1->new_undef_sym) {
3517 int i;
3518 s1->new_undef_sym = 0;
3519 for (i = 0; i < nblibs; i ++)
3520 ld_add_file(s1, libs[i]);
3521 }
3522 }
3523lib_parse_error:
3524 dynarray_reset(&libs, &nblibs);
3525 return ret;
3526}
3527
3528/* interpret a subset of GNU ldscripts to handle the dummy libc.so
3529 files */
3530ST_FUNC int tcc_load_ldscript(TCCState *s1, int fd)
3531{
3532 char cmd[64];
3533 char filename[1024];
3534 int t, ret;
3535
3536 s1->fd = fd;
3537 s1->cc = -1;
3538 for(;;) {
3539 t = ld_next(s1, cmd, sizeof(cmd));
3540 if (t == LD_TOK_EOF)
3541 return 0;
3542 else if (t != LD_TOK_NAME)
3543 return -1;
3544 if (!strcmp(cmd, "INPUT") ||
3545 !strcmp(cmd, "GROUP")) {
3546 ret = ld_add_file_list(s1, cmd, 0);
3547 if (ret)
3548 return ret;
3549 } else if (!strcmp(cmd, "OUTPUT_FORMAT") ||
3550 !strcmp(cmd, "TARGET")) {
3551 /* ignore some commands */
3552 t = ld_next(s1, cmd, sizeof(cmd));
3553 if (t != '(') {
3554 tcc_error_noabort("( expected");
3555 return -1;
3556 }
3557 for(;;) {
3558 t = ld_next(s1, filename, sizeof(filename));
3559 if (t == LD_TOK_EOF) {
3560 tcc_error_noabort("unexpected end of file");
3561 return -1;
3562 } else if (t == ')') {
3563 break;
3564 }
3565 }
3566 } else {
3567 return -1;
3568 }
3569 }
3570 return 0;
3571}
3572#endif /* !ELF_OBJ_ONLY */
3573