static RList *r_debug_native_map_get (RDebug *dbg) { RList *list = NULL; #if __KFBSD__ int ign; char unkstr[128]; #endif #if __APPLE__ list = xnu_dbg_maps (dbg, 0); #elif __WINDOWS__ && !__CYGWIN__ list = w32_dbg_maps (dbg); // TODO: moar? #else #if __sun char path[1024]; /* TODO: On solaris parse /proc/%d/map */ snprintf (path, sizeof(path) - 1, "pmap %d > /dev/stderr", ps.tid); system (path); #else RDebugMap *map; int i, perm, unk = 0; char *pos_c; char path[1024], line[1024]; char region[100], region2[100], perms[5]; FILE *fd; if (dbg->pid == -1) { //eprintf ("r_debug_native_map_get: No selected pid (-1)\n"); return NULL; } #if __KFBSD__ list = r_debug_native_sysctl_map (dbg); if (list != NULL) return list; snprintf (path, sizeof (path), "/proc/%d/map", dbg->pid); #else snprintf (path, sizeof (path), "/proc/%d/maps", dbg->pid); #endif fd = fopen (path, "r"); if (!fd) { perror (sdb_fmt (0, "Cannot open '%s'", path)); return NULL; } list = r_list_new(); if (!list) { fclose (fd); return NULL; } list->free = (RListFree)_map_free; while (!feof (fd)) { line[0] = '\0'; fgets (line, sizeof(line) - 1, fd); if (line[0] == '\0') break; path[0] = '\0'; line[strlen (line) - 1] = '\0'; #if __KFBSD__ // 0x8070000 0x8072000 2 0 0xc1fde948 rw- 1 0 0x2180 COW NC vnode /usr/bin/gcc sscanf (line, "%s %s %d %d 0x%s %3s %d %d", ®ion[2], ®ion2[2], &ign, &ign, unkstr, perms, &ign, &ign); pos_c = strchr (line, '/'); if (pos_c) strncpy (path, pos_c, sizeof(path) - 1); else path[0] = '\0'; #else char null[64]; // XXX: this can overflow sscanf (line, "%s %s %s %s %s %s", ®ion[2], perms, null, null, null, path); pos_c = strchr (®ion[2], '-'); if (!pos_c) continue; pos_c[-1] = (char)'0'; // xxx. this is wrong pos_c[ 0] = (char)'x'; strncpy (region2, pos_c - 1, sizeof(region2) - 1); #endif // __KFBSD__ region[0] = region2[0] = '0'; region[1] = region2[1] = 'x'; if (!*path) snprintf (path, sizeof(path), "unk%d", unk++); perm = 0; for (i = 0; perms[i] && i < 4; i++) switch (perms[i]) { case 'r': perm |= R_IO_READ; break; case 'w': perm |= R_IO_WRITE; break; case 'x': perm |= R_IO_EXEC; break; } map = r_debug_map_new (path, r_num_get (NULL, region), r_num_get (NULL, region2), perm, 0); if (!map) break; map->file = strdup (path); r_list_append (list, map); } fclose (fd); #endif // __sun #endif // __WINDOWS return list; }
static RList *r_debug_native_map_get (RDebug *dbg) { RList *list = NULL; #if __KFBSD__ int ign; char unkstr[128]; #endif #if __APPLE__ list = xnu_dbg_maps (dbg, 0); #elif __WINDOWS__ && !__CYGWIN__ list = w32_dbg_maps (dbg); // TODO: moar? #else #if __sun char path[1024]; /* TODO: On solaris parse /proc/%d/map */ snprintf (path, sizeof(path) - 1, "pmap %d > /dev/stderr", ps.tid); system (path); #else RDebugMap *map; int i, perm, unk = 0; char *pos_c; char path[1024], line[1024], name[1024]; char region[100], region2[100], perms[5]; FILE *fd; if (dbg->pid == -1) { //eprintf ("r_debug_native_map_get: No selected pid (-1)\n"); return NULL; } /* prepend 0x prefix */ region[0] = region2[0] = '0'; region[1] = region2[1] = 'x'; #if __OpenBSD__ /* OpenBSD has no procfs, so no idea trying. */ return r_debug_native_sysctl_map (dbg); #endif #if __KFBSD__ list = r_debug_native_sysctl_map (dbg); if (list) { return list; } snprintf (path, sizeof (path), "/proc/%d/map", dbg->pid); #else snprintf (path, sizeof (path), "/proc/%d/maps", dbg->pid); #endif fd = fopen (path, "r"); if (!fd) { perror (sdb_fmt (0, "Cannot open '%s'", path)); return NULL; } list = r_list_new (); if (!list) { fclose (fd); return NULL; } list->free = (RListFree)_map_free; while (!feof (fd)) { size_t line_len; ut64 map_start, map_end; if (!fgets (line, sizeof (line), fd)) break; /* kill the newline if we got one */ line_len = strlen (line); if (line[line_len - 1] == '\n') { line[line_len - 1] = '\0'; line_len--; } /* maps files should not have empty lines */ if (line_len == 0) { break; } #if __KFBSD__ // 0x8070000 0x8072000 2 0 0xc1fde948 rw- 1 0 0x2180 COW NC vnode /usr/bin/gcc if (sscanf (line, "%s %s %d %d 0x%s %3s %d %d", ®ion[2], ®ion2[2], &ign, &ign, unkstr, perms, &ign, &ign) != 8) { eprintf ("%s: Unable to parse \"%s\"\n", __func__, path); r_list_free (list); return NULL; } /* snag the file name */ pos_c = strchr (line, '/'); if (pos_c) { strncpy (name, pos_c, sizeof (name) - 1); } else { name[0] = '\0'; } #else // 7fc8124c4000-7fc81278d000 r--p 00000000 fc:00 17043921 /usr/lib/locale/locale-archive i = sscanf (line, "%s %s %*s %*s %*s %[^\n]", ®ion[2], perms, name); if (i == 2) { name[0] = '\0'; } else if (i != 3) { eprintf ("%s: Unable to parse \"%s\"\n", __func__, path); eprintf ("%s: problematic line: %s\n", __func__, line); r_list_free (list); return NULL; } /* split the region in two */ pos_c = strchr (®ion[2], '-'); if (!pos_c) // should this be an error? continue; strncpy (®ion2[2], pos_c + 1, sizeof (region2) - 2 - 1); #endif // __KFBSD__ if (!*name) snprintf (name, sizeof (name), "unk%d", unk++); perm = 0; for (i = 0; perms[i] && i < 4; i++) { switch (perms[i]) { case 'r': perm |= R_IO_READ; break; case 'w': perm |= R_IO_WRITE; break; case 'x': perm |= R_IO_EXEC; break; } } map_start = r_num_get (NULL, region); map_end = r_num_get (NULL, region2); if (map_start == map_end || map_end == 0) { eprintf ("%s: ignoring invalid map size: %s - %s\n", __func__, region, region2); continue; } map = r_debug_map_new (name, map_start, map_end, perm, 0); if (!map) { break; } map->file = strdup (name); r_list_append (list, map); } fclose (fd); #endif // __sun #endif // __WINDOWS return list; }