diff options
author | the lemons <citrons@mondecitronne.com> | 2023-02-06 13:58:46 -0600 |
---|---|---|
committer | the lemons <citrons@mondecitronne.com> | 2023-02-06 13:58:46 -0600 |
commit | 5b53f34340bff793106af3c475e5bb3315589e53 (patch) | |
tree | 010638870d206c3284192348d67487e749c5f054 | |
parent | 3af50b956b8887b64c3c29b30a0008be866b24c4 (diff) |
parse /proc/<pid>/maps
-rw-r--r-- | procfs.c | 37 | ||||
-rw-r--r-- | procfs.h | 7 |
2 files changed, 44 insertions, 0 deletions
@@ -15,6 +15,43 @@ int procfs_open(pid_t pid) { return open(path, O_RDWR); } +ssize_t procfs_maps(pid_t pid, struct procfs_map **maps) { + char path[2048]; + sprintf(path, "/proc/%d/maps", pid); + FILE *f = fopen(path, "r"); + if (!f) return -1; + + int n = 0; + int capacity = 2; + *maps = calloc(capacity, sizeof(**maps)); + if (!*maps) return -1; + while (1) { + void *base, *max; + int matches = fscanf(f, "%p-%p", &base, &max); + if (matches == EOF) goto eof; + if (matches < 2) goto err; + int c; + while ((c = getc(f)) != '\n') + if (c == EOF) goto eof; + n++; + if (n > capacity) { + capacity <<= 1; + struct procfs_map *r = reallocarray(*maps, capacity, sizeof(*r)); + if (!r) goto err; + *maps = r; + } + (*maps)[n - 1].base = (uintptr_t) base; + (*maps)[n - 1].max = (uintptr_t) max; + } +eof: + if (ferror(f)) goto err; + if (n == 0) free(*maps); + return n; +err: + free(*maps); + return -1; +} + int read_page(int fd, uintptr_t index, uint8_t *data) { if (lseek(fd, index * PAGE_SIZE, SEEK_SET) == -1) return -1; @@ -12,4 +12,11 @@ int procfs_open(pid_t pid); int read_page(int fd, uintptr_t index, uint8_t *data); +struct procfs_map { + uintptr_t base; + uintptr_t max; +}; + +ssize_t procfs_maps(pid_t pid, struct procfs_map **maps); + #endif |