struct map *map__new(struct mmap_event *event, enum map_type type, char *cwd, int cwdlen) { struct map *self = malloc(sizeof(*self)); if (self != NULL) { const char *filename = event->filename; char newfilename[PATH_MAX]; struct dso *dso; int anon; if (cwd) { int n = strcommon(filename, cwd, cwdlen); if (n == cwdlen) { snprintf(newfilename, sizeof(newfilename), ".%s", filename + n); filename = newfilename; } } anon = is_anon_memory(filename); if (anon) { snprintf(newfilename, sizeof(newfilename), "/tmp/perf-%d.map", event->pid); filename = newfilename; } dso = dsos__findnew(filename); if (dso == NULL) goto out_delete; map__init(self, type, event->start, event->start + event->len, event->pgoff, dso); if (anon) { set_identity: self->map_ip = self->unmap_ip = identity__map_ip; } else if (strcmp(filename, "[vdso]") == 0) { dso__set_loaded(dso, self->type); goto set_identity; } } return self; out_delete: free(self); return NULL; }
static int32_t command_matches (const char *input, char *output, uint8_t show_ambiguous, uint8_t show_complete, uint8_t execute_command, void *context) { char cand_expand_to[MAXSTR]; command_t *matched_command; char completes_to[MAXSTR]; char expands_to[MAXSTR]; tokens_t input_tokens; char match[MAXSTR]; char match2[MAXSTR]; int32_t longest_match; int32_t common_len; command_t *command; int32_t matches; int32_t cnt; int32_t t; matched_command = 0; longest_match = -1; matches = 0; /* * Convert the input into tokens for matching. */ tokens_tostring(input, &input_tokens); /* * Find the command(s) with the most number of matching tokens. */ TREE_WALK(commands, command) { for (t = 0; t < (int32_t)min(command->tokens.cnt, input_tokens.cnt); t++) { cnt = strncmp(command->tokens.args[t], input_tokens.args[t], strlen(input_tokens.args[t])); if (slre_match(&command->tokens.regexp[t], input_tokens.args[t], (int) strlen(input_tokens.args[t]), 0 /* captures */)) { /* * Success */ cnt = 0; } if (cnt) { t = -1; break; } } longest_match = max(t, longest_match); } if (longest_match == -1) { return (0); } /* * Repeat and optionally dump other possibilities if the command is * not complete. */ { TREE_WALK(commands, command) { for (t = 0; t < (int32_t)min(command->tokens.cnt, input_tokens.cnt); t++) { cnt = strncmp(command->tokens.args[t], input_tokens.args[t], strlen(input_tokens.args[t])); if (slre_match(&command->tokens.regexp[t], input_tokens.args[t], (int) strlen(input_tokens.args[t]), 0 /* captures */)) { /* * Success */ cnt = 0; } if (cnt) { break; } } // tokens_print_to(&command->readable_tokens, match, sizeof(match)); if (t == longest_match) { matches++; // CON(" MATCH \"%s\" [%d] longest %d", match,t,longest_match); matched_command = command; if (show_complete) { completes_to[0] = '\0'; for (t = 0; t < longest_match; t++) { strlcat(completes_to, command->tokens.args[t], sizeof(completes_to)); strlcat(completes_to, " ", sizeof(completes_to)); } if (output) { strlcpy(output, completes_to, MAXSTR); } } tokens_print_to(&command->input_tokens, match, sizeof(match)); tokens_print_to(&command->readable_tokens, match2, sizeof(match2)); if (show_ambiguous) { CON(" %-40s -- %s", match, match2); } } else { // CON(" NO MATCH \"%s\" [%d] longest %d", match,t,longest_match); } } } /* * Repeat and complete the command to any full matches. */ { expands_to[0] = '\0'; { TREE_WALK(commands, command) { for (t = 0; t < (int32_t)min(command->tokens.cnt, input_tokens.cnt); t++) { cnt = strncmp(command->tokens.args[t], input_tokens.args[t], strlen(input_tokens.args[t])); if (slre_match(&command->tokens.regexp[t], input_tokens.args[t], (int) strlen(input_tokens.args[t]), 0 /* captures */)) { /* * Success */ cnt = 0; } if (cnt) { break; } } if (t == longest_match) { cand_expand_to[0] = '\0'; for (t = 0; t < longest_match; t++) { if (strisregexp(command->tokens.args[t])) { strlcat(cand_expand_to, input_tokens.args[t], sizeof(cand_expand_to)); strlcat(cand_expand_to, " ", sizeof(cand_expand_to)); continue; } strlcat(cand_expand_to, command->tokens.args[t], sizeof(cand_expand_to)); strlcat(cand_expand_to, " ", sizeof(cand_expand_to)); } if (expands_to[0] != '\0') { common_len = strcommon(expands_to, cand_expand_to); expands_to[common_len] = '\0'; } else { strlcpy(expands_to, cand_expand_to, sizeof(expands_to)); } } } /* * Expands to: */ if (output) { strlcpy(output, expands_to, MAXSTR); } } } if (execute_command && matched_command && (matches == 1)) { (*matched_command->callback)(&input_tokens, context); } return (matches); }