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