Get ObjectFileMachO to handle @executable_path
Only do this when we are debugging an executable, since we
don't have a good way to trace from an ObjectFile back to its
containing executable. Detecting pre-run libs before running
is "best effort" in lldb, but this one is pretty easy.
llvm-svn: 298290
diff --git a/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp b/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp
index a6d5a85..716cd40 100644
--- a/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp
+++ b/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp
@@ -5052,6 +5052,7 @@
lldb::offset_t offset = MachHeaderSizeFromMagic(m_header.magic);
std::vector<std::string> rpath_paths;
std::vector<std::string> rpath_relative_paths;
+ std::vector<std::string> at_exec_relative_paths;
const bool resolve_path = false; // Don't resolve the dependent file paths
// since they may not reside on this system
uint32_t i;
@@ -5077,6 +5078,10 @@
if (path[0] == '@') {
if (strncmp(path, "@rpath", strlen("@rpath")) == 0)
rpath_relative_paths.push_back(path + strlen("@rpath"));
+ else if (strncmp(path, "@executable_path",
+ strlen("@executable_path")) == 0)
+ at_exec_relative_paths.push_back(path
+ + strlen("@executable_path"));
} else {
FileSpec file_spec(path, resolve_path);
if (files.AppendIfUnique(file_spec))
@@ -5092,10 +5097,11 @@
offset = cmd_offset + load_cmd.cmdsize;
}
+ FileSpec this_file_spec(m_file);
+ this_file_spec.ResolvePath();
+
if (!rpath_paths.empty()) {
// Fixup all LC_RPATH values to be absolute paths
- FileSpec this_file_spec(m_file);
- this_file_spec.ResolvePath();
std::string loader_path("@loader_path");
std::string executable_path("@executable_path");
for (auto &rpath : rpath_paths) {
@@ -5125,6 +5131,23 @@
}
}
}
+
+ // We may have @executable_paths but no RPATHS. Figure those out here.
+ // Only do this if this object file is the executable. We have no way to
+ // get back to the actual executable otherwise, so we won't get the right
+ // path.
+ if (!at_exec_relative_paths.empty() && CalculateType() == eTypeExecutable) {
+ FileSpec exec_dir = this_file_spec.CopyByRemovingLastPathComponent();
+ for (const auto &at_exec_relative_path : at_exec_relative_paths) {
+ FileSpec file_spec =
+ exec_dir.CopyByAppendingPathComponent(at_exec_relative_path);
+ file_spec = file_spec.GetNormalizedPath();
+ if (file_spec.Exists() && files.AppendIfUnique(file_spec)) {
+ count++;
+ break;
+ }
+ }
+ }
}
return count;
}