📄 tm-convex.h
字号:
and to describe the files. */#define XFER_CORE_FILE#define FILES_INFO_HOOK print_maps/* Hook to call to print a typeless integer value, normally printed in decimal. For convex, use hex instead if the number looks like an address. */#define PRINT_TYPELESS_INTEGER decout/* For the native compiler, variables for a particular lexical context are listed after the beginning LBRAC instead of before in the executables list of symbols. Using "gcc_compiled." to distinguish between GCC and native compiler doesn't work on Convex because the linker sorts the symbols to put "gcc_compiled." in the wrong place. desc is nonzero for native, zero for gcc. */#define VARIABLES_INSIDE_BLOCK(desc, gcc_p) (desc != 0)/* Pcc occaisionally puts an SO where there should be an SOL. */#define PCC_SOL_BROKEN/* Describe the pointer in each stack frame to the previous stack frame (its caller). *//* FRAME_CHAIN takes a frame_info with a frame's nominal address in fi->frame, and produces the frame's chain-pointer. *//* (caller fp is saved at 8(fp)) */#define FRAME_CHAIN(fi) (read_memory_integer ((fi)->frame + 8, 4))/* Define other aspects of the stack frame. *//* We need the boundaries of the text in the exec file, as a kludge, for FRAMELESS_FUNCTION_INVOCATION and CALL_DUMMY_LOCATION. */#define NEED_TEXT_START_END/* A macro that tells us whether the function invocation represented by FI does not have a frame on the stack associated with it. If it does not, FRAMELESS is set to 1, else 0. On convex, check at the return address for `callq' -- if so, frameless, otherwise, not. */#define FRAMELESS_FUNCTION_INVOCATION(FI, FRAMELESS) \{ \ extern CORE_ADDR text_start, text_end; \ CORE_ADDR call_addr = SAVED_PC_AFTER_CALL (FI); \ (FRAMELESS) = (call_addr >= text_start && call_addr < text_end \ && read_memory_integer (call_addr - 6, 1) == 0x22); \}#define FRAME_SAVED_PC(fi) (read_memory_integer ((fi)->frame, 4))#define FRAME_ARGS_ADDRESS(fi) (read_memory_integer ((fi)->frame + 12, 4))#define FRAME_LOCALS_ADDRESS(fi) (fi)->frame/* Return number of args passed to a frame. Can return -1, meaning no way to tell. */#define FRAME_NUM_ARGS(numargs, fi) \{ numargs = read_memory_integer (FRAME_ARGS_ADDRESS (fi) - 4, 4); \ if (numargs < 0 || numargs >= 256) numargs = -1;}/* Return number of bytes at start of arglist that are not really args. */#define FRAME_ARGS_SKIP 0/* 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. *//* Normal (short) frames save only PC, FP, (callee's) AP. To reasonably handle gcc and pcc register variables, scan the code following the call for the instructions the compiler inserts to reload register variables from stack slots and record the stack slots as the saved locations of those registers. This will occasionally identify some random load as a saved register; this is harmless. vc does not declare its register allocation actions in the stabs. */#define FRAME_FIND_SAVED_REGS(frame_info, frame_saved_regs) \{ register int regnum; \ register int frame_length = /* 3 short, 2 long, 1 extended, 0 context */\ (read_memory_integer ((frame_info)->frame + 4, 4) >> 25) & 3; \ register CORE_ADDR frame_fp = \ read_memory_integer ((frame_info)->frame + 8, 4); \ register CORE_ADDR next_addr; \ bzero (&frame_saved_regs, sizeof frame_saved_regs); \ (frame_saved_regs).regs[PC_REGNUM] = (frame_info)->frame + 0; \ (frame_saved_regs).regs[PS_REGNUM] = (frame_info)->frame + 4; \ (frame_saved_regs).regs[FP_REGNUM] = (frame_info)->frame + 8; \ (frame_saved_regs).regs[AP_REGNUM] = frame_fp + 12; \ next_addr = (frame_info)->frame + 12; \ if (frame_length < 3) \ for (regnum = A5_REGNUM; regnum < SP_REGNUM; ++regnum) \ (frame_saved_regs).regs[regnum] = (next_addr += 4); \ if (frame_length < 2) \ (frame_saved_regs).regs[SP_REGNUM] = (next_addr += 4); \ next_addr -= 4; \ if (frame_length < 3) \ for (regnum = S7_REGNUM; regnum < S0_REGNUM; ++regnum) \ (frame_saved_regs).regs[regnum] = (next_addr += 8); \ if (frame_length < 2) \ (frame_saved_regs).regs[S0_REGNUM] = (next_addr += 8); \ else \ (frame_saved_regs).regs[SP_REGNUM] = next_addr + 8; \ if (frame_length == 3) { \ CORE_ADDR pc = read_memory_integer ((frame_info)->frame, 4); \ int op, ix, disp; \ op = read_memory_integer (pc, 2); \ if ((op & 0xffc7) == 0x1480) pc += 4; /* add.w #-,sp */ \ else if ((op & 0xffc7) == 0x58c0) pc += 2; /* add.w #-,sp */ \ op = read_memory_integer (pc, 2); \ if ((op & 0xffc7) == 0x2a06) pc += 4; /* ld.w -,ap */ \ for (;;) { \ op = read_memory_integer (pc, 2); \ ix = (op >> 3) & 7; \ if ((op & 0xfcc0) == 0x2800) { /* ld.- -,ak */ \ regnum = SP_REGNUM - (op & 7); \ disp = read_memory_integer (pc + 2, 2); \ pc += 4;} \ else if ((op & 0xfcc0) == 0x2840) { /* ld.- -,ak */ \ regnum = SP_REGNUM - (op & 7); \ disp = read_memory_integer (pc + 2, 4); \ pc += 6;} \ if ((op & 0xfcc0) == 0x3000) { /* ld.- -,sk */ \ regnum = S0_REGNUM - (op & 7); \ disp = read_memory_integer (pc + 2, 2); \ pc += 4;} \ else if ((op & 0xfcc0) == 0x3040) { /* ld.- -,sk */ \ regnum = S0_REGNUM - (op & 7); \ disp = read_memory_integer (pc + 2, 4); \ pc += 6;} \ else if ((op & 0xff00) == 0x7100) { /* br crossjump */ \ pc += 2 * (char) op; \ continue;} \ else if (op == 0x0140) { /* jmp crossjump */ \ pc = read_memory_integer (pc + 2, 4); \ continue;} \ else break; \ if ((frame_saved_regs).regs[regnum]) \ break; \ if (ix == 7) disp += frame_fp; \ else if (ix == 6) disp += read_memory_integer (frame_fp + 12, 4); \ else if (ix != 0) break; \ (frame_saved_regs).regs[regnum] = \ disp - 8 + (1 << ((op >> 8) & 3)); \ if (regnum >= S7_REGNUM) \ (frame_saved_regs).regs[regnum - S0_REGNUM + s0_REGNUM] = \ disp - 4 + (1 << ((op >> 8) & 3)); \ } \ } \}/* Things needed for making the inferior call functions. */#define CALL_DUMMY_LOCATION BEFORE_TEXT_END/* 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; \ char buf[8]; \ long word; \ for (regnum = S0_REGNUM; regnum >= S7_REGNUM; --regnum) { \ read_register_bytes (REGISTER_BYTE (regnum), buf, 8); \ sp = push_bytes (sp, buf, 8);} \ for (regnum = SP_REGNUM; regnum >= FP_REGNUM; --regnum) { \ word = read_register (regnum); \ sp = push_bytes (sp, &word, 4);} \ word = (read_register (PS_REGNUM) &~ (3<<25)) | (1<<25); \ sp = push_bytes (sp, &word, 4); \ word = read_register (PC_REGNUM); \ sp = push_bytes (sp, &word, 4); \ write_register (SP_REGNUM, sp); \ write_register (FP_REGNUM, sp); \ write_register (AP_REGNUM, sp);}/* Discard from the stack the innermost frame, restoring all registers. */#define POP_FRAME do {\ register CORE_ADDR fp = read_register (FP_REGNUM); \ register int regnum; \ register int frame_length = /* 3 short, 2 long, 1 extended, 0 context */ \ (read_memory_integer (fp + 4, 4) >> 25) & 3; \ char buf[8]; \ write_register (PC_REGNUM, read_memory_integer (fp, 4)); \ write_register (PS_REGNUM, read_memory_integer (fp += 4, 4)); \ write_register (FP_REGNUM, read_memory_integer (fp += 4, 4)); \ write_register (AP_REGNUM, read_memory_integer (fp += 4, 4)); \ if (frame_length < 3) \ for (regnum = A5_REGNUM; regnum < SP_REGNUM; ++regnum) \ write_register (regnum, read_memory_integer (fp += 4, 4)); \ if (frame_length < 2) \ write_register (SP_REGNUM, read_memory_integer (fp += 4, 4)); \ fp -= 4; \ if (frame_length < 3) \ for (regnum = S7_REGNUM; regnum < S0_REGNUM; ++regnum) { \ read_memory (fp += 8, buf, 8); \ write_register_bytes (REGISTER_BYTE (regnum), buf, 8);} \ if (frame_length < 2) { \ read_memory (fp += 8, buf, 8); \ write_register_bytes (REGISTER_BYTE (regnum), buf, 8);} \ else write_register (SP_REGNUM, fp + 8); \ flush_cached_frames (); \ set_current_frame (create_new_frame (read_register (FP_REGNUM), \ read_pc ())); \} while (0)/* This sequence of words is the instructions mov sp,ap pshea 69696969 calls 32323232 bkpt Note this is 16 bytes. */#define CALL_DUMMY {0x50860d4069696969LL,0x2140323232327d50LL}#define CALL_DUMMY_LENGTH 16#define CALL_DUMMY_START_OFFSET 0/* 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 + 4) = nargs; \ *(int *)((char *) dummyname + 10) = fun; }/* Defs to read soff symbol tables, see dbxread.c */#define NUMBER_OF_SYMBOLS ((long) opthdr.o_nsyms)#define STRING_TABLE_OFFSET ((long) filehdr.h_strptr)#define SYMBOL_TABLE_OFFSET ((long) opthdr.o_symptr)#define STRING_TABLE_SIZE ((long) filehdr.h_strsiz)#define SIZE_OF_TEXT_SEGMENT ((long) txthdr.s_size)#define ENTRY_POINT ((long) opthdr.o_entry)#define READ_STRING_TABLE_SIZE(BUFFER) \ (BUFFER = STRING_TABLE_SIZE)#define DECLARE_FILE_HEADERS \ FILEHDR filehdr; \ OPTHDR opthdr; \ SCNHDR txthdr#define READ_FILE_HEADERS(DESC,NAME) \{ \ int n; \ val = myread (DESC, &filehdr, sizeof filehdr); \ if (val < 0) \ perror_with_name (NAME); \ if (! IS_SOFF_MAGIC (filehdr.h_magic)) \ error ("%s: not an executable file.", NAME); \ lseek (DESC, 0L, 0); \ if (myread (DESC, &filehdr, sizeof filehdr) < 0) \ perror_with_name (NAME); \ if (myread (DESC, &opthdr, filehdr.h_opthdr) <= 0) \ perror_with_name (NAME); \ for (n = 0; n < filehdr.h_nscns; n++) \ { \ if (myread (DESC, &txthdr, sizeof txthdr) < 0) \ perror_with_name (NAME); \ if ((txthdr.s_flags & S_TYPMASK) == S_TEXT) \ break; \ } \}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -