81783d0
infcall.c <unwind_on_signal_p>:
81783d0
Revert the change of: gdb-6.8-inlining.patch
81783d0
causing: FAIL: gdb.base/unwindonsignal.exp: unwindonsignal, stack unwound
81783d0
81783d0
resume() -> target_resume() move of clear_inline_frame_state() is for:
81783d0
gdb.mi/mi-nsmoribund.exp
81783d0
e5611bf
Index: gdb-6.8.50.20090803/gdb/testsuite/gdb.opt/inline-bt.c
407ebe9
===================================================================
e5611bf
--- gdb-6.8.50.20090803.orig/gdb/testsuite/gdb.opt/inline-bt.c	2009-06-28 02:20:24.000000000 +0200
e5611bf
+++ gdb-6.8.50.20090803/gdb/testsuite/gdb.opt/inline-bt.c	2009-08-03 16:57:40.000000000 +0200
407ebe9
@@ -13,10 +13,16 @@
407ebe9
    You should have received a copy of the GNU General Public License
407ebe9
    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
407ebe9
 
407ebe9
-int x, y;
407ebe9
+/* VOLATILE forces all the inlining to happen as otherwise the whole program
407ebe9
+   gets optimized by CSE to just simple assignments of the results.  */
407ebe9
+volatile int x, y;
407ebe9
 volatile int result;
407ebe9
 
407ebe9
-void bar(void);
407ebe9
+inline void bar(void)
407ebe9
+{
407ebe9
+  x += y; /* set breakpoint 1 here */
407ebe9
+}
407ebe9
+
407ebe9
 
407ebe9
 inline int func1(void)
407ebe9
 {
e5611bf
Index: gdb-6.8.50.20090803/gdb/testsuite/gdb.opt/inline-cmds.c
407ebe9
===================================================================
e5611bf
--- gdb-6.8.50.20090803.orig/gdb/testsuite/gdb.opt/inline-cmds.c	2009-06-28 02:20:24.000000000 +0200
e5611bf
+++ gdb-6.8.50.20090803/gdb/testsuite/gdb.opt/inline-cmds.c	2009-08-03 16:57:40.000000000 +0200
407ebe9
@@ -13,13 +13,19 @@
407ebe9
    You should have received a copy of the GNU General Public License
407ebe9
    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
407ebe9
 
407ebe9
-int x, y;
407ebe9
+/* VOLATILE forces all the inlining to happen as otherwise the whole program
407ebe9
+   gets optimized by CSE to just simple assignments of the results.  */
407ebe9
+volatile int x, y;
407ebe9
 volatile int result;
407ebe9
 
407ebe9
-void bar(void);
407ebe9
 void marker(void);
407ebe9
 void noinline(void);
407ebe9
 
407ebe9
+inline void bar(void)
407ebe9
+{
407ebe9
+  x += y; /* set breakpoint 1 here */
407ebe9
+}
407ebe9
+
407ebe9
 inline int func1(void)
407ebe9
 {
407ebe9
   bar ();
e5611bf
Index: gdb-6.8.50.20090803/gdb/testsuite/gdb.opt/inline-cmds.exp
407ebe9
===================================================================
e5611bf
--- gdb-6.8.50.20090803.orig/gdb/testsuite/gdb.opt/inline-cmds.exp	2009-06-28 02:20:24.000000000 +0200
e5611bf
+++ gdb-6.8.50.20090803/gdb/testsuite/gdb.opt/inline-cmds.exp	2009-08-03 16:57:40.000000000 +0200
e5611bf
@@ -230,7 +230,7 @@ set line3 [gdb_get_line_number "set brea
ec0fcb6
 gdb_breakpoint $line3
ec0fcb6
 gdb_continue_to_breakpoint "consecutive func1"
ec0fcb6
 
ec0fcb6
-gdb_test "next" ".*func1 .*first call.*" "next to first func1"
ec0fcb6
+gdb_test "next" "func1 .*first call.*" "next to first func1"
ec0fcb6
 set msg "next to second func1"
ec0fcb6
 gdb_test_multiple "next" $msg {
ec0fcb6
     -re ".*func1 .*second call.*$gdb_prompt $" {
e5611bf
@@ -253,16 +253,16 @@ set line4 [gdb_get_line_number "set brea
ec0fcb6
 gdb_breakpoint $line4
ec0fcb6
 gdb_continue_to_breakpoint "func1 then func3"
ec0fcb6
 
ec0fcb6
-gdb_test "next" ".*func1 \\\(\\\);" "next to func1 before func3"
ec0fcb6
-gdb_test "next" ".*func3 \\\(\\\);" "next to func3"
ec0fcb6
+gdb_test "next" "func1 \\\(\\\);" "next to func1 before func3"
ec0fcb6
+gdb_test "next" "func3 \\\(\\\);" "next to func3"
ec0fcb6
 
ec0fcb6
 # Test finishing out of one thing and into another.
ec0fcb6
 set line5 [gdb_get_line_number "set breakpoint 5 here"]
ec0fcb6
 gdb_breakpoint $line5
ec0fcb6
 gdb_continue_to_breakpoint "finish into func1"
ec0fcb6
 
ec0fcb6
-gdb_test "next" ".*marker \\\(\\\);" "next to finish marker"
ec0fcb6
-gdb_test "step" ".*set breakpoint 2 here.*" "step into finish marker"
ec0fcb6
+gdb_test "next" "marker \\\(\\\);" "next to finish marker"
ec0fcb6
+gdb_test "step" "set breakpoint 2 here.*" "step into finish marker"
ec0fcb6
 gdb_test "finish" "func1 \\\(\\\);" "finish from marker to func1"
ec0fcb6
 
ec0fcb6
 gdb_test "step" "bar \\\(\\\);" "step into func1 for finish"
e5611bf
@@ -297,12 +297,12 @@ gdb_test "step" "noinline \\\(\\\) at .*
ec0fcb6
 gdb_test "bt" "#0  noinline.*#1  .*outer_inline1.*#2  .*outer_inline2.*#3  main.*" "backtrace at noinline from outer_inline1"
ec0fcb6
 gdb_test "step" "inlined_fn \\\(\\\) at .*" "enter inlined_fn from noinline"
ec0fcb6
 gdb_test "bt" "#0  inlined_fn.*#1  noinline.*#2  .*outer_inline1.*#3  .*outer_inline2.*#4  main.*" "backtrace at inlined_fn from noinline"
ec0fcb6
-gdb_test "info frame" ".*inlined into frame.*" "inlined_fn from noinline inlined"
ec0fcb6
-gdb_test "up" "#1  noinline.*" "up to noinline"
ec0fcb6
-gdb_test "info frame" ".*\n called by frame.*" "noinline from outer_inline1 not inlined"
ec0fcb6
-gdb_test "up" "#2  .*outer_inline1.*" "up to outer_inline1"
ec0fcb6
-gdb_test "info frame" ".*inlined into frame.*" "outer_inline1 inlined"
ec0fcb6
-gdb_test "up" "#3  .*outer_inline2.*" "up to outer_inline2"
ec0fcb6
-gdb_test "info frame" ".*inlined into frame.*" "outer_inline2 inlined"
ec0fcb6
-gdb_test "up" "#4  main.*" "up from outer_inline2"
ec0fcb6
-gdb_test "info frame" ".*\n caller of frame.*" "main not inlined"
ec0fcb6
+gdb_test "info frame" "inlined into frame.*" "inlined_fn from noinline inlined"
ec0fcb6
+gdb_test "fini" "" "up to noinline"
ec0fcb6
+gdb_test "info frame" "\n called by frame.*" "noinline from outer_inline1 not inlined"
ec0fcb6
+gdb_test "fini" "" "up to outer_inline1"
ec0fcb6
+gdb_test "info frame" "inlined into frame.*" "outer_inline1 inlined"
ec0fcb6
+gdb_test "fini" "" "up to outer_inline2"
ec0fcb6
+gdb_test "info frame" "inlined into frame.*" "outer_inline2 inlined"
ec0fcb6
+gdb_test "fini" "" "up from outer_inline2"
ec0fcb6
+gdb_test "info frame" " in main \[^\n\]*\n source language.*" "main not inlined"
e5611bf
Index: gdb-6.8.50.20090803/gdb/testsuite/gdb.opt/inline-locals.c
407ebe9
===================================================================
e5611bf
--- gdb-6.8.50.20090803.orig/gdb/testsuite/gdb.opt/inline-locals.c	2009-06-28 02:20:24.000000000 +0200
e5611bf
+++ gdb-6.8.50.20090803/gdb/testsuite/gdb.opt/inline-locals.c	2009-08-03 16:57:40.000000000 +0200
407ebe9
@@ -13,11 +13,16 @@
407ebe9
    You should have received a copy of the GNU General Public License
407ebe9
    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
407ebe9
 
407ebe9
-int x, y;
407ebe9
+/* VOLATILE forces all the inlining to happen as otherwise the whole program
407ebe9
+   gets optimized by CSE to just simple assignments of the results.  */
407ebe9
+volatile int x, y;
407ebe9
 volatile int result;
407ebe9
 volatile int *array_p;
407ebe9
 
407ebe9
-void bar(void);
407ebe9
+inline void bar(void)
407ebe9
+{
407ebe9
+  x += y; /* set breakpoint 1 here */
407ebe9
+}
407ebe9
 
407ebe9
 inline int func1(int arg1)
407ebe9
 {
e5611bf
Index: gdb-6.8.50.20090803/gdb/testsuite/gdb.opt/inline-locals.exp
407ebe9
===================================================================
e5611bf
--- gdb-6.8.50.20090803.orig/gdb/testsuite/gdb.opt/inline-locals.exp	2009-06-30 17:50:27.000000000 +0200
e5611bf
+++ gdb-6.8.50.20090803/gdb/testsuite/gdb.opt/inline-locals.exp	2009-08-03 16:57:40.000000000 +0200
407ebe9
@@ -77,6 +77,9 @@ if { ! $no_frames } {
407ebe9
 
407ebe9
 # Make sure that locals on the stack are found.  This is an array to
407ebe9
 # prevent it from living in a register.
407ebe9
+if [test_compiler_info "gcc-4-3-*"] {
407ebe9
+    setup_kfail *-*-* "gcc/debug.optimization"
407ebe9
+}
407ebe9
 gdb_test "print array\[0\]" "\\\$$decimal = 0" "print local (2)"
407ebe9
 
407ebe9
 if { ! $no_frames } {
407ebe9
@@ -115,4 +118,7 @@ if { ! $no_frames } {
407ebe9
     gdb_test "info locals" ".*arg2 = 184.*" "info locals above bar (3b)"
407ebe9
 }
407ebe9
 
407ebe9
+if [test_compiler_info "gcc-4-3-*"] {
407ebe9
+    setup_kfail *-*-* "gcc/debug.optimization"
407ebe9
+}
407ebe9
 gdb_test "print array\[0\]" "\\\$$decimal = 184" "print local (3)"
e5611bf
Index: gdb-6.8.50.20090803/gdb/frame.c
407ebe9
===================================================================
e5611bf
--- gdb-6.8.50.20090803.orig/gdb/frame.c	2009-08-03 15:56:08.000000000 +0200
e5611bf
+++ gdb-6.8.50.20090803/gdb/frame.c	2009-08-03 16:57:40.000000000 +0200
e5611bf
@@ -276,7 +276,7 @@ fprint_frame (struct ui_file *file, stru
407ebe9
 static struct frame_info *
407ebe9
 skip_inlined_frames (struct frame_info *frame)
407ebe9
 {
407ebe9
-  while (get_frame_type (frame) == INLINE_FRAME)
407ebe9
+  while (frame && get_frame_type (frame) == INLINE_FRAME)
407ebe9
     frame = get_prev_frame (frame);
407ebe9
 
407ebe9
   return frame;
e5611bf
@@ -1715,6 +1715,7 @@ get_frame_address_in_block (struct frame
ec0fcb6
 {
ec0fcb6
   /* A draft address.  */
ec0fcb6
   CORE_ADDR pc = get_frame_pc (this_frame);
ec0fcb6
+  struct thread_info *tp = inferior_thread ();
ec0fcb6
 
ec0fcb6
   struct frame_info *next_frame = this_frame->next;
ec0fcb6
 
e5611bf
@@ -1757,6 +1758,9 @@ get_frame_address_in_block (struct frame
ec0fcb6
      while in an inlined function, then the code address of the
ec0fcb6
      "calling" normal function should not be adjusted either.  */
ec0fcb6
 
ec0fcb6
+  if (tp->current_pc_is_notcurrent)
ec0fcb6
+    return pc - 1;
ec0fcb6
+
ec0fcb6
   while (get_frame_type (next_frame) == INLINE_FRAME)
ec0fcb6
     next_frame = next_frame->next;
ec0fcb6
 
e5611bf
@@ -1788,7 +1792,7 @@ find_frame_sal (struct frame_info *frame
ec0fcb6
 	sym = inline_skipped_symbol (inferior_ptid);
ec0fcb6
 
ec0fcb6
       init_sal (sal);
ec0fcb6
-      if (SYMBOL_LINE (sym) != 0)
ec0fcb6
+      if (sym != NULL && SYMBOL_LINE (sym) != 0)
ec0fcb6
 	{
ec0fcb6
 	  sal->symtab = SYMBOL_SYMTAB (sym);
ec0fcb6
 	  sal->line = SYMBOL_LINE (sym);
e5611bf
Index: gdb-6.8.50.20090803/gdb/breakpoint.c
407ebe9
===================================================================
e5611bf
--- gdb-6.8.50.20090803.orig/gdb/breakpoint.c	2009-08-03 16:56:10.000000000 +0200
e5611bf
+++ gdb-6.8.50.20090803/gdb/breakpoint.c	2009-08-03 17:19:24.000000000 +0200
e5611bf
@@ -60,6 +60,7 @@
407ebe9
 #include "wrapper.h"
407ebe9
 #include "valprint.h"
e5611bf
 #include "parser-defs.h"
407ebe9
+#include "inline-frame.h"
407ebe9
 
e5611bf
 /* readline include files */
e5611bf
 #include "readline/readline.h"
e5611bf
@@ -3065,10 +3066,24 @@ bpstat_check_breakpoint_conditions (bpst
ec0fcb6
   const struct bp_location *bl = bs->breakpoint_at;
ec0fcb6
   struct breakpoint *b = bl->owner;
ec0fcb6
 
ec0fcb6
-  if (frame_id_p (b->frame_id)
ec0fcb6
-      && !frame_id_eq (b->frame_id, get_stack_frame_id (get_current_frame ())))
ec0fcb6
-    bs->stop = 0;
ec0fcb6
-  else if (bs->stop)
ec0fcb6
+  if (frame_id_p (b->frame_id))
ec0fcb6
+    {
ec0fcb6
+      struct frame_info *b_frame, *frame;
ec0fcb6
+      struct frame_id b_frame_id, current_frame_id;
ec0fcb6
+
ec0fcb6
+      b_frame = frame_find_by_id (b->frame_id);
ec0fcb6
+
ec0fcb6
+      /* get_stack_frame_id normalizes the id to the real non-inlined function
ec0fcb6
+	 by skip_inlined_frames.  */
ec0fcb6
+      b_frame_id = get_stack_frame_id (b_frame);
ec0fcb6
+      current_frame_id = get_stack_frame_id (get_current_frame ());
ec0fcb6
+
ec0fcb6
+      /* Completely different (inlining notwithstanding) frames?  */
ec0fcb6
+      if (!frame_id_eq (b_frame_id, current_frame_id))
ec0fcb6
+	bs->stop = 0;
ec0fcb6
+    }
ec0fcb6
+
ec0fcb6
+  if (bs->stop)
ec0fcb6
     {
ec0fcb6
       int value_is_zero = 0;
ec0fcb6
       
e5611bf
@@ -3215,6 +3230,12 @@ bpstat_stop_status (CORE_ADDR bp_addr, p
407ebe9
 	    bs->print = 0;
407ebe9
 	  }
407ebe9
 	bs->commands = copy_command_lines (bs->commands);
407ebe9
+
407ebe9
+	/* Display the innermost inlined frame at a breakpont as it gives to
407ebe9
+	   most of the available information.  */
407ebe9
+	if (b->type != bp_until && b->type != bp_finish)
407ebe9
+	  while (inline_skipped_frames (ptid))
407ebe9
+	    step_into_inline_frame (ptid);
407ebe9
       }
407ebe9
 
407ebe9
     /* Print nothing for this entry if we dont stop or if we dont print.  */
e5611bf
@@ -5164,9 +5185,9 @@ set_momentary_breakpoint (struct gdbarch
ec0fcb6
 {
ec0fcb6
   struct breakpoint *b;
ec0fcb6
 
ec0fcb6
-  /* If FRAME_ID is valid, it should be a real frame, not an inlined
ec0fcb6
-     one.  */
ec0fcb6
-  gdb_assert (!frame_id_inlined_p (frame_id));
ec0fcb6
+  /* We can be returning even into an inline frame.  While finish_command will
ec0fcb6
+     shortcut the case of returning _from_ an inline frame we still may be
ec0fcb6
+     returning from non-inlined frame _to_ an inlined frame.  */
ec0fcb6
 
e5611bf
   b = set_raw_breakpoint (gdbarch, sal, type);
ec0fcb6
   b->enable_state = bp_enabled;
e5611bf
Index: gdb-6.8.50.20090803/gdb/inline-frame.c
407ebe9
===================================================================
e5611bf
--- gdb-6.8.50.20090803.orig/gdb/inline-frame.c	2009-06-28 02:20:22.000000000 +0200
e5611bf
+++ gdb-6.8.50.20090803/gdb/inline-frame.c	2009-08-03 16:57:40.000000000 +0200
e5611bf
@@ -195,6 +195,12 @@ inline_frame_sniffer (const struct frame
407ebe9
   if (frame_block == NULL)
407ebe9
     return 0;
407ebe9
 
407ebe9
+  /* For >=2 inlined functions SKIPPED_SYMBOL needs to be different after each
407ebe9
+     step_into_inline_frame call.  But skip_inline_frames is called only once
407ebe9
+     and thus SKIPPED_SYMBOL needs to be calculated by INLINE_FRAME_SNIFFER.  */
407ebe9
+  if (state)
407ebe9
+    state->skipped_symbol = NULL;
407ebe9
+
407ebe9
   /* Calculate DEPTH, the number of inlined functions at this
407ebe9
      location.  */
407ebe9
   depth = 0;
e5611bf
@@ -204,6 +210,10 @@ inline_frame_sniffer (const struct frame
407ebe9
       if (block_inlined_p (cur_block))
407ebe9
 	depth++;
407ebe9
 
407ebe9
+      if (state && depth == state->skipped_frames
407ebe9
+	  && state->skipped_symbol == NULL)
407ebe9
+	state->skipped_symbol = BLOCK_FUNCTION (cur_block);
407ebe9
+
407ebe9
       cur_block = BLOCK_SUPERBLOCK (cur_block);
407ebe9
     }
407ebe9
 
e5611bf
@@ -287,7 +297,6 @@ skip_inline_frames (ptid_t ptid)
407ebe9
 {
407ebe9
   CORE_ADDR this_pc;
407ebe9
   struct block *frame_block, *cur_block;
407ebe9
-  struct symbol *last_sym = NULL;
407ebe9
   int skip_count = 0;
407ebe9
   struct inline_state *state;
407ebe9
 
e5611bf
@@ -308,10 +317,7 @@ skip_inline_frames (ptid_t ptid)
407ebe9
 		 of BLOCK_START.  */
407ebe9
 	      if (BLOCK_START (cur_block) == this_pc
407ebe9
 		  || block_starting_point_at (this_pc, cur_block))
407ebe9
-		{
407ebe9
-		  skip_count++;
407ebe9
-		  last_sym = BLOCK_FUNCTION (cur_block);
407ebe9
-		}
407ebe9
+		skip_count++;
407ebe9
 	      else
407ebe9
 		break;
407ebe9
 	    }
e5611bf
@@ -323,7 +329,6 @@ skip_inline_frames (ptid_t ptid)
407ebe9
   state = allocate_inline_frame_state (ptid);
407ebe9
   state->skipped_frames = skip_count;
407ebe9
   state->saved_pc = this_pc;
407ebe9
-  state->skipped_symbol = last_sym;
407ebe9
 
407ebe9
   if (skip_count != 0)
407ebe9
     reinit_frame_cache ();
e5611bf
@@ -341,6 +346,23 @@ step_into_inline_frame (ptid_t ptid)
ec0fcb6
   reinit_frame_cache ();
ec0fcb6
 }
ec0fcb6
 
ec0fcb6
+/* Step out of an inlined function by hiding it.  */
ec0fcb6
+
ec0fcb6
+void
ec0fcb6
+step_out_of_inline_frame (ptid_t ptid)
ec0fcb6
+{
ec0fcb6
+  struct inline_state *state = find_inline_frame_state (ptid);
ec0fcb6
+
ec0fcb6
+  gdb_assert (state != NULL);
ec0fcb6
+
ec0fcb6
+  /* Simulate the caller adjustment.  */
ec0fcb6
+  if (state->skipped_frames == 0)
ec0fcb6
+    state->saved_pc--;
ec0fcb6
+
ec0fcb6
+  state->skipped_frames++;
ec0fcb6
+  reinit_frame_cache ();
ec0fcb6
+}
ec0fcb6
+
ec0fcb6
 /* Return the number of hidden functions inlined into the current
ec0fcb6
    frame.  */
ec0fcb6
 
e5611bf
Index: gdb-6.8.50.20090803/gdb/testsuite/gdb.opt/inline-markers.c
407ebe9
===================================================================
e5611bf
--- gdb-6.8.50.20090803.orig/gdb/testsuite/gdb.opt/inline-markers.c	2009-06-28 02:20:24.000000000 +0200
e5611bf
+++ gdb-6.8.50.20090803/gdb/testsuite/gdb.opt/inline-markers.c	2009-08-03 16:57:40.000000000 +0200
407ebe9
@@ -15,11 +15,6 @@
407ebe9
 
407ebe9
 extern int x, y;
407ebe9
 
407ebe9
-void bar(void)
407ebe9
-{
407ebe9
-  x += y; /* set breakpoint 1 here */
407ebe9
-}
407ebe9
-
407ebe9
 void marker(void)
407ebe9
 {
407ebe9
   x += y; /* set breakpoint 2 here */
e5611bf
Index: gdb-6.8.50.20090803/gdb/gdbthread.h
ec0fcb6
===================================================================
e5611bf
--- gdb-6.8.50.20090803.orig/gdb/gdbthread.h	2009-08-03 15:55:53.000000000 +0200
e5611bf
+++ gdb-6.8.50.20090803/gdb/gdbthread.h	2009-08-03 16:57:40.000000000 +0200
e5611bf
@@ -187,6 +187,12 @@ struct thread_info
ec0fcb6
 
ec0fcb6
   /* Private data used by the target vector implementation.  */
ec0fcb6
   struct private_thread_info *private;
ec0fcb6
+
ec0fcb6
+  /* Nonzero if the current frame PC should be unwound as the caller.  It is
ec0fcb6
+     used to keep the backtrace upper levels existing after finish_command into
ec0fcb6
+     an inlined frame if the current inlined function/block was ending at the
ec0fcb6
+     current PC.  */
ec0fcb6
+  int current_pc_is_notcurrent;
ec0fcb6
 };
ec0fcb6
 
ec0fcb6
 /* Create an empty thread list, or empty the existing one.  */
e5611bf
Index: gdb-6.8.50.20090803/gdb/infcmd.c
ec0fcb6
===================================================================
e5611bf
--- gdb-6.8.50.20090803.orig/gdb/infcmd.c	2009-07-02 23:57:27.000000000 +0200
e5611bf
+++ gdb-6.8.50.20090803/gdb/infcmd.c	2009-08-03 17:17:24.000000000 +0200
e5611bf
@@ -1408,11 +1408,11 @@ finish_command_continuation (void *arg)
ec0fcb6
       struct type *value_type;
ec0fcb6
 
ec0fcb6
       value_type = TYPE_TARGET_TYPE (SYMBOL_TYPE (a->function));
ec0fcb6
-      if (!value_type)
ec0fcb6
+      if (!SYMBOL_INLINED (a->function) && !value_type)
ec0fcb6
 	internal_error (__FILE__, __LINE__,
ec0fcb6
 			_("finish_command: function has no target type"));
ec0fcb6
 
ec0fcb6
-      if (TYPE_CODE (value_type) != TYPE_CODE_VOID)
ec0fcb6
+      if (value_type && TYPE_CODE (value_type) != TYPE_CODE_VOID)
ec0fcb6
 	print_return_value (SYMBOL_TYPE (a->function), value_type);
ec0fcb6
     }
ec0fcb6
 
e5611bf
@@ -1514,6 +1514,16 @@ finish_forward (struct symbol *function,
ec0fcb6
 
ec0fcb6
   old_chain = make_cleanup_delete_breakpoint (breakpoint);
ec0fcb6
 
ec0fcb6
+  /* We should _always_ set CURRENT_PC_IS_NOTCURRENT here to always see the
ec0fcb6
+     calling line with the message `Value returned is ...'.  Currently it is
ec0fcb6
+     seen only if at least one instruction is on that source line after the
ec0fcb6
+     call instruction.  We would also need to hook step_once and only clear
ec0fcb6
+     CURRENT_PC_IS_NOTCURRENT on the first step.  But it would be a change of
ec0fcb6
+     general non-inlining behavior against upstream.  */
ec0fcb6
+
ec0fcb6
+  if (get_frame_type (frame) == INLINE_FRAME)
ec0fcb6
+    tp->current_pc_is_notcurrent = 1;
ec0fcb6
+
ec0fcb6
   tp->proceed_to_finish = 1;    /* We want stop_registers, please...  */
e5611bf
   proceed ((CORE_ADDR) -1, TARGET_SIGNAL_DEFAULT, 0);
e5611bf
 
e5611bf
@@ -1535,7 +1545,9 @@ finish_forward (struct symbol *function,
ec0fcb6
 static void
ec0fcb6
 finish_command (char *arg, int from_tty)
ec0fcb6
 {
ec0fcb6
-  struct frame_info *frame;
ec0fcb6
+  /* FIXME: Rename `current_frame' to `frame' upon a merge.  */
ec0fcb6
+  struct frame_info *current_frame, *prev_frame;
ec0fcb6
+  CORE_ADDR frame_pc;
ec0fcb6
   struct symbol *function;
ec0fcb6
 
ec0fcb6
   int async_exec = 0;
e5611bf
@@ -1566,45 +1578,63 @@ finish_command (char *arg, int from_tty)
ec0fcb6
   if (!target_has_execution)
ec0fcb6
     error (_("The program is not running."));
ec0fcb6
 
ec0fcb6
-  frame = get_prev_frame (get_selected_frame (_("No selected frame.")));
ec0fcb6
-  if (frame == 0)
ec0fcb6
+  current_frame = get_selected_frame (_("No selected frame."));
ec0fcb6
+  frame_pc = get_frame_pc (current_frame);
ec0fcb6
+  prev_frame = get_prev_frame (current_frame);
ec0fcb6
+  if (prev_frame == 0)
ec0fcb6
     error (_("\"finish\" not meaningful in the outermost frame."));
ec0fcb6
 
ec0fcb6
-  clear_proceed_status ();
ec0fcb6
-
ec0fcb6
   /* Finishing from an inline frame is completely different.  We don't
ec0fcb6
      try to show the "return value" - no way to locate it.  So we do
ec0fcb6
      not need a completion.  */
ec0fcb6
-  if (get_frame_type (get_selected_frame (_("No selected frame.")))
ec0fcb6
-      == INLINE_FRAME)
ec0fcb6
+  if (get_frame_type (current_frame) == INLINE_FRAME)
ec0fcb6
     {
ec0fcb6
-      /* Claim we are stepping in the calling frame.  An empty step
ec0fcb6
-	 range means that we will stop once we aren't in a function
ec0fcb6
-	 called by that frame.  We don't use the magic "1" value for
ec0fcb6
-	 step_range_end, because then infrun will think this is nexti,
ec0fcb6
-	 and not step over the rest of this inlined function call.  */
e5611bf
       struct thread_info *tp = inferior_thread ();
ec0fcb6
       struct symtab_and_line empty_sal;
ec0fcb6
-      init_sal (&empty_sal);
e5611bf
-      set_step_info (frame, empty_sal);
ec0fcb6
-      tp->step_range_start = tp->step_range_end = get_frame_pc (frame);
ec0fcb6
-      tp->step_over_calls = STEP_OVER_ALL;
ec0fcb6
+      struct block *frame_block;
ec0fcb6
 
ec0fcb6
       /* Print info on the selected frame, including level number but not
ec0fcb6
 	 source.  */
ec0fcb6
       if (from_tty)
ec0fcb6
 	{
ec0fcb6
 	  printf_filtered (_("Run till exit from "));
ec0fcb6
-	  print_stack_frame (get_selected_frame (NULL), 1, LOCATION);
ec0fcb6
+	  print_stack_frame (current_frame, 1, LOCATION);
e5611bf
+	}
e5611bf
+
ec0fcb6
+      /* Even just a single stepi would get us out of the caller function PC
ec0fcb6
+	 range.  */
ec0fcb6
+
ec0fcb6
+      frame_block = get_frame_block (current_frame, NULL);
ec0fcb6
+
ec0fcb6
+      /* FRAME_BLOCK must be initialized and also the frame printing above must
ec0fcb6
+         be done still with the original CURRENT_PC_IS_NOTCURRENT setting.  */
ec0fcb6
+      clear_proceed_status ();
ec0fcb6
+
ec0fcb6
+      if (frame_block && BLOCK_END (frame_block) == frame_pc)
ec0fcb6
+	{
ec0fcb6
+	  step_out_of_inline_frame (tp->ptid);
ec0fcb6
+	  tp->current_pc_is_notcurrent = 1;
ec0fcb6
+	  normal_stop ();
ec0fcb6
+	  return;
e5611bf
 	}
e5611bf
 
ec0fcb6
+      /* Claim we are stepping in the calling frame.  An empty step
ec0fcb6
+	 range means that we will stop once we aren't in a function
ec0fcb6
+	 called by that frame.  We don't use the magic "1" value for
ec0fcb6
+	 step_range_end, because then infrun will think this is nexti,
ec0fcb6
+	 and not step over the rest of this inlined function call.  */
ec0fcb6
+      init_sal (&empty_sal);
e5611bf
+      set_step_info (prev_frame, empty_sal);
ec0fcb6
+      tp->step_range_start = tp->step_range_end = get_frame_pc (prev_frame);
ec0fcb6
+      tp->step_over_calls = STEP_OVER_ALL;
ec0fcb6
+
ec0fcb6
       proceed ((CORE_ADDR) -1, TARGET_SIGNAL_DEFAULT, 1);
ec0fcb6
       return;
ec0fcb6
     }
ec0fcb6
 
ec0fcb6
   /* Find the function we will return from.  */
ec0fcb6
 
ec0fcb6
-  function = find_pc_function (get_frame_pc (get_selected_frame (NULL)));
ec0fcb6
+  function = find_pc_function (frame_pc);
ec0fcb6
 
ec0fcb6
   /* Print info on the selected frame, including level number but not
ec0fcb6
      source.  */
e5611bf
@@ -1618,10 +1648,14 @@ finish_command (char *arg, int from_tty)
ec0fcb6
       print_stack_frame (get_selected_frame (NULL), 1, LOCATION);
ec0fcb6
     }
ec0fcb6
 
ec0fcb6
+  /* Frames printing above must be done still with the original
ec0fcb6
+     CURRENT_PC_IS_NOTCURRENT setting.  */
ec0fcb6
+  clear_proceed_status ();
ec0fcb6
+
ec0fcb6
   if (execution_direction == EXEC_REVERSE)
ec0fcb6
     finish_backward (function);
ec0fcb6
   else
ec0fcb6
-    finish_forward (function, frame);
ec0fcb6
+    finish_forward (function, prev_frame);
ec0fcb6
 }
ec0fcb6
 
ec0fcb6
 
e5611bf
Index: gdb-6.8.50.20090803/gdb/target.c
ec0fcb6
===================================================================
e5611bf
--- gdb-6.8.50.20090803.orig/gdb/target.c	2009-08-03 16:04:15.000000000 +0200
e5611bf
+++ gdb-6.8.50.20090803/gdb/target.c	2009-08-03 16:57:40.000000000 +0200
e5611bf
@@ -2079,6 +2079,7 @@ target_resume (ptid_t ptid, int step, en
81783d0
 {
1592379
   struct target_ops *t;
1592379
 
81783d0
+  clear_inline_frame_state (ptid);
81783d0
   dcache_invalidate (target_dcache);
1592379
 
1592379
   for (t = current_target.beneath; t != NULL; t = t->beneath)
e5611bf
Index: gdb-6.8.50.20090803/gdb/inline-frame.h
ec0fcb6
===================================================================
e5611bf
--- gdb-6.8.50.20090803.orig/gdb/inline-frame.h	2009-06-28 02:20:22.000000000 +0200
e5611bf
+++ gdb-6.8.50.20090803/gdb/inline-frame.h	2009-08-03 16:57:40.000000000 +0200
ec0fcb6
@@ -43,6 +43,10 @@ void clear_inline_frame_state (ptid_t pt
ec0fcb6
 
ec0fcb6
 void step_into_inline_frame (ptid_t ptid);
ec0fcb6
 
ec0fcb6
+/* Step out of an inlined function by hiding it.  */
ec0fcb6
+
ec0fcb6
+void step_out_of_inline_frame (ptid_t ptid);
ec0fcb6
+
ec0fcb6
 /* Return the number of hidden functions inlined into the current
ec0fcb6
    frame.  */
ec0fcb6
 
e5611bf
Index: gdb-6.8.50.20090803/gdb/dwarf2read.c
8dadf56
===================================================================
e5611bf
--- gdb-6.8.50.20090803.orig/gdb/dwarf2read.c	2009-08-03 16:56:10.000000000 +0200
e5611bf
+++ gdb-6.8.50.20090803/gdb/dwarf2read.c	2009-08-03 16:57:40.000000000 +0200
e5611bf
@@ -4107,6 +4107,7 @@ read_func_scope (struct die_info *die, s
e5611bf
   struct block *block;
e5611bf
   unsigned die_children = 0;
8dadf56
   int inlined_func = (die->tag == DW_TAG_inlined_subroutine);
8dadf56
+  struct type *type;
8dadf56
 
8dadf56
   if (inlined_func)
8dadf56
     {
e5611bf
@@ -4148,7 +4149,10 @@ read_func_scope (struct die_info *die, s
8dadf56
   add_to_cu_func_list (name, lowpc, highpc, cu);
8dadf56
 
8dadf56
   new = push_context (0, lowpc);
8dadf56
-  new->name = new_symbol (die, read_type_die (die, cu), cu);
8dadf56
+  type = read_type_die (die, cu);
8dadf56
+  gdb_assert (type != NULL);
8dadf56
+  new->name = new_symbol (die, type, cu);
8dadf56
+  gdb_assert (TYPE_CODE (SYMBOL_TYPE (new->name)) == TYPE_CODE_FUNC);
8dadf56
 
8dadf56
   /* If there is a location expression for DW_AT_frame_base, record
8dadf56
      it.  */