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)) { Error 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); }
Error NativeRegisterContextLinux::WriteRegisterRaw(uint32_t reg_index, const RegisterValue ®_value) { uint32_t reg_to_write = reg_index; RegisterValue value_to_write = reg_value; // Check if this is a subregister of a full register. const RegisterInfo *reg_info = GetRegisterInfoAtIndex(reg_index); if (reg_info->invalidate_regs && (reg_info->invalidate_regs[0] != LLDB_INVALID_REGNUM)) { Error error; RegisterValue full_value; uint32_t full_reg = reg_info->invalidate_regs[0]; const RegisterInfo *full_reg_info = GetRegisterInfoAtIndex(full_reg); // Read the full register. error = ReadRegister(full_reg_info, full_value); if (error.Fail ()) return error; lldb::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 = reg_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; } } } const RegisterInfo *const register_to_write_info_p = GetRegisterInfoAtIndex (reg_to_write); assert (register_to_write_info_p && "register to write does not have valid RegisterInfo"); if (!register_to_write_info_p) return Error("NativeRegisterContextLinux::%s failed to get RegisterInfo for write register index %" PRIu32, __FUNCTION__, reg_to_write); return DoWriteRegisterValue(reg_info->byte_offset, reg_info->name, reg_value); }
Error RegisterContext::WriteRegisterValueToMemory (const RegisterInfo *reg_info, lldb::addr_t dst_addr, uint32_t dst_len, const RegisterValue ®_value) { uint8_t dst[RegisterValue::kMaxRegisterByteSize]; Error 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; }