This is the mail archive of the gdb-patches@sourceware.org mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [RFC] PPC: Skip call to __eabi in main()


On Tue, 22 Jul 2008 01:44:27 -0300
Thiago Jung Bauermann <bauerman@br.ibm.com> wrote:

> On Mon, 2008-07-21 at 15:53 -0700, Kevin Buettner wrote:
> > +  if ((op & 0xfc000001) == 0x48000001)
> > +    {
> > +      CORE_ADDR displ = op & 0x03fffffc;
> 
> I think this would be more legible with #defines instead of these
> hardcoded opcodes and bitmasks. Also, a comment above each #define
> explaining what the value means, of course.

I agree.

I found that this approach (of using macros for the masks and opcodes)
is used at two other locations in rs6000-tdep.c, but noticed that the
naming convention is not quite uniform.  The _MASK suffix is used in
both locations, but one location uses the _INSN suffix for opcode
values while the other location uses _INSTRUCTION.  I decided to go
with the longer name.  It does make the lines longer, but not long
enough to force me to have to split them in order to stay within
eighty columns.

I've placed the block of new macro definitions just ahead of
skip_prologue().  The existing convention seems to be that they are
placed just before the function in which they are first used.  Thus,
these macros would normally be placed just ahead of the new function,
rs6000_skip_main_prologue, that I'm introducing in this patch. 
However, skip_prologue() has a couple of spots which use hardcoded
constants for decoding `bl' instructions, thus it makes sense to put
these macros in a location where they'll be usable by both functions.

I'll post a later patch which updates skip_prologue() to also use
these macros instead of hardcoded constants for decoding the bl
instruction.

Further comments?

	* rs6000-tdep.c (BL_MASK, BL_INSTRUCTION, BL_DISPLACEMENT_MASK):
	New macros.
	(rs6000_skip_main_prologue): New function.
	(rs6000_gdb_arch_init): Register rs6000_skip_main_prologue.

Index: rs6000-tdep.c
===================================================================
RCS file: /cvs/src/src/gdb/rs6000-tdep.c,v
retrieving revision 1.318
diff -u -p -r1.318 rs6000-tdep.c
--- rs6000-tdep.c	15 Jul 2008 18:32:06 -0000	1.318
+++ rs6000-tdep.c	23 Jul 2008 00:43:05 -0000
@@ -1146,6 +1146,20 @@ bl_to_blrl_insn_p (CORE_ADDR pc, int ins
   return 0;
 }
 
+/* Masks for decoding a branch-and-link (bl) instruction.  
+
+   BL_MASK and BL_INSTRUCTION are used in combination with each other.
+   The former is anded with the opcode in question; if the result of
+   this masking operation is equal to BL_INSTRUCTION, then the opcode in
+   question is a ``bl'' instruction.
+   
+   BL_DISPLACMENT_MASK is anded with the opcode in order to extract
+   the branch displacement.  */
+
+#define BL_MASK 0xfc000001
+#define BL_INSTRUCTION 0x48000001
+#define BL_DISPLACEMENT_MASK 0x03fffffc
+
 /* return pc value after skipping a function prologue and also return
    information about a function frame.
 
@@ -1769,6 +1783,32 @@ rs6000_skip_prologue (struct gdbarch *gd
   return pc;
 }
 
+/* Check that the code pointed to by PC corresponds to a call to
+   __eabi, skip it if so.  Return PC otherwise.  */
+
+CORE_ADDR
+rs6000_skip_main_prologue (struct gdbarch *gdbarch, CORE_ADDR pc)
+{
+  gdb_byte buf[4];
+  unsigned long op;
+
+  if (target_read_memory (pc, buf, 4))
+    return pc;
+  op = extract_unsigned_integer (buf, 4);
+
+  if ((op & BL_MASK) == BL_INSTRUCTION)
+    {
+      CORE_ADDR displ = op & BL_DISPLACEMENT_MASK;
+      CORE_ADDR call_dest = pc + 4 + displ;
+      struct minimal_symbol *s = lookup_minimal_symbol_by_pc (call_dest);
+
+      if (s != NULL
+          && SYMBOL_LINKAGE_NAME (s) != NULL
+	  && strcmp (SYMBOL_LINKAGE_NAME (s), "__eabi") == 0)
+	pc += 4;
+    }
+  return pc;
+}
 
 /* All the ABI's require 16 byte alignment.  */
 static CORE_ADDR
@@ -3238,6 +3278,7 @@ rs6000_gdbarch_init (struct gdbarch_info
 
   set_gdbarch_skip_prologue (gdbarch, rs6000_skip_prologue);
   set_gdbarch_in_function_epilogue_p (gdbarch, rs6000_in_function_epilogue_p);
+  set_gdbarch_skip_main_prologue (gdbarch, rs6000_skip_main_prologue);
 
   set_gdbarch_inner_than (gdbarch, core_addr_lessthan);
   set_gdbarch_breakpoint_from_pc (gdbarch, rs6000_breakpoint_from_pc);


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]