LLDB  mainline
ObjectContainerBSDArchive.cpp
Go to the documentation of this file.
1 //===-- ObjectContainerBSDArchive.cpp -------------------------------------===//
2 //
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
6 //
7 //===----------------------------------------------------------------------===//
8 
10 
11 #if defined(_WIN32) || defined(__ANDROID__)
12 // Defines from ar, missing on Windows
13 #define ARMAG "!<arch>\n"
14 #define SARMAG 8
15 #define ARFMAG "`\n"
16 
17 typedef struct ar_hdr {
18  char ar_name[16];
19  char ar_date[12];
20  char ar_uid[6], ar_gid[6];
21  char ar_mode[8];
22  char ar_size[10];
23  char ar_fmag[2];
24 } ar_hdr;
25 #else
26 #include <ar.h>
27 #endif
28 
29 #include "lldb/Core/Module.h"
30 #include "lldb/Core/ModuleSpec.h"
32 #include "lldb/Host/FileSystem.h"
33 #include "lldb/Symbol/ObjectFile.h"
34 #include "lldb/Utility/ArchSpec.h"
35 #include "lldb/Utility/Stream.h"
36 #include "lldb/Utility/Timer.h"
37 
38 #include "llvm/Support/MemoryBuffer.h"
39 
40 using namespace lldb;
41 using namespace lldb_private;
42 
43 using namespace llvm::object;
44 
46 
48 
50  ar_name.Clear();
51  modification_time = 0;
52  uid = 0;
53  gid = 0;
54  mode = 0;
55  size = 0;
56  file_offset = 0;
57  file_size = 0;
58 }
59 
61  const DataExtractor &data, lldb::offset_t offset,
62  llvm::StringRef stringTable) {
63  size_t ar_name_len = 0;
64  std::string str;
65  char *err;
66 
67  // File header
68  //
69  // The common format is as follows.
70  //
71  // Offset Length Name Format
72  // 0 16 File name ASCII right padded with spaces (no spaces
73  // allowed in file name)
74  // 16 12 File mod Decimal as cstring right padded with
75  // spaces
76  // 28 6 Owner ID Decimal as cstring right padded with
77  // spaces
78  // 34 6 Group ID Decimal as cstring right padded with
79  // spaces
80  // 40 8 File mode Octal as cstring right padded with
81  // spaces
82  // 48 10 File byte size Decimal as cstring right padded with
83  // spaces
84  // 58 2 File magic 0x60 0x0A
85 
86  // Make sure there is enough data for the file header and bail if not
87  if (!data.ValidOffsetForDataOfSize(offset, 60))
88  return LLDB_INVALID_OFFSET;
89 
90  str.assign((const char *)data.GetData(&offset, 16), 16);
91  if (!(llvm::StringRef(str).startswith("//") || stringTable.empty())) {
92  // Strip off any trailing spaces.
93  const size_t last_pos = str.find_last_not_of(' ');
94  if (last_pos != std::string::npos) {
95  if (last_pos + 1 < 16)
96  str.erase(last_pos + 1);
97  }
98  int start = strtoul(str.c_str() + 1, &err, 10);
99  int end = stringTable.find('\n', start);
100  str.assign(stringTable.data() + start, end - start - 1);
101  ar_name.SetCString(str.c_str());
102  }
103 
104  str.assign((const char *)data.GetData(&offset, 12), 12);
105  modification_time = strtoul(str.c_str(), &err, 10);
106 
107  str.assign((const char *)data.GetData(&offset, 6), 6);
108  uid = strtoul(str.c_str(), &err, 10);
109 
110  str.assign((const char *)data.GetData(&offset, 6), 6);
111  gid = strtoul(str.c_str(), &err, 10);
112 
113  str.assign((const char *)data.GetData(&offset, 8), 8);
114  mode = strtoul(str.c_str(), &err, 8);
115 
116  str.assign((const char *)data.GetData(&offset, 10), 10);
117  size = strtoul(str.c_str(), &err, 10);
118 
119  str.assign((const char *)data.GetData(&offset, 2), 2);
120  if (str == ARFMAG) {
121  file_offset = offset;
122  file_size = size - ar_name_len;
123  return offset;
124  }
125  return LLDB_INVALID_OFFSET;
126 }
127 
130  lldb::offset_t offset) {
131  size_t ar_name_len = 0;
132  std::string str;
133  char *err;
134 
135  // File header
136  //
137  // The common format is as follows.
138  //
139  // Offset Length Name Format
140  // 0 16 File name ASCII right padded with spaces (no spaces
141  // allowed in file name)
142  // 16 12 File mod Decimal as cstring right padded with
143  // spaces
144  // 28 6 Owner ID Decimal as cstring right padded with
145  // spaces
146  // 34 6 Group ID Decimal as cstring right padded with
147  // spaces
148  // 40 8 File mode Octal as cstring right padded with
149  // spaces
150  // 48 10 File byte size Decimal as cstring right padded with
151  // spaces
152  // 58 2 File magic 0x60 0x0A
153 
154  // Make sure there is enough data for the file header and bail if not
155  if (!data.ValidOffsetForDataOfSize(offset, 60))
156  return LLDB_INVALID_OFFSET;
157 
158  str.assign((const char *)data.GetData(&offset, 16), 16);
159  if (llvm::StringRef(str).startswith("#1/")) {
160  // If the name is longer than 16 bytes, or contains an embedded space then
161  // it will use this format where the length of the name is here and the
162  // name characters are after this header.
163  ar_name_len = strtoul(str.c_str() + 3, &err, 10);
164  } else {
165  // Strip off any trailing spaces.
166  const size_t last_pos = str.find_last_not_of(' ');
167  if (last_pos != std::string::npos) {
168  if (last_pos + 1 < 16)
169  str.erase(last_pos + 1);
170  }
171  ar_name.SetCString(str.c_str());
172  }
173 
174  str.assign((const char *)data.GetData(&offset, 12), 12);
175  modification_time = strtoul(str.c_str(), &err, 10);
176 
177  str.assign((const char *)data.GetData(&offset, 6), 6);
178  uid = strtoul(str.c_str(), &err, 10);
179 
180  str.assign((const char *)data.GetData(&offset, 6), 6);
181  gid = strtoul(str.c_str(), &err, 10);
182 
183  str.assign((const char *)data.GetData(&offset, 8), 8);
184  mode = strtoul(str.c_str(), &err, 8);
185 
186  str.assign((const char *)data.GetData(&offset, 10), 10);
187  size = strtoul(str.c_str(), &err, 10);
188 
189  str.assign((const char *)data.GetData(&offset, 2), 2);
190  if (str == ARFMAG) {
191  if (ar_name_len > 0) {
192  const void *ar_name_ptr = data.GetData(&offset, ar_name_len);
193  // Make sure there was enough data for the string value and bail if not
194  if (ar_name_ptr == nullptr)
195  return LLDB_INVALID_OFFSET;
196  str.assign((const char *)ar_name_ptr, ar_name_len);
197  ar_name.SetCString(str.c_str());
198  }
199  file_offset = offset;
200  file_size = size - ar_name_len;
201  return offset;
202  }
203  return LLDB_INVALID_OFFSET;
204 }
205 
207  const llvm::sys::TimePoint<> &time,
208  lldb::offset_t file_offset,
210  ArchiveType archive_type)
211  : m_arch(arch), m_modification_time(time), m_file_offset(file_offset),
212  m_objects(), m_data(data), m_archive_type(archive_type) {}
213 
215 
217  DataExtractor &data = m_data;
218  std::string str;
219  lldb::offset_t offset = 0;
220  str.assign((const char *)data.GetData(&offset, SARMAG), SARMAG);
221  if (str == ARMAG) {
222  Object obj;
223  do {
224  offset = obj.Extract(data, offset);
225  if (offset == LLDB_INVALID_OFFSET)
226  break;
227  size_t obj_idx = m_objects.size();
228  m_objects.push_back(obj);
229  // Insert all of the C strings out of order for now...
230  m_object_name_to_index_map.Append(obj.ar_name, obj_idx);
231  offset += obj.file_size;
232  obj.Clear();
233  } while (data.ValidOffset(offset));
234 
235  // Now sort all of the object name pointers
236  m_object_name_to_index_map.Sort();
237  } else if (str == ThinArchiveMagic) {
238  Object obj;
239  size_t obj_idx;
240 
241  // Retrieve symbol table
242  offset = obj.ExtractFromThin(data, offset, "");
243  if (offset == LLDB_INVALID_OFFSET)
244  return m_objects.size();
245  obj_idx = m_objects.size();
246  m_objects.push_back(obj);
247  // Insert all of the C strings out of order for now...
248  m_object_name_to_index_map.Append(obj.ar_name, obj_idx);
249  offset += obj.file_size;
250  obj.Clear();
251 
252  // Retrieve string table
253  offset = obj.ExtractFromThin(data, offset, "");
254  if (offset == LLDB_INVALID_OFFSET)
255  return m_objects.size();
256  obj_idx = m_objects.size();
257  m_objects.push_back(obj);
258  // Insert all of the C strings out of order for now...
259  m_object_name_to_index_map.Append(obj.ar_name, obj_idx);
260  // Extract string table
261  llvm::StringRef strtab((const char *)data.GetData(&offset, obj.size),
262  obj.size);
263  obj.Clear();
264 
265  // Retrieve object files
266  do {
267  offset = obj.ExtractFromThin(data, offset, strtab);
268  if (offset == LLDB_INVALID_OFFSET)
269  break;
270  obj_idx = m_objects.size();
271  m_objects.push_back(obj);
272  // Insert all of the C strings out of order for now...
273  m_object_name_to_index_map.Append(obj.ar_name, obj_idx);
274  obj.Clear();
275  } while (data.ValidOffset(offset));
276 
277  // Now sort all of the object name pointers
278  m_object_name_to_index_map.Sort();
279  }
280  return m_objects.size();
281 }
282 
285  ConstString object_name, const llvm::sys::TimePoint<> &object_mod_time) {
286  const ObjectNameToIndexMap::Entry *match =
287  m_object_name_to_index_map.FindFirstValueForName(object_name);
288  if (!match)
289  return nullptr;
290  if (object_mod_time == llvm::sys::TimePoint<>())
291  return &m_objects[match->value];
292 
293  const uint64_t object_modification_date = llvm::sys::toTimeT(object_mod_time);
294  if (m_objects[match->value].modification_time == object_modification_date)
295  return &m_objects[match->value];
296 
297  const ObjectNameToIndexMap::Entry *next_match =
298  m_object_name_to_index_map.FindNextValueForName(match);
299  while (next_match) {
300  if (m_objects[next_match->value].modification_time ==
301  object_modification_date)
302  return &m_objects[next_match->value];
303  next_match = m_object_name_to_index_map.FindNextValueForName(next_match);
304  }
305 
306  return nullptr;
307 }
308 
311  const FileSpec &file, const ArchSpec &arch,
312  const llvm::sys::TimePoint<> &time, lldb::offset_t file_offset) {
313  std::lock_guard<std::recursive_mutex> guard(Archive::GetArchiveCacheMutex());
314  shared_ptr archive_sp;
315  Archive::Map &archive_map = Archive::GetArchiveCache();
316  Archive::Map::iterator pos = archive_map.find(file);
317  // Don't cache a value for "archive_map.end()" below since we might delete an
318  // archive entry...
319  while (pos != archive_map.end() && pos->first == file) {
320  bool match = true;
321  if (arch.IsValid() &&
322  !pos->second->GetArchitecture().IsCompatibleMatch(arch))
323  match = false;
324  else if (file_offset != LLDB_INVALID_OFFSET &&
325  pos->second->GetFileOffset() != file_offset)
326  match = false;
327  if (match) {
328  if (pos->second->GetModificationTime() == time) {
329  return pos->second;
330  } else {
331  // We have a file at the same path with the same architecture whose
332  // modification time doesn't match. It doesn't make sense for us to
333  // continue to use this BSD archive since we cache only the object info
334  // which consists of file time info and also the file offset and file
335  // size of any contained objects. Since this information is now out of
336  // date, we won't get the correct information if we go and extract the
337  // file data, so we should remove the old and outdated entry.
338  archive_map.erase(pos);
339  pos = archive_map.find(file);
340  continue; // Continue to next iteration so we don't increment pos
341  // below...
342  }
343  }
344  ++pos;
345  }
346  return archive_sp;
347 }
348 
351  const FileSpec &file, const ArchSpec &arch,
352  const llvm::sys::TimePoint<> &time, lldb::offset_t file_offset,
353  DataExtractor &data, ArchiveType archive_type) {
354  shared_ptr archive_sp(
355  new Archive(arch, time, file_offset, data, archive_type));
356  if (archive_sp) {
357  const size_t num_objects = archive_sp->ParseObjects();
358  if (num_objects > 0) {
359  std::lock_guard<std::recursive_mutex> guard(
361  Archive::GetArchiveCache().insert(std::make_pair(file, archive_sp));
362  } else {
363  archive_sp.reset();
364  }
365  }
366  return archive_sp;
367 }
368 
371  static Archive::Map g_archive_map;
372  return g_archive_map;
373 }
374 
375 std::recursive_mutex &
377  static std::recursive_mutex g_archive_map_mutex;
378  return g_archive_map_mutex;
379 }
380 
382  PluginManager::RegisterPlugin(GetPluginNameStatic(),
385 }
386 
388  PluginManager::UnregisterPlugin(CreateInstance);
389 }
390 
392  const lldb::ModuleSP &module_sp, DataBufferSP &data_sp,
393  lldb::offset_t data_offset, const FileSpec *file,
394  lldb::offset_t file_offset, lldb::offset_t length) {
395  ConstString object_name(module_sp->GetObjectName());
396  if (!object_name)
397  return nullptr;
398 
399  if (data_sp) {
400  // We have data, which means this is the first 512 bytes of the file Check
401  // to see if the magic bytes match and if they do, read the entire table of
402  // contents for the archive and cache it
403  DataExtractor data;
404  data.SetData(data_sp, data_offset, length);
406  if (file && data_sp && archive_type != ArchiveType::Invalid) {
408  "ObjectContainerBSDArchive::CreateInstance (module = %s, file = "
409  "%p, file_offset = 0x%8.8" PRIx64 ", file_size = 0x%8.8" PRIx64 ")",
410  module_sp->GetFileSpec().GetPath().c_str(),
411  static_cast<const void *>(file), static_cast<uint64_t>(file_offset),
412  static_cast<uint64_t>(length));
413 
414  // Map the entire .a file to be sure that we don't lose any data if the
415  // file gets updated by a new build while this .a file is being used for
416  // debugging
417  DataBufferSP archive_data_sp =
418  FileSystem::Instance().CreateDataBuffer(*file, length, file_offset);
419  if (!archive_data_sp)
420  return nullptr;
421 
422  lldb::offset_t archive_data_offset = 0;
423 
425  *file, module_sp->GetArchitecture(), module_sp->GetModificationTime(),
426  file_offset));
427  std::unique_ptr<ObjectContainerBSDArchive> container_up(
428  new ObjectContainerBSDArchive(module_sp, archive_data_sp,
429  archive_data_offset, file, file_offset,
430  length, archive_type));
431 
432  if (container_up) {
433  if (archive_sp) {
434  // We already have this archive in our cache, use it
435  container_up->SetArchive(archive_sp);
436  return container_up.release();
437  } else if (container_up->ParseHeader())
438  return container_up.release();
439  }
440  }
441  } else {
442  // No data, just check for a cached archive
444  *file, module_sp->GetArchitecture(), module_sp->GetModificationTime(),
445  file_offset));
446  if (archive_sp) {
447  std::unique_ptr<ObjectContainerBSDArchive> container_up(
448  new ObjectContainerBSDArchive(module_sp, data_sp, data_offset, file,
449  file_offset, length,
450  archive_sp->GetArchiveType()));
451 
452  if (container_up) {
453  // We already have this archive in our cache, use it
454  container_up->SetArchive(archive_sp);
455  return container_up.release();
456  }
457  }
458  }
459  return nullptr;
460 }
461 
464  uint32_t offset = 0;
465  const char *armag = (const char *)data.PeekData(offset, sizeof(ar_hdr));
466  if (armag == nullptr)
467  return ArchiveType::Invalid;
468  if (::strncmp(armag, ARMAG, SARMAG) == 0) {
469  armag += offsetof(struct ar_hdr, ar_fmag) + SARMAG;
470  if (strncmp(armag, ARFMAG, 2) == 0)
471  return ArchiveType::Archive;
472  } else if (::strncmp(armag, ThinArchiveMagic, strlen(ThinArchiveMagic)) ==
473  0) {
474  armag += offsetof(struct ar_hdr, ar_fmag) + strlen(ThinArchiveMagic);
475  if (strncmp(armag, ARFMAG, 2) == 0) {
477  }
478  }
479  return ArchiveType::Invalid;
480 }
481 
483  const lldb::ModuleSP &module_sp, DataBufferSP &data_sp,
484  lldb::offset_t data_offset, const lldb_private::FileSpec *file,
485  lldb::offset_t file_offset, lldb::offset_t size, ArchiveType archive_type)
486  : ObjectContainer(module_sp, file, file_offset, size, data_sp, data_offset),
487  m_archive_sp() {
488  m_archive_type = archive_type;
489 }
490 
492  m_archive_sp = archive_sp;
493 }
494 
496 
498  if (m_archive_sp.get() == nullptr) {
499  if (m_data.GetByteSize() > 0) {
500  ModuleSP module_sp(GetModule());
501  if (module_sp) {
503  m_file, module_sp->GetArchitecture(),
504  module_sp->GetModificationTime(), m_offset, m_data, m_archive_type);
505  }
506  // Clear the m_data that contains the entire archive data and let our
507  // m_archive_sp hold onto the data.
508  m_data.Clear();
509  }
510  }
511  return m_archive_sp.get() != nullptr;
512 }
513 
515  const FileSpec &parentFileSpec) {
516  llvm::SmallString<128> FullPath;
517  if (llvm::sys::path::is_absolute(childPath)) {
518  FullPath = childPath;
519  } else {
520  FullPath = parentFileSpec.GetDirectory().GetStringRef();
521  llvm::sys::path::append(FullPath, childPath);
522  }
523  FileSpec child = FileSpec(FullPath.str(), llvm::sys::path::Style::posix);
524  return child;
525 }
526 
528  ModuleSP module_sp(GetModule());
529  if (module_sp) {
530  if (module_sp->GetObjectName() && m_archive_sp) {
531  Object *object = m_archive_sp->FindObject(
532  module_sp->GetObjectName(), module_sp->GetObjectModificationTime());
533  if (object) {
535  // Set file to child object file
537  object->ar_name.GetStringRef(), m_file);
538  lldb::offset_t file_offset = 0;
539  lldb::offset_t file_size = object->size;
540  std::shared_ptr<DataBuffer> child_data_sp =
541  FileSystem::Instance().CreateDataBuffer(child, file_size,
542  file_offset);
543  if (child_data_sp->GetByteSize() != object->file_size)
544  return ObjectFileSP();
545  lldb::offset_t data_offset = 0;
546  return ObjectFile::FindPlugin(
547  module_sp, &child, m_offset + object->file_offset,
548  object->file_size, child_data_sp, data_offset);
549  }
550  lldb::offset_t data_offset = object->file_offset;
551  return ObjectFile::FindPlugin(
552  module_sp, file, m_offset + object->file_offset, object->file_size,
553  m_archive_sp->GetData().GetSharedDataBuffer(), data_offset);
554  }
555  }
556  }
557  return ObjectFileSP();
558 }
559 
561  const lldb_private::FileSpec &file, lldb::DataBufferSP &data_sp,
562  lldb::offset_t data_offset, lldb::offset_t file_offset,
563  lldb::offset_t file_size, lldb_private::ModuleSpecList &specs) {
564 
565  // We have data, which means this is the first 512 bytes of the file Check to
566  // see if the magic bytes match and if they do, read the entire table of
567  // contents for the archive and cache it
568  DataExtractor data;
569  data.SetData(data_sp, data_offset, data_sp->GetByteSize());
571  if (!file || !data_sp || archive_type == ArchiveType::Invalid)
572  return 0;
573 
574  const size_t initial_count = specs.GetSize();
575  llvm::sys::TimePoint<> file_mod_time = FileSystem::Instance().GetModificationTime(file);
576  Archive::shared_ptr archive_sp(
577  Archive::FindCachedArchive(file, ArchSpec(), file_mod_time, file_offset));
578  bool set_archive_arch = false;
579  if (!archive_sp) {
580  set_archive_arch = true;
581  data_sp =
582  FileSystem::Instance().CreateDataBuffer(file, file_size, file_offset);
583  if (data_sp) {
584  data.SetData(data_sp, 0, data_sp->GetByteSize());
586  file, ArchSpec(), file_mod_time, file_offset, data, archive_type);
587  }
588  }
589 
590  if (archive_sp) {
591  const size_t num_objects = archive_sp->GetNumObjects();
592  for (size_t idx = 0; idx < num_objects; ++idx) {
593  const Object *object = archive_sp->GetObjectAtIndex(idx);
594  if (object) {
595  if (archive_sp->GetArchiveType() == ArchiveType::ThinArchive) {
596  if (object->ar_name.IsEmpty())
597  continue;
599  object->ar_name.GetStringRef(), file);
600  if (ObjectFile::GetModuleSpecifications(child, 0, object->file_size,
601  specs)) {
602  ModuleSpec &spec =
603  specs.GetModuleSpecRefAtIndex(specs.GetSize() - 1);
604  llvm::sys::TimePoint<> object_mod_time(
605  std::chrono::seconds(object->modification_time));
606  spec.GetObjectName() = object->ar_name;
607  spec.SetObjectOffset(0);
608  spec.SetObjectSize(object->file_size);
609  spec.GetObjectModificationTime() = object_mod_time;
610  }
611  continue;
612  }
613  const lldb::offset_t object_file_offset =
614  file_offset + object->file_offset;
615  if (object->file_offset < file_size && file_size > object_file_offset) {
616  if (ObjectFile::GetModuleSpecifications(
617  file, object_file_offset, file_size - object_file_offset,
618  specs)) {
619  ModuleSpec &spec =
620  specs.GetModuleSpecRefAtIndex(specs.GetSize() - 1);
621  llvm::sys::TimePoint<> object_mod_time(
622  std::chrono::seconds(object->modification_time));
623  spec.GetObjectName() = object->ar_name;
624  spec.SetObjectOffset(object_file_offset);
625  spec.SetObjectSize(file_size - object_file_offset);
626  spec.GetObjectModificationTime() = object_mod_time;
627  }
628  }
629  }
630  }
631  }
632  const size_t end_count = specs.GetSize();
633  size_t num_specs_added = end_count - initial_count;
634  if (set_archive_arch && num_specs_added > 0) {
635  // The archive was created but we didn't have an architecture so we need to
636  // set it
637  for (size_t i = initial_count; i < end_count; ++i) {
638  ModuleSpec module_spec;
639  if (specs.GetModuleSpecAtIndex(i, module_spec)) {
640  if (module_spec.GetArchitecture().IsValid()) {
641  archive_sp->SetArchitecture(module_spec.GetArchitecture());
642  break;
643  }
644  }
645  }
646  }
647  return num_specs_added;
648 }
ObjectContainerBSDArchive::Object::modification_time
uint32_t modification_time
Object modification time in the archive.
Definition: ObjectContainerBSDArchive.h:94
LLDB_SCOPED_TIMERF
#define LLDB_SCOPED_TIMERF(...)
Definition: Timer.h:86
lldb_private::ArchSpec
Definition: ArchSpec.h:32
FileSystem.h
ModuleSpec.h
lldb_private::DataExtractor::ValidOffset
bool ValidOffset(lldb::offset_t offset) const
Test the validity of offset.
Definition: DataExtractor.h:956
ObjectContainerBSDArchive::GetModuleSpecifications
static size_t GetModuleSpecifications(const lldb_private::FileSpec &file, lldb::DataBufferSP &data_sp, lldb::offset_t data_offset, lldb::offset_t file_offset, lldb::offset_t length, lldb_private::ModuleSpecList &specs)
Definition: ObjectContainerBSDArchive.cpp:560
ObjectContainerBSDArchive::Object::Clear
void Clear()
Definition: ObjectContainerBSDArchive.cpp:49
lldb_private::ModuleSpecList
Definition: ModuleSpec.h:275
ObjectContainerBSDArchive::Terminate
static void Terminate()
Definition: ObjectContainerBSDArchive.cpp:387
lldb_private::ObjectContainer
Definition: ObjectContainer.h:30
lldb_private::ModuleSpec::GetObjectName
ConstString & GetObjectName()
Definition: ModuleSpec.h:103
Module.h
ObjectContainerBSDArchive::SetArchive
void SetArchive(Archive::shared_ptr &archive_sp)
Definition: ObjectContainerBSDArchive.cpp:491
lldb_private::DataExtractor::PeekData
const uint8_t * PeekData(lldb::offset_t offset, lldb::offset_t length) const
Peek at a bytes at offset.
Definition: DataExtractor.h:832
ObjectContainerBSDArchive
Definition: ObjectContainerBSDArchive.h:28
lldb_private::ModuleSpec::SetObjectOffset
void SetObjectOffset(uint64_t object_offset)
Definition: ModuleSpec.h:109
lldb::offset_t
uint64_t offset_t
Definition: lldb-types.h:87
lldb_private::ObjectContainer::m_data
DataExtractor m_data
The data for this object file so things can be parsed lazily.
Definition: ObjectContainer.h:143
ObjectContainerBSDArchive::Archive::GetArchiveCache
static Map & GetArchiveCache()
Definition: ObjectContainerBSDArchive.cpp:370
ObjectContainerBSDArchive::Object
Definition: ObjectContainerBSDArchive.h:79
ObjectContainerBSDArchive::Archive::FindObject
Object * FindObject(lldb_private::ConstString object_name, const llvm::sys::TimePoint<> &object_mod_time)
Definition: ObjectContainerBSDArchive.cpp:284
ObjectContainerBSDArchive::Archive::FindCachedArchive
static Archive::shared_ptr FindCachedArchive(const lldb_private::FileSpec &file, const lldb_private::ArchSpec &arch, const llvm::sys::TimePoint<> &mod_time, lldb::offset_t file_offset)
Definition: ObjectContainerBSDArchive.cpp:310
GetChildFileSpecificationsFromThin
FileSpec GetChildFileSpecificationsFromThin(llvm::StringRef childPath, const FileSpec &parentFileSpec)
Definition: ObjectContainerBSDArchive.cpp:514
lldb_private::DataExtractor::SetData
lldb::offset_t SetData(const void *bytes, lldb::offset_t length, lldb::ByteOrder byte_order)
Set data with a buffer that is caller owned.
Definition: DataExtractor.cpp:223
lldb_private::FileSpec
Definition: FileSpec.h:55
ArchiveType::Archive
@ Archive
ArchiveType::Invalid
@ Invalid
LLDB_INVALID_OFFSET
#define LLDB_INVALID_OFFSET
Definition: lldb-defines.h:85
lldb_private::DataExtractor
Definition: DataExtractor.h:48
lldb_private::ConstString::GetStringRef
llvm::StringRef GetStringRef() const
Get the string value as a llvm::StringRef.
Definition: ConstString.h:201
ObjectContainerBSDArchive::Archive::ParseObjects
size_t ParseObjects()
Definition: ObjectContainerBSDArchive.cpp:216
lldb_private::ModuleSpec::GetObjectModificationTime
llvm::sys::TimePoint & GetObjectModificationTime()
Definition: ModuleSpec.h:117
lldb_private::ConstString::IsEmpty
bool IsEmpty() const
Test for empty string.
Definition: ConstString.h:303
ObjectContainerBSDArchive::Archive::shared_ptr
std::shared_ptr< Archive > shared_ptr
Definition: ObjectContainerBSDArchive.h:117
lldb_private::ObjectContainer::m_offset
lldb::addr_t m_offset
The offset in bytes into the file, or the address in memory.
Definition: ObjectContainer.h:137
ObjectContainerBSDArchive::m_archive_type
ArchiveType m_archive_type
Definition: ObjectContainerBSDArchive.h:186
ObjectContainerBSDArchive::Object::Extract
lldb::offset_t Extract(const lldb_private::DataExtractor &data, lldb::offset_t offset)
Definition: ObjectContainerBSDArchive.cpp:129
ObjectContainerBSDArchive::ParseHeader
bool ParseHeader() override
Attempts to parse the object header.
Definition: ObjectContainerBSDArchive.cpp:497
lldb_private::ConstString
Definition: ConstString.h:39
ObjectContainerBSDArchive::~ObjectContainerBSDArchive
~ObjectContainerBSDArchive() override
Timer.h
lldb_private::ModuleSpecList::GetModuleSpecRefAtIndex
ModuleSpec & GetModuleSpecRefAtIndex(size_t i)
Definition: ModuleSpec.h:321
string
string(SUBSTRING ${p} 10 -1 pStripped) if($
Definition: Plugins/CMakeLists.txt:40
lldb_private::ArchSpec::IsValid
bool IsValid() const
Tests if this ArchSpec is valid.
Definition: ArchSpec.h:361
lldb_private::ObjectContainer::m_file
FileSpec m_file
The file that represents this container objects (which can be different from the module's file).
Definition: ObjectContainer.h:134
ObjectFile.h
lldb_private::ModuleSpec
Definition: ModuleSpec.h:27
ObjectContainerBSDArchive::Archive::GetArchiveCacheMutex
static std::recursive_mutex & GetArchiveCacheMutex()
Definition: ObjectContainerBSDArchive.cpp:376
ObjectContainerBSDArchive::Object::ar_name
lldb_private::ConstString ar_name
Object name in the archive.
Definition: ObjectContainerBSDArchive.h:91
uint32_t
lldb_private::FileSpec::GetDirectory
const ConstString & GetDirectory() const
Directory string const get accessor.
Definition: FileSpec.h:222
ObjectContainerBSDArchive::Initialize
static void Initialize()
Definition: ObjectContainerBSDArchive.cpp:381
ObjectContainerBSDArchive::m_archive_sp
Archive::shared_ptr m_archive_sp
Definition: ObjectContainerBSDArchive.h:184
ObjectContainerBSDArchive::Object::size
uint32_t size
Object size in bytes in the archive.
Definition: ObjectContainerBSDArchive.h:106
ArchSpec.h
lldb_private::ModuleChild::GetModule
lldb::ModuleSP GetModule() const
Get const accessor for the module pointer.
Definition: ModuleChild.cpp:24
ObjectContainerBSDArchive::ObjectContainerBSDArchive
ObjectContainerBSDArchive(const lldb::ModuleSP &module_sp, lldb::DataBufferSP &data_sp, lldb::offset_t data_offset, const lldb_private::FileSpec *file, lldb::offset_t offset, lldb::offset_t length, ArchiveType archive_type)
Definition: ObjectContainerBSDArchive.cpp:482
PluginManager.h
lldb_private::ModuleSpec::GetArchitecture
ArchSpec & GetArchitecture()
Definition: ModuleSpec.h:89
ObjectContainerBSDArchive::GetObjectFile
lldb::ObjectFileSP GetObjectFile(const lldb_private::FileSpec *file) override
Selects an architecture in an object file.
Definition: ObjectContainerBSDArchive.cpp:527
ObjectContainerBSDArchive::Archive::Map
std::multimap< lldb_private::FileSpec, shared_ptr > Map
Definition: ObjectContainerBSDArchive.h:118
lldb_private::ModuleSpec::SetObjectSize
void SetObjectSize(uint64_t object_size)
Definition: ModuleSpec.h:115
ObjectContainerBSDArchive::Object::file_size
lldb::offset_t file_size
Length of the object data.
Definition: ObjectContainerBSDArchive.h:112
ObjectContainerBSDArchive::Object::file_offset
lldb::offset_t file_offset
File offset in bytes from the beginning of the file of the object data.
Definition: ObjectContainerBSDArchive.h:109
ArchiveType::ThinArchive
@ ThinArchive
lldb_private
A class that represents a running process on the host machine.
Definition: SBCommandInterpreterRunOptions.h:16
ArchiveType
ArchiveType
Definition: ObjectContainerBSDArchive.h:26
lldb_private::ModuleSpecList::GetModuleSpecAtIndex
bool GetModuleSpecAtIndex(size_t i, ModuleSpec &module_spec) const
Definition: ModuleSpec.h:323
ObjectContainerBSDArchive::Object::ExtractFromThin
lldb::offset_t ExtractFromThin(const lldb_private::DataExtractor &data, lldb::offset_t offset, llvm::StringRef stringTable)
Definition: ObjectContainerBSDArchive.cpp:60
Entry
FormatEntity::Entry Entry
Definition: FormatEntity.cpp:82
lldb_private::DataExtractor::Clear
void Clear()
Clears the object state.
Definition: DataExtractor.cpp:192
lldb_private::DataExtractor::GetData
const void * GetData(lldb::offset_t *offset_ptr, lldb::offset_t length) const
Extract length bytes from *offset_ptr.
Definition: DataExtractor.h:337
ObjectContainerBSDArchive::Archive::Archive
Archive(const lldb_private::ArchSpec &arch, const llvm::sys::TimePoint<> &mod_time, lldb::offset_t file_offset, lldb_private::DataExtractor &data, ArchiveType archive_type)
Definition: ObjectContainerBSDArchive.cpp:206
lldb_private::ModuleSpecList::GetSize
size_t GetSize() const
Definition: ModuleSpec.h:298
Stream.h
LLDB_PLUGIN_DEFINE
#define LLDB_PLUGIN_DEFINE(PluginName)
Definition: PluginManager.h:31
ObjectContainerBSDArchive::GetPluginDescriptionStatic
static llvm::StringRef GetPluginDescriptionStatic()
Definition: ObjectContainerBSDArchive.h:46
ObjectContainerBSDArchive::Archive::~Archive
~Archive()
lldb_private::DataExtractor::GetByteSize
uint64_t GetByteSize() const
Get the number of bytes contained in this object.
Definition: DataExtractor.h:270
ObjectContainerBSDArchive.h
ObjectContainerBSDArchive::Archive::ParseAndCacheArchiveForFile
static Archive::shared_ptr ParseAndCacheArchiveForFile(const lldb_private::FileSpec &file, const lldb_private::ArchSpec &arch, const llvm::sys::TimePoint<> &mod_time, lldb::offset_t file_offset, lldb_private::DataExtractor &data, ArchiveType archive_type)
Definition: ObjectContainerBSDArchive.cpp:350
lldb_private::DataExtractor::ValidOffsetForDataOfSize
bool ValidOffsetForDataOfSize(lldb::offset_t offset, lldb::offset_t length) const
Test the availability of length bytes of data from offset.
Definition: DataExtractor.h:965
lldb
Definition: SBAddress.h:15
ObjectContainerBSDArchive::GetPluginNameStatic
static llvm::StringRef GetPluginNameStatic()
Definition: ObjectContainerBSDArchive.h:44
ObjectContainerBSDArchive::MagicBytesMatch
static ArchiveType MagicBytesMatch(const lldb_private::DataExtractor &data)
Definition: ObjectContainerBSDArchive.cpp:463
ObjectContainerBSDArchive::CreateInstance
static lldb_private::ObjectContainer * CreateInstance(const lldb::ModuleSP &module_sp, lldb::DataBufferSP &data_sp, lldb::offset_t data_offset, const lldb_private::FileSpec *file, lldb::offset_t offset, lldb::offset_t length)
Definition: ObjectContainerBSDArchive.cpp:391