memzap

replay memory writes
git clone git://git.2f30.org/memzap
Log | Files | Refs | README | LICENSE

commit 06aef97ceacf6506da8fc66e51735ad09cc88556
parent d533827b53eeeb8b54de589694f41c13d88f0bdd
Author: sin <sin@2f30.org>
Date:   Sun,  3 Mar 2013 15:55:25 +0000

mdiff: Fix bugs and add mdiff_read_diff()

Diffstat:
Mdocs/mdiff-fmt | 4+++-
Mmdiff.c | 65++++++++++++++++++++++++++++++++++++++++++++++++++++++-----------
Mproto.h | 10+++++++---
3 files changed, 64 insertions(+), 15 deletions(-)

diff --git a/docs/mdiff-fmt b/docs/mdiff-fmt @@ -3,9 +3,11 @@ File format of the mdiff files struct mdiff_hdr { /* MDIFF\0 */ - char magic[6]; + char magic[8]; /* Number of memory diff regions */ uint32_t nregions; + /* Block size */ + uint32_t blksize; }; struct mdiff_region { diff --git a/mdiff.c b/mdiff.c @@ -18,7 +18,7 @@ create_mdiff(const char *path) { int fd; - fd = open(path, O_RDWR); + fd = open(path, O_CREAT | O_RDWR | O_TRUNC, 0644); if (fd < 0) errx(1, "%s: %s", path, strerror(errno)); return fd; @@ -38,23 +38,24 @@ close_mdiff(int fd) return 0; } -int +struct mdiff_hdr * parse_mdiff_hdr(int fd) { - struct mdiff_hdr hdr; + struct mdiff_hdr *hdr; ssize_t ret; if (fd < 0) - return -EINVAL; + return NULL; - ret = read(fd, &hdr, sizeof(hdr)); - if (ret != sizeof(hdr)) + hdr = xmalloc(sizeof(*hdr)); + ret = read(fd, hdr, sizeof(*hdr)); + if (ret != sizeof(*hdr)) err(1, "read"); - if (memcmp(hdr.magic, "MDIFF", sizeof(hdr.magic))) - return -EINVAL; - if (!hdr.nregions) - return -EINVAL; - return 0; + if (strncmp(hdr->magic, "MDIFF", 5)) + return NULL; + if (!hdr->nregions) + return NULL; + return hdr; } int @@ -88,6 +89,48 @@ mdiff_start_diff(int fd) return 0; } +struct mdiff_region * +mdiff_read_diff(int fd, struct mdiff_hdr *hdr, uint32_t region) +{ + int ret; + off_t offset; + struct mdiff_region *mdiff; + uint32_t i; + uint32_t len; + + if (fd < 0 || !hdr) + return NULL; + + offset = sizeof(*hdr); + ret = lseek(fd, offset, SEEK_SET); + if (ret < 0) + err(1, "lseek"); + mdiff = xmalloc(sizeof(*mdiff)); + for (i = 0; i < region; i++) { + ret = read(fd, mdiff, sizeof(*mdiff)); + if (ret != sizeof(*mdiff)) + err(1, "read"); + offset += sizeof(*mdiff); + offset += mdiff->len; + ret = lseek(fd, offset, SEEK_SET); + if (ret < 0) + err(1, "lseek"); + } + + ret = read(fd, mdiff, sizeof(*mdiff)); + if (ret != sizeof(*mdiff)) + err(1, "mdiff"); + ret = lseek(fd, offset, SEEK_SET); + if (ret < 0) + err(1, "lseek"); + len = mdiff->len; + mdiff = xrealloc(mdiff, sizeof(*mdiff) + len); + ret = read(fd, mdiff, sizeof(*mdiff) + len); + if ((size_t)ret != sizeof(*mdiff) + len) + err(1, "read"); + return mdiff; +} + int mdiff_append_rdiff(int fd, struct mem_region_diff *rdiff) { diff --git a/proto.h b/proto.h @@ -101,10 +101,12 @@ struct mem_tree_entry { RB_HEAD(mem_tree, mem_tree_entry); struct mdiff_hdr { - /* MDIFF\0 */ - char magic[6]; + /* MDIFF */ + char magic[8]; /* Number of memory diff regions */ uint32_t nregions; + /* Block size */ + uint32_t blksize; }; struct mdiff_region { @@ -159,9 +161,11 @@ void readmem(pid_t pid, void *buf, void *offset, size_t size); int open_mdiff(const char *path); int create_mdiff(const char *path); int close_mdiff(int fd); -int parse_mdiff_hdr(int fd); +struct mdiff_hdr *parse_mdiff_hdr(int fd); int mdiff_insert_hdr(int fd, struct mdiff_hdr *hdr); int mdiff_start_diff(int fd); +struct mdiff_region *mdiff_read_diff(int fd, struct mdiff_hdr *hdr, + uint32_t region); int mdiff_append_rdiff(int fd, struct mem_region_diff *rdiff); #endif