* config/rs6000/tm-rs6000.h (IN_SOLIB_RETURN_TRAMPOLINE): Define.
authorNicholas Duffek <nsd@redhat.com>
Tue, 1 May 2001 19:36:11 +0000 (19:36 +0000)
committerNicholas Duffek <nsd@redhat.com>
Tue, 1 May 2001 19:36:11 +0000 (19:36 +0000)
(rs6000_in_solib_return_trampoline): Declare.
* rs6000-tdep.c (rs6000_in_solib_return_trampoline): New
function.
(rs6000_skip_trampoline_code): Skip bigtoc fixup code.
* xcoffread.c (read_xcoff_symtab): Perform the ISFCN function
check after the CSECT check rather than before it.  Allocate
separate symtabs for CSECTs whose names begin with '@'.
(scan_xcoff_symtab): Don't ignore symbols beginning with '@'.
Activate the misc_func_recorded mechanism for whose names begin
with '@'.

gdb/ChangeLog
gdb/config/rs6000/tm-rs6000.h
gdb/rs6000-tdep.c
gdb/xcoffread.c

index 7b9a4f85250dc7b81919391281d7adf09fc8a32c..30c6acbc5f1b819de188bfa3593c9ecd60428ccd 100644 (file)
@@ -1,3 +1,17 @@
+2001-05-01  Nicholas Duffek  <nsd@redhat.com>
+
+       * config/rs6000/tm-rs6000.h (IN_SOLIB_RETURN_TRAMPOLINE): Define.
+       (rs6000_in_solib_return_trampoline): Declare.
+       * rs6000-tdep.c (rs6000_in_solib_return_trampoline): New
+       function.
+       (rs6000_skip_trampoline_code): Skip bigtoc fixup code.
+       * xcoffread.c (read_xcoff_symtab): Perform the ISFCN function
+       check after the CSECT check rather than before it.  Allocate
+       separate symtabs for CSECTs whose names begin with '@'.
+       (scan_xcoff_symtab): Don't ignore symbols beginning with '@'.
+       Activate the misc_func_recorded mechanism for whose names begin
+       with '@'.
+
 2001-04-30  J.T. Conklin  <jtc@redback.com>
 
        * ppcnbsd-nat.c (fetch_inferior_registers)
index d16ca9a43a8fc4fa347a7bccb4acdf20cd6f79f0..96eb16337f7349aea4faa8d9db819b176bd911ca 100644 (file)
 #undef CPLUS_MARKER
 #define CPLUS_MARKER '.'
 
+/* Return whether PC in function NAME is in code that should be skipped when
+   single-stepping.  */
+
+#define IN_SOLIB_RETURN_TRAMPOLINE(pc, name) \
+  rs6000_in_solib_return_trampoline (pc, name)
+extern int rs6000_in_solib_return_trampoline (CORE_ADDR, char *);
+
 /* If PC is in some function-call trampoline code, return the PC
    where the function itself actually starts.  If not, return NULL.  */
 
index 3b4aeb95f6d4f54e546d760c241500782c04ad31..3c0a7b9ad5aef076acfe7950116d9e9996abbca7 100644 (file)
@@ -1132,19 +1132,55 @@ rs6000_extract_return_value (struct type *valtype, char *regbuf, char *valbuf)
 
 static CORE_ADDR rs6000_struct_return_address;
 
-/* Indirect function calls use a piece of trampoline code to do context
-   switching, i.e. to set the new TOC table. Skip such code if we are on
-   its first instruction (as when we have single-stepped to here). 
-   Also skip shared library trampoline code (which is different from
+/* Return whether handle_inferior_event() should proceed through code
+   starting at PC in function NAME when stepping.
+
+   The AIX -bbigtoc linker option generates functions @FIX0, @FIX1, etc. to
+   handle memory references that are too distant to fit in instructions
+   generated by the compiler.  For example, if 'foo' in the following
+   instruction:
+
+     lwz r9,foo(r2)
+
+   is greater than 32767, the linker might replace the lwz with a branch to
+   somewhere in @FIX1 that does the load in 2 instructions and then branches
+   back to where execution should continue.
+
+   GDB should silently step over @FIX code, just like AIX dbx does.
+   Unfortunately, the linker uses the "b" instruction for the branches,
+   meaning that the link register doesn't get set.  Therefore, GDB's usual
+   step_over_function() mechanism won't work.
+
+   Instead, use the IN_SOLIB_RETURN_TRAMPOLINE and SKIP_TRAMPOLINE_CODE hooks
+   in handle_inferior_event() to skip past @FIX code.  */
+
+int
+rs6000_in_solib_return_trampoline (CORE_ADDR pc, char *name)
+{
+  return name && !strncmp (name, "@FIX", 4);
+}
+
+/* Skip code that the user doesn't want to see when stepping:
+
+   1. Indirect function calls use a piece of trampoline code to do context
+   switching, i.e. to set the new TOC table.  Skip such code if we are on
+   its first instruction (as when we have single-stepped to here).
+
+   2. Skip shared library trampoline code (which is different from
    indirect function call trampolines).
+
+   3. Skip bigtoc fixup code.
+
    Result is desired PC to step until, or NULL if we are not in
-   trampoline code.  */
+   code that should be skipped.  */
 
 CORE_ADDR
 rs6000_skip_trampoline_code (CORE_ADDR pc)
 {
   register unsigned int ii, op;
+  int rel;
   CORE_ADDR solib_target_pc;
+  struct minimal_symbol *msymbol;
 
   static unsigned trampoline_code[] =
   {
@@ -1158,6 +1194,21 @@ rs6000_skip_trampoline_code (CORE_ADDR pc)
     0
   };
 
+  /* Check for bigtoc fixup code.  */
+  msymbol = lookup_minimal_symbol_by_pc (pc);
+  if (msymbol && rs6000_in_solib_return_trampoline (pc, SYMBOL_NAME (msymbol)))
+    {
+      /* Double-check that the third instruction from PC is relative "b".  */
+      op = read_memory_integer (pc + 8, 4);
+      if ((op & 0xfc000003) == 0x48000000)
+       {
+         /* Extract bits 6-29 as a signed 24-bit relative word address and
+            add it to the containing PC.  */
+         rel = ((int)(op << 6) >> 6);
+         return pc + 8 + rel;
+       }
+    }
+
   /* If pc is in a shared library trampoline, return its target.  */
   solib_target_pc = find_solib_trampoline_target (pc);
   if (solib_target_pc)
index 586f258d90f3d729676e9f39b33a3ad9a3d92860..6e52710d4722b10a370c6a5dfe37741c317af15b 100644 (file)
@@ -1081,14 +1081,6 @@ read_xcoff_symtab (struct partial_symtab *pst)
          /* done with all files, everything from here on is globals */
        }
 
-      /* if explicitly specified as a function, treat is as one. */
-      if (ISFCN (cs->c_type) && cs->c_sclass != C_TPDEF)
-       {
-         bfd_coff_swap_aux_in (abfd, raw_auxptr, cs->c_type, cs->c_sclass,
-                               0, cs->c_naux, &main_aux);
-         goto function_entry_point;
-       }
-
       if ((cs->c_sclass == C_EXT || cs->c_sclass == C_HIDEXT)
          && cs->c_naux == 1)
        {
@@ -1158,7 +1150,8 @@ read_xcoff_symtab (struct partial_symtab *pst)
                                                SECT_OFF_TEXT (objfile));
                      file_end_addr = file_start_addr + CSECT_LEN (&main_aux);
 
-                     if (cs->c_name && cs->c_name[0] == '.')
+                     if (cs->c_name && (cs->c_name[0] == '.'
+                                        || cs->c_name[0] == '@'))
                        {
                          last_csect_name = cs->c_name;
                          last_csect_val = cs->c_value;
@@ -1232,6 +1225,16 @@ read_xcoff_symtab (struct partial_symtab *pst)
            }
        }
 
+      /* If explicitly specified as a function, treat is as one.  This check
+        evaluates to true for @FIX* bigtoc CSECT symbols, so it must occur
+        after the above CSECT check.  */
+      if (ISFCN (cs->c_type) && cs->c_sclass != C_TPDEF)
+       {
+         bfd_coff_swap_aux_in (abfd, raw_auxptr, cs->c_type, cs->c_sclass,
+                               0, cs->c_naux, &main_aux);
+         goto function_entry_point;
+       }
+
       switch (cs->c_sclass)
        {
 
@@ -2243,14 +2246,8 @@ scan_xcoff_symtab (struct objfile *objfile)
            else
              csect_aux = main_aux[0];
 
-           /* If symbol name starts with ".$" or "$", ignore it. 
-
-              A symbol like "@FIX1" introduces a section for -bbigtoc jump
-              tables, which contain anonymous linker-generated code. 
-              Ignore those sections to avoid "pc 0x... in read in psymtab,
-              but not in symtab" warnings from find_pc_sect_symtab.  */
-
-           if (namestring[0] == '$' || namestring[0] == '@'
+           /* If symbol name starts with ".$" or "$", ignore it.  */
+           if (namestring[0] == '$'
                || (namestring[0] == '.' && namestring[1] == '$'))
              break;
 
@@ -2296,7 +2293,11 @@ scan_xcoff_symtab (struct objfile *objfile)
                               objfile->static_psymbols.next);
                          }
                      }
-                   if (namestring && namestring[0] == '.')
+                   /* Activate the misc_func_recorded mechanism for
+                      compiler- and linker-generated CSECTs like ".strcmp"
+                      and "@FIX1".  */ 
+                   if (namestring && (namestring[0] == '.'
+                                      || namestring[0] == '@'))
                      {
                        last_csect_name = namestring;
                        last_csect_val = symbol.n_value;