void fill_gregset (const struct regcache *regcache, gregset_t *gregsetp, int regno) { int regi, size; greg_t *regp = &(*gregsetp)[0]; gdb_byte buf[MAX_REGISTER_SIZE]; struct gdbarch *gdbarch = get_regcache_arch (regcache); enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); /* Under Irix6, if GDB is built with N32 ABI and is debugging an O32 executable, we have to sign extend the registers to 64 bits before filling in the gregset structure. */ for (regi = 0; regi <= CTX_RA; regi++) if ((regno == -1) || (regno == regi)) { size = register_size (gdbarch, regi); regcache_raw_collect (regcache, regi, buf); *(regp + regi) = extract_signed_integer (buf, size, byte_order); } if ((regno == -1) || (regno == mips_regnum (gdbarch)->pc)) { regi = mips_regnum (gdbarch)->pc; size = register_size (gdbarch, regi); regcache_raw_collect (regcache, regi, buf); *(regp + CTX_EPC) = extract_signed_integer (buf, size, byte_order); } if ((regno == -1) || (regno == mips_regnum (gdbarch)->cause)) { regi = mips_regnum (gdbarch)->cause; size = register_size (gdbarch, regi); regcache_raw_collect (regcache, regi, buf); *(regp + CTX_CAUSE) = extract_signed_integer (buf, size, byte_order); } if ((regno == -1) || (regno == mips_regnum (gdbarch)->hi)) { regi = mips_regnum (gdbarch)->hi; size = register_size (gdbarch, regi); regcache_raw_collect (regcache, regi, buf); *(regp + CTX_MDHI) = extract_signed_integer (buf, size, byte_order); } if ((regno == -1) || (regno == mips_regnum (gdbarch)->lo)) { regi = mips_regnum (gdbarch)->lo; size = register_size (gdbarch, regi); regcache_raw_collect (regcache, regi, buf); *(regp + CTX_MDLO) = extract_signed_integer (buf, size, byte_order); } }
int scm_val_print (struct type *type, const gdb_byte *valaddr, int embedded_offset, CORE_ADDR address, struct ui_file *stream, int format, int deref_ref, int recurse, enum val_prettyprint pretty) { if (is_scmvalue_type (type)) { LONGEST svalue = extract_signed_integer (valaddr, TYPE_LENGTH (type)); if (scm_inferior_print (svalue, stream, format, deref_ref, recurse, pretty) >= 0) { } else { scm_scmval_print (svalue, stream, format, deref_ref, recurse, pretty); } gdb_flush (stream); return (0); } else { return c_val_print (type, valaddr, 0, address, stream, format, deref_ref, recurse, pretty); } }
/* Return the current system call's number present in the r0 register. When the function fails, it returns -1. */ static LONGEST ppc_linux_get_syscall_number (struct gdbarch *gdbarch, ptid_t ptid) { struct regcache *regcache = get_thread_regcache (ptid); struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); struct cleanup *cleanbuf; /* The content of a register */ gdb_byte *buf; /* The result */ LONGEST ret; /* Make sure we're in a 32- or 64-bit machine */ gdb_assert (tdep->wordsize == 4 || tdep->wordsize == 8); buf = (gdb_byte *) xmalloc (tdep->wordsize * sizeof (gdb_byte)); cleanbuf = make_cleanup (xfree, buf); /* Getting the system call number from the register. When dealing with PowerPC architecture, this information is stored at 0th register. */ regcache_cooked_read (regcache, tdep->ppc_gp0_regnum, buf); ret = extract_signed_integer (buf, tdep->wordsize, byte_order); do_cleanups (cleanbuf); return ret; }
void mips64_fill_gregset (const struct regcache *regcache, mips64_elf_gregset_t *gregsetp, int regno) { int regaddr, regi; mips64_elf_greg_t *regp = *gregsetp; void *src, *dst; if (regno == -1) { memset (regp, 0, sizeof (mips64_elf_gregset_t)); for (regi = 1; regi < 32; regi++) mips64_fill_gregset (regcache, gregsetp, regi); mips64_fill_gregset (regcache, gregsetp, mips_regnum (current_gdbarch)->lo); mips64_fill_gregset (regcache, gregsetp, mips_regnum (current_gdbarch)->hi); mips64_fill_gregset (regcache, gregsetp, mips_regnum (current_gdbarch)->pc); mips64_fill_gregset (regcache, gregsetp, mips_regnum (current_gdbarch)->badvaddr); mips64_fill_gregset (regcache, gregsetp, MIPS_PS_REGNUM); mips64_fill_gregset (regcache, gregsetp, mips_regnum (current_gdbarch)->cause); mips64_fill_gregset (regcache, gregsetp, MIPS_RESTART_REGNUM); return; } if (regno > 0 && regno < 32) regaddr = regno + MIPS64_EF_REG0; else if (regno == mips_regnum (current_gdbarch)->lo) regaddr = MIPS64_EF_LO; else if (regno == mips_regnum (current_gdbarch)->hi) regaddr = MIPS64_EF_HI; else if (regno == mips_regnum (current_gdbarch)->pc) regaddr = MIPS64_EF_CP0_EPC; else if (regno == mips_regnum (current_gdbarch)->badvaddr) regaddr = MIPS64_EF_CP0_BADVADDR; else if (regno == MIPS_PS_REGNUM) regaddr = MIPS64_EF_CP0_STATUS; else if (regno == mips_regnum (current_gdbarch)->cause) regaddr = MIPS64_EF_CP0_CAUSE; else if (mips_linux_restart_reg_p (current_gdbarch) && regno == MIPS_RESTART_REGNUM) regaddr = MIPS64_EF_REG0; else regaddr = -1; if (regaddr != -1) { gdb_byte buf[MAX_REGISTER_SIZE]; LONGEST val; regcache_raw_collect (regcache, regno, buf); val = extract_signed_integer (buf, register_size (current_gdbarch, regno)); dst = regp + regaddr; store_signed_integer (dst, 8, val); } }
static LONGEST mips_linux_get_syscall_number (struct gdbarch *gdbarch, ptid_t ptid) { struct regcache *regcache = get_thread_regcache (ptid); struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); int regsize = register_size (gdbarch, MIPS_V0_REGNUM); /* The content of a register */ gdb_byte buf[8]; /* The result */ LONGEST ret; /* Make sure we're in a known ABI */ gdb_assert (tdep->mips_abi == MIPS_ABI_O32 || tdep->mips_abi == MIPS_ABI_N32 || tdep->mips_abi == MIPS_ABI_N64); gdb_assert (regsize <= sizeof (buf)); /* Getting the system call number from the register. syscall number is in v0 or $2. */ regcache_cooked_read (regcache, MIPS_V0_REGNUM, buf); ret = extract_signed_integer (buf, regsize, byte_order); return ret; }
static CORE_ADDR amd64_skip_main_prologue (struct gdbarch *gdbarch, CORE_ADDR pc) { enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); gdb_byte op; target_read_memory (pc, &op, 1); if (op == 0xe8) { gdb_byte buf[4]; if (target_read_memory (pc + 1, buf, sizeof buf) == 0) { struct bound_minimal_symbol s; CORE_ADDR call_dest; call_dest = pc + 5 + extract_signed_integer (buf, 4, byte_order); s = lookup_minimal_symbol_by_pc (call_dest); if (s.minsym != NULL && MSYMBOL_LINKAGE_NAME (s.minsym) != NULL && strcmp (MSYMBOL_LINKAGE_NAME (s.minsym), "__main") == 0) pc += 5; } } return pc; }
LONGEST read_memory_integer(CORE_ADDR memaddr, int len) { char buf[sizeof(LONGEST)]; read_memory(memaddr, (gdb_byte *)buf, len); return extract_signed_integer((const gdb_byte *)buf, len); }
static void supply_32bit_reg (struct regcache *regcache, int regnum, const void *addr) { gdb_byte buf[MAX_REGISTER_SIZE]; store_signed_integer (buf, register_size (current_gdbarch, regnum), extract_signed_integer (addr, 4)); regcache_raw_supply (regcache, regnum, buf); }
LONGEST scm_get_field (LONGEST svalue, int index) { char buffer[20]; read_memory (SCM2PTR (svalue) + index * TYPE_LENGTH (builtin_type_scm), buffer, TYPE_LENGTH (builtin_type_scm)); return extract_signed_integer (buffer, TYPE_LENGTH (builtin_type_scm)); }
static void supply_32bit_reg (struct regcache *regcache, int regnum, const void *addr) { struct gdbarch *gdbarch = get_regcache_arch (regcache); enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); gdb_byte buf[MAX_REGISTER_SIZE]; store_signed_integer (buf, register_size (gdbarch, regnum), byte_order, extract_signed_integer (addr, 4, byte_order)); regcache_raw_supply (regcache, regnum, buf); }
static int gnuv3_decode_method_ptr (struct gdbarch *gdbarch, const gdb_byte *contents, CORE_ADDR *value_p, LONGEST *adjustment_p) { struct type *funcptr_type = builtin_type (gdbarch)->builtin_func_ptr; struct type *offset_type = vtable_ptrdiff_type (gdbarch); enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); CORE_ADDR ptr_value; LONGEST voffset, adjustment; int vbit; /* Extract the pointer to member. The first element is either a pointer or a vtable offset. For pointers, we need to use extract_typed_address to allow the back-end to convert the pointer to a GDB address -- but vtable offsets we must handle as integers. At this point, we do not yet know which case we have, so we extract the value under both interpretations and choose the right one later on. */ ptr_value = extract_typed_address (contents, funcptr_type); voffset = extract_signed_integer (contents, TYPE_LENGTH (funcptr_type), byte_order); contents += TYPE_LENGTH (funcptr_type); adjustment = extract_signed_integer (contents, TYPE_LENGTH (offset_type), byte_order); if (!gdbarch_vbit_in_delta (gdbarch)) { vbit = voffset & 1; voffset = voffset ^ vbit; } else { vbit = adjustment & 1; adjustment = adjustment >> 1; } *value_p = vbit? voffset : ptr_value; *adjustment_p = adjustment; return vbit; }
static LONGEST i386_linux_get_syscall_number_from_regcache (struct regcache *regcache) { struct gdbarch *gdbarch = get_regcache_arch (regcache); enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); /* The content of a register. */ gdb_byte buf[4]; /* The result. */ LONGEST ret; /* Getting the system call number from the register. When dealing with x86 architecture, this information is stored at %eax register. */ regcache_cooked_read (regcache, I386_LINUX_ORIG_EAX_REGNUM, buf); ret = extract_signed_integer (buf, 4, byte_order); return ret; }
static LONGEST aarch64_linux_get_syscall_number (struct gdbarch *gdbarch, ptid_t ptid) { struct regcache *regs = get_thread_regcache (ptid); enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); /* The content of register x8. */ gdb_byte buf[X_REGISTER_SIZE]; /* The result. */ LONGEST ret; /* Getting the system call number from the register x8. */ regcache_cooked_read (regs, AARCH64_DWARF_X0 + 8, buf); ret = extract_signed_integer (buf, X_REGISTER_SIZE, byte_order); return ret; }
static LONGEST sparc64_linux_get_syscall_number (struct gdbarch *gdbarch, thread_info *thread) { struct regcache *regcache = get_thread_regcache (thread); enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); /* The content of a register. */ gdb_byte buf[8]; /* The result. */ LONGEST ret; /* Getting the system call number from the register. When dealing with the sparc architecture, this information is stored at the %g1 register. */ regcache->cooked_read (SPARC_G1_REGNUM, buf); ret = extract_signed_integer (buf, 8, byte_order); return ret; }
static void mips_fbsd_collect_reg (const struct regcache *regcache, int regnum, void *addr, size_t len) { struct gdbarch *gdbarch = get_regcache_arch (regcache); if (register_size (gdbarch, regnum) == len) regcache_raw_collect (regcache, regnum, addr); else { enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); gdb_byte buf[MAX_REGISTER_SIZE]; LONGEST val; regcache_raw_collect (regcache, regnum, buf); val = extract_signed_integer (buf, register_size (gdbarch, regnum), byte_order); store_signed_integer ((gdb_byte *) addr, len, byte_order, val); } }
static LONGEST bfin_linux_get_syscall_number (struct gdbarch *gdbarch, ptid_t ptid) { struct regcache *regcache = get_thread_regcache (ptid); enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); /* The content of a register. */ gdb_byte buf[4]; /* The result. */ LONGEST ret; /* Getting the system call number from the register. When dealing with Blackfin architecture, this information is stored at %p0 register. */ regcache_cooked_read (regcache, BFIN_P0_REGNUM, buf); ret = extract_signed_integer (buf, 4, byte_order); return ret; }
LONGEST scm_unpack (struct type *type, char *valaddr, enum type_code context) { if (is_scmvalue_type (type)) { LONGEST svalue = extract_signed_integer (valaddr, TYPE_LENGTH (type)); if (context == TYPE_CODE_BOOL) { if (svalue == SCM_BOOL_F) return 0; else return 1; } switch (7 & (int) svalue) { case 2: case 6: /* fixnum */ return svalue >> 2; case 4: /* other immediate value */ if (SCM_ICHRP (svalue)) /* character */ return SCM_ICHR (svalue); else if (SCM_IFLAGP (svalue)) { switch ((int) svalue) { #ifndef SICP case SCM_EOL: #endif case SCM_BOOL_F: return 0; case SCM_BOOL_T: return 1; } } error ("Value can't be converted to integer."); default: return svalue; } } else return unpack_long (type, valaddr);
/* Scan an FR-V prologue, starting at PC, until frame->PC. If FRAME is non-zero, fill in its saved_regs with appropriate addresses. We assume FRAME's saved_regs array has already been allocated and cleared. Return the first PC value after the prologue. Note that, for unoptimized code, we almost don't need this function at all; all arguments and locals live on the stack, so we just need the FP to find everything. The catch: structures passed by value have their addresses living in registers; they're never spilled to the stack. So if you ever want to be able to get to these arguments in any frame but the top, you'll need to do this serious prologue analysis. */ static CORE_ADDR frv_analyze_prologue (struct gdbarch *gdbarch, CORE_ADDR pc, struct frame_info *this_frame, struct frv_unwind_cache *info) { enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); /* When writing out instruction bitpatterns, we use the following letters to label instruction fields: P - The parallel bit. We don't use this. J - The register number of GRj in the instruction description. K - The register number of GRk in the instruction description. I - The register number of GRi. S - a signed imediate offset. U - an unsigned immediate offset. The dots below the numbers indicate where hex digit boundaries fall, to make it easier to check the numbers. */ /* Non-zero iff we've seen the instruction that initializes the frame pointer for this function's frame. */ int fp_set = 0; /* If fp_set is non_zero, then this is the distance from the stack pointer to frame pointer: fp = sp + fp_offset. */ int fp_offset = 0; /* Total size of frame prior to any alloca operations. */ int framesize = 0; /* Flag indicating if lr has been saved on the stack. */ int lr_saved_on_stack = 0; /* The number of the general-purpose register we saved the return address ("link register") in, or -1 if we haven't moved it yet. */ int lr_save_reg = -1; /* Offset (from sp) at which lr has been saved on the stack. */ int lr_sp_offset = 0; /* If gr_saved[i] is non-zero, then we've noticed that general register i has been saved at gr_sp_offset[i] from the stack pointer. */ char gr_saved[64]; int gr_sp_offset[64]; /* The address of the most recently scanned prologue instruction. */ CORE_ADDR last_prologue_pc; /* The address of the next instruction. */ CORE_ADDR next_pc; /* The upper bound to of the pc values to scan. */ CORE_ADDR lim_pc; memset (gr_saved, 0, sizeof (gr_saved)); last_prologue_pc = pc; /* Try to compute an upper limit (on how far to scan) based on the line number info. */ lim_pc = skip_prologue_using_sal (gdbarch, pc); /* If there's no line number info, lim_pc will be 0. In that case, set the limit to be 100 instructions away from pc. Hopefully, this will be far enough away to account for the entire prologue. Don't worry about overshooting the end of the function. The scan loop below contains some checks to avoid scanning unreasonably far. */ if (lim_pc == 0) lim_pc = pc + 400; /* If we have a frame, we don't want to scan past the frame's pc. This will catch those cases where the pc is in the prologue. */ if (this_frame) { CORE_ADDR frame_pc = get_frame_pc (this_frame); if (frame_pc < lim_pc) lim_pc = frame_pc; } /* Scan the prologue. */ while (pc < lim_pc) { gdb_byte buf[frv_instr_size]; LONGEST op; if (target_read_memory (pc, buf, sizeof buf) != 0) break; op = extract_signed_integer (buf, sizeof buf, byte_order); next_pc = pc + 4; /* The tests in this chain of ifs should be in order of decreasing selectivity, so that more particular patterns get to fire before less particular patterns. */ /* Some sort of control transfer instruction: stop scanning prologue. Integer Conditional Branch: X XXXX XX 0000110 XX XXXXXXXXXXXXXXXX Floating-point / media Conditional Branch: X XXXX XX 0000111 XX XXXXXXXXXXXXXXXX LCR Conditional Branch to LR X XXXX XX 0001110 XX XX 001 X XXXXXXXXXX Integer conditional Branches to LR X XXXX XX 0001110 XX XX 010 X XXXXXXXXXX X XXXX XX 0001110 XX XX 011 X XXXXXXXXXX Floating-point/Media Branches to LR X XXXX XX 0001110 XX XX 110 X XXXXXXXXXX X XXXX XX 0001110 XX XX 111 X XXXXXXXXXX Jump and Link X XXXXX X 0001100 XXXXXX XXXXXX XXXXXX X XXXXX X 0001101 XXXXXX XXXXXX XXXXXX Call X XXXXXX 0001111 XXXXXXXXXXXXXXXXXX Return from Trap X XXXXX X 0000101 XXXXXX XXXXXX XXXXXX Integer Conditional Trap X XXXX XX 0000100 XXXXXX XXXX 00 XXXXXX X XXXX XX 0011100 XXXXXX XXXXXXXXXXXX Floating-point /media Conditional Trap X XXXX XX 0000100 XXXXXX XXXX 01 XXXXXX X XXXX XX 0011101 XXXXXX XXXXXXXXXXXX Break X XXXX XX 0000100 XXXXXX XXXX 11 XXXXXX Media Trap X XXXX XX 0000100 XXXXXX XXXX 10 XXXXXX */ if ((op & 0x01d80000) == 0x00180000 /* Conditional branches and Call */ || (op & 0x01f80000) == 0x00300000 /* Jump and Link */ || (op & 0x01f80000) == 0x00100000 /* Return from Trap, Trap */ || (op & 0x01f80000) == 0x00700000) /* Trap immediate */ { /* Stop scanning; not in prologue any longer. */ break; } /* Loading something from memory into fp probably means that we're in the epilogue. Stop scanning the prologue. ld @(GRi, GRk), fp X 000010 0000010 XXXXXX 000100 XXXXXX ldi @(GRi, d12), fp X 000010 0110010 XXXXXX XXXXXXXXXXXX */ else if ((op & 0x7ffc0fc0) == 0x04080100 || (op & 0x7ffc0000) == 0x04c80000) { break; } /* Setting the FP from the SP: ori sp, 0, fp P 000010 0100010 000001 000000000000 = 0x04881000 0 111111 1111111 111111 111111111111 = 0x7fffffff . . . . . . . . We treat this as part of the prologue. */ else if ((op & 0x7fffffff) == 0x04881000) { fp_set = 1; fp_offset = 0; last_prologue_pc = next_pc; } /* Move the link register to the scratch register grJ, before saving: movsg lr, grJ P 000100 0000011 010000 000111 JJJJJJ = 0x080d01c0 0 111111 1111111 111111 111111 000000 = 0x7fffffc0 . . . . . . . . We treat this as part of the prologue. */ else if ((op & 0x7fffffc0) == 0x080d01c0) { int gr_j = op & 0x3f; /* If we're moving it to a scratch register, that's fine. */ if (is_caller_saves_reg (gr_j)) { lr_save_reg = gr_j; last_prologue_pc = next_pc; } } /* To save multiple callee-saves registers on the stack, at offset zero: std grK,@(sp,gr0) P KKKKKK 0000011 000001 000011 000000 = 0x000c10c0 0 000000 1111111 111111 111111 111111 = 0x01ffffff stq grK,@(sp,gr0) P KKKKKK 0000011 000001 000100 000000 = 0x000c1100 0 000000 1111111 111111 111111 111111 = 0x01ffffff . . . . . . . . We treat this as part of the prologue, and record the register's saved address in the frame structure. */ else if ((op & 0x01ffffff) == 0x000c10c0 || (op & 0x01ffffff) == 0x000c1100) { int gr_k = ((op >> 25) & 0x3f); int ope = ((op >> 6) & 0x3f); int count; int i; /* Is it an std or an stq? */ if (ope == 0x03) count = 2; else count = 4; /* Is it really a callee-saves register? */ if (is_callee_saves_reg (gr_k)) { for (i = 0; i < count; i++) { gr_saved[gr_k + i] = 1; gr_sp_offset[gr_k + i] = 4 * i; } last_prologue_pc = next_pc; } } /* Adjusting the stack pointer. (The stack pointer is GR1.) addi sp, S, sp P 000001 0010000 000001 SSSSSSSSSSSS = 0x02401000 0 111111 1111111 111111 000000000000 = 0x7ffff000 . . . . . . . . We treat this as part of the prologue. */ else if ((op & 0x7ffff000) == 0x02401000)
static void execute_stack_op (struct dwarf_expr_context *ctx, gdb_byte *op_ptr, gdb_byte *op_end) { enum bfd_endian byte_order = gdbarch_byte_order (ctx->gdbarch); ctx->location = DWARF_VALUE_MEMORY; ctx->initialized = 1; /* Default is initialized. */ if (ctx->recursion_depth > ctx->max_recursion_depth) error (_("DWARF-2 expression error: Loop detected (%d)."), ctx->recursion_depth); ctx->recursion_depth++; while (op_ptr < op_end) { enum dwarf_location_atom op = *op_ptr++; CORE_ADDR result; /* Assume the value is not in stack memory. Code that knows otherwise sets this to 1. Some arithmetic on stack addresses can probably be assumed to still be a stack address, but we skip this complication for now. This is just an optimization, so it's always ok to punt and leave this as 0. */ int in_stack_memory = 0; ULONGEST uoffset, reg; LONGEST offset; switch (op) { case DW_OP_lit0: case DW_OP_lit1: case DW_OP_lit2: case DW_OP_lit3: case DW_OP_lit4: case DW_OP_lit5: case DW_OP_lit6: case DW_OP_lit7: case DW_OP_lit8: case DW_OP_lit9: case DW_OP_lit10: case DW_OP_lit11: case DW_OP_lit12: case DW_OP_lit13: case DW_OP_lit14: case DW_OP_lit15: case DW_OP_lit16: case DW_OP_lit17: case DW_OP_lit18: case DW_OP_lit19: case DW_OP_lit20: case DW_OP_lit21: case DW_OP_lit22: case DW_OP_lit23: case DW_OP_lit24: case DW_OP_lit25: case DW_OP_lit26: case DW_OP_lit27: case DW_OP_lit28: case DW_OP_lit29: case DW_OP_lit30: case DW_OP_lit31: result = op - DW_OP_lit0; break; case DW_OP_addr: result = dwarf2_read_address (ctx->gdbarch, op_ptr, op_end, ctx->addr_size); op_ptr += ctx->addr_size; break; case DW_OP_const1u: result = extract_unsigned_integer (op_ptr, 1, byte_order); op_ptr += 1; break; case DW_OP_const1s: result = extract_signed_integer (op_ptr, 1, byte_order); op_ptr += 1; break; case DW_OP_const2u: result = extract_unsigned_integer (op_ptr, 2, byte_order); op_ptr += 2; break; case DW_OP_const2s: result = extract_signed_integer (op_ptr, 2, byte_order); op_ptr += 2; break; case DW_OP_const4u: result = extract_unsigned_integer (op_ptr, 4, byte_order); op_ptr += 4; break; case DW_OP_const4s: result = extract_signed_integer (op_ptr, 4, byte_order); op_ptr += 4; break; case DW_OP_const8u: result = extract_unsigned_integer (op_ptr, 8, byte_order); op_ptr += 8; break; case DW_OP_const8s: result = extract_signed_integer (op_ptr, 8, byte_order); op_ptr += 8; break; case DW_OP_constu: op_ptr = read_uleb128 (op_ptr, op_end, &uoffset); result = uoffset; break; case DW_OP_consts: op_ptr = read_sleb128 (op_ptr, op_end, &offset); result = offset; break; /* The DW_OP_reg operations are required to occur alone in location expressions. */ case DW_OP_reg0: case DW_OP_reg1: case DW_OP_reg2: case DW_OP_reg3: case DW_OP_reg4: case DW_OP_reg5: case DW_OP_reg6: case DW_OP_reg7: case DW_OP_reg8: case DW_OP_reg9: case DW_OP_reg10: case DW_OP_reg11: case DW_OP_reg12: case DW_OP_reg13: case DW_OP_reg14: case DW_OP_reg15: case DW_OP_reg16: case DW_OP_reg17: case DW_OP_reg18: case DW_OP_reg19: case DW_OP_reg20: case DW_OP_reg21: case DW_OP_reg22: case DW_OP_reg23: case DW_OP_reg24: case DW_OP_reg25: case DW_OP_reg26: case DW_OP_reg27: case DW_OP_reg28: case DW_OP_reg29: case DW_OP_reg30: case DW_OP_reg31: if (op_ptr != op_end && *op_ptr != DW_OP_piece && *op_ptr != DW_OP_GNU_uninit) error (_("DWARF-2 expression error: DW_OP_reg operations must be " "used either alone or in conjuction with DW_OP_piece.")); result = op - DW_OP_reg0; ctx->location = DWARF_VALUE_REGISTER; break; case DW_OP_regx: op_ptr = read_uleb128 (op_ptr, op_end, ®); require_composition (op_ptr, op_end, "DW_OP_regx"); result = reg; ctx->location = DWARF_VALUE_REGISTER; break; case DW_OP_implicit_value: { ULONGEST len; op_ptr = read_uleb128 (op_ptr, op_end, &len); if (op_ptr + len > op_end) error (_("DW_OP_implicit_value: too few bytes available.")); ctx->len = len; ctx->data = op_ptr; ctx->location = DWARF_VALUE_LITERAL; op_ptr += len; require_composition (op_ptr, op_end, "DW_OP_implicit_value"); } goto no_push; case DW_OP_stack_value: ctx->location = DWARF_VALUE_STACK; require_composition (op_ptr, op_end, "DW_OP_stack_value"); goto no_push; case DW_OP_breg0: case DW_OP_breg1: case DW_OP_breg2: case DW_OP_breg3: case DW_OP_breg4: case DW_OP_breg5: case DW_OP_breg6: case DW_OP_breg7: case DW_OP_breg8: case DW_OP_breg9: case DW_OP_breg10: case DW_OP_breg11: case DW_OP_breg12: case DW_OP_breg13: case DW_OP_breg14: case DW_OP_breg15: case DW_OP_breg16: case DW_OP_breg17: case DW_OP_breg18: case DW_OP_breg19: case DW_OP_breg20: case DW_OP_breg21: case DW_OP_breg22: case DW_OP_breg23: case DW_OP_breg24: case DW_OP_breg25: case DW_OP_breg26: case DW_OP_breg27: case DW_OP_breg28: case DW_OP_breg29: case DW_OP_breg30: case DW_OP_breg31: { op_ptr = read_sleb128 (op_ptr, op_end, &offset); result = (ctx->read_reg) (ctx->baton, op - DW_OP_breg0); result += offset; } break; case DW_OP_bregx: { op_ptr = read_uleb128 (op_ptr, op_end, ®); op_ptr = read_sleb128 (op_ptr, op_end, &offset); result = (ctx->read_reg) (ctx->baton, reg); result += offset; } break; case DW_OP_fbreg: { gdb_byte *datastart; size_t datalen; unsigned int before_stack_len; op_ptr = read_sleb128 (op_ptr, op_end, &offset); /* Rather than create a whole new context, we simply record the stack length before execution, then reset it afterwards, effectively erasing whatever the recursive call put there. */ before_stack_len = ctx->stack_len; /* FIXME: cagney/2003-03-26: This code should be using get_frame_base_address(), and then implement a dwarf2 specific this_base method. */ (ctx->get_frame_base) (ctx->baton, &datastart, &datalen); dwarf_expr_eval (ctx, datastart, datalen); if (ctx->location == DWARF_VALUE_LITERAL || ctx->location == DWARF_VALUE_STACK) error (_("Not implemented: computing frame base using explicit value operator")); result = dwarf_expr_fetch (ctx, 0); if (ctx->location == DWARF_VALUE_REGISTER) result = (ctx->read_reg) (ctx->baton, result); result = result + offset; in_stack_memory = 1; ctx->stack_len = before_stack_len; ctx->location = DWARF_VALUE_MEMORY; } break; case DW_OP_dup: result = dwarf_expr_fetch (ctx, 0); in_stack_memory = dwarf_expr_fetch_in_stack_memory (ctx, 0); break; case DW_OP_drop: dwarf_expr_pop (ctx); goto no_push; case DW_OP_pick: offset = *op_ptr++; result = dwarf_expr_fetch (ctx, offset); in_stack_memory = dwarf_expr_fetch_in_stack_memory (ctx, offset); break; case DW_OP_swap: { struct dwarf_stack_value t1, t2; if (ctx->stack_len < 2) error (_("Not enough elements for DW_OP_swap. Need 2, have %d."), ctx->stack_len); t1 = ctx->stack[ctx->stack_len - 1]; t2 = ctx->stack[ctx->stack_len - 2]; ctx->stack[ctx->stack_len - 1] = t2; ctx->stack[ctx->stack_len - 2] = t1; goto no_push; } case DW_OP_over: result = dwarf_expr_fetch (ctx, 1); in_stack_memory = dwarf_expr_fetch_in_stack_memory (ctx, 1); break; case DW_OP_rot: { struct dwarf_stack_value t1, t2, t3; if (ctx->stack_len < 3) error (_("Not enough elements for DW_OP_rot. Need 3, have %d."), ctx->stack_len); t1 = ctx->stack[ctx->stack_len - 1]; t2 = ctx->stack[ctx->stack_len - 2]; t3 = ctx->stack[ctx->stack_len - 3]; ctx->stack[ctx->stack_len - 1] = t2; ctx->stack[ctx->stack_len - 2] = t3; ctx->stack[ctx->stack_len - 3] = t1; goto no_push; } case DW_OP_deref: case DW_OP_deref_size: case DW_OP_abs: case DW_OP_neg: case DW_OP_not: case DW_OP_plus_uconst: /* Unary operations. */ result = dwarf_expr_fetch (ctx, 0); dwarf_expr_pop (ctx); switch (op) { case DW_OP_deref: { gdb_byte *buf = alloca (ctx->addr_size); (ctx->read_mem) (ctx->baton, buf, result, ctx->addr_size); result = dwarf2_read_address (ctx->gdbarch, buf, buf + ctx->addr_size, ctx->addr_size); } break; case DW_OP_deref_size: { int addr_size = *op_ptr++; gdb_byte *buf = alloca (addr_size); (ctx->read_mem) (ctx->baton, buf, result, addr_size); result = dwarf2_read_address (ctx->gdbarch, buf, buf + addr_size, addr_size); } break; case DW_OP_abs: if ((signed int) result < 0) result = -result; break; case DW_OP_neg: result = -result; break; case DW_OP_not: result = ~result; break; case DW_OP_plus_uconst: op_ptr = read_uleb128 (op_ptr, op_end, ®); result += reg; break; } break; case DW_OP_and: case DW_OP_div: case DW_OP_minus: case DW_OP_mod: case DW_OP_mul: case DW_OP_or: case DW_OP_plus: case DW_OP_shl: case DW_OP_shr: case DW_OP_shra: case DW_OP_xor: case DW_OP_le: case DW_OP_ge: case DW_OP_eq: case DW_OP_lt: case DW_OP_gt: case DW_OP_ne: { /* Binary operations. Use the value engine to do computations in the right width. */ CORE_ADDR first, second; enum exp_opcode binop; struct value *val1 = NULL, *val2 = NULL; struct type *stype, *utype; second = dwarf_expr_fetch (ctx, 0); dwarf_expr_pop (ctx); first = dwarf_expr_fetch (ctx, 0); dwarf_expr_pop (ctx); utype = unsigned_address_type (ctx->gdbarch, ctx->addr_size); stype = signed_address_type (ctx->gdbarch, ctx->addr_size); switch (op) { case DW_OP_and: binop = BINOP_BITWISE_AND; break; case DW_OP_div: binop = BINOP_DIV; val1 = value_from_longest (stype, first); val2 = value_from_longest (stype, second); break; case DW_OP_minus: binop = BINOP_SUB; break; case DW_OP_mod: binop = BINOP_MOD; break; case DW_OP_mul: binop = BINOP_MUL; break; case DW_OP_or: binop = BINOP_BITWISE_IOR; break; case DW_OP_plus: binop = BINOP_ADD; break; case DW_OP_shl: binop = BINOP_LSH; break; case DW_OP_shr: binop = BINOP_RSH; break; case DW_OP_shra: binop = BINOP_RSH; val1 = value_from_longest (stype, first); break; case DW_OP_xor: binop = BINOP_BITWISE_XOR; break; case DW_OP_le: binop = BINOP_LEQ; val1 = value_from_longest (stype, first); val2 = value_from_longest (stype, second); break; case DW_OP_ge: binop = BINOP_GEQ; val1 = value_from_longest (stype, first); val2 = value_from_longest (stype, second); break; case DW_OP_eq: binop = BINOP_EQUAL; val1 = value_from_longest (stype, first); val2 = value_from_longest (stype, second); break; case DW_OP_lt: binop = BINOP_LESS; val1 = value_from_longest (stype, first); val2 = value_from_longest (stype, second); break; case DW_OP_gt: binop = BINOP_GTR; val1 = value_from_longest (stype, first); val2 = value_from_longest (stype, second); break; case DW_OP_ne: binop = BINOP_NOTEQUAL; val1 = value_from_longest (stype, first); val2 = value_from_longest (stype, second); break; default: internal_error (__FILE__, __LINE__, _("Can't be reached.")); } /* We use unsigned operands by default. */ if (val1 == NULL) val1 = value_from_longest (utype, first); if (val2 == NULL) val2 = value_from_longest (utype, second); result = value_as_long (value_binop (val1, val2, binop)); } break; case DW_OP_call_frame_cfa: result = (ctx->get_frame_cfa) (ctx->baton); in_stack_memory = 1; break; case DW_OP_GNU_push_tls_address: /* Variable is at a constant offset in the thread-local storage block into the objfile for the current thread and the dynamic linker module containing this expression. Here we return returns the offset from that base. The top of the stack has the offset from the beginning of the thread control block at which the variable is located. Nothing should follow this operator, so the top of stack would be returned. */ result = dwarf_expr_fetch (ctx, 0); dwarf_expr_pop (ctx); result = (ctx->get_tls_address) (ctx->baton, result); break; case DW_OP_skip: offset = extract_signed_integer (op_ptr, 2, byte_order); op_ptr += 2; op_ptr += offset; goto no_push; case DW_OP_bra: offset = extract_signed_integer (op_ptr, 2, byte_order); op_ptr += 2; if (dwarf_expr_fetch (ctx, 0) != 0) op_ptr += offset; dwarf_expr_pop (ctx); goto no_push; case DW_OP_nop: goto no_push; case DW_OP_piece: { ULONGEST size; /* Record the piece. */ op_ptr = read_uleb128 (op_ptr, op_end, &size); add_piece (ctx, size); /* Pop off the address/regnum, and reset the location type. */ if (ctx->location != DWARF_VALUE_LITERAL) dwarf_expr_pop (ctx); ctx->location = DWARF_VALUE_MEMORY; } goto no_push; case DW_OP_GNU_uninit: if (op_ptr != op_end) error (_("DWARF-2 expression error: DW_OP_GNU_uninit must always " "be the very last op.")); ctx->initialized = 0; goto no_push; default: error (_("Unhandled dwarf expression opcode 0x%x"), op); } /* Most things push a result value. */ dwarf_expr_push (ctx, result, in_stack_memory); no_push:; } ctx->recursion_depth--; gdb_assert (ctx->recursion_depth >= 0); }
static CORE_ADDR mn10300_analyze_prologue (struct frame_info *fi, CORE_ADDR pc) { CORE_ADDR func_addr, func_end, addr, stop; CORE_ADDR stack_size; int imm_size; unsigned char buf[4]; int status, movm_args = 0; char *name; /* Use the PC in the frame if it's provided to look up the start of this function. */ pc = (fi ? fi->pc : pc); /* Find the start of this function. */ status = find_pc_partial_function (pc, &name, &func_addr, &func_end); /* Do nothing if we couldn't find the start of this function or if we're stopped at the first instruction in the prologue. */ if (status == 0) { return pc; } /* If we're in start, then give up. */ if (strcmp (name, "start") == 0) { if (fi != NULL) fi->extra_info->status = NO_MORE_FRAMES; return pc; } /* At the start of a function our frame is in the stack pointer. */ if (fi) fi->extra_info->status = MY_FRAME_IN_SP; /* Get the next two bytes into buf, we need two because rets is a two byte insn and the first isn't enough to uniquely identify it. */ status = read_memory_nobpt (pc, buf, 2); if (status != 0) return pc; /* If we're physically on an "rets" instruction, then our frame has already been deallocated. Note this can also be true for retf and ret if they specify a size of zero. In this case fi->frame is bogus, we need to fix it. */ if (fi && buf[0] == 0xf0 && buf[1] == 0xfc) { if (fi->next == NULL) fi->frame = read_sp (); return fi->pc; } /* Similarly if we're stopped on the first insn of a prologue as our frame hasn't been allocated yet. */ if (fi && fi->pc == func_addr) { if (fi->next == NULL) fi->frame = read_sp (); return fi->pc; } /* Figure out where to stop scanning. */ stop = fi ? fi->pc : func_end; /* Don't walk off the end of the function. */ stop = stop > func_end ? func_end : stop; /* Start scanning on the first instruction of this function. */ addr = func_addr; /* Suck in two bytes. */ status = read_memory_nobpt (addr, buf, 2); if (status != 0) { fix_frame_pointer (fi, 0); return addr; } /* First see if this insn sets the stack pointer from a register; if so, it's probably the initialization of the stack pointer in _start, so mark this as the bottom-most frame. */ if (buf[0] == 0xf2 && (buf[1] & 0xf3) == 0xf0) { if (fi) fi->extra_info->status = NO_MORE_FRAMES; return addr; } /* Now look for movm [regs],sp, which saves the callee saved registers. At this time we don't know if fi->frame is valid, so we only note that we encountered a movm instruction. Later, we'll set the entries in fsr.regs as needed. */ if (buf[0] == 0xcf) { /* Extract the register list for the movm instruction. */ status = read_memory_nobpt (addr + 1, buf, 1); movm_args = *buf; addr += 2; /* Quit now if we're beyond the stop point. */ if (addr >= stop) { /* Fix fi->frame since it's bogus at this point. */ if (fi && fi->next == NULL) fi->frame = read_sp (); /* Note if/where callee saved registers were saved. */ set_movm_offsets (fi, movm_args); return addr; } /* Get the next two bytes so the prologue scan can continue. */ status = read_memory_nobpt (addr, buf, 2); if (status != 0) { /* Fix fi->frame since it's bogus at this point. */ if (fi && fi->next == NULL) fi->frame = read_sp (); /* Note if/where callee saved registers were saved. */ set_movm_offsets (fi, movm_args); return addr; } } /* Now see if we set up a frame pointer via "mov sp,a3" */ if (buf[0] == 0x3f) { addr += 1; /* The frame pointer is now valid. */ if (fi) { fi->extra_info->status |= MY_FRAME_IN_FP; fi->extra_info->status &= ~MY_FRAME_IN_SP; } /* Quit now if we're beyond the stop point. */ if (addr >= stop) { /* Fix fi->frame if it's bogus at this point. */ fix_frame_pointer (fi, 0); /* Note if/where callee saved registers were saved. */ set_movm_offsets (fi, movm_args); return addr; } /* Get two more bytes so scanning can continue. */ status = read_memory_nobpt (addr, buf, 2); if (status != 0) { /* Fix fi->frame if it's bogus at this point. */ fix_frame_pointer (fi, 0); /* Note if/where callee saved registers were saved. */ set_movm_offsets (fi, movm_args); return addr; } } /* Next we should allocate the local frame. No more prologue insns are found after allocating the local frame. Search for add imm8,sp (0xf8feXX) or add imm16,sp (0xfafeXXXX) or add imm32,sp (0xfcfeXXXXXXXX). If none of the above was found, then this prologue has no additional stack. */ status = read_memory_nobpt (addr, buf, 2); if (status != 0) { /* Fix fi->frame if it's bogus at this point. */ fix_frame_pointer (fi, 0); /* Note if/where callee saved registers were saved. */ set_movm_offsets (fi, movm_args); return addr; } imm_size = 0; if (buf[0] == 0xf8 && buf[1] == 0xfe) imm_size = 1; else if (buf[0] == 0xfa && buf[1] == 0xfe) imm_size = 2; else if (buf[0] == 0xfc && buf[1] == 0xfe) imm_size = 4; if (imm_size != 0) { /* Suck in imm_size more bytes, they'll hold the size of the current frame. */ status = read_memory_nobpt (addr + 2, buf, imm_size); if (status != 0) { /* Fix fi->frame if it's bogus at this point. */ fix_frame_pointer (fi, 0); /* Note if/where callee saved registers were saved. */ set_movm_offsets (fi, movm_args); return addr; } /* Note the size of the stack in the frame info structure. */ stack_size = extract_signed_integer (buf, imm_size); if (fi) fi->extra_info->stack_size = stack_size; /* We just consumed 2 + imm_size bytes. */ addr += 2 + imm_size; /* No more prologue insns follow, so begin preparation to return. */ /* Fix fi->frame if it's bogus at this point. */ fix_frame_pointer (fi, stack_size); /* Note if/where callee saved registers were saved. */ set_movm_offsets (fi, movm_args); return addr; } /* We never found an insn which allocates local stack space, regardless this is the end of the prologue. */ /* Fix fi->frame if it's bogus at this point. */ fix_frame_pointer (fi, 0); /* Note if/where callee saved registers were saved. */ set_movm_offsets (fi, movm_args); return addr; }
static void trace_save (const char *filename, struct trace_file_writer *writer, int target_does_save) { struct trace_status *ts = current_trace_status (); struct uploaded_tp *uploaded_tps = NULL, *utp; struct uploaded_tsv *uploaded_tsvs = NULL, *utsv; ULONGEST offset = 0; #define MAX_TRACE_UPLOAD 2000 gdb_byte buf[MAX_TRACE_UPLOAD]; enum bfd_endian byte_order = gdbarch_byte_order (target_gdbarch ()); /* If the target is to save the data to a file on its own, then just send the command and be done with it. */ if (target_does_save) { if (!writer->ops->target_save (writer, filename)) error (_("Target failed to save trace data to '%s'."), filename); return; } /* Get the trace status first before opening the file, so if the target is losing, we can get out without touching files. Since we're just calling this for side effects, we ignore the result. */ target_get_trace_status (ts); writer->ops->start (writer, filename); writer->ops->write_header (writer); /* Write descriptive info. */ /* Write out the size of a register block. */ writer->ops->write_regblock_type (writer, trace_regblock_size); /* Write out the target description info. */ writer->ops->write_tdesc (writer); /* Write out status of the tracing run (aka "tstatus" info). */ writer->ops->write_status (writer, ts); /* Note that we want to upload tracepoints and save those, rather than simply writing out the local ones, because the user may have changed tracepoints in GDB in preparation for a future tracing run, or maybe just mass-deleted all types of breakpoints as part of cleaning up. So as not to contaminate the session, leave the data in its uploaded form, don't make into real tracepoints. */ /* Get trace state variables first, they may be checked when parsing uploaded commands. */ target_upload_trace_state_variables (&uploaded_tsvs); for (utsv = uploaded_tsvs; utsv; utsv = utsv->next) writer->ops->write_uploaded_tsv (writer, utsv); free_uploaded_tsvs (&uploaded_tsvs); target_upload_tracepoints (&uploaded_tps); for (utp = uploaded_tps; utp; utp = utp->next) target_get_tracepoint_status (NULL, utp); for (utp = uploaded_tps; utp; utp = utp->next) writer->ops->write_uploaded_tp (writer, utp); free_uploaded_tps (&uploaded_tps); /* Mark the end of the definition section. */ writer->ops->write_definition_end (writer); /* Get and write the trace data proper. */ while (1) { LONGEST gotten = 0; /* The writer supports writing the contents of trace buffer directly to trace file. Don't parse the contents of trace buffer. */ if (writer->ops->write_trace_buffer != NULL) { /* We ask for big blocks, in the hopes of efficiency, but will take less if the target has packet size limitations or some such. */ gotten = target_get_raw_trace_data (buf, offset, MAX_TRACE_UPLOAD); if (gotten < 0) error (_("Failure to get requested trace buffer data")); /* No more data is forthcoming, we're done. */ if (gotten == 0) break; writer->ops->write_trace_buffer (writer, buf, gotten); offset += gotten; } else { uint16_t tp_num; uint32_t tf_size; /* Parse the trace buffers according to how data are stored in trace buffer in GDBserver. */ gotten = target_get_raw_trace_data (buf, offset, 6); if (gotten == 0) break; /* Read the first six bytes in, which is the tracepoint number and trace frame size. */ tp_num = (uint16_t) extract_unsigned_integer (&buf[0], 2, byte_order); tf_size = (uint32_t) extract_unsigned_integer (&buf[2], 4, byte_order); writer->ops->frame_ops->start (writer, tp_num); gotten = 6; if (tf_size > 0) { unsigned int block; offset += 6; for (block = 0; block < tf_size; ) { gdb_byte block_type; /* We'll fetch one block each time, in order to handle the extremely large 'M' block. We first fetch one byte to get the type of the block. */ gotten = target_get_raw_trace_data (buf, offset, 1); if (gotten < 1) error (_("Failure to get requested trace buffer data")); gotten = 1; block += 1; offset += 1; block_type = buf[0]; switch (block_type) { case 'R': gotten = target_get_raw_trace_data (buf, offset, trace_regblock_size); if (gotten < trace_regblock_size) error (_("Failure to get requested trace" " buffer data")); TRACE_WRITE_R_BLOCK (writer, buf, trace_regblock_size); break; case 'M': { unsigned short mlen; ULONGEST addr; LONGEST t; int j; t = target_get_raw_trace_data (buf,offset, 10); if (t < 10) error (_("Failure to get requested trace" " buffer data")); offset += 10; block += 10; gotten = 0; addr = (ULONGEST) extract_unsigned_integer (buf, 8, byte_order); mlen = (unsigned short) extract_unsigned_integer (&buf[8], 2, byte_order); TRACE_WRITE_M_BLOCK_HEADER (writer, addr, mlen); /* The memory contents in 'M' block may be very large. Fetch the data from the target and write them into file one by one. */ for (j = 0; j < mlen; ) { unsigned int read_length; if (mlen - j > MAX_TRACE_UPLOAD) read_length = MAX_TRACE_UPLOAD; else read_length = mlen - j; t = target_get_raw_trace_data (buf, offset + j, read_length); if (t < read_length) error (_("Failure to get requested" " trace buffer data")); TRACE_WRITE_M_BLOCK_MEMORY (writer, buf, read_length); j += read_length; gotten += read_length; } break; } case 'V': { int vnum; LONGEST val; gotten = target_get_raw_trace_data (buf, offset, 12); if (gotten < 12) error (_("Failure to get requested" " trace buffer data")); vnum = (int) extract_signed_integer (buf, 4, byte_order); val = extract_signed_integer (&buf[4], 8, byte_order); TRACE_WRITE_V_BLOCK (writer, vnum, val); } break; default: error (_("Unknown block type '%c' (0x%x) in" " trace frame"), block_type, block_type); } block += gotten; offset += gotten; } } else offset += gotten; writer->ops->frame_ops->end (writer); } } writer->ops->end (writer); }
static struct value * evaluate_subexp_java (struct type *expect_type, struct expression *exp, int *pos, enum noside noside) { int pc = *pos; int i; const char *name; enum exp_opcode op = exp->elts[*pos].opcode; struct value *arg1; struct value *arg2; struct type *type; switch (op) { case UNOP_IND: if (noside == EVAL_SKIP) goto standard; (*pos)++; arg1 = evaluate_subexp_java (NULL_TYPE, exp, pos, EVAL_NORMAL); if (is_object_type (value_type (arg1))) { struct type *type; type = type_from_class (exp->gdbarch, java_class_from_object (arg1)); arg1 = value_cast (lookup_pointer_type (type), arg1); } return value_ind (arg1); case BINOP_SUBSCRIPT: (*pos)++; arg1 = evaluate_subexp_with_coercion (exp, pos, noside); arg2 = evaluate_subexp_with_coercion (exp, pos, noside); if (noside == EVAL_SKIP) goto nosideret; /* If the user attempts to subscript something that is not an array or pointer type (like a plain int variable for example), then report this as an error. */ arg1 = coerce_ref (arg1); type = check_typedef (value_type (arg1)); if (TYPE_CODE (type) == TYPE_CODE_PTR) type = check_typedef (TYPE_TARGET_TYPE (type)); name = TYPE_NAME (type); if (name == NULL) name = TYPE_TAG_NAME (type); i = name == NULL ? 0 : strlen (name); if (TYPE_CODE (type) == TYPE_CODE_STRUCT && i > 2 && name[i - 1] == ']') { enum bfd_endian byte_order = gdbarch_byte_order (exp->gdbarch); CORE_ADDR address; long length, index; struct type *el_type; gdb_byte buf4[4]; struct value *clas = java_class_from_object (arg1); struct value *temp = clas; /* Get CLASS_ELEMENT_TYPE of the array type. */ temp = value_struct_elt (&temp, NULL, "methods", NULL, "structure"); deprecated_set_value_type (temp, value_type (clas)); el_type = type_from_class (exp->gdbarch, temp); if (TYPE_CODE (el_type) == TYPE_CODE_STRUCT) el_type = lookup_pointer_type (el_type); if (noside == EVAL_AVOID_SIDE_EFFECTS) return value_zero (el_type, VALUE_LVAL (arg1)); address = value_as_address (arg1); address += get_java_object_header_size (exp->gdbarch); read_memory (address, buf4, 4); length = (long) extract_signed_integer (buf4, 4, byte_order); index = (long) value_as_long (arg2); if (index >= length || index < 0) error (_("array index (%ld) out of bounds (length: %ld)"), index, length); address = (address + 4) + index * TYPE_LENGTH (el_type); return value_at (el_type, address); } else if (TYPE_CODE (type) == TYPE_CODE_ARRAY) { if (noside == EVAL_AVOID_SIDE_EFFECTS) return value_zero (TYPE_TARGET_TYPE (type), VALUE_LVAL (arg1)); else return value_subscript (arg1, value_as_long (arg2)); } if (name) error (_("cannot subscript something of type `%s'"), name); else error (_("cannot subscript requested type")); case OP_STRING: (*pos)++; i = longest_to_int (exp->elts[pc + 1].longconst); (*pos) += 3 + BYTES_TO_EXP_ELEM (i + 1); if (noside == EVAL_SKIP) goto nosideret; return java_value_string (&exp->elts[pc + 2].string, i); case STRUCTOP_PTR: arg1 = evaluate_subexp_standard (expect_type, exp, pos, noside); /* Convert object field (such as TYPE.class) to reference. */ if (TYPE_CODE (value_type (arg1)) == TYPE_CODE_STRUCT) arg1 = value_addr (arg1); return arg1; default: break; } standard: return evaluate_subexp_standard (expect_type, exp, pos, noside); nosideret: return value_from_longest (builtin_type (exp->gdbarch)->builtin_int, 1); }
int java_value_print (struct value *val, struct ui_file *stream, const struct value_print_options *options) { struct gdbarch *gdbarch = get_type_arch (value_type (val)); enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); struct type *type; CORE_ADDR address; int i; char *name; struct value_print_options opts; type = value_type (val); address = value_address (val); if (is_object_type (type)) { CORE_ADDR obj_addr; /* Get the run-time type, and cast the object into that */ obj_addr = unpack_pointer (type, value_contents (val)); if (obj_addr != 0) { type = type_from_class (gdbarch, java_class_from_object (val)); type = lookup_pointer_type (type); val = value_at (type, address); } } if (TYPE_CODE (type) == TYPE_CODE_PTR && !value_logical_not (val)) type_print (TYPE_TARGET_TYPE (type), "", stream, -1); name = TYPE_TAG_NAME (type); if (TYPE_CODE (type) == TYPE_CODE_STRUCT && name != NULL && (i = strlen (name), name[i - 1] == ']')) { gdb_byte buf4[4]; long length; unsigned int things_printed = 0; int reps; struct type *el_type = java_primitive_type_from_name (gdbarch, name, i - 2); i = 0; read_memory (address + get_java_object_header_size (gdbarch), buf4, 4); length = (long) extract_signed_integer (buf4, 4, byte_order); fprintf_filtered (stream, "{length: %ld", length); if (el_type == NULL) { CORE_ADDR element; CORE_ADDR next_element = -1; /* dummy initial value */ /* Skip object header and length. */ address += get_java_object_header_size (gdbarch) + 4; while (i < length && things_printed < options->print_max) { gdb_byte *buf; buf = alloca (gdbarch_ptr_bit (gdbarch) / HOST_CHAR_BIT); fputs_filtered (", ", stream); wrap_here (n_spaces (2)); if (i > 0) element = next_element; else { read_memory (address, buf, sizeof (buf)); address += gdbarch_ptr_bit (gdbarch) / HOST_CHAR_BIT; /* FIXME: cagney/2003-05-24: Bogus or what. It pulls a host sized pointer out of the target and then extracts that as an address (while assuming that the address is unsigned)! */ element = extract_unsigned_integer (buf, sizeof (buf), byte_order); } for (reps = 1; i + reps < length; reps++) { read_memory (address, buf, sizeof (buf)); address += gdbarch_ptr_bit (gdbarch) / HOST_CHAR_BIT; /* FIXME: cagney/2003-05-24: Bogus or what. It pulls a host sized pointer out of the target and then extracts that as an address (while assuming that the address is unsigned)! */ next_element = extract_unsigned_integer (buf, sizeof (buf), byte_order); if (next_element != element) break; } if (reps == 1) fprintf_filtered (stream, "%d: ", i); else fprintf_filtered (stream, "%d..%d: ", i, i + reps - 1); if (element == 0) fprintf_filtered (stream, "null"); else fprintf_filtered (stream, "@%s", paddress (gdbarch, element)); things_printed++; i += reps; } } else { struct value *v = allocate_value (el_type); struct value *next_v = allocate_value (el_type); set_value_address (v, (address + get_java_object_header_size (gdbarch) + 4)); set_value_address (next_v, value_raw_address (v)); while (i < length && things_printed < options->print_max) { fputs_filtered (", ", stream); wrap_here (n_spaces (2)); if (i > 0) { struct value *tmp; tmp = next_v; next_v = v; v = tmp; } else { set_value_lazy (v, 1); set_value_offset (v, 0); } set_value_offset (next_v, value_offset (v)); for (reps = 1; i + reps < length; reps++) { set_value_lazy (next_v, 1); set_value_offset (next_v, value_offset (next_v) + TYPE_LENGTH (el_type)); if (memcmp (value_contents (v), value_contents (next_v), TYPE_LENGTH (el_type)) != 0) break; } if (reps == 1) fprintf_filtered (stream, "%d: ", i); else fprintf_filtered (stream, "%d..%d: ", i, i + reps - 1); opts = *options; opts.deref_ref = 1; common_val_print (v, stream, 1, &opts, current_language); things_printed++; i += reps; } } if (i < length) fprintf_filtered (stream, "..."); fprintf_filtered (stream, "}"); return 0; } /* If it's type String, print it */ if (TYPE_CODE (type) == TYPE_CODE_PTR && TYPE_TARGET_TYPE (type) && TYPE_TAG_NAME (TYPE_TARGET_TYPE (type)) && strcmp (TYPE_TAG_NAME (TYPE_TARGET_TYPE (type)), "java.lang.String") == 0 && (options->format == 0 || options->format == 's') && address != 0 && value_as_address (val) != 0) { struct type *char_type; struct value *data_val; CORE_ADDR data; struct value *boffset_val; unsigned long boffset; struct value *count_val; unsigned long count; struct value *mark; mark = value_mark (); /* Remember start of new values */ data_val = value_struct_elt (&val, NULL, "data", NULL, NULL); data = value_as_address (data_val); boffset_val = value_struct_elt (&val, NULL, "boffset", NULL, NULL); boffset = value_as_address (boffset_val); count_val = value_struct_elt (&val, NULL, "count", NULL, NULL); count = value_as_address (count_val); value_free_to_mark (mark); /* Release unnecessary values */ char_type = builtin_java_type (gdbarch)->builtin_char; val_print_string (char_type, data + boffset, count, stream, options); return 0; } opts = *options; opts.deref_ref = 1; return common_val_print (val, stream, 0, &opts, current_language); }
static void scm_lreadr (int skipping) { int c, j; struct stoken str; LONGEST svalue = 0; tryagain: c = *lexptr++; switch (c) { case '\0': lexptr--; return; case '[': case '(': scm_lreadparen (skipping); return; case ']': case ')': error ("unexpected #\\%c", c); goto tryagain; case '\'': case '`': str.ptr = lexptr - 1; scm_lreadr (skipping); if (!skipping) { struct value *val = scm_evaluate_string (str.ptr, lexptr - str.ptr); if (!is_scmvalue_type (value_type (val))) error ("quoted scm form yields non-SCM value"); svalue = extract_signed_integer (value_contents (val), TYPE_LENGTH (value_type (val))); goto handle_immediate; } return; case ',': c = *lexptr++; if ('@' != c) lexptr--; scm_lreadr (skipping); return; case '#': c = *lexptr++; switch (c) { case '[': case '(': scm_lreadparen (skipping); return; case 't': case 'T': svalue = SCM_BOOL_T; goto handle_immediate; case 'f': case 'F': svalue = SCM_BOOL_F; goto handle_immediate; case 'b': case 'B': case 'o': case 'O': case 'd': case 'D': case 'x': case 'X': case 'i': case 'I': case 'e': case 'E': lexptr--; c = '#'; goto num; case '*': /* bitvector */ scm_read_token (c, 0); return; case '{': scm_read_token (c, 1); return; case '\\': /* character */ c = *lexptr++; scm_read_token (c, 0); return; case '|': j = 1; /* here j is the comment nesting depth */ lp: c = *lexptr++; lpc: switch (c) { case '\0': error ("unbalanced comment"); default: goto lp; case '|': if ('#' != (c = *lexptr++)) goto lpc; if (--j) goto lp; break; case '#': if ('|' != (c = *lexptr++)) goto lpc; ++j; goto lp; } goto tryagain; case '.': default: #if 0 callshrp: #endif scm_lreadr (skipping); return; } case '\"': while ('\"' != (c = *lexptr++)) { if (c == '\\') switch (c = *lexptr++) { case '\0': error ("non-terminated string literal"); case '\n': continue; case '0': case 'f': case 'n': case 'r': case 't': case 'a': case 'v': break; } } return; case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': case '.': case '-': case '+': num: { str.ptr = lexptr - 1; scm_read_token (c, 0); if (!skipping) { svalue = scm_istring2number (str.ptr, lexptr - str.ptr, 10); if (svalue != SCM_BOOL_F) goto handle_immediate; goto tok; } } return; case ':': scm_read_token ('-', 0); return; #if 0 do_symbol: #endif default: str.ptr = lexptr - 1; scm_read_token (c, 0); tok: if (!skipping) { str.length = lexptr - str.ptr; if (str.ptr[0] == '$') { write_dollar_variable (str); return; } write_exp_elt_opcode (OP_NAME); write_exp_string (str); write_exp_elt_opcode (OP_NAME); } return; } handle_immediate: if (!skipping) { write_exp_elt_opcode (OP_LONG); write_exp_elt_type (builtin_type_scm); write_exp_elt_longcst (svalue); write_exp_elt_opcode (OP_LONG); } }
int java_value_print (struct value *val, struct ui_file *stream, int format, enum val_prettyprint pretty) { struct type *type; CORE_ADDR address; int i; char *name; type = VALUE_TYPE (val); address = VALUE_ADDRESS (val) + VALUE_OFFSET (val); if (is_object_type (type)) { CORE_ADDR obj_addr; /* Get the run-time type, and cast the object into that */ obj_addr = unpack_pointer (type, VALUE_CONTENTS (val)); if (obj_addr != 0) { type = type_from_class (java_class_from_object (val)); type = lookup_pointer_type (type); val = value_at (type, address, NULL); } } if (TYPE_CODE (type) == TYPE_CODE_PTR && !value_logical_not (val)) type_print (TYPE_TARGET_TYPE (type), "", stream, -1); name = TYPE_TAG_NAME (type); if (TYPE_CODE (type) == TYPE_CODE_STRUCT && name != NULL && (i = strlen (name), name[i - 1] == ']')) { char buf4[4]; long length; unsigned int things_printed = 0; int reps; struct type *el_type = java_primitive_type_from_name (name, i - 2); i = 0; read_memory (address + JAVA_OBJECT_SIZE, buf4, 4); length = (long) extract_signed_integer (buf4, 4); fprintf_filtered (stream, "{length: %ld", length); if (el_type == NULL) { CORE_ADDR element; CORE_ADDR next_element = -1; /* dummy initial value */ address += JAVA_OBJECT_SIZE + 4; /* Skip object header and length. */ while (i < length && things_printed < print_max) { char *buf; buf = alloca (TARGET_PTR_BIT / HOST_CHAR_BIT); fputs_filtered (", ", stream); wrap_here (n_spaces (2)); if (i > 0) element = next_element; else { read_memory (address, buf, sizeof (buf)); address += TARGET_PTR_BIT / HOST_CHAR_BIT; element = extract_address (buf, sizeof (buf)); } for (reps = 1; i + reps < length; reps++) { read_memory (address, buf, sizeof (buf)); address += TARGET_PTR_BIT / HOST_CHAR_BIT; next_element = extract_address (buf, sizeof (buf)); if (next_element != element) break; } if (reps == 1) fprintf_filtered (stream, "%d: ", i); else fprintf_filtered (stream, "%d..%d: ", i, i + reps - 1); if (element == 0) fprintf_filtered (stream, "null"); else fprintf_filtered (stream, "@%s", paddr_nz (element)); things_printed++; i += reps; } } else { struct value *v = allocate_value (el_type); struct value *next_v = allocate_value (el_type); VALUE_ADDRESS (v) = address + JAVA_OBJECT_SIZE + 4; VALUE_ADDRESS (next_v) = VALUE_ADDRESS (v); while (i < length && things_printed < print_max) { fputs_filtered (", ", stream); wrap_here (n_spaces (2)); if (i > 0) { struct value *tmp; tmp = next_v; next_v = v; v = tmp; } else { VALUE_LAZY (v) = 1; VALUE_OFFSET (v) = 0; } VALUE_OFFSET (next_v) = VALUE_OFFSET (v); for (reps = 1; i + reps < length; reps++) { VALUE_LAZY (next_v) = 1; VALUE_OFFSET (next_v) += TYPE_LENGTH (el_type); if (memcmp (VALUE_CONTENTS (v), VALUE_CONTENTS (next_v), TYPE_LENGTH (el_type)) != 0) break; } if (reps == 1) fprintf_filtered (stream, "%d: ", i); else fprintf_filtered (stream, "%d..%d: ", i, i + reps - 1); val_print (VALUE_TYPE (v), VALUE_CONTENTS (v), 0, 0, stream, format, 2, 1, pretty); things_printed++; i += reps; } } if (i < length) fprintf_filtered (stream, "..."); fprintf_filtered (stream, "}"); return 0; } /* If it's type String, print it */ if (TYPE_CODE (type) == TYPE_CODE_PTR && TYPE_TARGET_TYPE (type) && TYPE_NAME (TYPE_TARGET_TYPE (type)) && strcmp (TYPE_NAME (TYPE_TARGET_TYPE (type)), "java.lang.String") == 0 && (format == 0 || format == 's') && address != 0 && value_as_address (val) != 0) { struct value *data_val; CORE_ADDR data; struct value *boffset_val; unsigned long boffset; struct value *count_val; unsigned long count; struct value *mark; mark = value_mark (); /* Remember start of new values */ data_val = value_struct_elt (&val, NULL, "data", NULL, NULL); data = value_as_address (data_val); boffset_val = value_struct_elt (&val, NULL, "boffset", NULL, NULL); boffset = value_as_address (boffset_val); count_val = value_struct_elt (&val, NULL, "count", NULL, NULL); count = value_as_address (count_val); value_free_to_mark (mark); /* Release unnecessary values */ val_print_string (data + boffset, count, 2, stream); return 0; } return (val_print (type, VALUE_CONTENTS (val), 0, address, stream, format, 1, 0, pretty)); }
void mips64_fill_fpregset (const struct regcache *regcache, mips64_elf_fpregset_t *fpregsetp, int regno) { struct gdbarch *gdbarch = get_regcache_arch (regcache); enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); gdb_byte *to; if ((regno >= gdbarch_fp0_regnum (gdbarch)) && (regno < gdbarch_fp0_regnum (gdbarch) + 32)) { /* See mips_linux_o32_sigframe_init for a description of the peculiar FP register layout. */ if (register_size (gdbarch, regno) == 4) { int regi = regno - gdbarch_fp0_regnum (gdbarch); to = (gdb_byte *) (*fpregsetp + (regi & ~1)); if ((gdbarch_byte_order (gdbarch) == BFD_ENDIAN_BIG) != (regi & 1)) to += 4; regcache_raw_collect (regcache, regno, to); } else { to = (gdb_byte *) (*fpregsetp + regno - gdbarch_fp0_regnum (gdbarch)); regcache_raw_collect (regcache, regno, to); } } else if (regno == mips_regnum (gdbarch)->fp_control_status) { gdb_byte buf[MAX_REGISTER_SIZE]; LONGEST val; regcache_raw_collect (regcache, regno, buf); val = extract_signed_integer (buf, register_size (gdbarch, regno), byte_order); to = (gdb_byte *) (*fpregsetp + 32); store_signed_integer (to, 4, byte_order, val); } else if (regno == mips_regnum (gdbarch)->fp_implementation_revision) { gdb_byte buf[MAX_REGISTER_SIZE]; LONGEST val; regcache_raw_collect (regcache, regno, buf); val = extract_signed_integer (buf, register_size (gdbarch, regno), byte_order); to = (gdb_byte *) (*fpregsetp + 32) + 4; store_signed_integer (to, 4, byte_order, val); } else if (regno == -1) { int regi; for (regi = 0; regi < 32; regi++) mips64_fill_fpregset (regcache, fpregsetp, gdbarch_fp0_regnum (gdbarch) + regi); mips64_fill_fpregset (regcache, fpregsetp, mips_regnum (gdbarch)->fp_control_status); mips64_fill_fpregset (regcache, fpregsetp, (mips_regnum (gdbarch) ->fp_implementation_revision)); } }
static CORE_ADDR mn10300_analyze_prologue (struct frame_info *fi, void **this_cache, CORE_ADDR pc) { CORE_ADDR func_addr, func_end, addr, stop; long stack_size; int imm_size; unsigned char buf[4]; int status, movm_args = 0; char *name; /* Use the PC in the frame if it's provided to look up the start of this function. Note: kevinb/2003-07-16: We used to do the following here: pc = (fi ? get_frame_pc (fi) : pc); But this is (now) badly broken when called from analyze_dummy_frame(). */ if (fi) { pc = (pc ? pc : get_frame_pc (fi)); /* At the start of a function our frame is in the stack pointer. */ my_frame_is_in_sp (fi, this_cache); } /* Find the start of this function. */ status = find_pc_partial_function (pc, &name, &func_addr, &func_end); /* Do nothing if we couldn't find the start of this function MVS: comment went on to say "or if we're stopped at the first instruction in the prologue" -- but code doesn't reflect that, and I don't want to do that anyway. */ if (status == 0) { return pc; } /* If we're in start, then give up. */ if (strcmp (name, "start") == 0) { if (fi != NULL) my_frame_is_last (fi); return pc; } #if 0 /* Get the next two bytes into buf, we need two because rets is a two byte insn and the first isn't enough to uniquely identify it. */ status = deprecated_read_memory_nobpt (pc, buf, 2); if (status != 0) return pc; /* Note: kevinb/2003-07-16: We shouldn't be making these sorts of changes to the frame in prologue examination code. */ /* If we're physically on an "rets" instruction, then our frame has already been deallocated. Note this can also be true for retf and ret if they specify a size of zero. In this case fi->frame is bogus, we need to fix it. */ if (fi && buf[0] == 0xf0 && buf[1] == 0xfc) { if (get_next_frame (fi) == NULL) deprecated_update_frame_base_hack (fi, read_sp ()); return get_frame_pc (fi); } /* Similarly if we're stopped on the first insn of a prologue as our frame hasn't been allocated yet. */ if (fi && get_frame_pc (fi) == func_addr) { if (get_next_frame (fi) == NULL) deprecated_update_frame_base_hack (fi, read_sp ()); return get_frame_pc (fi); } #endif /* NOTE: from here on, we don't want to return without jumping to finish_prologue. */ /* Figure out where to stop scanning. */ stop = fi ? pc : func_end; /* Don't walk off the end of the function. */ stop = stop > func_end ? func_end : stop; /* Start scanning on the first instruction of this function. */ addr = func_addr; /* Suck in two bytes. */ if (addr + 2 >= stop || (status = deprecated_read_memory_nobpt (addr, buf, 2)) != 0) goto finish_prologue; /* First see if this insn sets the stack pointer from a register; if so, it's probably the initialization of the stack pointer in _start, so mark this as the bottom-most frame. */ if (buf[0] == 0xf2 && (buf[1] & 0xf3) == 0xf0) { if (fi) my_frame_is_last (fi); goto finish_prologue; } /* Now look for movm [regs],sp, which saves the callee saved registers. At this time we don't know if fi->frame is valid, so we only note that we encountered a movm instruction. Later, we'll set the entries in fsr.regs as needed. */ if (buf[0] == 0xcf) { /* Extract the register list for the movm instruction. */ movm_args = buf[1]; addr += 2; /* Quit now if we're beyond the stop point. */ if (addr >= stop) goto finish_prologue; /* Get the next two bytes so the prologue scan can continue. */ status = deprecated_read_memory_nobpt (addr, buf, 2); if (status != 0) goto finish_prologue; } /* Now see if we set up a frame pointer via "mov sp,a3" */ if (buf[0] == 0x3f) { addr += 1; /* The frame pointer is now valid. */ if (fi) { my_frame_is_in_fp (fi, this_cache); } /* Quit now if we're beyond the stop point. */ if (addr >= stop) goto finish_prologue; /* Get two more bytes so scanning can continue. */ status = deprecated_read_memory_nobpt (addr, buf, 2); if (status != 0) goto finish_prologue; } /* Next we should allocate the local frame. No more prologue insns are found after allocating the local frame. Search for add imm8,sp (0xf8feXX) or add imm16,sp (0xfafeXXXX) or add imm32,sp (0xfcfeXXXXXXXX). If none of the above was found, then this prologue has no additional stack. */ imm_size = 0; if (buf[0] == 0xf8 && buf[1] == 0xfe) imm_size = 1; else if (buf[0] == 0xfa && buf[1] == 0xfe) imm_size = 2; else if (buf[0] == 0xfc && buf[1] == 0xfe) imm_size = 4; if (imm_size != 0) { /* Suck in imm_size more bytes, they'll hold the size of the current frame. */ status = deprecated_read_memory_nobpt (addr + 2, buf, imm_size); if (status != 0) goto finish_prologue; /* Note the size of the stack in the frame info structure. */ stack_size = extract_signed_integer (buf, imm_size); if (fi) set_my_stack_size (fi, stack_size); /* We just consumed 2 + imm_size bytes. */ addr += 2 + imm_size; /* No more prologue insns follow, so begin preparation to return. */ goto finish_prologue; } /* Do the essentials and get out of here. */ finish_prologue: /* Note if/where callee saved registers were saved. */ if (fi) set_movm_offsets (fi, this_cache, movm_args); return addr; }
static void execute_stack_op (struct dwarf_expr_context *ctx, unsigned char *op_ptr, unsigned char *op_end) { ctx->in_reg = 0; while (op_ptr < op_end) { enum dwarf_location_atom op = *op_ptr++; CORE_ADDR result; ULONGEST uoffset, reg; LONGEST offset; int bytes_read; switch (op) { case DW_OP_lit0: case DW_OP_lit1: case DW_OP_lit2: case DW_OP_lit3: case DW_OP_lit4: case DW_OP_lit5: case DW_OP_lit6: case DW_OP_lit7: case DW_OP_lit8: case DW_OP_lit9: case DW_OP_lit10: case DW_OP_lit11: case DW_OP_lit12: case DW_OP_lit13: case DW_OP_lit14: case DW_OP_lit15: case DW_OP_lit16: case DW_OP_lit17: case DW_OP_lit18: case DW_OP_lit19: case DW_OP_lit20: case DW_OP_lit21: case DW_OP_lit22: case DW_OP_lit23: case DW_OP_lit24: case DW_OP_lit25: case DW_OP_lit26: case DW_OP_lit27: case DW_OP_lit28: case DW_OP_lit29: case DW_OP_lit30: case DW_OP_lit31: result = op - DW_OP_lit0; break; case DW_OP_addr: result = dwarf2_read_address (op_ptr, op_end, &bytes_read); op_ptr += bytes_read; break; case DW_OP_const1u: result = extract_unsigned_integer (op_ptr, 1); op_ptr += 1; break; case DW_OP_const1s: result = extract_signed_integer (op_ptr, 1); op_ptr += 1; break; case DW_OP_const2u: result = extract_unsigned_integer (op_ptr, 2); op_ptr += 2; break; case DW_OP_const2s: result = extract_signed_integer (op_ptr, 2); op_ptr += 2; break; case DW_OP_const4u: result = extract_unsigned_integer (op_ptr, 4); op_ptr += 4; break; case DW_OP_const4s: result = extract_signed_integer (op_ptr, 4); op_ptr += 4; break; case DW_OP_const8u: result = extract_unsigned_integer (op_ptr, 8); op_ptr += 8; break; case DW_OP_const8s: result = extract_signed_integer (op_ptr, 8); op_ptr += 8; break; case DW_OP_constu: op_ptr = read_uleb128 (op_ptr, op_end, &uoffset); result = uoffset; break; case DW_OP_consts: op_ptr = read_sleb128 (op_ptr, op_end, &offset); result = offset; break; /* The DW_OP_reg operations are required to occur alone in location expressions. */ case DW_OP_reg0: case DW_OP_reg1: case DW_OP_reg2: case DW_OP_reg3: case DW_OP_reg4: case DW_OP_reg5: case DW_OP_reg6: case DW_OP_reg7: case DW_OP_reg8: case DW_OP_reg9: case DW_OP_reg10: case DW_OP_reg11: case DW_OP_reg12: case DW_OP_reg13: case DW_OP_reg14: case DW_OP_reg15: case DW_OP_reg16: case DW_OP_reg17: case DW_OP_reg18: case DW_OP_reg19: case DW_OP_reg20: case DW_OP_reg21: case DW_OP_reg22: case DW_OP_reg23: case DW_OP_reg24: case DW_OP_reg25: case DW_OP_reg26: case DW_OP_reg27: case DW_OP_reg28: case DW_OP_reg29: case DW_OP_reg30: case DW_OP_reg31: if (op_ptr != op_end && *op_ptr != DW_OP_piece) error ("DWARF-2 expression error: DW_OP_reg operations must be " "used either alone or in conjuction with DW_OP_piece."); result = op - DW_OP_reg0; ctx->in_reg = 1; break; case DW_OP_regx: op_ptr = read_uleb128 (op_ptr, op_end, ®); if (op_ptr != op_end && *op_ptr != DW_OP_piece) error ("DWARF-2 expression error: DW_OP_reg operations must be " "used either alone or in conjuction with DW_OP_piece."); result = reg; ctx->in_reg = 1; break; case DW_OP_breg0: case DW_OP_breg1: case DW_OP_breg2: case DW_OP_breg3: case DW_OP_breg4: case DW_OP_breg5: case DW_OP_breg6: case DW_OP_breg7: case DW_OP_breg8: case DW_OP_breg9: case DW_OP_breg10: case DW_OP_breg11: case DW_OP_breg12: case DW_OP_breg13: case DW_OP_breg14: case DW_OP_breg15: case DW_OP_breg16: case DW_OP_breg17: case DW_OP_breg18: case DW_OP_breg19: case DW_OP_breg20: case DW_OP_breg21: case DW_OP_breg22: case DW_OP_breg23: case DW_OP_breg24: case DW_OP_breg25: case DW_OP_breg26: case DW_OP_breg27: case DW_OP_breg28: case DW_OP_breg29: case DW_OP_breg30: case DW_OP_breg31: { op_ptr = read_sleb128 (op_ptr, op_end, &offset); result = (ctx->read_reg) (ctx->baton, op - DW_OP_breg0); result += offset; } break; case DW_OP_bregx: { op_ptr = read_uleb128 (op_ptr, op_end, ®); op_ptr = read_sleb128 (op_ptr, op_end, &offset); result = (ctx->read_reg) (ctx->baton, reg); result += offset; } break; case DW_OP_fbreg: { unsigned char *datastart; size_t datalen; unsigned int before_stack_len; op_ptr = read_sleb128 (op_ptr, op_end, &offset); /* Rather than create a whole new context, we simply record the stack length before execution, then reset it afterwards, effectively erasing whatever the recursive call put there. */ before_stack_len = ctx->stack_len; /* FIXME: cagney/2003-03-26: This code should be using get_frame_base_address(), and then implement a dwarf2 specific this_base method. */ (ctx->get_frame_base) (ctx->baton, &datastart, &datalen); dwarf_expr_eval (ctx, datastart, datalen); result = dwarf_expr_fetch (ctx, 0); if (ctx->in_reg) result = (ctx->read_reg) (ctx->baton, result); result = result + offset; ctx->stack_len = before_stack_len; ctx->in_reg = 0; } break; case DW_OP_dup: result = dwarf_expr_fetch (ctx, 0); break; case DW_OP_drop: dwarf_expr_pop (ctx); goto no_push; case DW_OP_pick: offset = *op_ptr++; result = dwarf_expr_fetch (ctx, offset); break; case DW_OP_over: result = dwarf_expr_fetch (ctx, 1); break; case DW_OP_rot: { CORE_ADDR t1, t2, t3; if (ctx->stack_len < 3) error ("Not enough elements for DW_OP_rot. Need 3, have %d\n", ctx->stack_len); t1 = ctx->stack[ctx->stack_len - 1]; t2 = ctx->stack[ctx->stack_len - 2]; t3 = ctx->stack[ctx->stack_len - 3]; ctx->stack[ctx->stack_len - 1] = t2; ctx->stack[ctx->stack_len - 2] = t3; ctx->stack[ctx->stack_len - 3] = t1; goto no_push; } case DW_OP_deref: case DW_OP_deref_size: case DW_OP_abs: case DW_OP_neg: case DW_OP_not: case DW_OP_plus_uconst: /* Unary operations. */ result = dwarf_expr_fetch (ctx, 0); dwarf_expr_pop (ctx); switch (op) { case DW_OP_deref: { char *buf = alloca (TARGET_ADDR_BIT / TARGET_CHAR_BIT); int bytes_read; (ctx->read_mem) (ctx->baton, buf, result, TARGET_ADDR_BIT / TARGET_CHAR_BIT); result = dwarf2_read_address (buf, buf + (TARGET_ADDR_BIT / TARGET_CHAR_BIT), &bytes_read); } break; case DW_OP_deref_size: { char *buf = alloca (TARGET_ADDR_BIT / TARGET_CHAR_BIT); int bytes_read; (ctx->read_mem) (ctx->baton, buf, result, *op_ptr++); result = dwarf2_read_address (buf, buf + (TARGET_ADDR_BIT / TARGET_CHAR_BIT), &bytes_read); } break; case DW_OP_abs: if ((signed int) result < 0) result = -result; break; case DW_OP_neg: result = -result; break; case DW_OP_not: result = ~result; break; case DW_OP_plus_uconst: op_ptr = read_uleb128 (op_ptr, op_end, ®); result += reg; break; } break; case DW_OP_and: case DW_OP_div: case DW_OP_minus: case DW_OP_mod: case DW_OP_mul: case DW_OP_or: case DW_OP_plus: case DW_OP_shl: case DW_OP_shr: case DW_OP_shra: case DW_OP_xor: case DW_OP_le: case DW_OP_ge: case DW_OP_eq: case DW_OP_lt: case DW_OP_gt: case DW_OP_ne: { /* Binary operations. Use the value engine to do computations in the right width. */ CORE_ADDR first, second; enum exp_opcode binop; struct value *val1, *val2; second = dwarf_expr_fetch (ctx, 0); dwarf_expr_pop (ctx); first = dwarf_expr_fetch (ctx, 0); dwarf_expr_pop (ctx); val1 = value_from_longest (unsigned_address_type (), first); val2 = value_from_longest (unsigned_address_type (), second); switch (op) { case DW_OP_and: binop = BINOP_BITWISE_AND; break; case DW_OP_div: binop = BINOP_DIV; break; case DW_OP_minus: binop = BINOP_SUB; break; case DW_OP_mod: binop = BINOP_MOD; break; case DW_OP_mul: binop = BINOP_MUL; break; case DW_OP_or: binop = BINOP_BITWISE_IOR; break; case DW_OP_plus: binop = BINOP_ADD; break; case DW_OP_shl: binop = BINOP_LSH; break; case DW_OP_shr: binop = BINOP_RSH; break; case DW_OP_shra: binop = BINOP_RSH; val1 = value_from_longest (signed_address_type (), first); break; case DW_OP_xor: binop = BINOP_BITWISE_XOR; break; case DW_OP_le: binop = BINOP_LEQ; break; case DW_OP_ge: binop = BINOP_GEQ; break; case DW_OP_eq: binop = BINOP_EQUAL; break; case DW_OP_lt: binop = BINOP_LESS; break; case DW_OP_gt: binop = BINOP_GTR; break; case DW_OP_ne: binop = BINOP_NOTEQUAL; break; default: internal_error (__FILE__, __LINE__, "Can't be reached."); } result = value_as_long (value_binop (val1, val2, binop)); } break; case DW_OP_GNU_push_tls_address: /* Variable is at a constant offset in the thread-local storage block into the objfile for the current thread and the dynamic linker module containing this expression. Here we return returns the offset from that base. The top of the stack has the offset from the beginning of the thread control block at which the variable is located. Nothing should follow this operator, so the top of stack would be returned. */ result = dwarf_expr_fetch (ctx, 0); dwarf_expr_pop (ctx); result = (ctx->get_tls_address) (ctx->baton, result); break; case DW_OP_skip: offset = extract_signed_integer (op_ptr, 2); op_ptr += 2; op_ptr += offset; goto no_push; case DW_OP_bra: offset = extract_signed_integer (op_ptr, 2); op_ptr += 2; if (dwarf_expr_fetch (ctx, 0) != 0) op_ptr += offset; dwarf_expr_pop (ctx); goto no_push; case DW_OP_nop: goto no_push; case DW_OP_piece: { ULONGEST size; CORE_ADDR addr_or_regnum; /* Record the piece. */ op_ptr = read_uleb128 (op_ptr, op_end, &size); addr_or_regnum = dwarf_expr_fetch (ctx, 0); add_piece (ctx, ctx->in_reg, addr_or_regnum, size); /* Pop off the address/regnum, and clear the in_reg flag. */ dwarf_expr_pop (ctx); ctx->in_reg = 0; } goto no_push; default: error ("Unhandled dwarf expression opcode 0x%x", op); } /* Most things push a result value. */ dwarf_expr_push (ctx, result); no_push:; } }
static int amd64_windows_frame_decode_epilogue (struct frame_info *this_frame, struct amd64_windows_frame_cache *cache) { /* According to MSDN an epilogue "must consist of either an add RSP,constant or lea RSP,constant[FPReg], followed by a series of zero or more 8-byte register pops and a return or a jmp". Furthermore, according to RtlVirtualUnwind, the complete list of epilog marker is: - ret [c3] - ret n [c2 imm16] - rep ret [f3 c3] - jmp imm8 | imm32 [eb rel8] or [e9 rel32] - jmp qword ptr imm32 - not handled - rex.w jmp reg [4X ff eY] */ CORE_ADDR pc = cache->pc; CORE_ADDR cur_sp = cache->sp; struct gdbarch *gdbarch = get_frame_arch (this_frame); enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); gdb_byte op; gdb_byte rex; /* We don't care about the instruction deallocating the frame: if it hasn't been executed, the pc is still in the body, if it has been executed, the following epilog decoding will work. */ /* First decode: - pop reg [41 58-5f] or [58-5f]. */ while (1) { /* Read opcode. */ if (target_read_memory (pc, &op, 1) != 0) return -1; if (op >= 0x40 && op <= 0x4f) { /* REX prefix. */ rex = op; /* Read opcode. */ if (target_read_memory (pc + 1, &op, 1) != 0) return -1; } else rex = 0; if (op >= 0x58 && op <= 0x5f) { /* pop reg */ gdb_byte reg = (op & 0x0f) | ((rex & 1) << 3); cache->prev_reg_addr[amd64_windows_w2gdb_regnum[reg]] = cur_sp; cur_sp += 8; } else break; /* Allow the user to break this loop. This shouldn't happen as the number of consecutive pop should be small. */ QUIT; } /* Then decode the marker. */ /* Read opcode. */ if (target_read_memory (pc, &op, 1) != 0) return -1; switch (op) { case 0xc3: /* Ret. */ cache->prev_rip_addr = cur_sp; cache->prev_sp = cur_sp + 8; return 1; case 0xeb: { /* jmp rel8 */ gdb_byte rel8; CORE_ADDR npc; if (target_read_memory (pc + 1, &rel8, 1) != 0) return -1; npc = pc + 2 + (signed char) rel8; /* If the jump is within the function, then this is not a marker, otherwise this is a tail-call. */ return !pc_in_range (npc, cache); } case 0xec: { /* jmp rel32 */ gdb_byte rel32[4]; CORE_ADDR npc; if (target_read_memory (pc + 1, rel32, 4) != 0) return -1; npc = pc + 5 + extract_signed_integer (rel32, 4, byte_order); /* If the jump is within the function, then this is not a marker, otherwise this is a tail-call. */ return !pc_in_range (npc, cache); } case 0xc2: { /* ret n */ gdb_byte imm16[2]; if (target_read_memory (pc + 1, imm16, 2) != 0) return -1; cache->prev_rip_addr = cur_sp; cache->prev_sp = cur_sp + extract_unsigned_integer (imm16, 4, byte_order); return 1; } case 0xf3: { /* rep; ret */ gdb_byte op1; if (target_read_memory (pc + 2, &op1, 1) != 0) return -1; if (op1 != 0xc3) return 0; cache->prev_rip_addr = cur_sp; cache->prev_sp = cur_sp + 8; return 1; } case 0x40: case 0x41: case 0x42: case 0x43: case 0x44: case 0x45: case 0x46: case 0x47: case 0x48: case 0x49: case 0x4a: case 0x4b: case 0x4c: case 0x4d: case 0x4e: case 0x4f: /* Got a REX prefix, read next byte. */ rex = op; if (target_read_memory (pc + 1, &op, 1) != 0) return -1; if (op == 0xff) { /* rex jmp reg */ gdb_byte op1; unsigned int reg; gdb_byte buf[8]; if (target_read_memory (pc + 2, &op1, 1) != 0) return -1; return (op1 & 0xf8) == 0xe0; } else return 0; default: /* Not REX, so unknown. */ return 0; } }