Add support for an additional dictionary in the per-arch plists
that may be embedded in the Contents/Resources subdir of a dSYM
bundle. These allow for the specification of a build-time path
to debug-time path remapping for source files. Files may be built
in /BuildDirectory/sources/project-100 but when the debugger is
run, they're actually found via ~sources/project-100 - this plist
allows for that remapping through the DBGBuildSourcePath and
DBGSourcePath keys.
This patch adds support for a new DBGSourcePathRemapping
dictionary in the plist where the keys are the build-time paths
and the values are the debug-time paths that they should be
remapped to. There are instances were we have multiple possible
build-time paths that need to be included, so the dictionary was
required.
<rdar://problem/26725174>
llvm-svn: 276729
diff --git a/lldb/source/Host/macosx/Symbols.cpp b/lldb/source/Host/macosx/Symbols.cpp
index f6a18fe..3eba327 100644
--- a/lldb/source/Host/macosx/Symbols.cpp
+++ b/lldb/source/Host/macosx/Symbols.cpp
@@ -310,6 +310,7 @@
{
std::string str;
CFStringRef cf_str;
+ CFDictionaryRef cf_dict;
cf_str = (CFStringRef)CFDictionaryGetValue ((CFDictionaryRef) uuid_dict, CFSTR("DBGSymbolRichExecutable"));
if (cf_str && CFGetTypeID (cf_str) == CFStringGetTypeID ())
@@ -362,8 +363,69 @@
if (!DBGBuildSourcePath.empty() && !DBGSourcePath.empty())
{
+ if (DBGSourcePath[0] == '~')
+ {
+ FileSpec resolved_source_path(DBGSourcePath.c_str(), true);
+ DBGSourcePath = resolved_source_path.GetPath();
+ }
module_spec.GetSourceMappingList().Append (ConstString(DBGBuildSourcePath.c_str()), ConstString(DBGSourcePath.c_str()), true);
}
+
+ cf_dict = (CFDictionaryRef)CFDictionaryGetValue ((CFDictionaryRef) uuid_dict, CFSTR("DBGSourcePathRemapping"));
+ if (cf_dict && CFGetTypeID (cf_dict) == CFDictionaryGetTypeID ())
+ {
+ // If we see DBGVersion with any kind of value, this is a new style DBGSourcePathRemapping dictionary
+ bool new_style_source_remapping_dictionary = false;
+ std::string original_DBGSourcePath_value = DBGSourcePath;
+ const void *version_value;
+ version_value = CFDictionaryGetValue ((CFDictionaryRef) uuid_dict, CFSTR("DBGVersion"));
+ if (version_value)
+ new_style_source_remapping_dictionary = true;
+
+ CFIndex kv_pair_count = CFDictionaryGetCount ((CFDictionaryRef) uuid_dict);
+ if (kv_pair_count > 0)
+ {
+ CFStringRef *keys = (CFStringRef *) malloc (kv_pair_count * sizeof (CFStringRef));
+ CFStringRef *values = (CFStringRef *) malloc (kv_pair_count * sizeof (CFStringRef));
+ if (keys != nullptr && values != nullptr)
+ {
+ CFDictionaryGetKeysAndValues ((CFDictionaryRef) uuid_dict, (const void**)keys, (const void**)values);
+ }
+ for (CFIndex i = 0; i < kv_pair_count; i++)
+ {
+ DBGBuildSourcePath.clear();
+ DBGSourcePath.clear();
+ if (keys[i] && CFGetTypeID (keys[i]) == CFStringGetTypeID ())
+ {
+ CFCString::FileSystemRepresentation(keys[i], DBGBuildSourcePath);
+ }
+ if (values[i] && CFGetTypeID (values[i]) == CFStringGetTypeID ())
+ {
+ CFCString::FileSystemRepresentation(values[i], DBGSourcePath);
+ }
+ if (!DBGBuildSourcePath.empty() && !DBGSourcePath.empty())
+ {
+ // In the "old style" DBGSourcePathRemapping dictionary, the DBGSourcePath values
+ // (the "values" half of key-value path pairs) were wrong. Ignore them and use the
+ // universal DBGSourcePath string from earlier.
+ if (new_style_source_remapping_dictionary == true && !original_DBGSourcePath_value.empty())
+ {
+ DBGSourcePath = original_DBGSourcePath_value;
+ }
+ if (DBGSourcePath[0] == '~')
+ {
+ FileSpec resolved_source_path(DBGSourcePath.c_str(), true);
+ DBGSourcePath = resolved_source_path.GetPath();
+ }
+ module_spec.GetSourceMappingList().Append (ConstString(DBGBuildSourcePath.c_str()), ConstString(DBGSourcePath.c_str()), true);
+ }
+ }
+ if (keys)
+ free (keys);
+ if (values)
+ free (values);
+ }
+ }
}
return success;
}