📄 hppab-tdep.c
字号:
vtop_command(arg) char *arg;{ u_int sp, off, pa; if (!arg) error_no_arg("kernel virtual address"); if (!kernel_debugging) error("not debugging kernel"); sp = 0; /* XXX */ off = (u_int) parse_and_eval_address(arg); pa = vtophys(sp, off); printf("%lx.%lx -> ", sp, off); if (pa == ~0) printf("<invalid>\n"); else printf("%lx\n", pa);}set_paddr_command(arg) char *arg;{ u_int addr; if (!arg) { if (kerneltype == OS_BSD) error_no_arg("ps-style address for new process"); else error_no_arg("thread structure virtual address"); } if (!kernel_debugging) error("not debugging kernel"); addr = (u_int) parse_and_eval_address(arg); if (kerneltype == OS_BSD) addr = ctob(addr); else { addr = kvread(&(((int *)addr)[9])); /* XXX: pcb addr */ addr = vtophys(0, addr); /* XXX space */ } read_pcb(addr); flush_cached_frames(); set_current_frame(create_new_frame(read_register(FP_REGNUM), read_pc())); select_frame(get_current_frame(), 0);}/* * read len bytes from kernel virtual address 'addr' into local * buffer 'buf'. Return 0 if read ok, 1 otherwise. On read * errors, portion of buffer not read is zeroed. */kernel_core_file_hook(addr, buf, len) CORE_ADDR addr; char *buf; int len;{ int i; CORE_ADDR paddr; while (len > 0) { paddr = vtophys(0, addr); /* XXX space */ if (paddr == ~0) { bzero(buf, len); return (1); } /* we can't read across a page boundary */ i = min(len, NBPG - (addr & PGOFSET)); if (physrd(paddr, buf, i)) { bzero(buf, len); return (1); } buf += i; addr += i; len -= i; } return (0);}#endif/* Routines to extract various sized constants out of hppa instructions. *//* This assumes that no garbage lies outside of the lower bits of value. */intsign_extend (val, bits) unsigned val, bits;{ return (int)(val >> bits - 1 ? (-1 << bits) | val : val);}/* For many immediate values the sign bit is the low bit! */intlow_sign_extend (val, bits) unsigned val, bits;{ return (int)((val & 0x1 ? (-1 << (bits - 1)) : 0) | val >> 1);}/* extract the immediate field from a ld{bhw}s instruction */unsignedget_field (val, from, to) unsigned val, from, to;{ val = val >> 31 - to; return val & ((1 << 32 - from) - 1);}unsignedset_field (val, from, to, new_val) unsigned *val, from, to;{ unsigned mask = ~((1 << (to - from + 1)) << (31 - from)); return *val = *val & mask | (new_val << (31 - from));}/* extract a 3-bit space register number from a be, ble, mtsp or mfsp */extract_3 (word) unsigned word;{ return GET_FIELD (word, 18, 18) << 2 | GET_FIELD (word, 16, 17);} extract_5_load (word) unsigned word;{ return low_sign_extend (word >> 16 & MASK_5, 5);}/* extract the immediate field from a st{bhw}s instruction */intextract_5_store (word) unsigned word;{ return low_sign_extend (word & MASK_5, 5);}/* extract an 11 bit immediate field */intextract_11 (word) unsigned word;{ return low_sign_extend (word & MASK_11, 11);}/* extract a 14 bit immediate field */intextract_14 (word) unsigned word;{ return low_sign_extend (word & MASK_14, 14);}/* deposit a 14 bit constant in a word */unsigneddeposit_14 (opnd, word) int opnd; unsigned word;{ unsigned sign = (opnd < 0 ? 1 : 0); return word | ((unsigned)opnd << 1 & MASK_14) | sign;}/* extract a 21 bit constant */intextract_21 (word) unsigned word;{ int val; word &= MASK_21; word <<= 11; val = GET_FIELD (word, 20, 20); val <<= 11; val |= GET_FIELD (word, 9, 19); val <<= 2; val |= GET_FIELD (word, 5, 6); val <<= 5; val |= GET_FIELD (word, 0, 4); val <<= 2; val |= GET_FIELD (word, 7, 8); return sign_extend (val, 21) << 11;}/* deposit a 21 bit constant in a word. Although 21 bit constants are usually the top 21 bits of a 32 bit constant, we assume that only the low 21 bits of opnd are relevant */unsigneddeposit_21 (opnd, word) unsigned opnd, word;{ unsigned val = 0; val |= GET_FIELD (opnd, 11 + 14, 11 + 18); val <<= 2; val |= GET_FIELD (opnd, 11 + 12, 11 + 13); val <<= 2; val |= GET_FIELD (opnd, 11 + 19, 11 + 20); val <<= 11; val |= GET_FIELD (opnd, 11 + 1, 11 + 11); val <<= 1; val |= GET_FIELD (opnd, 11 + 0, 11 + 0); return word | val;}/* extract a 12 bit constant from branch instructions */intextract_12 (word) unsigned word;{ return sign_extend (GET_FIELD (word, 19, 28) | GET_FIELD (word, 29, 29) << 10 | (word & 0x1) << 11, 12) << 2;}/* extract a 17 bit constant from branch instructions, returning the 19 bit signed value. */intextract_17 (word) unsigned word;{ return sign_extend (GET_FIELD (word, 19, 28) | GET_FIELD (word, 29, 29) << 10 | GET_FIELD (word, 11, 15) << 11 | (word & 0x1) << 16, 17) << 2;}CORE_ADDRframe_saved_pc (frame) FRAME frame;{ if (get_current_frame () == frame) { struct frame_saved_regs saved_regs; get_frame_saved_regs (frame, &saved_regs); if (saved_regs.regs[RP_REGNUM]) return read_memory_integer (saved_regs.regs[RP_REGNUM], 4); else return read_register (RP_REGNUM); } return read_memory_integer (frame->frame - 20, 4) & ~0x3;}/* To see if a frame chain is valid, see if the caller looks like it was compiled with gcc. */int frame_chain_valid (chain, thisframe) FRAME_ADDR chain; FRAME thisframe;{ if (chain && (chain > 0x60000000 /* || remote_debugging -this is no longer used */#ifdef KERNELDEBUG || kernel_debugging#endif )) { CORE_ADDR pc = get_pc_function_start (FRAME_SAVED_PC (thisframe)); if (!inside_entry_file (pc)) return 0; /* look for stw rp, -20(0,sp); copy 4,1; copy sp, 4 */ if (read_memory_integer (pc, 4) == 0x6BC23FD9) pc = pc + 4; if (read_memory_integer (pc, 4) == 0x8040241 && read_memory_integer (pc + 4, 4) == 0x81E0244) return 1; else return 0; } else return 0;}/* Some helper functions. gcc_p returns 1 if the function beginning at pc appears to have been compiled with gcc. hpux_cc_p returns 1 if fn was compiled with hpux cc. gcc functions look like : stw rp,-0x14(sp) ; optional or r4,r0,r1 or sp,r0,r4 stwm r1,framesize(sp) hpux cc functions look like: stw rp,-0x14(sp) ; optional. stwm r3,framesiz(sp) */gcc_p (pc) CORE_ADDR pc;{ if (read_memory_integer (pc, 4) == 0x6BC23FD9) pc = pc + 4; if (read_memory_integer (pc, 4) == 0x8040241 && read_memory_integer (pc + 4, 4) == 0x81E0244) return 1; return 0;} find_dummy_frame_regs (frame, frame_saved_regs) struct frame_info *frame; struct frame_saved_regs *frame_saved_regs;{ CORE_ADDR fp = frame->frame; int i; frame_saved_regs->regs[RP_REGNUM] = fp - 20 & ~0x3; frame_saved_regs->regs[FP_REGNUM] = fp; frame_saved_regs->regs[1] = fp + 8; frame_saved_regs->regs[3] = fp + 12; for (fp += 16, i = 3; i < 30; fp += 4, i++) frame_saved_regs->regs[i] = fp; frame_saved_regs->regs[31] = fp; fp += 4; for (i = FP0_REGNUM; i < NUM_REGS; i++, fp += 8) frame_saved_regs->regs[i] = fp; /* depend on last increment of fp */ frame_saved_regs->regs[IPSW_REGNUM] = fp - 4; frame_saved_regs->regs[SAR_REGNUM] = fp; fp += 4; frame_saved_regs->regs[PCOQ_TAIL_REGNUM] = fp; frame_saved_regs->regs[PCSQ_TAIL_REGNUM] = fp;}CORE_ADDRhp_push_arguments (nargs, args, sp, struct_return, struct_addr) int nargs; value *args; CORE_ADDR sp; int struct_return; CORE_ADDR struct_addr;{ /* array of arguments' offsets */ int *offset = (int *)alloca(nargs); int cum = 0; int i, alignment; for (i = 0; i < nargs; i++) { cum += TYPE_LENGTH (VALUE_TYPE (args[i])); /* value must go at proper alignment. Assume alignment is a power of two.*/ alignment = hp_alignof (VALUE_TYPE (args[i])); if (cum % alignment) cum = (cum + alignment) & -alignment; offset[i] = -cum; } for (i == 0; i < nargs; i++) { write_memory (sp + offset[i], VALUE_CONTENTS (args[i]), sizeof(int)); } sp += min ((cum + 7) & -8, 48); if (struct_return) write_register (28, struct_addr); return sp + 48;}/* return the alignment of a type in bytes. Structures have the maximum alignment required by their fields. */inthp_alignof (arg) struct type *arg;{ int max_align, align, i; switch (TYPE_CODE (arg)) { case TYPE_CODE_PTR: case TYPE_CODE_INT: case TYPE_CODE_FLT: return TYPE_LENGTH (arg); case TYPE_CODE_ARRAY: return hp_alignof (TYPE_FIELD_TYPE (arg, 0)); case TYPE_CODE_STRUCT: case TYPE_CODE_UNION: max_align = 2; for (i = 0; i < TYPE_NFIELDS (arg); i++) { /* Bit fields have no real alignment. */ if (!TYPE_FIELD_BITPOS (arg, i)) { align = hp_alignof (TYPE_FIELD_TYPE (arg, i)); max_align = max (max_align, align); } } return max_align; default: return 4; }}/* Print the register regnum, or all registers if regnum is -1 */pa_do_registers_info (regnum, fpregs) int regnum; int fpregs;{ char raw_regs [REGISTER_BYTES]; int i; for (i = 0; i < NUM_REGS; i++) read_relative_register_raw_bytes (i, raw_regs + REGISTER_BYTE (i)); if (regnum = -1) pa_print_registers (raw_regs, regnum); else if (regnum < FP0_REGNUM) { printf ("%s %x\n", reg_names[regnum], *(long *)(raw_regs + REGISTER_BYTE (regnum))); } else pa_print_fp_reg (regnum);}pa_print_registers (raw_regs, regnum) char *raw_regs; int regnum;{ int i; for (i = 0; i < 18; i++) printf ("%8.8s: %8x %8.8s: %8x %8.8s: %8x %8.8s: %8x\n", reg_names[i], *(int *)(raw_regs + REGISTER_BYTE (i)), reg_names[i + 18], *(int *)(raw_regs + REGISTER_BYTE (i + 18)), reg_names[i + 36], *(int *)(raw_regs + REGISTER_BYTE (i + 36)), reg_names[i + 54], *(int *)(raw_regs + REGISTER_BYTE (i + 54))); for (i = 72; i < NUM_REGS; i++) pa_print_fp_reg (i);}pa_print_fp_reg (i) int i;{ unsigned char raw_buffer[MAX_REGISTER_RAW_SIZE]; unsigned char virtual_buffer[MAX_REGISTER_VIRTUAL_SIZE]; REGISTER_TYPE val; /* Get the data in raw format, then convert also to virtual format. */ read_relative_register_raw_bytes (i, raw_buffer); REGISTER_CONVERT_TO_VIRTUAL (i, raw_buffer, virtual_buffer); fputs_filtered (reg_names[i], stdout); print_spaces_filtered (15 - strlen (reg_names[i]), stdout);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -