void DumpToLog(IRMemoryMap &map, lldb::addr_t process_address, Log *log) override { StreamString dump_stream; Status err; const lldb::addr_t load_addr = process_address + m_offset; dump_stream.Printf("0x%" PRIx64 ": EntityPersistentVariable (%s)\n", load_addr, m_persistent_variable_sp->GetName().AsCString()); { dump_stream.Printf("Pointer:\n"); DataBufferHeap data(m_size, 0); map.ReadMemory(data.GetBytes(), load_addr, m_size, err); if (!err.Success()) { dump_stream.Printf(" <could not be read>\n"); } else { DumpHexBytes(&dump_stream, data.GetBytes(), data.GetByteSize(), 16, load_addr); dump_stream.PutChar('\n'); } } { dump_stream.Printf("Target:\n"); lldb::addr_t target_address; map.ReadPointerFromMemory(&target_address, load_addr, err); if (!err.Success()) { dump_stream.Printf(" <could not be read>\n"); } else { DataBufferHeap data(m_persistent_variable_sp->GetByteSize(), 0); map.ReadMemory(data.GetBytes(), target_address, m_persistent_variable_sp->GetByteSize(), err); if (!err.Success()) { dump_stream.Printf(" <could not be read>\n"); } else { DumpHexBytes(&dump_stream, data.GetBytes(), data.GetByteSize(), 16, target_address); dump_stream.PutChar('\n'); } } } log->PutString(dump_stream.GetString()); }
Status NativeRegisterContextLinux_mips64::WriteAllRegisterValues( const lldb::DataBufferSP &data_sp) { Status error; if (!data_sp) { error.SetErrorStringWithFormat( "NativeRegisterContextLinux_mips64::%s invalid data_sp provided", __FUNCTION__); return error; } if (data_sp->GetByteSize() != REG_CONTEXT_SIZE) { error.SetErrorStringWithFormat( "NativeRegisterContextLinux_mips64::%s data_sp contained mismatched " "data size, expected %" PRIu64 ", actual %" PRIu64, __FUNCTION__, REG_CONTEXT_SIZE, data_sp->GetByteSize()); return error; } uint8_t *src = data_sp->GetBytes(); if (src == nullptr) { error.SetErrorStringWithFormat("NativeRegisterContextLinux_mips64::%s " "DataBuffer::GetBytes() returned a null " "pointer", __FUNCTION__); return error; } ::memcpy(&m_gpr, src, GetRegisterInfoInterface().GetGPRSize()); src += GetRegisterInfoInterface().GetGPRSize(); ::memcpy(&m_fpr, src, GetFPRSize()); src += GetFPRSize(); ::memcpy(&m_msa, src, sizeof(MSA_linux_mips)); error = WriteGPR(); if (!error.Success()) { error.SetErrorStringWithFormat( "NativeRegisterContextLinux_mips64::%s WriteGPR() failed", __FUNCTION__); return error; } error = WriteCP1(); if (!error.Success()) { error.SetErrorStringWithFormat( "NativeRegisterContextLinux_mips64::%s WriteCP1() failed", __FUNCTION__); return error; } return error; }
Status ProcessFreeBSD::DoAttachToProcessWithID(lldb::pid_t pid, const ProcessAttachInfo &attach_info) { Status error; assert(m_monitor == NULL); Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PROCESS)); LLDB_LOGV(log, "pid = {0}", GetID()); m_monitor = new ProcessMonitor(this, pid, error); if (!error.Success()) return error; PlatformSP platform_sp(GetTarget().GetPlatform()); assert(platform_sp.get()); if (!platform_sp) return error; // FIXME: Detatch? // Find out what we can about this process ProcessInstanceInfo process_info; platform_sp->GetProcessInfo(pid, process_info); // Resolve the executable module ModuleSP exe_module_sp; FileSpecList executable_search_paths( Target::GetDefaultExecutableSearchPaths()); ModuleSpec exe_module_spec(process_info.GetExecutableFile(), GetTarget().GetArchitecture()); error = platform_sp->ResolveExecutable( exe_module_spec, exe_module_sp, executable_search_paths.GetSize() ? &executable_search_paths : NULL); if (!error.Success()) return error; // Fix the target architecture if necessary const ArchSpec &module_arch = exe_module_sp->GetArchitecture(); if (module_arch.IsValid() && !GetTarget().GetArchitecture().IsExactMatch(module_arch)) GetTarget().SetArchitecture(module_arch); // Initialize the target module list GetTarget().SetExecutableModule(exe_module_sp, eLoadDependentsYes); SetSTDIOFileDescriptor(m_monitor->GetTerminalFD()); SetID(pid); return error; }
bool RegisterContextPOSIXProcessMonitor_powerpc::WriteRegister( const unsigned reg, const RegisterValue &value) { unsigned reg_to_write = reg; RegisterValue value_to_write = value; // Check if this is a subregister of a full register. const RegisterInfo *reg_info = GetRegisterInfoAtIndex(reg); if (reg_info->invalidate_regs && (reg_info->invalidate_regs[0] != LLDB_INVALID_REGNUM)) { RegisterValue full_value; uint32_t full_reg = reg_info->invalidate_regs[0]; const RegisterInfo *full_reg_info = GetRegisterInfoAtIndex(full_reg); // Read the full register. if (ReadRegister(full_reg_info, full_value)) { Status error; ByteOrder byte_order = GetByteOrder(); uint8_t dst[RegisterValue::kMaxRegisterByteSize]; // Get the bytes for the full register. const uint32_t dest_size = full_value.GetAsMemoryData( full_reg_info, dst, sizeof(dst), byte_order, error); if (error.Success() && dest_size) { uint8_t src[RegisterValue::kMaxRegisterByteSize]; // Get the bytes for the source data. const uint32_t src_size = value.GetAsMemoryData( reg_info, src, sizeof(src), byte_order, error); if (error.Success() && src_size && (src_size < dest_size)) { // Copy the src bytes to the destination. memcpy(dst + (reg_info->byte_offset & 0x1), src, src_size); // Set this full register as the value to write. value_to_write.SetBytes(dst, full_value.GetByteSize(), byte_order); value_to_write.SetType(full_reg_info); reg_to_write = full_reg; } } } } ProcessMonitor &monitor = GetMonitor(); // Account for the fact that 32-bit targets on powerpc64 really use 64-bit // registers in ptrace, but expose here 32-bit registers with a higher // offset. uint64_t offset = GetRegisterOffset(reg_to_write); offset &= ~(sizeof(uintptr_t) - 1); return monitor.WriteRegisterValue( m_thread.GetID(), offset, GetRegisterName(reg_to_write), value_to_write); }
bool ClangUserExpression::PrepareForParsing( DiagnosticManager &diagnostic_manager, ExecutionContext &exe_ctx) { InstallContext(exe_ctx); if (!SetupPersistentState(diagnostic_manager, exe_ctx)) return false; Status err; ScanContext(exe_ctx, err); if (!err.Success()) { diagnostic_manager.PutString(eDiagnosticSeverityWarning, err.AsCString()); } //////////////////////////////////// // Generate the expression // ApplyObjcCastHack(m_expr_text); SetupDeclVendor(exe_ctx, m_target); UpdateLanguageForExpr(diagnostic_manager, exe_ctx); return true; }
bool Communication::JoinReadThread(Status *error_ptr) { if (!m_read_thread.IsJoinable()) return true; Status error = m_read_thread.Join(nullptr); return error.Success(); }
void DumpToLog(IRMemoryMap &map, lldb::addr_t process_address, Log *log) override { StreamString dump_stream; Status err; const lldb::addr_t load_addr = process_address + m_offset; dump_stream.Printf("0x%" PRIx64 ": EntityRegister (%s)\n", load_addr, m_register_info.name); { dump_stream.Printf("Value:\n"); DataBufferHeap data(m_size, 0); map.ReadMemory(data.GetBytes(), load_addr, m_size, err); if (!err.Success()) { dump_stream.Printf(" <could not be read>\n"); } else { DumpHexBytes(&dump_stream, data.GetBytes(), data.GetByteSize(), 16, load_addr); dump_stream.PutChar('\n'); } } log->PutString(dump_stream.GetString()); }
Status PlatformAndroidRemoteGDBServer::MakeConnectURL( const lldb::pid_t pid, const uint16_t remote_port, llvm::StringRef remote_socket_name, std::string &connect_url) { static const int kAttempsNum = 5; Status error; // There is a race possibility that somebody will occupy a port while we're // in between FindUnusedPort and ForwardPortWithAdb - adding the loop to // mitigate such problem. for (auto i = 0; i < kAttempsNum; ++i) { uint16_t local_port = 0; error = FindUnusedPort(local_port); if (error.Fail()) return error; error = ForwardPortWithAdb(local_port, remote_port, remote_socket_name, m_socket_namespace, m_device_id); if (error.Success()) { m_port_forwards[pid] = local_port; std::ostringstream url_str; url_str << "connect://localhost:" << local_port; connect_url = url_str.str(); break; } } return error; }
Status PipeWindows::CreateNew(llvm::StringRef name, bool child_process_inherit) { if (name.empty()) return Status(ERROR_INVALID_PARAMETER, eErrorTypeWin32); if (CanRead() || CanWrite()) return Status(ERROR_ALREADY_EXISTS, eErrorTypeWin32); std::string pipe_path = "\\\\.\\Pipe\\"; pipe_path.append(name); // Always open for overlapped i/o. We implement blocking manually in Read and // Write. DWORD read_mode = FILE_FLAG_OVERLAPPED; m_read = ::CreateNamedPipeA( pipe_path.c_str(), PIPE_ACCESS_INBOUND | read_mode, PIPE_TYPE_BYTE | PIPE_WAIT, 1, 1024, 1024, 120 * 1000, NULL); if (INVALID_HANDLE_VALUE == m_read) return Status(::GetLastError(), eErrorTypeWin32); m_read_fd = _open_osfhandle((intptr_t)m_read, _O_RDONLY); ZeroMemory(&m_read_overlapped, sizeof(m_read_overlapped)); m_read_overlapped.hEvent = ::CreateEvent(nullptr, TRUE, FALSE, nullptr); // Open the write end of the pipe. Status result = OpenNamedPipe(name, child_process_inherit, false); if (!result.Success()) { CloseReadFileDescriptor(); return result; } return result; }
Status OptionValueDictionary::SetValueFromString(llvm::StringRef value, VarSetOperationType op) { Args args(value.str()); Status error = SetArgs(args, op); if (error.Success()) NotifyValueChanged(); return error; }
bool HostProcessPosix::IsRunning() const { if (m_process == kInvalidPosixProcess) return false; // Send this process the null signal. If it succeeds the process is running. Status error = Signal(0); return error.Success(); }
Status NativeRegisterContextLinux_mips64::ReadAllRegisterValues( lldb::DataBufferSP &data_sp) { Status error; data_sp.reset(new DataBufferHeap(REG_CONTEXT_SIZE, 0)); if (!data_sp) { error.SetErrorStringWithFormat( "failed to allocate DataBufferHeap instance of size %" PRIu64, REG_CONTEXT_SIZE); return error; } error = ReadGPR(); if (!error.Success()) { error.SetErrorString("ReadGPR() failed"); return error; } error = ReadCP1(); if (!error.Success()) { error.SetErrorString("ReadCP1() failed"); return error; } uint8_t *dst = data_sp->GetBytes(); if (dst == nullptr) { error.SetErrorStringWithFormat("DataBufferHeap instance of size %" PRIu64 " returned a null pointer", REG_CONTEXT_SIZE); return error; } ::memcpy(dst, &m_gpr, GetRegisterInfoInterface().GetGPRSize()); dst += GetRegisterInfoInterface().GetGPRSize(); ::memcpy(dst, &m_fpr, GetFPRSize()); dst += GetFPRSize(); ::memcpy(dst, &m_msa, sizeof(MSA_linux_mips)); return error; }
static size_t ReadMemoryCallback(EmulateInstruction *instruction, void *baton, const EmulateInstruction::Context &context, lldb::addr_t addr, void *dst, size_t length) { EmulatorBaton *emulator_baton = static_cast<EmulatorBaton *>(baton); Status error; size_t bytes_read = emulator_baton->m_process->DoReadMemory(addr, dst, length, error); if (!error.Success()) bytes_read = 0; return bytes_read; }
static Status FindUnusedPort(uint16_t &port) { Status error; std::unique_ptr<TCPSocket> tcp_socket(new TCPSocket(true, false)); if (error.Fail()) return error; error = tcp_socket->Listen("127.0.0.1:0", 1); if (error.Success()) port = tcp_socket->GetLocalPortNumber(); return error; }
void DYLDRendezvous::UpdateBaseAddrIfNecessary(SOEntry &entry, std::string const &file_path) { // If the load bias reported by the linker is incorrect then fetch the load // address of the file from the proc file system. if (isLoadBiasIncorrect(m_process->GetTarget(), file_path)) { lldb::addr_t load_addr = LLDB_INVALID_ADDRESS; bool is_loaded = false; Status error = m_process->GetFileLoadAddress(entry.file_spec, is_loaded, load_addr); if (error.Success() && is_loaded) entry.base_addr = load_addr; } }
OptionValueFormatEntity::OptionValueFormatEntity(const char *default_format) : OptionValue(), m_current_format(), m_default_format(), m_current_entry(), m_default_entry() { if (default_format && default_format[0]) { llvm::StringRef default_format_str(default_format); Status error = FormatEntity::Parse(default_format_str, m_default_entry); if (error.Success()) { m_default_format = default_format; m_current_format = default_format; m_current_entry = m_default_entry; } } }
TEST_F(GDBRemoteCommunicationClientTest, SendStartTracePacket) { TraceOptions options; Status error; options.setType(lldb::TraceType::eTraceTypeProcessorTrace); options.setMetaDataBufferSize(8192); options.setTraceBufferSize(8192); options.setThreadID(0x23); StructuredData::DictionarySP custom_params = std::make_shared<StructuredData::Dictionary>(); custom_params->AddStringItem("tracetech", "intel-pt"); custom_params->AddIntegerItem("psb", 0x01); options.setTraceParams(custom_params); std::future<lldb::user_id_t> result = std::async(std::launch::async, [&] { return client.SendStartTracePacket(options, error); }); // Since the line is exceeding 80 characters. std::string expected_packet1 = R"(jTraceStart:{"buffersize" : 8192,"metabuffersize" : 8192,"params" :)"; std::string expected_packet2 = R"( {"psb" : 1,"tracetech" : "intel-pt"},"threadid" : 35,"type" : 1})"; HandlePacket(server, (expected_packet1 + expected_packet2), "1"); ASSERT_TRUE(error.Success()); ASSERT_EQ(result.get(), 1u); error.Clear(); result = std::async(std::launch::async, [&] { return client.SendStartTracePacket(options, error); }); HandlePacket(server, (expected_packet1 + expected_packet2), "E23"); ASSERT_EQ(result.get(), LLDB_INVALID_UID); ASSERT_FALSE(error.Success()); }
bool NativeRegisterContextLinux_mips64::IsMSAAvailable() { MSA_linux_mips msa_buf; unsigned int regset = NT_MIPS_MSA; Status error = NativeProcessLinux::PtraceWrapper( PTRACE_GETREGSET, Host::GetCurrentProcessID(), static_cast<void *>(®set), &msa_buf, sizeof(MSA_linux_mips)); if (error.Success() && msa_buf.mir) { return true; } return false; }
int RegisterContextKDP_i386::DoReadEXC(lldb::tid_t tid, int flavor, EXC &exc) { ProcessSP process_sp(CalculateProcess()); if (process_sp) { Status error; if (static_cast<ProcessKDP *>(process_sp.get()) ->GetCommunication() .SendRequestReadRegisters(tid, EXCRegSet, &exc, sizeof(exc), error)) { if (error.Success()) return 0; } } return -1; }
Status Socket::UnixAbstractConnect(llvm::StringRef name, bool child_processes_inherit, Socket *&socket) { Status error; std::unique_ptr<Socket> connect_socket( Create(ProtocolUnixAbstract, child_processes_inherit, error)); if (error.Fail()) return error; error = connect_socket->Connect(name); if (error.Success()) socket = connect_socket.release(); return error; }
bool Breakpoint::AddName(llvm::StringRef new_name, Status &error) { if (new_name.empty()) return false; if (!BreakpointID::StringIsBreakpointName(new_name, error)) { error.SetErrorStringWithFormatv("input name \"{0}\" not a breakpoint name.", new_name); return false; } if (!error.Success()) return false; m_name_list.insert(new_name); return true; }
Status RegisterContext::WriteRegisterValueToMemory( const RegisterInfo *reg_info, lldb::addr_t dst_addr, uint32_t dst_len, const RegisterValue ®_value) { uint8_t dst[RegisterValue::kMaxRegisterByteSize]; Status error; ProcessSP process_sp(m_thread.GetProcess()); if (process_sp) { // TODO: we might need to add a parameter to this function in case the byte // order of the memory data doesn't match the process. For now we are // assuming they are the same. const uint32_t bytes_copied = reg_value.GetAsMemoryData( reg_info, dst, dst_len, process_sp->GetByteOrder(), error); if (error.Success()) { if (bytes_copied == 0) { error.SetErrorString("byte copy failed."); } else { const uint32_t bytes_written = process_sp->WriteMemory(dst_addr, dst, bytes_copied, error); if (bytes_written != bytes_copied) { if (error.Success()) { // This might happen if we read _some_ bytes but not all error.SetErrorStringWithFormat("only wrote %u of %u bytes", bytes_written, bytes_copied); } } } } } else error.SetErrorString("invalid process"); return error; }
void Materialize(lldb::StackFrameSP &frame_sp, IRMemoryMap &map, lldb::addr_t process_address, Status &err) override { Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS)); const lldb::addr_t load_addr = process_address + m_offset; if (log) { log->Printf("EntityPersistentVariable::Materialize [address = 0x%" PRIx64 ", m_name = %s, m_flags = 0x%hx]", (uint64_t)load_addr, m_persistent_variable_sp->GetName().AsCString(), m_persistent_variable_sp->m_flags); } if (m_persistent_variable_sp->m_flags & ExpressionVariable::EVNeedsAllocation) { MakeAllocation(map, err); m_persistent_variable_sp->m_flags |= ExpressionVariable::EVIsLLDBAllocated; if (!err.Success()) return; } if ((m_persistent_variable_sp->m_flags & ExpressionVariable::EVIsProgramReference && m_persistent_variable_sp->m_live_sp) || m_persistent_variable_sp->m_flags & ExpressionVariable::EVIsLLDBAllocated) { Status write_error; map.WriteScalarToMemory( load_addr, m_persistent_variable_sp->m_live_sp->GetValue().GetScalar(), map.GetAddressByteSize(), write_error); if (!write_error.Success()) { err.SetErrorStringWithFormat( "couldn't write the location of %s to memory: %s", m_persistent_variable_sp->GetName().AsCString(), write_error.AsCString()); } } else { err.SetErrorStringWithFormat( "no materialization happened for persistent variable %s", m_persistent_variable_sp->GetName().AsCString()); return; } }
int RegisterContextKDP_x86_64::DoReadGPR(lldb::tid_t tid, int flavor, GPR &gpr) { ProcessSP process_sp(CalculateProcess()); if (process_sp) { Status error; if (static_cast<ProcessKDP *>(process_sp.get()) ->GetCommunication() .SendRequestReadRegisters(tid, GPRRegSet, &gpr, sizeof(gpr), error)) { if (error.Success()) return 0; } } return -1; }
int RegisterContextKDP_x86_64::DoWriteFPU(lldb::tid_t tid, int flavor, const FPU &fpu) { ProcessSP process_sp(CalculateProcess()); if (process_sp) { Status error; if (static_cast<ProcessKDP *>(process_sp.get()) ->GetCommunication() .SendRequestWriteRegisters(tid, FPURegSet, &fpu, sizeof(fpu), error)) { if (error.Success()) return 0; } } return -1; }
Status ProcessFreeBSD::DoDetach(bool keep_stopped) { Status error; if (keep_stopped) { error.SetErrorString("Detaching with keep_stopped true is not currently " "supported on FreeBSD."); return error; } error = m_monitor->Detach(GetID()); if (error.Success()) SetPrivateState(eStateDetached); return error; }
Status OptionValueFormatEntity::SetValueFromString(llvm::StringRef value_str, VarSetOperationType op) { Status error; switch (op) { case eVarSetOperationClear: Clear(); NotifyValueChanged(); break; case eVarSetOperationReplace: case eVarSetOperationAssign: { // Check if the string starts with a quote character after removing leading // and trailing spaces. If it does start with a quote character, make sure // it ends with the same quote character and remove the quotes before we // parse the format string. If the string doesn't start with a quote, leave // the string alone and parse as is. llvm::StringRef trimmed_value_str = value_str.trim(); if (!trimmed_value_str.empty()) { const char first_char = trimmed_value_str[0]; if (first_char == '"' || first_char == '\'') { const size_t trimmed_len = trimmed_value_str.size(); if (trimmed_len == 1 || value_str[trimmed_len - 1] != first_char) { error.SetErrorStringWithFormat("mismatched quotes"); return error; } value_str = trimmed_value_str.substr(1, trimmed_len - 2); } } FormatEntity::Entry entry; error = FormatEntity::Parse(value_str, entry); if (error.Success()) { m_current_entry = std::move(entry); m_current_format = value_str; m_value_was_set = true; NotifyValueChanged(); } } break; case eVarSetOperationInsertBefore: case eVarSetOperationInsertAfter: case eVarSetOperationRemove: case eVarSetOperationAppend: case eVarSetOperationInvalid: error = OptionValue::SetValueFromString(value_str, op); break; } return error; }
bool Communication::StopReadThread(Status *error_ptr) { if (!m_read_thread.IsJoinable()) return true; lldb_private::LogIfAnyCategoriesSet( LIBLLDB_LOG_COMMUNICATION, "%p Communication::StopReadThread ()", this); m_read_thread_enabled = false; BroadcastEvent(eBroadcastBitReadThreadShouldExit, nullptr); // error = m_read_thread.Cancel(); Status error = m_read_thread.Join(nullptr); return error.Success(); }
void IRMemoryMap::ReadPointerFromMemory(lldb::addr_t *address, lldb::addr_t process_address, Status &error) { error.Clear(); Scalar pointer_scalar; ReadScalarFromMemory(pointer_scalar, process_address, GetAddressByteSize(), error); if (!error.Success()) return; *address = pointer_scalar.ULongLong(); return; }
static bool ReadRegisterCallback(EmulateInstruction *instruction, void *baton, const RegisterInfo *reg_info, RegisterValue ®_value) { EmulatorBaton *emulator_baton = static_cast<EmulatorBaton *>(baton); const RegisterInfo *full_reg_info = emulator_baton->m_reg_context->GetRegisterInfo( lldb::eRegisterKindDWARF, reg_info->kinds[lldb::eRegisterKindDWARF]); Status error = emulator_baton->m_reg_context->ReadRegister(full_reg_info, reg_value); if (error.Success()) return true; return false; }