⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 am29k-tdep.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 2 页
字号:
	p += 4;    }  /* We've found the start of the function.     * Try looking for a tag word that indicates whether there is a   * memory frame pointer and what the memory stack allocation is.   * If one doesn't exist, try using a more exhaustive search of   * the prologue.  For now we don't care about the argcount or   * whether or not the routine is transparent.   */  if (examine_tag(p-4,&trans,NULL,&msize,&mfp_used)) /* Found a good tag */      examine_prologue (p, &rsize, 0, 0);  else 						/* No tag try prologue */      examine_prologue (p, &rsize, &msize, &mfp_used);  fci->rsize = rsize;  fci->msize = msize;  fci->flags = 0;  if (mfp_used)  	fci->flags |= MFP_USED;  if (trans)  	fci->flags |= TRANSPARENT;  if (innermost_frame)    {      fci->saved_msp = read_register (MSP_REGNUM) + msize;    }  else    {      if (mfp_used)  	 fci->saved_msp =	      read_register_stack_integer (fci->frame + rsize - 4, 4);      else  	    fci->saved_msp = fci->next->saved_msp + msize;    }}voidinit_extra_frame_info (fci)     struct frame_info *fci;{  if (fci->next == 0)    /* Assume innermost frame.  May produce strange results for "info frame"       but there isn't any way to tell the difference.  */    init_frame_info (1, fci);  else {      /* We're in get_prev_frame_info.         Take care of everything in init_frame_pc.  */      ;    }}voidinit_frame_pc (fromleaf, fci)     int fromleaf;     struct frame_info *fci;{  fci->pc = (fromleaf ? SAVED_PC_AFTER_CALL (fci->next) :	     fci->next ? FRAME_SAVED_PC (fci->next) : read_pc ());  init_frame_info (fromleaf, fci);}/* Local variables (i.e. LOC_LOCAL) are on the memory stack, with their   offsets being relative to the memory stack pointer (high C) or   saved_msp (gcc).  */CORE_ADDRframe_locals_address (fi)     struct frame_info *fi;{  if (fi->flags & MFP_USED)     return fi->saved_msp;  else    return fi->saved_msp - fi->msize;}/* Routines for reading the register stack.  The caller gets to treat   the register stack as a uniform stack in memory, from address $gr1   straight through $rfb and beyond.  *//* Analogous to read_memory except the length is understood to be 4.   Also, myaddr can be NULL (meaning don't bother to read), and   if actual_mem_addr is non-NULL, store there the address that it   was fetched from (or if from a register the offset within   registers).  Set *LVAL to lval_memory or lval_register, depending   on where it came from.  */voidread_register_stack (memaddr, myaddr, actual_mem_addr, lval)     CORE_ADDR memaddr;     char *myaddr;     CORE_ADDR *actual_mem_addr;     enum lval_type *lval;{  long rfb = read_register (RFB_REGNUM);  long rsp = read_register (RSP_REGNUM);  /* If we don't do this 'info register' stops in the middle. */  if (memaddr >= rstack_high_address)     {      int val = -1;			/* a bogus value */      /* It's in a local register, but off the end of the stack.  */      int regnum = (memaddr - rsp) / 4 + LR0_REGNUM;      if (myaddr != NULL)	*(int*)myaddr = val;		/* Provide bogusness */      supply_register(regnum,&val);	/* More bogusness */      if (lval != NULL)	*lval = lval_register;      if (actual_mem_addr != NULL)	*actual_mem_addr = REGISTER_BYTE (regnum);    }  else if (memaddr < rfb)    {      /* It's in a register.  */      int regnum = (memaddr - rsp) / 4 + LR0_REGNUM;      if (regnum < LR0_REGNUM || regnum > LR0_REGNUM + 127)	error ("Attempt to read register stack out of range.");      if (myaddr != NULL)	read_register_gen (regnum, myaddr);      if (lval != NULL)	*lval = lval_register;      if (actual_mem_addr != NULL)	*actual_mem_addr = REGISTER_BYTE (regnum);    }  else    {      /* It's in the memory portion of the register stack.  */      if (myaddr != NULL) 	   read_memory (memaddr, myaddr, 4);      if (lval != NULL)	*lval = lval_memory;      if (actual_mem_addr != NULL)	*actual_mem_addr = memaddr;    }}/* Analogous to read_memory_integer   except the length is understood to be 4.  */longread_register_stack_integer (memaddr, len)     CORE_ADDR memaddr;     int len;{  long buf;  read_register_stack (memaddr, &buf, NULL, NULL);  SWAP_TARGET_AND_HOST (&buf, 4);  return buf;}/* Copy 4 bytes from GDB memory at MYADDR into inferior memory   at MEMADDR and put the actual address written into in   *ACTUAL_MEM_ADDR.  */static voidwrite_register_stack (memaddr, myaddr, actual_mem_addr)     CORE_ADDR memaddr;     char *myaddr;     CORE_ADDR *actual_mem_addr;{  long rfb = read_register (RFB_REGNUM);  long rsp = read_register (RSP_REGNUM);  /* If we don't do this 'info register' stops in the middle. */  if (memaddr >= rstack_high_address)     {      /* It's in a register, but off the end of the stack.  */      if (actual_mem_addr != NULL)	*actual_mem_addr = NULL;     }  else if (memaddr < rfb)    {      /* It's in a register.  */      int regnum = (memaddr - rsp) / 4 + LR0_REGNUM;      if (regnum < LR0_REGNUM || regnum > LR0_REGNUM + 127)	error ("Attempt to read register stack out of range.");      if (myaddr != NULL)	write_register (regnum, *(long *)myaddr);      if (actual_mem_addr != NULL)	*actual_mem_addr = NULL;    }  else    {      /* It's in the memory portion of the register stack.  */      if (myaddr != NULL)	write_memory (memaddr, myaddr, 4);      if (actual_mem_addr != NULL)	*actual_mem_addr = memaddr;    }}/* Find register number REGNUM relative to FRAME and put its   (raw) contents in *RAW_BUFFER.  Set *OPTIMIZED if the variable   was optimized out (and thus can't be fetched).  If the variable   was fetched from memory, set *ADDRP to where it was fetched from,   otherwise it was fetched from a register.   The argument RAW_BUFFER must point to aligned memory.  */voidget_saved_register (raw_buffer, optimized, addrp, frame, regnum, lvalp)     char *raw_buffer;     int *optimized;     CORE_ADDR *addrp;     FRAME frame;     int regnum;     enum lval_type *lvalp;{  struct frame_info *fi;  CORE_ADDR addr;  enum lval_type lval;  if (frame == 0)    return;  fi = get_frame_info (frame);  /* Once something has a register number, it doesn't get optimized out.  */  if (optimized != NULL)    *optimized = 0;  if (regnum == RSP_REGNUM)    {      if (raw_buffer != NULL)	*(CORE_ADDR *)raw_buffer = fi->frame;      if (lvalp != NULL)	*lvalp = not_lval;      return;    }  else if (regnum == PC_REGNUM)    {      if (raw_buffer != NULL)	*(CORE_ADDR *)raw_buffer = fi->pc;      /* Not sure we have to do this.  */      if (lvalp != NULL)	*lvalp = not_lval;      return;    }  else if (regnum == MSP_REGNUM)    {      if (raw_buffer != NULL)	{	  if (fi->next != NULL)	    *(CORE_ADDR *)raw_buffer = fi->next->saved_msp;	  else	    *(CORE_ADDR *)raw_buffer = read_register (MSP_REGNUM);	}      /* The value may have been computed, not fetched.  */      if (lvalp != NULL)	*lvalp = not_lval;      return;    }  else if (regnum < LR0_REGNUM || regnum >= LR0_REGNUM + 128)    {      /* These registers are not saved over procedure calls,	 so just print out the current values.  */      if (raw_buffer != NULL)	*(CORE_ADDR *)raw_buffer = read_register (regnum);      if (lvalp != NULL)	*lvalp = lval_register;      if (addrp != NULL)	*addrp = REGISTER_BYTE (regnum);      return;    }        addr = fi->frame + (regnum - LR0_REGNUM) * 4;  if (raw_buffer != NULL)    read_register_stack (addr, raw_buffer, &addr, &lval);  if (lvalp != NULL)    *lvalp = lval;  if (addrp != NULL)    *addrp = addr;}/* Discard from the stack the innermost frame,   restoring all saved registers.  */voidpop_frame (){  FRAME frame = get_current_frame ();					        struct frame_info *fi = get_frame_info (frame);			        CORE_ADDR rfb = read_register (RFB_REGNUM);				        CORE_ADDR gr1 = fi->frame + fi->rsize;  CORE_ADDR lr1;							        int i;  /* If popping a dummy frame, need to restore registers.  */  if (PC_IN_CALL_DUMMY (read_register (PC_REGNUM),			read_register (SP_REGNUM),			FRAME_FP (fi)))    {      int lrnum = LR0_REGNUM + DUMMY_ARG/4;      for (i = 0; i < DUMMY_SAVE_SR128; ++i)	write_register (SR_REGNUM (i + 128),read_register (lrnum++));      for (i = 0; i < DUMMY_SAVE_SR160; ++i)	write_register (SR_REGNUM(i+160), read_register (lrnum++));      for (i = 0; i < DUMMY_SAVE_GREGS; ++i)	write_register (RETURN_REGNUM + i, read_register (lrnum++));      /* Restore the PCs.  */      write_register(PC_REGNUM, read_register (lrnum++));      write_register(NPC_REGNUM, read_register (lrnum));    }  /* Restore the memory stack pointer.  */  write_register (MSP_REGNUM, fi->saved_msp);				        /* Restore the register stack pointer.  */				        write_register (GR1_REGNUM, gr1);  /* Check whether we need to fill registers.  */			        lr1 = read_register (LR0_REGNUM + 1);				        if (lr1 > rfb)							          {									            /* Fill.  */							            int num_bytes = lr1 - rfb;      int i;								            long word;							            write_register (RAB_REGNUM, read_register (RAB_REGNUM) + num_bytes);        write_register (RFB_REGNUM, lr1);				            for (i = 0; i < num_bytes; i += 4)				              {	  /* Note: word is in host byte order.  */          word = read_memory_integer (rfb + i, 4);          write_register (LR0_REGNUM + ((rfb - gr1) % 0x80) + i / 4, word);					              }								          }  flush_cached_frames ();						        set_current_frame (create_new_frame (0, read_pc()));		      }/* Push an empty stack frame, to record the current PC, etc.  */void push_dummy_frame (){  long w;  CORE_ADDR rab, gr1;  CORE_ADDR msp = read_register (MSP_REGNUM);  int lrnum,  i, saved_lr0;    /* Allocate the new frame. */   gr1 = read_register (GR1_REGNUM) - DUMMY_FRAME_RSIZE;  write_register (GR1_REGNUM, gr1);  rab = read_register (RAB_REGNUM);  if (gr1 < rab)    {      /* We need to spill registers.  */      int num_bytes = rab - gr1;      CORE_ADDR rfb = read_register (RFB_REGNUM);      int i;      long word;      write_register (RFB_REGNUM, rfb - num_bytes);      write_register (RAB_REGNUM, gr1);      for (i = 0; i < num_bytes; i += 4)	{	  /* Note:  word is in target byte order.  */	  read_register_gen (LR0_REGNUM + i / 4, &word);	  write_memory (rfb - num_bytes + i, &word, 4);	}    }  /* There are no arguments in to the dummy frame, so we don't need     more than rsize plus the return address and lr1.  */  write_register (LR0_REGNUM + 1, gr1 + DUMMY_FRAME_RSIZE + 2 * 4);  /* Set the memory frame pointer.  */  write_register (LR0_REGNUM + DUMMY_FRAME_RSIZE / 4 - 1, msp);  /* Allocate arg_slop.  */  write_register (MSP_REGNUM, msp - 16 * 4);  /* Save registers.  */  lrnum = LR0_REGNUM + DUMMY_ARG/4;  for (i = 0; i < DUMMY_SAVE_SR128; ++i)    write_register (lrnum++, read_register (SR_REGNUM (i + 128)));  for (i = 0; i < DUMMY_SAVE_SR160; ++i)    write_register (lrnum++, read_register (SR_REGNUM (i + 160)));  for (i = 0; i < DUMMY_SAVE_GREGS; ++i)    write_register (lrnum++, read_register (RETURN_REGNUM + i));  /* Save the PCs.  */  write_register (lrnum++, read_register (PC_REGNUM));  write_register (lrnum, read_register (NPC_REGNUM));}reginv_com (args, fromtty)     char       *args;     int        fromtty;{   registers_changed();   if (fromtty)	printf_filtered("Gdb's register cache invalidated.\n");}/* We use this mostly for debugging gdb */void_initialize_29k(){  extern CORE_ADDR text_end;  add_com ("reginv ", class_obscure, reginv_com,         "Invalidate gdb's internal register cache.");  /* FIXME, there should be a way to make a CORE_ADDR variable settable. */  add_show_from_set    (add_set_cmd ("rstack_high_address", class_support, var_uinteger,		  (char *)&rstack_high_address,		  "Set top address in memory of the register stack.\n\Attempts to access registers saved above this address will be ignored\n\or will produce the value -1.", &setlist),     &showlist);  /* FIXME, there should be a way to make a CORE_ADDR variable settable. */  add_show_from_set    (add_set_cmd ("call_scratch_address", class_support, var_uinteger,		  (char *)&text_end,"Set address in memory where small amounts of RAM can be used when\n\making function calls into the inferior.", &setlist),     &showlist);}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -