Add helper functions for serialization and deserialization kernel structures to byte buffer.
Signed-off-by: Mikhail Abakumov <mikhail.abaku...@ispras.ru> Signed-off-by: Pavel Dovgalyuk <dovga...@ispras.ru> --- target/i386/windbgstub.c | 123 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 123 insertions(+) diff --git a/target/i386/windbgstub.c b/target/i386/windbgstub.c index 5d47d5c9e9..03807ce63e 100644 --- a/target/i386/windbgstub.c +++ b/target/i386/windbgstub.c @@ -280,6 +280,129 @@ static InitedAddr kdDebuggerDataBlock; static InitedAddr kdVersion; #endif /* TARGET_I386 */ +__attribute__ ((unused)) /* unused yet */ +static void windbg_set_dr(CPUState *cs, int index, target_ulong value) +{ + X86CPU *cpu = X86_CPU(cs); + CPUX86State *env = &cpu->env; + + switch (index) { + case 0 ... 3: + env->dr[index] = value; + return; + case 6: + env->dr[6] = value | DR6_FIXED_1; + return; + case 7: + cpu_x86_update_dr7(env, value); + return; + } +} + +/* copy from gdbstub.c */ +__attribute__ ((unused)) /* unused yet */ +static void windbg_set_sr(CPUState *cs, int sreg, uint16_t selector) +{ + X86CPU *cpu = X86_CPU(cs); + CPUX86State *env = &cpu->env; + + if (selector != env->segs[sreg].selector) { +#if defined(CONFIG_USER_ONLY) + cpu_x86_load_seg(env, sreg, selector); +#else + unsigned int limit, flags; + target_ulong base; + + if (!(env->cr[0] & CR0_PE_MASK) || (env->eflags & VM_MASK)) { + int dpl = (env->eflags & VM_MASK) ? 3 : 0; + base = selector << 4; + limit = 0xffff; + flags = DESC_P_MASK | DESC_S_MASK | DESC_W_MASK | + DESC_A_MASK | (dpl << DESC_DPL_SHIFT); + } else { + if (!cpu_x86_get_descr_debug(env, selector, &base, &limit, + &flags)) { + return; + } + } + cpu_x86_load_seg_cache(env, sreg, selector, base, limit, flags); +#endif + } +} + +#define rwuw_p(ptr, var, is_read) \ + do { \ + if (is_read) { \ + var = lduw_p(ptr); \ + } else { \ + stw_p(ptr, var); \ + } \ + } while (0) + +#define rwl_p(ptr, var, is_read) \ + do { \ + if (is_read) { \ + var = ldl_p(ptr); \ + } else { \ + stl_p(ptr, var); \ + } \ + } while (0) + +#define rwtul_p(ptr, var, is_read) \ + do { \ + if (is_read) { \ + var = ldtul_p(ptr); \ + } else { \ + sttul_p(ptr, var); \ + } \ + } while (0) + +#define RW_DR(ptr, cs, dr_index, is_read) \ + do { \ + if (is_read) { \ + windbg_set_dr(cs, dr_index, ldtul_p(ptr)); \ + } else { \ + sttul_p(ptr, X86_CPU(cs)->env.dr[dr_index]); \ + } \ + } while (0) + +#define RW_SR(ptr, cs, sr_index, is_read) \ + do { \ + if (is_read) { \ + windbg_set_sr(cs, sr_index, lduw_p(ptr)); \ + } else { \ + stw_p(ptr, X86_CPU(cs)->env.segs[R_CS].selector); \ + } \ + } while (0) + +#define RW_CR(ptr, cs, cr_index, is_read) \ + do { \ + if (is_read) { \ + cpu_x86_update_cr##cr_index(env, (int32_t) ldtul_p(ptr)); \ + } else { \ + sttul_p(ptr, (target_ulong) X86_CPU(cs)->env.cr[cr_index]); \ + } \ + } while (0) + +#define CASE_FIELD(srct, field, field_size, block) \ + case offsetof(srct, field): \ + field_size = sizeof_field(srct, field); \ + block; \ + break; + +#define CASE_FIELD_X32_64(srct, field_x32, field_x64, field_size, block) \ + CASE_FIELD(srct, TARGET_SAFE(field_x32, field_x64), field_size, block) + +#ifdef TARGET_X86_64 +#define CASE_FIELD_X32(srct, field, field_size, block) +#define CASE_FIELD_X64(srct, field, field_size, block) \ + CASE_FIELD(srct, field, field_size, block) +#else /* TARGET_I386 */ +#define CASE_FIELD_X64(srct, field, field_size, block) +#define CASE_FIELD_X32(srct, field, field_size, block) \ + CASE_FIELD(srct, field, field_size, block) +#endif /* TARGET_I386 */ + static bool find_KPCR(CPUState *cs) { X86CPU *cpu = X86_CPU(cs);