Merge topic 'file-RPATH-large-ELF'

615a1c6691 cmELF: Get correct section count for large ELF binaries

Acked-by: Kitware Robot <kwrobot@kitware.com>
Merge-request: !9310
This commit is contained in:
Brad King
2024-03-24 18:34:12 +00:00
committed by Kitware Robot
8 changed files with 63 additions and 6 deletions

View File

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

View File

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

View File

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

View File

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

View File

@@ -0,0 +1,3 @@
cmake_minimum_required(VERSION 3.29)
project(${RunCMake_TEST} NONE)
include(${RunCMake_TEST}.cmake)

View File

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

View File

@@ -0,0 +1,5 @@
enable_language(C)
add_executable(LargeELF LargeELF.c)
set_property(TARGET LargeELF PROPERTY INSTALL_RPATH "/test")
install(TARGETS LargeELF)

View File

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