mirror of https://github.com/xemu-project/xemu.git
accel/tcg: Implement translator_st
Copy data out of a completed translation. This will be used for both plugins and disassembly. Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
This commit is contained in:
parent
4abc892362
commit
3a247368e6
|
@ -354,6 +354,61 @@ static void record_save(DisasContextBase *db, vaddr pc,
|
||||||
memcpy(db->record + (offset - db->record_start), from, size);
|
memcpy(db->record + (offset - db->record_start), from, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
size_t translator_st_len(const DisasContextBase *db)
|
||||||
|
{
|
||||||
|
return db->fake_insn ? db->record_len : db->tb->size;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool translator_st(const DisasContextBase *db, void *dest,
|
||||||
|
vaddr addr, size_t len)
|
||||||
|
{
|
||||||
|
size_t offset, offset_end;
|
||||||
|
|
||||||
|
if (addr < db->pc_first) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
offset = addr - db->pc_first;
|
||||||
|
offset_end = offset + len;
|
||||||
|
if (offset_end > translator_st_len(db)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!db->fake_insn) {
|
||||||
|
size_t offset_page1 = -(db->pc_first | TARGET_PAGE_MASK);
|
||||||
|
|
||||||
|
/* Get all the bytes from the first page. */
|
||||||
|
if (db->host_addr[0]) {
|
||||||
|
if (offset_end <= offset_page1) {
|
||||||
|
memcpy(dest, db->host_addr[0] + offset, len);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (offset < offset_page1) {
|
||||||
|
size_t len0 = offset_page1 - offset;
|
||||||
|
memcpy(dest, db->host_addr[0] + offset, len0);
|
||||||
|
offset += len0;
|
||||||
|
dest += len0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Get any bytes from the second page. */
|
||||||
|
if (db->host_addr[1] && offset >= offset_page1) {
|
||||||
|
memcpy(dest, db->host_addr[1] + (offset - offset_page1),
|
||||||
|
offset_end - offset);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Else get recorded bytes. */
|
||||||
|
if (db->record_len != 0 &&
|
||||||
|
offset >= db->record_start &&
|
||||||
|
offset_end <= db->record_start + db->record_len) {
|
||||||
|
memcpy(dest, db->record + (offset - db->record_start),
|
||||||
|
offset_end - offset);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
static void plugin_insn_append(vaddr pc, const void *from, size_t size)
|
static void plugin_insn_append(vaddr pc, const void *from, size_t size)
|
||||||
{
|
{
|
||||||
#ifdef CONFIG_PLUGIN
|
#ifdef CONFIG_PLUGIN
|
||||||
|
|
|
@ -246,6 +246,29 @@ translator_ldq_swap(CPUArchState *env, DisasContextBase *db,
|
||||||
*/
|
*/
|
||||||
void translator_fake_ldb(DisasContextBase *db, vaddr pc, uint8_t insn8);
|
void translator_fake_ldb(DisasContextBase *db, vaddr pc, uint8_t insn8);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* translator_st
|
||||||
|
* @db: disassembly context
|
||||||
|
* @dest: address to copy into
|
||||||
|
* @addr: virtual address within TB
|
||||||
|
* @len: length
|
||||||
|
*
|
||||||
|
* Copy @len bytes from @addr into @dest.
|
||||||
|
* All bytes must have been read during translation.
|
||||||
|
* Return true on success or false on failure.
|
||||||
|
*/
|
||||||
|
bool translator_st(const DisasContextBase *db, void *dest,
|
||||||
|
vaddr addr, size_t len);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* translator_st_len
|
||||||
|
* @db: disassembly context
|
||||||
|
*
|
||||||
|
* Return the number of bytes available to copy from the
|
||||||
|
* current translation block with translator_st.
|
||||||
|
*/
|
||||||
|
size_t translator_st_len(const DisasContextBase *db);
|
||||||
|
|
||||||
#ifdef COMPILING_PER_TARGET
|
#ifdef COMPILING_PER_TARGET
|
||||||
/*
|
/*
|
||||||
* Return whether addr is on the same page as where disassembly started.
|
* Return whether addr is on the same page as where disassembly started.
|
||||||
|
|
Loading…
Reference in New Issue