forked from OSchip/llvm-project
Simplify LocateDSYMInVincinityOfExecutable by moving
some redundant code into a separate function, LookForDsymNextToExecutablePath, and having that function also look for .dSYM.yaa files in addition to .dSYM bundles. Differential Revision: https://reviews.llvm.org/D53305 <rdar://problem/40406580> llvm-svn: 344626
This commit is contained in:
parent
46eadcff9c
commit
4503c514d9
|
@ -65,96 +65,134 @@ static bool FileAtPathContainsArchAndUUID(const FileSpec &file_fspec,
|
|||
return false;
|
||||
}
|
||||
|
||||
// Given a binary exec_fspec, and a ModuleSpec with an architecture/uuid,
|
||||
// return true if there is a matching dSYM bundle next to the exec_fspec,
|
||||
// and return that value in dsym_fspec.
|
||||
// If there is a .dSYM.yaa compressed archive next to the exec_fspec,
|
||||
// call through Symbols::DownloadObjectAndSymbolFile to download the
|
||||
// expanded/uncompressed dSYM and return that filepath in dsym_fspec.
|
||||
|
||||
static bool LookForDsymNextToExecutablePath(const ModuleSpec &mod_spec,
|
||||
const FileSpec &exec_fspec,
|
||||
FileSpec &dsym_fspec) {
|
||||
ConstString filename = exec_fspec.GetFilename();
|
||||
FileSpec dsym_directory = exec_fspec;
|
||||
dsym_directory.RemoveLastPathComponent();
|
||||
|
||||
std::string dsym_filename = filename.AsCString();
|
||||
dsym_filename += ".dSYM";
|
||||
dsym_directory.AppendPathComponent(dsym_filename);
|
||||
dsym_directory.AppendPathComponent("Contents");
|
||||
dsym_directory.AppendPathComponent("Resources");
|
||||
dsym_directory.AppendPathComponent("DWARF");
|
||||
|
||||
if (dsym_directory.Exists()) {
|
||||
|
||||
// See if the binary name exists in the dSYM DWARF
|
||||
// subdir.
|
||||
FileSpec dsym_fspec = dsym_directory;
|
||||
dsym_fspec.AppendPathComponent(filename.AsCString());
|
||||
if (dsym_fspec.Exists()
|
||||
&& FileAtPathContainsArchAndUUID(dsym_fspec,
|
||||
mod_spec.GetArchitecturePtr(),
|
||||
mod_spec.GetUUIDPtr())) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// See if we have "../CF.framework" - so we'll look for
|
||||
// CF.framework.dSYM/Contents/Resources/DWARF/CF
|
||||
// We need to drop the last suffix after '.' to match
|
||||
// 'CF' in the DWARF subdir.
|
||||
std::string binary_name (filename.AsCString());
|
||||
auto last_dot = binary_name.find_last_of('.');
|
||||
if (last_dot != std::string::npos) {
|
||||
binary_name.erase(last_dot);
|
||||
dsym_fspec = dsym_directory;
|
||||
dsym_fspec.AppendPathComponent(binary_name);
|
||||
if (dsym_fspec.Exists()
|
||||
&& FileAtPathContainsArchAndUUID(dsym_fspec,
|
||||
mod_spec.GetArchitecturePtr(),
|
||||
mod_spec.GetUUIDPtr())) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// See if we have a .dSYM.yaa next to this executable path.
|
||||
FileSpec dsym_yaa_fspec = exec_fspec;
|
||||
dsym_yaa_fspec.RemoveLastPathComponent();
|
||||
std::string dsym_yaa_filename = filename.AsCString();
|
||||
dsym_yaa_filename += ".dSYM.yaa";
|
||||
dsym_yaa_fspec.AppendPathComponent(dsym_yaa_filename);
|
||||
|
||||
if (dsym_yaa_fspec.Exists()) {
|
||||
ModuleSpec mutable_mod_spec = mod_spec;
|
||||
if (Symbols::DownloadObjectAndSymbolFile (mutable_mod_spec, true)
|
||||
&& mutable_mod_spec.GetSymbolFileSpec().Exists()) {
|
||||
dsym_fspec = mutable_mod_spec.GetSymbolFileSpec();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// Given a ModuleSpec with a FileSpec and optionally uuid/architecture
|
||||
// filled in, look for a .dSYM bundle next to that binary. Returns true
|
||||
// if a .dSYM bundle is found, and that path is returned in the dsym_fspec
|
||||
// FileSpec.
|
||||
//
|
||||
// This routine looks a few directory layers above the given exec_path -
|
||||
// exec_path might be /System/Library/Frameworks/CF.framework/CF and the
|
||||
// dSYM might be /System/Library/Frameworks/CF.framework.dSYM.
|
||||
//
|
||||
// If there is a .dSYM.yaa compressed archive found next to the binary,
|
||||
// we'll call DownloadObjectAndSymbolFile to expand it into a plain .dSYM
|
||||
|
||||
static bool LocateDSYMInVincinityOfExecutable(const ModuleSpec &module_spec,
|
||||
FileSpec &dsym_fspec) {
|
||||
Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST);
|
||||
const FileSpec *exec_fspec = module_spec.GetFileSpecPtr();
|
||||
const FileSpec &exec_fspec = module_spec.GetFileSpec();
|
||||
if (exec_fspec) {
|
||||
char path[PATH_MAX];
|
||||
if (exec_fspec->GetPath(path, sizeof(path))) {
|
||||
// Make sure the module isn't already just a dSYM file...
|
||||
if (strcasestr(path, ".dSYM/Contents/Resources/DWARF") == NULL) {
|
||||
if (::LookForDsymNextToExecutablePath (module_spec, exec_fspec, dsym_fspec)) {
|
||||
if (log) {
|
||||
if (module_spec.GetUUIDPtr() && module_spec.GetUUIDPtr()->IsValid()) {
|
||||
log->Printf(
|
||||
"Searching for dSYM bundle next to executable %s, UUID %s",
|
||||
path, module_spec.GetUUIDPtr()->GetAsString().c_str());
|
||||
} else {
|
||||
log->Printf("Searching for dSYM bundle next to executable %s",
|
||||
path);
|
||||
}
|
||||
log->Printf("dSYM with matching UUID & arch found at %s", dsym_fspec.GetPath().c_str());
|
||||
}
|
||||
::strncat(path, ".dSYM/Contents/Resources/DWARF/",
|
||||
sizeof(path) - strlen(path) - 1);
|
||||
::strncat(path, exec_fspec->GetFilename().AsCString(),
|
||||
sizeof(path) - strlen(path) - 1);
|
||||
return true;
|
||||
} else {
|
||||
FileSpec parent_dirs = exec_fspec;
|
||||
|
||||
dsym_fspec.SetFile(path, false, FileSpec::Style::native);
|
||||
// Remove the binary name from the FileSpec
|
||||
parent_dirs.RemoveLastPathComponent();
|
||||
|
||||
ModuleSpecList module_specs;
|
||||
ModuleSpec matched_module_spec;
|
||||
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 {
|
||||
FileSpec parent_dirs = exec_fspec;
|
||||
// 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.
|
||||
|
||||
// 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",
|
||||
dsym_fspec.GetPath().c_str());
|
||||
}
|
||||
return true;
|
||||
}
|
||||
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) {
|
||||
if (::LookForDsymNextToExecutablePath (module_spec, parent_dirs, dsym_fspec)) {
|
||||
if (log) {
|
||||
log->Printf("dSYM with matching UUID & arch found at %s",
|
||||
dsym_fspec.GetPath().c_str());
|
||||
}
|
||||
parent_dirs.RemoveLastPathComponent();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
parent_dirs.RemoveLastPathComponent();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue