summaryrefslogtreecommitdiff
path: root/Source
diff options
context:
space:
mode:
authorKyle Edwards <kyle.edwards@kitware.com>2021-07-12 15:38:43 -0400
committerKyle Edwards <kyle.edwards@kitware.com>2021-07-12 16:11:38 -0400
commitb2c03347b07e24a5298361451277264fda8fdb4c (patch)
treea75226752cd15e5b81a079c3410ca54540de51a3 /Source
parentac984cb5f75349fd5ed00cc52fbb5154b7bb1527 (diff)
downloadcmake-b2c03347b07e24a5298361451277264fda8fdb4c.tar.gz
file(GET_RUNTIME_DEPENDENCIES): Check architecture of dependencies
Fixes: #22106
Diffstat (limited to 'Source')
-rw-r--r--Source/cmBinUtilsLinuxELFLinker.cxx43
-rw-r--r--Source/cmBinUtilsLinuxELFLinker.h4
-rw-r--r--Source/cmELF.cxx16
-rw-r--r--Source/cmELF.h4
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;