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

📄 mips-tdep.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 3 页
字号:
	write_memory (save_address, (char *)&buffer, 4);	save_address -= 4;      }  write_register (PUSH_FP_REGNUM, sp);  PROC_FRAME_REG(proc_desc) = PUSH_FP_REGNUM;  PROC_FRAME_OFFSET(proc_desc) = 0;  buffer = read_register (PC_REGNUM);  write_memory (sp - 4, (char *)&buffer, sizeof(REGISTER_TYPE));  buffer = read_register (HI_REGNUM);  write_memory (sp - 8, (char *)&buffer, sizeof(REGISTER_TYPE));  buffer = read_register (LO_REGNUM);  write_memory (sp - 12, (char *)&buffer, sizeof(REGISTER_TYPE));  buffer = read_register (FCRCS_REGNUM);  write_memory (sp - 16, (char *)&buffer, sizeof(REGISTER_TYPE));  sp -= 4 * (GEN_REG_SAVE_COUNT+FLOAT_REG_SAVE_COUNT+SPECIAL_REG_SAVE_COUNT);  write_register (SP_REGNUM, sp);  PROC_LOW_ADDR(proc_desc) = sp - CALL_DUMMY_SIZE + CALL_DUMMY_START_OFFSET;  PROC_HIGH_ADDR(proc_desc) = sp;  SET_PROC_DESC_IS_DUMMY(proc_desc);  PROC_PC_REG(proc_desc) = RA_REGNUM;}voidmips_pop_frame(){  register int regnum;  FRAME frame = get_current_frame ();  CORE_ADDR new_sp = frame->frame;  mips_extra_func_info_t proc_desc = frame->proc_desc;  write_register (PC_REGNUM, FRAME_SAVED_PC(frame));  if (proc_desc)    {      for (regnum = 32; --regnum >= 0; )	if (PROC_REG_MASK(proc_desc) & (1 << regnum))	  write_register (regnum,			  read_memory_integer (frame->saved_regs->regs[regnum],					       4));      for (regnum = 32; --regnum >= 0; )	if (PROC_FREG_MASK(proc_desc) & (1 << regnum))	  write_register (regnum + FP0_REGNUM,			  read_memory_integer (frame->saved_regs->regs[regnum + FP0_REGNUM], 4));    }  write_register (SP_REGNUM, new_sp);  flush_cached_frames ();  /* We let mips_init_extra_frame_info figure out the frame pointer */  set_current_frame (create_new_frame (0, read_pc ()));  if (PROC_DESC_IS_DUMMY(proc_desc))    {      struct linked_proc_info *pi_ptr, *prev_ptr;      for (pi_ptr = linked_proc_desc_table, prev_ptr = NULL;	   pi_ptr != NULL;	   prev_ptr = pi_ptr, pi_ptr = pi_ptr->next)	{	  if (&pi_ptr->info == proc_desc)	    break;	}      if (pi_ptr == NULL)	error ("Can't locate dummy extra frame info\n");      if (prev_ptr != NULL)	prev_ptr->next = pi_ptr->next;      else	linked_proc_desc_table = pi_ptr->next;      free (pi_ptr);      write_register (HI_REGNUM, read_memory_integer(new_sp - 8, 4));      write_register (LO_REGNUM, read_memory_integer(new_sp - 12, 4));      write_register (FCRCS_REGNUM, read_memory_integer(new_sp - 16, 4));    }}static voidmips_print_register (regnum, all)     int regnum, all;{      unsigned char raw_buffer[MAX_REGISTER_RAW_SIZE * 2]; /* *2 for doubles */      REGISTER_TYPE val;      /* Get the data in raw format.  */      if (read_relative_register_raw_bytes (regnum, raw_buffer))	{	  printf_filtered ("%s: [Invalid]", reg_names[regnum]);	  return;	}            /* If an even floating pointer register, also print as double. */      if (regnum >= FP0_REGNUM && regnum < FP0_REGNUM+32	  && !((regnum-FP0_REGNUM) & 1)) {	  read_relative_register_raw_bytes (regnum+1, raw_buffer+4);	  printf_filtered ("(d%d: ", regnum-FP0_REGNUM);	  val_print (builtin_type_double, raw_buffer, 0,		     stdout, 0, 1, 0, Val_pretty_default);	  printf_filtered ("); ");      }      fputs_filtered (reg_names[regnum], stdout);#ifndef NUMERIC_REG_NAMES      if (regnum < 32)	  printf_filtered ("(r%d): ", regnum);      else#endif	  printf_filtered (": ");      /* If virtual format is floating, print it that way.  */      if (TYPE_CODE (REGISTER_VIRTUAL_TYPE (regnum)) == TYPE_CODE_FLT	  && ! INVALID_FLOAT (raw_buffer, REGISTER_VIRTUAL_SIZE(regnum))) {	  val_print (REGISTER_VIRTUAL_TYPE (regnum), raw_buffer, 0,		     stdout, 0, 1, 0, Val_pretty_default);      }      /* Else print as integer in hex.  */      else	{	  long val;	  bcopy (raw_buffer, &val, sizeof (long));	  SWAP_TARGET_AND_HOST ((char *)&val, sizeof (long));	  if (val == 0)	    printf_filtered ("0");	  else if (all)	    printf_filtered (local_hex_format(), val);	  else	    printf_filtered ("%s=%d", local_hex_string(val), val);	}}/* Replacement for generic do_registers_info.  */voidmips_do_registers_info (regnum, fpregs)     int regnum;     int fpregs;{  if (regnum != -1) {      mips_print_register (regnum, 0);      printf_filtered ("\n");  }  else {      for (regnum = 0; regnum < NUM_REGS; ) {	  if ((!fpregs) && regnum >= FP0_REGNUM && regnum <= FCRIR_REGNUM) {	    regnum++;	    continue;	  }	  mips_print_register (regnum, 1);	  regnum++;	  if ((regnum & 3) == 0 || regnum == NUM_REGS)	      printf_filtered (";\n");	  else	      printf_filtered ("; ");      }  }}/* Return number of args passed to a frame. described by FIP.   Can return -1, meaning no way to tell.  */intmips_frame_num_args(fip)	FRAME fip;{#if 0	struct chain_info_t *p;	p = mips_find_cached_frame(FRAME_FP(fip));	if (p->valid)		return p->the_info.numargs;#endif	return -1;}/* Bad floats: Returns 0 if P points to a valid IEEE floating point number,   1 if P points to a denormalized number or a NaN. LEN says whether this is   a single-precision or double-precision float */#define SINGLE_EXP_BITS  8#define DOUBLE_EXP_BITS 11intisa_NAN(p, len)     int *p, len;{  int exponent;  if (len == 4)    {      exponent = *p;      exponent = exponent << 1 >> (32 - SINGLE_EXP_BITS - 1);      return ((exponent == -1) || (! exponent && *p));    }  else if (len == 8)    {      exponent = *(p+1);      exponent = exponent << 1 >> (32 - DOUBLE_EXP_BITS - 1);      return ((exponent == -1) || (! exponent && *p * *(p+1)));    }  else return 1;}/* To skip prologues, I use this predicate. Returns either PC   itself if the code at PC does not look like a function prologue,   PC+4 if it does (our caller does not need anything more fancy). */CORE_ADDRmips_skip_prologue(pc)     CORE_ADDR pc;{    struct symbol *f;    struct block *b;    unsigned long inst;    int offset;    /* For -g modules and most functions anyways the       first instruction adjusts the stack.       But we allow some number of stores before the stack adjustment.       (These are emitted by varags functions compiled by gcc-2.0. */    for (offset = 0; offset < 100; offset += 4) {	inst = read_memory_integer(pc + offset, 4);	if ((inst & 0xffff0000) == 0x27bd0000) /* addiu $sp,$sp,offset */	    return pc + offset + 4;	if ((inst & 0xFFE00000) != 0xAFA00000) /* sw reg,n($sp) */	    break;    }    /* Well, it looks like a frameless. Let's make sure.       Note that we are not called on the current PC,       but on the function`s start PC, and I have definitely       seen optimized code that adjusts the SP quite later */    b = block_for_pc(pc);    if (!b) return pc;    f = lookup_symbol(MIPS_EFI_SYMBOL_NAME, b, LABEL_NAMESPACE, 0, NULL);    if (!f) return pc;    /* Ideally, I would like to use the adjusted info       from mips_frame_info(), but for all practical       purposes it will not matter (and it would require       a different definition of SKIP_PROLOGUE())       Actually, it would not hurt to skip the storing       of arguments on the stack as well. */    if (((mips_extra_func_info_t)SYMBOL_VALUE(f))->pdr.frameoffset)	return pc + 4;    return pc;}#ifdef KERNELDEBUG/*XXX*/CORE_ADDR intstack_top;CORE_ADDR intstack_bottom;CORE_ADDR kernstack_top;CORE_ADDR kernstack_bottom;CORE_ADDR trap_pc_start;CORE_ADDR trap_pc_end;intin_trap_handler(pc)	CORE_ADDR pc;{	return (pc >= trap_pc_start && pc <= trap_pc_end);}intinside_kernstack(addr)	CORE_ADDR addr;{	return (addr < kernstack_top && addr >= kernstack_bottom);}/* * (re-)set the variables that make inside_kernstack() work. */voidset_kernel_boundaries(){        if (trap_pc_start == 0) {		trap_pc_start = ksym_lookup("trap_handler_start");		trap_pc_end = ksym_lookup("trap_handler_end");        }        kernstack_bottom = UADDR + sizeof(struct user);        kernstack_top = KERNELSTACK;}/* * Called from remote_wait, after the remote kernel has stopped. * Look up the current proc, and set up boundaries. * This is for active kernels only. */voidset_curproc(){#ifdef notdef	cpudata = fetch_cpudata();#endif	set_kernel_boundaries();}/* * Fetch registers from a crashdump or /dev/kmem. */voidkvm_fetch_registers(uaddr)	CORE_ADDR uaddr;{	int i;	u_long cps, reg, sp;	float freg;	struct pcb pcb;	if (target_read_memory(uaddr, (char *)&pcb, sizeof(pcb)) != 0)		error("cannot read pcb at 0x%x", uaddr);	/*	 * Invalidate all the registers then fill in the ones we know about.	 */	registers_changed();	for (i = 0; i < 32; ++i)		supply_register(i, (char *)&pcb.pcb_regs[i]);	supply_register(PC_REGNUM, (char *)&pcb.pcb_pc);	supply_register(PS_REGNUM, (char *)&pcb.pcb_sr);}/* * Set the process context to that of the proc structure at * system address paddr.  Read in the register state. */intset_procaddr(addr)	CORE_ADDR addr;{	if (addr == 0)		addr = ksym_lookup("u");#ifdef notdef	if (addr < KERNELBASE)		return (1);#endif	set_kernel_boundaries();	kvm_fetch_registers(addr);	return (0);}/* * Get the registers out of a crashdump or /dev/kmem. * XXX This somehow belongs in kcore.c. * * We just get all the registers, so we don't use regno. *//* ARGSUSED */voidkernel_core_registers(regno)	int regno;{	/*	 * Need to find current u area to get kernel stack and pcb	 * where "panic" saved registers.	 * (libkvm also needs to know current u area to get user	 * address space mapping).	 */	/* XXX */	(void)set_procaddr(0);}#endif

⌨️ 快捷键说明

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