diff options
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 9ce403d..99707a3 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 4e7e36d..395ed56 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 cde7cdf..1678ce8 100644 --- a/Source/cmELF.cxx +++ b/Source/cmELF.cxx @@ -137,6 +137,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. @@ -152,6 +155,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; @@ -439,6 +445,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) { @@ -709,6 +717,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 5807c16..ce8bd7f 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> @@ -68,6 +69,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; |