180814287SRaphael Isemann //===-- LocateSymbolFile.cpp ----------------------------------------------===//
280552918SZachary Turner //
380552918SZachary Turner // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
480552918SZachary Turner // See https://llvm.org/LICENSE.txt for license information.
580552918SZachary Turner // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
680552918SZachary Turner //
780552918SZachary Turner //===----------------------------------------------------------------------===//
880552918SZachary Turner
980552918SZachary Turner #include "lldb/Symbol/LocateSymbolFile.h"
1080552918SZachary Turner
11a89ce43cSZachary Turner #include "lldb/Core/ModuleList.h"
1280552918SZachary Turner #include "lldb/Core/ModuleSpec.h"
135a27b998SJonas Devlieghere #include "lldb/Core/Progress.h"
1480552918SZachary Turner #include "lldb/Host/FileSystem.h"
1580552918SZachary Turner #include "lldb/Symbol/ObjectFile.h"
1680552918SZachary Turner #include "lldb/Utility/ArchSpec.h"
1780552918SZachary Turner #include "lldb/Utility/DataBuffer.h"
1880552918SZachary Turner #include "lldb/Utility/DataExtractor.h"
19c34698a8SPavel Labath #include "lldb/Utility/LLDBLog.h"
2080552918SZachary Turner #include "lldb/Utility/Log.h"
21a842950bSJonas Devlieghere #include "lldb/Utility/Reproducer.h"
2280552918SZachary Turner #include "lldb/Utility/StreamString.h"
2380552918SZachary Turner #include "lldb/Utility/Timer.h"
2480552918SZachary Turner #include "lldb/Utility/UUID.h"
2580552918SZachary Turner
2680552918SZachary Turner #include "llvm/Support/FileSystem.h"
2780552918SZachary Turner
2880552918SZachary Turner // From MacOSX system header "mach/machine.h"
2980552918SZachary Turner typedef int cpu_type_t;
3080552918SZachary Turner typedef int cpu_subtype_t;
3180552918SZachary Turner
3280552918SZachary Turner using namespace lldb;
3380552918SZachary Turner using namespace lldb_private;
3480552918SZachary Turner
3580552918SZachary Turner #if defined(__APPLE__)
3680552918SZachary Turner
3780552918SZachary Turner // Forward declaration of method defined in source/Host/macosx/Symbols.cpp
3880552918SZachary Turner int LocateMacOSXFilesUsingDebugSymbols(const ModuleSpec &module_spec,
3980552918SZachary Turner ModuleSpec &return_module_spec);
4080552918SZachary Turner
4180552918SZachary Turner #else
4280552918SZachary Turner
LocateMacOSXFilesUsingDebugSymbols(const ModuleSpec & module_spec,ModuleSpec & return_module_spec)4380552918SZachary Turner int LocateMacOSXFilesUsingDebugSymbols(const ModuleSpec &module_spec,
4480552918SZachary Turner ModuleSpec &return_module_spec) {
4580552918SZachary Turner // Cannot find MacOSX files using debug symbols on non MacOSX.
4680552918SZachary Turner return 0;
4780552918SZachary Turner }
4880552918SZachary Turner
4980552918SZachary Turner #endif
5080552918SZachary Turner
FileAtPathContainsArchAndUUID(const FileSpec & file_fspec,const ArchSpec * arch,const lldb_private::UUID * uuid)5180552918SZachary Turner static bool FileAtPathContainsArchAndUUID(const FileSpec &file_fspec,
5280552918SZachary Turner const ArchSpec *arch,
5380552918SZachary Turner const lldb_private::UUID *uuid) {
5480552918SZachary Turner ModuleSpecList module_specs;
5580552918SZachary Turner if (ObjectFile::GetModuleSpecifications(file_fspec, 0, 0, module_specs)) {
5680552918SZachary Turner ModuleSpec spec;
5780552918SZachary Turner for (size_t i = 0; i < module_specs.GetSize(); ++i) {
5880552918SZachary Turner bool got_spec = module_specs.GetModuleSpecAtIndex(i, spec);
5980552918SZachary Turner UNUSED_IF_ASSERT_DISABLED(got_spec);
6080552918SZachary Turner assert(got_spec);
61248a1305SKonrad Kleine if ((uuid == nullptr || (spec.GetUUIDPtr() && spec.GetUUID() == *uuid)) &&
62248a1305SKonrad Kleine (arch == nullptr ||
63248a1305SKonrad Kleine (spec.GetArchitecturePtr() &&
6480552918SZachary Turner spec.GetArchitecture().IsCompatibleMatch(*arch)))) {
6580552918SZachary Turner return true;
6680552918SZachary Turner }
6780552918SZachary Turner }
6880552918SZachary Turner }
6980552918SZachary Turner return false;
7080552918SZachary Turner }
7180552918SZachary Turner
7280552918SZachary Turner // Given a binary exec_fspec, and a ModuleSpec with an architecture/uuid,
7380552918SZachary Turner // return true if there is a matching dSYM bundle next to the exec_fspec,
7480552918SZachary Turner // and return that value in dsym_fspec.
7580552918SZachary Turner // If there is a .dSYM.yaa compressed archive next to the exec_fspec,
7680552918SZachary Turner // call through Symbols::DownloadObjectAndSymbolFile to download the
7780552918SZachary Turner // expanded/uncompressed dSYM and return that filepath in dsym_fspec.
7880552918SZachary Turner
LookForDsymNextToExecutablePath(const ModuleSpec & mod_spec,const FileSpec & exec_fspec,FileSpec & dsym_fspec)7980552918SZachary Turner static bool LookForDsymNextToExecutablePath(const ModuleSpec &mod_spec,
8080552918SZachary Turner const FileSpec &exec_fspec,
8180552918SZachary Turner FileSpec &dsym_fspec) {
8280552918SZachary Turner ConstString filename = exec_fspec.GetFilename();
8380552918SZachary Turner FileSpec dsym_directory = exec_fspec;
8480552918SZachary Turner dsym_directory.RemoveLastPathComponent();
8580552918SZachary Turner
8680552918SZachary Turner std::string dsym_filename = filename.AsCString();
8780552918SZachary Turner dsym_filename += ".dSYM";
8880552918SZachary Turner dsym_directory.AppendPathComponent(dsym_filename);
8980552918SZachary Turner dsym_directory.AppendPathComponent("Contents");
9080552918SZachary Turner dsym_directory.AppendPathComponent("Resources");
9180552918SZachary Turner dsym_directory.AppendPathComponent("DWARF");
9280552918SZachary Turner
9380552918SZachary Turner if (FileSystem::Instance().Exists(dsym_directory)) {
9480552918SZachary Turner
9580552918SZachary Turner // See if the binary name exists in the dSYM DWARF
9680552918SZachary Turner // subdir.
9780552918SZachary Turner dsym_fspec = dsym_directory;
9880552918SZachary Turner dsym_fspec.AppendPathComponent(filename.AsCString());
9980552918SZachary Turner if (FileSystem::Instance().Exists(dsym_fspec) &&
10080552918SZachary Turner FileAtPathContainsArchAndUUID(dsym_fspec, mod_spec.GetArchitecturePtr(),
10180552918SZachary Turner mod_spec.GetUUIDPtr())) {
10280552918SZachary Turner return true;
10380552918SZachary Turner }
10480552918SZachary Turner
10580552918SZachary Turner // See if we have "../CF.framework" - so we'll look for
10680552918SZachary Turner // CF.framework.dSYM/Contents/Resources/DWARF/CF
10780552918SZachary Turner // We need to drop the last suffix after '.' to match
10880552918SZachary Turner // 'CF' in the DWARF subdir.
10980552918SZachary Turner std::string binary_name(filename.AsCString());
11080552918SZachary Turner auto last_dot = binary_name.find_last_of('.');
11180552918SZachary Turner if (last_dot != std::string::npos) {
11280552918SZachary Turner binary_name.erase(last_dot);
11380552918SZachary Turner dsym_fspec = dsym_directory;
11480552918SZachary Turner dsym_fspec.AppendPathComponent(binary_name);
11580552918SZachary Turner if (FileSystem::Instance().Exists(dsym_fspec) &&
11680552918SZachary Turner FileAtPathContainsArchAndUUID(dsym_fspec,
11780552918SZachary Turner mod_spec.GetArchitecturePtr(),
11880552918SZachary Turner mod_spec.GetUUIDPtr())) {
11980552918SZachary Turner return true;
12080552918SZachary Turner }
12180552918SZachary Turner }
12280552918SZachary Turner }
12380552918SZachary Turner
12480552918SZachary Turner // See if we have a .dSYM.yaa next to this executable path.
12580552918SZachary Turner FileSpec dsym_yaa_fspec = exec_fspec;
12680552918SZachary Turner dsym_yaa_fspec.RemoveLastPathComponent();
12780552918SZachary Turner std::string dsym_yaa_filename = filename.AsCString();
12880552918SZachary Turner dsym_yaa_filename += ".dSYM.yaa";
12980552918SZachary Turner dsym_yaa_fspec.AppendPathComponent(dsym_yaa_filename);
13080552918SZachary Turner
13180552918SZachary Turner if (FileSystem::Instance().Exists(dsym_yaa_fspec)) {
13280552918SZachary Turner ModuleSpec mutable_mod_spec = mod_spec;
133af91446aSJonas Devlieghere Status error;
134af91446aSJonas Devlieghere if (Symbols::DownloadObjectAndSymbolFile(mutable_mod_spec, error, true) &&
13580552918SZachary Turner FileSystem::Instance().Exists(mutable_mod_spec.GetSymbolFileSpec())) {
13680552918SZachary Turner dsym_fspec = mutable_mod_spec.GetSymbolFileSpec();
13780552918SZachary Turner return true;
13880552918SZachary Turner }
13980552918SZachary Turner }
14080552918SZachary Turner
14180552918SZachary Turner return false;
14280552918SZachary Turner }
14380552918SZachary Turner
14480552918SZachary Turner // Given a ModuleSpec with a FileSpec and optionally uuid/architecture
14580552918SZachary Turner // filled in, look for a .dSYM bundle next to that binary. Returns true
14680552918SZachary Turner // if a .dSYM bundle is found, and that path is returned in the dsym_fspec
14780552918SZachary Turner // FileSpec.
14880552918SZachary Turner //
14980552918SZachary Turner // This routine looks a few directory layers above the given exec_path -
15080552918SZachary Turner // exec_path might be /System/Library/Frameworks/CF.framework/CF and the
15180552918SZachary Turner // dSYM might be /System/Library/Frameworks/CF.framework.dSYM.
15280552918SZachary Turner //
15380552918SZachary Turner // If there is a .dSYM.yaa compressed archive found next to the binary,
15480552918SZachary Turner // we'll call DownloadObjectAndSymbolFile to expand it into a plain .dSYM
15580552918SZachary Turner
LocateDSYMInVincinityOfExecutable(const ModuleSpec & module_spec,FileSpec & dsym_fspec)15680552918SZachary Turner static bool LocateDSYMInVincinityOfExecutable(const ModuleSpec &module_spec,
15780552918SZachary Turner FileSpec &dsym_fspec) {
158a007a6d8SPavel Labath Log *log = GetLog(LLDBLog::Host);
15980552918SZachary Turner const FileSpec &exec_fspec = module_spec.GetFileSpec();
16080552918SZachary Turner if (exec_fspec) {
16180552918SZachary Turner if (::LookForDsymNextToExecutablePath(module_spec, exec_fspec,
16280552918SZachary Turner dsym_fspec)) {
16380552918SZachary Turner if (log) {
16463e5fb76SJonas Devlieghere LLDB_LOGF(log, "dSYM with matching UUID & arch found at %s",
16580552918SZachary Turner dsym_fspec.GetPath().c_str());
16680552918SZachary Turner }
16780552918SZachary Turner return true;
16880552918SZachary Turner } else {
16980552918SZachary Turner FileSpec parent_dirs = exec_fspec;
17080552918SZachary Turner
17180552918SZachary Turner // Remove the binary name from the FileSpec
17280552918SZachary Turner parent_dirs.RemoveLastPathComponent();
17380552918SZachary Turner
17480552918SZachary Turner // Add a ".dSYM" name to each directory component of the path,
17580552918SZachary Turner // stripping off components. e.g. we may have a binary like
17680552918SZachary Turner // /S/L/F/Foundation.framework/Versions/A/Foundation and
17780552918SZachary Turner // /S/L/F/Foundation.framework.dSYM
17880552918SZachary Turner //
17980552918SZachary Turner // so we'll need to start with
18080552918SZachary Turner // /S/L/F/Foundation.framework/Versions/A, add the .dSYM part to the
18180552918SZachary Turner // "A", and if that doesn't exist, strip off the "A" and try it again
18280552918SZachary Turner // with "Versions", etc., until we find a dSYM bundle or we've
18380552918SZachary Turner // stripped off enough path components that there's no need to
18480552918SZachary Turner // continue.
18580552918SZachary Turner
18680552918SZachary Turner for (int i = 0; i < 4; i++) {
18780552918SZachary Turner // Does this part of the path have a "." character - could it be a
18880552918SZachary Turner // bundle's top level directory?
18980552918SZachary Turner const char *fn = parent_dirs.GetFilename().AsCString();
19080552918SZachary Turner if (fn == nullptr)
19180552918SZachary Turner break;
19280552918SZachary Turner if (::strchr(fn, '.') != nullptr) {
19380552918SZachary Turner if (::LookForDsymNextToExecutablePath(module_spec, parent_dirs,
19480552918SZachary Turner dsym_fspec)) {
19580552918SZachary Turner if (log) {
19663e5fb76SJonas Devlieghere LLDB_LOGF(log, "dSYM with matching UUID & arch found at %s",
19780552918SZachary Turner dsym_fspec.GetPath().c_str());
19880552918SZachary Turner }
19980552918SZachary Turner return true;
20080552918SZachary Turner }
20180552918SZachary Turner }
20280552918SZachary Turner parent_dirs.RemoveLastPathComponent();
20380552918SZachary Turner }
20480552918SZachary Turner }
20580552918SZachary Turner }
20680552918SZachary Turner dsym_fspec.Clear();
20780552918SZachary Turner return false;
20880552918SZachary Turner }
20980552918SZachary Turner
LocateExecutableSymbolFileDsym(const ModuleSpec & module_spec)21080552918SZachary Turner static FileSpec LocateExecutableSymbolFileDsym(const ModuleSpec &module_spec) {
21180552918SZachary Turner const FileSpec *exec_fspec = module_spec.GetFileSpecPtr();
21280552918SZachary Turner const ArchSpec *arch = module_spec.GetArchitecturePtr();
21380552918SZachary Turner const UUID *uuid = module_spec.GetUUIDPtr();
21480552918SZachary Turner
2155c1c8443SJonas Devlieghere LLDB_SCOPED_TIMERF(
21680552918SZachary Turner "LocateExecutableSymbolFileDsym (file = %s, arch = %s, uuid = %p)",
21780552918SZachary Turner exec_fspec ? exec_fspec->GetFilename().AsCString("<NULL>") : "<NULL>",
21880552918SZachary Turner arch ? arch->GetArchitectureName() : "<NULL>", (const void *)uuid);
21980552918SZachary Turner
22080552918SZachary Turner FileSpec symbol_fspec;
22180552918SZachary Turner ModuleSpec dsym_module_spec;
22280552918SZachary Turner // First try and find the dSYM in the same directory as the executable or in
22380552918SZachary Turner // an appropriate parent directory
22480552918SZachary Turner if (!LocateDSYMInVincinityOfExecutable(module_spec, symbol_fspec)) {
22580552918SZachary Turner // We failed to easily find the dSYM above, so use DebugSymbols
22680552918SZachary Turner LocateMacOSXFilesUsingDebugSymbols(module_spec, dsym_module_spec);
22780552918SZachary Turner } else {
22880552918SZachary Turner dsym_module_spec.GetSymbolFileSpec() = symbol_fspec;
22980552918SZachary Turner }
230a842950bSJonas Devlieghere
23180552918SZachary Turner return dsym_module_spec.GetSymbolFileSpec();
23280552918SZachary Turner }
23380552918SZachary Turner
LocateExecutableObjectFile(const ModuleSpec & module_spec)23480552918SZachary Turner ModuleSpec Symbols::LocateExecutableObjectFile(const ModuleSpec &module_spec) {
23580552918SZachary Turner ModuleSpec result;
23628e4942bSPavel Labath const FileSpec &exec_fspec = module_spec.GetFileSpec();
23780552918SZachary Turner const ArchSpec *arch = module_spec.GetArchitecturePtr();
23880552918SZachary Turner const UUID *uuid = module_spec.GetUUIDPtr();
2395c1c8443SJonas Devlieghere LLDB_SCOPED_TIMERF(
2405c1c8443SJonas Devlieghere "LocateExecutableObjectFile (file = %s, arch = %s, uuid = %p)",
24128e4942bSPavel Labath exec_fspec ? exec_fspec.GetFilename().AsCString("<NULL>") : "<NULL>",
24280552918SZachary Turner arch ? arch->GetArchitectureName() : "<NULL>", (const void *)uuid);
24380552918SZachary Turner
24480552918SZachary Turner ModuleSpecList module_specs;
24580552918SZachary Turner ModuleSpec matched_module_spec;
24680552918SZachary Turner if (exec_fspec &&
24728e4942bSPavel Labath ObjectFile::GetModuleSpecifications(exec_fspec, 0, 0, module_specs) &&
24880552918SZachary Turner module_specs.FindMatchingModuleSpec(module_spec, matched_module_spec)) {
24980552918SZachary Turner result.GetFileSpec() = exec_fspec;
25080552918SZachary Turner } else {
25180552918SZachary Turner LocateMacOSXFilesUsingDebugSymbols(module_spec, result);
25280552918SZachary Turner }
253a842950bSJonas Devlieghere
25480552918SZachary Turner return result;
25580552918SZachary Turner }
25680552918SZachary Turner
25780552918SZachary Turner // Keep "symbols.enable-external-lookup" description in sync with this function.
25880552918SZachary Turner
259a89ce43cSZachary Turner FileSpec
LocateExecutableSymbolFile(const ModuleSpec & module_spec,const FileSpecList & default_search_paths)260a89ce43cSZachary Turner Symbols::LocateExecutableSymbolFile(const ModuleSpec &module_spec,
261a89ce43cSZachary Turner const FileSpecList &default_search_paths) {
26280552918SZachary Turner FileSpec symbol_file_spec = module_spec.GetSymbolFileSpec();
26380552918SZachary Turner if (symbol_file_spec.IsAbsolute() &&
26480552918SZachary Turner FileSystem::Instance().Exists(symbol_file_spec))
26580552918SZachary Turner return symbol_file_spec;
26680552918SZachary Turner
2675a27b998SJonas Devlieghere Progress progress(llvm::formatv(
2685a27b998SJonas Devlieghere "Locating external symbol file for {0}",
2695a27b998SJonas Devlieghere module_spec.GetFileSpec().GetFilename().AsCString("<Unknown>")));
2705a27b998SJonas Devlieghere
271a89ce43cSZachary Turner FileSpecList debug_file_search_paths = default_search_paths;
27280552918SZachary Turner
27380552918SZachary Turner // Add module directory.
27480552918SZachary Turner FileSpec module_file_spec = module_spec.GetFileSpec();
27580552918SZachary Turner // We keep the unresolved pathname if it fails.
27680552918SZachary Turner FileSystem::Instance().ResolveSymbolicLink(module_file_spec,
27780552918SZachary Turner module_file_spec);
27880552918SZachary Turner
2790e4c4821SAdrian Prantl ConstString file_dir = module_file_spec.GetDirectory();
28080552918SZachary Turner {
28180552918SZachary Turner FileSpec file_spec(file_dir.AsCString("."));
28280552918SZachary Turner FileSystem::Instance().Resolve(file_spec);
28380552918SZachary Turner debug_file_search_paths.AppendIfUnique(file_spec);
28480552918SZachary Turner }
28580552918SZachary Turner
28680552918SZachary Turner if (ModuleList::GetGlobalModuleListProperties().GetEnableExternalLookup()) {
28780552918SZachary Turner
28880552918SZachary Turner // Add current working directory.
28980552918SZachary Turner {
29080552918SZachary Turner FileSpec file_spec(".");
29180552918SZachary Turner FileSystem::Instance().Resolve(file_spec);
29280552918SZachary Turner debug_file_search_paths.AppendIfUnique(file_spec);
29380552918SZachary Turner }
29480552918SZachary Turner
29580552918SZachary Turner #ifndef _WIN32
29680552918SZachary Turner #if defined(__NetBSD__)
29780552918SZachary Turner // Add /usr/libdata/debug directory.
29880552918SZachary Turner {
29980552918SZachary Turner FileSpec file_spec("/usr/libdata/debug");
30080552918SZachary Turner FileSystem::Instance().Resolve(file_spec);
30180552918SZachary Turner debug_file_search_paths.AppendIfUnique(file_spec);
30280552918SZachary Turner }
30380552918SZachary Turner #else
30480552918SZachary Turner // Add /usr/lib/debug directory.
30580552918SZachary Turner {
30680552918SZachary Turner FileSpec file_spec("/usr/lib/debug");
30780552918SZachary Turner FileSystem::Instance().Resolve(file_spec);
30880552918SZachary Turner debug_file_search_paths.AppendIfUnique(file_spec);
30980552918SZachary Turner }
31080552918SZachary Turner #endif
31180552918SZachary Turner #endif // _WIN32
31280552918SZachary Turner }
31380552918SZachary Turner
31480552918SZachary Turner std::string uuid_str;
31580552918SZachary Turner const UUID &module_uuid = module_spec.GetUUID();
31680552918SZachary Turner if (module_uuid.IsValid()) {
31780552918SZachary Turner // Some debug files are stored in the .build-id directory like this:
31880552918SZachary Turner // /usr/lib/debug/.build-id/ff/e7fe727889ad82bb153de2ad065b2189693315.debug
31980552918SZachary Turner uuid_str = module_uuid.GetAsString("");
32080552918SZachary Turner std::transform(uuid_str.begin(), uuid_str.end(), uuid_str.begin(),
32180552918SZachary Turner ::tolower);
32280552918SZachary Turner uuid_str.insert(2, 1, '/');
32380552918SZachary Turner uuid_str = uuid_str + ".debug";
32480552918SZachary Turner }
32580552918SZachary Turner
32680552918SZachary Turner size_t num_directories = debug_file_search_paths.GetSize();
32780552918SZachary Turner for (size_t idx = 0; idx < num_directories; ++idx) {
32880552918SZachary Turner FileSpec dirspec = debug_file_search_paths.GetFileSpecAtIndex(idx);
32980552918SZachary Turner FileSystem::Instance().Resolve(dirspec);
33080552918SZachary Turner if (!FileSystem::Instance().IsDirectory(dirspec))
33180552918SZachary Turner continue;
33280552918SZachary Turner
33380552918SZachary Turner std::vector<std::string> files;
33480552918SZachary Turner std::string dirname = dirspec.GetPath();
33580552918SZachary Turner
336001ecbdeSPavel Labath if (!uuid_str.empty())
33780552918SZachary Turner files.push_back(dirname + "/.build-id/" + uuid_str);
338001ecbdeSPavel Labath if (symbol_file_spec.GetFilename()) {
339001ecbdeSPavel Labath files.push_back(dirname + "/" +
340001ecbdeSPavel Labath symbol_file_spec.GetFilename().GetCString());
341001ecbdeSPavel Labath files.push_back(dirname + "/.debug/" +
342001ecbdeSPavel Labath symbol_file_spec.GetFilename().GetCString());
34380552918SZachary Turner
34480552918SZachary Turner // Some debug files may stored in the module directory like this:
34580552918SZachary Turner // /usr/lib/debug/usr/lib/library.so.debug
34680552918SZachary Turner if (!file_dir.IsEmpty())
347001ecbdeSPavel Labath files.push_back(dirname + file_dir.AsCString() + "/" +
348001ecbdeSPavel Labath symbol_file_spec.GetFilename().GetCString());
349001ecbdeSPavel Labath }
35080552918SZachary Turner
35180552918SZachary Turner const uint32_t num_files = files.size();
35280552918SZachary Turner for (size_t idx_file = 0; idx_file < num_files; ++idx_file) {
35380552918SZachary Turner const std::string &filename = files[idx_file];
35480552918SZachary Turner FileSpec file_spec(filename);
35580552918SZachary Turner FileSystem::Instance().Resolve(file_spec);
35680552918SZachary Turner
35780552918SZachary Turner if (llvm::sys::fs::equivalent(file_spec.GetPath(),
35880552918SZachary Turner module_file_spec.GetPath()))
35980552918SZachary Turner continue;
36080552918SZachary Turner
36180552918SZachary Turner if (FileSystem::Instance().Exists(file_spec)) {
36280552918SZachary Turner lldb_private::ModuleSpecList specs;
36380552918SZachary Turner const size_t num_specs =
36480552918SZachary Turner ObjectFile::GetModuleSpecifications(file_spec, 0, 0, specs);
365*c8daf4a7SAlvin Wong ModuleSpec mspec;
366*c8daf4a7SAlvin Wong bool valid_mspec = false;
367*c8daf4a7SAlvin Wong if (num_specs == 2) {
368*c8daf4a7SAlvin Wong // Special case to handle both i386 and i686 from ObjectFilePECOFF
369*c8daf4a7SAlvin Wong ModuleSpec mspec2;
370*c8daf4a7SAlvin Wong if (specs.GetModuleSpecAtIndex(0, mspec) &&
371*c8daf4a7SAlvin Wong specs.GetModuleSpecAtIndex(1, mspec2) &&
372*c8daf4a7SAlvin Wong mspec.GetArchitecture().GetTriple().isCompatibleWith(
373*c8daf4a7SAlvin Wong mspec2.GetArchitecture().GetTriple())) {
374*c8daf4a7SAlvin Wong valid_mspec = true;
375*c8daf4a7SAlvin Wong }
376*c8daf4a7SAlvin Wong }
377*c8daf4a7SAlvin Wong if (!valid_mspec) {
37880552918SZachary Turner assert(num_specs <= 1 &&
37980552918SZachary Turner "Symbol Vendor supports only a single architecture");
38080552918SZachary Turner if (num_specs == 1) {
38180552918SZachary Turner if (specs.GetModuleSpecAtIndex(0, mspec)) {
382*c8daf4a7SAlvin Wong valid_mspec = true;
383*c8daf4a7SAlvin Wong }
384*c8daf4a7SAlvin Wong }
385*c8daf4a7SAlvin Wong }
386*c8daf4a7SAlvin Wong if (valid_mspec) {
38780552918SZachary Turner // Skip the uuids check if module_uuid is invalid. For example,
38880552918SZachary Turner // this happens for *.dwp files since at the moment llvm-dwp
38980552918SZachary Turner // doesn't output build ids, nor does binutils dwp.
39080552918SZachary Turner if (!module_uuid.IsValid() || module_uuid == mspec.GetUUID())
39180552918SZachary Turner return file_spec;
39280552918SZachary Turner }
39380552918SZachary Turner }
39480552918SZachary Turner }
39580552918SZachary Turner }
39680552918SZachary Turner
39780552918SZachary Turner return LocateExecutableSymbolFileDsym(module_spec);
39880552918SZachary Turner }
39980552918SZachary Turner
40080552918SZachary Turner #if !defined(__APPLE__)
40180552918SZachary Turner
FindSymbolFileInBundle(const FileSpec & symfile_bundle,const lldb_private::UUID * uuid,const ArchSpec * arch)40280552918SZachary Turner FileSpec Symbols::FindSymbolFileInBundle(const FileSpec &symfile_bundle,
40380552918SZachary Turner const lldb_private::UUID *uuid,
40480552918SZachary Turner const ArchSpec *arch) {
40580552918SZachary Turner // FIXME
40680552918SZachary Turner return FileSpec();
40780552918SZachary Turner }
40880552918SZachary Turner
DownloadObjectAndSymbolFile(ModuleSpec & module_spec,Status & error,bool force_lookup)40980552918SZachary Turner bool Symbols::DownloadObjectAndSymbolFile(ModuleSpec &module_spec,
410af91446aSJonas Devlieghere Status &error, bool force_lookup) {
41180552918SZachary Turner // Fill in the module_spec.GetFileSpec() for the object file and/or the
41280552918SZachary Turner // module_spec.GetSymbolFileSpec() for the debug symbols file.
41380552918SZachary Turner return false;
41480552918SZachary Turner }
41580552918SZachary Turner
41680552918SZachary Turner #endif
417