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); }
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); }
//----------------------------------------------------------------------------- // 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; }
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(); } }
//------------------------------------------------------------------------------ // 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(); }
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; }
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; } } }
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; }
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; }
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()); }
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; }