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