LLDB  mainline
HexagonDYLDRendezvous.cpp
Go to the documentation of this file.
1 //===-- HexagonDYLDRendezvous.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 
9 #include "lldb/Core/Module.h"
10 #include "lldb/Symbol/Symbol.h"
12 #include "lldb/Target/Process.h"
13 #include "lldb/Target/Target.h"
14 #include "lldb/Utility/Log.h"
15 #include "lldb/Utility/Status.h"
16 
17 #include "lldb/Symbol/ObjectFile.h"
18 #include "lldb/Target/Process.h"
19 #include "lldb/Target/Target.h"
20 
21 #include "HexagonDYLDRendezvous.h"
22 
23 using namespace lldb;
24 using namespace lldb_private;
25 
26 /// Locates the address of the rendezvous structure. Returns the address on
27 /// success and LLDB_INVALID_ADDRESS on failure.
29  addr_t info_location;
30  addr_t info_addr;
31  Status error;
32 
33  info_location = process->GetImageInfoAddress();
34 
35  if (info_location == LLDB_INVALID_ADDRESS)
36  return LLDB_INVALID_ADDRESS;
37 
38  info_addr = process->ReadPointerFromMemory(info_location, error);
39  if (error.Fail())
40  return LLDB_INVALID_ADDRESS;
41 
42  if (info_addr == 0)
43  return LLDB_INVALID_ADDRESS;
44 
45  return info_addr;
46 }
47 
49  : m_process(process), m_rendezvous_addr(LLDB_INVALID_ADDRESS), m_current(),
50  m_previous(), m_soentries(), m_added_soentries(), m_removed_soentries() {
51  m_thread_info.valid = false;
56 
57  // Cache a copy of the executable path
58  if (m_process) {
60  if (exe_mod)
62  }
63 }
64 
66  const size_t word_size = 4;
67  Rendezvous info;
68  size_t address_size;
69  size_t padding;
70  addr_t info_addr;
71  addr_t cursor;
72 
73  address_size = m_process->GetAddressByteSize();
74  padding = address_size - word_size;
75 
77  cursor = info_addr = ResolveRendezvousAddress(m_process);
78  else
79  cursor = info_addr = m_rendezvous_addr;
80 
81  if (cursor == LLDB_INVALID_ADDRESS)
82  return false;
83 
84  if (!(cursor = ReadWord(cursor, &info.version, word_size)))
85  return false;
86 
87  if (!(cursor = ReadPointer(cursor + padding, &info.map_addr)))
88  return false;
89 
90  if (!(cursor = ReadPointer(cursor, &info.brk)))
91  return false;
92 
93  if (!(cursor = ReadWord(cursor, &info.state, word_size)))
94  return false;
95 
96  if (!(cursor = ReadPointer(cursor + padding, &info.ldbase)))
97  return false;
98 
99  // The rendezvous was successfully read. Update our internal state.
100  m_rendezvous_addr = info_addr;
102  m_current = info;
103 
104  return UpdateSOEntries();
105 }
106 
108  m_rendezvous_addr = addr;
109 }
110 
113 }
114 
116  SOEntry entry;
117 
118  if (m_current.map_addr == 0)
119  return false;
120 
121  // When the previous and current states are consistent this is the first time
122  // we have been asked to update. Just take a snapshot of the currently
123  // loaded modules.
125  return TakeSnapshot(m_soentries);
126 
127  // If we are about to add or remove a shared object clear out the current
128  // state and take a snapshot of the currently loaded images.
129  if (m_current.state == eAdd || m_current.state == eDelete) {
130  // this is a fudge so that we can clear the assert below.
132  // We hit this assert on the 2nd run of this function after running the
133  // calc example
134  assert(m_previous.state == eConsistent);
135  m_soentries.clear();
136  m_added_soentries.clear();
137  m_removed_soentries.clear();
138  return TakeSnapshot(m_soentries);
139  }
140  assert(m_current.state == eConsistent);
141 
142  // Otherwise check the previous state to determine what to expect and update
143  // accordingly.
144  if (m_previous.state == eAdd)
146  else if (m_previous.state == eDelete)
148 
149  return false;
150 }
151 
153  SOEntry entry;
154  iterator pos;
155 
156  assert(m_previous.state == eAdd);
157 
158  if (m_current.map_addr == 0)
159  return false;
160 
161  for (addr_t cursor = m_current.map_addr; cursor != 0; cursor = entry.next) {
162  if (!ReadSOEntryFromMemory(cursor, entry))
163  return false;
164 
165  // Only add shared libraries and not the executable. On Linux this is
166  // indicated by an empty path in the entry. On FreeBSD it is the name of
167  // the executable.
168  if (entry.path.empty() || ::strcmp(entry.path.c_str(), m_exe_path) == 0)
169  continue;
170 
171  if (!llvm::is_contained(m_soentries, entry)) {
172  m_soentries.push_back(entry);
173  m_added_soentries.push_back(entry);
174  }
175  }
176 
177  return true;
178 }
179 
181  SOEntryList entry_list;
182  iterator pos;
183 
184  assert(m_previous.state == eDelete);
185 
186  if (!TakeSnapshot(entry_list))
187  return false;
188 
189  for (iterator I = begin(); I != end(); ++I) {
190  if (!llvm::is_contained(entry_list, *I))
191  m_removed_soentries.push_back(*I);
192  }
193 
194  m_soentries = entry_list;
195  return true;
196 }
197 
199  SOEntry entry;
200 
201  if (m_current.map_addr == 0)
202  return false;
203 
204  for (addr_t cursor = m_current.map_addr; cursor != 0; cursor = entry.next) {
205  if (!ReadSOEntryFromMemory(cursor, entry))
206  return false;
207 
208  // Only add shared libraries and not the executable. On Linux this is
209  // indicated by an empty path in the entry. On FreeBSD it is the name of
210  // the executable.
211  if (entry.path.empty() || ::strcmp(entry.path.c_str(), m_exe_path) == 0)
212  continue;
213 
214  entry_list.push_back(entry);
215  }
216 
217  return true;
218 }
219 
221  size_t size) {
222  Status error;
223 
224  *dst = m_process->ReadUnsignedIntegerFromMemory(addr, size, 0, error);
225  if (error.Fail())
226  return 0;
227 
228  return addr + size;
229 }
230 
232  Status error;
233 
234  *dst = m_process->ReadPointerFromMemory(addr, error);
235  if (error.Fail())
236  return 0;
237 
238  return addr + m_process->GetAddressByteSize();
239 }
240 
242  std::string str;
243  Status error;
244  size_t size;
245  char c;
246 
247  if (addr == LLDB_INVALID_ADDRESS)
248  return std::string();
249 
250  for (;;) {
251  size = m_process->ReadMemory(addr, &c, 1, error);
252  if (size != 1 || error.Fail())
253  return std::string();
254  if (c == 0)
255  break;
256  else {
257  str.push_back(c);
258  addr++;
259  }
260  }
261 
262  return str;
263 }
264 
266  SOEntry &entry) {
267  entry.clear();
268  entry.link_addr = addr;
269 
270  if (!(addr = ReadPointer(addr, &entry.base_addr)))
271  return false;
272 
273  if (!(addr = ReadPointer(addr, &entry.path_addr)))
274  return false;
275 
276  if (!(addr = ReadPointer(addr, &entry.dyn_addr)))
277  return false;
278 
279  if (!(addr = ReadPointer(addr, &entry.next)))
280  return false;
281 
282  if (!(addr = ReadPointer(addr, &entry.prev)))
283  return false;
284 
285  entry.path = ReadStringFromMemory(entry.path_addr);
286 
287  return true;
288 }
289 
291  uint32_t &value) {
292  Target &target = m_process->GetTarget();
293 
297  if (list.IsEmpty())
298  return false;
299 
300  Address address = list[0].symbol->GetAddress();
301  addr_t addr = address.GetLoadAddress(&target);
302  if (addr == LLDB_INVALID_ADDRESS)
303  return false;
304 
305  Status error;
307  addr + field * sizeof(uint32_t), sizeof(uint32_t), 0, error);
308  if (error.Fail())
309  return false;
310 
311  if (field == eSize)
312  value /= 8; // convert bits to bytes
313 
314  return true;
315 }
316 
319  if (!m_thread_info.valid) {
320  bool ok = true;
321 
322  ok &= FindMetadata("_thread_db_pthread_dtvp", eOffset,
324  ok &=
325  FindMetadata("_thread_db_dtv_dtv", eSize, m_thread_info.dtv_slot_size);
326  ok &= FindMetadata("_thread_db_link_map_l_tls_modid", eOffset,
328  ok &= FindMetadata("_thread_db_dtv_t_pointer_val", eOffset,
330 
331  if (ok)
332  m_thread_info.valid = true;
333  }
334 
335  return m_thread_info;
336 }
337 
339  int state = GetState();
340 
341  if (!log)
342  return;
343 
344  log->PutCString("HexagonDYLDRendezvous:");
345  LLDB_LOGF(log, " Address: %" PRIx64, GetRendezvousAddress());
346  LLDB_LOGF(log, " Version: %" PRIu64, GetVersion());
347  LLDB_LOGF(log, " Link : %" PRIx64, GetLinkMapAddress());
348  LLDB_LOGF(log, " Break : %" PRIx64, GetBreakAddress());
349  LLDB_LOGF(log, " LDBase : %" PRIx64, GetLDBase());
350  LLDB_LOGF(log, " State : %s",
351  (state == eConsistent)
352  ? "consistent"
353  : (state == eAdd) ? "add"
354  : (state == eDelete) ? "delete" : "unknown");
355 
356  iterator I = begin();
357  iterator E = end();
358 
359  if (I != E)
360  log->PutCString("HexagonDYLDRendezvous SOEntries:");
361 
362  for (int i = 1; I != E; ++I, ++i) {
363  LLDB_LOGF(log, "\n SOEntry [%d] %s", i, I->path.c_str());
364  LLDB_LOGF(log, " Base : %" PRIx64, I->base_addr);
365  LLDB_LOGF(log, " Path : %" PRIx64, I->path_addr);
366  LLDB_LOGF(log, " Dyn : %" PRIx64, I->dyn_addr);
367  LLDB_LOGF(log, " Next : %" PRIx64, I->next);
368  LLDB_LOGF(log, " Prev : %" PRIx64, I->prev);
369  }
370 }
list
MATCHES FreeBSD list(APPEND FBSDKERNEL_LIBS kvm) endif() if(NOT FBSDKERNEL_LIBS) message(STATUS "Skipping FreeBSDKernel plugin due to missing libfbsdvmcore") return() endif() add_lldb_library(lldbPluginProcessFreeBSDKernel PLUGIN ProcessFreeBSDKernel.cpp RegisterContextFreeBSDKernel_arm64.cpp RegisterContextFreeBSDKernel_i386.cpp RegisterContextFreeBSDKernel_x86_64.cpp ThreadFreeBSDKernel.cpp LINK_LIBS lldbCore lldbTarget $
Definition: Plugins/Process/FreeBSDKernel/CMakeLists.txt:6
HexagonDYLDRendezvous::ThreadInfo::dtv_offset
uint32_t dtv_offset
Definition: HexagonDYLDRendezvous.h:52
HexagonDYLDRendezvous::eOffset
@ eOffset
Definition: HexagonDYLDRendezvous.h:239
HexagonDYLDRendezvous::GetLinkMapAddress
lldb::addr_t GetLinkMapAddress() const
Definition: HexagonDYLDRendezvous.h:87
HexagonDYLDRendezvous::iterator
SOEntryList::const_iterator iterator
Definition: HexagonDYLDRendezvous.h:165
lldb_private::Process::ReadMemory
virtual size_t ReadMemory(lldb::addr_t vm_addr, void *buf, size_t size, Status &error)
Read of memory from a process.
Definition: Process.cpp:1922
HexagonDYLDRendezvous::UpdateSOEntries
bool UpdateSOEntries()
Updates the current set of SOEntries, the set of added entries, and the set of removed entries.
Definition: HexagonDYLDRendezvous.cpp:115
HexagonDYLDRendezvous.h
HexagonDYLDRendezvous::Rendezvous::state
uint64_t state
Definition: HexagonDYLDRendezvous.h:41
HexagonDYLDRendezvous::GetRendezvousAddress
lldb::addr_t GetRendezvousAddress() const
Definition: HexagonDYLDRendezvous.h:77
LLDB_LOGF
#define LLDB_LOGF(log,...)
Definition: Log.h:344
lldb_private::Process
Definition: Process.h:338
lldb_private::Target::GetExecutableModulePointer
Module * GetExecutableModulePointer()
Definition: Target.cpp:1383
HexagonDYLDRendezvous::SOEntry
Structure representing the shared objects currently loaded into the inferior process.
Definition: HexagonDYLDRendezvous.h:137
Module.h
HexagonDYLDRendezvous::Rendezvous::map_addr
lldb::addr_t map_addr
Definition: HexagonDYLDRendezvous.h:39
HexagonDYLDRendezvous::GetLDBase
lldb::addr_t GetLDBase() const
Definition: HexagonDYLDRendezvous.h:108
lldb_private::Process::GetTarget
Target & GetTarget()
Get the target object pointer for this module.
Definition: Process.h:1219
word_size
static const size_t word_size
Definition: ABISysV_arc.cpp:170
HexagonDYLDRendezvous::end
iterator end() const
Definition: HexagonDYLDRendezvous.h:169
HexagonDYLDRendezvous::Rendezvous::ldbase
lldb::addr_t ldbase
Definition: HexagonDYLDRendezvous.h:42
lldb_private::SymbolContextList
Definition: SymbolContext.h:379
HexagonDYLDRendezvous::PThreadField
PThreadField
Definition: HexagonDYLDRendezvous.h:239
lldb_private::Module
Definition: Module.h:85
HexagonDYLDRendezvous::GetVersion
uint64_t GetVersion() const
Definition: HexagonDYLDRendezvous.h:83
HexagonDYLDRendezvous::TakeSnapshot
bool TakeSnapshot(SOEntryList &entry_list)
Reads the current list of shared objects according to the link map supplied by the runtime linker.
Definition: HexagonDYLDRendezvous.cpp:198
lldb::addr_t
uint64_t addr_t
Definition: lldb-types.h:83
lldb_private::Target
Definition: Target.h:469
lldb_private::Target::GetImages
const ModuleList & GetImages() const
Get accessor for the images for this process.
Definition: Target.h:947
HexagonDYLDRendezvous::m_previous
Rendezvous m_previous
Definition: HexagonDYLDRendezvous.h:192
Process.h
HexagonDYLDRendezvous::ThreadInfo::valid
bool valid
Definition: HexagonDYLDRendezvous.h:51
HexagonDYLDRendezvous::SOEntry::path
std::string path
File name of shared object.
Definition: HexagonDYLDRendezvous.h:144
HexagonDYLDRendezvous::GetBreakAddress
lldb::addr_t GetBreakAddress() const
A breakpoint should be set at this address and Resolve called on each hit.
Definition: HexagonDYLDRendezvous.h:96
lldb_private::ModuleList::FindSymbolsWithNameAndType
void FindSymbolsWithNameAndType(ConstString name, lldb::SymbolType symbol_type, SymbolContextList &sc_list) const
Definition: ModuleList.cpp:509
HexagonDYLDRendezvous::m_process
lldb_private::Process * m_process
Definition: HexagonDYLDRendezvous.h:182
Target.h
lldb_private::Module::GetFileSpec
const FileSpec & GetFileSpec() const
Get const accessor for the module file specification.
Definition: Module.h:496
HexagonDYLDRendezvous::eAdd
@ eAdd
Definition: HexagonDYLDRendezvous.h:128
error
static llvm::raw_ostream & error(Stream &strm)
Definition: CommandReturnObject.cpp:17
lldb::eSymbolTypeAny
@ eSymbolTypeAny
Definition: lldb-enumerations.h:619
HexagonDYLDRendezvous::ThreadInfo::tls_offset
uint32_t tls_offset
Definition: HexagonDYLDRendezvous.h:55
Log.h
HexagonDYLDRendezvous::SOEntry::prev
lldb::addr_t prev
Address of previous so_entry.
Definition: HexagonDYLDRendezvous.h:143
HexagonDYLDRendezvous::IsValid
bool IsValid()
Definition: HexagonDYLDRendezvous.cpp:111
HexagonDYLDRendezvous::m_added_soentries
SOEntryList m_added_soentries
List of SOEntry's added to the link map since the last call to Resolve().
Definition: HexagonDYLDRendezvous.h:199
HexagonDYLDRendezvous::SOEntry::clear
void clear()
Definition: HexagonDYLDRendezvous.h:150
HexagonDYLDRendezvous::m_removed_soentries
SOEntryList m_removed_soentries
List of SOEntry's removed from the link map since the last call to Resolve().
Definition: HexagonDYLDRendezvous.h:203
HexagonDYLDRendezvous::m_current
Rendezvous m_current
Current and previous snapshots of the rendezvous structure.
Definition: HexagonDYLDRendezvous.h:191
HexagonDYLDRendezvous::Resolve
bool Resolve()
Update the internal snapshot of runtime linker rendezvous and recompute the currently loaded modules.
Definition: HexagonDYLDRendezvous.cpp:65
HexagonDYLDRendezvous::ReadStringFromMemory
std::string ReadStringFromMemory(lldb::addr_t addr)
Reads a null-terminated C string from the memory location starting at addr.
Definition: HexagonDYLDRendezvous.cpp:241
HexagonDYLDRendezvous::ThreadInfo
Definition: HexagonDYLDRendezvous.h:50
lldb_private::Process::GetAddressByteSize
uint32_t GetAddressByteSize() const
Definition: Process.cpp:3366
HexagonDYLDRendezvous::GetState
uint64_t GetState() const
Returns the current state of the rendezvous structure.
Definition: HexagonDYLDRendezvous.h:104
lldb_private::ConstString
Definition: ConstString.h:39
HexagonDYLDRendezvous::eDelete
@ eDelete
Definition: HexagonDYLDRendezvous.h:129
ResolveRendezvousAddress
static addr_t ResolveRendezvousAddress(Process *process)
Locates the address of the rendezvous structure.
Definition: HexagonDYLDRendezvous.cpp:28
HexagonDYLDRendezvous::ThreadInfo::dtv_slot_size
uint32_t dtv_slot_size
Definition: HexagonDYLDRendezvous.h:53
HexagonDYLDRendezvous::eSize
@ eSize
Definition: HexagonDYLDRendezvous.h:239
HexagonDYLDRendezvous::UpdateSOEntriesForAddition
bool UpdateSOEntriesForAddition()
Definition: HexagonDYLDRendezvous.cpp:152
HexagonDYLDRendezvous::ReadSOEntryFromMemory
bool ReadSOEntryFromMemory(lldb::addr_t addr, SOEntry &entry)
Reads an SOEntry starting at addr.
Definition: HexagonDYLDRendezvous.cpp:265
HexagonDYLDRendezvous::HexagonDYLDRendezvous
HexagonDYLDRendezvous(lldb_private::Process *process)
Definition: HexagonDYLDRendezvous.cpp:48
string
string(SUBSTRING ${p} 10 -1 pStripped) if($
Definition: Plugins/CMakeLists.txt:40
HexagonDYLDRendezvous::Rendezvous::brk
lldb::addr_t brk
Definition: HexagonDYLDRendezvous.h:40
HexagonDYLDRendezvous::GetThreadInfo
const ThreadInfo & GetThreadInfo()
Definition: HexagonDYLDRendezvous.cpp:318
HexagonDYLDRendezvous::ReadWord
lldb::addr_t ReadWord(lldb::addr_t addr, uint64_t *dst, size_t size)
Reads an unsigned integer of size bytes from the inferior's address space starting at addr.
Definition: HexagonDYLDRendezvous.cpp:220
ObjectFile.h
Symbol.h
HexagonDYLDRendezvous::Rendezvous::version
uint64_t version
Definition: HexagonDYLDRendezvous.h:38
HexagonDYLDRendezvous::SOEntry::link_addr
lldb::addr_t link_addr
Address of this link_map.
Definition: HexagonDYLDRendezvous.h:138
HexagonDYLDRendezvous::begin
iterator begin() const
Iterators over all currently loaded modules.
Definition: HexagonDYLDRendezvous.h:168
lldb_private::Status
Definition: Status.h:44
uint32_t
HexagonDYLDRendezvous::ReadPointer
lldb::addr_t ReadPointer(lldb::addr_t addr, lldb::addr_t *dst)
Reads an address from the inferior's address space starting at addr.
Definition: HexagonDYLDRendezvous.cpp:231
lldb_private::Address
Definition: Address.h:59
HexagonDYLDRendezvous::SOEntryList
std::list< SOEntry > SOEntryList
Definition: HexagonDYLDRendezvous.h:162
lldb_private::Address::GetLoadAddress
lldb::addr_t GetLoadAddress(Target *target) const
Get the load address.
Definition: Address.cpp:311
HexagonDYLDRendezvous::SOEntry::dyn_addr
lldb::addr_t dyn_addr
Dynamic section of shared object.
Definition: HexagonDYLDRendezvous.h:141
HexagonDYLDRendezvous::DumpToLog
void DumpToLog(lldb_private::Log *log) const
Definition: HexagonDYLDRendezvous.cpp:338
LLDB_INVALID_ADDRESS
#define LLDB_INVALID_ADDRESS
Definition: lldb-defines.h:74
HexagonDYLDRendezvous::SOEntry::next
lldb::addr_t next
Address of next so_entry.
Definition: HexagonDYLDRendezvous.h:142
HexagonDYLDRendezvous::eConsistent
@ eConsistent
Definition: HexagonDYLDRendezvous.h:127
HexagonDYLDRendezvous::SOEntry::base_addr
lldb::addr_t base_addr
Base address of the loaded object.
Definition: HexagonDYLDRendezvous.h:139
HexagonDYLDRendezvous::ThreadInfo::modid_offset
uint32_t modid_offset
Definition: HexagonDYLDRendezvous.h:54
HexagonDYLDRendezvous::m_soentries
SOEntryList m_soentries
List of SOEntry objects corresponding to the current link map state.
Definition: HexagonDYLDRendezvous.h:195
Status.h
SymbolContext.h
lldb_private::Process::GetImageInfoAddress
virtual lldb::addr_t GetImageInfoAddress()
Get the image information address for the current process.
Definition: Process.cpp:1481
lldb_private
A class that represents a running process on the host machine.
Definition: SBCommandInterpreterRunOptions.h:16
HexagonDYLDRendezvous::m_rendezvous_addr
lldb::addr_t m_rendezvous_addr
Location of the r_debug structure in the inferiors address space.
Definition: HexagonDYLDRendezvous.h:188
lldb_private::Process::ReadUnsignedIntegerFromMemory
uint64_t ReadUnsignedIntegerFromMemory(lldb::addr_t load_addr, size_t byte_size, uint64_t fail_value, Status &error)
Reads an unsigned integer of the specified byte size from process memory.
Definition: Process.cpp:2063
HexagonDYLDRendezvous::Rendezvous
Definition: HexagonDYLDRendezvous.h:37
lldb_private::Log
Definition: Log.h:115
lldb_private::Process::ReadPointerFromMemory
lldb::addr_t ReadPointerFromMemory(lldb::addr_t vm_addr, Status &error)
Definition: Process.cpp:2085
HexagonDYLDRendezvous::SetRendezvousAddress
void SetRendezvousAddress(lldb::addr_t)
Provide the dyld structure address.
Definition: HexagonDYLDRendezvous.cpp:107
HexagonDYLDRendezvous::FindMetadata
bool FindMetadata(const char *name, PThreadField field, uint32_t &value)
Definition: HexagonDYLDRendezvous.cpp:290
PATH_MAX
#define PATH_MAX
Definition: windows/PosixApi.h:25
HexagonDYLDRendezvous::m_exe_path
char m_exe_path[PATH_MAX]
Definition: HexagonDYLDRendezvous.h:185
HexagonDYLDRendezvous::UpdateSOEntriesForDeletion
bool UpdateSOEntriesForDeletion()
Definition: HexagonDYLDRendezvous.cpp:180
lldb_private::FileSpec::GetPath
size_t GetPath(char *path, size_t max_path_length, bool denormalize=true) const
Extract the full path to the file.
Definition: FileSpec.cpp:364
lldb
Definition: SBAddress.h:15
HexagonDYLDRendezvous::SOEntry::path_addr
lldb::addr_t path_addr
String naming the shared object.
Definition: HexagonDYLDRendezvous.h:140
HexagonDYLDRendezvous::m_thread_info
ThreadInfo m_thread_info
Threading metadata read from the inferior.
Definition: HexagonDYLDRendezvous.h:206
lldb_private::Log::PutCString
void PutCString(const char *cstr)
Definition: Log.cpp:134