Handle libraries with more than one .shstrtab section

This commit is contained in:
Pablo Galindo 2020-09-22 01:22:42 +01:00
parent 5cd451775a
commit a89d508130
No known key found for this signature in database
GPG Key ID: FFE87404168BD847
4 changed files with 40 additions and 6 deletions

View File

@ -495,7 +495,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;
@ -515,8 +515,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);
}
}
}

View File

@ -1,6 +1,6 @@
LIBS =
check_PROGRAMS = simple main main-scoped big-dynstr no-rpath
check_PROGRAMS = simple main too-many-strtab main-scoped big-dynstr no-rpath
no_rpath_arch_TESTS = \
no-rpath-amd64.sh \
@ -25,7 +25,8 @@ src_TESTS = \
force-rpath.sh \
plain-needed.sh \
output-flag.sh \
build-id.sh
build-id.sh \
too-many-strtab.sh
build_TESTS = \
$(no_rpath_arch_TESTS)
@ -77,7 +78,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
@ -101,6 +102,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 =

3
tests/too-many-strtab.c Normal file
View File

@ -0,0 +1,3 @@
const int __attribute__((section (".shstrtab"))) lel = 42;
int main(){return 0;}

21
tests/too-many-strtab.sh Executable file
View File

@ -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