diff --git a/src/patchelf.cc b/src/patchelf.cc index c8fb56a4..5c1fc0ee 100644 --- a/src/patchelf.cc +++ b/src/patchelf.cc @@ -997,9 +997,6 @@ void ElfFile::rewriteSectionsExecutable() Stop when we reach an irreplacable section (such as one of type SHT_PROGBITS). These cannot be moved in virtual address space since that would invalidate absolute references to them. */ - assert(lastReplaced + 1 < shdrs.size()); /* !!! I'm lazy. */ - size_t startOffset = rdi(shdrs.at(lastReplaced + 1).sh_offset); - Elf_Addr startAddr = rdi(shdrs.at(lastReplaced + 1).sh_addr); std::string prevSection; for (unsigned int i = 1; i <= lastReplaced; ++i) { Elf_Shdr & shdr(shdrs.at(i)); @@ -1010,8 +1007,6 @@ void ElfFile::rewriteSectionsExecutable() if ((rdi(shdr.sh_type) == SHT_PROGBITS && sectionName != ".interp") || prevSection == ".dynstr") { - startOffset = rdi(shdr.sh_offset); - startAddr = rdi(shdr.sh_addr); lastReplaced = i - 1; break; } @@ -1022,6 +1017,13 @@ void ElfFile::rewriteSectionsExecutable() prevSection = std::move(sectionName); } + while (lastReplaced < shdrs.size() && shdrs.at(lastReplaced).sh_type == SHT_NOBITS) + ++lastReplaced; + + assert(lastReplaced + 1 < shdrs.size()); /* !!! I'm lazy. */ + size_t startOffset = rdi(shdrs.at(lastReplaced + 1).sh_offset); + Elf_Addr startAddr = rdi(shdrs.at(lastReplaced + 1).sh_addr); + debug("first reserved offset/addr is 0x%x/0x%llx\n", startOffset, (unsigned long long) startAddr); @@ -1238,7 +1240,7 @@ void ElfFile::rewriteHeaders(Elf_Addr phdrAddress) section. Note that not all executables have .dynamic sections (e.g., those produced by klibc's klcc). */ auto shdrDynamic = tryFindSectionHeader(".dynamic"); - if (shdrDynamic) { + if (shdrDynamic && rdi((*shdrDynamic).get().sh_type) != SHT_NOBITS) { auto dyn_table = (Elf_Dyn *) (fileContents->data() + rdi((*shdrDynamic).get().sh_offset)); unsigned int d_tag; for (auto dyn = dyn_table; (d_tag = rdi(dyn->d_tag)) != DT_NULL; dyn++) diff --git a/tests/Makefile.am b/tests/Makefile.am index b08929f1..3a54c5f6 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -53,7 +53,8 @@ src_TESTS = \ shared-rpath.sh \ short-first-segment.sh \ empty-note.sh \ - set-interpreter-same.sh + set-interpreter-same.sh \ + debug-interp.sh build_TESTS = \ $(no_rpath_arch_TESTS) diff --git a/tests/debug-interp.sh b/tests/debug-interp.sh new file mode 100755 index 00000000..77ce2ee4 --- /dev/null +++ b/tests/debug-interp.sh @@ -0,0 +1,13 @@ +#! /bin/sh -e +SCRATCH=scratch/$(basename "$0" .sh) +OBJCOPY=${OBJCOPY:-objcopy} + +rm -rf "${SCRATCH}" +mkdir -p "${SCRATCH}" + +cp simple "${SCRATCH}/" + +${OBJCOPY} --only-keep-debug "${SCRATCH}/simple" "${SCRATCH}/simple.debug" + +# Check if patchelf handles debug-only executables +../src/patchelf --set-interpreter /oops "${SCRATCH}/simple.debug"