summaryrefslogtreecommitdiff
path: root/source/Host/common
diff options
context:
space:
mode:
Diffstat (limited to 'source/Host/common')
-rw-r--r--source/Host/common/Symbols.cpp76
1 files changed, 46 insertions, 30 deletions
diff --git a/source/Host/common/Symbols.cpp b/source/Host/common/Symbols.cpp
index 1d9180bf528e..fe29b9e78990 100644
--- a/source/Host/common/Symbols.cpp
+++ b/source/Host/common/Symbols.cpp
@@ -86,7 +86,6 @@ static bool LocateDSYMInVincinityOfExecutable(const ModuleSpec &module_spec,
path);
}
}
- size_t obj_file_path_length = strlen(path);
::strncat(path, ".dSYM/Contents/Resources/DWARF/",
sizeof(path) - strlen(path) - 1);
::strncat(path, exec_fspec->GetFilename().AsCString(),
@@ -105,38 +104,55 @@ static bool LocateDSYMInVincinityOfExecutable(const ModuleSpec &module_spec,
}
return true;
} else {
- path[obj_file_path_length] = '\0';
-
- char *last_dot = strrchr(path, '.');
- while (last_dot != NULL && last_dot[0]) {
- char *next_slash = strchr(last_dot, '/');
- if (next_slash != NULL) {
- *next_slash = '\0';
- ::strncat(path, ".dSYM/Contents/Resources/DWARF/",
- sizeof(path) - strlen(path) - 1);
- ::strncat(path, exec_fspec->GetFilename().AsCString(),
- sizeof(path) - strlen(path) - 1);
- dsym_fspec.SetFile(path, false);
+ FileSpec parent_dirs = exec_fspec;
+
+ // Remove the binary name from the FileSpec
+ parent_dirs.RemoveLastPathComponent();
+
+ // Add a ".dSYM" name to each directory component of the path, stripping
+ // off components. e.g. we may have a binary like
+ // /S/L/F/Foundation.framework/Versions/A/Foundation
+ // and
+ // /S/L/F/Foundation.framework.dSYM
+ //
+ // so we'll need to start with /S/L/F/Foundation.framework/Versions/A,
+ // add the .dSYM part to the "A", and if that doesn't exist, strip off
+ // the "A" and try it again with "Versions", etc., until we find a dSYM
+ // bundle or we've stripped off enough path components that there's no
+ // need to continue.
+
+ for (int i = 0; i < 4; i++) {
+ // Does this part of the path have a "." character - could it be a bundle's
+ // top level directory?
+ const char *fn = parent_dirs.GetFilename().AsCString();
+ if (fn == nullptr)
+ break;
+ if (::strchr (fn, '.') != nullptr) {
+ dsym_fspec = parent_dirs;
+ dsym_fspec.RemoveLastPathComponent();
+
+ // If the current directory name is "Foundation.framework", see if
+ // "Foundation.framework.dSYM/Contents/Resources/DWARF/Foundation"
+ // exists & has the right uuid.
+ std::string dsym_fn = fn;
+ dsym_fn += ".dSYM";
+ dsym_fspec.AppendPathComponent(dsym_fn.c_str());
+ dsym_fspec.AppendPathComponent("Contents");
+ dsym_fspec.AppendPathComponent("Resources");
+ dsym_fspec.AppendPathComponent("DWARF");
+ dsym_fspec.AppendPathComponent(exec_fspec->GetFilename().AsCString());
if (dsym_fspec.Exists() &&
- FileAtPathContainsArchAndUUID(
- dsym_fspec, module_spec.GetArchitecturePtr(),
- module_spec.GetUUIDPtr())) {
- if (log) {
- log->Printf("dSYM with matching UUID & arch found at %s",
- path);
- }
- return true;
- } else {
- *last_dot = '\0';
- char *prev_slash = strrchr(path, '/');
- if (prev_slash != NULL)
- *prev_slash = '\0';
- else
- break;
+ FileAtPathContainsArchAndUUID(
+ dsym_fspec, module_spec.GetArchitecturePtr(),
+ module_spec.GetUUIDPtr())) {
+ if (log) {
+ log->Printf("dSYM with matching UUID & arch found at %s",
+ dsym_fspec.GetPath().c_str());
+ }
+ return true;
}
- } else {
- break;
}
+ parent_dirs.RemoveLastPathComponent();
}
}
}