| //===-- LogChannelDWARF.cpp ------------------------------------*- C++ -*-===// |
| // |
| // The LLVM Compiler Infrastructure |
| // |
| // This file is distributed under the University of Illinois Open Source |
| // License. See LICENSE.TXT for details. |
| // |
| //===----------------------------------------------------------------------===// |
| |
| #include "LogChannelDWARF.h" |
| |
| #include "lldb/Interpreter/Args.h" |
| #include "lldb/Core/PluginManager.h" |
| #include "lldb/Core/StreamFile.h" |
| #include "SymbolFileDWARF.h" |
| |
| using namespace lldb; |
| using namespace lldb_private; |
| |
| |
| // when the one and only logging channel is abled, then this will be non NULL. |
| static LogChannelDWARF* g_log_channel = NULL; |
| |
| LogChannelDWARF::LogChannelDWARF () : |
| LogChannel () |
| { |
| } |
| |
| LogChannelDWARF::~LogChannelDWARF () |
| { |
| } |
| |
| |
| void |
| LogChannelDWARF::Initialize() |
| { |
| PluginManager::RegisterPlugin (GetPluginNameStatic(), |
| GetPluginDescriptionStatic(), |
| LogChannelDWARF::CreateInstance); |
| } |
| |
| void |
| LogChannelDWARF::Terminate() |
| { |
| PluginManager::UnregisterPlugin (LogChannelDWARF::CreateInstance); |
| } |
| |
| LogChannel* |
| LogChannelDWARF::CreateInstance () |
| { |
| return new LogChannelDWARF (); |
| } |
| |
| const char * |
| LogChannelDWARF::GetPluginNameStatic() |
| { |
| return SymbolFileDWARF::GetPluginNameStatic(); |
| } |
| |
| const char * |
| LogChannelDWARF::GetPluginDescriptionStatic() |
| { |
| return "DWARF log channel for debugging plug-in issues."; |
| } |
| |
| const char * |
| LogChannelDWARF::GetPluginName() |
| { |
| return GetPluginDescriptionStatic(); |
| } |
| |
| const char * |
| LogChannelDWARF::GetShortPluginName() |
| { |
| return GetPluginNameStatic(); |
| } |
| |
| uint32_t |
| LogChannelDWARF::GetPluginVersion() |
| { |
| return 1; |
| } |
| |
| |
| void |
| LogChannelDWARF::Delete () |
| { |
| g_log_channel = NULL; |
| m_log_sp.reset(); |
| } |
| |
| |
| void |
| LogChannelDWARF::Disable (const char **categories, Stream *feedback_strm) |
| { |
| if (!m_log_sp) |
| return; |
| |
| g_log_channel = this; |
| uint32_t flag_bits = m_log_sp->GetMask().Get(); |
| for (size_t i = 0; categories[i] != NULL; ++i) |
| { |
| const char *arg = categories[i]; |
| |
| if (::strcasecmp (arg, "all") == 0) flag_bits &= ~DWARF_LOG_ALL; |
| else if (::strcasecmp (arg, "info") == 0) flag_bits &= ~DWARF_LOG_DEBUG_INFO; |
| else if (::strcasecmp (arg, "line") == 0) flag_bits &= ~DWARF_LOG_DEBUG_LINE; |
| else if (::strcasecmp (arg, "pubnames") == 0) flag_bits &= ~DWARF_LOG_DEBUG_PUBNAMES; |
| else if (::strcasecmp (arg, "pubtypes") == 0) flag_bits &= ~DWARF_LOG_DEBUG_PUBTYPES; |
| else if (::strcasecmp (arg, "aranges") == 0) flag_bits &= ~DWARF_LOG_DEBUG_ARANGES; |
| else if (::strcasecmp (arg, "lookups") == 0) flag_bits &= ~DWARF_LOG_LOOKUPS; |
| else if (::strcasecmp (arg, "map") == 0) flag_bits &= ~DWARF_LOG_DEBUG_MAP; |
| else if (::strcasecmp (arg, "default") == 0) flag_bits &= ~DWARF_LOG_DEFAULT; |
| else if (::strncasecmp(arg, "comp", 4) == 0) flag_bits &= ~DWARF_LOG_TYPE_COMPLETION; |
| else |
| { |
| feedback_strm->Printf("error: unrecognized log category '%s'\n", arg); |
| ListCategories (feedback_strm); |
| } |
| } |
| |
| if (flag_bits == 0) |
| Delete (); |
| else |
| m_log_sp->GetMask().Reset (flag_bits); |
| |
| return; |
| } |
| |
| bool |
| LogChannelDWARF::Enable |
| ( |
| StreamSP &log_stream_sp, |
| uint32_t log_options, |
| Stream *feedback_strm, // Feedback stream for argument errors etc |
| const char **categories // The categories to enable within this logging stream, if empty, enable default set |
| ) |
| { |
| Delete (); |
| |
| m_log_sp.reset(new Log (log_stream_sp)); |
| g_log_channel = this; |
| uint32_t flag_bits = 0; |
| bool got_unknown_category = false; |
| for (size_t i = 0; categories[i] != NULL; ++i) |
| { |
| const char *arg = categories[i]; |
| |
| if (::strcasecmp (arg, "all") == 0) flag_bits |= DWARF_LOG_ALL; |
| else if (::strcasecmp (arg, "info") == 0) flag_bits |= DWARF_LOG_DEBUG_INFO; |
| else if (::strcasecmp (arg, "line") == 0) flag_bits |= DWARF_LOG_DEBUG_LINE; |
| else if (::strcasecmp (arg, "pubnames") == 0) flag_bits |= DWARF_LOG_DEBUG_PUBNAMES; |
| else if (::strcasecmp (arg, "pubtypes") == 0) flag_bits |= DWARF_LOG_DEBUG_PUBTYPES; |
| else if (::strcasecmp (arg, "aranges") == 0) flag_bits |= DWARF_LOG_DEBUG_ARANGES; |
| else if (::strcasecmp (arg, "lookups") == 0) flag_bits |= DWARF_LOG_LOOKUPS; |
| else if (::strcasecmp (arg, "map") == 0) flag_bits |= DWARF_LOG_DEBUG_MAP; |
| else if (::strcasecmp (arg, "default") == 0) flag_bits |= DWARF_LOG_DEFAULT; |
| else if (::strncasecmp(arg, "comp", 4) == 0) flag_bits |= DWARF_LOG_TYPE_COMPLETION; |
| else |
| { |
| feedback_strm->Printf("error: unrecognized log category '%s'\n", arg); |
| if (got_unknown_category == false) |
| { |
| got_unknown_category = true; |
| ListCategories (feedback_strm); |
| } |
| } |
| } |
| if (flag_bits == 0) |
| flag_bits = DWARF_LOG_DEFAULT; |
| m_log_sp->GetMask().Reset(flag_bits); |
| m_log_sp->GetOptions().Reset(log_options); |
| return m_log_sp.get() != NULL; |
| } |
| |
| void |
| LogChannelDWARF::ListCategories (Stream *strm) |
| { |
| strm->Printf ("Logging categories for '%s':\n" |
| " all - turn on all available logging categories\n" |
| " info - log the parsing if .debug_info\n" |
| " line - log the parsing if .debug_line\n" |
| " pubnames - log the parsing if .debug_pubnames\n" |
| " pubtypes - log the parsing if .debug_pubtypes\n" |
| " lookups - log any lookups that happen by name, regex, or address\n\n" |
| " completion - log struct/unions/class type completions\n\n" |
| " map - log insertions of object files into DWARF debug maps\n\n", |
| SymbolFileDWARF::GetPluginNameStatic()); |
| } |
| |
| LogSP |
| LogChannelDWARF::GetLog () |
| { |
| if (g_log_channel) |
| return g_log_channel->m_log_sp; |
| |
| return LogSP(); |
| } |
| |
| LogSP |
| LogChannelDWARF::GetLogIfAll (uint32_t mask) |
| { |
| if (g_log_channel && g_log_channel->m_log_sp) |
| { |
| if (g_log_channel->m_log_sp->GetMask().AllSet(mask)) |
| return g_log_channel->m_log_sp; |
| } |
| return LogSP(); |
| } |
| |
| LogSP |
| LogChannelDWARF::GetLogIfAny (uint32_t mask) |
| { |
| if (g_log_channel && g_log_channel->m_log_sp) |
| { |
| if (g_log_channel->m_log_sp->GetMask().AnySet(mask)) |
| return g_log_channel->m_log_sp; |
| } |
| return LogSP(); |
| } |
| |
| void |
| LogChannelDWARF::LogIf (uint32_t mask, const char *format, ...) |
| { |
| if (g_log_channel) |
| { |
| LogSP log_sp(g_log_channel->m_log_sp); |
| va_list args; |
| va_start (args, format); |
| log_sp->VAPrintf (format, args); |
| va_end (args); |
| } |
| } |