X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=gdb%2Fsymtab.c;h=67a784b2b6dec347aa64dc97c2f2056385b891a2;hb=3c0ee1a46468d89b8865cd70616af4558c499b16;hp=78118ee4d2a4b28e209c29f0d95f146e9f034f28;hpb=13387711b26dfd93e5b00e529df30f0132ec38fd;p=deliverable%2Fbinutils-gdb.git diff --git a/gdb/symtab.c b/gdb/symtab.c index 78118ee4d2..67a784b2b6 100644 --- a/gdb/symtab.c +++ b/gdb/symtab.c @@ -39,6 +39,7 @@ #include "source.h" #include "filenames.h" /* for FILENAME_CMP */ #include "objc-lang.h" +#include "d-lang.h" #include "ada-lang.h" #include "p-lang.h" #include "addrmap.h" @@ -346,6 +347,7 @@ symbol_init_language_specific (struct general_symbol_info *gsymbol, { gsymbol->language = language; if (gsymbol->language == language_cplus + || gsymbol->language == language_d || gsymbol->language == language_java || gsymbol->language == language_objc) { @@ -449,6 +451,16 @@ symbol_find_demangled_name (struct general_symbol_info *gsymbol, return demangled; } } + if (gsymbol->language == language_d + || gsymbol->language == language_auto) + { + demangled = d_demangle(mangled, 0); + if (demangled != NULL) + { + gsymbol->language = language_d; + return demangled; + } + } return NULL; } @@ -626,6 +638,7 @@ symbol_natural_name (const struct general_symbol_info *gsymbol) switch (gsymbol->language) { case language_cplus: + case language_d: case language_java: case language_objc: if (gsymbol->language_specific.cplus_specific.demangled_name != NULL) @@ -651,6 +664,7 @@ symbol_demangled_name (const struct general_symbol_info *gsymbol) switch (gsymbol->language) { case language_cplus: + case language_d: case language_java: case language_objc: if (gsymbol->language_specific.cplus_specific.demangled_name != NULL) @@ -940,7 +954,7 @@ lookup_symbol_in_language (const char *name, const struct block *block, modified_name = name; - /* If we are using C++ or Java, demangle the name before doing a lookup, so + /* If we are using C++, D, or Java, demangle the name before doing a lookup, so we can always binary search. */ if (lang == language_cplus) { @@ -972,6 +986,15 @@ lookup_symbol_in_language (const char *name, const struct block *block, make_cleanup (xfree, demangled_name); } } + else if (lang == language_d) + { + demangled_name = d_demangle (name, 0); + if (demangled_name) + { + modified_name = demangled_name; + make_cleanup (xfree, demangled_name); + } + } if (case_sensitivity == case_sensitive_off) { @@ -1150,7 +1173,7 @@ lookup_symbol_aux_local (const char *name, const struct block *block, /* Look up OBJFILE to BLOCK. */ -static struct objfile * +struct objfile * lookup_objfile_from_block (const struct block *block) { struct objfile *obj; @@ -1412,6 +1435,7 @@ symbol_matches_domain (enum language symbol_language, A Java class declaration also defines a typedef for the class. Similarly, any Ada type declaration implicitly defines a typedef. */ if (symbol_language == language_cplus + || symbol_language == language_d || symbol_language == language_java || symbol_language == language_ada) { @@ -2240,26 +2264,6 @@ find_pc_line_pc_range (CORE_ADDR pc, CORE_ADDR *startptr, CORE_ADDR *endptr) return sal.symtab != 0; } -/* Given a function start address PC and SECTION, find the first - address after the function prologue. */ -CORE_ADDR -find_function_start_pc (struct gdbarch *gdbarch, - CORE_ADDR pc, struct obj_section *section) -{ - /* If the function is in an unmapped overlay, use its unmapped LMA address, - so that gdbarch_skip_prologue has something unique to work on. */ - if (section_is_overlay (section) && !section_is_mapped (section)) - pc = overlay_unmapped_address (pc, section); - - pc += gdbarch_deprecated_function_start_offset (gdbarch); - pc = gdbarch_skip_prologue (gdbarch, pc); - - /* For overlays, map pc back into its mapped VMA range. */ - pc = overlay_mapped_address (pc, section); - - return pc; -} - /* Given a function start address FUNC_ADDR and SYMTAB, find the first address for that function that has an entry in SYMTAB's line info table. If such an entry cannot be found, return FUNC_ADDR @@ -2309,52 +2313,121 @@ skip_prologue_using_lineinfo (CORE_ADDR func_addr, struct symtab *symtab) struct symtab_and_line find_function_start_sal (struct symbol *sym, int funfirstline) { - struct block *block = SYMBOL_BLOCK_VALUE (sym); - struct objfile *objfile = lookup_objfile_from_block (block); - struct gdbarch *gdbarch = get_objfile_arch (objfile); + struct symtab_and_line sal; + + fixup_symbol_section (sym, NULL); + sal = find_pc_sect_line (BLOCK_START (SYMBOL_BLOCK_VALUE (sym)), + SYMBOL_OBJ_SECTION (sym), 0); + + /* We always should have a line for the function start address. + If we don't, something is odd. Create a plain SAL refering + just the PC and hope that skip_prologue_sal (if requested) + can find a line number for after the prologue. */ + if (sal.pc < BLOCK_START (SYMBOL_BLOCK_VALUE (sym))) + { + init_sal (&sal); + sal.pspace = current_program_space; + sal.pc = BLOCK_START (SYMBOL_BLOCK_VALUE (sym)); + sal.section = SYMBOL_OBJ_SECTION (sym); + } + if (funfirstline) + skip_prologue_sal (&sal); + + return sal; +} + +/* Adjust SAL to the first instruction past the function prologue. + If the PC was explicitly specified, the SAL is not changed. + If the line number was explicitly specified, at most the SAL's PC + is updated. If SAL is already past the prologue, then do nothing. */ +void +skip_prologue_sal (struct symtab_and_line *sal) +{ + struct symbol *sym; + struct symtab_and_line start_sal; + struct cleanup *old_chain; CORE_ADDR pc; - struct symtab_and_line sal; + struct obj_section *section; + const char *name; + struct objfile *objfile; + struct gdbarch *gdbarch; struct block *b, *function_block; - struct cleanup *old_chain; + /* Do not change the SAL is PC was specified explicitly. */ + if (sal->explicit_pc) + return; old_chain = save_current_space_and_thread (); - switch_to_program_space_and_thread (objfile->pspace); + switch_to_program_space_and_thread (sal->pspace); - pc = BLOCK_START (block); - fixup_symbol_section (sym, objfile); - if (funfirstline) + sym = find_pc_sect_function (sal->pc, sal->section); + if (sym != NULL) + { + fixup_symbol_section (sym, NULL); + + pc = BLOCK_START (SYMBOL_BLOCK_VALUE (sym)); + section = SYMBOL_OBJ_SECTION (sym); + name = SYMBOL_LINKAGE_NAME (sym); + objfile = SYMBOL_SYMTAB (sym)->objfile; + } + else { - /* Skip "first line" of function (which is actually its prologue). */ - pc = find_function_start_pc (gdbarch, pc, SYMBOL_OBJ_SECTION (sym)); + struct minimal_symbol *msymbol + = lookup_minimal_symbol_by_pc_section (sal->pc, sal->section); + if (msymbol == NULL) + { + do_cleanups (old_chain); + return; + } + + pc = SYMBOL_VALUE_ADDRESS (msymbol); + section = SYMBOL_OBJ_SECTION (msymbol); + name = SYMBOL_LINKAGE_NAME (msymbol); + objfile = msymbol_objfile (msymbol); } - sal = find_pc_sect_line (pc, SYMBOL_OBJ_SECTION (sym), 0); + + gdbarch = get_objfile_arch (objfile); + + /* If the function is in an unmapped overlay, use its unmapped LMA address, + so that gdbarch_skip_prologue has something unique to work on. */ + if (section_is_overlay (section) && !section_is_mapped (section)) + pc = overlay_unmapped_address (pc, section); + + /* Skip "first line" of function (which is actually its prologue). */ + pc += gdbarch_deprecated_function_start_offset (gdbarch); + pc = gdbarch_skip_prologue (gdbarch, pc); + + /* For overlays, map pc back into its mapped VMA range. */ + pc = overlay_mapped_address (pc, section); + + /* Calculate line number. */ + start_sal = find_pc_sect_line (pc, section, 0); /* Check if gdbarch_skip_prologue left us in mid-line, and the next line is still part of the same function. */ - if (sal.pc != pc - && BLOCK_START (block) <= sal.end - && sal.end < BLOCK_END (block)) + if (start_sal.pc != pc + && (sym? (BLOCK_START (SYMBOL_BLOCK_VALUE (sym)) <= start_sal.end + && start_sal.end < BLOCK_END (SYMBOL_BLOCK_VALUE (sym))) + : (lookup_minimal_symbol_by_pc_section (start_sal.end, section) + == lookup_minimal_symbol_by_pc_section (pc, section)))) { /* First pc of next line */ - pc = sal.end; + pc = start_sal.end; /* Recalculate the line number (might not be N+1). */ - sal = find_pc_sect_line (pc, SYMBOL_OBJ_SECTION (sym), 0); + start_sal = find_pc_sect_line (pc, section, 0); } /* On targets with executable formats that don't have a concept of constructors (ELF with .init has, PE doesn't), gcc emits a call to `__main' in `main' between the prologue and before user code. */ - if (funfirstline - && gdbarch_skip_main_prologue_p (gdbarch) - && SYMBOL_LINKAGE_NAME (sym) - && strcmp (SYMBOL_LINKAGE_NAME (sym), "main") == 0) + if (gdbarch_skip_main_prologue_p (gdbarch) + && name && strcmp (name, "main") == 0) { pc = gdbarch_skip_main_prologue (gdbarch, pc); /* Recalculate the line number (might not be N+1). */ - sal = find_pc_sect_line (pc, SYMBOL_OBJ_SECTION (sym), 0); + start_sal = find_pc_sect_line (pc, section, 0); } /* If we still don't have a valid source line, try to find the first @@ -2365,19 +2438,35 @@ find_function_start_sal (struct symbol *sym, int funfirstline) the case with the DJGPP target using "gcc -gcoff" when the compiler inserted code after the prologue to make sure the stack is aligned. */ - if (funfirstline && sal.symtab == NULL) + if (sym && start_sal.symtab == NULL) { pc = skip_prologue_using_lineinfo (pc, SYMBOL_SYMTAB (sym)); /* Recalculate the line number. */ - sal = find_pc_sect_line (pc, SYMBOL_OBJ_SECTION (sym), 0); + start_sal = find_pc_sect_line (pc, section, 0); } - sal.pc = pc; - sal.pspace = objfile->pspace; + do_cleanups (old_chain); + + /* If we're already past the prologue, leave SAL unchanged. Otherwise + forward SAL to the end of the prologue. */ + if (sal->pc >= pc) + return; + + sal->pc = pc; + sal->section = section; + + /* Unless the explicit_line flag was set, update the SAL line + and symtab to correspond to the modified PC location. */ + if (sal->explicit_line) + return; + + sal->symtab = start_sal.symtab; + sal->line = start_sal.line; + sal->end = start_sal.end; /* Check if we are now inside an inlined function. If we can, use the call site of the function instead. */ - b = block_for_pc_sect (sal.pc, SYMBOL_OBJ_SECTION (sym)); + b = block_for_pc_sect (sal->pc, sal->section); function_block = NULL; while (b != NULL) { @@ -2390,12 +2479,9 @@ find_function_start_sal (struct symbol *sym, int funfirstline) if (function_block != NULL && SYMBOL_LINE (BLOCK_FUNCTION (function_block)) != 0) { - sal.line = SYMBOL_LINE (BLOCK_FUNCTION (function_block)); - sal.symtab = SYMBOL_SYMTAB (BLOCK_FUNCTION (function_block)); + sal->line = SYMBOL_LINE (BLOCK_FUNCTION (function_block)); + sal->symtab = SYMBOL_SYMTAB (BLOCK_FUNCTION (function_block)); } - - do_cleanups (old_chain); - return sal; } /* If P is of the form "operator[ \t]+..." where `...' is @@ -3170,23 +3256,64 @@ rbreak_command_wrapper (char *regexp, int from_tty) rbreak_command (regexp, from_tty); } +/* A cleanup function that calls end_rbreak_breakpoints. */ + +static void +do_end_rbreak_breakpoints (void *ignore) +{ + end_rbreak_breakpoints (); +} + static void rbreak_command (char *regexp, int from_tty) { struct symbol_search *ss; struct symbol_search *p; struct cleanup *old_chain; + char *string = NULL; + int len = 0; + char **files = NULL; + int nfiles = 0; - search_symbols (regexp, FUNCTIONS_DOMAIN, 0, (char **) NULL, &ss); + if (regexp) + { + char *colon = strchr (regexp, ':'); + if (colon && *(colon + 1) != ':') + { + int colon_index; + char * file_name; + + colon_index = colon - regexp; + file_name = alloca (colon_index + 1); + memcpy (file_name, regexp, colon_index); + file_name[colon_index--] = 0; + while (isspace (file_name[colon_index])) + file_name[colon_index--] = 0; + files = &file_name; + nfiles = 1; + regexp = colon + 1; + while (isspace (*regexp)) regexp++; + } + } + + search_symbols (regexp, FUNCTIONS_DOMAIN, nfiles, files, &ss); old_chain = make_cleanup_free_search_symbols (ss); + make_cleanup (free_current_contents, &string); + start_rbreak_breakpoints (); + make_cleanup (do_end_rbreak_breakpoints, NULL); for (p = ss; p != NULL; p = p->next) { if (p->msymbol == NULL) { - char *string = alloca (strlen (p->symtab->filename) - + strlen (SYMBOL_LINKAGE_NAME (p->symbol)) - + 4); + int newlen = (strlen (p->symtab->filename) + + strlen (SYMBOL_LINKAGE_NAME (p->symbol)) + + 4); + if (newlen > len) + { + string = xrealloc (string, newlen); + len = newlen; + } strcpy (string, p->symtab->filename); strcat (string, ":'"); strcat (string, SYMBOL_LINKAGE_NAME (p->symbol)); @@ -3200,8 +3327,13 @@ rbreak_command (char *regexp, int from_tty) } else { - char *string = alloca (strlen (SYMBOL_LINKAGE_NAME (p->msymbol)) - + 3); + int newlen = (strlen (SYMBOL_LINKAGE_NAME (p->msymbol)) + + 3); + if (newlen > len) + { + string = xrealloc (string, newlen); + len = newlen; + } strcpy (string, "'"); strcat (string, SYMBOL_LINKAGE_NAME (p->msymbol)); strcat (string, "'"); @@ -4424,6 +4556,31 @@ expand_line_sal (struct symtab_and_line sal) return ret; } +/* Return 1 if the supplied producer string matches the ARM RealView + compiler (armcc). */ + +int +producer_is_realview (const char *producer) +{ + static const char *const arm_idents[] = { + "ARM C Compiler, ADS", + "Thumb C Compiler, ADS", + "ARM C++ Compiler, ADS", + "Thumb C++ Compiler, ADS", + "ARM/Thumb C/C++ Compiler, RVCT", + "ARM C/C++ Compiler, RVCT" + }; + int i; + + if (producer == NULL) + return 0; + + for (i = 0; i < ARRAY_SIZE (arm_idents); i++) + if (strncmp (producer, arm_idents[i], strlen (arm_idents[i])) == 0) + return 1; + + return 0; +} void _initialize_symtab (void)