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:
deadwood
2022-02-20 11:32:45 +01:00
parent a992616722
commit c6c4304ed6
2 changed files with 42 additions and 0 deletions

View File

@@ -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;

View File

@@ -131,6 +131,8 @@ public:
void noDefaultLib();
void addDebug();
void clearSymbolVersions(const std::set<std::string> & syms);
private: