mirror of
https://github.com/NixOS/patchelf.git
synced 2025-10-23 00:58:24 +08:00
@@ -366,7 +366,9 @@ typedef struct
|
|||||||
required */
|
required */
|
||||||
#define SHF_GROUP (1 << 9) /* Section is member of a group. */
|
#define SHF_GROUP (1 << 9) /* Section is member of a group. */
|
||||||
#define SHF_TLS (1 << 10) /* Section hold thread-local data. */
|
#define SHF_TLS (1 << 10) /* Section hold thread-local data. */
|
||||||
|
#define SHF_COMPRESSED (1 << 11) /* Section with compressed data */
|
||||||
#define SHF_MASKOS 0x0ff00000 /* OS-specific. */
|
#define SHF_MASKOS 0x0ff00000 /* OS-specific. */
|
||||||
|
#define SHF_GNU_BUILD_NOTE (1 << 20) /* Section contains GNU BUILD ATTRIBUTE notes. */
|
||||||
#define SHF_MASKPROC 0xf0000000 /* Processor-specific */
|
#define SHF_MASKPROC 0xf0000000 /* Processor-specific */
|
||||||
#define SHF_ORDERED (1 << 30) /* Special ordering requirement
|
#define SHF_ORDERED (1 << 30) /* Special ordering requirement
|
||||||
(Solaris). */
|
(Solaris). */
|
||||||
|
@@ -380,8 +380,8 @@ static void checkPointer(const FileContents & contents, void * p, unsigned int s
|
|||||||
|
|
||||||
|
|
||||||
template<ElfFileParams>
|
template<ElfFileParams>
|
||||||
ElfFile<ElfFileParamNames>::ElfFile(FileContents fileContents)
|
ElfFile<ElfFileParamNames>::ElfFile(FileContents fContents)
|
||||||
: fileContents(fileContents)
|
: fileContents(fContents)
|
||||||
, contents(fileContents->data())
|
, contents(fileContents->data())
|
||||||
{
|
{
|
||||||
/* Check the ELF header for basic validity. */
|
/* Check the ELF header for basic validity. */
|
||||||
@@ -673,7 +673,7 @@ void ElfFile<ElfFileParamNames>::writeReplacedSections(Elf_Off & curOff,
|
|||||||
*before* writing the new section contents (below) to prevent
|
*before* writing the new section contents (below) to prevent
|
||||||
clobbering previously written new section contents. */
|
clobbering previously written new section contents. */
|
||||||
for (auto & i : replacedSections) {
|
for (auto & i : replacedSections) {
|
||||||
std::string sectionName = i.first;
|
const std::string & sectionName = i.first;
|
||||||
Elf_Shdr & shdr = findSection(sectionName);
|
Elf_Shdr & shdr = findSection(sectionName);
|
||||||
if (rdi(shdr.sh_type) != SHT_NOBITS)
|
if (rdi(shdr.sh_type) != SHT_NOBITS)
|
||||||
memset(contents + rdi(shdr.sh_offset), 'X', rdi(shdr.sh_size));
|
memset(contents + rdi(shdr.sh_offset), 'X', rdi(shdr.sh_size));
|
||||||
@@ -681,7 +681,7 @@ void ElfFile<ElfFileParamNames>::writeReplacedSections(Elf_Off & curOff,
|
|||||||
|
|
||||||
std::set<unsigned int> noted_phdrs = {};
|
std::set<unsigned int> noted_phdrs = {};
|
||||||
for (auto & i : replacedSections) {
|
for (auto & i : replacedSections) {
|
||||||
std::string sectionName = i.first;
|
const std::string & sectionName = i.first;
|
||||||
auto & shdr = findSection(sectionName);
|
auto & shdr = findSection(sectionName);
|
||||||
Elf_Shdr orig_shdr = shdr;
|
Elf_Shdr orig_shdr = shdr;
|
||||||
debug("rewriting section '%s' from offset 0x%x (size %d) to offset 0x%x (size %d)\n",
|
debug("rewriting section '%s' from offset 0x%x (size %d) to offset 0x%x (size %d)\n",
|
||||||
@@ -710,7 +710,7 @@ void ElfFile<ElfFileParamNames>::writeReplacedSections(Elf_Off & curOff,
|
|||||||
|
|
||||||
/* If this is the .dynamic section, then the PT_DYNAMIC segment
|
/* If this is the .dynamic section, then the PT_DYNAMIC segment
|
||||||
must be sync'ed with it. */
|
must be sync'ed with it. */
|
||||||
if (sectionName == ".dynamic") {
|
else if (sectionName == ".dynamic") {
|
||||||
for (auto & phdr : phdrs) {
|
for (auto & phdr : phdrs) {
|
||||||
if (rdi(phdr.p_type) == PT_DYNAMIC) {
|
if (rdi(phdr.p_type) == PT_DYNAMIC) {
|
||||||
phdr.p_offset = shdr.sh_offset;
|
phdr.p_offset = shdr.sh_offset;
|
||||||
@@ -802,11 +802,11 @@ void ElfFile<ElfFileParamNames>::rewriteSectionsLibrary()
|
|||||||
|
|
||||||
/* Compute the total space needed for the replaced sections */
|
/* Compute the total space needed for the replaced sections */
|
||||||
off_t neededSpace = 0;
|
off_t neededSpace = 0;
|
||||||
for (auto & i : replacedSections)
|
for (auto & s : replacedSections)
|
||||||
neededSpace += roundUp(i.second.size(), sectionAlignment);
|
neededSpace += roundUp(s.second.size(), sectionAlignment);
|
||||||
debug("needed space is %d\n", neededSpace);
|
debug("needed space is %d\n", neededSpace);
|
||||||
|
|
||||||
size_t startOffset = roundUp(fileContents->size(), getPageSize());
|
Elf_Off startOffset = roundUp(fileContents->size(), getPageSize());
|
||||||
|
|
||||||
growFile(fileContents, startOffset + neededSpace);
|
growFile(fileContents, startOffset + neededSpace);
|
||||||
|
|
||||||
@@ -903,7 +903,7 @@ void ElfFile<ElfFileParamNames>::rewriteSectionsExecutable()
|
|||||||
debug("replacing section '%s' which is in the way\n", sectionName.c_str());
|
debug("replacing section '%s' which is in the way\n", sectionName.c_str());
|
||||||
replaceSection(sectionName, rdi(shdr.sh_size));
|
replaceSection(sectionName, rdi(shdr.sh_size));
|
||||||
}
|
}
|
||||||
prevSection = sectionName;
|
prevSection = std::move(sectionName);
|
||||||
}
|
}
|
||||||
|
|
||||||
debug("first reserved offset/addr is 0x%x/0x%llx\n",
|
debug("first reserved offset/addr is 0x%x/0x%llx\n",
|
||||||
@@ -1147,7 +1147,7 @@ void ElfFile<ElfFileParamNames>::rewriteHeaders(Elf_Addr phdrAddress)
|
|||||||
fprintf(stderr, "warning: entry %d in symbol table refers to a non-existent section, skipping\n", shndx);
|
fprintf(stderr, "warning: entry %d in symbol table refers to a non-existent section, skipping\n", shndx);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
std::string section = sectionsByOldIndex.at(shndx);
|
const std::string & section = sectionsByOldIndex.at(shndx);
|
||||||
assert(!section.empty());
|
assert(!section.empty());
|
||||||
auto newIndex = findSection3(section); // inefficient
|
auto newIndex = findSection3(section); // inefficient
|
||||||
//debug("rewriting symbol %d: index = %d (%s) -> %d\n", entry, shndx, section.c_str(), newIndex);
|
//debug("rewriting symbol %d: index = %d (%s) -> %d\n", entry, shndx, section.c_str(), newIndex);
|
||||||
@@ -1202,7 +1202,7 @@ void ElfFile<ElfFileParamNames>::modifySoname(sonameMode op, const std::string &
|
|||||||
|
|
||||||
if (op == printSoname) {
|
if (op == printSoname) {
|
||||||
if (soname) {
|
if (soname) {
|
||||||
if (std::string(soname ? soname : "").empty())
|
if (strlen(soname) == 0)
|
||||||
debug("DT_SONAME is empty\n");
|
debug("DT_SONAME is empty\n");
|
||||||
else
|
else
|
||||||
printf("%s\n", soname);
|
printf("%s\n", soname);
|
||||||
@@ -1212,7 +1212,7 @@ void ElfFile<ElfFileParamNames>::modifySoname(sonameMode op, const std::string &
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (std::string(soname ? soname : "") == newSoname) {
|
if (soname && soname == newSoname) {
|
||||||
debug("current and proposed new SONAMEs are equal keeping DT_SONAME entry\n");
|
debug("current and proposed new SONAMEs are equal keeping DT_SONAME entry\n");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -1373,7 +1373,7 @@ void ElfFile<ElfFileParamNames>::modifyRPath(RPathOp op,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto dyn = (Elf_Dyn *)(contents + rdi(shdrDynamic.sh_offset));
|
dyn = (Elf_Dyn *)(contents + rdi(shdrDynamic.sh_offset));
|
||||||
Elf_Dyn * last = dyn;
|
Elf_Dyn * last = dyn;
|
||||||
for ( ; rdi(dyn->d_tag) != DT_NULL; dyn++) {
|
for ( ; rdi(dyn->d_tag) != DT_NULL; dyn++) {
|
||||||
if (rdi(dyn->d_tag) == DT_RPATH) {
|
if (rdi(dyn->d_tag) == DT_RPATH) {
|
||||||
@@ -1403,7 +1403,7 @@ void ElfFile<ElfFileParamNames>::modifyRPath(RPathOp op,
|
|||||||
changed = true;
|
changed = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (std::string(rpath ? rpath : "") == newRPath) {
|
if (rpath && rpath == newRPath) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1508,7 +1508,7 @@ void ElfFile<ElfFileParamNames>::replaceNeeded(const std::map<std::string, std::
|
|||||||
if (rdi(dyn->d_tag) == DT_NEEDED) {
|
if (rdi(dyn->d_tag) == DT_NEEDED) {
|
||||||
char * name = strTab + rdi(dyn->d_un.d_val);
|
char * name = strTab + rdi(dyn->d_un.d_val);
|
||||||
auto i = libs.find(name);
|
auto i = libs.find(name);
|
||||||
if (i != libs.end()) {
|
if (i != libs.end() && name != i->second) {
|
||||||
auto replacement = i->second;
|
auto replacement = i->second;
|
||||||
|
|
||||||
debug("replacing DT_NEEDED entry '%s' with '%s'\n", name, replacement.c_str());
|
debug("replacing DT_NEEDED entry '%s' with '%s'\n", name, replacement.c_str());
|
||||||
@@ -1560,7 +1560,7 @@ void ElfFile<ElfFileParamNames>::replaceNeeded(const std::map<std::string, std::
|
|||||||
while (verNeedNum > 0) {
|
while (verNeedNum > 0) {
|
||||||
char * file = verStrTab + rdi(need->vn_file);
|
char * file = verStrTab + rdi(need->vn_file);
|
||||||
auto i = libs.find(file);
|
auto i = libs.find(file);
|
||||||
if (i != libs.end()) {
|
if (i != libs.end() && file != i->second) {
|
||||||
auto replacement = i->second;
|
auto replacement = i->second;
|
||||||
|
|
||||||
debug("replacing .gnu.version_r entry '%s' with '%s'\n", file, replacement.c_str());
|
debug("replacing .gnu.version_r entry '%s' with '%s'\n", file, replacement.c_str());
|
||||||
@@ -1739,7 +1739,7 @@ static bool printNeeded = false;
|
|||||||
static bool noDefaultLib = false;
|
static bool noDefaultLib = false;
|
||||||
|
|
||||||
template<class ElfFile>
|
template<class ElfFile>
|
||||||
static void patchElf2(ElfFile && elfFile, const FileContents & fileContents, std::string fileName)
|
static void patchElf2(ElfFile && elfFile, const FileContents & fileContents, const std::string & fileName)
|
||||||
{
|
{
|
||||||
if (printInterpreter)
|
if (printInterpreter)
|
||||||
printf("%s\n", elfFile.getInterpreter().c_str());
|
printf("%s\n", elfFile.getInterpreter().c_str());
|
||||||
@@ -1790,7 +1790,7 @@ static void patchElf()
|
|||||||
debug("patching ELF file '%s'\n", fileName.c_str());
|
debug("patching ELF file '%s'\n", fileName.c_str());
|
||||||
|
|
||||||
auto fileContents = readFile(fileName);
|
auto fileContents = readFile(fileName);
|
||||||
std::string outputFileName2 = outputFileName.empty() ? fileName : outputFileName;
|
const 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, Elf32_Versym>(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);
|
||||||
|
Reference in New Issue
Block a user