This is the mail archive of the gdb-patches@sourceware.org mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[patch 05/12] entryval#3: Self tail calls verification


Hi,

[patch 05/12] entryval#2: Self tail calls verification
http://sourceware.org/ml/gdb-patches/2011-09/msg00227.html

only some technical updates.


Thanks,
Jan


gdb/
2011-07-18  Jan Kratochvil  <jan.kratochvil@redhat.com>

	Protect entry values against self tail calls.
	* dwarf2loc.c (VEC (CORE_ADDR), func_verify_no_selftailcall): New.
	(dwarf_expr_dwarf_reg_entry_value): Call func_verify_no_selftailcall.

gdb/testsuite/
2011-07-18  Jan Kratochvil  <jan.kratochvil@redhat.com>

	Protect entry values against self tail calls.
	* gdb.arch/amd64-entry-value.cc (self2, self): New.
	(main): Call self.
	* gdb.arch/amd64-entry-value.exp (self: breakhere, self: bt)
	(set debug entry-values 1, self: bt debug entry-values): New tests.

--- a/gdb/dwarf2loc.c
+++ b/gdb/dwarf2loc.c
@@ -422,6 +422,87 @@ func_addr_to_tail_call_list (struct gdbarch *gdbarch, CORE_ADDR addr)
   return sym;
 }
 
+/* Define VEC (CORE_ADDR) functions.  */
+DEF_VEC_I (CORE_ADDR);
+
+/* Verify function with entry point exact address ADDR can never call itself
+   via its tail calls (incl. transitively).  Throw NO_ENTRY_VALUE_ERROR if it
+   can call itself via tail calls.
+
+   If a funtion can tail call itself its entry value based parameters are
+   unreliable.  There is no verification whether the value of some/all
+   parameters is unchanged through the self tail call, we expect if there is
+   a self tail call all the parameters can be modified.  */
+
+static void
+func_verify_no_selftailcall (struct gdbarch *gdbarch, CORE_ADDR verify_addr)
+{
+  struct obstack addr_obstack;
+  struct cleanup *old_chain;
+  CORE_ADDR addr;
+
+  /* Track here CORE_ADDRs which were already visited.  */
+  htab_t addr_hash;
+
+  /* The verification is completely unordered.  Track here function addresses
+     which still need to be iterated.  */
+  VEC (CORE_ADDR) *todo = NULL;
+
+  obstack_init (&addr_obstack);
+  old_chain = make_cleanup_obstack_free (&addr_obstack);   
+  addr_hash = htab_create_alloc_ex (64, core_addr_hash, core_addr_eq, NULL,
+				    &addr_obstack, hashtab_obstack_allocate,
+				    NULL);
+  make_cleanup_htab_delete (addr_hash);
+
+  make_cleanup (VEC_cleanup (CORE_ADDR), &todo);
+
+  VEC_safe_push (CORE_ADDR, todo, verify_addr);
+  while (!VEC_empty (CORE_ADDR, todo))
+    {
+      struct symbol *func_sym;
+      struct call_site *call_site;
+
+      addr = VEC_pop (CORE_ADDR, todo);
+
+      func_sym = func_addr_to_tail_call_list (gdbarch, addr);
+
+      for (call_site = TYPE_TAIL_CALL_LIST (SYMBOL_TYPE (func_sym));
+	   call_site; call_site = call_site->tail_call_next)
+	{
+	  CORE_ADDR target_addr;
+	  void **slot;
+
+	  /* CALLER_FRAME with registers is not available for tail-call jumped
+	     frames.  */
+	  target_addr = call_site_to_target_addr (gdbarch, call_site, NULL);
+
+	  if (target_addr == verify_addr)
+	    {
+	      struct minimal_symbol *msym;
+	      
+	      msym = lookup_minimal_symbol_by_pc (verify_addr);
+	      throw_error (NO_ENTRY_VALUE_ERROR,
+			   _("DW_OP_GNU_entry_value resolving has found "
+			     "function \"%s\" at %s can call itself via tail "
+			     "calls"),
+			   msym == NULL ? "???" : SYMBOL_PRINT_NAME (msym),
+			   paddress (gdbarch, verify_addr));
+	    }
+
+	  slot = htab_find_slot (addr_hash, &target_addr, INSERT);
+	  if (*slot == NULL)
+	    {
+	      *slot = obstack_copy (&addr_obstack, &target_addr,
+				    sizeof (target_addr));
+	      VEC_safe_push (CORE_ADDR, todo, target_addr);
+	    }
+	}
+    }
+
+  do_cleanups (old_chain);
+}
+
 /* Print user readable form of CALL_SITE->PC to gdb_stdlog.  Used only for
    ENTRY_VALUES_DEBUG.  */
 
@@ -780,6 +861,10 @@ dwarf_expr_reg_to_entry_parameter (struct frame_info *frame, int dwarf_reg,
 		   paddress (gdbarch, func_addr));
     }
 
+  /* No entry value based parameters would be reliable if this function can
+     call itself via tail calls.  */
+  func_verify_no_selftailcall (gdbarch, func_addr);
+
   for (iparams = 0; iparams < call_site->parameter_count; iparams++)
     {
       parameter = &call_site->parameter[iparams];
--- a/gdb/testsuite/gdb.arch/amd64-entry-value.cc
+++ b/gdb/testsuite/gdb.arch/amd64-entry-value.cc
@@ -91,6 +91,29 @@ amb_a (int i)
   amb_b (i + 1);
 }
 
+static void __attribute__((noinline, noclone)) self (int i);
+
+static void __attribute__((noinline, noclone))
+self2 (int i)
+{
+  self (i);
+}
+
+static void __attribute__((noinline, noclone))
+self (int i)
+{
+  if (i == 200)
+    {
+      /* GCC would inline `self' as `cmovne' without the `self2' indirect.  */
+      self2 (i + 1);
+    }
+  else
+    {
+      e (v, v);
+      d (i + 2, i + 2.5);
+    }
+}
+
 int
 main ()
 {
@@ -100,5 +123,6 @@ main ()
   else
     b (5, 5.25);
   amb_a (100);
+  self (200);
   return 0;
 }
--- a/gdb/testsuite/gdb.arch/amd64-entry-value.exp
+++ b/gdb/testsuite/gdb.arch/amd64-entry-value.exp
@@ -73,3 +73,16 @@ gdb_continue_to_breakpoint "ambiguous: breakhere"
 
 gdb_test "bt" "^bt\r\n#0 +d \\(i=<optimized out>, j=<optimized out>\\)\[^\r\n\]*\r\n#1 +0x\[0-9a-f\]+ in amb_z \\(i=<optimized out>\\)\[^\r\n\]*\r\n#2 +0x\[0-9a-f\]+ in amb_y \\(i=<optimized out>\\)\[^\r\n\]*\r\n#3 +0x\[0-9a-f\]+ in amb_x \\(i=<optimized out>\\)\[^\r\n\]*\r\n#4 +0x\[0-9a-f\]+ in amb_b \\(i=101\\)\[^\r\n\]*\r\n#5 +0x\[0-9a-f\]+ in amb_a \\(i=100\\)\[^\r\n\]*\r\n#6 +0x\[0-9a-f\]+ in main \\(\\)\[^\r\n\]*" \
 	 "ambiguous: bt"
+
+
+# Test self tail calls verification.
+# GDB should not print the real value as it is ambiguous.
+
+gdb_continue_to_breakpoint "self: breakhere"
+
+gdb_test "bt" "^bt\r\n#0 +d \\(i=<optimized out>, j=<optimized out>\\)\[^\r\n\]*\r\n#1 +0x\[0-9a-f\]+ in self \\(i=<optimized out>\\)\[^\r\n\]*\r\n#2 +0x\[0-9a-f\]+ in main \\(\\)\[^\r\n\]*" \
+	 "self: bt"
+
+gdb_test_no_output "set debug entry-values 1"
+gdb_test "bt" "DW_OP_GNU_entry_value resolving has found function \"self\\(int\\)\" at 0x\[0-9a-f\]+ can call itself via tail calls\r\n.*" \
+	 "self: bt debug entry-values"


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]