Skip to content

Commit 2a1ffca

Browse files
[lldb] Teach LLDB to load gmodules from CAS
1 parent 915d498 commit 2a1ffca

File tree

4 files changed

+124
-2
lines changed

4 files changed

+124
-2
lines changed

clang/test/ClangScanDeps/gmodules.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -218,6 +218,7 @@ int main(void) {
218218
struct Right _right;
219219
struct Top _top;
220220
struct Prefix _prefix;
221+
return 0;
221222
}
222223

223224
//--- cas-config.template

lldb/include/lldb/Core/ModuleList.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -528,6 +528,11 @@ class ModuleList {
528528
llvm::SmallVectorImpl<lldb::ModuleSP> *old_modules,
529529
bool *did_create_ptr, bool always_create = false);
530530

531+
static Status GetSharedModuleFromCAS(ConstString module_name,
532+
const char *cas_id, FileSpec cu_path,
533+
ModuleSpec &module_spec,
534+
lldb::ModuleSP &module_sp);
535+
531536
static bool RemoveSharedModule(lldb::ModuleSP &module_sp);
532537

533538
static void FindSharedModules(const ModuleSpec &module_spec,

lldb/source/Core/ModuleList.cpp

Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,13 +26,16 @@
2626
#include "lldb/Utility/Log.h"
2727
#include "lldb/Utility/UUID.h"
2828
#include "lldb/lldb-defines.h"
29+
#include "llvm/Support/FileUtilities.h"
2930

3031
#if defined(_WIN32)
3132
#include "lldb/Host/windows/PosixApi.h"
3233
#endif
3334

3435
#include "clang/Driver/Driver.h"
3536
#include "llvm/ADT/StringRef.h"
37+
#include "llvm/CAS/CASConfiguration.h"
38+
#include "llvm/CAS/ObjectStore.h"
3639
#include "llvm/Support/FileSystem.h"
3740
#include "llvm/Support/Threading.h"
3841
#include "llvm/Support/raw_ostream.h"
@@ -1050,8 +1053,13 @@ namespace {
10501053
struct SharedModuleListInfo {
10511054
ModuleList module_list;
10521055
ModuleListProperties module_list_properties;
1056+
std::shared_ptr<llvm::cas::ObjectStore> cas_object_store;
1057+
llvm::StringMap<FileSpec> loaded_cas_files;
1058+
std::vector<std::unique_ptr<llvm::FileRemover>> module_file_removers;
1059+
std::mutex shared_lock;
10531060
};
10541061
}
1062+
10551063
static SharedModuleListInfo &GetSharedModuleListInfo()
10561064
{
10571065
static SharedModuleListInfo *g_shared_module_list_info = nullptr;
@@ -1070,6 +1078,45 @@ static ModuleList &GetSharedModuleList() {
10701078
return GetSharedModuleListInfo().module_list;
10711079
}
10721080

1081+
static std::shared_ptr<llvm::cas::ObjectStore>
1082+
GetOrCreateCASStorage(FileSpec CandidateConfigSearchPath) {
1083+
auto &shared_module_list = GetSharedModuleListInfo();
1084+
if (shared_module_list.cas_object_store)
1085+
return shared_module_list.cas_object_store;
1086+
1087+
std::scoped_lock<std::mutex> lock(shared_module_list.shared_lock);
1088+
// Config CAS from properties.
1089+
llvm::cas::CASConfiguration cas_config;
1090+
cas_config.CASPath =
1091+
ModuleList::GetGlobalModuleListProperties().GetCASOnDiskPath().GetPath();
1092+
cas_config.PluginPath =
1093+
ModuleList::GetGlobalModuleListProperties().GetCASPluginPath().GetPath();
1094+
cas_config.PluginOptions =
1095+
ModuleList::GetGlobalModuleListProperties().GetCASPluginOptions();
1096+
1097+
if (!cas_config.CASPath.empty()) {
1098+
if (auto maybe_cas = cas_config.createDatabases()) {
1099+
shared_module_list.cas_object_store = std::move(maybe_cas->first);
1100+
return shared_module_list.cas_object_store;
1101+
} else
1102+
llvm::consumeError(maybe_cas.takeError());
1103+
}
1104+
1105+
// Try search from candidiate path.
1106+
auto search_config = llvm::cas::CASConfiguration::createFromSearchConfigFile(
1107+
CandidateConfigSearchPath.GetPath());
1108+
if (!search_config)
1109+
return nullptr;
1110+
1111+
if (auto maybe_cas = search_config->second.createDatabases()) {
1112+
shared_module_list.cas_object_store = std::move(maybe_cas->first);
1113+
return shared_module_list.cas_object_store;
1114+
} else
1115+
llvm::consumeError(maybe_cas.takeError());
1116+
1117+
return nullptr;
1118+
}
1119+
10731120
ModuleListProperties &ModuleList::GetGlobalModuleListProperties() {
10741121
return GetSharedModuleListInfo().module_list_properties;
10751122
}
@@ -1342,6 +1389,66 @@ ModuleList::GetSharedModule(const ModuleSpec &module_spec, ModuleSP &module_sp,
13421389
return error;
13431390
}
13441391

1392+
static Status loadModuleFromCAS(ConstString module_name, const char *cas_id,
1393+
FileSpec cu_path, ModuleSpec &module_spec) {
1394+
auto cas = GetOrCreateCASStorage(cu_path);
1395+
if (!cas)
1396+
return Status::FromErrorString("CAS is not available");
1397+
1398+
auto &shared_module_list = GetSharedModuleListInfo();
1399+
std::scoped_lock<std::mutex> lock(shared_module_list.shared_lock);
1400+
auto result = shared_module_list.loaded_cas_files.find(cas_id);
1401+
if (result != shared_module_list.loaded_cas_files.end()) {
1402+
module_spec.GetFileSpec() = result->second;
1403+
return Status();
1404+
}
1405+
1406+
auto id = cas->parseID(cas_id) ;
1407+
if (!id)
1408+
return Status::FromError(id.takeError());
1409+
1410+
auto module_proxy = cas->getProxy(*id);
1411+
if (!module_proxy)
1412+
return Status::FromError(module_proxy.takeError());
1413+
1414+
// Create a temporary file that holds the module info.
1415+
// TODO: remove temporary file when finished.
1416+
llvm::SmallString<0> name;
1417+
int fd;
1418+
auto ec =
1419+
llvm::sys::fs::createTemporaryFile("lldb-module-cas", "pcm", fd, name);
1420+
if (ec || fd <= 0)
1421+
return Status::FromErrorString(
1422+
"Could not create temporary file for module");
1423+
1424+
NativeFile file(fd, File::eOpenOptionWriteOnly, true);
1425+
size_t num_bytes = module_proxy->getData().size();
1426+
file.Write(module_proxy->getData().data(), num_bytes);
1427+
1428+
Log *log = GetLog(LLDBLog::Modules);
1429+
if (log != nullptr)
1430+
LLDB_LOGF(log, "loading module '%s' using CASID '%s' from temp file: %s",
1431+
module_name.AsCString(), cas_id, name.c_str());
1432+
1433+
module_spec.GetFileSpec().SetFile(name, FileSpec::Style::native);
1434+
shared_module_list.loaded_cas_files.try_emplace(cas_id,
1435+
module_spec.GetFileSpec());
1436+
1437+
return Status();
1438+
}
1439+
1440+
Status ModuleList::GetSharedModuleFromCAS(ConstString module_name,
1441+
const char *cas_id, FileSpec cu_path,
1442+
ModuleSpec &module_spec,
1443+
lldb::ModuleSP &module_sp) {
1444+
Status load_result =
1445+
loadModuleFromCAS(module_name, cas_id, cu_path, module_spec);
1446+
if (load_result.Fail())
1447+
return load_result;
1448+
1449+
return GetSharedModule(module_spec, module_sp, nullptr, nullptr, nullptr);
1450+
}
1451+
13451452
bool ModuleList::RemoveSharedModule(lldb::ModuleSP &module_sp) {
13461453
return GetSharedModuleList().Remove(module_sp);
13471454
}

lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1998,6 +1998,17 @@ void SymbolFileDWARF::UpdateExternalModuleListIfNeeded() {
19981998
continue;
19991999

20002000
ModuleSpec dwo_module_spec;
2001+
2002+
dwo_module_spec.GetArchitecture() =
2003+
m_objfile_sp->GetModule()->GetArchitecture();
2004+
2005+
// Try load from CAS, if loaded, continue to next one.
2006+
if (ModuleList::GetSharedModuleFromCAS(const_name, dwo_path,
2007+
GetObjectFile()->GetFileSpec(),
2008+
dwo_module_spec, module_sp)
2009+
.Success())
2010+
continue;
2011+
20012012
dwo_module_spec.GetFileSpec().SetFile(dwo_path, FileSpec::Style::native);
20022013
if (dwo_module_spec.GetFileSpec().IsRelative()) {
20032014
const char *comp_dir =
@@ -2009,8 +2020,6 @@ void SymbolFileDWARF::UpdateExternalModuleListIfNeeded() {
20092020
dwo_module_spec.GetFileSpec().AppendPathComponent(dwo_path);
20102021
}
20112022
}
2012-
dwo_module_spec.GetArchitecture() =
2013-
m_objfile_sp->GetModule()->GetArchitecture();
20142023

20152024
// When LLDB loads "external" modules it looks at the presence of
20162025
// DW_AT_dwo_name. However, when the already created module

0 commit comments

Comments
 (0)