summaryrefslogtreecommitdiffstats
path: root/Source
diff options
context:
space:
mode:
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 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;