Mirror of the gdb-patches mailing list
 help / color / mirror / Atom feed
* [RFC] New GDB Port CR16
@ 2012-08-27  6:37 Kaushik Phatak
  2012-08-27 16:21 ` Yao Qi
                   ` (2 more replies)
  0 siblings, 3 replies; 18+ messages in thread
From: Kaushik Phatak @ 2012-08-27  6:37 UTC (permalink / raw)
  To: gdb-patches

[-- Attachment #1: Type: text/plain, Size: 2354 bytes --]

Hi,

Please find attached a patch that adds support for the National Semiconductor CR16 
architecture to GDB. The sim patch is already present in the sources. This patch
enhances the sim to support breakpoints for sim based debugging.

I had earlier posted a patch to fix the build failures in CR16 sim,
http://sourceware.org/ml/gdb-patches/2012-05/msg00342.html
However these were already fixed by Mike Frysinger,
http://sourceware.org/bugzilla/show_bug.cgi?id=12862

This fixed the build failures, but the target was not emulating the correct
system calls. This patch should fix this problem by regenerating nltvals.def 
using gennltvals.sh with the following libgloss additions to Newlib posted 
recently,
http://sourceware.org/ml/newlib/2012/msg00319.html

The attached patch includes the expected nltvals.def file changes, however I 
may have not run the script correctly. Please let me know if this is ok.

Additionally, the port uses two functions from the disassembler in 
opcodes/cr16-dis.c. The static declarations have been removed from these. These
are added to the patch below. Do I need to copy that hunk to binutils mailing
list?

The port uses basic structure of the Renesas RX port and some concepts borrowed 
from the ARM port. Kindly review the same and let me know if further modifications
are required.

Additional Information on CR16 target:
The CR16 target saves the return address (right shifted by 1) onto the RA
register, which is later pushed onto the stack for leaf calls. The unwinder
takes care of this in the frame_prev_register call.
The CR16 target has a combination of 16 and 32 bit registers. R0 to R11 are
16 bits wide and can be accessed as 16 bit or 32 bit (register pair).
R12, R13, RA and SP are 32 bit registers.


2012-08-24 Kaushik Phatak  <kaushik.phatak@kpitcummins.com>

gdb/ChangeLog:
	* configure.tgt (cr16-*-elf): New target.
	* cr16-tdep.c: New file.

sim/cr16/ChangeLog:
	* interp.c (sim_complete_command): New stub function.
	* cr16_sim.h : Add defines for TRAP handling
	* simops.c: Breakpoint handling code

opcodes/ChangeLog:
	* cr16-dis.c (match_opcode): Remove static function
	declaration.
	(make_instruction): Likewise.


Thanks & Best Regards,
Kaushik
kaushik.phatak@kpitcummins.com
KPIT Cummins Infosystems Ltd
www.kpitcummins.com


[-- Attachment #2: cr16_gdb.diff --]
[-- Type: application/octet-stream, Size: 34370 bytes --]

--- gdb_src.orig/sim/common/gennltvals.sh	2012-03-19 10:24:48.000000000 +0530
+++ ./gdb_src/sim/common/gennltvals.sh	2012-08-17 15:35:15.000000000 +0530
@@ -41,7 +41,7 @@ $shell ${srccom}/gentvals.sh $target sys
 # OBSOLETE $shell ${srccom}/gentvals.sh $target sys ${srcroot}/$dir \
 # OBSOLETE 	"syscall.h" 'SYS_[_[:alnum:]]*' "${cpp}"
 
-dir=libgloss target=cr16
+dir=libgloss/cr16/sys target=cr16
 $shell ${srccom}/gentvals.sh $target sys ${srcroot}/$dir \
 	"syscall.h" 'SYS_[_[:alnum:]]*' "${cpp}"
 
--- gdb_src.orig/sim/common/nltvals.def	2011-05-26 23:50:13.000000000 +0530
+++ ./gdb_src/sim/common/nltvals.def	2012-08-17 15:36:39.000000000 +0530
@@ -218,30 +218,34 @@
 #ifdef sys_defs
 /* from syscall.h */
 /* begin cr16 sys target macros */
- { "SYS_argc", 22 },
- { "SYS_argn", 24 },
- { "SYS_argnlen", 23 },
- { "SYS_argv", 13 },
- { "SYS_argvlen", 12 },
- { "SYS_chdir", 14 },
- { "SYS_chmod", 16 },
- { "SYS_close", 3 },
- { "SYS_exit", 1 },
- { "SYS_fstat", 10 },
- { "SYS_getpid", 8 },
- { "SYS_gettimeofday", 19 },
- { "SYS_kill", 9 },
- { "SYS_link", 21 },
- { "SYS_lseek", 6 },
- { "SYS_open", 2 },
- { "SYS_read", 4 },
- { "SYS_reconfig", 25 },
- { "SYS_stat", 15 },
- { "SYS_time", 18 },
- { "SYS_times", 20 },
- { "SYS_unlink", 7 },
- { "SYS_utime", 17 },
- { "SYS_write", 5 },
+ { "SYS_ARG", 24 },
+ { "SYS_chdir", 12 },
+ { "SYS_chmod", 15 },
+ { "SYS_chown", 16 },
+ { "SYS_close", 0x402 },
+ { "SYS_create", 8 },
+ { "SYS_execv", 11 },
+ { "SYS_execve", 59 },
+ { "SYS_exit", 0x410 },
+ { "SYS_fork", 2 },
+ { "SYS_fstat", 22 },
+ { "SYS_getpid", 20 },
+ { "SYS_isatty", 21 },
+ { "SYS_kill", 60 },
+ { "SYS_link", 9 },
+ { "SYS_lseek", 0x405 },
+ { "SYS_mknod", 14 },
+ { "SYS_open", 0x401 },
+ { "SYS_pipe", 42 },
+ { "SYS_read", 0x403 },
+ { "SYS_rename", 0x406 },
+ { "SYS_stat", 38 },
+ { "SYS_time", 0x300 },
+ { "SYS_unlink", 0x407 },
+ { "SYS_utime", 201 },
+ { "SYS_wait", 202 },
+ { "SYS_wait4", 7 },
+ { "SYS_write", 0x404 },
 /* end cr16 sys target macros */
 #endif
 #endif
--- gdb_src.orig/sim/cr16/cr16_sim.h	2012-01-04 13:58:07.000000000 +0530
+++ ./gdb_src/sim/cr16/cr16_sim.h	2012-08-24 17:22:24.000000000 +0530
@@ -472,3 +472,9 @@ extern void write_longlong PARAMS ((uint
    PSR is masked for zero bits. */
 
 extern creg_t move_to_cr (int cr, creg_t mask, creg_t val, int psw_hw_p);
+
+#ifndef SIGTRAP
+#define SIGTRAP 5
+#endif
+/* Special purpose trap  */
+#define TRAP_BREAKPOINT 8
--- gdb_src.orig/sim/cr16/interp.c	2012-06-18 05:04:17.000000000 +0530
+++ ./gdb_src/sim/cr16/interp.c	2012-08-17 15:41:35.000000000 +0530
@@ -1192,7 +1192,11 @@ sim_resume (SIM_DESC sd, int step, int s
       iaddr = imem_addr ((uint32)PC);
       if (iaddr == State.mem.fault)
         {
+#ifdef SIGBUS
           State.exception = SIGBUS;
+#else
+          State.exception = SIGSEGV;
+#endif
           break;
         }
  
@@ -1548,6 +1552,11 @@ sim_store_register (sd, rn, memory, leng
   return size;
 }
 
+char **
+sim_complete_command (SIM_DESC sd, char *text, char *word)
+{
+  return NULL;
+}
 
 void
 sim_do_command (sd, cmd)
--- gdb_src.orig/sim/cr16/simops.c	2012-01-04 13:58:07.000000000 +0530
+++ ./gdb_src/sim/cr16/simops.c	2012-08-17 16:34:11.000000000 +0530
@@ -5059,6 +5059,8 @@ OP_14C_14 ()
 void
 OP_C_C ()
 {
+  uint32 tmp;
+  uint16 a;
   trace_input ("excp", OP_CONSTANT4, OP_VOID, OP_VOID);
   switch (OP[0])
     {
@@ -5465,9 +5467,24 @@ OP_C_C ()
 #endif
 	    
 	  default:
+	    a = OP[0];
+	    switch(a)
+	    {
+	  case  TRAP_BREAKPOINT:
+	    State.exception = SIGTRAP;
+	    tmp = (PC);
+	    JMP(tmp);
+	    trace_output_void ();
+	  break;
+	  case  SIGTRAP:  // supervisor call ?
+	    State.exception = SIG_CR16_EXIT;
+	    trace_output_void ();
+	  break;
+	  default:
 	    cr16_callback->error (cr16_callback, "Unknown syscall %d", FUNC);
+	  break;
+	    }
 	  }
-
 	if ((uint16) result == (uint16) -1)
 	  RETERR (cr16_callback->get_errno(cr16_callback));
 	else
diff -uprN gdb_src.orig/opcodes/cr16-dis.c ./gdb_src/opcodes/cr16-dis.c
--- gdb_src.orig/opcodes/cr16-dis.c	2012-05-17 20:43:25.000000000 +0530
+++ ./gdb_src/opcodes/cr16-dis.c	2012-08-17 16:10:44.000000000 +0530
@@ -317,7 +317,9 @@ build_mask (void)
 
 /* Search for a matching opcode. Return 1 for success, 0 for failure.  */
 
-static int
+int match_opcode (void);
+
+int
 match_opcode (void)
 {
   unsigned long mask;
@@ -734,7 +736,9 @@ print_arguments (ins *currentInsn, bfd_v
 
 /* Build the instruction's arguments.  */
 
-static void
+void make_instruction (void);
+
+void
 make_instruction (void)
 {
   int i;
Common subdirectories: gdb_src.orig/gdb/cli and ./gdb_src/gdb/cli
Common subdirectories: gdb_src.orig/gdb/common and ./gdb_src/gdb/common
Common subdirectories: gdb_src.orig/gdb/config and ./gdb_src/gdb/config
diff -upN gdb_src.orig/gdb/configure.tgt ./gdb_src/gdb/configure.tgt
--- gdb_src.orig/gdb/configure.tgt	2012-08-02 01:18:44.000000000 +0530
+++ ./gdb_src/gdb/configure.tgt	2012-08-17 16:01:37.000000000 +0530
@@ -116,6 +116,13 @@ bfin-*-*)
 	gdb_sim=../sim/bfin/libsim.a
 	;;
 
+cr16*-*-*)
+	# Target: CR16 processor
+	gdb_target_obs="cr16-tdep.o"
+	gdb_sim=../sim/cr16/libsim.a
+	build_gdbserver=yes
+	;;
+
 cris*)
 	# Target: CRIS
 	gdb_target_obs="cris-tdep.o solib-svr4.o"
Common subdirectories: gdb_src.orig/gdb/contrib and ./gdb_src/gdb/contrib
diff -upN gdb_src.orig/gdb/cr16-tdep.c ./gdb_src/gdb/cr16-tdep.c
--- gdb_src.orig/gdb/cr16-tdep.c	1970-01-01 05:30:00.000000000 +0530
+++ ./gdb_src/gdb/cr16-tdep.c	2012-08-27 10:10:22.000000000 +0530
@@ -0,0 +1,891 @@
+/* Target-dependent code for the Sitel CR16 for GDB, the GNU debugger.
+ 
+   Copyright (C) 2012 Free Software Foundation, Inc.
+ 
+   Contributed by KPIT Cummins Infosystems Limited.
+   This file is part of GDB.
+
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of the GNU General Public License as published by
+  the Free Software Foundation; either version 3 of the License, or
+  (at your option) any later version.
+ 
+  This program is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License for more details.
+ 
+  You should have received a copy of the GNU General Public License
+  along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+#include "defs.h"
+#include "arch-utils.h"
+#include "prologue-value.h"
+#include "target.h"
+#include "regcache.h"
+#include "opcode/cr16.h"
+#include "dis-asm.h"
+#include "gdbtypes.h"
+#include "frame.h"
+#include "frame-unwind.h"
+#include "frame-base.h"
+#include "value.h"
+#include "gdbcore.h"
+#include "dwarf2-frame.h"
+#include "gdb/sim-cr16.h"
+#include "elf/cr16.h"
+#include "elf-bfd.h"
+
+typedef unsigned short wordU;
+extern wordU words[3];
+extern ULONGLONG allWords;
+extern ins currInsn;
+
+/* Architecture specific data.  */
+struct gdbarch_tdep
+{
+  /* The ELF header flags specify the multilib used.  */
+  int elf_flags;
+};
+
+/* Certain important register numbers.  */
+enum
+{
+  CR16_R0_REGNUM = 0,
+  CR16_R7_REGNUM = 7,
+  CR16_R12_REGNUM = 12,
+  CR16_FP_REGNUM = 13,
+  CR16_RA_REGNUM = 14,
+  CR16_SP_REGNUM = 15,
+  CR16_PC_REGNUM = 16,
+  CR16_NUM_REGS = 22
+};
+
+/* This structure holds the results of a prologue analysis.  */
+struct cr16_prologue
+{
+  /* The offset from the frame base to the stack pointer --- always
+     zero or negative.
+
+     Calling this a "size" is a bit misleading, but given that the
+     stack grows downwards, using offsets for everything keeps one
+     from going completely sign-crazy: you never change anything's
+     sign for an ADD instruction; always change the second operand's
+     sign for a SUB instruction; and everything takes care of
+     itself.  */
+  int frame_size;
+
+  /* Non-zero if this function has initialized the frame pointer from
+     the stack pointer, zero otherwise.  */
+  int has_frame_ptr;
+
+  /* If has_frame_ptr is non-zero, this is the offset from the frame
+     base to where the frame pointer points.  This is always zero or
+     negative.  */
+  int frame_ptr_offset;
+
+  /* The address of the first instruction at which the frame has been
+     set up and the arguments are where the debug info says they are
+     --- as best as we can tell.  */
+  CORE_ADDR prologue_end;
+
+  /* reg_offset[R] is the offset from the CFA at which register R is
+     saved, or 1 if register R has not been saved.  (Real values are
+     always zero or negative.)  */
+  int reg_offset[CR16_NUM_REGS];
+};
+
+/* Implement the "register_name" gdbarch method.  */
+static const char *
+cr16_register_name (struct gdbarch *gdbarch, int regnr)
+{
+  static const char *const reg_names[] = {
+    "r0",
+    "r1",
+    "r2",
+    "r3",
+    "r4",
+    "r5",
+    "r6",
+    "r7",
+    "r8",
+    "r9",
+    "r10",
+    "r11",
+    "r12",
+    "r13",
+    "ra",
+    "sp",
+    "pc",
+    "isp",
+    "usp",
+    "intbase",
+    "psr",
+    "cfg"
+  };
+
+  return reg_names[regnr];
+}
+
+/* Implement the "register_type" gdbarch method.  */
+static struct type *
+cr16_register_type (struct gdbarch *gdbarch, int reg_nr)
+{
+  switch (reg_nr)
+    {
+    case CR16_PC_REGNUM:	/* Note:PC in CR16 is of 24 bits */
+      return builtin_type (gdbarch)->builtin_func_ptr;
+
+    case CR16_RA_REGNUM:	/* Return address reg */
+      return builtin_type (gdbarch)->builtin_data_ptr;
+      break;
+
+    case CR16_FP_REGNUM:	/*Frame Pointer reg */
+    case CR16_SP_REGNUM:	/*Stack Pointer reg */
+      return builtin_type (gdbarch)->builtin_data_ptr;
+      break;
+
+    case SIM_CR16_ISP_REGNUM:
+    case SIM_CR16_USP_REGNUM:
+    case SIM_CR16_INTBASE_REGNUM:
+      return builtin_type (gdbarch)->builtin_int32;
+      break;
+
+    case SIM_CR16_PSR_REGNUM:
+    case SIM_CR16_CFG_REGNUM:
+      return builtin_type (gdbarch)->builtin_uint32;
+      break;
+
+    case SIM_CR16_R0_REGNUM:
+    case SIM_CR16_R1_REGNUM:
+    case SIM_CR16_R2_REGNUM:
+    case SIM_CR16_R3_REGNUM:
+    case SIM_CR16_R4_REGNUM:
+    case SIM_CR16_R5_REGNUM:
+    case SIM_CR16_R6_REGNUM:
+    case SIM_CR16_R7_REGNUM:
+    case SIM_CR16_R8_REGNUM:
+    case SIM_CR16_R9_REGNUM:
+    case SIM_CR16_R10_REGNUM:
+    case SIM_CR16_R11_REGNUM:
+      return builtin_type (gdbarch)->builtin_int16;
+      break;
+
+    case SIM_CR16_R12_REGNUM:
+      return builtin_type (gdbarch)->builtin_int32;
+      break;
+
+    default:
+      printf
+	("\nRegister Type not supported\nFunction : cr16_register_type\n");
+      return 0;
+      break;
+    }
+}
+
+/* Function for finding saved registers in a 'struct pv_area'; this
+   function is passed to pv_area_scan.
+ 
+   If VALUE is a saved register, ADDR says it was saved at a constant
+   offset from the frame base, and SIZE indicates that the whole
+   register was saved, record its offset.  */
+static void
+check_for_saved (void *result_untyped, pv_t addr, CORE_ADDR size, pv_t value)
+{
+  struct cr16_prologue *result = (struct cr16_prologue *) result_untyped;
+
+  if (value.kind == pvk_register
+      && value.k == 0
+      && pv_is_register (addr, CR16_SP_REGNUM)
+      && size == register_size (target_gdbarch, value.reg))
+    result->reg_offset[value.reg] = addr.k;
+}
+
+/* Define a "handle" struct for fetching the next opcode.  */
+struct cr16_get_opcode_byte_handle
+{
+  CORE_ADDR pc;
+};
+
+/* Use functions from opcodes/cr16-dis.c by making them non-static*/
+extern void make_instruction (void);
+extern int match_opcode (void);
+extern void get_words_at_PC (bfd_vma memaddr, struct disassemble_info *info);
+
+/* Analyze a prologue starting at START_PC, going no further than
+   LIMIT_PC.  Fill in RESULT as appropriate.  */
+static void
+cr16_analyze_prologue (CORE_ADDR start_pc,
+		       CORE_ADDR limit_pc, struct cr16_prologue *result)
+{
+  CORE_ADDR pc, next_pc;
+  gdb_byte buf[6];
+  char insn_byte1, insn_byte2;
+  int rn;
+  int length;
+  pv_t reg[CR16_NUM_REGS];
+  struct pv_area *stack;
+  struct cleanup *back_to;
+  CORE_ADDR after_last_frame_setup_insn = start_pc;
+  int is_decoded;               /* Nonzero means instruction has a match.  */
+
+  memset (result, 0, sizeof (*result));
+
+  for (rn = 0; rn < CR16_NUM_REGS; rn++)
+    {
+      reg[rn] = pv_register (rn, 0);
+      result->reg_offset[rn] = 1;
+    }
+
+  stack = make_pv_area (CR16_SP_REGNUM, gdbarch_addr_bit (target_gdbarch));
+  back_to = make_cleanup_free_pv_area (stack);
+
+  pc = start_pc;
+  while (pc < limit_pc)
+    {
+      target_read_memory (pc, buf, 6);	// read 6 bytes, max 48 bit opcode
+      words[0] = buf[1] << 8 | buf[0];
+      words[1] = buf[3] << 8 | buf[2];
+      words[2] = buf[5] << 8 | buf[4];
+      allWords =
+	((ULONGLONG) words[0] << 32) + ((unsigned long) words[1] << 16) +
+	words[2];
+
+      /* Find a matching opcode in table.  */
+      is_decoded = match_opcode ();
+      make_instruction ();
+      length = currInsn.size;
+      next_pc = pc + length;
+      insn_byte1 = (words[0] >> 8) & 0xFF;
+
+      if (insn_byte1 == 0x01)	// PUSH
+	{
+	  int r1, r2;
+	  int r;
+	  insn_byte2 = words[0];
+
+	  if (insn_byte2 & 0x80)	// Save RA reg
+	    {
+	      reg[CR16_SP_REGNUM] = pv_add_constant (reg[CR16_SP_REGNUM], -4);
+	      pv_area_store (stack, reg[CR16_SP_REGNUM], 4,
+			     reg[CR16_RA_REGNUM]);
+	    }
+
+	  r1 = insn_byte2 & 0x0F;	// Start Register
+	  r2 = ((insn_byte2 & 0x70) >> 4);	//3 bit imm count
+	  r2 = r2 + r1 + 1;	// 3 bit count is 1 to 8
+
+	  for (r = r1; r < r2; r++)
+	    {
+	      if (r >= CR16_R12_REGNUM)
+		{
+		  reg[CR16_SP_REGNUM] =
+		    pv_add_constant (reg[CR16_SP_REGNUM], -4);
+		  pv_area_store (stack, reg[CR16_SP_REGNUM], 4, reg[r]);
+		  r++;
+		}
+	      else
+		{
+		  reg[CR16_SP_REGNUM] =
+		    pv_add_constant (reg[CR16_SP_REGNUM], -2);
+		  pv_area_store (stack, reg[CR16_SP_REGNUM], 2, reg[r]);
+		}
+	    }
+	  after_last_frame_setup_insn = next_pc;
+	}
+
+      else if (insn_byte1 == 0x60)	// Add constant to SP
+	{
+	  int rdst;
+	  signed short addend;
+	  insn_byte2 = words[0];
+	  rdst = insn_byte2 & 0x0F;	// mask upper nibble 
+	  if (rdst == CR16_SP_REGNUM)	// adding to SP?
+	    {
+	      if (length == 2)
+		{
+		  addend = (insn_byte2 & 0xF0) >> 4;	// use upper nibble
+		  reg[rdst] = pv_add_constant (reg[rdst], addend);
+		}
+	      if (length == 4)
+		{
+		  addend = words[1];
+		  reg[rdst] = pv_add_constant (reg[rdst], addend);
+		}
+	      after_last_frame_setup_insn = next_pc;
+	    }
+	}
+      else if (insn_byte1 == 0x55)	// MOVD
+	{
+	  int rdst, rsrc;
+	  insn_byte2 = words[0];
+	  rsrc = (insn_byte2 & 0xF0) >> 4;
+	  rdst = (insn_byte2 & 0x0F);
+	  reg[rdst] = reg[rsrc];
+	  if (rsrc == CR16_SP_REGNUM && rdst == CR16_FP_REGNUM)
+	    after_last_frame_setup_insn = next_pc;
+	}
+      else if (((insn_byte1 >> 4) & 0x0F) == 0xd)	// mask of lower nibble
+	{
+	  /* This moves an argument register to the stack.  Don't
+	     record it, but allow it to be a part of the prologue.  */
+	  after_last_frame_setup_insn = next_pc;
+	}
+      else
+	{
+	  break;		/* Terminate the prologue scan.  */
+	}
+
+      pc = next_pc;
+    }
+
+  /* Is the frame size (offset, really) a known constant?  */
+  if (pv_is_register (reg[CR16_SP_REGNUM], CR16_SP_REGNUM))
+    result->frame_size = reg[CR16_SP_REGNUM].k;
+
+  /* Was the frame pointer initialized?  */
+  if (pv_is_register (reg[CR16_FP_REGNUM], CR16_SP_REGNUM))
+    {
+      result->has_frame_ptr = 1;
+      result->frame_ptr_offset = reg[CR16_FP_REGNUM].k;
+    }
+
+  /* Record where all the registers were saved.  */
+  pv_area_scan (stack, check_for_saved, (void *) result);
+
+  result->prologue_end = after_last_frame_setup_insn;
+  do_cleanups (back_to);
+}
+
+
+/* Implement the "skip_prologue" gdbarch method.  */
+static CORE_ADDR
+cr16_skip_prologue (struct gdbarch *gdbarch, CORE_ADDR pc)
+{
+  const char *name;
+  CORE_ADDR func_addr, func_end;
+  struct cr16_prologue p;
+
+  /* Try to find the extent of the function that contains PC.  */
+  if (!find_pc_partial_function (pc, &name, &func_addr, &func_end))
+    return pc;
+
+  cr16_analyze_prologue (pc, func_end, &p);
+  return p.prologue_end;
+}
+
+/* Given a frame described by THIS_FRAME, decode the prologue of its
+   associated function if there is not cache entry as specified by
+   THIS_PROLOGUE_CACHE.  Save the decoded prologue in the cache and
+   return that struct as the value of this function.  */
+static struct cr16_prologue *
+cr16_analyze_frame_prologue (struct frame_info *this_frame,
+			     void **this_prologue_cache)
+{
+  if (!*this_prologue_cache)
+    {
+      CORE_ADDR func_start, stop_addr;
+
+      *this_prologue_cache = FRAME_OBSTACK_ZALLOC (struct cr16_prologue);
+
+      func_start = get_frame_func (this_frame);
+      stop_addr = get_frame_pc (this_frame);
+
+      /* If we couldn't find any function containing the PC, then
+         just initialize the prologue cache, but don't do anything.  */
+      if (!func_start)
+	stop_addr = func_start;
+
+      cr16_analyze_prologue (func_start, stop_addr, *this_prologue_cache);
+    }
+
+  return *this_prologue_cache;
+}
+
+/* Given the next frame and a prologue cache, return this frame's
+   base.  */
+static CORE_ADDR
+cr16_frame_base (struct frame_info *this_frame, void **this_prologue_cache)
+{
+  struct cr16_prologue *p
+    = cr16_analyze_frame_prologue (this_frame, this_prologue_cache);
+
+  /* In functions that use alloca, the distance between the stack
+     pointer and the frame base varies dynamically, so we can't use
+     the SP plus static information like prologue analysis to find the
+     frame base.  However, such functions must have a frame pointer,
+     to be able to restore the SP on exit.  So whenever we do have a
+     frame pointer, use that to find the base.  */
+  if (p->has_frame_ptr)
+    {
+      CORE_ADDR fp = get_frame_register_unsigned (this_frame, CR16_FP_REGNUM);
+      return fp - p->frame_ptr_offset;
+    }
+  else
+    {
+      CORE_ADDR sp = get_frame_register_unsigned (this_frame, CR16_SP_REGNUM);
+      return sp - p->frame_size;
+    }
+}
+
+/* Implement the "frame_this_id" method for unwinding frames.  */
+static void
+cr16_frame_this_id (struct frame_info *this_frame,
+		    void **this_prologue_cache, struct frame_id *this_id)
+{
+  *this_id =
+    frame_id_build (cr16_frame_base (this_frame, this_prologue_cache),
+		    get_frame_func (this_frame));
+}
+
+static struct value *
+cr16_frame_prev_register (struct frame_info *this_frame,
+			  void **this_prologue_cache, int regnum)
+{
+  struct cr16_prologue *p =
+    cr16_analyze_frame_prologue (this_frame, this_prologue_cache);
+  CORE_ADDR frame_base = cr16_frame_base (this_frame, this_prologue_cache);
+  int reg_size = register_size (get_frame_arch (this_frame), regnum);
+  ULONGEST ra_prev;
+
+  if (regnum == CR16_SP_REGNUM)
+    return frame_unwind_got_constant (this_frame, regnum, frame_base);
+
+  /* The call instruction has saved the return address on the RA register,
+     CR16_R13_REGNUM. So, we need not adjust anything directly. We will 
+     analyze prologue as this RA register is pushed onto stack for further
+     leaf function calls to work */
+  else if (regnum == CR16_PC_REGNUM)
+    {
+      ra_prev = frame_unwind_register_unsigned (this_frame, CR16_RA_REGNUM);
+      ra_prev = ra_prev << 1;
+      return frame_unwind_got_constant (this_frame, CR16_PC_REGNUM, ra_prev);
+    }
+
+  /* If prologue analysis says we saved this register somewhere,
+     return a description of the stack slot holding it.  */
+  else if (p->reg_offset[regnum] != 1)
+    {
+      return frame_unwind_got_memory (this_frame, regnum,
+				      frame_base + p->reg_offset[regnum]);
+    }
+
+  /* Otherwise, presume we haven't changed the value of this
+     register, and get it from the next frame.  */
+  else
+    {
+      return frame_unwind_got_register (this_frame, regnum, regnum);
+    }
+}
+
+static const struct frame_unwind cr16_frame_unwind = {
+  NORMAL_FRAME,
+  default_frame_unwind_stop_reason,
+  cr16_frame_this_id,
+  cr16_frame_prev_register,
+  NULL,
+  default_frame_sniffer
+};
+
+/* Implement the "unwind_pc" gdbarch method.  */
+static CORE_ADDR
+cr16_unwind_pc (struct gdbarch *gdbarch, struct frame_info *this_frame)
+{
+  ULONGEST pc;
+
+  pc = frame_unwind_register_unsigned (this_frame, CR16_PC_REGNUM);
+  return pc;
+}
+
+/* Implement the "unwind_sp" gdbarch method.  */
+static CORE_ADDR
+cr16_unwind_sp (struct gdbarch *gdbarch, struct frame_info *this_frame)
+{
+  ULONGEST sp;
+
+  sp = frame_unwind_register_unsigned (this_frame, CR16_SP_REGNUM);
+  return sp;
+}
+
+/* Implement the "dummy_id" gdbarch method.  */
+static struct frame_id
+cr16_dummy_id (struct gdbarch *gdbarch, struct frame_info *this_frame)
+{
+  return
+    frame_id_build (get_frame_register_unsigned (this_frame, CR16_SP_REGNUM),
+		    get_frame_pc (this_frame));
+}
+
+/* Implement the "push_dummy_call" gdbarch method.  */
+static CORE_ADDR
+cr16_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
+		      struct regcache *regcache, CORE_ADDR bp_addr, int nargs,
+		      struct value **args, CORE_ADDR sp, int struct_return,
+		      CORE_ADDR struct_addr)
+{
+  enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
+  int write_pass;
+  int sp_off = 0;
+  CORE_ADDR cfa;
+  int num_register_candidate_args;
+
+  struct type *func_type = value_type (function);
+
+  /* Dereference function pointer types.  */
+  while (TYPE_CODE (func_type) == TYPE_CODE_PTR)
+    func_type = TYPE_TARGET_TYPE (func_type);
+
+  /* The end result had better be a function or a method.  */
+  gdb_assert (TYPE_CODE (func_type) == TYPE_CODE_FUNC
+	      || TYPE_CODE (func_type) == TYPE_CODE_METHOD);
+
+  /* Functions with a variable number of arguments have all of their
+     variable arguments and the last non-variable argument passed
+     on the stack.
+
+     Otherwise, we can pass up to four arguments on the stack.
+
+     Once computed, we leave this value alone.  I.e. we don't update
+     it in case of a struct return going in a register or an argument
+     requiring multiple registers, etc.  We rely instead on the value
+     of the ``arg_reg'' variable to get these other details correct.  */
+
+  if (TYPE_VARARGS (func_type))
+    num_register_candidate_args = TYPE_NFIELDS (func_type) - 1;
+  else
+    num_register_candidate_args = 4;
+
+  /* We make two passes; the first does the stack allocation,
+     the second actually stores the arguments.  */
+  for (write_pass = 0; write_pass <= 1; write_pass++)
+    {
+      int i;
+      int arg_reg = CR16_R0_REGNUM;
+
+      if (write_pass)
+	sp = align_down (sp - sp_off, 4);
+      sp_off = 0;
+
+      if (struct_return)
+	{
+	  struct type *return_type = TYPE_TARGET_TYPE (func_type);
+
+	  gdb_assert (TYPE_CODE (return_type) == TYPE_CODE_STRUCT
+		      || TYPE_CODE (func_type) == TYPE_CODE_UNION);
+
+	  if (TYPE_LENGTH (return_type) > 16
+	      || TYPE_LENGTH (return_type) % 4 != 0)
+	    {
+	      if (write_pass)
+		regcache_cooked_write_unsigned (regcache, CR16_R12_REGNUM,
+						struct_addr);
+	    }
+	}
+
+      /* Push the arguments.  */
+      for (i = 0; i < nargs; i++)
+	{
+	  struct value *arg = args[i];
+	  const gdb_byte *arg_bits = value_contents_all (arg);
+	  struct type *arg_type = check_typedef (value_type (arg));
+	  ULONGEST arg_size = TYPE_LENGTH (arg_type);
+
+	  if (i == 0 && struct_addr != 0 && !struct_return
+	      && TYPE_CODE (arg_type) == TYPE_CODE_PTR
+	      && extract_unsigned_integer (arg_bits, 4,
+					   byte_order) == struct_addr)
+	    {
+	      /* This argument represents the address at which C++ (and
+	         possibly other languages) store their return value.
+	         Put this value in R15.  */
+	      if (write_pass)
+		regcache_cooked_write_unsigned (regcache, CR16_R12_REGNUM,
+						struct_addr);
+	    }
+	  else if (TYPE_CODE (arg_type) != TYPE_CODE_STRUCT
+		   && TYPE_CODE (arg_type) != TYPE_CODE_UNION)
+	    {
+	      /* Argument is a scalar.  */
+	      if (arg_size == 8)
+		{
+		  if (i < num_register_candidate_args
+		      && arg_reg <= CR16_R7_REGNUM - 1)
+		    {
+		      /* If argument registers are going to be used to pass
+		         an 8 byte scalar, the ABI specifies that two registers
+		         must be available.  */
+		      if (write_pass)
+			{
+			  regcache_cooked_write_unsigned (regcache, arg_reg,
+							  extract_unsigned_integer
+							  (arg_bits, 4,
+							   byte_order));
+			  regcache_cooked_write_unsigned (regcache,
+							  arg_reg + 1,
+							  extract_unsigned_integer
+							  (arg_bits + 4, 4,
+							   byte_order));
+			}
+		      arg_reg += 2;
+		    }
+		  else
+		    {
+		      sp_off = align_up (sp_off, 4);
+		      /* Otherwise, pass the 8 byte scalar on the stack.  */
+		      if (write_pass)
+			write_memory (sp + sp_off, arg_bits, 8);
+		      sp_off += 8;
+		    }
+		}
+	      else
+		{
+		  ULONGEST u;
+
+		  gdb_assert (arg_size <= 4);
+
+		  u =
+		    extract_unsigned_integer (arg_bits, arg_size, byte_order);
+
+		  if (i < num_register_candidate_args
+		      && arg_reg <= CR16_R7_REGNUM)
+		    {
+		      if (write_pass)
+			regcache_cooked_write_unsigned (regcache, arg_reg, u);
+		      arg_reg += 1;
+		    }
+		  else
+		    {
+		      int p_arg_size = 4;
+
+		      if (TYPE_PROTOTYPED (func_type)
+			  && i < TYPE_NFIELDS (func_type))
+			{
+			  struct type *p_arg_type =
+			    TYPE_FIELD_TYPE (func_type, i);
+			  p_arg_size = TYPE_LENGTH (p_arg_type);
+			}
+
+		      sp_off = align_up (sp_off, p_arg_size);
+
+		      if (write_pass)
+			write_memory_unsigned_integer (sp + sp_off,
+						       p_arg_size, byte_order,
+						       u);
+		      sp_off += p_arg_size;
+		    }
+		}
+	    }
+	  else
+	    {
+	      /* Argument is a struct or union.  Pass as much of the struct
+	         in registers, if possible.  Pass the rest on the stack.  */
+	      while (arg_size > 0)
+		{
+		  if (i < num_register_candidate_args
+		      && arg_reg <= CR16_R7_REGNUM
+		      && arg_size <= 4 * (CR16_R7_REGNUM - arg_reg + 1)
+		      && arg_size % 4 == 0)
+		    {
+		      int len = min (arg_size, 4);
+
+		      if (write_pass)
+			regcache_cooked_write_unsigned (regcache, arg_reg,
+							extract_unsigned_integer
+							(arg_bits, len,
+							 byte_order));
+		      arg_bits += len;
+		      arg_size -= len;
+		      arg_reg++;
+		    }
+		  else
+		    {
+		      sp_off = align_up (sp_off, 4);
+		      if (write_pass)
+			write_memory (sp + sp_off, arg_bits, arg_size);
+		      sp_off += align_up (arg_size, 4);
+		      arg_size = 0;
+		    }
+		}
+	    }
+	}
+    }
+
+  /* Keep track of the stack address prior to pushing the return address.
+     This is the value that we'll return.  */
+  cfa = sp;
+
+  /* Push the return address.  */
+  sp = sp - 4;
+  write_memory_unsigned_integer (sp, 4, byte_order, bp_addr);
+
+  /* Update the stack pointer.  */
+  regcache_cooked_write_unsigned (regcache, CR16_SP_REGNUM, sp);
+
+  return cfa;
+}
+
+/* Implement the "return_value" gdbarch method.  */
+static enum return_value_convention
+cr16_return_value (struct gdbarch *gdbarch,
+		   struct type *func_type,
+		   struct type *valtype,
+		   struct regcache *regcache,
+		   gdb_byte * readbuf, const gdb_byte * writebuf)
+{
+  enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
+  ULONGEST valtype_len = TYPE_LENGTH (valtype);
+
+  if (TYPE_LENGTH (valtype) > 16
+      || ((TYPE_CODE (valtype) == TYPE_CODE_STRUCT
+	   || TYPE_CODE (valtype) == TYPE_CODE_UNION)
+	  && TYPE_LENGTH (valtype) % 4 != 0))
+    return RETURN_VALUE_STRUCT_CONVENTION;
+
+  if (readbuf)
+    {
+      ULONGEST u;
+      int argreg = CR16_R0_REGNUM;
+      int offset = 0;
+
+      while (valtype_len > 0)
+	{
+	  int len = min (valtype_len, 4);
+
+	  regcache_cooked_read_unsigned (regcache, argreg, &u);
+	  store_unsigned_integer (readbuf + offset, len, byte_order, u);
+	  valtype_len -= len;
+	  offset += len;
+	  argreg++;
+	}
+    }
+
+  if (writebuf)
+    {
+      ULONGEST u;
+      int argreg = CR16_R0_REGNUM;
+      int offset = 0;
+
+      while (valtype_len > 0)
+	{
+	  int len = min (valtype_len, 4);
+
+	  u = extract_unsigned_integer (writebuf + offset, len, byte_order);
+	  regcache_cooked_write_unsigned (regcache, argreg, u);
+	  valtype_len -= len;
+	  offset += len;
+	  argreg++;
+	}
+    }
+
+  return RETURN_VALUE_REGISTER_CONVENTION;
+}
+
+/* Implement the "breakpoint_from_pc" gdbarch method.  */
+static const gdb_byte *
+cr16_breakpoint_from_pc (struct gdbarch *gdbarch, CORE_ADDR * pcptr,
+			 int *lenptr)
+{
+  /* opcode of excp instruction for bpt is 0x00C8, however for uclinux we use
+     excp flg (0x00C7) to insert a breakpoint. The excp bpt requires external
+     hardware support for breakpoints to work on CR16 target. Software based
+     breakpoints are implemented in the kernel using excp flg and tested on
+     the SC14452 target. Use 0x00C7 with gdbserver/kernel and 0x00C8 for sim/ELF
+     We represent the breakpoint in little endian format since CR16 supports 
+     only little endian.
+   */
+  static gdb_byte breakpoint[] = { 0xC8, 0x00 };
+  *lenptr = sizeof breakpoint;
+  return breakpoint;
+}
+
+
+
+/* Allocate and initialize a gdbarch object.  */
+static struct gdbarch *
+cr16_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
+{
+  struct gdbarch *gdbarch;
+  struct gdbarch_tdep *tdep;
+  int elf_flags;
+
+  /* Extract the elf_flags if available.  */
+  if (info.abfd != NULL
+      && bfd_get_flavour (info.abfd) == bfd_target_elf_flavour)
+    elf_flags = elf_elfheader (info.abfd)->e_flags;
+  else
+    elf_flags = 0;
+
+  /* Try to find the architecture in the list of already defined
+     architectures.  */
+  for (arches = gdbarch_list_lookup_by_info (arches, &info);
+       arches != NULL;
+       arches = gdbarch_list_lookup_by_info (arches->next, &info))
+    {
+      if (gdbarch_tdep (arches->gdbarch)->elf_flags != elf_flags)
+	continue;
+
+      return arches->gdbarch;
+    }
+  /* None found, create a new architecture from the information
+     provided.  */
+  tdep = (struct gdbarch_tdep *) xmalloc (sizeof (struct gdbarch_tdep));
+  gdbarch = gdbarch_alloc (&info, tdep);
+  tdep->elf_flags = elf_flags;
+
+  set_gdbarch_num_regs (gdbarch, CR16_NUM_REGS);
+  set_gdbarch_num_pseudo_regs (gdbarch, 0);
+  set_gdbarch_register_name (gdbarch, cr16_register_name);
+  set_gdbarch_register_type (gdbarch, cr16_register_type);
+  set_gdbarch_pc_regnum (gdbarch, CR16_PC_REGNUM);
+  set_gdbarch_sp_regnum (gdbarch, CR16_SP_REGNUM);
+  set_gdbarch_inner_than (gdbarch, core_addr_lessthan);
+  set_gdbarch_decr_pc_after_break (gdbarch, 2);
+  set_gdbarch_breakpoint_from_pc (gdbarch, cr16_breakpoint_from_pc);
+  set_gdbarch_skip_prologue (gdbarch, cr16_skip_prologue);
+
+  /* Passing NULL  values in the following two functions
+     for the time being, to fix later  */
+  set_gdbarch_print_insn (gdbarch, print_insn_cr16);
+  set_gdbarch_unwind_pc (gdbarch, cr16_unwind_pc);
+  set_gdbarch_unwind_sp (gdbarch, cr16_unwind_sp);
+
+  /* Methods for saving / extracting a dummy frame's ID.
+     The ID's stack address must match the SP value returned by
+     PUSH_DUMMY_CALL, and saved by generic_save_dummy_frame_tos.  */
+  set_gdbarch_dummy_id (gdbarch, cr16_dummy_id);
+  set_gdbarch_push_dummy_call (gdbarch, cr16_push_dummy_call);
+  /* Target builtin data types.  */
+  set_gdbarch_char_signed (gdbarch, 8);
+  set_gdbarch_short_bit (gdbarch, 16);
+
+  /* if we don't pass the option -mint32
+     To fix : add if else case depending on the option passed,
+     sp that we can have int size as 16 or 32 bits both. */
+  set_gdbarch_int_bit (gdbarch, 16);
+  set_gdbarch_long_bit (gdbarch, 32);
+  set_gdbarch_long_long_bit (gdbarch, 64);
+  set_gdbarch_float_bit (gdbarch, 32);
+
+  set_gdbarch_ptr_bit (gdbarch, 32);
+  set_gdbarch_float_format (gdbarch, floatformats_ieee_single);
+  set_gdbarch_double_bit (gdbarch, 64);
+  set_gdbarch_long_double_bit (gdbarch, 64);
+  set_gdbarch_double_format (gdbarch, floatformats_ieee_double);
+  set_gdbarch_long_double_format (gdbarch, floatformats_ieee_double);
+
+  frame_unwind_append_unwinder (gdbarch, &cr16_frame_unwind);
+  set_gdbarch_return_value (gdbarch, cr16_return_value);
+
+  return gdbarch;
+
+}
+
+/* -Wmissing-prototypes */
+extern initialize_file_ftype _initialize_cr16_tdep;
+
+/* Register the above initialization routine.  */
+void
+_initialize_cr16_tdep (void)
+{
+  register_gdbarch_init (bfd_arch_cr16, cr16_gdbarch_init);
+}
diff -upN gdb_src.orig/configure ./gdb_src/configure
--- gdb_src.orig/configure	2012-06-28 17:20:52.000000000 +0530
+++ ./gdb_src/configure	2012-08-17 16:56:10.000000000 +0530
@@ -3447,7 +3447,7 @@ case "${target}" in
     noconfigdirs="$noconfigdirs target-libgloss gdb"
     ;;
   cr16-*-*)
-    noconfigdirs="$noconfigdirs gdb"
+    noconfigdirs="$noconfigdirs target-libgloss"
     ;;
   d10v-*-*)
     noconfigdirs="$noconfigdirs target-libgloss"
diff -upN gdb_src.orig/configure.ac ./gdb_src/configure.ac
--- gdb_src.orig/configure.ac	2012-06-28 17:20:52.000000000 +0530
+++ ./gdb_src/configure.ac	2012-08-17 16:56:17.000000000 +0530
@@ -873,7 +873,7 @@ case "${target}" in
     noconfigdirs="$noconfigdirs target-libgloss gdb"
     ;;
   cr16-*-*)
-    noconfigdirs="$noconfigdirs gdb"
+    noconfigdirs="$noconfigdirs target-libgloss"
     ;;
   d10v-*-*)
     noconfigdirs="$noconfigdirs target-libgloss"
Common subdirectories: gdb_src.orig/cpu and ./gdb_src/cpu
Common subdirectories: gdb_src.orig/CVS and ./gdb_src/CVS
Common subdirectories: gdb_src.orig/etc and ./gdb_src/etc
Common subdirectories: gdb_src.orig/gdb and ./gdb_src/gdb
Common subdirectories: gdb_src.orig/include and ./gdb_src/include
Common subdirectories: gdb_src.orig/intl and ./gdb_src/intl
Common subdirectories: gdb_src.orig/libdecnumber and ./gdb_src/libdecnumber
Common subdirectories: gdb_src.orig/libiberty and ./gdb_src/libiberty
Common subdirectories: gdb_src.orig/opcodes and ./gdb_src/opcodes
Common subdirectories: gdb_src.orig/readline and ./gdb_src/readline
Common subdirectories: gdb_src.orig/sim and ./gdb_src/sim
Common subdirectories: gdb_src.orig/texinfo and ./gdb_src/texinfo

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [RFC] New GDB Port CR16
  2012-08-27  6:37 [RFC] New GDB Port CR16 Kaushik Phatak
@ 2012-08-27 16:21 ` Yao Qi
  2012-08-28 14:47   ` Kaushik Phatak
  2012-08-27 21:10 ` Mike Frysinger
  2012-08-28 16:24 ` Pedro Alves
  2 siblings, 1 reply; 18+ messages in thread
From: Yao Qi @ 2012-08-27 16:21 UTC (permalink / raw)
  To: Kaushik Phatak; +Cc: gdb-patches

Kaushik,
Thanks for the patch.  I didn't read your patch in details yet, but have 
some comments on patch submission at first.

On 08/27/2012 02:36 PM, Kaushik Phatak wrote:
> 2012-08-24 Kaushik Phatak<kaushik.phatak@kpitcummins.com>
>
> gdb/ChangeLog:
> 	* configure.tgt (cr16-*-elf): New target.
> 	* cr16-tdep.c: New file.
>
> sim/cr16/ChangeLog:
> 	* interp.c (sim_complete_command): New stub function.
> 	* cr16_sim.h : Add defines for TRAP handling
> 	* simops.c: Breakpoint handling code
>
> opcodes/ChangeLog:
> 	* cr16-dis.c (match_opcode): Remove static function
> 	declaration.
> 	(make_instruction): Likewise.
>

Changes under opcodes dir should be submitted to binutils@sourceware.org.


> diff -upN gdb_src.orig/configure ./gdb_src/configure
> --- gdb_src.orig/configure	2012-06-28 17:20:52.000000000 +0530
> +++ ./gdb_src/configure	2012-08-17 16:56:10.000000000 +0530
> @@ -3447,7 +3447,7 @@ case "${target}" in
>       noconfigdirs="$noconfigdirs target-libgloss gdb"
>       ;;
>     cr16-*-*)
> -    noconfigdirs="$noconfigdirs gdb"
> +    noconfigdirs="$noconfigdirs target-libgloss"
>       ;;
>     d10v-*-*)
>       noconfigdirs="$noconfigdirs target-libgloss"
> diff -upN gdb_src.orig/configure.ac ./gdb_src/configure.ac
> --- gdb_src.orig/configure.ac	2012-06-28 17:20:52.000000000 +0530
> +++ ./gdb_src/configure.ac	2012-08-17 16:56:17.000000000 +0530
> @@ -873,7 +873,7 @@ case "${target}" in
>       noconfigdirs="$noconfigdirs target-libgloss gdb"
>       ;;
>     cr16-*-*)
> -    noconfigdirs="$noconfigdirs gdb"
> +    noconfigdirs="$noconfigdirs target-libgloss"
>       ;;
>     d10v-*-*)
>       noconfigdirs="$noconfigdirs target-libgloss"

The changes for top-level configure stuff should be submitted to 
gcc-patches with changelog entry.  Get it approved, apply it to gcc repo 
once your gdb patch is approved, and finally merge this change from gcc 
to binutils/gdb.  This is what I did for adding new port tic6x last 
year, IIRC.

-- 
Yao


^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [RFC] New GDB Port CR16
  2012-08-27  6:37 [RFC] New GDB Port CR16 Kaushik Phatak
  2012-08-27 16:21 ` Yao Qi
@ 2012-08-27 21:10 ` Mike Frysinger
  2012-08-28 16:24 ` Pedro Alves
  2 siblings, 0 replies; 18+ messages in thread
From: Mike Frysinger @ 2012-08-27 21:10 UTC (permalink / raw)
  To: gdb-patches; +Cc: Kaushik Phatak

[-- Attachment #1: Type: Text/Plain, Size: 2246 bytes --]

On Monday 27 August 2012 02:36:15 Kaushik Phatak wrote:
> Please find attached a patch that adds support for the National
> Semiconductor CR16 architecture to GDB. The sim patch is already present
> in the sources. This patch enhances the sim to support breakpoints for sim
> based debugging.

this one diff has multiple unrelated changes.  might be nice if you were to 
split them up and commit them separately.  the sim/common/ changes could be 
merged now for example.  the other cr16 sim changes should be split up from 
the gdb changes so that they may be merged independently.

> --- gdb_src.orig/sim/common/gennltvals.sh
> +++ ./gdb_src/sim/common/gennltvals.sh
> 
> --- gdb_src.orig/sim/common/nltvals.def
> +++ ./gdb_src/sim/common/nltvals.def
> 
> --- gdb_src.orig/sim/cr16/cr16_sim.h
> +++ ./gdb_src/sim/cr16/cr16_sim.h
> 
> --- gdb_src.orig/sim/cr16/interp.c
> +++ ./gdb_src/sim/cr16/interp.c

changes to these files look fine

> --- gdb_src.orig/sim/cr16/simops.c
> +++ ./gdb_src/sim/cr16/simops.c
> void
> OP_C_C ()

unrelated, but that should be "(void)".  i imagine this sim port probably has 
a bunch of those bugs lurking though.

> @@ -5465,9 +5467,24 @@ OP_C_C ()
>  #endif
>  	    
>  	  default:
> +	    a = OP[0];
> +	    switch(a)
> +	    {
> +	  case  TRAP_BREAKPOINT:
> +	    State.exception = SIGTRAP;
> +	    tmp = (PC);
> +	    JMP(tmp);
> +	    trace_output_void ();
> +	  break;
> +	  case  SIGTRAP:  // supervisor call ?
> +	    State.exception = SIG_CR16_EXIT;
> +	    trace_output_void ();
> +	  break;
> +	  default:
>  	    cr16_callback->error (cr16_callback, "Unknown syscall %d", FUNC);
> +	  break;
> +	    }

pretty sure the indentation here is incorrect.  the case statements inside 
this new switch statement are not indented far enough.

also, please do not use C++ style comments //.  use /* */ instead.

> --- gdb_src.orig/opcodes/cr16-dis.c
> +++ ./gdb_src/opcodes/cr16-dis.c
>  
> -static int
> +int match_opcode (void);
> +
> +int
>  match_opcode (void)

this new local prototype makes no sense.  just delete it.

> -static void
> +void make_instruction (void);
> +
> +void
>  make_instruction (void)

same here
-mike

[-- Attachment #2: This is a digitally signed message part. --]
[-- Type: application/pgp-signature, Size: 836 bytes --]

^ permalink raw reply	[flat|nested] 18+ messages in thread

* RE: [RFC] New GDB Port CR16
  2012-08-27 16:21 ` Yao Qi
@ 2012-08-28 14:47   ` Kaushik Phatak
  2012-08-29 22:14     ` Mike Frysinger
  0 siblings, 1 reply; 18+ messages in thread
From: Kaushik Phatak @ 2012-08-28 14:47 UTC (permalink / raw)
  To: gdb-patches; +Cc: Yao Qi, Mike Frysinger

[-- Attachment #1: Type: text/plain, Size: 1633 bytes --]

Hi Mike,Yao,
Thanks for all your comments. 

> might be nice if you were to split them up and commit them separately
I have attached an updated patch with purely sim port related changes.
The patch changes the following files in gdb-sim
/sim/common/gennltvals.sh
/sim/common/nltvals.def
/sim/cr16/cr16_sim.h
/sim/cr16/interp.c
/sim/cr16/simops.c

I have tried to address the other points as follows,

> but that should be "(void)".  i imagine this sim port probably has 
> a bunch of those bugs lurking though.
Yes, but I have not tinkered with this as yet.

> pretty sure the indentation here is incorrect. 
My mistake. This was a switch inside a switch and my case statements were
aligned with the first level case statements. This is now fixed.

> please do not use C++ style comments
This is now fixed.

> this new local prototype makes no sense.  just delete it.
OK. I will create separate binutils patch with these changes and submit it
to binutils at sourceware dot org as per Yao Qi's suggestion.

> The changes for top-level configure stuff should be submitted to 
> gcc-patches with changelog entry.
Thanks Yao for these patch submission tips. 


2012-08-28 Kaushik Phatak  <kaushik.phatak@kpitcummins.com>

sim/common/
	* gennltvals.sh: Use libgloss/syscall.h for cr16.
	* nltvals.def: Regenerate.
sim/cr16/ChangeLog:
	* interp.c (sim_complete_command): New stub function.
	* cr16_sim.h : Add defines for TRAP handling.
	* simops.c: Breakpoint handling code.

Thanks & Best Regards,
Kaushik
kaushik.phatak@kpitcummins.com
KPIT Cummins Infosystems Ltd
www.kpitcummins.com


[-- Attachment #2: cr16_sim.diff --]
[-- Type: application/octet-stream, Size: 4001 bytes --]

--- gdb_src.orig/sim/common/gennltvals.sh	2012-03-19 10:24:48.000000000 +0530
+++ ./gdb_src/sim/common/gennltvals.sh	2012-08-17 15:35:15.000000000 +0530
@@ -41,7 +41,7 @@ $shell ${srccom}/gentvals.sh $target sys
 # OBSOLETE $shell ${srccom}/gentvals.sh $target sys ${srcroot}/$dir \
 # OBSOLETE 	"syscall.h" 'SYS_[_[:alnum:]]*' "${cpp}"
 
-dir=libgloss target=cr16
+dir=libgloss/cr16/sys target=cr16
 $shell ${srccom}/gentvals.sh $target sys ${srcroot}/$dir \
 	"syscall.h" 'SYS_[_[:alnum:]]*' "${cpp}"
 
--- gdb_src.orig/sim/common/nltvals.def	2011-05-26 23:50:13.000000000 +0530
+++ ./gdb_src/sim/common/nltvals.def	2012-08-17 15:36:39.000000000 +0530
@@ -218,30 +218,34 @@
 #ifdef sys_defs
 /* from syscall.h */
 /* begin cr16 sys target macros */
- { "SYS_argc", 22 },
- { "SYS_argn", 24 },
- { "SYS_argnlen", 23 },
- { "SYS_argv", 13 },
- { "SYS_argvlen", 12 },
- { "SYS_chdir", 14 },
- { "SYS_chmod", 16 },
- { "SYS_close", 3 },
- { "SYS_exit", 1 },
- { "SYS_fstat", 10 },
- { "SYS_getpid", 8 },
- { "SYS_gettimeofday", 19 },
- { "SYS_kill", 9 },
- { "SYS_link", 21 },
- { "SYS_lseek", 6 },
- { "SYS_open", 2 },
- { "SYS_read", 4 },
- { "SYS_reconfig", 25 },
- { "SYS_stat", 15 },
- { "SYS_time", 18 },
- { "SYS_times", 20 },
- { "SYS_unlink", 7 },
- { "SYS_utime", 17 },
- { "SYS_write", 5 },
+ { "SYS_ARG", 24 },
+ { "SYS_chdir", 12 },
+ { "SYS_chmod", 15 },
+ { "SYS_chown", 16 },
+ { "SYS_close", 0x402 },
+ { "SYS_create", 8 },
+ { "SYS_execv", 11 },
+ { "SYS_execve", 59 },
+ { "SYS_exit", 0x410 },
+ { "SYS_fork", 2 },
+ { "SYS_fstat", 22 },
+ { "SYS_getpid", 20 },
+ { "SYS_isatty", 21 },
+ { "SYS_kill", 60 },
+ { "SYS_link", 9 },
+ { "SYS_lseek", 0x405 },
+ { "SYS_mknod", 14 },
+ { "SYS_open", 0x401 },
+ { "SYS_pipe", 42 },
+ { "SYS_read", 0x403 },
+ { "SYS_rename", 0x406 },
+ { "SYS_stat", 38 },
+ { "SYS_time", 0x300 },
+ { "SYS_unlink", 0x407 },
+ { "SYS_utime", 201 },
+ { "SYS_wait", 202 },
+ { "SYS_wait4", 7 },
+ { "SYS_write", 0x404 },
 /* end cr16 sys target macros */
 #endif
 #endif
--- gdb_src.orig/sim/cr16/cr16_sim.h	2012-01-04 13:58:07.000000000 +0530
+++ ./gdb_src/sim/cr16/cr16_sim.h	2012-08-24 17:22:24.000000000 +0530
@@ -472,3 +472,9 @@ extern void write_longlong PARAMS ((uint
    PSR is masked for zero bits. */
 
 extern creg_t move_to_cr (int cr, creg_t mask, creg_t val, int psw_hw_p);
+
+#ifndef SIGTRAP
+#define SIGTRAP 5
+#endif
+/* Special purpose trap  */
+#define TRAP_BREAKPOINT 8
--- gdb_src.orig/sim/cr16/interp.c	2012-06-18 05:04:17.000000000 +0530
+++ ./gdb_src/sim/cr16/interp.c	2012-08-17 15:41:35.000000000 +0530
@@ -1192,7 +1192,11 @@ sim_resume (SIM_DESC sd, int step, int s
       iaddr = imem_addr ((uint32)PC);
       if (iaddr == State.mem.fault)
         {
+#ifdef SIGBUS
           State.exception = SIGBUS;
+#else
+          State.exception = SIGSEGV;
+#endif
           break;
         }
  
@@ -1548,6 +1552,11 @@ sim_store_register (sd, rn, memory, leng
   return size;
 }
 
+char **
+sim_complete_command (SIM_DESC sd, char *text, char *word)
+{
+  return NULL;
+}
 
 void
 sim_do_command (sd, cmd)
--- gdb_src.orig/sim/cr16/simops.c	2012-01-04 13:58:07.000000000 +0530
+++ ./gdb_src/sim/cr16/simops.c	2012-08-28 17:57:49.000000000 +0530
@@ -5059,6 +5059,8 @@ OP_14C_14 ()
 void
 OP_C_C ()
 {
+  uint32 tmp;
+  uint16 a;
   trace_input ("excp", OP_CONSTANT4, OP_VOID, OP_VOID);
   switch (OP[0])
     {
@@ -5465,9 +5467,24 @@ OP_C_C ()
 #endif
 	    
 	  default:
-	    cr16_callback->error (cr16_callback, "Unknown syscall %d", FUNC);
+	    a = OP[0];
+	    switch(a)
+	    {
+	      case  TRAP_BREAKPOINT:
+		State.exception = SIGTRAP;
+		tmp = (PC);
+		JMP(tmp);
+		trace_output_void ();
+		break;
+	      case  SIGTRAP:  /* supervisor call ? */
+		State.exception = SIG_CR16_EXIT;
+		trace_output_void ();
+		break;
+	      default:
+		cr16_callback->error (cr16_callback, "Unknown syscall %d", FUNC);
+		break;
+	    }
 	  }
-
 	if ((uint16) result == (uint16) -1)
 	  RETERR (cr16_callback->get_errno(cr16_callback));
 	else

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [RFC] New GDB Port CR16
  2012-08-27  6:37 [RFC] New GDB Port CR16 Kaushik Phatak
  2012-08-27 16:21 ` Yao Qi
  2012-08-27 21:10 ` Mike Frysinger
@ 2012-08-28 16:24 ` Pedro Alves
  2012-08-30  4:49   ` Kaushik Phatak
  2 siblings, 1 reply; 18+ messages in thread
From: Pedro Alves @ 2012-08-28 16:24 UTC (permalink / raw)
  To: Kaushik Phatak; +Cc: gdb-patches

On 08/27/2012 07:36 AM, Kaushik Phatak wrote:
> +cr16*-*-*)
> +	# Target: CR16 processor
> +	gdb_target_obs="cr16-tdep.o"
> +	gdb_sim=../sim/cr16/libsim.a
> +	build_gdbserver=yes

I didn't see a gdbserver port in the patch.  In any case, setting "build_gdbserver" means
that on a native cr16 gdb build, the build system will descend into gdbserver, and build
it as well, automatically.  I don't think you'll be able to gdb build natively on
cr16 (at least with this patch set).

> +	;;
> +
>  cris*)
-- 
Pedro Alves


^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [RFC] New GDB Port CR16
  2012-08-28 14:47   ` Kaushik Phatak
@ 2012-08-29 22:14     ` Mike Frysinger
  2012-08-30  5:23       ` Kaushik Phatak
  0 siblings, 1 reply; 18+ messages in thread
From: Mike Frysinger @ 2012-08-29 22:14 UTC (permalink / raw)
  To: Kaushik Phatak; +Cc: gdb-patches, Yao Qi

On Tue, Aug 28, 2012 at 10:45 AM, Kaushik Phatak wrote:
> +	    switch(a)

needs a space there:
switch (a)

> +	      case  TRAP_BREAKPOINT:
> +	      case  SIGTRAP:  /* supervisor call ? */

just one space after "case"

also, the comment should have two spaces before the */:
/* Supervisor call ?  */

otherwise looks fine
-mike


^ permalink raw reply	[flat|nested] 18+ messages in thread

* RE: [RFC] New GDB Port CR16
  2012-08-28 16:24 ` Pedro Alves
@ 2012-08-30  4:49   ` Kaushik Phatak
  2012-08-30  5:14     ` Yao Qi
  0 siblings, 1 reply; 18+ messages in thread
From: Kaushik Phatak @ 2012-08-30  4:49 UTC (permalink / raw)
  To: Pedro Alves; +Cc: gdb-patches

Hi,
Thanks for looking at the patch.

> I didn't see a gdbserver port in the patch.
Yes, that is correct. We do have a gdbserver port ready in the pipeline. 
I plan to post that later along with a tdep file customized for uclinux
platform. The current cr16-tdep.c works well with the existing simulator.

I have another cr16-tdep.c file (might call it cr16-linux-tdep.c) that would 
work with the kernel port. They have slightly different register set and use 
different breakpoint instruction. I am still not sure how to go about that part.

Right now, as per Mike's suggestion I will get the sim related changes approved
and checked in, then go step by step from there.

Best Regards,
Kaushik
KPIT Cummins Infosystems Ltd
www.kpitcummins.com

-----Original Message-----
From: Pedro Alves [mailto:palves@redhat.com] 
Sent: 28 August 2012 20:59
To: Kaushik Phatak
Cc: gdb-patches@sourceware.org
Subject: Re: [RFC] New GDB Port CR16

On 08/27/2012 07:36 AM, Kaushik Phatak wrote:
> +cr16*-*-*)
> +	# Target: CR16 processor
> +	gdb_target_obs="cr16-tdep.o"
> +	gdb_sim=../sim/cr16/libsim.a
> +	build_gdbserver=yes

I didn't see a gdbserver port in the patch.  In any case, setting "build_gdbserver" means
that on a native cr16 gdb build, the build system will descend into gdbserver, and build
it as well, automatically.  I don't think you'll be able to gdb build natively on
cr16 (at least with this patch set).

> +	;;
> +
>  cris*)
-- 
Pedro Alves



^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [RFC] New GDB Port CR16
  2012-08-30  4:49   ` Kaushik Phatak
@ 2012-08-30  5:14     ` Yao Qi
  0 siblings, 0 replies; 18+ messages in thread
From: Yao Qi @ 2012-08-30  5:14 UTC (permalink / raw)
  To: Kaushik Phatak; +Cc: Pedro Alves, gdb-patches

On 08/30/2012 12:49 PM, Kaushik Phatak wrote:
> I have another cr16-tdep.c file (might call it cr16-linux-tdep.c) that would
> work with the kernel port. They have slightly different register set and use
> different breakpoint instruction. I am still not sure how to go about that part.

We've handled different breakpoint instructions in other ports, and you 
can follow the similar way for your port.

   You need a 'struct gdbarch_tdep' defined in ${arch}-tdep.h, with a 
field 'breakpoint', for example, which points to the exact breakpoint 
instruction you'll use.

   Set field 'breakpoint' in 
${arch}-linux-tdep.c:${arch}_uclinux_init_abi according to some ELF 
header or attributes.

   Return correct breakpoint instruction in ${arch}_breakpoint_from_pc.

Set ${arch} to 'tic6x' above, you'll see the example in details.

With respect to different register sets, you may have to use 'target 
description' feature in GDB.

-- 
Yao


^ permalink raw reply	[flat|nested] 18+ messages in thread

* RE: [RFC] New GDB Port CR16
  2012-08-29 22:14     ` Mike Frysinger
@ 2012-08-30  5:23       ` Kaushik Phatak
  2012-08-30  6:10         ` Mike Frysinger
  2012-09-03  9:31         ` Pedro Alves
  0 siblings, 2 replies; 18+ messages in thread
From: Kaushik Phatak @ 2012-08-30  5:23 UTC (permalink / raw)
  To: Mike Frysinger; +Cc: gdb-patches, Yao Qi

[-- Attachment #1: Type: text/plain, Size: 502 bytes --]

Hi Mike,
Thanks for detailed review.

> needs a space there: > +	    switch(a)
> just one space after "case"
> also, the comment should have two spaces before the */:

I have fixed the above three issues in the attached patch.
If everything else looks OK, could you please check these in for me as I
do not have write privileges to the repository?

I will create a separate thread for cr16 gdb related patches.

Best Regards,
Kaushik
KPIT Cummins Infosystems Ltd
www.kpitcummins.com


[-- Attachment #2: cr16_sim.diff --]
[-- Type: application/octet-stream, Size: 4001 bytes --]

--- gdb_src.orig/sim/common/gennltvals.sh	2012-03-19 10:24:48.000000000 +0530
+++ ./gdb_src/sim/common/gennltvals.sh	2012-08-17 15:35:15.000000000 +0530
@@ -41,7 +41,7 @@ $shell ${srccom}/gentvals.sh $target sys
 # OBSOLETE $shell ${srccom}/gentvals.sh $target sys ${srcroot}/$dir \
 # OBSOLETE 	"syscall.h" 'SYS_[_[:alnum:]]*' "${cpp}"
 
-dir=libgloss target=cr16
+dir=libgloss/cr16/sys target=cr16
 $shell ${srccom}/gentvals.sh $target sys ${srcroot}/$dir \
 	"syscall.h" 'SYS_[_[:alnum:]]*' "${cpp}"
 
--- gdb_src.orig/sim/common/nltvals.def	2011-05-26 23:50:13.000000000 +0530
+++ ./gdb_src/sim/common/nltvals.def	2012-08-17 15:36:39.000000000 +0530
@@ -218,30 +218,34 @@
 #ifdef sys_defs
 /* from syscall.h */
 /* begin cr16 sys target macros */
- { "SYS_argc", 22 },
- { "SYS_argn", 24 },
- { "SYS_argnlen", 23 },
- { "SYS_argv", 13 },
- { "SYS_argvlen", 12 },
- { "SYS_chdir", 14 },
- { "SYS_chmod", 16 },
- { "SYS_close", 3 },
- { "SYS_exit", 1 },
- { "SYS_fstat", 10 },
- { "SYS_getpid", 8 },
- { "SYS_gettimeofday", 19 },
- { "SYS_kill", 9 },
- { "SYS_link", 21 },
- { "SYS_lseek", 6 },
- { "SYS_open", 2 },
- { "SYS_read", 4 },
- { "SYS_reconfig", 25 },
- { "SYS_stat", 15 },
- { "SYS_time", 18 },
- { "SYS_times", 20 },
- { "SYS_unlink", 7 },
- { "SYS_utime", 17 },
- { "SYS_write", 5 },
+ { "SYS_ARG", 24 },
+ { "SYS_chdir", 12 },
+ { "SYS_chmod", 15 },
+ { "SYS_chown", 16 },
+ { "SYS_close", 0x402 },
+ { "SYS_create", 8 },
+ { "SYS_execv", 11 },
+ { "SYS_execve", 59 },
+ { "SYS_exit", 0x410 },
+ { "SYS_fork", 2 },
+ { "SYS_fstat", 22 },
+ { "SYS_getpid", 20 },
+ { "SYS_isatty", 21 },
+ { "SYS_kill", 60 },
+ { "SYS_link", 9 },
+ { "SYS_lseek", 0x405 },
+ { "SYS_mknod", 14 },
+ { "SYS_open", 0x401 },
+ { "SYS_pipe", 42 },
+ { "SYS_read", 0x403 },
+ { "SYS_rename", 0x406 },
+ { "SYS_stat", 38 },
+ { "SYS_time", 0x300 },
+ { "SYS_unlink", 0x407 },
+ { "SYS_utime", 201 },
+ { "SYS_wait", 202 },
+ { "SYS_wait4", 7 },
+ { "SYS_write", 0x404 },
 /* end cr16 sys target macros */
 #endif
 #endif
--- gdb_src.orig/sim/cr16/cr16_sim.h	2012-01-04 13:58:07.000000000 +0530
+++ ./gdb_src/sim/cr16/cr16_sim.h	2012-08-24 17:22:24.000000000 +0530
@@ -472,3 +472,9 @@ extern void write_longlong PARAMS ((uint
    PSR is masked for zero bits. */
 
 extern creg_t move_to_cr (int cr, creg_t mask, creg_t val, int psw_hw_p);
+
+#ifndef SIGTRAP
+#define SIGTRAP 5
+#endif
+/* Special purpose trap  */
+#define TRAP_BREAKPOINT 8
--- gdb_src.orig/sim/cr16/interp.c	2012-06-18 05:04:17.000000000 +0530
+++ ./gdb_src/sim/cr16/interp.c	2012-08-17 15:41:35.000000000 +0530
@@ -1192,7 +1192,11 @@ sim_resume (SIM_DESC sd, int step, int s
       iaddr = imem_addr ((uint32)PC);
       if (iaddr == State.mem.fault)
         {
+#ifdef SIGBUS
           State.exception = SIGBUS;
+#else
+          State.exception = SIGSEGV;
+#endif
           break;
         }
  
@@ -1548,6 +1552,11 @@ sim_store_register (sd, rn, memory, leng
   return size;
 }
 
+char **
+sim_complete_command (SIM_DESC sd, char *text, char *word)
+{
+  return NULL;
+}
 
 void
 sim_do_command (sd, cmd)
--- gdb_src.orig/sim/cr16/simops.c	2012-01-04 13:58:07.000000000 +0530
+++ ./gdb_src/sim/cr16/simops.c	2012-08-30 10:29:28.000000000 +0530
@@ -5059,6 +5059,8 @@ OP_14C_14 ()
 void
 OP_C_C ()
 {
+  uint32 tmp;
+  uint16 a;
   trace_input ("excp", OP_CONSTANT4, OP_VOID, OP_VOID);
   switch (OP[0])
     {
@@ -5465,9 +5467,24 @@ OP_C_C ()
 #endif
 	    
 	  default:
-	    cr16_callback->error (cr16_callback, "Unknown syscall %d", FUNC);
+	    a = OP[0];
+	    switch (a)
+	    {
+	      case TRAP_BREAKPOINT:
+		State.exception = SIGTRAP;
+		tmp = (PC);
+		JMP(tmp);
+		trace_output_void ();
+		break;
+	      case SIGTRAP:  /* supervisor call ?  */
+		State.exception = SIG_CR16_EXIT;
+		trace_output_void ();
+		break;
+	      default:
+		cr16_callback->error (cr16_callback, "Unknown syscall %d", FUNC);
+		break;
+	    }
 	  }
-
 	if ((uint16) result == (uint16) -1)
 	  RETERR (cr16_callback->get_errno(cr16_callback));
 	else

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [RFC] New GDB Port CR16
  2012-08-30  5:23       ` Kaushik Phatak
@ 2012-08-30  6:10         ` Mike Frysinger
  2012-09-03  9:31         ` Pedro Alves
  1 sibling, 0 replies; 18+ messages in thread
From: Mike Frysinger @ 2012-08-30  6:10 UTC (permalink / raw)
  To: Kaushik Phatak; +Cc: gdb-patches, Yao Qi

On Thu, Aug 30, 2012 at 1:23 AM, Kaushik Phatak wrote:
>> needs a space there: > +          switch(a)
>> just one space after "case"
>> also, the comment should have two spaces before the */:
>
> I have fixed the above three issues in the attached patch.
> If everything else looks OK, could you please check these in for me as I
> do not have write privileges to the repository?

i've committed the sim/cr16/ changes.  i can't commit the sim/common/
changes yet because the libgloss header hasn't been merged yet.
-mike


^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [RFC] New GDB Port CR16
  2012-08-30  5:23       ` Kaushik Phatak
  2012-08-30  6:10         ` Mike Frysinger
@ 2012-09-03  9:31         ` Pedro Alves
  2012-09-04  3:52           ` Mike Frysinger
  1 sibling, 1 reply; 18+ messages in thread
From: Pedro Alves @ 2012-09-03  9:31 UTC (permalink / raw)
  To: Kaushik Phatak; +Cc: Mike Frysinger, gdb-patches, Yao Qi

On 08/30/2012 06:23 AM, Kaushik Phatak wrote:
> --- gdb_src.orig/sim/cr16/interp.c	2012-06-18 05:04:17.000000000 +0530
> +++ ./gdb_src/sim/cr16/interp.c	2012-08-17 15:41:35.000000000 +0530
> @@ -1192,7 +1192,11 @@ sim_resume (SIM_DESC sd, int step, int s
>        iaddr = imem_addr ((uint32)PC);
>        if (iaddr == State.mem.fault)
>          {
> +#ifdef SIGBUS
>            State.exception = SIGBUS;
> +#else
> +          State.exception = SIGSEGV;
> +#endif
>            break;
>          }

Is this dependency on host signal defines what is done on other sims?
It rings alarm bells to me that a sim's behavior would depend on
which host it runs on.

-- 
Pedro Alves


^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [RFC] New GDB Port CR16
  2012-09-03  9:31         ` Pedro Alves
@ 2012-09-04  3:52           ` Mike Frysinger
  2012-09-04  6:50             ` Kaushik Phatak
  0 siblings, 1 reply; 18+ messages in thread
From: Mike Frysinger @ 2012-09-04  3:52 UTC (permalink / raw)
  To: Pedro Alves; +Cc: Kaushik Phatak, gdb-patches, Yao Qi

On Mon, Sep 3, 2012 at 5:30 AM, Pedro Alves wrote:
> On 08/30/2012 06:23 AM, Kaushik Phatak wrote:
>> --- gdb_src.orig/sim/cr16/interp.c    2012-06-18 05:04:17.000000000 +0530
>> +++ ./gdb_src/sim/cr16/interp.c       2012-08-17 15:41:35.000000000 +0530
>> @@ -1192,7 +1192,11 @@ sim_resume (SIM_DESC sd, int step, int s
>>        iaddr = imem_addr ((uint32)PC);
>>        if (iaddr == State.mem.fault)
>>          {
>> +#ifdef SIGBUS
>>            State.exception = SIGBUS;
>> +#else
>> +          State.exception = SIGSEGV;
>> +#endif
>>            break;
>>          }
>
> Is this dependency on host signal defines what is done on other sims?
> It rings alarm bells to me that a sim's behavior would depend on
> which host it runs on.

there is cruft like this in other sims.  it probably would be
desirable to clean it up.
-mike


^ permalink raw reply	[flat|nested] 18+ messages in thread

* RE: [RFC] New GDB Port CR16
  2012-09-04  3:52           ` Mike Frysinger
@ 2012-09-04  6:50             ` Kaushik Phatak
  2012-09-07 17:47               ` Pedro Alves
  2012-09-11 19:00               ` Mike Frysinger
  0 siblings, 2 replies; 18+ messages in thread
From: Kaushik Phatak @ 2012-09-04  6:50 UTC (permalink / raw)
  To: Mike Frysinger; +Cc: gdb-patches, Yao Qi, Pedro Alves

Hi Pedro,
> Is this dependency on host signal defines what is done on other sims?
This was probably added when breakpoint support was being added to this
sim port with reference of the SH port I believe.

> there is cruft like this in other sims.  it probably would be desirable to clean it up.
Yes Mike, I agree. I have tested it without this hunk and breakpoints seem to
work as expected. Please see below the patch that reverts this in sim.
I am rearranging some code to create cr16-linux-tdep.c file as suggested by Yao
and will post the gdb related patches soon.
Thanks!


2012-09-03 Kaushik Phatak<kaushik.phatak@kpitcummins.com>

sim/cr16/ChangeLog:
	* interp.c: Clean SIGBUS related macro.

--- gdb_src.orig/sim/cr16/interp.c      2012-09-04 12:08:34.000000000 +0530
+++ gdb_src/src/sim/cr16/interp.c       2012-06-18 05:04:17.000000000 +0530
@@ -1192,11 +1192,7 @@ sim_resume (SIM_DESC sd, int step, int s
       iaddr = imem_addr ((uint32)PC);
       if (iaddr == State.mem.fault)
         {
-#ifdef SIGBUS
           State.exception = SIGBUS;
-#else
-          State.exception = SIGSEGV;
-#endif
           break;
         }



^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [RFC] New GDB Port CR16
  2012-09-04  6:50             ` Kaushik Phatak
@ 2012-09-07 17:47               ` Pedro Alves
  2012-09-11 13:16                 ` Kaushik Phatak
  2012-09-11 19:00               ` Mike Frysinger
  1 sibling, 1 reply; 18+ messages in thread
From: Pedro Alves @ 2012-09-07 17:47 UTC (permalink / raw)
  To: Kaushik Phatak; +Cc: Mike Frysinger, gdb-patches, Yao Qi, Pedro Alves

On 09/04/2012 07:49 AM, Kaushik Phatak wrote:
> Hi Pedro,
>> Is this dependency on host signal defines what is done on other sims?
> This was probably added when breakpoint support was being added to this
> sim port with reference of the SH port I believe.
> 
>> there is cruft like this in other sims.  it probably would be desirable to clean it up.
> Yes Mike, I agree. I have tested it without this hunk and breakpoints seem to
> work as expected. Please see below the patch that reverts this in sim.
> I am rearranging some code to create cr16-linux-tdep.c file as suggested by Yao
> and will post the gdb related patches soon.
> Thanks!
> 
> 
> 2012-09-03 Kaushik Phatak<kaushik.phatak@kpitcummins.com>
> 
> sim/cr16/ChangeLog:
> 	* interp.c: Clean SIGBUS related macro.
> 
> --- gdb_src.orig/sim/cr16/interp.c      2012-09-04 12:08:34.000000000 +0530
> +++ gdb_src/src/sim/cr16/interp.c       2012-06-18 05:04:17.000000000 +0530
> @@ -1192,11 +1192,7 @@ sim_resume (SIM_DESC sd, int step, int s
>        iaddr = imem_addr ((uint32)PC);
>        if (iaddr == State.mem.fault)
>          {
> -#ifdef SIGBUS
>            State.exception = SIGBUS;
> -#else
> -          State.exception = SIGSEGV;
> -#endif
>            break;
>          }

Looks obvious enough to me.

Though, we should really get away with using host signals for this stuff,
using sim/gdb's own signal numbers instead.  For a rainy day, perhaps...

-- 
Pedro Alves


^ permalink raw reply	[flat|nested] 18+ messages in thread

* RE: [RFC] New GDB Port CR16
  2012-09-07 17:47               ` Pedro Alves
@ 2012-09-11 13:16                 ` Kaushik Phatak
  2012-09-11 19:02                   ` Mike Frysinger
  0 siblings, 1 reply; 18+ messages in thread
From: Kaushik Phatak @ 2012-09-11 13:16 UTC (permalink / raw)
  To: gdb-patches; +Cc: Mike Frysinger, Yao Qi, Pedro Alves

[-- Attachment #1: Type: text/plain, Size: 2613 bytes --]

Hi,
Thanks for all your comments till date. I have attached the diffs separately,
though I do plan to do it in different threads soon. I am still trying to clear 
up couple of issues before that. If anybody could give me suggestions on these,
it would be very much appreciated.

1. The elf and uclinux binaries seem to get built after adding their triplets
in configure.tgt, however I am having a hard time getting the cr16-uclinux-gdb
to work with the hardware. On debugging, I found that this binary transmitted 
data during a call to update_address_spaces function called from 
remote_start_remote in remote.c
The additional packet transmitted is as below,
{
Sending packet: $qXfer:auxv:read::0,1000#6b...Packet received: l\000\000\000\000\000\000\000\000
}
After this, the gdbserver communication would either hang, or kernel would crash
and the host would get a timeout. On additional debugging, this packet seemed
to get generated from the call to gdbarch_has_shared_address_space().
Previously, the whole setup has been tested with host side gdb being built
independently with different breakpoint and register set. This method of using
linux-tdep.c seems to be inline with other ports, but maybe I am missing 
something, any pointers?

2. The cr16 target has -fPIC support and the data section is at an offset
to the end of text section. However, the symbol file created only shows me one
segment(0). So, the global data access takes place with offsets calculated with
respect to the start of .text section. This causes all reads to global data
to be incorrect. The attached patch which is a hack to get around 
this:"gdb_core_fpic_suspect.diff" Is there an elegant way to achieve this?

Mike, you had given the below feedback,
http://sourceware.org/ml/gdb-patches/2012-08/msg00819.html
> +int
>  match_opcode (void)
> this new local prototype makes no sense.  just delete it.

When I remove these prototypes, it gives me a warning as follows,
warning: no previous prototype for match_opcode
Our build fails as it treats warnings as error. We can get around that by
using "--disable-werror" I guess. But would this hunk be acceptable as is?

The attached patched are:
cr16_config_toplevel_alpha.diff -> top level changes to be submitted to gcc-patches
cr16_config_tgt_alpha.diff -> configure.tgt changes
cr16_bfd.diff -> bfd level changes to be submitted to binutils
cr16_gdb_alpha.diff -> cr16-tdep and cr16-linux-tdep related patch
gdb_core_fpic_suspect.diff -> The patch in question for -fPIC implementation.


Thanks & Best Regards,
Kaushik Phatak


[-- Attachment #2: cr16_gdb_alpha.diff --]
[-- Type: application/octet-stream, Size: 31611 bytes --]

--- gdb_src.orig/gdb/cr16-linux-tdep.c	1970-01-01 05:30:00.000000000 +0530
+++ ./gdb_src/gdb/cr16-linux-tdep.c	2012-09-04 13:06:03.000000000 +0530
@@ -0,0 +1,64 @@
+/* Target-dependent code for GNU/Linux on Xtensa processors.
+
+   Copyright 2007-2012 Free Software Foundation, Inc.
+
+   Contributed by Kaushik Phatak (kaushik.pahatk@kpitcummins.com)
+   KPIT Cummins Infosystems Limited, Pune India.
+
+   This file is part of GDB.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+#include "defs.h"
+#include "osabi.h"
+#include "linux-tdep.h"
+#include "solib-svr4.h"
+#include "symtab.h"
+#include "cr16-tdep.h"
+
+const gdb_byte breakpoint_uclinux[] = { 0xC7, 0x00 };
+
+
+/* OS specific initialization of gdbarch.  */
+
+static void
+cr16_uclinux_init_abi (struct gdbarch_info info,
+                    struct gdbarch *gdbarch)
+{
+  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+
+  linux_init_abi (info, gdbarch);
+
+  /* The opcode of excp bpt is 0x00C8, however for uclinux we will use the 
+     excp flg (0x00C7) to insert a breakpoint. The excp bpt requires external
+     hardware support for breakpoints to work on CR16 target. Software based
+     breakpoints are implemented in the kernel using excp flg and tested on
+     the SC14452 target. Use 0x00C7 with gdbserver/kernel and 0x00C8 for sim/ELF
+     We represent the breakpoint in little endian format since CR16 supports
+     only little endian.
+   */
+  tdep->breakpoint = breakpoint_uclinux;
+
+}
+/* Provide a prototype to silence -Wmissing-prototypes.  */
+extern initialize_file_ftype _initialize_cr16_linux_tdep;
+
+void
+_initialize_cr16_linux_tdep (void)
+{
+  gdbarch_register_osabi (bfd_arch_cr16, 0, GDB_OSABI_LINUX,
+                          cr16_uclinux_init_abi);
+}
+
+
--- gdb_src.orig/gdb/cr16-tdep.c	1970-01-01 05:30:00.000000000 +0530
+++ ./gdb_src/gdb/cr16-tdep.c	2012-09-07 17:54:10.000000000 +0530
@@ -0,0 +1,929 @@
+/* Target-dependent code for the Sitel CR16 for GDB, the GNU debugger.
+ 
+   Copyright (C) 2012 Free Software Foundation, Inc.
+ 
+   Contributed by Kaushik Phatak (kaushik.pahatk@kpitcummins.com)
+   KPIT Cummins Infosystems Limited, Pune India.
+   This file is part of GDB.
+
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of the GNU General Public License as published by
+  the Free Software Foundation; either version 3 of the License, or
+  (at your option) any later version.
+ 
+  This program is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License for more details.
+ 
+  You should have received a copy of the GNU General Public License
+  along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+#include "defs.h"
+#include "arch-utils.h"
+#include "prologue-value.h"
+#include "target.h"
+#include "regcache.h"
+#include "opcode/cr16.h"
+#include "dis-asm.h"
+#include "gdbtypes.h"
+#include "frame.h"
+#include "frame-unwind.h"
+#include "frame-base.h"
+#include "value.h"
+#include "gdbcore.h"
+#include "dwarf2-frame.h"
+#include "gdb/sim-cr16.h"
+#include "elf/cr16.h"
+#include "elf-bfd.h"
+#include "linux-tdep.h"
+#include "osabi.h"
+#include "cr16-tdep.h"
+
+const gdb_byte breakpoint_elf[] = { 0xC8, 0x00 };
+
+typedef unsigned short wordU;
+extern wordU words[3];
+extern ULONGLONG allWords;
+extern ins currInsn;
+
+/* Certain important register numbers.  */
+enum
+{
+  CR16_R0_REGNUM = 0,
+  CR16_R7_REGNUM = 7,
+  CR16_R12_REGNUM = 12,
+  CR16_FP_REGNUM = 13,
+  CR16_RA_REGNUM = 14,
+  CR16_SP_REGNUM = 15,
+  CR16_PC_REGNUM = 16,
+};
+
+/* This structure holds the results of a prologue analysis.  */
+struct cr16_prologue
+{
+  /* The offset from the frame base to the stack pointer --- always
+     zero or negative.
+
+     Calling this a "size" is a bit misleading, but given that the
+     stack grows downwards, using offsets for everything keeps one
+     from going completely sign-crazy: you never change anything's
+     sign for an ADD instruction; always change the second operand's
+     sign for a SUB instruction; and everything takes care of
+     itself.  */
+  int frame_size;
+
+  /* Non-zero if this function has initialized the frame pointer from
+     the stack pointer, zero otherwise.  */
+  int has_frame_ptr;
+
+  /* If has_frame_ptr is non-zero, this is the offset from the frame
+     base to where the frame pointer points.  This is always zero or
+     negative.  */
+  int frame_ptr_offset;
+
+  /* The address of the first instruction at which the frame has been
+     set up and the arguments are where the debug info says they are
+     --- as best as we can tell.  */
+  CORE_ADDR prologue_end;
+
+  /* reg_offset[R] is the offset from the CFA at which register R is
+     saved, or 1 if register R has not been saved.  (Real values are
+     always zero or negative.)  */
+  int reg_offset[CR16_NUM_REGS];
+};
+
+/* Implement the "register_name" gdbarch method.  */
+static const char *
+cr16_register_name (struct gdbarch *gdbarch, int regnr)
+{
+  static const char *const reg_names[] = {
+    "r0",
+    "r1",
+    "r2",
+    "r3",
+    "r4",
+    "r5",
+    "r6",
+    "r7",
+    "r8",
+    "r9",
+    "r10",
+    "r11",
+    "r12",
+    "r13",
+    "ra",
+    "sp",
+    "pc",
+    "isp",
+    "usp",
+    "intbase",
+    "psr",
+    "cfg"
+  };
+
+  return reg_names[regnr];
+}
+
+static const char *
+cr16_linux_register_name (struct gdbarch *gdbarch, int regnr)
+{
+  static const char *const reg_names[] = {
+    "r0",
+    "r1",
+    "r2",
+    "r3",
+    "r4",
+    "r5",
+    "r6",
+    "r7",
+    "r8",
+    "r9",
+    "r10",
+    "r11",
+    "r12",
+    "r13",
+    "ra",
+    "psr",
+    "pc",
+    "r0r1_orig",
+    "intbase",
+    "usp",
+    "cfg"
+  };
+
+  return reg_names[regnr];
+}
+
+/* Implement the "register_type" gdbarch method.  */
+static struct type *
+cr16_register_type (struct gdbarch *gdbarch, int reg_nr)
+{
+  switch (reg_nr)
+    {
+    case CR16_PC_REGNUM:	/* Note:PC in CR16 is of 24 bits */
+      return builtin_type (gdbarch)->builtin_func_ptr;
+
+    case CR16_RA_REGNUM:	/* Return address reg */
+      return builtin_type (gdbarch)->builtin_data_ptr;
+      break;
+
+    case CR16_FP_REGNUM:	/*Frame Pointer reg */
+    case CR16_SP_REGNUM:	/*Stack Pointer reg */
+      return builtin_type (gdbarch)->builtin_data_ptr;
+      break;
+
+    case SIM_CR16_ISP_REGNUM:
+    case SIM_CR16_USP_REGNUM:
+    case SIM_CR16_INTBASE_REGNUM:
+      return builtin_type (gdbarch)->builtin_int32;
+      break;
+
+    case SIM_CR16_PSR_REGNUM:
+    case SIM_CR16_CFG_REGNUM:
+      return builtin_type (gdbarch)->builtin_uint32;
+      break;
+
+    case SIM_CR16_R0_REGNUM:
+    case SIM_CR16_R1_REGNUM:
+    case SIM_CR16_R2_REGNUM:
+    case SIM_CR16_R3_REGNUM:
+    case SIM_CR16_R4_REGNUM:
+    case SIM_CR16_R5_REGNUM:
+    case SIM_CR16_R6_REGNUM:
+    case SIM_CR16_R7_REGNUM:
+    case SIM_CR16_R8_REGNUM:
+    case SIM_CR16_R9_REGNUM:
+    case SIM_CR16_R10_REGNUM:
+    case SIM_CR16_R11_REGNUM:
+      return builtin_type (gdbarch)->builtin_int16;
+      break;
+
+    case SIM_CR16_R12_REGNUM:
+      return builtin_type (gdbarch)->builtin_int32;
+      break;
+
+    default:
+      printf
+	("\nRegister Type not supported\nFunction : cr16_register_type\n");
+      return 0;
+      break;
+    }
+}
+
+/* Function for finding saved registers in a 'struct pv_area'; this
+   function is passed to pv_area_scan.
+ 
+   If VALUE is a saved register, ADDR says it was saved at a constant
+   offset from the frame base, and SIZE indicates that the whole
+   register was saved, record its offset.  */
+static void
+check_for_saved (void *result_untyped, pv_t addr, CORE_ADDR size, pv_t value)
+{
+  struct cr16_prologue *result = (struct cr16_prologue *) result_untyped;
+
+  if (value.kind == pvk_register
+      && value.k == 0
+      && pv_is_register (addr, CR16_SP_REGNUM)
+      && size == register_size (target_gdbarch, value.reg))
+    result->reg_offset[value.reg] = addr.k;
+}
+
+/* Define a "handle" struct for fetching the next opcode.  */
+struct cr16_get_opcode_byte_handle
+{
+  CORE_ADDR pc;
+};
+
+/* Use functions from opcodes/cr16-dis.c by making them non-static*/
+extern void make_instruction (void);
+extern int match_opcode (void);
+extern void get_words_at_PC (bfd_vma memaddr, struct disassemble_info *info);
+
+/* Analyze a prologue starting at START_PC, going no further than
+   LIMIT_PC.  Fill in RESULT as appropriate.  */
+static void
+cr16_analyze_prologue (CORE_ADDR start_pc,
+		       CORE_ADDR limit_pc, struct cr16_prologue *result)
+{
+  CORE_ADDR pc, next_pc;
+  gdb_byte buf[6];
+  char insn_byte1, insn_byte2;
+  int rn;
+  int length;
+  pv_t reg[CR16_NUM_REGS];
+  struct pv_area *stack;
+  struct cleanup *back_to;
+  CORE_ADDR after_last_frame_setup_insn = start_pc;
+  int is_decoded;               /* Nonzero means instruction has a match.  */
+
+  memset (result, 0, sizeof (*result));
+
+  for (rn = 0; rn < CR16_NUM_REGS; rn++)
+    {
+      reg[rn] = pv_register (rn, 0);
+      result->reg_offset[rn] = 1;
+    }
+
+  stack = make_pv_area (CR16_SP_REGNUM, gdbarch_addr_bit (target_gdbarch));
+  back_to = make_cleanup_free_pv_area (stack);
+
+  pc = start_pc;
+  while (pc < limit_pc)
+    {
+      target_read_memory (pc, buf, 6);	// read 6 bytes, max 48 bit opcode
+      words[0] = buf[1] << 8 | buf[0];
+      words[1] = buf[3] << 8 | buf[2];
+      words[2] = buf[5] << 8 | buf[4];
+      allWords =
+	((ULONGLONG) words[0] << 32) + ((unsigned long) words[1] << 16) +
+	words[2];
+
+      /* Find a matching opcode in table.  */
+      is_decoded = match_opcode ();
+      make_instruction ();
+      length = currInsn.size;
+      next_pc = pc + length;
+      insn_byte1 = (words[0] >> 8) & 0xFF;
+
+      if (insn_byte1 == 0x01)	// PUSH
+	{
+	  int r1, r2;
+	  int r;
+	  insn_byte2 = words[0];
+
+	  if (insn_byte2 & 0x80)	// Save RA reg
+	    {
+	      reg[CR16_SP_REGNUM] = pv_add_constant (reg[CR16_SP_REGNUM], -4);
+	      pv_area_store (stack, reg[CR16_SP_REGNUM], 4,
+			     reg[CR16_RA_REGNUM]);
+	    }
+
+	  r1 = insn_byte2 & 0x0F;	// Start Register
+	  r2 = ((insn_byte2 & 0x70) >> 4);	//3 bit imm count
+	  r2 = r2 + r1 + 1;	// 3 bit count is 1 to 8
+
+	  for (r = r1; r < r2; r++)
+	    {
+	      if (r >= CR16_R12_REGNUM)
+		{
+		  reg[CR16_SP_REGNUM] =
+		    pv_add_constant (reg[CR16_SP_REGNUM], -4);
+		  pv_area_store (stack, reg[CR16_SP_REGNUM], 4, reg[r]);
+		  r++;
+		}
+	      else
+		{
+		  reg[CR16_SP_REGNUM] =
+		    pv_add_constant (reg[CR16_SP_REGNUM], -2);
+		  pv_area_store (stack, reg[CR16_SP_REGNUM], 2, reg[r]);
+		}
+	    }
+	  after_last_frame_setup_insn = next_pc;
+	}
+
+      else if (insn_byte1 == 0x60)	// Add constant to SP
+	{
+	  int rdst;
+	  signed short addend;
+	  insn_byte2 = words[0];
+	  rdst = insn_byte2 & 0x0F;	// mask upper nibble 
+	  if (rdst == CR16_SP_REGNUM)	// adding to SP?
+	    {
+	      if (length == 2)
+		{
+		  addend = (insn_byte2 & 0xF0) >> 4;	// use upper nibble
+		  reg[rdst] = pv_add_constant (reg[rdst], addend);
+		}
+	      if (length == 4)
+		{
+		  addend = words[1];
+		  reg[rdst] = pv_add_constant (reg[rdst], addend);
+		}
+	      after_last_frame_setup_insn = next_pc;
+	    }
+	}
+      else if (insn_byte1 == 0x55)	// MOVD
+	{
+	  int rdst, rsrc;
+	  insn_byte2 = words[0];
+	  rsrc = (insn_byte2 & 0xF0) >> 4;
+	  rdst = (insn_byte2 & 0x0F);
+	  reg[rdst] = reg[rsrc];
+	  if (rsrc == CR16_SP_REGNUM && rdst == CR16_FP_REGNUM)
+	    after_last_frame_setup_insn = next_pc;
+	}
+      else if (((insn_byte1 >> 4) & 0x0F) == 0xd)	// mask of lower nibble
+	{
+	  /* This moves an argument register to the stack.  Don't
+	     record it, but allow it to be a part of the prologue.  */
+	  after_last_frame_setup_insn = next_pc;
+	}
+      else
+	{
+	  break;		/* Terminate the prologue scan.  */
+	}
+
+      pc = next_pc;
+    }
+
+  /* Is the frame size (offset, really) a known constant?  */
+  if (pv_is_register (reg[CR16_SP_REGNUM], CR16_SP_REGNUM))
+    result->frame_size = reg[CR16_SP_REGNUM].k;
+
+  /* Was the frame pointer initialized?  */
+  if (pv_is_register (reg[CR16_FP_REGNUM], CR16_SP_REGNUM))
+    {
+      result->has_frame_ptr = 1;
+      result->frame_ptr_offset = reg[CR16_FP_REGNUM].k;
+    }
+
+  /* Record where all the registers were saved.  */
+  pv_area_scan (stack, check_for_saved, (void *) result);
+
+  result->prologue_end = after_last_frame_setup_insn;
+  do_cleanups (back_to);
+}
+
+
+/* Implement the "skip_prologue" gdbarch method.  */
+static CORE_ADDR
+cr16_skip_prologue (struct gdbarch *gdbarch, CORE_ADDR pc)
+{
+  const char *name;
+  CORE_ADDR func_addr, func_end;
+  struct cr16_prologue p;
+
+  /* Try to find the extent of the function that contains PC.  */
+  if (!find_pc_partial_function (pc, &name, &func_addr, &func_end))
+    return pc;
+
+  cr16_analyze_prologue (pc, func_end, &p);
+  return p.prologue_end;
+}
+
+/* Given a frame described by THIS_FRAME, decode the prologue of its
+   associated function if there is not cache entry as specified by
+   THIS_PROLOGUE_CACHE.  Save the decoded prologue in the cache and
+   return that struct as the value of this function.  */
+static struct cr16_prologue *
+cr16_analyze_frame_prologue (struct frame_info *this_frame,
+			     void **this_prologue_cache)
+{
+  if (!*this_prologue_cache)
+    {
+      CORE_ADDR func_start, stop_addr;
+
+      *this_prologue_cache = FRAME_OBSTACK_ZALLOC (struct cr16_prologue);
+
+      func_start = get_frame_func (this_frame);
+      stop_addr = get_frame_pc (this_frame);
+
+      /* If we couldn't find any function containing the PC, then
+         just initialize the prologue cache, but don't do anything.  */
+      if (!func_start)
+	stop_addr = func_start;
+
+      cr16_analyze_prologue (func_start, stop_addr, *this_prologue_cache);
+    }
+
+  return *this_prologue_cache;
+}
+
+/* Given the next frame and a prologue cache, return this frame's
+   base.  */
+static CORE_ADDR
+cr16_frame_base (struct frame_info *this_frame, void **this_prologue_cache)
+{
+  struct cr16_prologue *p
+    = cr16_analyze_frame_prologue (this_frame, this_prologue_cache);
+
+  /* In functions that use alloca, the distance between the stack
+     pointer and the frame base varies dynamically, so we can't use
+     the SP plus static information like prologue analysis to find the
+     frame base.  However, such functions must have a frame pointer,
+     to be able to restore the SP on exit.  So whenever we do have a
+     frame pointer, use that to find the base.  */
+  if (p->has_frame_ptr)
+    {
+      CORE_ADDR fp = get_frame_register_unsigned (this_frame, CR16_FP_REGNUM);
+      return fp - p->frame_ptr_offset;
+    }
+  else
+    {
+      CORE_ADDR sp = get_frame_register_unsigned (this_frame, CR16_SP_REGNUM);
+      return sp - p->frame_size;
+    }
+}
+
+/* Implement the "frame_this_id" method for unwinding frames.  */
+static void
+cr16_frame_this_id (struct frame_info *this_frame,
+		    void **this_prologue_cache, struct frame_id *this_id)
+{
+  *this_id =
+    frame_id_build (cr16_frame_base (this_frame, this_prologue_cache),
+		    get_frame_func (this_frame));
+}
+
+static struct value *
+cr16_frame_prev_register (struct frame_info *this_frame,
+			  void **this_prologue_cache, int regnum)
+{
+  struct cr16_prologue *p =
+    cr16_analyze_frame_prologue (this_frame, this_prologue_cache);
+  CORE_ADDR frame_base = cr16_frame_base (this_frame, this_prologue_cache);
+  int reg_size = register_size (get_frame_arch (this_frame), regnum);
+  ULONGEST ra_prev;
+
+  if (regnum == CR16_SP_REGNUM)
+    return frame_unwind_got_constant (this_frame, regnum, frame_base);
+
+  /* The call instruction has saved the return address on the RA register,
+     CR16_R13_REGNUM. So, we need not adjust anything directly. We will 
+     analyze prologue as this RA register is pushed onto stack for further
+     leaf function calls to work */
+  else if (regnum == CR16_PC_REGNUM)
+    {
+      ra_prev = frame_unwind_register_unsigned (this_frame, CR16_RA_REGNUM);
+      ra_prev = ra_prev << 1;
+      return frame_unwind_got_constant (this_frame, CR16_PC_REGNUM, ra_prev);
+    }
+
+  /* If prologue analysis says we saved this register somewhere,
+     return a description of the stack slot holding it.  */
+  else if (p->reg_offset[regnum] != 1)
+    {
+      return frame_unwind_got_memory (this_frame, regnum,
+				      frame_base + p->reg_offset[regnum]);
+    }
+
+  /* Otherwise, presume we haven't changed the value of this
+     register, and get it from the next frame.  */
+  else
+    {
+      return frame_unwind_got_register (this_frame, regnum, regnum);
+    }
+}
+
+static const struct frame_unwind cr16_frame_unwind = {
+  NORMAL_FRAME,
+  default_frame_unwind_stop_reason,
+  cr16_frame_this_id,
+  cr16_frame_prev_register,
+  NULL,
+  default_frame_sniffer
+};
+
+/* Implement the "unwind_pc" gdbarch method.  */
+static CORE_ADDR
+cr16_unwind_pc (struct gdbarch *gdbarch, struct frame_info *this_frame)
+{
+  ULONGEST pc;
+
+  pc = frame_unwind_register_unsigned (this_frame, CR16_PC_REGNUM);
+  return pc;
+}
+
+/* Implement the "unwind_sp" gdbarch method.  */
+static CORE_ADDR
+cr16_unwind_sp (struct gdbarch *gdbarch, struct frame_info *this_frame)
+{
+  ULONGEST sp;
+
+  sp = frame_unwind_register_unsigned (this_frame, CR16_SP_REGNUM);
+  return sp;
+}
+
+/* Implement the "dummy_id" gdbarch method.  */
+static struct frame_id
+cr16_dummy_id (struct gdbarch *gdbarch, struct frame_info *this_frame)
+{
+  return
+    frame_id_build (get_frame_register_unsigned (this_frame, CR16_SP_REGNUM),
+		    get_frame_pc (this_frame));
+}
+
+/* Implement the "push_dummy_call" gdbarch method.  */
+static CORE_ADDR
+cr16_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
+		      struct regcache *regcache, CORE_ADDR bp_addr, int nargs,
+		      struct value **args, CORE_ADDR sp, int struct_return,
+		      CORE_ADDR struct_addr)
+{
+  enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
+  int write_pass;
+  int sp_off = 0;
+  CORE_ADDR cfa;
+  int num_register_candidate_args;
+
+  struct type *func_type = value_type (function);
+
+  /* Dereference function pointer types.  */
+  while (TYPE_CODE (func_type) == TYPE_CODE_PTR)
+    func_type = TYPE_TARGET_TYPE (func_type);
+
+  /* The end result had better be a function or a method.  */
+  gdb_assert (TYPE_CODE (func_type) == TYPE_CODE_FUNC
+	      || TYPE_CODE (func_type) == TYPE_CODE_METHOD);
+
+  /* Functions with a variable number of arguments have all of their
+     variable arguments and the last non-variable argument passed
+     on the stack.
+
+     Otherwise, we can pass up to four arguments on the stack.
+
+     Once computed, we leave this value alone.  I.e. we don't update
+     it in case of a struct return going in a register or an argument
+     requiring multiple registers, etc.  We rely instead on the value
+     of the ``arg_reg'' variable to get these other details correct.  */
+
+  if (TYPE_VARARGS (func_type))
+    num_register_candidate_args = TYPE_NFIELDS (func_type) - 1;
+  else
+    num_register_candidate_args = 4;
+
+  /* We make two passes; the first does the stack allocation,
+     the second actually stores the arguments.  */
+  for (write_pass = 0; write_pass <= 1; write_pass++)
+    {
+      int i;
+      int arg_reg = CR16_R0_REGNUM;
+
+      if (write_pass)
+	sp = align_down (sp - sp_off, 4);
+      sp_off = 0;
+
+      if (struct_return)
+	{
+	  struct type *return_type = TYPE_TARGET_TYPE (func_type);
+
+	  gdb_assert (TYPE_CODE (return_type) == TYPE_CODE_STRUCT
+		      || TYPE_CODE (func_type) == TYPE_CODE_UNION);
+
+	  if (TYPE_LENGTH (return_type) > 16
+	      || TYPE_LENGTH (return_type) % 4 != 0)
+	    {
+	      if (write_pass)
+		regcache_cooked_write_unsigned (regcache, CR16_R12_REGNUM,
+						struct_addr);
+	    }
+	}
+
+      /* Push the arguments.  */
+      for (i = 0; i < nargs; i++)
+	{
+	  struct value *arg = args[i];
+	  const gdb_byte *arg_bits = value_contents_all (arg);
+	  struct type *arg_type = check_typedef (value_type (arg));
+	  ULONGEST arg_size = TYPE_LENGTH (arg_type);
+
+	  if (i == 0 && struct_addr != 0 && !struct_return
+	      && TYPE_CODE (arg_type) == TYPE_CODE_PTR
+	      && extract_unsigned_integer (arg_bits, 4,
+					   byte_order) == struct_addr)
+	    {
+	      /* This argument represents the address at which C++ (and
+	         possibly other languages) store their return value.
+	         Put this value in R15.  */
+	      if (write_pass)
+		regcache_cooked_write_unsigned (regcache, CR16_R12_REGNUM,
+						struct_addr);
+	    }
+	  else if (TYPE_CODE (arg_type) != TYPE_CODE_STRUCT
+		   && TYPE_CODE (arg_type) != TYPE_CODE_UNION)
+	    {
+	      /* Argument is a scalar.  */
+	      if (arg_size == 8)
+		{
+		  if (i < num_register_candidate_args
+		      && arg_reg <= CR16_R7_REGNUM - 1)
+		    {
+		      /* If argument registers are going to be used to pass
+		         an 8 byte scalar, the ABI specifies that two registers
+		         must be available.  */
+		      if (write_pass)
+			{
+			  regcache_cooked_write_unsigned (regcache, arg_reg,
+							  extract_unsigned_integer
+							  (arg_bits, 4,
+							   byte_order));
+			  regcache_cooked_write_unsigned (regcache,
+							  arg_reg + 1,
+							  extract_unsigned_integer
+							  (arg_bits + 4, 4,
+							   byte_order));
+			}
+		      arg_reg += 2;
+		    }
+		  else
+		    {
+		      sp_off = align_up (sp_off, 4);
+		      /* Otherwise, pass the 8 byte scalar on the stack.  */
+		      if (write_pass)
+			write_memory (sp + sp_off, arg_bits, 8);
+		      sp_off += 8;
+		    }
+		}
+	      else
+		{
+		  ULONGEST u;
+
+		  gdb_assert (arg_size <= 4);
+
+		  u =
+		    extract_unsigned_integer (arg_bits, arg_size, byte_order);
+
+		  if (i < num_register_candidate_args
+		      && arg_reg <= CR16_R7_REGNUM)
+		    {
+		      if (write_pass)
+			regcache_cooked_write_unsigned (regcache, arg_reg, u);
+		      arg_reg += 1;
+		    }
+		  else
+		    {
+		      int p_arg_size = 4;
+
+		      if (TYPE_PROTOTYPED (func_type)
+			  && i < TYPE_NFIELDS (func_type))
+			{
+			  struct type *p_arg_type =
+			    TYPE_FIELD_TYPE (func_type, i);
+			  p_arg_size = TYPE_LENGTH (p_arg_type);
+			}
+
+		      sp_off = align_up (sp_off, p_arg_size);
+
+		      if (write_pass)
+			write_memory_unsigned_integer (sp + sp_off,
+						       p_arg_size, byte_order,
+						       u);
+		      sp_off += p_arg_size;
+		    }
+		}
+	    }
+	  else
+	    {
+	      /* Argument is a struct or union.  Pass as much of the struct
+	         in registers, if possible.  Pass the rest on the stack.  */
+	      while (arg_size > 0)
+		{
+		  if (i < num_register_candidate_args
+		      && arg_reg <= CR16_R7_REGNUM
+		      && arg_size <= 4 * (CR16_R7_REGNUM - arg_reg + 1)
+		      && arg_size % 4 == 0)
+		    {
+		      int len = min (arg_size, 4);
+
+		      if (write_pass)
+			regcache_cooked_write_unsigned (regcache, arg_reg,
+							extract_unsigned_integer
+							(arg_bits, len,
+							 byte_order));
+		      arg_bits += len;
+		      arg_size -= len;
+		      arg_reg++;
+		    }
+		  else
+		    {
+		      sp_off = align_up (sp_off, 4);
+		      if (write_pass)
+			write_memory (sp + sp_off, arg_bits, arg_size);
+		      sp_off += align_up (arg_size, 4);
+		      arg_size = 0;
+		    }
+		}
+	    }
+	}
+    }
+
+  /* Keep track of the stack address prior to pushing the return address.
+     This is the value that we'll return.  */
+  cfa = sp;
+
+  /* Push the return address.  */
+  sp = sp - 4;
+  write_memory_unsigned_integer (sp, 4, byte_order, bp_addr);
+
+  /* Update the stack pointer.  */
+  regcache_cooked_write_unsigned (regcache, CR16_SP_REGNUM, sp);
+
+  return cfa;
+}
+
+/* Implement the "return_value" gdbarch method.  */
+static enum return_value_convention
+cr16_return_value (struct gdbarch *gdbarch,
+		   struct type *func_type,
+		   struct type *valtype,
+		   struct regcache *regcache,
+		   gdb_byte * readbuf, const gdb_byte * writebuf)
+{
+  enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
+  ULONGEST valtype_len = TYPE_LENGTH (valtype);
+
+  if (TYPE_LENGTH (valtype) > 16
+      || ((TYPE_CODE (valtype) == TYPE_CODE_STRUCT
+	   || TYPE_CODE (valtype) == TYPE_CODE_UNION)
+	  && TYPE_LENGTH (valtype) % 4 != 0))
+    return RETURN_VALUE_STRUCT_CONVENTION;
+
+  if (readbuf)
+    {
+      ULONGEST u;
+      int argreg = CR16_R0_REGNUM;
+      int offset = 0;
+
+      while (valtype_len > 0)
+	{
+	  int len = min (valtype_len, 4);
+
+	  regcache_cooked_read_unsigned (regcache, argreg, &u);
+	  store_unsigned_integer (readbuf + offset, len, byte_order, u);
+	  valtype_len -= len;
+	  offset += len;
+	  argreg++;
+	}
+    }
+
+  if (writebuf)
+    {
+      ULONGEST u;
+      int argreg = CR16_R0_REGNUM;
+      int offset = 0;
+
+      while (valtype_len > 0)
+	{
+	  int len = min (valtype_len, 4);
+
+	  u = extract_unsigned_integer (writebuf + offset, len, byte_order);
+	  regcache_cooked_write_unsigned (regcache, argreg, u);
+	  valtype_len -= len;
+	  offset += len;
+	  argreg++;
+	}
+    }
+
+  return RETURN_VALUE_REGISTER_CONVENTION;
+}
+
+/* Implement the "breakpoint_from_pc" gdbarch method.  */
+static const gdb_byte *
+cr16_breakpoint_from_pc (struct gdbarch *gdbarch, CORE_ADDR * pcptr,
+			 int *lenptr)
+{
+  /* We use different breakpoint instructions for ELF and uClinux.
+     See cr16-linux-tdep.c for more details. 
+  */
+  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+  *lenptr = 2;
+  if (tdep == NULL || tdep->breakpoint == NULL)
+    {
+        return  breakpoint_elf;
+    }
+  return tdep->breakpoint;
+}
+
+
+
+/* Allocate and initialize a gdbarch object.  */
+static struct gdbarch *
+cr16_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
+{
+  struct gdbarch *gdbarch;
+  struct gdbarch_tdep *tdep;
+  int elf_flags;
+
+  /* Extract the elf_flags if available.  */
+  if (info.abfd != NULL
+      && bfd_get_flavour (info.abfd) == bfd_target_elf_flavour)
+    elf_flags = elf_elfheader (info.abfd)->e_flags;
+  else
+    elf_flags = 0;
+
+  /* Try to find the architecture in the list of already defined
+     architectures.  */
+  for (arches = gdbarch_list_lookup_by_info (arches, &info);
+       arches != NULL;
+       arches = gdbarch_list_lookup_by_info (arches->next, &info))
+    {
+      if (gdbarch_tdep (arches->gdbarch)->elf_flags != elf_flags)
+	continue;
+
+      return arches->gdbarch;
+    }
+  /* None found, create a new architecture from the information
+     provided.  */
+  tdep = (struct gdbarch_tdep *) xcalloc (1,sizeof (struct gdbarch_tdep));
+  tdep->elf_flags = elf_flags;
+  gdbarch = gdbarch_alloc (&info, tdep);
+
+  set_gdbarch_num_pseudo_regs (gdbarch, 0);
+  if(info.osabi == GDB_OSABI_LINUX)
+  {
+    set_gdbarch_num_regs (gdbarch, CR16_LINUX_NUM_REGS);
+    set_gdbarch_register_name (gdbarch, cr16_linux_register_name);
+  }
+  else
+  {
+    set_gdbarch_num_regs (gdbarch, CR16_NUM_REGS);
+    set_gdbarch_register_name (gdbarch, cr16_register_name);
+  }
+  set_gdbarch_register_type (gdbarch, cr16_register_type);
+  set_gdbarch_pc_regnum (gdbarch, CR16_PC_REGNUM);
+  set_gdbarch_sp_regnum (gdbarch, CR16_SP_REGNUM);
+  set_gdbarch_inner_than (gdbarch, core_addr_lessthan);
+  set_gdbarch_decr_pc_after_break (gdbarch, 2);
+  set_gdbarch_breakpoint_from_pc (gdbarch, cr16_breakpoint_from_pc);
+  set_gdbarch_skip_prologue (gdbarch, cr16_skip_prologue);
+
+  /* Passing NULL  values in the following two functions
+     for the time being, to fix later  */
+  set_gdbarch_print_insn (gdbarch, print_insn_cr16);
+  set_gdbarch_unwind_pc (gdbarch, cr16_unwind_pc);
+  set_gdbarch_unwind_sp (gdbarch, cr16_unwind_sp);
+
+  /* Methods for saving / extracting a dummy frame's ID.
+     The ID's stack address must match the SP value returned by
+     PUSH_DUMMY_CALL, and saved by generic_save_dummy_frame_tos.  */
+  set_gdbarch_dummy_id (gdbarch, cr16_dummy_id);
+  set_gdbarch_push_dummy_call (gdbarch, cr16_push_dummy_call);
+  /* Target builtin data types.  */
+  set_gdbarch_char_signed (gdbarch, 8);
+  set_gdbarch_short_bit (gdbarch, 16);
+
+  /* if we don't pass the option -mint32
+     To fix : add if else case depending on the option passed,
+     sp that we can have int size as 16 or 32 bits both. */
+  set_gdbarch_int_bit (gdbarch, 16);
+  set_gdbarch_long_bit (gdbarch, 32);
+  set_gdbarch_long_long_bit (gdbarch, 64);
+  set_gdbarch_float_bit (gdbarch, 32);
+
+  set_gdbarch_ptr_bit (gdbarch, 32);
+  set_gdbarch_float_format (gdbarch, floatformats_ieee_single);
+  set_gdbarch_double_bit (gdbarch, 64);
+  set_gdbarch_long_double_bit (gdbarch, 64);
+  set_gdbarch_double_format (gdbarch, floatformats_ieee_double);
+  set_gdbarch_long_double_format (gdbarch, floatformats_ieee_double);
+
+  frame_unwind_append_unwinder (gdbarch, &cr16_frame_unwind);
+  set_gdbarch_return_value (gdbarch, cr16_return_value);
+
+  /* Hook in ABI-specific overrides, if they have been registered.  */
+  gdbarch_init_osabi (info, gdbarch);
+
+  return gdbarch;
+
+}
+
+/* -Wmissing-prototypes */
+extern initialize_file_ftype _initialize_cr16_tdep;
+
+/* Register the above initialization routine.  */
+void
+_initialize_cr16_tdep (void)
+{
+  register_gdbarch_init (bfd_arch_cr16, cr16_gdbarch_init);
+}
--- gdb_src.orig/gdb/cr16-tdep.h	1970-01-01 05:30:00.000000000 +0530
+++ ./gdb_src/gdb/cr16-tdep.h	2012-09-04 13:05:39.000000000 +0530
@@ -0,0 +1,36 @@
+/* GNU/Linux on  CR16 target support.
+   Copyright (C) 2011-2012 Free Software Foundation, Inc.
+
+   Contributed by Kaushik Phatak (kaushik.pahatk@kpitcummins.com)
+   KPIT Cummins Infosystems Limited, Pune India.
+
+   This file is part of GDB.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+#define CR16_NUM_REGS  22
+#define CR16_LINUX_NUM_REGS  21
+
+extern const gdb_byte breakpoint_elf[];
+extern const gdb_byte breakpoint_linux[];
+
+/* Target-dependent structure in gdbarch.  */
+/* Architecture specific data.  */
+struct gdbarch_tdep
+{
+  /* The ELF header flags specify the multilib used.  */
+  int elf_flags;
+
+  const char *breakpoint; /* Breakpoint instruction.  */
+};

[-- Attachment #3: gdb_core_fpic_suspect.diff --]
[-- Type: application/octet-stream, Size: 2107 bytes --]

--- gdb_src.orig/gdb/findvar.c	2012-06-05 19:20:49.000000000 +0530
+++ ./gdb_src/gdb/findvar.c	2012-08-17 16:21:54.000000000 +0530
@@ -501,6 +501,7 @@ default_read_var_value (struct symbol *v
 					 SYMBOL_OBJ_SECTION (var));
       else
 	addr = SYMBOL_VALUE_ADDRESS (var);
+	addr = addr + temp_fpic_addr;
       break;
 
     case LOC_ARG:
@@ -610,6 +611,7 @@ default_read_var_value (struct symbol *v
 					   SYMBOL_OBJ_SECTION (msym));
 	else
 	  addr = SYMBOL_VALUE_ADDRESS (msym);
+	  addr = addr + temp_fpic_addr;
 
 	obj_section = SYMBOL_OBJ_SECTION (msym);
 	if (obj_section
--- gdb_src.orig/gdb/remote.c	2012-07-02 20:59:34.000000000 +0530
+++ ./gdb_src/gdb/remote.c	2012-09-11 14:50:08.000000000 +0530
@@ -3151,6 +3151,7 @@ get_offsets (void)
   else if (data && data->num_segments == 1)
     {
       segments[0] = data->segment_bases[0] + text_addr;
+      segments[1] = data->segment_bases[1] + data_addr;
       num_segments = 1;
     }
   /* There's no way to relocate by segment.  */
--- gdb_src.orig/gdb/symfile.c	2012-06-27 01:44:02.000000000 +0530
+++ ./gdb_src/gdb/symfile.c	2012-08-17 16:19:09.000000000 +0530
@@ -3757,6 +3757,16 @@ symfile_map_offsets_to_segments (bfd *ab
                              - data->segment_bases[which - 1]);
     }
 
+  /* Below code to handle data address in fPIC mode, offset from .text */
+  temp_fpic_addr = abfd->sections->size;
+  if(segment_bases[1] > segment_bases[0])
+    temp_fpic_addr = segment_bases[1] - (segment_bases[0] + temp_fpic_addr);
+  else
+  {
+    temp_fpic_addr = (segment_bases[0] + temp_fpic_addr) - segment_bases[1];
+    temp_fpic_addr = 0 - temp_fpic_addr;
+  }
+
   return 1;
 }
 
--- gdb_src.orig/gdb/symfile.h	2012-07-20 23:29:05.000000000 +0530
+++ ./gdb_src/gdb/symfile.h	2012-08-17 16:17:56.000000000 +0530
@@ -72,6 +72,8 @@ struct psymbol_allocation_list
   int size;
 };
 
+CORE_ADDR temp_fpic_addr;
+
 /* Define an array of addresses to accommodate non-contiguous dynamic
    loading of modules.  This is for use when entering commands, so we
    can keep track of the section names until we read the file and can

[-- Attachment #4: cr16_bfd.diff --]
[-- Type: application/octet-stream, Size: 1000 bytes --]

diff -uprN gdb_src.orig/opcodes/cr16-dis.c ./gdb_src/opcodes/cr16-dis.c
--- gdb_src.orig/opcodes/cr16-dis.c	2012-05-17 20:43:25.000000000 +0530
+++ ./gdb_src/opcodes/cr16-dis.c	2012-09-11 12:18:43.000000000 +0530
@@ -317,7 +317,9 @@ build_mask (void)
 
 /* Search for a matching opcode. Return 1 for success, 0 for failure.  */
 
-static int
+int match_opcode (void);
+
+int
 match_opcode (void)
 {
   unsigned long mask;
@@ -734,7 +736,9 @@ print_arguments (ins *currentInsn, bfd_v
 
 /* Build the instruction's arguments.  */
 
-static void
+void make_instruction (void);
+
+void
 make_instruction (void)
 {
   int i;
--- ./gdb_src.orig/bfd/config.bfd	2012-05-15 18:25:34.000000000 +0530
+++ ./gdb_src/bfd/config.bfd	2012-09-11 16:18:16.000000000 +0530
@@ -345,6 +345,11 @@ case "${targ}" in
     targ_underscore=yes
     ;;
 
+  cr16*-*-uclinux*)
+    targ_defvec=bfd_elf32_cr16_vec
+    targ_underscore=yes
+    ;;
+
   cr16c-*-elf*)
     targ_defvec=bfd_elf32_cr16c_vec
     targ_underscore=yes

[-- Attachment #5: cr16_config_tgt_alpha.diff --]
[-- Type: application/octet-stream, Size: 574 bytes --]

--- gdb_src.orig/gdb/configure.tgt	2012-08-02 01:18:44.000000000 +0530
+++ ./gdb_src/gdb/configure.tgt	2012-09-11 14:48:26.000000000 +0530
@@ -116,6 +116,20 @@ bfin-*-*)
 	gdb_sim=../sim/bfin/libsim.a
 	;;
 
+cr16*-*-*linux*)
+	# Target: CR16 processor
+	gdb_target_obs="cr16-tdep.o cr16-linux-tdep.o linux-tdep.o"
+	gdb_sim=../sim/cr16/libsim.a
+	build_gdbserver=yes
+	;;
+
+cr16*-*-*)
+	# Target: CR16 processor
+	gdb_target_obs="cr16-tdep.o"
+	gdb_sim=../sim/cr16/libsim.a
+	build_gdbserver=yes
+	;;
+
 cris*)
 	# Target: CRIS
 	gdb_target_obs="cris-tdep.o solib-svr4.o"

[-- Attachment #6: cr16_config_toplevel_alpha.diff --]
[-- Type: application/octet-stream, Size: 802 bytes --]

--- gdb_src.orig/configure	2012-06-28 17:20:52.000000000 +0530
+++ ./gdb_src/configure	2012-08-17 16:56:10.000000000 +0530
@@ -3447,7 +3447,7 @@ case "${target}" in
     noconfigdirs="$noconfigdirs target-libgloss gdb"
     ;;
   cr16-*-*)
-    noconfigdirs="$noconfigdirs gdb"
+    noconfigdirs="$noconfigdirs target-libgloss"
     ;;
   d10v-*-*)
     noconfigdirs="$noconfigdirs target-libgloss"
--- gdb_src.orig/configure.ac	2012-06-28 17:20:52.000000000 +0530
+++ ./gdb_src/configure.ac	2012-08-17 16:56:17.000000000 +0530
@@ -873,7 +873,7 @@ case "${target}" in
     noconfigdirs="$noconfigdirs target-libgloss gdb"
     ;;
   cr16-*-*)
-    noconfigdirs="$noconfigdirs gdb"
+    noconfigdirs="$noconfigdirs target-libgloss"
     ;;
   d10v-*-*)
     noconfigdirs="$noconfigdirs target-libgloss"

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [RFC] New GDB Port CR16
  2012-09-04  6:50             ` Kaushik Phatak
  2012-09-07 17:47               ` Pedro Alves
@ 2012-09-11 19:00               ` Mike Frysinger
  1 sibling, 0 replies; 18+ messages in thread
From: Mike Frysinger @ 2012-09-11 19:00 UTC (permalink / raw)
  To: Kaushik Phatak; +Cc: gdb-patches, Yao Qi, Pedro Alves

On Mon, Sep 3, 2012 at 11:49 PM, Kaushik Phatak wrote:
> Hi Pedro,
>> Is this dependency on host signal defines what is done on other sims?
> This was probably added when breakpoint support was being added to this
> sim port with reference of the SH port I believe.
>
>> there is cruft like this in other sims.  it probably would be desirable to clean it up.
> Yes Mike, I agree. I have tested it without this hunk and breakpoints seem to
> work as expected. Please see below the patch that reverts this in sim.
> I am rearranging some code to create cr16-linux-tdep.c file as suggested by Yao
> and will post the gdb related patches soon.

well, the idea would be that you wouldn't use host signals at all.
you'd only use SIM_SIGXXX.  this patch doesn't really address that, so
i wouldn't bother unless you go the distance ;).
-mike


^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [RFC] New GDB Port CR16
  2012-09-11 13:16                 ` Kaushik Phatak
@ 2012-09-11 19:02                   ` Mike Frysinger
  2012-09-24 12:55                     ` Kaushik Phatak
  0 siblings, 1 reply; 18+ messages in thread
From: Mike Frysinger @ 2012-09-11 19:02 UTC (permalink / raw)
  To: Kaushik Phatak; +Cc: gdb-patches, Yao Qi, Pedro Alves

On Tue, Sep 11, 2012 at 6:16 AM, Kaushik Phatak wrote:
> Mike, you had given the below feedback,
> http://sourceware.org/ml/gdb-patches/2012-08/msg00819.html
>> +int
>>  match_opcode (void)
>> this new local prototype makes no sense.  just delete it.
>
> When I remove these prototypes, it gives me a warning as follows,
> warning: no previous prototype for match_opcode
> Our build fails as it treats warnings as error. We can get around that by
> using "--disable-werror" I guess. But would this hunk be acceptable as is?

that means this file isn't including the header with the new
prototype.  so the fix would be to change this file to include the
header.
-mike


^ permalink raw reply	[flat|nested] 18+ messages in thread

* RE: [RFC] New GDB Port CR16
  2012-09-11 19:02                   ` Mike Frysinger
@ 2012-09-24 12:55                     ` Kaushik Phatak
  0 siblings, 0 replies; 18+ messages in thread
From: Kaushik Phatak @ 2012-09-24 12:55 UTC (permalink / raw)
  To: Mike Frysinger; +Cc: gdb-patches, Yao Qi, Pedro Alves

>> so the fix would be to change this file to include the header.

Yes, I agree. I have added the prototypes to the header file and the patch below
should fix this issue,

include/opcode/ChangeLog:
	* cr16.h: Add prototypes for cr16-dis.c

	
--- ./gdb_src.orig/include/opcode/cr16.h        2010-04-15 15:56:09.000000000 +0530
+++ ./gdb_src/include/opcode/cr16.h     2012-09-12 10:44:09.000000000 +0530
@@ -435,4 +435,8 @@ extern const inst *instruction;
 typedef long long int LONGLONG;
 typedef unsigned long long ULONGLONG;

+/* Prototypes for function in cr16-dis.c  */
+void make_instruction (void);
+int match_opcode (void);
+
 #endif /* _CR16_H_ */


Additionally, I was working on couple of issues as mentioned in the post below,
http://sourceware.org/ml/gdb-patches/2012-09/msg00152.html
Issue 1 is sorted out by migrating my gdbserver sources to the latest 7.5 release
version. I was earlier working on a much older branch and had only migrated the
host side gdb to 7.5.

Issue 2 is related to the -fPIC option which causes my global data to be placed
at an offset causing the host side gdb to query incorrect addresses for global
variables. Any comments on my proposed patch/hack ?
http://sourceware.org/ml/gdb-patches/2012-09/msg00152/gdb_core_fpic_suspect.diff

Thanks & Best Regards,
Kaushik Phatak



^ permalink raw reply	[flat|nested] 18+ messages in thread

end of thread, other threads:[~2012-09-24 12:55 UTC | newest]

Thread overview: 18+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2012-08-27  6:37 [RFC] New GDB Port CR16 Kaushik Phatak
2012-08-27 16:21 ` Yao Qi
2012-08-28 14:47   ` Kaushik Phatak
2012-08-29 22:14     ` Mike Frysinger
2012-08-30  5:23       ` Kaushik Phatak
2012-08-30  6:10         ` Mike Frysinger
2012-09-03  9:31         ` Pedro Alves
2012-09-04  3:52           ` Mike Frysinger
2012-09-04  6:50             ` Kaushik Phatak
2012-09-07 17:47               ` Pedro Alves
2012-09-11 13:16                 ` Kaushik Phatak
2012-09-11 19:02                   ` Mike Frysinger
2012-09-24 12:55                     ` Kaushik Phatak
2012-09-11 19:00               ` Mike Frysinger
2012-08-27 21:10 ` Mike Frysinger
2012-08-28 16:24 ` Pedro Alves
2012-08-30  4:49   ` Kaushik Phatak
2012-08-30  5:14     ` Yao Qi

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox