Changeset 331 for EcnlProtoTool/trunk/tcc-0.9.27/tccelf.c
- Timestamp:
- Jan 21, 2018, 12:10:09 AM (6 years ago)
- Location:
- EcnlProtoTool/trunk/tcc-0.9.27
- Files:
-
- 1 edited
- 1 moved
Legend:
- Unmodified
- Added
- Removed
-
EcnlProtoTool/trunk/tcc-0.9.27/tccelf.c
r321 r331 1 1 /* 2 2 * ELF file handling for TCC 3 * 3 * 4 4 * Copyright (c) 2001-2004 Fabrice Bellard 5 5 * … … 21 21 #include "tcc.h" 22 22 23 /* Define this to get some debug output during relocation processing. */ 24 #undef DEBUG_RELOC 25 26 /********************************************************/ 27 /* global variables */ 28 29 ST_DATA Section *text_section, *data_section, *bss_section; /* predefined sections */ 30 ST_DATA Section *common_section; 31 ST_DATA Section *cur_text_section; /* current section where function code is generated */ 32 #ifdef CONFIG_TCC_ASM 33 ST_DATA Section *last_text_section; /* to handle .previous asm directive */ 34 #endif 35 #ifdef CONFIG_TCC_BCHECK 36 /* bound check related sections */ 37 ST_DATA Section *bounds_section; /* contains global data bound description */ 38 ST_DATA Section *lbounds_section; /* contains local data bound description */ 39 #endif 40 /* symbol sections */ 41 ST_DATA Section *symtab_section; 42 /* debug sections */ 43 ST_DATA Section *stab_section, *stabstr_section; 44 45 /* XXX: avoid static variable */ 23 46 static int new_undef_sym = 0; /* Is there a new undefined sym since last new_undef_sym() */ 47 48 /* special flag to indicate that the section should not be linked to the other ones */ 49 #define SHF_PRIVATE 0x80000000 50 /* section is dynsymtab_section */ 51 #define SHF_DYNSYM 0x40000000 52 53 /* ------------------------------------------------------------------------- */ 54 55 ST_FUNC void tccelf_new(TCCState *s) 56 { 57 /* no section zero */ 58 dynarray_add(&s->sections, &s->nb_sections, NULL); 59 60 /* create standard sections */ 61 text_section = new_section(s, ".text", SHT_PROGBITS, SHF_ALLOC | SHF_EXECINSTR); 62 data_section = new_section(s, ".data", SHT_PROGBITS, SHF_ALLOC | SHF_WRITE); 63 bss_section = new_section(s, ".bss", SHT_NOBITS, SHF_ALLOC | SHF_WRITE); 64 common_section = new_section(s, ".common", SHT_NOBITS, SHF_PRIVATE); 65 common_section->sh_num = SHN_COMMON; 66 67 /* symbols are always generated for linking stage */ 68 symtab_section = new_symtab(s, ".symtab", SHT_SYMTAB, 0, 69 ".strtab", 70 ".hashtab", SHF_PRIVATE); 71 s->symtab = symtab_section; 72 73 /* private symbol table for dynamic symbols */ 74 s->dynsymtab_section = new_symtab(s, ".dynsymtab", SHT_SYMTAB, SHF_PRIVATE|SHF_DYNSYM, 75 ".dynstrtab", 76 ".dynhashtab", SHF_PRIVATE); 77 get_sym_attr(s, 0, 1); 78 } 79 80 #ifdef CONFIG_TCC_BCHECK 81 ST_FUNC void tccelf_bounds_new(TCCState *s) 82 { 83 /* create bounds sections */ 84 bounds_section = new_section(s, ".bounds", 85 SHT_PROGBITS, SHF_ALLOC); 86 lbounds_section = new_section(s, ".lbounds", 87 SHT_PROGBITS, SHF_ALLOC); 88 } 89 #endif 90 91 ST_FUNC void tccelf_stab_new(TCCState *s) 92 { 93 stab_section = new_section(s, ".stab", SHT_PROGBITS, 0); 94 stab_section->sh_entsize = sizeof(Stab_Sym); 95 stabstr_section = new_section(s, ".stabstr", SHT_STRTAB, 0); 96 put_elf_str(stabstr_section, ""); 97 stab_section->link = stabstr_section; 98 /* put first entry */ 99 put_stabs("", 0, 0, 0, 0); 100 } 101 102 static void free_section(Section *s) 103 { 104 tcc_free(s->data); 105 } 106 107 ST_FUNC void tccelf_delete(TCCState *s1) 108 { 109 int i; 110 111 /* free all sections */ 112 for(i = 1; i < s1->nb_sections; i++) 113 free_section(s1->sections[i]); 114 dynarray_reset(&s1->sections, &s1->nb_sections); 115 116 for(i = 0; i < s1->nb_priv_sections; i++) 117 free_section(s1->priv_sections[i]); 118 dynarray_reset(&s1->priv_sections, &s1->nb_priv_sections); 119 120 /* free any loaded DLLs */ 121 #ifdef TCC_IS_NATIVE 122 for ( i = 0; i < s1->nb_loaded_dlls; i++) { 123 DLLReference *ref = s1->loaded_dlls[i]; 124 if ( ref->handle ) 125 # ifdef _WIN32 126 FreeLibrary((HMODULE)ref->handle); 127 # else 128 dlclose(ref->handle); 129 # endif 130 } 131 #endif 132 /* free loaded dlls array */ 133 dynarray_reset(&s1->loaded_dlls, &s1->nb_loaded_dlls); 134 tcc_free(s1->sym_attrs); 135 136 symtab_section = NULL; /* for tccrun.c:rt_printline() */ 137 } 138 139 /* save section data state */ 140 ST_FUNC void tccelf_begin_file(TCCState *s1) 141 { 142 Section *s; int i; 143 for (i = 1; i < s1->nb_sections; i++) { 144 s = s1->sections[i]; 145 s->sh_offset = s->data_offset; 146 } 147 /* disable symbol hashing during compilation */ 148 s = s1->symtab, s->reloc = s->hash, s->hash = NULL; 149 #if defined TCC_TARGET_X86_64 && defined TCC_TARGET_PE 150 s1->uw_sym = 0; 151 #endif 152 } 153 154 /* At the end of compilation, convert any UNDEF syms to global, and merge 155 with previously existing symbols */ 156 ST_FUNC void tccelf_end_file(TCCState *s1) 157 { 158 Section *s = s1->symtab; 159 int first_sym, nb_syms, *tr, i; 160 161 first_sym = s->sh_offset / sizeof (ElfSym); 162 nb_syms = s->data_offset / sizeof (ElfSym) - first_sym; 163 s->data_offset = s->sh_offset; 164 s->link->data_offset = s->link->sh_offset; 165 s->hash = s->reloc, s->reloc = NULL; 166 tr = tcc_mallocz(nb_syms * sizeof *tr); 167 168 for (i = 0; i < nb_syms; ++i) { 169 ElfSym *sym = (ElfSym*)s->data + first_sym + i; 170 if (sym->st_shndx == SHN_UNDEF 171 && ELFW(ST_BIND)(sym->st_info) == STB_LOCAL) 172 sym->st_info = ELFW(ST_INFO)(STB_GLOBAL, ELFW(ST_TYPE)(sym->st_info)); 173 tr[i] = set_elf_sym(s, sym->st_value, sym->st_size, sym->st_info, 174 sym->st_other, sym->st_shndx, s->link->data + sym->st_name); 175 } 176 /* now update relocations */ 177 for (i = 1; i < s1->nb_sections; i++) { 178 Section *sr = s1->sections[i]; 179 if (sr->sh_type == SHT_RELX && sr->link == s) { 180 ElfW_Rel *rel = (ElfW_Rel*)(sr->data + sr->sh_offset); 181 ElfW_Rel *rel_end = (ElfW_Rel*)(sr->data + sr->data_offset); 182 for (; rel < rel_end; ++rel) { 183 int n = ELFW(R_SYM)(rel->r_info) - first_sym; 184 //if (n < 0) tcc_error("internal: invalid symbol index in relocation"); 185 rel->r_info = ELFW(R_INFO)(tr[n], ELFW(R_TYPE)(rel->r_info)); 186 } 187 } 188 } 189 tcc_free(tr); 190 } 191 192 ST_FUNC Section *new_section(TCCState *s1, const char *name, int sh_type, int sh_flags) 193 { 194 Section *sec; 195 196 sec = tcc_mallocz(sizeof(Section) + strlen(name)); 197 strcpy(sec->name, name); 198 sec->sh_type = sh_type; 199 sec->sh_flags = sh_flags; 200 switch(sh_type) { 201 case SHT_HASH: 202 case SHT_REL: 203 case SHT_RELA: 204 case SHT_DYNSYM: 205 case SHT_SYMTAB: 206 case SHT_DYNAMIC: 207 sec->sh_addralign = 4; 208 break; 209 case SHT_STRTAB: 210 sec->sh_addralign = 1; 211 break; 212 default: 213 sec->sh_addralign = PTR_SIZE; /* gcc/pcc default alignment */ 214 break; 215 } 216 217 if (sh_flags & SHF_PRIVATE) { 218 dynarray_add(&s1->priv_sections, &s1->nb_priv_sections, sec); 219 } else { 220 sec->sh_num = s1->nb_sections; 221 dynarray_add(&s1->sections, &s1->nb_sections, sec); 222 } 223 224 return sec; 225 } 226 227 ST_FUNC Section *new_symtab(TCCState *s1, 228 const char *symtab_name, int sh_type, int sh_flags, 229 const char *strtab_name, 230 const char *hash_name, int hash_sh_flags) 231 { 232 Section *symtab, *strtab, *hash; 233 int *ptr, nb_buckets; 234 235 symtab = new_section(s1, symtab_name, sh_type, sh_flags); 236 symtab->sh_entsize = sizeof(ElfW(Sym)); 237 strtab = new_section(s1, strtab_name, SHT_STRTAB, sh_flags); 238 put_elf_str(strtab, ""); 239 symtab->link = strtab; 240 put_elf_sym(symtab, 0, 0, 0, 0, 0, NULL); 241 242 nb_buckets = 1; 243 244 hash = new_section(s1, hash_name, SHT_HASH, hash_sh_flags); 245 hash->sh_entsize = sizeof(int); 246 symtab->hash = hash; 247 hash->link = symtab; 248 249 ptr = section_ptr_add(hash, (2 + nb_buckets + 1) * sizeof(int)); 250 ptr[0] = nb_buckets; 251 ptr[1] = 1; 252 memset(ptr + 2, 0, (nb_buckets + 1) * sizeof(int)); 253 return symtab; 254 } 255 256 /* realloc section and set its content to zero */ 257 ST_FUNC void section_realloc(Section *sec, unsigned long new_size) 258 { 259 unsigned long size; 260 unsigned char *data; 261 262 size = sec->data_allocated; 263 if (size == 0) 264 size = 1; 265 while (size < new_size) 266 size = size * 2; 267 data = tcc_realloc(sec->data, size); 268 memset(data + sec->data_allocated, 0, size - sec->data_allocated); 269 sec->data = data; 270 sec->data_allocated = size; 271 } 272 273 /* reserve at least 'size' bytes aligned per 'align' in section 274 'sec' from current offset, and return the aligned offset */ 275 ST_FUNC size_t section_add(Section *sec, addr_t size, int align) 276 { 277 size_t offset, offset1; 278 279 offset = (sec->data_offset + align - 1) & -align; 280 offset1 = offset + size; 281 if (sec->sh_type != SHT_NOBITS && offset1 > sec->data_allocated) 282 section_realloc(sec, offset1); 283 sec->data_offset = offset1; 284 if (align > sec->sh_addralign) 285 sec->sh_addralign = align; 286 return offset; 287 } 288 289 /* reserve at least 'size' bytes in section 'sec' from 290 sec->data_offset. */ 291 ST_FUNC void *section_ptr_add(Section *sec, addr_t size) 292 { 293 size_t offset = section_add(sec, size, 1); 294 return sec->data + offset; 295 } 296 297 /* reserve at least 'size' bytes from section start */ 298 ST_FUNC void section_reserve(Section *sec, unsigned long size) 299 { 300 if (size > sec->data_allocated) 301 section_realloc(sec, size); 302 if (size > sec->data_offset) 303 sec->data_offset = size; 304 } 305 306 /* return a reference to a section, and create it if it does not 307 exists */ 308 ST_FUNC Section *find_section(TCCState *s1, const char *name) 309 { 310 Section *sec; 311 int i; 312 for(i = 1; i < s1->nb_sections; i++) { 313 sec = s1->sections[i]; 314 if (!strcmp(name, sec->name)) 315 return sec; 316 } 317 /* sections are created as PROGBITS */ 318 return new_section(s1, name, SHT_PROGBITS, SHF_ALLOC); 319 } 320 321 /* ------------------------------------------------------------------------- */ 24 322 25 323 ST_FUNC int put_elf_str(Section *s, const char *sym) … … 31 329 offset = s->data_offset; 32 330 ptr = section_ptr_add(s, len); 33 mem cpy(ptr, sym, len);331 memmove(ptr, sym, len); 34 332 return offset; 35 333 } … … 39 337 { 40 338 unsigned long h = 0, g; 41 339 42 340 while (*name) { 43 341 h = (h << 4) + *name++; … … 56 354 ElfW(Sym) *sym; 57 355 int *ptr, *hash, nb_syms, sym_index, h; 58 char *strtab;356 unsigned char *strtab; 59 357 60 358 strtab = s->link->data; 61 359 nb_syms = s->data_offset / sizeof(ElfW(Sym)); 360 361 if (!nb_buckets) 362 nb_buckets = ((int*)s->hash->data)[0]; 62 363 63 364 s->hash->data_offset = 0; … … 92 393 ElfW(Sym) *sym; 93 394 Section *hs; 94 395 95 396 sym = section_ptr_add(s, sizeof(ElfW(Sym))); 96 if (name )397 if (name && name[0]) 97 398 name_offset = put_elf_str(s->link, name); 98 399 else … … 111 412 ptr = section_ptr_add(hs, sizeof(int)); 112 413 base = (int *)hs->data; 113 /* only add global or weak symbols */414 /* only add global or weak symbols. */ 114 415 if (ELFW(ST_BIND)(info) != STB_LOCAL) { 115 416 /* add another hashing entry */ 116 417 nbuckets = base[0]; 117 h = elf_hash( name) % nbuckets;418 h = elf_hash((unsigned char *)s->link->data + name_offset) % nbuckets; 118 419 *ptr = base[2 + h]; 119 420 base[2 + h] = sym_index; … … 132 433 } 133 434 134 /* find global ELF symbol 'name' and return its index. Return 0 if not135 found. */136 435 ST_FUNC int find_elf_sym(Section *s, const char *name) 137 436 { … … 140 439 int nbuckets, sym_index, h; 141 440 const char *name1; 142 441 143 442 hs = s->hash; 144 443 if (!hs) 145 444 return 0; 146 445 nbuckets = ((int *)hs->data)[0]; 147 h = elf_hash( name) % nbuckets;446 h = elf_hash((unsigned char *) name) % nbuckets; 148 447 sym_index = ((int *)hs->data)[2 + h]; 149 448 while (sym_index != 0) { 150 449 sym = &((ElfW(Sym) *)s->data)[sym_index]; 151 name1 = s->link->data + sym->st_name;450 name1 = (char *) s->link->data + sym->st_name; 152 451 if (!strcmp(name, name1)) 153 452 return sym_index; … … 179 478 } 180 479 181 #if def TCC_IS_NATIVE480 #if defined TCC_IS_NATIVE || defined TCC_TARGET_PE 182 481 /* return elf symbol value or error */ 183 482 ST_FUNC void* tcc_get_symbol_err(TCCState *s, const char *name) 184 483 { 185 return (void*) get_elf_sym_addr(s, name, 1);484 return (void*)(uintptr_t)get_elf_sym_addr(s, name, 1); 186 485 } 187 486 #endif … … 189 488 /* add an elf symbol : check if it is already defined and patch 190 489 it. Return symbol index. NOTE that sh_num can be SHN_UNDEF. */ 191 ST_FUNC int add_elf_sym(Section *s, addr_t value, unsigned long size,192 int info, int other, int sh _num, const char *name)490 ST_FUNC int set_elf_sym(Section *s, addr_t value, unsigned long size, 491 int info, int other, int shndx, const char *name) 193 492 { 194 493 ElfW(Sym) *esym; … … 199 498 sym_type = ELFW(ST_TYPE)(info); 200 499 sym_vis = ELFW(ST_VISIBILITY)(other); 201 500 202 501 if (sym_bind != STB_LOCAL) { 203 502 /* we search global or weak symbols */ … … 206 505 goto do_def; 207 506 esym = &((ElfW(Sym) *)s->data)[sym_index]; 507 if (esym->st_value == value && esym->st_size == size && esym->st_info == info 508 && esym->st_other == other && esym->st_shndx == shndx) 509 return sym_index; 208 510 if (esym->st_shndx != SHN_UNDEF) { 209 511 esym_bind = ELFW(ST_BIND)(esym->st_info); … … 221 523 | new_vis; 222 524 other = esym->st_other; /* in case we have to patch esym */ 223 if (sh _num== SHN_UNDEF) {525 if (shndx == SHN_UNDEF) { 224 526 /* ignore adding of undefined symbol if the 225 527 corresponding symbol is already defined */ … … 233 535 } else if (sym_vis == STV_HIDDEN || sym_vis == STV_INTERNAL) { 234 536 /* ignore hidden symbols after */ 235 } else if (esym->st_shndx == SHN_COMMON 236 && (sh_num < SHN_LORESERVE || sh_num == SHN_COMMON)) { 237 /* gr: Happens with 'tcc ... -static tcctest.c' on e.g. Ubuntu 6.01 238 No idea if this is the correct solution ... */ 537 } else if ((esym->st_shndx == SHN_COMMON 538 || esym->st_shndx == bss_section->sh_num) 539 && (shndx < SHN_LORESERVE 540 && shndx != bss_section->sh_num)) { 541 /* data symbol gets precedence over common/bss */ 239 542 goto do_patch; 240 } else if (s == tcc_state->dynsymtab_section) { 543 } else if (shndx == SHN_COMMON || shndx == bss_section->sh_num) { 544 /* data symbol keeps precedence over common/bss */ 545 } else if (s->sh_flags & SHF_DYNSYM) { 241 546 /* we accept that two DLL define the same symbol */ 547 } else if (esym->st_other & ST_ASM_SET) { 548 /* If the existing symbol came from an asm .set 549 we can override. */ 550 goto do_patch; 242 551 } else { 243 552 #if 0 244 553 printf("new_bind=%x new_shndx=%x new_vis=%x old_bind=%x old_shndx=%x old_vis=%x\n", 245 sym_bind, sh _num, new_vis, esym_bind, esym->st_shndx, esym_vis);554 sym_bind, shndx, new_vis, esym_bind, esym->st_shndx, esym_vis); 246 555 #endif 247 556 tcc_error_noabort("'%s' defined twice", name); … … 250 559 do_patch: 251 560 esym->st_info = ELFW(ST_INFO)(sym_bind, sym_type); 252 esym->st_shndx = sh _num;561 esym->st_shndx = shndx; 253 562 new_undef_sym = 1; 254 563 esym->st_value = value; … … 258 567 } else { 259 568 do_def: 260 sym_index = put_elf_sym(s, value, size, 261 ELFW(ST_INFO)(sym_bind, sym_type), other, 262 sh _num, name);569 sym_index = put_elf_sym(s, value, size, 570 ELFW(ST_INFO)(sym_bind, sym_type), other, 571 shndx, name); 263 572 } 264 573 return sym_index; … … 266 575 267 576 /* put relocation */ 268 ST_FUNC void put_elf_reloc (Section *symtab, Section *s, unsigned long offset,269 int type, int symbol)577 ST_FUNC void put_elf_reloca(Section *symtab, Section *s, unsigned long offset, 578 int type, int symbol, addr_t addend) 270 579 { 271 580 char buf[256]; … … 288 597 rel->r_offset = offset; 289 598 rel->r_info = ELFW(R_INFO)(symbol, type); 290 #ifdef TCC_TARGET_X86_64 291 rel->r_addend = 0; 292 #endif 599 #if SHT_RELX == SHT_RELA 600 rel->r_addend = addend; 601 #else 602 if (addend) 603 tcc_error("non-zero addend on REL architecture"); 604 #endif 605 } 606 607 ST_FUNC void put_elf_reloc(Section *symtab, Section *s, unsigned long offset, 608 int type, int symbol) 609 { 610 put_elf_reloca(symtab, s, offset, type, symbol, 0); 611 } 612 613 /* Remove relocations for section S->reloc starting at oldrelocoffset 614 that are to the same place, retaining the last of them. As side effect 615 the relocations are sorted. Possibly reduces the number of relocs. */ 616 ST_FUNC void squeeze_multi_relocs(Section *s, size_t oldrelocoffset) 617 { 618 Section *sr = s->reloc; 619 ElfW_Rel *r, *dest; 620 ssize_t a; 621 ElfW(Addr) addr; 622 623 if (oldrelocoffset + sizeof(*r) >= sr->data_offset) 624 return; 625 /* The relocs we're dealing with are the result of initializer parsing. 626 So they will be mostly in order and there aren't many of them. 627 Secondly we need a stable sort (which qsort isn't). We use 628 a simple insertion sort. */ 629 for (a = oldrelocoffset + sizeof(*r); a < sr->data_offset; a += sizeof(*r)) { 630 ssize_t i = a - sizeof(*r); 631 addr = ((ElfW_Rel*)(sr->data + a))->r_offset; 632 for (; i >= (ssize_t)oldrelocoffset && 633 ((ElfW_Rel*)(sr->data + i))->r_offset > addr; i -= sizeof(*r)) { 634 ElfW_Rel tmp = *(ElfW_Rel*)(sr->data + a); 635 *(ElfW_Rel*)(sr->data + a) = *(ElfW_Rel*)(sr->data + i); 636 *(ElfW_Rel*)(sr->data + i) = tmp; 637 } 638 } 639 640 r = (ElfW_Rel*)(sr->data + oldrelocoffset); 641 dest = r; 642 for (; r < (ElfW_Rel*)(sr->data + sr->data_offset); r++) { 643 if (dest->r_offset != r->r_offset) 644 dest++; 645 *dest = *r; 646 } 647 sr->data_offset = (unsigned char*)dest - sr->data + sizeof(*r); 293 648 } 294 649 … … 312 667 } 313 668 314 ST_FUNC void put_stabs_r(const char *str, int type, int other, int desc, 669 ST_FUNC void put_stabs_r(const char *str, int type, int other, int desc, 315 670 unsigned long value, Section *sec, int sym_index) 316 671 { 317 672 put_stabs(str, type, other, desc, value); 318 put_elf_reloc(symtab_section, stab_section, 673 put_elf_reloc(symtab_section, stab_section, 319 674 stab_section->data_offset - sizeof(unsigned int), 320 675 R_DATA_32, sym_index); … … 331 686 } 332 687 333 /* In an ELF file symbol table, the local symbols must appear below 334 the global and weak ones. Since TCC cannot sort it while generating 335 the code, we must do it after. All the relocation tables are also 336 modified to take into account the symbol table sorting */ 337 static void sort_syms(TCCState *s1, Section *s) 338 { 339 int *old_to_new_syms; 340 ElfW(Sym) *new_syms; 341 int nb_syms, i; 342 ElfW(Sym) *p, *q; 343 ElfW_Rel *rel, *rel_end; 344 Section *sr; 345 int type, sym_index; 346 347 nb_syms = s->data_offset / sizeof(ElfW(Sym)); 348 new_syms = tcc_malloc(nb_syms * sizeof(ElfW(Sym))); 349 old_to_new_syms = tcc_malloc(nb_syms * sizeof(int)); 350 351 /* first pass for local symbols */ 352 p = (ElfW(Sym) *)s->data; 353 q = new_syms; 354 for(i = 0; i < nb_syms; i++) { 355 if (ELFW(ST_BIND)(p->st_info) == STB_LOCAL) { 356 old_to_new_syms[i] = q - new_syms; 357 *q++ = *p; 358 } 359 p++; 360 } 361 /* save the number of local symbols in section header */ 362 s->sh_info = q - new_syms; 363 364 /* then second pass for non local symbols */ 365 p = (ElfW(Sym) *)s->data; 366 for(i = 0; i < nb_syms; i++) { 367 if (ELFW(ST_BIND)(p->st_info) != STB_LOCAL) { 368 old_to_new_syms[i] = q - new_syms; 369 *q++ = *p; 370 } 371 p++; 372 } 373 374 /* we copy the new symbols to the old */ 375 memcpy(s->data, new_syms, nb_syms * sizeof(ElfW(Sym))); 376 tcc_free(new_syms); 377 378 /* now we modify all the relocations */ 379 for(i = 1; i < s1->nb_sections; i++) { 380 sr = s1->sections[i]; 381 if (sr->sh_type == SHT_RELX && sr->link == s) { 382 rel_end = (ElfW_Rel *)(sr->data + sr->data_offset); 383 for(rel = (ElfW_Rel *)sr->data; 384 rel < rel_end; 385 rel++) { 386 sym_index = ELFW(R_SYM)(rel->r_info); 387 type = ELFW(R_TYPE)(rel->r_info); 388 sym_index = old_to_new_syms[sym_index]; 389 rel->r_info = ELFW(R_INFO)(sym_index, type); 390 } 391 } 392 } 393 394 tcc_free(old_to_new_syms); 395 } 396 397 /* relocate common symbols in the .bss section */ 398 ST_FUNC void relocate_common_syms(void) 399 { 400 ElfW(Sym) *sym, *sym_end; 401 unsigned long offset, align; 402 403 sym_end = (ElfW(Sym) *)(symtab_section->data + symtab_section->data_offset); 404 for(sym = (ElfW(Sym) *)symtab_section->data + 1; 405 sym < sym_end; 406 sym++) { 407 if (sym->st_shndx == SHN_COMMON) { 408 /* align symbol */ 409 align = sym->st_value; 410 offset = bss_section->data_offset; 411 offset = (offset + align - 1) & -align; 412 sym->st_value = offset; 413 sym->st_shndx = bss_section->sh_num; 414 offset += sym->st_size; 415 bss_section->data_offset = offset; 416 } 417 } 418 } 419 420 /* relocate symbol table, resolve undefined symbols if do_resolve is 421 true and output error if undefined symbol. */ 422 ST_FUNC void relocate_syms(TCCState *s1, int do_resolve) 423 { 424 ElfW(Sym) *sym, *esym, *sym_end; 425 int sym_bind, sh_num, sym_index; 426 const char *name; 427 428 sym_end = (ElfW(Sym) *)(symtab_section->data + symtab_section->data_offset); 429 for(sym = (ElfW(Sym) *)symtab_section->data + 1; 430 sym < sym_end; 431 sym++) { 432 sh_num = sym->st_shndx; 433 if (sh_num == SHN_UNDEF) { 434 name = strtab_section->data + sym->st_name; 435 if (do_resolve) { 436 #if defined TCC_IS_NATIVE && !defined _WIN32 437 void *addr; 438 name = symtab_section->link->data + sym->st_name; 439 addr = resolve_sym(s1, name); 440 if (addr) { 441 sym->st_value = (addr_t)addr; 442 goto found; 443 } 444 #endif 445 } else if (s1->dynsym) { 446 /* if dynamic symbol exist, then use it */ 447 sym_index = find_elf_sym(s1->dynsym, name); 448 if (sym_index) { 449 esym = &((ElfW(Sym) *)s1->dynsym->data)[sym_index]; 450 sym->st_value = esym->st_value; 451 goto found; 452 } 453 } 454 /* XXX: _fp_hw seems to be part of the ABI, so we ignore 455 it */ 456 if (!strcmp(name, "_fp_hw")) 457 goto found; 458 /* only weak symbols are accepted to be undefined. Their 459 value is zero */ 460 sym_bind = ELFW(ST_BIND)(sym->st_info); 461 if (sym_bind == STB_WEAK) { 462 sym->st_value = 0; 463 } else { 464 tcc_error_noabort("undefined symbol '%s'", name); 465 } 466 } else if (sh_num < SHN_LORESERVE) { 467 /* add section base */ 468 sym->st_value += s1->sections[sym->st_shndx]->sh_addr; 469 } 470 found: ; 471 } 472 } 473 474 #ifdef TCC_HAS_RUNTIME_PLTGOT 475 #ifdef TCC_TARGET_X86_64 476 #define JMP_TABLE_ENTRY_SIZE 14 477 static addr_t add_jmp_table(TCCState *s1, addr_t val) 478 { 479 char *p = s1->runtime_plt_and_got + s1->runtime_plt_and_got_offset; 480 s1->runtime_plt_and_got_offset += JMP_TABLE_ENTRY_SIZE; 481 /* jmp *0x0(%rip) */ 482 p[0] = 0xff; 483 p[1] = 0x25; 484 *(int *)(p + 2) = 0; 485 *(addr_t *)(p + 6) = val; 486 return (addr_t)p; 487 } 488 489 static addr_t add_got_table(TCCState *s1, addr_t val) 490 { 491 addr_t *p = (addr_t *)(s1->runtime_plt_and_got + s1->runtime_plt_and_got_offset); 492 s1->runtime_plt_and_got_offset += sizeof(addr_t); 493 *p = val; 494 return (addr_t)p; 495 } 496 #elif defined TCC_TARGET_ARM 497 #define JMP_TABLE_ENTRY_SIZE 8 498 static addr_t add_jmp_table(TCCState *s1, int val) 499 { 500 uint32_t *p = (uint32_t *)(s1->runtime_plt_and_got + s1->runtime_plt_and_got_offset); 501 s1->runtime_plt_and_got_offset += JMP_TABLE_ENTRY_SIZE; 502 /* ldr pc, [pc, #-4] */ 503 p[0] = 0xE51FF004; 504 p[1] = val; 505 return (addr_t)p; 506 } 507 #endif 508 #endif /* def TCC_HAS_RUNTIME_PLTGOT */ 509 510 /* relocate a given section (CPU dependent) */ 511 ST_FUNC void relocate_section(TCCState *s1, Section *s) 512 { 513 Section *sr; 514 ElfW_Rel *rel, *rel_end, *qrel; 515 ElfW(Sym) *sym; 516 int type, sym_index; 517 unsigned char *ptr; 518 addr_t val, addr; 519 #if defined TCC_TARGET_I386 || defined TCC_TARGET_X86_64 520 int esym_index; 521 #endif 522 523 sr = s->reloc; 524 rel_end = (ElfW_Rel *)(sr->data + sr->data_offset); 525 qrel = (ElfW_Rel *)sr->data; 526 for(rel = qrel; 527 rel < rel_end; 528 rel++) { 529 ptr = s->data + rel->r_offset; 530 531 sym_index = ELFW(R_SYM)(rel->r_info); 532 sym = &((ElfW(Sym) *)symtab_section->data)[sym_index]; 533 val = sym->st_value; 534 #ifdef TCC_TARGET_X86_64 535 val += rel->r_addend; 536 #endif 537 type = ELFW(R_TYPE)(rel->r_info); 538 addr = s->sh_addr + rel->r_offset; 539 540 /* CPU specific */ 541 switch(type) { 542 #if defined(TCC_TARGET_I386) 543 case R_386_32: 544 if (s1->output_type == TCC_OUTPUT_DLL) { 545 esym_index = s1->symtab_to_dynsym[sym_index]; 546 qrel->r_offset = rel->r_offset; 547 if (esym_index) { 548 qrel->r_info = ELFW(R_INFO)(esym_index, R_386_32); 549 qrel++; 550 break; 551 } else { 552 qrel->r_info = ELFW(R_INFO)(0, R_386_RELATIVE); 553 qrel++; 554 } 555 } 556 *(int *)ptr += val; 557 break; 558 case R_386_PC32: 559 if (s1->output_type == TCC_OUTPUT_DLL) { 560 /* DLL relocation */ 561 esym_index = s1->symtab_to_dynsym[sym_index]; 562 if (esym_index) { 563 qrel->r_offset = rel->r_offset; 564 qrel->r_info = ELFW(R_INFO)(esym_index, R_386_PC32); 565 qrel++; 566 break; 567 } 568 } 569 *(int *)ptr += val - addr; 570 break; 571 case R_386_PLT32: 572 *(int *)ptr += val - addr; 573 break; 574 case R_386_GLOB_DAT: 575 case R_386_JMP_SLOT: 576 *(int *)ptr = val; 577 break; 578 case R_386_GOTPC: 579 *(int *)ptr += s1->got->sh_addr - addr; 580 break; 581 case R_386_GOTOFF: 582 *(int *)ptr += val - s1->got->sh_addr; 583 break; 584 case R_386_GOT32: 585 /* we load the got offset */ 586 *(int *)ptr += s1->sym_attrs[sym_index].got_offset; 587 break; 588 case R_386_16: 589 if (s1->output_format != TCC_OUTPUT_FORMAT_BINARY) { 590 output_file: 591 tcc_error("can only produce 16-bit binary files"); 592 } 593 *(short *)ptr += val; 594 break; 595 case R_386_PC16: 596 if (s1->output_format != TCC_OUTPUT_FORMAT_BINARY) 597 goto output_file; 598 *(short *)ptr += val - addr; 599 break; 600 #elif defined(TCC_TARGET_ARM) 601 case R_ARM_PC24: 602 case R_ARM_CALL: 603 case R_ARM_JUMP24: 604 case R_ARM_PLT32: 605 { 606 int x, is_thumb, is_call, h, blx_avail; 607 x = (*(int *)ptr)&0xffffff; 608 (*(int *)ptr) &= 0xff000000; 609 if (x & 0x800000) 610 x -= 0x1000000; 611 x <<= 2; 612 blx_avail = (TCC_ARM_VERSION >= 5); 613 is_thumb = val & 1; 614 is_call = (type == R_ARM_CALL); 615 x += val - addr; 616 h = x & 2; 617 #ifdef TCC_HAS_RUNTIME_PLTGOT 618 if (s1->output_type == TCC_OUTPUT_MEMORY) { 619 if ((x & 3) || x >= 0x2000000 || x < -0x2000000) 620 if (!(x & 3) || !blx_avail || !is_call) { 621 x += add_jmp_table(s1, val) - val; /* add veneer */ 622 is_thumb = 0; /* Veneer uses ARM instructions */ 623 } 624 } 625 #endif 626 if ((x & 3) || x >= 0x2000000 || x < -0x2000000) 627 if (!(x & 3) || !blx_avail || !is_call) 628 tcc_error("can't relocate value at %x",addr); 629 x >>= 2; 630 x &= 0xffffff; 631 /* Only reached if blx is avail and it is a call */ 632 if (is_thumb) { 633 x |= h << 24; 634 (*(int *)ptr) = 0xfa << 24; /* bl -> blx */ 635 } 636 (*(int *)ptr) |= x; 637 } 638 break; 639 /* Since these relocations only concern Thumb-2 and blx instruction was 640 introduced before Thumb-2, we can assume blx is available and not 641 guard its use */ 642 case R_ARM_THM_CALL: 643 case R_ARM_THM_JUMP24: 644 { 645 int x, hi, lo, s, j1, j2, i1, i2, imm10, imm11; 646 int to_thumb, is_call, to_plt, blx_bit = 1 << 12; 647 Section *plt; 648 649 /* weak reference */ 650 if (sym->st_shndx == SHN_UNDEF && 651 ELFW(ST_BIND)(sym->st_info) == STB_WEAK) 652 break; 653 654 /* Get initial offset */ 655 hi = (*(uint16_t *)ptr); 656 lo = (*(uint16_t *)(ptr+2)); 657 s = (hi >> 10) & 1; 658 j1 = (lo >> 13) & 1; 659 j2 = (lo >> 11) & 1; 660 i1 = (j1 ^ s) ^ 1; 661 i2 = (j2 ^ s) ^ 1; 662 imm10 = hi & 0x3ff; 663 imm11 = lo & 0x7ff; 664 x = (s << 24) | (i1 << 23) | (i2 << 22) | 665 (imm10 << 12) | (imm11 << 1); 666 if (x & 0x01000000) 667 x -= 0x02000000; 668 669 /* Relocation infos */ 670 to_thumb = val & 1; 671 plt = s1->plt; 672 to_plt = (val >= plt->sh_addr) && 673 (val < plt->sh_addr + plt->data_offset); 674 is_call = (type == R_ARM_THM_CALL); 675 676 /* Compute final offset */ 677 if (to_plt && !is_call) /* Point to 1st instr of Thumb stub */ 678 x -= 4; 679 x += val - addr; 680 if (!to_thumb && is_call) { 681 blx_bit = 0; /* bl -> blx */ 682 x = (x + 3) & -4; /* Compute offset from aligned PC */ 683 } 684 685 /* Check that relocation is possible 686 * offset must not be out of range 687 * if target is to be entered in arm mode: 688 - bit 1 must not set 689 - instruction must be a call (bl) or a jump to PLT */ 690 if (!to_thumb || x >= 0x1000000 || x < -0x1000000) 691 if (to_thumb || (val & 2) || (!is_call && !to_plt)) 692 tcc_error("can't relocate value at %x",addr); 693 694 /* Compute and store final offset */ 695 s = (x >> 24) & 1; 696 i1 = (x >> 23) & 1; 697 i2 = (x >> 22) & 1; 698 j1 = s ^ (i1 ^ 1); 699 j2 = s ^ (i2 ^ 1); 700 imm10 = (x >> 12) & 0x3ff; 701 imm11 = (x >> 1) & 0x7ff; 702 (*(uint16_t *)ptr) = (uint16_t) ((hi & 0xf800) | 703 (s << 10) | imm10); 704 (*(uint16_t *)(ptr+2)) = (uint16_t) ((lo & 0xc000) | 705 (j1 << 13) | blx_bit | (j2 << 11) | 706 imm11); 707 } 708 break; 709 case R_ARM_MOVT_ABS: 710 case R_ARM_MOVW_ABS_NC: 711 { 712 int x, imm4, imm12; 713 if (type == R_ARM_MOVT_ABS) 714 val >>= 16; 715 imm12 = val & 0xfff; 716 imm4 = (val >> 12) & 0xf; 717 x = (imm4 << 16) | imm12; 718 if (type == R_ARM_THM_MOVT_ABS) 719 *(int *)ptr |= x; 720 else 721 *(int *)ptr += x; 722 } 723 break; 724 case R_ARM_THM_MOVT_ABS: 725 case R_ARM_THM_MOVW_ABS_NC: 726 { 727 int x, i, imm4, imm3, imm8; 728 if (type == R_ARM_THM_MOVT_ABS) 729 val >>= 16; 730 imm8 = val & 0xff; 731 imm3 = (val >> 8) & 0x7; 732 i = (val >> 11) & 1; 733 imm4 = (val >> 12) & 0xf; 734 x = (imm3 << 28) | (imm8 << 16) | (i << 10) | imm4; 735 if (type == R_ARM_THM_MOVT_ABS) 736 *(int *)ptr |= x; 737 else 738 *(int *)ptr += x; 739 } 740 break; 741 case R_ARM_PREL31: 742 { 743 int x; 744 x = (*(int *)ptr) & 0x7fffffff; 745 (*(int *)ptr) &= 0x80000000; 746 x = (x * 2) / 2; 747 x += val - addr; 748 if((x^(x>>1))&0x40000000) 749 tcc_error("can't relocate value at %x",addr); 750 (*(int *)ptr) |= x & 0x7fffffff; 751 } 752 case R_ARM_ABS32: 753 *(int *)ptr += val; 754 break; 755 case R_ARM_REL32: 756 *(int *)ptr += val - addr; 757 break; 758 case R_ARM_BASE_PREL: 759 *(int *)ptr += s1->got->sh_addr - addr; 760 break; 761 case R_ARM_GOTOFF32: 762 *(int *)ptr += val - s1->got->sh_addr; 763 break; 764 case R_ARM_GOT_BREL: 765 /* we load the got offset */ 766 *(int *)ptr += s1->sym_attrs[sym_index].got_offset; 767 break; 768 case R_ARM_COPY: 769 break; 770 case R_ARM_V4BX: 771 /* trade Thumb support for ARMv4 support */ 772 if ((0x0ffffff0 & *(int*)ptr) == 0x012FFF10) 773 *(int*)ptr ^= 0xE12FFF10 ^ 0xE1A0F000; /* BX Rm -> MOV PC, Rm */ 774 break; 775 default: 776 fprintf(stderr,"FIXME: handle reloc type %x at %x [%p] to %x\n", 777 type, (unsigned)addr, ptr, (unsigned)val); 778 break; 779 #elif defined(TCC_TARGET_C67) 780 case R_C60_32: 781 *(int *)ptr += val; 782 break; 783 case R_C60LO16: 784 { 785 uint32_t orig; 786 787 /* put the low 16 bits of the absolute address */ 788 // add to what is already there 789 790 orig = ((*(int *)(ptr )) >> 7) & 0xffff; 791 orig |= (((*(int *)(ptr+4)) >> 7) & 0xffff) << 16; 792 793 //patch both at once - assumes always in pairs Low - High 794 795 *(int *) ptr = (*(int *) ptr & (~(0xffff << 7)) ) | (((val+orig) & 0xffff) << 7); 796 *(int *)(ptr+4) = (*(int *)(ptr+4) & (~(0xffff << 7)) ) | ((((val+orig)>>16) & 0xffff) << 7); 797 } 798 break; 799 case R_C60HI16: 800 break; 801 default: 802 fprintf(stderr,"FIXME: handle reloc type %x at %x [%p] to %x\n", 803 type, (unsigned)addr, ptr, (unsigned)val); 804 break; 805 #elif defined(TCC_TARGET_X86_64) 806 case R_X86_64_64: 807 if (s1->output_type == TCC_OUTPUT_DLL) { 808 qrel->r_info = ELFW(R_INFO)(0, R_X86_64_RELATIVE); 809 qrel->r_addend = *(long long *)ptr + val; 810 qrel++; 811 } 812 *(long long *)ptr += val; 813 break; 814 case R_X86_64_32: 815 case R_X86_64_32S: 816 if (s1->output_type == TCC_OUTPUT_DLL) { 817 /* XXX: this logic may depend on TCC's codegen 818 now TCC uses R_X86_64_32 even for a 64bit pointer */ 819 qrel->r_info = ELFW(R_INFO)(0, R_X86_64_RELATIVE); 820 qrel->r_addend = *(int *)ptr + val; 821 qrel++; 822 } 823 *(int *)ptr += val; 824 break; 825 826 case R_X86_64_PC32: 827 if (s1->output_type == TCC_OUTPUT_DLL) { 828 /* DLL relocation */ 829 esym_index = s1->symtab_to_dynsym[sym_index]; 830 if (esym_index) { 831 qrel->r_offset = rel->r_offset; 832 qrel->r_info = ELFW(R_INFO)(esym_index, R_X86_64_PC32); 833 qrel->r_addend = *(int *)ptr; 834 qrel++; 835 break; 836 } 837 } 838 /* fall through */ 839 case R_X86_64_PLT32: { 840 long long diff; 841 diff = (long long)val - addr; 842 if (diff <= -2147483647 || diff > 2147483647) { 843 #ifdef TCC_HAS_RUNTIME_PLTGOT 844 /* XXX: naive support for over 32bit jump */ 845 if (s1->output_type == TCC_OUTPUT_MEMORY) { 846 val = (add_jmp_table(s1, val - rel->r_addend) + 847 rel->r_addend); 848 diff = val - addr; 849 } 850 #endif 851 if (diff <= -2147483647 || diff > 2147483647) { 852 tcc_error("internal error: relocation failed"); 853 } 854 } 855 *(int *)ptr += diff; 856 } 857 break; 858 case R_X86_64_GLOB_DAT: 859 case R_X86_64_JUMP_SLOT: 860 /* They don't need addend */ 861 *(int *)ptr = val - rel->r_addend; 862 break; 863 case R_X86_64_GOTPCREL: 864 #ifdef TCC_HAS_RUNTIME_PLTGOT 865 if (s1->output_type == TCC_OUTPUT_MEMORY) { 866 val = add_got_table(s1, val - rel->r_addend) + rel->r_addend; 867 *(int *)ptr += val - addr; 868 break; 869 } 870 #endif 871 *(int *)ptr += (s1->got->sh_addr - addr + 872 s1->sym_attrs[sym_index].got_offset - 4); 873 break; 874 case R_X86_64_GOTTPOFF: 875 *(int *)ptr += val - s1->got->sh_addr; 876 break; 877 case R_X86_64_GOT32: 878 /* we load the got offset */ 879 *(int *)ptr += s1->sym_attrs[sym_index].got_offset; 880 break; 881 #elif defined(TCC_TARGET_IL) 882 #else 883 #error unsupported processor 884 #endif 885 } 886 } 887 /* if the relocation is allocated, we change its symbol table */ 888 if (sr->sh_flags & SHF_ALLOC) 889 sr->link = s1->dynsym; 890 } 891 892 /* relocate relocation table in 'sr' */ 893 static void relocate_rel(TCCState *s1, Section *sr) 894 { 895 Section *s; 896 ElfW_Rel *rel, *rel_end; 897 898 s = s1->sections[sr->sh_info]; 899 rel_end = (ElfW_Rel *)(sr->data + sr->data_offset); 900 for(rel = (ElfW_Rel *)sr->data; 901 rel < rel_end; 902 rel++) { 903 rel->r_offset += s->sh_addr; 904 } 905 } 906 907 /* count the number of dynamic relocations so that we can reserve 908 their space */ 909 static int prepare_dynamic_rel(TCCState *s1, Section *sr) 910 { 911 ElfW_Rel *rel, *rel_end; 912 int sym_index, esym_index, type, count; 913 914 count = 0; 915 rel_end = (ElfW_Rel *)(sr->data + sr->data_offset); 916 for(rel = (ElfW_Rel *)sr->data; rel < rel_end; rel++) { 917 sym_index = ELFW(R_SYM)(rel->r_info); 918 type = ELFW(R_TYPE)(rel->r_info); 919 switch(type) { 920 #if defined(TCC_TARGET_I386) 921 case R_386_32: 922 #elif defined(TCC_TARGET_X86_64) 923 case R_X86_64_32: 924 case R_X86_64_32S: 925 case R_X86_64_64: 926 #endif 927 count++; 928 break; 929 #if defined(TCC_TARGET_I386) 930 case R_386_PC32: 931 #elif defined(TCC_TARGET_X86_64) 932 case R_X86_64_PC32: 933 #endif 934 esym_index = s1->symtab_to_dynsym[sym_index]; 935 if (esym_index) 936 count++; 937 break; 938 default: 939 break; 940 } 941 } 942 if (count) { 943 /* allocate the section */ 944 sr->sh_flags |= SHF_ALLOC; 945 sr->sh_size = count * sizeof(ElfW_Rel); 946 } 947 return count; 948 } 949 950 static struct sym_attr *alloc_sym_attr(TCCState *s1, int index) 688 ST_FUNC struct sym_attr *get_sym_attr(TCCState *s1, int index, int alloc) 951 689 { 952 690 int n; … … 954 692 955 693 if (index >= s1->nb_sym_attrs) { 694 if (!alloc) 695 return s1->sym_attrs; 956 696 /* find immediately bigger power of 2 and reallocate array */ 957 697 n = 1; … … 967 707 } 968 708 969 /* XXX: suppress that */ 970 static void put32(unsigned char *p, uint32_t val) 971 { 972 p[0] = val; 973 p[1] = val >> 8; 974 p[2] = val >> 16; 975 p[3] = val >> 24; 976 } 977 978 #if defined(TCC_TARGET_I386) || defined(TCC_TARGET_ARM) || \ 979 defined(TCC_TARGET_X86_64) 980 static uint32_t get32(unsigned char *p) 981 { 982 return p[0] | (p[1] << 8) | (p[2] << 16) | (p[3] << 24); 983 } 984 #endif 709 /* Browse each elem of type <type> in section <sec> starting at elem <startoff> 710 using variable <elem> */ 711 #define for_each_elem(sec, startoff, elem, type) \ 712 for (elem = (type *) sec->data + startoff; \ 713 elem < (type *) (sec->data + sec->data_offset); elem++) 714 715 /* In an ELF file symbol table, the local symbols must appear below 716 the global and weak ones. Since TCC cannot sort it while generating 717 the code, we must do it after. All the relocation tables are also 718 modified to take into account the symbol table sorting */ 719 static void sort_syms(TCCState *s1, Section *s) 720 { 721 int *old_to_new_syms; 722 ElfW(Sym) *new_syms; 723 int nb_syms, i; 724 ElfW(Sym) *p, *q; 725 ElfW_Rel *rel; 726 Section *sr; 727 int type, sym_index; 728 729 nb_syms = s->data_offset / sizeof(ElfW(Sym)); 730 new_syms = tcc_malloc(nb_syms * sizeof(ElfW(Sym))); 731 old_to_new_syms = tcc_malloc(nb_syms * sizeof(int)); 732 733 /* first pass for local symbols */ 734 p = (ElfW(Sym) *)s->data; 735 q = new_syms; 736 for(i = 0; i < nb_syms; i++) { 737 if (ELFW(ST_BIND)(p->st_info) == STB_LOCAL) { 738 old_to_new_syms[i] = q - new_syms; 739 *q++ = *p; 740 } 741 p++; 742 } 743 /* save the number of local symbols in section header */ 744 if( s->sh_size ) /* this 'if' makes IDA happy */ 745 s->sh_info = q - new_syms; 746 747 /* then second pass for non local symbols */ 748 p = (ElfW(Sym) *)s->data; 749 for(i = 0; i < nb_syms; i++) { 750 if (ELFW(ST_BIND)(p->st_info) != STB_LOCAL) { 751 old_to_new_syms[i] = q - new_syms; 752 *q++ = *p; 753 } 754 p++; 755 } 756 757 /* we copy the new symbols to the old */ 758 memcpy(s->data, new_syms, nb_syms * sizeof(ElfW(Sym))); 759 tcc_free(new_syms); 760 761 /* now we modify all the relocations */ 762 for(i = 1; i < s1->nb_sections; i++) { 763 sr = s1->sections[i]; 764 if (sr->sh_type == SHT_RELX && sr->link == s) { 765 for_each_elem(sr, 0, rel, ElfW_Rel) { 766 sym_index = ELFW(R_SYM)(rel->r_info); 767 type = ELFW(R_TYPE)(rel->r_info); 768 sym_index = old_to_new_syms[sym_index]; 769 rel->r_info = ELFW(R_INFO)(sym_index, type); 770 } 771 } 772 } 773 774 tcc_free(old_to_new_syms); 775 } 776 777 /* relocate symbol table, resolve undefined symbols if do_resolve is 778 true and output error if undefined symbol. */ 779 ST_FUNC void relocate_syms(TCCState *s1, Section *symtab, int do_resolve) 780 { 781 ElfW(Sym) *sym; 782 int sym_bind, sh_num; 783 const char *name; 784 785 for_each_elem(symtab, 1, sym, ElfW(Sym)) { 786 sh_num = sym->st_shndx; 787 if (sh_num == SHN_UNDEF) { 788 name = (char *) s1->symtab->link->data + sym->st_name; 789 /* Use ld.so to resolve symbol for us (for tcc -run) */ 790 if (do_resolve) { 791 #if defined TCC_IS_NATIVE && !defined TCC_TARGET_PE 792 void *addr = dlsym(RTLD_DEFAULT, name); 793 if (addr) { 794 sym->st_value = (addr_t) addr; 795 #ifdef DEBUG_RELOC 796 printf ("relocate_sym: %s -> 0x%lx\n", name, sym->st_value); 797 #endif 798 goto found; 799 } 800 #endif 801 /* if dynamic symbol exist, it will be used in relocate_section */ 802 } else if (s1->dynsym && find_elf_sym(s1->dynsym, name)) 803 goto found; 804 /* XXX: _fp_hw seems to be part of the ABI, so we ignore 805 it */ 806 if (!strcmp(name, "_fp_hw")) 807 goto found; 808 /* only weak symbols are accepted to be undefined. Their 809 value is zero */ 810 sym_bind = ELFW(ST_BIND)(sym->st_info); 811 if (sym_bind == STB_WEAK) 812 sym->st_value = 0; 813 else 814 tcc_error_noabort("undefined symbol '%s'", name); 815 } else if (sh_num < SHN_LORESERVE) { 816 /* add section base */ 817 sym->st_value += s1->sections[sym->st_shndx]->sh_addr; 818 } 819 found: ; 820 } 821 } 822 823 /* relocate a given section (CPU dependent) by applying the relocations 824 in the associated relocation section */ 825 ST_FUNC void relocate_section(TCCState *s1, Section *s) 826 { 827 Section *sr = s->reloc; 828 ElfW_Rel *rel; 829 ElfW(Sym) *sym; 830 int type, sym_index; 831 unsigned char *ptr; 832 addr_t tgt, addr; 833 834 relocate_init(sr); 835 836 for_each_elem(sr, 0, rel, ElfW_Rel) { 837 ptr = s->data + rel->r_offset; 838 sym_index = ELFW(R_SYM)(rel->r_info); 839 sym = &((ElfW(Sym) *)symtab_section->data)[sym_index]; 840 type = ELFW(R_TYPE)(rel->r_info); 841 tgt = sym->st_value; 842 #if SHT_RELX == SHT_RELA 843 tgt += rel->r_addend; 844 #endif 845 addr = s->sh_addr + rel->r_offset; 846 relocate(s1, rel, type, ptr, addr, tgt); 847 } 848 /* if the relocation is allocated, we change its symbol table */ 849 if (sr->sh_flags & SHF_ALLOC) 850 sr->link = s1->dynsym; 851 } 852 853 /* relocate relocation table in 'sr' */ 854 static void relocate_rel(TCCState *s1, Section *sr) 855 { 856 Section *s; 857 ElfW_Rel *rel; 858 859 s = s1->sections[sr->sh_info]; 860 for_each_elem(sr, 0, rel, ElfW_Rel) 861 rel->r_offset += s->sh_addr; 862 } 863 864 /* count the number of dynamic relocations so that we can reserve 865 their space */ 866 static int prepare_dynamic_rel(TCCState *s1, Section *sr) 867 { 868 ElfW_Rel *rel; 869 int sym_index, type, count; 870 871 count = 0; 872 for_each_elem(sr, 0, rel, ElfW_Rel) { 873 sym_index = ELFW(R_SYM)(rel->r_info); 874 type = ELFW(R_TYPE)(rel->r_info); 875 switch(type) { 876 #if defined(TCC_TARGET_I386) 877 case R_386_32: 878 if (!get_sym_attr(s1, sym_index, 0)->dyn_index 879 && ((ElfW(Sym)*)symtab_section->data + sym_index)->st_shndx == SHN_UNDEF) { 880 /* don't fixup unresolved (weak) symbols */ 881 rel->r_info = ELFW(R_INFO)(sym_index, R_386_RELATIVE); 882 break; 883 } 884 #elif defined(TCC_TARGET_X86_64) 885 case R_X86_64_32: 886 case R_X86_64_32S: 887 case R_X86_64_64: 888 #endif 889 count++; 890 break; 891 #if defined(TCC_TARGET_I386) 892 case R_386_PC32: 893 #elif defined(TCC_TARGET_X86_64) 894 case R_X86_64_PC32: 895 #endif 896 if (get_sym_attr(s1, sym_index, 0)->dyn_index) 897 count++; 898 break; 899 default: 900 break; 901 } 902 } 903 if (count) { 904 /* allocate the section */ 905 sr->sh_flags |= SHF_ALLOC; 906 sr->sh_size = count * sizeof(ElfW_Rel); 907 } 908 return count; 909 } 985 910 986 911 static void build_got(TCCState *s1) 987 912 { 988 unsigned char *ptr;989 990 913 /* if no got, then create it */ 991 914 s1->got = new_section(s1, ".got", SHT_PROGBITS, SHF_ALLOC | SHF_WRITE); 992 915 s1->got->sh_entsize = 4; 993 add_elf_sym(symtab_section, 0, 4, ELFW(ST_INFO)(STB_GLOBAL, STT_OBJECT),916 set_elf_sym(symtab_section, 0, 4, ELFW(ST_INFO)(STB_GLOBAL, STT_OBJECT), 994 917 0, s1->got->sh_num, "_GLOBAL_OFFSET_TABLE_"); 995 ptr = section_ptr_add(s1->got, 3 * PTR_SIZE); 996 #if PTR_SIZE == 4 997 /* keep space for _DYNAMIC pointer, if present */ 998 put32(ptr, 0); 999 /* two dummy got entries */ 1000 put32(ptr + 4, 0); 1001 put32(ptr + 8, 0); 1002 #else 1003 /* keep space for _DYNAMIC pointer, if present */ 1004 put32(ptr, 0); 1005 put32(ptr + 4, 0); 1006 /* two dummy got entries */ 1007 put32(ptr + 8, 0); 1008 put32(ptr + 12, 0); 1009 put32(ptr + 16, 0); 1010 put32(ptr + 20, 0); 1011 #endif 1012 } 1013 1014 /* put a got entry corresponding to a symbol in symtab_section. 'size' 1015 and 'info' can be modifed if more precise info comes from the DLL */ 1016 static void put_got_entry(TCCState *s1, 1017 int reloc_type, unsigned long size, int info, 1018 int sym_index) 1019 { 1020 int index; 918 /* keep space for _DYNAMIC pointer and two dummy got entries */ 919 section_ptr_add(s1->got, 3 * PTR_SIZE); 920 } 921 922 /* Create a GOT and (for function call) a PLT entry corresponding to a symbol 923 in s1->symtab. When creating the dynamic symbol table entry for the GOT 924 relocation, use 'size' and 'info' for the corresponding symbol metadata. 925 Returns the offset of the GOT or (if any) PLT entry. */ 926 static struct sym_attr * put_got_entry(TCCState *s1, int dyn_reloc_type, 927 unsigned long size, 928 int info, int sym_index) 929 { 930 int need_plt_entry; 1021 931 const char *name; 1022 932 ElfW(Sym) *sym; 1023 unsigned long offset; 1024 int *ptr; 1025 1026 if (!s1->got) 1027 build_got(s1); 1028 1029 /* if a got entry already exists for that symbol, no need to add one */ 1030 if (sym_index < s1->nb_sym_attrs && 1031 s1->sym_attrs[sym_index].got_offset) 1032 return; 1033 1034 alloc_sym_attr(s1, sym_index)->got_offset = s1->got->data_offset; 933 struct sym_attr *attr; 934 unsigned got_offset; 935 char plt_name[100]; 936 int len; 937 938 need_plt_entry = (dyn_reloc_type == R_JMP_SLOT); 939 attr = get_sym_attr(s1, sym_index, 1); 940 941 /* In case a function is both called and its address taken 2 GOT entries 942 are created, one for taking the address (GOT) and the other for the PLT 943 entry (PLTGOT). */ 944 if (need_plt_entry ? attr->plt_offset : attr->got_offset) 945 return attr; 946 947 /* create the GOT entry */ 948 got_offset = s1->got->data_offset; 949 section_ptr_add(s1->got, PTR_SIZE); 950 951 /* Create the GOT relocation that will insert the address of the object or 952 function of interest in the GOT entry. This is a static relocation for 953 memory output (dlsym will give us the address of symbols) and dynamic 954 relocation otherwise (executable and DLLs). The relocation should be 955 done lazily for GOT entry with *_JUMP_SLOT relocation type (the one 956 associated to a PLT entry) but is currently done at load time for an 957 unknown reason. */ 958 959 sym = &((ElfW(Sym) *) symtab_section->data)[sym_index]; 960 name = (char *) symtab_section->link->data + sym->st_name; 1035 961 1036 962 if (s1->dynsym) { 1037 sym = &((ElfW(Sym) *)symtab_section->data)[sym_index]; 1038 name = symtab_section->link->data + sym->st_name; 1039 offset = sym->st_value; 1040 #if defined(TCC_TARGET_I386) || defined(TCC_TARGET_X86_64) 1041 if (reloc_type == 1042 #ifdef TCC_TARGET_X86_64 1043 R_X86_64_JUMP_SLOT 1044 #else 1045 R_386_JMP_SLOT 1046 #endif 1047 ) { 1048 Section *plt; 1049 uint8_t *p; 1050 int modrm; 1051 1052 #if defined(TCC_OUTPUT_DLL_WITH_PLT) 1053 modrm = 0x25; 1054 #else 1055 /* if we build a DLL, we add a %ebx offset */ 1056 if (s1->output_type == TCC_OUTPUT_DLL) 1057 modrm = 0xa3; 1058 else 1059 modrm = 0x25; 1060 #endif 1061 1062 /* add a PLT entry */ 1063 plt = s1->plt; 1064 if (plt->data_offset == 0) { 1065 /* first plt entry */ 1066 p = section_ptr_add(plt, 16); 1067 p[0] = 0xff; /* pushl got + PTR_SIZE */ 1068 p[1] = modrm + 0x10; 1069 put32(p + 2, PTR_SIZE); 1070 p[6] = 0xff; /* jmp *(got + PTR_SIZE * 2) */ 1071 p[7] = modrm; 1072 put32(p + 8, PTR_SIZE * 2); 1073 } 1074 1075 p = section_ptr_add(plt, 16); 1076 p[0] = 0xff; /* jmp *(got + x) */ 1077 p[1] = modrm; 1078 put32(p + 2, s1->got->data_offset); 1079 p[6] = 0x68; /* push $xxx */ 1080 put32(p + 7, (plt->data_offset - 32) >> 1); 1081 p[11] = 0xe9; /* jmp plt_start */ 1082 put32(p + 12, -(plt->data_offset)); 1083 1084 /* the symbol is modified so that it will be relocated to 1085 the PLT */ 1086 #if !defined(TCC_OUTPUT_DLL_WITH_PLT) 1087 if (s1->output_type == TCC_OUTPUT_EXE) 1088 #endif 1089 offset = plt->data_offset - 16; 1090 } 1091 #elif defined(TCC_TARGET_ARM) 1092 if (reloc_type == R_ARM_JUMP_SLOT) { 1093 Section *plt; 1094 uint8_t *p; 1095 1096 /* if we build a DLL, we add a %ebx offset */ 1097 if (s1->output_type == TCC_OUTPUT_DLL) 1098 tcc_error("DLLs unimplemented!"); 1099 1100 /* add a PLT entry */ 1101 plt = s1->plt; 1102 if (plt->data_offset == 0) { 1103 /* first plt entry */ 1104 p = section_ptr_add(plt, 16); 1105 put32(p , 0xe52de004); 1106 put32(p + 4, 0xe59fe010); 1107 put32(p + 8, 0xe08fe00e); 1108 put32(p + 12, 0xe5bef008); 1109 } 1110 1111 if (s1->sym_attrs[sym_index].plt_thumb_stub) { 1112 p = section_ptr_add(plt, 20); 1113 put32(p , 0x4778); // bx pc 1114 put32(p+2, 0x46c0); // nop 1115 p += 4; 1116 } else 1117 p = section_ptr_add(plt, 16); 1118 put32(p , 0xe59fc004); // ldr ip, [pc, #4] // offset in GOT 1119 put32(p+4, 0xe08fc00c); // add ip, pc, ip // absolute address or offset 1120 put32(p+8, 0xe59cf000); // ldr pc, [ip] // load absolute address or load offset 1121 put32(p+12, s1->got->data_offset); 1122 1123 /* the symbol is modified so that it will be relocated to 1124 the PLT */ 1125 if (s1->output_type == TCC_OUTPUT_EXE) 1126 offset = plt->data_offset - 16; 1127 } 1128 #elif defined(TCC_TARGET_C67) 1129 tcc_error("C67 got not implemented"); 1130 #elif defined(TCC_TARGET_IL) 1131 tcc_error("IL got not implemented"); 1132 #else 1133 #error unsupported CPU 1134 #endif 1135 index = put_elf_sym(s1->dynsym, offset, 1136 size, info, 0, sym->st_shndx, name); 1137 /* put a got entry */ 1138 put_elf_reloc(s1->dynsym, s1->got, 1139 s1->got->data_offset, 1140 reloc_type, index); 1141 } 1142 ptr = section_ptr_add(s1->got, PTR_SIZE); 1143 *ptr = 0; 963 if (ELFW(ST_BIND)(sym->st_info) == STB_LOCAL) { 964 /* Hack alarm. We don't want to emit dynamic symbols 965 and symbol based relocs for STB_LOCAL symbols, but rather 966 want to resolve them directly. At this point the symbol 967 values aren't final yet, so we must defer this. We will later 968 have to create a RELATIVE reloc anyway, so we misuse the 969 relocation slot to smuggle the symbol reference until 970 fill_local_got_entries. Not that the sym_index is 971 relative to symtab_section, not s1->dynsym! Nevertheless 972 we use s1->dyn_sym so that if this is the first call 973 that got->reloc is correctly created. Also note that 974 RELATIVE relocs are not normally created for the .got, 975 so the types serves as a marker for later (and is retained 976 also for the final output, which is okay because then the 977 got is just normal data). */ 978 put_elf_reloc(s1->dynsym, s1->got, got_offset, R_RELATIVE, 979 sym_index); 980 } else { 981 if (0 == attr->dyn_index) 982 attr->dyn_index = set_elf_sym(s1->dynsym, sym->st_value, size, 983 info, 0, sym->st_shndx, name); 984 put_elf_reloc(s1->dynsym, s1->got, got_offset, dyn_reloc_type, 985 attr->dyn_index); 986 } 987 } else { 988 put_elf_reloc(symtab_section, s1->got, got_offset, dyn_reloc_type, 989 sym_index); 990 } 991 992 if (need_plt_entry) { 993 if (!s1->plt) { 994 s1->plt = new_section(s1, ".plt", SHT_PROGBITS, 995 SHF_ALLOC | SHF_EXECINSTR); 996 s1->plt->sh_entsize = 4; 997 } 998 999 attr->plt_offset = create_plt_entry(s1, got_offset, attr); 1000 1001 /* create a symbol 'sym@plt' for the PLT jump vector */ 1002 len = strlen(name); 1003 if (len > sizeof plt_name - 5) 1004 len = sizeof plt_name - 5; 1005 memcpy(plt_name, name, len); 1006 strcpy(plt_name + len, "@plt"); 1007 attr->plt_sym = put_elf_sym(s1->symtab, attr->plt_offset, sym->st_size, 1008 ELFW(ST_INFO)(STB_GLOBAL, STT_FUNC), 0, s1->plt->sh_num, plt_name); 1009 1010 } else { 1011 attr->got_offset = got_offset; 1012 } 1013 1014 return attr; 1144 1015 } 1145 1016 … … 1148 1019 { 1149 1020 Section *s; 1150 ElfW_Rel *rel , *rel_end;1021 ElfW_Rel *rel; 1151 1022 ElfW(Sym) *sym; 1152 int i, type, reloc_type, sym_index; 1023 int i, type, gotplt_entry, reloc_type, sym_index; 1024 struct sym_attr *attr; 1153 1025 1154 1026 for(i = 1; i < s1->nb_sections; i++) { … … 1159 1031 if (s->link != symtab_section) 1160 1032 continue; 1161 rel_end = (ElfW_Rel *)(s->data + s->data_offset); 1162 for(rel = (ElfW_Rel *)s->data; 1163 rel < rel_end; 1164 rel++) { 1033 for_each_elem(s, 0, rel, ElfW_Rel) { 1165 1034 type = ELFW(R_TYPE)(rel->r_info); 1166 switch(type) { 1167 #if defined(TCC_TARGET_I386) 1168 case R_386_GOT32: 1169 case R_386_GOTOFF: 1170 case R_386_GOTPC: 1171 case R_386_PLT32: 1172 if (!s1->got) 1173 build_got(s1); 1174 if (type == R_386_GOT32 || type == R_386_PLT32) { 1175 sym_index = ELFW(R_SYM)(rel->r_info); 1176 sym = &((ElfW(Sym) *)symtab_section->data)[sym_index]; 1177 /* look at the symbol got offset. If none, then add one */ 1178 if (type == R_386_GOT32) 1179 reloc_type = R_386_GLOB_DAT; 1180 else 1181 reloc_type = R_386_JMP_SLOT; 1182 put_got_entry(s1, reloc_type, sym->st_size, sym->st_info, 1183 sym_index); 1184 } 1185 break; 1186 #elif defined(TCC_TARGET_ARM) 1187 case R_ARM_GOT_BREL: 1188 case R_ARM_GOTOFF32: 1189 case R_ARM_BASE_PREL: 1190 case R_ARM_PLT32: 1191 if (!s1->got) 1192 build_got(s1); 1193 if (type == R_ARM_GOT_BREL || type == R_ARM_PLT32) { 1194 sym_index = ELFW(R_SYM)(rel->r_info); 1195 sym = &((ElfW(Sym) *)symtab_section->data)[sym_index]; 1196 /* look at the symbol got offset. If none, then add one */ 1197 if (type == R_ARM_GOT_BREL) 1198 reloc_type = R_ARM_GLOB_DAT; 1199 else 1200 reloc_type = R_ARM_JUMP_SLOT; 1201 put_got_entry(s1, reloc_type, sym->st_size, sym->st_info, 1202 sym_index); 1203 } 1204 break; 1205 #elif defined(TCC_TARGET_C67) 1206 case R_C60_GOT32: 1207 case R_C60_GOTOFF: 1208 case R_C60_GOTPC: 1209 case R_C60_PLT32: 1210 if (!s1->got) 1211 build_got(s1); 1212 if (type == R_C60_GOT32 || type == R_C60_PLT32) { 1213 sym_index = ELFW(R_SYM)(rel->r_info); 1214 sym = &((ElfW(Sym) *)symtab_section->data)[sym_index]; 1215 /* look at the symbol got offset. If none, then add one */ 1216 if (type == R_C60_GOT32) 1217 reloc_type = R_C60_GLOB_DAT; 1218 else 1219 reloc_type = R_C60_JMP_SLOT; 1220 put_got_entry(s1, reloc_type, sym->st_size, sym->st_info, 1221 sym_index); 1222 } 1223 break; 1224 #elif defined(TCC_TARGET_X86_64) 1225 case R_X86_64_GOT32: 1226 case R_X86_64_GOTTPOFF: 1227 case R_X86_64_GOTPCREL: 1228 case R_X86_64_PLT32: 1229 if (!s1->got) 1230 build_got(s1); 1231 if (type == R_X86_64_GOT32 || type == R_X86_64_GOTPCREL || 1232 type == R_X86_64_PLT32) { 1233 sym_index = ELFW(R_SYM)(rel->r_info); 1234 sym = &((ElfW(Sym) *)symtab_section->data)[sym_index]; 1235 /* look at the symbol got offset. If none, then add one */ 1236 if (type == R_X86_64_GOT32 || type == R_X86_64_GOTPCREL) 1237 reloc_type = R_X86_64_GLOB_DAT; 1238 else 1239 reloc_type = R_X86_64_JUMP_SLOT; 1240 put_got_entry(s1, reloc_type, sym->st_size, sym->st_info, 1241 sym_index); 1242 } 1243 break; 1244 #elif defined(TCC_TARGET_IL) 1245 #else 1246 #error unsupported CPU 1247 #endif 1248 default: 1249 break; 1250 } 1251 } 1252 } 1253 } 1254 1255 ST_FUNC Section *new_symtab(TCCState *s1, 1256 const char *symtab_name, int sh_type, int sh_flags, 1257 const char *strtab_name, 1258 const char *hash_name, int hash_sh_flags) 1259 { 1260 Section *symtab, *strtab, *hash; 1261 int *ptr, nb_buckets; 1262 1263 symtab = new_section(s1, symtab_name, sh_type, sh_flags); 1264 symtab->sh_entsize = sizeof(ElfW(Sym)); 1265 strtab = new_section(s1, strtab_name, SHT_STRTAB, sh_flags); 1266 put_elf_str(strtab, ""); 1267 symtab->link = strtab; 1268 put_elf_sym(symtab, 0, 0, 0, 0, 0, NULL); 1269 1270 nb_buckets = 1; 1271 1272 hash = new_section(s1, hash_name, SHT_HASH, hash_sh_flags); 1273 hash->sh_entsize = sizeof(int); 1274 symtab->hash = hash; 1275 hash->link = symtab; 1276 1277 ptr = section_ptr_add(hash, (2 + nb_buckets + 1) * sizeof(int)); 1278 ptr[0] = nb_buckets; 1279 ptr[1] = 1; 1280 memset(ptr + 2, 0, (nb_buckets + 1) * sizeof(int)); 1281 return symtab; 1035 gotplt_entry = gotplt_entry_type(type); 1036 sym_index = ELFW(R_SYM)(rel->r_info); 1037 sym = &((ElfW(Sym) *)symtab_section->data)[sym_index]; 1038 1039 if (gotplt_entry == NO_GOTPLT_ENTRY) { 1040 continue; 1041 } 1042 1043 /* Automatically create PLT/GOT [entry] if it is an undefined 1044 reference (resolved at runtime), or the symbol is absolute, 1045 probably created by tcc_add_symbol, and thus on 64-bit 1046 targets might be too far from application code. */ 1047 if (gotplt_entry == AUTO_GOTPLT_ENTRY) { 1048 if (sym->st_shndx == SHN_UNDEF) { 1049 ElfW(Sym) *esym; 1050 int dynindex; 1051 if (s1->output_type == TCC_OUTPUT_DLL && ! PCRELATIVE_DLLPLT) 1052 continue; 1053 /* Relocations for UNDEF symbols would normally need 1054 to be transferred into the executable or shared object. 1055 If that were done AUTO_GOTPLT_ENTRY wouldn't exist. 1056 But TCC doesn't do that (at least for exes), so we 1057 need to resolve all such relocs locally. And that 1058 means PLT slots for functions in DLLs and COPY relocs for 1059 data symbols. COPY relocs were generated in 1060 bind_exe_dynsyms (and the symbol adjusted to be defined), 1061 and for functions we were generated a dynamic symbol 1062 of function type. */ 1063 if (s1->dynsym) { 1064 /* dynsym isn't set for -run :-/ */ 1065 dynindex = get_sym_attr(s1, sym_index, 0)->dyn_index; 1066 esym = (ElfW(Sym) *)s1->dynsym->data + dynindex; 1067 if (dynindex 1068 && (ELFW(ST_TYPE)(esym->st_info) == STT_FUNC 1069 || (ELFW(ST_TYPE)(esym->st_info) == STT_NOTYPE 1070 && ELFW(ST_TYPE)(sym->st_info) == STT_FUNC))) 1071 goto jmp_slot; 1072 } 1073 } else if (!(sym->st_shndx == SHN_ABS 1074 #ifndef TCC_TARGET_ARM 1075 && PTR_SIZE == 8 1076 #endif 1077 )) 1078 continue; 1079 } 1080 1081 #ifdef TCC_TARGET_X86_64 1082 if ((type == R_X86_64_PLT32 || type == R_X86_64_PC32) && 1083 (ELFW(ST_VISIBILITY)(sym->st_other) != STV_DEFAULT || 1084 ELFW(ST_BIND)(sym->st_info) == STB_LOCAL)) { 1085 rel->r_info = ELFW(R_INFO)(sym_index, R_X86_64_PC32); 1086 continue; 1087 } 1088 #endif 1089 if (code_reloc(type)) { 1090 jmp_slot: 1091 reloc_type = R_JMP_SLOT; 1092 } else 1093 reloc_type = R_GLOB_DAT; 1094 1095 if (!s1->got) 1096 build_got(s1); 1097 1098 if (gotplt_entry == BUILD_GOT_ONLY) 1099 continue; 1100 1101 attr = put_got_entry(s1, reloc_type, sym->st_size, sym->st_info, 1102 sym_index); 1103 1104 if (reloc_type == R_JMP_SLOT) 1105 rel->r_info = ELFW(R_INFO)(attr->plt_sym, type); 1106 } 1107 } 1282 1108 } 1283 1109 … … 1291 1117 } 1292 1118 1119 #ifndef TCC_TARGET_PE 1293 1120 static void add_init_array_defines(TCCState *s1, const char *section_name) 1294 1121 { … … 1297 1124 char sym_start[1024]; 1298 1125 char sym_end[1024]; 1299 1126 1300 1127 snprintf(sym_start, sizeof(sym_start), "__%s_start", section_name + 1); 1301 1128 snprintf(sym_end, sizeof(sym_end), "__%s_end", section_name + 1); … … 1309 1136 } 1310 1137 1311 add_elf_sym(symtab_section,1138 set_elf_sym(symtab_section, 1312 1139 0, 0, 1313 1140 ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0, 1314 1141 s->sh_num, sym_start); 1315 add_elf_sym(symtab_section,1142 set_elf_sym(symtab_section, 1316 1143 end_offset, 0, 1317 1144 ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0, 1318 1145 s->sh_num, sym_end); 1319 1146 } 1320 1321 ST_FUNC void tcc_add_bcheck(TCCState *s1) 1322 { 1323 #ifdef CONFIG_TCC_BCHECK 1324 unsigned long *ptr; 1325 Section *init_section; 1326 unsigned char *pinit; 1327 int sym_index; 1328 1329 if (0 == s1->do_bounds_check) 1330 return; 1331 1332 /* XXX: add an object file to do that */ 1333 ptr = section_ptr_add(bounds_section, sizeof(unsigned long)); 1334 *ptr = 0; 1335 add_elf_sym(symtab_section, 0, 0, 1336 ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0, 1337 bounds_section->sh_num, "__bounds_start"); 1338 #ifdef TCC_TARGET_I386 1339 if (s1->output_type != TCC_OUTPUT_MEMORY) { 1340 /* add 'call __bound_init()' in .init section */ 1341 init_section = find_section(s1, ".init"); 1342 pinit = section_ptr_add(init_section, 5); 1343 pinit[0] = 0xe8; 1344 put32(pinit + 1, -4); 1345 sym_index = find_elf_sym(symtab_section, "__bound_init"); 1346 put_elf_reloc(symtab_section, init_section, 1347 init_section->data_offset - 4, R_386_PC32, sym_index); 1348 } 1349 #endif 1350 #endif 1351 } 1352 1353 static inline int tcc_add_support(TCCState *s1, const char *filename) 1147 #endif 1148 1149 static int tcc_add_support(TCCState *s1, const char *filename) 1354 1150 { 1355 1151 char buf[1024]; … … 1358 1154 } 1359 1155 1156 ST_FUNC void tcc_add_bcheck(TCCState *s1) 1157 { 1158 #ifdef CONFIG_TCC_BCHECK 1159 addr_t *ptr; 1160 int sym_index; 1161 1162 if (0 == s1->do_bounds_check) 1163 return; 1164 /* XXX: add an object file to do that */ 1165 ptr = section_ptr_add(bounds_section, sizeof(*ptr)); 1166 *ptr = 0; 1167 set_elf_sym(symtab_section, 0, 0, 1168 ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0, 1169 bounds_section->sh_num, "__bounds_start"); 1170 /* pull bcheck.o from libtcc1.a */ 1171 sym_index = set_elf_sym(symtab_section, 0, 0, 1172 ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0, 1173 SHN_UNDEF, "__bound_init"); 1174 if (s1->output_type != TCC_OUTPUT_MEMORY) { 1175 /* add 'call __bound_init()' in .init section */ 1176 Section *init_section = find_section(s1, ".init"); 1177 unsigned char *pinit = section_ptr_add(init_section, 5); 1178 pinit[0] = 0xe8; 1179 write32le(pinit + 1, -4); 1180 put_elf_reloc(symtab_section, init_section, 1181 init_section->data_offset - 4, R_386_PC32, sym_index); 1182 /* R_386_PC32 = R_X86_64_PC32 = 2 */ 1183 } 1184 #endif 1185 } 1186 1360 1187 /* add tcc runtime libraries */ 1361 1188 ST_FUNC void tcc_add_runtime(TCCState *s1) 1362 1189 { 1363 1190 tcc_add_bcheck(s1); 1364 1191 tcc_add_pragma_libs(s1); 1365 1192 /* add libc */ 1366 1193 if (!s1->nostdlib) { 1367 tcc_add_library(s1, "c"); 1368 #ifdef CONFIG_USE_LIBGCC 1369 tcc_add_file(s1, TCC_LIBGCC); 1370 #elif !defined WITHOUT_LIBTCC 1371 tcc_add_support(s1, "libtcc1.a"); 1372 #endif 1194 tcc_add_library_err(s1, "c"); 1195 #ifdef TCC_LIBGCC 1196 if (!s1->static_link) { 1197 if (TCC_LIBGCC[0] == '/') 1198 tcc_add_file(s1, TCC_LIBGCC); 1199 else 1200 tcc_add_dll(s1, TCC_LIBGCC, 0); 1201 } 1202 #endif 1203 tcc_add_support(s1, TCC_LIBTCC1); 1373 1204 /* add crt end if not memory output */ 1374 1205 if (s1->output_type != TCC_OUTPUT_MEMORY) … … 1380 1211 sections are filled (for example after allocating common 1381 1212 symbols)) */ 1382 ST_FUNCvoid tcc_add_linker_symbols(TCCState *s1)1213 static void tcc_add_linker_symbols(TCCState *s1) 1383 1214 { 1384 1215 char buf[1024]; … … 1386 1217 Section *s; 1387 1218 1388 add_elf_sym(symtab_section,1219 set_elf_sym(symtab_section, 1389 1220 text_section->data_offset, 0, 1390 1221 ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0, 1391 1222 text_section->sh_num, "_etext"); 1392 add_elf_sym(symtab_section,1223 set_elf_sym(symtab_section, 1393 1224 data_section->data_offset, 0, 1394 1225 ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0, 1395 1226 data_section->sh_num, "_edata"); 1396 add_elf_sym(symtab_section,1227 set_elf_sym(symtab_section, 1397 1228 bss_section->data_offset, 0, 1398 1229 ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0, 1399 1230 bss_section->sh_num, "_end"); 1231 #ifndef TCC_TARGET_PE 1400 1232 /* horrible new standard ldscript defines */ 1401 1233 add_init_array_defines(s1, ".preinit_array"); 1402 1234 add_init_array_defines(s1, ".init_array"); 1403 1235 add_init_array_defines(s1, ".fini_array"); 1404 1236 #endif 1237 1405 1238 /* add start and stop symbols for sections whose name can be 1406 1239 expressed in C */ … … 1423 1256 } 1424 1257 snprintf(buf, sizeof(buf), "__start_%s", s->name); 1425 add_elf_sym(symtab_section,1258 set_elf_sym(symtab_section, 1426 1259 0, 0, 1427 1260 ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0, 1428 1261 s->sh_num, buf); 1429 1262 snprintf(buf, sizeof(buf), "__stop_%s", s->name); 1430 add_elf_sym(symtab_section,1263 set_elf_sym(symtab_section, 1431 1264 s->data_offset, 0, 1432 1265 ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0, … … 1437 1270 } 1438 1271 1272 ST_FUNC void resolve_common_syms(TCCState *s1) 1273 { 1274 ElfW(Sym) *sym; 1275 1276 /* Allocate common symbols in BSS. */ 1277 for_each_elem(symtab_section, 1, sym, ElfW(Sym)) { 1278 if (sym->st_shndx == SHN_COMMON) { 1279 /* symbol alignment is in st_value for SHN_COMMONs */ 1280 sym->st_value = section_add(bss_section, sym->st_size, 1281 sym->st_value); 1282 sym->st_shndx = bss_section->sh_num; 1283 } 1284 } 1285 1286 /* Now assign linker provided symbols their value. */ 1287 tcc_add_linker_symbols(s1); 1288 } 1289 1439 1290 static void tcc_output_binary(TCCState *s1, FILE *f, 1440 const int *sec tion_order)1291 const int *sec_order) 1441 1292 { 1442 1293 Section *s; … … 1445 1296 offset = 0; 1446 1297 for(i=1;i<s1->nb_sections;i++) { 1447 s = s1->sections[sec tion_order[i]];1298 s = s1->sections[sec_order[i]]; 1448 1299 if (s->sh_type != SHT_NOBITS && 1449 1300 (s->sh_flags & SHF_ALLOC)) { … … 1459 1310 } 1460 1311 1461 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) 1462 #define HAVE_PHDR 1 1463 #define EXTRA_RELITEMS 14 1464 1465 /* move the relocation value from .dynsym to .got */ 1466 void patch_dynsym_undef(TCCState *s1, Section *s) 1467 { 1468 uint32_t *gotd = (void *)s1->got->data; 1469 ElfW(Sym) *sym, *sym_end; 1470 1471 gotd += 3; // dummy entries in .got 1472 /* relocate symbols in .dynsym */ 1473 sym_end = (ElfW(Sym) *)(s->data + s->data_offset); 1474 for (sym = (ElfW(Sym) *)s->data + 1; sym < sym_end; sym++) { 1475 if (sym->st_shndx == SHN_UNDEF) { 1476 *gotd++ = sym->st_value + 6; // XXX 6 is magic ? 1477 sym->st_value = 0; 1312 ST_FUNC void fill_got_entry(TCCState *s1, ElfW_Rel *rel) 1313 { 1314 int sym_index = ELFW(R_SYM) (rel->r_info); 1315 ElfW(Sym) *sym = &((ElfW(Sym) *) symtab_section->data)[sym_index]; 1316 struct sym_attr *attr = get_sym_attr(s1, sym_index, 0); 1317 unsigned offset = attr->got_offset; 1318 1319 if (0 == offset) 1320 return; 1321 section_reserve(s1->got, offset + PTR_SIZE); 1322 #ifdef TCC_TARGET_X86_64 1323 write64le(s1->got->data + offset, sym->st_value); 1324 #else 1325 write32le(s1->got->data + offset, sym->st_value); 1326 #endif 1327 } 1328 1329 /* Perform relocation to GOT or PLT entries */ 1330 ST_FUNC void fill_got(TCCState *s1) 1331 { 1332 Section *s; 1333 ElfW_Rel *rel; 1334 int i; 1335 1336 for(i = 1; i < s1->nb_sections; i++) { 1337 s = s1->sections[i]; 1338 if (s->sh_type != SHT_RELX) 1339 continue; 1340 /* no need to handle got relocations */ 1341 if (s->link != symtab_section) 1342 continue; 1343 for_each_elem(s, 0, rel, ElfW_Rel) { 1344 switch (ELFW(R_TYPE) (rel->r_info)) { 1345 case R_X86_64_GOT32: 1346 case R_X86_64_GOTPCREL: 1347 case R_X86_64_GOTPCRELX: 1348 case R_X86_64_REX_GOTPCRELX: 1349 case R_X86_64_PLT32: 1350 fill_got_entry(s1, rel); 1351 break; 1352 } 1353 } 1354 } 1355 } 1356 1357 /* See put_got_entry for a description. This is the second stage 1358 where GOT references to local defined symbols are rewritten. */ 1359 static void fill_local_got_entries(TCCState *s1) 1360 { 1361 ElfW_Rel *rel; 1362 for_each_elem(s1->got->reloc, 0, rel, ElfW_Rel) { 1363 if (ELFW(R_TYPE)(rel->r_info) == R_RELATIVE) { 1364 int sym_index = ELFW(R_SYM) (rel->r_info); 1365 ElfW(Sym) *sym = &((ElfW(Sym) *) symtab_section->data)[sym_index]; 1366 struct sym_attr *attr = get_sym_attr(s1, sym_index, 0); 1367 unsigned offset = attr->got_offset; 1368 if (offset != rel->r_offset - s1->got->sh_addr) 1369 tcc_error_noabort("huh"); 1370 rel->r_info = ELFW(R_INFO)(0, R_RELATIVE); 1371 #if SHT_RELX == SHT_RELA 1372 rel->r_addend = sym->st_value; 1373 #else 1374 /* All our REL architectures also happen to be 32bit LE. */ 1375 write32le(s1->got->data + offset, sym->st_value); 1376 #endif 1478 1377 } 1479 1378 } 1480 1379 } 1481 #else 1482 #define HAVE_PHDR 0 1483 #define EXTRA_RELITEMS 9 1484 1485 /* zero plt offsets of weak symbols in .dynsym */ 1486 void patch_dynsym_undef(TCCState *s1, Section *s) 1487 { 1488 ElfW(Sym) *sym, *sym_end; 1489 1490 sym_end = (ElfW(Sym) *)(s->data + s->data_offset); 1491 for (sym = (ElfW(Sym) *)s->data + 1; sym < sym_end; sym++) 1492 if (sym->st_shndx == SHN_UNDEF && ELFW(ST_BIND)(sym->st_info) == STB_WEAK) 1493 sym->st_value = 0; 1494 } 1495 #endif 1496 1497 ST_FUNC void fill_got_entry(TCCState *s1, ElfW_Rel *rel) 1498 { 1499 int sym_index = ELFW(R_SYM) (rel->r_info); 1500 ElfW(Sym) *sym = &((ElfW(Sym) *) symtab_section->data)[sym_index]; 1501 unsigned long offset; 1502 1503 if (sym_index >= s1->nb_sym_attrs) 1504 return; 1505 offset = s1->sym_attrs[sym_index].got_offset; 1506 section_reserve(s1->got, offset + PTR_SIZE); 1507 #ifdef TCC_TARGET_X86_64 1508 /* only works for x86-64 */ 1509 put32(s1->got->data + offset + 4, sym->st_value >> 32); 1510 #endif 1511 put32(s1->got->data + offset, sym->st_value & 0xffffffff); 1512 } 1513 1514 ST_FUNC void fill_got(TCCState *s1) 1515 { 1516 Section *s; 1517 ElfW_Rel *rel, *rel_end; 1518 int i; 1519 1520 for(i = 1; i < s1->nb_sections; i++) { 1521 s = s1->sections[i]; 1522 if (s->sh_type != SHT_RELX) 1523 continue; 1524 /* no need to handle got relocations */ 1525 if (s->link != symtab_section) 1526 continue; 1527 rel_end = (ElfW_Rel *) (s->data + s->data_offset); 1528 for(rel = (ElfW_Rel *) s->data; rel < rel_end; rel++) { 1529 switch (ELFW(R_TYPE) (rel->r_info)) { 1530 case R_X86_64_GOT32: 1531 case R_X86_64_GOTPCREL: 1532 case R_X86_64_PLT32: 1533 fill_got_entry(s1, rel); 1534 break; 1535 } 1536 } 1537 } 1538 } 1539 1540 1541 /* output an ELF file */ 1542 /* XXX: suppress unneeded sections */ 1543 static int elf_output_file(TCCState *s1, const char *filename) 1544 { 1545 ElfW(Ehdr) ehdr; 1546 FILE *f; 1547 int fd, mode, ret; 1548 int *section_order; 1549 int shnum, i, phnum, file_offset, offset, size, j, sh_order_index, k; 1550 long long tmp; 1551 addr_t addr; 1552 Section *strsec, *s; 1553 ElfW(Shdr) shdr, *sh; 1554 ElfW(Phdr) *phdr, *ph; 1555 Section *interp, *dynamic, *dynstr; 1556 unsigned long saved_dynamic_data_offset; 1557 ElfW(Sym) *sym; 1558 int type, file_type; 1559 addr_t rel_addr, rel_size; 1560 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) 1561 addr_t bss_addr, bss_size; 1562 #endif 1563 1564 file_type = s1->output_type; 1565 s1->nb_errors = 0; 1566 1567 if (file_type != TCC_OUTPUT_OBJ) { 1568 tcc_add_runtime(s1); 1569 } 1570 1571 phdr = NULL; 1572 section_order = NULL; 1573 interp = NULL; 1574 dynamic = NULL; 1575 dynstr = NULL; /* avoid warning */ 1576 saved_dynamic_data_offset = 0; /* avoid warning */ 1577 1578 if (file_type != TCC_OUTPUT_OBJ) { 1579 relocate_common_syms(); 1580 1581 tcc_add_linker_symbols(s1); 1582 1583 if (!s1->static_link) { 1584 const char *name; 1585 int sym_index, index; 1586 ElfW(Sym) *esym, *sym_end; 1587 1588 if (file_type == TCC_OUTPUT_EXE) { 1589 char *ptr; 1590 /* allow override the dynamic loader */ 1591 const char *elfint = getenv("LD_SO"); 1592 if (elfint == NULL) 1593 elfint = CONFIG_TCC_ELFINTERP; 1594 /* add interpreter section only if executable */ 1595 interp = new_section(s1, ".interp", SHT_PROGBITS, SHF_ALLOC); 1596 interp->sh_addralign = 1; 1597 ptr = section_ptr_add(interp, 1+strlen(elfint)); 1598 strcpy(ptr, elfint); 1599 } 1600 1601 /* add dynamic symbol table */ 1602 s1->dynsym = new_symtab(s1, ".dynsym", SHT_DYNSYM, SHF_ALLOC, 1603 ".dynstr", 1604 ".hash", SHF_ALLOC); 1605 dynstr = s1->dynsym->link; 1606 1607 /* add dynamic section */ 1608 dynamic = new_section(s1, ".dynamic", SHT_DYNAMIC, 1609 SHF_ALLOC | SHF_WRITE); 1610 dynamic->link = dynstr; 1611 dynamic->sh_entsize = sizeof(ElfW(Dyn)); 1612 1613 /* add PLT */ 1614 s1->plt = new_section(s1, ".plt", SHT_PROGBITS, 1615 SHF_ALLOC | SHF_EXECINSTR); 1616 s1->plt->sh_entsize = 4; 1617 1618 build_got(s1); 1619 1620 /* scan for undefined symbols and see if they are in the 1621 dynamic symbols. If a symbol STT_FUNC or STT_GNU_IFUNC 1622 is found, then we add it in the PLT. If a symbol 1623 STT_OBJECT is found, we add it in the .bss section with 1624 a suitable relocation */ 1625 sym_end = (ElfW(Sym) *)(symtab_section->data + 1626 symtab_section->data_offset); 1627 if (file_type == TCC_OUTPUT_EXE) { 1628 for(sym = (ElfW(Sym) *)symtab_section->data + 1; 1629 sym < sym_end; 1630 sym++) { 1631 if (sym->st_shndx == SHN_UNDEF) { 1632 name = symtab_section->link->data + sym->st_name; 1633 sym_index = find_elf_sym(s1->dynsymtab_section, name); 1634 if (sym_index) { 1635 esym = &((ElfW(Sym) *)s1->dynsymtab_section->data)[sym_index]; 1636 type = ELFW(ST_TYPE)(esym->st_info); 1637 if ((type == STT_FUNC) || (type == STT_GNU_IFUNC)) { 1638 /* Indirect functions shall have STT_FUNC type 1639 * in executable dynsym section. Indeed, a dlsym 1640 * call following a lazy resolution would pick 1641 * the symbol value from the executable dynsym 1642 * entry which would contain the address of the 1643 * function wanted by the caller of dlsym 1644 * instead of the address of the function that 1645 * would return that address */ 1646 put_got_entry(s1, R_JMP_SLOT, esym->st_size, 1647 ELFW(ST_INFO)(STB_GLOBAL,STT_FUNC), 1648 sym - (ElfW(Sym) *)symtab_section->data); 1649 } else if (type == STT_OBJECT) { 1650 unsigned long offset; 1651 ElfW(Sym) *dynsym, *dynsym_end; 1652 offset = bss_section->data_offset; 1653 /* XXX: which alignment ? */ 1654 offset = (offset + 16 - 1) & -16; 1655 index = put_elf_sym(s1->dynsym, offset, esym->st_size, 1656 esym->st_info, 0, 1657 bss_section->sh_num, name); 1658 // Ensure R_COPY works for weak symbol aliases 1659 if (ELFW(ST_BIND)(esym->st_info) == STB_WEAK) { 1660 dynsym_end = (ElfW(Sym) *) 1661 (s1->dynsymtab_section->data + 1662 s1->dynsymtab_section->data_offset); 1663 for(dynsym = (ElfW(Sym) *)s1->dynsymtab_section->data + 1; 1664 dynsym < dynsym_end; dynsym++) { 1665 if ((dynsym->st_value == esym->st_value) 1666 && (ELFW(ST_BIND)(dynsym->st_info) == STB_GLOBAL)) { 1667 char *dynname; 1668 dynname = s1->dynsymtab_section->link->data 1669 + dynsym->st_name; 1670 put_elf_sym(s1->dynsym, offset, 1671 dynsym->st_size, 1672 dynsym->st_info, 0, 1673 bss_section->sh_num, 1674 dynname); 1675 break; 1676 } 1677 } 1678 } 1679 put_elf_reloc(s1->dynsym, bss_section, 1680 offset, R_COPY, index); 1681 offset += esym->st_size; 1682 bss_section->data_offset = offset; 1683 } 1684 } else { 1685 /* STB_WEAK undefined symbols are accepted */ 1686 /* XXX: _fp_hw seems to be part of the ABI, so we ignore 1687 it */ 1688 if (ELFW(ST_BIND)(sym->st_info) == STB_WEAK || 1689 !strcmp(name, "_fp_hw")) { 1690 } else { 1691 tcc_error_noabort("undefined symbol '%s'", name); 1692 } 1693 } 1694 } else if (s1->rdynamic && 1695 ELFW(ST_BIND)(sym->st_info) != STB_LOCAL) { 1696 /* if -rdynamic option, then export all non 1697 local symbols */ 1698 name = symtab_section->link->data + sym->st_name; 1699 put_elf_sym(s1->dynsym, sym->st_value, sym->st_size, 1700 sym->st_info, 0, 1701 sym->st_shndx, name); 1702 } 1703 } 1704 1705 if (s1->nb_errors) 1706 goto fail; 1707 1708 /* now look at unresolved dynamic symbols and export 1709 corresponding symbol */ 1710 sym_end = (ElfW(Sym) *)(s1->dynsymtab_section->data + 1711 s1->dynsymtab_section->data_offset); 1712 for(esym = (ElfW(Sym) *)s1->dynsymtab_section->data + 1; 1713 esym < sym_end; 1714 esym++) { 1715 if (esym->st_shndx == SHN_UNDEF) { 1716 name = s1->dynsymtab_section->link->data + esym->st_name; 1717 sym_index = find_elf_sym(symtab_section, name); 1718 if (sym_index) { 1719 /* XXX: avoid adding a symbol if already 1720 present because of -rdynamic ? */ 1721 sym = &((ElfW(Sym) *)symtab_section->data)[sym_index]; 1722 put_elf_sym(s1->dynsym, sym->st_value, sym->st_size, 1723 sym->st_info, 0, 1724 sym->st_shndx, name); 1725 } else { 1726 if (ELFW(ST_BIND)(esym->st_info) == STB_WEAK) { 1727 /* weak symbols can stay undefined */ 1728 } else { 1729 tcc_warning("undefined dynamic symbol '%s'", name); 1380 1381 /* Bind symbols of executable: resolve undefined symbols from exported symbols 1382 in shared libraries and export non local defined symbols to shared libraries 1383 if -rdynamic switch was given on command line */ 1384 static void bind_exe_dynsyms(TCCState *s1) 1385 { 1386 const char *name; 1387 int sym_index, index; 1388 ElfW(Sym) *sym, *esym; 1389 int type; 1390 1391 /* Resolve undefined symbols from dynamic symbols. When there is a match: 1392 - if STT_FUNC or STT_GNU_IFUNC symbol -> add it in PLT 1393 - if STT_OBJECT symbol -> add it in .bss section with suitable reloc */ 1394 for_each_elem(symtab_section, 1, sym, ElfW(Sym)) { 1395 if (sym->st_shndx == SHN_UNDEF) { 1396 name = (char *) symtab_section->link->data + sym->st_name; 1397 sym_index = find_elf_sym(s1->dynsymtab_section, name); 1398 if (sym_index) { 1399 esym = &((ElfW(Sym) *)s1->dynsymtab_section->data)[sym_index]; 1400 type = ELFW(ST_TYPE)(esym->st_info); 1401 if ((type == STT_FUNC) || (type == STT_GNU_IFUNC)) { 1402 /* Indirect functions shall have STT_FUNC type in executable 1403 * dynsym section. Indeed, a dlsym call following a lazy 1404 * resolution would pick the symbol value from the 1405 * executable dynsym entry which would contain the address 1406 * of the function wanted by the caller of dlsym instead of 1407 * the address of the function that would return that 1408 * address */ 1409 int dynindex 1410 = put_elf_sym(s1->dynsym, 0, esym->st_size, 1411 ELFW(ST_INFO)(STB_GLOBAL,STT_FUNC), 0, 0, 1412 name); 1413 int index = sym - (ElfW(Sym) *) symtab_section->data; 1414 get_sym_attr(s1, index, 1)->dyn_index = dynindex; 1415 } else if (type == STT_OBJECT) { 1416 unsigned long offset; 1417 ElfW(Sym) *dynsym; 1418 offset = bss_section->data_offset; 1419 /* XXX: which alignment ? */ 1420 offset = (offset + 16 - 1) & -16; 1421 set_elf_sym (s1->symtab, offset, esym->st_size, 1422 esym->st_info, 0, bss_section->sh_num, name); 1423 index = put_elf_sym(s1->dynsym, offset, esym->st_size, 1424 esym->st_info, 0, bss_section->sh_num, 1425 name); 1426 1427 /* Ensure R_COPY works for weak symbol aliases */ 1428 if (ELFW(ST_BIND)(esym->st_info) == STB_WEAK) { 1429 for_each_elem(s1->dynsymtab_section, 1, dynsym, ElfW(Sym)) { 1430 if ((dynsym->st_value == esym->st_value) 1431 && (ELFW(ST_BIND)(dynsym->st_info) == STB_GLOBAL)) { 1432 char *dynname = (char *) s1->dynsymtab_section->link->data 1433 + dynsym->st_name; 1434 put_elf_sym(s1->dynsym, offset, dynsym->st_size, 1435 dynsym->st_info, 0, 1436 bss_section->sh_num, dynname); 1437 break; 1730 1438 } 1731 1439 } 1732 1440 } 1441 1442 put_elf_reloc(s1->dynsym, bss_section, 1443 offset, R_COPY, index); 1444 offset += esym->st_size; 1445 bss_section->data_offset = offset; 1733 1446 } 1734 1447 } else { 1735 int nb_syms; 1736 /* shared library case : we simply export all the global symbols */ 1737 nb_syms = symtab_section->data_offset / sizeof(ElfW(Sym)); 1738 s1->symtab_to_dynsym = tcc_mallocz(sizeof(int) * nb_syms); 1739 for(sym = (ElfW(Sym) *)symtab_section->data + 1; 1740 sym < sym_end; 1741 sym++) { 1742 if (ELFW(ST_BIND)(sym->st_info) != STB_LOCAL) { 1743 #if defined(TCC_OUTPUT_DLL_WITH_PLT) 1744 if ((ELFW(ST_TYPE)(sym->st_info) == STT_FUNC || 1745 ELFW(ST_TYPE)(sym->st_info) == STT_GNU_IFUNC) 1746 && sym->st_shndx == SHN_UNDEF) { 1747 int visibility = ELFW(ST_BIND)(sym->st_info); 1748 put_got_entry(s1, R_JMP_SLOT, sym->st_size, 1749 ELFW(ST_INFO)(visibility,STT_FUNC), 1750 sym - (ElfW(Sym) *)symtab_section->data); 1751 } 1752 else if (ELFW(ST_TYPE)(sym->st_info) == STT_OBJECT) { 1753 put_got_entry(s1, R_X86_64_GLOB_DAT, sym->st_size, 1754 sym->st_info, 1755 sym - (ElfW(Sym) *)symtab_section->data); 1756 } 1757 else 1758 #endif 1759 { 1760 name = symtab_section->link->data + sym->st_name; 1761 index = put_elf_sym(s1->dynsym, sym->st_value, sym->st_size, 1762 sym->st_info, 0, 1763 sym->st_shndx, name); 1764 s1->symtab_to_dynsym[sym - 1765 (ElfW(Sym) *)symtab_section->data] = 1766 index; 1767 } 1768 } 1448 /* STB_WEAK undefined symbols are accepted */ 1449 /* XXX: _fp_hw seems to be part of the ABI, so we ignore it */ 1450 if (ELFW(ST_BIND)(sym->st_info) == STB_WEAK || 1451 !strcmp(name, "_fp_hw")) { 1452 } else { 1453 tcc_error_noabort("undefined symbol '%s'", name); 1769 1454 } 1770 1455 } 1771 1772 build_got_entries(s1); 1773 1774 /* add a list of needed dlls */ 1775 for(i = 0; i < s1->nb_loaded_dlls; i++) { 1776 DLLReference *dllref = s1->loaded_dlls[i]; 1777 if (dllref->level == 0) 1778 put_dt(dynamic, DT_NEEDED, put_elf_str(dynstr, dllref->name)); 1779 } 1780 1781 if (s1->rpath) 1782 put_dt(dynamic, DT_RPATH, put_elf_str(dynstr, s1->rpath)); 1783 1784 /* XXX: currently, since we do not handle PIC code, we 1785 must relocate the readonly segments */ 1786 if (file_type == TCC_OUTPUT_DLL) { 1787 if (s1->soname) 1788 put_dt(dynamic, DT_SONAME, put_elf_str(dynstr, s1->soname)); 1789 put_dt(dynamic, DT_TEXTREL, 0); 1790 } 1791 1792 if (s1->symbolic) 1793 put_dt(dynamic, DT_SYMBOLIC, 0); 1794 1795 /* add necessary space for other entries */ 1796 saved_dynamic_data_offset = dynamic->data_offset; 1797 dynamic->data_offset += sizeof(ElfW(Dyn)) * EXTRA_RELITEMS; 1798 } else { 1799 /* still need to build got entries in case of static link */ 1800 build_got_entries(s1); 1801 } 1802 } 1803 1804 memset(&ehdr, 0, sizeof(ehdr)); 1805 1806 /* we add a section for symbols */ 1807 strsec = new_section(s1, ".shstrtab", SHT_STRTAB, 0); 1808 put_elf_str(strsec, ""); 1809 1810 /* compute number of sections */ 1811 shnum = s1->nb_sections; 1812 1813 /* this array is used to reorder sections in the output file */ 1814 section_order = tcc_malloc(sizeof(int) * shnum); 1815 section_order[0] = 0; 1816 sh_order_index = 1; 1817 1818 /* compute number of program headers */ 1819 switch(file_type) { 1820 default: 1821 case TCC_OUTPUT_OBJ: 1822 phnum = 0; 1823 break; 1824 case TCC_OUTPUT_EXE: 1825 if (!s1->static_link) 1826 phnum = 4 + HAVE_PHDR; 1827 else 1828 phnum = 2; 1829 break; 1830 case TCC_OUTPUT_DLL: 1831 phnum = 3; 1832 break; 1833 } 1834 1835 /* allocate strings for section names and decide if an unallocated 1836 section should be output */ 1837 /* NOTE: the strsec section comes last, so its size is also 1838 correct ! */ 1456 } else if (s1->rdynamic && ELFW(ST_BIND)(sym->st_info) != STB_LOCAL) { 1457 /* if -rdynamic option, then export all non local symbols */ 1458 name = (char *) symtab_section->link->data + sym->st_name; 1459 set_elf_sym(s1->dynsym, sym->st_value, sym->st_size, sym->st_info, 1460 0, sym->st_shndx, name); 1461 } 1462 } 1463 } 1464 1465 /* Bind symbols of libraries: export all non local symbols of executable that 1466 are referenced by shared libraries. The reason is that the dynamic loader 1467 search symbol first in executable and then in libraries. Therefore a 1468 reference to a symbol already defined by a library can still be resolved by 1469 a symbol in the executable. */ 1470 static void bind_libs_dynsyms(TCCState *s1) 1471 { 1472 const char *name; 1473 int sym_index; 1474 ElfW(Sym) *sym, *esym; 1475 1476 for_each_elem(s1->dynsymtab_section, 1, esym, ElfW(Sym)) { 1477 name = (char *) s1->dynsymtab_section->link->data + esym->st_name; 1478 sym_index = find_elf_sym(symtab_section, name); 1479 sym = &((ElfW(Sym) *)symtab_section->data)[sym_index]; 1480 if (sym_index && sym->st_shndx != SHN_UNDEF 1481 && ELFW(ST_BIND)(sym->st_info) != STB_LOCAL) { 1482 set_elf_sym(s1->dynsym, sym->st_value, sym->st_size, 1483 sym->st_info, 0, sym->st_shndx, name); 1484 } else if (esym->st_shndx == SHN_UNDEF) { 1485 /* weak symbols can stay undefined */ 1486 if (ELFW(ST_BIND)(esym->st_info) != STB_WEAK) 1487 tcc_warning("undefined dynamic symbol '%s'", name); 1488 } 1489 } 1490 } 1491 1492 /* Export all non local symbols. This is used by shared libraries so that the 1493 non local symbols they define can resolve a reference in another shared 1494 library or in the executable. Correspondingly, it allows undefined local 1495 symbols to be resolved by other shared libraries or by the executable. */ 1496 static void export_global_syms(TCCState *s1) 1497 { 1498 int dynindex, index; 1499 const char *name; 1500 ElfW(Sym) *sym; 1501 1502 for_each_elem(symtab_section, 1, sym, ElfW(Sym)) { 1503 if (ELFW(ST_BIND)(sym->st_info) != STB_LOCAL) { 1504 name = (char *) symtab_section->link->data + sym->st_name; 1505 dynindex = put_elf_sym(s1->dynsym, sym->st_value, sym->st_size, 1506 sym->st_info, 0, sym->st_shndx, name); 1507 index = sym - (ElfW(Sym) *) symtab_section->data; 1508 get_sym_attr(s1, index, 1)->dyn_index = dynindex; 1509 } 1510 } 1511 } 1512 1513 /* Allocate strings for section names and decide if an unallocated section 1514 should be output. 1515 NOTE: the strsec section comes last, so its size is also correct ! */ 1516 static int alloc_sec_names(TCCState *s1, int file_type, Section *strsec) 1517 { 1518 int i; 1519 Section *s; 1520 int textrel = 0; 1521 1522 /* Allocate strings for section names */ 1839 1523 for(i = 1; i < s1->nb_sections; i++) { 1840 1524 s = s1->sections[i]; 1841 s->sh_name = put_elf_str(strsec, s->name);1842 #if 0 //gr1843 printf("section: f=%08x t=%08x i=%08x %s %s\n",1844 s->sh_flags,1845 s->sh_type,1846 s->sh_info,1847 s->name,1848 s->reloc ? s->reloc->name : "n"1849 );1850 #endif1851 1525 /* when generating a DLL, we include relocations but we may 1852 1526 patch them */ 1853 if (file_type == TCC_OUTPUT_DLL && 1854 s->sh_type == SHT_RELX && 1855 !(s->sh_flags & SHF_ALLOC)) { 1856 /* //gr: avoid bogus relocs for empty (debug) sections */ 1857 if (s1->sections[s->sh_info]->sh_flags & SHF_ALLOC) 1858 prepare_dynamic_rel(s1, s); 1859 else if (s1->do_debug) 1860 s->sh_size = s->data_offset; 1527 if (file_type == TCC_OUTPUT_DLL && 1528 s->sh_type == SHT_RELX && 1529 !(s->sh_flags & SHF_ALLOC) && 1530 (s1->sections[s->sh_info]->sh_flags & SHF_ALLOC) && 1531 prepare_dynamic_rel(s1, s)) { 1532 if (s1->sections[s->sh_info]->sh_flags & SHF_EXECINSTR) 1533 textrel = 1; 1861 1534 } else if (s1->do_debug || 1862 file_type == TCC_OUTPUT_OBJ || 1535 file_type == TCC_OUTPUT_OBJ || 1863 1536 (s->sh_flags & SHF_ALLOC) || 1864 1537 i == (s1->nb_sections - 1)) { 1865 1538 /* we output all sections if debug or object file */ 1866 1539 s->sh_size = s->data_offset; 1867 1540 } 1868 } 1869 1870 /* allocate program segment headers */ 1871 phdr = tcc_mallocz(phnum * sizeof(ElfW(Phdr))); 1872 1873 if (s1->output_format == TCC_OUTPUT_FORMAT_ELF) { 1541 if (s->sh_size || (s->sh_flags & SHF_ALLOC)) 1542 s->sh_name = put_elf_str(strsec, s->name); 1543 } 1544 strsec->sh_size = strsec->data_offset; 1545 return textrel; 1546 } 1547 1548 /* Info to be copied in dynamic section */ 1549 struct dyn_inf { 1550 Section *dynamic; 1551 Section *dynstr; 1552 unsigned long data_offset; 1553 addr_t rel_addr; 1554 addr_t rel_size; 1555 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) 1556 addr_t bss_addr; 1557 addr_t bss_size; 1558 #endif 1559 }; 1560 1561 /* Assign sections to segments and decide how are sections laid out when loaded 1562 in memory. This function also fills corresponding program headers. */ 1563 static int layout_sections(TCCState *s1, ElfW(Phdr) *phdr, int phnum, 1564 Section *interp, Section* strsec, 1565 struct dyn_inf *dyninf, int *sec_order) 1566 { 1567 int i, j, k, file_type, sh_order_index, file_offset; 1568 unsigned long s_align; 1569 long long tmp; 1570 addr_t addr; 1571 ElfW(Phdr) *ph; 1572 Section *s; 1573 1574 file_type = s1->output_type; 1575 sh_order_index = 1; 1576 file_offset = 0; 1577 if (s1->output_format == TCC_OUTPUT_FORMAT_ELF) 1874 1578 file_offset = sizeof(ElfW(Ehdr)) + phnum * sizeof(ElfW(Phdr)); 1875 } else { 1876 file_offset = 0; 1877 } 1579 s_align = ELF_PAGE_SIZE; 1580 if (s1->section_align) 1581 s_align = s1->section_align; 1582 1878 1583 if (phnum > 0) { 1879 /* compute section to program header mapping */ 1880 if (s1->has_text_addr) { 1584 if (s1->has_text_addr) { 1881 1585 int a_offset, p_offset; 1882 1586 addr = s1->text_addr; 1883 1587 /* we ensure that (addr % ELF_PAGE_SIZE) == file_offset % 1884 1588 ELF_PAGE_SIZE */ 1885 a_offset = (int) (addr & (s 1->section_align - 1));1886 p_offset = file_offset & (s 1->section_align - 1);1887 if (a_offset < p_offset) 1888 a_offset += s 1->section_align;1589 a_offset = (int) (addr & (s_align - 1)); 1590 p_offset = file_offset & (s_align - 1); 1591 if (a_offset < p_offset) 1592 a_offset += s_align; 1889 1593 file_offset += (a_offset - p_offset); 1890 1594 } else { … … 1894 1598 addr = ELF_START_ADDR; 1895 1599 /* compute address after headers */ 1896 addr += (file_offset & (s1->section_align - 1)); 1897 } 1898 1600 addr += (file_offset & (s_align - 1)); 1601 } 1602 1603 ph = &phdr[0]; 1604 /* Leave one program headers for the program interpreter and one for 1605 the program header table itself if needed. These are done later as 1606 they require section layout to be done first. */ 1607 if (interp) 1608 ph += 2; 1609 1899 1610 /* dynamic relocation table information, for .dynamic section */ 1900 rel_size = 0; 1901 rel_addr = 0; 1902 1611 dyninf->rel_addr = dyninf->rel_size = 0; 1903 1612 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) 1904 bss_addr = bss_size = 0; 1905 #endif 1906 /* leave one program header for the program interpreter */ 1907 ph = &phdr[0]; 1908 if (interp) 1909 ph += 1 + HAVE_PHDR; 1613 dyninf->bss_addr = dyninf->bss_size = 0; 1614 #endif 1910 1615 1911 1616 for(j = 0; j < 2; j++) { … … 1915 1620 else 1916 1621 ph->p_flags = PF_R | PF_W; 1917 ph->p_align = s1->section_align; 1918 1919 /* we do the following ordering: interp, symbol tables, 1920 relocations, progbits, nobits */ 1622 ph->p_align = s_align; 1623 1624 /* Decide the layout of sections loaded in memory. This must 1625 be done before program headers are filled since they contain 1626 info about the layout. We do the following ordering: interp, 1627 symbol tables, relocations, progbits, nobits */ 1921 1628 /* XXX: do faster and simpler sorting */ 1922 1629 for(k = 0; k < 5; k++) { … … 1925 1632 /* compute if section should be included */ 1926 1633 if (j == 0) { 1927 if ((s->sh_flags & (SHF_ALLOC | SHF_WRITE)) != 1634 if ((s->sh_flags & (SHF_ALLOC | SHF_WRITE)) != 1928 1635 SHF_ALLOC) 1929 1636 continue; 1930 1637 } else { 1931 if ((s->sh_flags & (SHF_ALLOC | SHF_WRITE)) != 1638 if ((s->sh_flags & (SHF_ALLOC | SHF_WRITE)) != 1932 1639 (SHF_ALLOC | SHF_WRITE)) 1933 1640 continue; … … 1951 1658 continue; 1952 1659 } 1953 sec tion_order[sh_order_index++] = i;1660 sec_order[sh_order_index++] = i; 1954 1661 1955 1662 /* section matches: we align it and add its size */ 1956 1663 tmp = addr; 1957 addr = (addr + s->sh_addralign - 1) & 1664 addr = (addr + s->sh_addralign - 1) & 1958 1665 ~(s->sh_addralign - 1); 1959 1666 file_offset += (int) ( addr - tmp ); 1960 1667 s->sh_offset = file_offset; 1961 1668 s->sh_addr = addr; 1962 1669 1963 1670 /* update program header infos */ 1964 1671 if (ph->p_offset == 0) { … … 1970 1677 if (s->sh_type == SHT_RELX) { 1971 1678 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) 1972 if (!strcmp(strsec->data + s->sh_name, ".rel.got")) { // rel_size == 0) {1973 rel_addr = addr;1974 rel_size += s->sh_size; // XXX only first rel. 1975 1976 if (!strcmp(strsec->data + s->sh_name, ".rel.bss")) { // rel_size == 0) {1977 bss_addr = addr;1978 bss_size = s->sh_size; // XXX only first rel. 1979 1679 if (!strcmp(strsec->data + s->sh_name, ".rel.got")) { 1680 dyninf->rel_addr = addr; 1681 dyninf->rel_size += s->sh_size; /* XXX only first rel. */ 1682 } 1683 if (!strcmp(strsec->data + s->sh_name, ".rel.bss")) { 1684 dyninf->bss_addr = addr; 1685 dyninf->bss_size = s->sh_size; /* XXX only first rel. */ 1686 } 1980 1687 #else 1981 if ( rel_size == 0)1982 rel_addr = addr;1983 rel_size += s->sh_size;1688 if (dyninf->rel_size == 0) 1689 dyninf->rel_addr = addr; 1690 dyninf->rel_size += s->sh_size; 1984 1691 #endif 1985 1692 } … … 1989 1696 } 1990 1697 } 1698 if (j == 0) { 1699 /* Make the first PT_LOAD segment include the program 1700 headers itself (and the ELF header as well), it'll 1701 come out with same memory use but will make various 1702 tools like binutils strip work better. */ 1703 ph->p_offset &= ~(ph->p_align - 1); 1704 ph->p_vaddr &= ~(ph->p_align - 1); 1705 ph->p_paddr &= ~(ph->p_align - 1); 1706 } 1991 1707 ph->p_filesz = file_offset - ph->p_offset; 1992 1708 ph->p_memsz = addr - ph->p_vaddr; … … 1996 1712 /* if in the middle of a page, we duplicate the page in 1997 1713 memory so that one copy is RX and the other is RW */ 1998 if ((addr & (s 1->section_align - 1)) != 0)1999 addr += s 1->section_align;1714 if ((addr & (s_align - 1)) != 0) 1715 addr += s_align; 2000 1716 } else { 2001 addr = (addr + s1->section_align - 1) & ~(s1->section_align - 1); 2002 file_offset = (file_offset + s1->section_align - 1) & 2003 ~(s1->section_align - 1); 1717 addr = (addr + s_align - 1) & ~(s_align - 1); 1718 file_offset = (file_offset + s_align - 1) & ~(s_align - 1); 2004 1719 } 2005 1720 } 2006 1721 } 2007 2008 /* if interpreter, then add corresponing program header */2009 if (interp) {2010 ph = &phdr[0];2011 2012 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)2013 {2014 int len = phnum * sizeof(ElfW(Phdr));2015 2016 ph->p_type = PT_PHDR;2017 ph->p_offset = sizeof(ElfW(Ehdr));2018 ph->p_vaddr = interp->sh_addr - len;2019 ph->p_paddr = ph->p_vaddr;2020 ph->p_filesz = ph->p_memsz = len;2021 ph->p_flags = PF_R | PF_X;2022 ph->p_align = 4; // interp->sh_addralign;2023 ph++;2024 }2025 #endif2026 2027 ph->p_type = PT_INTERP;2028 ph->p_offset = interp->sh_offset;2029 ph->p_vaddr = interp->sh_addr;2030 ph->p_paddr = ph->p_vaddr;2031 ph->p_filesz = interp->sh_size;2032 ph->p_memsz = interp->sh_size;2033 ph->p_flags = PF_R;2034 ph->p_align = interp->sh_addralign;2035 }2036 2037 /* if dynamic section, then add corresponing program header */2038 if (dynamic) {2039 ElfW(Sym) *sym_end;2040 2041 ph = &phdr[phnum - 1];2042 2043 ph->p_type = PT_DYNAMIC;2044 ph->p_offset = dynamic->sh_offset;2045 ph->p_vaddr = dynamic->sh_addr;2046 ph->p_paddr = ph->p_vaddr;2047 ph->p_filesz = dynamic->sh_size;2048 ph->p_memsz = dynamic->sh_size;2049 ph->p_flags = PF_R | PF_W;2050 ph->p_align = dynamic->sh_addralign;2051 2052 /* put GOT dynamic section address */2053 put32(s1->got->data, dynamic->sh_addr);2054 2055 /* relocate the PLT */2056 if (file_type == TCC_OUTPUT_EXE2057 #if defined(TCC_OUTPUT_DLL_WITH_PLT)2058 || file_type == TCC_OUTPUT_DLL2059 #endif2060 ) {2061 uint8_t *p, *p_end;2062 2063 p = s1->plt->data;2064 p_end = p + s1->plt->data_offset;2065 if (p < p_end) {2066 #if defined(TCC_TARGET_I386)2067 put32(p + 2, get32(p + 2) + s1->got->sh_addr);2068 put32(p + 8, get32(p + 8) + s1->got->sh_addr);2069 p += 16;2070 while (p < p_end) {2071 put32(p + 2, get32(p + 2) + s1->got->sh_addr);2072 p += 16;2073 }2074 #elif defined(TCC_TARGET_X86_64)2075 int x = s1->got->sh_addr - s1->plt->sh_addr - 6;2076 put32(p + 2, get32(p + 2) + x);2077 put32(p + 8, get32(p + 8) + x - 6);2078 p += 16;2079 while (p < p_end) {2080 put32(p + 2, get32(p + 2) + x + s1->plt->data - p);2081 p += 16;2082 }2083 #elif defined(TCC_TARGET_ARM)2084 int x;2085 x=s1->got->sh_addr - s1->plt->sh_addr - 12;2086 p += 16;2087 while (p < p_end) {2088 if (get32(p) == 0x46c04778) /* PLT Thumb stub present */2089 p += 4;2090 put32(p + 12, x + get32(p + 12) + s1->plt->data - p);2091 p += 16;2092 }2093 #elif defined(TCC_TARGET_C67)2094 /* XXX: TODO */2095 #elif defined(TCC_TARGET_IL)2096 #else2097 #error unsupported CPU2098 #endif2099 }2100 }2101 2102 /* relocate symbols in .dynsym */2103 sym_end = (ElfW(Sym) *)(s1->dynsym->data + s1->dynsym->data_offset);2104 for(sym = (ElfW(Sym) *)s1->dynsym->data + 1;2105 sym < sym_end;2106 sym++) {2107 if (sym->st_shndx == SHN_UNDEF) {2108 /* relocate to the PLT if the symbol corresponds2109 to a PLT entry */2110 if (sym->st_value)2111 sym->st_value += s1->plt->sh_addr;2112 } else if (sym->st_shndx < SHN_LORESERVE) {2113 /* do symbol relocation */2114 sym->st_value += s1->sections[sym->st_shndx]->sh_addr;2115 }2116 }2117 2118 /* put dynamic section entries */2119 dynamic->data_offset = saved_dynamic_data_offset;2120 put_dt(dynamic, DT_HASH, s1->dynsym->hash->sh_addr);2121 put_dt(dynamic, DT_STRTAB, dynstr->sh_addr);2122 put_dt(dynamic, DT_SYMTAB, s1->dynsym->sh_addr);2123 put_dt(dynamic, DT_STRSZ, dynstr->data_offset);2124 put_dt(dynamic, DT_SYMENT, sizeof(ElfW(Sym)));2125 #ifdef TCC_TARGET_X86_642126 put_dt(dynamic, DT_RELA, rel_addr);2127 put_dt(dynamic, DT_RELASZ, rel_size);2128 put_dt(dynamic, DT_RELAENT, sizeof(ElfW_Rel));2129 #else2130 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)2131 put_dt(dynamic, DT_PLTGOT, s1->got->sh_addr);2132 put_dt(dynamic, DT_PLTRELSZ, rel_size);2133 put_dt(dynamic, DT_JMPREL, rel_addr);2134 put_dt(dynamic, DT_PLTREL, DT_REL);2135 put_dt(dynamic, DT_REL, bss_addr);2136 put_dt(dynamic, DT_RELSZ, bss_size);2137 #else2138 put_dt(dynamic, DT_REL, rel_addr);2139 put_dt(dynamic, DT_RELSZ, rel_size);2140 put_dt(dynamic, DT_RELENT, sizeof(ElfW_Rel));2141 #endif2142 #endif2143 if (s1->do_debug)2144 put_dt(dynamic, DT_DEBUG, 0);2145 put_dt(dynamic, DT_NULL, 0);2146 }2147 2148 ehdr.e_phentsize = sizeof(ElfW(Phdr));2149 ehdr.e_phnum = phnum;2150 ehdr.e_phoff = sizeof(ElfW(Ehdr));2151 1722 } 2152 1723 … … 2156 1727 if (phnum > 0 && (s->sh_flags & SHF_ALLOC)) 2157 1728 continue; 2158 sec tion_order[sh_order_index++] = i;2159 2160 file_offset = (file_offset + s->sh_addralign - 1) & 1729 sec_order[sh_order_index++] = i; 1730 1731 file_offset = (file_offset + s->sh_addralign - 1) & 2161 1732 ~(s->sh_addralign - 1); 2162 1733 s->sh_offset = file_offset; … … 2164 1735 file_offset += s->sh_size; 2165 1736 } 2166 2167 /* if building executable or DLL, then relocate each section 2168 except the GOT which is already relocated */ 2169 if (file_type != TCC_OUTPUT_OBJ) { 2170 relocate_syms(s1, 0); 2171 2172 if (s1->nb_errors != 0) { 2173 fail: 2174 ret = -1; 2175 goto the_end; 2176 } 2177 2178 /* relocate sections */ 2179 /* XXX: ignore sections with allocated relocations ? */ 2180 for(i = 1; i < s1->nb_sections; i++) { 2181 s = s1->sections[i]; 2182 if (s->reloc && s != s1->got) 2183 relocate_section(s1, s); 2184 } 2185 2186 /* relocate relocation entries if the relocation tables are 2187 allocated in the executable */ 2188 for(i = 1; i < s1->nb_sections; i++) { 2189 s = s1->sections[i]; 2190 if ((s->sh_flags & SHF_ALLOC) && 2191 s->sh_type == SHT_RELX) { 2192 relocate_rel(s1, s); 2193 } 2194 } 2195 2196 /* get entry point address */ 2197 if (file_type == TCC_OUTPUT_EXE) 2198 ehdr.e_entry = get_elf_sym_addr(s1, "_start", 1); 2199 else 2200 ehdr.e_entry = text_section->sh_addr; /* XXX: is it correct ? */ 2201 } 2202 if (file_type == TCC_OUTPUT_EXE && s1->static_link) 2203 fill_got(s1); 2204 2205 /* write elf file */ 1737 1738 return file_offset; 1739 } 1740 1741 static void fill_unloadable_phdr(ElfW(Phdr) *phdr, int phnum, Section *interp, 1742 Section *dynamic) 1743 { 1744 ElfW(Phdr) *ph; 1745 1746 /* if interpreter, then add corresponding program header */ 1747 if (interp) { 1748 ph = &phdr[0]; 1749 1750 ph->p_type = PT_PHDR; 1751 ph->p_offset = sizeof(ElfW(Ehdr)); 1752 ph->p_filesz = ph->p_memsz = phnum * sizeof(ElfW(Phdr)); 1753 ph->p_vaddr = interp->sh_addr - ph->p_filesz; 1754 ph->p_paddr = ph->p_vaddr; 1755 ph->p_flags = PF_R | PF_X; 1756 ph->p_align = 4; /* interp->sh_addralign; */ 1757 ph++; 1758 1759 ph->p_type = PT_INTERP; 1760 ph->p_offset = interp->sh_offset; 1761 ph->p_vaddr = interp->sh_addr; 1762 ph->p_paddr = ph->p_vaddr; 1763 ph->p_filesz = interp->sh_size; 1764 ph->p_memsz = interp->sh_size; 1765 ph->p_flags = PF_R; 1766 ph->p_align = interp->sh_addralign; 1767 } 1768 1769 /* if dynamic section, then add corresponding program header */ 1770 if (dynamic) { 1771 ph = &phdr[phnum - 1]; 1772 1773 ph->p_type = PT_DYNAMIC; 1774 ph->p_offset = dynamic->sh_offset; 1775 ph->p_vaddr = dynamic->sh_addr; 1776 ph->p_paddr = ph->p_vaddr; 1777 ph->p_filesz = dynamic->sh_size; 1778 ph->p_memsz = dynamic->sh_size; 1779 ph->p_flags = PF_R | PF_W; 1780 ph->p_align = dynamic->sh_addralign; 1781 } 1782 } 1783 1784 /* Fill the dynamic section with tags describing the address and size of 1785 sections */ 1786 static void fill_dynamic(TCCState *s1, struct dyn_inf *dyninf) 1787 { 1788 Section *dynamic = dyninf->dynamic; 1789 1790 /* put dynamic section entries */ 1791 put_dt(dynamic, DT_HASH, s1->dynsym->hash->sh_addr); 1792 put_dt(dynamic, DT_STRTAB, dyninf->dynstr->sh_addr); 1793 put_dt(dynamic, DT_SYMTAB, s1->dynsym->sh_addr); 1794 put_dt(dynamic, DT_STRSZ, dyninf->dynstr->data_offset); 1795 put_dt(dynamic, DT_SYMENT, sizeof(ElfW(Sym))); 1796 #if PTR_SIZE == 8 1797 put_dt(dynamic, DT_RELA, dyninf->rel_addr); 1798 put_dt(dynamic, DT_RELASZ, dyninf->rel_size); 1799 put_dt(dynamic, DT_RELAENT, sizeof(ElfW_Rel)); 1800 #else 1801 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) 1802 put_dt(dynamic, DT_PLTGOT, s1->got->sh_addr); 1803 put_dt(dynamic, DT_PLTRELSZ, dyninf->rel_size); 1804 put_dt(dynamic, DT_JMPREL, dyninf->rel_addr); 1805 put_dt(dynamic, DT_PLTREL, DT_REL); 1806 put_dt(dynamic, DT_REL, dyninf->bss_addr); 1807 put_dt(dynamic, DT_RELSZ, dyninf->bss_size); 1808 #else 1809 put_dt(dynamic, DT_REL, dyninf->rel_addr); 1810 put_dt(dynamic, DT_RELSZ, dyninf->rel_size); 1811 put_dt(dynamic, DT_RELENT, sizeof(ElfW_Rel)); 1812 #endif 1813 #endif 1814 if (s1->do_debug) 1815 put_dt(dynamic, DT_DEBUG, 0); 1816 put_dt(dynamic, DT_NULL, 0); 1817 } 1818 1819 /* Relocate remaining sections and symbols (that is those not related to 1820 dynamic linking) */ 1821 static int final_sections_reloc(TCCState *s1) 1822 { 1823 int i; 1824 Section *s; 1825 1826 relocate_syms(s1, s1->symtab, 0); 1827 1828 if (s1->nb_errors != 0) 1829 return -1; 1830 1831 /* relocate sections */ 1832 /* XXX: ignore sections with allocated relocations ? */ 1833 for(i = 1; i < s1->nb_sections; i++) { 1834 s = s1->sections[i]; 1835 #if defined(TCC_TARGET_I386) || defined(TCC_MUSL) 1836 if (s->reloc && s != s1->got && (s->sh_flags & SHF_ALLOC)) //gr 1837 /* On X86 gdb 7.3 works in any case but gdb 6.6 will crash if SHF_ALLOC 1838 checking is removed */ 1839 #else 1840 if (s->reloc && s != s1->got) 1841 /* On X86_64 gdb 7.3 will crash if SHF_ALLOC checking is present */ 1842 #endif 1843 relocate_section(s1, s); 1844 } 1845 1846 /* relocate relocation entries if the relocation tables are 1847 allocated in the executable */ 1848 for(i = 1; i < s1->nb_sections; i++) { 1849 s = s1->sections[i]; 1850 if ((s->sh_flags & SHF_ALLOC) && 1851 s->sh_type == SHT_RELX) { 1852 relocate_rel(s1, s); 1853 } 1854 } 1855 return 0; 1856 } 1857 1858 /* Create an ELF file on disk. 1859 This function handle ELF specific layout requirements */ 1860 static void tcc_output_elf(TCCState *s1, FILE *f, int phnum, ElfW(Phdr) *phdr, 1861 int file_offset, int *sec_order) 1862 { 1863 int i, shnum, offset, size, file_type; 1864 Section *s; 1865 ElfW(Ehdr) ehdr; 1866 ElfW(Shdr) shdr, *sh; 1867 1868 file_type = s1->output_type; 1869 shnum = s1->nb_sections; 1870 1871 memset(&ehdr, 0, sizeof(ehdr)); 1872 1873 if (phnum > 0) { 1874 ehdr.e_phentsize = sizeof(ElfW(Phdr)); 1875 ehdr.e_phnum = phnum; 1876 ehdr.e_phoff = sizeof(ElfW(Ehdr)); 1877 } 1878 1879 /* align to 4 */ 1880 file_offset = (file_offset + 3) & -4; 1881 1882 /* fill header */ 1883 ehdr.e_ident[0] = ELFMAG0; 1884 ehdr.e_ident[1] = ELFMAG1; 1885 ehdr.e_ident[2] = ELFMAG2; 1886 ehdr.e_ident[3] = ELFMAG3; 1887 ehdr.e_ident[4] = ELFCLASSW; 1888 ehdr.e_ident[5] = ELFDATA2LSB; 1889 ehdr.e_ident[6] = EV_CURRENT; 1890 #if !defined(TCC_TARGET_PE) && (defined(__FreeBSD__) || defined(__FreeBSD_kernel__)) 1891 /* FIXME: should set only for freebsd _target_, but we exclude only PE target */ 1892 ehdr.e_ident[EI_OSABI] = ELFOSABI_FREEBSD; 1893 #endif 1894 #ifdef TCC_TARGET_ARM 1895 #ifdef TCC_ARM_EABI 1896 ehdr.e_ident[EI_OSABI] = 0; 1897 ehdr.e_flags = EF_ARM_EABI_VER4; 1898 if (file_type == TCC_OUTPUT_EXE || file_type == TCC_OUTPUT_DLL) 1899 ehdr.e_flags |= EF_ARM_HASENTRY; 1900 if (s1->float_abi == ARM_HARD_FLOAT) 1901 ehdr.e_flags |= EF_ARM_VFP_FLOAT; 1902 else 1903 ehdr.e_flags |= EF_ARM_SOFT_FLOAT; 1904 #else 1905 ehdr.e_ident[EI_OSABI] = ELFOSABI_ARM; 1906 #endif 1907 #endif 1908 switch(file_type) { 1909 default: 1910 case TCC_OUTPUT_EXE: 1911 ehdr.e_type = ET_EXEC; 1912 ehdr.e_entry = get_elf_sym_addr(s1, "_start", 1); 1913 break; 1914 case TCC_OUTPUT_DLL: 1915 ehdr.e_type = ET_DYN; 1916 ehdr.e_entry = text_section->sh_addr; /* XXX: is it correct ? */ 1917 break; 1918 case TCC_OUTPUT_OBJ: 1919 ehdr.e_type = ET_REL; 1920 break; 1921 } 1922 ehdr.e_machine = EM_TCC_TARGET; 1923 ehdr.e_version = EV_CURRENT; 1924 ehdr.e_shoff = file_offset; 1925 ehdr.e_ehsize = sizeof(ElfW(Ehdr)); 1926 ehdr.e_shentsize = sizeof(ElfW(Shdr)); 1927 ehdr.e_shnum = shnum; 1928 ehdr.e_shstrndx = shnum - 1; 1929 1930 fwrite(&ehdr, 1, sizeof(ElfW(Ehdr)), f); 1931 fwrite(phdr, 1, phnum * sizeof(ElfW(Phdr)), f); 1932 offset = sizeof(ElfW(Ehdr)) + phnum * sizeof(ElfW(Phdr)); 1933 1934 sort_syms(s1, symtab_section); 1935 for(i = 1; i < s1->nb_sections; i++) { 1936 s = s1->sections[sec_order[i]]; 1937 if (s->sh_type != SHT_NOBITS) { 1938 while (offset < s->sh_offset) { 1939 fputc(0, f); 1940 offset++; 1941 } 1942 size = s->sh_size; 1943 if (size) 1944 fwrite(s->data, 1, size, f); 1945 offset += size; 1946 } 1947 } 1948 1949 /* output section headers */ 1950 while (offset < ehdr.e_shoff) { 1951 fputc(0, f); 1952 offset++; 1953 } 1954 1955 for(i = 0; i < s1->nb_sections; i++) { 1956 sh = &shdr; 1957 memset(sh, 0, sizeof(ElfW(Shdr))); 1958 s = s1->sections[i]; 1959 if (s) { 1960 sh->sh_name = s->sh_name; 1961 sh->sh_type = s->sh_type; 1962 sh->sh_flags = s->sh_flags; 1963 sh->sh_entsize = s->sh_entsize; 1964 sh->sh_info = s->sh_info; 1965 if (s->link) 1966 sh->sh_link = s->link->sh_num; 1967 sh->sh_addralign = s->sh_addralign; 1968 sh->sh_addr = s->sh_addr; 1969 sh->sh_offset = s->sh_offset; 1970 sh->sh_size = s->sh_size; 1971 } 1972 fwrite(sh, 1, sizeof(ElfW(Shdr)), f); 1973 } 1974 } 1975 1976 /* Write an elf, coff or "binary" file */ 1977 static int tcc_write_elf_file(TCCState *s1, const char *filename, int phnum, 1978 ElfW(Phdr) *phdr, int file_offset, int *sec_order) 1979 { 1980 int fd, mode, file_type; 1981 FILE *f; 1982 1983 file_type = s1->output_type; 2206 1984 if (file_type == TCC_OUTPUT_OBJ) 2207 1985 mode = 0666; … … 2209 1987 mode = 0777; 2210 1988 unlink(filename); 2211 fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, mode); 1989 fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, mode); 2212 1990 if (fd < 0) { 2213 1991 tcc_error_noabort("could not write '%s'", filename); 2214 goto fail;1992 return -1; 2215 1993 } 2216 1994 f = fdopen(fd, "wb"); … … 2219 1997 2220 1998 #ifdef TCC_TARGET_COFF 2221 if (s1->output_format == TCC_OUTPUT_FORMAT_COFF) {1999 if (s1->output_format == TCC_OUTPUT_FORMAT_COFF) 2222 2000 tcc_output_coff(s1, f); 2223 } else 2224 #endif 2225 if (s1->output_format == TCC_OUTPUT_FORMAT_ELF) { 2226 sort_syms(s1, symtab_section); 2227 2228 /* align to 4 */ 2229 file_offset = (file_offset + 3) & -4; 2230 2231 /* fill header */ 2232 ehdr.e_ident[0] = ELFMAG0; 2233 ehdr.e_ident[1] = ELFMAG1; 2234 ehdr.e_ident[2] = ELFMAG2; 2235 ehdr.e_ident[3] = ELFMAG3; 2236 ehdr.e_ident[4] = ELFCLASSW; 2237 ehdr.e_ident[5] = ELFDATA2LSB; 2238 ehdr.e_ident[6] = EV_CURRENT; 2239 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) 2240 ehdr.e_ident[EI_OSABI] = ELFOSABI_FREEBSD; 2241 #endif 2242 #ifdef TCC_TARGET_ARM 2243 #ifdef TCC_ARM_EABI 2244 ehdr.e_ident[EI_OSABI] = 0; 2245 ehdr.e_flags = 4 << 24; 2246 #else 2247 ehdr.e_ident[EI_OSABI] = ELFOSABI_ARM; 2248 #endif 2249 #endif 2250 switch(file_type) { 2251 default: 2252 case TCC_OUTPUT_EXE: 2253 ehdr.e_type = ET_EXEC; 2254 break; 2255 case TCC_OUTPUT_DLL: 2256 ehdr.e_type = ET_DYN; 2257 break; 2258 case TCC_OUTPUT_OBJ: 2259 ehdr.e_type = ET_REL; 2260 break; 2261 } 2262 ehdr.e_machine = EM_TCC_TARGET; 2263 ehdr.e_version = EV_CURRENT; 2264 ehdr.e_shoff = file_offset; 2265 ehdr.e_ehsize = sizeof(ElfW(Ehdr)); 2266 ehdr.e_shentsize = sizeof(ElfW(Shdr)); 2267 ehdr.e_shnum = shnum; 2268 ehdr.e_shstrndx = shnum - 1; 2269 2270 fwrite(&ehdr, 1, sizeof(ElfW(Ehdr)), f); 2271 fwrite(phdr, 1, phnum * sizeof(ElfW(Phdr)), f); 2272 offset = sizeof(ElfW(Ehdr)) + phnum * sizeof(ElfW(Phdr)); 2273 2274 for(i=1;i<s1->nb_sections;i++) { 2275 s = s1->sections[section_order[i]]; 2276 if (s->sh_type != SHT_NOBITS) { 2277 if (s->sh_type == SHT_DYNSYM) 2278 patch_dynsym_undef(s1, s); 2279 while (offset < s->sh_offset) { 2280 fputc(0, f); 2281 offset++; 2001 else 2002 #endif 2003 if (s1->output_format == TCC_OUTPUT_FORMAT_ELF) 2004 tcc_output_elf(s1, f, phnum, phdr, file_offset, sec_order); 2005 else 2006 tcc_output_binary(s1, f, sec_order); 2007 fclose(f); 2008 2009 return 0; 2010 } 2011 2012 /* Sort section headers by assigned sh_addr, remove sections 2013 that we aren't going to output. */ 2014 static void tidy_section_headers(TCCState *s1, int *sec_order) 2015 { 2016 int i, nnew, l, *backmap; 2017 Section **snew, *s; 2018 ElfW(Sym) *sym; 2019 2020 snew = tcc_malloc(s1->nb_sections * sizeof(snew[0])); 2021 backmap = tcc_malloc(s1->nb_sections * sizeof(backmap[0])); 2022 for (i = 0, nnew = 0, l = s1->nb_sections; i < s1->nb_sections; i++) { 2023 s = s1->sections[sec_order[i]]; 2024 if (!i || s->sh_name) { 2025 backmap[sec_order[i]] = nnew; 2026 snew[nnew] = s; 2027 ++nnew; 2028 } else { 2029 backmap[sec_order[i]] = 0; 2030 snew[--l] = s; 2031 } 2032 } 2033 for (i = 0; i < nnew; i++) { 2034 s = snew[i]; 2035 if (s) { 2036 s->sh_num = i; 2037 if (s->sh_type == SHT_RELX) 2038 s->sh_info = backmap[s->sh_info]; 2039 } 2040 } 2041 2042 for_each_elem(symtab_section, 1, sym, ElfW(Sym)) 2043 if (sym->st_shndx != SHN_UNDEF && sym->st_shndx < SHN_LORESERVE) 2044 sym->st_shndx = backmap[sym->st_shndx]; 2045 if( !s1->static_link ) { 2046 for_each_elem(s1->dynsym, 1, sym, ElfW(Sym)) 2047 if (sym->st_shndx != SHN_UNDEF && sym->st_shndx < SHN_LORESERVE) 2048 sym->st_shndx = backmap[sym->st_shndx]; 2049 } 2050 for (i = 0; i < s1->nb_sections; i++) 2051 sec_order[i] = i; 2052 tcc_free(s1->sections); 2053 s1->sections = snew; 2054 s1->nb_sections = nnew; 2055 tcc_free(backmap); 2056 } 2057 2058 /* Output an elf, coff or binary file */ 2059 /* XXX: suppress unneeded sections */ 2060 static int elf_output_file(TCCState *s1, const char *filename) 2061 { 2062 int i, ret, phnum, shnum, file_type, file_offset, *sec_order; 2063 struct dyn_inf dyninf = {0}; 2064 ElfW(Phdr) *phdr; 2065 ElfW(Sym) *sym; 2066 Section *strsec, *interp, *dynamic, *dynstr; 2067 int textrel; 2068 2069 file_type = s1->output_type; 2070 s1->nb_errors = 0; 2071 ret = -1; 2072 phdr = NULL; 2073 sec_order = NULL; 2074 interp = dynamic = dynstr = NULL; /* avoid warning */ 2075 textrel = 0; 2076 2077 if (file_type != TCC_OUTPUT_OBJ) { 2078 /* if linking, also link in runtime libraries (libc, libgcc, etc.) */ 2079 tcc_add_runtime(s1); 2080 resolve_common_syms(s1); 2081 2082 if (!s1->static_link) { 2083 if (file_type == TCC_OUTPUT_EXE) { 2084 char *ptr; 2085 /* allow override the dynamic loader */ 2086 const char *elfint = getenv("LD_SO"); 2087 if (elfint == NULL) 2088 elfint = DEFAULT_ELFINTERP(s1); 2089 /* add interpreter section only if executable */ 2090 interp = new_section(s1, ".interp", SHT_PROGBITS, SHF_ALLOC); 2091 interp->sh_addralign = 1; 2092 ptr = section_ptr_add(interp, 1 + strlen(elfint)); 2093 strcpy(ptr, elfint); 2094 } 2095 2096 /* add dynamic symbol table */ 2097 s1->dynsym = new_symtab(s1, ".dynsym", SHT_DYNSYM, SHF_ALLOC, 2098 ".dynstr", 2099 ".hash", SHF_ALLOC); 2100 dynstr = s1->dynsym->link; 2101 2102 /* add dynamic section */ 2103 dynamic = new_section(s1, ".dynamic", SHT_DYNAMIC, 2104 SHF_ALLOC | SHF_WRITE); 2105 dynamic->link = dynstr; 2106 dynamic->sh_entsize = sizeof(ElfW(Dyn)); 2107 2108 build_got(s1); 2109 2110 if (file_type == TCC_OUTPUT_EXE) { 2111 bind_exe_dynsyms(s1); 2112 if (s1->nb_errors) 2113 goto the_end; 2114 bind_libs_dynsyms(s1); 2115 } else { 2116 /* shared library case: simply export all global symbols */ 2117 export_global_syms(s1); 2118 } 2119 } 2120 build_got_entries(s1); 2121 } 2122 2123 /* we add a section for symbols */ 2124 strsec = new_section(s1, ".shstrtab", SHT_STRTAB, 0); 2125 put_elf_str(strsec, ""); 2126 2127 /* Allocate strings for section names */ 2128 textrel = alloc_sec_names(s1, file_type, strsec); 2129 2130 if (dynamic) { 2131 /* add a list of needed dlls */ 2132 for(i = 0; i < s1->nb_loaded_dlls; i++) { 2133 DLLReference *dllref = s1->loaded_dlls[i]; 2134 if (dllref->level == 0) 2135 put_dt(dynamic, DT_NEEDED, put_elf_str(dynstr, dllref->name)); 2136 } 2137 2138 if (s1->rpath) 2139 put_dt(dynamic, s1->enable_new_dtags ? DT_RUNPATH : DT_RPATH, 2140 put_elf_str(dynstr, s1->rpath)); 2141 2142 if (file_type == TCC_OUTPUT_DLL) { 2143 if (s1->soname) 2144 put_dt(dynamic, DT_SONAME, put_elf_str(dynstr, s1->soname)); 2145 /* XXX: currently, since we do not handle PIC code, we 2146 must relocate the readonly segments */ 2147 if (textrel) 2148 put_dt(dynamic, DT_TEXTREL, 0); 2149 } 2150 2151 if (s1->symbolic) 2152 put_dt(dynamic, DT_SYMBOLIC, 0); 2153 2154 dyninf.dynamic = dynamic; 2155 dyninf.dynstr = dynstr; 2156 /* remember offset and reserve space for 2nd call below */ 2157 dyninf.data_offset = dynamic->data_offset; 2158 fill_dynamic(s1, &dyninf); 2159 dynamic->sh_size = dynamic->data_offset; 2160 dynstr->sh_size = dynstr->data_offset; 2161 } 2162 2163 /* compute number of program headers */ 2164 if (file_type == TCC_OUTPUT_OBJ) 2165 phnum = 0; 2166 else if (file_type == TCC_OUTPUT_DLL) 2167 phnum = 3; 2168 else if (s1->static_link) 2169 phnum = 2; 2170 else 2171 phnum = 5; 2172 2173 /* allocate program segment headers */ 2174 phdr = tcc_mallocz(phnum * sizeof(ElfW(Phdr))); 2175 2176 /* compute number of sections */ 2177 shnum = s1->nb_sections; 2178 2179 /* this array is used to reorder sections in the output file */ 2180 sec_order = tcc_malloc(sizeof(int) * shnum); 2181 sec_order[0] = 0; 2182 2183 /* compute section to program header mapping */ 2184 file_offset = layout_sections(s1, phdr, phnum, interp, strsec, &dyninf, 2185 sec_order); 2186 2187 /* Fill remaining program header and finalize relocation related to dynamic 2188 linking. */ 2189 if (file_type != TCC_OUTPUT_OBJ) { 2190 fill_unloadable_phdr(phdr, phnum, interp, dynamic); 2191 if (dynamic) { 2192 dynamic->data_offset = dyninf.data_offset; 2193 fill_dynamic(s1, &dyninf); 2194 2195 /* put in GOT the dynamic section address and relocate PLT */ 2196 write32le(s1->got->data, dynamic->sh_addr); 2197 if (file_type == TCC_OUTPUT_EXE 2198 || (RELOCATE_DLLPLT && file_type == TCC_OUTPUT_DLL)) 2199 relocate_plt(s1); 2200 2201 /* relocate symbols in .dynsym now that final addresses are known */ 2202 for_each_elem(s1->dynsym, 1, sym, ElfW(Sym)) { 2203 if (sym->st_shndx != SHN_UNDEF && sym->st_shndx < SHN_LORESERVE) { 2204 /* do symbol relocation */ 2205 sym->st_value += s1->sections[sym->st_shndx]->sh_addr; 2282 2206 } 2283 size = s->sh_size; 2284 fwrite(s->data, 1, size, f); 2285 offset += size; 2286 } 2287 } 2288 2289 /* output section headers */ 2290 while (offset < ehdr.e_shoff) { 2291 fputc(0, f); 2292 offset++; 2293 } 2294 2295 for(i=0;i<s1->nb_sections;i++) { 2296 sh = &shdr; 2297 memset(sh, 0, sizeof(ElfW(Shdr))); 2298 s = s1->sections[i]; 2299 if (s) { 2300 sh->sh_name = s->sh_name; 2301 sh->sh_type = s->sh_type; 2302 sh->sh_flags = s->sh_flags; 2303 sh->sh_entsize = s->sh_entsize; 2304 sh->sh_info = s->sh_info; 2305 if (s->link) 2306 sh->sh_link = s->link->sh_num; 2307 sh->sh_addralign = s->sh_addralign; 2308 sh->sh_addr = s->sh_addr; 2309 sh->sh_offset = s->sh_offset; 2310 sh->sh_size = s->sh_size; 2311 } 2312 fwrite(sh, 1, sizeof(ElfW(Shdr)), f); 2313 } 2314 } else { 2315 tcc_output_binary(s1, f, section_order); 2316 } 2317 fclose(f); 2318 2319 ret = 0; 2207 } 2208 } 2209 2210 /* if building executable or DLL, then relocate each section 2211 except the GOT which is already relocated */ 2212 ret = final_sections_reloc(s1); 2213 if (ret) 2214 goto the_end; 2215 tidy_section_headers(s1, sec_order); 2216 2217 /* Perform relocation to GOT or PLT entries */ 2218 if (file_type == TCC_OUTPUT_EXE && s1->static_link) 2219 fill_got(s1); 2220 else if (s1->got) 2221 fill_local_got_entries(s1); 2222 } 2223 2224 /* Create the ELF file with name 'filename' */ 2225 ret = tcc_write_elf_file(s1, filename, phnum, phdr, file_offset, sec_order); 2226 s1->nb_sections = shnum; 2320 2227 the_end: 2321 tcc_free(s1->symtab_to_dynsym); 2322 tcc_free(section_order); 2228 tcc_free(sec_order); 2323 2229 tcc_free(phdr); 2324 tcc_free(s1->sym_attrs);2325 2230 return ret; 2326 2231 } … … 2334 2239 } else 2335 2240 #endif 2336 {2337 2241 ret = elf_output_file(s, filename); 2338 }2339 2242 return ret; 2340 2243 } … … 2357 2260 } SectionMergeInfo; 2358 2261 2262 ST_FUNC int tcc_object_type(int fd, ElfW(Ehdr) *h) 2263 { 2264 int size = read(fd, h, sizeof *h); 2265 if (size == sizeof *h && 0 == memcmp(h, ELFMAG, 4)) { 2266 if (h->e_type == ET_REL) 2267 return AFF_BINTYPE_REL; 2268 if (h->e_type == ET_DYN) 2269 return AFF_BINTYPE_DYN; 2270 } else if (size >= 8) { 2271 if (0 == memcmp(h, ARMAG, 8)) 2272 return AFF_BINTYPE_AR; 2273 #ifdef TCC_TARGET_COFF 2274 if (((struct filehdr*)h)->f_magic == COFF_C67_MAGIC) 2275 return AFF_BINTYPE_C67; 2276 #endif 2277 } 2278 return 0; 2279 } 2280 2359 2281 /* load an object file and merge it with current files */ 2360 2282 /* XXX: handle correctly stab (debug) info */ 2361 ST_FUNC int tcc_load_object_file(TCCState *s1, 2283 ST_FUNC int tcc_load_object_file(TCCState *s1, 2362 2284 int fd, unsigned long file_offset) 2363 { 2285 { 2364 2286 ElfW(Ehdr) ehdr; 2365 2287 ElfW(Shdr) *shdr, *sh; 2366 int size, i, j, offset, offseti, nb_syms, sym_index, ret ;2288 int size, i, j, offset, offseti, nb_syms, sym_index, ret, seencompressed; 2367 2289 unsigned char *strsec, *strtab; 2368 2290 int *old_to_new_syms; … … 2370 2292 SectionMergeInfo *sm_table, *sm; 2371 2293 ElfW(Sym) *sym, *symtab; 2372 ElfW_Rel *rel , *rel_end;2294 ElfW_Rel *rel; 2373 2295 Section *s; 2374 2296 … … 2378 2300 stab_index = stabstr_index = 0; 2379 2301 2380 if (read(fd, &ehdr, sizeof(ehdr)) != sizeof(ehdr)) 2381 goto fail1; 2382 if (ehdr.e_ident[0] != ELFMAG0 || 2383 ehdr.e_ident[1] != ELFMAG1 || 2384 ehdr.e_ident[2] != ELFMAG2 || 2385 ehdr.e_ident[3] != ELFMAG3) 2386 goto fail1; 2387 /* test if object file */ 2388 if (ehdr.e_type != ET_REL) 2302 lseek(fd, file_offset, SEEK_SET); 2303 if (tcc_object_type(fd, &ehdr) != AFF_BINTYPE_REL) 2389 2304 goto fail1; 2390 2305 /* test CPU specific stuff */ … … 2396 2311 } 2397 2312 /* read sections */ 2398 shdr = load_data(fd, file_offset + ehdr.e_shoff, 2313 shdr = load_data(fd, file_offset + ehdr.e_shoff, 2399 2314 sizeof(ElfW(Shdr)) * ehdr.e_shnum); 2400 2315 sm_table = tcc_mallocz(sizeof(SectionMergeInfo) * ehdr.e_shnum); 2401 2316 2402 2317 /* load section names */ 2403 2318 sh = &shdr[ehdr.e_shstrndx]; … … 2409 2324 strtab = NULL; 2410 2325 nb_syms = 0; 2326 seencompressed = 0; 2411 2327 for(i = 1; i < ehdr.e_shnum; i++) { 2412 2328 sh = &shdr[i]; … … 2426 2342 strtab = load_data(fd, file_offset + sh->sh_offset, sh->sh_size); 2427 2343 } 2428 } 2429 2344 if (sh->sh_flags & SHF_COMPRESSED) 2345 seencompressed = 1; 2346 } 2347 2430 2348 /* now examine each section and try to merge its content with the 2431 2349 ones in memory */ … … 2435 2353 continue; 2436 2354 sh = &shdr[i]; 2437 sh_name = strsec + sh->sh_name;2355 sh_name = (char *) strsec + sh->sh_name; 2438 2356 /* ignore sections types we do not handle */ 2439 2357 if (sh->sh_type != SHT_PROGBITS && 2440 sh->sh_type != SHT_RELX && 2358 sh->sh_type != SHT_RELX && 2441 2359 #ifdef TCC_ARM_EABI 2442 2360 sh->sh_type != SHT_ARM_EXIDX && 2443 2361 #endif 2444 sh->sh_type != SHT_NOBITS && 2362 sh->sh_type != SHT_NOBITS && 2445 2363 sh->sh_type != SHT_PREINIT_ARRAY && 2446 2364 sh->sh_type != SHT_INIT_ARRAY && … … 2449 2367 ) 2450 2368 continue; 2369 if (seencompressed 2370 && (!strncmp(sh_name, ".debug_", sizeof(".debug_")-1) 2371 || (sh->sh_type == SHT_RELX 2372 && !strncmp((char*)strsec + shdr[sh->sh_info].sh_name, 2373 ".debug_", sizeof(".debug_")-1)))) 2374 continue; 2451 2375 if (sh->sh_addralign < 1) 2452 2376 sh->sh_addralign = 1; … … 2455 2379 s = s1->sections[j]; 2456 2380 if (!strcmp(s->name, sh_name)) { 2457 if (!strncmp(sh_name, ".gnu.linkonce", 2381 if (!strncmp(sh_name, ".gnu.linkonce", 2458 2382 sizeof(".gnu.linkonce") - 1)) { 2459 2383 /* if a 'linkonce' section is already present, we … … 2469 2393 } 2470 2394 /* not found: create new section */ 2471 s = new_section(s1, sh_name, sh->sh_type, sh->sh_flags );2395 s = new_section(s1, sh_name, sh->sh_type, sh->sh_flags & ~SHF_GROUP); 2472 2396 /* take as much info as possible from the section. sh_link and 2473 2397 sh_info will be updated later */ … … 2514 2438 } 2515 2439 2516 /* //gr relocate stab strings */2440 /* gr relocate stab strings */ 2517 2441 if (stab_index && stabstr_index) { 2518 2442 Stab_Sym *a, *b; … … 2522 2446 b = (Stab_Sym *)(s->data + s->data_offset); 2523 2447 o = sm_table[stabstr_index].offset; 2524 while (a < b) 2448 while (a < b) 2525 2449 a->n_strx += o, a++; 2526 2450 } … … 2556 2480 correct relocations */ 2557 2481 if (ELFW(ST_BIND)(sym->st_info) != STB_LOCAL) { 2558 name = strtab + sym->st_name;2482 name = (char *) strtab + sym->st_name; 2559 2483 sym_index = find_elf_sym(symtab_section, name); 2560 2484 if (sym_index) … … 2572 2496 } 2573 2497 /* add symbol */ 2574 name = strtab + sym->st_name;2575 sym_index = add_elf_sym(symtab_section, sym->st_value, sym->st_size,2576 sym->st_info, sym->st_other, 2498 name = (char *) strtab + sym->st_name; 2499 sym_index = set_elf_sym(symtab_section, sym->st_value, sym->st_size, 2500 sym->st_info, sym->st_other, 2577 2501 sym->st_shndx, name); 2578 2502 old_to_new_syms[i] = sym_index; … … 2590 2514 /* take relocation offset information */ 2591 2515 offseti = sm_table[sh->sh_info].offset; 2592 rel_end = (ElfW_Rel *)(s->data + s->data_offset); 2593 for(rel = (ElfW_Rel *)(s->data + offset); 2594 rel < rel_end; 2595 rel++) { 2516 for_each_elem(s, (offset / sizeof(*rel)), rel, ElfW_Rel) { 2596 2517 int type; 2597 2518 unsigned sym_index; … … 2624 2545 instructions. Other case of instructions referencing a PLT 2625 2546 entry require to add a Thumb stub before the PLT entry to 2626 switch to ARM mode. We set bit 0 of the got offset of a2627 symbol to indicate such a case. */2547 switch to ARM mode. We set bit plt_thumb_stub of the 2548 attribute of a symbol to indicate such a case. */ 2628 2549 if (type == R_ARM_THM_JUMP24) 2629 alloc_sym_attr(s1, sym_index)->plt_thumb_stub = 1;2550 get_sym_attr(s1, sym_index, 1)->plt_thumb_stub = 1; 2630 2551 #endif 2631 2552 } … … 2635 2556 } 2636 2557 } 2637 2558 2638 2559 ret = 0; 2639 2560 the_end: … … 2662 2583 } 2663 2584 2585 static long get_be64(const uint8_t *b) 2586 { 2587 long long ret = get_be32(b); 2588 ret = (ret << 32) | (unsigned)get_be32(b+4); 2589 return (long)ret; 2590 } 2591 2664 2592 /* load only the objects which resolve undefined symbols */ 2665 static int tcc_load_alacarte(TCCState *s1, int fd, int size )2666 { 2667 inti, bound, nsyms, sym_index, off, ret;2593 static int tcc_load_alacarte(TCCState *s1, int fd, int size, int entrysize) 2594 { 2595 long i, bound, nsyms, sym_index, off, ret; 2668 2596 uint8_t *data; 2669 2597 const char *ar_names, *p; … … 2674 2602 if (read(fd, data, size) != size) 2675 2603 goto fail; 2676 nsyms = get_be32(data);2677 ar_index = data + 4;2678 ar_names = ar_index + nsyms * 4;2604 nsyms = entrysize == 4 ? get_be32(data) : get_be64(data); 2605 ar_index = data + entrysize; 2606 ar_names = (char *) ar_index + nsyms * entrysize; 2679 2607 2680 2608 do { … … 2685 2613 sym = &((ElfW(Sym) *)symtab_section->data)[sym_index]; 2686 2614 if(sym->st_shndx == SHN_UNDEF) { 2687 off = get_be32(ar_index + i * 4) + sizeof(ArchiveHeader);2688 #if 0 2689 printf("%5d\t%s\t%08x\n", i, p, sym->st_shndx); 2690 #endif 2615 off = (entrysize == 4 2616 ? get_be32(ar_index + i * 4) 2617 : get_be64(ar_index + i * 8)) 2618 + sizeof(ArchiveHeader); 2691 2619 ++bound; 2692 lseek(fd, off, SEEK_SET);2693 2620 if(tcc_load_object_file(s1, fd, off) < 0) { 2694 2621 fail: … … 2718 2645 /* skip magic which was already checked */ 2719 2646 read(fd, magic, sizeof(magic)); 2720 2647 2721 2648 for(;;) { 2722 2649 len = read(fd, &hdr, sizeof(hdr)); … … 2736 2663 } 2737 2664 ar_name[i + 1] = '\0'; 2738 // printf("name='%s' size=%d %s\n", ar_name, size, ar_size);2739 2665 file_offset = lseek(fd, 0, SEEK_CUR); 2740 2666 /* align to even */ … … 2743 2669 /* coff symbol table : we handle it */ 2744 2670 if(s1->alacarte_link) 2745 return tcc_load_alacarte(s1, fd, size); 2746 } else if (!strcmp(ar_name, "//") || 2747 !strcmp(ar_name, "__.SYMDEF") || 2748 !strcmp(ar_name, "__.SYMDEF/") || 2749 !strcmp(ar_name, "ARFILENAMES/")) { 2750 /* skip symbol table or archive names */ 2671 return tcc_load_alacarte(s1, fd, size, 4); 2672 } else if (!strcmp(ar_name, "/SYM64/")) { 2673 if(s1->alacarte_link) 2674 return tcc_load_alacarte(s1, fd, size, 8); 2751 2675 } else { 2752 if (tcc_load_object_file(s1, fd, file_offset) < 0) 2753 return -1; 2676 ElfW(Ehdr) ehdr; 2677 if (tcc_object_type(fd, &ehdr) == AFF_BINTYPE_REL) { 2678 if (tcc_load_object_file(s1, fd, file_offset) < 0) 2679 return -1; 2680 } 2754 2681 } 2755 2682 lseek(fd, file_offset + size, SEEK_SET); … … 2763 2690 the generated ELF file) */ 2764 2691 ST_FUNC int tcc_load_dll(TCCState *s1, int fd, const char *filename, int level) 2765 { 2692 { 2766 2693 ElfW(Ehdr) ehdr; 2767 2694 ElfW(Shdr) *shdr, *sh, *sh1; … … 2772 2699 const char *name, *soname; 2773 2700 DLLReference *dllref; 2774 2701 2775 2702 read(fd, &ehdr, sizeof(ehdr)); 2776 2703 … … 2807 2734 } 2808 2735 } 2809 2736 2810 2737 /* compute the real library name */ 2811 2738 soname = tcc_basename(filename); 2812 2739 2813 2740 for(i = 0, dt = dynamic; i < nb_dts; i++, dt++) { 2814 2741 if (dt->d_tag == DT_SONAME) { 2815 soname = dynstr + dt->d_un.d_val;2742 soname = (char *) dynstr + dt->d_un.d_val; 2816 2743 } 2817 2744 } … … 2828 2755 } 2829 2756 } 2830 2831 // printf("loading dll '%s'\n", soname);2832 2757 2833 2758 /* add the dll and its level */ … … 2835 2760 dllref->level = level; 2836 2761 strcpy(dllref->name, soname); 2837 dynarray_add( (void ***)&s1->loaded_dlls, &s1->nb_loaded_dlls, dllref);2762 dynarray_add(&s1->loaded_dlls, &s1->nb_loaded_dlls, dllref); 2838 2763 2839 2764 /* add dynamic symbols in dynsym_section */ … … 2842 2767 if (sym_bind == STB_LOCAL) 2843 2768 continue; 2844 name = dynstr + sym->st_name;2845 add_elf_sym(s1->dynsymtab_section, sym->st_value, sym->st_size,2769 name = (char *) dynstr + sym->st_name; 2770 set_elf_sym(s1->dynsymtab_section, sym->st_value, sym->st_size, 2846 2771 sym->st_info, sym->st_other, sym->st_shndx, name); 2847 2772 } … … 2851 2776 switch(dt->d_tag) { 2852 2777 case DT_NEEDED: 2853 name = dynstr + dt->d_un.d_val;2778 name = (char *) dynstr + dt->d_un.d_val; 2854 2779 for(j = 0; j < s1->nb_loaded_dlls; j++) { 2855 2780 dllref = s1->loaded_dlls[j]; … … 2906 2831 } 2907 2832 break; 2833 case '\\': 2834 ch = handle_eob(); 2835 if (ch != '\\') 2836 goto redo; 2837 /* fall through */ 2908 2838 /* case 'a' ... 'z': */ 2909 2839 case 'a': … … 2961 2891 case 'Z': 2962 2892 case '_': 2963 case '\\':2964 2893 case '.': 2965 2894 case '$': … … 2989 2918 break; 2990 2919 } 2991 #if 02992 printf("tok=%c %d\n", c, c);2993 if (c == LD_TOK_NAME)2994 printf(" name=%s\n", name);2995 #endif2996 2920 return c; 2997 2921 } … … 2999 2923 static int ld_add_file(TCCState *s1, const char filename[]) 3000 2924 { 3001 int ret; 3002 3003 ret = tcc_add_file_internal(s1, filename, 0); 3004 if (ret) 3005 ret = tcc_add_dll(s1, filename, 0); 3006 return ret; 2925 if (filename[0] == '/') { 2926 if (CONFIG_SYSROOT[0] == '\0' 2927 && tcc_add_file_internal(s1, filename, AFF_TYPE_BIN) == 0) 2928 return 0; 2929 filename = tcc_basename(filename); 2930 } 2931 return tcc_add_dll(s1, filename, 0); 3007 2932 } 3008 2933 … … 3066 2991 if (group) { 3067 2992 /* Add the filename *and* the libname to avoid future conversions */ 3068 dynarray_add( (void ***)&libs, &nblibs, tcc_strdup(filename));2993 dynarray_add(&libs, &nblibs, tcc_strdup(filename)); 3069 2994 if (libname[0] != '\0') 3070 dynarray_add( (void ***)&libs, &nblibs, tcc_strdup(libname));2995 dynarray_add(&libs, &nblibs, tcc_strdup(libname)); 3071 2996 } 3072 2997 } … … 3097 3022 char filename[1024]; 3098 3023 int t, ret; 3099 3100 ch = file->buf_ptr[0]; 3024 3101 3025 ch = handle_eob(); 3102 3026 for(;;) { … … 3132 3056 return 0; 3133 3057 } 3134 #endif /* ndefTCC_TARGET_PE */3058 #endif /* !TCC_TARGET_PE */
Note:
See TracChangeset
for help on using the changeset viewer.