X-Git-Url: http://git.efficios.com/?a=blobdiff_plain;f=gdb%2Fvax-tdep.c;h=9373dc848d419de92f659ea0228cd646b04355f2;hb=3112ed9799124edf4d1f9c903da0d59f5a4ca102;hp=d43ba67941432a2c124f85dfd5bbeb3b862ee090;hpb=67b441e1281bb06d579858018050705524f0dcaa;p=deliverable%2Fbinutils-gdb.git diff --git a/gdb/vax-tdep.c b/gdb/vax-tdep.c index d43ba67941..9373dc848d 100644 --- a/gdb/vax-tdep.c +++ b/gdb/vax-tdep.c @@ -1,13 +1,12 @@ -/* Print VAX instructions for GDB, the GNU debugger. +/* Target-dependent code for the VAX. - Copyright 1986, 1989, 1991, 1992, 1995, 1996, 1998, 1999, 2000, - 2002, 2003, 2004 Free Software Foundation, Inc. + Copyright (C) 1986-2020 Free Software Foundation, Inc. This file is part of GDB. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or + the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, @@ -16,34 +15,30 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, - Boston, MA 02111-1307, USA. */ + along with this program. If not, see . */ #include "defs.h" -#include "symtab.h" -#include "opcode/vax.h" -#include "gdbcore.h" -#include "inferior.h" -#include "regcache.h" +#include "arch-utils.h" +#include "dis-asm.h" #include "frame.h" #include "frame-base.h" #include "frame-unwind.h" +#include "gdbcore.h" +#include "gdbtypes.h" +#include "osabi.h" +#include "regcache.h" +#include "regset.h" #include "trad-frame.h" #include "value.h" -#include "arch-utils.h" -#include "gdb_string.h" -#include "osabi.h" -#include "dis-asm.h" #include "vax-tdep.h" /* Return the name of register REGNUM. */ static const char * -vax_register_name (int regnum) +vax_register_name (struct gdbarch *gdbarch, int regnum) { - static char *register_names[] = + static const char *register_names[] = { "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "ap", "fp", "sp", "pc", @@ -57,16 +52,54 @@ vax_register_name (int regnum) } /* Return the GDB type object for the "standard" data type of data in - register REGNUM. */ + register REGNUM. */ static struct type * vax_register_type (struct gdbarch *gdbarch, int regnum) { - return builtin_type_int; + return builtin_type (gdbarch)->builtin_int; } +/* Core file support. */ + +/* Supply register REGNUM from the buffer specified by GREGS and LEN + in the general-purpose register set REGSET to register cache + REGCACHE. If REGNUM is -1, do this for all registers in REGSET. */ -/* The VAX Unix calling convention uses R1 to pass a structure return +static void +vax_supply_gregset (const struct regset *regset, struct regcache *regcache, + int regnum, const void *gregs, size_t len) +{ + const gdb_byte *regs = (const gdb_byte *) gregs; + int i; + + for (i = 0; i < VAX_NUM_REGS; i++) + { + if (regnum == i || regnum == -1) + regcache->raw_supply (i, regs + i * 4); + } +} + +/* VAX register set. */ + +static const struct regset vax_gregset = +{ + NULL, + vax_supply_gregset +}; + +/* Iterate over core file register note sections. */ + +static void +vax_iterate_over_regset_sections (struct gdbarch *gdbarch, + iterate_over_regset_sections_cb *cb, + void *cb_data, + const struct regcache *regcache) +{ + cb (".reg", VAX_NUM_REGS * 4, VAX_NUM_REGS * 4, &vax_gregset, NULL, cb_data); +} + +/* The VAX UNIX calling convention uses R1 to pass a structure return value address instead of passing it as a first (hidden) argument as the VMS calling convention suggests. */ @@ -74,7 +107,9 @@ static CORE_ADDR vax_store_arguments (struct regcache *regcache, int nargs, struct value **args, CORE_ADDR sp) { - char buf[4]; + struct gdbarch *gdbarch = regcache->arch (); + enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); + gdb_byte buf[4]; int count = 0; int i; @@ -84,49 +119,51 @@ vax_store_arguments (struct regcache *regcache, int nargs, /* Push arguments in reverse order. */ for (i = nargs - 1; i >= 0; i--) { - int len = TYPE_LENGTH (VALUE_ENCLOSING_TYPE (args[i])); + int len = TYPE_LENGTH (value_enclosing_type (args[i])); sp -= (len + 3) & ~3; count += (len + 3) / 4; - write_memory (sp, VALUE_CONTENTS_ALL (args[i]), len); + write_memory (sp, value_contents_all (args[i]), len); } /* Push argument count. */ sp -= 4; - store_unsigned_integer (buf, 4, count); + store_unsigned_integer (buf, 4, byte_order, count); write_memory (sp, buf, 4); /* Update the argument pointer. */ - store_unsigned_integer (buf, 4, sp); - regcache_cooked_write (regcache, VAX_AP_REGNUM, buf); + store_unsigned_integer (buf, 4, byte_order, sp); + regcache->cooked_write (VAX_AP_REGNUM, buf); return sp; } static CORE_ADDR -vax_push_dummy_call (struct gdbarch *gdbarch, CORE_ADDR func_addr, +vax_push_dummy_call (struct gdbarch *gdbarch, struct value *function, struct regcache *regcache, CORE_ADDR bp_addr, int nargs, - struct value **args, CORE_ADDR sp, int struct_return, + struct value **args, CORE_ADDR sp, + function_call_return_method return_method, CORE_ADDR struct_addr) { + enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); CORE_ADDR fp = sp; - char buf[4]; + gdb_byte buf[4]; /* Set up the function arguments. */ sp = vax_store_arguments (regcache, nargs, args, sp); /* Store return value address. */ - if (struct_return) + if (return_method == return_method_struct) regcache_cooked_write_unsigned (regcache, VAX_R1_REGNUM, struct_addr); /* Store return address in the PC slot. */ sp -= 4; - store_unsigned_integer (buf, 4, bp_addr); + store_unsigned_integer (buf, 4, byte_order, bp_addr); write_memory (sp, buf, 4); /* Store the (fake) frame pointer in the FP slot. */ sp -= 4; - store_unsigned_integer (buf, 4, fp); + store_unsigned_integer (buf, 4, byte_order, fp); write_memory (sp, buf, 4); /* Skip the AP slot. */ @@ -134,61 +171,75 @@ vax_push_dummy_call (struct gdbarch *gdbarch, CORE_ADDR func_addr, /* Store register save mask and control bits. */ sp -= 4; - store_unsigned_integer (buf, 4, 0); + store_unsigned_integer (buf, 4, byte_order, 0); write_memory (sp, buf, 4); /* Store condition handler. */ sp -= 4; - store_unsigned_integer (buf, 4, 0); + store_unsigned_integer (buf, 4, byte_order, 0); write_memory (sp, buf, 4); /* Update the stack pointer and frame pointer. */ - store_unsigned_integer (buf, 4, sp); - regcache_cooked_write (regcache, VAX_SP_REGNUM, buf); - regcache_cooked_write (regcache, VAX_FP_REGNUM, buf); + store_unsigned_integer (buf, 4, byte_order, sp); + regcache->cooked_write (VAX_SP_REGNUM, buf); + regcache->cooked_write (VAX_FP_REGNUM, buf); /* Return the saved (fake) frame pointer. */ return fp; } static struct frame_id -vax_unwind_dummy_id (struct gdbarch *gdbarch, struct frame_info *next_frame) +vax_dummy_id (struct gdbarch *gdbarch, struct frame_info *this_frame) { CORE_ADDR fp; - fp = frame_unwind_register_unsigned (next_frame, VAX_FP_REGNUM); - return frame_id_build (fp, frame_pc_unwind (next_frame)); + fp = get_frame_register_unsigned (this_frame, VAX_FP_REGNUM); + return frame_id_build (fp, get_frame_pc (this_frame)); } static enum return_value_convention -vax_return_value (struct gdbarch *gdbarch, struct type *type, - struct regcache *regcache, void *readbuf, - const void *writebuf) +vax_return_value (struct gdbarch *gdbarch, struct value *function, + struct type *type, struct regcache *regcache, + gdb_byte *readbuf, const gdb_byte *writebuf) { int len = TYPE_LENGTH (type); - char buf[8]; + gdb_byte buf[8]; if (TYPE_CODE (type) == TYPE_CODE_STRUCT - || TYPE_CODE (type) == TYPE_CODE_STRUCT + || TYPE_CODE (type) == TYPE_CODE_UNION || TYPE_CODE (type) == TYPE_CODE_ARRAY) - return RETURN_VALUE_STRUCT_CONVENTION; + { + /* The default on VAX is to return structures in static memory. + Consequently a function must return the address where we can + find the return value. */ + + if (readbuf) + { + ULONGEST addr; + + regcache_raw_read_unsigned (regcache, VAX_R0_REGNUM, &addr); + read_memory (addr, readbuf, len); + } + + return RETURN_VALUE_ABI_RETURNS_ADDRESS; + } if (readbuf) { /* Read the contents of R0 and (if necessary) R1. */ - regcache_cooked_read (regcache, VAX_R0_REGNUM, buf); + regcache->cooked_read (VAX_R0_REGNUM, buf); if (len > 4) - regcache_cooked_read (regcache, VAX_R1_REGNUM, buf + 4); + regcache->cooked_read (VAX_R1_REGNUM, buf + 4); memcpy (readbuf, buf, len); } if (writebuf) { /* Read the contents to R0 and (if necessary) R1. */ memcpy (buf, writebuf, len); - regcache_cooked_write (regcache, VAX_R0_REGNUM, buf); + regcache->cooked_write (VAX_R0_REGNUM, buf); if (len > 4) - regcache_cooked_write (regcache, VAX_R1_REGNUM, buf + 4); + regcache->cooked_write (VAX_R1_REGNUM, buf + 4); } return RETURN_VALUE_REGISTER_CONVENTION; @@ -200,42 +251,40 @@ vax_return_value (struct gdbarch *gdbarch, struct type *type, encode a breakpoint instruction, store the length of the string in *LEN and optionally adjust *PC to point to the correct memory location for inserting the breakpoint. */ - -static const unsigned char * -vax_breakpoint_from_pc (CORE_ADDR *pc, int *len) -{ - static unsigned char break_insn[] = { 3 }; - *len = sizeof (break_insn); - return break_insn; -} +constexpr gdb_byte vax_break_insn[] = { 3 }; + +typedef BP_MANIPULATION (vax_break_insn) vax_breakpoint; /* Advance PC across any function entry prologue instructions to reach some "real" code. */ static CORE_ADDR -vax_skip_prologue (CORE_ADDR pc) +vax_skip_prologue (struct gdbarch *gdbarch, CORE_ADDR pc) { - int op = (unsigned char) read_memory_integer (pc, 1); + enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); + gdb_byte op = read_memory_unsigned_integer (pc, 1, byte_order); + if (op == 0x11) pc += 2; /* skip brb */ if (op == 0x31) pc += 3; /* skip brw */ if (op == 0xC2 - && ((unsigned char) read_memory_integer (pc + 2, 1)) == 0x5E) + && read_memory_unsigned_integer (pc + 2, 1, byte_order) == 0x5E) pc += 3; /* skip subl2 */ if (op == 0x9E - && ((unsigned char) read_memory_integer (pc + 1, 1)) == 0xAE - && ((unsigned char) read_memory_integer (pc + 3, 1)) == 0x5E) + && read_memory_unsigned_integer (pc + 1, 1, byte_order) == 0xAE + && read_memory_unsigned_integer (pc + 3, 1, byte_order) == 0x5E) pc += 4; /* skip movab */ if (op == 0x9E - && ((unsigned char) read_memory_integer (pc + 1, 1)) == 0xCE - && ((unsigned char) read_memory_integer (pc + 4, 1)) == 0x5E) + && read_memory_unsigned_integer (pc + 1, 1, byte_order) == 0xCE + && read_memory_unsigned_integer (pc + 4, 1, byte_order) == 0x5E) pc += 5; /* skip movab */ if (op == 0x9E - && ((unsigned char) read_memory_integer (pc + 1, 1)) == 0xEE - && ((unsigned char) read_memory_integer (pc + 6, 1)) == 0x5E) + && read_memory_unsigned_integer (pc + 1, 1, byte_order) == 0xEE + && read_memory_unsigned_integer (pc + 6, 1, byte_order) == 0x5E) pc += 7; /* skip movab */ + return pc; } @@ -255,8 +304,8 @@ struct vax_frame_cache struct trad_frame_saved_reg *saved_regs; }; -struct vax_frame_cache * -vax_frame_cache (struct frame_info *next_frame, void **this_cache) +static struct vax_frame_cache * +vax_frame_cache (struct frame_info *this_frame, void **this_cache) { struct vax_frame_cache *cache; CORE_ADDR addr; @@ -264,20 +313,20 @@ vax_frame_cache (struct frame_info *next_frame, void **this_cache) int regnum; if (*this_cache) - return *this_cache; + return (struct vax_frame_cache *) *this_cache; /* Allocate a new cache. */ cache = FRAME_OBSTACK_ZALLOC (struct vax_frame_cache); - cache->saved_regs = trad_frame_alloc_saved_regs (next_frame); + cache->saved_regs = trad_frame_alloc_saved_regs (this_frame); /* The frame pointer is used as the base for the frame. */ - cache->base = frame_unwind_register_unsigned (next_frame, VAX_FP_REGNUM); + cache->base = get_frame_register_unsigned (this_frame, VAX_FP_REGNUM); if (cache->base == 0) return cache; /* The register save mask and control bits determine the layout of the stack frame. */ - mask = get_frame_memory_unsigned (next_frame, cache->base + 4, 4) >> 16; + mask = get_frame_memory_unsigned (this_frame, cache->base + 4, 4) >> 16; /* These are always saved. */ cache->saved_regs[VAX_PC_REGNUM].addr = cache->base + 16; @@ -304,10 +353,10 @@ vax_frame_cache (struct frame_info *next_frame, void **this_cache) ULONGEST numarg; /* This is a procedure with Stack Argument List. Adjust the - stack address for the arguments thet were pushed onto the + stack address for the arguments that were pushed onto the stack. The return instruction will automatically pop the arguments from the stack. */ - numarg = get_frame_memory_unsigned (next_frame, addr, 1); + numarg = get_frame_memory_unsigned (this_frame, addr, 1); addr += 4 + numarg * 4; } @@ -318,56 +367,50 @@ vax_frame_cache (struct frame_info *next_frame, void **this_cache) } static void -vax_frame_this_id (struct frame_info *next_frame, void **this_cache, +vax_frame_this_id (struct frame_info *this_frame, void **this_cache, struct frame_id *this_id) { - struct vax_frame_cache *cache = vax_frame_cache (next_frame, this_cache); + struct vax_frame_cache *cache = vax_frame_cache (this_frame, this_cache); /* This marks the outermost frame. */ if (cache->base == 0) return; - (*this_id) = frame_id_build (cache->base, frame_pc_unwind (next_frame)); + (*this_id) = frame_id_build (cache->base, get_frame_func (this_frame)); } -static void -vax_frame_prev_register (struct frame_info *next_frame, void **this_cache, - int regnum, int *optimizedp, - enum lval_type *lvalp, CORE_ADDR *addrp, - int *realnump, void *valuep) +static struct value * +vax_frame_prev_register (struct frame_info *this_frame, + void **this_cache, int regnum) { - struct vax_frame_cache *cache = vax_frame_cache (next_frame, this_cache); + struct vax_frame_cache *cache = vax_frame_cache (this_frame, this_cache); - trad_frame_prev_register (next_frame, cache->saved_regs, regnum, - optimizedp, lvalp, addrp, realnump, valuep); + return trad_frame_get_prev_register (this_frame, cache->saved_regs, regnum); } static const struct frame_unwind vax_frame_unwind = { NORMAL_FRAME, + default_frame_unwind_stop_reason, vax_frame_this_id, - vax_frame_prev_register + vax_frame_prev_register, + NULL, + default_frame_sniffer }; - -static const struct frame_unwind * -vax_frame_sniffer (struct frame_info *next_frame) -{ - return &vax_frame_unwind; -} static CORE_ADDR -vax_frame_base_address (struct frame_info *next_frame, void **this_cache) +vax_frame_base_address (struct frame_info *this_frame, void **this_cache) { - struct vax_frame_cache *cache = vax_frame_cache (next_frame, this_cache); + struct vax_frame_cache *cache = vax_frame_cache (this_frame, this_cache); return cache->base; } static CORE_ADDR -vax_frame_args_address (struct frame_info *next_frame, void **this_cache) +vax_frame_args_address (struct frame_info *this_frame, void **this_cache) { - return frame_unwind_register_unsigned (next_frame, VAX_AP_REGNUM); + return get_frame_register_unsigned (this_frame, VAX_AP_REGNUM); } static const struct frame_base vax_frame_base = @@ -387,18 +430,13 @@ vax_frame_num_args (struct frame_info *frame) /* Assume that the argument pointer for the outermost frame is hosed, as is the case on NetBSD/vax ELF. */ - if (get_frame_base (frame) == 0) + if (get_frame_base_address (frame) == 0) return 0; args = get_frame_register_unsigned (frame, VAX_AP_REGNUM); return get_frame_memory_unsigned (frame, args, 1); } -static CORE_ADDR -vax_unwind_pc (struct gdbarch *gdbarch, struct frame_info *next_frame) -{ - return frame_unwind_register_unsigned (next_frame, VAX_PC_REGNUM); -} /* Initialize the current architecture based on INFO. If possible, re-use an @@ -420,6 +458,11 @@ vax_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) gdbarch = gdbarch_alloc (&info, NULL); + set_gdbarch_float_format (gdbarch, floatformats_vax_f); + set_gdbarch_double_format (gdbarch, floatformats_vax_d); + set_gdbarch_long_double_format (gdbarch, floatformats_vax_d); + set_gdbarch_long_double_bit (gdbarch, 64); + /* Register info */ set_gdbarch_num_regs (gdbarch, VAX_NUM_REGS); set_gdbarch_register_name (gdbarch, vax_register_name); @@ -428,10 +471,12 @@ vax_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) set_gdbarch_pc_regnum (gdbarch, VAX_PC_REGNUM); set_gdbarch_ps_regnum (gdbarch, VAX_PS_REGNUM); + set_gdbarch_iterate_over_regset_sections + (gdbarch, vax_iterate_over_regset_sections); + /* Frame and stack info */ set_gdbarch_skip_prologue (gdbarch, vax_skip_prologue); set_gdbarch_frame_num_args (gdbarch, vax_frame_num_args); - set_gdbarch_frame_args_skip (gdbarch, 4); /* Stack grows downward. */ @@ -442,33 +487,29 @@ vax_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) /* Call dummy code. */ set_gdbarch_push_dummy_call (gdbarch, vax_push_dummy_call); - set_gdbarch_unwind_dummy_id (gdbarch, vax_unwind_dummy_id); + set_gdbarch_dummy_id (gdbarch, vax_dummy_id); /* Breakpoint info */ - set_gdbarch_breakpoint_from_pc (gdbarch, vax_breakpoint_from_pc); + set_gdbarch_breakpoint_kind_from_pc (gdbarch, vax_breakpoint::kind_from_pc); + set_gdbarch_sw_breakpoint_from_kind (gdbarch, vax_breakpoint::bp_from_kind); /* Misc info */ - set_gdbarch_function_start_offset (gdbarch, 2); + set_gdbarch_deprecated_function_start_offset (gdbarch, 2); set_gdbarch_believe_pcc_promotion (gdbarch, 1); - set_gdbarch_unwind_pc (gdbarch, vax_unwind_pc); - frame_base_set_default (gdbarch, &vax_frame_base); /* Hook in ABI-specific overrides, if they have been registered. */ gdbarch_init_osabi (info, gdbarch); - frame_unwind_append_sniffer (gdbarch, vax_frame_sniffer); - - set_gdbarch_print_insn (gdbarch, print_insn_vax); + frame_unwind_append_unwinder (gdbarch, &vax_frame_unwind); return (gdbarch); } -extern initialize_file_ftype _initialize_vax_tdep; /* -Wmissing-prototypes */ - +void _initialize_vax_tdep (); void -_initialize_vax_tdep (void) +_initialize_vax_tdep () { gdbarch_register (bfd_arch_vax, vax_gdbarch_init, NULL); }