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

📄 rs6000-tdep.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 3 页
字号:
        bcopy (VALUE_CONTENTS (arg),            &registers[REGISTER_BYTE(FP0_REGNUM + 1 + f_argno)], len);        ++f_argno;      }      write_memory (sp+24+(ii*4), VALUE_CONTENTS (arg), len);      ii += ((len + 3) & -4) / 4;    }  }  else    /* Secure stack areas first, before doing anything else. */    write_register (SP_REGNUM, sp);  saved_sp = dummy_frame_addr [dummy_frame_count - 1];  read_memory (saved_sp, tmp_buffer, 24);  write_memory (sp, tmp_buffer, 24);    write_memory (sp, &saved_sp, 4);	/* set back chain properly */  target_store_registers (-1);  return sp;}/* a given return value in `regbuf' with a type `valtype', extract and copy its   value into `valbuf' */voidextract_return_value (valtype, regbuf, valbuf)  struct type *valtype;  char regbuf[REGISTER_BYTES];  char *valbuf;{  if (TYPE_CODE (valtype) == TYPE_CODE_FLT) {    double dd; float ff;    /* floats and doubles are returned in fpr1. fpr's have a size of 8 bytes.       We need to truncate the return value into float size (4 byte) if       necessary. */    if (TYPE_LENGTH (valtype) > 4) 		/* this is a double */      bcopy (&regbuf[REGISTER_BYTE (FP0_REGNUM + 1)], valbuf, 						TYPE_LENGTH (valtype));    else {		/* float */      bcopy (&regbuf[REGISTER_BYTE (FP0_REGNUM + 1)], &dd, 8);      ff = (float)dd;      bcopy (&ff, valbuf, sizeof(float));    }  }  else    /* return value is copied starting from r3. */    bcopy (&regbuf[REGISTER_BYTE (3)], valbuf, TYPE_LENGTH (valtype));}/* keep structure return address in this variable.   FIXME:  This is a horrid kludge which should not be allowed to continue   living.  This only allows a single nested call to a structure-returning   function.  Come on, guys!  -- gnu@cygnus.com, Aug 92  */CORE_ADDR rs6000_struct_return_address;/* Throw away this debugging code. FIXMEmgo. */voidprint_frame(fram)int fram;{  int ii, val;  for (ii=0; ii<40; ++ii) {    if ((ii % 4) == 0)      printf ("\n");    val = read_memory_integer (fram + ii * 4, 4);    printf ("0x%08x\t", val);  }  printf ("\n");}/* Indirect function calls use a piece of trampoline code to do context   switching, i.e. to set the new TOC table. Skip such code if we are on   its first instruction (as when we have single-stepped to here).    Result is desired PC to step until, or NULL if we are not in   trampoline code.  */CORE_ADDRskip_trampoline_code (pc)CORE_ADDR pc;{  register unsigned int ii, op;  static unsigned trampoline_code[] = {	0x800b0000,			/*     l   r0,0x0(r11)	*/	0x90410014,			/*    st   r2,0x14(r1)	*/	0x7c0903a6,			/* mtctr   r0		*/	0x804b0004,			/*     l   r2,0x4(r11)	*/	0x816b0008,			/*     l  r11,0x8(r11)	*/	0x4e800420,			/*  bctr		*/	0x4e800020,			/*    br		*/	0  };  for (ii=0; trampoline_code[ii]; ++ii) {    op  = read_memory_integer (pc + (ii*4), 4);    if (op != trampoline_code [ii])      return NULL;  }  ii = read_register (11);		/* r11 holds destination addr	*/  pc = read_memory_integer (ii, 4);	/* (r11) value			*/  return pc;}/* Determines whether the function FI has a frame on the stack or not.   Called from the FRAMELESS_FUNCTION_INVOCATION macro in tm.h.  */intframeless_function_invocation (fi)struct frame_info *fi;{  CORE_ADDR func_start;  struct aix_framedata fdata;  func_start = get_pc_function_start (fi->pc) + FUNCTION_START_OFFSET;  /* If we failed to find the start of the function, it is a mistake     to inspect the instructions. */  if (!func_start)    return 0;  function_frame_info (func_start, &fdata);  return fdata.frameless;}/* If saved registers of frame FI are not known yet, read and cache them.   &FDATAP contains aix_framedata; TDATAP can be NULL,   in which case the framedata are read.  */static voidframe_get_cache_fsr (fi, fdatap)     struct frame_info *fi;     struct aix_framedata *fdatap;{  int ii;  CORE_ADDR frame_addr;   struct aix_framedata work_fdata;  if (fi->cache_fsr)    return;    if (fdatap == NULL) {    fdatap = &work_fdata;    function_frame_info (get_pc_function_start (fi->pc), fdatap);  }  fi->cache_fsr = (struct frame_saved_regs *)      obstack_alloc (&frame_cache_obstack, sizeof (struct frame_saved_regs));  bzero (fi->cache_fsr, sizeof (struct frame_saved_regs));  if (fi->prev && fi->prev->frame)    frame_addr = fi->prev->frame;  else    frame_addr = read_memory_integer (fi->frame, 4);    /* if != -1, fdatap->saved_fpr is the smallest number of saved_fpr.     All fpr's from saved_fpr to fp31 are saved right underneath caller     stack pointer, starting from fp31 first. */  if (fdatap->saved_fpr >= 0) {    for (ii=31; ii >= fdatap->saved_fpr; --ii)      fi->cache_fsr->regs [FP0_REGNUM + ii] = frame_addr - ((32 - ii) * 8);    frame_addr -= (32 - fdatap->saved_fpr) * 8;  }  /* if != -1, fdatap->saved_gpr is the smallest number of saved_gpr.     All gpr's from saved_gpr to gpr31 are saved right under saved fprs,     starting from r31 first. */    if (fdatap->saved_gpr >= 0)    for (ii=31; ii >= fdatap->saved_gpr; --ii)      fi->cache_fsr->regs [ii] = frame_addr - ((32 - ii) * 4);}/* Return the address of a frame. This is the inital %sp value when the frame   was first allocated. For functions calling alloca(), it might be saved in   an alloca register. */CORE_ADDRframe_initial_stack_address (fi)     struct frame_info *fi;{  CORE_ADDR tmpaddr;  struct aix_framedata fdata;  struct frame_info *callee_fi;  /* if the initial stack pointer (frame address) of this frame is known,     just return it. */  if (fi->initial_sp)    return fi->initial_sp;  /* find out if this function is using an alloca register.. */  function_frame_info (get_pc_function_start (fi->pc), &fdata);  /* if saved registers of this frame are not known yet, read and cache them. */  if (!fi->cache_fsr)    frame_get_cache_fsr (fi, &fdata);  /* If no alloca register used, then fi->frame is the value of the %sp for     this frame, and it is good enough. */  if (fdata.alloca_reg < 0) {    fi->initial_sp = fi->frame;    return fi->initial_sp;  }  /* This function has an alloca register. If this is the top-most frame     (with the lowest address), the value in alloca register is good. */  if (!fi->next)    return fi->initial_sp = read_register (fdata.alloca_reg);       /* Otherwise, this is a caller frame. Callee has usually already saved     registers, but there are exceptions (such as when the callee     has no parameters). Find the address in which caller's alloca     register is saved. */  for (callee_fi = fi->next; callee_fi; callee_fi = callee_fi->next) {    if (!callee_fi->cache_fsr)      frame_get_cache_fsr (fi, NULL);    /* this is the address in which alloca register is saved. */    tmpaddr = callee_fi->cache_fsr->regs [fdata.alloca_reg];    if (tmpaddr) {      fi->initial_sp = read_memory_integer (tmpaddr, 4);       return fi->initial_sp;    }    /* Go look into deeper levels of the frame chain to see if any one of       the callees has saved alloca register. */  }  /* If alloca register was not saved, by the callee (or any of its callees)     then the value in the register is still good. */  return fi->initial_sp = read_register (fdata.alloca_reg);     }/* xcoff_relocate_symtab -	hook for symbol table relocation.   also reads shared libraries.. */xcoff_relocate_symtab (pid)unsigned int pid;{#define	MAX_LOAD_SEGS 64		/* maximum number of load segments */    struct ld_info *ldi;    int temp;    ldi = (void *) alloca(MAX_LOAD_SEGS * sizeof (*ldi));    /* According to my humble theory, AIX has some timing problems and       when the user stack grows, kernel doesn't update stack info in time       and ptrace calls step on user stack. That is why we sleep here a little,       and give kernel to update its internals. */    usleep (36000);    errno = 0;    ptrace(PT_LDINFO, pid, (PTRACE_ARG3_TYPE) ldi,	   MAX_LOAD_SEGS * sizeof(*ldi), ldi);    if (errno) {      perror_with_name ("ptrace ldinfo");      return 0;    }    vmap_ldinfo(ldi);   do {     add_text_to_loadinfo (ldi->ldinfo_textorg, ldi->ldinfo_dataorg);    } while (ldi->ldinfo_next	     && (ldi = (void *) (ldi->ldinfo_next + (char *) ldi)));#if 0  /* Now that we've jumbled things around, re-sort them.  */  sort_minimal_symbols ();#endif  /* relocate the exec and core sections as well. */  vmap_exec ();}/* Keep an array of load segment information and their TOC table addresses.   This info will be useful when calling a shared library function by hand. */   struct loadinfo {  CORE_ADDR textorg, dataorg;  unsigned long toc_offset;};#define	LOADINFOLEN	10/* FIXME Warning -- loadinfotextindex is used for a nefarious purpose by   tm-rs6000.h.  */static	struct loadinfo *loadinfo = NULL;static	int	loadinfolen = 0;static	int	loadinfotocindex = 0;int	loadinfotextindex = 0;voidxcoff_init_loadinfo (){  loadinfotocindex = 0;  loadinfotextindex = 0;  if (loadinfolen == 0) {    loadinfo = (struct loadinfo *)               xmalloc (sizeof (struct loadinfo) * LOADINFOLEN);    loadinfolen = LOADINFOLEN;  }}/* FIXME -- this is never called!  */voidfree_loadinfo (){  if (loadinfo)    free (loadinfo);  loadinfo = NULL;  loadinfolen = 0;  loadinfotocindex = 0;  loadinfotextindex = 0;}/* this is called from xcoffread.c */voidxcoff_add_toc_to_loadinfo (unsigned long tocoff){  while (loadinfotocindex >= loadinfolen) {    loadinfolen += LOADINFOLEN;    loadinfo = (struct loadinfo *)               xrealloc (loadinfo, sizeof(struct loadinfo) * loadinfolen);  }  loadinfo [loadinfotocindex++].toc_offset = tocoff;}static voidadd_text_to_loadinfo (textaddr, dataaddr)     CORE_ADDR textaddr;     CORE_ADDR dataaddr;{  while (loadinfotextindex >= loadinfolen) {    loadinfolen += LOADINFOLEN;    loadinfo = (struct loadinfo *)               xrealloc (loadinfo, sizeof(struct loadinfo) * loadinfolen);  }  loadinfo [loadinfotextindex].textorg = textaddr;  loadinfo [loadinfotextindex].dataorg = dataaddr;  ++loadinfotextindex;}/* FIXME:  This assumes that the "textorg" and "dataorg" elements   of a member of this array are correlated with the "toc_offset"   element of the same member.  But they are sequentially assigned in wildly   different places, and probably there is no correlation.  FIXME!  */static CORE_ADDRfind_toc_address (pc)     CORE_ADDR pc;{  int ii, toc_entry, tocbase = 0;  for (ii=0; ii < loadinfotextindex; ++ii)    if (pc > loadinfo[ii].textorg && loadinfo[ii].textorg > tocbase) {      toc_entry = ii;      tocbase = loadinfo[ii].textorg;    }  return loadinfo[toc_entry].dataorg + loadinfo[toc_entry].toc_offset;}

⌨️ 快捷键说明

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