diff options
author | Martin Duffy <martin.duffy@kitware.com> | 2024-02-22 01:39:00 (GMT) |
---|---|---|
committer | Brad King <brad.king@kitware.com> | 2024-03-22 14:18:06 (GMT) |
commit | 615a1c6691f25a7805cf9a132f3143385c5a5772 (patch) | |
tree | 6cd978129575352b107edba97cc63106771bac17 | |
parent | 30d8bcd35c318d8c1802b4a07785a01905aeb17d (diff) | |
download | CMake-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.cmake | 2 | ||||
-rw-r--r-- | .gitlab/ci/configure_fedora39_makefiles.cmake | 2 | ||||
-rw-r--r-- | Source/cmELF.cxx | 14 | ||||
-rw-r--r-- | Tests/RunCMake/CMakeLists.txt | 5 | ||||
-rw-r--r-- | Tests/RunCMake/file-RPATH/CMakeLists.txt | 3 | ||||
-rw-r--r-- | Tests/RunCMake/file-RPATH/LargeELF.c | 26 | ||||
-rw-r--r-- | Tests/RunCMake/file-RPATH/LargeELF.cmake | 5 | ||||
-rw-r--r-- | Tests/RunCMake/file-RPATH/RunCMakeTest.cmake | 12 |
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() |