- {
- char regbuf[MAX_REGISTER_RAW_SIZE];
- /* What's the overlap between this register's bytes and
- those the caller wants to write? */
- int overlapstart = max (regstart, myregstart);
- int overlapend = min (regend, myregend);
-
- /* We may be doing a partial update of an invalid register.
- Update it from the target before scribbling on it. */
- read_register_gen (regno, regbuf);
-
- memcpy (registers + overlapstart,
- myaddr + (overlapstart - myregstart),
- overlapend - overlapstart);
-
- target_store_registers (regno);
- }
- }
-}
-
-
-/* Return the raw contents of register REGNO, regarding it as an integer. */
-/* This probably should be returning LONGEST rather than CORE_ADDR. */
-
-CORE_ADDR
-read_register (regno)
- int regno;
-{
- if (registers_pid != inferior_pid)
- {
- registers_changed ();
- registers_pid = inferior_pid;
- }
-
- if (!register_valid[regno])
- target_fetch_registers (regno);
-
- return ((CORE_ADDR)
- extract_unsigned_integer (®isters[REGISTER_BYTE (regno)],
- REGISTER_RAW_SIZE (regno)));
-}
-
-CORE_ADDR
-read_register_pid (regno, pid)
- int regno, pid;
-{
- int save_pid;
- CORE_ADDR retval;
-
- if (pid == inferior_pid)
- return read_register (regno);
-
- save_pid = inferior_pid;
-
- inferior_pid = pid;
-
- retval = read_register (regno);
-
- inferior_pid = save_pid;
-
- return retval;
-}
-
-/* Store VALUE, into the raw contents of register number REGNO.
- This should probably write a LONGEST rather than a CORE_ADDR */
-
-void
-write_register (regno, val)
- int regno;
- LONGEST val;
-{
- PTR buf;
- int size;
-
- /* 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;
-
- if (registers_pid != inferior_pid)
- {
- registers_changed ();
- registers_pid = inferior_pid;
- }
-
- size = REGISTER_RAW_SIZE (regno);
- buf = alloca (size);
- store_signed_integer (buf, size, (LONGEST) val);
-
- /* If we have a valid copy of the register, and new value == old value,
- then don't bother doing the actual store. */
-
- if (register_valid[regno]
- && memcmp (®isters[REGISTER_BYTE (regno)], buf, size) == 0)
- return;
-
- target_prepare_to_store ();
-
- memcpy (®isters[REGISTER_BYTE (regno)], buf, size);
-
- register_valid[regno] = 1;
-
- target_store_registers (regno);
-}
-
-void
-write_register_pid (regno, val, pid)
- int regno;
- CORE_ADDR val;
- int pid;
-{
- int save_pid;
-
- if (pid == inferior_pid)
- {
- write_register (regno, val);
- return;
- }
-
- save_pid = inferior_pid;
-
- inferior_pid = pid;
-
- write_register (regno, val);
-
- inferior_pid = save_pid;
-}
-
-/* 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.
-
- If VAL is a NULL pointer, then it's probably an unsupported register. We
- just set it's value to all zeros. We might want to record this fact, and
- report it to the users of read_register and friends.
- */
-
-void
-supply_register (regno, val)
- int regno;
- char *val;
-{
-#if 1
- if (registers_pid != inferior_pid)
- {
- registers_changed ();
- registers_pid = inferior_pid;
- }
-#endif
-
- register_valid[regno] = 1;
- if (val)
- memcpy (®isters[REGISTER_BYTE (regno)], val, REGISTER_RAW_SIZE (regno));
- else
- memset (®isters[REGISTER_BYTE (regno)], '\000', REGISTER_RAW_SIZE (regno));
-
- /* On some architectures, e.g. HPPA, there are a few stray bits in some
- registers, that the rest of the code would like to ignore. */
-#ifdef CLEAN_UP_REGISTER_VALUE
- CLEAN_UP_REGISTER_VALUE (regno, ®isters[REGISTER_BYTE (regno)]);
-#endif
-}
-
-
-/* This routine is getting awfully cluttered with #if's. It's probably
- time to turn this into READ_PC and define it in the tm.h file.
- Ditto for write_pc.
-
- 1999-06-08: The following were re-written so that it assumes the
- existance of a TARGET_READ_PC et.al. macro. A default generic
- version of that macro is made available where needed.
-
- Since the ``TARGET_READ_PC'' et.al. macro is going to be controlled
- by the multi-arch framework, it will eventually be possible to
- eliminate the intermediate read_pc_pid(). The client would call
- TARGET_READ_PC directly. (cagney). */
-
-#ifndef TARGET_READ_PC
-#define TARGET_READ_PC generic_target_read_pc
-#endif
-
-CORE_ADDR
-generic_target_read_pc (int pid)
-{
-#ifdef PC_REGNUM
- if (PC_REGNUM >= 0)
- {
- CORE_ADDR pc_val = ADDR_BITS_REMOVE ((CORE_ADDR) read_register_pid (PC_REGNUM, pid));
- return pc_val;
- }
-#endif
- internal_error ("generic_target_read_pc");
- return 0;
-}
-
-CORE_ADDR
-read_pc_pid (pid)
- int pid;
-{
- int saved_inferior_pid;
- CORE_ADDR pc_val;
-
- /* In case pid != inferior_pid. */
- saved_inferior_pid = inferior_pid;
- inferior_pid = pid;
-
- pc_val = TARGET_READ_PC (pid);
-
- inferior_pid = saved_inferior_pid;
- return pc_val;
-}
-
-CORE_ADDR
-read_pc ()
-{
- return read_pc_pid (inferior_pid);
-}
-
-#ifndef TARGET_WRITE_PC
-#define TARGET_WRITE_PC generic_target_write_pc
-#endif
-
-void
-generic_target_write_pc (pc, pid)
- CORE_ADDR pc;
- int pid;
-{
-#ifdef PC_REGNUM
- if (PC_REGNUM >= 0)
- write_register_pid (PC_REGNUM, pc, pid);
-#ifdef NPC_REGNUM
- if (NPC_REGNUM >= 0)
- write_register_pid (NPC_REGNUM, pc + 4, pid);
-#ifdef NNPC_REGNUM
- if (NNPC_REGNUM >= 0)
- write_register_pid (NNPC_REGNUM, pc + 8, pid);
-#endif
-#endif
-#else
- internal_error ("generic_target_write_pc");
-#endif
-}
-
-void
-write_pc_pid (pc, pid)
- CORE_ADDR pc;
- int pid;
-{
- int saved_inferior_pid;
-
- /* In case pid != inferior_pid. */
- saved_inferior_pid = inferior_pid;
- inferior_pid = pid;
-
- TARGET_WRITE_PC (pc, pid);
-
- inferior_pid = saved_inferior_pid;
-}
-
-void
-write_pc (pc)
- CORE_ADDR pc;
-{
- write_pc_pid (pc, inferior_pid);
-}
-
-/* Cope with strage ways of getting to the stack and frame pointers */
-
-#ifndef TARGET_READ_SP
-#define TARGET_READ_SP generic_target_read_sp
-#endif
-
-CORE_ADDR
-generic_target_read_sp ()
-{
-#ifdef SP_REGNUM
- if (SP_REGNUM >= 0)
- return read_register (SP_REGNUM);
-#endif
- internal_error ("generic_target_read_sp");
-}
-
-CORE_ADDR
-read_sp ()
-{
- return TARGET_READ_SP ();
-}
-
-#ifndef TARGET_WRITE_SP
-#define TARGET_WRITE_SP generic_target_write_sp
-#endif
-
-void
-generic_target_write_sp (val)
- CORE_ADDR val;
-{
-#ifdef SP_REGNUM
- if (SP_REGNUM >= 0)
- {
- write_register (SP_REGNUM, val);
- return;
- }
-#endif
- internal_error ("generic_target_write_sp");
-}
-
-void
-write_sp (val)
- CORE_ADDR val;
-{
- TARGET_WRITE_SP (val);
-}
-
-#ifndef TARGET_READ_FP
-#define TARGET_READ_FP generic_target_read_fp
-#endif
-
-CORE_ADDR
-generic_target_read_fp ()
-{
-#ifdef FP_REGNUM
- if (FP_REGNUM >= 0)
- return read_register (FP_REGNUM);
-#endif
- internal_error ("generic_target_read_fp");
-}
-
-CORE_ADDR
-read_fp ()
-{
- return TARGET_READ_FP ();
-}
-
-#ifndef TARGET_WRITE_FP
-#define TARGET_WRITE_FP generic_target_write_fp
-#endif
-
-void
-generic_target_write_fp (val)
- CORE_ADDR val;
-{
-#ifdef FP_REGNUM
- if (FP_REGNUM >= 0)
- {
- write_register (FP_REGNUM, val);
- return;
- }
-#endif
- internal_error ("generic_target_write_fp");
-}
-
-void
-write_fp (val)
- CORE_ADDR val;
-{
- TARGET_WRITE_FP (val);
-}
-
-
-/* Given a pointer of type TYPE in target form in BUF, return the
- address it represents. */
-CORE_ADDR
-generic_pointer_to_address (struct type *type, char *buf)
-{
- return extract_address (buf, TYPE_LENGTH (type));
-}
-
-
-/* Given an address, store it as a pointer of type TYPE in target
- format in BUF. */
-void
-generic_address_to_pointer (struct type *type, char *buf, CORE_ADDR addr)
-{
- store_address (buf, TYPE_LENGTH (type), addr);
-}
-
-\f
-/* Will calling read_var_value or locate_var_value on SYM end
- up caring what frame it is being evaluated relative to? SYM must
- be non-NULL. */
-int
-symbol_read_needs_frame (sym)
- struct symbol *sym;
-{
- switch (SYMBOL_CLASS (sym))
- {
- /* All cases listed explicitly so that gcc -Wall will detect it if
- we failed to consider one. */
- case LOC_REGISTER:
- case LOC_ARG:
- case LOC_REF_ARG:
- case LOC_REGPARM:
- case LOC_REGPARM_ADDR:
- case LOC_LOCAL:
- case LOC_LOCAL_ARG:
- case LOC_BASEREG:
- case LOC_BASEREG_ARG:
- case LOC_THREAD_LOCAL_STATIC:
- return 1;
-
- case LOC_UNDEF:
- case LOC_CONST:
- case LOC_STATIC:
- case LOC_INDIRECT:
- case LOC_TYPEDEF:
-
- case LOC_LABEL:
- /* Getting the address of a label can be done independently of the block,
- even if some *uses* of that address wouldn't work so well without
- the right frame. */
-
- case LOC_BLOCK:
- case LOC_CONST_BYTES:
- case LOC_UNRESOLVED:
- case LOC_OPTIMIZED_OUT:
- return 0;
- }
- return 1;
-}
-
-/* Given a struct symbol for a variable,
- and a stack frame id, read the value of the variable
- and return a (pointer to a) struct value containing the value.
- If the variable cannot be found, return a zero pointer.
- If FRAME is NULL, use the selected_frame. */
-
-value_ptr
-read_var_value (var, frame)
- register struct symbol *var;
- struct frame_info *frame;
-{
- register value_ptr v;
- struct type *type = SYMBOL_TYPE (var);
- CORE_ADDR addr;
- register int len;
-
- v = allocate_value (type);
- VALUE_LVAL (v) = lval_memory; /* The most likely possibility. */
- VALUE_BFD_SECTION (v) = SYMBOL_BFD_SECTION (var);
-
- len = TYPE_LENGTH (type);
-
- if (frame == NULL)
- frame = selected_frame;
-
- switch (SYMBOL_CLASS (var))
- {
- case LOC_CONST:
- /* Put the constant back in target format. */
- store_signed_integer (VALUE_CONTENTS_RAW (v), len,
- (LONGEST) SYMBOL_VALUE (var));
- VALUE_LVAL (v) = not_lval;
- return v;
-
- case LOC_LABEL:
- /* Put the constant back in target format. */
- if (overlay_debugging)
- {
- CORE_ADDR addr
- = symbol_overlayed_address (SYMBOL_VALUE_ADDRESS (var),
- SYMBOL_BFD_SECTION (var));
- store_typed_address (VALUE_CONTENTS_RAW (v), type, addr);
- }
- else
- store_typed_address (VALUE_CONTENTS_RAW (v), type,
- SYMBOL_VALUE_ADDRESS (var));
- VALUE_LVAL (v) = not_lval;
- return v;
-
- case LOC_CONST_BYTES:
- {
- char *bytes_addr;
- bytes_addr = SYMBOL_VALUE_BYTES (var);
- memcpy (VALUE_CONTENTS_RAW (v), bytes_addr, len);
- VALUE_LVAL (v) = not_lval;
- return v;
- }
-
- case LOC_STATIC:
- if (overlay_debugging)
- addr = symbol_overlayed_address (SYMBOL_VALUE_ADDRESS (var),
- SYMBOL_BFD_SECTION (var));
- else
- addr = SYMBOL_VALUE_ADDRESS (var);
- break;
-
- case LOC_INDIRECT:
- /* The import slot does not have a real address in it from the
- dynamic loader (dld.sl on HP-UX), if the target hasn't begun
- execution yet, so check for that. */
- if (!target_has_execution)
- error ("\
-Attempt to access variable defined in different shared object or load module when\n\
-addresses have not been bound by the dynamic loader. Try again when executable is running.");
-
- addr = SYMBOL_VALUE_ADDRESS (var);
- addr = read_memory_unsigned_integer
- (addr, TARGET_PTR_BIT / TARGET_CHAR_BIT);
- break;
-
- case LOC_ARG:
- if (frame == NULL)
- return 0;
- addr = FRAME_ARGS_ADDRESS (frame);
- if (!addr)
- return 0;
- addr += SYMBOL_VALUE (var);
- break;
-
- case LOC_REF_ARG:
- if (frame == NULL)
- return 0;
- addr = FRAME_ARGS_ADDRESS (frame);
- if (!addr)
- return 0;
- addr += SYMBOL_VALUE (var);
- addr = read_memory_unsigned_integer
- (addr, TARGET_PTR_BIT / TARGET_CHAR_BIT);
- break;
-
- case LOC_LOCAL:
- case LOC_LOCAL_ARG:
- if (frame == NULL)
- return 0;
- addr = FRAME_LOCALS_ADDRESS (frame);
- addr += SYMBOL_VALUE (var);
- break;
-
- case LOC_BASEREG:
- case LOC_BASEREG_ARG:
- {
- char buf[MAX_REGISTER_RAW_SIZE];
- get_saved_register (buf, NULL, NULL, frame, SYMBOL_BASEREG (var),
- NULL);
- addr = extract_address (buf, REGISTER_RAW_SIZE (SYMBOL_BASEREG (var)));
- addr += SYMBOL_VALUE (var);
- break;
- }
-
- case LOC_THREAD_LOCAL_STATIC:
- {
- char buf[MAX_REGISTER_RAW_SIZE];
-
- get_saved_register (buf, NULL, NULL, frame, SYMBOL_BASEREG (var),
- NULL);
- addr = extract_address (buf, REGISTER_RAW_SIZE (SYMBOL_BASEREG (var)));
- addr += SYMBOL_VALUE (var);
- break;
- }
-
- case LOC_TYPEDEF:
- error ("Cannot look up value of a typedef");
- break;
-
- case LOC_BLOCK:
- if (overlay_debugging)
- VALUE_ADDRESS (v) = symbol_overlayed_address
- (BLOCK_START (SYMBOL_BLOCK_VALUE (var)), SYMBOL_BFD_SECTION (var));
- else
- VALUE_ADDRESS (v) = BLOCK_START (SYMBOL_BLOCK_VALUE (var));
- return v;