mirror of
https://github.com/NixOS/patchelf.git
synced 2025-10-23 00:58:24 +08:00
add --clear-symbol-version
This sets the versym entry for a given symbol to 1.
This commit is contained in:
@@ -57,8 +57,8 @@ static int forcedPageSize = -1;
|
|||||||
typedef std::shared_ptr<std::vector<unsigned char>> FileContents;
|
typedef std::shared_ptr<std::vector<unsigned char>> FileContents;
|
||||||
|
|
||||||
|
|
||||||
#define ElfFileParams class Elf_Ehdr, class Elf_Phdr, class Elf_Shdr, class Elf_Addr, class Elf_Off, class Elf_Dyn, class Elf_Sym, class Elf_Verneed
|
#define ElfFileParams class Elf_Ehdr, class Elf_Phdr, class Elf_Shdr, class Elf_Addr, class Elf_Off, class Elf_Dyn, class Elf_Sym, class Elf_Verneed, class Elf_Versym
|
||||||
#define ElfFileParamNames Elf_Ehdr, Elf_Phdr, Elf_Shdr, Elf_Addr, Elf_Off, Elf_Dyn, Elf_Sym, Elf_Verneed
|
#define ElfFileParamNames Elf_Ehdr, Elf_Phdr, Elf_Shdr, Elf_Addr, Elf_Off, Elf_Dyn, Elf_Sym, Elf_Verneed, Elf_Versym
|
||||||
|
|
||||||
|
|
||||||
static std::vector<std::string> splitColonDelimitedString(const char * s)
|
static std::vector<std::string> splitColonDelimitedString(const char * s)
|
||||||
@@ -215,6 +215,8 @@ public:
|
|||||||
|
|
||||||
void noDefaultLib();
|
void noDefaultLib();
|
||||||
|
|
||||||
|
void clearSymbolVersions(const std::set<std::string> & syms);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
/* Convert an integer in big or little endian representation (as
|
/* Convert an integer in big or little endian representation (as
|
||||||
@@ -1675,6 +1677,33 @@ void ElfFile<ElfFileParamNames>::noDefaultLib()
|
|||||||
changed = true;
|
changed = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<ElfFileParams>
|
||||||
|
void ElfFile<ElfFileParamNames>::clearSymbolVersions(const std::set<std::string> & syms)
|
||||||
|
{
|
||||||
|
if (syms.empty()) return;
|
||||||
|
|
||||||
|
auto shdrDynStr = findSection(".dynstr");
|
||||||
|
auto shdrDynsym = findSection(".dynsym");
|
||||||
|
auto shdrVersym = findSection(".gnu.version");
|
||||||
|
|
||||||
|
char * strTab = (char *) contents + rdi(shdrDynStr.sh_offset);
|
||||||
|
Elf_Sym * dynsyms = (Elf_Sym *) (contents + rdi(shdrDynsym.sh_offset));
|
||||||
|
Elf_Versym * versyms = (Elf_Versym *) (contents + rdi(shdrVersym.sh_offset));
|
||||||
|
size_t count = rdi(shdrDynsym.sh_size) / sizeof(Elf_Sym);
|
||||||
|
|
||||||
|
if (count != rdi(shdrVersym.sh_size) / sizeof(Elf_Versym))
|
||||||
|
error("versym size mismatch");
|
||||||
|
|
||||||
|
for (size_t i = 0; i < count; i++) {
|
||||||
|
auto dynsym = dynsyms[i];
|
||||||
|
auto name = strTab + rdi(dynsym.st_name);
|
||||||
|
if (syms.find(name) != syms.end()) {
|
||||||
|
debug("clearing symbol version for %s\n", name);
|
||||||
|
wri(versyms[i], 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
|
|
||||||
static bool printInterpreter = false;
|
static bool printInterpreter = false;
|
||||||
static bool printSoname = false;
|
static bool printSoname = false;
|
||||||
@@ -1690,6 +1719,7 @@ static std::string newRPath;
|
|||||||
static std::set<std::string> neededLibsToRemove;
|
static std::set<std::string> neededLibsToRemove;
|
||||||
static std::map<std::string, std::string> neededLibsToReplace;
|
static std::map<std::string, std::string> neededLibsToReplace;
|
||||||
static std::set<std::string> neededLibsToAdd;
|
static std::set<std::string> neededLibsToAdd;
|
||||||
|
static std::set<std::string> symbolsToClearVersion;
|
||||||
static bool printNeeded = false;
|
static bool printNeeded = false;
|
||||||
static bool noDefaultLib = false;
|
static bool noDefaultLib = false;
|
||||||
|
|
||||||
@@ -1723,6 +1753,7 @@ static void patchElf2(ElfFile && elfFile, const FileContents & fileContents, std
|
|||||||
elfFile.removeNeeded(neededLibsToRemove);
|
elfFile.removeNeeded(neededLibsToRemove);
|
||||||
elfFile.replaceNeeded(neededLibsToReplace);
|
elfFile.replaceNeeded(neededLibsToReplace);
|
||||||
elfFile.addNeeded(neededLibsToAdd);
|
elfFile.addNeeded(neededLibsToAdd);
|
||||||
|
elfFile.clearSymbolVersions(symbolsToClearVersion);
|
||||||
|
|
||||||
if (noDefaultLib)
|
if (noDefaultLib)
|
||||||
elfFile.noDefaultLib();
|
elfFile.noDefaultLib();
|
||||||
@@ -1747,9 +1778,9 @@ static void patchElf()
|
|||||||
std::string outputFileName2 = outputFileName.empty() ? fileName : outputFileName;
|
std::string outputFileName2 = outputFileName.empty() ? fileName : outputFileName;
|
||||||
|
|
||||||
if (getElfType(fileContents).is32Bit)
|
if (getElfType(fileContents).is32Bit)
|
||||||
patchElf2(ElfFile<Elf32_Ehdr, Elf32_Phdr, Elf32_Shdr, Elf32_Addr, Elf32_Off, Elf32_Dyn, Elf32_Sym, Elf32_Verneed>(fileContents), fileContents, outputFileName2);
|
patchElf2(ElfFile<Elf32_Ehdr, Elf32_Phdr, Elf32_Shdr, Elf32_Addr, Elf32_Off, Elf32_Dyn, Elf32_Sym, Elf32_Verneed, Elf32_Versym>(fileContents), fileContents, outputFileName2);
|
||||||
else
|
else
|
||||||
patchElf2(ElfFile<Elf64_Ehdr, Elf64_Phdr, Elf64_Shdr, Elf64_Addr, Elf64_Off, Elf64_Dyn, Elf64_Sym, Elf64_Verneed>(fileContents), fileContents, outputFileName2);
|
patchElf2(ElfFile<Elf64_Ehdr, Elf64_Phdr, Elf64_Shdr, Elf64_Addr, Elf64_Off, Elf64_Dyn, Elf64_Sym, Elf64_Verneed, Elf64_Versym>(fileContents), fileContents, outputFileName2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1773,6 +1804,7 @@ void showHelp(const std::string & progName)
|
|||||||
[--replace-needed LIBRARY NEW_LIBRARY]\n\
|
[--replace-needed LIBRARY NEW_LIBRARY]\n\
|
||||||
[--print-needed]\n\
|
[--print-needed]\n\
|
||||||
[--no-default-lib]\n\
|
[--no-default-lib]\n\
|
||||||
|
[--clear-symbol-version SYMBOL]\n\
|
||||||
[--output FILE]\n\
|
[--output FILE]\n\
|
||||||
[--debug]\n\
|
[--debug]\n\
|
||||||
[--version]\n\
|
[--version]\n\
|
||||||
@@ -1860,6 +1892,10 @@ int mainWrapped(int argc, char * * argv)
|
|||||||
neededLibsToReplace[ argv[i+1] ] = argv[i+2];
|
neededLibsToReplace[ argv[i+1] ] = argv[i+2];
|
||||||
i += 2;
|
i += 2;
|
||||||
}
|
}
|
||||||
|
else if (arg == "--clear-symbol-version") {
|
||||||
|
if (++i == argc) error("missing argument");
|
||||||
|
symbolsToClearVersion.insert(argv[i]);
|
||||||
|
}
|
||||||
else if (arg == "--output") {
|
else if (arg == "--output") {
|
||||||
if (++i == argc) error("missing argument");
|
if (++i == argc) error("missing argument");
|
||||||
outputFileName = argv[i];
|
outputFileName = argv[i];
|
||||||
|
Reference in New Issue
Block a user