/* * qtest function wrappers * * Copyright Red Hat Inc., 2019 * * Authors: * Alexander Bulekov * * This work is licensed under the terms of the GNU GPL, version 2 or later. * See the COPYING file in the top-level directory. * */ #include "qemu/osdep.h" #include "cpu.h" #include "exec/ioport.h" #include "fuzz.h" static bool serialize = true; #define WRAP(RET_TYPE, NAME_AND_ARGS)\ RET_TYPE __wrap_##NAME_AND_ARGS;\ RET_TYPE __real_##NAME_AND_ARGS; WRAP(uint8_t , qtest_inb(QTestState *s, uint16_t addr)) WRAP(uint16_t , qtest_inw(QTestState *s, uint16_t addr)) WRAP(uint32_t , qtest_inl(QTestState *s, uint16_t addr)) WRAP(void , qtest_outb(QTestState *s, uint16_t addr, uint8_t value)) WRAP(void , qtest_outw(QTestState *s, uint16_t addr, uint16_t value)) WRAP(void , qtest_outl(QTestState *s, uint16_t addr, uint32_t value)) WRAP(uint8_t , qtest_readb(QTestState *s, uint64_t addr)) WRAP(uint16_t , qtest_readw(QTestState *s, uint64_t addr)) WRAP(uint32_t , qtest_readl(QTestState *s, uint64_t addr)) WRAP(uint64_t , qtest_readq(QTestState *s, uint64_t addr)) WRAP(void , qtest_writeb(QTestState *s, uint64_t addr, uint8_t value)) WRAP(void , qtest_writew(QTestState *s, uint64_t addr, uint16_t value)) WRAP(void , qtest_writel(QTestState *s, uint64_t addr, uint32_t value)) WRAP(void , qtest_writeq(QTestState *s, uint64_t addr, uint64_t value)) WRAP(void , qtest_memread(QTestState *s, uint64_t addr, void *data, size_t size)) WRAP(void , qtest_bufread(QTestState *s, uint64_t addr, void *data, size_t size)) WRAP(void , qtest_memwrite(QTestState *s, uint64_t addr, const void *data, size_t size)) WRAP(void, qtest_bufwrite(QTestState *s, uint64_t addr, const void *data, size_t size)) WRAP(void, qtest_memset(QTestState *s, uint64_t addr, uint8_t patt, size_t size)) uint8_t __wrap_qtest_inb(QTestState *s, uint16_t addr) { if (!serialize) { return cpu_inb(addr); } else { return __real_qtest_inb(s, addr); } } uint16_t __wrap_qtest_inw(QTestState *s, uint16_t addr) { if (!serialize) { return cpu_inw(addr); } else { return __real_qtest_inw(s, addr); } } uint32_t __wrap_qtest_inl(QTestState *s, uint16_t addr) { if (!serialize) { return cpu_inl(addr); } else { return __real_qtest_inl(s, addr); } } void __wrap_qtest_outb(QTestState *s, uint16_t addr, uint8_t value) { if (!serialize) { cpu_outb(addr, value); } else { __real_qtest_outb(s, addr, value); } } void __wrap_qtest_outw(QTestState *s, uint16_t addr, uint16_t value) { if (!serialize) { cpu_outw(addr, value); } else { __real_qtest_outw(s, addr, value); } } void __wrap_qtest_outl(QTestState *s, uint16_t addr, uint32_t value) { if (!serialize) { cpu_outl(addr, value); } else { __real_qtest_outl(s, addr, value); } } uint8_t __wrap_qtest_readb(QTestState *s, uint64_t addr) { uint8_t value; if (!serialize) { address_space_read(first_cpu->as, addr, MEMTXATTRS_UNSPECIFIED, &value, 1); return value; } else { return __real_qtest_readb(s, addr); } } uint16_t __wrap_qtest_readw(QTestState *s, uint64_t addr) { uint16_t value; if (!serialize) { address_space_read(first_cpu->as, addr, MEMTXATTRS_UNSPECIFIED, &value, 2); return value; } else { return __real_qtest_readw(s, addr); } } uint32_t __wrap_qtest_readl(QTestState *s, uint64_t addr) { uint32_t value; if (!serialize) { address_space_read(first_cpu->as, addr, MEMTXATTRS_UNSPECIFIED, &value, 4); return value; } else { return __real_qtest_readl(s, addr); } } uint64_t __wrap_qtest_readq(QTestState *s, uint64_t addr) { uint64_t value; if (!serialize) { address_space_read(first_cpu->as, addr, MEMTXATTRS_UNSPECIFIED, &value, 8); return value; } else { return __real_qtest_readq(s, addr); } } void __wrap_qtest_writeb(QTestState *s, uint64_t addr, uint8_t value) { if (!serialize) { address_space_write(first_cpu->as, addr, MEMTXATTRS_UNSPECIFIED, &value, 1); } else { __real_qtest_writeb(s, addr, value); } } void __wrap_qtest_writew(QTestState *s, uint64_t addr, uint16_t value) { if (!serialize) { address_space_write(first_cpu->as, addr, MEMTXATTRS_UNSPECIFIED, &value, 2); } else { __real_qtest_writew(s, addr, value); } } void __wrap_qtest_writel(QTestState *s, uint64_t addr, uint32_t value) { if (!serialize) { address_space_write(first_cpu->as, addr, MEMTXATTRS_UNSPECIFIED, &value, 4); } else { __real_qtest_writel(s, addr, value); } } void __wrap_qtest_writeq(QTestState *s, uint64_t addr, uint64_t value) { if (!serialize) { address_space_write(first_cpu->as, addr, MEMTXATTRS_UNSPECIFIED, &value, 8); } else { __real_qtest_writeq(s, addr, value); } } void __wrap_qtest_memread(QTestState *s, uint64_t addr, void *data, size_t size) { if (!serialize) { address_space_read(first_cpu->as, addr, MEMTXATTRS_UNSPECIFIED, data, size); } else { __real_qtest_memread(s, addr, data, size); } } void __wrap_qtest_bufread(QTestState *s, uint64_t addr, void *data, size_t size) { if (!serialize) { address_space_read(first_cpu->as, addr, MEMTXATTRS_UNSPECIFIED, data, size); } else { __real_qtest_bufread(s, addr, data, size); } } void __wrap_qtest_memwrite(QTestState *s, uint64_t addr, const void *data, size_t size) { if (!serialize) { address_space_write(first_cpu->as, addr, MEMTXATTRS_UNSPECIFIED, data, size); } else { __real_qtest_memwrite(s, addr, data, size); } } void __wrap_qtest_bufwrite(QTestState *s, uint64_t addr, const void *data, size_t size) { if (!serialize) { address_space_write(first_cpu->as, addr, MEMTXATTRS_UNSPECIFIED, data, size); } else { __real_qtest_bufwrite(s, addr, data, size); } } void __wrap_qtest_memset(QTestState *s, uint64_t addr, uint8_t patt, size_t size) { void *data; if (!serialize) { data = malloc(size); memset(data, patt, size); address_space_write(first_cpu->as, addr, MEMTXATTRS_UNSPECIFIED, data, size); } else { __real_qtest_memset(s, addr, patt, size); } } void fuzz_qtest_set_serialize(bool option) { serialize = option; }