Signed-off-by: Eric Pouech eric.pouech@gmail.com
--- programs/winedbg/debugger.h | 1 + programs/winedbg/memory.c | 31 +++++++++++++++++++++++++++++++ programs/winedbg/types.c | 19 +++---------------- 3 files changed, 35 insertions(+), 16 deletions(-)
diff --git a/programs/winedbg/debugger.h b/programs/winedbg/debugger.h index 35829e83f96..97f79a1883c 100644 --- a/programs/winedbg/debugger.h +++ b/programs/winedbg/debugger.h @@ -392,6 +392,7 @@ extern void info_wine_dbg_channel(BOOL add, const char* chnl, const /* memory.c */ extern BOOL memory_read_value(const struct dbg_lvalue* lvalue, DWORD size, void* result); extern BOOL memory_write_value(const struct dbg_lvalue* val, DWORD size, void* value); +extern BOOL memory_transfer_value(const struct dbg_lvalue* to, const struct dbg_lvalue* from); extern BOOL memory_fetch_integer(const struct dbg_lvalue* lvalue, unsigned size, BOOL is_signed, dbg_lgint_t* ret); extern BOOL memory_store_integer(const struct dbg_lvalue* lvalue, dbg_lgint_t val); diff --git a/programs/winedbg/memory.c b/programs/winedbg/memory.c index fd8293687b6..5e32caec1d2 100644 --- a/programs/winedbg/memory.c +++ b/programs/winedbg/memory.c @@ -133,6 +133,37 @@ BOOL memory_write_value(const struct dbg_lvalue* lvalue, DWORD size, void* value return ret; }
+/* transfer a block of memory + * the two lvalue:s are expected to be of same size + */ +BOOL memory_transfer_value(const struct dbg_lvalue* to, const struct dbg_lvalue* from) +{ + DWORD64 size_to, size_from; + BYTE tmp[256]; + BYTE* ptr = tmp; + BOOL ret; + + if (to->bitlen || from->bitlen) return FALSE; + if (!types_get_info(&to->type, TI_GET_LENGTH, &size_to) || + !types_get_info(&from->type, TI_GET_LENGTH, &size_from) || + size_from != size_to) return FALSE; + /* optimize debugger to debugger transfer */ + if (!to->in_debuggee && !from->in_debuggee) + { + memcpy(memory_to_linear_addr(&to->addr), memory_to_linear_addr(&from->addr), size_from); + return TRUE; + } + if (size_to > sizeof(tmp)) + { + ptr = malloc(size_from); + if (!ptr) return FALSE; + } + ret = memory_read_value(from, size_from, ptr) && + memory_write_value(to, size_from, ptr); + if (size_to > sizeof(tmp)) free(ptr); + return ret; +} + /*********************************************************************** * memory_examine * diff --git a/programs/winedbg/types.c b/programs/winedbg/types.c index 2d7bce5de7e..3aca184942c 100644 --- a/programs/winedbg/types.c +++ b/programs/winedbg/types.c @@ -162,30 +162,17 @@ void types_extract_as_address(const struct dbg_lvalue* lvalue, ADDRESS64* addr)
BOOL types_store_value(struct dbg_lvalue* lvalue_to, const struct dbg_lvalue* lvalue_from) { - dbg_lgint_t val; - DWORD64 size; - BOOL equal; - if (!lvalue_to->bitlen && !lvalue_from->bitlen) { + BOOL equal; if (!types_compare(lvalue_to->type, lvalue_from->type, &equal)) return FALSE; if (equal) - { - if (!types_get_info(&lvalue_to->type, TI_GET_LENGTH, &size)) return FALSE; - if (sizeof(val) < size) - { - return memory_read_value(lvalue_from, size, &val) && - memory_write_value(lvalue_to, size, &val); - } - dbg_printf("NIY\n"); - /* else: should allocate intermediate buffer... */ - return FALSE; - } + return memory_transfer_value(lvalue_to, lvalue_from); } if (types_is_integral_type(lvalue_from) && types_is_integral_type(lvalue_to)) { /* doing integer conversion (about sign, size) */ - val = types_extract_as_integer(lvalue_from); + dbg_lgint_t val = types_extract_as_integer(lvalue_from); return memory_store_integer(lvalue_to, val); } /* FIXME: should support floats as well */