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);
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
#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);
|
||||
|
||||
/**
|
||||
* 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
|
||||
/*
|
||||
* Return whether addr is on the same page as where disassembly started.
|
||||
|
Loading…
Reference in New Issue
Block a user