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

📄 tm-pn.h

📁 早期freebsd实现
💻 H
📖 第 1 页 / 共 2 页
字号:
   to be actual register numbers as far as the user is concerned   but do serve to get the desired values when passed to read_register.  */#define R1_REGNUM	1	/* Gr1 => return address of caller */#define R4_REGNUM	4	/* Gr4 => register save area */#define R5_REGNUM	5	/* Gr5 => register save area */#define R6_REGNUM	6	/* Gr6 => register save area */#define R7_REGNUM	7	/* Gr7 => register save area */#define B1_REGNUM	9	/* Br1 => start of this code routine */#define FP_REGNUM	10	/* Br2 == (sp) */#define AP_REGNUM	11	/* Br3 == (ap) */#define SP_REGNUM 	16	/* A copy of Br2 saved in trap */#define PS_REGNUM 	17	/* Contains processor status */#define PC_REGNUM 	18	/* Contains program counter *//* Total amount of space needed to store our copies of the machine's   register state, the array `registers'.  */#define REGISTER_BYTES			(NUM_GEN_REGS*4 + NUM_CPU_REGS*4)/* Index within `registers' of the first byte of the space for   register N.  */#define REGISTER_BYTE(N)  		((N) * 4)/* Number of bytes of storage in the actual machine representation   for register N.  On the PN, all normal regs are 4 bytes. */#define REGISTER_RAW_SIZE(N) 		(4)/* Number of bytes of storage in the program's representation   for register N.  On the PN, all regs are 4 bytes. */#define REGISTER_VIRTUAL_SIZE(N)	(4)/* Largest value REGISTER_RAW_SIZE can have.  */#define MAX_REGISTER_RAW_SIZE		(4)/* Largest value REGISTER_VIRTUAL_SIZE can have.  */#define MAX_REGISTER_VIRTUAL_SIZE	(4)/* Nonzero if register N requires conversion   from raw format to virtual format.  */#define REGISTER_CONVERTIBLE(N)		(0)/* Convert data from raw format for register REGNUM   to virtual format for register REGNUM.  */#define REGISTER_CONVERT_TO_VIRTUAL(REGNUM,FROM,TO)	\	bcopy ((FROM), (TO), REGISTER_RAW_SIZE(REGNUM));/* Convert data from virtual format for register REGNUM   to raw format for register REGNUM.  */#define REGISTER_CONVERT_TO_RAW(REGNUM,FROM,TO)	\	bcopy ((FROM), (TO), REGISTER_VIRTUAL_SIZE(REGNUM));/* Return the GDB type object for the "standard" data type   of data in register N.  */#define REGISTER_VIRTUAL_TYPE(N)	(builtin_type_int)/* Store the address of the place in which to copy the structure the   subroutine will return.  This is called from call_function.   On this machine this is a no-op, because gcc isn't used on it   yet.  So this calling convention is not used. */#define STORE_STRUCT_RETURN(ADDR, SP)/* Extract from an arrary REGBUF containing the (raw) register state   a function return value of type TYPE, and copy that, in virtual format,   into VALBUF. */#define EXTRACT_RETURN_VALUE(TYPE,REGBUF,VALBUF) \	bcopy (REGBUF, VALBUF, TYPE_LENGTH (TYPE))/* Write into appropriate registers a function return value   of type TYPE, given in virtual format.  */#define STORE_RETURN_VALUE(TYPE,VALBUF) \	write_register_bytes (0, VALBUF, TYPE_LENGTH (TYPE))/* Extract from an array REGBUF containing the (raw) register state   the address in which a function should return its structure value,   as a CORE_ADDR (or an expression that can be used as one).  */#define EXTRACT_STRUCT_VALUE_ADDRESS(REGBUF) (*(int *)(REGBUF))/* Describe the pointer in each stack frame to the previous stack frame   (its caller).  *//* FRAME_CHAIN takes a frame's nominal address   and produces the frame's chain-pointer.   However, if FRAME_CHAIN_VALID returns zero,   it means the given frame is the outermost one and has no caller.  *//* In the case of the NPL, the frame's norminal address is Br2 and the    previous routines frame is up the stack X bytes, where X is the   value stored in the code function header xA(Br1). */#define FRAME_CHAIN(thisframe)		(findframe(thisframe))#define FRAME_CHAIN_VALID(chain, thisframe) \        (chain != 0 && chain != (thisframe)->frame)/* Define other aspects of the stack frame on NPL.  */#define FRAME_SAVED_PC(frame) \	(read_memory_integer ((frame)->frame + 8, 4))#define FRAME_ARGS_ADDRESS(fi) \	((fi)->next_frame ? \	 read_memory_integer ((fi)->frame + 12, 4) : \	 read_register (AP_REGNUM))#define FRAME_LOCALS_ADDRESS(fi)	((fi)->frame + 80)/* Set VAL to the number of args passed to frame described by FI.   Can set VAL to -1, meaning no way to tell.  *//* We can check the stab info to see how   many arg we have.  No info in stack will tell us */#define FRAME_NUM_ARGS(val,fi)		(val = findarg(fi))/* Return number of bytes at start of arglist that are not really args.  */#define FRAME_ARGS_SKIP			8/* Put here the code to store, into a struct frame_saved_regs,   the addresses of the saved registers of frame described by FRAME_INFO.   This includes special registers such as pc and fp saved in special   ways in the stack frame.  sp is even more special:   the address we return for it IS the sp for the next frame.  */#define FRAME_FIND_SAVED_REGS(frame_info, frame_saved_regs)		\{                                                                       \  bzero (&frame_saved_regs, sizeof frame_saved_regs);			\  (frame_saved_regs).regs[PC_REGNUM] = (frame_info)->frame + 8;		\  (frame_saved_regs).regs[R4_REGNUM] = (frame_info)->frame + 0x30;	\  (frame_saved_regs).regs[R5_REGNUM] = (frame_info)->frame + 0x34;	\  (frame_saved_regs).regs[R6_REGNUM] = (frame_info)->frame + 0x38;	\  (frame_saved_regs).regs[R7_REGNUM] = (frame_info)->frame + 0x3C;	\}/* Things needed for making the inferior call functions.  *//* Push an empty stack frame, to record the current PC, etc.  */#define PUSH_DUMMY_FRAME \{ register CORE_ADDR sp = read_register (SP_REGNUM);			\  register int regnum;							\  sp = push_word (sp, read_register (PC_REGNUM));			\  sp = push_word (sp, read_register (FP_REGNUM));			\  write_register (FP_REGNUM, sp);					\  for (regnum = FP_REGNUM - 1; regnum >= 0; regnum--)			\    sp = push_word (sp, read_register (regnum));			\  sp = push_word (sp, read_register (PS_REGNUM));			\  write_register (SP_REGNUM, sp);  }/* Discard from the stack the innermost frame,    restoring all saved registers.  */#define POP_FRAME  \{ register FRAME frame = get_current_frame ();			 \  register CORE_ADDR fp;					 \  register int regnum;						 \  struct frame_saved_regs fsr;					 \  struct frame_info *fi;					 \  fi = get_frame_info (frame);					 \  fp = fi->frame;						 \  get_frame_saved_regs (fi, &fsr);				 \  for (regnum = FP_REGNUM - 1; regnum >= 0; regnum--)		 \    if (fsr.regs[regnum])					 \      write_register (regnum, read_memory_integer (fsr.regs[regnum], 4)); \  if (fsr.regs[PS_REGNUM])					 \    write_register (PS_REGNUM, read_memory_integer (fsr.regs[PS_REGNUM], 4)); \  write_register (FP_REGNUM, read_memory_integer (fp, 4));	 \  write_register (PC_REGNUM, read_memory_integer (fp + 4, 4));   \  write_register (SP_REGNUM, fp + 8);				 \  flush_cached_frames ();					 \  set_current_frame ( create_new_frame (read_register (FP_REGNUM),\					read_pc ())); }/* This sequence of words is the instructions:     halt     halt     halt     halt     suabr	b2, #<stacksize>     lwbr	b6, #con     stw	r1, 8(b2)	- save caller address, do we care?     lw		r2, 60(b2)	- arg1     labr	b3, 50(b2)     std	r4, 30(b2)	- save r4-r7     std	r6, 38(b2)     lwbr	b1, #<func>	- load function call address     brlnk	r1, 8(b1)	- call function     halt     halt     ld		r4, 30(b2)	- restore r4-r7     ld		r6, 38(b2)   Setup our stack frame, load argumemts, call and then restore registers.*//* FIXME:  The below defines an m68k CALL_DUMMY, which looks nothing like what   is documented above. */#define CALL_DUMMY {0xf227e0ff, 0x48e7fffc, 0x426742e7, 0x4eb93232, 0x3232dffc, 0x69696969, 0x4e4f4e71}#define CALL_DUMMY_LENGTH 28#define CALL_DUMMY_START_OFFSET 12/* Insert the specified number of args and function address   into a call sequence of the above form stored at DUMMYNAME.  */#define FIX_CALL_DUMMY(dummyname, pc, fun, nargs, args, type, gcc_p)     \{ *(int *)((char *) dummyname + 20) = nargs * 4;  \  *(int *)((char *) dummyname + 14) = fun; }

⌨️ 快捷键说明

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