From 40b647e9e227be8176afeb77f219c3cfb44d2d06 Mon Sep 17 00:00:00 2001 From: Fred Fish Date: Fri, 13 Jun 1997 17:30:24 +0000 Subject: [PATCH] * config/i386/nm-linux.h: Enable prototypes that were #ifdef out. * config/tm-sysv4.h (in_plt_section): Add prototype. * maint.c (maintenance_translate_address): Avoid assignment inside if, per GNU coding standards. * symfile.c (simple_read_overlay_table): Avoid assignments inside if, per GNU coding standards. * monitor.c (parse_register_dump): Is really a void function. Add prototype. (monitor_read_memory): Remove unused variable "name". (monitor_read_memory): Remove unused variable "regbuf". (monitor_open): Remove unused variable "i". (get_hex_word): Apparently unused, #if away for now. (from_hex): Ditto. * i386v4-nat.c (supply_fpregset): Remove unused variable "regi". (fill_fpregset): Remove unused variables "regi", "to", "from" and "registers". * remote-e7000.c (ctype.h): Include. (e7000_insert_breakpoint): #if away unused arg used by unused expr. * frame.h (generic_get_saved_register): Add prototype. (enum lval_type): Add partial forward decl. * dsrec.c (make_srec): Remove unused variable "type_code". * remote-sim.c (gdbsim_wait): Handle sim_running and sim_polling cases by just ignoring them. (command.h): Include. * java-exp.y (parse_number): Remove unused variable "unsigned_p". * java-lang.c (gdbcore.h): Include for prototypes. (type_from_class): Remove unused variable "ftype". (type_from_class): Remove unused variable "name_length". (evaluate_subexp_java): Add default case to handle remaining enumerations. * java-valprint.c (c-lang.h): Include for prototypes. * symfile.c (simple_read_overlay_region_table): #if away unused function. (simple_free_overlay_region_table): Ditto. (overlay_is_mapped): Add default case to switch. (simple_read_overlay_region_table): Ditto. (simple_read_overlay_region_table): Add prototype. * symtab.c (fixup_symbol_section): Remove unused msym variable. (fixup_psymbol_section): Ditto. (find_pc_sect_symtab): Make distance a CORE_ADDR. * utils.c: Add comment about t_addr being either unsigned long or unsigned long long. (paddr): Change formats to match actual types args are cast to. (preg): Ditto. (paddr_nz): Ditto. (preg_nz): Ditto. --- gdb/ChangeLog | 57 +++- gdb/config/tm-sysv4.h | 1 + gdb/i386v4-nat.c | 7 - gdb/java-exp.y | 1 - gdb/java-lang.c | 5 +- gdb/java-valprint.c | 1 + gdb/maint.c | 7 +- gdb/objfiles.c | 2 +- gdb/remote-sim.c | 5 + gdb/symfile.c | 772 +++++++++++++++++++++++++++++++++++++++++- gdb/symtab.c | 6 +- gdb/utils.c | 64 ++-- 12 files changed, 875 insertions(+), 53 deletions(-) diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 063ae52eea..cc835d1911 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,4 +1,59 @@ -Fri Jun 13 07:30:48 1997 Fred Fish +Fri Jun 13 10:28:09 1997 Fred Fish + + * config/i386/nm-linux.h: Enable prototypes that were #ifdef out. + * config/tm-sysv4.h (in_plt_section): Add prototype. + + * maint.c (maintenance_translate_address): Avoid assignment + inside if, per GNU coding standards. + * symfile.c (simple_read_overlay_table): Avoid assignments inside if, per + GNU coding standards. + + * monitor.c (parse_register_dump): Is really a void function. + Add prototype. + (monitor_read_memory): Remove unused variable "name". + (monitor_read_memory): Remove unused variable "regbuf". + (monitor_open): Remove unused variable "i". + (get_hex_word): Apparently unused, #if away for now. + (from_hex): Ditto. + + * i386v4-nat.c (supply_fpregset): Remove unused variable "regi". + (fill_fpregset): Remove unused variables "regi", "to", "from" and + "registers". + + * remote-e7000.c (ctype.h): Include. + (e7000_insert_breakpoint): #if away unused arg used by unused expr. + * frame.h (generic_get_saved_register): Add prototype. + (enum lval_type): Add partial forward decl. + * dsrec.c (make_srec): Remove unused variable "type_code". + * remote-sim.c (gdbsim_wait): Handle sim_running and sim_polling + cases by just ignoring them. + (command.h): Include. + + * java-exp.y (parse_number): Remove unused variable "unsigned_p". + * java-lang.c (gdbcore.h): Include for prototypes. + (type_from_class): Remove unused variable "ftype". + (type_from_class): Remove unused variable "name_length". + (evaluate_subexp_java): Add default case to handle remaining + enumerations. + * java-valprint.c (c-lang.h): Include for prototypes. + + * symfile.c (simple_read_overlay_region_table): #if away + unused function. + (simple_free_overlay_region_table): Ditto. + (overlay_is_mapped): Add default case to switch. + (simple_read_overlay_region_table): Ditto. + (simple_read_overlay_region_table): Add prototype. + + * symtab.c (fixup_symbol_section): Remove unused msym variable. + (fixup_psymbol_section): Ditto. + (find_pc_sect_symtab): Make distance a CORE_ADDR. + + * utils.c: Add comment about t_addr being either unsigned long or + unsigned long long. + (paddr): Change formats to match actual types args are cast to. + (preg): Ditto. + (paddr_nz): Ditto. + (preg_nz): Ditto. * defs.h (perror_with_name): Is a NORETURN function. * utils.c (perror_with_name): Is a NORETURN function. diff --git a/gdb/config/tm-sysv4.h b/gdb/config/tm-sysv4.h index 5f7da9512a..2c085410c0 100644 --- a/gdb/config/tm-sysv4.h +++ b/gdb/config/tm-sysv4.h @@ -27,6 +27,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ (e.g. on Irix5). */ #define IN_SOLIB_CALL_TRAMPOLINE(pc, name) in_plt_section((pc), (name)) +extern int in_plt_section PARAMS ((CORE_ADDR, char *)); /* If PC is in a shared library trampoline code, return the PC where the function itself actually starts. If not, return 0. */ diff --git a/gdb/i386v4-nat.c b/gdb/i386v4-nat.c index 98f736520c..3882ac7b6e 100644 --- a/gdb/i386v4-nat.c +++ b/gdb/i386v4-nat.c @@ -135,8 +135,6 @@ void supply_fpregset (fpregsetp) fpregset_t *fpregsetp; { - register int regi; - /* FIXME: see m68k-tdep.c for an example, for the m68k. */ } @@ -150,11 +148,6 @@ fill_fpregset (fpregsetp, regno) fpregset_t *fpregsetp; int regno; { - int regi; - char *to; - char *from; - extern char registers[]; - /* FIXME: see m68k-tdep.c for an example, for the m68k. */ } diff --git a/gdb/java-exp.y b/gdb/java-exp.y index 716dbe0577..0e9ac4776e 100644 --- a/gdb/java-exp.y +++ b/gdb/java-exp.y @@ -639,7 +639,6 @@ parse_number (p, len, parsed_float, putithere) register int c; register int base = input_radix; - int unsigned_p = 0; struct type *type; diff --git a/gdb/java-lang.c b/gdb/java-lang.c index a3bee65b4b..66cf392ae1 100644 --- a/gdb/java-lang.c +++ b/gdb/java-lang.c @@ -31,6 +31,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "value.h" #include "c-lang.h" #include "java-lang.h" +#include "gdbcore.h" struct type *java_int_type; struct type *java_byte_type; @@ -217,7 +218,6 @@ type_from_class (clas) value_ptr temp; struct objfile *objfile = get_dynamics_objfile(); value_ptr utf8_name, fields, field, method, methods; - int name_length; char *nptr; CORE_ADDR addr; struct block *bl; @@ -350,7 +350,6 @@ type_from_class (clas) { int accflags; int boffset; - struct type *ftype; if (fields == NULL) { temp = clas; @@ -597,6 +596,8 @@ evaluate_subexp_java (expect_type, exp, pos, noside) if (noside == EVAL_SKIP) goto nosideret; return java_value_string (&exp->elts[pc + 2].string, i); + default: + break; } standard: return evaluate_subexp_standard (expect_type, exp, pos, noside); diff --git a/gdb/java-valprint.c b/gdb/java-valprint.c index bc9f0ae4dc..511ac08bb6 100644 --- a/gdb/java-valprint.c +++ b/gdb/java-valprint.c @@ -26,6 +26,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "valprint.h" #include "language.h" #include "java-lang.h" +#include "c-lang.h" int java_value_print (val, stream, format, pretty) diff --git a/gdb/maint.c b/gdb/maint.c index 2bec6346f8..cf4ceb7e9a 100644 --- a/gdb/maint.c +++ b/gdb/maint.c @@ -313,8 +313,11 @@ maintenance_translate_address (arg, from_tty) while (isspace (*p)) p++; /* Skip whitespace */ ALL_OBJFILES (objfile) - if (sect = bfd_get_section_by_name (objfile->obfd, arg)) - break; + { + sect = bfd_get_section_by_name (objfile->obfd, arg); + if (sect != NULL) + break; + } if (!sect) error ("Unknown section %s.", arg); diff --git a/gdb/objfiles.c b/gdb/objfiles.c index 2a05eac98e..c4cb02e9a9 100644 --- a/gdb/objfiles.c +++ b/gdb/objfiles.c @@ -630,7 +630,7 @@ objfile_relocate (objfile, new_offsets) } } - if (objfile->ei.entry_point != ~0) + if (objfile->ei.entry_point != ~(CORE_ADDR)0) objfile->ei.entry_point += ANOFFSET (delta, SECT_OFF_TEXT); if (objfile->ei.entry_func_lowpc != INVALID_ENTRY_LOWPC) diff --git a/gdb/remote-sim.c b/gdb/remote-sim.c index 7c210092d7..ba9695f700 100644 --- a/gdb/remote-sim.c +++ b/gdb/remote-sim.c @@ -35,6 +35,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "callback.h" #include "remote-sim.h" #include "remote-utils.h" +#include "command.h" /* Prototypes */ @@ -691,6 +692,10 @@ gdbsim_wait (pid, status) should be fixed. */ status->value.sig = target_signal_from_host (sigrc); break; + case sim_running: + case sim_polling: + /* FIXME: Is this correct? */ + break; } return inferior_pid; diff --git a/gdb/symfile.c b/gdb/symfile.c index 79f33e2ca6..ecdeaf9b81 100644 --- a/gdb/symfile.c +++ b/gdb/symfile.c @@ -72,6 +72,11 @@ extern void report_transfer_performance PARAMS ((unsigned long, /* Functions this file defines */ +#if 0 +static int simple_read_overlay_region_table PARAMS ((void)); +static void simple_free_overlay_region_table PARAMS ((void)); +#endif + static void set_initial_language PARAMS ((void)); static void load_command PARAMS ((char *, int)); @@ -840,7 +845,7 @@ symfile_bfd_open (name) /* Look down path for it, allocate 2nd new malloc'd copy. */ desc = openp (getenv ("PATH"), 1, name, O_RDONLY | O_BINARY, 0, &absolute_name); -#if defined(__GO32__) || defined(__WIN32__) +#if defined(__GO32__) || defined(_WIN32) if (desc < 0) { char *exename = alloca (strlen (name) + 5); @@ -1001,27 +1006,27 @@ generic_load (filename, from_tty) { char *buffer; struct cleanup *old_chain; - bfd_vma vma; + bfd_vma lma; data_count += size; buffer = xmalloc (size); old_chain = make_cleanup (free, buffer); - vma = bfd_get_section_vma (loadfile_bfd, s); - vma += load_offset; + lma = s->lma; + lma += load_offset; /* Is this really necessary? I guess it gives the user something to look at during a long download. */ - printf_filtered ("Loading section %s, size 0x%lx vma ", + printf_filtered ("Loading section %s, size 0x%lx lma ", bfd_get_section_name (loadfile_bfd, s), (unsigned long) size); - print_address_numeric (vma, 1, gdb_stdout); + print_address_numeric (lma, 1, gdb_stdout); printf_filtered ("\n"); bfd_get_section_contents (loadfile_bfd, s, buffer, 0, size); - target_write_memory (vma, buffer, size); + target_write_memory (lma, buffer, size); do_cleanups (old_chain); } @@ -1374,6 +1379,8 @@ deduce_language_from_filename (filename) else if (STREQ (c, ".cc") || STREQ (c, ".C") || STREQ (c, ".cxx") || STREQ (c, ".cpp") || STREQ (c, ".cp") || STREQ (c, ".c++")) return language_cplus; + else if (STREQ (c, ".java")) + return language_java; else if (STREQ (c, ".ch") || STREQ (c, ".c186") || STREQ (c, ".c286")) return language_chill; else if (STREQ (c, ".f") || STREQ (c, ".F")) @@ -1462,7 +1469,7 @@ allocate_psymtab (filename, objfile) /* Reset all data structures in gdb which may contain references to symbol - table date. */ + table data. */ void clear_symtab_users () @@ -1795,7 +1802,730 @@ init_psymbol_list (objfile, total_symbols) xmmalloc (objfile -> md, objfile -> static_psymbols.size * sizeof (struct partial_symbol *)); } - + +/* OVERLAYS: + The following code implements an abstraction for debugging overlay sections. + + The target model is as follows: + 1) The gnu linker will permit multiple sections to be mapped into the + same VMA, each with its own unique LMA (or load address). + 2) It is assumed that some runtime mechanism exists for mapping the + sections, one by one, from the load address into the VMA address. + 3) This code provides a mechanism for gdb to keep track of which + sections should be considered to be mapped from the VMA to the LMA. + This information is used for symbol lookup, and memory read/write. + For instance, if a section has been mapped then its contents + should be read from the VMA, otherwise from the LMA. + + Two levels of debugger support for overlays are available. One is + "manual", in which the debugger relies on the user to tell it which + overlays are currently mapped. This level of support is + implemented entirely in the core debugger, and the information about + whether a section is mapped is kept in the objfile->obj_section table. + + The second level of support is "automatic", and is only available if + the target-specific code provides functionality to read the target's + overlay mapping table, and translate its contents for the debugger + (by updating the mapped state information in the obj_section tables). + + The interface is as follows: + User commands: + overlay map -- tell gdb to consider this section mapped + overlay unmap -- tell gdb to consider this section unmapped + overlay list -- list the sections that GDB thinks are mapped + overlay read-target -- get the target's state of what's mapped + overlay off/manual/auto -- set overlay debugging state + Functional interface: + find_pc_mapped_section(pc): if the pc is in the range of a mapped + section, return that section. + find_pc_overlay(pc): find any overlay section that contains + the pc, either in its VMA or its LMA + overlay_is_mapped(sect): true if overlay is marked as mapped + section_is_overlay(sect): true if section's VMA != LMA + pc_in_mapped_range(pc,sec): true if pc belongs to section's VMA + pc_in_unmapped_range(...): true if pc belongs to section's LMA + overlay_mapped_address(...): map an address from section's LMA to VMA + overlay_unmapped_address(...): map an address from section's VMA to LMA + symbol_overlayed_address(...): Return a "current" address for symbol: + either in VMA or LMA depending on whether + the symbol's section is currently mapped + */ + +/* Overlay debugging state: */ + +int overlay_debugging = 0; /* 0 == off, 1 == manual, -1 == auto */ +int overlay_cache_invalid = 0; /* True if need to refresh mapped state */ + +/* Target vector for refreshing overlay mapped state */ +static void simple_overlay_update PARAMS ((struct obj_section *)); +void (*target_overlay_update) PARAMS ((struct obj_section *)) + = simple_overlay_update; + +/* Function: section_is_overlay (SECTION) + Returns true if SECTION has VMA not equal to LMA, ie. + SECTION is loaded at an address different from where it will "run". */ + +int +section_is_overlay (section) + asection *section; +{ + if (overlay_debugging) + if (section && section->lma != 0 && + section->vma != section->lma) + return 1; + + return 0; +} + +/* Function: overlay_invalidate_all (void) + Invalidate the mapped state of all overlay sections (mark it as stale). */ + +static void +overlay_invalidate_all () +{ + struct objfile *objfile; + struct obj_section *sect; + + ALL_OBJSECTIONS (objfile, sect) + if (section_is_overlay (sect->the_bfd_section)) + sect->ovly_mapped = -1; +} + +/* Function: overlay_is_mapped (SECTION) + Returns true if section is an overlay, and is currently mapped. + Private: public access is thru function section_is_mapped. + + Access to the ovly_mapped flag is restricted to this function, so + that we can do automatic update. If the global flag + OVERLAY_CACHE_INVALID is set (by wait_for_inferior), then call + overlay_invalidate_all. If the mapped state of the particular + section is stale, then call TARGET_OVERLAY_UPDATE to refresh it. */ + +static int +overlay_is_mapped (osect) + struct obj_section *osect; +{ + if (osect == 0 || !section_is_overlay (osect->the_bfd_section)) + return 0; + + switch (overlay_debugging) + { + default: + case 0: return 0; /* overlay debugging off */ + case -1: /* overlay debugging automatic */ + /* Unles there is a target_overlay_update function, + there's really nothing useful to do here (can't really go auto) */ + if (target_overlay_update) + { + if (overlay_cache_invalid) + { + overlay_invalidate_all (); + overlay_cache_invalid = 0; + } + if (osect->ovly_mapped == -1) + (*target_overlay_update) (osect); + } + /* fall thru to manual case */ + case 1: /* overlay debugging manual */ + return osect->ovly_mapped == 1; + } +} + +/* Function: section_is_mapped + Returns true if section is an overlay, and is currently mapped. */ + +int +section_is_mapped (section) + asection *section; +{ + struct objfile *objfile; + struct obj_section *osect; + + if (overlay_debugging) + if (section && section_is_overlay (section)) + ALL_OBJSECTIONS (objfile, osect) + if (osect->the_bfd_section == section) + return overlay_is_mapped (osect); + + return 0; +} + +/* Function: pc_in_unmapped_range + If PC falls into the lma range of SECTION, return true, else false. */ + +CORE_ADDR +pc_in_unmapped_range (pc, section) + CORE_ADDR pc; + asection *section; +{ + int size; + + if (overlay_debugging) + if (section && section_is_overlay (section)) + { + size = bfd_get_section_size_before_reloc (section); + if (section->lma <= pc && pc < section->lma + size) + return 1; + } + return 0; +} + +/* Function: pc_in_mapped_range + If PC falls into the vma range of SECTION, return true, else false. */ + +CORE_ADDR +pc_in_mapped_range (pc, section) + CORE_ADDR pc; + asection *section; +{ + int size; + + if (overlay_debugging) + if (section && section_is_overlay (section)) + { + size = bfd_get_section_size_before_reloc (section); + if (section->vma <= pc && pc < section->vma + size) + return 1; + } + return 0; +} + +/* Function: overlay_unmapped_address (PC, SECTION) + Returns the address corresponding to PC in the unmapped (load) range. + May be the same as PC. */ + +CORE_ADDR +overlay_unmapped_address (pc, section) + CORE_ADDR pc; + asection *section; +{ + if (overlay_debugging) + if (section && section_is_overlay (section) && + pc_in_mapped_range (pc, section)) + return pc + section->lma - section->vma; + + return pc; +} + +/* Function: overlay_mapped_address (PC, SECTION) + Returns the address corresponding to PC in the mapped (runtime) range. + May be the same as PC. */ + +CORE_ADDR +overlay_mapped_address (pc, section) + CORE_ADDR pc; + asection *section; +{ + if (overlay_debugging) + if (section && section_is_overlay (section) && + pc_in_unmapped_range (pc, section)) + return pc + section->vma - section->lma; + + return pc; +} + + +/* Function: symbol_overlayed_address + Return one of two addresses (relative to the VMA or to the LMA), + depending on whether the section is mapped or not. */ + +CORE_ADDR +symbol_overlayed_address (address, section) + CORE_ADDR address; + asection *section; +{ + if (overlay_debugging) + { + /* If the symbol has no section, just return its regular address. */ + if (section == 0) + return address; + /* If the symbol's section is not an overlay, just return its address */ + if (!section_is_overlay (section)) + return address; + /* If the symbol's section is mapped, just return its address */ + if (section_is_mapped (section)) + return address; + /* + * HOWEVER: if the symbol is in an overlay section which is NOT mapped, + * then return its LOADED address rather than its vma address!! + */ + return overlay_unmapped_address (address, section); + } + return address; +} + +/* Function: find_pc_overlay (PC) + Return the best-match overlay section for PC: + If PC matches a mapped overlay section's VMA, return that section. + Else if PC matches an unmapped section's VMA, return that section. + Else if PC matches an unmapped section's LMA, return that section. */ + +asection * +find_pc_overlay (pc) + CORE_ADDR pc; +{ + struct objfile *objfile; + struct obj_section *osect, *best_match = NULL; + + if (overlay_debugging) + ALL_OBJSECTIONS (objfile, osect) + if (section_is_overlay (osect->the_bfd_section)) + { + if (pc_in_mapped_range (pc, osect->the_bfd_section)) + { + if (overlay_is_mapped (osect)) + return osect->the_bfd_section; + else + best_match = osect; + } + else if (pc_in_unmapped_range (pc, osect->the_bfd_section)) + best_match = osect; + } + return best_match ? best_match->the_bfd_section : NULL; +} + +/* Function: find_pc_mapped_section (PC) + If PC falls into the VMA address range of an overlay section that is + currently marked as MAPPED, return that section. Else return NULL. */ + +asection * +find_pc_mapped_section (pc) + CORE_ADDR pc; +{ + struct objfile *objfile; + struct obj_section *osect; + + if (overlay_debugging) + ALL_OBJSECTIONS (objfile, osect) + if (pc_in_mapped_range (pc, osect->the_bfd_section) && + overlay_is_mapped (osect)) + return osect->the_bfd_section; + + return NULL; +} + +/* Function: list_overlays_command + Print a list of mapped sections and their PC ranges */ + +void +list_overlays_command (args, from_tty) + char *args; + int from_tty; +{ + int nmapped = 0; + struct objfile *objfile; + struct obj_section *osect; + + if (overlay_debugging) + ALL_OBJSECTIONS (objfile, osect) + if (overlay_is_mapped (osect)) + { + const char *name; + bfd_vma lma, vma; + int size; + + vma = bfd_section_vma (objfile->obfd, osect->the_bfd_section); + lma = bfd_section_lma (objfile->obfd, osect->the_bfd_section); + size = bfd_get_section_size_before_reloc (osect->the_bfd_section); + name = bfd_section_name (objfile->obfd, osect->the_bfd_section); + printf_filtered ("Section %s, loaded at %08x - %08x, ", + name, lma, lma + size); + printf_filtered ("mapped at %08x - %08x\n", + vma, vma + size); + nmapped ++; + } + if (nmapped == 0) + printf_filtered ("No sections are mapped.\n"); +} + +/* Function: map_overlay_command + Mark the named section as mapped (ie. residing at its VMA address). */ + +void +map_overlay_command (args, from_tty) + char *args; + int from_tty; +{ + struct objfile *objfile, *objfile2; + struct obj_section *sec, *sec2; + asection *bfdsec; + + if (!overlay_debugging) + error ("Overlay debugging not enabled. Use the 'OVERLAY ON' command."); + + if (args == 0 || *args == 0) + error ("Argument required: name of an overlay section"); + + /* First, find a section matching the user supplied argument */ + ALL_OBJSECTIONS (objfile, sec) + if (!strcmp (bfd_section_name (objfile->obfd, sec->the_bfd_section), args)) + { + /* Now, check to see if the section is an overlay. */ + bfdsec = sec->the_bfd_section; + if (!section_is_overlay (bfdsec)) + continue; /* not an overlay section */ + + /* Mark the overlay as "mapped" */ + sec->ovly_mapped = 1; + + /* Next, make a pass and unmap any sections that are + overlapped by this new section: */ + ALL_OBJSECTIONS (objfile2, sec2) + if (sec2->ovly_mapped && + sec != sec2 && + sec->the_bfd_section != sec2->the_bfd_section && + (pc_in_mapped_range (sec2->addr, sec->the_bfd_section) || + pc_in_mapped_range (sec2->endaddr, sec->the_bfd_section))) + { + if (info_verbose) + printf_filtered ("Note: section %s unmapped by overlap\n", + bfd_section_name (objfile->obfd, + sec2->the_bfd_section)); + sec2->ovly_mapped = 0; /* sec2 overlaps sec: unmap sec2 */ + } + return; + } + error ("No overlay section called %s", args); +} + +/* Function: unmap_overlay_command + Mark the overlay section as unmapped + (ie. resident in its LMA address range, rather than the VMA range). */ + +void +unmap_overlay_command (args, from_tty) + char *args; + int from_tty; +{ + struct objfile *objfile; + struct obj_section *sec; + + if (!overlay_debugging) + error ("Overlay debugging not enabled. Use the 'OVERLAY ON' command."); + + if (args == 0 || *args == 0) + error ("Argument required: name of an overlay section"); + + /* First, find a section matching the user supplied argument */ + ALL_OBJSECTIONS (objfile, sec) + if (!strcmp (bfd_section_name (objfile->obfd, sec->the_bfd_section), args)) + { + if (!sec->ovly_mapped) + error ("Section %s is not mapped", args); + sec->ovly_mapped = 0; + return; + } + error ("No overlay section called %s", args); +} + +/* Function: overlay_auto_command + A utility command to turn on overlay debugging. + Possibly this should be done via a set/show command. */ + +static void +overlay_auto_command (args, from_tty) +{ + overlay_debugging = -1; + if (info_verbose) + printf_filtered ("Automatic overlay debugging enabled."); +} + +/* Function: overlay_manual_command + A utility command to turn on overlay debugging. + Possibly this should be done via a set/show command. */ + +static void +overlay_manual_command (args, from_tty) +{ + overlay_debugging = 1; + if (info_verbose) + printf_filtered ("Overlay debugging enabled."); +} + +/* Function: overlay_off_command + A utility command to turn on overlay debugging. + Possibly this should be done via a set/show command. */ + +static void +overlay_off_command (args, from_tty) +{ + overlay_debugging = 0; + if (info_verbose) + printf_filtered ("Overlay debugging disabled."); +} + +static void +overlay_load_command (args, from_tty) +{ + if (target_overlay_update) + (*target_overlay_update) (NULL); + else + error ("This target does not know how to read its overlay state."); +} + +/* Function: overlay_command + A place-holder for a mis-typed command */ + +/* Command list chain containing all defined "overlay" subcommands. */ +struct cmd_list_element *overlaylist; + +static void +overlay_command (args, from_tty) + char *args; + int from_tty; +{ + printf_unfiltered + ("\"overlay\" must be followed by the name of an overlay command.\n"); + help_list (overlaylist, "overlay ", -1, gdb_stdout); +} + + +/* Target Overlays for the "Simplest" overlay manager: + + This is GDB's default target overlay layer. It works with the + minimal overlay manager supplied as an example by Cygnus. The + entry point is via a function pointer "target_overlay_update", + so targets that use a different runtime overlay manager can + substitute their own overlay_update function and take over the + function pointer. + + The overlay_update function pokes around in the target's data structures + to see what overlays are mapped, and updates GDB's overlay mapping with + this information. + + In this simple implementation, the target data structures are as follows: + unsigned _novlys; /# number of overlay sections #/ + unsigned _ovly_table[_novlys][4] = { + {VMA, SIZE, LMA, MAPPED}, /# one entry per overlay section #/ + {..., ..., ..., ...}, + } + unsigned _novly_regions; /# number of overlay regions #/ + unsigned _ovly_region_table[_novly_regions][3] = { + {VMA, SIZE, MAPPED_TO_LMA}, /# one entry per overlay region #/ + {..., ..., ...}, + } + These functions will attempt to update GDB's mappedness state in the + symbol section table, based on the target's mappedness state. + + To do this, we keep a cached copy of the target's _ovly_table, and + attempt to detect when the cached copy is invalidated. The main + entry point is "simple_overlay_update(SECT), which looks up SECT in + the cached table and re-reads only the entry for that section from + the target (whenever possible). + */ + +/* Cached, dynamically allocated copies of the target data structures: */ +static unsigned (*cache_ovly_table)[4] = 0; +#if 0 +static unsigned (*cache_ovly_region_table)[3] = 0; +#endif +static unsigned cache_novlys = 0; +#if 0 +static unsigned cache_novly_regions = 0; +#endif +static CORE_ADDR cache_ovly_table_base = 0; +#if 0 +static CORE_ADDR cache_ovly_region_table_base = 0; +#endif +enum ovly_index { VMA, SIZE, LMA, MAPPED}; +#define TARGET_INT_BYTES (TARGET_INT_BIT / TARGET_CHAR_BIT) + +/* Throw away the cached copy of _ovly_table */ +static void +simple_free_overlay_table () +{ + if (cache_ovly_table) + free(cache_ovly_table); + cache_novlys = 0; + cache_ovly_table = NULL; + cache_ovly_table_base = 0; +} + +#if 0 +/* Throw away the cached copy of _ovly_region_table */ +static void +simple_free_overlay_region_table () +{ + if (cache_ovly_region_table) + free(cache_ovly_region_table); + cache_novly_regions = 0; + cache_ovly_region_table = NULL; + cache_ovly_region_table_base = 0; +} +#endif + +/* Read an array of ints from the target into a local buffer. + Convert to host order. int LEN is number of ints */ +static void +read_target_int_array (memaddr, myaddr, len) + CORE_ADDR memaddr; + unsigned int *myaddr; + int len; +{ + char *buf = alloca (len * TARGET_INT_BYTES); + int i; + + read_memory (memaddr, buf, len * TARGET_INT_BYTES); + for (i = 0; i < len; i++) + myaddr[i] = extract_unsigned_integer (TARGET_INT_BYTES * i + buf, + TARGET_INT_BYTES); +} + +/* Find and grab a copy of the target _ovly_table + (and _novlys, which is needed for the table's size) */ +static int +simple_read_overlay_table () +{ + struct minimal_symbol *msym; + + simple_free_overlay_table (); + msym = lookup_minimal_symbol ("_novlys", 0, 0); + if (msym != NULL) + cache_novlys = read_memory_integer (SYMBOL_VALUE_ADDRESS (msym), 4); + else + return 0; /* failure */ + cache_ovly_table = (void *) xmalloc (cache_novlys * sizeof(*cache_ovly_table)); + if (cache_ovly_table != NULL) + { + msym = lookup_minimal_symbol ("_ovly_table", 0, 0); + if (msym != NULL) + { + cache_ovly_table_base = SYMBOL_VALUE_ADDRESS (msym); + read_target_int_array (cache_ovly_table_base, + (int *) cache_ovly_table, + cache_novlys * 4); + } + else + return 0; /* failure */ + } + else + return 0; /* failure */ + return 1; /* SUCCESS */ +} + +#if 0 +/* Find and grab a copy of the target _ovly_region_table + (and _novly_regions, which is needed for the table's size) */ +static int +simple_read_overlay_region_table () +{ + struct minimal_symbol *msym; + + simple_free_overlay_region_table (); + msym = lookup_minimal_symbol ("_novly_regions", 0, 0); + if (msym != NULL) + cache_novly_regions = read_memory_integer (SYMBOL_VALUE_ADDRESS (msym), 4); + else + return 0; /* failure */ + cache_ovly_region_table = (void *) xmalloc (cache_novly_regions * 12); + if (cache_ovly_region_table != NULL) + { + msym = lookup_minimal_symbol ("_ovly_region_table", 0, 0); + if (msym != NULL) + { + cache_ovly_region_table_base = SYMBOL_VALUE_ADDRESS (msym); + read_target_int_array (cache_ovly_region_table_base, + (int *) cache_ovly_region_table, + cache_novly_regions * 3); + } + else + return 0; /* failure */ + } + else + return 0; /* failure */ + return 1; /* SUCCESS */ +} +#endif + +/* Function: simple_overlay_update_1 + A helper function for simple_overlay_update. Assuming a cached copy + of _ovly_table exists, look through it to find an entry whose vma, + lma and size match those of OSECT. Re-read the entry and make sure + it still matches OSECT (else the table may no longer be valid). + Set OSECT's mapped state to match the entry. Return: 1 for + success, 0 for failure. */ + +static int +simple_overlay_update_1 (osect) + struct obj_section *osect; +{ + int i, size; + + size = bfd_get_section_size_before_reloc (osect->the_bfd_section); + for (i = 0; i < cache_novlys; i++) + if (cache_ovly_table[i][VMA] == osect->the_bfd_section->vma && + cache_ovly_table[i][LMA] == osect->the_bfd_section->lma && + cache_ovly_table[i][SIZE] == size) + { + read_target_int_array (cache_ovly_table_base + i * TARGET_INT_BYTES, + (int *) &cache_ovly_table[i], 4); + if (cache_ovly_table[i][VMA] == osect->the_bfd_section->vma && + cache_ovly_table[i][LMA] == osect->the_bfd_section->lma && + cache_ovly_table[i][SIZE] == size) + { + osect->ovly_mapped = cache_ovly_table[i][MAPPED]; + return 1; + } + else /* Warning! Warning! Target's ovly table has changed! */ + return 0; + } + return 0; +} + +/* Function: simple_overlay_update + If OSECT is NULL, then update all sections' mapped state + (after re-reading the entire target _ovly_table). + If OSECT is non-NULL, then try to find a matching entry in the + cached ovly_table and update only OSECT's mapped state. + If a cached entry can't be found or the cache isn't valid, then + re-read the entire cache, and go ahead and update all sections. */ + +static void +simple_overlay_update (osect) + struct obj_section *osect; +{ + struct objfile *objfile; + + /* Were we given an osect to look up? NULL means do all of them. */ + if (osect) + /* Have we got a cached copy of the target's overlay table? */ + if (cache_ovly_table != NULL) + /* Does its cached location match what's currently in the symtab? */ + if (cache_ovly_table_base == + SYMBOL_VALUE_ADDRESS (lookup_minimal_symbol ("_ovly_table", 0, 0))) + /* Then go ahead and try to look up this single section in the cache */ + if (simple_overlay_update_1 (osect)) + /* Found it! We're done. */ + return; + + /* Cached table no good: need to read the entire table anew. + Or else we want all the sections, in which case it's actually + more efficient to read the whole table in one block anyway. */ + + if (simple_read_overlay_table () == 0) /* read failed? No table? */ + { + warning ("Failed to read the target overlay mapping table."); + return; + } + /* Now may as well update all sections, even if only one was requested. */ + ALL_OBJSECTIONS (objfile, osect) + if (section_is_overlay (osect->the_bfd_section)) + { + int i, size; + + size = bfd_get_section_size_before_reloc (osect->the_bfd_section); + for (i = 0; i < cache_novlys; i++) + if (cache_ovly_table[i][VMA] == osect->the_bfd_section->vma && + cache_ovly_table[i][LMA] == osect->the_bfd_section->lma && + cache_ovly_table[i][SIZE] == size) + { /* obj_section matches i'th entry in ovly_table */ + osect->ovly_mapped = cache_ovly_table[i][MAPPED]; + break; /* finished with inner for loop: break out */ + } + } +} + + void _initialize_symfile () { @@ -1833,4 +2563,28 @@ for access from GDB.", &cmdlist); &setlist), &showlist); + add_prefix_cmd ("overlay", class_support, overlay_command, + "Commands for debugging overlays.", &overlaylist, + "overlay ", 0, &cmdlist); + + add_com_alias ("ovly", "overlay", class_alias, 1); + add_com_alias ("ov", "overlay", class_alias, 1); + + add_cmd ("map-overlay", class_support, map_overlay_command, + "Assert that an overlay section is mapped.", &overlaylist); + + add_cmd ("unmap-overlay", class_support, unmap_overlay_command, + "Assert that an overlay section is unmapped.", &overlaylist); + + add_cmd ("list-overlays", class_support, list_overlays_command, + "List mappings of overlay sections.", &overlaylist); + + add_cmd ("manual", class_support, overlay_manual_command, + "Enable overlay debugging.", &overlaylist); + add_cmd ("off", class_support, overlay_off_command, + "Disable overlay debugging.", &overlaylist); + add_cmd ("auto", class_support, overlay_auto_command, + "Enable automatic overlay debugging.", &overlaylist); + add_cmd ("load-target", class_support, overlay_load_command, + "Read the overlay mapping state from the target.", &overlaylist); } diff --git a/gdb/symtab.c b/gdb/symtab.c index 43668272ed..7edd1a6d56 100644 --- a/gdb/symtab.c +++ b/gdb/symtab.c @@ -520,8 +520,6 @@ fixup_symbol_section (sym, objfile) struct symbol *sym; struct objfile *objfile; { - struct minimal_symbol *msym; - if (!sym) return NULL; @@ -538,8 +536,6 @@ fixup_psymbol_section (psym, objfile) struct partial_symbol *psym; struct objfile *objfile; { - struct minimal_symbol *msym; - if (!psym) return NULL; @@ -1066,7 +1062,7 @@ find_pc_sect_symtab (pc, section) register struct symtab *best_s = NULL; register struct partial_symtab *ps; register struct objfile *objfile; - int distance = 0; + CORE_ADDR distance = 0; /* Search all symtabs for the one whose file contains our address, and which is the smallest of all the ones containing the address. This is designed diff --git a/gdb/utils.c b/gdb/utils.c index 859f65b629..e4de853151 100644 --- a/gdb/utils.c +++ b/gdb/utils.c @@ -2469,7 +2469,21 @@ get_cell() return buf[cell]; } -/* print routines to handle variable size regs, etc */ +/* print routines to handle variable size regs, etc. + + FIXME: Note that t_addr is a bfd_vma, which is currently either an + unsigned long or unsigned long long, determined at configure time. + If t_addr is an unsigned long long and sizeof (unsigned long long) + is greater than sizeof (unsigned long), then I believe this code will + probably lose, at least for little endian machines. I believe that + it would also be better to eliminate the switch on the absolute size + of t_addr and replace it with a sequence of if statements that compare + sizeof t_addr with sizeof the various types and do the right thing, + which includes knowing whether or not the host supports long long. + -fnf + + */ + static int thirty_two = 32; /* eliminate warning from compiler on 32-bit systems */ char* @@ -2480,17 +2494,17 @@ paddr(addr) switch (sizeof(t_addr)) { case 8: - sprintf(paddr_str,"%08x%08x", - (unsigned long)(addr>>thirty_two),(unsigned long)(addr&0xffffffff)); + sprintf (paddr_str, "%08lx%08lx", + (unsigned long) (addr >> thirty_two), (unsigned long) (addr & 0xffffffff)); break; case 4: - sprintf(paddr_str,"%08x",(unsigned long)addr); + sprintf (paddr_str, "%08lx", (unsigned long) addr); break; case 2: - sprintf(paddr_str,"%04x",(unsigned short)(addr&0xffff)); + sprintf (paddr_str, "%04x", (unsigned short) (addr & 0xffff)); break; default: - sprintf(paddr_str,"%x",addr); + sprintf (paddr_str, "%lx", (unsigned long) addr); } return paddr_str; } @@ -2503,17 +2517,17 @@ preg(reg) switch (sizeof(t_reg)) { case 8: - sprintf(preg_str,"%08x%08x", - (unsigned long)(reg>>thirty_two),(unsigned long)(reg&0xffffffff)); + sprintf (preg_str, "%08lx%08lx", + (unsigned long) (reg >> thirty_two), (unsigned long) (reg & 0xffffffff)); break; case 4: - sprintf(preg_str,"%08x",(unsigned long)reg); + sprintf (preg_str, "%08lx", (unsigned long) reg); break; case 2: - sprintf(preg_str,"%04x",(unsigned short)(reg&0xffff)); + sprintf (preg_str, "%04x", (unsigned short) (reg & 0xffff)); break; default: - sprintf(preg_str,"%x",reg); + sprintf (preg_str, "%lx", (unsigned long) reg); } return preg_str; } @@ -2527,22 +2541,22 @@ paddr_nz(addr) { case 8: { - unsigned long high = (unsigned long)(addr>>thirty_two); + unsigned long high = (unsigned long) (addr >> thirty_two); if (high == 0) - sprintf(paddr_str,"%x", (unsigned long)(addr&0xffffffff)); + sprintf (paddr_str, "%lx", (unsigned long) (addr & 0xffffffff)); else - sprintf(paddr_str,"%x%08x", - high, (unsigned long)(addr&0xffffffff)); + sprintf (paddr_str, "%lx%08lx", + high, (unsigned long) (addr & 0xffffffff)); break; } case 4: - sprintf(paddr_str,"%x",(unsigned long)addr); + sprintf (paddr_str, "%lx", (unsigned long) addr); break; case 2: - sprintf(paddr_str,"%x",(unsigned short)(addr&0xffff)); + sprintf (paddr_str, "%x", (unsigned short) (addr & 0xffff)); break; default: - sprintf(paddr_str,"%x",addr); + sprintf (paddr_str,"%lx", (unsigned long) addr); } return paddr_str; } @@ -2556,22 +2570,22 @@ preg_nz(reg) { case 8: { - unsigned long high = (unsigned long)(reg>>thirty_two); + unsigned long high = (unsigned long) (reg >> thirty_two); if (high == 0) - sprintf(preg_str,"%x", (unsigned long)(reg&0xffffffff)); + sprintf (preg_str, "%lx", (unsigned long) (reg & 0xffffffff)); else - sprintf(preg_str,"%x%08x", - high, (unsigned long)(reg&0xffffffff)); + sprintf (preg_str, "%lx%08lx", + high, (unsigned long) (reg & 0xffffffff)); break; } case 4: - sprintf(preg_str,"%x",(unsigned long)reg); + sprintf (preg_str, "%lx", (unsigned long) reg); break; case 2: - sprintf(preg_str,"%x",(unsigned short)(reg&0xffff)); + sprintf (preg_str, "%x", (unsigned short) (reg & 0xffff)); break; default: - sprintf(preg_str,"%x",reg); + sprintf (preg_str, "%lx", (unsigned long) reg); } return preg_str; }