History

Add macro to browse reloc and sym entries

Introduce for_each_elem to browse relocation entries and symbols of a section.

Thomas Preud'homme committed 12 years ago

Commit 55f751a1 parent 88c9f1b1 file · +39 −79Browse files

Unified · Split

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

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t