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/Core/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 
24 LogChannelDWARF::LogChannelDWARF () :
25     LogChannel ()
26 {
27 }
28 
29 LogChannelDWARF::~LogChannelDWARF ()
30 {
31 }
32 
33 
34 void
35 LogChannelDWARF::Initialize()
36 {
37     PluginManager::RegisterPlugin (GetPluginNameStatic(),
38                                    GetPluginDescriptionStatic(),
39                                    LogChannelDWARF::CreateInstance);
40 }
41 
42 void
43 LogChannelDWARF::Terminate()
44 {
45     PluginManager::UnregisterPlugin (LogChannelDWARF::CreateInstance);
46 }
47 
48 LogChannel*
49 LogChannelDWARF::CreateInstance ()
50 {
51     return new LogChannelDWARF ();
52 }
53 
54 const char *
55 LogChannelDWARF::GetPluginNameStatic()
56 {
57     static std::string g_plugin_name;
58     if (g_plugin_name.empty())
59     {
60         g_plugin_name = SymbolFileDWARF::GetPluginNameStatic();
61         g_plugin_name += LogChannel::GetPluginSuffix ();
62     }
63     return g_plugin_name.c_str();
64 }
65 
66 
67 const char *
68 LogChannelDWARF::GetPluginDescriptionStatic()
69 {
70     return "DWARF log channel for debugging plug-in issues.";
71 }
72 
73 const char *
74 LogChannelDWARF::GetPluginName()
75 {
76     return GetPluginDescriptionStatic();
77 }
78 
79 const char *
80 LogChannelDWARF::GetShortPluginName()
81 {
82     return GetPluginNameStatic();
83 }
84 
85 uint32_t
86 LogChannelDWARF::GetPluginVersion()
87 {
88     return 1;
89 }
90 
91 
92 void
93 LogChannelDWARF::GetPluginCommandHelp (const char *command, Stream *strm)
94 {
95 }
96 
97 
98 Error
99 LogChannelDWARF::ExecutePluginCommand (Args &command, Stream *strm)
100 {
101     Error error;
102     error.SetErrorStringWithFormat("No commands are supported.\n");
103     return error;
104 }
105 
106 
107 Log *
108 LogChannelDWARF::EnablePluginLogging (Stream *strm, Args &command)
109 {
110     return NULL;
111 }
112 
113 
114 void
115 LogChannelDWARF::Disable ()
116 {
117     g_log_channel = NULL;
118     m_log_sp.reset();
119 }
120 
121 bool
122 LogChannelDWARF::Enable
123 (
124     StreamSP &log_stream_sp,
125     uint32_t log_options,
126     Stream *feedback_strm,  // Feedback stream for argument errors etc
127     const Args &categories  // The categories to enable within this logging stream, if empty, enable default set
128 )
129 {
130     Disable ();
131 
132     m_log_sp.reset(new Log (log_stream_sp));
133     g_log_channel = this;
134     uint32_t flag_bits = 0;
135     bool got_unknown_category = false;
136     const size_t argc = categories.GetArgumentCount();
137     for (size_t i=0; i<argc; ++i)
138     {
139         const char *arg = categories.GetArgumentAtIndex(i);
140 
141         if      (::strcasecmp (arg, "all")        == 0   ) flag_bits |= DWARF_LOG_ALL;
142         else if (::strcasecmp (arg, "info")       == 0   ) flag_bits |= DWARF_LOG_DEBUG_INFO;
143         else if (::strcasecmp (arg, "line")       == 0   ) flag_bits |= DWARF_LOG_DEBUG_LINE;
144         else if (::strcasecmp (arg, "pubnames")   == 0   ) flag_bits |= DWARF_LOG_DEBUG_PUBNAMES;
145         else if (::strcasecmp (arg, "pubtypes")   == 0   ) flag_bits |= DWARF_LOG_DEBUG_PUBTYPES;
146         else if (::strcasecmp (arg, "default")    == 0   ) flag_bits |= DWARF_LOG_DEFAULT;
147         else
148         {
149             feedback_strm->Printf("error: unrecognized log category '%s'\n", arg);
150             if (got_unknown_category == false)
151             {
152                 got_unknown_category = true;
153                 ListCategories (feedback_strm);
154             }
155         }
156     }
157     if (flag_bits == 0)
158         flag_bits = DWARF_LOG_DEFAULT;
159     m_log_sp->GetMask().SetAllFlagBits(flag_bits);
160     m_log_sp->GetOptions().SetAllFlagBits(log_options);
161     return m_log_sp.get() != NULL;
162 }
163 
164 void
165 LogChannelDWARF::ListCategories (Stream *strm)
166 {
167     strm->Printf("Logging categories for '%s':\n"
168         "   all - turn on all available logging categories\n"
169         "   info - log the parsing if .debug_info\n"
170         "   line - log the parsing if .debug_line\n"
171         "   pubnames - log the parsing if .debug_pubnames\n"
172         "   pubtypes - log the parsing if .debug_pubtypes\n\n",
173         SymbolFileDWARF::GetPluginNameStatic());
174 }
175 
176 Log *
177 LogChannelDWARF::GetLog ()
178 {
179     if (g_log_channel)
180         return g_log_channel->m_log_sp.get();
181     else
182         return NULL;
183 }
184 
185 Log *
186 LogChannelDWARF::GetLogIfAll (uint32_t mask)
187 {
188     Log *log = GetLog();
189     if (log)
190         if (log->GetMask().IsSet(mask))
191             return log;
192     return NULL;
193 }
194 
195 
196 void
197 LogChannelDWARF::LogIf (uint32_t mask, const char *format, ...)
198 {
199     if (g_log_channel)
200     {
201         LogSP log_sp(g_log_channel->m_log_sp);
202         va_list args;
203         va_start (args, format);
204         log_sp->VAPrintf (format, args);
205         va_end (args);
206     }
207 }
208