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;
|
||||
}
|
||||
|
||||
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>
|
||||
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 setRPath = false;
|
||||
static bool addRPath = false;
|
||||
static bool addDebug = false;
|
||||
static bool printRPath = false;
|
||||
static std::string newRPath;
|
||||
static std::set<std::string> neededLibsToRemove;
|
||||
@@ -1737,6 +1770,9 @@ static void patchElf2(ElfFile && elfFile, const FileContents & fileContents, con
|
||||
if (noDefaultLib)
|
||||
elfFile.noDefaultLib();
|
||||
|
||||
if (addDebug)
|
||||
elfFile.addDebug();
|
||||
|
||||
if (elfFile.isChanged()){
|
||||
writeFile(fileName, elfFile.fileContents);
|
||||
} else if (alwaysWrite) {
|
||||
@@ -1793,6 +1829,7 @@ void showHelp(const std::string & progName)
|
||||
[--print-needed]\n\
|
||||
[--no-default-lib]\n\
|
||||
[--clear-symbol-version SYMBOL]\n\
|
||||
[--add-debug]\n\
|
||||
[--output FILE]\n\
|
||||
[--debug]\n\
|
||||
[--version]\n\
|
||||
@@ -1901,6 +1938,9 @@ int mainWrapped(int argc, char * * argv)
|
||||
else if (arg == "--no-default-lib") {
|
||||
noDefaultLib = true;
|
||||
}
|
||||
else if (arg == "--add-debug") {
|
||||
addDebug = true;
|
||||
}
|
||||
else if (arg == "--help" || arg == "-h" ) {
|
||||
showHelp(argv[0]);
|
||||
return 0;
|
||||
|
@@ -131,6 +131,8 @@ public:
|
||||
|
||||
void noDefaultLib();
|
||||
|
||||
void addDebug();
|
||||
|
||||
void clearSymbolVersions(const std::set<std::string> & syms);
|
||||
|
||||
private:
|
||||
|
Reference in New Issue
Block a user