proto.h (3946B)
1 /* See LICENSE file for copyright and license details. */ 2 3 #ifndef _PROTO_H 4 #define _PROTO_H 5 6 #include <errno.h> 7 #include <unistd.h> 8 #include <sys/stat.h> 9 #include <sys/ptrace.h> 10 #include <sys/wait.h> 11 #include <sys/mman.h> 12 #include <fcntl.h> 13 14 #include <stdio.h> 15 #include <stdlib.h> 16 #include <string.h> 17 #include <stdint.h> 18 #include <stdbool.h> 19 #include <limits.h> 20 #include <signal.h> 21 #include <err.h> 22 #include <getopt.h> 23 24 #include "queue.h" 25 #include "tree.h" 26 #include "md5.h" 27 28 #define min(a, b) ((a) < (b) ? (a) : (b)) 29 30 enum { 31 /* The preferred block size */ 32 BLKSIZE = 16384 33 }; 34 35 struct mem_blk { 36 /* Points to the actual data for this 37 * block. The user should never free pointers 38 * passed to this API unless the corresponding 39 * memory region has been freed. */ 40 void *buf; 41 /* Simple rolling sum of this block */ 42 uint32_t weak_sum; 43 /* The MD5 digest */ 44 unsigned char digest[MD5_DIGEST_LENGTH]; 45 /* Offset into the memory region of this block */ 46 off_t offset; 47 /* Size of this block, typically `BLKSIZE' 48 * or less for the last block */ 49 size_t len; 50 }; 51 52 struct mem_region { 53 /* Size of the memory region */ 54 size_t rsize; 55 /* Number of blocks in this region */ 56 size_t nblocks; 57 /* rsize % nblocks */ 58 size_t rem; 59 /* The block size used for this region */ 60 size_t blksize; 61 /* There are `nblocks' mem_blk entries 62 * here, describing the entire memory region */ 63 struct mem_blk *mblks; 64 }; 65 66 struct mem_diff { 67 /* Our updated data */ 68 void *buf; 69 /* Offset into the memory region where 70 * this buffer should be written */ 71 off_t offset; 72 /* Actual size of the buffer */ 73 size_t len; 74 /* Index into the memory region where 75 * the corresponding memory block is located */ 76 int index; 77 }; 78 79 struct mem_region_diff { 80 /* The diffs for this memory region */ 81 struct mem_diff *mrdiffs; 82 /* The number of diffs */ 83 size_t nmrdiffs; 84 }; 85 86 struct mdiff_hdr { 87 /* MDIFF */ 88 uint8_t magic[8]; 89 /* 0 for little endian, 1 for big endian */ 90 uint8_t endianness; 91 /* Version info */ 92 uint8_t version; 93 /* Reserved */ 94 uint8_t reserved; 95 /* Number of memory diff regions */ 96 uint32_t nregions; 97 /* Size of the traced region */ 98 uint32_t rsize; 99 /* Block size */ 100 uint32_t blksize; 101 }; 102 103 struct mdiff_region { 104 /* Cycle count */ 105 uint64_t cycle; 106 /* Offset into memory where this region should 107 * be written to */ 108 uint32_t offset; 109 /* Length of this memory diff region */ 110 uint32_t len; 111 /* Actual data */ 112 char buf[]; 113 }; 114 115 /* Return the number of blocks in a buffer of `len' bytes */ 116 static inline size_t 117 num_blocks(size_t len) 118 { 119 return (len + (BLKSIZE - 1)) / BLKSIZE; 120 } 121 122 /* utils.c */ 123 void *xmalloc(size_t len); 124 void *xrealloc(void *ptr, size_t len); 125 void *map_buf(size_t len); 126 void unmap_buf(void *buf, size_t len); 127 128 /* mem.c */ 129 uint32_t weak_sum(const void *buf, size_t len); 130 void strong_sum(const void *buf, size_t len, void *digest); 131 void dump_mem_blk(struct mem_blk *mb); 132 struct mem_region *build_mem_region(unsigned char *buf, size_t len); 133 void dump_mem_region(struct mem_region *mr); 134 void free_mem_region(struct mem_region *mr); 135 struct mem_region_diff *diff_mem_region(struct mem_region *dst, 136 struct mem_region *src); 137 struct mem_region *apply_diff(struct mem_region *dst, 138 struct mem_region_diff *rdiff); 139 void dump_mem_region_diff(struct mem_region_diff *rdiff); 140 void free_mem_region_diff(struct mem_region_diff *rdiff); 141 142 /* *_ops.c */ 143 int traceme(void); 144 int single_step(pid_t pid); 145 void readmem(pid_t pid, void *buf, void *offset, size_t size); 146 147 /* mdiff.c */ 148 int open_mdiff(const char *path); 149 int create_mdiff(const char *path); 150 int close_mdiff(int fd); 151 struct mdiff_hdr *parse_mdiff_hdr(int fd); 152 int mdiff_insert_hdr(int fd, struct mdiff_hdr *hdr); 153 int mdiff_start_diff(int fd); 154 struct mdiff_region *mdiff_read_diff(int fd, struct mdiff_hdr *hdr, 155 uint32_t region); 156 int mdiff_append_rdiff(int fd, struct mem_region_diff *rdiff, 157 uint64_t cycle); 158 void free_mdiff_region(struct mdiff_region *mdiff); 159 160 #endif