📄 findvar.c
字号:
/* Find a variable's value in memory, for GDB, the GNU debugger. Copyright 1986, 1987, 1989, 1991 Free Software Foundation, Inc.This file is part of GDB.This program is free software; you can redistribute it and/or modifyit under the terms of the GNU General Public License as published bythe Free Software Foundation; either version 2 of the License, or(at your option) any later version.This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; without even the implied warranty ofMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See theGNU General Public License for more details.You should have received a copy of the GNU General Public Licensealong with this program; if not, write to the Free SoftwareFoundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */#include "defs.h"#include "symtab.h"#include "gdbtypes.h"#include "frame.h"#include "value.h"#include "gdbcore.h"#include "inferior.h"#include "target.h"#if !defined (GET_SAVED_REGISTER)/* Return the address in which frame FRAME's value of register REGNUM has been saved in memory. Or return zero if it has not been saved. If REGNUM specifies the SP, the value we return is actually the SP value, not an address where it was saved. */CORE_ADDRfind_saved_register (frame, regnum) FRAME frame; int regnum;{ struct frame_info *fi; struct frame_saved_regs saved_regs; register FRAME frame1 = 0; register CORE_ADDR addr = 0; if (frame == 0) /* No regs saved if want current frame */ return 0;#ifdef HAVE_REGISTER_WINDOWS /* We assume that a register in a register window will only be saved in one place (since the name changes and/or disappears as you go towards inner frames), so we only call get_frame_saved_regs on the current frame. This is directly in contradiction to the usage below, which assumes that registers used in a frame must be saved in a lower (more interior) frame. This change is a result of working on a register window machine; get_frame_saved_regs always returns the registers saved within a frame, within the context (register namespace) of that frame. */ /* However, note that we don't want this to return anything if nothing is saved (if there's a frame inside of this one). Also, callers to this routine asking for the stack pointer want the stack pointer saved for *this* frame; this is returned from the next frame. */ if (REGISTER_IN_WINDOW_P(regnum)) { frame1 = get_next_frame (frame); if (!frame1) return 0; /* Registers of this frame are active. */ /* Get the SP from the next frame in; it will be this current frame. */ if (regnum != SP_REGNUM) frame1 = frame; fi = get_frame_info (frame1); get_frame_saved_regs (fi, &saved_regs); return saved_regs.regs[regnum]; /* ... which might be zero */ }#endif /* HAVE_REGISTER_WINDOWS */ /* Note that this next routine assumes that registers used in frame x will be saved only in the frame that x calls and frames interior to it. This is not true on the sparc, but the above macro takes care of it, so we should be all right. */ while (1) { QUIT; frame1 = get_prev_frame (frame1); if (frame1 == 0 || frame1 == frame) break; fi = get_frame_info (frame1); get_frame_saved_regs (fi, &saved_regs); if (saved_regs.regs[regnum]) addr = saved_regs.regs[regnum]; } return addr;}/* Find register number REGNUM relative to FRAME and put its (raw) contents in *RAW_BUFFER. Set *OPTIMIZED if the variable was optimized out (and thus can't be fetched). Set *LVAL to lval_memory, lval_register, or not_lval, depending on whether the value was fetched from memory, from a register, or in a strange and non-modifiable way (e.g. a frame pointer which was calculated rather than fetched). Set *ADDRP to the address, either in memory on as a REGISTER_BYTE offset into the registers array. Note that this implementation never sets *LVAL to not_lval. But it can be replaced by defining GET_SAVED_REGISTER and supplying your own. The argument RAW_BUFFER must point to aligned memory. */voidget_saved_register (raw_buffer, optimized, addrp, frame, regnum, lval) char *raw_buffer; int *optimized; CORE_ADDR *addrp; FRAME frame; int regnum; enum lval_type *lval;{ CORE_ADDR addr; /* Normal systems don't optimize out things with register numbers. */ if (optimized != NULL) *optimized = 0; addr = find_saved_register (frame, regnum); if (addr != 0) { if (lval != NULL) *lval = lval_memory; if (regnum == SP_REGNUM) { if (raw_buffer != NULL) *(CORE_ADDR *)raw_buffer = addr; if (addrp != NULL) *addrp = 0; return; } if (raw_buffer != NULL) read_memory (addr, raw_buffer, REGISTER_RAW_SIZE (regnum)); } else { if (lval != NULL) *lval = lval_register; addr = REGISTER_BYTE (regnum); if (raw_buffer != NULL) read_register_gen (regnum, raw_buffer); } if (addrp != NULL) *addrp = addr;}#endif /* GET_SAVED_REGISTER. *//* Copy the bytes of register REGNUM, relative to the current stack frame, into our memory at MYADDR, in target byte order. The number of bytes copied is REGISTER_RAW_SIZE (REGNUM). Returns 1 if could not be read, 0 if could. */intread_relative_register_raw_bytes (regnum, myaddr) int regnum; char *myaddr;{ int optim; if (regnum == FP_REGNUM && selected_frame) { memcpy (myaddr, &FRAME_FP(selected_frame), REGISTER_RAW_SIZE(FP_REGNUM)); SWAP_TARGET_AND_HOST (myaddr, REGISTER_RAW_SIZE(FP_REGNUM)); /* in target order */ return 0; } get_saved_register (myaddr, &optim, (CORE_ADDR *) NULL, selected_frame, regnum, (enum lval_type *)NULL); return optim;}/* Return a `value' with the contents of register REGNUM in its virtual format, with the type specified by REGISTER_VIRTUAL_TYPE. */valuevalue_of_register (regnum) int regnum;{ CORE_ADDR addr; int optim; register value val; char raw_buffer[MAX_REGISTER_RAW_SIZE]; char virtual_buffer[MAX_REGISTER_VIRTUAL_SIZE]; enum lval_type lval; get_saved_register (raw_buffer, &optim, &addr, selected_frame, regnum, &lval); REGISTER_CONVERT_TO_VIRTUAL (regnum, raw_buffer, virtual_buffer); val = allocate_value (REGISTER_VIRTUAL_TYPE (regnum)); memcpy (VALUE_CONTENTS_RAW (val), virtual_buffer, REGISTER_VIRTUAL_SIZE (regnum)); VALUE_LVAL (val) = lval; VALUE_ADDRESS (val) = addr; VALUE_REGNO (val) = regnum; VALUE_OPTIMIZED_OUT (val) = optim; return val;}/* Low level examining and depositing of registers. The caller is responsible for making sure that the inferior is stopped before calling the fetching routines, or it will get garbage. (a change from GDB version 3, in which the caller got the value from the last stop). *//* Contents of the registers in target byte order. We allocate some extra slop since we do a lot of bcopy's around `registers', and failing-soft is better than failing hard. */char registers[REGISTER_BYTES + /* SLOP */ 256];/* Nonzero if that register has been fetched. */char register_valid[NUM_REGS];/* Indicate that registers may have changed, so invalidate the cache. */voidregisters_changed (){ int i; for (i = 0; i < NUM_REGS; i++) register_valid[i] = 0;}/* Indicate that all registers have been fetched, so mark them all valid. */voidregisters_fetched (){ int i; for (i = 0; i < NUM_REGS; i++) register_valid[i] = 1;}/* Copy LEN bytes of consecutive data from registers starting with the REGBYTE'th byte of register data into memory at MYADDR. */voidread_register_bytes (regbyte, myaddr, len) int regbyte; char *myaddr; int len;{ /* Fetch all registers. */ int i; for (i = 0; i < NUM_REGS; i++) if (!register_valid[i]) { target_fetch_registers (-1); break; } if (myaddr != NULL) memcpy (myaddr, ®isters[regbyte], len);}/* Read register REGNO into memory at MYADDR, which must be large enough for REGISTER_RAW_BYTES (REGNO). Target byte-order. If the register is known to be the size of a CORE_ADDR or smaller, read_register can be used instead. */voidread_register_gen (regno, myaddr) int regno; char *myaddr;{ if (!register_valid[regno]) target_fetch_registers (regno); memcpy (myaddr, ®isters[REGISTER_BYTE (regno)], REGISTER_RAW_SIZE (regno));}/* Copy LEN bytes of consecutive data from memory at MYADDR into registers starting with the REGBYTE'th byte of register data. */voidwrite_register_bytes (regbyte, myaddr, len) int regbyte; char *myaddr; int len;{ /* Make sure the entire registers array is valid. */ read_register_bytes (0, (char *)NULL, REGISTER_BYTES); memcpy (®isters[regbyte], myaddr, len); target_store_registers (-1);}/* Return the contents of register REGNO, regarding it as an integer. *//* FIXME, this loses when the REGISTER_VIRTUAL (REGNO) is true. Also, why is the return type CORE_ADDR rather than some integer type? */CORE_ADDRread_register (regno) int regno;{ REGISTER_TYPE reg; if (!register_valid[regno]) target_fetch_registers (regno); memcpy (®, ®isters[REGISTER_BYTE (regno)], sizeof (REGISTER_TYPE)); SWAP_TARGET_AND_HOST (®, sizeof (REGISTER_TYPE)); return reg;}/* Registers we shouldn't try to store. */#if !defined (CANNOT_STORE_REGISTER)#define CANNOT_STORE_REGISTER(regno) 0#endif/* Store VALUE in the register number REGNO, regarded as an integer. *//* FIXME, this loses when REGISTER_VIRTUAL (REGNO) is true. Also, shouldn't the val arg be a LONGEST or something? */voidwrite_register (regno, val) int regno, val;{ REGISTER_TYPE reg; /* On the sparc, writing %g0 is a no-op, so we don't even want to change the registers array if something writes to this register. */ if (CANNOT_STORE_REGISTER (regno)) return; reg = val; SWAP_TARGET_AND_HOST (®, sizeof (REGISTER_TYPE)); target_prepare_to_store (); register_valid [regno] = 1; memcpy (®isters[REGISTER_BYTE (regno)], ®, REGISTER_RAW_SIZE (regno)); target_store_registers (regno);}/* Record that register REGNO contains VAL. This is used when the value is obtained from the inferior or core dump, so there is no need to store the value there. */voidsupply_register (regno, val) int regno; char *val;{ register_valid[regno] = 1; memcpy (®isters[REGISTER_BYTE (regno)], val, REGISTER_RAW_SIZE (regno)); /* On some architectures, e.g. HPPA, there are a few stray bits in some
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -