diff options
author | Eelco Dolstra <e.dolstra@tudelft.nl> | 2005-09-30 23:59:40 (GMT) |
---|---|---|
committer | Eelco Dolstra <e.dolstra@tudelft.nl> | 2005-09-30 23:59:40 (GMT) |
commit | 2369d8b2def0775b0666350fd266bdc0abb07b0d (patch) | |
tree | 363548878e4e56e2cb1c0e8dcfbd30b164a8760a | |
parent | 58ec67927fb649a8325c016f04e050d17f787d66 (diff) | |
download | patchelf-2369d8b2def0775b0666350fd266bdc0abb07b0d.zip patchelf-2369d8b2def0775b0666350fd266bdc0abb07b0d.tar.gz patchelf-2369d8b2def0775b0666350fd266bdc0abb07b0d.tar.bz2 |
* Handle `--set-rpath' for the growing case.
-rw-r--r-- | src/patchelf.cc | 51 | ||||
-rw-r--r-- | tests/Makefile.am | 6 | ||||
-rwxr-xr-x | tests/set-rpath.sh | 15 | ||||
-rwxr-xr-x | tests/shrink.sh | 8 |
4 files changed, 58 insertions, 22 deletions
diff --git a/src/patchelf.cc b/src/patchelf.cc index a5b804b..f93e89d 100644 --- a/src/patchelf.cc +++ b/src/patchelf.cc @@ -185,7 +185,7 @@ static void rewriteSections() for (ReplacedSections::iterator i = replacedSections.begin(); i != replacedSections.end(); ++i) - fprintf(stderr, "replacing section `%s' with size `%d', content `%s'\n", + fprintf(stderr, "replacing section `%s' with size %d, content `%s'\n", i->first.c_str(), i->second.size(), i->second.c_str()); @@ -215,7 +215,8 @@ static void rewriteSections() string sectionName = getSectionName(shdr); fprintf(stderr, "looking at section `%s'\n", sectionName.c_str()); if (replacedSections.find(sectionName) != replacedSections.end()) continue; - if (shdr.sh_type == SHT_PROGBITS && sectionName != ".interp") { + if (true /* XXX shdr.sh_type == SHT_PROGBITS && sectionName != + ".interp" */) { startOffset = shdr.sh_offset; startAddr = shdr.sh_addr; lastReplaced = i - 1; @@ -288,13 +289,25 @@ static void rewriteSections() shdr.sh_addralign = 4; /* If this is the .interp section, then the PT_INTERP segment - has to be synced with it. */ - for (int j = 0; j < phdrs.size(); ++j) - if (phdrs[j].p_type == PT_INTERP) { - phdrs[j].p_offset = shdr.sh_offset; - phdrs[j].p_vaddr = phdrs[j].p_paddr = shdr.sh_addr; - phdrs[j].p_filesz = phdrs[j].p_memsz = shdr.sh_size; - } + has to be sync'ed with it. */ + if (i->first == ".interp") { + for (int j = 0; j < phdrs.size(); ++j) + if (phdrs[j].p_type == PT_INTERP) { + phdrs[j].p_offset = shdr.sh_offset; + phdrs[j].p_vaddr = phdrs[j].p_paddr = shdr.sh_addr; + phdrs[j].p_filesz = phdrs[j].p_memsz = shdr.sh_size; + } + } + + /* If this is the .dynstr section, then the .dynamic section + has to be sync'ed with it. */ + if (i->first == ".dynstr") { + Elf32_Shdr & shdrDynamic = findSection(".dynamic"); + Elf32_Dyn * dyn = (Elf32_Dyn *) (contents + shdrDynamic.sh_offset); + for ( ; dyn->d_tag != DT_NULL; dyn++) + if (dyn->d_tag == DT_STRTAB) + dyn->d_un.d_ptr = shdr.sh_addr; + } curOff += roundUp(i->second.size(), 4); } @@ -369,10 +382,12 @@ static void modifyRPath(RPathOp op, string newRPath) /* Walk through the dynamic section, look for the RPATH entry. */ static vector<string> neededLibs; dyn = (Elf32_Dyn *) (contents + shdrDynamic.sh_offset); + Elf32_Dyn * dynRPath = 0; Elf32_Dyn * rpathEntry = 0; char * rpath = 0; for ( ; dyn->d_tag != DT_NULL; dyn++) { if (dyn->d_tag == DT_RPATH) { + dynRPath = dyn; rpathEntry = dyn; rpath = strTab + dyn->d_un.d_val; } @@ -437,14 +452,17 @@ static void modifyRPath(RPathOp op, string newRPath) } - if (string(rpath) == newRPath) return; + if (string(rpath ? rpath : "") == newRPath) return; changed = true; /* Zero out the previous rpath to prevent retained dependencies in Nix. */ - unsigned int rpathSize = strlen(rpath); - memset(rpath, 0, rpathSize); + unsigned int rpathSize = 0; + if (rpath) { + rpathSize = strlen(rpath); + memset(rpath, 'X', rpathSize); + } fprintf(stderr, "new rpath is `%s'\n", newRPath.c_str()); @@ -453,7 +471,16 @@ static void modifyRPath(RPathOp op, string newRPath) return; } + /* Grow the .dynstr section to make room for the new RPATH. */ fprintf(stderr, "rpath is too long, resizing...\n"); + + string & newDynStr = replaceSection(".dynstr", + shdrDynStr.sh_size + newRPath.size() + 1); + setSubstr(newDynStr, shdrDynStr.sh_size, newRPath + '\0'); + + /* Update the DT_RPATH entry. */ + assert(dynRPath != 0); + dynRPath->d_un.d_val = shdrDynStr.sh_size; } diff --git a/tests/Makefile.am b/tests/Makefile.am index ccd86dd..3d6a726 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -10,19 +10,19 @@ simple_SOURCES = simple.c main: main.o libfoo.so - LD_LIBRARY_PATH=. $(CC) -o main main.o -L . -lfoo + LD_LIBRARY_PATH=. gcc -o main main.o -L . -lfoo main.o: main.c $(CC) -fpic -o main.o -c main.c libfoo.so: foo.o libbar.so - $(CC) -shared -o libfoo.so foo.o -L . -lbar -Wl,-rpath,`pwd`/no-such-path + $(CC) -shared -o libfoo.so foo.o -L . -lbar foo.o: foo.c $(CC) -fpic -o foo.o -c foo.c libbar.so: bar.o - $(CC) -shared -o libbar.so bar.o -L . + NIX_DONT_SET_RPATH=1 $(CC) -shared -o libbar.so bar.o -L . -Wl,-rpath,`pwd`/no-such-path bar.o: bar.c $(CC) -fpic -o bar.o -c bar.c diff --git a/tests/set-rpath.sh b/tests/set-rpath.sh index 6446395..cbe1006 100755 --- a/tests/set-rpath.sh +++ b/tests/set-rpath.sh @@ -9,11 +9,20 @@ cp main scratch/ cp libfoo.so scratch/libsA/ cp libbar.so scratch/libsB/ -../src/patchelf --set-rpath $(pwd)/scratch/libsA scratch/main -../src/patchelf --set-rpath $(pwd)/scratch/libsB scratch/libsA/libfoo.so +oldRPath=$(../src/patchelf --print-rpath scratch/main) +if test -z "$oldRPath"; then oldRPath="/oops"; fi +../src/patchelf --set-rpath $oldRPath:$(pwd)/scratch/libsA:$(pwd)/scratch/libsB scratch/main + +#oldRPath=$(../src/patchelf --print-rpath scratch/libsA/libfoo.so) +#if test -z "$oldRPath"; then oldRPath="/oops"; fi +#../src/patchelf --set-rpath $oldRPath:$(pwd)/scratch/libsB scratch/libsA/libfoo.so + +#oldRPath=$(../src/patchelf --print-rpath scratch/libsB/libbar.so) +#if test -z "$oldRPath"; then oldRPath="/oops"; fi +#../src/patchelf --set-rpath $oldRPath:$(pwd)/scratch/libsC scratch/libsB/libbar.so exitCode=0 -scratch/main || exitCode=$? +cd scratch && ./main || exitCode=$? if test "$exitCode" != 46; then echo "bad exit code!" diff --git a/tests/shrink.sh b/tests/shrink.sh index 563270f..bbbf4d6 100755 --- a/tests/shrink.sh +++ b/tests/shrink.sh @@ -1,6 +1,6 @@ #! /bin/sh -e -rpath=$(../src/patchelf --print-rpath ./libfoo.so) +rpath=$(../src/patchelf --print-rpath ./libbar.so) echo "RPATH before: $rpath" if ! echo "$rpath" | grep -q /no-such-path; then echo "incomplete RPATH" @@ -9,10 +9,10 @@ fi rm -rf scratch mkdir -p scratch -cp libfoo.so scratch/ -../src/patchelf --shrink-rpath scratch/libfoo.so +cp libbar.so scratch/ +../src/patchelf --shrink-rpath scratch/libbar.so -rpath=$(../src/patchelf --print-rpath scratch/libfoo.so) +rpath=$(../src/patchelf --print-rpath scratch/libbar.so) echo "RPATH after: $rpath" if echo "$rpath" | grep -q /no-such-path; then echo "RPATH not shrunk" |