summaryrefslogtreecommitdiffstats
path: root/Source/cmSystemTools.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'Source/cmSystemTools.cxx')
-rw-r--r--Source/cmSystemTools.cxx206
1 files changed, 119 insertions, 87 deletions
diff --git a/Source/cmSystemTools.cxx b/Source/cmSystemTools.cxx
index 10d2e50..f082ae8 100644
--- a/Source/cmSystemTools.cxx
+++ b/Source/cmSystemTools.cxx
@@ -20,6 +20,7 @@
#include <cm3p/uv.h>
#include "cmDuration.h"
+#include "cmELF.h"
#include "cmMessageMetadata.h"
#include "cmProcessOutput.h"
#include "cmRange.h"
@@ -46,10 +47,6 @@
# include "cmCryptoHash.h"
#endif
-#if defined(CMake_USE_ELF_PARSER)
-# include "cmELF.h"
-#endif
-
#if defined(CMake_USE_MACH_PARSER)
# include "cmMachO.h"
#endif
@@ -2446,14 +2443,12 @@ void cmSystemTools::MakefileColorEcho(int color, const char* message,
bool cmSystemTools::GuessLibrarySOName(std::string const& fullPath,
std::string& soname)
{
-// For ELF shared libraries use a real parser to get the correct
-// soname.
-#if defined(CMake_USE_ELF_PARSER)
+ // For ELF shared libraries use a real parser to get the correct
+ // soname.
cmELF elf(fullPath.c_str());
if (elf) {
return elf.GetSOName(soname);
}
-#endif
// If the file is not a symlink we have no guess for its soname.
if (!cmSystemTools::FileIsSymlink(fullPath)) {
@@ -2491,7 +2486,6 @@ bool cmSystemTools::GuessLibraryInstallName(std::string const& fullPath,
return false;
}
-#if defined(CMake_USE_ELF_PARSER) || defined(CMake_USE_XCOFF_PARSER)
std::string::size_type cmSystemToolsFindRPath(cm::string_view const& have,
cm::string_view const& want)
{
@@ -2523,9 +2517,7 @@ std::string::size_type cmSystemToolsFindRPath(cm::string_view const& have,
// The desired rpath was not found.
return std::string::npos;
}
-#endif
-#if defined(CMake_USE_ELF_PARSER)
namespace {
struct cmSystemToolsRPathInfo
{
@@ -2539,10 +2531,10 @@ using EmptyCallback = std::function<bool(std::string*, const cmELF&)>;
using AdjustCallback = std::function<bool(
cm::optional<std::string>&, const std::string&, const char*, std::string*)>;
-// FIXME: Dispatch if multiple formats are supported.
-bool AdjustRPath(std::string const& file, const EmptyCallback& emptyCallback,
- const AdjustCallback& adjustCallback, std::string* emsg,
- bool* changed)
+cm::optional<bool> AdjustRPathELF(std::string const& file,
+ const EmptyCallback& emptyCallback,
+ const AdjustCallback& adjustCallback,
+ std::string* emsg, bool* changed)
{
if (changed) {
*changed = false;
@@ -2553,6 +2545,9 @@ bool AdjustRPath(std::string const& file, const EmptyCallback& emptyCallback,
{
// Parse the ELF binary.
cmELF elf(file.c_str());
+ if (!elf) {
+ return cm::nullopt; // Not a valid ELF file.
+ }
// Get the RPATH and RUNPATH entries from it.
int se_count = 0;
@@ -2686,14 +2681,14 @@ std::function<bool(std::string*, const cmELF&)> MakeEmptyCallback(
}
return false;
};
-};
+}
}
-bool cmSystemTools::ChangeRPath(std::string const& file,
- std::string const& oldRPath,
- std::string const& newRPath,
- bool removeEnvironmentRPath, std::string* emsg,
- bool* changed)
+cm::optional<bool> ChangeRPathELF(std::string const& file,
+ std::string const& oldRPath,
+ std::string const& newRPath,
+ bool removeEnvironmentRPath,
+ std::string* emsg, bool* changed)
{
auto adjustCallback = [oldRPath, newRPath, removeEnvironmentRPath](
cm::optional<std::string>& outRPath,
@@ -2741,13 +2736,13 @@ bool cmSystemTools::ChangeRPath(std::string const& file,
return true;
};
- return AdjustRPath(file, MakeEmptyCallback(newRPath), adjustCallback, emsg,
- changed);
+ return AdjustRPathELF(file, MakeEmptyCallback(newRPath), adjustCallback,
+ emsg, changed);
}
-bool cmSystemTools::SetRPath(std::string const& file,
- std::string const& newRPath, std::string* emsg,
- bool* changed)
+static cm::optional<bool> SetRPathELF(std::string const& file,
+ std::string const& newRPath,
+ std::string* emsg, bool* changed)
{
auto adjustCallback = [newRPath](cm::optional<std::string>& outRPath,
const std::string& inRPath,
@@ -2759,22 +2754,31 @@ bool cmSystemTools::SetRPath(std::string const& file,
return true;
};
- return AdjustRPath(file, MakeEmptyCallback(newRPath), adjustCallback, emsg,
- changed);
+ return AdjustRPathELF(file, MakeEmptyCallback(newRPath), adjustCallback,
+ emsg, changed);
}
-#elif defined(CMake_USE_XCOFF_PARSER)
-bool cmSystemTools::ChangeRPath(std::string const& file,
- std::string const& oldRPath,
- std::string const& newRPath,
- bool removeEnvironmentRPath, std::string* emsg,
- bool* changed)
+static cm::optional<bool> ChangeRPathXCOFF(std::string const& file,
+ std::string const& oldRPath,
+ std::string const& newRPath,
+ bool removeEnvironmentRPath,
+ std::string* emsg, bool* changed)
{
if (changed) {
*changed = false;
}
-
+#if !defined(CMake_USE_XCOFF_PARSER)
+ (void)file;
+ (void)oldRPath;
+ (void)newRPath;
+ (void)removeEnvironmentRPath;
+ (void)emsg;
+ return cm::nullopt;
+#else
bool chg = false;
cmXCOFF xcoff(file.c_str(), cmXCOFF::Mode::ReadWrite);
+ if (!xcoff) {
+ return cm::nullopt; // Not a valid XCOFF file
+ }
if (cm::optional<cm::string_view> maybeLibPath = xcoff.GetLibPath()) {
cm::string_view libPath = *maybeLibPath;
// Make sure the current rpath contains the old rpath.
@@ -2830,31 +2834,47 @@ bool cmSystemTools::ChangeRPath(std::string const& file,
*changed = chg;
}
return true;
+#endif
}
-bool cmSystemTools::SetRPath(std::string const& /*file*/,
- std::string const& /*newRPath*/,
- std::string* /*emsg*/, bool* /*changed*/)
+static cm::optional<bool> SetRPathXCOFF(std::string const& /*file*/,
+ std::string const& /*newRPath*/,
+ std::string* /*emsg*/,
+ bool* /*changed*/)
{
- return false;
+ return cm::nullopt; // Not implemented.
}
-#else
-bool cmSystemTools::ChangeRPath(std::string const& /*file*/,
- std::string const& /*oldRPath*/,
- std::string const& /*newRPath*/,
- bool /*removeEnvironmentRPath*/,
- std::string* /*emsg*/, bool* /*changed*/)
+
+bool cmSystemTools::ChangeRPath(std::string const& file,
+ std::string const& oldRPath,
+ std::string const& newRPath,
+ bool removeEnvironmentRPath, std::string* emsg,
+ bool* changed)
{
+ if (cm::optional<bool> result = ChangeRPathELF(
+ file, oldRPath, newRPath, removeEnvironmentRPath, emsg, changed)) {
+ return result.value();
+ }
+ if (cm::optional<bool> result = ChangeRPathXCOFF(
+ file, oldRPath, newRPath, removeEnvironmentRPath, emsg, changed)) {
+ return result.value();
+ }
return false;
}
-bool cmSystemTools::SetRPath(std::string const& /*file*/,
- std::string const& /*newRPath*/,
- std::string* /*emsg*/, bool* /*changed*/)
+bool cmSystemTools::SetRPath(std::string const& file,
+ std::string const& newRPath, std::string* emsg,
+ bool* changed)
{
+ if (cm::optional<bool> result = SetRPathELF(file, newRPath, emsg, changed)) {
+ return result.value();
+ }
+ if (cm::optional<bool> result =
+ SetRPathXCOFF(file, newRPath, emsg, changed)) {
+ return result.value();
+ }
return false;
}
-#endif
bool cmSystemTools::VersionCompare(cmSystemTools::CompareOp op,
const char* lhss, const char* rhss)
@@ -2989,10 +3009,8 @@ int cmSystemTools::strverscmp(std::string const& lhs, std::string const& rhs)
return cm_strverscmp(lhs.c_str(), rhs.c_str());
}
-// FIXME: Dispatch if multiple formats are supported.
-#if defined(CMake_USE_ELF_PARSER)
-bool cmSystemTools::RemoveRPath(std::string const& file, std::string* emsg,
- bool* removed)
+static cm::optional<bool> RemoveRPathELF(std::string const& file,
+ std::string* emsg, bool* removed)
{
if (removed) {
*removed = false;
@@ -3005,6 +3023,9 @@ bool cmSystemTools::RemoveRPath(std::string const& file, std::string* emsg,
{
// Parse the ELF binary.
cmELF elf(file.c_str());
+ if (!elf) {
+ return cm::nullopt; // Not a valid ELF file.
+ }
// Get the RPATH and RUNPATH entries from it and sort them by index
// in the dynamic section header.
@@ -3054,8 +3075,7 @@ bool cmSystemTools::RemoveRPath(std::string const& file, std::string* emsg,
entriesErased++;
continue;
}
- if (cmELF::TagMipsRldMapRel != 0 &&
- it->first == cmELF::TagMipsRldMapRel) {
+ if (it->first == cmELF::TagMipsRldMapRel && elf.IsMIPS()) {
// Background: debuggers need to know the "linker map" which contains
// the addresses each dynamic object is loaded at. Most arches use
// the DT_DEBUG tag which the dynamic linker writes to (directly) and
@@ -3131,15 +3151,22 @@ bool cmSystemTools::RemoveRPath(std::string const& file, std::string* emsg,
}
return true;
}
-#elif defined(CMake_USE_XCOFF_PARSER)
-bool cmSystemTools::RemoveRPath(std::string const& file, std::string* emsg,
- bool* removed)
+
+static cm::optional<bool> RemoveRPathXCOFF(std::string const& file,
+ std::string* emsg, bool* removed)
{
if (removed) {
*removed = false;
}
-
+#if !defined(CMake_USE_XCOFF_PARSER)
+ (void)file;
+ (void)emsg;
+ return cm::nullopt; // Cannot handle XCOFF files.
+#else
cmXCOFF xcoff(file.c_str(), cmXCOFF::Mode::ReadWrite);
+ if (!xcoff) {
+ return cm::nullopt; // Not a valid XCOFF file.
+ }
bool rm = xcoff.RemoveLibPath();
if (!xcoff) {
if (emsg) {
@@ -3152,55 +3179,60 @@ bool cmSystemTools::RemoveRPath(std::string const& file, std::string* emsg,
*removed = rm;
}
return true;
+#endif
}
-#else
-bool cmSystemTools::RemoveRPath(std::string const& /*file*/,
- std::string* /*emsg*/, bool* /*removed*/)
+bool cmSystemTools::RemoveRPath(std::string const& file, std::string* emsg,
+ bool* removed)
{
+ if (cm::optional<bool> result = RemoveRPathELF(file, emsg, removed)) {
+ return result.value();
+ }
+ if (cm::optional<bool> result = RemoveRPathXCOFF(file, emsg, removed)) {
+ return result.value();
+ }
return false;
}
-#endif
-// FIXME: Dispatch if multiple formats are supported.
bool cmSystemTools::CheckRPath(std::string const& file,
std::string const& newRPath)
{
-#if defined(CMake_USE_ELF_PARSER)
// Parse the ELF binary.
cmELF elf(file.c_str());
-
- // Get the RPATH or RUNPATH entry from it.
- cmELF::StringEntry const* se = elf.GetRPath();
- if (!se) {
- se = elf.GetRunPath();
- }
-
- // Make sure the current rpath contains the new rpath.
- if (newRPath.empty()) {
+ if (elf) {
+ // Get the RPATH or RUNPATH entry from it.
+ cmELF::StringEntry const* se = elf.GetRPath();
if (!se) {
- return true;
+ se = elf.GetRunPath();
}
- } else {
- if (se &&
- cmSystemToolsFindRPath(se->Value, newRPath) != std::string::npos) {
- return true;
+
+ // Make sure the current rpath contains the new rpath.
+ if (newRPath.empty()) {
+ if (!se) {
+ return true;
+ }
+ } else {
+ if (se &&
+ cmSystemToolsFindRPath(se->Value, newRPath) != std::string::npos) {
+ return true;
+ }
}
+ return false;
}
- return false;
-#elif defined(CMake_USE_XCOFF_PARSER)
+#if defined(CMake_USE_XCOFF_PARSER)
// Parse the XCOFF binary.
cmXCOFF xcoff(file.c_str());
- if (cm::optional<cm::string_view> libPath = xcoff.GetLibPath()) {
- if (cmSystemToolsFindRPath(*libPath, newRPath) != std::string::npos) {
- return true;
+ if (xcoff) {
+ if (cm::optional<cm::string_view> libPath = xcoff.GetLibPath()) {
+ if (cmSystemToolsFindRPath(*libPath, newRPath) != std::string::npos) {
+ return true;
+ }
}
+ return false;
}
- return false;
-#else
+#endif
(void)file;
(void)newRPath;
return false;
-#endif
}
bool cmSystemTools::RepeatedRemoveDirectory(const std::string& dir)