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 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 return SymbolFileDWARF::GetPluginNameStatic(); 58 } 59 60 const char * 61 LogChannelDWARF::GetPluginDescriptionStatic() 62 { 63 return "DWARF log channel for debugging plug-in issues."; 64 } 65 66 const char * 67 LogChannelDWARF::GetPluginName() 68 { 69 return GetPluginDescriptionStatic(); 70 } 71 72 const char * 73 LogChannelDWARF::GetShortPluginName() 74 { 75 return GetPluginNameStatic(); 76 } 77 78 uint32_t 79 LogChannelDWARF::GetPluginVersion() 80 { 81 return 1; 82 } 83 84 85 void 86 LogChannelDWARF::Delete () 87 { 88 g_log_channel = NULL; 89 } 90 91 92 void 93 LogChannelDWARF::Disable (const char **categories, Stream *feedback_strm) 94 { 95 if (m_log_ap.get() == NULL) 96 return; 97 98 uint32_t flag_bits = m_log_ap->GetMask().Get(); 99 for (size_t i = 0; categories[i] != NULL; ++i) 100 { 101 const char *arg = categories[i]; 102 103 if (::strcasecmp (arg, "all") == 0) flag_bits &= ~DWARF_LOG_ALL; 104 else if (::strcasecmp (arg, "info") == 0) flag_bits &= ~DWARF_LOG_DEBUG_INFO; 105 else if (::strcasecmp (arg, "line") == 0) flag_bits &= ~DWARF_LOG_DEBUG_LINE; 106 else if (::strcasecmp (arg, "pubnames") == 0) flag_bits &= ~DWARF_LOG_DEBUG_PUBNAMES; 107 else if (::strcasecmp (arg, "pubtypes") == 0) flag_bits &= ~DWARF_LOG_DEBUG_PUBTYPES; 108 else if (::strcasecmp (arg, "aranges") == 0) flag_bits &= ~DWARF_LOG_DEBUG_ARANGES; 109 else if (::strcasecmp (arg, "lookups") == 0) flag_bits &= ~DWARF_LOG_LOOKUPS; 110 else if (::strcasecmp (arg, "map") == 0) flag_bits &= ~DWARF_LOG_DEBUG_MAP; 111 else if (::strcasecmp (arg, "default") == 0) flag_bits &= ~DWARF_LOG_DEFAULT; 112 else if (::strncasecmp(arg, "comp", 4) == 0) flag_bits &= ~DWARF_LOG_TYPE_COMPLETION; 113 else 114 { 115 feedback_strm->Printf("error: unrecognized log category '%s'\n", arg); 116 ListCategories (feedback_strm); 117 } 118 } 119 120 if (flag_bits == 0) 121 Delete (); 122 else 123 m_log_ap->GetMask().Reset (flag_bits); 124 125 return; 126 } 127 128 bool 129 LogChannelDWARF::Enable 130 ( 131 StreamSP &log_stream_sp, 132 uint32_t log_options, 133 Stream *feedback_strm, // Feedback stream for argument errors etc 134 const char **categories // The categories to enable within this logging stream, if empty, enable default set 135 ) 136 { 137 Delete (); 138 139 if (m_log_ap) 140 m_log_ap->SetStream(log_stream_sp); 141 else 142 m_log_ap.reset(new Log (log_stream_sp)); 143 144 g_log_channel = this; 145 uint32_t flag_bits = 0; 146 bool got_unknown_category = false; 147 for (size_t i = 0; categories[i] != NULL; ++i) 148 { 149 const char *arg = categories[i]; 150 151 if (::strcasecmp (arg, "all") == 0) flag_bits |= DWARF_LOG_ALL; 152 else if (::strcasecmp (arg, "info") == 0) flag_bits |= DWARF_LOG_DEBUG_INFO; 153 else if (::strcasecmp (arg, "line") == 0) flag_bits |= DWARF_LOG_DEBUG_LINE; 154 else if (::strcasecmp (arg, "pubnames") == 0) flag_bits |= DWARF_LOG_DEBUG_PUBNAMES; 155 else if (::strcasecmp (arg, "pubtypes") == 0) flag_bits |= DWARF_LOG_DEBUG_PUBTYPES; 156 else if (::strcasecmp (arg, "aranges") == 0) flag_bits |= DWARF_LOG_DEBUG_ARANGES; 157 else if (::strcasecmp (arg, "lookups") == 0) flag_bits |= DWARF_LOG_LOOKUPS; 158 else if (::strcasecmp (arg, "map") == 0) flag_bits |= DWARF_LOG_DEBUG_MAP; 159 else if (::strcasecmp (arg, "default") == 0) flag_bits |= DWARF_LOG_DEFAULT; 160 else if (::strncasecmp(arg, "comp", 4) == 0) flag_bits |= DWARF_LOG_TYPE_COMPLETION; 161 else 162 { 163 feedback_strm->Printf("error: unrecognized log category '%s'\n", arg); 164 if (got_unknown_category == false) 165 { 166 got_unknown_category = true; 167 ListCategories (feedback_strm); 168 } 169 } 170 } 171 if (flag_bits == 0) 172 flag_bits = DWARF_LOG_DEFAULT; 173 m_log_ap->GetMask().Reset(flag_bits); 174 m_log_ap->GetOptions().Reset(log_options); 175 return m_log_ap.get() != NULL; 176 } 177 178 void 179 LogChannelDWARF::ListCategories (Stream *strm) 180 { 181 strm->Printf ("Logging categories for '%s':\n" 182 " all - turn on all available logging categories\n" 183 " info - log the parsing if .debug_info\n" 184 " line - log the parsing if .debug_line\n" 185 " pubnames - log the parsing if .debug_pubnames\n" 186 " pubtypes - log the parsing if .debug_pubtypes\n" 187 " lookups - log any lookups that happen by name, regex, or address\n" 188 " completion - log struct/unions/class type completions\n" 189 " map - log insertions of object files into DWARF debug maps\n", 190 SymbolFileDWARF::GetPluginNameStatic()); 191 } 192 193 Log * 194 LogChannelDWARF::GetLog () 195 { 196 if (g_log_channel) 197 return g_log_channel->m_log_ap.get(); 198 199 return NULL; 200 } 201 202 Log * 203 LogChannelDWARF::GetLogIfAll (uint32_t mask) 204 { 205 if (g_log_channel && g_log_channel->m_log_ap.get()) 206 { 207 if (g_log_channel->m_log_ap->GetMask().AllSet(mask)) 208 return g_log_channel->m_log_ap.get(); 209 } 210 return NULL; 211 } 212 213 Log * 214 LogChannelDWARF::GetLogIfAny (uint32_t mask) 215 { 216 if (g_log_channel && g_log_channel->m_log_ap.get()) 217 { 218 if (g_log_channel->m_log_ap->GetMask().AnySet(mask)) 219 return g_log_channel->m_log_ap.get(); 220 } 221 return NULL; 222 } 223 224 void 225 LogChannelDWARF::LogIf (uint32_t mask, const char *format, ...) 226 { 227 if (g_log_channel) 228 { 229 Log *log = g_log_channel->m_log_ap.get(); 230 if (log && log->GetMask().AnySet(mask)) 231 { 232 va_list args; 233 va_start (args, format); 234 log->VAPrintf (format, args); 235 va_end (args); 236 } 237 } 238 } 239