示例#1
0
ValueObjectSP
GoUserExpression::GoInterpreter::VisitStarExpr(const GoASTStarExpr *e) {
  ValueObjectSP target = EvaluateExpr(e->GetX());
  if (!target)
    return nullptr;
  return target->Dereference(m_error);
}
示例#2
0
void ValueObjectPrinter::PrintChild(
    ValueObjectSP child_sp,
    const DumpValueObjectOptions::PointerDepth &curr_ptr_depth) {
  const uint32_t consumed_depth = (!m_options.m_pointer_as_array) ? 1 : 0;
  const bool does_consume_ptr_depth =
      ((IsPtr() && !m_options.m_pointer_as_array) || IsRef());

  DumpValueObjectOptions child_options(m_options);
  child_options.SetFormat(m_options.m_format)
      .SetSummary()
      .SetRootValueObjectName();
  child_options.SetScopeChecked(true)
      .SetHideName(m_options.m_hide_name)
      .SetHideValue(m_options.m_hide_value)
      .SetOmitSummaryDepth(child_options.m_omit_summary_depth > 1
                               ? child_options.m_omit_summary_depth -
                                     consumed_depth
                               : 0)
      .SetElementCount(0);

  if (child_sp.get()) {
    ValueObjectPrinter child_printer(
        child_sp.get(), m_stream, child_options,
        does_consume_ptr_depth ? --curr_ptr_depth : curr_ptr_depth,
        m_curr_depth + consumed_depth, m_printed_instance_pointers);
    child_printer.PrintValueObject();
  }
}
ValueObjectSP
GoUserExpression::GoInterpreter::VisitSelectorExpr(const lldb_private::GoASTSelectorExpr *e)
{
    ValueObjectSP target = EvaluateExpr(e->GetX());
    if (target)
    {
        if (target->GetCompilerType().IsPointerType())
        {
            target = target->Dereference(m_error);
            if (m_error.Fail())
                return nullptr;
        }
        ConstString field(e->GetSel()->GetName().m_value);
        ValueObjectSP result = target->GetChildMemberWithName(field, true);
        if (!result)
            m_error.SetErrorStringWithFormat("Unknown child %s", field.AsCString());
        return result;
    }
    if (const GoASTIdent *package = llvm::dyn_cast<GoASTIdent>(e->GetX()))
    {
        if (VariableSP global = FindGlobalVariable(m_exe_ctx.GetTargetSP(),
                                                   package->GetName().m_value + "." + e->GetSel()->GetName().m_value))
        {
            if (m_frame)
            {
                m_error.Clear();
                return m_frame->GetValueObjectForFrameVariable(global, m_use_dynamic);
            }
        }
    }
    if (const GoASTBasicLit *packageLit = llvm::dyn_cast<GoASTBasicLit>(e->GetX()))
    {
        if (packageLit->GetValue().m_type == GoLexer::LIT_STRING)
        {
            std::string value = packageLit->GetValue().m_value.str();
            value = value.substr(1, value.size() - 2);
            if (VariableSP global =
                    FindGlobalVariable(m_exe_ctx.GetTargetSP(), value + "." + e->GetSel()->GetName().m_value))
            {
                if (m_frame)
                {
                    m_error.Clear();
                    return m_frame->TrackGlobalVariable(global, m_use_dynamic);
                }
            }
        }
    }
    // EvaluateExpr should have already set m_error.
    return target;
}
示例#4
0
// this function abstracts away the layout and mode details of a libc++ string
// and returns the address of the data and the size ready for callers to consume
static bool
ExtractLibcxxStringInfo (ValueObject& valobj,
                         ValueObjectSP &location_sp,
                         uint64_t& size)
{
    ValueObjectSP D(valobj.GetChildAtIndexPath({0,0,0,0}));
    if (!D)
        return false;
    
    ValueObjectSP layout_decider(D->GetChildAtIndexPath({0,0}));
    
    // this child should exist
    if (!layout_decider)
        return false;
    
    ConstString g_data_name("__data_");
    ConstString g_size_name("__size_");
    bool short_mode = false; // this means the string is in short-mode and the data is stored inline
    LibcxxStringLayoutMode layout = (layout_decider->GetName() == g_data_name) ? eLibcxxStringLayoutModeDSC : eLibcxxStringLayoutModeCSD;
    uint64_t size_mode_value = 0;
    
    if (layout == eLibcxxStringLayoutModeDSC)
    {
        ValueObjectSP size_mode(D->GetChildAtIndexPath({1,1,0}));
        if (!size_mode)
            return false;
        
        if (size_mode->GetName() != g_size_name)
        {
            // we are hitting the padding structure, move along
            size_mode = D->GetChildAtIndexPath({1,1,1});
            if (!size_mode)
                return false;
        }
        
        size_mode_value = (size_mode->GetValueAsUnsigned(0));
        short_mode = ((size_mode_value & 0x80) == 0);
    }
    else
    {
        ValueObjectSP size_mode(D->GetChildAtIndexPath({1,0,0}));
        if (!size_mode)
            return false;
        
        size_mode_value = (size_mode->GetValueAsUnsigned(0));
        short_mode = ((size_mode_value & 1) == 0);
    }
    
    if (short_mode)
    {
        ValueObjectSP s(D->GetChildAtIndex(1, true));
        if (!s)
            return false;
        location_sp = s->GetChildAtIndex((layout == eLibcxxStringLayoutModeDSC) ? 0 : 1, true);
        size = (layout == eLibcxxStringLayoutModeDSC) ? size_mode_value : ((size_mode_value >> 1) % 256);
        return (location_sp.get() != nullptr);
    }
    else
    {
示例#5
0
文件: LibCxxMap.cpp 项目: Arhzi/lldb
bool
lldb_private::formatters::LibcxxStdMapSyntheticFrontEnd::GetDataType()
{
    if (m_element_type.GetOpaqueQualType() && m_element_type.GetTypeSystem())
        return true;
    m_element_type.Clear();
    ValueObjectSP deref;
    Error error;
    deref = m_root_node->Dereference(error);
    if (!deref || error.Fail())
        return false;
    deref = deref->GetChildMemberWithName(ConstString("__value_"), true);
    if (!deref)
        return false;
    m_element_type = deref->GetCompilerType();
    return true;
}
示例#6
0
void
ValueObjectPrinter::PrintChild (ValueObjectSP child_sp,
                                const DumpValueObjectOptions::PointerDepth& curr_ptr_depth)
{
    DumpValueObjectOptions child_options(m_options);
    child_options.SetFormat(m_options.m_format).SetSummary().SetRootValueObjectName();
    child_options.SetScopeChecked(true).SetHideName(m_options.m_hide_name).SetHideValue(m_options.m_hide_value)
    .SetOmitSummaryDepth(child_options.m_omit_summary_depth > 1 ? child_options.m_omit_summary_depth - 1 : 0);
    if (child_sp.get())
    {
        ValueObjectPrinter child_printer(child_sp.get(),
                                         m_stream,
                                         child_options,
                                         (IsPtr() || IsRef()) ? --curr_ptr_depth : curr_ptr_depth,
                                         m_curr_depth + 1);
        child_printer.PrintValueObject();
    }
}
示例#7
0
ValueObjectSP GoUserExpression::GoInterpreter::VisitCallExpr(
    const lldb_private::GoASTCallExpr *e) {
  ValueObjectSP x = EvaluateExpr(e->GetFun());
  if (x || e->NumArgs() != 1) {
    m_error.SetErrorStringWithFormat("Code execution not supported");
    return nullptr;
  }
  m_error.Clear();
  CompilerType type = EvaluateType(e->GetFun());
  if (!type) {
    return nullptr;
  }
  ValueObjectSP value = EvaluateExpr(e->GetArgs(0));
  if (!value)
    return nullptr;
  // TODO: Handle special conversions
  return value->Cast(type);
}
示例#8
0
ValueObjectSP
GoUserExpression::GoInterpreter::VisitUnaryExpr(const GoASTUnaryExpr *e) {
  ValueObjectSP x = EvaluateExpr(e->GetX());
  if (!x)
    return nullptr;
  switch (e->GetOp()) {
  case GoLexer::OP_AMP: {
    CompilerType type = x->GetCompilerType().GetPointerType();
    uint64_t address = x->GetAddressOf();
    return ValueObject::CreateValueObjectFromAddress(nullptr, address,
                                                     m_exe_ctx, type);
  }
  case GoLexer::OP_PLUS:
    return x;
  default:
    m_error.SetErrorStringWithFormat(
        "Operator %s not supported",
        GoLexer::LookupToken(e->GetOp()).str().c_str());
    return nullptr;
  }
}
示例#9
0
bool lldb_private::formatters::LibcxxStdMapSyntheticFrontEnd::GetDataType() {
  static ConstString g___value_("__value_");
  static ConstString g_tree_("__tree_");
  static ConstString g_pair3("__pair3_");

  if (m_element_type.GetOpaqueQualType() && m_element_type.GetTypeSystem())
    return true;
  m_element_type.Clear();
  ValueObjectSP deref;
  Status error;
  deref = m_root_node->Dereference(error);
  if (!deref || error.Fail())
    return false;
  deref = deref->GetChildMemberWithName(g___value_, true);
  if (deref) {
    m_element_type = deref->GetCompilerType();
    return true;
  }
  deref = m_backend.GetChildAtNamePath({g_tree_, g_pair3});
  if (!deref)
    return false;
  m_element_type = deref->GetCompilerType()
                       .GetTypeTemplateArgument(1)
                       .GetTypeTemplateArgument(1);
  if (m_element_type) {
    std::string name;
    uint64_t bit_offset_ptr;
    uint32_t bitfield_bit_size_ptr;
    bool is_bitfield_ptr;
    m_element_type = m_element_type.GetFieldAtIndex(
        0, name, &bit_offset_ptr, &bitfield_bit_size_ptr, &is_bitfield_ptr);
    m_element_type = m_element_type.GetTypedefedType();
    return m_element_type.IsValid();
  } else {
    m_element_type = m_backend.GetCompilerType().GetTypeTemplateArgument(0);
    return m_element_type.IsValid();
  }
}
示例#10
0
ValueObjectSP BitsetFrontEnd::GetChildAtIndex(size_t idx) {
  if (idx >= m_elements.size() || !m_first)
    return ValueObjectSP();

  if (m_elements[idx])
    return m_elements[idx];

  ExecutionContext ctx = m_backend.GetExecutionContextRef().Lock(false);
  CompilerType type;
  ValueObjectSP chunk;
  // For small bitsets __first_ is not an array, but a plain size_t.
  if (m_first->GetCompilerType().IsArrayType(&type, nullptr, nullptr)) {
    llvm::Optional<uint64_t> bit_size =
        type.GetBitSize(ctx.GetBestExecutionContextScope());
    if (!bit_size || *bit_size == 0)
      return {};
    chunk = m_first->GetChildAtIndex(idx / *bit_size, true);
  } else {
    type = m_first->GetCompilerType();
    chunk = m_first;
  }
  if (!type || !chunk)
    return {};

  llvm::Optional<uint64_t> bit_size =
      type.GetBitSize(ctx.GetBestExecutionContextScope());
  if (!bit_size || *bit_size == 0)
    return {};
  size_t chunk_idx = idx % *bit_size;
  uint8_t value = !!(chunk->GetValueAsUnsigned(0) & (uint64_t(1) << chunk_idx));
  DataExtractor data(&value, sizeof(value), m_byte_order, m_byte_size);

  m_elements[idx] = CreateValueObjectFromData(llvm::formatv("[{0}]", idx).str(),
                                              data, ctx, m_bool_type);

  return m_elements[idx];
}
示例#11
0
bool
isThrownError(ValueObjectSP valobj_sp)
{
    ConstString name = valobj_sp->GetName();
    size_t length = name.GetLength();
    if (length < 3)
        return false;
    
    const char *name_cstr = name.AsCString();
    if (name_cstr[0] != '$')
        return false;
    if (name_cstr[1] != 'E')
        return false;
    for (int index = 2; index < length; index++)
    {
        
        char digit = name_cstr[index];
        if (digit < '0' || digit > '9')
            return false;
    }
    return true;
}
示例#12
0
bool
SwiftREPL::PrintOneVariable (Debugger &debugger,
                             StreamFileSP &output_sp,
                             ValueObjectSP &valobj_sp,
                             ExpressionVariable *var)
{
    bool is_computed = false;
    
    if (var)
    {
        if (lldb::ValueObjectSP valobj_sp = var->GetValueObject())
        {
            Flags valobj_type_flags(valobj_sp->GetCompilerType().GetTypeInfo());
            const bool is_swift(valobj_type_flags.AllSet(eTypeIsSwift));
            if ((var->GetName().AsCString("anonymous")[0] != '$') &&
                is_swift)
            {
                is_computed = llvm::cast<SwiftExpressionVariable>(var)->GetIsComputed();
            }
            else
            {
                return false;
            }
        }
        else
        {
            return false;
        }
    }
        
    const bool colorize_out = output_sp->GetFile().GetIsTerminalWithColors();

    bool handled = false;
    
    Format format = m_format_options.GetFormat();
    
    bool treat_as_void = (format == eFormatVoid);
    // if we are asked to suppress void, check if this is the empty tuple type, and if so suppress it
    if (!treat_as_void && !debugger.GetNotifyVoid())
    {
        const CompilerType &expr_type(valobj_sp->GetCompilerType());
        Flags expr_type_flags(expr_type.GetTypeInfo());
        if (expr_type_flags.AllSet(eTypeIsSwift | eTypeIsTuple))
        {
            treat_as_void = (expr_type.GetNumFields() == 0);
        }
    }
    
    if (!treat_as_void)
    {
        if (format != eFormatDefault)
            valobj_sp->SetFormat (format);
        
        DumpValueObjectOptions options;
        options.SetUseDynamicType(lldb::eDynamicCanRunTarget);
        options.SetMaximumPointerDepth( {DumpValueObjectOptions::PointerDepth::Mode::Formatters,1} );
        options.SetUseSyntheticValue(true);
        options.SetRevealEmptyAggregates(false);
        options.SetHidePointerValue(true);
        options.SetVariableFormatDisplayLanguage(lldb::eLanguageTypeSwift);
	options.SetDeclPrintingHelper ([] (ConstString type_name,
               ConstString var_name,
               const DumpValueObjectOptions &options,
               Stream &stream) -> bool {
      		   if (!type_name || !var_name)
			return false;

		   std::string type_name_str(type_name ? type_name.GetCString() : "");
                   for(auto iter = type_name_str.find(" *");
                       iter != std::string::npos;
                       iter = type_name_str.find(" *"))
                   {
                       type_name_str.erase(iter, 2);
                   }
                   if (!type_name_str.empty())
                   {
		       stream.Printf("%s: %s =", var_name.GetCString(), type_name_str.c_str());	
		       return true;
		   }
                       
                   return false;
               });
        
        if (is_computed)
        {
            StringSummaryFormat::Flags flags;
            flags.SetDontShowChildren(true);
            flags.SetDontShowValue(true);
            flags.SetHideItemNames(true);
            flags.SetShowMembersOneLiner(false);
            flags.SetSkipPointers(false);
            flags.SetSkipReferences(false);
            options.SetHideValue(true);
            options.SetShowSummary(true);
            options.SetSummary(lldb::TypeSummaryImplSP(new StringSummaryFormat(flags,"<computed property>")));
        }
        
        if (colorize_out)
        {
            const char *color = isThrownError(valobj_sp) ?
                ANSI_ESCAPE1(ANSI_FG_COLOR_RED) : ANSI_ESCAPE1(ANSI_FG_COLOR_CYAN);
            fprintf(output_sp->GetFile().GetStream(), "%s", color);
        }
        
        valobj_sp->Dump(*output_sp, options);
        
        if (colorize_out)
            fprintf(output_sp->GetFile().GetStream(), ANSI_ESCAPE1(ANSI_CTRL_NORMAL));
        
        handled = true;
    }
    
    return handled;
}
示例#13
0
OperatingSystemGo::Goroutine
OperatingSystemGo::CreateGoroutineAtIndex(uint64_t idx, Error &err)
{
    err.Clear();
    Goroutine result;
    ValueObjectSP g = m_allg_sp->GetSyntheticArrayMember(idx, true)->Dereference(err);
    if (err.Fail())
    {
        return result;
    }

    ConstString name("goid");
    ValueObjectSP val = g->GetChildMemberWithName(name, true);
    bool success = false;
    result.m_goid = val->GetValueAsUnsigned(0, &success);
    if (!success)
    {
        err.SetErrorToGenericError();
        err.SetErrorString("unable to read goid");
        return result;
    }
    name.SetCString("atomicstatus");
    val = g->GetChildMemberWithName(name, true);
    result.m_status = (uint32_t)val->GetValueAsUnsigned(0, &success);
    if (!success)
    {
        err.SetErrorToGenericError();
        err.SetErrorString("unable to read atomicstatus");
        return result;
    }
    name.SetCString("sched");
    val = g->GetChildMemberWithName(name, true);
    result.m_gobuf = val->GetAddressOf(false);
    name.SetCString("stack");
    val = g->GetChildMemberWithName(name, true);
    name.SetCString("lo");
    ValueObjectSP child = val->GetChildMemberWithName(name, true);
    result.m_lostack = child->GetValueAsUnsigned(0, &success);
    if (!success)
    {
        err.SetErrorToGenericError();
        err.SetErrorString("unable to read stack.lo");
        return result;
    }
    name.SetCString("hi");
    child = val->GetChildMemberWithName(name, true);
    result.m_histack = child->GetValueAsUnsigned(0, &success);
    if (!success)
    {
        err.SetErrorToGenericError();
        err.SetErrorString("unable to read stack.hi");
        return result;
    }
    return result;
}
ValueObjectSP
GoUserExpression::GoInterpreter::VisitIndexExpr(const lldb_private::GoASTIndexExpr *e)
{
    ValueObjectSP target = EvaluateExpr(e->GetX());
    if (!target)
        return nullptr;
    ValueObjectSP index = EvaluateExpr(e->GetIndex());
    if (!index)
        return nullptr;
    bool is_signed;
    if (!index->GetCompilerType().IsIntegerType(is_signed))
    {
        m_error.SetErrorString("Unsupported index");
        return nullptr;
    }
    size_t idx;
    if (is_signed)
        idx = index->GetValueAsSigned(0);
    else
        idx = index->GetValueAsUnsigned(0);
    if (GoASTContext::IsGoSlice(target->GetCompilerType()))
    {
        target = target->GetStaticValue();
        ValueObjectSP cap = target->GetChildMemberWithName(ConstString("cap"), true);
        if (cap)
        {
            uint64_t capval = cap->GetValueAsUnsigned(0);
            if (idx >= capval)
            {
                m_error.SetErrorStringWithFormat("Invalid index %" PRIu64 " , cap = %" PRIu64, uint64_t(idx), capval);
                return nullptr;
            }
        }
        target = target->GetChildMemberWithName(ConstString("array"), true);
        if (target && m_use_dynamic != eNoDynamicValues)
        {
            ValueObjectSP dynamic = target->GetDynamicValue(m_use_dynamic);
            if (dynamic)
                target = dynamic;
        }
        if (!target)
            return nullptr;
        return target->GetSyntheticArrayMember(idx, true);
    }
    return target->GetChildAtIndex(idx, true);
}
ValueObjectSP
GoUserExpression::GoInterpreter::VisitIdent(const GoASTIdent *e)
{
    ValueObjectSP val;
    if (m_frame)
    {
        VariableSP var_sp;
        std::string varname = e->GetName().m_value.str();
        if (varname.size() > 1 && varname[0] == '$')
        {
            RegisterContextSP reg_ctx_sp = m_frame->GetRegisterContext();
            const RegisterInfo *reg = reg_ctx_sp->GetRegisterInfoByName(varname.c_str() + 1);
            if (reg)
            {
                std::string type;
                switch (reg->encoding)
                {
                    case lldb::eEncodingSint:
                        type.append("int");
                        break;
                    case lldb::eEncodingUint:
                        type.append("uint");
                        break;
                    case lldb::eEncodingIEEE754:
                        type.append("float");
                        break;
                    default:
                        m_error.SetErrorString("Invaild register encoding");
                        return nullptr;
                }
                switch (reg->byte_size)
                {
                    case 8:
                        type.append("64");
                        break;
                    case 4:
                        type.append("32");
                        break;
                    case 2:
                        type.append("16");
                        break;
                    case 1:
                        type.append("8");
                        break;
                    default:
                        m_error.SetErrorString("Invaild register size");
                        return nullptr;
                }
                ValueObjectSP regVal =
                    ValueObjectRegister::Create(m_frame.get(), reg_ctx_sp, reg->kinds[eRegisterKindLLDB]);
                CompilerType goType = LookupType(m_frame->CalculateTarget(), ConstString(type));
                if (regVal)
                {
                    regVal = regVal->Cast(goType);
                    return regVal;
                }
            }
            m_error.SetErrorString("Invaild register name");
            return nullptr;
        }
        VariableListSP var_list_sp(m_frame->GetInScopeVariableList(false));
        if (var_list_sp)
        {
            var_sp = var_list_sp->FindVariable(ConstString(varname));
            if (var_sp)
                val = m_frame->GetValueObjectForFrameVariable(var_sp, m_use_dynamic);
            else
            {
                // When a variable is on the heap instead of the stack, go records a variable
                // '&x' instead of 'x'.
                var_sp = var_list_sp->FindVariable(ConstString("&" + varname));
                if (var_sp)
                {
                    val = m_frame->GetValueObjectForFrameVariable(var_sp, m_use_dynamic);
                    if (val)
                        val = val->Dereference(m_error);
                    if (m_error.Fail())
                        return nullptr;
                }
            }
        }
        if (!val)
        {
            m_error.Clear();
            TargetSP target = m_frame->CalculateTarget();
            if (!target)
            {
                m_error.SetErrorString("No target");
                return nullptr;
            }
            var_sp = FindGlobalVariable(target, m_package + "." + e->GetName().m_value);
            if (var_sp)
                return m_frame->TrackGlobalVariable(var_sp, m_use_dynamic);
        }
    }
    if (!val)
        m_error.SetErrorStringWithFormat("Unknown variable %s", e->GetName().m_value.str().c_str());
    return val;
}