diff --git a/patchelf.1 b/patchelf.1 index 6a8a94e1..7bb94f7f 100644 --- a/patchelf.1 +++ b/patchelf.1 @@ -131,6 +131,15 @@ old_name new_name Symbol names do not contain version specifier that are also shown in the output of the nm -D command from binutils. So instead of the name write@GLIBC_2.2.5 it is just write. +.IP "--no-clobber-old-sections" +Do not clobber old section values. + +patchelf defaults to overwriting replaced header sections with garbage to ensure they are not +used accidentally. This option allows to opt out of that behavior, so that binaries that attempt +to read their own headers from a fixed offset (e.g. Firefox) continue working. + +Use sparingly and with caution. + .IP "--output FILE" Set the output file name. If not specified, the input will be modified in place. diff --git a/src/patchelf.cc b/src/patchelf.cc index 82b4b46c..b42111dd 100644 --- a/src/patchelf.cc +++ b/src/patchelf.cc @@ -58,6 +58,7 @@ static bool debugMode = false; static bool forceRPath = false; +static bool clobberOldSections = true; static std::vector fileNames; static std::string outputFileName; @@ -664,14 +665,16 @@ template void ElfFile::writeReplacedSections(Elf_Off & curOff, Elf_Addr startAddr, Elf_Off startOffset) { - /* Overwrite the old section contents with 'Z's. Do this - *before* writing the new section contents (below) to prevent - clobbering previously written new section contents. */ - for (auto & i : replacedSections) { - const std::string & sectionName = i.first; - const Elf_Shdr & shdr = findSectionHeader(sectionName); - if (rdi(shdr.sh_type) != SHT_NOBITS) - memset(fileContents->data() + rdi(shdr.sh_offset), 'Z', rdi(shdr.sh_size)); + if (clobberOldSections) { + /* Overwrite the old section contents with 'Z's. Do this + *before* writing the new section contents (below) to prevent + clobbering previously written new section contents. */ + for (auto & i : replacedSections) { + const std::string & sectionName = i.first; + const Elf_Shdr & shdr = findSectionHeader(sectionName); + if (rdi(shdr.sh_type) != SHT_NOBITS) + memset(fileContents->data() + rdi(shdr.sh_offset), 'Z', rdi(shdr.sh_size)); + } } std::set noted_phdrs = {}; @@ -2505,6 +2508,7 @@ static void showHelp(const std::string & progName) [--clear-execstack]\n\ [--set-execstack]\n\ [--rename-dynamic-symbols NAME_MAP_FILE]\tRenames dynamic symbols. The map file should contain two symbols (old_name new_name) per line\n\ + [--no-clobber-old-sections]\t\tDo not clobber old section values - only use when the binary expects to find section info at the old location.\n\ [--output FILE]\n\ [--debug]\n\ [--version]\n\ @@ -2661,6 +2665,9 @@ static int mainWrapped(int argc, char * * argv) symbolsToRename[*symbolsToRenameKeys.insert(from).first] = to; } } + else if (arg == "--no-clobber-old-sections") { + clobberOldSections = false; + } else if (arg == "--help" || arg == "-h" ) { showHelp(argv[0]); return 0;