static bool GetNetBSDProcessArgs (const ProcessInstanceInfoMatch *match_info_ptr, ProcessInstanceInfo &process_info) { if (!process_info.ProcessIDIsValid()) return false; int pid = process_info.GetProcessID(); int mib[4] = { CTL_KERN, KERN_PROC_ARGS, pid, KERN_PROC_ARGV }; char arg_data[8192]; size_t arg_data_size = sizeof(arg_data); if (::sysctl (mib, 4, arg_data, &arg_data_size , NULL, 0) != 0) return false; DataExtractor data (arg_data, arg_data_size, lldb::endian::InlHostByteOrder(), sizeof(void *)); lldb::offset_t offset = 0; const char *cstr; cstr = data.GetCStr (&offset); if (!cstr) return false; process_info.GetExecutableFile().SetFile(cstr, false); if (!(match_info_ptr == NULL || NameMatches (process_info.GetExecutableFile().GetFilename().GetCString(), match_info_ptr->GetNameMatchType(), match_info_ptr->GetProcessInfo().GetName()))) return false; Args &proc_args = process_info.GetArguments(); while (1) { const uint8_t *p = data.PeekData(offset, 1); while ((p != NULL) && (*p == '\0') && offset < arg_data_size) { ++offset; p = data.PeekData(offset, 1); } if (p == NULL || offset >= arg_data_size) break; cstr = data.GetCStr(&offset); if (!cstr) break; proc_args.AppendArgument(cstr); } return true; }
bool Type::ReadFromMemory(ExecutionContext *exe_ctx, lldb::addr_t addr, AddressType address_type, DataExtractor &data) { if (address_type == eAddressTypeFile) { // Can't convert a file address to anything valid without more // context (which Module it came from) return false; } const uint64_t byte_size = GetByteSize(); if (data.GetByteSize() < byte_size) { lldb::DataBufferSP data_sp(new DataBufferHeap(byte_size, '\0')); data.SetData(data_sp); } uint8_t *dst = const_cast<uint8_t *>(data.PeekData(0, byte_size)); if (dst != nullptr) { if (address_type == eAddressTypeHost) { // The address is an address in this process, so just copy it if (addr == 0) return false; memcpy(dst, (uint8_t *)nullptr + addr, byte_size); return true; } else { if (exe_ctx) { Process *process = exe_ctx->GetProcessPtr(); if (process) { Error error; return exe_ctx->GetProcessPtr()->ReadMemory(addr, dst, byte_size, error) == byte_size; } } } } return false; }
bool ObjectContainerBSDArchive::MagicBytesMatch (const DataExtractor &data) { uint32_t offset = 0; const char* armag = (const char* )data.PeekData (offset, sizeof(ar_hdr)); if (armag && ::strncmp(armag, ARMAG, SARMAG) == 0) { armag += offsetof(struct ar_hdr, ar_fmag) + SARMAG; if (strncmp(armag, ARFMAG, 2) == 0) return true; }
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; }
virtual void CalculateMnemonicOperandsAndComment (const lldb_private::ExecutionContext *exe_ctx) { DataExtractor data; const AddressClass address_class = GetAddressClass (); if (m_opcode.GetData(data)) { char out_string[512]; DisassemblerLLVMC &llvm_disasm = GetDisassemblerLLVMC(); DisassemblerLLVMC::LLVMCDisassembler *mc_disasm_ptr; if (address_class == eAddressClassCodeAlternateISA) mc_disasm_ptr = llvm_disasm.m_alternate_disasm_ap.get(); else mc_disasm_ptr = llvm_disasm.m_disasm_ap.get(); lldb::addr_t pc = m_address.GetFileAddress(); m_using_file_addr = true; const bool data_from_file = GetDisassemblerLLVMC().m_data_from_file; bool use_hex_immediates = true; Disassembler::HexImmediateStyle hex_style = Disassembler::eHexStyleC; if (exe_ctx) { Target *target = exe_ctx->GetTargetPtr(); if (target) { use_hex_immediates = target->GetUseHexImmediates(); hex_style = target->GetHexImmediateStyle(); if (!data_from_file) { const lldb::addr_t load_addr = m_address.GetLoadAddress(target); if (load_addr != LLDB_INVALID_ADDRESS) { pc = load_addr; m_using_file_addr = false; } } } } llvm_disasm.Lock(this, exe_ctx); const uint8_t *opcode_data = data.GetDataStart(); const size_t opcode_data_len = data.GetByteSize(); llvm::MCInst inst; size_t inst_size = mc_disasm_ptr->GetMCInst (opcode_data, opcode_data_len, pc, inst); if (inst_size > 0) { mc_disasm_ptr->SetStyle(use_hex_immediates, hex_style); mc_disasm_ptr->PrintMCInst(inst, out_string, sizeof(out_string)); } llvm_disasm.Unlock(); if (inst_size == 0) { m_comment.assign ("unknown opcode"); inst_size = m_opcode.GetByteSize(); StreamString mnemonic_strm; lldb::offset_t offset = 0; lldb::ByteOrder byte_order = data.GetByteOrder(); switch (inst_size) { case 1: { const uint8_t uval8 = data.GetU8 (&offset); m_opcode.SetOpcode8 (uval8, byte_order); m_opcode_name.assign (".byte"); mnemonic_strm.Printf("0x%2.2x", uval8); } break; case 2: { const uint16_t uval16 = data.GetU16(&offset); m_opcode.SetOpcode16(uval16, byte_order); m_opcode_name.assign (".short"); mnemonic_strm.Printf("0x%4.4x", uval16); } break; case 4: { const uint32_t uval32 = data.GetU32(&offset); m_opcode.SetOpcode32(uval32, byte_order); m_opcode_name.assign (".long"); mnemonic_strm.Printf("0x%8.8x", uval32); } break; case 8: { const uint64_t uval64 = data.GetU64(&offset); m_opcode.SetOpcode64(uval64, byte_order); m_opcode_name.assign (".quad"); mnemonic_strm.Printf("0x%16.16" PRIx64, uval64); } break; default: if (inst_size == 0) return; else { const uint8_t *bytes = data.PeekData(offset, inst_size); if (bytes == NULL) return; m_opcode_name.assign (".byte"); m_opcode.SetOpcodeBytes(bytes, inst_size); mnemonic_strm.Printf("0x%2.2x", bytes[0]); for (uint32_t i=1; i<inst_size; ++i) mnemonic_strm.Printf(" 0x%2.2x", bytes[i]); } break; } m_mnemonics.swap(mnemonic_strm.GetString()); return; } else { if (m_does_branch == eLazyBoolCalculate) { const bool can_branch = mc_disasm_ptr->CanBranch(inst); if (can_branch) m_does_branch = eLazyBoolYes; else m_does_branch = eLazyBoolNo; } } static RegularExpression s_regex("[ \t]*([^ ^\t]+)[ \t]*([^ ^\t].*)?", REG_EXTENDED); RegularExpression::Match matches(3); if (s_regex.Execute(out_string, &matches)) { matches.GetMatchAtIndex(out_string, 1, m_opcode_name); matches.GetMatchAtIndex(out_string, 2, m_mnemonics); } } }
bool RegisterContextMach_i386::WriteRegisterBytes (uint32_t reg, DataExtractor &data, uint32_t data_offset) { int set = GetSetForNativeRegNum (reg); if (set == -1) return false; if (ReadRegisterSet(set, false) != KERN_SUCCESS) return false; const RegisterInfo * reg_info = GetRegisterInfoAtIndex (reg); if (reg_info == NULL && data.ValidOffsetForDataOfSize(data_offset, reg_info->byte_size)) return false; uint32_t offset = data_offset; switch (reg) { case gpr_eax: case gpr_ebx: case gpr_ecx: case gpr_edx: case gpr_edi: case gpr_esi: case gpr_ebp: case gpr_esp: case gpr_ss: case gpr_eflags: case gpr_eip: case gpr_cs: case gpr_ds: case gpr_es: case gpr_fs: case gpr_gs: (&gpr.eax)[reg - gpr_eax] = data.GetU32 (&offset); break; case fpu_fcw: fpu.fcw = data.GetU16(&offset); break; case fpu_fsw: fpu.fsw = data.GetU16(&offset); break; case fpu_ftw: fpu.ftw = data.GetU8(&offset); break; case fpu_fop: fpu.fop = data.GetU16(&offset); break; case fpu_ip: fpu.ip = data.GetU32(&offset); break; case fpu_cs: fpu.cs = data.GetU16(&offset); break; case fpu_dp: fpu.dp = data.GetU32(&offset); break; case fpu_ds: fpu.ds = data.GetU16(&offset); break; case fpu_mxcsr: fpu.mxcsr = data.GetU32(&offset); break; case fpu_mxcsrmask: fpu.mxcsrmask = data.GetU32(&offset); break; case fpu_stmm0: case fpu_stmm1: case fpu_stmm2: case fpu_stmm3: case fpu_stmm4: case fpu_stmm5: case fpu_stmm6: case fpu_stmm7: ::memcpy (fpu.stmm[reg - fpu_stmm0].bytes, data.PeekData(offset, reg_info->byte_size), reg_info->byte_size); return false; case fpu_xmm0: case fpu_xmm1: case fpu_xmm2: case fpu_xmm3: case fpu_xmm4: case fpu_xmm5: case fpu_xmm6: case fpu_xmm7: // These values don't fit into scalar types, RegisterContext::ReadRegisterBytes() // must be used for these registers ::memcpy (fpu.xmm[reg - fpu_xmm0].bytes, data.PeekData(offset, reg_info->byte_size), reg_info->byte_size); return false; case exc_trapno: exc.trapno = data.GetU32 (&offset); break; case exc_err: exc.err = data.GetU32 (&offset); break; case exc_faultvaddr: exc.faultvaddr = data.GetU32 (&offset); break; default: return false; } return WriteRegisterSet(set) == KERN_SUCCESS; }
virtual void CalculateMnemonicOperandsAndComment (const lldb_private::ExecutionContext *exe_ctx) { DataExtractor data; const AddressClass address_class = GetAddressClass (); if (m_opcode.GetData(data, address_class)) { char out_string[512]; ::LLVMDisasmContextRef disasm_context; if (address_class == eAddressClassCodeAlternateISA) disasm_context = m_disasm.m_alternate_disasm_context; else disasm_context = m_disasm.m_disasm_context; lldb::addr_t pc = LLDB_INVALID_ADDRESS; if (exe_ctx) { Target *target = exe_ctx->GetTargetPtr(); if (target) pc = m_address.GetLoadAddress(target); } if (pc == LLDB_INVALID_ADDRESS) pc = m_address.GetFileAddress(); m_disasm.Lock(this, exe_ctx); uint8_t *opcode_data = const_cast<uint8_t *>(data.PeekData (0, 1)); const size_t opcode_data_len = data.GetByteSize(); size_t inst_size = ::LLVMDisasmInstruction (disasm_context, opcode_data, opcode_data_len, pc, out_string, sizeof(out_string)); m_disasm.Unlock(); if (inst_size == 0) { m_comment.assign ("unknown opcode"); inst_size = m_opcode.GetByteSize(); StreamString mnemonic_strm; uint32_t offset = 0; switch (inst_size) { case 1: { const uint8_t uval8 = data.GetU8 (&offset); m_opcode.SetOpcode8 (uval8); m_opcode_name.assign (".byte"); mnemonic_strm.Printf("0x%2.2x", uval8); } break; case 2: { const uint16_t uval16 = data.GetU16(&offset); m_opcode.SetOpcode16(uval16); m_opcode_name.assign (".short"); mnemonic_strm.Printf("0x%4.4x", uval16); } break; case 4: { const uint32_t uval32 = data.GetU32(&offset); m_opcode.SetOpcode32(uval32); m_opcode_name.assign (".long"); mnemonic_strm.Printf("0x%8.8x", uval32); } break; case 8: { const uint64_t uval64 = data.GetU64(&offset); m_opcode.SetOpcode64(uval64); m_opcode_name.assign (".quad"); mnemonic_strm.Printf("0x%16.16llx", uval64); } break; default: if (inst_size == 0) return; else { const uint8_t *bytes = data.PeekData(offset, inst_size); if (bytes == NULL) return; m_opcode_name.assign (".byte"); m_opcode.SetOpcodeBytes(bytes, inst_size); mnemonic_strm.Printf("0x%2.2x", bytes[0]); for (uint32_t i=1; i<inst_size; ++i) mnemonic_strm.Printf(" 0x%2.2x", bytes[i]); } break; } m_mnemocics.swap(mnemonic_strm.GetString()); return; } else { if (m_does_branch == eLazyBoolCalculate) { if (StringRepresentsBranch (out_string, strlen(out_string))) m_does_branch = eLazyBoolYes; else m_does_branch = eLazyBoolNo; } } if (!s_regex_compiled) { ::regcomp(&s_regex, "[ \t]*([^ ^\t]+)[ \t]*([^ ^\t].*)?", REG_EXTENDED); s_regex_compiled = true; } ::regmatch_t matches[3]; if (!::regexec(&s_regex, out_string, sizeof(matches) / sizeof(::regmatch_t), matches, 0)) { if (matches[1].rm_so != -1) m_opcode_name.assign(out_string + matches[1].rm_so, matches[1].rm_eo - matches[1].rm_so); if (matches[2].rm_so != -1) m_mnemocics.assign(out_string + matches[2].rm_so, matches[2].rm_eo - matches[2].rm_so); } } }
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; }
bool DWARFFormValue::ExtractValue(const DataExtractor& data, lldb::offset_t* offset_ptr, const DWARFCompileUnit* cu) { bool indirect = false; bool is_block = false; m_value.data = NULL; // Read the value for the form into value and follow and DW_FORM_indirect instances we run into do { indirect = false; switch (m_form) { case DW_FORM_addr: m_value.value.uval = data.GetMaxU64(offset_ptr, DWARFCompileUnit::GetAddressByteSize(cu)); break; case DW_FORM_block2: m_value.value.uval = data.GetU16(offset_ptr); is_block = true; break; case DW_FORM_block4: m_value.value.uval = data.GetU32(offset_ptr); is_block = true; break; case DW_FORM_data2: m_value.value.uval = data.GetU16(offset_ptr); break; case DW_FORM_data4: m_value.value.uval = data.GetU32(offset_ptr); break; case DW_FORM_data8: m_value.value.uval = data.GetU64(offset_ptr); break; case DW_FORM_string: m_value.value.cstr = data.GetCStr(offset_ptr); // Set the string value to also be the data for inlined cstr form values only // so we can tell the differnence between DW_FORM_string and DW_FORM_strp form // values; m_value.data = (uint8_t*)m_value.value.cstr; break; case DW_FORM_exprloc: case DW_FORM_block: m_value.value.uval = data.GetULEB128(offset_ptr); is_block = true; break; case DW_FORM_block1: m_value.value.uval = data.GetU8(offset_ptr); is_block = true; break; case DW_FORM_data1: m_value.value.uval = data.GetU8(offset_ptr); break; case DW_FORM_flag: m_value.value.uval = data.GetU8(offset_ptr); break; case DW_FORM_sdata: m_value.value.sval = data.GetSLEB128(offset_ptr); break; case DW_FORM_strp: m_value.value.uval = data.GetU32(offset_ptr); break; // case DW_FORM_APPLE_db_str: case DW_FORM_udata: m_value.value.uval = data.GetULEB128(offset_ptr); break; case DW_FORM_ref_addr: if (cu->GetVersion() <= 2) m_value.value.uval = data.GetMaxU64(offset_ptr, DWARFCompileUnit::GetAddressByteSize(cu)); else m_value.value.uval = data.GetU32(offset_ptr); // 4 for DWARF32, 8 for DWARF64, but we don't support DWARF64 yet break; case DW_FORM_ref1: m_value.value.uval = data.GetU8(offset_ptr); break; case DW_FORM_ref2: m_value.value.uval = data.GetU16(offset_ptr); break; case DW_FORM_ref4: m_value.value.uval = data.GetU32(offset_ptr); break; case DW_FORM_ref8: m_value.value.uval = data.GetU64(offset_ptr); break; case DW_FORM_ref_udata: m_value.value.uval = data.GetULEB128(offset_ptr); break; case DW_FORM_indirect: m_form = data.GetULEB128(offset_ptr); indirect = true; break; case DW_FORM_sec_offset: m_value.value.uval = data.GetU32(offset_ptr); break; case DW_FORM_flag_present: m_value.value.uval = 1; break; case DW_FORM_ref_sig8: m_value.value.uval = data.GetU64(offset_ptr); break; default: return false; break; } } while (indirect); if (is_block) { m_value.data = data.PeekData(*offset_ptr, m_value.value.uval); if (m_value.data != NULL) { *offset_ptr += m_value.value.uval; } } return true; }