summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorthe lemons <citrons@mondecitronne.com>2023-02-06 13:58:46 -0600
committerthe lemons <citrons@mondecitronne.com>2023-02-06 13:58:46 -0600
commit5b53f34340bff793106af3c475e5bb3315589e53 (patch)
tree010638870d206c3284192348d67487e749c5f054
parent3af50b956b8887b64c3c29b30a0008be866b24c4 (diff)
parse /proc/<pid>/maps
-rw-r--r--procfs.c37
-rw-r--r--procfs.h7
2 files changed, 44 insertions, 0 deletions
diff --git a/procfs.c b/procfs.c
index 63aef3a..e3bfb2c 100644
--- a/procfs.c
+++ b/procfs.c
@@ -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;
diff --git a/procfs.h b/procfs.h
index 7b81a13..b36c242 100644
--- a/procfs.h
+++ b/procfs.h
@@ -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