1 //===-- DataFileCache.cpp -------------------------------------------------===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
9 #include "lldb/Core/DataFileCache.h"
10 #include "lldb/Core/Module.h"
11 #include "lldb/Core/ModuleList.h"
12 #include "lldb/Host/FileSystem.h"
13 #include "lldb/Symbol/ObjectFile.h"
14 #include "lldb/Utility/DataEncoder.h"
15 #include "lldb/Utility/LLDBLog.h"
16 #include "lldb/Utility/Log.h"
17 #include "llvm/Support/CachePruning.h"
19 using namespace lldb_private
;
22 llvm::CachePruningPolicy
DataFileCache::GetLLDBIndexCachePolicy() {
23 static llvm::CachePruningPolicy policy
;
24 static llvm::once_flag once_flag
;
26 llvm::call_once(once_flag
, []() {
27 // Prune the cache based off of the LLDB settings each time we create a
29 ModuleListProperties
&properties
=
30 ModuleList::GetGlobalModuleListProperties();
31 // Only scan once an hour. If we have lots of debug sessions we don't want
32 // to scan this directory too often. A timestamp file is written to the
33 // directory to ensure different processes don't scan the directory too
34 // often. This setting doesn't mean that a thread will continually scan the
35 // cache directory within this process.
36 policy
.Interval
= std::chrono::hours(1);
37 // Get the user settings for pruning.
38 policy
.MaxSizeBytes
= properties
.GetLLDBIndexCacheMaxByteSize();
39 policy
.MaxSizePercentageOfAvailableSpace
=
40 properties
.GetLLDBIndexCacheMaxPercent();
42 std::chrono::hours(properties
.GetLLDBIndexCacheExpirationDays() * 24);
47 DataFileCache::DataFileCache(llvm::StringRef path
, llvm::CachePruningPolicy policy
) {
48 m_cache_dir
.SetPath(path
);
49 pruneCache(path
, policy
);
51 // This lambda will get called when the data is gotten from the cache and
52 // also after the data was set for a given key. We only need to take
53 // ownership of the data if we are geting the data, so we use the
54 // m_take_ownership member variable to indicate if we need to take
57 auto add_buffer
= [this](unsigned task
, const llvm::Twine
&moduleName
,
58 std::unique_ptr
<llvm::MemoryBuffer
> m
) {
60 m_mem_buff_up
= std::move(m
);
62 llvm::Expected
<llvm::FileCache
> cache_or_err
=
63 llvm::localCache("LLDBModuleCache", "lldb-module", path
, add_buffer
);
65 m_cache_callback
= std::move(*cache_or_err
);
67 Log
*log
= GetLog(LLDBLog::Modules
);
68 LLDB_LOG_ERROR(log
, cache_or_err
.takeError(),
69 "failed to create lldb index cache directory: {0}");
73 std::unique_ptr
<llvm::MemoryBuffer
>
74 DataFileCache::GetCachedData(llvm::StringRef key
) {
75 std::lock_guard
<std::mutex
> guard(m_mutex
);
77 const unsigned task
= 1;
78 m_take_ownership
= true;
79 // If we call the "m_cache_callback" function and the data is cached, it will
80 // call the "add_buffer" lambda function from the constructor which will in
81 // turn take ownership of the member buffer that is passed to the callback and
82 // put it into a member variable.
83 llvm::Expected
<llvm::AddStreamFn
> add_stream_or_err
=
84 m_cache_callback(task
, key
, "");
85 m_take_ownership
= false;
86 // At this point we either already called the "add_buffer" lambda with
87 // the data or we haven't. We can tell if we got the cached data by checking
88 // the add_stream function pointer value below.
89 if (add_stream_or_err
) {
90 llvm::AddStreamFn
&add_stream
= *add_stream_or_err
;
91 // If the "add_stream" is nullptr, then the data was cached and we already
92 // called the "add_buffer" lambda. If it is valid, then if we were to call
93 // the add_stream function it would cause a cache file to get generated
94 // and we would be expected to fill in the data. In this function we only
95 // want to check if the data was cached, so we don't want to call
96 // "add_stream" in this function.
98 return std::move(m_mem_buff_up
);
100 Log
*log
= GetLog(LLDBLog::Modules
);
101 LLDB_LOG_ERROR(log
, add_stream_or_err
.takeError(),
102 "failed to get the cache add stream callback for key: {0}");
104 // Data was not cached.
105 return std::unique_ptr
<llvm::MemoryBuffer
>();
108 bool DataFileCache::SetCachedData(llvm::StringRef key
,
109 llvm::ArrayRef
<uint8_t> data
) {
110 std::lock_guard
<std::mutex
> guard(m_mutex
);
111 const unsigned task
= 2;
112 // If we call this function and the data is cached, it will call the
113 // add_buffer lambda function from the constructor which will ignore the
115 llvm::Expected
<llvm::AddStreamFn
> add_stream_or_err
=
116 m_cache_callback(task
, key
, "");
117 // If we reach this code then we either already called the callback with
118 // the data or we haven't. We can tell if we had the cached data by checking
119 // the CacheAddStream function pointer value below.
120 if (add_stream_or_err
) {
121 llvm::AddStreamFn
&add_stream
= *add_stream_or_err
;
122 // If the "add_stream" is nullptr, then the data was cached. If it is
123 // valid, then if we call the add_stream function with a task it will
124 // cause the file to get generated, but we only want to check if the data
125 // is cached here, so we don't want to call it here. Note that the
126 // add_buffer will also get called in this case after the data has been
127 // provided, but we won't take ownership of the memory buffer as we just
128 // want to write the data.
130 llvm::Expected
<std::unique_ptr
<llvm::CachedFileStream
>> file_or_err
=
131 add_stream(task
, "");
133 llvm::CachedFileStream
*cfs
= file_or_err
->get();
134 cfs
->OS
->write((const char *)data
.data(), data
.size());
137 Log
*log
= GetLog(LLDBLog::Modules
);
138 LLDB_LOG_ERROR(log
, file_or_err
.takeError(),
139 "failed to get the cache file stream for key: {0}");
143 Log
*log
= GetLog(LLDBLog::Modules
);
144 LLDB_LOG_ERROR(log
, add_stream_or_err
.takeError(),
145 "failed to get the cache add stream callback for key: {0}");
150 FileSpec
DataFileCache::GetCacheFilePath(llvm::StringRef key
) {
151 FileSpec
cache_file(m_cache_dir
);
152 std::string
filename("llvmcache-");
153 filename
+= key
.str();
154 cache_file
.AppendPathComponent(filename
);
158 Status
DataFileCache::RemoveCacheFile(llvm::StringRef key
) {
159 FileSpec cache_file
= GetCacheFilePath(key
);
160 FileSystem
&fs
= FileSystem::Instance();
161 if (!fs
.Exists(cache_file
))
163 return fs
.RemoveFile(cache_file
);
166 CacheSignature::CacheSignature(lldb_private::Module
*module
) {
168 UUID uuid
= module
->GetUUID();
172 std::time_t mod_time
= 0;
173 mod_time
= llvm::sys::toTimeT(module
->GetModificationTime());
175 m_mod_time
= mod_time
;
177 mod_time
= llvm::sys::toTimeT(module
->GetObjectModificationTime());
179 m_obj_mod_time
= mod_time
;
182 CacheSignature::CacheSignature(lldb_private::ObjectFile
*objfile
) {
184 UUID uuid
= objfile
->GetUUID();
188 std::time_t mod_time
= 0;
189 // Grab the modification time of the object file's file. It isn't always the
190 // same as the module's file when you have a executable file as the main
191 // executable, and you have a object file for a symbol file.
192 FileSystem
&fs
= FileSystem::Instance();
193 mod_time
= llvm::sys::toTimeT(fs
.GetModificationTime(objfile
->GetFileSpec()));
195 m_mod_time
= mod_time
;
198 llvm::sys::toTimeT(objfile
->GetModule()->GetObjectModificationTime());
200 m_obj_mod_time
= mod_time
;
203 enum SignatureEncoding
{
205 eSignatureModTime
= 2u,
206 eSignatureObjectModTime
= 3u,
207 eSignatureEnd
= 255u,
210 bool CacheSignature::Encode(DataEncoder
&encoder
) const {
212 return false; // Invalid signature, return false!
215 llvm::ArrayRef
<uint8_t> uuid_bytes
= m_uuid
->GetBytes();
216 encoder
.AppendU8(eSignatureUUID
);
217 encoder
.AppendU8(uuid_bytes
.size());
218 encoder
.AppendData(uuid_bytes
);
221 encoder
.AppendU8(eSignatureModTime
);
222 encoder
.AppendU32(*m_mod_time
);
224 if (m_obj_mod_time
) {
225 encoder
.AppendU8(eSignatureObjectModTime
);
226 encoder
.AppendU32(*m_obj_mod_time
);
228 encoder
.AppendU8(eSignatureEnd
);
232 bool CacheSignature::Decode(const lldb_private::DataExtractor
&data
,
233 lldb::offset_t
*offset_ptr
) {
235 while (uint8_t sig_encoding
= data
.GetU8(offset_ptr
)) {
236 switch (sig_encoding
) {
237 case eSignatureUUID
: {
238 const uint8_t length
= data
.GetU8(offset_ptr
);
239 const uint8_t *bytes
= (const uint8_t *)data
.GetData(offset_ptr
, length
);
240 if (bytes
!= nullptr && length
> 0)
241 m_uuid
= UUID(llvm::ArrayRef
<uint8_t>(bytes
, length
));
243 case eSignatureModTime
: {
244 uint32_t mod_time
= data
.GetU32(offset_ptr
);
246 m_mod_time
= mod_time
;
248 case eSignatureObjectModTime
: {
249 uint32_t mod_time
= data
.GetU32(offset_ptr
);
251 m_obj_mod_time
= mod_time
;
254 // The definition of is valid changed to only be valid if the UUID is
255 // valid so make sure that if we attempt to decode an old cache file
256 // that we will fail to decode the cache file if the signature isn't
266 uint32_t ConstStringTable::Add(ConstString s
) {
267 auto [pos
, inserted
] = m_string_to_offset
.try_emplace(s
, m_next_offset
);
269 m_strings
.push_back(s
);
270 m_next_offset
+= s
.GetLength() + 1;
275 static const llvm::StringRef
kStringTableIdentifier("STAB");
277 bool ConstStringTable::Encode(DataEncoder
&encoder
) {
278 // Write an 4 character code into the stream. This will help us when decoding
279 // to make sure we find this identifier when decoding the string table to make
280 // sure we have the rigth data. It also helps to identify the string table
281 // when dumping the hex bytes in a cache file.
282 encoder
.AppendData(kStringTableIdentifier
);
283 size_t length_offset
= encoder
.GetByteSize();
284 encoder
.AppendU32(0); // Total length of all strings which will be fixed up.
285 size_t strtab_offset
= encoder
.GetByteSize();
286 encoder
.AppendU8(0); // Start the string table with an empty string.
287 for (auto s
: m_strings
) {
288 // Make sure all of the offsets match up with what we handed out!
289 assert(m_string_to_offset
.find(s
)->second
==
290 encoder
.GetByteSize() - strtab_offset
);
291 // Append the C string into the encoder
292 encoder
.AppendCString(s
.GetStringRef());
294 // Fixup the string table length.
295 encoder
.PutU32(length_offset
, encoder
.GetByteSize() - strtab_offset
);
299 bool StringTableReader::Decode(const lldb_private::DataExtractor
&data
,
300 lldb::offset_t
*offset_ptr
) {
301 llvm::StringRef
identifier((const char *)data
.GetData(offset_ptr
, 4), 4);
302 if (identifier
!= kStringTableIdentifier
)
304 const uint32_t length
= data
.GetU32(offset_ptr
);
305 // We always have at least one byte for the empty string at offset zero.
308 const char *bytes
= (const char *)data
.GetData(offset_ptr
, length
);
309 if (bytes
== nullptr)
311 m_data
= llvm::StringRef(bytes
, length
);
315 llvm::StringRef
StringTableReader::Get(uint32_t offset
) const {
316 if (offset
>= m_data
.size())
317 return llvm::StringRef();
318 return llvm::StringRef(m_data
.data() + offset
);