1 //===-- LogChannelDWARF.cpp ------------------------------------*- C++ -*-===//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9
10 #include "LogChannelDWARF.h"
11
12 #include "lldb/Interpreter/Args.h"
13 #include "lldb/Core/PluginManager.h"
14 #include "lldb/Core/StreamFile.h"
15 #include "SymbolFileDWARF.h"
16
17 using namespace lldb;
18 using namespace lldb_private;
19
20
21 // when the one and only logging channel is abled, then this will be non NULL.
22 static LogChannelDWARF* g_log_channel = NULL;
23
LogChannelDWARF()24 LogChannelDWARF::LogChannelDWARF () :
25 LogChannel ()
26 {
27 }
28
~LogChannelDWARF()29 LogChannelDWARF::~LogChannelDWARF ()
30 {
31 }
32
33
34 void
Initialize()35 LogChannelDWARF::Initialize()
36 {
37 PluginManager::RegisterPlugin (GetPluginNameStatic(),
38 GetPluginDescriptionStatic(),
39 LogChannelDWARF::CreateInstance);
40 }
41
42 void
Terminate()43 LogChannelDWARF::Terminate()
44 {
45 PluginManager::UnregisterPlugin (LogChannelDWARF::CreateInstance);
46 }
47
48 LogChannel*
CreateInstance()49 LogChannelDWARF::CreateInstance ()
50 {
51 return new LogChannelDWARF ();
52 }
53
54 lldb_private::ConstString
GetPluginNameStatic()55 LogChannelDWARF::GetPluginNameStatic()
56 {
57 return SymbolFileDWARF::GetPluginNameStatic();
58 }
59
60 const char *
GetPluginDescriptionStatic()61 LogChannelDWARF::GetPluginDescriptionStatic()
62 {
63 return "DWARF log channel for debugging plug-in issues.";
64 }
65
66 lldb_private::ConstString
GetPluginName()67 LogChannelDWARF::GetPluginName()
68 {
69 return GetPluginNameStatic();
70 }
71
72 uint32_t
GetPluginVersion()73 LogChannelDWARF::GetPluginVersion()
74 {
75 return 1;
76 }
77
78
79 void
Delete()80 LogChannelDWARF::Delete ()
81 {
82 g_log_channel = NULL;
83 }
84
85
86 void
Disable(const char ** categories,Stream * feedback_strm)87 LogChannelDWARF::Disable (const char **categories, Stream *feedback_strm)
88 {
89 if (m_log_ap.get() == NULL)
90 return;
91
92 uint32_t flag_bits = m_log_ap->GetMask().Get();
93 for (size_t i = 0; categories[i] != NULL; ++i)
94 {
95 const char *arg = categories[i];
96
97 if (::strcasecmp (arg, "all") == 0) flag_bits &= ~DWARF_LOG_ALL;
98 else if (::strcasecmp (arg, "info") == 0) flag_bits &= ~DWARF_LOG_DEBUG_INFO;
99 else if (::strcasecmp (arg, "line") == 0) flag_bits &= ~DWARF_LOG_DEBUG_LINE;
100 else if (::strcasecmp (arg, "pubnames") == 0) flag_bits &= ~DWARF_LOG_DEBUG_PUBNAMES;
101 else if (::strcasecmp (arg, "pubtypes") == 0) flag_bits &= ~DWARF_LOG_DEBUG_PUBTYPES;
102 else if (::strcasecmp (arg, "aranges") == 0) flag_bits &= ~DWARF_LOG_DEBUG_ARANGES;
103 else if (::strcasecmp (arg, "lookups") == 0) flag_bits &= ~DWARF_LOG_LOOKUPS;
104 else if (::strcasecmp (arg, "map") == 0) flag_bits &= ~DWARF_LOG_DEBUG_MAP;
105 else if (::strcasecmp (arg, "default") == 0) flag_bits &= ~DWARF_LOG_DEFAULT;
106 else if (::strncasecmp(arg, "comp", 4) == 0) flag_bits &= ~DWARF_LOG_TYPE_COMPLETION;
107 else
108 {
109 feedback_strm->Printf("error: unrecognized log category '%s'\n", arg);
110 ListCategories (feedback_strm);
111 }
112 }
113
114 if (flag_bits == 0)
115 Delete ();
116 else
117 m_log_ap->GetMask().Reset (flag_bits);
118
119 return;
120 }
121
122 bool
Enable(StreamSP & log_stream_sp,uint32_t log_options,Stream * feedback_strm,const char ** categories)123 LogChannelDWARF::Enable
124 (
125 StreamSP &log_stream_sp,
126 uint32_t log_options,
127 Stream *feedback_strm, // Feedback stream for argument errors etc
128 const char **categories // The categories to enable within this logging stream, if empty, enable default set
129 )
130 {
131 Delete ();
132
133 if (m_log_ap)
134 m_log_ap->SetStream(log_stream_sp);
135 else
136 m_log_ap.reset(new Log (log_stream_sp));
137
138 g_log_channel = this;
139 uint32_t flag_bits = 0;
140 bool got_unknown_category = false;
141 for (size_t i = 0; categories[i] != NULL; ++i)
142 {
143 const char *arg = categories[i];
144
145 if (::strcasecmp (arg, "all") == 0) flag_bits |= DWARF_LOG_ALL;
146 else if (::strcasecmp (arg, "info") == 0) flag_bits |= DWARF_LOG_DEBUG_INFO;
147 else if (::strcasecmp (arg, "line") == 0) flag_bits |= DWARF_LOG_DEBUG_LINE;
148 else if (::strcasecmp (arg, "pubnames") == 0) flag_bits |= DWARF_LOG_DEBUG_PUBNAMES;
149 else if (::strcasecmp (arg, "pubtypes") == 0) flag_bits |= DWARF_LOG_DEBUG_PUBTYPES;
150 else if (::strcasecmp (arg, "aranges") == 0) flag_bits |= DWARF_LOG_DEBUG_ARANGES;
151 else if (::strcasecmp (arg, "lookups") == 0) flag_bits |= DWARF_LOG_LOOKUPS;
152 else if (::strcasecmp (arg, "map") == 0) flag_bits |= DWARF_LOG_DEBUG_MAP;
153 else if (::strcasecmp (arg, "default") == 0) flag_bits |= DWARF_LOG_DEFAULT;
154 else if (::strncasecmp(arg, "comp", 4) == 0) flag_bits |= DWARF_LOG_TYPE_COMPLETION;
155 else
156 {
157 feedback_strm->Printf("error: unrecognized log category '%s'\n", arg);
158 if (got_unknown_category == false)
159 {
160 got_unknown_category = true;
161 ListCategories (feedback_strm);
162 }
163 }
164 }
165 if (flag_bits == 0)
166 flag_bits = DWARF_LOG_DEFAULT;
167 m_log_ap->GetMask().Reset(flag_bits);
168 m_log_ap->GetOptions().Reset(log_options);
169 return m_log_ap.get() != NULL;
170 }
171
172 void
ListCategories(Stream * strm)173 LogChannelDWARF::ListCategories (Stream *strm)
174 {
175 strm->Printf ("Logging categories for '%s':\n"
176 " all - turn on all available logging categories\n"
177 " info - log the parsing if .debug_info\n"
178 " line - log the parsing if .debug_line\n"
179 " pubnames - log the parsing if .debug_pubnames\n"
180 " pubtypes - log the parsing if .debug_pubtypes\n"
181 " lookups - log any lookups that happen by name, regex, or address\n"
182 " completion - log struct/unions/class type completions\n"
183 " map - log insertions of object files into DWARF debug maps\n",
184 SymbolFileDWARF::GetPluginNameStatic().GetCString());
185 }
186
187 Log *
GetLog()188 LogChannelDWARF::GetLog ()
189 {
190 if (g_log_channel)
191 return g_log_channel->m_log_ap.get();
192
193 return NULL;
194 }
195
196 Log *
GetLogIfAll(uint32_t mask)197 LogChannelDWARF::GetLogIfAll (uint32_t mask)
198 {
199 if (g_log_channel && g_log_channel->m_log_ap.get())
200 {
201 if (g_log_channel->m_log_ap->GetMask().AllSet(mask))
202 return g_log_channel->m_log_ap.get();
203 }
204 return NULL;
205 }
206
207 Log *
GetLogIfAny(uint32_t mask)208 LogChannelDWARF::GetLogIfAny (uint32_t mask)
209 {
210 if (g_log_channel && g_log_channel->m_log_ap.get())
211 {
212 if (g_log_channel->m_log_ap->GetMask().AnySet(mask))
213 return g_log_channel->m_log_ap.get();
214 }
215 return NULL;
216 }
217
218 void
LogIf(uint32_t mask,const char * format,...)219 LogChannelDWARF::LogIf (uint32_t mask, const char *format, ...)
220 {
221 if (g_log_channel)
222 {
223 Log *log = g_log_channel->m_log_ap.get();
224 if (log && log->GetMask().AnySet(mask))
225 {
226 va_list args;
227 va_start (args, format);
228 log->VAPrintf (format, args);
229 va_end (args);
230 }
231 }
232 }
233