aboutsummaryrefslogtreecommitdiffstats
path: root/src/vm.c
blob: 8e624262b5fc2d08bb57404472c5bf1f0b374e67 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <stdint.h>
#include "vm.h"
#include "util.h"

static void strtrim (char *str)
{
  char *begin = str;
  while (isspace(*begin)) {
    begin++;
  }
  size_t len = strlen(begin);
  char *end = begin + len;
  while (end > begin && isspace(*end)) {
    end++;
  }

  memmove(str, begin, end - begin + 1);
}

VMMapping* parse_vmmap (int pid)
{
  char fmaps_path[128];
  sprintf(fmaps_path, "/proc/%d/maps", pid);
  FILE *fmaps;

  if ((fmaps = fopen(fmaps_path, "r")) == NULL) {
    perror("fopen");
    exit(1);
  }

  uint64_t begin, end;
  char perms[16];
  char filename[1024];
  VMMapping *head = NULL;
  VMMapping *cur = NULL;

  while(
    fscanf(fmaps, "%lx-%lx %15s %*x %*x:%*x %*u%1023[^\n]",
	   &begin, &end, perms, filename) != EOF) {
    strtrim(filename);

    VMMapping *new_mapping = xmalloc(sizeof(VMMapping));
    *new_mapping = (VMMapping) {
      .begin = begin,
      .end = end,
      .r = perms[0] == 'r',
      .w = perms[1] == 'w',
      .x = perms[2] == 'x',
      .s = perms[3] == 's',
      .p = perms[3] == 'p',
      .name = strdup(filename),
      .next = NULL,
    };

    if (head) {
      cur->next = new_mapping;
      cur = new_mapping;
    } else {
      head = cur = new_mapping;
    }

    LOG("%lx-%lx %c%c%c%c %s\n",
	cur->begin,
	cur->end,
	cur->r ? 'r' : '-',
	cur->w ? 'w' : '-',
	cur->x ? 'x' : '-',
	cur->s ? 's' : 'p',
	cur->name);
  }

  return head;
}