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 &reg_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);
}
Example #3
0
Error
RegisterContext::WriteRegisterValueToMemory (const RegisterInfo *reg_info,
                                             lldb::addr_t dst_addr, 
                                             uint32_t dst_len, 
                                             const RegisterValue &reg_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;

}