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 (::strncasecmp(arg, "comp", 4) == 0) 82 flag_bits &= ~DWARF_LOG_TYPE_COMPLETION; 83 else { 84 feedback_strm->Printf("error: unrecognized log category '%s'\n", arg); 85 ListCategories(feedback_strm); 86 } 87 } 88 89 if (flag_bits == 0) 90 Delete(); 91 else 92 m_log_ap->GetMask().Reset(flag_bits); 93 94 return; 95 } 96 97 bool LogChannelDWARF::Enable( 98 const std::shared_ptr<llvm::raw_ostream> &log_stream_sp, 99 uint32_t log_options, 100 Stream *feedback_strm, // Feedback stream for argument errors etc 101 const char **categories // The categories to enable within this logging 102 // stream, if empty, enable default set 103 ) { 104 Delete(); 105 106 if (m_log_ap) 107 m_log_ap->SetStream(log_stream_sp); 108 else 109 m_log_ap.reset(new Log(log_stream_sp)); 110 111 g_log_channel = this; 112 uint32_t flag_bits = 0; 113 bool got_unknown_category = false; 114 for (size_t i = 0; categories[i] != NULL; ++i) { 115 const char *arg = categories[i]; 116 117 if (::strcasecmp(arg, "all") == 0) 118 flag_bits |= DWARF_LOG_ALL; 119 else if (::strcasecmp(arg, "info") == 0) 120 flag_bits |= DWARF_LOG_DEBUG_INFO; 121 else if (::strcasecmp(arg, "line") == 0) 122 flag_bits |= DWARF_LOG_DEBUG_LINE; 123 else if (::strcasecmp(arg, "pubnames") == 0) 124 flag_bits |= DWARF_LOG_DEBUG_PUBNAMES; 125 else if (::strcasecmp(arg, "pubtypes") == 0) 126 flag_bits |= DWARF_LOG_DEBUG_PUBTYPES; 127 else if (::strcasecmp(arg, "aranges") == 0) 128 flag_bits |= DWARF_LOG_DEBUG_ARANGES; 129 else if (::strcasecmp(arg, "lookups") == 0) 130 flag_bits |= DWARF_LOG_LOOKUPS; 131 else if (::strcasecmp(arg, "map") == 0) 132 flag_bits |= DWARF_LOG_DEBUG_MAP; 133 else if (::strcasecmp(arg, "default") == 0) 134 flag_bits |= DWARF_LOG_DEFAULT; 135 else if (::strncasecmp(arg, "comp", 4) == 0) 136 flag_bits |= DWARF_LOG_TYPE_COMPLETION; 137 else { 138 feedback_strm->Printf("error: unrecognized log category '%s'\n", arg); 139 if (got_unknown_category == false) { 140 got_unknown_category = true; 141 ListCategories(feedback_strm); 142 } 143 } 144 } 145 if (flag_bits == 0) 146 flag_bits = DWARF_LOG_DEFAULT; 147 m_log_ap->GetMask().Reset(flag_bits); 148 m_log_ap->GetOptions().Reset(log_options); 149 return m_log_ap.get() != NULL; 150 } 151 152 void LogChannelDWARF::ListCategories(Stream *strm) { 153 strm->Printf( 154 "Logging categories for '%s':\n" 155 " all - turn on all available logging categories\n" 156 " info - log the parsing of .debug_info\n" 157 " line - log the parsing of .debug_line\n" 158 " pubnames - log the parsing of .debug_pubnames\n" 159 " pubtypes - log the parsing of .debug_pubtypes\n" 160 " aranges - log the parsing of .debug_aranges\n" 161 " lookups - log any lookups that happen by name, regex, or address\n" 162 " completion - log struct/unions/class type completions\n" 163 " map - log insertions of object files into DWARF debug maps\n", 164 SymbolFileDWARF::GetPluginNameStatic().GetCString()); 165 } 166 167 Log *LogChannelDWARF::GetLog() { 168 if (g_log_channel) 169 return g_log_channel->m_log_ap.get(); 170 171 return NULL; 172 } 173 174 Log *LogChannelDWARF::GetLogIfAll(uint32_t mask) { 175 if (g_log_channel && g_log_channel->m_log_ap.get()) { 176 if (g_log_channel->m_log_ap->GetMask().AllSet(mask)) 177 return g_log_channel->m_log_ap.get(); 178 } 179 return NULL; 180 } 181 182 Log *LogChannelDWARF::GetLogIfAny(uint32_t mask) { 183 if (g_log_channel && g_log_channel->m_log_ap.get()) { 184 if (g_log_channel->m_log_ap->GetMask().AnySet(mask)) 185 return g_log_channel->m_log_ap.get(); 186 } 187 return NULL; 188 } 189 190 void LogChannelDWARF::LogIf(uint32_t mask, const char *format, ...) { 191 if (g_log_channel) { 192 Log *log = g_log_channel->m_log_ap.get(); 193 if (log && log->GetMask().AnySet(mask)) { 194 va_list args; 195 va_start(args, format); 196 log->VAPrintf(format, args); 197 va_end(args); 198 } 199 } 200 } 201