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