Beispiel #1
0
void Options::OutputFormattedUsageText(Stream &strm,
                                       const OptionDefinition &option_def,
                                       uint32_t output_max_columns) {
  std::string actual_text;
  if (option_def.validator) {
    const char *condition = option_def.validator->ShortConditionString();
    if (condition) {
      actual_text = "[";
      actual_text.append(condition);
      actual_text.append("] ");
    }
  }
  actual_text.append(option_def.usage_text);

  // Will it all fit on one line?

  if (static_cast<uint32_t>(actual_text.length() + strm.GetIndentLevel()) <
      output_max_columns) {
    // Output it as a single line.
    strm.Indent(actual_text.c_str());
    strm.EOL();
  } else {
    // We need to break it up into multiple lines.

    int text_width = output_max_columns - strm.GetIndentLevel() - 1;
    int start = 0;
    int end = start;
    int final_end = actual_text.length();
    int sub_len;

    while (end < final_end) {
      // Don't start the 'text' on a space, since we're already outputting the
      // indentation.
      while ((start < final_end) && (actual_text[start] == ' '))
        start++;

      end = start + text_width;
      if (end > final_end)
        end = final_end;
      else {
        // If we're not at the end of the text, make sure we break the line on
        // white space.
        while (end > start && actual_text[end] != ' ' &&
               actual_text[end] != '\t' && actual_text[end] != '\n')
          end--;
      }

      sub_len = end - start;
      if (start != 0)
        strm.EOL();
      strm.Indent();
      assert(start < final_end);
      assert(start + sub_len <= final_end);
      strm.Write(actual_text.c_str() + start, sub_len);
      start = end + 1;
    }
    strm.EOL();
  }
}
Beispiel #2
0
void
Options::OutputFormattedUsageText
(
    Stream &strm,
    const char *text,
    uint32_t output_max_columns
)
{
    int len = strlen (text);

    // Will it all fit on one line?

    if (static_cast<uint32_t>(len + strm.GetIndentLevel()) < output_max_columns)
    {
        // Output it as a single line.
        strm.Indent (text);
        strm.EOL();
    }
    else
    {
        // We need to break it up into multiple lines.

        int text_width = output_max_columns - strm.GetIndentLevel() - 1;
        int start = 0;
        int end = start;
        int final_end = strlen (text);
        int sub_len;

        while (end < final_end)
        {
            // Don't start the 'text' on a space, since we're already outputting the indentation.
            while ((start < final_end) && (text[start] == ' '))
                start++;

            end = start + text_width;
            if (end > final_end)
                end = final_end;
            else
            {
                // If we're not at the end of the text, make sure we break the line on white space.
                while (end > start
                       && text[end] != ' ' && text[end] != '\t' && text[end] != '\n')
                    end--;
            }

            sub_len = end - start;
            if (start != 0)
                strm.EOL();
            strm.Indent();
            assert (start < final_end);
            assert (start + sub_len <= final_end);
            strm.Write(text + start, sub_len);
            start = end + 1;
        }
        strm.EOL();
    }
}
Beispiel #3
0
  bool DumpRegister(const ExecutionContext &exe_ctx, Stream &strm,
                    RegisterContext *reg_ctx, const RegisterInfo *reg_info) {
    if (reg_info) {
      RegisterValue reg_value;

      if (reg_ctx->ReadRegister(reg_info, reg_value)) {
        strm.Indent();

        bool prefix_with_altname = (bool)m_command_options.alternate_name;
        bool prefix_with_name = !prefix_with_altname;
        reg_value.Dump(&strm, reg_info, prefix_with_name, prefix_with_altname,
                       m_format_options.GetFormat(), 8);
        if ((reg_info->encoding == eEncodingUint) ||
            (reg_info->encoding == eEncodingSint)) {
          Process *process = exe_ctx.GetProcessPtr();
          if (process && reg_info->byte_size == process->GetAddressByteSize()) {
            addr_t reg_addr = reg_value.GetAsUInt64(LLDB_INVALID_ADDRESS);
            if (reg_addr != LLDB_INVALID_ADDRESS) {
              Address so_reg_addr;
              if (exe_ctx.GetTargetRef()
                      .GetSectionLoadList()
                      .ResolveLoadAddress(reg_addr, so_reg_addr)) {
                strm.PutCString("  ");
                so_reg_addr.Dump(&strm, exe_ctx.GetBestExecutionContextScope(),
                                 Address::DumpStyleResolvedDescription);
              }
            }
          }
        }
        strm.EOL();
        return true;
      }
    }
    return false;
  }
Beispiel #4
0
void
Property::Dump (const ExecutionContext *exe_ctx, Stream &strm, uint32_t dump_mask) const
{
    if (m_value_sp)
    {
        const bool dump_desc = dump_mask & OptionValue::eDumpOptionDescription;
        const bool transparent = m_value_sp->ValueIsTransparent ();
        if (dump_desc || !transparent)
        {
            if ((dump_mask & OptionValue::eDumpOptionName) && m_name)
            {
                DumpQualifiedName(strm);
                if (dump_mask & ~OptionValue::eDumpOptionName)
                    strm.PutChar(' ');
            }
        }
        if (dump_desc)
        {
            const char *desc = GetDescription();
            if (desc)
                strm.Printf ("-- %s", desc);
            
            if (transparent && (dump_mask == (OptionValue::eDumpOptionName | OptionValue::eDumpOptionDescription)))
                strm.EOL();
        }
        m_value_sp->DumpValue(exe_ctx, strm, dump_mask);
    }
}
void StructuredData::Array::Dump(Stream &s, bool pretty_print) const {
  bool first = true;
  s << "[";
  if (pretty_print) {
    s << "\n";
    s.IndentMore();
  }
  for (const auto &item_sp : m_items) {
    if (first) {
      first = false;
    } else {
      s << ",";
      if (pretty_print)
        s << "\n";
    }

    if (pretty_print)
      s.Indent();
    item_sp->Dump(s, pretty_print);
  }
  if (pretty_print) {
    s.IndentLess();
    s.EOL();
    s.Indent();
  }
  s << "]";
}
void StructuredData::Dictionary::Dump(Stream &s, bool pretty_print) const {
  bool first = true;
  s << "{";
  if (pretty_print) {
    s << "\n";
    s.IndentMore();
  }
  for (const auto &pair : m_dict) {
    if (first)
      first = false;
    else {
      s << ",";
      if (pretty_print)
        s << "\n";
    }
    if (pretty_print)
      s.Indent();
    s << "\"" << pair.first.AsCString() << "\" : ";
    pair.second->Dump(s, pretty_print);
  }
  if (pretty_print) {
    s.IndentLess();
    s.EOL();
    s.Indent();
  }
  s << "}";
}
Beispiel #7
0
void
UnwindPlan::Row::Dump (Stream& s, const UnwindPlan* unwind_plan, Thread* thread, addr_t base_addr) const
{
    const RegisterInfo *reg_info = unwind_plan->GetRegisterInfo (thread, GetCFARegister());

    if (base_addr != LLDB_INVALID_ADDRESS)
        s.Printf ("0x%16.16" PRIx64 ": CFA=", base_addr + GetOffset());
    else
        s.Printf ("0x%8.8" PRIx64 ": CFA=", GetOffset());
            
    if (reg_info)
        s.Printf ("%s", reg_info->name);
    else
        s.Printf ("reg(%u)", GetCFARegister());
    s.Printf ("%+3d => ", GetCFAOffset ());
    for (collection::const_iterator idx = m_register_locations.begin (); idx != m_register_locations.end (); ++idx)
    {
        reg_info = unwind_plan->GetRegisterInfo (thread, idx->first);
        if (reg_info)
            s.Printf ("%s", reg_info->name);
        else
            s.Printf ("reg(%u)", idx->first);
        const bool verbose = false;
        idx->second.Dump(s, unwind_plan, this, thread, verbose);
        s.PutChar (' ');
    }
    s.EOL();
}
Beispiel #8
0
size_t
Disassembler::Disassemble
(
    Debugger &debugger,
    const ArchSpec &arch,
    const ExecutionContext &exe_ctx,
    SymbolContextList &sc_list,
    uint32_t num_mixed_context_lines,
    bool show_bytes,
    Stream &strm
)
{
    size_t success_count = 0;
    const size_t count = sc_list.GetSize();
    SymbolContext sc;
    AddressRange range;
    for (size_t i=0; i<count; ++i)
    {
        if (sc_list.GetContextAtIndex(i, sc) == false)
            break;
        if (sc.GetAddressRange(eSymbolContextFunction | eSymbolContextSymbol, range))
        {
            if (Disassemble (debugger, arch, exe_ctx, range, num_mixed_context_lines, show_bytes, strm))
            {
                ++success_count;
                strm.EOL();
            }
        }
    }
    return success_count;
}
Beispiel #9
0
void
UnwindPlan::Dump (Stream& s, Thread *thread, lldb::addr_t base_addr) const
{
    if (!m_source_name.IsEmpty())
    {
        s.Printf ("This UnwindPlan originally sourced from %s\n", m_source_name.GetCString());
    }
    if (m_lsda_address.IsValid() && m_personality_func_addr.IsValid())
    {
        TargetSP target_sp(thread->CalculateTarget());
        addr_t lsda_load_addr = m_lsda_address.GetLoadAddress (target_sp.get());
        addr_t personality_func_load_addr = m_personality_func_addr.GetLoadAddress (target_sp.get());
        
        if (lsda_load_addr != LLDB_INVALID_ADDRESS && personality_func_load_addr != LLDB_INVALID_ADDRESS)
        {
            s.Printf("LSDA address 0x%" PRIx64 ", personality routine is at address 0x%" PRIx64 "\n",
                     lsda_load_addr, personality_func_load_addr);
        }
    }
    s.Printf ("This UnwindPlan is sourced from the compiler: ");
    switch (m_plan_is_sourced_from_compiler)
    {
        case eLazyBoolYes:
            s.Printf ("yes.\n");
            break;
        case eLazyBoolNo:
            s.Printf ("no.\n");
            break;
        case eLazyBoolCalculate:
            s.Printf ("not specified.\n");
            break;
    }
    s.Printf ("This UnwindPlan is valid at all instruction locations: ");
    switch (m_plan_is_valid_at_all_instruction_locations)
    {
        case eLazyBoolYes:
            s.Printf ("yes.\n");
            break;
        case eLazyBoolNo:
            s.Printf ("no.\n");
            break;
        case eLazyBoolCalculate:
            s.Printf ("not specified.\n");
            break;
    }
    if (m_plan_valid_address_range.GetBaseAddress().IsValid() && m_plan_valid_address_range.GetByteSize() > 0)
    {
        s.PutCString ("Address range of this UnwindPlan: ");
        TargetSP target_sp(thread->CalculateTarget());
        m_plan_valid_address_range.Dump (&s, target_sp.get(), Address::DumpStyleSectionNameOffset);
        s.EOL();
    }
    collection::const_iterator pos, begin = m_row_list.begin(), end = m_row_list.end();
    for (pos = begin; pos != end; ++pos)
    {
        s.Printf ("row[%u]: ", (uint32_t)std::distance (begin, pos));
        (*pos)->Dump(s, this, thread, base_addr);
    }
}
Beispiel #10
0
 bool DumpToStream(Stream &stream, bool print_help_if_available) override {
   if (IsValid()) {
     m_compiler_type.DumpTypeDescription(&stream);
     stream.EOL();
     return true;
   }
   return false;
 }
void
OptionValueDictionary::DumpValue (const ExecutionContext *exe_ctx, Stream &strm, uint32_t dump_mask)
{
    const Type dict_type = ConvertTypeMaskToType (m_type_mask);
    if (dump_mask & eDumpOptionType)
    {
        if (m_type_mask != eTypeInvalid)
            strm.Printf ("(%s of %ss)", GetTypeAsCString(), GetBuiltinTypeAsCString(dict_type));
        else
            strm.Printf ("(%s)", GetTypeAsCString());
    }
    if (dump_mask & eDumpOptionValue)
    {
        if (dump_mask & eDumpOptionType)
            strm.PutCString (" =");

        collection::iterator pos, end = m_values.end();

        strm.IndentMore();
        
        for (pos = m_values.begin(); pos != end; ++pos)
        {
            OptionValue *option_value = pos->second.get();
            strm.EOL();
            strm.Indent(pos->first.GetCString());
            
            const uint32_t extra_dump_options = m_raw_value_dump ? eDumpOptionRaw : 0;
            switch (dict_type)
            {
                default:
                case eTypeArray:
                case eTypeDictionary:
                case eTypeProperties:
                case eTypeFileSpecList:
                case eTypePathMap:
                    strm.PutChar (' ');
                    option_value->DumpValue(exe_ctx, strm, dump_mask | extra_dump_options);
                    break;

                case eTypeBoolean:
                case eTypeChar:
                case eTypeEnum:
                case eTypeFileSpec:
                case eTypeFormat:
                case eTypeSInt64:
                case eTypeString:
                case eTypeUInt64:
                case eTypeUUID:
                    // No need to show the type for dictionaries of simple items
                    strm.PutCString("=");
                    option_value->DumpValue(exe_ctx, strm, (dump_mask & (~eDumpOptionType)) | extra_dump_options);
                    break;
            }
        }
        strm.IndentLess();
    }

}
Beispiel #12
0
void
Platform::GetStatus (Stream &strm)
{
    uint32_t major = UINT32_MAX;
    uint32_t minor = UINT32_MAX;
    uint32_t update = UINT32_MAX;
    std::string s;
    strm.Printf ("  Platform: %s\n", GetPluginName().GetCString());

    ArchSpec arch (GetSystemArchitecture());
    if (arch.IsValid())
    {
        if (!arch.GetTriple().str().empty())
        strm.Printf("    Triple: %s\n", arch.GetTriple().str().c_str());        
    }

    if (GetOSVersion(major, minor, update))
    {
        strm.Printf("OS Version: %u", major);
        if (minor != UINT32_MAX)
            strm.Printf(".%u", minor);
        if (update != UINT32_MAX)
            strm.Printf(".%u", update);

        if (GetOSBuildString (s))
            strm.Printf(" (%s)", s.c_str());

        strm.EOL();
    }

    if (GetOSKernelDescription (s))
        strm.Printf("    Kernel: %s\n", s.c_str());

    if (IsHost())
    {
        strm.Printf("  Hostname: %s\n", GetHostname());
    }
    else
    {
        const bool is_connected = IsConnected();
        if (is_connected)
            strm.Printf("  Hostname: %s\n", GetHostname());
        strm.Printf(" Connected: %s\n", is_connected ? "yes" : "no");
    }

    if (GetWorkingDirectory())
    {
        strm.Printf("WorkingDir: %s\n", GetWorkingDirectory().GetCString());
    }
    if (!IsConnected())
        return;

    std::string specific_info(GetPlatformSpecificConnectionInformation());
    
    if (specific_info.empty() == false)
        strm.Printf("Platform-specific connection: %s\n", specific_info.c_str());
}
void SectionLoadHistory::Dump(Stream &s, Target *target) {
  std::lock_guard<std::recursive_mutex> guard(m_mutex);
  StopIDToSectionLoadList::iterator pos,
      end = m_stop_id_to_section_load_list.end();
  for (pos = m_stop_id_to_section_load_list.begin(); pos != end; ++pos) {
    s.Printf("StopID = %u:\n", pos->first);
    pos->second->Dump(s, target);
    s.EOL();
  }
}
Beispiel #14
0
void
UnwindTable::Dump (Stream &s)
{
    s.Printf("UnwindTable for %s/%s:\n", m_object_file.GetFileSpec().GetDirectory().GetCString(), m_object_file.GetFileSpec().GetFilename().GetCString());
    const_iterator begin = m_unwinds.begin();
    const_iterator end = m_unwinds.end();
    for (const_iterator pos = begin; pos != end; ++pos)
    {
        s.Printf ("[%u] 0x%16.16llx\n", (unsigned)std::distance (begin, pos), pos->first);
    }
    s.EOL();
}
Beispiel #15
0
void
UnwindTable::Dump (Stream &s)
{
    s.Printf("UnwindTable for '%s':\n", m_object_file.GetFileSpec().GetPath().c_str());
    const_iterator begin = m_unwinds.begin();
    const_iterator end = m_unwinds.end();
    for (const_iterator pos = begin; pos != end; ++pos)
    {
        s.Printf ("[%u] 0x%16.16" PRIx64 "\n", (unsigned)std::distance (begin, pos), pos->first);
    }
    s.EOL();
}
Beispiel #16
0
void
OptionValueArray::DumpValue (const ExecutionContext *exe_ctx, Stream &strm, uint32_t dump_mask)
{
    const Type array_element_type = ConvertTypeMaskToType (m_type_mask);
    if (dump_mask & eDumpOptionType)
    {
        if ((GetType() == eTypeArray) && (m_type_mask != eTypeInvalid))
            strm.Printf ("(%s of %ss)", GetTypeAsCString(), GetBuiltinTypeAsCString(array_element_type));
        else
            strm.Printf ("(%s)", GetTypeAsCString());
    }
    if (dump_mask & eDumpOptionValue)
    {
        if (dump_mask & eDumpOptionType)
            strm.Printf (" =%s", (m_values.size() > 0) ? "\n" : "");
        strm.IndentMore();
        const uint32_t size = m_values.size();
        for (uint32_t i = 0; i<size; ++i)
        {
            strm.Indent();
            strm.Printf("[%u]: ", i);
            const uint32_t extra_dump_options = m_raw_value_dump ? eDumpOptionRaw : 0;
            switch (array_element_type)
            {
                default:
                case eTypeArray:
                case eTypeDictionary:
                case eTypeProperties:
                case eTypeFileSpecList:
                case eTypePathMap:
                    m_values[i]->DumpValue(exe_ctx, strm, dump_mask | extra_dump_options);
                    break;
                    
                case eTypeBoolean:
                case eTypeChar:
                case eTypeEnum:
                case eTypeFileSpec:
                case eTypeFormat:
                case eTypeSInt64:
                case eTypeString:
                case eTypeUInt64:
                case eTypeUUID:
                    // No need to show the type for dictionaries of simple items
                    m_values[i]->DumpValue(exe_ctx, strm, (dump_mask & (~eDumpOptionType)) | extra_dump_options);
                    break;
            }
            if (i < (size - 1))
                strm.EOL();
        }
        strm.IndentLess();
    }
}
Beispiel #17
0
void
Property::DumpDescription (CommandInterpreter &interpreter,
                           Stream &strm,
                           uint32_t output_width,
                           bool display_qualified_name) const
{
    if (m_value_sp)
    {
        const char *desc = GetDescription();

        if (desc)
        {
            StreamString qualified_name;
            const OptionValueProperties *sub_properties = m_value_sp->GetAsProperties();
            if (sub_properties)
            {
                strm.EOL();
                
                if (m_value_sp->DumpQualifiedName(qualified_name))
                    strm.Printf("'%s' variables:\n\n", qualified_name.GetString().c_str());
                sub_properties->DumpAllDescriptions(interpreter, strm);
            }
            else
            {
                if (desc)
                {
                    if (display_qualified_name)
                    {
                        StreamString qualified_name;
                        DumpQualifiedName(qualified_name);
                        interpreter.OutputFormattedHelpText (strm,
                                                             qualified_name.GetString().c_str(),
                                                             "--",
                                                             desc,
                                                             output_width);
                    }
                    else
                    {
                        interpreter.OutputFormattedHelpText (strm,
                                                             m_name.GetCString(),
                                                             "--",
                                                             desc,
                                                             output_width);
                    }
                }
            }
        }
    }
}
void OptionValueProperties::DumpValue(const ExecutionContext *exe_ctx,
                                      Stream &strm, uint32_t dump_mask) {
  const size_t num_properties = m_properties.size();
  for (size_t i = 0; i < num_properties; ++i) {
    const Property *property = GetPropertyAtIndex(exe_ctx, false, i);
    if (property) {
      OptionValue *option_value = property->GetValue().get();
      assert(option_value);
      const bool transparent_value = option_value->ValueIsTransparent();
      property->Dump(exe_ctx, strm, dump_mask);
      if (!transparent_value)
        strm.EOL();
    }
  }
}
Beispiel #19
0
size_t
Disassembler::Disassemble
(
    Debugger &debugger,
    const ArchSpec &arch,
    const char *plugin_name,
    const char *flavor,
    const ExecutionContext &exe_ctx,
    SymbolContextList &sc_list,
    uint32_t num_instructions,
    uint32_t num_mixed_context_lines,
    uint32_t options,
    Stream &strm
)
{
    size_t success_count = 0;
    const size_t count = sc_list.GetSize();
    SymbolContext sc;
    AddressRange range;
    const uint32_t scope = eSymbolContextBlock | eSymbolContextFunction | eSymbolContextSymbol;
    const bool use_inline_block_range = true;
    for (size_t i=0; i<count; ++i)
    {
        if (sc_list.GetContextAtIndex(i, sc) == false)
            break;
        for (uint32_t range_idx = 0; sc.GetAddressRange(scope, range_idx, use_inline_block_range, range); ++range_idx)
        {
            if (Disassemble (debugger, 
                             arch, 
                             plugin_name,
                             flavor,
                             exe_ctx, 
                             range, 
                             num_instructions,
                             num_mixed_context_lines, 
                             options, 
                             strm))
            {
                ++success_count;
                strm.EOL();
            }
        }
    }
    return success_count;
}
Beispiel #20
0
void
UnwindPlan::Row::Dump (Stream& s, const UnwindPlan* unwind_plan, Thread* thread, addr_t base_addr) const
{
    if (base_addr != LLDB_INVALID_ADDRESS)
        s.Printf ("0x%16.16" PRIx64 ": CFA=", base_addr + GetOffset());
    else
        s.Printf ("%4" PRId64 ": CFA=", GetOffset());
            
    m_cfa_value.Dump(s, unwind_plan, thread);
    s.Printf(" => ");
    for (collection::const_iterator idx = m_register_locations.begin (); idx != m_register_locations.end (); ++idx)
    {
        DumpRegisterName(s, unwind_plan, thread, idx->first);
        const bool verbose = false;
        idx->second.Dump(s, unwind_plan, this, thread, verbose);
        s.PutChar (' ');
    }
    s.EOL();
}
    bool
    DumpRegisterSet (const ExecutionContext &exe_ctx,
                     Stream &strm,
                     RegisterContext *reg_ctx,
                     size_t set_idx,
                     bool primitive_only=false)
    {
        uint32_t unavailable_count = 0;
        uint32_t available_count = 0;

        if (!reg_ctx)
            return false; // thread has no registers (i.e. core files are corrupt, incomplete crash logs...)

        const RegisterSet * const reg_set = reg_ctx->GetRegisterSet(set_idx);
        if (reg_set)
        {
            strm.Printf ("%s:\n", reg_set->name);
            strm.IndentMore ();
            const size_t num_registers = reg_set->num_registers;
            for (size_t reg_idx = 0; reg_idx < num_registers; ++reg_idx)
            {
                const uint32_t reg = reg_set->registers[reg_idx];
                const RegisterInfo *reg_info = reg_ctx->GetRegisterInfoAtIndex(reg);
                // Skip the dumping of derived register if primitive_only is true.
                if (primitive_only && reg_info && reg_info->value_regs)
                    continue;

                if (DumpRegister (exe_ctx, strm, reg_ctx, reg_info))
                    ++available_count;
                else
                    ++unavailable_count;
            }
            strm.IndentLess ();
            if (unavailable_count)
            {
                strm.Indent ();
                strm.Printf("%u registers were unavailable.\n", unavailable_count);
            }
            strm.EOL();
        }
        return available_count > 0;
    }
Beispiel #22
0
void
UnwindPlan::Dump (Stream& s, Thread *thread, lldb::addr_t base_addr) const
{
    if (!m_source_name.IsEmpty())
    {
        s.Printf ("This UnwindPlan originally sourced from %s\n", m_source_name.GetCString());
    }
    if (m_plan_valid_address_range.GetBaseAddress().IsValid() && m_plan_valid_address_range.GetByteSize() > 0)
    {
        s.PutCString ("Address range of this UnwindPlan: ");
        TargetSP target_sp(thread->CalculateTarget());
        m_plan_valid_address_range.Dump (&s, target_sp.get(), Address::DumpStyleSectionNameOffset);
        s.EOL();
    }
    collection::const_iterator pos, begin = m_row_list.begin(), end = m_row_list.end();
    for (pos = begin; pos != end; ++pos)
    {
        s.Printf ("row[%u]: ", (uint32_t)std::distance (begin, pos));
        (*pos)->Dump(s, this, thread, base_addr);
    }
}
Beispiel #23
0
static void
DumpStringToStreamWithNewline (Stream &strm, const std::string &s, bool add_newline_if_empty)
{
    bool add_newline = false;
    if (s.empty())
    {
        add_newline = add_newline_if_empty;
    }
    else
    {
        // We already checked for empty above, now make sure there is a newline
        // in the error, and if there isn't one, add one.
        strm.Write(s.c_str(), s.size());

        const char last_char = *s.rbegin();
        add_newline = last_char != '\n' && last_char != '\r';

    }
    if (add_newline)
        strm.EOL();
}
Beispiel #24
0
void
StructuredData::Array::Dump(Stream &s) const
{
    bool first = true;
    s << "[\n";
    s.IndentMore();
    for (const auto &item_sp : m_items)
    {
        if (first)
            first = false;
        else
            s << ",\n";

        s.Indent();
        item_sp->Dump(s);
    }
    s.IndentLess();
    s.EOL();
    s.Indent();
    s << "]";
}
Beispiel #25
0
void
StructuredData::Dictionary::Dump (Stream &s) const
{
    bool first = true;
    s << "{\n";
    s.IndentMore();
    for (const auto &pair : m_dict)
    {
        if (first)
            first = false;
        else
            s << ",\n";
        s.Indent();
        s << "\"" << pair.first.AsCString() << "\" : ";
        pair.second->Dump(s);
    }
    s.IndentLess();
    s.EOL();
    s.Indent();
    s << "}";
}
void ThreadPlanAssemblyTracer::Log() {
  Stream *stream = GetLogStream();

  if (!stream)
    return;

  RegisterContext *reg_ctx = m_thread.GetRegisterContext().get();

  lldb::addr_t pc = reg_ctx->GetPC();
  ProcessSP process_sp(m_thread.GetProcess());
  Address pc_addr;
  bool addr_valid = false;
  uint8_t buffer[16] = {0}; // Must be big enough for any single instruction
  addr_valid = process_sp->GetTarget().GetSectionLoadList().ResolveLoadAddress(
      pc, pc_addr);

  pc_addr.Dump(stream, &m_thread, Address::DumpStyleResolvedDescription,
               Address::DumpStyleModuleWithFileAddress);
  stream->PutCString(" ");

  Disassembler *disassembler = GetDisassembler();
  if (disassembler) {
    Status err;
    process_sp->ReadMemory(pc, buffer, sizeof(buffer), err);

    if (err.Success()) {
      DataExtractor extractor(buffer, sizeof(buffer),
                              process_sp->GetByteOrder(),
                              process_sp->GetAddressByteSize());

      bool data_from_file = false;
      if (addr_valid)
        disassembler->DecodeInstructions(pc_addr, extractor, 0, 1, false,
                                         data_from_file);
      else
        disassembler->DecodeInstructions(Address(pc), extractor, 0, 1, false,
                                         data_from_file);

      InstructionList &instruction_list = disassembler->GetInstructionList();
      const uint32_t max_opcode_byte_size =
          instruction_list.GetMaxOpcocdeByteSize();

      if (instruction_list.GetSize()) {
        const bool show_bytes = true;
        const bool show_address = true;
        Instruction *instruction =
            instruction_list.GetInstructionAtIndex(0).get();
        const FormatEntity::Entry *disassemble_format =
            m_thread.GetProcess()
                ->GetTarget()
                .GetDebugger()
                .GetDisassemblyFormat();
        instruction->Dump(stream, max_opcode_byte_size, show_address,
                          show_bytes, nullptr, nullptr, nullptr,
                          disassemble_format, 0);
      }
    }
  }

  const ABI *abi = process_sp->GetABI().get();
  TypeFromUser intptr_type = GetIntPointerType();

  if (abi && intptr_type.IsValid()) {
    ValueList value_list;
    const int num_args = 1;

    for (int arg_index = 0; arg_index < num_args; ++arg_index) {
      Value value;
      value.SetValueType(Value::eValueTypeScalar);
      //            value.SetContext (Value::eContextTypeClangType,
      //            intptr_type.GetOpaqueQualType());
      value.SetCompilerType(intptr_type);
      value_list.PushValue(value);
    }

    if (abi->GetArgumentValues(m_thread, value_list)) {
      for (int arg_index = 0; arg_index < num_args; ++arg_index) {
        stream->Printf(
            "\n\targ[%d]=%llx", arg_index,
            value_list.GetValueAtIndex(arg_index)->GetScalar().ULongLong());

        if (arg_index + 1 < num_args)
          stream->PutCString(", ");
      }
    }
  }

  RegisterValue reg_value;
  for (uint32_t reg_num = 0, num_registers = reg_ctx->GetRegisterCount();
       reg_num < num_registers; ++reg_num) {
    const RegisterInfo *reg_info = reg_ctx->GetRegisterInfoAtIndex(reg_num);
    if (reg_ctx->ReadRegister(reg_info, reg_value)) {
      assert(reg_num < m_register_values.size());
      if (m_register_values[reg_num].GetType() == RegisterValue::eTypeInvalid ||
          reg_value != m_register_values[reg_num]) {
        if (reg_value.GetType() != RegisterValue::eTypeInvalid) {
          stream->PutCString("\n\t");
          reg_value.Dump(stream, reg_info, true, false, eFormatDefault);
        }
      }
      m_register_values[reg_num] = reg_value;
    }
  }
  stream->EOL();
  stream->Flush();
}
Beispiel #27
0
bool 
Disassembler::PrintInstructions
(
    Disassembler *disasm_ptr,
    Debugger &debugger,
    const ArchSpec &arch,
    const ExecutionContext &exe_ctx,
    uint32_t num_instructions,
    uint32_t num_mixed_context_lines,
    uint32_t options,
    Stream &strm
)
{
    // We got some things disassembled...
    size_t num_instructions_found = disasm_ptr->GetInstructionList().GetSize();
    
    if (num_instructions > 0 && num_instructions < num_instructions_found)
        num_instructions_found = num_instructions;
        
    const uint32_t max_opcode_byte_size = disasm_ptr->GetInstructionList().GetMaxOpcocdeByteSize ();
    uint32_t offset = 0;
    SymbolContext sc;
    SymbolContext prev_sc;
    AddressRange sc_range;
    const Address *pc_addr_ptr = NULL;
    ExecutionContextScope *exe_scope = exe_ctx.GetBestExecutionContextScope();
    Frame *frame = exe_ctx.GetFramePtr();

    TargetSP target_sp (exe_ctx.GetTargetSP());
    SourceManager &source_manager = target_sp ? target_sp->GetSourceManager() : debugger.GetSourceManager();

    if (frame)
        pc_addr_ptr = &frame->GetFrameCodeAddress();
    const uint32_t scope = eSymbolContextLineEntry | eSymbolContextFunction | eSymbolContextSymbol;
    const bool use_inline_block_range = false;
    for (size_t i=0; i<num_instructions_found; ++i)
    {
        Instruction *inst = disasm_ptr->GetInstructionList().GetInstructionAtIndex (i).get();
        if (inst)
        {
            const Address &addr = inst->GetAddress();
            const bool inst_is_at_pc = pc_addr_ptr && addr == *pc_addr_ptr;

            prev_sc = sc;

            ModuleSP module_sp (addr.GetModule());
            if (module_sp)
            {
                uint32_t resolved_mask = module_sp->ResolveSymbolContextForAddress(addr, eSymbolContextEverything, sc);
                if (resolved_mask)
                {
                    if (num_mixed_context_lines)
                    {
                        if (!sc_range.ContainsFileAddress (addr))
                        {
                            sc.GetAddressRange (scope, 0, use_inline_block_range, sc_range);
                            
                            if (sc != prev_sc)
                            {
                                if (offset != 0)
                                    strm.EOL();
                                
                                sc.DumpStopContext(&strm, exe_ctx.GetProcessPtr(), addr, false, true, false);
                                strm.EOL();
                                
                                if (sc.comp_unit && sc.line_entry.IsValid())
                                {
                                    source_manager.DisplaySourceLinesWithLineNumbers (sc.line_entry.file,
                                                                                      sc.line_entry.line,
                                                                                      num_mixed_context_lines,
                                                                                      num_mixed_context_lines,
                                                                                      ((inst_is_at_pc && (options & eOptionMarkPCSourceLine)) ? "->" : ""),
                                                                                      &strm);
                                }
                            }
                        }
                    }
                    else if ((sc.function || sc.symbol) && (sc.function != prev_sc.function || sc.symbol != prev_sc.symbol))
                    {
                        if (prev_sc.function || prev_sc.symbol)
                            strm.EOL();

                        bool show_fullpaths = false;
                        bool show_module = true;
                        bool show_inlined_frames = true;
                        sc.DumpStopContext (&strm, 
                                            exe_scope, 
                                            addr, 
                                            show_fullpaths,
                                            show_module,
                                            show_inlined_frames);
                        
                        strm << ":\n";
                    }
                }
                else
                {
                    sc.Clear(true);
                }
            }

            if ((options & eOptionMarkPCAddress) && pc_addr_ptr)
            {
                strm.PutCString(inst_is_at_pc ? "-> " : "   ");
            }
            const bool show_bytes = (options & eOptionShowBytes) != 0;
            inst->Dump(&strm, max_opcode_byte_size, true, show_bytes, &exe_ctx);
            strm.EOL();            
        }
        else
        {
            break;
        }
    }
        
    return true;
}
Beispiel #28
0
bool 
Disassembler::PrintInstructions
(
    Disassembler *disasm_ptr,
    Debugger &debugger,
    const ArchSpec &arch,
    const ExecutionContext &exe_ctx,
    uint32_t num_instructions,
    uint32_t num_mixed_context_lines,
    uint32_t options,
    Stream &strm
)
{
    // We got some things disassembled...
    size_t num_instructions_found = disasm_ptr->GetInstructionList().GetSize();
    
    if (num_instructions > 0 && num_instructions < num_instructions_found)
        num_instructions_found = num_instructions;
        
    const uint32_t max_opcode_byte_size = disasm_ptr->GetInstructionList().GetMaxOpcocdeByteSize ();
    uint32_t offset = 0;
    SymbolContext sc;
    SymbolContext prev_sc;
    AddressRange sc_range;
    const Address *pc_addr_ptr = NULL;
    StackFrame *frame = exe_ctx.GetFramePtr();

    TargetSP target_sp (exe_ctx.GetTargetSP());
    SourceManager &source_manager = target_sp ? target_sp->GetSourceManager() : debugger.GetSourceManager();

    if (frame)
    {
        pc_addr_ptr = &frame->GetFrameCodeAddress();
    }
    const uint32_t scope = eSymbolContextLineEntry | eSymbolContextFunction | eSymbolContextSymbol;
    const bool use_inline_block_range = false;

    const FormatEntity::Entry *disassembly_format = NULL;
    FormatEntity::Entry format;
    if (exe_ctx.HasTargetScope())
    {
        disassembly_format = exe_ctx.GetTargetRef().GetDebugger().GetDisassemblyFormat ();
    }
    else
    {
        FormatEntity::Parse("${addr}: ", format);
        disassembly_format = &format;
    }

    // First pass: step through the list of instructions, 
    // find how long the initial addresses strings are, insert padding 
    // in the second pass so the opcodes all line up nicely.
    size_t address_text_size = 0;
    for (size_t i = 0; i < num_instructions_found; ++i)
    {
        Instruction *inst = disasm_ptr->GetInstructionList().GetInstructionAtIndex (i).get();
        if (inst)
        {
            const Address &addr = inst->GetAddress();
            ModuleSP module_sp (addr.GetModule());
            if (module_sp)
            {
                const uint32_t resolve_mask = eSymbolContextFunction | eSymbolContextSymbol;
                uint32_t resolved_mask = module_sp->ResolveSymbolContextForAddress(addr, resolve_mask, sc);
                if (resolved_mask)
                {
                    StreamString strmstr;
                    Debugger::FormatDisassemblerAddress (disassembly_format, &sc, NULL, &exe_ctx, &addr, strmstr);
                    size_t cur_line = strmstr.GetSizeOfLastLine();
                    if (cur_line > address_text_size)
                        address_text_size = cur_line;
                }
                sc.Clear(false);
            }
        }
    }

    for (size_t i = 0; i < num_instructions_found; ++i)
    {
        Instruction *inst = disasm_ptr->GetInstructionList().GetInstructionAtIndex (i).get();
        if (inst)
        {
            const Address &addr = inst->GetAddress();
            const bool inst_is_at_pc = pc_addr_ptr && addr == *pc_addr_ptr;

            prev_sc = sc;

            ModuleSP module_sp (addr.GetModule());
            if (module_sp)
            {
                uint32_t resolved_mask = module_sp->ResolveSymbolContextForAddress(addr, eSymbolContextEverything, sc);
                if (resolved_mask)
                {
                    if (num_mixed_context_lines)
                    {
                        if (!sc_range.ContainsFileAddress (addr))
                        {
                            sc.GetAddressRange (scope, 0, use_inline_block_range, sc_range);
                            
                            if (sc != prev_sc)
                            {
                                if (offset != 0)
                                    strm.EOL();
                                
                                sc.DumpStopContext(&strm, exe_ctx.GetProcessPtr(), addr, false, true, false, false, true);
                                strm.EOL();
                                
                                if (sc.comp_unit && sc.line_entry.IsValid())
                                {
                                    source_manager.DisplaySourceLinesWithLineNumbers (sc.line_entry.file,
                                                                                      sc.line_entry.line,
                                                                                      num_mixed_context_lines,
                                                                                      num_mixed_context_lines,
                                                                                      ((inst_is_at_pc && (options & eOptionMarkPCSourceLine)) ? "->" : ""),
                                                                                      &strm);
                                }
                            }
                        }
                    }
                }
                else
                {
                    sc.Clear(true);
                }
            }

            const bool show_bytes = (options & eOptionShowBytes) != 0;
            inst->Dump (&strm, max_opcode_byte_size, true, show_bytes, &exe_ctx, &sc, &prev_sc, NULL, address_text_size);
            strm.EOL();            
        }
        else
        {
            break;
        }
    }
        
    return true;
}
Beispiel #29
0
void
CommandInterpreter::OutputFormattedHelpText (Stream &strm,
                                             const char *word_text,
                                             const char *separator,
                                             const char *help_text,
                                             uint32_t max_word_len)
{
    StateVariable *var = GetStateVariable ("term-width");
    int max_columns = var->GetIntValue();
    // Sanity check max_columns, to cope with emacs shell mode with TERM=dumb
    // (0 rows; 0 columns;).
    if (max_columns <= 0) max_columns = 80;
    
    int indent_size = max_word_len + strlen (separator) + 2;

    strm.IndentMore (indent_size);

    int len = indent_size + strlen (help_text) + 1;
    char *text  = (char *) malloc (len);
    sprintf (text, "%-*s %s %s",  max_word_len, word_text, separator, help_text);
    if (text[len - 1] == '\n')
        text[--len] = '\0';

    if (len  < max_columns)
    {
        // Output it as a single line.
        strm.Printf ("%s", text);
    }
    else
    {
        // We need to break it up into multiple lines.
        bool first_line = true;
        int text_width;
        int start = 0;
        int end = start;
        int final_end = strlen (text);
        int sub_len;
        
        while (end < final_end)
        {
            if (first_line)
                text_width = max_columns - 1;
            else
                text_width = max_columns - indent_size - 1;

            // Don't start the 'text' on a space, since we're already outputting the indentation.
            if (!first_line)
            {
                while ((start < final_end) && (text[start] == ' '))
                  start++;
            }

            end = start + text_width;
            if (end > final_end)
                end = final_end;
            else
            {
                // If we're not at the end of the text, make sure we break the line on white space.
                while (end > start
                       && text[end] != ' ' && text[end] != '\t' && text[end] != '\n')
                    end--;
            }

            sub_len = end - start;
            if (start != 0)
              strm.EOL();
            if (!first_line)
                strm.Indent();
            else
                first_line = false;
            assert (start <= final_end);
            assert (start + sub_len <= final_end);
            if (sub_len > 0)
                strm.Write (text + start, sub_len);
            start = end + 1;
        }
    }
    strm.EOL();
    strm.IndentLess(indent_size);
    free (text);
}
Beispiel #30
0
void Options::GenerateOptionUsage(Stream &strm, CommandObject *cmd,
                                  uint32_t screen_width) {
  const bool only_print_args = cmd->IsDashDashCommand();

  auto opt_defs = GetDefinitions();
  const uint32_t save_indent_level = strm.GetIndentLevel();
  llvm::StringRef name;

  StreamString arguments_str;

  if (cmd) {
    name = cmd->GetCommandName();
    cmd->GetFormattedCommandArguments(arguments_str);
  } else
    name = "";

  strm.PutCString("\nCommand Options Usage:\n");

  strm.IndentMore(2);

  // First, show each usage level set of options, e.g. <cmd>
  // [options-for-level-0]
  //                                                   <cmd>
  //                                                   [options-for-level-1]
  //                                                   etc.

  const uint32_t num_options = NumCommandOptions();
  if (num_options == 0)
    return;

  uint32_t num_option_sets = GetRequiredOptions().size();

  uint32_t i;

  if (!only_print_args) {
    for (uint32_t opt_set = 0; opt_set < num_option_sets; ++opt_set) {
      uint32_t opt_set_mask;

      opt_set_mask = 1 << opt_set;
      if (opt_set > 0)
        strm.Printf("\n");
      strm.Indent(name);

      // Different option sets may require different args.
      StreamString args_str;
      if (cmd)
        cmd->GetFormattedCommandArguments(args_str, opt_set_mask);

      // First go through and print all options that take no arguments as
      // a single string. If a command has "-a" "-b" and "-c", this will show
      // up as [-abc]

      std::set<int> options;
      std::set<int>::const_iterator options_pos, options_end;
      for (auto &def : opt_defs) {
        if (def.usage_mask & opt_set_mask && isprint8(def.short_option)) {
          // Add current option to the end of out_stream.

          if (def.required && def.option_has_arg == OptionParser::eNoArgument) {
            options.insert(def.short_option);
          }
        }
      }

      if (options.empty() == false) {
        // We have some required options with no arguments
        strm.PutCString(" -");
        for (i = 0; i < 2; ++i)
          for (options_pos = options.begin(), options_end = options.end();
               options_pos != options_end; ++options_pos) {
            if (i == 0 && ::islower(*options_pos))
              continue;
            if (i == 1 && ::isupper(*options_pos))
              continue;
            strm << (char)*options_pos;
          }
      }

      options.clear();
      for (auto &def : opt_defs) {
        if (def.usage_mask & opt_set_mask && isprint8(def.short_option)) {
          // Add current option to the end of out_stream.

          if (def.required == false &&
              def.option_has_arg == OptionParser::eNoArgument) {
            options.insert(def.short_option);
          }
        }
      }

      if (options.empty() == false) {
        // We have some required options with no arguments
        strm.PutCString(" [-");
        for (i = 0; i < 2; ++i)
          for (options_pos = options.begin(), options_end = options.end();
               options_pos != options_end; ++options_pos) {
            if (i == 0 && ::islower(*options_pos))
              continue;
            if (i == 1 && ::isupper(*options_pos))
              continue;
            strm << (char)*options_pos;
          }
        strm.PutChar(']');
      }

      // First go through and print the required options (list them up front).

      for (auto &def : opt_defs) {
        if (def.usage_mask & opt_set_mask && isprint8(def.short_option)) {
          if (def.required && def.option_has_arg != OptionParser::eNoArgument)
            PrintOption(def, eDisplayBestOption, " ", nullptr, true, strm);
        }
      }

      // Now go through again, and this time only print the optional options.

      for (auto &def : opt_defs) {
        if (def.usage_mask & opt_set_mask) {
          // Add current option to the end of out_stream.

          if (!def.required && def.option_has_arg != OptionParser::eNoArgument)
            PrintOption(def, eDisplayBestOption, " ", nullptr, true, strm);
        }
      }

      if (args_str.GetSize() > 0) {
        if (cmd->WantsRawCommandString() && !only_print_args)
          strm.Printf(" --");

        strm << " " << args_str.GetString();
        if (only_print_args)
          break;
      }
    }
  }

  if (cmd && (only_print_args || cmd->WantsRawCommandString()) &&
      arguments_str.GetSize() > 0) {
    if (!only_print_args)
      strm.PutChar('\n');
    strm.Indent(name);
    strm << " " << arguments_str.GetString();
  }

  strm.Printf("\n\n");

  if (!only_print_args) {
    // Now print out all the detailed information about the various options:
    // long form, short form and help text:
    //   -short <argument> ( --long_name <argument> )
    //   help text

    // This variable is used to keep track of which options' info we've printed
    // out, because some options can be in
    // more than one usage level, but we only want to print the long form of its
    // information once.

    std::multimap<int, uint32_t> options_seen;
    strm.IndentMore(5);

    // Put the unique command options in a vector & sort it, so we can output
    // them alphabetically (by short_option)
    // when writing out detailed help for each option.

    i = 0;
    for (auto &def : opt_defs)
      options_seen.insert(std::make_pair(def.short_option, i++));

    // Go through the unique'd and alphabetically sorted vector of options, find
    // the table entry for each option
    // and write out the detailed help information for that option.

    bool first_option_printed = false;

    for (auto pos : options_seen) {
      i = pos.second;
      // Print out the help information for this option.

      // Put a newline separation between arguments
      if (first_option_printed)
        strm.EOL();
      else
        first_option_printed = true;

      CommandArgumentType arg_type = opt_defs[i].argument_type;

      StreamString arg_name_str;
      arg_name_str.Printf("<%s>", CommandObject::GetArgumentName(arg_type));

      strm.Indent();
      if (opt_defs[i].short_option && isprint8(opt_defs[i].short_option)) {
        PrintOption(opt_defs[i], eDisplayShortOption, nullptr, nullptr, false,
                    strm);
        PrintOption(opt_defs[i], eDisplayLongOption, " ( ", " )", false, strm);
      } else {
        // Short option is not printable, just print long option
        PrintOption(opt_defs[i], eDisplayLongOption, nullptr, nullptr, false,
                    strm);
      }
      strm.EOL();

      strm.IndentMore(5);

      if (opt_defs[i].usage_text)
        OutputFormattedUsageText(strm, opt_defs[i], screen_width);
      if (opt_defs[i].enum_values != nullptr) {
        strm.Indent();
        strm.Printf("Values: ");
        for (int k = 0; opt_defs[i].enum_values[k].string_value != nullptr;
             k++) {
          if (k == 0)
            strm.Printf("%s", opt_defs[i].enum_values[k].string_value);
          else
            strm.Printf(" | %s", opt_defs[i].enum_values[k].string_value);
        }
        strm.EOL();
      }
      strm.IndentLess(5);
    }
  }

  // Restore the indent level
  strm.SetIndentLevel(save_indent_level);
}