Mon Mar 21 11:02:51 1994 Stu Grossman (grossman at cygnus.com)
authorStu Grossman <grossman@cygnus>
Mon, 21 Mar 1994 19:57:38 +0000 (19:57 +0000)
committerStu Grossman <grossman@cygnus>
Mon, 21 Mar 1994 19:57:38 +0000 (19:57 +0000)
* alpha-tdep.c:  Gobs of changes (many imported from mips-tdep) to
improve remote debugging efficiency.  Also fixed problems with
doing function calls for programs with no entry points.
* infcmd.c (run_stack_dummy):  Use CALL_DUMMY_ADDRESS instead of
entry_point_address.
* inferior.h (PC_IN_CALL_DUMMY):  ditto.
* mdebugread.c (parse_symbol, parse_procedure, parse_external,
parse_lines):  Pass section_offsets info to these routines so that
we can relocate symbol table entries upon readin.
* (psymtab_to_symtab_1):  Set symtab->primary to tell
objfile_relocate to do relocations for our symbols.
* (ecoff_relocate_efi):  New routine to relocate adr field of PDRs
(which hang off of the symbol table).
* Use prim_record_minimal_symbols_and_info instead of
prim_record_minimal_symbols to supply section info to make minimal
symbol relocations work.
* minsyms.c (prim_record_minimal_symbols_and_info):  If section is
-1, try to deduce it from ms_type.
* objfiles.c (objfile_relocate):  Use ALL_OBJFILE_SYMTABS where
appropriate.  Handle relocation of MIPS_EFI symbols special. Also,
add code to relocate objfile->sections data structure.
* remote.c (get_offsets):  Use new protocol message to acquire
section offsets from the target.
* (remote_wait):  Get rid of relocation stuff.  That's all handled
by objfile_relocate now.
* config/alpha/alpha-nw.mt (TM_FILE):  Use tm-alphanw.h.
* config/alpha/tm-alpha.h:  Define CALL_DUMMY_ADDRESS, and
VM_MIN_ADDRESS.
* config/alpha/tm-alphanw.h:  DECR_PC_AFTER_BREAK=0, VM_MIN_ADDRESS=0.

gdb/ChangeLog
gdb/alpha-tdep.c
gdb/mdebugread.c
gdb/minsyms.c
gdb/objfiles.c
gdb/remote.c

index b87030d157d524a68e4fb6560f5cea9ec9198b90..2e116cb0188f419f431b8cde12e76826069b10b1 100644 (file)
@@ -3,6 +3,38 @@ Mon Mar 21 11:50:28 1994  Jeffrey A. Law  (law@snake.cs.utah.edu)
        * hppa-tdep.c (hppa_fix_call_dummy): Use value_ptr.
        (hppa_push_arguments): Likewise.
 
+Mon Mar 21 11:02:51 1994  Stu Grossman  (grossman at cygnus.com)
+
+       * alpha-tdep.c:  Gobs of changes (many imported from mips-tdep) to
+       improve remote debugging efficiency.  Also fixed problems with
+       doing function calls for programs with no entry points.
+       * infcmd.c (run_stack_dummy):  Use CALL_DUMMY_ADDRESS instead of
+       entry_point_address.
+       * inferior.h (PC_IN_CALL_DUMMY):  ditto.
+       * mdebugread.c (parse_symbol, parse_procedure, parse_external,
+       parse_lines):  Pass section_offsets info to these routines so that
+       we can relocate symbol table entries upon readin.
+       * (psymtab_to_symtab_1):  Set symtab->primary to tell
+       objfile_relocate to do relocations for our symbols.
+       * (ecoff_relocate_efi):  New routine to relocate adr field of PDRs
+       (which hang off of the symbol table).
+       * Use prim_record_minimal_symbols_and_info instead of
+       prim_record_minimal_symbols to supply section info to make minimal
+       symbol relocations work.
+       * minsyms.c (prim_record_minimal_symbols_and_info):  If section is
+       -1, try to deduce it from ms_type.
+       * objfiles.c (objfile_relocate):  Use ALL_OBJFILE_SYMTABS where
+       appropriate.  Handle relocation of MIPS_EFI symbols special. Also,
+       add code to relocate objfile->sections data structure.
+       * remote.c (get_offsets):  Use new protocol message to acquire
+       section offsets from the target.
+       * (remote_wait):  Get rid of relocation stuff.  That's all handled
+       by objfile_relocate now.
+       * config/alpha/alpha-nw.mt (TM_FILE):  Use tm-alphanw.h.
+       * config/alpha/tm-alpha.h:  Define CALL_DUMMY_ADDRESS, and
+       VM_MIN_ADDRESS.
+       * config/alpha/tm-alphanw.h:  DECR_PC_AFTER_BREAK=0, VM_MIN_ADDRESS=0.
+
 Sun Mar 20 15:21:57 1994  Doug Evans  (dje@cygnus.com)
 
        * sparc-tdep.c (sparc_frame_find_save_regs): Use REGISTER_RAW_SIZE
index 31c467be6e75042cb12c3d76f7fddc05e6e7ca2b..ce06b818311a259d32d538b5f7b189f2ba802584 100644 (file)
@@ -25,10 +25,13 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
 #include "gdbcmd.h"
 #include "gdbcore.h"
 #include "dis-asm.h"
+#include "symfile.h"
+#include "objfiles.h"
 
 /* FIXME: Some of this code should perhaps be merged with mips-tdep.c.  */
 
-#define VM_MIN_ADDRESS (CORE_ADDR)0x120000000
+/* FIXME: Put this declaration in frame.h.  */
+extern struct obstack frame_cache_obstack;
 \f
 
 /* Forward declarations.  */
@@ -51,6 +54,12 @@ alpha_in_lenient_prologue PARAMS ((CORE_ADDR, CORE_ADDR));
 static void
 reinit_frame_cache_sfunc PARAMS ((char *, int, struct cmd_list_element *));
 
+static CORE_ADDR after_prologue PARAMS ((CORE_ADDR pc,
+                                        alpha_extra_func_info_t proc_desc));
+
+static int in_prologue PARAMS ((CORE_ADDR pc,
+                               alpha_extra_func_info_t proc_desc));
+
 /* Heuristic_proc_start may hunt through the text section for a long
    time across a 2400 baud serial line.  Allows the user to limit this
    search.  */
@@ -122,7 +131,70 @@ struct linked_proc_info
 } *linked_proc_desc_table = NULL;
 
 \f
-#define READ_FRAME_REG(fi, regno) read_next_frame_reg((fi)->next, regno)
+/* Guaranteed to set fci->saved_regs to some values (it never leaves it
+   NULL).  */
+
+void
+alpha_find_saved_regs (fci)
+     FRAME fci;
+{
+  int ireg;
+  CORE_ADDR reg_position;
+  unsigned long mask;
+  alpha_extra_func_info_t proc_desc;
+  int returnreg;
+
+  fci->saved_regs = (struct frame_saved_regs *)
+    obstack_alloc (&frame_cache_obstack, sizeof(struct frame_saved_regs));
+  memset (fci->saved_regs, 0, sizeof (struct frame_saved_regs));
+
+  proc_desc = fci->proc_desc;
+  if (proc_desc == NULL)
+    /* I'm not sure how/whether this can happen.  Normally when we can't
+       find a proc_desc, we "synthesize" one using heuristic_proc_desc
+       and set the saved_regs right away.  */
+    return;
+
+  /* Fill in the offsets for the registers which gen_mask says
+     were saved.  */
+
+  reg_position = fci->frame + PROC_REG_OFFSET (proc_desc);
+  mask = PROC_REG_MASK (proc_desc);
+
+  returnreg = PROC_PC_REG (proc_desc);
+
+  /* Note that RA is always saved first, regardless of it's actual
+     register number.  */
+  if (mask & (1 << returnreg))
+    {
+      fci->saved_regs->regs[returnreg] = reg_position;
+      reg_position += 8;
+      mask &= ~(1 << returnreg); /* Clear bit for RA so we
+                                   don't save again later. */
+    }
+
+  for (ireg = 0; ireg <= 31 ; ++ireg)
+    if (mask & (1 << ireg))
+      {
+       fci->saved_regs->regs[ireg] = reg_position;
+       reg_position += 8;
+      }
+
+  /* Fill in the offsets for the registers which float_mask says
+     were saved.  */
+
+  reg_position = fci->frame + PROC_FREG_OFFSET (proc_desc);
+  mask = PROC_FREG_MASK (proc_desc);
+
+  for (ireg = 0; ireg <= 31 ; ++ireg)
+    if (mask & (1 << ireg))
+      {
+       fci->saved_regs->regs[FP0_REGNUM+ireg] = reg_position;
+       reg_position += 8;
+      }
+
+  fci->saved_regs->regs[PC_REGNUM] = fci->saved_regs->regs[returnreg];
+}
 
 static CORE_ADDR
 read_next_frame_reg(fi, regno)
@@ -154,8 +226,13 @@ read_next_frame_reg(fi, regno)
         }
       else if (regno == SP_REGNUM)
        return fi->frame;
-      else if (fi->saved_regs->regs[regno])
-       return read_memory_integer(fi->saved_regs->regs[regno], 8);
+      else
+       {
+         if (fi->saved_regs == NULL)
+           alpha_find_saved_regs (fi);
+         if (fi->saved_regs->regs[regno])
+           return read_memory_integer(fi->saved_regs->regs[regno], 8);
+       }
     }
   return read_register(regno);
 }
@@ -297,9 +374,67 @@ heuristic_proc_desc(start_pc, limit_pc, next_frame)
     PROC_FRAME_OFFSET(&temp_proc_desc) = frame_size;
     PROC_REG_MASK(&temp_proc_desc) = reg_mask;
     PROC_PC_REG(&temp_proc_desc) = RA_REGNUM;
+    PROC_LOCALOFF(&temp_proc_desc) = 0;        /* XXX - bogus */
     return &temp_proc_desc;
 }
 
+/* This returns the PC of the first inst after the prologue.  If we can't
+   find the prologue, then return 0.  */
+
+static CORE_ADDR
+after_prologue (pc, proc_desc)
+     CORE_ADDR pc;
+     alpha_extra_func_info_t proc_desc;
+{
+  struct block *b;
+  struct symtab_and_line sal;
+  CORE_ADDR func_addr, func_end;
+
+  if (!proc_desc)
+    proc_desc = find_proc_desc (pc, NULL);
+
+  if (proc_desc)
+    {
+      /* If function is frameless, then we need to do it the hard way.  I
+        strongly suspect that frameless always means prologueless... */
+      if (PROC_FRAME_REG (proc_desc) == SP_REGNUM
+         && PROC_FRAME_OFFSET (proc_desc) == 0)
+       return 0;
+    }
+
+  if (!find_pc_partial_function (pc, NULL, &func_addr, &func_end))
+    return 0;                  /* Unknown */
+
+  sal = find_pc_line (func_addr, 0);
+
+  if (sal.end < func_end)
+    return sal.end;
+
+  /* The line after the prologue is after the end of the function.  In this
+     case, tell the caller to find the prologue the hard way.  */
+
+  return 0;
+}
+
+/* Return non-zero if we *might* be in a function prologue.  Return zero if we
+   are definatly *not* in a function prologue.  */
+
+static int
+in_prologue (pc, proc_desc)
+     CORE_ADDR pc;
+     alpha_extra_func_info_t proc_desc;
+{
+  CORE_ADDR after_prologue_pc;
+
+  after_prologue_pc = after_prologue (pc, proc_desc);
+
+  if (after_prologue_pc == 0
+      || pc < after_prologue_pc)
+    return 1;
+  else
+    return 0;
+}
+
 static alpha_extra_func_info_t
 find_proc_desc(pc, next_frame)
     CORE_ADDR pc;
@@ -317,6 +452,7 @@ find_proc_desc(pc, next_frame)
      as it will be contained in the proc_desc we are searching for.
      So we have to find the proc_desc whose frame is closest to the current
      stack pointer.  */
+
   if (PC_IN_CALL_DUMMY (pc, 0, 0))
     {
       struct linked_proc_info *link;
@@ -338,6 +474,7 @@ find_proc_desc(pc, next_frame)
     }
 
   b = block_for_pc(pc);
+
   find_pc_partial_function (pc, NULL, &startaddr, NULL);
   if (b == NULL)
     sym = NULL;
@@ -355,45 +492,39 @@ find_proc_desc(pc, next_frame)
 
   if (sym)
     {
-       /* IF (this is the topmost frame OR a frame interrupted by a signal)
-        * AND (this proc does not have debugging information OR
+       /* IF this is the topmost frame AND
+        * (this proc does not have debugging information OR
         * the PC is in the procedure prologue)
         * THEN create a "heuristic" proc_desc (by analyzing
         * the actual code) to replace the "official" proc_desc.
         */
        proc_desc = (alpha_extra_func_info_t)SYMBOL_VALUE(sym);
-       if (next_frame == NULL || next_frame->signal_handler_caller) {
-           struct symtab_and_line val;
-           struct symbol *proc_symbol =
-               PROC_DESC_IS_DUMMY(proc_desc) ? 0 : PROC_SYMBOL(proc_desc);
-
-           if (proc_symbol) {
-               val = find_pc_line (BLOCK_START
-                                   (SYMBOL_BLOCK_VALUE(proc_symbol)),
-                                   0);
-               val.pc = val.end ? val.end : pc;
-           }
-           if (!proc_symbol || pc < val.pc) {
+       if (next_frame == NULL)
+         {
+           if (PROC_DESC_IS_DUMMY (proc_desc) || in_prologue (pc, proc_desc))
+             {
                alpha_extra_func_info_t found_heuristic =
-                   heuristic_proc_desc(PROC_LOW_ADDR(proc_desc),
-                                       pc, next_frame);
+                 heuristic_proc_desc (PROC_LOW_ADDR (proc_desc),
+                                      pc, next_frame);
+               PROC_LOCALOFF (found_heuristic) = PROC_LOCALOFF (proc_desc);
                if (found_heuristic)
-                 {
-                   /* The call to heuristic_proc_desc determines
-                      which registers have been saved so far and if the
-                      frame is already set up.
-                      The heuristic algorithm doesn't work well for other
-                      information in the procedure descriptor, so copy
-                      it from the found procedure descriptor.  */
-                   PROC_LOCALOFF(found_heuristic) = PROC_LOCALOFF(proc_desc);
-                   PROC_PC_REG(found_heuristic) = PROC_PC_REG(proc_desc);
-                   proc_desc = found_heuristic;
-                 }
-           }
-       }
+                 proc_desc = found_heuristic;
+             }
+         }
     }
   else
     {
+      /* Is linked_proc_desc_table really necessary?  It only seems to be used
+        by procedure call dummys.  However, the procedures being called ought
+        to have their own proc_descs, and even if they don't,
+        heuristic_proc_desc knows how to create them! */
+
+      register struct linked_proc_info *link;
+      for (link = linked_proc_desc_table; link; link = link->next)
+         if (PROC_LOW_ADDR(&link->info) <= pc
+             && PROC_HIGH_ADDR(&link->info) > pc)
+             return &link->info;
+
       if (startaddr == 0)
        startaddr = heuristic_proc_start (pc);
 
@@ -454,104 +585,43 @@ void
 init_extra_frame_info(fci)
      struct frame_info *fci;
 {
-  extern struct obstack frame_cache_obstack;
   /* Use proc_desc calculated in frame_chain */
   alpha_extra_func_info_t proc_desc =
     fci->next ? cached_proc_desc : find_proc_desc(fci->pc, fci->next);
 
-  fci->saved_regs = (struct frame_saved_regs*)
-    obstack_alloc (&frame_cache_obstack, sizeof(struct frame_saved_regs));
-  memset (fci->saved_regs, 0, sizeof (struct frame_saved_regs));
+  fci->saved_regs = NULL;
   fci->proc_desc =
     proc_desc == &temp_proc_desc ? 0 : proc_desc;
   if (proc_desc)
     {
-      int ireg;
-      CORE_ADDR reg_position;
-      unsigned long mask;
-      int returnreg;
-
       /* Get the locals offset from the procedure descriptor, it is valid
         even if we are in the middle of the prologue.  */
       fci->localoff = PROC_LOCALOFF(proc_desc);
 
       /* Fixup frame-pointer - only needed for top frame */
+
       /* Fetch the frame pointer for a dummy frame from the procedure
         descriptor.  */
       if (PROC_DESC_IS_DUMMY(proc_desc))
        fci->frame = (FRAME_ADDR) PROC_DUMMY_FRAME(proc_desc);
+
       /* This may not be quite right, if proc has a real frame register.
         Get the value of the frame relative sp, procedure might have been
         interrupted by a signal at it's very start.  */
-      else if (fci->pc == PROC_LOW_ADDR(proc_desc))
-       fci->frame = READ_FRAME_REG(fci, SP_REGNUM);
+      else if (fci->pc == PROC_LOW_ADDR (proc_desc) && !PROC_DESC_IS_DUMMY (proc_desc))
+       fci->frame = read_next_frame_reg (fci->next, SP_REGNUM);
       else
-       fci->frame = READ_FRAME_REG(fci, PROC_FRAME_REG(proc_desc))
-                     + PROC_FRAME_OFFSET(proc_desc);
-
-      /* If this is the innermost frame, and we are still in the
-        prologue (loosely defined), then the registers may not have
-        been saved yet.  */
-      if (fci->next == NULL
-          && !PROC_DESC_IS_DUMMY(proc_desc)
-         && alpha_in_lenient_prologue (PROC_LOW_ADDR (proc_desc), fci->pc))
-       {
-         /* Can't just say that the registers are not saved, because they
-            might get clobbered halfway through the prologue.
-            heuristic_proc_desc already has the right code to figure out
-            exactly what has been saved, so use it.  As far as I know we
-            could be doing this (as we do on the 68k, for example)
-            regardless of whether we are in the prologue; I'm leaving in
-            the check for being in the prologue only out of conservatism
-            (I'm not sure whether heuristic_proc_desc handles all cases,
-            for example).
-
-            This stuff is ugly (and getting uglier by the minute).  Probably
-            the best way to clean it up is to ignore the proc_desc's from
-            the symbols altogher, and get all the information we need by
-            examining the prologue (provided we can make the prologue
-            examining code good enough to get all the cases...).  */
-         proc_desc =
-           heuristic_proc_desc (PROC_LOW_ADDR (proc_desc),
-                                fci->pc,
-                                fci->next);
-       }
+       fci->frame = read_next_frame_reg (fci->next, PROC_FRAME_REG (proc_desc))
+                       + PROC_FRAME_OFFSET (proc_desc);
 
       if (proc_desc == &temp_proc_desc)
-       *fci->saved_regs = temp_saved_regs;
-      else
        {
-         /* Find which general-purpose registers were saved.
-            The return address register is the first saved register,
-            the other registers follow in ascending order.  */
-         reg_position = fci->frame + PROC_REG_OFFSET(proc_desc);
-         mask = PROC_REG_MASK(proc_desc) & 0xffffffffL;
-         returnreg = PROC_PC_REG(proc_desc);
-         if (mask & (1 << returnreg))
-           {
-             fci->saved_regs->regs[returnreg] = reg_position;
-             reg_position += 8;
-           }
-         for (ireg = 0; mask; ireg++, mask >>= 1)
-           if (mask & 1)
-             {
-               if (ireg == returnreg)
-                 continue;
-               fci->saved_regs->regs[ireg] = reg_position;
-               reg_position += 8;
-             }
-         /* find which floating-point registers were saved */
-         reg_position = fci->frame + PROC_FREG_OFFSET(proc_desc);
-         mask = PROC_FREG_MASK(proc_desc) & 0xffffffffL;
-         for (ireg = 0; mask; ireg++, mask >>= 1)
-           if (mask & 1)
-             {
-               fci->saved_regs->regs[FP0_REGNUM+ireg] = reg_position;
-               reg_position += 8;
-             }
+         fci->saved_regs = (struct frame_saved_regs*)
+           obstack_alloc (&frame_cache_obstack,
+                          sizeof (struct frame_saved_regs));
+         *fci->saved_regs = temp_saved_regs;
+         fci->saved_regs->regs[PC_REGNUM] = fci->saved_regs->regs[RA_REGNUM];
        }
-
-      fci->saved_regs->regs[PC_REGNUM] = fci->saved_regs->regs[PROC_PC_REG(proc_desc)];
     }
 }
 
@@ -661,16 +731,18 @@ void
 alpha_push_dummy_frame()
 {
   int ireg;
-  struct linked_proc_info *link = (struct linked_proc_info*)
-      xmalloc(sizeof (struct linked_proc_info));
-  alpha_extra_func_info_t proc_desc = &link->info;
+  struct linked_proc_info *link;
+  alpha_extra_func_info_t proc_desc;
   CORE_ADDR sp = read_register (SP_REGNUM);
   CORE_ADDR save_address;
   char raw_buffer[MAX_REGISTER_RAW_SIZE];
   unsigned long mask;
 
+  link = (struct linked_proc_info *) xmalloc(sizeof (struct linked_proc_info));
   link->next = linked_proc_desc_table;
   linked_proc_desc_table = link;
+  proc_desc = &link->info;
 
   /*
    * The registers we must save are all those not preserved across
@@ -764,7 +836,7 @@ alpha_push_dummy_frame()
   sp += PROC_REG_OFFSET(proc_desc);
   write_register (SP_REGNUM, sp);
 
-  PROC_LOW_ADDR(proc_desc) = entry_point_address ();
+  PROC_LOW_ADDR(proc_desc) = CALL_DUMMY_ADDRESS ();
   PROC_HIGH_ADDR(proc_desc) = PROC_LOW_ADDR(proc_desc) + 4;
 
   SET_PROC_DESC_IS_DUMMY(proc_desc);
@@ -781,6 +853,8 @@ alpha_pop_frame()
   alpha_extra_func_info_t proc_desc = frame->proc_desc;
 
   write_register (PC_REGNUM, FRAME_SAVED_PC(frame));
+  if (frame->saved_regs == NULL)
+    alpha_find_saved_regs (frame);
   if (proc_desc)
     {
       for (regnum = 32; --regnum >= 0; )
@@ -838,6 +912,19 @@ alpha_skip_prologue (pc, lenient)
 {
     unsigned long inst;
     int offset;
+    CORE_ADDR post_prologue_pc;
+
+    /* See if we can determine the end of the prologue via the symbol table.
+       If so, then return either PC, or the PC after the prologue, whichever
+       is greater.  */
+
+    post_prologue_pc = after_prologue (pc, NULL);
+
+    if (post_prologue_pc != 0)
+      return max (pc, post_prologue_pc);
+
+    /* Can't determine prologue from the symbol table, need to examine
+       instructions.  */
 
     /* Skip the typical prologue instructions. These are the stack adjustment
        instruction and the instructions that save registers on the stack
@@ -1015,6 +1102,30 @@ reinit_frame_cache_sfunc (args, from_tty, c)
   reinit_frame_cache ();
 }
 
+/* This is the definition of CALL_DUMMY_ADDRESS.  It's a heuristic that is used
+   to find a convenient place in the text segment to stick a breakpoint to
+   detect the completion of a target function call (ala call_function_by_hand).
+ */
+
+CORE_ADDR
+alpha_call_dummy_address ()
+{
+  CORE_ADDR entry;
+  struct minimal_symbol *sym;
+
+  entry = entry_point_address ();
+
+  if (entry != 0)
+    return entry;
+
+  sym = lookup_minimal_symbol ("_Prelude", symfile_objfile);
+
+  if (!sym || MSYMBOL_TYPE (sym) != mst_text)
+    return 0;
+  else
+    return SYMBOL_VALUE_ADDRESS (sym) + 4;
+}
+
 void
 _initialize_alpha_tdep ()
 {
index 4e713222bc54dad96726fc2e6fcb0f509e91d155..7471f1e4729f706cecb35c209687776cce013950 100644 (file)
@@ -315,7 +315,7 @@ static struct blockvector *
 new_bvect PARAMS ((int));
 
 static int
-parse_symbol PARAMS ((SYMR *, union aux_ext *, char *, int));
+parse_symbol PARAMS ((SYMR *, union aux_ext *, char *, int, struct section_offsets *));
 
 static struct type *
 parse_type PARAMS ((int, union aux_ext *, unsigned int, int *, int, char *));
@@ -648,11 +648,12 @@ add_pending (fh, sh, t)
    SYMR's handled (normally one).  */
 
 static int
-parse_symbol (sh, ax, ext_sh, bigend)
+parse_symbol (sh, ax, ext_sh, bigend, section_offsets)
      SYMR *sh;
      union aux_ext *ax;
      char *ext_sh;
      int bigend;
+     struct section_offsets *section_offsets;
 {
   const bfd_size_type external_sym_size = debug_swap->external_sym_size;
   void (* const swap_sym_in) PARAMS ((bfd *, PTR, SYMR *)) =
@@ -674,6 +675,19 @@ parse_symbol (sh, ax, ext_sh, bigend)
   else
     name = debug_info->ss + cur_fdr->issBase + sh->iss;
 
+  switch (sh->sc)
+    {
+    case scText:
+      sh->value += ANOFFSET (section_offsets, SECT_OFF_TEXT);
+      break;
+    case scData:
+      sh->value += ANOFFSET (section_offsets, SECT_OFF_DATA);
+      break;
+    case scBss:
+      sh->value += ANOFFSET (section_offsets, SECT_OFF_BSS);
+      break;
+    }
+
   switch (sh->st)
     {
     case stNil:
@@ -1699,13 +1713,15 @@ upgrade_type (fd, tpp, tq, ax, bigend, sym_name)
    to look for the function which contains the MIPS_EFI_SYMBOL_NAME symbol
    in question, or NULL to use top_stack->cur_block.  */
 
-static void parse_procedure PARAMS ((PDR *, struct symtab *, unsigned long));
+static void parse_procedure PARAMS ((PDR *, struct symtab *, unsigned long,
+                                    struct section_offsets *));
 
 static void
-parse_procedure (pr, search_symtab, first_off)
+parse_procedure (pr, search_symtab, first_off, section_offsets)
      PDR *pr;
      struct symtab *search_symtab;
      unsigned long first_off;
+     struct section_offsets *section_offsets;
 {
   struct symbol *s, *i;
   struct block *b;
@@ -1810,7 +1826,8 @@ parse_procedure (pr, search_symtab, first_off)
       e = (struct mips_extra_func_info *) SYMBOL_VALUE (i);
       e->pdr = *pr;
       e->pdr.isym = (long) s;
-      e->pdr.adr += cur_fdr->adr - first_off;
+      e->pdr.adr += cur_fdr->adr - first_off
+       + ANOFFSET (section_offsets, SECT_OFF_TEXT);
 
       /* Correct incorrect setjmp procedure descriptor from the library
         to make backtrace through setjmp work.  */
@@ -1824,6 +1841,20 @@ parse_procedure (pr, search_symtab, first_off)
     }
 }
 
+/* Relocate the extra function info pointed to by the symbol table.  */
+
+void
+ecoff_relocate_efi (sym, delta)
+     struct symbol *sym;
+     CORE_ADDR delta;
+{
+  struct mips_extra_func_info *e;
+
+  e = (struct mips_extra_func_info *) SYMBOL_VALUE (sym);
+  
+  e->pdr.adr += delta;
+}
+
 /* Parse the external symbol ES. Just call parse_symbol() after
    making sure we know where the aux are for it. For procedures,
    parsing of the PDRs has already provided all the needed
@@ -1834,10 +1865,11 @@ parse_procedure (pr, search_symtab, first_off)
    This routine clobbers top_stack->cur_block and ->cur_st. */
 
 static void
-parse_external (es, skip_procedures, bigend)
+parse_external (es, skip_procedures, bigend, section_offsets)
      EXTR *es;
      int skip_procedures;
      int bigend;
+     struct section_offsets *section_offsets;
 {
   union aux_ext *ax;
 
@@ -1904,7 +1936,7 @@ parse_external (es, skip_procedures, bigend)
     case stLabel:
       /* Note that the case of a symbol with indexNil must be handled
         anyways by parse_symbol().  */
-      parse_symbol (&es->asym, ax, (char *) NULL, bigend);
+      parse_symbol (&es->asym, ax, (char *) NULL, bigend, section_offsets);
       break;
     default:
       break;
@@ -1918,11 +1950,12 @@ parse_external (es, skip_procedures, bigend)
    with that and do not need to reorder our linetables */
 
 static void
-parse_lines (fh, pr, lt, maxlines)
+parse_lines (fh, pr, lt, maxlines, section_offsets)
      FDR *fh;
      PDR *pr;
      struct linetable *lt;
      int maxlines;
+     struct section_offsets *section_offsets;
 {
   unsigned char *base;
   int j, k;
@@ -1932,8 +1965,6 @@ parse_lines (fh, pr, lt, maxlines)
   if (fh->cbLine == 0)
     return;
 
-  base = debug_info->line + fh->cbLineOffset;
-
   /* Scan by procedure descriptors */
   k = 0;
   for (j = 0; j < fh->cpd; j++, pr++)
@@ -1956,7 +1987,9 @@ parse_lines (fh, pr, lt, maxlines)
        halt = base + fh->cbLine;
       base += pr->cbLineOffset;
 
-      adr = fh->adr + pr->adr - first_off;
+      adr = fh->adr + pr->adr - first_off
+       + ANOFFSET (section_offsets, SECT_OFF_TEXT);
+
       l = adr >> 2;            /* in words */
       for (lineno = pr->lnLow; base < halt; )
        {
@@ -2286,9 +2319,11 @@ parse_partial_symbols (objfile, section_offsets)
                {
                  if (sh.st == stProc || sh.st == stStaticProc)
                    {
-                     long procaddr = sh.value;
+                     long procaddr;
                      long isym;
-
+       
+                     sh.value += ANOFFSET (section_offsets, SECT_OFF_TEXT);
+                     procaddr = sh.value;
 
                      isym = AUX_GET_ISYM (fh->fBigendian,
                                           (debug_info->external_aux
@@ -2358,8 +2393,9 @@ parse_partial_symbols (objfile, section_offsets)
                  int new_sdx;
 
                case stStaticProc:
-                 prim_record_minimal_symbol (name, sh.value, mst_file_text,
-                                             objfile);
+                 prim_record_minimal_symbol_and_info (name, sh.value,
+                                                      mst_file_text, NULL,
+                                                      SECT_OFF_TEXT, objfile);
 
                  /* FALLTHROUGH */
 
@@ -2427,11 +2463,15 @@ parse_partial_symbols (objfile, section_offsets)
                      || sh.sc == scRData
                      || sh.sc == scPData
                      || sh.sc == scXData)
-                   prim_record_minimal_symbol (name, sh.value, mst_file_data,
-                                               objfile);
+                   prim_record_minimal_symbol_and_info (name, sh.value,
+                                                        mst_file_data, NULL,
+                                                        SECT_OFF_DATA,
+                                                        objfile);
                  else
-                   prim_record_minimal_symbol (name, sh.value, mst_file_bss,
-                                               objfile);
+                   prim_record_minimal_symbol_and_info (name, sh.value,
+                                                        mst_file_bss, NULL,
+                                                        SECT_OFF_BSS,
+                                                        objfile);
                  class = LOC_STATIC;
                  break;
 
@@ -2899,7 +2939,7 @@ psymtab_to_symtab_1 (pst, filename)
              first_off = pr.adr;
              first_pdr = 0;
            }
-         parse_procedure (&pr, st, first_off);
+         parse_procedure (&pr, st, first_off, pst->section_offsets);
        }
     }
   else
@@ -2966,7 +3006,7 @@ psymtab_to_symtab_1 (pst, filename)
              (*swap_sym_in) (cur_bfd, sym_ptr, &sh);
              c = parse_symbol (&sh,
                                debug_info->external_aux + fh->iauxBase,
-                               sym_ptr, fh->fBigendian);
+                               sym_ptr, fh->fBigendian, pst->section_offsets);
              sym_ptr += c * external_sym_size;
            }
 
@@ -2995,7 +3035,8 @@ psymtab_to_symtab_1 (pst, filename)
                   pdr_ptr += external_pdr_size, pdr_in++)
                (*swap_pdr_in) (cur_bfd, pdr_ptr, pdr_in);
 
-             parse_lines (fh, pr_block, lines, maxlines);
+             parse_lines (fh, pr_block, lines, maxlines,
+                          pst->section_offsets);
              if (lines->nitems < fh->cline)
                lines = shrink_linetable (lines);
 
@@ -3003,7 +3044,8 @@ psymtab_to_symtab_1 (pst, filename)
              pdr_in = pr_block;
              pdr_in_end = pdr_in + fh->cpd;
              for (; pdr_in < pdr_in_end; pdr_in++)
-               parse_procedure (pdr_in, 0, pr_block->adr);
+               parse_procedure (pdr_in, 0, pr_block->adr,
+                                pst->section_offsets);
 
              do_cleanups (old_chain);
            }
@@ -3025,7 +3067,7 @@ psymtab_to_symtab_1 (pst, filename)
 
       ext_ptr = PST_PRIVATE (pst)->extern_tab;
       for (i = PST_PRIVATE (pst)->extern_count; --i >= 0; ext_ptr++)
-       parse_external (ext_ptr, 1, fh->fBigendian);
+       parse_external (ext_ptr, 1, fh->fBigendian, pst->section_offsets);
 
       /* If there are undefined symbols, tell the user.
         The alpha has an undefined symbol for every symbol that is
@@ -3041,6 +3083,8 @@ psymtab_to_symtab_1 (pst, filename)
        }
       pop_parse_stack ();
 
+      st->primary = 1;
+
       /* Sort the symbol table now, we are done adding symbols to it.*/
       sort_symtab_syms (st);
 
index ec724713f4889cbc520e3e0bcbd4f37d7a314973..ff31f73a3b61436e8993bddcf7853527a54daeff 100644 (file)
@@ -44,6 +44,7 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
 #include "symfile.h"
 #include "objfiles.h"
 #include "demangle.h"
+#include "gdb-stabs.h"
 
 /* Accumulate the minimal symbols for each objfile in bunches of BUNCH_SIZE.
    At the end, copy them all into one newly allocated location on an objfile's
@@ -327,7 +328,27 @@ prim_record_minimal_symbol_and_info (name, address, ms_type, info, section,
   SYMBOL_NAME (msymbol) = (char *) name;
   SYMBOL_INIT_LANGUAGE_SPECIFIC (msymbol, language_unknown);
   SYMBOL_VALUE_ADDRESS (msymbol) = address;
-  SYMBOL_SECTION (msymbol) = section;
+  if (section == -1)
+    switch (ms_type)
+      {
+      case mst_text:
+      case mst_file_text:
+       SYMBOL_SECTION (msymbol) = SECT_OFF_TEXT;
+       break;
+      case mst_data:
+      case mst_file_data:
+       SYMBOL_SECTION (msymbol) = SECT_OFF_DATA;
+       break;
+      case mst_bss:
+      case mst_file_bss:
+       SYMBOL_SECTION (msymbol) = SECT_OFF_BSS;
+       break;
+      default:
+       SYMBOL_SECTION (msymbol) = -1;
+      }
+  else
+    SYMBOL_SECTION (msymbol) = section;
+
   MSYMBOL_TYPE (msymbol) = ms_type;
   /* FIXME:  This info, if it remains, needs its own field.  */
   MSYMBOL_INFO (msymbol) = info; /* FIXME! */
index 6c6dfc20724319af876882f86532e2a5366d85cc..4f0dfd6d93922ff1ba9058bdff0e3a3b6b1d0910 100644 (file)
@@ -450,7 +450,7 @@ objfile_relocate (objfile, new_offsets)
   {
     struct symtab *s;
 
-    for (s = objfile->symtabs; s; s = s->next)
+    ALL_OBJFILE_SYMTABS (objfile, s)
       {
        struct linetable *l;
        struct blockvector *bv;
@@ -492,6 +492,15 @@ objfile_relocate (objfile, new_offsets)
                    SYMBOL_VALUE_ADDRESS (sym) +=
                      ANOFFSET (delta, SYMBOL_SECTION (sym));
                  }
+#ifdef MIPS_EFI_SYMBOL_NAME
+               /* Relocate Extra Function Info for ecoff.  */
+
+               else
+                 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));
+#endif
              }
          }
       }
@@ -538,6 +547,37 @@ objfile_relocate (objfile, new_offsets)
     for (i = 0; i < objfile->num_sections; ++i)
       ANOFFSET (objfile->section_offsets, i) = ANOFFSET (new_offsets, i);
   }
+
+  {
+    struct obj_section *s;
+    bfd *abfd;
+
+    abfd = symfile_objfile->obfd;
+
+    for (s = symfile_objfile->sections;
+        s < symfile_objfile->sections_end; ++s)
+      {
+       flagword flags;
+
+       flags = bfd_get_section_flags (abfd, s->the_bfd_section);
+
+       if (flags & SEC_CODE)
+         {
+           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->endaddr += ANOFFSET (delta, SECT_OFF_DATA);
+         }
+       else if (flags & SEC_ALLOC)
+         {
+           s->addr += ANOFFSET (delta, SECT_OFF_BSS);
+           s->endaddr += ANOFFSET (delta, SECT_OFF_BSS);
+         }
+      }
+  }
 }
 \f
 /* Many places in gdb want to test just to see if we have any partial
index 7240f0b52774128111424b3187d444ded0fe7418..d969e11d8cf107cba6c8a37b058f6bfd0eb15137 100644 (file)
@@ -90,22 +90,10 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
                                        AA = signal number
                                        n... = register number
                                        r... = register contents
-       or...           WAA             The process extited, and AA is
+       or...           WAA             The process exited, and AA is
                                        the exit status.  This is only
                                        applicable for certains sorts of
                                        targets.
-       or...           NAATT;DD;BB     Relocate the object file.
-                                       AA = signal number
-                                       TT = text address
-                                       DD = data address
-                                       BB = bss address
-                                       This is used by the NLM stub,
-                                       which is why it only has three
-                                       addresses rather than one per
-                                       section: the NLM stub always
-                                       sees only three sections, even
-                                       though gdb may see more.
-
        kill request    k
 
        toggle debug    d               toggle debug flag (see 386 & 68k stubs)
@@ -116,17 +104,33 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
                                        we can extend the protocol and GDB
                                        can tell whether the stub it is
                                        talking to uses the old or the new.
+<<<<<<< remote.c
+       search          tAA:PP,MM       Search backwards starting at address
+||||||| 1.81
+       search          tAA:PP,MM       Search backword starting at address
+=======
        search          tAA:PP,MM       Search backward starting at address
+>>>>>>> 1.82
                                        AA for a match with pattern PP and
                                        mask MM.  PP and MM are 4 bytes.
                                        Not supported by all stubs.
 
+<<<<<<< remote.c
+       general query   qXXXX           Request info about XXXX.
+       general set     QXXXX=yyyy      Set value of XXXX to yyyy.
+       query sect offs qOffsets        Get section offsets.  Reply is
+                                       Text=xxx;Data=yyy;Bss=zzz
+*/
+
+||||||| 1.81
+=======
        Responses can be run-length encoded to save space.  A '*' means that
        the next two characters are hex digits giving a repeat count which
        stands for that many repititions of the character preceding the '*'.
        Note that this means that responses cannot contain '*'.  Example:
         "0*03" means the same as "0000".  */
 
+>>>>>>> 1.82
 #include "defs.h"
 #include <string.h>
 #include <fcntl.h>
@@ -265,6 +269,49 @@ remote_close (quitting)
   remote_desc = NULL;
 }
 
+/* Query the remote side for the text, data and bss offsets. */
+
+static void
+get_offsets ()
+{
+  unsigned char buf [PBUFSIZ];
+  int nvals;
+  CORE_ADDR text_addr, data_addr, bss_addr;
+  struct section_offsets *offs;
+
+  putpkt ("qOffsets");
+
+  getpkt (buf, 1);
+
+  if (buf[0] == 'E')
+    {
+      warning ("Remote failure reply: %s", buf);
+      return;
+    }
+
+  nvals = sscanf (buf, "Text=%lx;Data=%lx;Bss=%lx", &text_addr, &data_addr,
+                 &bss_addr);
+  if (nvals != 3)
+    error ("Malformed response to offset query, %s", buf);
+
+  if (symfile_objfile == NULL)
+    return;
+
+  offs = (struct section_offsets *) alloca (sizeof (struct section_offsets)
+                                           + symfile_objfile->num_sections
+                                           * sizeof (offs->offsets));
+  memcpy (offs, symfile_objfile->section_offsets,
+         sizeof (struct section_offsets)
+         + symfile_objfile->num_sections
+         * sizeof (offs->offsets));
+
+  ANOFFSET (offs, SECT_OFF_TEXT) = text_addr;
+  ANOFFSET (offs, SECT_OFF_DATA) = data_addr;
+  ANOFFSET (offs, SECT_OFF_BSS) = bss_addr;
+
+  objfile_relocate (symfile_objfile, offs);
+}
+
 /* Stub for catch_errors.  */
 
 static int
@@ -274,13 +321,16 @@ remote_start_remote (dummy)
   immediate_quit = 1;          /* Allow user to interrupt it */
 
   /* Ack any packet which the remote side has already sent.  */
-  /* I'm not sure this \r is needed; we don't use it any other time we
-     send an ack.  */
-  SERIAL_WRITE (remote_desc, "+\r", 2);
+
+  SERIAL_WRITE (remote_desc, "+", 1);
+
+  get_offsets ();              /* Get text, data & bss offsets */
+
   putpkt ("?");                        /* initiate a query from remote machine */
   immediate_quit = 0;
 
   start_remote ();             /* Initialize gdb process mechanisms */
+
   return 1;
 }
 
@@ -536,90 +586,6 @@ remote_wait (pid, status)
            }
          break;
        }
-      else if (buf[0] == 'N')
-       {
-         unsigned char *p1;
-         bfd_vma text_addr, data_addr, bss_addr;
-
-         /* Relocate object file.  Format is NAATT;DD;BB where AA is
-            the signal number, TT is the new text address, DD is the
-            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 = strtoul (p, &p1, 16);
-         if (p1 == p || *p1 != ';')
-           warning ("Malformed relocation packet: Packet '%s'", buf);
-         p = p1 + 1;
-         data_addr = strtoul (p, &p1, 16);
-         if (p1 == p || *p1 != ';')
-           warning ("Malformed relocation packet: Packet '%s'", buf);
-         p = p1 + 1;
-         bss_addr = strtoul (p, &p1, 16);
-         if (p1 == p)
-           warning ("Malformed relocation packet: Packet '%s'", buf);
-
-         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;
-
-             /* FIXME: This code assumes gdb-stabs.h is being used;
-                it's broken for xcoff, dwarf, sdb-coff, etc.  But
-                there is no simple canonical representation for this
-                stuff.  (Just what does "text" as seen by the stub
-                mean, anyway?).  */
-
-             offs = ((struct section_offsets *)
-                     alloca (sizeof (struct section_offsets)
-                             + (symfile_objfile->num_sections
-                                * sizeof (offs->offsets))));
-             memcpy (offs, symfile_objfile->section_offsets,
-                     (sizeof (struct section_offsets)
-                      + (symfile_objfile->num_sections
-                         * sizeof (offs->offsets))));
-             ANOFFSET (offs, SECT_OFF_TEXT) = text_addr;
-             ANOFFSET (offs, SECT_OFF_DATA) = data_addr;
-             ANOFFSET (offs, SECT_OFF_BSS) = bss_addr;
-
-             objfile_relocate (symfile_objfile, offs);
-             {
-               struct obj_section *s;
-               bfd *abfd;
-
-               abfd = symfile_objfile->obfd;
-
-               for (s = symfile_objfile->sections;
-                    s < symfile_objfile->sections_end; ++s)
-                 {
-                   flagword flags;
-
-                   flags = bfd_get_section_flags (abfd, s->the_bfd_section);
-
-                   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;
-       }
       else if (buf[0] == 'W')
        {
          /* The remote process exited.  */