@@ -1709,6 +1709,73 @@ void ElfFile<ElfFileParamNames>::addDebugTag()
1709
1709
changed = true ;
1710
1710
}
1711
1711
1712
+ /* Remove any unused dependency symbol versions from .gnu.version_r */
1713
+ template <ElfFileParams>
1714
+ void ElfFile<ElfFileParamNames>::cleanDependencySymbolVersions()
1715
+ {
1716
+ auto shdrVersym = findSectionHeader (" .gnu.version" );
1717
+ auto shdrVersymR = findSectionHeader (" .gnu.version_r" );
1718
+
1719
+ auto versyms = (Elf_Versym *)(fileContents->data () + rdi (shdrVersym.sh_offset ));
1720
+ size_t count = rdi (shdrVersym.sh_size ) / sizeof (Elf_Versym);
1721
+
1722
+ /* Set of versions actually used. */
1723
+ std::set<Elf_Versym> allVersions;
1724
+
1725
+ for (size_t i = 0 ; i < count; i++) {
1726
+ allVersions.insert (versyms[i]);
1727
+ }
1728
+
1729
+ /* Strings associated with .gnu_version_r section: used for debug only. */
1730
+ Elf_Shdr & shdrVersionRStrings = shdrs.at (rdi (shdrVersymR.sh_link ));
1731
+ char * verStrTab = (char *) fileContents->data () + rdi (shdrVersionRStrings.sh_offset );
1732
+
1733
+
1734
+ auto ver_r = (Elf_Verneed *)(fileContents->data () + rdi (shdrVersymR.sh_offset ));
1735
+ while (true ) {
1736
+ auto prev = (Elf_Vernaux *)nullptr ;
1737
+ auto vern_aux = (Elf_Vernaux *)((char *)ver_r + rdi (ver_r->vn_aux ));
1738
+ char * file = verStrTab + rdi (ver_r->vn_file );
1739
+ for (size_t j = 0 ; j < ver_r->vn_cnt ; j++) {
1740
+ char * ver_name = verStrTab + rdi (vern_aux->vna_name );
1741
+ auto next = (Elf_Vernaux *)((char *)vern_aux + rdi (vern_aux->vna_next ));
1742
+
1743
+ if (!allVersions.count (rdi (vern_aux->vna_other ) & ~0x8000 )) {
1744
+ debug (" Removing version identifier %d %s@%s\n " , rdi (vern_aux->vna_other ), file, ver_name);
1745
+ /* Symbol version is no longer used, unlink it. */
1746
+ if (!prev) {
1747
+ auto next_off = (intptr_t )(vern_aux) + rdi (vern_aux->vna_next ) - (intptr_t )(ver_r);
1748
+ wri (ver_r->vn_aux , next_off);
1749
+ } else {
1750
+ auto next_off = (intptr_t )(vern_aux) + rdi (vern_aux->vna_next ) - (intptr_t )(prev);
1751
+ wri (prev->vna_next , next_off);
1752
+ }
1753
+ wri (ver_r->vn_cnt , rdi (ver_r->vn_cnt ) - 1 );
1754
+ } else {
1755
+ prev = vern_aux;
1756
+ }
1757
+
1758
+ if (vern_aux == next) {
1759
+ if (j != rdi (ver_r->vn_cnt )) {
1760
+ debug (" Section missing elements! Ended on element %d, expected %d\n " , j, rdi (ver_r->vn_cnt ));
1761
+ }
1762
+ break ;
1763
+ }
1764
+ vern_aux = next;
1765
+ }
1766
+
1767
+ /* If this was the last entry, we're done. */
1768
+ if (!rdi (ver_r->vn_next )) {
1769
+ break ;
1770
+ }
1771
+
1772
+ ver_r = (Elf_Verneed *) (((char *) ver_r) + rdi (ver_r->vn_next ));
1773
+ }
1774
+
1775
+ changed = true ;
1776
+ this ->rewriteSections ();
1777
+ }
1778
+
1712
1779
template <ElfFileParams>
1713
1780
void ElfFile<ElfFileParamNames>::clearSymbolVersions(const std::set<std::string> & syms)
1714
1781
{
@@ -1734,6 +1801,10 @@ void ElfFile<ElfFileParamNames>::clearSymbolVersions(const std::set<std::string>
1734
1801
wri (versyms[i], 1 );
1735
1802
}
1736
1803
}
1804
+
1805
+ /* Remove entries in the .gnu.versions_r table which are no;-longer required. */
1806
+ cleanDependencySymbolVersions ();
1807
+
1737
1808
changed = true ;
1738
1809
this ->rewriteSections ();
1739
1810
}
@@ -1817,9 +1888,9 @@ static void patchElf()
1817
1888
const std::string & outputFileName2 = outputFileName.empty () ? fileName : outputFileName;
1818
1889
1819
1890
if (getElfType (fileContents).is32Bit )
1820
- patchElf2 (ElfFile<Elf32_Ehdr, Elf32_Phdr, Elf32_Shdr, Elf32_Addr, Elf32_Off, Elf32_Dyn, Elf32_Sym, Elf32_Verneed, Elf32_Versym>(fileContents), fileContents, outputFileName2);
1891
+ patchElf2 (ElfFile<Elf32_Ehdr, Elf32_Phdr, Elf32_Shdr, Elf32_Addr, Elf32_Off, Elf32_Dyn, Elf32_Sym, Elf32_Verneed, Elf32_Vernaux, Elf32_Versym>(fileContents), fileContents, outputFileName2);
1821
1892
else
1822
- patchElf2 (ElfFile<Elf64_Ehdr, Elf64_Phdr, Elf64_Shdr, Elf64_Addr, Elf64_Off, Elf64_Dyn, Elf64_Sym, Elf64_Verneed, Elf64_Versym>(fileContents), fileContents, outputFileName2);
1893
+ patchElf2 (ElfFile<Elf64_Ehdr, Elf64_Phdr, Elf64_Shdr, Elf64_Addr, Elf64_Off, Elf64_Dyn, Elf64_Sym, Elf64_Verneed, Elf64_Vernaux, Elf64_Versym>(fileContents), fileContents, outputFileName2);
1823
1894
}
1824
1895
}
1825
1896
0 commit comments