* blockframe.c (find_pc_partial_function): Fix handling for PCs
authorStu Grossman <grossman@cygnus>
Thu, 7 Oct 1993 16:42:08 +0000 (16:42 +0000)
committerStu Grossman <grossman@cygnus>
Thu, 7 Oct 1993 16:42:08 +0000 (16:42 +0000)
beyond the end of the last function in an objfile.
* coff-solib.c (coff_solib_add):  Use BFD to get fields from .lib
section.
* infrun.c (wait_for_inferior):  Modify test for subroutine entry
to include pc out of bounds of the previous function.
* remote.c (remote_wait):  Use strtoul for parsing 'N' message.
Add code to relocate symfile_objfile->sections.

gdb/ChangeLog
gdb/blockframe.c
gdb/coff-solib.c
gdb/infrun.c
gdb/remote.c

index 34a359395b8909fdc7d0e3a940c3631561a1b39e..b141b9568e16435d75544dcde9883717ee5c3423 100644 (file)
@@ -1,3 +1,14 @@
+Thu Oct  7 09:22:04 1993  Stu Grossman  (grossman at cygnus.com)
+
+       * blockframe.c (find_pc_partial_function):  Fix handling for PCs
+       beyond the end of the last function in an objfile.
+       * coff-solib.c (coff_solib_add):  Use BFD to get fields from .lib
+       section.
+       * infrun.c (wait_for_inferior):  Modify test for subroutine entry
+       to include pc out of bounds of the previous function.
+       * remote.c (remote_wait):  Use strtoul for parsing 'N' message.
+       Add code to relocate symfile_objfile->sections.
+
 Thu Oct  7 06:22:43 1993  Jim Kingdon  (kingdon@lioth.cygnus.com)
 
        * config/sparc/sun4os4.mh: Add comment saying why we don't use
index 7acbf6a41f22f895b00b955101a090714973a405..0d0e89a8d5f03f9ecb542de2e0077325fec47bdd 100644 (file)
@@ -624,6 +624,7 @@ find_pc_partial_function (pc, name, address, endaddr)
   struct symbol *f;
   struct minimal_symbol *msymbol;
   struct partial_symbol *psb;
+  struct obj_section *sec;
 
   if (pc >= cache_pc_function_low && pc < cache_pc_function_high)
     goto return_cached_value;
@@ -688,6 +689,16 @@ find_pc_partial_function (pc, name, address, endaddr)
        }
     }
 
+  /* Not in the normal symbol tables, see if the pc is in a known section.
+     If it's not, then give up.  This ensures that anything beyond the end
+     of the text seg doesn't appear to be part of the last function in the
+     text segment.  */
+
+  sec = find_pc_section (pc);
+
+  if (!sec)
+    msymbol = NULL;
+
   /* Must be in the minimal symbol table.  */
   if (msymbol == NULL)
     {
@@ -701,40 +712,26 @@ find_pc_partial_function (pc, name, address, endaddr)
       return 0;
     }
 
-  /* I believe the purpose of this check is to make sure that anything
-     beyond the end of the text segment does not appear as part of the
-     last function of the text segment.  It assumes that there is something
-     other than a mst_text symbol after the text segment.  It is broken in
-     various cases, so anything relying on this behavior (there might be
-     some places) should be using find_pc_section or some such instead.  */
+  /* See if we're in a transfer table for Sun shared libs.  */
+
   if (msymbol -> type == mst_text)
     cache_pc_function_low = SYMBOL_VALUE_ADDRESS (msymbol);
   else
     /* It is a transfer table for Sun shared libraries.  */
     cache_pc_function_low = pc - FUNCTION_START_OFFSET;
+
   cache_pc_function_name = SYMBOL_NAME (msymbol);
 
-  if (SYMBOL_NAME (msymbol + 1) != NULL)
-    /* This might be part of a different segment, which might be a bad
-       idea.  Perhaps we should be using the smaller of this address or the
-       endaddr from find_pc_section.  */
+  /* Use the lesser of the next minimal symbol, or the end of the section, as
+     the end of the function.  */
+
+  if (SYMBOL_NAME (msymbol + 1) != NULL
+      && SYMBOL_VALUE_ADDRESS (msymbol + 1) < sec->endaddr)
     cache_pc_function_high = SYMBOL_VALUE_ADDRESS (msymbol + 1);
   else
-    {
-      /* We got the start address from the last msymbol in the objfile.
-        So the end address is the end of the section.  */
-      struct obj_section *sec;
-
-      sec = find_pc_section (pc);
-      if (sec == NULL)
-       {
-         /* Don't know if this can happen but if it does, then just say
-            that the function is 1 byte long.  */
-         cache_pc_function_high = cache_pc_function_low + 1;
-       }
-      else
-       cache_pc_function_high = sec->endaddr;
-    }
+    /* We got the start address from the last msymbol in the objfile.
+       So the end address is the end of the section.  */
+    cache_pc_function_high = sec->endaddr;
 
  return_cached_value:
   if (address)
index d6ea6455ac478aada51dd29401ba48ec3e88672e..a4bf6c4ebf770110b160e9cd5e65b80edb85a04a 100644 (file)
@@ -61,8 +61,8 @@ coff_solib_add (arg_string, from_tty, target)
       unsigned char *lib;
       struct libent
        {
-         long len;
-         long unk;
+         bfd_byte len[4];
+         bfd_byte unk[4];
          char filename[1];
        };
 
@@ -76,10 +76,13 @@ coff_solib_add (arg_string, from_tty, target)
        {
          struct libent *ent;
          struct objfile *objfile;
+         int len;
 
          ent = (struct libent *)lib;
 
-         if (ent->len <= 0)
+         len = bfd_get_32 (exec_bfd, ent->len);
+
+         if (len <= 0)
            break;
 
          objfile = symbol_file_add (ent->filename, from_tty,
@@ -87,8 +90,8 @@ coff_solib_add (arg_string, from_tty, target)
                                     0, /* not mainline */
                                     0, /* not mapped */
                                     0); /* Not readnow */
-         libsize -= ent->len * 4;
-         lib += ent->len * 4;
+         libsize -= len * 4;
+         lib += len * 4;
        }
     }
 }
index 37447334eb0d5c34857e02a02019c107191de5fc..d539ddd5750b36dc758cfa49ce6273f7bcbb8b0c 100644 (file)
@@ -475,6 +475,7 @@ wait_for_inferior ()
   int random_signal;
   CORE_ADDR stop_sp = 0;
   CORE_ADDR stop_func_start;
+  CORE_ADDR stop_func_end;
   char *stop_func_name;
   CORE_ADDR prologue_pc = 0, tmp;
   struct symtab_and_line sal;
@@ -649,11 +650,12 @@ wait_for_inferior ()
       stop_frame_address = FRAME_FP (get_current_frame ());
       stop_sp = read_sp ();
       stop_func_start = 0;
+      stop_func_end = 0;
       stop_func_name = 0;
       /* Don't care about return value; stop_func_start and stop_func_name
         will both be 0 if it doesn't work.  */
       find_pc_partial_function (stop_pc, &stop_func_name, &stop_func_start,
-                               (CORE_ADDR *)NULL);
+                               &stop_func_end);
       stop_func_start += FUNCTION_START_OFFSET;
       another_trap = 0;
       bpstat_clear (&stop_bpstat);
@@ -1015,7 +1017,9 @@ wait_for_inferior ()
 
       /* ==> See comments at top of file on this algorithm.  <==*/
 
-      if ((stop_pc == stop_func_start
+      if ((stop_pc < stop_func_start
+          || stop_pc >= stop_func_end
+          || stop_pc == stop_func_start
           || IN_SOLIB_TRAMPOLINE (stop_pc, stop_func_name))
          && (stop_func_start != prev_func_start
              || prologue_pc != stop_func_start
index d3fef8ba12b440c4b283dec1875f3cb25909dd78..9900b3b1ad71af96cf7a4ecb9b2a711a7de6537b 100644 (file)
@@ -209,6 +209,9 @@ remote_interrupt PARAMS ((int signo));
 static void
 remote_interrupt_twice PARAMS ((int signo));
 
+static void
+interrupt_query PARAMS ((void));
+
 extern struct target_ops remote_ops;   /* Forward decl */
 
 /* This was 5 seconds, which is a long time to sit and wait.
@@ -424,18 +427,26 @@ remote_interrupt_twice (signo)
 {
   signal (signo, ofunc);
   
+  interrupt_query ();
+
+  signal (signo, remote_interrupt);
+}
+
+/* Ask the user what to do when an interrupt is received.  */
+
+static void
+interrupt_query ()
+{
   target_terminal_ours ();
+
   if (query ("Interrupted while waiting for the program.\n\
 Give up (and stop debugging it)? "))
     {
       target_mourn_inferior ();
       return_to_top_level (RETURN_QUIT);
     }
-  else
-    {
-      signal (signo, remote_interrupt);
-      target_terminal_inferior ();
-    }
+
+  target_terminal_inferior ();
 }
 
 /* Wait until the remote machine stops, then return,
@@ -521,19 +532,25 @@ remote_wait (status)
             new data address, and BB is the new bss address.  This is
             used by the NLM stub; gdb may see more sections.  */
          p = &buf[3];
-         text_addr = strtol (p, &p1, 16);
+         text_addr = strtoul (p, &p1, 16);
          if (p1 == p || *p1 != ';')
            warning ("Malformed relocation packet: Packet '%s'", buf);
          p = p1 + 1;
-         data_addr = strtol (p, &p1, 16);
+         data_addr = strtoul (p, &p1, 16);
          if (p1 == p || *p1 != ';')
            warning ("Malformed relocation packet: Packet '%s'", buf);
          p = p1 + 1;
-         bss_addr = strtol (p, &p1, 16);
+         bss_addr = strtoul (p, &p1, 16);
          if (p1 == p)
            warning ("Malformed relocation packet: Packet '%s'", buf);
 
-         if (symfile_objfile != NULL)
+         if (symfile_objfile != NULL
+             && (ANOFFSET (symfile_objfile->section_offsets,
+                           SECT_OFF_TEXT) != text_addr
+                 || ANOFFSET (symfile_objfile->section_offsets,
+                              SECT_OFF_DATA) != data_addr
+                 || ANOFFSET (symfile_objfile->section_offsets,
+                              SECT_OFF_BSS) != bss_addr))
            {
              struct section_offsets *offs;
 
@@ -562,6 +579,36 @@ remote_wait (status)
              ANOFFSET (offs, SECT_OFF_BSS) = bss_addr;
 
              objfile_relocate (symfile_objfile, offs);
+             {
+               struct obj_section *s;
+               bfd *bfd;
+
+               bfd = symfile_objfile->obfd;
+
+               for (s = symfile_objfile->sections;
+                    s < symfile_objfile->sections_end; ++s)
+                 {
+                   flagword flags;
+
+                   flags = bfd_get_section_flags (bfd, s->sec_ptr);
+
+                   if (flags & SEC_CODE)
+                     {
+                       s->addr += text_addr;
+                       s->endaddr += text_addr;
+                     }
+                   else if (flags & (SEC_DATA | SEC_LOAD))
+                     {
+                       s->addr += data_addr;
+                       s->endaddr += data_addr;
+                     }
+                   else if (flags & SEC_ALLOC)
+                     {
+                       s->addr += bss_addr;
+                       s->endaddr += bss_addr;
+                     }
+                 }
+             }
            }
          break;
        }
@@ -603,6 +650,17 @@ remote_fetch_registers (regno)
   /* Unimplemented registers read as all bits zero.  */
   memset (regs, 0, REGISTER_BYTES);
 
+  /* We can get out of synch in various cases.  If the first character
+     in the buffer is not a hex character, assume that has happened
+     and try to fetch another packet to read.  */
+  while ((buf[0] < '0' || buf[0] > '9')
+        && (buf[0] < 'a' || buf[0] > 'f'))
+    {
+      if (sr_get_debug () > 0)
+       printf ("Bad register packet; fetching a new packet\n");
+      getpkt (buf, 0);
+    }
+
   /* Reply describes registers byte by byte, each byte encoded as two
      hex characters.  Suck them all up, then supply them to the
      register cacheing/storage mechanism.  */
@@ -972,6 +1030,12 @@ putpkt (buf)
            }
          break;                /* Here to retransmit */
        }
+
+      if (quit_flag)
+       {
+         quit_flag = 0;
+         interrupt_query ();
+       }
     }
 }
 
@@ -994,6 +1058,12 @@ getpkt (buf, forever)
 
   while (1)
     {
+      if (quit_flag)
+       {
+         quit_flag = 0;
+         interrupt_query ();
+       }
+
       /* This can loop forever if the remote side sends us characters
         continuously, but if it pauses, we'll get a zero from readchar
         because of timeout.  Then we'll count that as a retry.  */