diff options
-rw-r--r-- | gdb/ChangeLog | 53 | ||||
-rw-r--r-- | gdb/maint.c | 28 | ||||
-rw-r--r-- | gdb/minsyms.c | 53 | ||||
-rw-r--r-- | gdb/objfiles.c | 56 | ||||
-rw-r--r-- | gdb/objfiles.h | 13 |
5 files changed, 163 insertions, 40 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 3d45b9b..b5ddf0d 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,56 @@ +Thu Apr 3 15:10:30 1997 Michael Snyder <msnyder@cleaver.cygnus.com> + + * blockframe.c: blockvector_for_pc_sect(), block_for_pc_sect(), + find_pc_sect_function(), find_pc_sect_partial_function(): new + functions for debugging overlays; pc without section is ambiguous. + * breakpoint.[ch]: add section pointer to breakpoint struct; + add section argument to check_duplicates(); check section as well + as pc in [breakpoint_here_p(), breakpoint_inserted_here_p(), + breakpoint_thread_match(), bpstat_stop_status()]; + add section argument to describe_other_breakpoints(); + use INIT_SAL() macro to zero-out new sal structures; + make resolve_sal_pc() fix up the sal's section as well as its pc; + match on section + pc in clear_command() and delete_breakpoint(); + account for overlay sections in insert_breakpoints(), + remove_breakpoint() and breakpoint_re_set_one(); + all this to support overlays where a PC is not unique. + * exec.c: change xfer_memory() to handle overlay sections. + * findvar.c: change read_var_value() to handle overlay sections. + * frame.h: declaration for block_for_pc_sect() [blockframe.c]. + * infcmd.c: jump_command() warns against jumping into an overlay + that's not in memory. Also use INIT_SAL() to initialize sals. + * infrun.c: wait_for_inferior() sets a flag to invalidate cached + overlay state information; Also use INIT_SAL() to init sals. + * m32r-rom.c: modify load routines to use LMA instead of VMA. + * m32r-stub.c: mask exit value down to 8 bits; screen out any + memory read/writes in the range 600000 to a00000, and ff680000 + to ff800000 (hangs because nothing is mapped there); fix strcpy(). + * maint.c: maintenance command "translate-address" supports overlays. + * minsyms.c: lookup_minimal_symbol_by_pc_sect() supports overlays. + * objfiles.[ch]: add ovly_mapped field to the obj_section struct; + this constitutes gdb's internal overlay mapping table. Add macro + ALL_OBJSECTIONS() to loop thru the obj_structs and look at overlays. + Add function find_pc_sect_section(). + * printcmd.c: modify print_address_symbolic() with overlay smarts; + modify address_info() with overlay smarts; add function sym_info() + to support the INFO SYMBOL command (translate address to symbol(s)); + modify disassemble_command() to work on unmapped overlays. + * source.c: use INIT_SAL() to initialize sals. + * symfile.[ch]: change generic_load() to use section's LMA address + instead of VMA address, for overlay sections. + Add numerous functions for finding a PC's section / overlay, + translating between VMA and LMA address ranges, determining if an + overlay section is mapped, etc. Add several user commands for + overlay debugging. Add support for a "generic" form of automatically + reading overlay mapping info from the inferior (based on the default + (simple) overlay manager which Cygnus provides as an example). + * symtab.[ch]: add functions find_pc_sect_symtab(), + find_pc_sect_psymtab(), find_pc_sect_psymbol(), find_pc_sect_line() + for lookup; modify lookup_symbol and decode_line_1() to use them; + modify find_function_start_sal() to account for overlay sections; + add macro INIT_SAL() for initializing struct symtab_and_line. + * target.c: fix a comment in the declaration of target_ops. + Thu Apr 3 10:31:12 1997 Mark Alexander <marka@cygnus.com> * mips-tdep.c (mips_in_call_stub, mips_in_return_stub, diff --git a/gdb/maint.c b/gdb/maint.c index 28dde76..2bec634 100644 --- a/gdb/maint.c +++ b/gdb/maint.c @@ -294,7 +294,11 @@ maintenance_translate_address (arg, from_tty) CORE_ADDR address; asection *sect; char *p; - struct symbol *sym; + struct minimal_symbol *sym; + struct objfile *objfile; + + if (arg == NULL || *arg == 0) + error ("requires argument (address or section + address)"); sect = NULL; p = arg; @@ -308,17 +312,31 @@ maintenance_translate_address (arg, from_tty) *p++ = '\000'; while (isspace (*p)) p++; /* Skip whitespace */ - sect = bfd_get_section_by_name (exec_bfd, arg); + ALL_OBJFILES (objfile) + if (sect = bfd_get_section_by_name (objfile->obfd, arg)) + break; + if (!sect) error ("Unknown section %s.", arg); } address = parse_and_eval_address (p); - return; -/* sym = find_pc_function_section (address, sect);*/ + if (sect) + sym = lookup_minimal_symbol_by_pc_section (address, sect); + else + sym = lookup_minimal_symbol_by_pc (address); + + if (sym) + printf_filtered ("%s+%u\n", + SYMBOL_SOURCE_NAME (sym), + address - SYMBOL_VALUE_ADDRESS (sym)); + else if (sect) + printf_filtered ("no symbol at %s:0x%08x\n", sect->name, address); + else + printf_filtered ("no symbol at 0x%08x\n", address); - printf_unfiltered ("%s+%u\n", SYMBOL_SOURCE_NAME (sym), address - SYMBOL_VALUE_ADDRESS (sym)); + return; } #endif /* MAINTENANCE_CMDS */ diff --git a/gdb/minsyms.c b/gdb/minsyms.c index 174c3ed..9d6fd04 100644 --- a/gdb/minsyms.c +++ b/gdb/minsyms.c @@ -302,25 +302,27 @@ lookup_minimal_symbol_solib_trampoline (name, sfile, objf) } -/* Search through the minimal symbol table for each objfile and find the - symbol whose address is the largest address that is still less than or - equal to PC. Returns a pointer to the minimal symbol if such a symbol - is found, or NULL if PC is not in a suitable range. Note that we need - to look through ALL the minimal symbol tables before deciding on the - symbol that comes closest to the specified PC. This is because objfiles - can overlap, for example objfile A has .text at 0x100 and .data at 0x40000 - and objfile B has .text at 0x234 and .data at 0x40048. */ +/* Search through the minimal symbol table for each objfile and find + the symbol whose address is the largest address that is still less + than or equal to PC, and matches SECTION (if non-null). Returns a + pointer to the minimal symbol if such a symbol is found, or NULL if + PC is not in a suitable range. Note that we need to look through + ALL the minimal symbol tables before deciding on the symbol that + comes closest to the specified PC. This is because objfiles can + overlap, for example objfile A has .text at 0x100 and .data at + 0x40000 and objfile B has .text at 0x234 and .data at 0x40048. */ struct minimal_symbol * -lookup_minimal_symbol_by_pc (pc) - register CORE_ADDR pc; +lookup_minimal_symbol_by_pc_section (pc, section) + CORE_ADDR pc; + asection *section; { - register int lo; - register int hi; - register int new; - register struct objfile *objfile; - register struct minimal_symbol *msymbol; - register struct minimal_symbol *best_symbol = NULL; + int lo; + int hi; + int new; + struct objfile *objfile; + struct minimal_symbol *msymbol; + struct minimal_symbol *best_symbol = NULL; /* pc has to be in a known section. This ensures that anything beyond the end of the last segment doesn't appear to be part of the last @@ -361,7 +363,7 @@ lookup_minimal_symbol_by_pc (pc) Warning: this code is trickier than it would appear at first. */ - /* Should also requires that pc is <= end of objfile. FIXME! */ + /* Should also require that pc is <= end of objfile. FIXME! */ if (pc >= SYMBOL_VALUE_ADDRESS (&msymbol[lo])) { while (SYMBOL_VALUE_ADDRESS (&msymbol[hi]) > pc) @@ -405,6 +407,13 @@ lookup_minimal_symbol_by_pc (pc) && msymbol[hi].type == mst_abs) --hi; + /* If "section" specified, skip any symbol from wrong section */ + /* This is the new code that distinguishes it from the old function */ + if (section) + while (hi >= 0 + && SYMBOL_BFD_SECTION (&msymbol[hi]) != section) + --hi; + if (hi >= 0 && ((best_symbol == NULL) || (SYMBOL_VALUE_ADDRESS (best_symbol) < @@ -418,6 +427,16 @@ lookup_minimal_symbol_by_pc (pc) return (best_symbol); } +/* Backward compatibility: search through the minimal symbol table + for a matching PC (no section given) */ + +struct minimal_symbol * +lookup_minimal_symbol_by_pc (pc) + CORE_ADDR pc; +{ + return lookup_minimal_symbol_by_pc_section (pc, find_pc_mapped_section (pc)); +} + #ifdef SOFUN_ADDRESS_MAYBE_MISSING CORE_ADDR find_stab_function_addr (namestring, pst, objfile) diff --git a/gdb/objfiles.c b/gdb/objfiles.c index b78f80b..6573293 100644 --- a/gdb/objfiles.c +++ b/gdb/objfiles.c @@ -85,6 +85,7 @@ add_to_objfile_sections (abfd, asect, objfile_p_char) section.offset = 0; section.objfile = objfile; section.the_bfd_section = asect; + section.ovly_mapped = 0; section.addr = bfd_section_vma (abfd, asect); section.endaddr = section.addr + bfd_section_size (abfd, asect); obstack_grow (&objfile->psymbol_obstack, (char *) §ion, sizeof(section)); @@ -472,9 +473,9 @@ objfile_relocate (objfile, new_offsets) struct objfile *objfile; struct section_offsets *new_offsets; { - struct section_offsets *delta = (struct section_offsets *) alloca - (sizeof (struct section_offsets) - + objfile->num_sections * sizeof (delta->offsets)); + struct section_offsets *delta = (struct section_offsets *) + alloca (sizeof (struct section_offsets) + + objfile->num_sections * sizeof (delta->offsets)); { int i; @@ -520,7 +521,7 @@ objfile_relocate (objfile, new_offsets) b = BLOCKVECTOR_BLOCK (bv, i); BLOCK_START (b) += ANOFFSET (delta, s->block_line_section); - BLOCK_END (b) += ANOFFSET (delta, s->block_line_section); + BLOCK_END (b) += ANOFFSET (delta, s->block_line_section); for (j = 0; j < BLOCK_NSYMS (b); ++j) { @@ -533,7 +534,7 @@ objfile_relocate (objfile, new_offsets) || SYMBOL_CLASS (sym) == LOC_STATIC) && SYMBOL_SECTION (sym) >= 0) { - SYMBOL_VALUE_ADDRESS (sym) += + SYMBOL_VALUE_ADDRESS (sym) += ANOFFSET (delta, SYMBOL_SECTION (sym)); } #ifdef MIPS_EFI_SYMBOL_NAME @@ -543,7 +544,8 @@ objfile_relocate (objfile, new_offsets) if (SYMBOL_CLASS (sym) == LOC_CONST && SYMBOL_NAMESPACE (sym) == LABEL_NAMESPACE && STRCMP (SYMBOL_NAME (sym), MIPS_EFI_SYMBOL_NAME) == 0) - ecoff_relocate_efi (sym, ANOFFSET (delta, s->block_line_section)); + ecoff_relocate_efi (sym, ANOFFSET (delta, + s->block_line_section)); #endif } } @@ -567,12 +569,14 @@ objfile_relocate (objfile, new_offsets) psym < objfile->global_psymbols.next; psym++) if (SYMBOL_SECTION (*psym) >= 0) - SYMBOL_VALUE_ADDRESS (*psym) += ANOFFSET (delta, SYMBOL_SECTION (*psym)); + SYMBOL_VALUE_ADDRESS (*psym) += ANOFFSET (delta, + SYMBOL_SECTION (*psym)); for (psym = objfile->static_psymbols.list; psym < objfile->static_psymbols.next; psym++) if (SYMBOL_SECTION (*psym) >= 0) - SYMBOL_VALUE_ADDRESS (*psym) += ANOFFSET (delta, SYMBOL_SECTION (*psym)); + SYMBOL_VALUE_ADDRESS (*psym) += ANOFFSET (delta, + SYMBOL_SECTION (*psym)); } { @@ -606,17 +610,17 @@ objfile_relocate (objfile, new_offsets) if (flags & SEC_CODE) { - s->addr += ANOFFSET (delta, SECT_OFF_TEXT); + s->addr += ANOFFSET (delta, SECT_OFF_TEXT); s->endaddr += ANOFFSET (delta, SECT_OFF_TEXT); } else if (flags & (SEC_DATA | SEC_LOAD)) { - s->addr += ANOFFSET (delta, SECT_OFF_DATA); + s->addr += ANOFFSET (delta, SECT_OFF_DATA); s->endaddr += ANOFFSET (delta, SECT_OFF_DATA); } else if (flags & SEC_ALLOC) { - s->addr += ANOFFSET (delta, SECT_OFF_BSS); + s->addr += ANOFFSET (delta, SECT_OFF_BSS); s->endaddr += ANOFFSET (delta, SECT_OFF_BSS); } } @@ -627,19 +631,19 @@ objfile_relocate (objfile, new_offsets) if (objfile->ei.entry_func_lowpc != INVALID_ENTRY_LOWPC) { - objfile->ei.entry_func_lowpc += ANOFFSET (delta, SECT_OFF_TEXT); + objfile->ei.entry_func_lowpc += ANOFFSET (delta, SECT_OFF_TEXT); objfile->ei.entry_func_highpc += ANOFFSET (delta, SECT_OFF_TEXT); } if (objfile->ei.entry_file_lowpc != INVALID_ENTRY_LOWPC) { - objfile->ei.entry_file_lowpc += ANOFFSET (delta, SECT_OFF_TEXT); + objfile->ei.entry_file_lowpc += ANOFFSET (delta, SECT_OFF_TEXT); objfile->ei.entry_file_highpc += ANOFFSET (delta, SECT_OFF_TEXT); } if (objfile->ei.main_func_lowpc != INVALID_ENTRY_LOWPC) { - objfile->ei.main_func_lowpc += ANOFFSET (delta, SECT_OFF_TEXT); + objfile->ei.main_func_lowpc += ANOFFSET (delta, SECT_OFF_TEXT); objfile->ei.main_func_highpc += ANOFFSET (delta, SECT_OFF_TEXT); } } @@ -870,24 +874,40 @@ map_to_file (fd) #endif /* !defined(NO_MMALLOC) && defined(HAVE_MMAP) */ -/* Returns a section whose range includes PC or NULL if none found. */ +/* Returns a section whose range includes PC and SECTION, + or NULL if none found. Note the distinction between the return type, + struct obj_section (which is defined in gdb), and the input type + struct sec (which is a bfd-defined data type). The obj_section + contains a pointer to the bfd struct sec section. */ struct obj_section * -find_pc_section(pc) +find_pc_sect_section (pc, section) CORE_ADDR pc; + struct sec *section; { struct obj_section *s; struct objfile *objfile; ALL_OBJFILES (objfile) for (s = objfile->sections; s < objfile->sections_end; ++s) - if (s->addr <= pc - && pc < s->endaddr) + if ((section == 0 || section == s->the_bfd_section) && + s->addr <= pc && pc < s->endaddr) return(s); return(NULL); } +/* Returns a section whose range includes PC or NULL if none found. + Backward compatibility, no section. */ + +struct obj_section * +find_pc_section(pc) + CORE_ADDR pc; +{ + return find_pc_sect_section (pc, find_pc_mapped_section (pc)); +} + + /* In SVR4, we recognize a trampoline by it's section name. That is, if the pc is in a section named ".plt" then we are in a trampoline. */ diff --git a/gdb/objfiles.h b/gdb/objfiles.h index 937d0d4..d90095d 100644 --- a/gdb/objfiles.h +++ b/gdb/objfiles.h @@ -154,6 +154,9 @@ struct obj_section { /* Objfile this section is part of. */ struct objfile *objfile; + + /* True if this "overlay section" is mapped into an "overlay region". */ + int ovly_mapped; }; /* The "objstats" structure provides a place for gdb to record some @@ -454,6 +457,9 @@ have_minimal_symbols PARAMS ((void)); extern struct obj_section * find_pc_section PARAMS((CORE_ADDR pc)); +extern struct obj_section * +find_pc_sect_section PARAMS((CORE_ADDR pc, asection *section)); + extern int in_plt_section PARAMS ((CORE_ADDR, char *)); @@ -502,4 +508,11 @@ in_plt_section PARAMS ((CORE_ADDR, char *)); if ((objfile)->msymbols) \ ALL_OBJFILE_MSYMBOLS (objfile, m) +#define ALL_OBJFILE_OSECTIONS(objfile, osect) \ + for (osect = objfile->sections; osect < objfile->sections_end; osect++) + +#define ALL_OBJSECTIONS(objfile, osect) \ + ALL_OBJFILES (objfile) \ + ALL_OBJFILE_OSECTIONS (objfile, osect) + #endif /* !defined (OBJFILES_H) */ |