diff options
author | Kyle Edwards <kyle.edwards@kitware.com> | 2021-07-12 15:38:43 -0400 |
---|---|---|
committer | Kyle Edwards <kyle.edwards@kitware.com> | 2021-07-12 16:11:38 -0400 |
commit | b2c03347b07e24a5298361451277264fda8fdb4c (patch) | |
tree | a75226752cd15e5b81a079c3410ca54540de51a3 /Source | |
parent | ac984cb5f75349fd5ed00cc52fbb5154b7bb1527 (diff) | |
download | cmake-b2c03347b07e24a5298361451277264fda8fdb4c.tar.gz |
file(GET_RUNTIME_DEPENDENCIES): Check architecture of dependencies
Fixes: #22106
Diffstat (limited to 'Source')
-rw-r--r-- | Source/cmBinUtilsLinuxELFLinker.cxx | 43 | ||||
-rw-r--r-- | Source/cmBinUtilsLinuxELFLinker.h | 4 | ||||
-rw-r--r-- | Source/cmELF.cxx | 16 | ||||
-rw-r--r-- | Source/cmELF.h | 4 |
4 files changed, 65 insertions, 2 deletions
diff --git a/Source/cmBinUtilsLinuxELFLinker.cxx b/Source/cmBinUtilsLinuxELFLinker.cxx index 9ce403dcc0..99707a3f70 100644 --- a/Source/cmBinUtilsLinuxELFLinker.cxx +++ b/Source/cmBinUtilsLinuxELFLinker.cxx @@ -18,6 +18,10 @@ #include "cmStringAlgorithms.h" #include "cmSystemTools.h" +#ifdef CMake_USE_ELF_PARSER +# include "cmELF.h" +#endif + static std::string ReplaceOrigin(const std::string& rpath, const std::string& origin) { @@ -86,6 +90,24 @@ bool cmBinUtilsLinuxELFLinker::ScanDependencies( std::string const& file, cmStateEnums::TargetType /* unused */) { std::vector<std::string> parentRpaths; + +#ifdef CMake_USE_ELF_PARSER + cmELF elf(file.c_str()); + if (!elf) { + return false; + } + if (elf.GetMachine() != 0) { + if (this->Machine != 0) { + if (elf.GetMachine() != this->Machine) { + this->SetError("All files must have the same architecture."); + return false; + } + } else { + this->Machine = elf.GetMachine(); + } + } +#endif + return this->ScanDependencies(file, parentRpaths); } @@ -150,13 +172,29 @@ bool cmBinUtilsLinuxELFLinker::ScanDependencies( return true; } +namespace { +bool FileHasArchitecture(const char* filename, std::uint16_t machine) +{ +#ifdef CMake_USE_ELF_PARSER + cmELF elf(filename); + if (!elf) { + return false; + } + return machine == 0 || machine == elf.GetMachine(); +#else + return true; +#endif +} +} + bool cmBinUtilsLinuxELFLinker::ResolveDependency( std::string const& name, std::vector<std::string> const& searchPaths, std::string& path, bool& resolved) { for (auto const& searchPath : searchPaths) { path = cmStrCat(searchPath, '/', name); - if (cmSystemTools::PathExists(path)) { + if (cmSystemTools::PathExists(path) && + FileHasArchitecture(path.c_str(), this->Machine)) { resolved = true; return true; } @@ -164,7 +202,8 @@ bool cmBinUtilsLinuxELFLinker::ResolveDependency( for (auto const& searchPath : this->Archive->GetSearchDirectories()) { path = cmStrCat(searchPath, '/', name); - if (cmSystemTools::PathExists(path)) { + if (cmSystemTools::PathExists(path) && + FileHasArchitecture(path.c_str(), this->Machine)) { std::ostringstream warning; warning << "Dependency " << name << " found in search directory:\n " << searchPath diff --git a/Source/cmBinUtilsLinuxELFLinker.h b/Source/cmBinUtilsLinuxELFLinker.h index 4e7e36d4c8..395ed567b4 100644 --- a/Source/cmBinUtilsLinuxELFLinker.h +++ b/Source/cmBinUtilsLinuxELFLinker.h @@ -3,6 +3,9 @@ #pragma once +#include "cmConfigure.h" // IWYU pragma: keep + +#include <cstdint> #include <memory> #include <string> #include <vector> @@ -29,6 +32,7 @@ private: std::unique_ptr<cmLDConfigTool> LDConfigTool; bool HaveLDConfigPaths = false; std::vector<std::string> LDConfigPaths; + std::uint16_t Machine = 0; bool ScanDependencies(std::string const& file, std::vector<std::string> const& parentRpaths); diff --git a/Source/cmELF.cxx b/Source/cmELF.cxx index deffdb6467..9a474e32c5 100644 --- a/Source/cmELF.cxx +++ b/Source/cmELF.cxx @@ -168,6 +168,9 @@ public: // Return the recorded ELF type. cmELF::FileType GetFileType() const { return this->ELFType; } + // Return the recorded machine. + std::uint16_t GetMachine() const { return this->Machine; } + protected: // Data common to all ELF class implementations. @@ -183,6 +186,9 @@ protected: // The ELF file type. cmELF::FileType ELFType; + // The ELF architecture. + std::uint16_t Machine; + // Whether we need to byte-swap structures read from the stream. bool NeedSwap; @@ -478,6 +484,8 @@ 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) { @@ -757,6 +765,14 @@ cmELF::FileType cmELF::GetFileType() const return FileTypeInvalid; } +std::uint16_t cmELF::GetMachine() const +{ + if (this->Valid()) { + return this->Internal->GetMachine(); + } + return 0; +} + unsigned int cmELF::GetNumberOfSections() const { if (this->Valid()) { diff --git a/Source/cmELF.h b/Source/cmELF.h index c479e2b951..f88ebe9920 100644 --- a/Source/cmELF.h +++ b/Source/cmELF.h @@ -4,6 +4,7 @@ #include "cmConfigure.h" // IWYU pragma: keep +#include <cstdint> #include <iosfwd> #include <memory> #include <string> @@ -72,6 +73,9 @@ public: /** Get the type of the file opened. */ FileType GetFileType() const; + /** Get the machine of the file opened. */ + std::uint16_t GetMachine() const; + /** Get the number of ELF sections present. */ unsigned int GetNumberOfSections() const; |