Introduce for_each_elem to browse relocation entries and symbols of a section.
Unified · Split
| @@ -330,6 +330,12 @@ ST_FUNC void put_stabd(int type, int other, int desc) · 329 unmodified lines | ||
| 330 | 330 | put_stabs(NULL, type, other, desc, 0); |
| 331 | 331 | } |
| 332 | 332 | |
| 333 | +/* Browse each elem of type <type> in section <sec> starting at elem <startoff> | |
| 334 | + using variable <elem> */ | |
| 335 | +#define for_each_elem(sec, startoff, elem, type) \ | |
| 336 | + for (elem = (type *) sec->data + startoff; \ | |
| 337 | + elem < (type *) (sec->data + sec->data_offset); elem++) | |
| 338 | + | |
| 333 | 339 | /* In an ELF file symbol table, the local symbols must appear below |
| 334 | 340 | the global and weak ones. Since TCC cannot sort it while generating |
| 335 | 341 | the code, we must do it after. All the relocation tables are also |
| @@ -340,7 +346,7 @@ static void sort_syms(TCCState *s1, Section *s) · 4 unmodified lines | ||
| 340 | 346 | ElfW(Sym) *new_syms; |
| 341 | 347 | int nb_syms, i; |
| 342 | 348 | ElfW(Sym) *p, *q; |
| 343 | − ElfW_Rel *rel, *rel_end; | |
| 349 | + ElfW_Rel *rel; | |
| 344 | 350 | Section *sr; |
| 345 | 351 | int type, sym_index; |
| 346 | 352 | |
| @@ -379,10 +385,7 @@ static void sort_syms(TCCState *s1, Section *s) · 32 unmodified lines | ||
| 379 | 385 | for(i = 1; i < s1->nb_sections; i++) { |
| 380 | 386 | sr = s1->sections[i]; |
| 381 | 387 | 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++) { | |
| 388 | + for_each_elem(sr, 0, rel, ElfW_Rel) { | |
| 386 | 389 | sym_index = ELFW(R_SYM)(rel->r_info); |
| 387 | 390 | type = ELFW(R_TYPE)(rel->r_info); |
| 388 | 391 | sym_index = old_to_new_syms[sym_index]; |
| @@ -397,13 +400,10 @@ static void sort_syms(TCCState *s1, Section *s) · 8 unmodified lines | ||
| 397 | 400 | /* relocate common symbols in the .bss section */ |
| 398 | 401 | ST_FUNC void relocate_common_syms(void) |
| 399 | 402 | { |
| 400 | − ElfW(Sym) *sym, *sym_end; | |
| 403 | + ElfW(Sym) *sym; | |
| 401 | 404 | 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++) { | |
| 405 | + | |
| 406 | + for_each_elem(symtab_section, 1, sym, ElfW(Sym)) { | |
| 407 | 407 | if (sym->st_shndx == SHN_COMMON) { |
| 408 | 408 | /* align symbol */ |
| 409 | 409 | align = sym->st_value; |
| @@ -421,14 +421,11 @@ ST_FUNC void relocate_common_syms(void) · 11 unmodified lines | ||
| 421 | 421 | true and output error if undefined symbol. */ |
| 422 | 422 | ST_FUNC void relocate_syms(TCCState *s1, int do_resolve) |
| 423 | 423 | { |
| 424 | − ElfW(Sym) *sym, *esym, *sym_end; | |
| 424 | + ElfW(Sym) *sym, *esym; | |
| 425 | 425 | int sym_bind, sh_num, sym_index; |
| 426 | 426 | const char *name; |
| 427 | 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++) { | |
| 428 | + for_each_elem(symtab_section, 1, sym, ElfW(Sym)) { | |
| 432 | 429 | sh_num = sym->st_shndx; |
| 433 | 430 | if (sh_num == SHN_UNDEF) { |
| 434 | 431 | name = strtab_section->data + sym->st_name; |
| @@ -510,22 +507,18 @@ static addr_t add_jmp_table(TCCState *s1, int val) · 75 unmodified lines | ||
| 510 | 507 | /* relocate a given section (CPU dependent) */ |
| 511 | 508 | ST_FUNC void relocate_section(TCCState *s1, Section *s) |
| 512 | 509 | { |
| 513 | − Section *sr; | |
| 514 | − ElfW_Rel *rel, *rel_end, *qrel; | |
| 510 | + Section *sr = s->reloc; | |
| 511 | + ElfW_Rel *rel; | |
| 515 | 512 | ElfW(Sym) *sym; |
| 516 | 513 | int type, sym_index; |
| 517 | 514 | unsigned char *ptr; |
| 518 | 515 | addr_t val, addr; |
| 519 | 516 | #if defined TCC_TARGET_I386 || defined TCC_TARGET_X86_64 |
| 517 | + ElfW_Rel *qrel = (ElfW_Rel *) sr->data; /* ptr to next reloc entry reused */ | |
| 520 | 518 | int esym_index; |
| 521 | 519 | #endif |
| 522 | 520 | |
| 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++) { | |
| 521 | + for_each_elem(sr, 0, rel, ElfW_Rel) { | |
| 529 | 522 | ptr = s->data + rel->r_offset; |
| 530 | 523 | |
| 531 | 524 | sym_index = ELFW(R_SYM)(rel->r_info); |
| @@ -893,27 +886,22 @@ ST_FUNC void relocate_section(TCCState *s1, Section *s) · 361 unmodified lines | ||
| 893 | 886 | static void relocate_rel(TCCState *s1, Section *sr) |
| 894 | 887 | { |
| 895 | 888 | Section *s; |
| 896 | − ElfW_Rel *rel, *rel_end; | |
| 897 | − | |
| 889 | + ElfW_Rel *rel; | |
| 890 | + | |
| 898 | 891 | 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++) { | |
| 892 | + for_each_elem(sr, 0, rel, ElfW_Rel) | |
| 903 | 893 | rel->r_offset += s->sh_addr; |
| 904 | − } | |
| 905 | 894 | } |
| 906 | 895 | |
| 907 | 896 | /* count the number of dynamic relocations so that we can reserve |
| 908 | 897 | their space */ |
| 909 | 898 | static int prepare_dynamic_rel(TCCState *s1, Section *sr) |
| 910 | 899 | { |
| 911 | − ElfW_Rel *rel, *rel_end; | |
| 900 | + ElfW_Rel *rel; | |
| 912 | 901 | int sym_index, esym_index, type, count; |
| 913 | 902 | |
| 914 | 903 | count = 0; |
| 915 | − rel_end = (ElfW_Rel *)(sr->data + sr->data_offset); | |
| 916 | − for(rel = (ElfW_Rel *)sr->data; rel < rel_end; rel++) { | |
| 904 | + for_each_elem(sr, 0, rel, ElfW_Rel) { | |
| 917 | 905 | sym_index = ELFW(R_SYM)(rel->r_info); |
| 918 | 906 | type = ELFW(R_TYPE)(rel->r_info); |
| 919 | 907 | switch(type) { |
| @@ -1145,7 +1133,7 @@ static void put_got_entry(TCCState *s1, · 225 unmodified lines | ||
| 1145 | 1133 | ST_FUNC void build_got_entries(TCCState *s1) |
| 1146 | 1134 | { |
| 1147 | 1135 | Section *s; |
| 1148 | − ElfW_Rel *rel, *rel_end; | |
| 1136 | + ElfW_Rel *rel; | |
| 1149 | 1137 | ElfW(Sym) *sym; |
| 1150 | 1138 | int i, type, reloc_type, sym_index; |
| 1151 | 1139 | |
| @@ -1156,10 +1144,7 @@ ST_FUNC void build_got_entries(TCCState *s1) · 4 unmodified lines | ||
| 1156 | 1144 | /* no need to handle got relocations */ |
| 1157 | 1145 | if (s->link != symtab_section) |
| 1158 | 1146 | continue; |
| 1159 | − rel_end = (ElfW_Rel *)(s->data + s->data_offset); | |
| 1160 | − for(rel = (ElfW_Rel *)s->data; | |
| 1161 | − rel < rel_end; | |
| 1162 | − rel++) { | |
| 1147 | + for_each_elem(s, 0, rel, ElfW_Rel) { | |
| 1163 | 1148 | type = ELFW(R_TYPE)(rel->r_info); |
| 1164 | 1149 | switch(type) { |
| 1165 | 1150 | #if defined(TCC_TARGET_I386) |
| @@ -1466,12 +1451,11 @@ static void tcc_output_binary(TCCState *s1, FILE *f, · 300 unmodified lines | ||
| 1466 | 1451 | void patch_dynsym_undef(TCCState *s1, Section *s) |
| 1467 | 1452 | { |
| 1468 | 1453 | uint32_t *gotd = (void *)s1->got->data; |
| 1469 | − ElfW(Sym) *sym, *sym_end; | |
| 1454 | + ElfW(Sym) *sym; | |
| 1470 | 1455 | |
| 1471 | 1456 | gotd += 3; /* dummy entries in .got */ |
| 1472 | 1457 | /* 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++) { | |
| 1458 | + for_each_elem(s, 1, sym, ElfW(Sym)) { | |
| 1475 | 1459 | if (sym->st_shndx == SHN_UNDEF) { |
| 1476 | 1460 | *gotd++ = sym->st_value + 6; /* XXX 6 is magic ? */ |
| 1477 | 1461 | sym->st_value = 0; |
| @@ -1485,10 +1469,9 @@ void patch_dynsym_undef(TCCState *s1, Section *s) · 7 unmodified lines | ||
| 1485 | 1469 | /* zero plt offsets of weak symbols in .dynsym */ |
| 1486 | 1470 | void patch_dynsym_undef(TCCState *s1, Section *s) |
| 1487 | 1471 | { |
| 1488 | − ElfW(Sym) *sym, *sym_end; | |
| 1472 | + ElfW(Sym) *sym; | |
| 1489 | 1473 | |
| 1490 | − sym_end = (ElfW(Sym) *)(s->data + s->data_offset); | |
| 1491 | − for (sym = (ElfW(Sym) *)s->data + 1; sym < sym_end; sym++) | |
| 1474 | + for_each_elem(s, 1, sym, ElfW(Sym)) | |
| 1492 | 1475 | if (sym->st_shndx == SHN_UNDEF && ELFW(ST_BIND)(sym->st_info) == STB_WEAK) |
| 1493 | 1476 | sym->st_value = 0; |
| 1494 | 1477 | } |
| @@ -1514,7 +1497,7 @@ ST_FUNC void fill_got_entry(TCCState *s1, ElfW_Rel *rel) · 19 unmodified lines | ||
| 1514 | 1497 | ST_FUNC void fill_got(TCCState *s1) |
| 1515 | 1498 | { |
| 1516 | 1499 | Section *s; |
| 1517 | − ElfW_Rel *rel, *rel_end; | |
| 1500 | + ElfW_Rel *rel; | |
| 1518 | 1501 | int i; |
| 1519 | 1502 | |
| 1520 | 1503 | for(i = 1; i < s1->nb_sections; i++) { |
| @@ -1524,8 +1507,7 @@ ST_FUNC void fill_got(TCCState *s1) · 3 unmodified lines | ||
| 1524 | 1507 | /* no need to handle got relocations */ |
| 1525 | 1508 | if (s->link != symtab_section) |
| 1526 | 1509 | continue; |
| 1527 | − rel_end = (ElfW_Rel *) (s->data + s->data_offset); | |
| 1528 | − for(rel = (ElfW_Rel *) s->data; rel < rel_end; rel++) { | |
| 1510 | + for_each_elem(s, 0, rel, ElfW_Rel) { | |
| 1529 | 1511 | switch (ELFW(R_TYPE) (rel->r_info)) { |
| 1530 | 1512 | case R_X86_64_GOT32: |
| 1531 | 1513 | case R_X86_64_GOTPCREL: |
| @@ -1583,7 +1565,7 @@ static int elf_output_file(TCCState *s1, const char *filename) · 51 unmodified lines | ||
| 1583 | 1565 | if (!s1->static_link) { |
| 1584 | 1566 | const char *name; |
| 1585 | 1567 | int sym_index, index; |
| 1586 | − ElfW(Sym) *esym, *sym_end; | |
| 1568 | + ElfW(Sym) *esym; | |
| 1587 | 1569 | |
| 1588 | 1570 | if (file_type == TCC_OUTPUT_EXE) { |
| 1589 | 1571 | char *ptr; |
| @@ -1622,12 +1604,8 @@ static int elf_output_file(TCCState *s1, const char *filename) · 32 unmodified lines | ||
| 1622 | 1604 | is found, then we add it in the PLT. If a symbol |
| 1623 | 1605 | STT_OBJECT is found, we add it in the .bss section with |
| 1624 | 1606 | a suitable relocation */ |
| 1625 | − sym_end = (ElfW(Sym) *)(symtab_section->data + | |
| 1626 | − symtab_section->data_offset); | |
| 1627 | 1607 | if (file_type == TCC_OUTPUT_EXE) { |
| 1628 | − for(sym = (ElfW(Sym) *)symtab_section->data + 1; | |
| 1629 | − sym < sym_end; | |
| 1630 | − sym++) { | |
| 1608 | + for_each_elem(symtab_section, 1, sym, ElfW(Sym)) { | |
| 1631 | 1609 | if (sym->st_shndx == SHN_UNDEF) { |
| 1632 | 1610 | name = symtab_section->link->data + sym->st_name; |
| 1633 | 1611 | sym_index = find_elf_sym(s1->dynsymtab_section, name); |
| @@ -1648,7 +1626,7 @@ static int elf_output_file(TCCState *s1, const char *filename) · 14 unmodified lines | ||
| 1648 | 1626 | sym - (ElfW(Sym) *)symtab_section->data); |
| 1649 | 1627 | } else if (type == STT_OBJECT) { |
| 1650 | 1628 | unsigned long offset; |
| 1651 | − ElfW(Sym) *dynsym, *dynsym_end; | |
| 1629 | + ElfW(Sym) *dynsym; | |
| 1652 | 1630 | offset = bss_section->data_offset; |
| 1653 | 1631 | /* XXX: which alignment ? */ |
| 1654 | 1632 | offset = (offset + 16 - 1) & -16; |
| @@ -1657,11 +1635,7 @@ static int elf_output_file(TCCState *s1, const char *filename) · 2 unmodified lines | ||
| 1657 | 1635 | bss_section->sh_num, name); |
| 1658 | 1636 | /* Ensure R_COPY works for weak symbol aliases */ |
| 1659 | 1637 | 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++) { | |
| 1638 | + for_each_elem(s1->dynsymtab_section, 1, dynsym, ElfW(Sym)) { | |
| 1665 | 1639 | if ((dynsym->st_value == esym->st_value) |
| 1666 | 1640 | && (ELFW(ST_BIND)(dynsym->st_info) == STB_GLOBAL)) { |
| 1667 | 1641 | char *dynname; |
| @@ -1707,11 +1681,7 @@ static int elf_output_file(TCCState *s1, const char *filename) · 39 unmodified lines | ||
| 1707 | 1681 | |
| 1708 | 1682 | /* now look at unresolved dynamic symbols and export |
| 1709 | 1683 | 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++) { | |
| 1684 | + for_each_elem(s1->dynsymtab_section, 1, esym, ElfW(Sym)) { | |
| 1715 | 1685 | if (esym->st_shndx == SHN_UNDEF) { |
| 1716 | 1686 | name = s1->dynsymtab_section->link->data + esym->st_name; |
| 1717 | 1687 | sym_index = find_elf_sym(symtab_section, name); |
| @@ -1736,9 +1706,7 @@ static int elf_output_file(TCCState *s1, const char *filename) · 18 unmodified lines | ||
| 1736 | 1706 | /* shared library case : we simply export all the global symbols */ |
| 1737 | 1707 | nb_syms = symtab_section->data_offset / sizeof(ElfW(Sym)); |
| 1738 | 1708 | 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++) { | |
| 1709 | + for_each_elem(symtab_section, 1, sym, ElfW(Sym)) { | |
| 1742 | 1710 | if (ELFW(ST_BIND)(sym->st_info) != STB_LOCAL) { |
| 1743 | 1711 | #if defined(TCC_OUTPUT_DLL_WITH_PLT) |
| 1744 | 1712 | if ((ELFW(ST_TYPE)(sym->st_info) == STT_FUNC || |
| @@ -2027,8 +1995,6 @@ static int elf_output_file(TCCState *s1, const char *filename) · 282 unmodified lines | ||
| 2027 | 1995 | |
| 2028 | 1996 | /* if dynamic section, then add corresponing program header */ |
| 2029 | 1997 | if (dynamic) { |
| 2030 | − ElfW(Sym) *sym_end; | |
| 2031 | − | |
| 2032 | 1998 | ph = &phdr[phnum - 1]; |
| 2033 | 1999 | |
| 2034 | 2000 | ph->p_type = PT_DYNAMIC; |
| @@ -2090,10 +2056,7 @@ static int elf_output_file(TCCState *s1, const char *filename) · 55 unmodified lines | ||
| 2090 | 2056 | } |
| 2091 | 2057 | |
| 2092 | 2058 | /* relocate symbols in .dynsym */ |
| 2093 | − sym_end = (ElfW(Sym) *)(s1->dynsym->data + s1->dynsym->data_offset); | |
| 2094 | − for(sym = (ElfW(Sym) *)s1->dynsym->data + 1; | |
| 2095 | − sym < sym_end; | |
| 2096 | − sym++) { | |
| 2059 | + for_each_elem(s1->dynsym, 1, sym, ElfW(Sym)) { | |
| 2097 | 2060 | if (sym->st_shndx == SHN_UNDEF) { |
| 2098 | 2061 | /* relocate to the PLT if the symbol corresponds |
| 2099 | 2062 | to a PLT entry */ |
| @@ -2365,7 +2328,7 @@ ST_FUNC int tcc_load_object_file(TCCState *s1, · 265 unmodified lines | ||
| 2365 | 2328 | char *sh_name, *name; |
| 2366 | 2329 | SectionMergeInfo *sm_table, *sm; |
| 2367 | 2330 | ElfW(Sym) *sym, *symtab; |
| 2368 | − ElfW_Rel *rel, *rel_end; | |
| 2331 | + ElfW_Rel *rel; | |
| 2369 | 2332 | Section *s; |
| 2370 | 2333 | |
| 2371 | 2334 | int stab_index; |
| @@ -2585,10 +2548,7 @@ ST_FUNC int tcc_load_object_file(TCCState *s1, · 213 unmodified lines | ||
| 2585 | 2548 | case SHT_RELX: |
| 2586 | 2549 | /* take relocation offset information */ |
| 2587 | 2550 | offseti = sm_table[sh->sh_info].offset; |
| 2588 | − rel_end = (ElfW_Rel *)(s->data + s->data_offset); | |
| 2589 | − for(rel = (ElfW_Rel *)(s->data + offset); | |
| 2590 | − rel < rel_end; | |
| 2591 | − rel++) { | |
| 2551 | + for_each_elem(s, (offset / sizeof(*rel)), rel, ElfW_Rel) { | |
| 2592 | 2552 | int type; |
| 2593 | 2553 | unsigned sym_index; |
| 2594 | 2554 | /* convert symbol index */ |