Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 9 additions & 3 deletions src/patchelf.cc
Original file line number Diff line number Diff line change
Expand Up @@ -501,7 +501,7 @@ void ElfFile<ElfFileParamNames>::sortShdrs()
info[getSectionName(shdrs[i])] = getSectionName(shdrs[rdi(shdrs[i].sh_info)]);

/* Idem for the index of the .shstrtab section in the ELF header. */
SectionName shstrtabName = getSectionName(shdrs[rdi(hdr->e_shstrndx)]);
Elf_Shdr shstrtab = shdrs[rdi(hdr->e_shstrndx)];

/* Sort the sections by offset. */
CompShdr comp;
Expand All @@ -521,8 +521,14 @@ void ElfFile<ElfFileParamNames>::sortShdrs()
wri(shdrs[i].sh_info,
findSection3(info[getSectionName(shdrs[i])]));

/* And the .shstrtab index. */
wri(hdr->e_shstrndx, findSection3(shstrtabName));
/* And the .shstrtab index. Note: the match here is done by checking the offset as searching
* by name can yield incorrect results in case there are multiple sections with the same
* name as the one initially pointed by hdr->e_shstrndx */
for (unsigned int i = 1; i < rdi(hdr->e_shnum); ++i) {
if (shdrs[i].sh_offset == shstrtab.sh_offset) {
wri(hdr->e_shstrndx, i);
}
}
}

static void writeFile(const std::string & fileName, const FileContents & contents)
Expand Down
8 changes: 6 additions & 2 deletions tests/Makefile.am
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
LIBS =

check_PROGRAMS = simple main main-scoped big-dynstr no-rpath contiguous_note_sections
check_PROGRAMS = simple main too-many-strtab main-scoped big-dynstr no-rpath contiguous_note_sections

no_rpath_arch_TESTS = \
no-rpath-amd64.sh \
Expand All @@ -25,6 +25,7 @@ src_TESTS = \
force-rpath.sh \
plain-needed.sh \
output-flag.sh \
too-many-strtab.sh \
no-rpath-pie-powerpc.sh \
build-id.sh \
invalid-elf.sh \
Expand Down Expand Up @@ -81,7 +82,7 @@ big_dynstr_LDFLAGS = $(LDFLAGS_local)
# - without libtool, only archives (static libraries) can be built by automake
# - with libtool, it is difficult to control options
# - with libtool, it is not possible to compile convenience *dynamic* libraries :-(
check_PROGRAMS += libfoo.so libfoo-scoped.so libbar.so libbar-scoped.so libsimple.so libbuildid.so
check_PROGRAMS += libfoo.so libfoo-scoped.so libbar.so libbar-scoped.so libsimple.so libbuildid.so libtoomanystrtab.so

libbuildid_so_SOURCES = simple.c
libbuildid_so_LDFLAGS = $(LDFLAGS_sharedlib) -Wl,-build-id
Expand All @@ -105,6 +106,9 @@ libbar_scoped_so_LDFLAGS = $(LDFLAGS_sharedlib)
libsimple_so_SOURCES = simple.c
libsimple_so_LDFLAGS = $(LDFLAGS_sharedlib)

libtoomanystrtab_so_SOURCES = too-many-strtab.c
libtoomanystrtab_so_LDFLAGS = $(LDFLAGS_sharedlib)

no_rpath_SOURCES = no-rpath.c
# no -fpic for no-rpath.o
no_rpath_CFLAGS =
Expand Down
3 changes: 3 additions & 0 deletions tests/too-many-strtab.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
const int __attribute__((section (".shstrtab"))) lel = 42;

int main(){return 0;}
21 changes: 21 additions & 0 deletions tests/too-many-strtab.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
#! /bin/sh -e
SCRATCH=scratch/$(basename $0 .sh)

rm -rf ${SCRATCH}
mkdir -p ${SCRATCH}

cp libtoomanystrtab.so ${SCRATCH}/

# Set a RUNPATH on the library
../src/patchelf --set-rpath '$ORIGIN' ${SCRATCH}/libtoomanystrtab.so

# Check that patchelf is able to patch it again without crashing. Previously,
# it will wrongly identify the lib as a static object because there was no
# .dynamic section
exitCode=0
(../src/patchelf --set-rpath '$ORIGIN' ${SCRATCH}/libtoomanystrtab.so) || exitCode=$?
if test "$exitCode" != 0; then
echo "bad exit code!"
exit 1
fi