mirror of
https://github.com/NixOS/patchelf.git
synced 2025-10-19 02:23:15 +08:00
Add --add-debug option
A shared library (-shared) by default does not receive DT_DEBUG tag. This means that when a shared library has an entry point (so that it can be run as an executable), the debugger does not connect to it correctly and symbols are not resolved. --add-debug option adds DT_DEBUG tag if it not yet present to an ELF object.
This commit is contained in:
@@ -1652,6 +1652,38 @@ void ElfFile<ElfFileParamNames>::noDefaultLib()
|
|||||||
changed = true;
|
changed = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<ElfFileParams>
|
||||||
|
void ElfFile<ElfFileParamNames>::addDebug()
|
||||||
|
{
|
||||||
|
auto shdrDynamic = findSectionHeader(".dynamic");
|
||||||
|
|
||||||
|
auto dyn = (Elf_Dyn *)(fileContents->data() + rdi(shdrDynamic.sh_offset));
|
||||||
|
for ( ; rdi(dyn->d_tag) != DT_NULL; dyn++) {
|
||||||
|
if (rdi(dyn->d_tag) == DT_DEBUG) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
std::string & newDynamic = replaceSection(".dynamic",
|
||||||
|
rdi(shdrDynamic.sh_size) + sizeof(Elf_Dyn));
|
||||||
|
|
||||||
|
unsigned int idx = 0;
|
||||||
|
for ( ; rdi(((Elf_Dyn *) newDynamic.c_str())[idx].d_tag) != DT_NULL; idx++) ;
|
||||||
|
debug("DT_NULL index is %d\n", idx);
|
||||||
|
|
||||||
|
/* Shift all entries down by one. */
|
||||||
|
setSubstr(newDynamic, sizeof(Elf_Dyn),
|
||||||
|
std::string(newDynamic, 0, sizeof(Elf_Dyn) * (idx + 1)));
|
||||||
|
|
||||||
|
/* Add the DT_DEBUG entry at the top. */
|
||||||
|
Elf_Dyn newDyn;
|
||||||
|
wri(newDyn.d_tag, DT_DEBUG);
|
||||||
|
newDyn.d_un.d_val = 0;
|
||||||
|
setSubstr(newDynamic, 0, std::string((char *) &newDyn, sizeof(Elf_Dyn)));
|
||||||
|
|
||||||
|
this->rewriteSections();
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
|
|
||||||
template<ElfFileParams>
|
template<ElfFileParams>
|
||||||
void ElfFile<ElfFileParamNames>::clearSymbolVersions(const std::set<std::string> & syms)
|
void ElfFile<ElfFileParamNames>::clearSymbolVersions(const std::set<std::string> & syms)
|
||||||
{
|
{
|
||||||
@@ -1691,6 +1723,7 @@ static std::vector<std::string> allowedRpathPrefixes;
|
|||||||
static bool removeRPath = false;
|
static bool removeRPath = false;
|
||||||
static bool setRPath = false;
|
static bool setRPath = false;
|
||||||
static bool addRPath = false;
|
static bool addRPath = false;
|
||||||
|
static bool addDebug = false;
|
||||||
static bool printRPath = false;
|
static bool printRPath = false;
|
||||||
static std::string newRPath;
|
static std::string newRPath;
|
||||||
static std::set<std::string> neededLibsToRemove;
|
static std::set<std::string> neededLibsToRemove;
|
||||||
@@ -1737,6 +1770,9 @@ static void patchElf2(ElfFile && elfFile, const FileContents & fileContents, con
|
|||||||
if (noDefaultLib)
|
if (noDefaultLib)
|
||||||
elfFile.noDefaultLib();
|
elfFile.noDefaultLib();
|
||||||
|
|
||||||
|
if (addDebug)
|
||||||
|
elfFile.addDebug();
|
||||||
|
|
||||||
if (elfFile.isChanged()){
|
if (elfFile.isChanged()){
|
||||||
writeFile(fileName, elfFile.fileContents);
|
writeFile(fileName, elfFile.fileContents);
|
||||||
} else if (alwaysWrite) {
|
} else if (alwaysWrite) {
|
||||||
@@ -1793,6 +1829,7 @@ void showHelp(const std::string & progName)
|
|||||||
[--print-needed]\n\
|
[--print-needed]\n\
|
||||||
[--no-default-lib]\n\
|
[--no-default-lib]\n\
|
||||||
[--clear-symbol-version SYMBOL]\n\
|
[--clear-symbol-version SYMBOL]\n\
|
||||||
|
[--add-debug]\n\
|
||||||
[--output FILE]\n\
|
[--output FILE]\n\
|
||||||
[--debug]\n\
|
[--debug]\n\
|
||||||
[--version]\n\
|
[--version]\n\
|
||||||
@@ -1901,6 +1938,9 @@ int mainWrapped(int argc, char * * argv)
|
|||||||
else if (arg == "--no-default-lib") {
|
else if (arg == "--no-default-lib") {
|
||||||
noDefaultLib = true;
|
noDefaultLib = true;
|
||||||
}
|
}
|
||||||
|
else if (arg == "--add-debug") {
|
||||||
|
addDebug = true;
|
||||||
|
}
|
||||||
else if (arg == "--help" || arg == "-h" ) {
|
else if (arg == "--help" || arg == "-h" ) {
|
||||||
showHelp(argv[0]);
|
showHelp(argv[0]);
|
||||||
return 0;
|
return 0;
|
||||||
|
@@ -131,6 +131,8 @@ public:
|
|||||||
|
|
||||||
void noDefaultLib();
|
void noDefaultLib();
|
||||||
|
|
||||||
|
void addDebug();
|
||||||
|
|
||||||
void clearSymbolVersions(const std::set<std::string> & syms);
|
void clearSymbolVersions(const std::set<std::string> & syms);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
Reference in New Issue
Block a user