static bool graphite_legal_transform_bb (poly_bb_p pbb1, poly_bb_p pbb2) { int i, j; poly_dr_p pdr1, pdr2; for (i = 0; VEC_iterate (poly_dr_p, PBB_DRS (pbb1), i, pdr1); i++) for (j = 0; VEC_iterate (poly_dr_p, PBB_DRS (pbb2), j, pdr2); j++) if (!graphite_legal_transform_dr (pbb1, pbb2, pdr1, pdr2)) return false; return true; }
bool graphite_legal_transform (scop_p scop) { int i, j; poly_bb_p pbb1, pbb2; for (i = 0; VEC_iterate (poly_bb_p, SCOP_BBS (scop), i, pbb1); i++) for (j = 0; VEC_iterate (poly_bb_p, SCOP_BBS (scop), j, pbb2); j++) if (!graphite_legal_transform_bb (pbb1, pbb2)) return false; return true; }
bool dependency_between_pbbs_p (poly_bb_p pbb1, poly_bb_p pbb2, int level) { int i, j; poly_dr_p pdr1, pdr2; for (i = 0; VEC_iterate (poly_dr_p, PBB_DRS (pbb1), i, pdr1); i++) for (j = 0; VEC_iterate (poly_dr_p, PBB_DRS (pbb2), j, pdr2); j++) if (graphite_carried_dependence_level_k (pdr1, pdr2, level)) return true; return false; }
static void tfile_write_uploaded_tp (struct trace_file_writer *self, struct uploaded_tp *utp) { struct tfile_trace_file_writer *writer = (struct tfile_trace_file_writer *) self; int a; char *act; char buf[MAX_TRACE_UPLOAD]; fprintf (writer->fp, "tp T%x:%s:%c:%x:%x", utp->number, phex_nz (utp->addr, sizeof (utp->addr)), (utp->enabled ? 'E' : 'D'), utp->step, utp->pass); if (utp->type == bp_fast_tracepoint) fprintf (writer->fp, ":F%x", utp->orig_size); if (utp->cond) fprintf (writer->fp, ":X%x,%s", (unsigned int) strlen (utp->cond) / 2, utp->cond); fprintf (writer->fp, "\n"); for (a = 0; VEC_iterate (char_ptr, utp->actions, a, act); ++a) fprintf (writer->fp, "tp A%x:%s:%s\n", utp->number, phex_nz (utp->addr, sizeof (utp->addr)), act); for (a = 0; VEC_iterate (char_ptr, utp->step_actions, a, act); ++a) fprintf (writer->fp, "tp S%x:%s:%s\n", utp->number, phex_nz (utp->addr, sizeof (utp->addr)), act); if (utp->at_string) { encode_source_string (utp->number, utp->addr, "at", utp->at_string, buf, MAX_TRACE_UPLOAD); fprintf (writer->fp, "tp Z%s\n", buf); } if (utp->cond_string) { encode_source_string (utp->number, utp->addr, "cond", utp->cond_string, buf, MAX_TRACE_UPLOAD); fprintf (writer->fp, "tp Z%s\n", buf); } for (a = 0; VEC_iterate (char_ptr, utp->cmd_strings, a, act); ++a) { encode_source_string (utp->number, utp->addr, "cmd", act, buf, MAX_TRACE_UPLOAD); fprintf (writer->fp, "tp Z%s\n", buf); } fprintf (writer->fp, "tp V%x:%s:%x:%s\n", utp->number, phex_nz (utp->addr, sizeof (utp->addr)), utp->hit_count, phex_nz (utp->traceframe_usage, sizeof (utp->traceframe_usage))); }
int unify_scattering_dimensions (scop_p scop) { int i; poly_bb_p pbb; graphite_dim_t max_scattering = 0; for (i = 0; VEC_iterate (poly_bb_p, SCOP_BBS (scop), i, pbb); i++) max_scattering = MAX (pbb_nb_scattering_transform (pbb), max_scattering); for (i = 0; VEC_iterate (poly_bb_p, SCOP_BBS (scop), i, pbb); i++) extend_scattering (pbb, max_scattering); return max_scattering; }
static void emit_mfence_after_loop (struct loop *loop) { VEC (edge, heap) *exits = get_loop_exit_edges (loop); edge exit; gimple call; gimple_stmt_iterator bsi; unsigned i; for (i = 0; VEC_iterate (edge, exits, i, exit); i++) { call = gimple_build_call (FENCE_FOLLOWING_MOVNT, 0); if (!single_pred_p (exit->dest) /* If possible, we prefer not to insert the fence on other paths in cfg. */ && !(exit->flags & EDGE_ABNORMAL)) split_loop_exit_edge (exit); bsi = gsi_after_labels (exit->dest); gsi_insert_before (&bsi, call, GSI_NEW_STMT); mark_virtual_ops_for_renaming (call); } VEC_free (edge, heap, exits); update_ssa (TODO_update_ssa_only_virtuals); }
static bool may_use_storent_in_loop_p (struct loop *loop) { bool ret = true; if (loop->inner != NULL) return false; /* If we must issue a mfence insn after using storent, check that there is a suitable place for it at each of the loop exits. */ if (FENCE_FOLLOWING_MOVNT != NULL_TREE) { VEC (edge, heap) *exits = get_loop_exit_edges (loop); unsigned i; edge exit; for (i = 0; VEC_iterate (edge, exits, i, exit); i++) if ((exit->flags & EDGE_ABNORMAL) && exit->dest == EXIT_BLOCK_PTR) ret = false; VEC_free (edge, heap, exits); } return ret; }
static void mem_disable_command (char *args, int from_tty) { int num; struct mem_region *m; int ix; require_user_regions (from_tty); target_dcache_invalidate (); if (args == NULL || *args == '\0') { for (ix = 0; VEC_iterate (mem_region_s, mem_region_list, ix, m); ix++) m->enabled_p = 0; } else { struct get_number_or_range_state state; init_number_or_range (&state, args); while (!state.finished) { num = get_number_or_range (&state); mem_disable (num); } } }
void pbb_remove_duplicate_pdrs (poly_bb_p pbb) { int i, j; poly_dr_p pdr1, pdr2; unsigned n = VEC_length (poly_dr_p, PBB_DRS (pbb)); VEC (poly_dr_p, heap) *collapsed = VEC_alloc (poly_dr_p, heap, n); for (i = 0; VEC_iterate (poly_dr_p, PBB_DRS (pbb), i, pdr1); i++) for (j = 0; VEC_iterate (poly_dr_p, collapsed, j, pdr2); j++) if (!can_collapse_pdrs (pdr1, pdr2)) VEC_quick_push (poly_dr_p, collapsed, pdr1); VEC_free (poly_dr_p, heap, collapsed); PBB_PDR_DUPLICATES_REMOVED (pbb) = true; }
static void require_user_regions (int from_tty) { struct mem_region *m; int ix, length; /* If we're already using a user-provided list, nothing to do. */ if (!mem_use_target) return; /* Switch to a user-provided list (possibly a copy of the current one). */ mem_use_target = 0; /* If we don't have a target-provided region list yet, then no need to warn. */ if (mem_region_list == NULL) return; /* Otherwise, let the user know how to get back. */ if (from_tty) warning (_("Switching to manual control of memory regions; use " "\"mem auto\" to fetch regions from the target again.")); /* And create a new list for the user to modify. */ length = VEC_length (mem_region_s, target_mem_region_list); mem_region_list = VEC_alloc (mem_region_s, length); for (ix = 0; VEC_iterate (mem_region_s, target_mem_region_list, ix, m); ix++) VEC_quick_push (mem_region_s, mem_region_list, m); }
static void verify_flow_insensitive_alias_info (void) { tree var; bitmap visited = BITMAP_ALLOC (NULL); referenced_var_iterator rvi; FOR_EACH_REFERENCED_VAR (var, rvi) { size_t j; var_ann_t ann; VEC(tree,gc) *may_aliases; tree alias; ann = var_ann (var); may_aliases = ann->may_aliases; for (j = 0; VEC_iterate (tree, may_aliases, j, alias); j++) { bitmap_set_bit (visited, DECL_UID (alias)); if (!may_be_aliased (alias)) { error ("non-addressable variable inside an alias set"); debug_variable (alias); goto err; } } }
static int signal_catchpoint_breakpoint_hit (const struct bp_location *bl, struct address_space *aspace, CORE_ADDR bp_addr, const struct target_waitstatus *ws) { const struct signal_catchpoint *c = (void *) bl->owner; gdb_signal_type signal_number; if (ws->kind != TARGET_WAITKIND_STOPPED) return 0; signal_number = ws->value.sig; /* If we are catching specific signals in this breakpoint, then we must guarantee that the called signal is the same signal we are catching. */ if (c->signals_to_be_caught) { int i; gdb_signal_type iter; for (i = 0; VEC_iterate (gdb_signal_type, c->signals_to_be_caught, i, iter); i++) if (signal_number == iter) return 1; /* Not the same. */ gdb_assert (!iter); return 0; } else return c->catch_all || !INTERNAL_SIGNAL (signal_number); }
static void signal_catchpoint_print_mention (struct breakpoint *b) { struct signal_catchpoint *c = (void *) b; if (c->signals_to_be_caught) { int i; gdb_signal_type iter; if (VEC_length (gdb_signal_type, c->signals_to_be_caught) > 1) printf_filtered (_("Catchpoint %d (signals"), b->number); else printf_filtered (_("Catchpoint %d (signal"), b->number); for (i = 0; VEC_iterate (gdb_signal_type, c->signals_to_be_caught, i, iter); i++) { const char *name = signal_to_name_or_int (iter); printf_filtered (" %s", name); } printf_filtered (")"); } else if (c->catch_all) printf_filtered (_("Catchpoint %d (any signal)"), b->number); else printf_filtered (_("Catchpoint %d (standard signals)"), b->number); }
static int signal_catchpoint_remove_location (struct bp_location *bl) { struct signal_catchpoint *c = (void *) bl->owner; int i; if (c->signals_to_be_caught != NULL) { gdb_signal_type iter; for (i = 0; VEC_iterate (gdb_signal_type, c->signals_to_be_caught, i, iter); i++) { gdb_assert (signal_catch_counts[iter] > 0); --signal_catch_counts[iter]; } } else { for (i = 0; i < GDB_SIGNAL_LAST; ++i) { if (c->catch_all || !INTERNAL_SIGNAL (i)) { gdb_assert (signal_catch_counts[i] > 0); --signal_catch_counts[i]; } } } signal_catch_update (signal_catch_counts); return 0; }
void print_iteration_domains (FILE *file, scop_p scop, int verbosity) { int i; poly_bb_p pbb; for (i = 0; VEC_iterate (poly_bb_p, SCOP_BBS (scop), i, pbb); i++) print_iteration_domain (file, pbb, verbosity); }
static void signal_catchpoint_print_one (struct breakpoint *b, struct bp_location **last_loc) { struct signal_catchpoint *c = (void *) b; struct value_print_options opts; struct ui_out *uiout = current_uiout; get_user_print_options (&opts); /* Field 4, the address, is omitted (which makes the columns not line up too nicely with the headers, but the effect is relatively readable). */ if (opts.addressprint) ui_out_field_skip (uiout, "addr"); annotate_field (5); if (c->signals_to_be_caught && VEC_length (gdb_signal_type, c->signals_to_be_caught) > 1) ui_out_text (uiout, "signals \""); else ui_out_text (uiout, "signal \""); if (c->signals_to_be_caught) { int i; gdb_signal_type iter; struct obstack text; struct cleanup *cleanup; obstack_init (&text); cleanup = make_cleanup_obstack_free (&text); for (i = 0; VEC_iterate (gdb_signal_type, c->signals_to_be_caught, i, iter); i++) { const char *name = signal_to_name_or_int (iter); if (i > 0) obstack_grow (&text, " ", 1); obstack_grow (&text, name, strlen (name)); } obstack_grow (&text, "", 1); ui_out_field_string (uiout, "what", obstack_base (&text)); do_cleanups (cleanup); } else ui_out_field_string (uiout, "what", c->catch_all ? "<any signal>" : "<standard signals>"); ui_out_text (uiout, "\" "); if (ui_out_is_mi_like_p (uiout)) ui_out_field_string (uiout, "catch-type", "signal"); }
static const struct serial_ops * serial_interface_lookup (const char *name) { const struct serial_ops *ops; int i; for (i = 0; VEC_iterate (serial_ops_p, serial_ops_list, i, ops); ++i) if (strcmp (name, ops->name) == 0) return ops; return NULL; }
static void mem_disable (int num) { struct mem_region *m; int ix; for (ix = 0; VEC_iterate (mem_region_s, mem_region_list, ix, m); ix++) if (m->number == num) { m->enabled_p = 0; return; } printf_unfiltered (_("No memory region number %d.\n"), num); }
static int thread_db_load_search (void) { VEC (char_ptr) *dir_vec; char *this_dir; int i, rc = 0; if (libthread_db_search_path == NULL) libthread_db_search_path = xstrdup (LIBTHREAD_DB_SEARCH_PATH); dir_vec = dirnames_to_char_ptr_vec (libthread_db_search_path); for (i = 0; VEC_iterate (char_ptr, dir_vec, i, this_dir); ++i) { const int pdir_len = sizeof ("$pdir") - 1; size_t this_dir_len; this_dir_len = strlen (this_dir); if (strncmp (this_dir, "$pdir", pdir_len) == 0 && (this_dir[pdir_len] == '\0' || this_dir[pdir_len] == '/')) { /* We don't maintain a list of loaded libraries so we don't know where libpthread lives. We *could* fetch the info, but we don't do that yet. Ignore it. */ } else if (strcmp (this_dir, "$sdir") == 0) { if (try_thread_db_load_from_sdir ()) { rc = 1; break; } } else { if (try_thread_db_load_from_dir (this_dir, this_dir_len)) { rc = 1; break; } } } free_char_ptr_vec (dir_vec); if (debug_threads) debug_printf ("thread_db_load_search returning %d\n", rc); return rc; }
static void add_block_to_enclosing (tree block) { unsigned i; tree enclosing; gimple bind; VEC(gimple, heap) *stack = gimple_bind_expr_stack (); for (i = 0; VEC_iterate (gimple, stack, i, bind); i++) if (gimple_bind_block (bind)) break; enclosing = gimple_bind_block (bind); BLOCK_SUBBLOCKS (enclosing) = chainon (BLOCK_SUBBLOCKS (enclosing), block); }
int scop_max_loop_depth (scop_p scop) { int i; poly_bb_p pbb; int max_nb_loops = 0; for (i = 0; VEC_iterate (poly_bb_p, SCOP_BBS (scop), i, pbb); i++) { int nb_loops = pbb_dim_iter_domain (pbb); if (max_nb_loops < nb_loops) max_nb_loops = nb_loops; } return max_nb_loops; }
void mi_cmd_info_ada_exceptions (char *command, char **argv, int argc) { struct ui_out *uiout = current_uiout; struct gdbarch *gdbarch = get_current_arch (); char *regexp; struct cleanup *old_chain; VEC(ada_exc_info) *exceptions; int ix; struct ada_exc_info *info; switch (argc) { case 0: regexp = NULL; break; case 1: regexp = argv[0]; break; default: error (_("Usage: -info-ada-exceptions [REGEXP]")); break; } exceptions = ada_exceptions_list (regexp); old_chain = make_cleanup (VEC_cleanup (ada_exc_info), &exceptions); make_cleanup_ui_out_table_begin_end (uiout, 2, VEC_length (ada_exc_info, exceptions), "ada-exceptions"); ui_out_table_header (uiout, 1, ui_left, "name", "Name"); ui_out_table_header (uiout, 1, ui_left, "address", "Address"); ui_out_table_body (uiout); for (ix = 0; VEC_iterate(ada_exc_info, exceptions, ix, info); ix++) { struct cleanup *sub_chain; sub_chain = make_cleanup_ui_out_tuple_begin_end (uiout, NULL); ui_out_field_string (uiout, "name", info->name); ui_out_field_core_addr (uiout, "address", gdbarch, info->addr); do_cleanups (sub_chain); } do_cleanups (old_chain); }
static void signal_catchpoint_print_recreate (struct breakpoint *b, struct ui_file *fp) { struct signal_catchpoint *c = (void *) b; fprintf_unfiltered (fp, "catch signal"); if (c->signals_to_be_caught) { int i; gdb_signal_type iter; for (i = 0; VEC_iterate (gdb_signal_type, c->signals_to_be_caught, i, iter); i++) fprintf_unfiltered (fp, " %s", signal_to_name_or_int (iter)); } else if (c->catch_all) fprintf_unfiltered (fp, " all"); }
static int val_expr_pair_expr_eq (const void *p1, const void *p2) { int i; tree vuse1; const val_expr_pair_t ve1 = (val_expr_pair_t) p1; const val_expr_pair_t ve2 = (val_expr_pair_t) p2; if (! expressions_equal_p (ve1->e, ve2->e)) return false; if (ve1->vuses == ve2->vuses) return true; if (VEC_length (tree, ve1->vuses) != VEC_length (tree, ve2->vuses)) return false; for (i = 0; VEC_iterate (tree, ve1->vuses, i, vuse1); i++) { if (VEC_index (tree, ve2->vuses, i) != vuse1) return false; } return true; }
static void mem_delete (int num) { struct mem_region *m; int ix; if (!mem_region_list) { printf_unfiltered (_("No memory region number %d.\n"), num); return; } for (ix = 0; VEC_iterate (mem_region_s, mem_region_list, ix, m); ix++) if (m->number == num) break; if (m == NULL) { printf_unfiltered (_("No memory region number %d.\n"), num); return; } VEC_ordered_remove (mem_region_s, mem_region_list, ix); }
static void btrace_func_history (struct btrace_thread_info *btinfo, struct ui_out *uiout, unsigned int begin, unsigned int end, enum record_print_flag flags) { struct btrace_func *bfun; unsigned int idx; DEBUG ("ftrace (0x%x): [%u; %u[", flags, begin, end); for (idx = begin; VEC_iterate (btrace_func_s, btinfo->ftrace, idx, bfun) && idx < end; ++idx) { /* Print the function index. */ ui_out_field_uint (uiout, "index", idx); ui_out_text (uiout, "\t"); if ((flags & record_print_insn_range) != 0) { btrace_func_history_insn_range (uiout, bfun); ui_out_text (uiout, "\t"); } if ((flags & record_print_src_line) != 0) { btrace_func_history_src_line (uiout, bfun); ui_out_text (uiout, "\t"); } if (bfun->sym != NULL) ui_out_field_string (uiout, "function", SYMBOL_PRINT_NAME (bfun->sym)); else if (bfun->msym != NULL) ui_out_field_string (uiout, "function", SYMBOL_PRINT_NAME (bfun->msym)); ui_out_text (uiout, "\n"); } }
static void btrace_insn_history (struct btrace_thread_info *btinfo, struct ui_out *uiout, unsigned int begin, unsigned int end, int flags) { struct gdbarch *gdbarch; struct btrace_inst *inst; unsigned int idx; DEBUG ("itrace (0x%x): [%u; %u[", flags, begin, end); gdbarch = target_gdbarch (); for (idx = begin; VEC_iterate (btrace_inst_s, btinfo->itrace, idx, inst) && idx < end; ++idx) { /* Print the instruction index. */ ui_out_field_uint (uiout, "index", idx); ui_out_text (uiout, "\t"); /* Disassembly with '/m' flag may not produce the expected result. See PR gdb/11833. */ gdb_disassembly (gdbarch, uiout, NULL, flags, 1, inst->pc, inst->pc + 1); } }
static void do_build_copy_constructor (tree fndecl) { tree parm = FUNCTION_FIRST_USER_PARM (fndecl); parm = convert_from_reference (parm); if (TYPE_HAS_TRIVIAL_INIT_REF (current_class_type) && is_empty_class (current_class_type)) /* Don't copy the padding byte; it might not have been allocated if *this is a base subobject. */; else if (TYPE_HAS_TRIVIAL_INIT_REF (current_class_type)) { tree t = build2 (INIT_EXPR, void_type_node, current_class_ref, parm); finish_expr_stmt (t); } else { tree fields = TYPE_FIELDS (current_class_type); tree member_init_list = NULL_TREE; int cvquals = cp_type_quals (TREE_TYPE (parm)); int i; tree binfo, base_binfo; VEC(tree,gc) *vbases; /* Initialize all the base-classes with the parameter converted to their type so that we get their copy constructor and not another constructor that takes current_class_type. We must deal with the binfo's directly as a direct base might be inaccessible due to ambiguity. */ for (vbases = CLASSTYPE_VBASECLASSES (current_class_type), i = 0; VEC_iterate (tree, vbases, i, binfo); i++) { member_init_list = tree_cons (binfo, build_tree_list (NULL_TREE, build_base_path (PLUS_EXPR, parm, binfo, 1)), member_init_list); } for (binfo = TYPE_BINFO (current_class_type), i = 0; BINFO_BASE_ITERATE (binfo, i, base_binfo); i++) { if (BINFO_VIRTUAL_P (base_binfo)) continue; member_init_list = tree_cons (base_binfo, build_tree_list (NULL_TREE, build_base_path (PLUS_EXPR, parm, base_binfo, 1)), member_init_list); } for (; fields; fields = TREE_CHAIN (fields)) { tree init = parm; tree field = fields; tree expr_type; if (TREE_CODE (field) != FIELD_DECL) continue; expr_type = TREE_TYPE (field); if (DECL_NAME (field)) { if (VFIELD_NAME_P (DECL_NAME (field))) continue; } else if (ANON_AGGR_TYPE_P (expr_type) && TYPE_FIELDS (expr_type)) /* Just use the field; anonymous types can't have nontrivial copy ctors or assignment ops. */; else continue; /* Compute the type of "init->field". If the copy-constructor parameter is, for example, "const S&", and the type of the field is "T", then the type will usually be "const T". (There are no cv-qualified variants of reference types.) */ if (TREE_CODE (expr_type) != REFERENCE_TYPE) { int quals = cvquals; if (DECL_MUTABLE_P (field)) quals &= ~TYPE_QUAL_CONST; expr_type = cp_build_qualified_type (expr_type, quals); } init = build3 (COMPONENT_REF, expr_type, init, field, NULL_TREE); init = build_tree_list (NULL_TREE, init); member_init_list = tree_cons (field, init, member_init_list); } finish_mem_initializers (member_init_list); } }
VEC (char_ptr) * location_completer (struct cmd_list_element *ignore, const char *text, const char *word) { int n_syms, n_files, ix; VEC (char_ptr) *fn_list = NULL; VEC (char_ptr) *list = NULL; const char *p; int quote_found = 0; int quoted = *text == '\'' || *text == '"'; int quote_char = '\0'; const char *colon = NULL; char *file_to_match = NULL; const char *symbol_start = text; const char *orig_text = text; size_t text_len; /* Do we have an unquoted colon, as in "break foo.c:bar"? */ for (p = text; *p != '\0'; ++p) { if (*p == '\\' && p[1] == '\'') p++; else if (*p == '\'' || *p == '"') { quote_found = *p; quote_char = *p++; while (*p != '\0' && *p != quote_found) { if (*p == '\\' && p[1] == quote_found) p++; p++; } if (*p == quote_found) quote_found = 0; else break; /* Hit the end of text. */ } #if HAVE_DOS_BASED_FILE_SYSTEM /* If we have a DOS-style absolute file name at the beginning of TEXT, and the colon after the drive letter is the only colon we found, pretend the colon is not there. */ else if (p < text + 3 && *p == ':' && p == text + 1 + quoted) ; #endif else if (*p == ':' && !colon) { colon = p; symbol_start = p + 1; } else if (strchr (current_language->la_word_break_characters(), *p)) symbol_start = p + 1; } if (quoted) text++; text_len = strlen (text); /* Where is the file name? */ if (colon) { char *s; file_to_match = (char *) xmalloc (colon - text + 1); strncpy (file_to_match, text, colon - text + 1); /* Remove trailing colons and quotes from the file name. */ for (s = file_to_match + (colon - text); s > file_to_match; s--) if (*s == ':' || *s == quote_char) *s = '\0'; } /* If the text includes a colon, they want completion only on a symbol name after the colon. Otherwise, we need to complete on symbols as well as on files. */ if (colon) { list = make_file_symbol_completion_list (symbol_start, word, file_to_match); xfree (file_to_match); } else { list = make_symbol_completion_list (symbol_start, word); /* If text includes characters which cannot appear in a file name, they cannot be asking for completion on files. */ if (strcspn (text, gdb_completer_file_name_break_characters) == text_len) fn_list = make_source_files_completion_list (text, text); } n_syms = VEC_length (char_ptr, list); n_files = VEC_length (char_ptr, fn_list); /* Catenate fn_list[] onto the end of list[]. */ if (!n_syms) { VEC_free (char_ptr, list); /* Paranoia. */ list = fn_list; fn_list = NULL; } else { char *fn; for (ix = 0; VEC_iterate (char_ptr, fn_list, ix, fn); ++ix) VEC_safe_push (char_ptr, list, fn); VEC_free (char_ptr, fn_list); } if (n_syms && n_files) { /* Nothing. */ } else if (n_files) { char *fn; /* If we only have file names as possible completion, we should bring them in sync with what rl_complete expects. The problem is that if the user types "break /foo/b TAB", and the possible completions are "/foo/bar" and "/foo/baz" rl_complete expects us to return "bar" and "baz", without the leading directories, as possible completions, because `word' starts at the "b". But we ignore the value of `word' when we call make_source_files_completion_list above (because that would not DTRT when the completion results in both symbols and file names), so make_source_files_completion_list returns the full "/foo/bar" and "/foo/baz" strings. This produces wrong results when, e.g., there's only one possible completion, because rl_complete will prepend "/foo/" to each candidate completion. The loop below removes that leading part. */ for (ix = 0; VEC_iterate (char_ptr, list, ix, fn); ++ix) { memmove (fn, fn + (word - text), strlen (fn) + 1 - (word - text)); } } else if (!n_syms) { /* No completions at all. As the final resort, try completing on the entire text as a symbol. */ list = make_symbol_completion_list (orig_text, word); } return list; }
gdb_bfd_ref_ptr build_id_to_debug_bfd (size_t build_id_len, const bfd_byte *build_id) { char *link, *debugdir; VEC (char_ptr) *debugdir_vec; struct cleanup *back_to; int ix; gdb_bfd_ref_ptr abfd; int alloc_len; /* DEBUG_FILE_DIRECTORY/.build-id/ab/cdef */ alloc_len = (strlen (debug_file_directory) + (sizeof "/.build-id/" - 1) + 1 + 2 * build_id_len + (sizeof ".debug" - 1) + 1); link = (char *) alloca (alloc_len); /* Keep backward compatibility so that DEBUG_FILE_DIRECTORY being "" will cause "/.build-id/..." lookups. */ debugdir_vec = dirnames_to_char_ptr_vec (debug_file_directory); back_to = make_cleanup_free_char_ptr_vec (debugdir_vec); for (ix = 0; VEC_iterate (char_ptr, debugdir_vec, ix, debugdir); ++ix) { size_t debugdir_len = strlen (debugdir); const gdb_byte *data = build_id; size_t size = build_id_len; char *s; char *filename = NULL; struct cleanup *inner; memcpy (link, debugdir, debugdir_len); s = &link[debugdir_len]; s += sprintf (s, "/.build-id/"); if (size > 0) { size--; s += sprintf (s, "%02x", (unsigned) *data++); } if (size > 0) *s++ = '/'; while (size-- > 0) s += sprintf (s, "%02x", (unsigned) *data++); strcpy (s, ".debug"); if (separate_debug_file_debug) printf_unfiltered (_(" Trying %s\n"), link); /* lrealpath() is expensive even for the usually non-existent files. */ if (access (link, F_OK) == 0) filename = lrealpath (link); if (filename == NULL) continue; /* We expect to be silent on the non-existing files. */ inner = make_cleanup (xfree, filename); abfd = gdb_bfd_open (filename, gnutarget, -1); do_cleanups (inner); if (abfd == NULL) continue; if (build_id_verify (abfd.get(), build_id_len, build_id)) break; abfd.release (); } do_cleanups (back_to); return abfd; }