Пример #1
0
void MainWindow::EditRow(int row)
{
    QString name = ui->Table->item(row,NAME)->text();
    Variable * var = variables.value(name);
    VariableDialog dlg(var,Map,this);
    dlg.exec();

    if (name != var->GetName())
    {
        variables.remove(name);
        variables.insert(var->GetName(),var);
    }

    RefreshTable();
}
void DataSegment::AddVariable
    (
    Variable const& pVariable
    )
{
    mVars.Add(pVariable.GetName(), pVariable);
}
Пример #3
0
void MainWindow::FillRow(int row, const Variable &var)
{
    QTableWidgetItem * item;
    item = new QTableWidgetItem(var.GetName());
    item->setFlags(Qt::ItemIsEnabled);
    ui->Table->setItem(row,NAME, item);
    item = new QTableWidgetItem(QString("0x%1").arg(var.GetAddressOffset(),0,16));
    item->setFlags(Qt::ItemIsEnabled);
    ui->Table->setItem(row,ADDRESS,item);
    item = new QTableWidgetItem(var.GetType());
    item->setFlags(Qt::ItemIsEnabled);
    ui->Table->setItem(row,TYPE,item);
    item = new QTableWidgetItem(QString("%1 ms").arg(var.RefreshTime()));
    item->setFlags(Qt::ItemIsEnabled);
    ui->Table->setItem(row,PERIOD,item);
    item = new QTableWidgetItem("");
    item->setFlags(Qt::ItemIsEnabled);
    ui->Table->setItem(row, VALUE, item);
    item = new QTableWidgetItem("");
    item->setFlags(Qt::ItemIsEnabled | Qt::ItemIsEditable);
    ui->Table->setItem(row, MODIFY, item);
    item = new QTableWidgetItem("");
    item->setFlags(Qt::ItemIsEnabled);
    ui->Table->setItem(row, FLOAT, item);
}
Пример #4
0
//-----------------------------------------------------------------------------
// Returns colour data from the named variable.
//-----------------------------------------------------------------------------
D3DCOLORVALUE *Script::GetColourData( char *variable )
{
	m_variables->Iterate( true );
	while( m_variables->Iterate() != NULL )
	{
		Variable* pVar = m_variables->GetCurrent();
		if( strcmp( pVar->GetName(), variable ) == 0 )
			return (D3DCOLORVALUE*)m_variables->GetCurrent()->GetData();
	}

	return NULL;
}
Пример #5
0
void MainWindow::AddNewRow()
{
    Variable *  var = new Variable(client,this);
    VariableDialog dlg(var,Map,this);
    if (dlg.exec() == QDialog::Accepted)
    {
        variables.insert(var->GetName(),var);
        var->connectNewSample(this,SLOT(VariableModified()));
        RefreshTable();

        if (ui->actionConnect->isChecked())
            emit TimerStart();
    }
    else
    {
        var->deleteLater();
    }
}
Пример #6
0
//------------------------------------------------------------------------------
// void AssignSimpleExpression(const Variable &right)
//------------------------------------------------------------------------------
void Variable::AssignSimpleExpression(const Variable &right)
{
   if (mParamDb)
   {
      #ifdef DEBUG_MEMORY
      MemoryTracker::Instance()->Remove
         (mParamDb, GetName(), wxT("Variable::operator="), wxT("deleting mParamDb"));
      #endif
      delete mParamDb;
   }
   
   mParamDb = new ParameterDatabase(*right.mParamDb);
   
   #ifdef DEBUG_MEMORY
   MemoryTracker::Instance()->Add
      (mParamDb, GetName(), wxT("Variable::operator="), wxT("mParamDb = new ParameterDatabase()"));
   #endif
   
   if (mExpParser)
   {
      #ifdef DEBUG_MEMORY
      MemoryTracker::Instance()->Remove
         (mExpParser, GetName(), wxT("Variable::operator="), wxT("deleting mExpParser"));
      #endif
      delete mExpParser;
   }
   
   mExpParser = new ExpressionParser();
   
   #ifdef DEBUG_MEMORY
   MemoryTracker::Instance()->Add
      (mExpParser, GetName(), wxT("Variable::operator="), wxT("mExpParser = new ExpressionParser()"));
   #endif
   
   mExpParser->SetParameterDatabase(mParamDb);
   // Set expression to name of right side since expression is used for
   // writnig in GetGeneratingString() (loj: 2008.08.13)
   // For example:
   // var1 = 123.45;
   // var2 = var1;
   // We want to write wxT("var2 = var1") instead of wxT("var2 = 123.45")
   mExpr = right.GetName();
}
Пример #7
0
Error
Value::GetValueAsData (ExecutionContext *exe_ctx,
                       DataExtractor &data,
                       uint32_t data_offset,
                       Module *module)
{
    data.Clear();

    Error error;
    lldb::addr_t address = LLDB_INVALID_ADDRESS;
    AddressType address_type = eAddressTypeFile;
    Address file_so_addr;
    const CompilerType &ast_type = GetCompilerType();
    switch (m_value_type)
    {
    case eValueTypeVector:
        if (ast_type.IsValid())
            data.SetAddressByteSize (ast_type.GetPointerByteSize());
        else
            data.SetAddressByteSize(sizeof(void *));
        data.SetData(m_vector.bytes, m_vector.length, m_vector.byte_order);
        break;

    case eValueTypeScalar:
        {
            data.SetByteOrder (endian::InlHostByteOrder());
            if (ast_type.IsValid())
                data.SetAddressByteSize (ast_type.GetPointerByteSize());
            else
                data.SetAddressByteSize(sizeof(void *));

            uint32_t limit_byte_size = UINT32_MAX;
            
            if (ast_type.IsValid() && ast_type.IsScalarType())
            {
                uint64_t type_encoding_count = 0;
                lldb::Encoding type_encoding = ast_type.GetEncoding(type_encoding_count);
                
                if (type_encoding == eEncodingUint || type_encoding == eEncodingSint)
                    limit_byte_size = ast_type.GetByteSize(exe_ctx ? exe_ctx->GetBestExecutionContextScope() : nullptr);
            }
            
            if (m_value.GetData (data, limit_byte_size))
                return error;   // Success;
            
            error.SetErrorStringWithFormat("extracting data from value failed");
            break;
        }
    case eValueTypeLoadAddress:
        if (exe_ctx == NULL)
        {
            error.SetErrorString ("can't read load address (no execution context)");
        }
        else 
        {
            Process *process = exe_ctx->GetProcessPtr();
            if (process == NULL || !process->IsAlive())
            {
                Target *target = exe_ctx->GetTargetPtr();
                if (target)
                {
                    // Allow expressions to run and evaluate things when the target
                    // has memory sections loaded. This allows you to use "target modules load"
                    // to load your executable and any shared libraries, then execute
                    // commands where you can look at types in data sections.
                    const SectionLoadList &target_sections = target->GetSectionLoadList();
                    if (!target_sections.IsEmpty())
                    {
                        address = m_value.ULongLong(LLDB_INVALID_ADDRESS);
                        if (target_sections.ResolveLoadAddress(address, file_so_addr))
                        {
                            address_type = eAddressTypeLoad;
                            data.SetByteOrder(target->GetArchitecture().GetByteOrder());
                            data.SetAddressByteSize(target->GetArchitecture().GetAddressByteSize());
                        }
                        else
                            address = LLDB_INVALID_ADDRESS;
                    }
//                    else
//                    {
//                        ModuleSP exe_module_sp (target->GetExecutableModule());
//                        if (exe_module_sp)
//                        {
//                            address = m_value.ULongLong(LLDB_INVALID_ADDRESS);
//                            if (address != LLDB_INVALID_ADDRESS)
//                            {
//                                if (exe_module_sp->ResolveFileAddress(address, file_so_addr))
//                                {
//                                    data.SetByteOrder(target->GetArchitecture().GetByteOrder());
//                                    data.SetAddressByteSize(target->GetArchitecture().GetAddressByteSize());
//                                    address_type = eAddressTypeFile;
//                                }
//                                else
//                                {
//                                    address = LLDB_INVALID_ADDRESS;
//                                }
//                            }
//                        }
//                    }
                }
                else
                {
                    error.SetErrorString ("can't read load address (invalid process)");
                }
            }
            else
            {
                address = m_value.ULongLong(LLDB_INVALID_ADDRESS);
                address_type = eAddressTypeLoad;
                data.SetByteOrder(process->GetTarget().GetArchitecture().GetByteOrder());
                data.SetAddressByteSize(process->GetTarget().GetArchitecture().GetAddressByteSize());
            }
        }
        break;

    case eValueTypeFileAddress:
        if (exe_ctx == NULL)
        {
            error.SetErrorString ("can't read file address (no execution context)");
        }
        else if (exe_ctx->GetTargetPtr() == NULL)
        {
            error.SetErrorString ("can't read file address (invalid target)");
        }
        else
        {
            address = m_value.ULongLong(LLDB_INVALID_ADDRESS);
            if (address == LLDB_INVALID_ADDRESS)
            {
                error.SetErrorString ("invalid file address");
            }
            else
            {
                if (module == NULL)
                {
                    // The only thing we can currently lock down to a module so that
                    // we can resolve a file address, is a variable.
                    Variable *variable = GetVariable();
                    if (variable)
                    {
                        SymbolContext var_sc;
                        variable->CalculateSymbolContext(&var_sc);
                        module = var_sc.module_sp.get();
                    }
                }
                
                if (module)
                {
                    bool resolved = false;
                    ObjectFile *objfile = module->GetObjectFile();
                    if (objfile)
                    {
                        Address so_addr(address, objfile->GetSectionList());
                        addr_t load_address = so_addr.GetLoadAddress (exe_ctx->GetTargetPtr());
                        bool process_launched_and_stopped = exe_ctx->GetProcessPtr()
                            ? StateIsStoppedState(exe_ctx->GetProcessPtr()->GetState(), true /* must_exist */)
                            : false;
                        // Don't use the load address if the process has exited.
                        if (load_address != LLDB_INVALID_ADDRESS && process_launched_and_stopped)
                        {
                            resolved = true;
                            address = load_address;
                            address_type = eAddressTypeLoad;
                            data.SetByteOrder(exe_ctx->GetTargetRef().GetArchitecture().GetByteOrder());
                            data.SetAddressByteSize(exe_ctx->GetTargetRef().GetArchitecture().GetAddressByteSize());
                        }
                        else
                        {
                            if (so_addr.IsSectionOffset())
                            {
                                resolved = true;
                                file_so_addr = so_addr;
                                data.SetByteOrder(objfile->GetByteOrder());
                                data.SetAddressByteSize(objfile->GetAddressByteSize());
                            }
                        }
                    }
                    if (!resolved)
                    {
                        Variable *variable = GetVariable();
                        
                        if (module)
                        {
                            if (variable)
                                error.SetErrorStringWithFormat ("unable to resolve the module for file address 0x%" PRIx64 " for variable '%s' in %s",
                                                                address, 
                                                                variable->GetName().AsCString(""),
                                                                module->GetFileSpec().GetPath().c_str());
                            else
                                error.SetErrorStringWithFormat ("unable to resolve the module for file address 0x%" PRIx64 " in %s",
                                                                address, 
                                                                module->GetFileSpec().GetPath().c_str());
                        }
                        else
                        {
                            if (variable)
                                error.SetErrorStringWithFormat ("unable to resolve the module for file address 0x%" PRIx64 " for variable '%s'",
                                                                address, 
                                                                variable->GetName().AsCString(""));
                            else
                                error.SetErrorStringWithFormat ("unable to resolve the module for file address 0x%" PRIx64, address);
                        }
                    }
                }
                else
                {
                    // Can't convert a file address to anything valid without more
                    // context (which Module it came from)
                    error.SetErrorString ("can't read memory from file address without more context");
                }
            }
        }
        break;

    case eValueTypeHostAddress:
        address = m_value.ULongLong(LLDB_INVALID_ADDRESS);
        address_type = eAddressTypeHost;
        if (exe_ctx)
        {
            Target *target = exe_ctx->GetTargetPtr();
            if (target)
            {
                data.SetByteOrder(target->GetArchitecture().GetByteOrder());
                data.SetAddressByteSize(target->GetArchitecture().GetAddressByteSize());
                break;
            }
        }
        // fallback to host settings
        data.SetByteOrder(endian::InlHostByteOrder());
        data.SetAddressByteSize(sizeof(void *));
        break;
    }

    // Bail if we encountered any errors
    if (error.Fail())
        return error;

    if (address == LLDB_INVALID_ADDRESS)
    {
        error.SetErrorStringWithFormat ("invalid %s address", address_type == eAddressTypeHost ? "host" : "load");
        return error;
    }

    // If we got here, we need to read the value from memory
    size_t byte_size = GetValueByteSize (&error, exe_ctx);

    // Bail if we encountered any errors getting the byte size
    if (error.Fail())
        return error;

    // Make sure we have enough room within "data", and if we don't make
    // something large enough that does
    if (!data.ValidOffsetForDataOfSize (data_offset, byte_size))
    {
        DataBufferSP data_sp(new DataBufferHeap (data_offset + byte_size, '\0'));
        data.SetData(data_sp);
    }

    uint8_t* dst = const_cast<uint8_t*>(data.PeekData (data_offset, byte_size));
    if (dst != NULL)
    {
        if (address_type == eAddressTypeHost)
        {
            // The address is an address in this process, so just copy it.
            if (address == 0)
            {
                error.SetErrorStringWithFormat("trying to read from host address of 0.");
                return error;
            }
            memcpy (dst, (uint8_t*)NULL + address, byte_size);
        }
        else if ((address_type == eAddressTypeLoad) || (address_type == eAddressTypeFile))
        {
            if (file_so_addr.IsValid())
            {
                // We have a file address that we were able to translate into a
                // section offset address so we might be able to read this from
                // the object files if we don't have a live process. Lets always
                // try and read from the process if we have one though since we
                // want to read the actual value by setting "prefer_file_cache"
                // to false. 
                const bool prefer_file_cache = false;
                if (exe_ctx->GetTargetRef().ReadMemory(file_so_addr, prefer_file_cache, dst, byte_size, error) != byte_size)
                {
                    error.SetErrorStringWithFormat("read memory from 0x%" PRIx64 " failed", (uint64_t)address);
                }
            }
            else
            {
                // The execution context might have a NULL process, but it
                // might have a valid process in the exe_ctx->target, so use
                // the ExecutionContext::GetProcess accessor to ensure we
                // get the process if there is one.
                Process *process = exe_ctx->GetProcessPtr();

                if (process)
                {
                    const size_t bytes_read = process->ReadMemory(address, dst, byte_size, error);
                    if (bytes_read != byte_size)
                        error.SetErrorStringWithFormat("read memory from 0x%" PRIx64 " failed (%u of %u bytes read)",
                                                       (uint64_t)address, 
                                                       (uint32_t)bytes_read, 
                                                       (uint32_t)byte_size);
                }
                else
                {
                    error.SetErrorStringWithFormat("read memory from 0x%" PRIx64 " failed (invalid process)", (uint64_t)address);
                }
            }
        }
        else
        {
            error.SetErrorStringWithFormat ("unsupported AddressType value (%i)", address_type);
        }
    }
    else
    {
        error.SetErrorStringWithFormat ("out of memory");
    }

    return error;
}
Пример #8
0
static void
PrivateAutoComplete (StackFrame *frame,
                     const std::string &partial_path,
                     const std::string &prefix_path, // Anything that has been resolved already will be in here
                     const CompilerType& compiler_type,
                     StringList &matches,
                     bool &word_complete)
{
//    printf ("\nPrivateAutoComplete()\n\tprefix_path = '%s'\n\tpartial_path = '%s'\n", prefix_path.c_str(), partial_path.c_str());
    std::string remaining_partial_path;

    const lldb::TypeClass type_class = compiler_type.GetTypeClass();
    if (partial_path.empty())
    {
        if (compiler_type.IsValid())
        {
            switch (type_class)
            {
                default:
                case eTypeClassArray:
                case eTypeClassBlockPointer:
                case eTypeClassBuiltin:
                case eTypeClassComplexFloat:
                case eTypeClassComplexInteger:
                case eTypeClassEnumeration:
                case eTypeClassFunction:
                case eTypeClassMemberPointer:
                case eTypeClassReference:
                case eTypeClassTypedef:
                case eTypeClassVector:
                    {
                        matches.AppendString (prefix_path);
                        word_complete = matches.GetSize() == 1;
                    }
                    break;
                    
                case eTypeClassClass:
                case eTypeClassStruct:
                case eTypeClassUnion:
                    if (prefix_path.back() != '.')
                        matches.AppendString (prefix_path + '.');
                    break;

                case eTypeClassObjCObject:
                case eTypeClassObjCInterface:
                    break;
                case eTypeClassObjCObjectPointer:
                case eTypeClassPointer:
                    {
                        bool omit_empty_base_classes = true;
                        if (compiler_type.GetNumChildren (omit_empty_base_classes) > 0)
                            matches.AppendString (prefix_path + "->");
                        else
                        {
                            matches.AppendString (prefix_path);
                            word_complete = true;
                        }
                    }
                    break;
            }
        }
        else
        {
            if (frame)
            {
                const bool get_file_globals = true;
                
                VariableList *variable_list = frame->GetVariableList(get_file_globals);
                
                if (variable_list)
                {
                    const size_t num_variables = variable_list->GetSize();
                    for (size_t i=0; i<num_variables; ++i)
                    {
                        Variable *variable = variable_list->GetVariableAtIndex(i).get();
                        matches.AppendString (variable->GetName().AsCString());
                    }
                }
            }
        }
    }
    else
    {
        const char ch = partial_path[0];
        switch (ch)
        {
        case '*':
            if (prefix_path.empty())
            {
                PrivateAutoComplete (frame,
                                     partial_path.substr(1),
                                     std::string("*"),
                                     compiler_type,
                                     matches,
                                     word_complete);
            }
            break;

        case '&':
            if (prefix_path.empty())
            {
                PrivateAutoComplete (frame,
                                     partial_path.substr(1),
                                     std::string("&"),
                                     compiler_type,
                                     matches,
                                     word_complete);
            }
            break;

        case '-':
            if (partial_path[1] == '>' && !prefix_path.empty())
            {
                switch (type_class)
                {
                    case lldb::eTypeClassPointer:
                        {
                            CompilerType pointee_type(compiler_type.GetPointeeType());
                            if (partial_path[2])
                            {
                                // If there is more after the "->", then search deeper
                                PrivateAutoComplete (frame,
                                                     partial_path.substr(2),
                                                     prefix_path + "->",
                                                     pointee_type.GetCanonicalType(),
                                                     matches,
                                                     word_complete);
                            }
                            else
                            {
                                // Nothing after the "->", so list all members
                                PrivateAutoCompleteMembers (frame,
                                                            std::string(),
                                                            std::string(),
                                                            prefix_path + "->",
                                                            pointee_type.GetCanonicalType(),
                                                            matches,
                                                            word_complete);                            
                            }
                        }
                        break;
                    default:
                        break;
                }
            }
            break;
            
        case '.':
            if (compiler_type.IsValid())
            {
                switch (type_class)
                {
                    case lldb::eTypeClassUnion:
                    case lldb::eTypeClassStruct:
                    case lldb::eTypeClassClass:
                        if (partial_path[1])
                        {
                            // If there is more after the ".", then search deeper
                            PrivateAutoComplete (frame,
                                                 partial_path.substr(1),
                                                 prefix_path + ".",
                                                 compiler_type,
                                                 matches,
                                                 word_complete);
                            
                        }
                        else
                        {
                            // Nothing after the ".", so list all members
                            PrivateAutoCompleteMembers (frame,
                                                        std::string(),
                                                        partial_path,
                                                        prefix_path + ".",
                                                        compiler_type,
                                                        matches,
                                                        word_complete);
                        }
                        break;
                    default:
                        break;
                }
            }
            break;
        default:
            if (isalpha(ch) || ch == '_' || ch == '$')
            {
                const size_t partial_path_len = partial_path.size();
                size_t pos = 1;
                while (pos < partial_path_len)
                {
                    const char curr_ch = partial_path[pos];
                    if (isalnum(curr_ch) || curr_ch == '_'  || curr_ch == '$')
                    {
                        ++pos;
                        continue;
                    }
                    break;
                }

                std::string token(partial_path, 0, pos);
                remaining_partial_path = partial_path.substr(pos);
                
                if (compiler_type.IsValid())
                {
                    PrivateAutoCompleteMembers (frame,
                                                token,
                                                remaining_partial_path,
                                                prefix_path,
                                                compiler_type,
                                                matches,
                                                word_complete);
                }
                else if (frame)
                {
                    // We haven't found our variable yet
                    const bool get_file_globals = true;
                    
                    VariableList *variable_list = frame->GetVariableList(get_file_globals);
                    
                    if (!variable_list)
                        break;
                    
                    const size_t num_variables = variable_list->GetSize();
                    for (size_t i=0; i<num_variables; ++i)
                    {
                        Variable *variable = variable_list->GetVariableAtIndex(i).get();
                        
                        if (!variable)
                            continue;
                        
                        const char *variable_name = variable->GetName().AsCString();
                        if (strstr(variable_name, token.c_str()) == variable_name)
                        {
                            if (strcmp (variable_name, token.c_str()) == 0)
                            {
                                Type *variable_type = variable->GetType();
                                if (variable_type)
                                {
                                    CompilerType variable_compiler_type (variable_type->GetForwardCompilerType ());
                                    PrivateAutoComplete (frame,
                                                         remaining_partial_path,
                                                         prefix_path + token, // Anything that has been resolved already will be in here
                                                         variable_compiler_type.GetCanonicalType(),
                                                         matches,
                                                         word_complete);
                                }
                                else
                                {
                                    matches.AppendString (prefix_path + variable_name);
                                }
                            }
                            else if (remaining_partial_path.empty())
                            {
                                matches.AppendString (prefix_path + variable_name);
                            }
                        }
                    }
                }
            }
            break;
        }
    }
}
Пример #9
0
bool Address::Dump(Stream *s, ExecutionContextScope *exe_scope, DumpStyle style,
                   DumpStyle fallback_style, uint32_t addr_size) const {
  // If the section was nullptr, only load address is going to work unless we
  // are
  // trying to deref a pointer
  SectionSP section_sp(GetSection());
  if (!section_sp && style != DumpStyleResolvedPointerDescription)
    style = DumpStyleLoadAddress;

  ExecutionContext exe_ctx(exe_scope);
  Target *target = exe_ctx.GetTargetPtr();
  // If addr_byte_size is UINT32_MAX, then determine the correct address
  // byte size for the process or default to the size of addr_t
  if (addr_size == UINT32_MAX) {
    if (target)
      addr_size = target->GetArchitecture().GetAddressByteSize();
    else
      addr_size = sizeof(addr_t);
  }

  Address so_addr;
  switch (style) {
  case DumpStyleInvalid:
    return false;

  case DumpStyleSectionNameOffset:
    if (section_sp) {
      section_sp->DumpName(s);
      s->Printf(" + %" PRIu64, m_offset);
    } else {
      s->Address(m_offset, addr_size);
    }
    break;

  case DumpStyleSectionPointerOffset:
    s->Printf("(Section *)%p + ", static_cast<void *>(section_sp.get()));
    s->Address(m_offset, addr_size);
    break;

  case DumpStyleModuleWithFileAddress:
    if (section_sp) {
      ModuleSP module_sp = section_sp->GetModule();
      if (module_sp)
        s->Printf("%s[", module_sp->GetFileSpec().GetFilename().AsCString(
                             "<Unknown>"));
      else
        s->Printf("%s[", "<Unknown>");
    }
    LLVM_FALLTHROUGH;
  case DumpStyleFileAddress: {
    addr_t file_addr = GetFileAddress();
    if (file_addr == LLDB_INVALID_ADDRESS) {
      if (fallback_style != DumpStyleInvalid)
        return Dump(s, exe_scope, fallback_style, DumpStyleInvalid, addr_size);
      return false;
    }
    s->Address(file_addr, addr_size);
    if (style == DumpStyleModuleWithFileAddress && section_sp)
      s->PutChar(']');
  } break;

  case DumpStyleLoadAddress: {
    addr_t load_addr = GetLoadAddress(target);

    /*
     * MIPS:
     * Display address in compressed form for MIPS16 or microMIPS
     * if the address belongs to eAddressClassCodeAlternateISA.
    */
    if (target) {
      const llvm::Triple::ArchType llvm_arch =
          target->GetArchitecture().GetMachine();
      if (llvm_arch == llvm::Triple::mips ||
          llvm_arch == llvm::Triple::mipsel ||
          llvm_arch == llvm::Triple::mips64 ||
          llvm_arch == llvm::Triple::mips64el)
        load_addr = GetCallableLoadAddress(target);
    }

    if (load_addr == LLDB_INVALID_ADDRESS) {
      if (fallback_style != DumpStyleInvalid)
        return Dump(s, exe_scope, fallback_style, DumpStyleInvalid, addr_size);
      return false;
    }
    s->Address(load_addr, addr_size);
  } break;

  case DumpStyleResolvedDescription:
  case DumpStyleResolvedDescriptionNoModule:
  case DumpStyleResolvedDescriptionNoFunctionArguments:
  case DumpStyleNoFunctionName:
    if (IsSectionOffset()) {
      uint32_t pointer_size = 4;
      ModuleSP module_sp(GetModule());
      if (target)
        pointer_size = target->GetArchitecture().GetAddressByteSize();
      else if (module_sp)
        pointer_size = module_sp->GetArchitecture().GetAddressByteSize();

      bool showed_info = false;
      if (section_sp) {
        SectionType sect_type = section_sp->GetType();
        switch (sect_type) {
        case eSectionTypeData:
          if (module_sp) {
            SymbolVendor *sym_vendor = module_sp->GetSymbolVendor();
            if (sym_vendor) {
              Symtab *symtab = sym_vendor->GetSymtab();
              if (symtab) {
                const addr_t file_Addr = GetFileAddress();
                Symbol *symbol =
                    symtab->FindSymbolContainingFileAddress(file_Addr);
                if (symbol) {
                  const char *symbol_name = symbol->GetName().AsCString();
                  if (symbol_name) {
                    s->PutCString(symbol_name);
                    addr_t delta =
                        file_Addr - symbol->GetAddressRef().GetFileAddress();
                    if (delta)
                      s->Printf(" + %" PRIu64, delta);
                    showed_info = true;
                  }
                }
              }
            }
          }
          break;

        case eSectionTypeDataCString:
          // Read the C string from memory and display it
          showed_info = true;
          ReadCStringFromMemory(exe_scope, *this, s);
          break;

        case eSectionTypeDataCStringPointers:
          if (ReadAddress(exe_scope, *this, pointer_size, so_addr)) {
#if VERBOSE_OUTPUT
            s->PutCString("(char *)");
            so_addr.Dump(s, exe_scope, DumpStyleLoadAddress,
                         DumpStyleFileAddress);
            s->PutCString(": ");
#endif
            showed_info = true;
            ReadCStringFromMemory(exe_scope, so_addr, s);
          }
          break;

        case eSectionTypeDataObjCMessageRefs:
          if (ReadAddress(exe_scope, *this, pointer_size, so_addr)) {
            if (target && so_addr.IsSectionOffset()) {
              SymbolContext func_sc;
              target->GetImages().ResolveSymbolContextForAddress(
                  so_addr, eSymbolContextEverything, func_sc);
              if (func_sc.function != nullptr || func_sc.symbol != nullptr) {
                showed_info = true;
#if VERBOSE_OUTPUT
                s->PutCString("(objc_msgref *) -> { (func*)");
                so_addr.Dump(s, exe_scope, DumpStyleLoadAddress,
                             DumpStyleFileAddress);
#else
                s->PutCString("{ ");
#endif
                Address cstr_addr(*this);
                cstr_addr.SetOffset(cstr_addr.GetOffset() + pointer_size);
                func_sc.DumpStopContext(s, exe_scope, so_addr, true, true,
                                        false, true, true);
                if (ReadAddress(exe_scope, cstr_addr, pointer_size, so_addr)) {
#if VERBOSE_OUTPUT
                  s->PutCString("), (char *)");
                  so_addr.Dump(s, exe_scope, DumpStyleLoadAddress,
                               DumpStyleFileAddress);
                  s->PutCString(" (");
#else
                  s->PutCString(", ");
#endif
                  ReadCStringFromMemory(exe_scope, so_addr, s);
                }
#if VERBOSE_OUTPUT
                s->PutCString(") }");
#else
                s->PutCString(" }");
#endif
              }
            }
          }
          break;

        case eSectionTypeDataObjCCFStrings: {
          Address cfstring_data_addr(*this);
          cfstring_data_addr.SetOffset(cfstring_data_addr.GetOffset() +
                                       (2 * pointer_size));
          if (ReadAddress(exe_scope, cfstring_data_addr, pointer_size,
                          so_addr)) {
#if VERBOSE_OUTPUT
            s->PutCString("(CFString *) ");
            cfstring_data_addr.Dump(s, exe_scope, DumpStyleLoadAddress,
                                    DumpStyleFileAddress);
            s->PutCString(" -> @");
#else
            s->PutChar('@');
#endif
            if (so_addr.Dump(s, exe_scope, DumpStyleResolvedDescription))
              showed_info = true;
          }
        } break;

        case eSectionTypeData4:
          // Read the 4 byte data and display it
          showed_info = true;
          s->PutCString("(uint32_t) ");
          DumpUInt(exe_scope, *this, 4, s);
          break;

        case eSectionTypeData8:
          // Read the 8 byte data and display it
          showed_info = true;
          s->PutCString("(uint64_t) ");
          DumpUInt(exe_scope, *this, 8, s);
          break;

        case eSectionTypeData16:
          // Read the 16 byte data and display it
          showed_info = true;
          s->PutCString("(uint128_t) ");
          DumpUInt(exe_scope, *this, 16, s);
          break;

        case eSectionTypeDataPointers:
          // Read the pointer data and display it
          if (ReadAddress(exe_scope, *this, pointer_size, so_addr)) {
            s->PutCString("(void *)");
            so_addr.Dump(s, exe_scope, DumpStyleLoadAddress,
                         DumpStyleFileAddress);

            showed_info = true;
            if (so_addr.IsSectionOffset()) {
              SymbolContext pointer_sc;
              if (target) {
                target->GetImages().ResolveSymbolContextForAddress(
                    so_addr, eSymbolContextEverything, pointer_sc);
                if (pointer_sc.function != nullptr ||
                    pointer_sc.symbol != nullptr) {
                  s->PutCString(": ");
                  pointer_sc.DumpStopContext(s, exe_scope, so_addr, true, false,
                                             false, true, true);
                }
              }
            }
          }
          break;

        default:
          break;
        }
      }

      if (!showed_info) {
        if (module_sp) {
          SymbolContext sc;
          module_sp->ResolveSymbolContextForAddress(
              *this, eSymbolContextEverything, sc);
          if (sc.function || sc.symbol) {
            bool show_stop_context = true;
            const bool show_module = (style == DumpStyleResolvedDescription);
            const bool show_fullpaths = false;
            const bool show_inlined_frames = true;
            const bool show_function_arguments =
                (style != DumpStyleResolvedDescriptionNoFunctionArguments);
            const bool show_function_name = (style != DumpStyleNoFunctionName);
            if (sc.function == nullptr && sc.symbol != nullptr) {
              // If we have just a symbol make sure it is in the right section
              if (sc.symbol->ValueIsAddress()) {
                if (sc.symbol->GetAddressRef().GetSection() != GetSection()) {
                  // don't show the module if the symbol is a trampoline symbol
                  show_stop_context = false;
                }
              }
            }
            if (show_stop_context) {
              // We have a function or a symbol from the same
              // sections as this address.
              sc.DumpStopContext(s, exe_scope, *this, show_fullpaths,
                                 show_module, show_inlined_frames,
                                 show_function_arguments, show_function_name);
            } else {
              // We found a symbol but it was in a different
              // section so it isn't the symbol we should be
              // showing, just show the section name + offset
              Dump(s, exe_scope, DumpStyleSectionNameOffset);
            }
          }
        }
      }
    } else {
      if (fallback_style != DumpStyleInvalid)
        return Dump(s, exe_scope, fallback_style, DumpStyleInvalid, addr_size);
      return false;
    }
    break;

  case DumpStyleDetailedSymbolContext:
    if (IsSectionOffset()) {
      ModuleSP module_sp(GetModule());
      if (module_sp) {
        SymbolContext sc;
        module_sp->ResolveSymbolContextForAddress(
            *this, eSymbolContextEverything | eSymbolContextVariable, sc);
        if (sc.symbol) {
          // If we have just a symbol make sure it is in the same section
          // as our address. If it isn't, then we might have just found
          // the last symbol that came before the address that we are
          // looking up that has nothing to do with our address lookup.
          if (sc.symbol->ValueIsAddress() &&
              sc.symbol->GetAddressRef().GetSection() != GetSection())
            sc.symbol = nullptr;
        }
        sc.GetDescription(s, eDescriptionLevelBrief, target);

        if (sc.block) {
          bool can_create = true;
          bool get_parent_variables = true;
          bool stop_if_block_is_inlined_function = false;
          VariableList variable_list;
          sc.block->AppendVariables(can_create, get_parent_variables,
                                    stop_if_block_is_inlined_function,
                                    [](Variable *) { return true; },
                                    &variable_list);

          const size_t num_variables = variable_list.GetSize();
          for (size_t var_idx = 0; var_idx < num_variables; ++var_idx) {
            Variable *var = variable_list.GetVariableAtIndex(var_idx).get();
            if (var && var->LocationIsValidForAddress(*this)) {
              s->Indent();
              s->Printf("   Variable: id = {0x%8.8" PRIx64 "}, name = \"%s\"",
                        var->GetID(), var->GetName().GetCString());
              Type *type = var->GetType();
              if (type)
                s->Printf(", type = \"%s\"", type->GetName().GetCString());
              else
                s->PutCString(", type = <unknown>");
              s->PutCString(", location = ");
              var->DumpLocationForAddress(s, *this);
              s->PutCString(", decl = ");
              var->GetDeclaration().DumpStopContext(s, false);
              s->EOL();
            }
          }
        }
      }
    } else {
      if (fallback_style != DumpStyleInvalid)
        return Dump(s, exe_scope, fallback_style, DumpStyleInvalid, addr_size);
      return false;
    }
    break;

  case DumpStyleResolvedPointerDescription: {
    Process *process = exe_ctx.GetProcessPtr();
    if (process) {
      addr_t load_addr = GetLoadAddress(target);
      if (load_addr != LLDB_INVALID_ADDRESS) {
        Error memory_error;
        addr_t dereferenced_load_addr =
            process->ReadPointerFromMemory(load_addr, memory_error);
        if (dereferenced_load_addr != LLDB_INVALID_ADDRESS) {
          Address dereferenced_addr;
          if (dereferenced_addr.SetLoadAddress(dereferenced_load_addr,
                                               target)) {
            StreamString strm;
            if (dereferenced_addr.Dump(&strm, exe_scope,
                                       DumpStyleResolvedDescription,
                                       DumpStyleInvalid, addr_size)) {
              s->Address(dereferenced_load_addr, addr_size, " -> ", " ");
              s->Write(strm.GetData(), strm.GetSize());
              return true;
            }
          }
        }
      }
    }
    if (fallback_style != DumpStyleInvalid)
      return Dump(s, exe_scope, fallback_style, DumpStyleInvalid, addr_size);
    return false;
  } break;
  }

  return true;
}
Пример #10
0
bool Registry::SynchronizeCellMLConnection(nsCOMPtr<cellml_apiIConnection> connection)
{
  nsString cellmltext;
  string cellmlname;
  nsresult rv;

  nsCOMPtr<cellml_apiIModel> topmodel; //used when the encapsulation parent is null (in GetNameAccordingToEncapsulationParent)
  rv = connection->GetModelElement(getter_AddRefs(topmodel));
  nsCOMPtr<cellml_apiICellMLElement> parentel;
  rv = topmodel->GetParentElement(getter_AddRefs(parentel));
  while (parentel != NULL) {
    rv = parentel->GetModelElement(getter_AddRefs(topmodel));
    rv = topmodel->GetParentElement(getter_AddRefs(parentel));
  }
  //rv = topmodel->GetName(cellmltext);
  //cout << "Top model: " << ToThinString(cellmltext.get()) << endl;
  
  //First we get the list of the component and any/all encapsulation parents
  vector<string> comp1moduleparents, comp2moduleparents;
  vector<string> comp1modulenames, comp2modulenames;
  nsCOMPtr<cellml_apiIMapComponents> compmap;
  rv = connection->GetComponentMapping(getter_AddRefs(compmap));
  nsCOMPtr<cellml_apiICellMLComponent> component;

  //First
  rv = compmap->GetFirstComponent(getter_AddRefs(component));
  while (component != NULL) {
    string modname = GetModuleNameFrom(component);
    comp1moduleparents.insert(comp1moduleparents.begin(), modname);
    modname = GetNameAccordingToEncapsulationParent(component, topmodel);
    FixName(modname);
    comp1modulenames.insert(comp1modulenames.begin(), modname);
    rv = component->GetEncapsulationParent(getter_AddRefs(component));
  }
  comp1moduleparents.insert(comp1moduleparents.begin(), CurrentModule()->GetModuleName());

  //Second
  rv = compmap->GetSecondComponent(getter_AddRefs(component));
  while (component != NULL) {
    string modname = GetModuleNameFrom(component);
    comp2moduleparents.insert(comp2moduleparents.begin(), modname);
    modname = GetNameAccordingToEncapsulationParent(component, topmodel);
    FixName(modname);
    comp2modulenames.insert(comp2modulenames.begin(), modname);
    rv = component->GetEncapsulationParent(getter_AddRefs(component));
  }
  comp2moduleparents.insert(comp2moduleparents.begin(), CurrentModule()->GetModuleName());

  //cout << "First component's parents: " << ToStringFromVecDelimitedBy(comp1moduleparents, '.') << endl << "Second component's parents: " << ToStringFromVecDelimitedBy(comp2moduleparents, '.') << endl;
  //cout << "First component's names: " << ToStringFromVecDelimitedBy(comp1modulenames, '.') << endl << "Second component's names: " << ToStringFromVecDelimitedBy(comp2modulenames, '.') << endl;
  //Now figure out the 'lowest' common parent in the encapsulation tree:
  string commonparent = "";
  assert(comp1moduleparents.size() > 0 && comp2moduleparents.size() > 0 && comp1moduleparents[0] == comp2moduleparents[0]);
  size_t pnum = 0;
  while (comp1modulenames.size() > 0 && comp2modulenames.size() > 0 &&
         comp1modulenames[0] == comp2modulenames[0]) {
    comp1modulenames.erase(comp1modulenames.begin());
    comp2modulenames.erase(comp2modulenames.begin());
    pnum++;
  }
  commonparent = comp1moduleparents[pnum];

  //At this point, we have the name of the module where the encapsulation happens:
  Module* topmod = CurrentModule();
  if (commonparent != "") {
    topmod = GetModule(commonparent);
  }
  assert(topmod != NULL);

  // cout << "Top module: " << commonparent << endl;
  // cout << "first compartment submodule name: " << ToStringFromVecDelimitedBy(comp1modulenames, '.') << endl;
  // cout << "second compartment submodule name: " << ToStringFromVecDelimitedBy(comp2modulenames, '.') << endl;

  //And we have the full names of the submodules whose variables need to be synchronized.  But there might be multiple variables, so we go through them all:
  nsCOMPtr<cellml_apiIMapVariablesSet> mvs;
  rv = connection->GetVariableMappings(getter_AddRefs(mvs));
  nsCOMPtr<cellml_apiIMapVariablesIterator> mvsi;
  rv = mvs->IterateMapVariables(getter_AddRefs(mvsi));
  nsCOMPtr<cellml_apiIMapVariables> mapvars;
  rv = mvsi->NextMapVariable(getter_AddRefs(mapvars));
  bool somefalse = false;
  while (mapvars != NULL) {
    rv = mapvars->GetFirstVariableName(cellmltext);
    cellmlname = ToThinString(cellmltext.get());
    FixName(cellmlname);
    vector<string> fullvarname = comp1modulenames;
    fullvarname.push_back(cellmlname);
    Variable* firstvar = topmod->GetVariable(fullvarname);
    assert(firstvar != NULL);
    firstvar = firstvar->GetSameVariable();
    rv = mapvars->GetSecondVariableName(cellmltext);
    cellmlname = ToThinString(cellmltext.get());
    FixName(cellmlname);
    fullvarname = comp2modulenames;
    fullvarname.push_back(cellmlname);
    Variable* secondvar = topmod->GetVariable(fullvarname);
    assert(secondvar != NULL);
    secondvar = secondvar->GetSameVariable();
    //Now we create a local name for the variables to be synchronized if one doesn't already exist.
    vector<string> firstvarname = firstvar->GetName();
    vector<string> secondvarname = secondvar->GetName();
    if (firstvarname.size() > 1 && secondvarname.size() > 1) {
      //Create a local variable
      vector<string> newvarname;
      newvarname.push_back(secondvarname[secondvarname.size()-1]);
      Variable* newvar = topmod->GetVariable(newvarname);
      if (newvar == NULL) {
        newvar = topmod->AddOrFindVariable(&newvarname[0]);
      }
      else {
        newvar = topmod->AddNewNumberedVariable(newvarname[0]);
      }
      if (firstvar->Synchronize(newvar)) {
        g_registry.AddWarning("In module '" + topmod->GetModuleName() + "', the variables " + firstvar->GetNameDelimitedBy('.') + " and " + newvar->GetNameDelimitedBy('.') + " were unable to be set as equivalent:  " + g_registry.GetError());
        somefalse = true;
      }
      if (secondvar->Synchronize(newvar)) {
        g_registry.AddWarning("In module '" + topmod->GetModuleName() + "', the variables " + secondvar->GetNameDelimitedBy('.') + " and " + newvar->GetNameDelimitedBy('.') + " were unable to be set as equivalent:  " + g_registry.GetError());
        somefalse = true;
      }
    }
    else {
      if (firstvar->Synchronize(secondvar)) {
        g_registry.AddWarning("In module '" + topmod->GetModuleName() + "', the variables " + firstvar->GetNameDelimitedBy('.') + " and " + secondvar->GetNameDelimitedBy('.') + " were unable to be set as equivalent:  " + g_registry.GetError());
        somefalse = true;
      }
    }
    rv = mvsi->NextMapVariable(getter_AddRefs(mapvars));
  }
  return somefalse;
}  
Пример #11
0
void InferSummaries(const Vector<BlockSummary*> &summary_list)
{
  static BaseTimer infer_timer("infer_summaries");
  Timer _timer(&infer_timer);

  if (summary_list.Empty())
    return;

  Variable *function = summary_list[0]->GetId()->BaseVar();
  Vector<BlockCFG*> *annot_list = BodyAnnotCache.Lookup(function->GetName());

  // all traces which might refer to the result of pointer arithmetic.
  Vector<Exp*> arithmetic_list;
  ArithmeticEscape escape(function, arithmetic_list);

  // initial pass over the CFGs to get traces used in pointer arithmetic.
  for (size_t ind = 0; ind < summary_list.Size(); ind++) {
    BlockSummary *sum = summary_list[ind];

    BlockCFG *cfg = sum->GetMemory()->GetCFG();
    for (size_t eind = 0; eind < cfg->GetEdgeCount(); eind++) {
      PEdge *edge = cfg->GetEdge(eind);

      if (PEdgeAssign *assign_edge = edge->IfAssign()) {
        Exp *left = assign_edge->GetLeftSide();
        Exp *right = assign_edge->GetRightSide();
        ProcessArithmeticAssign(&escape, cfg->GetId(), left, right);
      }
    }
  }

  for (size_t ind = 0; ind < summary_list.Size(); ind++) {
    BlockSummary *sum = summary_list[ind];
    BlockMemory *mcfg = sum->GetMemory();
    BlockCFG *cfg = mcfg->GetCFG();

    // accumulate all the assertions at points in the CFG.
    Vector<AssertInfo> asserts;

    // add assertions at function exit for any postconditions.
    if (cfg->GetId()->Kind() == B_Function) {
      for (size_t aind = 0; annot_list && aind < annot_list->Size(); aind++) {
        BlockCFG *annot_cfg = annot_list->At(aind);

        if (annot_cfg->GetAnnotationKind() != AK_Postcondition)
          continue;
        if (Bit *bit = BlockMemory::GetAnnotationBit(annot_cfg)) {
          AssertInfo info;
          info.kind = ASK_Annotation;
          info.cls = ASC_Check;
          info.point = cfg->GetExitPoint();
          info.bit = bit;
          asserts.PushBack(info);
        }
      }
    }

    // add assertions for any point annotations within the CFG.
    for (size_t pind = 0; pind < cfg->GetPointAnnotationCount(); pind++) {
      PointAnnotation pann = cfg->GetPointAnnotation(pind);
      BlockCFG *annot_cfg = GetAnnotationCFG(pann.annot);
      if (!annot_cfg) continue;

      if (annot_cfg->GetAnnotationKind() != AK_Assert)
        continue;

      if (Bit *bit = BlockMemory::GetAnnotationBit(annot_cfg)) {
        AssertInfo info;
        info.kind = ASK_Annotation;
        info.cls = ASC_Check;
        info.point = pann.point;
        info.bit = bit;
        asserts.PushBack(info);
      }
    }

    for (size_t eind = 0; eind < cfg->GetEdgeCount(); eind++) {
      PEdge *edge = cfg->GetEdge(eind);
      PPoint point = edge->GetSource();

      if (PEdgeAnnotation *nedge = edge->IfAnnotation()) {
        // add an assertion for this annotation if it not an assume.
        BlockCFG *annot_cfg = GetAnnotationCFG(nedge->GetAnnotationId());
        if (!annot_cfg) continue;

        if (annot_cfg->GetAnnotationKind() != AK_Assert &&
            annot_cfg->GetAnnotationKind() != AK_AssertRuntime) {
          continue;
        }

        if (Bit *bit = BlockMemory::GetAnnotationBit(annot_cfg)) {
          AssertInfo info;
          info.kind = (annot_cfg->GetAnnotationKind() == AK_Assert)
            ? ASK_Annotation : ASK_AnnotationRuntime;
          info.cls = ASC_Check;
          info.point = point;
          info.bit = bit;
          asserts.PushBack(info);
        }
      }

      // add assertions for any invariants affected by a write.

      Exp *left = NULL;
      if (PEdgeAssign *nedge = edge->IfAssign())
        left = nedge->GetLeftSide();
      if (PEdgeCall *nedge = edge->IfCall())
        left = nedge->GetReturnValue();

      // for now our detection of affected invariants is pretty crude;
      // writes to fields can affect type invariants on the field's type
      // which use that field, and writes to global variables can affect
      // invariants on that global. TODO: pin this down once we draw a
      // precise line between which invariants can and can't be checked.

      if (left && left->IsFld()) {
        ExpFld *nleft = left->AsFld();
        String *csu_name = nleft->GetField()->GetCSUType()->GetCSUName();
        Vector<BlockCFG*> *comp_annot_list = CompAnnotCache.Lookup(csu_name);

        for (size_t aind = 0; comp_annot_list &&
                              aind < comp_annot_list->Size(); aind++) {
          BlockCFG *annot_cfg = comp_annot_list->At(aind);

          if (annot_cfg->GetAnnotationKind() != AK_Invariant)
            continue;
          Bit *bit = BlockMemory::GetAnnotationBit(annot_cfg);
          if (!bit) continue;

          Vector<Exp*> lval_list;
          LvalListVisitor visitor(&lval_list);
          bit->DoVisit(&visitor);

          bool uses_field = false;
          for (size_t ind = 0; ind < lval_list.Size(); ind++) {
            if (ExpFld *lval = lval_list[ind]->IfFld()) {
              if (lval->GetField() == nleft->GetField())
                uses_field = true;
            }
          }

          if (uses_field) {
            // this is a type invariant which uses the field being written
            // as an lvalue. we need to assert this write preserves
            // the invariant.
            BlockId *id = annot_cfg->GetId();
            Variable *this_var = Variable::Make(id, VK_This, NULL, 0, NULL);
            Exp *this_exp = Exp::MakeVar(this_var);
            Exp *this_drf = Exp::MakeDrf(this_exp);

            Bit *new_bit = BitReplaceExp(bit, this_drf, nleft->GetTarget());

            AssertInfo info;
            info.kind = ASK_Invariant;
            info.cls = ASC_Check;
            info.point = point;
            info.bit = new_bit;
            asserts.PushBack(info);
          }
        }

        CompAnnotCache.Release(csu_name);
      }

      if (left && left->IsVar()) {
        Variable *var = left->AsVar()->GetVariable();
        if (var->Kind() == VK_Glob) {
          Vector<BlockCFG*> *glob_annot_list =
            InitAnnotCache.Lookup(var->GetName());

          for (size_t aind = 0; glob_annot_list &&
                                aind < glob_annot_list->Size(); aind++) {
            BlockCFG *annot_cfg = glob_annot_list->At(aind);

            Bit *bit = BlockMemory::GetAnnotationBit(annot_cfg);
            if (!bit) continue;

            AssertInfo info;
            info.kind = ASK_Invariant;
            info.cls = ASC_Check;
            info.point = point;
            info.bit = bit;
            asserts.PushBack(info);
          }

          InitAnnotCache.Release(var->GetName());
        }
      }

      if (PEdgeCall *nedge = edge->IfCall()) {
        // add assertions for any callee preconditions.

        // pull preconditions from both direct and indirect calls.
        Vector<Variable*> callee_names;

        if (Variable *callee = nedge->GetDirectFunction()) {
          callee_names.PushBack(callee);
        }
        else {
          CallEdgeSet *callees = CalleeCache.Lookup(function);

          if (callees) {
            for (size_t cind = 0; cind < callees->GetEdgeCount(); cind++) {
              const CallEdge &edge = callees->GetEdge(cind);
              if (edge.where.id == cfg->GetId() && edge.where.point == point)
                callee_names.PushBack(edge.callee);
            }
          }

          // CalleeCache release is below.
        }

        for (size_t cind = 0; cind < callee_names.Size(); cind++) {
          String *callee = callee_names[cind]->GetName();
          Vector<BlockCFG*> *call_annot_list = BodyAnnotCache.Lookup(callee);

          for (size_t aind = 0;
               call_annot_list && aind < call_annot_list->Size(); aind++) {
            BlockCFG *annot_cfg = call_annot_list->At(aind);

            if (annot_cfg->GetAnnotationKind() != AK_Precondition)
              continue;
            if (Bit *bit = BlockMemory::GetAnnotationBit(annot_cfg)) {
              ConvertCallsiteMapper mapper(cfg, point, false);
              Bit *caller_bit = bit->DoMap(&mapper);
              if (!caller_bit)
                continue;

              AssertInfo info;
              info.kind = ASK_Annotation;
              info.cls = ASC_Check;
              info.point = point;
              info.bit = caller_bit;
              asserts.PushBack(info);
            }
          }

          BodyAnnotCache.Release(callee);
        }

        if (!nedge->GetDirectFunction())
          CalleeCache.Release(function);
      }

      BufferScanVisitor write_visitor(asserts, arithmetic_list, point, true);
      BufferScanVisitor read_visitor(asserts, arithmetic_list, point, false);
      IntegerScanVisitor integer_visitor(asserts, point);
      GCScanVisitor gcsafe_visitor(asserts, point);

      // only look at the written lvalues for the write visitor.
      if (PEdgeAssign *assign = edge->IfAssign())
        write_visitor.Visit(assign->GetLeftSide());
      if (PEdgeCall *call = edge->IfCall()) {
        if (Exp *returned = call->GetReturnValue())
          write_visitor.Visit(returned);
      }

      edge->DoVisit(&read_visitor);

      // disable integer overflow visitor for now.
      // edge->DoVisit(&integer_visitor);

      edge->DoVisit(&gcsafe_visitor);
    }

    if (cfg->GetId()->Kind() == B_Function) {
      BlockModset *modset = GetBlockModset(cfg->GetId());
      if (modset->CanGC()) {
        AssertInfo info;
        info.kind = ASK_CanGC;
        info.cls = ASC_Check;
        info.point = cfg->GetExitPoint();

        String *name = cfg->GetId()->BaseVar()->GetName();
        Variable *var = Variable::Make(NULL, VK_Glob, name, 0, name);
        Exp *varexp = Exp::MakeVar(var);
        Exp *gcsafe = Exp::MakeGCSafe(varexp, false);
        info.bit = Bit::MakeVar(gcsafe);
        asserts.PushBack(info);
      }
    }

    MarkRedundantAssertions(mcfg, asserts);

    // move the finished assertion list into the summary.
    for (size_t ind = 0; ind < asserts.Size(); ind++) {
      const AssertInfo &info = asserts[ind];
      sum->AddAssert(info.kind, info.cls, info.point, info.bit);
    }
  }

  // infer delta and termination invariants for all summaries.
  for (size_t ind = 0; ind < summary_list.Size(); ind++)
    InferInvariants(summary_list[ind], arithmetic_list);

  BodyAnnotCache.Release(function->GetName());
}
Пример #12
0
Error
Value::GetValueAsData (ExecutionContext *exe_ctx, 
                       clang::ASTContext *ast_context, 
                       DataExtractor &data, 
                       uint32_t data_offset,
                       Module *module)
{
    data.Clear();

    Error error;
    lldb::addr_t address = LLDB_INVALID_ADDRESS;
    AddressType address_type = eAddressTypeFile;
    Address file_so_addr;
    switch (m_value_type)
    {
    default:
        error.SetErrorStringWithFormat("invalid value type %i", m_value_type);
        break;

    case eValueTypeScalar:
        data.SetByteOrder (lldb::endian::InlHostByteOrder());
        if (m_context_type == eContextTypeClangType && ast_context)
        {
            uint32_t ptr_bit_width = ClangASTType::GetClangTypeBitWidth (ast_context, 
                                                                     ClangASTContext::GetVoidPtrType(ast_context, false));
            uint32_t ptr_byte_size = (ptr_bit_width + 7) / 8;
            data.SetAddressByteSize (ptr_byte_size);
        }
        else
            data.SetAddressByteSize(sizeof(void *));
        if (m_value.GetData (data))
            return error;   // Success;
        error.SetErrorStringWithFormat("extracting data from value failed");
        break;

    case eValueTypeLoadAddress:
        if (exe_ctx == NULL)
        {
            error.SetErrorString ("can't read load address (no execution context)");
        }
        else 
        {
            Process *process = exe_ctx->GetProcessPtr();
            if (process == NULL)
            {
                error.SetErrorString ("can't read load address (invalid process)");
            }
            else
            {
                address = m_value.ULongLong(LLDB_INVALID_ADDRESS);
                address_type = eAddressTypeLoad;
                data.SetByteOrder(process->GetTarget().GetArchitecture().GetByteOrder());
                data.SetAddressByteSize(process->GetTarget().GetArchitecture().GetAddressByteSize());
            }
        }
        break;

    case eValueTypeFileAddress:
        if (exe_ctx == NULL)
        {
            error.SetErrorString ("can't read file address (no execution context)");
        }
        else if (exe_ctx->GetTargetPtr() == NULL)
        {
            error.SetErrorString ("can't read file address (invalid target)");
        }
        else
        {
            address = m_value.ULongLong(LLDB_INVALID_ADDRESS);
            if (address == LLDB_INVALID_ADDRESS)
            {
                error.SetErrorString ("invalid file address");
            }
            else
            {
                if (module == NULL)
                {
                    // The only thing we can currently lock down to a module so that
                    // we can resolve a file address, is a variable.
                    Variable *variable = GetVariable();
                    if (variable)
                    {
                        SymbolContext var_sc;
                        variable->CalculateSymbolContext(&var_sc);
                        module = var_sc.module_sp.get();
                    }
                }
                
                if (module)
                {
                    bool resolved = false;
                    ObjectFile *objfile = module->GetObjectFile();
                    if (objfile)
                    {
                        Address so_addr(address, objfile->GetSectionList());
                        addr_t load_address = so_addr.GetLoadAddress (exe_ctx->GetTargetPtr());
                        bool process_launched_and_stopped = exe_ctx->GetProcessPtr()
                            ? StateIsStoppedState(exe_ctx->GetProcessPtr()->GetState(), true /* must_exist */)
                            : false;
                        // Don't use the load address if the process has exited.
                        if (load_address != LLDB_INVALID_ADDRESS && process_launched_and_stopped)
                        {
                            resolved = true;
                            address = load_address;
                            address_type = eAddressTypeLoad;
                            data.SetByteOrder(exe_ctx->GetTargetRef().GetArchitecture().GetByteOrder());
                            data.SetAddressByteSize(exe_ctx->GetTargetRef().GetArchitecture().GetAddressByteSize());
                        }
                        else
                        {
                            if (so_addr.IsSectionOffset())
                            {
                                resolved = true;
                                file_so_addr = so_addr;
                                data.SetByteOrder(objfile->GetByteOrder());
                                data.SetAddressByteSize(objfile->GetAddressByteSize());
                            }
                        }
                    }
                    if (!resolved)
                    {
                        Variable *variable = GetVariable();
                        
                        if (module)
                        {
                            if (variable)
                                error.SetErrorStringWithFormat ("unable to resolve the module for file address 0x%llx for variable '%s' in %s%s%s", 
                                                                address, 
                                                                variable->GetName().AsCString(""),
                                                                module->GetFileSpec().GetDirectory().GetCString(),
                                                                module->GetFileSpec().GetDirectory() ? "/" : "",
                                                                module->GetFileSpec().GetFilename().GetCString());
                            else
                                error.SetErrorStringWithFormat ("unable to resolve the module for file address 0x%llx in %s%s%s", 
                                                                address, 
                                                                module->GetFileSpec().GetDirectory().GetCString(),
                                                                module->GetFileSpec().GetDirectory() ? "/" : "",
                                                                module->GetFileSpec().GetFilename().GetCString());
                        }
                        else
                        {
                            if (variable)
                                error.SetErrorStringWithFormat ("unable to resolve the module for file address 0x%llx for variable '%s'", 
                                                                address, 
                                                                variable->GetName().AsCString(""));
                            else
                                error.SetErrorStringWithFormat ("unable to resolve the module for file address 0x%llx", address);
                        }
                    }
                }
                else
                {
                    // Can't convert a file address to anything valid without more
                    // context (which Module it came from)
                    error.SetErrorString ("can't read memory from file address without more context");
                }
            }
        }
        break;

    case eValueTypeHostAddress:
        address = m_value.ULongLong(LLDB_INVALID_ADDRESS);
        address_type = eAddressTypeHost;
        if (exe_ctx)
        {
            Target *target = exe_ctx->GetTargetPtr();
            if (target)
            {
                data.SetByteOrder(target->GetArchitecture().GetByteOrder());
                data.SetAddressByteSize(target->GetArchitecture().GetAddressByteSize());
                break;
            }
        }
        // fallback to host settings
        data.SetByteOrder(lldb::endian::InlHostByteOrder());
        data.SetAddressByteSize(sizeof(void *));
        break;
    }

    // Bail if we encountered any errors
    if (error.Fail())
        return error;

    if (address == LLDB_INVALID_ADDRESS)
    {
        error.SetErrorStringWithFormat ("invalid %s address", address_type == eAddressTypeHost ? "host" : "load");
        return error;
    }

    // If we got here, we need to read the value from memory
    uint32_t byte_size = GetValueByteSize (ast_context, &error);

    // Bail if we encountered any errors getting the byte size
    if (error.Fail())
        return error;

    // Make sure we have enough room within "data", and if we don't make
    // something large enough that does
    if (!data.ValidOffsetForDataOfSize (data_offset, byte_size))
    {
        DataBufferSP data_sp(new DataBufferHeap (data_offset + byte_size, '\0'));
        data.SetData(data_sp);
    }

    uint8_t* dst = const_cast<uint8_t*>(data.PeekData (data_offset, byte_size));
    if (dst != NULL)
    {
        if (address_type == eAddressTypeHost)
        {
            // The address is an address in this process, so just copy it
            memcpy (dst, (uint8_t*)NULL + address, byte_size);
        }
        else if ((address_type == eAddressTypeLoad) || (address_type == eAddressTypeFile))
        {
            if (file_so_addr.IsValid())
            {
                // We have a file address that we were able to translate into a
                // section offset address so we might be able to read this from
                // the object files if we don't have a live process. Lets always
                // try and read from the process if we have one though since we
                // want to read the actual value by setting "prefer_file_cache"
                // to false. 
                const bool prefer_file_cache = false;
                if (exe_ctx->GetTargetRef().ReadMemory(file_so_addr, prefer_file_cache, dst, byte_size, error) != byte_size)
                {
                    error.SetErrorStringWithFormat("read memory from 0x%llx failed", (uint64_t)address);
                }
            }
            else
            {
                // The execution context might have a NULL process, but it
                // might have a valid process in the exe_ctx->target, so use
                // the ExecutionContext::GetProcess accessor to ensure we
                // get the process if there is one.
                Process *process = exe_ctx->GetProcessPtr();

                if (process)
                {
                    const size_t bytes_read = process->ReadMemory(address, dst, byte_size, error);
                    if (bytes_read != byte_size)
                        error.SetErrorStringWithFormat("read memory from 0x%llx failed (%u of %u bytes read)", 
                                                       (uint64_t)address, 
                                                       (uint32_t)bytes_read, 
                                                       (uint32_t)byte_size);
                }
                else
                {
                    error.SetErrorStringWithFormat("read memory from 0x%llx failed (invalid process)", (uint64_t)address);                    
                }
            }
        }
        else
        {
            error.SetErrorStringWithFormat ("unsupported AddressType value (%i)", address_type);
        }
    }
    else
    {
        error.SetErrorStringWithFormat ("out of memory");
    }

    return error;
}