Exemple #1
0
static void
create_mem_region (CORE_ADDR lo, CORE_ADDR hi,
		   const struct mem_attrib *attrib)
{
  struct mem_region newobj;
  int i, ix;

  /* lo == hi is a useless empty region.  */
  if (lo >= hi && hi != 0)
    {
      printf_unfiltered (_("invalid memory region: low >= high\n"));
      return;
    }

  mem_region_init (&newobj);
  newobj.lo = lo;
  newobj.hi = hi;

  ix = VEC_lower_bound (mem_region_s, mem_region_list, &newobj,
			mem_region_lessthan);

  /* Check for an overlapping memory region.  We only need to check
     in the vicinity - at most one before and one after the
     insertion point.  */
  for (i = ix - 1; i < ix + 1; i++)
    {
      struct mem_region *n;

      if (i < 0)
	continue;
      if (i >= VEC_length (mem_region_s, mem_region_list))
	continue;

      n = VEC_index (mem_region_s, mem_region_list, i);

      if ((lo >= n->lo && (lo < n->hi || n->hi == 0)) 
	  || (hi > n->lo && (hi <= n->hi || n->hi == 0))
	  || (lo <= n->lo && ((hi >= n->hi && n->hi != 0) || hi == 0)))
	{
	  printf_unfiltered (_("overlapping memory region\n"));
	  return;
	}
    }

  newobj.number = ++mem_number;
  newobj.attrib = *attrib;
  VEC_safe_insert (mem_region_s, mem_region_list, ix, &newobj);
}
int main(void)
{
	const struct dt_property *names, *ranges;
	struct mem_region *r;
	unsigned int i, l, c;
	uint64_t *rangep;
	const char *name;
	void *buf;

	/* Use malloc for the heap, so valgrind can find issues. */
	skiboot_heap.start = (long)real_malloc(TEST_HEAP_SIZE);
	skiboot_heap.len = TEST_HEAP_SIZE;
	skiboot_os_reserve.len = skiboot_heap.start;

	dt_root = dt_new_root("");
	dt_add_property_cells(dt_root, "#address-cells", 2);
	dt_add_property_cells(dt_root, "#size-cells", 2);

	buf = real_malloc(1024*1024);
	add_mem_node((unsigned long)buf, 1024*1024);

	/* Now convert. */
	mem_region_init();

	/* create our reservations */
	for (i = 0; i < ARRAY_SIZE(test_regions); i++)
		mem_reserve(test_regions[i].name, test_regions[i].addr, 0x1000);

	/* release unused */
	mem_region_release_unused();

	/* and create reservations */
	mem_region_add_dt_reserved();

	/* ensure we can't create further reservations */
	r = new_region("test.4", 0x5000, 0x1000, NULL, REGION_RESERVED);
	assert(!add_region(r));

	/* check dt properties */
	names = dt_find_property(dt_root, "reserved-names");
	ranges = dt_find_property(dt_root, "reserved-ranges");

	assert(names && ranges);

	/* walk through names & ranges properies, ensuring that the test
	 * regions are all present */
	for (name = names->prop, rangep = (uint64_t *)ranges->prop, c = 0;
			name < names->prop + names->len;
			name += l, rangep += 2) {
		uint64_t addr;

		addr = dt_get_number(rangep, 2);
		l = strlen(name) + 1;

		for (i = 0; i < ARRAY_SIZE(test_regions); i++) {
			if (strcmp(test_regions[i].name, name))
				continue;
			assert(test_regions[i].addr == addr);
			assert(!test_regions[i].found);
			test_regions[i].found = true;
			c++;
		}
	}

	assert(c == ARRAY_SIZE(test_regions));

	dt_free(dt_root);
	real_free(buf);
	real_free((void *)(long)skiboot_heap.start);
	return 0;
}
Exemple #3
0
struct mem_map *create_maps(int pid)
{
    FILE *f;
    char *buf = NULL, *str = NULL;
    size_t total_read, capacity;

    size_t addr_start, addr_end, offset, len;
    char r, w, x, p;
    int dev_major, dev_minor, inode;
    char path[PATH_MAX];

    struct mem_map *map = NULL;
    struct mem_region *region;

    capacity = 0x100000;
    buf = calloc(1, capacity);

    sprintf(buf, "/proc/%d/maps", pid);
    if ((f = fopen(buf, "r")) == NULL) {
        fprintf(stderr, "cannot open %s: %s\n", buf, strerror(errno));
        return NULL;
    }

    map = malloc(sizeof(struct mem_map));
    mem_map_init(map);

    memset(buf, 0, capacity);
    total_read = 0;
    while (!feof(f)) {
        fread(&buf[total_read], capacity - total_read - 1, 1, f);
        if (errno) {
            perror("maps");
            mem_map_destroy(map);
            map = NULL;
            goto create_maps_end;
        }

        total_read = strlen(buf);
        if ((total_read + 1) == capacity) {
            capacity *= 2;
            buf = realloc(buf, capacity);
            memset(&buf[total_read], 0, capacity - total_read);
        } else {
            buf[total_read] = '\0';
        }
    }

    str = &buf[0];
    while (*str) {
        int scan;
        char *next;

        next = strchr(str, '\n');
        if (next != NULL)
            *next = '\0';

        scan = sscanf(str, "%zx-%zx %c%c%c%c %zx %x:%x %d %[^\t\n]",
                &addr_start, &addr_end,
                &r, &w, &x, &p,
                &offset,
                &dev_major, &dev_minor,
                &inode,
                path);

        if (scan < 10) {
            fprintf(stderr, "warning: unable to parse maps "
                    "entry '%s' (read %d)\n", str, scan);
            break;
        }

        region = malloc(sizeof(struct mem_region));
        mem_region_init(region);

        region->start = (void *)addr_start;
        region->length = addr_end - addr_start;
        region->offset = offset;
        if (scan > 10 && path[0] != '\0') {
            if (!strcmp(path, "[vdso]")) {
                region->type = MEM_REGION_TYPE_VDSO;
            } else if (!strcmp(path, "[vsyscall]")) {
                region->type = MEM_REGION_TYPE_VSYSCALL;
            } else if ((len = strlen(path)) > 10 &&
                    !strcmp(path + len - 10, " (deleted)")) {
                *(path + len - 10) = '\0';
                region->path = strdup(path);
                region->type = MEM_REGION_TYPE_DELETED;
            } else {
                region->path = strdup(path);
                region->type = MEM_REGION_TYPE_MMAP;
            }
        }

        if (mem_map_add_region(map, region) != 0) {
            mem_map_destroy(map);
            map = NULL;
            break;
        }

        if (next != NULL)
            str = next + 1;
    }

    if (map != NULL)
        mem_map_create_region_index(map);

create_maps_end:
    fclose(f);
    free(buf);
    return map;
}