fxos/include/fxos/target.h

138 lines
4.7 KiB
C++

//---
// fxos.target: The target which is being studied
//---
#ifndef LIBFXOS_TARGET_H
#define LIBFXOS_TARGET_H
#include <fxos/memory.h>
#include <fxos/util.h>
#include <vector>
#include <cstdint>
namespace FxOS {
class OS;
/* A common interface for simulated memory */
class AbstractMemory
{
public:
/* Checks if an address or interval is simulated */
virtual bool covers(uint32_t addr, int size=1) const noexcept = 0;
/* Returns the data located at the provided virtual address. Throws
std::out_of_range if the interval is not entirely simulated */
virtual char const *translate(uint32_t addr, int size=1) const = 0;
/* Read data from the memory. The following methods read data of
various types. (Not a template because of the restriction about
template specialization in non-namespaces scopes still in g++.)
When reading data, provide a virtual address. The addres is saved in
the returned object for later printing or inspection. The returned
object Addressable<T> automatically converts to T when used, and
supports operator & which returns the original address.
The size parameter is only meaningful for variable-sized types such
as string, and ignored for fixed-size types such as integers. If the
desired object is not within the range of the simulated memory,
throws std::out_of_range. */
/* Read integers with signed or unsigned extension. These functions do
not check alignment, because exceptionnally the processor supports
unaligned operations (eg. movual.l). */
Addressable<int8_t> read_i8 (uint32_t addr) const;
Addressable<uint8_t> read_u8 (uint32_t addr) const;
Addressable<int16_t> read_i16(uint32_t addr) const;
Addressable<uint16_t> read_u16(uint32_t addr) const;
Addressable<int32_t> read_i32(uint32_t addr) const;
Addressable<uint32_t> read_u32(uint32_t addr) const;
/* Read a non-NUL-terminated string */
Addressable<std::string> read_str(uint32_t addr, size_t len) const;
/* Search a binary pattern in the specified area. Returns the virtual
address of the first occurrence if any is found, [end] otherwise. */
virtual uint32_t search(uint32_t start, uint32_t end,
void const *pattern, int size) const = 0;
};
/* A binding of a data buffer into a memory region of the target. */
struct Binding: public AbstractMemory
{
/* Constructor from data buffer. An error is raised if the buffer is
not at least of the size of the region. In this case, a new buffer
can be constructed with the required size. */
Binding(MemoryRegion const &region, Buffer const &buffer);
/* Targeted region, might overlap with other bindings */
MemoryRegion region;
/* Actual data. This area must have at least [size] bytes */
void const *data;
/* Binding size (equal to the region size) */
uint32_t size;
/* Checks if an address is covered by the binding */
bool covers(uint32_t addr, int size=1) const noexcept override;
/* Returns this process' address (in [data]) corresponding to the
provided virtual address */
char const *translate(uint32_t addr, int size=1) const override;
/* Search a pattern */
uint32_t search(uint32_t start, uint32_t end, void const *pattern,
int size) const override;
};
/* A composite target where regions can be bound dynamically */
class Target: public AbstractMemory
{
public:
/* Create an empty target with no regions */
Target();
/* Bind an OS. This is used to either disassemble the OS itself, or
select the OS version for which code is being disassembled (for
instance for add-ins). */
void bind_os(OS &os);
/* Bind a memory region from a buffer. The region can either be
standard (see <fxos/memory.h>) or custom.
If several loaded regions overlap on some addresses, *the last
loaded region will be used*. Thus, new regions can be loaded to
selectively override parts of the target.
Generally it is preferable to bind an OS image to the target's ROM
area using bind_os(), rather than using bind_region(). This is
because bind_os() which will also enable OS-specific tasks such as
syscall resolution.
An error is raised if the buffer is smaller than the region being
bound. */
void bind_region(MemoryRegion const &region, Buffer const &buffer);
/* Check if an address is bound */
bool covers(uint32_t addr, int size=1) const noexcept override;
/* Returns the data at the provided virtual address */
char const *translate(uint32_t addr, int size=1) const override;
/* Search a pattern */
uint32_t search(uint32_t start, uint32_t end, void const *pattern,
int size) const override;
private:
/* Bound OS image */
OS *m_os;
/* Bound regions (in order of binding) */
std::vector<Binding> m_bindings;
};
} /* namespace FxOS */
#endif /* LIBFXOS_TARGET_H */