summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMartin Duffy <martin.duffy@kitware.com>2024-02-22 01:39:00 (GMT)
committerBrad King <brad.king@kitware.com>2024-03-22 14:18:06 (GMT)
commit615a1c6691f25a7805cf9a132f3143385c5a5772 (patch)
tree6cd978129575352b107edba97cc63106771bac17
parent30d8bcd35c318d8c1802b4a07785a01905aeb17d (diff)
downloadCMake-615a1c6691f25a7805cf9a132f3143385c5a5772.zip
CMake-615a1c6691f25a7805cf9a132f3143385c5a5772.tar.gz
CMake-615a1c6691f25a7805cf9a132f3143385c5a5772.tar.bz2
cmELF: Get correct section count for large ELF binaries
Fixes: #24877
-rw-r--r--.gitlab/ci/configure_debian12_ninja_common.cmake2
-rw-r--r--.gitlab/ci/configure_fedora39_makefiles.cmake2
-rw-r--r--Source/cmELF.cxx14
-rw-r--r--Tests/RunCMake/CMakeLists.txt5
-rw-r--r--Tests/RunCMake/file-RPATH/CMakeLists.txt3
-rw-r--r--Tests/RunCMake/file-RPATH/LargeELF.c26
-rw-r--r--Tests/RunCMake/file-RPATH/LargeELF.cmake5
-rw-r--r--Tests/RunCMake/file-RPATH/RunCMakeTest.cmake12
8 files changed, 63 insertions, 6 deletions
diff --git a/.gitlab/ci/configure_debian12_ninja_common.cmake b/.gitlab/ci/configure_debian12_ninja_common.cmake
index 78c1d55..8cebd01 100644
--- a/.gitlab/ci/configure_debian12_ninja_common.cmake
+++ b/.gitlab/ci/configure_debian12_ninja_common.cmake
@@ -90,6 +90,8 @@ set(CMake_TEST_FindwxWidgets "ON" CACHE BOOL "")
set(CMake_TEST_FindX11 "ON" CACHE BOOL "")
set(CMake_TEST_FindXalanC "ON" CACHE BOOL "")
set(CMake_TEST_FindXercesC "ON" CACHE BOOL "")
+
+set(CMake_TEST_ELF_LARGE "ON" CACHE BOOL "")
set(CMake_TEST_Fortran_SUBMODULES "ON" CACHE BOOL "")
set(CMake_TEST_IPO_WORKS_C "ON" CACHE BOOL "")
set(CMake_TEST_IPO_WORKS_CXX "ON" CACHE BOOL "")
diff --git a/.gitlab/ci/configure_fedora39_makefiles.cmake b/.gitlab/ci/configure_fedora39_makefiles.cmake
index fe03851..2c18fde 100644
--- a/.gitlab/ci/configure_fedora39_makefiles.cmake
+++ b/.gitlab/ci/configure_fedora39_makefiles.cmake
@@ -89,6 +89,8 @@ set(CMake_TEST_FindwxWidgets "ON" CACHE BOOL "")
set(CMake_TEST_FindX11 "ON" CACHE BOOL "")
set(CMake_TEST_FindXalanC "ON" CACHE BOOL "")
set(CMake_TEST_FindXercesC "ON" CACHE BOOL "")
+
+set(CMake_TEST_ELF_LARGE "ON" CACHE BOOL "")
set(CMake_TEST_Fortran_SUBMODULES "ON" CACHE BOOL "")
set(CMake_TEST_IPO_WORKS_C "ON" CACHE BOOL "")
set(CMake_TEST_IPO_WORKS_CXX "ON" CACHE BOOL "")
diff --git a/Source/cmELF.cxx b/Source/cmELF.cxx
index 8aea753..d9a4408 100644
--- a/Source/cmELF.cxx
+++ b/Source/cmELF.cxx
@@ -212,7 +212,8 @@ public:
// Return the number of sections as specified by the ELF header.
unsigned int GetNumberOfSections() const override
{
- return static_cast<unsigned int>(this->ELFHeader.e_shnum);
+ return static_cast<unsigned int>(this->ELFHeader.e_shnum +
+ this->SectionHeaders[0].sh_size);
}
// Get the file position of a dynamic section entry.
@@ -367,7 +368,7 @@ private:
return !this->Stream->fail();
}
- bool LoadSectionHeader(ELF_Half i)
+ bool LoadSectionHeader(unsigned int i)
{
// Read the section header from the file.
this->Stream->seekg(this->ELFHeader.e_shoff +
@@ -378,7 +379,7 @@ private:
// Identify some important sections.
if (this->SectionHeaders[i].sh_type == SHT_DYNAMIC) {
- this->DynamicSectionIndex = i;
+ this->DynamicSectionIndex = static_cast<int>(i);
}
return true;
}
@@ -444,8 +445,11 @@ cmELFInternalImpl<Types>::cmELFInternalImpl(cmELF* external,
this->Machine = this->ELFHeader.e_machine;
// Load the section headers.
- this->SectionHeaders.resize(this->ELFHeader.e_shnum);
- for (ELF_Half i = 0; i < this->ELFHeader.e_shnum; ++i) {
+ this->SectionHeaders.resize(
+ this->ELFHeader.e_shnum == 0 ? 1 : this->ELFHeader.e_shnum);
+ this->LoadSectionHeader(0);
+ this->SectionHeaders.resize(this->GetNumberOfSections());
+ for (unsigned int i = 1; i < this->GetNumberOfSections(); ++i) {
if (!this->LoadSectionHeader(i)) {
this->SetErrorMessage("Failed to load section headers.");
return;
diff --git a/Tests/RunCMake/CMakeLists.txt b/Tests/RunCMake/CMakeLists.txt
index d4bb490..aec21fb 100644
--- a/Tests/RunCMake/CMakeLists.txt
+++ b/Tests/RunCMake/CMakeLists.txt
@@ -560,7 +560,10 @@ foreach(var
endif()
endforeach()
add_RunCMake_test(file-DOWNLOAD)
-add_RunCMake_test(file-RPATH -DCMAKE_SYSTEM_NAME=${CMAKE_SYSTEM_NAME})
+add_RunCMake_test(file-RPATH
+ -DCMAKE_SYSTEM_NAME=${CMAKE_SYSTEM_NAME}
+ -DCMake_TEST_ELF_LARGE=${CMake_TEST_ELF_LARGE}
+)
add_RunCMake_test(file-STRINGS)
add_RunCMake_test(find_file -DMINGW=${MINGW})
add_RunCMake_test(find_library -DMINGW=${MINGW} -DCYGWIN=${CYGWIN} -DMSYS=${MSYS} -DMSVC=${MSVC})
diff --git a/Tests/RunCMake/file-RPATH/CMakeLists.txt b/Tests/RunCMake/file-RPATH/CMakeLists.txt
new file mode 100644
index 0000000..94e43ba
--- /dev/null
+++ b/Tests/RunCMake/file-RPATH/CMakeLists.txt
@@ -0,0 +1,3 @@
+cmake_minimum_required(VERSION 3.29)
+project(${RunCMake_TEST} NONE)
+include(${RunCMake_TEST}.cmake)
diff --git a/Tests/RunCMake/file-RPATH/LargeELF.c b/Tests/RunCMake/file-RPATH/LargeELF.c
new file mode 100644
index 0000000..263c2f3
--- /dev/null
+++ b/Tests/RunCMake/file-RPATH/LargeELF.c
@@ -0,0 +1,26 @@
+/* Create more than 65536 ELF sections. */
+
+/* clang-format off */
+#define C0(i) int v##i __attribute__((section("s" #i)))
+#define C1(i) C0(i##0); C0(i##1); C0(i##2); C0(i##3); C0(i##4); \
+ C0(i##5); C0(i##6); C0(i##7); C0(i##8); C0(i##9)
+#define C2(i) C1(i##0); C1(i##1); C1(i##2); C1(i##3); C1(i##4); \
+ C1(i##5); C1(i##6); C1(i##7); C1(i##8); C1(i##9)
+#define C3(i) C2(i##0); C2(i##1); C2(i##2); C2(i##3); C2(i##4); \
+ C2(i##5); C2(i##6); C2(i##7); C2(i##8); C2(i##9)
+#define C4(i) C3(i##0); C3(i##1); C3(i##2); C3(i##3); C3(i##4); \
+ C3(i##5); C3(i##6); C3(i##7); C3(i##8); C3(i##9)
+/* clang-format on */
+
+C4(1);
+C4(2);
+C4(3);
+C4(4);
+C4(5);
+C4(6);
+C4(7);
+
+int main(void)
+{
+ return 0;
+}
diff --git a/Tests/RunCMake/file-RPATH/LargeELF.cmake b/Tests/RunCMake/file-RPATH/LargeELF.cmake
new file mode 100644
index 0000000..2eb813e
--- /dev/null
+++ b/Tests/RunCMake/file-RPATH/LargeELF.cmake
@@ -0,0 +1,5 @@
+enable_language(C)
+
+add_executable(LargeELF LargeELF.c)
+set_property(TARGET LargeELF PROPERTY INSTALL_RPATH "/test")
+install(TARGETS LargeELF)
diff --git a/Tests/RunCMake/file-RPATH/RunCMakeTest.cmake b/Tests/RunCMake/file-RPATH/RunCMakeTest.cmake
index 525df09..028fa11 100644
--- a/Tests/RunCMake/file-RPATH/RunCMakeTest.cmake
+++ b/Tests/RunCMake/file-RPATH/RunCMakeTest.cmake
@@ -16,3 +16,15 @@ run_cmake_command(TextSet ${CMAKE_COMMAND} -P ${RunCMake_SOURCE_DIR}/TextSet.cma
run_cmake_command(TextSetEmpty ${CMAKE_COMMAND} -P ${RunCMake_SOURCE_DIR}/TextSetEmpty.cmake)
run_cmake_command(TextRemove ${CMAKE_COMMAND} -P ${RunCMake_SOURCE_DIR}/TextRemove.cmake)
+
+# Test install RPATH for ELF files with more than 65536 sections.
+# This is supported only by certain platforms/toolchains, so run
+# this case only if explicitly enabled.
+if(CMake_TEST_ELF_LARGE)
+ block()
+ set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/LargeELF-build)
+ run_cmake_with_options(LargeELF -DCMAKE_INSTALL_PREFIX=${RunCMake_TEST_BINARY_DIR}/root)
+ set(RunCMake_TEST_NO_CLEAN 1)
+ run_cmake_command(LargeELF-build ${CMAKE_COMMAND} --build . --target install)
+ endblock()
+endif()