From 4478b372e973afcd2253fe4c1ec3f2d083ac3943 Mon Sep 17 00:00:00 2001 From: Jim Blandy Date: Fri, 14 Apr 2000 18:43:41 +0000 Subject: [PATCH] * gdbarch.sh (POINTER_TO_ADDRESS, ADDRESS_TO_POINTER): Two new functions which architectures can redefine, defaulting to generic_pointer_to_address and generic_address_to_pointer. * findvar.c (extract_typed_address, store_typed_address, generic_pointer_to_address, generic_address_to_pointer): New functions. (POINTER_TO_ADDRESS, ADDRESS_TO_POINTER): Provide default definitions. (extract_address, store_address): Doc fixes. * values.c (value_as_pointer): Doc fix. (value_from_pointer): New function. * defs.h (extract_typed_address, store_typed_address): New declarations. * inferior.h (generic_address_to_pointer, generic_pointer_to_address): New declarations. * value.h (value_from_pointer): New declaration. * ax-gdb.c (const_var_ref): Use value_from_pointer, not value_from_longest. * blockframe.c (generic_push_dummy_frame): Use read_pc and read_sp, not read_register. * c-valprint.c (c_val_print): Use extract_typed_address instead of extract_address to extract vtable entries and references. * cp-valprint.c (cp_print_value_fields): Use value_from_pointer instead of value_from_longest to extract the vtable's address. * eval.c (evaluate_subexp_standard): Use value_from_pointer instead of value_from_longest to compute `this', and for doing pointer-to-member dereferencing. * findvar.c (read_register): Use extract_unsigned_integer, not extract_address. (read_var_value): Use store_typed_address instead of store_address for building label values. (locate_var_value): Use value_from_pointer instead of value_from_longest. * hppa-tdep.c (find_stub_with_shl_get): Use value_from_pointer, instead of value_from_longest, to build arguments to __d_shl_get. * printcmd.c (set_next_address): Use value_from_pointer, not value_from_longest. (x_command): Use value_from_pointer, not value_from_longest. * tracepoint.c (set_traceframe_context): Use value_from_pointer, not value_from_longest. * valarith.c (value_add, value_sub): Use value_from_pointer, not value_from_longest. * valops.c (find_function_in_inferior, value_coerce_array, value_coerce_function, value_addr, hand_function_call): Same. * value.h (COERCE_REF): Use unpack_pointer, not unpack_long. * values.c (unpack_long): Use extract_typed_address to produce addresses from pointers and references, not extract_address. (value_from_longest): Use store_typed_address instead of store_address to produce pointer and reference values. --- gdb/ax-gdb.c | 2 +- gdb/blockframe.c | 4 +- gdb/c-valprint.c | 23 +++++----- gdb/cp-valprint.c | 2 +- gdb/defs.h | 4 ++ gdb/eval.c | 7 +-- gdb/findvar.c | 110 +++++++++++++++++++++++++++++++++++++++++----- gdb/gdbarch.c | 51 +++++++++++++++++++++ gdb/gdbarch.h | 18 ++++++++ gdb/gdbarch.sh | 4 ++ gdb/hppa-tdep.c | 8 ++-- gdb/inferior.h | 5 +++ gdb/printcmd.c | 11 ++--- gdb/tracepoint.c | 10 ++--- gdb/valarith.c | 10 ++--- gdb/valops.c | 26 +++++------ gdb/value.h | 6 ++- gdb/values.c | 24 +++++++--- 18 files changed, 256 insertions(+), 69 deletions(-) diff --git a/gdb/ax-gdb.c b/gdb/ax-gdb.c index 51fe5b6d54..890731bf40 100644 --- a/gdb/ax-gdb.c +++ b/gdb/ax-gdb.c @@ -185,7 +185,7 @@ const_var_ref (var) return value_from_longest (type, (LONGEST) SYMBOL_VALUE (var)); case LOC_LABEL: - return value_from_longest (type, (LONGEST) SYMBOL_VALUE_ADDRESS (var)); + return value_from_pointer (type, (CORE_ADDR) SYMBOL_VALUE_ADDRESS (var)); default: return 0; diff --git a/gdb/blockframe.c b/gdb/blockframe.c index d00f5c23fc..6ac35b774c 100644 --- a/gdb/blockframe.c +++ b/gdb/blockframe.c @@ -1213,8 +1213,8 @@ generic_push_dummy_frame () dummy_frame = xmalloc (sizeof (struct dummy_frame)); dummy_frame->registers = xmalloc (REGISTER_BYTES); - dummy_frame->pc = read_register (PC_REGNUM); - dummy_frame->sp = read_register (SP_REGNUM); + dummy_frame->pc = read_pc (); + dummy_frame->sp = read_sp (); dummy_frame->top = dummy_frame->sp; dummy_frame->fp = fp; read_register_bytes (0, dummy_frame->registers, REGISTER_BYTES); diff --git a/gdb/c-valprint.c b/gdb/c-valprint.c index ec4b3cf862..f9dbd033fc 100644 --- a/gdb/c-valprint.c +++ b/gdb/c-valprint.c @@ -135,8 +135,9 @@ c_val_print (type, valaddr, embedded_offset, address, stream, format, deref_ref, /* Print the unmangled name if desired. */ /* Print vtable entry - we only get here if we ARE using -fvtable_thunks. (Otherwise, look under TYPE_CODE_STRUCT.) */ - print_address_demangle (extract_address (valaddr + embedded_offset, TYPE_LENGTH (type)), - stream, demangle); + CORE_ADDR addr + = extract_typed_address (valaddr + embedded_offset, type); + print_address_demangle (addr, stream, demangle); break; } elttype = check_typedef (TYPE_TARGET_TYPE (type)); @@ -249,10 +250,10 @@ c_val_print (type, valaddr, embedded_offset, address, stream, format, deref_ref, } if (addressprint) { + CORE_ADDR addr + = extract_typed_address (valaddr + embedded_offset, type); fprintf_filtered (stream, "@"); - print_address_numeric - (extract_address (valaddr + embedded_offset, - TARGET_PTR_BIT / HOST_CHAR_BIT), 1, stream); + print_address_numeric (addr, 1, stream); if (deref_ref) fputs_filtered (": ", stream); } @@ -295,11 +296,13 @@ c_val_print (type, valaddr, embedded_offset, address, stream, format, deref_ref, /* Print the unmangled name if desired. */ /* Print vtable entry - we only get here if NOT using -fvtable_thunks. (Otherwise, look under TYPE_CODE_PTR.) */ - print_address_demangle (extract_address ( - valaddr + embedded_offset + - TYPE_FIELD_BITPOS (type, VTBL_FNADDR_OFFSET) / 8, - TYPE_LENGTH (TYPE_FIELD_TYPE (type, VTBL_FNADDR_OFFSET))), - stream, demangle); + int offset = (embedded_offset + + TYPE_FIELD_BITPOS (type, VTBL_FNADDR_OFFSET) / 8); + struct type *field_type = TYPE_FIELD_TYPE (type, VTBL_FNADDR_OFFSET); + CORE_ADDR addr + = extract_typed_address (valaddr + offset, field_type); + + print_address_demangle (addr, stream, demangle); } else cp_print_value_fields (type, type, valaddr, embedded_offset, address, stream, format, diff --git a/gdb/cp-valprint.c b/gdb/cp-valprint.c index b70ef219d6..bec2c52197 100644 --- a/gdb/cp-valprint.c +++ b/gdb/cp-valprint.c @@ -429,7 +429,7 @@ cp_print_value_fields (type, real_type, valaddr, offset, address, stream, format /* pai: FIXME 32x64 problem? */ /* Not sure what the best notation is in the case where there is no baseclass name. */ - v = value_from_longest (lookup_pointer_type (builtin_type_unsigned_long), + v = value_from_pointer (lookup_pointer_type (builtin_type_unsigned_long), *(unsigned long *) (valaddr + offset)); val_print (VALUE_TYPE (v), VALUE_CONTENTS (v), 0, 0, diff --git a/gdb/defs.h b/gdb/defs.h index 0270ddd1d8..86ad0f7741 100644 --- a/gdb/defs.h +++ b/gdb/defs.h @@ -1067,12 +1067,16 @@ extern int extract_long_unsigned_integer (void *, int, LONGEST *); extern CORE_ADDR extract_address (void *, int); +extern CORE_ADDR extract_typed_address (void *buf, struct type *type); + extern void store_signed_integer (void *, int, LONGEST); extern void store_unsigned_integer (void *, int, ULONGEST); extern void store_address (void *, int, LONGEST); +extern void store_typed_address (void *buf, struct type *type, CORE_ADDR addr); + /* Setup definitions for host and target floating point formats. We need to consider the format for `float', `double', and `long double' for both target and host. We need to do this so that we know what kind of conversions need diff --git a/gdb/eval.c b/gdb/eval.c index c2ff903d99..06ec1914eb 100644 --- a/gdb/eval.c +++ b/gdb/eval.c @@ -832,8 +832,9 @@ evaluate_subexp_standard (expect_type, exp, pos, noside) /* Method invocation : stuff "this" as first parameter */ /* pai: this used to have lookup_pointer_type for some reason, * but temp is already a pointer to the object */ - argvec[1] = value_from_longest (VALUE_TYPE (temp), - VALUE_ADDRESS (temp) + VALUE_OFFSET (temp)); + argvec[1] + = value_from_pointer (VALUE_TYPE (temp), + VALUE_ADDRESS (temp) + VALUE_OFFSET (temp)); /* Name of method from expression */ strcpy (tstr, &exp->elts[pc2 + 2].string); @@ -1122,7 +1123,7 @@ evaluate_subexp_standard (expect_type, exp, pos, noside) /* Now, convert these values to an address. */ arg1 = value_cast (lookup_pointer_type (TYPE_DOMAIN_TYPE (type)), arg1); - arg3 = value_from_longest (lookup_pointer_type (TYPE_TARGET_TYPE (type)), + arg3 = value_from_pointer (lookup_pointer_type (TYPE_TARGET_TYPE (type)), value_as_long (arg1) + mem_offset); return value_ind (arg3); bad_pointer_to_member: diff --git a/gdb/findvar.c b/gdb/findvar.c index 98a7133b79..10f9c3f3b8 100644 --- a/gdb/findvar.c +++ b/gdb/findvar.c @@ -169,6 +169,20 @@ extract_long_unsigned_integer (void *addr, int orig_len, LONGEST *pval) return 0; } + +/* Treat the LEN bytes at ADDR as a target-format address, and return + that address. ADDR is a buffer in the GDB process, not in the + inferior. + + This function should only be used by target-specific code. It + assumes that a pointer has the same representation as that thing's + address represented as an integer. Some machines use word + addresses, or similarly munged things, for certain types of + pointers, so that assumption doesn't hold everywhere. + + Common code should use extract_typed_address instead, or something + else based on POINTER_TO_ADDRESS. */ + CORE_ADDR extract_address (void *addr, int len) { @@ -177,6 +191,25 @@ extract_address (void *addr, int len) return (CORE_ADDR) extract_unsigned_integer (addr, len); } + +#ifndef POINTER_TO_ADDRESS +#define POINTER_TO_ADDRESS generic_pointer_to_address +#endif + +/* Treat the bytes at BUF as a pointer of type TYPE, and return the + address it represents. */ +CORE_ADDR +extract_typed_address (void *buf, struct type *type) +{ + if (TYPE_CODE (type) != TYPE_CODE_PTR + && TYPE_CODE (type) != TYPE_CODE_REF) + internal_error ("findvar.c (generic_pointer_to_address): " + "type is not a pointer or reference"); + + return POINTER_TO_ADDRESS (type, buf); +} + + void store_signed_integer (void *addr, int len, LONGEST val) { @@ -231,14 +264,43 @@ store_unsigned_integer (void *addr, int len, ULONGEST val) } } -/* Store the literal address "val" into - gdb-local memory pointed to by "addr" - for "len" bytes. */ +/* Store the address VAL as a LEN-byte value in target byte order at + ADDR. ADDR is a buffer in the GDB process, not in the inferior. + + This function should only be used by target-specific code. It + assumes that a pointer has the same representation as that thing's + address represented as an integer. Some machines use word + addresses, or similarly munged things, for certain types of + pointers, so that assumption doesn't hold everywhere. + + Common code should use store_typed_address instead, or something else + based on ADDRESS_TO_POINTER. */ void store_address (void *addr, int len, LONGEST val) { store_unsigned_integer (addr, len, val); } + + +#ifndef ADDRESS_TO_POINTER +#define ADDRESS_TO_POINTER generic_address_to_pointer +#endif + +/* Store the address ADDR as a pointer of type TYPE at BUF, in target + form. */ +void +store_typed_address (void *buf, struct type *type, CORE_ADDR addr) +{ + if (TYPE_CODE (type) != TYPE_CODE_PTR + && TYPE_CODE (type) != TYPE_CODE_REF) + internal_error ("findvar.c (generic_address_to_pointer): " + "type is not a pointer or reference"); + + ADDRESS_TO_POINTER (type, buf, addr); +} + + + /* Extract a floating-point number from a target-order byte-stream at ADDR. Returns the value as type DOUBLEST. @@ -445,7 +507,8 @@ default_get_saved_register (raw_buffer, optimized, addrp, frame, regnum, lval) if (raw_buffer != NULL) { /* Put it back in target format. */ - store_address (raw_buffer, REGISTER_RAW_SIZE (regnum), (LONGEST) addr); + store_address (raw_buffer, REGISTER_RAW_SIZE (regnum), + (LONGEST) addr); } if (addrp != NULL) *addrp = 0; @@ -831,8 +894,9 @@ read_register (regno) if (!register_valid[regno]) target_fetch_registers (regno); - return (CORE_ADDR) extract_address (®isters[REGISTER_BYTE (regno)], - REGISTER_RAW_SIZE (regno)); + return ((CORE_ADDR) + extract_unsigned_integer (®isters[REGISTER_BYTE (regno)], + REGISTER_RAW_SIZE (regno))); } CORE_ADDR @@ -1150,6 +1214,25 @@ write_fp (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); +} + /* Will calling read_var_value or locate_var_value on SYM end up caring what frame it is being evaluated relative to? SYM must @@ -1231,12 +1314,15 @@ read_var_value (var, frame) case LOC_LABEL: /* Put the constant back in target format. */ if (overlay_debugging) - store_address (VALUE_CONTENTS_RAW (v), len, - (LONGEST) symbol_overlayed_address (SYMBOL_VALUE_ADDRESS (var), - SYMBOL_BFD_SECTION (var))); + { + 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_address (VALUE_CONTENTS_RAW (v), len, - (LONGEST) SYMBOL_VALUE_ADDRESS (var)); + store_typed_address (VALUE_CONTENTS_RAW (v), type, + SYMBOL_VALUE_ADDRESS (var)); VALUE_LVAL (v) = not_lval; return v; @@ -1678,7 +1764,7 @@ locate_var_value (var, frame) value_ptr val; addr = VALUE_ADDRESS (lazy_value); - val = value_from_longest (lookup_pointer_type (type), (LONGEST) addr); + val = value_from_pointer (lookup_pointer_type (type), addr); VALUE_BFD_SECTION (val) = VALUE_BFD_SECTION (lazy_value); return val; } diff --git a/gdb/gdbarch.c b/gdb/gdbarch.c index 98e0743374..a1b02ace82 100644 --- a/gdb/gdbarch.c +++ b/gdb/gdbarch.c @@ -175,6 +175,8 @@ struct gdbarch gdbarch_register_convertible_ftype *register_convertible; gdbarch_register_convert_to_virtual_ftype *register_convert_to_virtual; gdbarch_register_convert_to_raw_ftype *register_convert_to_raw; + gdbarch_pointer_to_address_ftype *pointer_to_address; + gdbarch_address_to_pointer_ftype *address_to_pointer; gdbarch_extract_return_value_ftype *extract_return_value; gdbarch_push_arguments_ftype *push_arguments; gdbarch_push_dummy_frame_ftype *push_dummy_frame; @@ -309,6 +311,8 @@ struct gdbarch startup_gdbarch = { 0, 0, 0, + 0, + 0, /* startup_gdbarch() */ }; struct gdbarch *current_gdbarch = &startup_gdbarch; @@ -351,6 +355,8 @@ gdbarch_alloc (const struct gdbarch_info *info, gdbarch->call_dummy_stack_adjust_p = -1; gdbarch->coerce_float_to_double = default_coerce_float_to_double; gdbarch->register_convertible = generic_register_convertible_not; + gdbarch->pointer_to_address = generic_pointer_to_address; + gdbarch->address_to_pointer = generic_address_to_pointer; gdbarch->breakpoint_from_pc = legacy_breakpoint_from_pc; gdbarch->memory_insert_breakpoint = default_memory_insert_breakpoint; gdbarch->memory_remove_breakpoint = default_memory_remove_breakpoint; @@ -517,6 +523,8 @@ verify_gdbarch (struct gdbarch *gdbarch) /* Skip verify of register_convertible, invalid_p == 0 */ /* Skip verify of register_convert_to_virtual, invalid_p == 0 */ /* Skip verify of register_convert_to_raw, invalid_p == 0 */ + /* Skip verify of pointer_to_address, invalid_p == 0 */ + /* Skip verify of address_to_pointer, invalid_p == 0 */ if ((GDB_MULTI_ARCH >= 2) && (gdbarch->extract_return_value == 0)) internal_error ("gdbarch: verify_gdbarch: extract_return_value invalid"); @@ -792,6 +800,14 @@ gdbarch_dump (void) "gdbarch_update: REGISTER_CONVERT_TO_RAW = 0x%08lx\n", (long) current_gdbarch->register_convert_to_raw /*REGISTER_CONVERT_TO_RAW ()*/); + fprintf_unfiltered (gdb_stdlog, + "gdbarch_update: POINTER_TO_ADDRESS = 0x%08lx\n", + (long) current_gdbarch->pointer_to_address + /*POINTER_TO_ADDRESS ()*/); + fprintf_unfiltered (gdb_stdlog, + "gdbarch_update: ADDRESS_TO_POINTER = 0x%08lx\n", + (long) current_gdbarch->address_to_pointer + /*ADDRESS_TO_POINTER ()*/); fprintf_unfiltered (gdb_stdlog, "gdbarch_update: EXTRACT_RETURN_VALUE = 0x%08lx\n", (long) current_gdbarch->extract_return_value @@ -1778,6 +1794,40 @@ set_gdbarch_register_convert_to_raw (struct gdbarch *gdbarch, gdbarch->register_convert_to_raw = register_convert_to_raw; } +CORE_ADDR +gdbarch_pointer_to_address (struct gdbarch *gdbarch, struct type *type, char *buf) +{ + if (gdbarch->pointer_to_address == 0) + internal_error ("gdbarch: gdbarch_pointer_to_address invalid"); + if (gdbarch_debug >= 2) + fprintf_unfiltered (gdb_stdlog, "gdbarch_pointer_to_address called\n"); + return gdbarch->pointer_to_address (type, buf); +} + +void +set_gdbarch_pointer_to_address (struct gdbarch *gdbarch, + gdbarch_pointer_to_address_ftype pointer_to_address) +{ + gdbarch->pointer_to_address = pointer_to_address; +} + +void +gdbarch_address_to_pointer (struct gdbarch *gdbarch, struct type *type, char *buf, CORE_ADDR addr) +{ + if (gdbarch->address_to_pointer == 0) + internal_error ("gdbarch: gdbarch_address_to_pointer invalid"); + if (gdbarch_debug >= 2) + fprintf_unfiltered (gdb_stdlog, "gdbarch_address_to_pointer called\n"); + gdbarch->address_to_pointer (type, buf, addr); +} + +void +set_gdbarch_address_to_pointer (struct gdbarch *gdbarch, + gdbarch_address_to_pointer_ftype address_to_pointer) +{ + gdbarch->address_to_pointer = address_to_pointer; +} + void gdbarch_extract_return_value (struct gdbarch *gdbarch, struct type *type, char *regbuf, char *valbuf) { @@ -3093,6 +3143,7 @@ generic_register_convertible_not (num) return 0; } + /* Disassembler */ /* Pointer to the target-dependent disassembly function. */ diff --git a/gdb/gdbarch.h b/gdb/gdbarch.h index e7b4e014d6..f24c26e76f 100644 --- a/gdb/gdbarch.h +++ b/gdb/gdbarch.h @@ -510,6 +510,24 @@ extern void set_gdbarch_register_convert_to_raw (struct gdbarch *gdbarch, gdbarc #endif #endif +typedef CORE_ADDR (gdbarch_pointer_to_address_ftype) (struct type *type, char *buf); +extern CORE_ADDR gdbarch_pointer_to_address (struct gdbarch *gdbarch, struct type *type, char *buf); +extern void set_gdbarch_pointer_to_address (struct gdbarch *gdbarch, gdbarch_pointer_to_address_ftype *pointer_to_address); +#if GDB_MULTI_ARCH +#if (GDB_MULTI_ARCH > 1) || !defined (POINTER_TO_ADDRESS) +#define POINTER_TO_ADDRESS(type, buf) (gdbarch_pointer_to_address (current_gdbarch, type, buf)) +#endif +#endif + +typedef void (gdbarch_address_to_pointer_ftype) (struct type *type, char *buf, CORE_ADDR addr); +extern void gdbarch_address_to_pointer (struct gdbarch *gdbarch, struct type *type, char *buf, CORE_ADDR addr); +extern void set_gdbarch_address_to_pointer (struct gdbarch *gdbarch, gdbarch_address_to_pointer_ftype *address_to_pointer); +#if GDB_MULTI_ARCH +#if (GDB_MULTI_ARCH > 1) || !defined (ADDRESS_TO_POINTER) +#define ADDRESS_TO_POINTER(type, buf, addr) (gdbarch_address_to_pointer (current_gdbarch, type, buf, addr)) +#endif +#endif + typedef void (gdbarch_extract_return_value_ftype) (struct type *type, char *regbuf, char *valbuf); extern void gdbarch_extract_return_value (struct gdbarch *gdbarch, struct type *type, char *regbuf, char *valbuf); extern void set_gdbarch_extract_return_value (struct gdbarch *gdbarch, gdbarch_extract_return_value_ftype *extract_return_value); diff --git a/gdb/gdbarch.sh b/gdb/gdbarch.sh index 8a907cc37d..9575e7fbac 100755 --- a/gdb/gdbarch.sh +++ b/gdb/gdbarch.sh @@ -239,6 +239,9 @@ f:1:REGISTER_CONVERTIBLE:int:register_convertible:int nr:nr:::generic_register_c f:2:REGISTER_CONVERT_TO_VIRTUAL:void:register_convert_to_virtual:int regnum, struct type *type, char *from, char *to:regnum, type, from, to:::0:0 f:2:REGISTER_CONVERT_TO_RAW:void:register_convert_to_raw:struct type *type, int regnum, char *from, char *to:type, regnum, from, to:::0:0 # +f:2:POINTER_TO_ADDRESS:CORE_ADDR:pointer_to_address:struct type *type, char *buf:type, buf:::generic_pointer_to_address:0 +f:2:ADDRESS_TO_POINTER:void:address_to_pointer:struct type *type, char *buf, CORE_ADDR addr:type, buf, addr:::generic_address_to_pointer:0 +# f:2:EXTRACT_RETURN_VALUE:void:extract_return_value:struct type *type, char *regbuf, char *valbuf:type, regbuf, valbuf::0:0 f:1:PUSH_ARGUMENTS:CORE_ADDR:push_arguments:int nargs, struct value **args, CORE_ADDR sp, int struct_return, CORE_ADDR struct_addr:nargs, args, sp, struct_return, struct_addr::0:0 f:2:PUSH_DUMMY_FRAME:void:push_dummy_frame:void:-:::0 @@ -1953,6 +1956,7 @@ generic_register_convertible_not (num) return 0; } + /* Disassembler */ /* Pointer to the target-dependent disassembly function. */ diff --git a/gdb/hppa-tdep.c b/gdb/hppa-tdep.c index b9d0a5c266..f97b3c84ed 100644 --- a/gdb/hppa-tdep.c +++ b/gdb/hppa-tdep.c @@ -2005,11 +2005,11 @@ find_stub_with_shl_get (function, handle) /* now prepare the arguments for the call */ args[0] = value_from_longest (TYPE_FIELD_TYPE (ftype, 0), 12); - args[1] = value_from_longest (TYPE_FIELD_TYPE (ftype, 1), SYMBOL_VALUE_ADDRESS (msymbol)); - args[2] = value_from_longest (TYPE_FIELD_TYPE (ftype, 2), endo_buff_addr); + args[1] = value_from_pointer (TYPE_FIELD_TYPE (ftype, 1), SYMBOL_VALUE_ADDRESS (msymbol)); + args[2] = value_from_pointer (TYPE_FIELD_TYPE (ftype, 2), endo_buff_addr); args[3] = value_from_longest (TYPE_FIELD_TYPE (ftype, 3), TYPE_PROCEDURE); - args[4] = value_from_longest (TYPE_FIELD_TYPE (ftype, 4), value_return_addr); - args[5] = value_from_longest (TYPE_FIELD_TYPE (ftype, 5), errno_return_addr); + args[4] = value_from_pointer (TYPE_FIELD_TYPE (ftype, 4), value_return_addr); + args[5] = value_from_pointer (TYPE_FIELD_TYPE (ftype, 5), errno_return_addr); /* now call the function */ diff --git a/gdb/inferior.h b/gdb/inferior.h index 5965f045ee..66513b6365 100644 --- a/gdb/inferior.h +++ b/gdb/inferior.h @@ -156,6 +156,11 @@ extern void write_fp PARAMS ((CORE_ADDR)); extern void generic_target_write_fp PARAMS ((CORE_ADDR)); +extern CORE_ADDR generic_pointer_to_address (struct type *type, char *buf); + +extern void generic_address_to_pointer (struct type *type, char *buf, + CORE_ADDR addr); + extern void wait_for_inferior PARAMS ((void)); extern void fetch_inferior_event PARAMS ((void *)); diff --git a/gdb/printcmd.c b/gdb/printcmd.c index 5068cc96c4..ff4ff36eca 100644 --- a/gdb/printcmd.c +++ b/gdb/printcmd.c @@ -537,8 +537,8 @@ set_next_address (addr) /* Make address available to the user as $_. */ set_internalvar (lookup_internalvar ("_"), - value_from_longest (lookup_pointer_type (builtin_type_void), - (LONGEST) addr)); + value_from_pointer (lookup_pointer_type (builtin_type_void), + addr)); } /* Optionally print address ADDR symbolically as on STREAM, @@ -1396,10 +1396,11 @@ x_command (exp, from_tty) { /* Make last address examined available to the user as $_. Use the correct pointer type. */ + struct type *pointer_type + = lookup_pointer_type (VALUE_TYPE (last_examine_value)); set_internalvar (lookup_internalvar ("_"), - value_from_longest ( - lookup_pointer_type (VALUE_TYPE (last_examine_value)), - (LONGEST) last_examine_address)); + value_from_pointer (pointer_type, + last_examine_address)); /* Make contents of last address examined available to the user as $__. */ /* If the last value has not been fetched from memory then don't diff --git a/gdb/tracepoint.c b/gdb/tracepoint.c index 245f1d07f8..95f79c19f3 100644 --- a/gdb/tracepoint.c +++ b/gdb/tracepoint.c @@ -268,11 +268,11 @@ set_traceframe_context (trace_pc) traceframe_sal.pc = traceframe_sal.line = 0; traceframe_sal.symtab = NULL; set_internalvar (lookup_internalvar ("trace_func"), - value_from_longest (charstar, (LONGEST) 0)); + value_from_pointer (charstar, (LONGEST) 0)); set_internalvar (lookup_internalvar ("trace_file"), - value_from_longest (charstar, (LONGEST) 0)); + value_from_pointer (charstar, (LONGEST) 0)); set_internalvar (lookup_internalvar ("trace_line"), - value_from_longest (builtin_type_int, (LONGEST) - 1)); + value_from_pointer (builtin_type_int, (LONGEST) - 1)); return; } @@ -289,7 +289,7 @@ set_traceframe_context (trace_pc) if (traceframe_fun == NULL || SYMBOL_NAME (traceframe_fun) == NULL) set_internalvar (lookup_internalvar ("trace_func"), - value_from_longest (charstar, (LONGEST) 0)); + value_from_pointer (charstar, (LONGEST) 0)); else { len = strlen (SYMBOL_NAME (traceframe_fun)); @@ -310,7 +310,7 @@ set_traceframe_context (trace_pc) if (traceframe_sal.symtab == NULL || traceframe_sal.symtab->filename == NULL) set_internalvar (lookup_internalvar ("trace_file"), - value_from_longest (charstar, (LONGEST) 0)); + value_from_pointer (charstar, (LONGEST) 0)); else { len = strlen (traceframe_sal.symtab->filename); diff --git a/gdb/valarith.c b/gdb/valarith.c index 97c3ca7736..5f814331aa 100644 --- a/gdb/valarith.c +++ b/gdb/valarith.c @@ -79,8 +79,8 @@ value_add (arg1, arg2) len = TYPE_LENGTH (check_typedef (TYPE_TARGET_TYPE (valptrtype))); if (len == 0) len = 1; /* For (void *) */ - retval = value_from_longest (valptrtype, - value_as_long (valptr) + retval = value_from_pointer (valptrtype, + value_as_pointer (valptr) + (len * value_as_long (valint))); VALUE_BFD_SECTION (retval) = VALUE_BFD_SECTION (valptr); return retval; @@ -105,9 +105,9 @@ value_sub (arg1, arg2) { /* pointer - integer. */ LONGEST sz = TYPE_LENGTH (check_typedef (TYPE_TARGET_TYPE (type1))); - return value_from_longest - (VALUE_TYPE (arg1), - value_as_long (arg1) - (sz * value_as_long (arg2))); + return value_from_pointer (VALUE_TYPE (arg1), + (value_as_pointer (arg1) + - (sz * value_as_long (arg2)))); } else if (TYPE_CODE (type2) == TYPE_CODE_PTR && TYPE_LENGTH (TYPE_TARGET_TYPE (type1)) diff --git a/gdb/valops.c b/gdb/valops.c index a99ad1c8f8..e73487746d 100644 --- a/gdb/valops.c +++ b/gdb/valops.c @@ -108,12 +108,12 @@ find_function_in_inferior (name) if (msymbol != NULL) { struct type *type; - LONGEST maddr; + CORE_ADDR maddr; type = lookup_pointer_type (builtin_type_char); type = lookup_function_type (type); type = lookup_pointer_type (type); - maddr = (LONGEST) SYMBOL_VALUE_ADDRESS (msymbol); - return value_from_longest (type, maddr); + maddr = SYMBOL_VALUE_ADDRESS (msymbol); + return value_from_pointer (type, maddr); } else { @@ -901,8 +901,8 @@ value_coerce_array (arg1) if (VALUE_LVAL (arg1) != lval_memory) error ("Attempt to take address of value not located in memory."); - return value_from_longest (lookup_pointer_type (TYPE_TARGET_TYPE (type)), - (LONGEST) (VALUE_ADDRESS (arg1) + VALUE_OFFSET (arg1))); + return value_from_pointer (lookup_pointer_type (TYPE_TARGET_TYPE (type)), + (VALUE_ADDRESS (arg1) + VALUE_OFFSET (arg1))); } /* Given a value which is a function, return a value which is a pointer @@ -917,8 +917,8 @@ value_coerce_function (arg1) if (VALUE_LVAL (arg1) != lval_memory) error ("Attempt to take address of value not located in memory."); - retval = value_from_longest (lookup_pointer_type (VALUE_TYPE (arg1)), - (LONGEST) (VALUE_ADDRESS (arg1) + VALUE_OFFSET (arg1))); + retval = value_from_pointer (lookup_pointer_type (VALUE_TYPE (arg1)), + (VALUE_ADDRESS (arg1) + VALUE_OFFSET (arg1))); VALUE_BFD_SECTION (retval) = VALUE_BFD_SECTION (arg1); return retval; } @@ -948,10 +948,10 @@ value_addr (arg1) error ("Attempt to take address of value not located in memory."); /* Get target memory address */ - arg2 = value_from_longest (lookup_pointer_type (VALUE_TYPE (arg1)), - (LONGEST) (VALUE_ADDRESS (arg1) - + VALUE_OFFSET (arg1) - + VALUE_EMBEDDED_OFFSET (arg1))); + arg2 = value_from_pointer (lookup_pointer_type (VALUE_TYPE (arg1)), + (VALUE_ADDRESS (arg1) + + VALUE_OFFSET (arg1) + + VALUE_EMBEDDED_OFFSET (arg1))); /* This may be a pointer to a base subobject; so remember the full derived object's type ... */ @@ -1582,8 +1582,8 @@ You must use a pointer to function type variable. Command ignored.", arg_name); we just pushed. */ /*args[i] = value_from_longest (lookup_pointer_type (value_type), (LONGEST) addr); */ - args[i] = value_from_longest (lookup_pointer_type (arg_type), - (LONGEST) addr); + args[i] = value_from_pointer (lookup_pointer_type (arg_type), + addr); } } } diff --git a/gdb/value.h b/gdb/value.h index 9b6989a28c..b67967a301 100644 --- a/gdb/value.h +++ b/gdb/value.h @@ -186,8 +186,8 @@ extern int value_fetch_lazy PARAMS ((value_ptr val)); do { struct type *value_type_arg_tmp = check_typedef (VALUE_TYPE (arg));\ if (TYPE_CODE (value_type_arg_tmp) == TYPE_CODE_REF) \ arg = value_at_lazy (TYPE_TARGET_TYPE (value_type_arg_tmp), \ - unpack_long (VALUE_TYPE (arg), \ - VALUE_CONTENTS (arg)), \ + unpack_pointer (VALUE_TYPE (arg), \ + VALUE_CONTENTS (arg)), \ VALUE_BFD_SECTION (arg)); \ } while (0) @@ -264,6 +264,8 @@ extern LONGEST unpack_field_as_long PARAMS ((struct type * type, char *valaddr, extern value_ptr value_from_longest PARAMS ((struct type * type, LONGEST num)); +extern value_ptr value_from_pointer (struct type *type, CORE_ADDR addr); + extern value_ptr value_from_double PARAMS ((struct type * type, DOUBLEST num)); extern value_ptr value_from_string PARAMS ((char *string)); diff --git a/gdb/values.c b/gdb/values.c index 07aff7a805..6186b34524 100644 --- a/gdb/values.c +++ b/gdb/values.c @@ -580,8 +580,9 @@ value_as_double (val) error ("Invalid floating value found in program."); return foo; } -/* Extract a value as a C pointer. - Does not deallocate the value. */ +/* Extract a value as a C pointer. Does not deallocate the value. + Note that val's type may not actually be a pointer; value_as_long + handles all the cases. */ CORE_ADDR value_as_pointer (val) value_ptr val; @@ -649,7 +650,7 @@ unpack_long (type, valaddr) if (GDB_TARGET_IS_D10V && len == 2) return D10V_MAKE_DADDR (extract_address (valaddr, len)); - return extract_address (valaddr, len); + return extract_typed_address (valaddr, type); case TYPE_CODE_MEMBER: error ("not implemented: member types in unpack_long"); @@ -731,6 +732,7 @@ unpack_pointer (type, valaddr) whether we want this to be true eventually. */ return unpack_long (type, valaddr); } + /* Get the value of the FIELDN'th field (which must be static) of TYPE. */ @@ -1420,9 +1422,7 @@ retry: case TYPE_CODE_REF: case TYPE_CODE_PTR: - /* This assumes that all pointers of a given length - have the same form. */ - store_address (VALUE_CONTENTS_RAW (val), len, (CORE_ADDR) num); + store_typed_address (VALUE_CONTENTS_RAW (val), type, (CORE_ADDR) num); break; default: @@ -1431,6 +1431,18 @@ retry: return val; } + +/* Create a value representing a pointer of type TYPE to the address + ADDR. */ +value_ptr +value_from_pointer (struct type *type, CORE_ADDR addr) +{ + value_ptr val = allocate_value (type); + store_typed_address (VALUE_CONTENTS_RAW (val), type, addr); + return val; +} + + /* Create a value for a string constant to be stored locally (not in the inferior's memory space, but in GDB memory). This is analogous to value_from_longest, which also does not -- 2.34.1