26
26
#include " lldb/Utility/Log.h"
27
27
#include " lldb/Utility/UUID.h"
28
28
#include " lldb/lldb-defines.h"
29
+ #include " llvm/Support/FileUtilities.h"
29
30
30
31
#if defined(_WIN32)
31
32
#include " lldb/Host/windows/PosixApi.h"
32
33
#endif
33
34
34
35
#include " clang/Driver/Driver.h"
35
36
#include " llvm/ADT/StringRef.h"
37
+ #include " llvm/CAS/CASConfiguration.h"
38
+ #include " llvm/CAS/ObjectStore.h"
36
39
#include " llvm/Support/FileSystem.h"
37
40
#include " llvm/Support/Threading.h"
38
41
#include " llvm/Support/raw_ostream.h"
@@ -1050,8 +1053,13 @@ namespace {
1050
1053
struct SharedModuleListInfo {
1051
1054
ModuleList module_list;
1052
1055
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;
1053
1060
};
1054
1061
}
1062
+
1055
1063
static SharedModuleListInfo &GetSharedModuleListInfo ()
1056
1064
{
1057
1065
static SharedModuleListInfo *g_shared_module_list_info = nullptr ;
@@ -1070,6 +1078,45 @@ static ModuleList &GetSharedModuleList() {
1070
1078
return GetSharedModuleListInfo ().module_list ;
1071
1079
}
1072
1080
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
+
1073
1120
ModuleListProperties &ModuleList::GetGlobalModuleListProperties () {
1074
1121
return GetSharedModuleListInfo ().module_list_properties ;
1075
1122
}
@@ -1342,6 +1389,66 @@ ModuleList::GetSharedModule(const ModuleSpec &module_spec, ModuleSP &module_sp,
1342
1389
return error;
1343
1390
}
1344
1391
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
+
1345
1452
bool ModuleList::RemoveSharedModule (lldb::ModuleSP &module_sp) {
1346
1453
return GetSharedModuleList ().Remove (module_sp);
1347
1454
}
0 commit comments