X-Git-Url: http://git.efficios.com/?a=blobdiff_plain;f=gdb%2Fframe.c;h=90d0ac7b87034ceb8720509f935c6c4e32ae491c;hb=40c03530b197d8d6ef550283ecd6684e8d49301b;hp=00001bcf3f5728c2e136c5e9bbce70449d01852c;hpb=7c2ba67e6ab10879968c938aefd4d0d0b4ce79bc;p=deliverable%2Fbinutils-gdb.git diff --git a/gdb/frame.c b/gdb/frame.c index 00001bcf3f..90d0ac7b87 100644 --- a/gdb/frame.c +++ b/gdb/frame.c @@ -1,6 +1,6 @@ /* Cache and manage frames for GDB, the GNU debugger. - Copyright (C) 1986-2016 Free Software Foundation, Inc. + Copyright (C) 1986-2018 Free Software Foundation, Inc. This file is part of GDB. @@ -34,7 +34,7 @@ #include "frame-base.h" #include "command.h" #include "gdbcmd.h" -#include "observer.h" +#include "observable.h" #include "objfiles.h" #include "gdbthread.h" #include "block.h" @@ -99,7 +99,7 @@ struct frame_info struct program_space *pspace; /* The frame's address space. */ - struct address_space *aspace; + const address_space *aspace; /* The frame's low-level unwinder and corresponding cache. The low-level unwinder is responsible for unwinding register values @@ -1017,16 +1017,13 @@ do_frame_register_read (void *src, int regnum, gdb_byte *buf) return REG_VALID; } -struct regcache * +std::unique_ptr frame_save_as_regcache (struct frame_info *this_frame) { - struct address_space *aspace = get_frame_address_space (this_frame); - struct regcache *regcache = regcache_xmalloc (get_frame_arch (this_frame), - aspace); - struct cleanup *cleanups = make_cleanup_regcache_xfree (regcache); + std::unique_ptr regcache + (new readonly_detached_regcache (get_frame_arch (this_frame), + do_frame_register_read, this_frame)); - regcache_save (regcache, do_frame_register_read, this_frame); - discard_cleanups (cleanups); return regcache; } @@ -1034,8 +1031,6 @@ void frame_pop (struct frame_info *this_frame) { struct frame_info *prev_frame; - struct regcache *scratch; - struct cleanup *cleanups; if (get_frame_type (this_frame) == DUMMY_FRAME) { @@ -1062,8 +1057,8 @@ frame_pop (struct frame_info *this_frame) Save them in a scratch buffer so that there isn't a race between trying to extract the old values from the current regcache while at the same time writing new values into that same cache. */ - scratch = frame_save_as_regcache (prev_frame); - cleanups = make_cleanup_regcache_xfree (scratch); + std::unique_ptr scratch + = frame_save_as_regcache (prev_frame); /* FIXME: cagney/2003-03-16: It should be possible to tell the target's register cache that it is about to be hit with a burst @@ -1073,10 +1068,8 @@ frame_pop (struct frame_info *this_frame) Unfortunately, they don't implement it. Their lack of a formal definition can lead to targets writing back bogus values (arguably a bug in the target code mind). */ - /* Now copy those saved registers into the current regcache. - Here, regcache_cpy() calls regcache_restore(). */ - regcache_cpy (get_current_regcache (), scratch); - do_cleanups (cleanups); + /* Now copy those saved registers into the current regcache. */ + get_current_regcache ()->restore (scratch.get ()); /* We've made right mess of GDB's local state, just discard everything. */ @@ -1124,7 +1117,6 @@ frame_register_unwind (struct frame_info *frame, int regnum, /* Dispose of the new value. This prevents watchpoints from trying to watch the saved frame pointer. */ release_value (value); - value_free (value); } void @@ -1252,10 +1244,26 @@ frame_unwind_register_signed (struct frame_info *frame, int regnum) struct gdbarch *gdbarch = frame_unwind_arch (frame); enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); int size = register_size (gdbarch, regnum); - gdb_byte buf[MAX_REGISTER_SIZE]; + struct value *value = frame_unwind_register_value (frame, regnum); - frame_unwind_register (frame, regnum, buf); - return extract_signed_integer (buf, size, byte_order); + gdb_assert (value != NULL); + + if (value_optimized_out (value)) + { + throw_error (OPTIMIZED_OUT_ERROR, + _("Register %d was not saved"), regnum); + } + if (!value_entirely_available (value)) + { + throw_error (NOT_AVAILABLE_ERROR, + _("Register %d is not available"), regnum); + } + + LONGEST r = extract_signed_integer (value_contents_all (value), size, + byte_order); + + release_value (value); + return r; } LONGEST @@ -1270,10 +1278,26 @@ frame_unwind_register_unsigned (struct frame_info *frame, int regnum) struct gdbarch *gdbarch = frame_unwind_arch (frame); enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); int size = register_size (gdbarch, regnum); - gdb_byte buf[MAX_REGISTER_SIZE]; + struct value *value = frame_unwind_register_value (frame, regnum); - frame_unwind_register (frame, regnum, buf); - return extract_unsigned_integer (buf, size, byte_order); + gdb_assert (value != NULL); + + if (value_optimized_out (value)) + { + throw_error (OPTIMIZED_OUT_ERROR, + _("Register %d was not saved"), regnum); + } + if (!value_entirely_available (value)) + { + throw_error (NOT_AVAILABLE_ERROR, + _("Register %d is not available"), regnum); + } + + ULONGEST r = extract_unsigned_integer (value_contents_all (value), size, + byte_order); + + release_value (value); + return r; } ULONGEST @@ -1410,16 +1434,19 @@ get_frame_register_bytes (struct frame_info *frame, int regnum, } else { - gdb_byte buf[MAX_REGISTER_SIZE]; - enum lval_type lval; - CORE_ADDR addr; - int realnum; + struct value *value = frame_unwind_register_value (frame->next, + regnum); + gdb_assert (value != NULL); + *optimizedp = value_optimized_out (value); + *unavailablep = !value_entirely_available (value); - frame_register (frame, regnum, optimizedp, unavailablep, - &lval, &addr, &realnum, buf); if (*optimizedp || *unavailablep) - return 0; - memcpy (myaddr, buf + offset, curr_len); + { + release_value (value); + return 0; + } + memcpy (myaddr, value_contents_all (value) + offset, curr_len); + release_value (value); } myaddr += curr_len; @@ -1460,11 +1487,14 @@ put_frame_register_bytes (struct frame_info *frame, int regnum, } else { - gdb_byte buf[MAX_REGISTER_SIZE]; - - deprecated_frame_register_read (frame, regnum, buf); - memcpy (buf + offset, myaddr, curr_len); - put_frame_register (frame, regnum, buf); + struct value *value = frame_unwind_register_value (frame->next, + regnum); + gdb_assert (value != NULL); + + memcpy ((char *) value_contents_writeable (value) + offset, myaddr, + curr_len); + put_frame_register (frame, regnum, value_contents_raw (value)); + release_value (value); } myaddr += curr_len; @@ -1483,7 +1513,7 @@ create_sentinel_frame (struct program_space *pspace, struct regcache *regcache) frame->level = -1; frame->pspace = pspace; - frame->aspace = get_regcache_aspace (regcache); + frame->aspace = regcache->aspace (); /* Explicitly initialize the sentinel frame's cache. Provide it with the underlying regcache. In the future additional information, such as the frame's thread will be added. */ @@ -2446,8 +2476,8 @@ get_frame_address_in_block_if_available (struct frame_info *this_frame, return 1; } -void -find_frame_sal (struct frame_info *frame, struct symtab_and_line *sal) +symtab_and_line +find_frame_sal (frame_info *frame) { struct frame_info *next_frame; int notcurrent; @@ -2468,21 +2498,21 @@ find_frame_sal (struct frame_info *frame, struct symtab_and_line *sal) /* If frame is inline, it certainly has symbols. */ gdb_assert (sym); - init_sal (sal); + + symtab_and_line sal; if (SYMBOL_LINE (sym) != 0) { - sal->symtab = symbol_symtab (sym); - sal->line = SYMBOL_LINE (sym); + sal.symtab = symbol_symtab (sym); + sal.line = SYMBOL_LINE (sym); } else /* If the symbol does not have a location, we don't know where the call site is. Do not pretend to. This is jarring, but we can't do much better. */ - sal->pc = get_frame_pc (frame); - - sal->pspace = get_frame_program_space (frame); + sal.pc = get_frame_pc (frame); - return; + sal.pspace = get_frame_program_space (frame); + return sal; } /* If FRAME is not the innermost frame, that normally means that @@ -2495,13 +2525,10 @@ find_frame_sal (struct frame_info *frame, struct symtab_and_line *sal) instruction/line, consequently, for such cases, want to get the line containing fi->pc. */ if (!get_frame_pc_if_available (frame, &pc)) - { - init_sal (sal); - return; - } + return {}; notcurrent = (pc != get_frame_address_in_block (frame)); - (*sal) = find_pc_line (pc, notcurrent); + return find_pc_line (pc, notcurrent); } /* Per "frame.h", return the ``address'' of the frame. Code should @@ -2608,7 +2635,7 @@ frame_unwind_program_space (struct frame_info *this_frame) return this_frame->pspace; } -struct address_space * +const address_space * get_frame_address_space (struct frame_info *frame) { return frame->aspace; @@ -2829,11 +2856,9 @@ frame_stop_reason_symbol_string (enum unwind_stop_reason reason) /* Clean up after a failed (wrong unwinder) attempt to unwind past FRAME. */ -static void -frame_cleanup_after_sniffer (void *arg) +void +frame_cleanup_after_sniffer (struct frame_info *frame) { - struct frame_info *frame = (struct frame_info *) arg; - /* The sniffer should not allocate a prologue cache if it did not match this frame. */ gdb_assert (frame->prologue_cache == NULL); @@ -2858,32 +2883,29 @@ frame_cleanup_after_sniffer (void *arg) } /* Set FRAME's unwinder temporarily, so that we can call a sniffer. - Return a cleanup which should be called if unwinding fails, and - discarded if it succeeds. */ + If sniffing fails, the caller should be sure to call + frame_cleanup_after_sniffer. */ -struct cleanup * +void frame_prepare_for_sniffer (struct frame_info *frame, const struct frame_unwind *unwind) { gdb_assert (frame->unwind == NULL); frame->unwind = unwind; - return make_cleanup (frame_cleanup_after_sniffer, frame); } -extern initialize_file_ftype _initialize_frame; /* -Wmissing-prototypes */ - static struct cmd_list_element *set_backtrace_cmdlist; static struct cmd_list_element *show_backtrace_cmdlist; static void -set_backtrace_cmd (char *args, int from_tty) +set_backtrace_cmd (const char *args, int from_tty) { help_list (set_backtrace_cmdlist, "set backtrace ", all_commands, gdb_stdout); } static void -show_backtrace_cmd (char *args, int from_tty) +show_backtrace_cmd (const char *args, int from_tty) { cmd_show_list (show_backtrace_cmdlist, from_tty, ""); } @@ -2895,7 +2917,7 @@ _initialize_frame (void) frame_stash_create (); - observer_attach_target_changed (frame_observer_target_changed); + gdb::observers::target_changed.attach (frame_observer_target_changed); add_prefix_cmd ("backtrace", class_maintenance, set_backtrace_cmd, _("\ Set backtrace specific variables.\n\