From 8e717966f9ecdbaafd35520f8d8c9984db68cac4 Mon Sep 17 00:00:00 2001 From: Jeff Johnston Date: Tue, 14 Dec 2004 01:07:04 +0000 Subject: [PATCH] Fix to support listing base and regular constructors from gdb list and breakpoint commands. --- gdb-6.3-linespec-20041213.patch | 412 ++++++++++++++++++++++++++++++++ gdb.spec | 4 + 2 files changed, 416 insertions(+) create mode 100644 gdb-6.3-linespec-20041213.patch diff --git a/gdb-6.3-linespec-20041213.patch b/gdb-6.3-linespec-20041213.patch new file mode 100644 index 0000000..9cf38e6 --- /dev/null +++ b/gdb-6.3-linespec-20041213.patch @@ -0,0 +1,412 @@ +--- gdb-6.3/gdb/linespec.c.fix Mon Dec 13 19:55:27 2004 ++++ gdb-6.3/gdb/linespec.c Mon Dec 13 19:59:05 2004 +@@ -73,7 +73,8 @@ static struct symtabs_and_lines find_met + struct symbol *sym_class); + + static int collect_methods (char *copy, struct type *t, +- struct symbol **sym_arr); ++ struct symbol **sym_arr, ++ struct minimal_symbol **msym_arr); + + static NORETURN void cplusplus_error (const char *name, + const char *fmt, ...) +@@ -81,10 +82,12 @@ static NORETURN void cplusplus_error (co + + static int total_number_of_methods (struct type *type); + +-static int find_methods (struct type *, char *, struct symbol **); ++static int find_methods (struct type *, char *, struct symbol **, ++ struct minimal_symbol **); + + static int add_matching_methods (int method_counter, struct type *t, +- struct symbol **sym_arr); ++ struct symbol **sym_arr, ++ struct minimal_symbol **msym_arr); + + static int add_constructors (int method_counter, struct type *t, + struct symbol **sym_arr); +@@ -99,6 +102,9 @@ static int is_objc_method_format (const + static struct symtabs_and_lines decode_line_2 (struct symbol *[], + int, int, char ***); + ++static struct symtabs_and_lines decode_line_3 (struct minimal_symbol *[], ++ int, int, char ***); ++ + static struct symtab *symtab_from_filename (char **argptr, + char *p, int is_quote_enclosed, + int *not_found_ptr); +@@ -189,12 +195,18 @@ total_number_of_methods (struct type *ty + /* Recursive helper function for decode_line_1. + Look for methods named NAME in type T. + Return number of matches. +- Put matches in SYM_ARR, which should have been allocated with ++ Put symbol matches in SYM_ARR, which should have been allocated with + a size of total_number_of_methods (T) * sizeof (struct symbol *). ++ In a special case where we are looking for constructors, we may ++ have to return minimal symbols in the array: MSYM_ARR. This occurs ++ when the compiler does not generate mangled names for the constructor's ++ debug info because there are multiple versions of the constructor ++ (in-charge vs not-in-charge). + Note that this function is g++ specific. */ + + static int +-find_methods (struct type *t, char *name, struct symbol **sym_arr) ++find_methods (struct type *t, char *name, struct symbol **sym_arr, ++ struct minimal_symbol **msym_arr) + { + int i1 = 0; + int ibase; +@@ -237,7 +249,8 @@ find_methods (struct type *t, char *name + if (strcmp_iw (name, method_name) == 0) + /* Find all the overloaded methods with that name. */ + i1 += add_matching_methods (method_counter, t, +- sym_arr + i1); ++ sym_arr + i1, ++ msym_arr); + else if (strncmp (class_name, name, name_len) == 0 + && (class_name[name_len] == '\0' + || class_name[name_len] == '<')) +@@ -259,21 +272,83 @@ find_methods (struct type *t, char *name + + if (i1 == 0) + for (ibase = 0; ibase < TYPE_N_BASECLASSES (t); ibase++) +- i1 += find_methods (TYPE_BASECLASS (t, ibase), name, sym_arr + i1); ++ i1 += find_methods (TYPE_BASECLASS (t, ibase), name, sym_arr + i1, ++ msym_arr); + + return i1; + } + ++static int ++add_minsym_members (const char *class_name, ++ const char *member_name, ++ struct minimal_symbol **msym_arr) ++{ ++ char *completion_name; ++ char **list; ++ int i; ++ int comp_len; ++ int counter = 0; ++ ++ /* To find the member, we first cheat and use symbol completion. ++ This will give us a list of all the member names including ++ the function signature. */ ++ completion_name = xmalloc (strlen (class_name) + ++ strlen (member_name) + 9); ++ completion_name[0] = '\''; ++ strcpy (completion_name+1, class_name); ++ /* FIXME: make this the language class separator. */ ++ strcat (completion_name, "::"); ++ strcat (completion_name, member_name); ++ strcat (completion_name, "("); ++ list = make_symbol_completion_list (completion_name, ++ completion_name+1); ++ ++ /* Now that we have the list, we generate an array of their ++ corresponding minimal symbols. */ ++ counter = 0; ++ while (list && list[counter] != NULL) ++ { ++ msym_arr[counter] = lookup_minimal_symbol (list[counter], NULL, NULL); ++ ++counter; ++ } ++ ++ xfree (list); ++ ++ /* In the case of constructors, there may be in-charge vs not-in-charge ++ constructors. Check for names with $base which indicates not-in-charge ++ constructors. */ ++ comp_len = strlen (completion_name); ++ strcpy (completion_name + comp_len - 1, "$base("); ++ list = make_symbol_completion_list (completion_name, ++ completion_name+1); ++ ++ /* Again we have a list. Add their minimal symbols to the array. */ ++ i = 0; ++ while (list && list[i] != NULL) ++ { ++ msym_arr[counter] = lookup_minimal_symbol (list[i++], NULL, NULL); ++ ++counter; ++ } ++ xfree (list); ++ xfree (completion_name); ++ ++ return counter; ++} ++ + /* Add the symbols associated to methods of the class whose type is T + and whose name matches the method indexed by METHOD_COUNTER in the + array SYM_ARR. Return the number of methods added. */ + + static int + add_matching_methods (int method_counter, struct type *t, +- struct symbol **sym_arr) ++ struct symbol **sym_arr, ++ struct minimal_symbol **msym_arr) + { + int field_counter; + int i1 = 0; ++ int cons_index = 0; ++ char *class_name = type_name_no_tag (t); ++ char **list = NULL; + + for (field_counter = TYPE_FN_FIELDLIST_LENGTH (t, method_counter) - 1; + field_counter >= 0; +@@ -297,6 +372,16 @@ add_matching_methods (int method_counter + } + else + phys_name = TYPE_FN_FIELD_PHYSNAME (f, field_counter); ++ ++ /* Check for special case of looking for member that ++ doesn't have a mangled name provided. This will happen ++ when we have in-charge and not-in-charge constructors. ++ Since we don't have a mangled name to work with, if we ++ look for the symbol, we can only find the class itself. ++ We can find the information we need in the minimal symbol ++ table which has the full member name information we need. */ ++ if (strlen (phys_name) <= strlen (class_name)) ++ return add_minsym_members (class_name, phys_name, msym_arr); + + /* Destructor is handled by caller, don't add it to + the list. */ +@@ -322,6 +407,9 @@ add_matching_methods (int method_counter + } + } + ++ if (list) ++ xfree (list); ++ + return i1; + } + +@@ -601,6 +689,146 @@ decode_line_2 (struct symbol *sym_arr[], + discard_cleanups (old_chain); + return return_values; + } ++ ++/* Given a list of NELTS minimal symbols in MSYM_ARR, return a list of lines to ++ operate on (ask user if necessary). ++ If CANONICAL is non-NULL return a corresponding array of mangled names ++ as canonical line specs there. */ ++ ++static struct symtabs_and_lines ++decode_line_3 (struct minimal_symbol *msym_arr[], ++ int nelts, int funfirstline, ++ char ***canonical) ++{ ++ struct symtabs_and_lines values, return_values; ++ char *args, *arg1; ++ int i; ++ char *prompt; ++ char *symname; ++ struct cleanup *old_chain; ++ char **canonical_arr = (char **) NULL; ++ ++ values.sals = (struct symtab_and_line *) ++ alloca (nelts * sizeof (struct symtab_and_line)); ++ return_values.sals = (struct symtab_and_line *) ++ xmalloc (nelts * sizeof (struct symtab_and_line)); ++ old_chain = make_cleanup (xfree, return_values.sals); ++ ++ if (canonical) ++ { ++ canonical_arr = (char **) xmalloc (nelts * sizeof (char *)); ++ make_cleanup (xfree, canonical_arr); ++ memset (canonical_arr, 0, nelts * sizeof (char *)); ++ *canonical = canonical_arr; ++ } ++ ++ i = 0; ++ printf_unfiltered ("[0] cancel\n[1] all\n"); ++ while (i < nelts) ++ { ++ init_sal (&return_values.sals[i]); /* Initialize to zeroes. */ ++ init_sal (&values.sals[i]); ++ if (msym_arr[i]) ++ { ++ struct symtabs_and_lines msal = minsym_found (funfirstline, ++ msym_arr[i]); ++ memcpy (&values.sals[i], &msal.sals[0], ++ sizeof (struct symtab_and_line)); ++ if (values.sals[i].symtab) ++ printf_unfiltered ("[%d] %s at %s:%d\n", ++ (i + 2), ++ SYMBOL_PRINT_NAME (msym_arr[i]), ++ values.sals[i].symtab->filename, ++ values.sals[i].line); ++ else ++ printf_unfiltered ("[%d] %s at ?FILE:%d [No symtab? Probably broken debug info...]\n", ++ (i + 2), ++ SYMBOL_PRINT_NAME (msym_arr[i]), ++ values.sals[i].line); ++ ++ } ++ else ++ printf_unfiltered ("?HERE\n"); ++ i++; ++ } ++ ++ prompt = getenv ("PS2"); ++ if (prompt == NULL) ++ { ++ prompt = "> "; ++ } ++ args = command_line_input (prompt, 0, "overload-choice"); ++ ++ if (args == 0 || *args == 0) ++ error_no_arg ("one or more choice numbers"); ++ ++ i = 0; ++ while (*args) ++ { ++ int num; ++ ++ arg1 = args; ++ while (*arg1 >= '0' && *arg1 <= '9') ++ arg1++; ++ if (*arg1 && *arg1 != ' ' && *arg1 != '\t') ++ error ("Arguments must be choice numbers."); ++ ++ num = atoi (args); ++ ++ if (num == 0) ++ error ("canceled"); ++ else if (num == 1) ++ { ++ if (canonical_arr) ++ { ++ for (i = 0; i < nelts; i++) ++ { ++ if (canonical_arr[i] == NULL) ++ { ++ symname = DEPRECATED_SYMBOL_NAME (msym_arr[i]); ++ canonical_arr[i] = savestring (symname, strlen (symname)); ++ } ++ } ++ } ++ memcpy (return_values.sals, values.sals, ++ (nelts * sizeof (struct symtab_and_line))); ++ return_values.nelts = nelts; ++ discard_cleanups (old_chain); ++ return return_values; ++ } ++ ++ if (num >= nelts + 2) ++ { ++ printf_unfiltered ("No choice number %d.\n", num); ++ } ++ else ++ { ++ num -= 2; ++ if (values.sals[num].pc) ++ { ++ if (canonical_arr) ++ { ++ symname = DEPRECATED_SYMBOL_NAME (msym_arr[num]); ++ make_cleanup (xfree, symname); ++ canonical_arr[i] = savestring (symname, strlen (symname)); ++ } ++ return_values.sals[i++] = values.sals[num]; ++ values.sals[num].pc = 0; ++ } ++ else ++ { ++ printf_unfiltered ("duplicate request for %d ignored.\n", num); ++ } ++ } ++ ++ args = arg1; ++ while (*args == ' ' || *args == '\t') ++ args++; ++ } ++ return_values.nelts = i; ++ discard_cleanups (old_chain); ++ return return_values; ++} + + /* The parser of linespec itself. */ + +@@ -1404,35 +1632,46 @@ find_method (int funfirstline, char ***c + int i1; /* Counter for the symbol array. */ + struct symbol **sym_arr = alloca (total_number_of_methods (t) + * sizeof (struct symbol *)); ++ struct minimal_symbol **msym_arr = alloca (total_number_of_methods (t) ++ * sizeof (struct minimal_symbol *)); ++ ++ msym_arr[0] = NULL; + + /* Find all methods with a matching name, and put them in + sym_arr. */ + +- i1 = collect_methods (copy, t, sym_arr); ++ i1 = collect_methods (copy, t, sym_arr, msym_arr); + + if (i1 == 1) + { + /* There is exactly one field with that name. */ +- sym = sym_arr[0]; +- +- if (sym && SYMBOL_CLASS (sym) == LOC_BLOCK) +- { +- values.sals = (struct symtab_and_line *) +- xmalloc (sizeof (struct symtab_and_line)); +- values.nelts = 1; +- values.sals[0] = find_function_start_sal (sym, +- funfirstline); +- } ++ if (msym_arr[0] != NULL) ++ return minsym_found (funfirstline, msym_arr[0]); + else + { +- values.nelts = 0; ++ sym = sym_arr[0]; ++ ++ if (sym && SYMBOL_CLASS (sym) == LOC_BLOCK) ++ { ++ values.sals = (struct symtab_and_line *) ++ xmalloc (sizeof (struct symtab_and_line)); ++ values.nelts = 1; ++ values.sals[0] = find_function_start_sal (sym, ++ funfirstline); ++ } ++ else ++ { ++ values.nelts = 0; ++ } ++ return values; + } +- return values; + } + if (i1 > 0) + { + /* There is more than one field with that name + (overloaded). Ask the user which one to use. */ ++ if (msym_arr[0] != NULL) ++ return decode_line_3 (msym_arr, i1, funfirstline, canonical); + return decode_line_2 (sym_arr, i1, funfirstline, canonical); + } + else +@@ -1459,11 +1698,12 @@ find_method (int funfirstline, char ***c + } + + /* Find all methods named COPY in the class whose type is T, and put +- them in SYM_ARR. Return the number of methods found. */ ++ them in SYM_ARR or MSYM_ARR. Return the number of methods found. */ + + static int + collect_methods (char *copy, struct type *t, +- struct symbol **sym_arr) ++ struct symbol **sym_arr, ++ struct minimal_symbol **msym_arr) + { + int i1 = 0; /* Counter for the symbol array. */ + +@@ -1485,7 +1725,7 @@ collect_methods (char *copy, struct type + } + } + else +- i1 = find_methods (t, copy, sym_arr); ++ i1 = find_methods (t, copy, sym_arr, msym_arr); + + return i1; + } diff --git a/gdb.spec b/gdb.spec index 27e36b9..3626b52 100644 --- a/gdb.spec +++ b/gdb.spec @@ -134,6 +134,9 @@ Patch114: gdb-6.3-ia64-backtrace-20041213.patch # Fix to ensure types are visible Patch115: gdb-6.3-type-fix-20041213.patch +# Fix to display base constructors from list and breakpoint commands +Patch116: gdb-6.3-linespec-20041213.patch + %ifarch ia64 BuildRequires: ncurses-devel glibc-devel gcc make gzip texinfo dejagnu libunwind >= 0.96-3 %else @@ -182,6 +185,7 @@ and printing their data. %patch113 -p1 %patch114 -p1 %patch115 -p1 +%patch116 -p1 %patch50 -p1