summaryrefslogtreecommitdiffstats
path: root/src/patchelf.cc
diff options
context:
space:
mode:
authorEelco Dolstra <e.dolstra@tudelft.nl>2005-09-30 21:59:38 (GMT)
committerEelco Dolstra <e.dolstra@tudelft.nl>2005-09-30 21:59:38 (GMT)
commitc95131955924d63b2acd26fb9f0f04cdf38fed01 (patch)
tree3309f429e0f45f9cf19fb1d5a1aef3df424a942e /src/patchelf.cc
parentddf3b787d77324f61afb86816c0393bf65130b10 (diff)
downloadpatchelf-c95131955924d63b2acd26fb9f0f04cdf38fed01.zip
patchelf-c95131955924d63b2acd26fb9f0f04cdf38fed01.tar.gz
patchelf-c95131955924d63b2acd26fb9f0f04cdf38fed01.tar.bz2
* Refactoring continued: `--shrink-rpath' works again.
Diffstat (limited to 'src/patchelf.cc')
-rw-r--r--src/patchelf.cc195
1 files changed, 61 insertions, 134 deletions
diff --git a/src/patchelf.cc b/src/patchelf.cc
index 62ef22f..1932fa3 100644
--- a/src/patchelf.cc
+++ b/src/patchelf.cc
@@ -337,40 +337,6 @@ static void setInterpreter(const string & newInterpreter)
}
-#if 0
-static void setInterpreter()
-{
- /* Find the PT_INTERP segment and replace it by a new one that
- contains the new interpreter name. */
- if ((newInterpreter != "" || printInterpreter) && hdr->e_type == ET_EXEC) {
- shiftFile();
- int i;
- for (i = 0; i < hdr->e_phnum; ++i) {
- Elf32_Phdr & phdr = phdrs[i];
- if (phdr.p_type == PT_INTERP) {
- if (printInterpreter) {
- printf("%s\n", (char *) (contents + phdr.p_offset));
- exit(0);
- }
- fprintf(stderr, "changing interpreter from `%s' to `%s'\n",
- (char *) (contents + phdr.p_offset), newInterpreter.c_str());
- unsigned int interpOffset = freeOffset;
- unsigned int interpSize = newInterpreter.size() + 1;
- freeOffset += roundUp(interpSize, 4);
- phdr.p_offset = interpOffset;
- growFile(phdr.p_offset + interpSize);
- phdr.p_vaddr = phdr.p_paddr = firstPage + interpOffset % 4096;
- phdr.p_filesz = phdr.p_memsz = interpSize;
- strncpy((char *) contents + interpOffset,
- newInterpreter.c_str(), interpSize);
- changed = true;
- break;
- }
- }
- }
-}
-
-
static void concatToRPath(string & rpath, const string & path)
{
if (!rpath.empty()) rpath += ":";
@@ -378,76 +344,59 @@ static void concatToRPath(string & rpath, const string & path)
}
-static void shrinkRPath()
-{
- /* Shrink the RPATH. */
- if (doShrinkRPath || printRPath) {
+typedef enum { rpPrint, rpShrink, rpSet } RPathOp;
- static vector<string> neededLibs;
-
- /* Find the .dynamic section. */
- int i, dynSec = 0;
- for (i = 0; i < hdr->e_shnum; ++i)
- if (shdrs[i].sh_type == SHT_DYNAMIC) dynSec = i;
-
- if (!dynSec) {
- fprintf(stderr, "no dynamic section, so no RPATH to shrink\n");
- return;
- }
- /* Find the DT_STRTAB entry in the dynamic section. */
- Elf32_Dyn * dyn = (Elf32_Dyn *) (contents + shdrs[dynSec].sh_offset);
- Elf32_Addr strTabAddr = 0;
- for ( ; dyn->d_tag != DT_NULL; dyn++)
- if (dyn->d_tag == DT_STRTAB) strTabAddr = dyn->d_un.d_ptr;
+static void modifyRPath(RPathOp op, string newRPath)
+{
+ Elf32_Shdr & shdrDynamic = findSection(".dynamic");
- if (!strTabAddr) {
- fprintf(stderr, "strange: no string table\n");
- return;
- }
+ /* !!! We assume that the virtual address in the DT_STRTAB entry
+ of the dynamic section corresponds to the .dynstr section. */
+ Elf32_Shdr & shdrDynStr = findSection(".dynstr");
+ char * strTab = (char *) contents + shdrDynStr.sh_offset;
- /* Nasty: map the virtual address for the string table back to
- a offset in the file. */
- char * strTab = 0;
- for (i = 0; i < hdr->e_phnum; ++i)
- if (phdrs[i].p_vaddr <= strTabAddr &&
- strTabAddr < phdrs[i].p_vaddr + phdrs[i].p_filesz)
- {
- strTab = (char *) contents +
- strTabAddr - phdrs[i].p_vaddr + phdrs[i].p_offset;
- }
+ /* Find the DT_STRTAB entry in the dynamic section. */
+ Elf32_Dyn * dyn = (Elf32_Dyn *) (contents + shdrDynamic.sh_offset);
+ Elf32_Addr strTabAddr = 0;
+ for ( ; dyn->d_tag != DT_NULL; dyn++)
+ if (dyn->d_tag == DT_STRTAB) strTabAddr = dyn->d_un.d_ptr;
+ if (!strTabAddr) error("strange: no string table");
- if (!strTab) error("could not reverse map DT_STRTAB");
-
- /* Walk through the dynamic section, look for the RPATH
- entry. */
- dyn = (Elf32_Dyn *) (contents + shdrs[dynSec].sh_offset);
- Elf32_Dyn * rpathEntry = 0;
- char * rpath = 0;
- for ( ; dyn->d_tag != DT_NULL; dyn++) {
- if (dyn->d_tag == DT_RPATH) {
- rpathEntry = dyn;
- rpath = strTab + dyn->d_un.d_val;
- }
- else if (dyn->d_tag == DT_NEEDED)
- neededLibs.push_back(string(strTab + dyn->d_un.d_val));
+ assert(strTabAddr == shdrDynStr.sh_addr);
+
+
+ /* Walk through the dynamic section, look for the RPATH entry. */
+ static vector<string> neededLibs;
+ dyn = (Elf32_Dyn *) (contents + shdrDynamic.sh_offset);
+ Elf32_Dyn * rpathEntry = 0;
+ char * rpath = 0;
+ for ( ; dyn->d_tag != DT_NULL; dyn++) {
+ if (dyn->d_tag == DT_RPATH) {
+ rpathEntry = dyn;
+ rpath = strTab + dyn->d_un.d_val;
}
+ else if (dyn->d_tag == DT_NEEDED)
+ neededLibs.push_back(string(strTab + dyn->d_un.d_val));
+ }
- if (printRPath) {
- printf("%s\n", rpath ? rpath : "");
- exit(0);
- }
-
- if (!rpath) {
- fprintf(stderr, "no RPATH to shrink\n");
- return;
- }
+ if (op == rpPrint) {
+ printf("%s\n", rpath ? rpath : "");
+ return;
+ }
+
+ if (op == rpShrink && !rpath) {
+ fprintf(stderr, "no RPATH to shrink\n");
+ return;
+ }
- /* For each directory in the RPATH, check if it contains any
- needed library. */
+
+ /* For each directory in the RPATH, check if it contains any
+ needed library. */
+ if (op == rpShrink) {
static vector<bool> neededLibFound(neededLibs.size(), false);
- string newRPath;
+ newRPath = "";
char * pos = rpath;
while (*pos) {
@@ -485,18 +434,19 @@ static void shrinkRPath()
else
concatToRPath(newRPath, dirName);
}
+ }
- if (string(rpath) != newRPath) {
- assert(newRPath.size() <= strlen(rpath));
- /* Zero out the previous rpath to prevent retained
- dependencies in Nix. */
- memset(rpath, 0, strlen(rpath));
- strcpy(rpath, newRPath.c_str());
- changed = true;
- }
+
+ if (string(rpath) != newRPath) {
+ assert(newRPath.size() <= strlen(rpath));
+ /* Zero out the previous rpath to prevent retained
+ dependencies in Nix. */
+ memset(rpath, 0, strlen(rpath));
+ strcpy(rpath, newRPath.c_str());
+ changed = true;
}
+
}
-#endif
static void parseElf()
@@ -551,7 +501,7 @@ static void parseElf()
static string newInterpreter;
-static bool doShrinkRPath = false;
+static bool shrinkRPath = false;
static bool printRPath = false;
static bool printInterpreter = false;
@@ -577,41 +527,18 @@ static void patchElf()
if (newInterpreter != "")
setInterpreter(newInterpreter);
+ if (shrinkRPath)
+ modifyRPath(rpShrink, "");
+
+ if (printRPath)
+ modifyRPath(rpPrint, "");
+
if (changed){
rewriteSections();
writeFile(fileName, fileMode);
}
-
-#if 0
- /* Find the next free virtual address page so that we can add
- segments without messing up other segments. */
- int i;
- unsigned int nextFreePage = 0;
- for (i = 0; i < hdr->e_phnum; ++i) {
- Elf32_Phdr & phdr = phdrs[i];
- unsigned int end = roundUp(phdr.p_vaddr + phdr.p_memsz, 4096);
- if (end > nextFreePage) nextFreePage = end;
- }
-
- firstPage = 0x08047000;
-
- /* Do what we're supposed to do. */
- setInterpreter();
- shrinkRPath();
-
- assert(!printInterpreter && !printRPath);
-
- if (rewriteHeaders) {
- hdr->e_shoff = freeOffset;
- freeOffset += hdr->e_shnum * sizeof(Elf32_Shdr);
- for (int i = 0; i < hdr->e_shnum; ++i)
- * ((Elf32_Shdr *) (contents + hdr->e_shoff) + i) = shdrs[i];
-
- if (freeOffset > 4096) error("ran out of space in page 0");
- }
-#endif
}
@@ -638,7 +565,7 @@ int main(int argc, char * * argv)
printInterpreter = true;
}
else if (arg == "--shrink-rpath") {
- doShrinkRPath = true;
+ shrinkRPath = true;
}
else if (arg == "--print-rpath") {
printRPath = true;