public inbox for gdb-patches@sourceware.org
 help / color / mirror / Atom feed
* [PATCH v2 4/9] compile: Support relocation to GNU-IFUNCs
  2015-04-06 17:26 [PATCH v2 0/9] compile: compile print&printf Jan Kratochvil
@ 2015-04-06 17:26 ` Jan Kratochvil
  2015-04-06 17:26 ` [PATCH v2 1/9] Code cleanup: Make parts of print_command_1 public Jan Kratochvil
                   ` (8 subsequent siblings)
  9 siblings, 0 replies; 30+ messages in thread
From: Jan Kratochvil @ 2015-04-06 17:26 UTC (permalink / raw)
  To: gdb-patches; +Cc: Phil Muldoon

The 'compile print' part disclosed that calling memcpy() may fail as memcpy()
from libc is GNU-IFUNC.

gdb/ChangeLog
2015-04-06  Jan Kratochvil  <jan.kratochvil@redhat.com>

	* compile/compile-object-load.c (compile_object_load): Support
	mst_text_gnu_ifunc.
---
 gdb/compile/compile-object-load.c |    4 ++++
 1 file changed, 4 insertions(+)

diff --git a/gdb/compile/compile-object-load.c b/gdb/compile/compile-object-load.c
index 70b2e2e..ed2cad4 100644
--- a/gdb/compile/compile-object-load.c
+++ b/gdb/compile/compile-object-load.c
@@ -555,6 +555,10 @@ compile_object_load (const char *object_file, const char *source_file,
 	case mst_text:
 	  sym->value = BMSYMBOL_VALUE_ADDRESS (bmsym);
 	  break;
+	case mst_text_gnu_ifunc:
+	  sym->value = gnu_ifunc_resolve_addr (target_gdbarch (),
+					       BMSYMBOL_VALUE_ADDRESS (bmsym));
+	  break;
 	default:
 	  warning (_("Could not find symbol \"%s\" "
 		     "for compiled module \"%s\"."),

^ permalink raw reply	[flat|nested] 30+ messages in thread

* [PATCH v2 0/9] compile: compile print&printf
@ 2015-04-06 17:26 Jan Kratochvil
  2015-04-06 17:26 ` [PATCH v2 4/9] compile: Support relocation to GNU-IFUNCs Jan Kratochvil
                   ` (9 more replies)
  0 siblings, 10 replies; 30+ messages in thread
From: Jan Kratochvil @ 2015-04-06 17:26 UTC (permalink / raw)
  To: gdb-patches; +Cc: Phil Muldoon

Hi,

GIT branch:
	https://github.com/tromey/gdb/tree/pmuldoon/compile/print


Jan

^ permalink raw reply	[flat|nested] 30+ messages in thread

* [PATCH v2 3/9] Code cleanup: compile: Constify some parameters
  2015-04-06 17:26 [PATCH v2 0/9] compile: compile print&printf Jan Kratochvil
                   ` (2 preceding siblings ...)
  2015-04-06 17:26 ` [PATCH v2 2/9] compile: Distribute scope, add scope_data Jan Kratochvil
@ 2015-04-06 17:26 ` Jan Kratochvil
  2015-04-06 17:27 ` [PATCH v2 7/9] compile: New 'compile print' Jan Kratochvil
                   ` (5 subsequent siblings)
  9 siblings, 0 replies; 30+ messages in thread
From: Jan Kratochvil @ 2015-04-06 17:26 UTC (permalink / raw)
  To: gdb-patches; +Cc: Phil Muldoon

gdb/ChangeLog
2015-03-26  Jan Kratochvil  <jan.kratochvil@redhat.com>

	* compile/compile.c (compile_to_object): Make the cmd_string parameter
	const.  Use new variables for the const compatibility.
	(eval_compile_command): Make the cmd_string parameter const.
	* compile/compile.h (eval_compile_command): Make the cmd_string
	parameter const.
---
 gdb/compile/compile.c |   15 +++++++++------
 gdb/compile/compile.h |    3 ++-
 2 files changed, 11 insertions(+), 7 deletions(-)

diff --git a/gdb/compile/compile.c b/gdb/compile/compile.c
index 3cbbc29..621de66 100644
--- a/gdb/compile/compile.c
+++ b/gdb/compile/compile.c
@@ -415,11 +415,12 @@ print_callback (void *ignore, const char *message)
    freeing both strings.  */
 
 static char *
-compile_to_object (struct command_line *cmd, char *cmd_string,
+compile_to_object (struct command_line *cmd, const char *cmd_string,
 		   enum compile_i_scope_types scope,
 		   char **source_filep)
 {
   char *code;
+  const char *input;
   char *source_file, *object_file;
   struct compile_instance *compiler;
   struct cleanup *cleanup, *inner_cleanup;
@@ -459,6 +460,7 @@ compile_to_object (struct command_line *cmd, char *cmd_string,
     {
       struct ui_file *stream = mem_fileopen ();
       struct command_line *iter;
+      char *stream_buf;
 
       make_cleanup_ui_file_delete (stream);
       for (iter = cmd->body_list[0]; iter; iter = iter->next)
@@ -467,15 +469,16 @@ compile_to_object (struct command_line *cmd, char *cmd_string,
 	  fputs_unfiltered ("\n", stream);
 	}
 
-      code = ui_file_xstrdup (stream, NULL);
-      make_cleanup (xfree, code);
+      stream_buf = ui_file_xstrdup (stream, NULL);
+      make_cleanup (xfree, stream_buf);
+      input = stream_buf;
     }
   else if (cmd_string != NULL)
-    code = cmd_string;
+    input = cmd_string;
   else
     error (_("Neither a simple expression, or a multi-line specified."));
 
-  code = current_language->la_compute_program (compiler, code, gdbarch,
+  code = current_language->la_compute_program (compiler, input, gdbarch,
 					       expr_block, expr_pc);
   make_cleanup (xfree, code);
   if (compile_debug)
@@ -556,7 +559,7 @@ compile_command (char *args, int from_tty)
 /* See compile.h.  */
 
 void
-eval_compile_command (struct command_line *cmd, char *cmd_string,
+eval_compile_command (struct command_line *cmd, const char *cmd_string,
 		      enum compile_i_scope_types scope, void *scope_data)
 {
   char *object_file, *source_file;
diff --git a/gdb/compile/compile.h b/gdb/compile/compile.h
index 93c4786..a973167 100644
--- a/gdb/compile/compile.h
+++ b/gdb/compile/compile.h
@@ -28,7 +28,8 @@ struct dynamic_prop;
    expression command.  GDB returns either a CMD, or a CMD_STRING, but
    never both.  */
 
-extern void eval_compile_command (struct command_line *cmd, char *cmd_string,
+extern void eval_compile_command (struct command_line *cmd,
+				  const char *cmd_string,
 				  enum compile_i_scope_types scope,
 				  void *scope_data);
 

^ permalink raw reply	[flat|nested] 30+ messages in thread

* [PATCH v2 1/9] Code cleanup: Make parts of print_command_1 public
  2015-04-06 17:26 [PATCH v2 0/9] compile: compile print&printf Jan Kratochvil
  2015-04-06 17:26 ` [PATCH v2 4/9] compile: Support relocation to GNU-IFUNCs Jan Kratochvil
@ 2015-04-06 17:26 ` Jan Kratochvil
  2015-04-06 17:26 ` [PATCH v2 2/9] compile: Distribute scope, add scope_data Jan Kratochvil
                   ` (7 subsequent siblings)
  9 siblings, 0 replies; 30+ messages in thread
From: Jan Kratochvil @ 2015-04-06 17:26 UTC (permalink / raw)
  To: gdb-patches; +Cc: Phil Muldoon

The later 'compile print' command should share its behavior with the existing
'print' command.  Make the needed existing parts of print_command_1 public.

gdb/ChangeLog
2015-03-26  Jan Kratochvil  <jan.kratochvil@redhat.com>

	* printcmd.c (print_command_parse_format, print_value): New functions
	from ...
	(print_command_1): ... here.  Call them.
	* valprint.h (struct format_data, print_command_parse_format)
	(print_value): New declarations.
---
 gdb/printcmd.c |   89 +++++++++++++++++++++++++++++++++-----------------------
 gdb/valprint.h |    5 +++
 2 files changed, 58 insertions(+), 36 deletions(-)

diff --git a/gdb/printcmd.c b/gdb/printcmd.c
index deb501a..d89e6df 100644
--- a/gdb/printcmd.c
+++ b/gdb/printcmd.c
@@ -939,6 +939,56 @@ validate_format (struct format_data fmt, const char *cmdname)
 	   fmt.format, cmdname);
 }
 
+/* Parse print command format string and update *EXPP, return it allocated,
+   caller has to call xfree for it.  Return NULL if no format string has been
+   found.  CMDNAME should name the current command.  */
+
+struct format_data *
+print_command_parse_format (const char **expp, const char *cmdname)
+{
+  struct format_data *fmtp;
+  const char *exp = *expp;
+  struct cleanup *cleanup;
+
+  if (exp == NULL || *exp != '/')
+    return NULL;
+  exp++;
+
+  fmtp = xmalloc (sizeof (*fmtp));
+  cleanup = make_cleanup (xfree, fmtp);
+  *fmtp = decode_format (&exp, last_format, 0);
+  validate_format (*fmtp, cmdname);
+  last_format = fmtp->format;
+
+  discard_cleanups (cleanup);
+  *expp = exp;
+  return fmtp;
+}
+
+
+/* Print VAL to console, including recording it to the history.  */
+
+void
+print_value (struct value *val, const struct format_data *fmtp)
+{
+  struct value_print_options opts;
+  int histindex = record_latest_value (val);
+
+  annotate_value_history_begin (histindex, value_type (val));
+
+  printf_filtered ("$%d = ", histindex);
+
+  annotate_value_history_value ();
+
+  get_formatted_print_options (&opts, (fmtp == NULL ? 0 : fmtp->format));
+  opts.raw = (fmtp == NULL ? 0 : fmtp->raw);
+
+  print_formatted (val, (fmtp == NULL ? 0 : fmtp->size), &opts, gdb_stdout);
+  printf_filtered ("\n");
+
+  annotate_value_history_end ();
+}
+
 /* Evaluate string EXP as an expression in the current language and
    print the resulting value.  EXP may contain a format specifier as the
    first argument ("/x myvar" for example, to print myvar in hex).  */
@@ -947,25 +997,9 @@ static void
 print_command_1 (const char *exp, int voidprint)
 {
   struct expression *expr;
-  struct cleanup *old_chain = make_cleanup (null_cleanup, NULL);
-  char format = 0;
   struct value *val;
-  struct format_data fmt;
-
-  if (exp && *exp == '/')
-    {
-      exp++;
-      fmt = decode_format (&exp, last_format, 0);
-      validate_format (fmt, "print");
-      last_format = format = fmt.format;
-    }
-  else
-    {
-      fmt.count = 1;
-      fmt.format = 0;
-      fmt.size = 0;
-      fmt.raw = 0;
-    }
+  struct format_data *fmtp = print_command_parse_format (&exp, "print");
+  struct cleanup *old_chain = make_cleanup (xfree, fmtp);
 
   if (exp && *exp)
     {
@@ -978,24 +1012,7 @@ print_command_1 (const char *exp, int voidprint)
 
   if (voidprint || (val && value_type (val) &&
 		    TYPE_CODE (value_type (val)) != TYPE_CODE_VOID))
-    {
-      struct value_print_options opts;
-      int histindex = record_latest_value (val);
-
-      annotate_value_history_begin (histindex, value_type (val));
-
-      printf_filtered ("$%d = ", histindex);
-
-      annotate_value_history_value ();
-
-      get_formatted_print_options (&opts, format);
-      opts.raw = fmt.raw;
-
-      print_formatted (val, fmt.size, &opts, gdb_stdout);
-      printf_filtered ("\n");
-
-      annotate_value_history_end ();
-    }
+    print_value (val, fmtp);
 
   do_cleanups (old_chain);
 }
diff --git a/gdb/valprint.h b/gdb/valprint.h
index e3d0137..3ab531f 100644
--- a/gdb/valprint.h
+++ b/gdb/valprint.h
@@ -217,4 +217,9 @@ extern void output_command_const (const char *args, int from_tty);
 
 extern int val_print_scalar_type_p (struct type *type);
 
+struct format_data;
+extern struct format_data *print_command_parse_format (const char **expp,
+						       const char *cmdname);
+extern void print_value (struct value *val, const struct format_data *fmtp);
+
 #endif

^ permalink raw reply	[flat|nested] 30+ messages in thread

* [PATCH v2 2/9] compile: Distribute scope, add scope_data
  2015-04-06 17:26 [PATCH v2 0/9] compile: compile print&printf Jan Kratochvil
  2015-04-06 17:26 ` [PATCH v2 4/9] compile: Support relocation to GNU-IFUNCs Jan Kratochvil
  2015-04-06 17:26 ` [PATCH v2 1/9] Code cleanup: Make parts of print_command_1 public Jan Kratochvil
@ 2015-04-06 17:26 ` Jan Kratochvil
  2015-04-06 17:26 ` [PATCH v2 3/9] Code cleanup: compile: Constify some parameters Jan Kratochvil
                   ` (6 subsequent siblings)
  9 siblings, 0 replies; 30+ messages in thread
From: Jan Kratochvil @ 2015-04-06 17:26 UTC (permalink / raw)
  To: gdb-patches; +Cc: Phil Muldoon

Provide a way to access current 'scope' during struct the do_module_cleanup
stage and associate more data with it.

It should be all sub-classed but AFAIK GDB does not require C++ compiler yet.

gdb/ChangeLog
2015-04-06  Jan Kratochvil  <jan.kratochvil@redhat.com>

	* cli/cli-script.c (execute_control_command): Update
	eval_compile_command caller.
	* compile/compile-object-load.c (compile_object_load): Add parameters
	scope and scope_data.  Set them.
	* compile/compile-object-load.h (struct compile_module): Add fields
	scope and scope_data.
	(compile_object_load): Add parameters scope and scope_data.
	* compile/compile-object-run.c (struct do_module_cleanup): Add fields
	scope and scope_data.
	(compile_object_run): Propage the fields scope and scope_data.
	* compile/compile.c (compile_file_command, compile_code_command):
	Update eval_compile_command callers.
	(eval_compile_command): Add parameter scope_data.  Pass it plus scope.
	* compile/compile.h (eval_compile_command): Add parameter scope_data.
	* defs.h (struct command_line): Add field scope_data.
---
 gdb/cli/cli-script.c              |    3 ++-
 gdb/compile/compile-object-load.c |    5 ++++-
 gdb/compile/compile-object-load.h |   10 +++++++++-
 gdb/compile/compile-object-run.c  |    6 ++++++
 gdb/compile/compile.c             |    9 +++++----
 gdb/compile/compile.h             |    3 ++-
 gdb/defs.h                        |    1 +
 7 files changed, 29 insertions(+), 8 deletions(-)

diff --git a/gdb/cli/cli-script.c b/gdb/cli/cli-script.c
index 7a4ed78..4bd18a7 100644
--- a/gdb/cli/cli-script.c
+++ b/gdb/cli/cli-script.c
@@ -615,7 +615,8 @@ execute_control_command (struct command_line *cmd)
       }
 
     case compile_control:
-      eval_compile_command (cmd, NULL, cmd->control_u.compile.scope);
+      eval_compile_command (cmd, NULL, cmd->control_u.compile.scope,
+			    cmd->control_u.compile.scope_data);
       ret = simple_control;
       break;
 
diff --git a/gdb/compile/compile-object-load.c b/gdb/compile/compile-object-load.c
index 8a7f232..70b2e2e 100644
--- a/gdb/compile/compile-object-load.c
+++ b/gdb/compile/compile-object-load.c
@@ -464,7 +464,8 @@ store_regs (struct type *regs_type, CORE_ADDR regs_base)
    function returns.  */
 
 struct compile_module *
-compile_object_load (const char *object_file, const char *source_file)
+compile_object_load (const char *object_file, const char *source_file,
+		     enum compile_i_scope_types scope, void *scope_data)
 {
   struct cleanup *cleanups, *cleanups_free_objfile;
   bfd *abfd;
@@ -587,5 +588,7 @@ compile_object_load (const char *object_file, const char *source_file)
   retval->source_file = xstrdup (source_file);
   retval->func_addr = func_addr;
   retval->regs_addr = regs_addr;
+  retval->scope = scope;
+  retval->scope_data = scope_data;
   return retval;
 }
diff --git a/gdb/compile/compile-object-load.h b/gdb/compile/compile-object-load.h
index bef575e..4f9493b 100644
--- a/gdb/compile/compile-object-load.h
+++ b/gdb/compile/compile-object-load.h
@@ -31,9 +31,17 @@ struct compile_module
   /* Inferior registers address or NULL if the inferior function does not
      require any.  */
   CORE_ADDR regs_addr;
+
+  /* The "scope" of this compilation.  */
+  enum compile_i_scope_types scope;
+
+  /* User data for SCOPE in use.  */
+  void *scope_data;
 };
 
 extern struct compile_module *compile_object_load (const char *object_file,
-						   const char *source_file);
+						   const char *source_file,
+					       enum compile_i_scope_types scope,
+						   void *scope_data);
 
 #endif /* GDB_COMPILE_OBJECT_LOAD_H */
diff --git a/gdb/compile/compile-object-run.c b/gdb/compile/compile-object-run.c
index 6738aad..bfd2473 100644
--- a/gdb/compile/compile-object-run.c
+++ b/gdb/compile/compile-object-run.c
@@ -36,6 +36,10 @@ struct do_module_cleanup
   /* .c file OBJFILE was built from.  It needs to be xfree-d.  */
   char *source_file;
 
+  /* Copy from struct compile_module.  */
+  enum compile_i_scope_types scope;
+  void *scope_data;
+
   /* objfile_name of our objfile.  */
   char objfile_name_string[1];
 };
@@ -96,6 +100,8 @@ compile_object_run (struct compile_module *module)
   data->executedp = &executed;
   data->source_file = xstrdup (module->source_file);
   strcpy (data->objfile_name_string, objfile_name_s);
+  data->scope = module->scope;
+  data->scope_data = module->scope_data;
 
   xfree (module->source_file);
   xfree (module);
diff --git a/gdb/compile/compile.c b/gdb/compile/compile.c
index 90cfc36..3cbbc29 100644
--- a/gdb/compile/compile.c
+++ b/gdb/compile/compile.c
@@ -117,7 +117,7 @@ compile_file_command (char *arg, int from_tty)
   make_cleanup (xfree, arg);
   buffer = xstrprintf ("#include \"%s\"\n", arg);
   make_cleanup (xfree, buffer);
-  eval_compile_command (NULL, buffer, scope);
+  eval_compile_command (NULL, buffer, scope, NULL);
   do_cleanups (cleanup);
 }
 
@@ -150,7 +150,7 @@ compile_code_command (char *arg, int from_tty)
     }
 
   if (arg && *arg)
-      eval_compile_command (NULL, arg, scope);
+    eval_compile_command (NULL, arg, scope, NULL);
   else
     {
       struct command_line *l = get_command_line (compile_control, "");
@@ -557,7 +557,7 @@ compile_command (char *args, int from_tty)
 
 void
 eval_compile_command (struct command_line *cmd, char *cmd_string,
-		      enum compile_i_scope_types scope)
+		      enum compile_i_scope_types scope, void *scope_data)
 {
   char *object_file, *source_file;
 
@@ -571,7 +571,8 @@ eval_compile_command (struct command_line *cmd, char *cmd_string,
       make_cleanup (xfree, source_file);
       cleanup_unlink = make_cleanup (cleanup_unlink_file, object_file);
       make_cleanup (cleanup_unlink_file, source_file);
-      compile_module = compile_object_load (object_file, source_file);
+      compile_module = compile_object_load (object_file, source_file,
+					    scope, scope_data);
       discard_cleanups (cleanup_unlink);
       do_cleanups (cleanup_xfree);
       compile_object_run (compile_module);
diff --git a/gdb/compile/compile.h b/gdb/compile/compile.h
index 1e3f934..93c4786 100644
--- a/gdb/compile/compile.h
+++ b/gdb/compile/compile.h
@@ -29,7 +29,8 @@ struct dynamic_prop;
    never both.  */
 
 extern void eval_compile_command (struct command_line *cmd, char *cmd_string,
-				  enum compile_i_scope_types scope);
+				  enum compile_i_scope_types scope,
+				  void *scope_data);
 
 /* Compile a DWARF location expression to C, suitable for use by the
    compiler.
diff --git a/gdb/defs.h b/gdb/defs.h
index 72512f6..6476f80 100644
--- a/gdb/defs.h
+++ b/gdb/defs.h
@@ -400,6 +400,7 @@ struct command_line
 	struct
 	  {
 	    enum compile_i_scope_types scope;
+	    void *scope_data;
 	  }
 	compile;
       }

^ permalink raw reply	[flat|nested] 30+ messages in thread

* [PATCH v2 8/9] compile: New compile printf
  2015-04-06 17:26 [PATCH v2 0/9] compile: compile print&printf Jan Kratochvil
                   ` (6 preceding siblings ...)
  2015-04-06 17:27 ` [PATCH v2 9/9] compile: compile printf: gdbserver support Jan Kratochvil
@ 2015-04-06 17:27 ` Jan Kratochvil
  2015-04-06 17:27 ` [PATCH v2 6/9] Code cleanup: compile: func_addr -> func_sym Jan Kratochvil
  2015-04-11 19:46 ` obsolete: [PATCH v2 0/9] compile: compile print&printf Jan Kratochvil
  9 siblings, 0 replies; 30+ messages in thread
From: Jan Kratochvil @ 2015-04-06 17:27 UTC (permalink / raw)
  To: gdb-patches; +Cc: Phil Muldoon

Hi,

command naming needs to follow what gets decided for 'compile print'.

This part sends the output to inferior stdout, only the next patch will
redirect it to GDB (so that for example it works for remote gdbserver).

It cannot work for core files as one cannot execute inferior code there.
There were some ideas such as compiling the entered sources into GCC
intermediate form (GIMPLE?) and interpret it by GDB on top of the core file.
That would be much more complicated, this implementation is made according to
Phil's specification.

Besides existing
	(gdb) set compile-args
there will be now also:
	(gdb) set compile-printf-args
Maybe it would be worth to start some set sub-category 'compile' such as:
	(gdb) set compile args
	(gdb) set compile printf-args
That would mean the whole process of deprecating 'set compile-args' etc.


Jan


gdb/ChangeLog
2015-04-06  Jan Kratochvil  <jan.kratochvil@redhat.com>

	* compile/compile-c-support.c (add_code_header, add_code_footer)
	(c_compute_program): Add COMPILE_I_PRINTF_SCOPE.
	* compile/compile-object-load.c (get_regs_type): Verify 2nd parameter
	type.
	(compile_object_load): Add COMPILE_I_PRINTF_SCOPE.
	* compile/compile.c (compile_print_command): Rename to ...
	(compile_print): ... here.
	(compile_print_command, compile_printf_command, compile_printf_args)
	(compile_printf_args_argv, set_compile_printf_args)
	(show_compile_printf_args): New.
	(get_args): Add COMPILE_I_PRINTF_SCOPE support.
	(_initialize_compile): Install compile_printf_command,
	set_compile_printf_args and show_compile_printf_args.  Set default
	COMPILE_PRINTF_ARGS.
	* defs.h (enum compile_i_scope_types): Add COMPILE_I_PRINTF_SCOPE.

gdb/doc/ChangeLog
2015-04-06  Jan Kratochvil  <jan.kratochvil@redhat.com>

	* gdb.texinfo (Compiling and Injecting Code): Add compile printf.

gdb/testsuite/ChangeLog
2015-04-06  Jan Kratochvil  <jan.kratochvil@redhat.com>

	* gdb.compile/compile-print.exp (compile printf "0x%x\n", varint)
	(compile printf "0x%x\n"): New.

diff --git a/gdb/compile/compile-c-support.c b/gdb/compile/compile-c-support.c
index 86b02cf..92c41b6 100644
--- a/gdb/compile/compile-c-support.c
+++ b/gdb/compile/compile-c-support.c
@@ -206,7 +206,17 @@ add_code_header (enum compile_i_scope_types type, struct ui_file *buf)
 			") {\n",
 			buf);
       break;
-
+    case COMPILE_I_PRINTF_SCOPE:
+      fputs_unfiltered ("#include <stdio.h>\n"
+			"void "
+			GCC_FE_WRAPPER_FUNCTION
+			" (struct "
+			COMPILE_I_SIMPLE_REGISTER_STRUCT_TAG
+			" *"
+			COMPILE_I_SIMPLE_REGISTER_ARG_NAME
+			") {\n",
+			buf);
+      break;
     case COMPILE_I_RAW_SCOPE:
       break;
     default:
@@ -226,6 +236,7 @@ add_code_footer (enum compile_i_scope_types type, struct ui_file *buf)
     case COMPILE_I_SIMPLE_SCOPE:
     case COMPILE_I_PRINT_ADDRESS_SCOPE:
     case COMPILE_I_PRINT_VALUE_SCOPE:
+    case COMPILE_I_PRINTF_SCOPE:
       fputs_unfiltered ("}\n", buf);
       break;
     case COMPILE_I_RAW_SCOPE:
@@ -390,7 +401,8 @@ c_compute_program (struct compile_instance *inst,

   if (inst->scope == COMPILE_I_SIMPLE_SCOPE
       || inst->scope == COMPILE_I_PRINT_ADDRESS_SCOPE
-      || inst->scope == COMPILE_I_PRINT_VALUE_SCOPE)
+      || inst->scope == COMPILE_I_PRINT_VALUE_SCOPE
+      || inst->scope == COMPILE_I_PRINTF_SCOPE)
     {
       ui_file_put (var_stream, ui_file_write_for_put, buf);
       fputs_unfiltered ("#pragma GCC user_expression\n", buf);
@@ -418,6 +430,11 @@ c_compute_program (struct compile_instance *inst,
 			  (inst->scope == COMPILE_I_PRINT_ADDRESS_SCOPE
 			   ? "&" : ""));
       break;
+    case COMPILE_I_PRINTF_SCOPE:
+      fprintf_unfiltered (buf,
+"printf (%s);\n"
+			  , input);
+      break;
     default:
       fputs_unfiltered (input, buf);
       break;
diff --git a/gdb/compile/compile-object-load.c b/gdb/compile/compile-object-load.c
index e67e5ba..bc74590 100644
--- a/gdb/compile/compile-object-load.c
+++ b/gdb/compile/compile-object-load.c
@@ -470,7 +470,7 @@ static struct type *
 get_regs_type (struct symbol *func_sym, struct objfile *objfile)
 {
   struct type *func_type = SYMBOL_TYPE (func_sym);
-  struct type *regsp_type, *regs_type;
+  struct type *regsp_type, *regs_type, *void_type, *voidp_type;

   /* No register parameter present.  */
   if (TYPE_NFIELDS (func_type) == 0)
@@ -490,6 +490,18 @@ get_regs_type (struct symbol *func_sym, struct objfile *objfile)
 	   TYPE_CODE (regs_type), GCC_FE_WRAPPER_FUNCTION,
 	   objfile_name (objfile));

+  /* No register parameter present.  */
+  if (TYPE_NFIELDS (func_type) == 1)
+    return regs_type;
+
+  void_type = builtin_type (target_gdbarch ())->builtin_void;
+  voidp_type = lookup_pointer_type (void_type);
+  if (!types_deeply_equal (voidp_type, TYPE_FIELD_TYPE (func_type, 1)))
+    error (_("Invalid type of function \"%s\" parameter \"%s\" in compiled "
+	    "module \"%s\"."),
+	  GCC_FE_WRAPPER_FUNCTION, COMPILE_I_PRINT_OUT_ARG,
+	  objfile_name (objfile));
+
   return regs_type;
 }

@@ -637,6 +649,10 @@ compile_object_load (const char *object_file, const char *source_file,
       expect_parameters = 2;
       expect_return_type = builtin_type (target_gdbarch ())->builtin_void;
       break;
+    case COMPILE_I_PRINTF_SCOPE:
+      expect_parameters = 1;
+      expect_return_type = builtin_type (target_gdbarch ())->builtin_void;
+      break;
     default:
       internal_error (__FILE__, __LINE__, _("invalid scope %d"), scope);
     }
diff --git a/gdb/compile/compile.c b/gdb/compile/compile.c
index c4b8f2e..6bbe8df 100644
--- a/gdb/compile/compile.c
+++ b/gdb/compile/compile.c
@@ -174,17 +174,14 @@ compile_print_value (struct value *val, void *data_voidp)
   print_value (val, fmtp);
 }

-/* Handle the input from the 'compile print' command.  The "compile
-   print" command is used to evaluate and print an expression that may
-   contain calls to the GCC compiler.  The language expected in this
-   compile command is the language currently set in GDB.  */
+/* Implement 'compile print' and 'compile printf' command according
+   to SCOPE.  */

 static void
-compile_print_command (char *arg_param, int from_tty)
+compile_print (char *arg_param, enum compile_i_scope_types scope)
 {
   const char *arg = arg_param;
   struct cleanup *cleanup;
-  enum compile_i_scope_types scope = COMPILE_I_PRINT_ADDRESS_SCOPE;
   struct format_data *fmtp;

   cleanup = make_cleanup_restore_integer (&interpreter_async);
@@ -207,6 +204,25 @@ compile_print_command (char *arg_param, int from_tty)
   do_cleanups (cleanup);
 }

+/* Handle the input from the 'compile print' command.  The "compile
+   print" command is used to evaluate and print an expression that may
+   contain calls to the GCC compiler.  The language expected in this
+   compile command is the language currently set in GDB.  */
+
+static void
+compile_print_command (char *arg, int from_tty)
+{
+  compile_print (arg, COMPILE_I_PRINT_ADDRESS_SCOPE);
+}
+
+/* Handle the input from the 'compile printf' command.  */
+
+static void
+compile_printf_command (char *arg, int from_tty)
+{
+  compile_print (arg, COMPILE_I_PRINTF_SCOPE);
+}
+
 /* A cleanup function to remove a directory and all its contents.  */

 static void
@@ -308,6 +324,14 @@ static char *compile_args;
 static int compile_args_argc;
 static char **compile_args_argv;

+/* String for 'set compile-printf-args' and 'show compile-printf-args'.  */
+static char *compile_printf_args;
+
+/* Parsed form of COMPILE_PRINTF_ARGS.
+   COMPILE_PRINTF_ARGS_ARGV is NULL terminated.  */
+static int compile_printf_args_argc;
+static char **compile_printf_args_argv;
+
 /* Implement 'set compile-args'.  */

 static void
@@ -328,6 +352,27 @@ show_compile_args (struct ui_file *file, int from_tty,
 		    value);
 }

+/* Implement 'set compile-printf-args'.  */
+
+static void
+set_compile_printf_args (char *args, int from_tty, struct cmd_list_element *c)
+{
+  freeargv (compile_printf_args_argv);
+  build_argc_argv (compile_printf_args,
+		   &compile_printf_args_argc, &compile_printf_args_argv);
+}
+
+/* Implement 'show compile-printf-args'.  */
+
+static void
+show_compile_printf_args (struct ui_file *file, int from_tty,
+		   struct cmd_list_element *c, const char *value)
+{
+  fprintf_filtered (file, _("Compile printf command command-line arguments "
+			    "are \"%s\".\n"),
+		    value);
+}
+
 /* Append ARGC and ARGV (as parsed by build_argc_argv) to *ARGCP and *ARGVP.
    ARGCP+ARGVP can be zero+NULL and also ARGC+ARGV can be zero+NULL.  */

@@ -422,6 +467,10 @@ get_args (const struct compile_instance *compiler, struct gdbarch *gdbarch,
   freeargv (argv_compiler);

   append_args (argcp, argvp, compile_args_argc, compile_args_argv);
+
+  if (compiler->scope == COMPILE_I_PRINTF_SCOPE)
+    append_args (argcp, argvp,
+		 compile_printf_args_argc, compile_printf_args_argv);
 }

 /* A cleanup function to destroy a gdb_gcc_instance.  */
@@ -727,6 +776,24 @@ EXPR may be preceded with /FMT, where FMT is a format letter\n\
 but no count or size letter (see \"x\" command)."),
 	   &compile_command_list);

+  add_cmd ("printf", class_obscure, compile_printf_command,
+	   _("\
+Print formatted output with the compiler.\n\
+\n\
+Usage: compile printf \"printf format string\", arg1, arg2, arg3, ..., argn\n\
+\n\
+The arguments may be specified on the same line as the command, e.g.:\n\
+\n\
+    compile printf \"%d\\n\", i\n\
+\n\
+Alternatively, you can type the arguments interactively.\n\
+You can invoke this mode when no argument is given to the command\n\
+(i.e., \"compile printf\" is typed with nothing after it).  An\n\
+interactive prompt will be shown allowing you to enter multiple\n\
+lines of source code.  Type a line containing \"end\" to indicate\n\
+the end of the source code."),
+	   &compile_command_list);
+
   add_setshow_boolean_cmd ("compile", class_maintenance, &compile_debug, _("\
 Set compile command debugging."), _("\
 Show compile command debugging."), _("\
@@ -744,6 +811,15 @@ String quoting is parsed like in shell, for example:\n\
   -mno-align-double \"-I/dir with a space/include\""),
 			  set_compile_args, show_compile_args, &setlist, &showlist);

+  add_setshow_string_cmd ("compile-printf-args", class_support,
+			  &compile_printf_args,
+			  _("Set compile command GCC command-line arguments FIXME"),
+			  _("Show compile command GCC command-line arguments FIXME"),
+			  _("\
+Use options like -Werror which get added for 'compile printf' command."),
+			  set_compile_printf_args, show_compile_printf_args,
+			  &setlist, &showlist);
+
   /* Override flags possibly coming from DW_AT_producer.  */
   compile_args = xstrdup ("-O0 -gdwarf-4"
   /* We use -fPIE Otherwise GDB would need to reserve space large enough for
@@ -762,4 +838,7 @@ String quoting is parsed like in shell, for example:\n\
 			 " -fno-stack-protector"
   );
   set_compile_args (compile_args, 0, NULL);
+
+  compile_printf_args = xstrdup ("-Werror=format");
+  set_compile_printf_args (compile_printf_args, 0, NULL);
 }
diff --git a/gdb/defs.h b/gdb/defs.h
index 8da7d24..0bcb7f0 100644
--- a/gdb/defs.h
+++ b/gdb/defs.h
@@ -73,9 +73,16 @@ enum compile_i_scope_types

     /* A printable expression scope.  Wrap an expression into a scope
        suitable for the "compile print" command.  It uses the generic
-       function name "_gdb_expr". */
+       function name "_gdb_expr".  COMPILE_I_PRINT_ADDRESS_SCOPE variant
+       is the usual one, taking address of the object.
+       COMPILE_I_PRINT_VALUE_SCOPE is needed for arrays where the array
+       name already specifies its address.  */
     COMPILE_I_PRINT_ADDRESS_SCOPE,
     COMPILE_I_PRINT_VALUE_SCOPE,
+
+    /* Implement the "compile printf" command.  SCOPE_DATA contains
+       string containing the format string together with its arguments.  */
+    COMPILE_I_PRINTF_SCOPE,
   };

 /* Just in case they're not defined in stdio.h.  */
diff --git a/gdb/testsuite/gdb.compile/compile-print.exp b/gdb/testsuite/gdb.compile/compile-print.exp
index 92c6240..14fd489 100644
--- a/gdb/testsuite/gdb.compile/compile-print.exp
+++ b/gdb/testsuite/gdb.compile/compile-print.exp
@@ -56,3 +56,8 @@ gdb_test "compile print/x 256" " = 0x100"
 gdb_test {print $} " = 256"

 gdb_test "compile print varobject" { = {field = 1}}
+
+if ![is_remote target] {
+    gdb_test {compile printf "0x%x\n", varint} "\r\n0xa"
+    gdb_test {compile printf "0x%x\n"} "\r\nCompilation failed\\."
+}
---
 gdb/compile/compile-c-support.c             |   21 ++++++
 gdb/compile/compile-object-load.c           |   18 +++++
 gdb/compile/compile.c                       |   91 +++++++++++++++++++++++++--
 gdb/defs.h                                  |    4 +
 gdb/doc/gdb.texinfo                         |   14 ++++
 gdb/testsuite/gdb.compile/compile-print.exp |    5 +
 6 files changed, 144 insertions(+), 9 deletions(-)

diff --git a/gdb/compile/compile-c-support.c b/gdb/compile/compile-c-support.c
index 86b02cf..92c41b6 100644
--- a/gdb/compile/compile-c-support.c
+++ b/gdb/compile/compile-c-support.c
@@ -206,7 +206,17 @@ add_code_header (enum compile_i_scope_types type, struct ui_file *buf)
 			") {\n",
 			buf);
       break;
-
+    case COMPILE_I_PRINTF_SCOPE:
+      fputs_unfiltered ("#include <stdio.h>\n"
+			"void "
+			GCC_FE_WRAPPER_FUNCTION
+			" (struct "
+			COMPILE_I_SIMPLE_REGISTER_STRUCT_TAG
+			" *"
+			COMPILE_I_SIMPLE_REGISTER_ARG_NAME
+			") {\n",
+			buf);
+      break;
     case COMPILE_I_RAW_SCOPE:
       break;
     default:
@@ -226,6 +236,7 @@ add_code_footer (enum compile_i_scope_types type, struct ui_file *buf)
     case COMPILE_I_SIMPLE_SCOPE:
     case COMPILE_I_PRINT_ADDRESS_SCOPE:
     case COMPILE_I_PRINT_VALUE_SCOPE:
+    case COMPILE_I_PRINTF_SCOPE:
       fputs_unfiltered ("}\n", buf);
       break;
     case COMPILE_I_RAW_SCOPE:
@@ -390,7 +401,8 @@ c_compute_program (struct compile_instance *inst,
 
   if (inst->scope == COMPILE_I_SIMPLE_SCOPE
       || inst->scope == COMPILE_I_PRINT_ADDRESS_SCOPE
-      || inst->scope == COMPILE_I_PRINT_VALUE_SCOPE)
+      || inst->scope == COMPILE_I_PRINT_VALUE_SCOPE
+      || inst->scope == COMPILE_I_PRINTF_SCOPE)
     {
       ui_file_put (var_stream, ui_file_write_for_put, buf);
       fputs_unfiltered ("#pragma GCC user_expression\n", buf);
@@ -418,6 +430,11 @@ c_compute_program (struct compile_instance *inst,
 			  (inst->scope == COMPILE_I_PRINT_ADDRESS_SCOPE
 			   ? "&" : ""));
       break;
+    case COMPILE_I_PRINTF_SCOPE:
+      fprintf_unfiltered (buf,
+"printf (%s);\n"
+			  , input);
+      break;
     default:
       fputs_unfiltered (input, buf);
       break;
diff --git a/gdb/compile/compile-object-load.c b/gdb/compile/compile-object-load.c
index e67e5ba..bc74590 100644
--- a/gdb/compile/compile-object-load.c
+++ b/gdb/compile/compile-object-load.c
@@ -470,7 +470,7 @@ static struct type *
 get_regs_type (struct symbol *func_sym, struct objfile *objfile)
 {
   struct type *func_type = SYMBOL_TYPE (func_sym);
-  struct type *regsp_type, *regs_type;
+  struct type *regsp_type, *regs_type, *void_type, *voidp_type;
 
   /* No register parameter present.  */
   if (TYPE_NFIELDS (func_type) == 0)
@@ -490,6 +490,18 @@ get_regs_type (struct symbol *func_sym, struct objfile *objfile)
 	   TYPE_CODE (regs_type), GCC_FE_WRAPPER_FUNCTION,
 	   objfile_name (objfile));
 
+  /* No register parameter present.  */
+  if (TYPE_NFIELDS (func_type) == 1)
+    return regs_type;
+
+  void_type = builtin_type (target_gdbarch ())->builtin_void;
+  voidp_type = lookup_pointer_type (void_type);
+  if (!types_deeply_equal (voidp_type, TYPE_FIELD_TYPE (func_type, 1)))
+    error (_("Invalid type of function \"%s\" parameter \"%s\" in compiled "
+	    "module \"%s\"."),
+	  GCC_FE_WRAPPER_FUNCTION, COMPILE_I_PRINT_OUT_ARG,
+	  objfile_name (objfile));
+
   return regs_type;
 }
 
@@ -637,6 +649,10 @@ compile_object_load (const char *object_file, const char *source_file,
       expect_parameters = 2;
       expect_return_type = builtin_type (target_gdbarch ())->builtin_void;
       break;
+    case COMPILE_I_PRINTF_SCOPE:
+      expect_parameters = 1;
+      expect_return_type = builtin_type (target_gdbarch ())->builtin_void;
+      break;
     default:
       internal_error (__FILE__, __LINE__, _("invalid scope %d"), scope);
     }
diff --git a/gdb/compile/compile.c b/gdb/compile/compile.c
index c4b8f2e..6bbe8df 100644
--- a/gdb/compile/compile.c
+++ b/gdb/compile/compile.c
@@ -174,17 +174,14 @@ compile_print_value (struct value *val, void *data_voidp)
   print_value (val, fmtp);
 }
 
-/* Handle the input from the 'compile print' command.  The "compile
-   print" command is used to evaluate and print an expression that may
-   contain calls to the GCC compiler.  The language expected in this
-   compile command is the language currently set in GDB.  */
+/* Implement 'compile print' and 'compile printf' command according
+   to SCOPE.  */
 
 static void
-compile_print_command (char *arg_param, int from_tty)
+compile_print (char *arg_param, enum compile_i_scope_types scope)
 {
   const char *arg = arg_param;
   struct cleanup *cleanup;
-  enum compile_i_scope_types scope = COMPILE_I_PRINT_ADDRESS_SCOPE;
   struct format_data *fmtp;
 
   cleanup = make_cleanup_restore_integer (&interpreter_async);
@@ -207,6 +204,25 @@ compile_print_command (char *arg_param, int from_tty)
   do_cleanups (cleanup);
 }
 
+/* Handle the input from the 'compile print' command.  The "compile
+   print" command is used to evaluate and print an expression that may
+   contain calls to the GCC compiler.  The language expected in this
+   compile command is the language currently set in GDB.  */
+
+static void
+compile_print_command (char *arg, int from_tty)
+{
+  compile_print (arg, COMPILE_I_PRINT_ADDRESS_SCOPE);
+}
+
+/* Handle the input from the 'compile printf' command.  */
+
+static void
+compile_printf_command (char *arg, int from_tty)
+{
+  compile_print (arg, COMPILE_I_PRINTF_SCOPE);
+}
+
 /* A cleanup function to remove a directory and all its contents.  */
 
 static void
@@ -308,6 +324,14 @@ static char *compile_args;
 static int compile_args_argc;
 static char **compile_args_argv;
 
+/* String for 'set compile-printf-args' and 'show compile-printf-args'.  */
+static char *compile_printf_args;
+
+/* Parsed form of COMPILE_PRINTF_ARGS.
+   COMPILE_PRINTF_ARGS_ARGV is NULL terminated.  */
+static int compile_printf_args_argc;
+static char **compile_printf_args_argv;
+
 /* Implement 'set compile-args'.  */
 
 static void
@@ -328,6 +352,27 @@ show_compile_args (struct ui_file *file, int from_tty,
 		    value);
 }
 
+/* Implement 'set compile-printf-args'.  */
+
+static void
+set_compile_printf_args (char *args, int from_tty, struct cmd_list_element *c)
+{
+  freeargv (compile_printf_args_argv);
+  build_argc_argv (compile_printf_args,
+		   &compile_printf_args_argc, &compile_printf_args_argv);
+}
+
+/* Implement 'show compile-printf-args'.  */
+
+static void
+show_compile_printf_args (struct ui_file *file, int from_tty,
+		   struct cmd_list_element *c, const char *value)
+{
+  fprintf_filtered (file, _("Compile printf command command-line arguments "
+			    "are \"%s\".\n"),
+		    value);
+}
+
 /* Append ARGC and ARGV (as parsed by build_argc_argv) to *ARGCP and *ARGVP.
    ARGCP+ARGVP can be zero+NULL and also ARGC+ARGV can be zero+NULL.  */
 
@@ -422,6 +467,10 @@ get_args (const struct compile_instance *compiler, struct gdbarch *gdbarch,
   freeargv (argv_compiler);
 
   append_args (argcp, argvp, compile_args_argc, compile_args_argv);
+
+  if (compiler->scope == COMPILE_I_PRINTF_SCOPE)
+    append_args (argcp, argvp,
+		 compile_printf_args_argc, compile_printf_args_argv);
 }
 
 /* A cleanup function to destroy a gdb_gcc_instance.  */
@@ -727,6 +776,24 @@ EXPR may be preceded with /FMT, where FMT is a format letter\n\
 but no count or size letter (see \"x\" command)."),
 	   &compile_command_list);
 
+  add_cmd ("printf", class_obscure, compile_printf_command,
+	   _("\
+Print formatted output with the compiler.\n\
+\n\
+Usage: compile printf \"printf format string\", arg1, arg2, arg3, ..., argn\n\
+\n\
+The arguments may be specified on the same line as the command, e.g.:\n\
+\n\
+    compile printf \"%d\\n\", i\n\
+\n\
+Alternatively, you can type the arguments interactively.\n\
+You can invoke this mode when no argument is given to the command\n\
+(i.e., \"compile printf\" is typed with nothing after it).  An\n\
+interactive prompt will be shown allowing you to enter multiple\n\
+lines of source code.  Type a line containing \"end\" to indicate\n\
+the end of the source code."),
+	   &compile_command_list);
+
   add_setshow_boolean_cmd ("compile", class_maintenance, &compile_debug, _("\
 Set compile command debugging."), _("\
 Show compile command debugging."), _("\
@@ -744,6 +811,15 @@ String quoting is parsed like in shell, for example:\n\
   -mno-align-double \"-I/dir with a space/include\""),
 			  set_compile_args, show_compile_args, &setlist, &showlist);
 
+  add_setshow_string_cmd ("compile-printf-args", class_support,
+			  &compile_printf_args,
+			  _("Set compile command GCC command-line arguments FIXME"),
+			  _("Show compile command GCC command-line arguments FIXME"),
+			  _("\
+Use options like -Werror which get added for 'compile printf' command."),
+			  set_compile_printf_args, show_compile_printf_args,
+			  &setlist, &showlist);
+
   /* Override flags possibly coming from DW_AT_producer.  */
   compile_args = xstrdup ("-O0 -gdwarf-4"
   /* We use -fPIE Otherwise GDB would need to reserve space large enough for
@@ -762,4 +838,7 @@ String quoting is parsed like in shell, for example:\n\
 			 " -fno-stack-protector"
   );
   set_compile_args (compile_args, 0, NULL);
+
+  compile_printf_args = xstrdup ("-Werror=format");
+  set_compile_printf_args (compile_printf_args, 0, NULL);
 }
diff --git a/gdb/defs.h b/gdb/defs.h
index f6e010c..0bcb7f0 100644
--- a/gdb/defs.h
+++ b/gdb/defs.h
@@ -79,6 +79,10 @@ enum compile_i_scope_types
        name already specifies its address.  */
     COMPILE_I_PRINT_ADDRESS_SCOPE,
     COMPILE_I_PRINT_VALUE_SCOPE,
+
+    /* Implement the "compile printf" command.  SCOPE_DATA contains
+       string containing the format string together with its arguments.  */
+    COMPILE_I_PRINTF_SCOPE,
   };
 
 /* Just in case they're not defined in stdio.h.  */
diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo
index 3eaf9d3..46a7bf4 100644
--- a/gdb/doc/gdb.texinfo
+++ b/gdb/doc/gdb.texinfo
@@ -17242,6 +17242,20 @@ command without any text following the command.  This will start the
 multiple-line editor.
 @end table
 
+@table @code
+@item compile printf @var{template}, @var{expressions}@dots{}
+Compile and execute @code{printf} function call with the compiler
+language found as the current language in @value{GDBN}
+(@pxref{Languages}).
+
+@item compile printf
+@cindex reprint the last value
+Alternatively you can enter the template and expression (source code
+producing them) as multiple lines of text.  To enter this mode, invoke
+the @samp{compile printf} command without any text following the
+command.  This will start the multiple-line editor.
+@end table
+
 @subsection Caveats when using the @code{compile} command
 
 There are a few caveats to keep in mind when using the @code{compile}
diff --git a/gdb/testsuite/gdb.compile/compile-print.exp b/gdb/testsuite/gdb.compile/compile-print.exp
index 92c6240..14fd489 100644
--- a/gdb/testsuite/gdb.compile/compile-print.exp
+++ b/gdb/testsuite/gdb.compile/compile-print.exp
@@ -56,3 +56,8 @@ gdb_test "compile print/x 256" " = 0x100"
 gdb_test {print $} " = 256"
 
 gdb_test "compile print varobject" { = {field = 1}}
+
+if ![is_remote target] {
+    gdb_test {compile printf "0x%x\n", varint} "\r\n0xa"
+    gdb_test {compile printf "0x%x\n"} "\r\nCompilation failed\\."
+}

^ permalink raw reply	[flat|nested] 30+ messages in thread

* [PATCH v2 9/9] compile: compile printf: gdbserver support
  2015-04-06 17:26 [PATCH v2 0/9] compile: compile print&printf Jan Kratochvil
                   ` (5 preceding siblings ...)
  2015-04-06 17:27 ` [PATCH v2 5/9] compile: Use -Wall, not -w Jan Kratochvil
@ 2015-04-06 17:27 ` Jan Kratochvil
  2015-04-06 17:43   ` Eli Zaretskii
  2015-04-06 17:27 ` [PATCH v2 8/9] compile: New compile printf Jan Kratochvil
                   ` (2 subsequent siblings)
  9 siblings, 1 reply; 30+ messages in thread
From: Jan Kratochvil @ 2015-04-06 17:27 UTC (permalink / raw)
  To: gdb-patches; +Cc: Phil Muldoon

Hi,

former patch injects plain:
	printf (...);
This patch injects gdbserver-compatible:
	f = open_memstream (&s, ...);
	fprintf (f, ...);
	fclose (f);
	return s;

Jan


gdb/
2015-04-06  Jan Kratochvil  <jan.kratochvil@redhat.com>

	* compile/compile-c-support.c (add_code_header, add_code_footer)
	(c_compute_program): Use open_memstream, fprintf and fclose.
	* compile/compile-object-load.c (compile_object_load): Set expected
	char * for COMPILE_I_PRINTF_SCOPE.
	* compile/compile-object-run.c: Include gdbcore.h.
	(free_inferior_memory): New function.
	(compile_object_run): Support COMPILE_I_PRINTF_SCOPE's return value.

gdb/doc/ChangeLog
2015-04-06  Jan Kratochvil  <jan.kratochvil@redhat.com>

	* gdb.texinfo (Compiling and Injecting Code): Mention for compile
	printf open_memstream and fprintf.

gdb/testsuite/ChangeLog
2015-04-06  Jan Kratochvil  <jan.kratochvil@redhat.com>

	* gdb.compile/compile-print.exp (compile printf "0x%x\n", varint)
	(compile printf "0x%x\n"): Remove !is_remote conditional.

diff --git a/gdb/compile/compile-c-support.c b/gdb/compile/compile-c-support.c
index 92c41b6..3b9bb52 100644
--- a/gdb/compile/compile-c-support.c
+++ b/gdb/compile/compile-c-support.c
@@ -208,13 +208,21 @@ add_code_header (enum compile_i_scope_types type, struct ui_file *buf)
       break;
     case COMPILE_I_PRINTF_SCOPE:
       fputs_unfiltered ("#include <stdio.h>\n"
-			"void "
+			"char *"
 			GCC_FE_WRAPPER_FUNCTION
 			" (struct "
 			COMPILE_I_SIMPLE_REGISTER_STRUCT_TAG
 			" *"
 			COMPILE_I_SIMPLE_REGISTER_ARG_NAME
-			") {\n",
+			") {\n"
+			"\tchar *__gdb_retval;\n"
+			"\tsize_t __gdb_retval_size;\n"
+			"\tFILE *__gdb_outf;\n"
+			"\n"
+			"\t__gdb_outf = open_memstream (&__gdb_retval, "
+						       "&__gdb_retval_size);\n"
+			"\tif (__gdb_outf == NULL)\n"
+			"\t\treturn NULL;\n",
 			buf);
       break;
     case COMPILE_I_RAW_SCOPE:
@@ -233,10 +241,15 @@ add_code_footer (enum compile_i_scope_types type, struct ui_file *buf)
 {
   switch (type)
     {
+    case COMPILE_I_PRINTF_SCOPE:
+      fputs_unfiltered ("\tif (fclose (__gdb_outf) != 0)\n"
+			"\t\treturn NULL;\n"
+			"\treturn __gdb_retval;\n",
+			buf);
+      // FALLTHRU
     case COMPILE_I_SIMPLE_SCOPE:
     case COMPILE_I_PRINT_ADDRESS_SCOPE:
     case COMPILE_I_PRINT_VALUE_SCOPE:
-    case COMPILE_I_PRINTF_SCOPE:
       fputs_unfiltered ("}\n", buf);
       break;
     case COMPILE_I_RAW_SCOPE:
@@ -432,7 +445,7 @@ c_compute_program (struct compile_instance *inst,
       break;
     case COMPILE_I_PRINTF_SCOPE:
       fprintf_unfiltered (buf,
-"printf (%s);\n"
+"fprintf (__gdb_outf, %s);\n"
 			  , input);
       break;
     default:
diff --git a/gdb/compile/compile-object-load.c b/gdb/compile/compile-object-load.c
index bc74590..d7c13c9 100644
--- a/gdb/compile/compile-object-load.c
+++ b/gdb/compile/compile-object-load.c
@@ -651,7 +651,8 @@ compile_object_load (const char *object_file, const char *source_file,
       break;
     case COMPILE_I_PRINTF_SCOPE:
       expect_parameters = 1;
-      expect_return_type = builtin_type (target_gdbarch ())->builtin_void;
+      expect_return_type = lookup_pointer_type
+			       (builtin_type (target_gdbarch ())->builtin_char);
       break;
     default:
       internal_error (__FILE__, __LINE__, _("invalid scope %d"), scope);
diff --git a/gdb/compile/compile-object-run.c b/gdb/compile/compile-object-run.c
index 216cbf9..ed56410 100644
--- a/gdb/compile/compile-object-run.c
+++ b/gdb/compile/compile-object-run.c
@@ -27,6 +27,7 @@
 #include "block.h"
 #include "valprint.h"
 #include "compile.h"
+#include "gdbcore.h"

 /* Helper for do_module_cleanup.  */

@@ -99,6 +100,18 @@ do_module_cleanup (void *arg)
   xfree (data);
 }

+static void
+free_inferior_memory (CORE_ADDR addr)
+{
+  struct objfile *objf;
+  struct value *func_val = find_function_in_inferior ("free", &objf);
+  struct gdbarch *gdbarch = get_objfile_arch (objf);
+  struct type *addr_type = builtin_type (gdbarch)->builtin_data_ptr;
+  struct value *addr_val = value_from_pointer (addr_type, addr);
+
+  call_function_by_hand (func_val, 1, &addr_val);
+}
+
 /* Perform inferior call of MODULE.  This function may throw an error.
    This function may leave files referenced by MODULE on disk until
    the inferior call dummy frame is discarded.  This function may throw errors.
@@ -117,6 +130,7 @@ compile_object_run (struct compile_module *module)
   struct symbol *func_sym = module->func_sym;
   CORE_ADDR regs_addr = module->regs_addr;
   struct objfile *objfile = module->objfile;
+  enum compile_i_scope_types scope = module->scope;

   data = xmalloc (sizeof (*data) + strlen (objfile_name_s));
   data->executedp = &executed;
@@ -136,7 +150,7 @@ compile_object_run (struct compile_module *module)
       struct type *func_type = SYMBOL_TYPE (func_sym);
       htab_t copied_types;
       int current_arg = 0;
-      struct value **vargs;
+      struct value **vargs, *func_return_value;

       /* OBJFILE may disappear while FUNC_TYPE still will be in use.  */
       copied_types = create_copied_types_hash (objfile);
@@ -163,8 +177,42 @@ compile_object_run (struct compile_module *module)
 	  ++current_arg;
 	}
       gdb_assert (current_arg == TYPE_NFIELDS (func_type));
-      call_function_by_hand_dummy (func_val, TYPE_NFIELDS (func_type), vargs,
-				   do_module_cleanup, data);
+      func_return_value = call_function_by_hand_dummy (func_val,
+						       TYPE_NFIELDS (func_type),
+						       vargs,
+						       do_module_cleanup, data);
+
+      // DATA can be already freed now.
+      data = NULL;
+
+      if (scope == COMPILE_I_PRINTF_SCOPE)
+	{
+	  struct value_print_options opts;
+	  gdb_byte *buffer = NULL;
+	  struct cleanup *old_chain;
+	  int errcode, bytes_read;
+	  struct type *retval_type = value_type (func_return_value);
+	  struct type *char_type;
+
+	  gdb_assert (TYPE_CODE (retval_type) == TYPE_CODE_PTR);
+	  char_type = TYPE_TARGET_TYPE (retval_type);
+	  gdb_assert (TYPE_CODE (char_type) == TYPE_CODE_INT);
+
+	  get_user_print_options (&opts);
+	  errcode = read_string (value_as_address (func_return_value), -1,
+				 TYPE_LENGTH (char_type), opts.print_max,
+				 gdbarch_byte_order (target_gdbarch ()),
+				 &buffer, &bytes_read);
+	  old_chain = make_cleanup (xfree, buffer);
+	  if (errcode != 0)
+	    memory_error (errcode, value_as_address (func_return_value));
+
+	  while (bytes_read-- > 0)
+	    putchar_filtered (*buffer++);
+	  do_cleanups (old_chain);
+
+	  free_inferior_memory (value_as_address (func_return_value));
+	}
     }
   CATCH (ex, RETURN_MASK_ERROR)
     {
diff --git a/gdb/testsuite/gdb.compile/compile-print.exp b/gdb/testsuite/gdb.compile/compile-print.exp
index 14fd489..43b9f24 100644
--- a/gdb/testsuite/gdb.compile/compile-print.exp
+++ b/gdb/testsuite/gdb.compile/compile-print.exp
@@ -57,7 +57,5 @@ gdb_test {print $} " = 256"

 gdb_test "compile print varobject" { = {field = 1}}

-if ![is_remote target] {
-    gdb_test {compile printf "0x%x\n", varint} "\r\n0xa"
-    gdb_test {compile printf "0x%x\n"} "\r\nCompilation failed\\."
-}
+gdb_test {compile printf "0x%x\n", varint} "\r\n0xa"
+gdb_test {compile printf "0x%x\n"} "\r\nCompilation failed\\."
---
 gdb/compile/compile-c-support.c             |   21 ++++++++--
 gdb/compile/compile-object-load.c           |    3 +
 gdb/compile/compile-object-run.c            |   56 ++++++++++++++++++++++++++-
 gdb/doc/gdb.texinfo                         |    4 +-
 gdb/testsuite/gdb.compile/compile-print.exp |    6 +--
 5 files changed, 77 insertions(+), 13 deletions(-)

diff --git a/gdb/compile/compile-c-support.c b/gdb/compile/compile-c-support.c
index 92c41b6..3b9bb52 100644
--- a/gdb/compile/compile-c-support.c
+++ b/gdb/compile/compile-c-support.c
@@ -208,13 +208,21 @@ add_code_header (enum compile_i_scope_types type, struct ui_file *buf)
       break;
     case COMPILE_I_PRINTF_SCOPE:
       fputs_unfiltered ("#include <stdio.h>\n"
-			"void "
+			"char *"
 			GCC_FE_WRAPPER_FUNCTION
 			" (struct "
 			COMPILE_I_SIMPLE_REGISTER_STRUCT_TAG
 			" *"
 			COMPILE_I_SIMPLE_REGISTER_ARG_NAME
-			") {\n",
+			") {\n"
+			"\tchar *__gdb_retval;\n"
+			"\tsize_t __gdb_retval_size;\n"
+			"\tFILE *__gdb_outf;\n"
+			"\n"
+			"\t__gdb_outf = open_memstream (&__gdb_retval, "
+						       "&__gdb_retval_size);\n"
+			"\tif (__gdb_outf == NULL)\n"
+			"\t\treturn NULL;\n",
 			buf);
       break;
     case COMPILE_I_RAW_SCOPE:
@@ -233,10 +241,15 @@ add_code_footer (enum compile_i_scope_types type, struct ui_file *buf)
 {
   switch (type)
     {
+    case COMPILE_I_PRINTF_SCOPE:
+      fputs_unfiltered ("\tif (fclose (__gdb_outf) != 0)\n"
+			"\t\treturn NULL;\n"
+			"\treturn __gdb_retval;\n",
+			buf);
+      // FALLTHRU
     case COMPILE_I_SIMPLE_SCOPE:
     case COMPILE_I_PRINT_ADDRESS_SCOPE:
     case COMPILE_I_PRINT_VALUE_SCOPE:
-    case COMPILE_I_PRINTF_SCOPE:
       fputs_unfiltered ("}\n", buf);
       break;
     case COMPILE_I_RAW_SCOPE:
@@ -432,7 +445,7 @@ c_compute_program (struct compile_instance *inst,
       break;
     case COMPILE_I_PRINTF_SCOPE:
       fprintf_unfiltered (buf,
-"printf (%s);\n"
+"fprintf (__gdb_outf, %s);\n"
 			  , input);
       break;
     default:
diff --git a/gdb/compile/compile-object-load.c b/gdb/compile/compile-object-load.c
index bc74590..d7c13c9 100644
--- a/gdb/compile/compile-object-load.c
+++ b/gdb/compile/compile-object-load.c
@@ -651,7 +651,8 @@ compile_object_load (const char *object_file, const char *source_file,
       break;
     case COMPILE_I_PRINTF_SCOPE:
       expect_parameters = 1;
-      expect_return_type = builtin_type (target_gdbarch ())->builtin_void;
+      expect_return_type = lookup_pointer_type
+			       (builtin_type (target_gdbarch ())->builtin_char);
       break;
     default:
       internal_error (__FILE__, __LINE__, _("invalid scope %d"), scope);
diff --git a/gdb/compile/compile-object-run.c b/gdb/compile/compile-object-run.c
index 216cbf9..3606d42 100644
--- a/gdb/compile/compile-object-run.c
+++ b/gdb/compile/compile-object-run.c
@@ -27,6 +27,7 @@
 #include "block.h"
 #include "valprint.h"
 #include "compile.h"
+#include "gdbcore.h"
 
 /* Helper for do_module_cleanup.  */
 
@@ -99,6 +100,20 @@ do_module_cleanup (void *arg)
   xfree (data);
 }
 
+/* Call inferior function "free" for ADDR.  */
+
+static void
+free_inferior_memory (CORE_ADDR addr)
+{
+  struct objfile *objf;
+  struct value *func_val = find_function_in_inferior ("free", &objf);
+  struct gdbarch *gdbarch = get_objfile_arch (objf);
+  struct type *addr_type = builtin_type (gdbarch)->builtin_data_ptr;
+  struct value *addr_val = value_from_pointer (addr_type, addr);
+
+  call_function_by_hand (func_val, 1, &addr_val);
+}
+
 /* Perform inferior call of MODULE.  This function may throw an error.
    This function may leave files referenced by MODULE on disk until
    the inferior call dummy frame is discarded.  This function may throw errors.
@@ -117,6 +132,7 @@ compile_object_run (struct compile_module *module)
   struct symbol *func_sym = module->func_sym;
   CORE_ADDR regs_addr = module->regs_addr;
   struct objfile *objfile = module->objfile;
+  enum compile_i_scope_types scope = module->scope;
 
   data = xmalloc (sizeof (*data) + strlen (objfile_name_s));
   data->executedp = &executed;
@@ -136,7 +152,7 @@ compile_object_run (struct compile_module *module)
       struct type *func_type = SYMBOL_TYPE (func_sym);
       htab_t copied_types;
       int current_arg = 0;
-      struct value **vargs;
+      struct value **vargs, *func_return_value;
 
       /* OBJFILE may disappear while FUNC_TYPE still will be in use.  */
       copied_types = create_copied_types_hash (objfile);
@@ -163,8 +179,42 @@ compile_object_run (struct compile_module *module)
 	  ++current_arg;
 	}
       gdb_assert (current_arg == TYPE_NFIELDS (func_type));
-      call_function_by_hand_dummy (func_val, TYPE_NFIELDS (func_type), vargs,
-				   do_module_cleanup, data);
+      func_return_value = call_function_by_hand_dummy (func_val,
+						       TYPE_NFIELDS (func_type),
+						       vargs,
+						       do_module_cleanup, data);
+
+      // DATA can be already freed now.
+      data = NULL;
+
+      if (scope == COMPILE_I_PRINTF_SCOPE)
+	{
+	  struct value_print_options opts;
+	  gdb_byte *buffer = NULL;
+	  struct cleanup *old_chain;
+	  int errcode, bytes_read;
+	  struct type *retval_type = value_type (func_return_value);
+	  struct type *char_type;
+
+	  gdb_assert (TYPE_CODE (retval_type) == TYPE_CODE_PTR);
+	  char_type = TYPE_TARGET_TYPE (retval_type);
+	  gdb_assert (TYPE_CODE (char_type) == TYPE_CODE_INT);
+
+	  get_user_print_options (&opts);
+	  errcode = read_string (value_as_address (func_return_value), -1,
+				 TYPE_LENGTH (char_type), opts.print_max,
+				 gdbarch_byte_order (target_gdbarch ()),
+				 &buffer, &bytes_read);
+	  old_chain = make_cleanup (xfree, buffer);
+	  if (errcode != 0)
+	    memory_error (errcode, value_as_address (func_return_value));
+
+	  while (bytes_read-- > 0)
+	    putchar_filtered (*buffer++);
+	  do_cleanups (old_chain);
+
+	  free_inferior_memory (value_as_address (func_return_value));
+	}
     }
   CATCH (ex, RETURN_MASK_ERROR)
     {
diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo
index 46a7bf4..4e5ea51 100644
--- a/gdb/doc/gdb.texinfo
+++ b/gdb/doc/gdb.texinfo
@@ -17246,7 +17246,9 @@ multiple-line editor.
 @item compile printf @var{template}, @var{expressions}@dots{}
 Compile and execute @code{printf} function call with the compiler
 language found as the current language in @value{GDBN}
-(@pxref{Languages}).
+(@pxref{Languages}).  Inferior executes @code{open_memstream} and
+@code{fprintf} instead so that the produced string is printed by
+@value{GDBN} and not the inferior.
 
 @item compile printf
 @cindex reprint the last value
diff --git a/gdb/testsuite/gdb.compile/compile-print.exp b/gdb/testsuite/gdb.compile/compile-print.exp
index 14fd489..43b9f24 100644
--- a/gdb/testsuite/gdb.compile/compile-print.exp
+++ b/gdb/testsuite/gdb.compile/compile-print.exp
@@ -57,7 +57,5 @@ gdb_test {print $} " = 256"
 
 gdb_test "compile print varobject" { = {field = 1}}
 
-if ![is_remote target] {
-    gdb_test {compile printf "0x%x\n", varint} "\r\n0xa"
-    gdb_test {compile printf "0x%x\n"} "\r\nCompilation failed\\."
-}
+gdb_test {compile printf "0x%x\n", varint} "\r\n0xa"
+gdb_test {compile printf "0x%x\n"} "\r\nCompilation failed\\."

^ permalink raw reply	[flat|nested] 30+ messages in thread

* [PATCH v2 7/9] compile: New 'compile print'
  2015-04-06 17:26 [PATCH v2 0/9] compile: compile print&printf Jan Kratochvil
                   ` (3 preceding siblings ...)
  2015-04-06 17:26 ` [PATCH v2 3/9] Code cleanup: compile: Constify some parameters Jan Kratochvil
@ 2015-04-06 17:27 ` Jan Kratochvil
  2015-04-06 17:41   ` Eli Zaretskii
  2015-04-06 17:27 ` [PATCH v2 5/9] compile: Use -Wall, not -w Jan Kratochvil
                   ` (4 subsequent siblings)
  9 siblings, 1 reply; 30+ messages in thread
From: Jan Kratochvil @ 2015-04-06 17:27 UTC (permalink / raw)
  To: gdb-patches; +Cc: Phil Muldoon

It is planned the existing GDB command 'print' will be able to evaluate its
expressions using the compiler.  There will be some option to choose between
the existing GDB evaluation and the compiler evaluation.  But as an
intermediate step this patch provides the expression printing feature as a new
command.

I can imagine it could be also called 'maintenance compile print' as in the
future one should be able to use its functionality by the normal 'print'
command.

There was a discussion with Eli about the command name:
	https://sourceware.org/ml/gdb-patches/2015-03/msg00880.html
As there were no other comments yet I haven't renamed it yet, before there is
some confirmation about settlement on the final name.

Support for the GDB '@' operator to create arrays has been submitted for GCC:
	[gcc patch] libcc1: '@' GDB array operator
	https://gcc.gnu.org/ml/gcc-patches/2015-03/msg01451.html


gdb/ChangeLog
2015-03-26  Jan Kratochvil  <jan.kratochvil@redhat.com>
	    Phil Muldoon  <pmuldoon@redhat.com>

	* NEWS (Changes since GDB 7.9): Add compile print.
	* compile/compile-c-support.c (add_code_header, add_code_footer)
	(c_compute_program): Add COMPILE_I_PRINT_ADDRESS_SCOPE and
	COMPILE_I_PRINT_VALUE_SCOPE.
	* compile/compile-internal.h (COMPILE_I_PRINT_OUT_ARG_TYPE)
	(COMPILE_I_PRINT_OUT_ARG, COMPILE_I_EXPR_VAL, COMPILE_I_EXPR_PTR_TYPE):
	New.
	* compile/compile-object-load.c: Include block.h.
	(get_out_value_type): New function.
	(compile_object_load): Handle COMPILE_I_PRINT_ADDRESS_SCOPE and
	COMPILE_I_PRINT_VALUE_SCOPE.  Set compile_module's OUT_VALUE_ADDR and
	OUT_VALUE_TYPE.
	* compile/compile-object-load.h (struct compile_module): Add fields
	out_value_addr and out_value_type.
	* compile/compile-object-run.c: Include valprint.h and compile.h.
	(struct do_module_cleanup): Add fields out_value_addr and
	out_value_type.
	(do_module_cleanup): Handle COMPILE_I_PRINT_ADDRESS_SCOPE and
	COMPILE_I_PRINT_VALUE_SCOPE.
	(compile_object_run): Propagate out_value_addr and out_value_type.
	Pass OUT_VALUE_ADDR.
	* compile/compile.c: Include valprint.h.
	(compile_print_value, compile_print_command): New functions.
	(eval_compile_command): Handle failed COMPILE_I_PRINT_ADDRESS_SCOPE.
	(_initialize_compile): Install compile_print_command.
	* compile/compile.h (compile_print_value): New prototype.
	* defs.h (enum compile_i_scope_types): Add
	COMPILE_I_PRINT_ADDRESS_SCOPE and COMPILE_I_PRINT_VALUE_SCOPE.

gdb/doc/ChangeLog
2015-03-26  Jan Kratochvil  <jan.kratochvil@redhat.com>

	* gdb.texinfo (Compiling and Injecting Code): Add compile print.

gdb/testsuite/ChangeLog
2015-03-26  Jan Kratochvil  <jan.kratochvil@redhat.com>

	* gdb.compile/compile-print.c: New file.
	* gdb.compile/compile-print.exp: New file.
---
 gdb/NEWS                                    |    3 +
 gdb/compile/compile-c-support.c             |   43 ++++++++
 gdb/compile/compile-internal.h              |    4 +
 gdb/compile/compile-object-load.c           |  141 ++++++++++++++++++++++++++-
 gdb/compile/compile-object-load.h           |    8 ++
 gdb/compile/compile-object-run.c            |   31 ++++++
 gdb/compile/compile.c                       |   73 ++++++++++++++
 gdb/compile/compile.h                       |    2 
 gdb/defs.h                                  |    9 ++
 gdb/doc/gdb.texinfo                         |   19 ++++
 gdb/testsuite/gdb.compile/compile-print.c   |   32 ++++++
 gdb/testsuite/gdb.compile/compile-print.exp |   58 +++++++++++
 12 files changed, 417 insertions(+), 6 deletions(-)
 create mode 100644 gdb/testsuite/gdb.compile/compile-print.c
 create mode 100644 gdb/testsuite/gdb.compile/compile-print.exp

diff --git a/gdb/NEWS b/gdb/NEWS
index 884c381..8dd3767 100644
--- a/gdb/NEWS
+++ b/gdb/NEWS
@@ -53,6 +53,9 @@ record btrace bts
 record bts
   Start branch trace recording using Branch Trace Store (BTS) format.
 
+compile print
+  Evaluate expression with the compiler and print result.
+
 * New options
 
 set max-completions
diff --git a/gdb/compile/compile-c-support.c b/gdb/compile/compile-c-support.c
index 48a17e2..86b02cf 100644
--- a/gdb/compile/compile-c-support.c
+++ b/gdb/compile/compile-c-support.c
@@ -190,6 +190,23 @@ add_code_header (enum compile_i_scope_types type, struct ui_file *buf)
 			") {\n",
 			buf);
       break;
+    case COMPILE_I_PRINT_ADDRESS_SCOPE:
+    case COMPILE_I_PRINT_VALUE_SCOPE:
+      fputs_unfiltered ("#include <string.h>\n"
+			"void "
+			GCC_FE_WRAPPER_FUNCTION
+			" (struct "
+			COMPILE_I_SIMPLE_REGISTER_STRUCT_TAG
+			" *"
+			COMPILE_I_SIMPLE_REGISTER_ARG_NAME
+			", "
+			COMPILE_I_PRINT_OUT_ARG_TYPE
+			" "
+			COMPILE_I_PRINT_OUT_ARG
+			") {\n",
+			buf);
+      break;
+
     case COMPILE_I_RAW_SCOPE:
       break;
     default:
@@ -207,6 +224,8 @@ add_code_footer (enum compile_i_scope_types type, struct ui_file *buf)
   switch (type)
     {
     case COMPILE_I_SIMPLE_SCOPE:
+    case COMPILE_I_PRINT_ADDRESS_SCOPE:
+    case COMPILE_I_PRINT_VALUE_SCOPE:
       fputs_unfiltered ("}\n", buf);
       break;
     case COMPILE_I_RAW_SCOPE:
@@ -369,7 +388,9 @@ c_compute_program (struct compile_instance *inst,
 
   add_code_header (inst->scope, buf);
 
-  if (inst->scope == COMPILE_I_SIMPLE_SCOPE)
+  if (inst->scope == COMPILE_I_SIMPLE_SCOPE
+      || inst->scope == COMPILE_I_PRINT_ADDRESS_SCOPE
+      || inst->scope == COMPILE_I_PRINT_VALUE_SCOPE)
     {
       ui_file_put (var_stream, ui_file_write_for_put, buf);
       fputs_unfiltered ("#pragma GCC user_expression\n", buf);
@@ -383,7 +404,25 @@ c_compute_program (struct compile_instance *inst,
     fputs_unfiltered ("{\n", buf);
 
   fputs_unfiltered ("#line 1 \"gdb command line\"\n", buf);
-  fputs_unfiltered (input, buf);
+
+  switch (inst->scope)
+    {
+    case COMPILE_I_PRINT_ADDRESS_SCOPE:
+    case COMPILE_I_PRINT_VALUE_SCOPE:
+      fprintf_unfiltered (buf,
+"__auto_type " COMPILE_I_EXPR_VAL " = %s;\n"
+"typeof (%s) *" COMPILE_I_EXPR_PTR_TYPE ";\n"
+"memcpy (" COMPILE_I_PRINT_OUT_ARG ", %s" COMPILE_I_EXPR_VAL ",\n"
+	 "sizeof (*" COMPILE_I_EXPR_PTR_TYPE "));\n"
+			  , input, input,
+			  (inst->scope == COMPILE_I_PRINT_ADDRESS_SCOPE
+			   ? "&" : ""));
+      break;
+    default:
+      fputs_unfiltered (input, buf);
+      break;
+    }
+
   fputs_unfiltered ("\n", buf);
 
   /* For larger user expressions the automatic semicolons may be
diff --git a/gdb/compile/compile-internal.h b/gdb/compile/compile-internal.h
index c369d46..b1a5a88 100644
--- a/gdb/compile/compile-internal.h
+++ b/gdb/compile/compile-internal.h
@@ -84,6 +84,10 @@ struct compile_c_instance
 #define COMPILE_I_SIMPLE_REGISTER_STRUCT_TAG "__gdb_regs"
 #define COMPILE_I_SIMPLE_REGISTER_ARG_NAME "__regs"
 #define COMPILE_I_SIMPLE_REGISTER_DUMMY "_dummy"
+#define COMPILE_I_PRINT_OUT_ARG_TYPE "void *"
+#define COMPILE_I_PRINT_OUT_ARG "__gdb_out_param"
+#define COMPILE_I_EXPR_VAL "__gdb_expr_val"
+#define COMPILE_I_EXPR_PTR_TYPE "__gdb_expr_ptr_type"
 
 /* Call gdbarch_register_name (GDBARCH, REGNUM) and convert its result
    to a form suitable for the compiler source.  The register names
diff --git a/gdb/compile/compile-object-load.c b/gdb/compile/compile-object-load.c
index 3c07840..e67e5ba 100644
--- a/gdb/compile/compile-object-load.c
+++ b/gdb/compile/compile-object-load.c
@@ -29,6 +29,7 @@
 #include "regcache.h"
 #include "inferior.h"
 #include "compile.h"
+#include "block.h"
 #include "arch-utils.h"
 
 /* Helper data for setup_sections.  */
@@ -354,6 +355,114 @@ copy_sections (bfd *abfd, asection *sect, void *data)
   do_cleanups (cleanups);
 }
 
+/* Fetch the type of COMPILE_I_EXPR_PTR_TYPE and COMPILE_I_EXPR_VAL
+   symbols in OBJFILE so we can calculate how much memory to allocate
+   for the out parameter.  This avoids needing a malloc in the generated
+   code.  Throw an error if anything fails.
+   Set *OUT_VALUE_TAKE_ADDRESSP depending whether inferior code should
+   copy COMPILE_I_EXPR_VAL or its address - this depends on __auto_type
+   array-to-pointer type conversion of COMPILE_I_EXPR_VAL, as detected
+   by COMPILE_I_EXPR_PTR_TYPE preserving the array type.  */
+
+static struct type *
+get_out_value_type (struct symbol *func_sym, struct objfile *objfile,
+		    enum compile_i_scope_types scope)
+{
+  struct symbol *gdb_ptr_type_sym, *gdb_val_sym;
+  struct type *gdb_ptr_type, *gdb_type_from_ptr, *gdb_type, *retval;
+  const struct block *block;
+  const struct blockvector *bv;
+  int nblocks = 0;
+  int block_loop = 0;
+
+  bv = SYMTAB_BLOCKVECTOR (func_sym->owner.symtab);
+  nblocks = BLOCKVECTOR_NBLOCKS (bv);
+
+  gdb_ptr_type_sym = NULL;
+  for (block_loop = 0; block_loop < nblocks; block_loop++)
+    {
+      struct symbol *function;
+      const struct block *function_block;
+
+      block = BLOCKVECTOR_BLOCK (bv, block_loop);
+      if (BLOCK_FUNCTION (block) != NULL)
+	continue;
+      gdb_val_sym = block_lookup_symbol (block, COMPILE_I_EXPR_VAL, VAR_DOMAIN);
+      if (gdb_val_sym == NULL)
+	continue;
+
+      function_block = block;
+      while (function_block != BLOCKVECTOR_BLOCK (bv, STATIC_BLOCK)
+	     && function_block != BLOCKVECTOR_BLOCK (bv, GLOBAL_BLOCK))
+	{
+	  function_block = BLOCK_SUPERBLOCK (function_block);
+	  function = BLOCK_FUNCTION (function_block);
+	  if (function != NULL)
+	    break;
+	}
+      if (function != NULL
+	  && (BLOCK_SUPERBLOCK (function_block)
+	      == BLOCKVECTOR_BLOCK (bv, STATIC_BLOCK))
+	  && (strcmp (SYMBOL_LINKAGE_NAME (function), GCC_FE_WRAPPER_FUNCTION)
+	      == 0))
+	break;
+    }
+  if (block_loop == nblocks)
+    error (_("No \"%s\" symbol found"), COMPILE_I_EXPR_PTR_TYPE);
+
+  gdb_type = SYMBOL_TYPE (gdb_val_sym);
+  CHECK_TYPEDEF (gdb_type);
+
+  gdb_ptr_type_sym = block_lookup_symbol (block, COMPILE_I_EXPR_PTR_TYPE,
+					  VAR_DOMAIN);
+  if (gdb_ptr_type_sym == NULL)
+    error (_("No \"%s\" symbol found"), COMPILE_I_EXPR_PTR_TYPE);
+  gdb_ptr_type = SYMBOL_TYPE (gdb_ptr_type_sym);
+  CHECK_TYPEDEF (gdb_ptr_type);
+  if (TYPE_CODE (gdb_ptr_type) != TYPE_CODE_PTR)
+    error (_("Type of \"%s\" is not a pointer"), COMPILE_I_EXPR_PTR_TYPE);
+  gdb_type_from_ptr = TYPE_TARGET_TYPE (gdb_ptr_type);
+
+  if (types_deeply_equal (gdb_type, gdb_type_from_ptr))
+    {
+      if (scope != COMPILE_I_PRINT_ADDRESS_SCOPE)
+	error (_("Expected address scope in compiled module \"%s\"."),
+	       objfile_name (objfile));
+      return gdb_type;
+    }
+
+  if (TYPE_CODE (gdb_type) != TYPE_CODE_PTR)
+    error (_("Invalid type code %d of symbol \"%s\" "
+	     "in compiled module \"%s\"."),
+	   TYPE_CODE (gdb_type_from_ptr), COMPILE_I_EXPR_VAL,
+	   objfile_name (objfile));
+  
+  switch (TYPE_CODE (gdb_type_from_ptr))
+    {
+    case TYPE_CODE_ARRAY:
+      retval = gdb_type_from_ptr;
+      gdb_type_from_ptr = TYPE_TARGET_TYPE (gdb_type_from_ptr);
+      break;
+    case TYPE_CODE_FUNC:
+      retval = gdb_type_from_ptr;
+      break;
+    default:
+      error (_("Invalid type code %d of symbol \"%s\" "
+	       "in compiled module \"%s\"."),
+	     TYPE_CODE (gdb_type_from_ptr), COMPILE_I_EXPR_PTR_TYPE,
+	     objfile_name (objfile));
+    }
+  if (!types_deeply_equal (gdb_type_from_ptr,
+			   TYPE_TARGET_TYPE (gdb_type)))
+    error (_("Referenced types do not match for symbols \"%s\" and \"%s\" "
+	     "in compiled module \"%s\"."),
+	   COMPILE_I_EXPR_PTR_TYPE, COMPILE_I_EXPR_VAL,
+	   objfile_name (objfile));
+  if (scope == COMPILE_I_PRINT_ADDRESS_SCOPE)
+    return NULL;
+  return retval;
+}
+
 /* Fetch the type of first parameter of FUNC_SYM.
    Return NULL if FUNC_SYM has no parameters.  Throw an error otherwise.  */
 
@@ -440,7 +549,9 @@ store_regs (struct type *regs_type, CORE_ADDR regs_base)
    Caller must fully dispose the return value by calling compile_object_run.
    SOURCE_FILE's copy is stored into the returned object.
    Caller should free both OBJECT_FILE and SOURCE_FILE immediatelly after this
-   function returns.  */
+   function returns.
+   Function returns NULL only for COMPILE_I_PRINT_ADDRESS_SCOPE when
+   COMPILE_I_PRINT_VALUE_SCOPE should have been used instead.  */
 
 struct compile_module *
 compile_object_load (const char *object_file, const char *source_file,
@@ -449,7 +560,7 @@ compile_object_load (const char *object_file, const char *source_file,
   struct cleanup *cleanups, *cleanups_free_objfile;
   bfd *abfd;
   struct setup_sections_data setup_sections_data;
-  CORE_ADDR addr, regs_addr;
+  CORE_ADDR addr, regs_addr, out_value_addr = 0;
   struct symbol *func_sym;
   struct type *func_type;
   struct bound_minimal_symbol bmsym;
@@ -459,7 +570,7 @@ compile_object_load (const char *object_file, const char *source_file,
   struct type *dptr_type = builtin_type (target_gdbarch ())->builtin_data_ptr;
   unsigned dptr_type_len = TYPE_LENGTH (dptr_type);
   struct compile_module *retval;
-  struct type *regs_type;
+  struct type *regs_type, *out_value_type = NULL;
   char *filename, **matching;
   struct objfile *objfile;
   int expect_parameters;
@@ -521,6 +632,11 @@ compile_object_load (const char *object_file, const char *source_file,
       expect_parameters = 0;
       expect_return_type = builtin_type (target_gdbarch ())->builtin_void;
       break;
+    case COMPILE_I_PRINT_ADDRESS_SCOPE:
+    case COMPILE_I_PRINT_VALUE_SCOPE:
+      expect_parameters = 2;
+      expect_return_type = builtin_type (target_gdbarch ())->builtin_void;
+      break;
     default:
       internal_error (__FILE__, __LINE__, _("invalid scope %d"), scope);
     }
@@ -597,6 +713,23 @@ compile_object_load (const char *object_file, const char *source_file,
       store_regs (regs_type, regs_addr);
     }
 
+  if (scope == COMPILE_I_PRINT_ADDRESS_SCOPE
+      || scope == COMPILE_I_PRINT_VALUE_SCOPE)
+    {
+      out_value_type = get_out_value_type (func_sym, objfile, scope);
+      if (out_value_type == NULL)
+	{
+	  do_cleanups (cleanups);
+	  return NULL;
+	}
+      check_typedef (out_value_type);
+      out_value_addr = gdbarch_infcall_mmap (target_gdbarch (),
+					     TYPE_LENGTH (out_value_type),
+					     (GDB_MMAP_PROT_READ
+					      | GDB_MMAP_PROT_WRITE));
+      gdb_assert (out_value_addr != 0);
+    }
+
   discard_cleanups (cleanups_free_objfile);
   do_cleanups (cleanups);
 
@@ -607,5 +740,7 @@ compile_object_load (const char *object_file, const char *source_file,
   retval->regs_addr = regs_addr;
   retval->scope = scope;
   retval->scope_data = scope_data;
+  retval->out_value_addr = out_value_addr;
+  retval->out_value_type = out_value_type;
   return retval;
 }
diff --git a/gdb/compile/compile-object-load.h b/gdb/compile/compile-object-load.h
index 94f77be..ac72a6a 100644
--- a/gdb/compile/compile-object-load.h
+++ b/gdb/compile/compile-object-load.h
@@ -37,6 +37,14 @@ struct compile_module
 
   /* User data for SCOPE in use.  */
   void *scope_data;
+
+  /* Inferior parameter out value address or NULL if the inferior function does not
+     have one.  */
+  CORE_ADDR out_value_addr;
+
+  /* Inferior parameter out value type or NULL if the inferior function does not
+     have one.  */
+  struct type *out_value_type;
 };
 
 extern struct compile_module *compile_object_load (const char *object_file,
diff --git a/gdb/compile/compile-object-run.c b/gdb/compile/compile-object-run.c
index c454bd1..216cbf9 100644
--- a/gdb/compile/compile-object-run.c
+++ b/gdb/compile/compile-object-run.c
@@ -25,6 +25,8 @@
 #include "compile-internal.h"
 #include "dummy-frame.h"
 #include "block.h"
+#include "valprint.h"
+#include "compile.h"
 
 /* Helper for do_module_cleanup.  */
 
@@ -41,6 +43,10 @@ struct do_module_cleanup
   enum compile_i_scope_types scope;
   void *scope_data;
 
+  /* Copy from struct compile_module.  */
+  CORE_ADDR out_value_addr;
+  struct type *out_value_type;
+
   /* objfile_name of our objfile.  */
   char objfile_name_string[1];
 };
@@ -56,7 +62,21 @@ do_module_cleanup (void *arg)
   struct objfile *objfile;
 
   if (data->executedp != NULL)
-    *data->executedp = 1;
+    {
+      *data->executedp = 1;
+
+      /* This code cannot be in compile_object_run as OUT_VALUE_TYPE
+	 no longer exists there.  */
+      if (data->scope == COMPILE_I_PRINT_ADDRESS_SCOPE
+	  || data->scope == COMPILE_I_PRINT_VALUE_SCOPE)
+	{
+	  struct value *addr_value;
+	  struct type *ptr_type = lookup_pointer_type (data->out_value_type);
+
+	  addr_value = value_from_pointer (ptr_type, data->out_value_addr);
+	  compile_print_value (value_ind (addr_value), data->scope_data);
+	}
+    }
 
   ALL_OBJFILES (objfile)
     if ((objfile->flags & OBJF_USERLOADED) == 0
@@ -104,6 +124,8 @@ compile_object_run (struct compile_module *module)
   strcpy (data->objfile_name_string, objfile_name_s);
   data->scope = module->scope;
   data->scope_data = module->scope_data;
+  data->out_value_addr = module->out_value_addr;
+  data->out_value_type = module->out_value_type;
 
   xfree (module->source_file);
   xfree (module);
@@ -133,6 +155,13 @@ compile_object_run (struct compile_module *module)
 			  (TYPE_FIELD_TYPE (func_type, current_arg), regs_addr);
 	  ++current_arg;
 	}
+      if (TYPE_NFIELDS (func_type) >= 2)
+	{
+	  gdb_assert (data->out_value_addr != 0);
+	  vargs[current_arg] = value_from_pointer
+	       (TYPE_FIELD_TYPE (func_type, current_arg), data->out_value_addr);
+	  ++current_arg;
+	}
       gdb_assert (current_arg == TYPE_NFIELDS (func_type));
       call_function_by_hand_dummy (func_val, TYPE_NFIELDS (func_type), vargs,
 				   do_module_cleanup, data);
diff --git a/gdb/compile/compile.c b/gdb/compile/compile.c
index ab19a5d..c4b8f2e 100644
--- a/gdb/compile/compile.c
+++ b/gdb/compile/compile.c
@@ -38,6 +38,7 @@
 #include "target.h"
 #include "osabi.h"
 #include "gdb_wait.h"
+#include "valprint.h"
 
 \f
 
@@ -163,6 +164,49 @@ compile_code_command (char *arg, int from_tty)
   do_cleanups (cleanup);
 }
 
+/* Callback for compile_print_command.  */
+
+void
+compile_print_value (struct value *val, void *data_voidp)
+{
+  const struct format_data *fmtp = data_voidp;
+
+  print_value (val, fmtp);
+}
+
+/* Handle the input from the 'compile print' command.  The "compile
+   print" command is used to evaluate and print an expression that may
+   contain calls to the GCC compiler.  The language expected in this
+   compile command is the language currently set in GDB.  */
+
+static void
+compile_print_command (char *arg_param, int from_tty)
+{
+  const char *arg = arg_param;
+  struct cleanup *cleanup;
+  enum compile_i_scope_types scope = COMPILE_I_PRINT_ADDRESS_SCOPE;
+  struct format_data *fmtp;
+
+  cleanup = make_cleanup_restore_integer (&interpreter_async);
+  interpreter_async = 0;
+
+  fmtp = print_command_parse_format (&arg, "compile print");
+
+  if (arg && *arg)
+    eval_compile_command (NULL, arg, scope, fmtp);
+  else
+    {
+      struct command_line *l = get_command_line (compile_control, "");
+
+      make_cleanup_free_command_lines (&l);
+      l->control_u.compile.scope = scope;
+      l->control_u.compile.scope_data = fmtp;
+      execute_control_command_untraced (l);
+    }
+
+  do_cleanups (cleanup);
+}
+
 /* A cleanup function to remove a directory and all its contents.  */
 
 static void
@@ -576,6 +620,14 @@ eval_compile_command (struct command_line *cmd, const char *cmd_string,
       make_cleanup (cleanup_unlink_file, source_file);
       compile_module = compile_object_load (object_file, source_file,
 					    scope, scope_data);
+      if (compile_module == NULL)
+	{
+	  gdb_assert (scope == COMPILE_I_PRINT_ADDRESS_SCOPE);
+	  do_cleanups (cleanup_xfree);
+	  eval_compile_command (cmd, cmd_string,
+				COMPILE_I_PRINT_VALUE_SCOPE, scope_data);
+	  return;
+	}
       discard_cleanups (cleanup_unlink);
       do_cleanups (cleanup_xfree);
       compile_object_run (compile_module);
@@ -654,6 +706,27 @@ Usage: compile file [-r|-raw] [filename]\n\
 	       &compile_command_list);
   set_cmd_completer (c, filename_completer);
 
+  add_cmd ("print", class_obscure, compile_print_command,
+	   _("\
+Evaluate EXPR with the compiler and print result.\n\
+\n\
+Usage: compile print[/FMT] [EXPR]\n\
+\n\
+The expression may be specified on the same line as the command, e.g.:\n\
+\n\
+    compile print i\n\
+\n\
+Alternatively, you can type the expression interactively.\n\
+You can invoke this mode when no argument is given to the command\n\
+(i.e., \"compile print\" is typed with nothing after it).  An\n\
+interactive prompt will be shown allowing you to enter multiple\n\
+lines of source code.  Type a line containing \"end\" to indicate\n\
+the end of the source code.\n\
+\n\
+EXPR may be preceded with /FMT, where FMT is a format letter\n\
+but no count or size letter (see \"x\" command)."),
+	   &compile_command_list);
+
   add_setshow_boolean_cmd ("compile", class_maintenance, &compile_debug, _("\
 Set compile command debugging."), _("\
 Show compile command debugging."), _("\
diff --git a/gdb/compile/compile.h b/gdb/compile/compile.h
index a973167..6e108c7 100644
--- a/gdb/compile/compile.h
+++ b/gdb/compile/compile.h
@@ -101,4 +101,6 @@ extern void compile_dwarf_bounds_to_c (struct ui_file *stream,
 				       const gdb_byte *op_end,
 				       struct dwarf2_per_cu_data *per_cu);
 
+extern void compile_print_value (struct value *val, void *data_voidp);
+
 #endif /* GDB_COMPILE_H */
diff --git a/gdb/defs.h b/gdb/defs.h
index 6476f80..f6e010c 100644
--- a/gdb/defs.h
+++ b/gdb/defs.h
@@ -70,6 +70,15 @@ enum compile_i_scope_types
     /* Do not wrap the expression,
        it has to provide function "_gdb_expr" on its own.  */
     COMPILE_I_RAW_SCOPE,
+
+    /* A printable expression scope.  Wrap an expression into a scope
+       suitable for the "compile print" command.  It uses the generic
+       function name "_gdb_expr".  COMPILE_I_PRINT_ADDRESS_SCOPE variant
+       is the usual one, taking address of the object.
+       COMPILE_I_PRINT_VALUE_SCOPE is needed for arrays where the array
+       name already specifies its address.  */
+    COMPILE_I_PRINT_ADDRESS_SCOPE,
+    COMPILE_I_PRINT_VALUE_SCOPE,
   };
 
 /* Just in case they're not defined in stdio.h.  */
diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo
index d794893..3eaf9d3 100644
--- a/gdb/doc/gdb.texinfo
+++ b/gdb/doc/gdb.texinfo
@@ -17223,6 +17223,25 @@ compile file /home/user/example.c
 @end smallexample
 @end table
 
+@table @code
+@item compile print @var{expr}
+@itemx compile print /@var{f} @var{expr}
+Compile @var{expr} with the compiler language found as the current
+language in @value{GDBN} (@pxref{Languages}).  By default the
+value of @var{expr} is printed in a format appropriate to its data type;
+you can choose a different format by specifying @samp{/@var{f}}, where
+@var{f} is a letter specifying the format; see @ref{Output Formats,,Output
+Formats}.
+
+@item compile print
+@itemx compile print /@var{f}
+@cindex reprint the last value
+Alternatively you can enter the expression (source code producing it) as
+multiple lines of text.  To enter this mode, invoke the @samp{compile print}
+command without any text following the command.  This will start the
+multiple-line editor.
+@end table
+
 @subsection Caveats when using the @code{compile} command
 
 There are a few caveats to keep in mind when using the @code{compile}
diff --git a/gdb/testsuite/gdb.compile/compile-print.c b/gdb/testsuite/gdb.compile/compile-print.c
new file mode 100644
index 0000000..e83b620
--- /dev/null
+++ b/gdb/testsuite/gdb.compile/compile-print.c
@@ -0,0 +1,32 @@
+/* This testcase is part of GDB, the GNU debugger.
+
+   Copyright 2015 Free Software Foundation, Inc.
+
+   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 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   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, see <http://www.gnu.org/licenses/>.  */
+
+#include <stdlib.h>
+
+int varint = 10;
+int vararray[] = { 1, 2, 3, 4, 5 };
+int *vararrayp = vararray;
+struct object
+{
+  int field;
+} varobject = { 1 };
+
+int
+main (void)
+{
+  return 0;
+}
diff --git a/gdb/testsuite/gdb.compile/compile-print.exp b/gdb/testsuite/gdb.compile/compile-print.exp
new file mode 100644
index 0000000..92c6240
--- /dev/null
+++ b/gdb/testsuite/gdb.compile/compile-print.exp
@@ -0,0 +1,58 @@
+# Copyright 2015 Free Software Foundation, Inc.
+
+# 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 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# 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, see <http://www.gnu.org/licenses/>.
+
+standard_testfile
+
+if { [prepare_for_testing ${testfile}.exp "$testfile"] } {
+    return -1
+}
+
+if ![runto_main] {
+    return -1
+}
+
+if {[skip_compile_feature_tests]} {
+    untested "compile command not supported (could not find libcc1 shared library?)"
+    return -1
+}
+
+gdb_test "compile print varint" " = 10"
+gdb_test "compile print vararray" " = \\{1, 2, 3, 4, 5\\}"
+gdb_test "compile print main" " = \\{int \\(void\\)\\} 0x\[0-9a-f\]+"
+
+set test "compile print *vararray@3"
+gdb_test_multiple $test $test {
+    -re " = \\{1, 2, 3\\}\r\n$gdb_prompt $" {
+	pass $test
+    }
+    -re ": error: stray '@' in program\r\n.*\r\n$gdb_prompt $" {
+	xfail "$test (gcc does not support '@')"
+    }
+}
+
+set test "compile print *vararrayp@3"
+gdb_test_multiple $test $test {
+    -re " = \\{1, 2, 3\\}\r\n$gdb_prompt $" {
+	pass $test
+    }
+    -re ": error: stray '@' in program\r\n.*\r\n$gdb_prompt $" {
+	xfail "$test (gcc does not support '@')"
+    }
+}
+
+gdb_test "compile print/x 256" " = 0x100"
+gdb_test {print $} " = 256"
+
+gdb_test "compile print varobject" { = {field = 1}}

^ permalink raw reply	[flat|nested] 30+ messages in thread

* [PATCH v2 5/9] compile: Use -Wall, not -w
  2015-04-06 17:26 [PATCH v2 0/9] compile: compile print&printf Jan Kratochvil
                   ` (4 preceding siblings ...)
  2015-04-06 17:27 ` [PATCH v2 7/9] compile: New 'compile print' Jan Kratochvil
@ 2015-04-06 17:27 ` Jan Kratochvil
  2015-04-06 17:27 ` [PATCH v2 9/9] compile: compile printf: gdbserver support Jan Kratochvil
                   ` (3 subsequent siblings)
  9 siblings, 0 replies; 30+ messages in thread
From: Jan Kratochvil @ 2015-04-06 17:27 UTC (permalink / raw)
  To: gdb-patches; +Cc: Phil Muldoon

Hi,

for a reason unknown to me GDB was using -w instead of -Wall for 'compile code'.
The problem is later patch for 'compile printf' really needs some warnings to
be able to catch for example missing format string parameters:
	(gdb) compile printf "%d\n"
GCC does not seem to be able to cancel -w (there is nothing like -no-w).

Besides that I think even 'compile code' can benefit from -Wall.

That #ifndef hack in print_one_macro() is not nice but while GCC does not warn
for redefinitions like
	#define MACRO val
	#define MACRO val
together with the GCC build-in macros I haven't found any other way how to
prevent the macro-redefinition warnings (when -w is no longer in effect).

That new testsuite XFAIL is there as if one changes the struct definition to be
compliant with cv-qualifiers (to prevent the warnings):
struct struct_type {
-  struct struct_type *selffield;
+  volatile struct struct_type *selffield;
only then GCC/GDB will hit the crash, described in that GDB PR 18202.


Thanks,
Jan


gdb/ChangeLog
2015-04-05  Jan Kratochvil  <jan.kratochvil@redhat.com>

	* compile/compile-c-support.c (print_one_macro): Use #ifndef.
	(generate_register_struct): Use __gdb_uintptr for TYPE_CODE_PTR.
	(c_compute_program): Call generate_register_struct after typedefs.
	* compile/compile-loc2c.c (push, pushf_register_address)
	(pushf_register): Cast to GCC_UINTPTR.
	(do_compile_dwarf_expr_to_c): Use unused attribute.  Add space after
	type.  Use GCC_UINTPTR instead of void *.  Remove excessive cast.
	(compile_dwarf_expr_to_c): Use GCC_UINTPTR instead of void *.
	* compile/compile.c (_initialize_compile): Enable warnings for
	COMPILE_ARGS.

gdb/testsuite/ChangeLog
2015-04-05  Jan Kratochvil  <jan.kratochvil@redhat.com>

	* gdb.compile/compile-ops.exp: Cast param to void.
	* gdb.compile/compile.exp: Complete type for _gdb_expr.
	(compile code struct_object.selffield = &struct_object): Add xfail.
---
 gdb/compile/compile-c-support.c           |   12 +++++++-----
 gdb/compile/compile-loc2c.c               |   22 +++++++++++++---------
 gdb/compile/compile.c                     |    7 +++++--
 gdb/testsuite/gdb.compile/compile-ops.exp |    2 +-
 gdb/testsuite/gdb.compile/compile.exp     |   15 ++++++++++-----
 5 files changed, 36 insertions(+), 22 deletions(-)

diff --git a/gdb/compile/compile-c-support.c b/gdb/compile/compile-c-support.c
index 1711cda..48a17e2 100644
--- a/gdb/compile/compile-c-support.c
+++ b/gdb/compile/compile-c-support.c
@@ -131,7 +131,9 @@ print_one_macro (const char *name, const struct macro_definition *macro,
   if (line == 0)
     return;
 
-  fprintf_filtered (file, "#define %s", name);
+  /* None of -Wno-builtin-macro-redefined, #undef first
+     or plain #define of the same value would avoid a warning.  */
+  fprintf_filtered (file, "#ifndef %s\n# define %s", name, name);
 
   if (macro->kind == macro_function_like)
     {
@@ -147,7 +149,7 @@ print_one_macro (const char *name, const struct macro_definition *macro,
       fputs_filtered (")", file);
     }
 
-  fprintf_filtered (file, " %s\n", macro->replacement);
+  fprintf_filtered (file, " %s\n#endif\n", macro->replacement);
 }
 
 /* Write macro definitions at PC to FILE.  */
@@ -252,7 +254,7 @@ generate_register_struct (struct ui_file *stream, struct gdbarch *gdbarch,
 	    switch (TYPE_CODE (regtype))
 	      {
 	      case TYPE_CODE_PTR:
-		fprintf_filtered (stream, "void *%s", regname);
+		fprintf_filtered (stream, "__gdb_uintptr %s", regname);
 		break;
 
 	      case TYPE_CODE_INT:
@@ -340,8 +342,6 @@ c_compute_program (struct compile_instance *inst,
 							  expr_block, expr_pc);
       make_cleanup (xfree, registers_used);
 
-      generate_register_struct (buf, gdbarch, registers_used);
-
       fputs_unfiltered ("typedef unsigned int"
 			" __attribute__ ((__mode__(__pointer__)))"
 			" __gdb_uintptr;\n",
@@ -363,6 +363,8 @@ c_compute_program (struct compile_instance *inst,
 			      " __gdb_int_%s;\n",
 			      mode, mode);
 	}
+
+      generate_register_struct (buf, gdbarch, registers_used);
     }
 
   add_code_header (inst->scope, buf);
diff --git a/gdb/compile/compile-loc2c.c b/gdb/compile/compile-loc2c.c
index 6a3615d..6f53814 100644
--- a/gdb/compile/compile-loc2c.c
+++ b/gdb/compile/compile-loc2c.c
@@ -436,7 +436,8 @@ compute_stack_depth (enum bfd_endian byte_order, unsigned int addr_size,
 static void
 push (int indent, struct ui_file *stream, ULONGEST l)
 {
-  fprintfi_filtered (indent, stream, "__gdb_stack[++__gdb_tos] = %s;\n",
+  fprintfi_filtered (indent, stream,
+		     "__gdb_stack[++__gdb_tos] = (" GCC_UINTPTR ") %s;\n",
 		     hex_string (l));
 }
 
@@ -520,7 +521,8 @@ pushf_register_address (int indent, struct ui_file *stream,
   struct cleanup *cleanups = make_cleanup (xfree, regname);
 
   registers_used[regnum] = 1;
-  pushf (indent, stream, "&" COMPILE_I_SIMPLE_REGISTER_ARG_NAME	 "->%s",
+  pushf (indent, stream,
+	 "(" GCC_UINTPTR ") &" COMPILE_I_SIMPLE_REGISTER_ARG_NAME "->%s",
 	 regname);
 
   do_cleanups (cleanups);
@@ -544,7 +546,8 @@ pushf_register (int indent, struct ui_file *stream,
     pushf (indent, stream, COMPILE_I_SIMPLE_REGISTER_ARG_NAME "->%s",
 	   regname);
   else
-    pushf (indent, stream, COMPILE_I_SIMPLE_REGISTER_ARG_NAME "->%s + %s",
+    pushf (indent, stream,
+	   COMPILE_I_SIMPLE_REGISTER_ARG_NAME "->%s + (" GCC_UINTPTR ") %s",
 	   regname, hex_string (offset));
 
   do_cleanups (cleanups);
@@ -605,7 +608,8 @@ do_compile_dwarf_expr_to_c (int indent, struct ui_file *stream,
 
   ++scope;
 
-  fprintfi_filtered (indent, stream, "%s%s;\n", type_name, result_name);
+  fprintfi_filtered (indent, stream, "__attribute__ ((unused)) %s %s;\n",
+		     type_name, result_name);
   fprintfi_filtered (indent, stream, "{\n");
   indent += 2;
 
@@ -899,7 +903,7 @@ do_compile_dwarf_expr_to_c (int indent, struct ui_file *stream,
 		       (long) (op_ptr - base));
 
 	    do_compile_dwarf_expr_to_c (indent, stream,
-					"void *", fb_name,
+					GCC_UINTPTR, fb_name,
 					sym, pc,
 					arch, registers_used, addr_size,
 					datastart, datastart + datalen,
@@ -1080,7 +1084,7 @@ do_compile_dwarf_expr_to_c (int indent, struct ui_file *stream,
 			   "__cfa_%ld", (long) (op_ptr - base));
 
 		do_compile_dwarf_expr_to_c (indent, stream,
-					    "void *", cfa_name,
+					    GCC_UINTPTR, cfa_name,
 					    sym, pc, arch, registers_used,
 					    addr_size,
 					    cfa_start, cfa_end,
@@ -1117,8 +1121,8 @@ do_compile_dwarf_expr_to_c (int indent, struct ui_file *stream,
 	}
     }
 
-  fprintfi_filtered (indent, stream, "%s = (%s) __gdb_stack[__gdb_tos];\n",
-		     result_name, type_name);
+  fprintfi_filtered (indent, stream, "%s = __gdb_stack[__gdb_tos];\n",
+		     result_name);
   fprintfi_filtered (indent - 2, stream, "}\n");
 
   do_cleanups (cleanup);
@@ -1134,7 +1138,7 @@ compile_dwarf_expr_to_c (struct ui_file *stream, const char *result_name,
 			 const gdb_byte *op_ptr, const gdb_byte *op_end,
 			 struct dwarf2_per_cu_data *per_cu)
 {
-  do_compile_dwarf_expr_to_c (2, stream, "void *", result_name, sym, pc,
+  do_compile_dwarf_expr_to_c (2, stream, GCC_UINTPTR, result_name, sym, pc,
 			      arch, registers_used, addr_size, op_ptr, op_end,
 			      NULL, per_cu);
 }
diff --git a/gdb/compile/compile.c b/gdb/compile/compile.c
index 621de66..ab19a5d 100644
--- a/gdb/compile/compile.c
+++ b/gdb/compile/compile.c
@@ -680,8 +680,11 @@ String quoting is parsed like in shell, for example:\n\
      absolute target address.
      -fPIC is not used at is would require from GDB to generate .got.  */
 			 " -fPIE"
-  /* We don't want warnings.  */
-			 " -w"
+  /* We want warnings, except for some commonly happening for GDB commands.  */
+			 " -Wall "
+			 " -Wno-implicit-function-declaration"
+			 " -Wno-unused-but-set-variable"
+			 " -Wno-unused-variable"
   /* Override CU's possible -fstack-protector-strong.  */
 			 " -fno-stack-protector"
   );
diff --git a/gdb/testsuite/gdb.compile/compile-ops.exp b/gdb/testsuite/gdb.compile/compile-ops.exp
index 26882bd..0ef3c8d 100644
--- a/gdb/testsuite/gdb.compile/compile-ops.exp
+++ b/gdb/testsuite/gdb.compile/compile-ops.exp
@@ -416,7 +416,7 @@ if {[skip_compile_feature_tests]} {
 }
 
 # If we have a bug, this will hang.
-gdb_test_no_output "compile code param"
+gdb_test_no_output "compile code (void) param"
 
 # We can't access optimized-out variables, but their presence should
 # not affect compilations that don't refer to them.
diff --git a/gdb/testsuite/gdb.compile/compile.exp b/gdb/testsuite/gdb.compile/compile.exp
index dc09770..abe5e9b 100644
--- a/gdb/testsuite/gdb.compile/compile.exp
+++ b/gdb/testsuite/gdb.compile/compile.exp
@@ -71,13 +71,13 @@ gdb_test_no_output "compile -- f = 10" \
 gdb_test "compile f = 10;" ".*= 10;: No such file.*" \
     "Test abbreviations and code collision"
 
-gdb_test_no_output "compile -r -- _gdb_expr(){int i = 5;}" \
+gdb_test_no_output "compile -r -- void _gdb_expr(){int i = 5;}" \
     "Test delimiter with -r"
 
-gdb_test_no_output "compile -raw -- _gdb_expr(){int i = 5;}" \
+gdb_test_no_output "compile -raw -- void _gdb_expr(){int i = 5;}" \
     "Test delimiter with -raw"
 
-gdb_test "compile -- -r  _gdb_expr(){int i = 5;}" \
+gdb_test "compile -- -r  void _gdb_expr(){int i = 5;}" \
     ".* error: 'r' undeclared \\(first use in this function\\).*" \
     "Test delimiter with -r after it"
 
@@ -189,7 +189,12 @@ gdb_test "p localvar" " = 1"
 # Test setting fields and also many different types.
 #
 
-gdb_test_no_output "compile code struct_object.selffield = &struct_object"
+set test "compile code struct_object.selffield = &struct_object"
+gdb_test_multiple $test $test {
+    -re "gdb command line:1:25: warning: assignment discards 'volatile' qualifier from pointer target type \\\[-Wdiscarded-qualifiers\\\]\r\n$gdb_prompt $" {
+	xfail "$test (PR compile/18202)"
+    }
+}
 gdb_test "print struct_object.selffield == &struct_object" " = 1"
 
 gdb_test_no_output "compile code struct_object.charfield = 1"
@@ -261,7 +266,7 @@ gdb_test "print 'compile.c'::globalshadow" " = 77000" \
 
 # Test GOT vs. resolving jit function pointers.
 
-gdb_test_no_output "compile -raw -- int func(){return 21;} _gdb_expr(){int (*funcp)()=func; if (funcp()!=21) abort();}" \
+gdb_test_no_output "compile -raw -- int func(){return 21;} void _gdb_expr(){ void abort (void); int (*funcp)()=func; if (funcp()!=21) abort(); }" \
     "pointer to jit function"
 
 #

^ permalink raw reply	[flat|nested] 30+ messages in thread

* [PATCH v2 6/9] Code cleanup: compile: func_addr -> func_sym
  2015-04-06 17:26 [PATCH v2 0/9] compile: compile print&printf Jan Kratochvil
                   ` (7 preceding siblings ...)
  2015-04-06 17:27 ` [PATCH v2 8/9] compile: New compile printf Jan Kratochvil
@ 2015-04-06 17:27 ` Jan Kratochvil
  2015-04-11 19:46 ` obsolete: [PATCH v2 0/9] compile: compile print&printf Jan Kratochvil
  9 siblings, 0 replies; 30+ messages in thread
From: Jan Kratochvil @ 2015-04-06 17:27 UTC (permalink / raw)
  To: gdb-patches; +Cc: Phil Muldoon

Hi,

currently the code fetches _gdb_expr address/types at multiple places, guessing
its parameters at multiple places etc.

Fetch it once, verify it has expected type and then rely on it.

While the patch tries to clean up the code it is still horrible due to the
missing C++ sub-classing.


Jan


gdb/ChangeLog
2015-04-06  Jan Kratochvil  <jan.kratochvil@redhat.com>

	* compile/compile-object-load.c (get_regs_type): Add parameter func_sym.
	Rely on its parameter count.
	(compile_object_load): Replace lookup_minimal_symbol_text by
	lookup_global_symbol_from_objfile.  Verify FUNC_SYM.  Set it in the
	return value.
	* compile/compile-object-load.h (struct compile_module): Replace
	func_addr by func_sym.
	* compile/compile-object-run.c: Include block.h.
	(compile_object_run): Reset module variable after it is freed.  Use
	FUNC_SYM instead of FUNC_ADDR.  Rely on it.
---
 gdb/compile/compile-object-load.c |   81 +++++++++++++++++++++----------------
 gdb/compile/compile-object-load.h |    4 +-
 gdb/compile/compile-object-run.c  |   43 ++++++++++++--------
 3 files changed, 76 insertions(+), 52 deletions(-)

diff --git a/gdb/compile/compile-object-load.c b/gdb/compile/compile-object-load.c
index ed2cad4..3c07840 100644
--- a/gdb/compile/compile-object-load.c
+++ b/gdb/compile/compile-object-load.c
@@ -354,40 +354,19 @@ copy_sections (bfd *abfd, asection *sect, void *data)
   do_cleanups (cleanups);
 }
 
-/* Fetch the type of first parameter of GCC_FE_WRAPPER_FUNCTION.
-   Return NULL if GCC_FE_WRAPPER_FUNCTION has no parameters.
-   Throw an error otherwise.  */
+/* Fetch the type of first parameter of FUNC_SYM.
+   Return NULL if FUNC_SYM has no parameters.  Throw an error otherwise.  */
 
 static struct type *
-get_regs_type (struct objfile *objfile)
+get_regs_type (struct symbol *func_sym, struct objfile *objfile)
 {
-  struct symbol *func_sym;
-  struct type *func_type, *regsp_type, *regs_type;
-
-  func_sym = lookup_global_symbol_from_objfile (objfile,
-						GCC_FE_WRAPPER_FUNCTION,
-						VAR_DOMAIN);
-  if (func_sym == NULL)
-    error (_("Cannot find function \"%s\" in compiled module \"%s\"."),
-	   GCC_FE_WRAPPER_FUNCTION, objfile_name (objfile));
-
-  func_type = SYMBOL_TYPE (func_sym);
-  if (TYPE_CODE (func_type) != TYPE_CODE_FUNC)
-    error (_("Invalid type code %d of function \"%s\" in compiled "
-	     "module \"%s\"."),
-	   TYPE_CODE (func_type), GCC_FE_WRAPPER_FUNCTION,
-	   objfile_name (objfile));
+  struct type *func_type = SYMBOL_TYPE (func_sym);
+  struct type *regsp_type, *regs_type;
 
   /* No register parameter present.  */
   if (TYPE_NFIELDS (func_type) == 0)
     return NULL;
 
-  if (TYPE_NFIELDS (func_type) != 1)
-    error (_("Invalid %d parameters of function \"%s\" in compiled "
-	     "module \"%s\"."),
-	   TYPE_NFIELDS (func_type), GCC_FE_WRAPPER_FUNCTION,
-	   objfile_name (objfile));
-
   regsp_type = check_typedef (TYPE_FIELD_TYPE (func_type, 0));
   if (TYPE_CODE (regsp_type) != TYPE_CODE_PTR)
     error (_("Invalid type code %d of first parameter of function \"%s\" "
@@ -470,7 +449,9 @@ compile_object_load (const char *object_file, const char *source_file,
   struct cleanup *cleanups, *cleanups_free_objfile;
   bfd *abfd;
   struct setup_sections_data setup_sections_data;
-  CORE_ADDR addr, func_addr, regs_addr;
+  CORE_ADDR addr, regs_addr;
+  struct symbol *func_sym;
+  struct type *func_type;
   struct bound_minimal_symbol bmsym;
   long storage_needed;
   asymbol **symbol_table, **symp;
@@ -481,6 +462,8 @@ compile_object_load (const char *object_file, const char *source_file,
   struct type *regs_type;
   char *filename, **matching;
   struct objfile *objfile;
+  int expect_parameters;
+  struct type *expect_return_type;
 
   filename = tilde_expand (object_file);
   cleanups = make_cleanup (xfree, filename);
@@ -515,11 +498,41 @@ compile_object_load (const char *object_file, const char *source_file,
   objfile = symbol_file_add_from_bfd (abfd, filename, 0, NULL, 0, NULL);
   cleanups_free_objfile = make_cleanup_free_objfile (objfile);
 
-  bmsym = lookup_minimal_symbol_text (GCC_FE_WRAPPER_FUNCTION, objfile);
-  if (bmsym.minsym == NULL || MSYMBOL_TYPE (bmsym.minsym) == mst_file_text)
-    error (_("Could not find symbol \"%s\" of compiled module \"%s\"."),
-	   GCC_FE_WRAPPER_FUNCTION, filename);
-  func_addr = BMSYMBOL_VALUE_ADDRESS (bmsym);
+  func_sym = lookup_global_symbol_from_objfile (objfile,
+						GCC_FE_WRAPPER_FUNCTION,
+						VAR_DOMAIN);
+  if (func_sym == NULL)
+    error (_("Cannot find function \"%s\" in compiled module \"%s\"."),
+	   GCC_FE_WRAPPER_FUNCTION, objfile_name (objfile));
+  func_type = SYMBOL_TYPE (func_sym);
+  if (TYPE_CODE (func_type) != TYPE_CODE_FUNC)
+    error (_("Invalid type code %d of function \"%s\" in compiled "
+	     "module \"%s\"."),
+	   TYPE_CODE (func_type), GCC_FE_WRAPPER_FUNCTION,
+	   objfile_name (objfile));
+
+  switch (scope)
+    {
+    case COMPILE_I_SIMPLE_SCOPE:
+      expect_parameters = 1;
+      expect_return_type = builtin_type (target_gdbarch ())->builtin_void;
+      break;
+    case COMPILE_I_RAW_SCOPE:
+      expect_parameters = 0;
+      expect_return_type = builtin_type (target_gdbarch ())->builtin_void;
+      break;
+    default:
+      internal_error (__FILE__, __LINE__, _("invalid scope %d"), scope);
+    }
+  if (TYPE_NFIELDS (func_type) != expect_parameters)
+    error (_("Invalid %d parameters of function \"%s\" in compiled "
+	     "module \"%s\"."),
+	   TYPE_NFIELDS (func_type), GCC_FE_WRAPPER_FUNCTION,
+	   objfile_name (objfile));
+  if (!types_deeply_equal (expect_return_type, TYPE_TARGET_TYPE (func_type)))
+    error (_("Invalid return type of function \"%s\" in compiled "
+	    "module \"%s\"."),
+	  GCC_FE_WRAPPER_FUNCTION, objfile_name (objfile));
 
   /* The memory may be later needed
      by bfd_generic_get_relocated_section_contents
@@ -571,7 +584,7 @@ compile_object_load (const char *object_file, const char *source_file,
 
   bfd_map_over_sections (abfd, copy_sections, symbol_table);
 
-  regs_type = get_regs_type (objfile);
+  regs_type = get_regs_type (func_sym, objfile);
   if (regs_type == NULL)
     regs_addr = 0;
   else
@@ -590,7 +603,7 @@ compile_object_load (const char *object_file, const char *source_file,
   retval = xmalloc (sizeof (*retval));
   retval->objfile = objfile;
   retval->source_file = xstrdup (source_file);
-  retval->func_addr = func_addr;
+  retval->func_sym = func_sym;
   retval->regs_addr = regs_addr;
   retval->scope = scope;
   retval->scope_data = scope_data;
diff --git a/gdb/compile/compile-object-load.h b/gdb/compile/compile-object-load.h
index 4f9493b..94f77be 100644
--- a/gdb/compile/compile-object-load.h
+++ b/gdb/compile/compile-object-load.h
@@ -25,8 +25,8 @@ struct compile_module
   /* .c file OBJFILE was built from.  It needs to be xfree-d.  */
   char *source_file;
 
-  /* Inferior function address.  */
-  CORE_ADDR func_addr;
+  /* Inferior function GCC_FE_WRAPPER_FUNCTION.  */
+  struct symbol *func_sym;
 
   /* Inferior registers address or NULL if the inferior function does not
      require any.  */
diff --git a/gdb/compile/compile-object-run.c b/gdb/compile/compile-object-run.c
index bfd2473..c454bd1 100644
--- a/gdb/compile/compile-object-run.c
+++ b/gdb/compile/compile-object-run.c
@@ -24,6 +24,7 @@
 #include "objfiles.h"
 #include "compile-internal.h"
 #include "dummy-frame.h"
+#include "block.h"
 
 /* Helper for do_module_cleanup.  */
 
@@ -93,8 +94,9 @@ compile_object_run (struct compile_module *module)
   struct do_module_cleanup *data;
   const char *objfile_name_s = objfile_name (module->objfile);
   int dtor_found, executed = 0;
-  CORE_ADDR func_addr = module->func_addr;
+  struct symbol *func_sym = module->func_sym;
   CORE_ADDR regs_addr = module->regs_addr;
+  struct objfile *objfile = module->objfile;
 
   data = xmalloc (sizeof (*data) + strlen (objfile_name_s));
   data->executedp = &executed;
@@ -105,26 +107,35 @@ compile_object_run (struct compile_module *module)
 
   xfree (module->source_file);
   xfree (module);
+  module = NULL;
 
   TRY
     {
-      func_val = value_from_pointer
-		 (builtin_type (target_gdbarch ())->builtin_func_ptr,
-		  func_addr);
-
-      if (regs_addr == 0)
-	call_function_by_hand_dummy (func_val, 0, NULL,
-				     do_module_cleanup, data);
-      else
+      struct type *func_type = SYMBOL_TYPE (func_sym);
+      htab_t copied_types;
+      int current_arg = 0;
+      struct value **vargs;
+
+      /* OBJFILE may disappear while FUNC_TYPE still will be in use.  */
+      copied_types = create_copied_types_hash (objfile);
+      func_type = copy_type_recursive (objfile, func_type, copied_types);
+      htab_delete (copied_types);
+
+      gdb_assert (TYPE_CODE (func_type) == TYPE_CODE_FUNC);
+      func_val = value_from_pointer (lookup_pointer_type (func_type),
+				   BLOCK_START (SYMBOL_BLOCK_VALUE (func_sym)));
+
+      vargs = alloca (sizeof (*vargs) * TYPE_NFIELDS (func_type));
+      if (TYPE_NFIELDS (func_type) >= 1)
 	{
-	  struct value *arg_val;
-
-	  arg_val = value_from_pointer
-		    (builtin_type (target_gdbarch ())->builtin_func_ptr,
-		     regs_addr);
-	  call_function_by_hand_dummy (func_val, 1, &arg_val,
-				       do_module_cleanup, data);
+	  gdb_assert (regs_addr != 0);
+	  vargs[current_arg] = value_from_pointer
+			  (TYPE_FIELD_TYPE (func_type, current_arg), regs_addr);
+	  ++current_arg;
 	}
+      gdb_assert (current_arg == TYPE_NFIELDS (func_type));
+      call_function_by_hand_dummy (func_val, TYPE_NFIELDS (func_type), vargs,
+				   do_module_cleanup, data);
     }
   CATCH (ex, RETURN_MASK_ERROR)
     {

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [PATCH v2 7/9] compile: New 'compile print'
  2015-04-06 17:27 ` [PATCH v2 7/9] compile: New 'compile print' Jan Kratochvil
@ 2015-04-06 17:41   ` Eli Zaretskii
  2015-04-06 17:49     ` Paul_Koning
  2015-04-11 19:20     ` Jan Kratochvil
  0 siblings, 2 replies; 30+ messages in thread
From: Eli Zaretskii @ 2015-04-06 17:41 UTC (permalink / raw)
  To: Jan Kratochvil; +Cc: gdb-patches, pmuldoon

> From: Jan Kratochvil <jan.kratochvil@redhat.com>
> Cc: Phil Muldoon <pmuldoon@redhat.com>
> Date: Mon, 06 Apr 2015 19:27:16 +0200
> 
> --- a/gdb/NEWS
> +++ b/gdb/NEWS
> @@ -53,6 +53,9 @@ record btrace bts
>  record bts
>    Start branch trace recording using Branch Trace Store (BTS) format.
>  
> +compile print
> +  Evaluate expression with the compiler and print result.

Perhaps "by using the compiler" or "by compiling and running it"?
Saying "with the compiler" is slightly incorrect here, and might even
be confusing, if some non-native speaker interprets the "with" as
referring to "expression" and not to "evaluate".

> +  add_cmd ("print", class_obscure, compile_print_command,
> +	   _("\
> +Evaluate EXPR with the compiler and print result.\n\

Same here.

> +Alternatively, you can type the expression interactively.\n\
> +You can invoke this mode when no argument is given to the command\n\
> +(i.e., \"compile print\" is typed with nothing after it).  An\n\
> +interactive prompt will be shown allowing you to enter multiple\n\
> +lines of source code.  Type a line containing \"end\" to indicate\n\
> +the end of the source code.\n\

I suggest to rephrase:

  Alternatively, you can type a multiline expression by invoking
  this command with no argument.  GDB will then prompt for the
  expression interactively; type a line containing "end" to
  indicate the end of the expression.

> +@table @code
> +@item compile print @var{expr}
> +@itemx compile print /@var{f} @var{expr}
> +Compile @var{expr} with the compiler language found as the current

"Compile and execute", I would think.

The documentation parts are OK with those changes.

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [PATCH v2 9/9] compile: compile printf: gdbserver support
  2015-04-06 17:27 ` [PATCH v2 9/9] compile: compile printf: gdbserver support Jan Kratochvil
@ 2015-04-06 17:43   ` Eli Zaretskii
  2015-04-11 19:23     ` Jan Kratochvil
  0 siblings, 1 reply; 30+ messages in thread
From: Eli Zaretskii @ 2015-04-06 17:43 UTC (permalink / raw)
  To: Jan Kratochvil; +Cc: gdb-patches, pmuldoon

> From: Jan Kratochvil <jan.kratochvil@redhat.com>
> Cc: Phil Muldoon <pmuldoon@redhat.com>
> Date: Mon, 06 Apr 2015 19:27:35 +0200
> 
> --- a/gdb/doc/gdb.texinfo
> +++ b/gdb/doc/gdb.texinfo
> @@ -17246,7 +17246,9 @@ multiple-line editor.
>  @item compile printf @var{template}, @var{expressions}@dots{}
>  Compile and execute @code{printf} function call with the compiler
>  language found as the current language in @value{GDBN}
> -(@pxref{Languages}).
> +(@pxref{Languages}).  Inferior executes @code{open_memstream} and
> +@code{fprintf} instead so that the produced string is printed by
> +@value{GDBN} and not the inferior.

Is this really important to say in the manual?

And if it is, why not simply say that the value is printed by GDB
itself, not by calling functions in the inferior?

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [PATCH v2 7/9] compile: New 'compile print'
  2015-04-06 17:41   ` Eli Zaretskii
@ 2015-04-06 17:49     ` Paul_Koning
  2015-04-06 17:52       ` Jan Kratochvil
  2015-04-11 19:20     ` Jan Kratochvil
  1 sibling, 1 reply; 30+ messages in thread
From: Paul_Koning @ 2015-04-06 17:49 UTC (permalink / raw)
  To: eliz; +Cc: jan.kratochvil, gdb-patches, pmuldoon


> On Apr 6, 2015, at 1:41 PM, Eli Zaretskii <eliz@gnu.org> wrote:
> 
>> From: Jan Kratochvil <jan.kratochvil@redhat.com>
>> Cc: Phil Muldoon <pmuldoon@redhat.com>
>> Date: Mon, 06 Apr 2015 19:27:16 +0200
>> 
>> --- a/gdb/NEWS
>> +++ b/gdb/NEWS
>> @@ -53,6 +53,9 @@ record btrace bts
>> record bts
>>   Start branch trace recording using Branch Trace Store (BTS) format.
>> 
>> +compile print
>> +  Evaluate expression with the compiler and print result.
> 
> Perhaps "by using the compiler" or "by compiling and running it"?
> Saying "with the compiler" is slightly incorrect here, and might even
> be confusing, if some non-native speaker interprets the "with" as
> referring to "expression" and not to "evaluate”.

That’s still not fully clear.  If it actually is compile-and-run (as opposed to using the compiler to evaluate a compile-time expression), where does it run?  Presumably on the target.  Does it only work for native gdb?  Does it work with gdbserver?  It would be good to state the limitations and assumptions.

Also, “the compiler” begs the question: which one, i.e., how is “the compiler” found?

	paul


^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [PATCH v2 7/9] compile: New 'compile print'
  2015-04-06 17:49     ` Paul_Koning
@ 2015-04-06 17:52       ` Jan Kratochvil
  2015-04-06 18:00         ` Paul_Koning
  2015-04-06 18:47         ` Jan Kratochvil
  0 siblings, 2 replies; 30+ messages in thread
From: Jan Kratochvil @ 2015-04-06 17:52 UTC (permalink / raw)
  To: Paul_Koning; +Cc: eliz, gdb-patches, pmuldoon

On Mon, 06 Apr 2015 19:49:28 +0200, Paul_Koning@dell.com wrote:
> where does it run?  Presumably on the target.

Yes.

> Does it only work for native gdb?

Yes.

> Does it work with gdbserver?

Yes.

> It would be good to state the limitations and assumptions.

I am not aware of any, there may be needed some target-specific support like
for s390 gcc -m31 but in general it should work.

I could pick some 10 years old discussion that NEWS file should not contain
limitations, that those are just bugs for future ChangeLog entries.


> Also, “the compiler” begs the question: which one, i.e., how is “the
> compiler” found?

A complicated way, for non-native targets an appropriate cross-gcc should be
found.


Jan

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [PATCH v2 7/9] compile: New 'compile print'
  2015-04-06 17:52       ` Jan Kratochvil
@ 2015-04-06 18:00         ` Paul_Koning
  2015-04-08 20:03           ` Jan Kratochvil
  2015-04-08 20:12           ` [PATCH v2 7/9] compile: New 'compile print' Paul_Koning
  2015-04-06 18:47         ` Jan Kratochvil
  1 sibling, 2 replies; 30+ messages in thread
From: Paul_Koning @ 2015-04-06 18:00 UTC (permalink / raw)
  To: jan.kratochvil; +Cc: eliz, gdb-patches, pmuldoon


> On Apr 6, 2015, at 1:52 PM, Jan Kratochvil <jan.kratochvil@redhat.com> wrote:
> 
> On Mon, 06 Apr 2015 19:49:28 +0200, Paul_Koning@dell.com wrote:
>> where does it run?  Presumably on the target.
> 
> Yes.
> 
>> Does it only work for native gdb?
> 
> Yes.
> 
>> Does it work with gdbserver?
> 
> Yes.
> 
>> It would be good to state the limitations and assumptions.
> 
> I am not aware of any, there may be needed some target-specific support like
> for s390 gcc -m31 but in general it should work.
> 
> I could pick some 10 years old discussion that NEWS file should not contain
> limitations, that those are just bugs for future ChangeLog entries.

I meant limitations such as “native only”.   But given that it works across the board (give or take bugs) I agree that NEWS doesn’t need to say anything further.
> 
> 
>> Also, “the compiler” begs the question: which one, i.e., how is “the
>> compiler” found?
> 
> A complicated way, for non-native targets an appropriate cross-gcc should be
> found.

Ok.  I would not expect that to be documented in NEWS, but it seems like it should be in gdb.texinfo or some similar spot.  I have a whole pile of cross-compilers in various places; I would need to understand what the algorithm looks like to be able to ensure that the correct one is found.  

	paul

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [PATCH v2 7/9] compile: New 'compile print'
  2015-04-06 17:52       ` Jan Kratochvil
  2015-04-06 18:00         ` Paul_Koning
@ 2015-04-06 18:47         ` Jan Kratochvil
  1 sibling, 0 replies; 30+ messages in thread
From: Jan Kratochvil @ 2015-04-06 18:47 UTC (permalink / raw)
  To: Paul_Koning; +Cc: eliz, gdb-patches, pmuldoon

On Mon, 06 Apr 2015 19:52:50 +0200, Jan Kratochvil wrote:
> On Mon, 06 Apr 2015 19:49:28 +0200, Paul_Koning@dell.com wrote:
> > Does it only work for native gdb?
> 
> Yes.

No; that was a mistake but that was probably clear from the text below.


Jan

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [PATCH v2 7/9] compile: New 'compile print'
  2015-04-06 18:00         ` Paul_Koning
@ 2015-04-08 20:03           ` Jan Kratochvil
  2015-04-09  7:39             ` Eli Zaretskii
  2015-04-08 20:12           ` [PATCH v2 7/9] compile: New 'compile print' Paul_Koning
  1 sibling, 1 reply; 30+ messages in thread
From: Jan Kratochvil @ 2015-04-08 20:03 UTC (permalink / raw)
  To: Paul_Koning; +Cc: eliz, gdb-patches, pmuldoon

On Mon, 06 Apr 2015 19:58:31 +0200, Paul_Koning@dell.com wrote:
> On Apr 6, 2015, at 1:52 PM, Jan Kratochvil <jan.kratochvil@redhat.com> wrote:
> > On Mon, 06 Apr 2015 19:49:28 +0200, Paul_Koning@dell.com wrote:
> > > Also, “the compiler” begs the question: which one, i.e., how is “the
> > > compiler” found?
> > 
> > A complicated way, for non-native targets an appropriate cross-gcc should be
> > found.
> 
> Ok.  I would not expect that to be documented in NEWS, but it seems like it
> should be in gdb.texinfo or some similar spot.  I have a whole pile of
> cross-compilers in various places; I would need to understand what the
> algorithm looks like to be able to ensure that the correct one is found.  

I find it should "just work":
gdb:
	compile_to_object():
	ARCH(-[^-]*)?-OS
	ARCH=gdbarch_gnu_triplet_regexp
		i386/x86_64: (x86_64|i.86)
		s390/s390x: s390x?
		*: bfd_arch_info::arch_name
	OS=gdb_osabi_names.regexp
		GNU/Linux: linux(-gnu)?
		*: ""
gcc:
	libcc1_set_arguments()->find_compiler():
		$PATH

Just make your cross-compiler accessible by $PATH and cross your fingers.
If it does not work it is a bug that should be filed+fixed.

It is questionable whether it should be in GDB manual or GCC manual.
So far the GCC manual does not mention GCC's libcc1 GDB interface at all.


Jan

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [PATCH v2 7/9] compile: New 'compile print'
  2015-04-06 18:00         ` Paul_Koning
  2015-04-08 20:03           ` Jan Kratochvil
@ 2015-04-08 20:12           ` Paul_Koning
  2015-04-08 20:33             ` Jan Kratochvil
  1 sibling, 1 reply; 30+ messages in thread
From: Paul_Koning @ 2015-04-08 20:12 UTC (permalink / raw)
  To: jan.kratochvil; +Cc: eliz, gdb-patches, pmuldoon


> On Apr 6, 2015, at 1:58 PM, paul_koning@dell.com wrote:
> 
> 
>> On Apr 6, 2015, at 1:52 PM, Jan Kratochvil <jan.kratochvil@redhat.com> wrote:
>> ...
>>> Also, “the compiler” begs the question: which one, i.e., how is “the
>>> compiler” found?
>> 
>> A complicated way, for non-native targets an appropriate cross-gcc should be
>> found.
> 
> Ok.  I would not expect that to be documented in NEWS, but it seems like it should be in gdb.texinfo or some similar spot.  I have a whole pile of cross-compilers in various places; I would need to understand what the algorithm looks like to be able to ensure that the correct one is found.  

A related question: what controls the compiler switches sent to the compiler for this operation?  In some cases, specific switches may be needed to produce the correct flavor of code generation, say -msoft-float or -mabi=xyz.

	paul

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [PATCH v2 7/9] compile: New 'compile print'
  2015-04-08 20:12           ` [PATCH v2 7/9] compile: New 'compile print' Paul_Koning
@ 2015-04-08 20:33             ` Jan Kratochvil
  0 siblings, 0 replies; 30+ messages in thread
From: Jan Kratochvil @ 2015-04-08 20:33 UTC (permalink / raw)
  To: Paul_Koning; +Cc: eliz, gdb-patches, pmuldoon

On Wed, 08 Apr 2015 22:11:58 +0200, Paul_Koning@dell.com wrote:
> A related question: what controls the compiler switches sent to the compiler
> for this operation?  In some cases, specific switches may be needed to
> produce the correct flavor of code generation, say -msoft-float or
> -mabi=xyz.

gdbarch_gcc_target_options()
DW_AT_producer - -grecord-gcc-switches - gcc default if DWARF is present
Some GDB overrides like -O0 -gdwarf-4 -fPIE etc.

The specific switched you mention should get applied by DW_AT_producer.
Some basic ones may be provided already by gdbarch_gcc_target_options().


Jan

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [PATCH v2 7/9] compile: New 'compile print'
  2015-04-08 20:03           ` Jan Kratochvil
@ 2015-04-09  7:39             ` Eli Zaretskii
  2015-04-09 17:40               ` [doc patch] compile: missing bits [Re: [PATCH v2 7/9] compile: New 'compile print'] Jan Kratochvil
  0 siblings, 1 reply; 30+ messages in thread
From: Eli Zaretskii @ 2015-04-09  7:39 UTC (permalink / raw)
  To: Jan Kratochvil; +Cc: Paul_Koning, gdb-patches, pmuldoon

> Date: Wed, 8 Apr 2015 22:03:15 +0200
> From: Jan Kratochvil <jan.kratochvil@redhat.com>
> Cc: eliz@gnu.org, gdb-patches@sourceware.org, pmuldoon@redhat.com
> 
> Just make your cross-compiler accessible by $PATH and cross your fingers.
> If it does not work it is a bug that should be filed+fixed.
> 
> It is questionable whether it should be in GDB manual or GCC manual.
> So far the GCC manual does not mention GCC's libcc1 GDB interface at all.

"Cross your fingers" is not a good proactive policy for someone who
has several different compilers installed.  They need the information
requested by Paul to adapt this feature to their complex setups, which
we here will never be able to second-guess.

So I think we should tell the story in the manual, yes.

^ permalink raw reply	[flat|nested] 30+ messages in thread

* [doc patch] compile: missing bits  [Re: [PATCH v2 7/9] compile: New 'compile print']
  2015-04-09  7:39             ` Eli Zaretskii
@ 2015-04-09 17:40               ` Jan Kratochvil
  2015-04-09 18:12                 ` Eli Zaretskii
  0 siblings, 1 reply; 30+ messages in thread
From: Jan Kratochvil @ 2015-04-09 17:40 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: Paul_Koning, gdb-patches, pmuldoon

[-- Attachment #1: Type: text/plain, Size: 218 bytes --]

Hi Eli,

On Thu, 09 Apr 2015 09:39:46 +0200, Eli Zaretskii wrote:
> So I think we should tell the story in the manual, yes.

there were various missing bits for the 'compile' feature so adding them here.


Thanks,
Jan

[-- Attachment #2: 1 --]
[-- Type: text/plain, Size: 4053 bytes --]

gdb/doc/
2015-04-09  Jan Kratochvil  <jan.kratochvil@redhat.com>

	* gdb.texinfo (Compiling and Injecting Code): Describe set debug 
	compile, show debug compile.  New subsection Compilation options for 
	the compile command.  New subsection Compiler search for the compile
	command.

diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo
index d794893..ac50ea8 100644
--- a/gdb/doc/gdb.texinfo
+++ b/gdb/doc/gdb.texinfo
@@ -17223,6 +17223,66 @@ compile file /home/user/example.c
 @end smallexample
 @end table
 
+@noindent
+The process of compiling and injecting the code can be inspected using:
+
+@table @code
+@anchor{set debug compile}
+@item set debug compile
+@cindex compile command debugging info
+Turns on or off display of @value{GDBN} process of compiling and
+injecting the code.  The default is off.
+
+@item show debug compile
+Displays the current state of displaying @value{GDBN} process of
+compiling and injecting the code.
+@end table
+
+@subsection Compilation options for the @code{compile} command
+
+@value{GDBN} needs to specify the right compilation options for the code
+to be injected.  In part to make its ABI compatible with the inferior
+and in part to make the injected code compatible with GDB's injecting
+process.
+
+@noindent
+The options used, in increasing precedence:
+
+@table @asis
+@item target architecture and OS options (@code{gdbarch})
+These options depend on target processor type and target operating
+system, usually they specify at least 32-bit (@code{-m32}) or 64-bit
+(@code{-m64}) compilation option.
+
+@item compilation options recorded in the target
+@value{NGCC} (since version 4.7) stores the options used for compilation
+into @code{DW_AT_producer} part of DWARF debugging information according
+to the @value{NGCC} option @code{-grecord-gcc-switches}.  One has to
+explicitly specify @code{-g} during inferior compilation otherwise
+@value{NGCC} produces no DWARF.
+
+@item set compile-args
+@value{GDBN} contains default compilation options to set and possibly
+override the options required for proper injection of the compiled code.
+@end table
+
+@noindent
+The options mentioned last can be specified with command:
+
+@table @code
+@item set compile-args
+@cindex compile command options override
+Set compilation options used for compiling and injecting code with the
+@code{compile} commands.  These options override any conflicting ones
+from the target architecture and/or options stored during inferior
+compilation.
+
+@item show compile-args
+Displays the current state of compilation options override.
+This does not show all the options actually used during compilation,
+use @ref{set debug compile} for that.
+@end table
+
 @subsection Caveats when using the @code{compile} command
 
 There are a few caveats to keep in mind when using the @code{compile}
@@ -17380,6 +17440,24 @@ Access to those variables will generate a compiler error which @value{GDBN}
 will print to the console.
 @end table
 
+@subsection Compiler search for the @code{compile} command
+
+@value{GDBN} needs to find @value{NGCC} for the inferior being debugged which
+may not be obvious for remote targets of different architecture than where
+@value{GDBN} is running.  Environment variable @code{PATH} (@code{PATH} from
+shell that executed @value{GDBN}, not the one set by @value{GDBN}
+command @code{set environment}.  @xref{Environment}.  @code{PATH} on
+@value{GDBN} host is searched for @value{NGCC} binary matching the
+target architecture and operating system.
+
+Specifically @code{PATH} is searched for binaries matching regular expression
+@code{@var{ARCH}(-[^-]*)?-@var{OS}-gcc} according to the inferior target being
+debugged.  @code{@var{ARCH}} is processor name - multiarch is supported,
+so for example both @code{i386} and @code{x86_64} targets look for pattern
+@code{(x86_64|i.86)} and both @code{s390} and @code{s390x} targets look
+for pattern @code{s390x?}.  @code{OS} is currently supported only for
+pattern @code{linux(-gnu)?}.
+
 @node GDB Files
 @chapter @value{GDBN} Files
 

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [doc patch] compile: missing bits  [Re: [PATCH v2 7/9] compile: New 'compile print']
  2015-04-09 17:40               ` [doc patch] compile: missing bits [Re: [PATCH v2 7/9] compile: New 'compile print'] Jan Kratochvil
@ 2015-04-09 18:12                 ` Eli Zaretskii
  2015-04-10  8:09                   ` Jan Kratochvil
  0 siblings, 1 reply; 30+ messages in thread
From: Eli Zaretskii @ 2015-04-09 18:12 UTC (permalink / raw)
  To: Jan Kratochvil; +Cc: Paul_Koning, gdb-patches, pmuldoon

> Date: Thu, 9 Apr 2015 19:39:50 +0200
> From: Jan Kratochvil <jan.kratochvil@redhat.com>
> Cc: Paul_Koning@dell.com, gdb-patches@sourceware.org, pmuldoon@redhat.com
> 
> On Thu, 09 Apr 2015 09:39:46 +0200, Eli Zaretskii wrote:
> > So I think we should tell the story in the manual, yes.
> 
> there were various missing bits for the 'compile' feature so adding them here.

Thanks.

> +@value{GDBN} needs to specify the right compilation options for the code
> +to be injected.  In part to make its ABI compatible with the inferior
> +and in part to make the injected code compatible with GDB's injecting
> +process.

The second sentence is not a complete sentence; suggest to make it
part of the first (as in "...to be injected, in part to make its
ABI...").

Also, there's a bare "GDB" there.

> +@value{NGCC} (since version 4.7) stores the options used for compilation
> +into @code{DW_AT_producer} part of DWARF debugging information according
> +to the @value{NGCC} option @code{-grecord-gcc-switches}.  One has to
> +explicitly specify @code{-g} during inferior compilation otherwise
> +@value{NGCC} produces no DWARF.

Hmm...  Are you sure -g always produces DWARF?  Maybe we should say
that for targets where DWARF is not the default, -gdwarf-N should be
used, and also that -gstabs etc. should _not_ be used?

> +@item set compile-args
> +@value{GDBN} contains default compilation options to set and possibly
> +override the options required for proper injection of the compiled code.
> +@end table
> +
> +@noindent
> +The options mentioned last can be specified with command:
> +
> +@table @code
> +@item set compile-args

This is slightly confusing.  I suggest the following text instead:

 @item compilation options set by @code{set compile-args}
 @end table

 @noindent
 You can override compilation options using the following command:

 @table @code
 @item set compile-args
 @cindex compile command options override
 Set compilation options used for compiling and injecting code with the
 @code{compile} commands.  These options override any conflicting ones
 from the target architecture and/or options stored during inferior
 compilation.
 
 @item show compile-args
 Displays the current state of compilation options override.
 This does not show all the options actually used during compilation,
 use @ref{set debug compile} for that.
 @end table

> +@value{GDBN} needs to find @value{NGCC} for the inferior being debugged which
> +may not be obvious for remote targets of different architecture than where
> +@value{GDBN} is running.  Environment variable @code{PATH} (@code{PATH} from
> +shell that executed @value{GDBN}, not the one set by @value{GDBN}
> +command @code{set environment}.  @xref{Environment}.  @code{PATH} on

There's a right parenthesis missing here.

> +Specifically @code{PATH} is searched for binaries matching regular expression
> +@code{@var{ARCH}(-[^-]*)?-@var{OS}-gcc} according to the inferior target being
> +debugged.  @code{@var{ARCH}} is processor name - multiarch is supported,

Please don't up-case ARCH and OS, makeinfo will do that when needed.

Also, please use "---" instead of just one dash.

> +for pattern @code{s390x?}.  @code{OS} is currently supported only for
>                              ^^^^^^^^^

@var{os}.

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [doc patch] compile: missing bits  [Re: [PATCH v2 7/9] compile: New 'compile print']
  2015-04-09 18:12                 ` Eli Zaretskii
@ 2015-04-10  8:09                   ` Jan Kratochvil
  2015-04-10  8:31                     ` Eli Zaretskii
  2015-04-10 14:09                     ` Paul_Koning
  0 siblings, 2 replies; 30+ messages in thread
From: Jan Kratochvil @ 2015-04-10  8:09 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: Paul_Koning, gdb-patches, pmuldoon

[-- Attachment #1: Type: text/plain, Size: 1676 bytes --]

On Thu, 09 Apr 2015 20:12:21 +0200, Eli Zaretskii wrote:
> > +@value{NGCC} (since version 4.7) stores the options used for compilation
> > +into @code{DW_AT_producer} part of DWARF debugging information according
> > +to the @value{NGCC} option @code{-grecord-gcc-switches}.  One has to
> > +explicitly specify @code{-g} during inferior compilation otherwise
> > +@value{NGCC} produces no DWARF.
> 
> Hmm...  Are you sure -g always produces DWARF?  Maybe we should say
> that for targets where DWARF is not the default, -gdwarf-N should be
> used, and also that -gstabs etc. should _not_ be used?

While you are technically right I do not think it is appropriate to mention it
that way.

When some platform is still using -gstabs by default (is there any?) there are
probably some serious reasons for it - such as some old debugging / crash
analysing tools incompatible with DWARF.  Using -gdwarf-X may do more harm
than good there IMO; unless one really knows what s/he is doing and then one
does not need to read this doc.

I have just added:
	This feature is only relevant for 
	platforms where @code{-g} produces DWARF by default, otherwise one may
	try to enforce DWARF by using @code{-gdwarf-4}.


> > +Specifically @code{PATH} is searched for binaries matching regular expression
> > +@code{@var{ARCH}(-[^-]*)?-@var{OS}-gcc} according to the inferior target being
> > +debugged.  @code{@var{ARCH}} is processor name - multiarch is supported,
[...]
> > +for pattern @code{s390x?}.  @code{OS} is currently supported only for
> >                              ^^^^^^^^^
> 
> @var{os}.

Not sure if @code{@var{os}} is the same as @var{os}, used only @var{os}.


Thanks,
Jan

[-- Attachment #2: 1 --]
[-- Type: text/plain, Size: 4144 bytes --]

gdb/doc/
2015-04-10  Jan Kratochvil  <jan.kratochvil@redhat.com>
	    Eli Zaretskii  <eliz@gnu.org>

	* gdb.texinfo (Compiling and Injecting Code): Describe set debug 
	compile, show debug compile.  New subsection Compilation options for 
	the compile command.  New subsection Compiler search for the compile
	command.

diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo
index d794893..419439a 100644
--- a/gdb/doc/gdb.texinfo
+++ b/gdb/doc/gdb.texinfo
@@ -17223,6 +17223,66 @@ compile file /home/user/example.c
 @end smallexample
 @end table
 
+@noindent
+The process of compiling and injecting the code can be inspected using:
+
+@table @code
+@anchor{set debug compile}
+@item set debug compile
+@cindex compile command debugging info
+Turns on or off display of @value{GDBN} process of compiling and
+injecting the code.  The default is off.
+
+@item show debug compile
+Displays the current state of displaying @value{GDBN} process of
+compiling and injecting the code.
+@end table
+
+@subsection Compilation options for the @code{compile} command
+
+@value{GDBN} needs to specify the right compilation options for the code
+to be injected, in part to make its ABI compatible with the inferior
+and in part to make the injected code compatible with @value{GDBN}'s
+injecting process.
+
+@noindent
+The options used, in increasing precedence:
+
+@table @asis
+@item target architecture and OS options (@code{gdbarch})
+These options depend on target processor type and target operating
+system, usually they specify at least 32-bit (@code{-m32}) or 64-bit
+(@code{-m64}) compilation option.
+
+@item compilation options recorded in the target
+@value{NGCC} (since version 4.7) stores the options used for compilation
+into @code{DW_AT_producer} part of DWARF debugging information according
+to the @value{NGCC} option @code{-grecord-gcc-switches}.  One has to
+explicitly specify @code{-g} during inferior compilation otherwise
+@value{NGCC} produces no DWARF.  This feature is only relevant for
+platforms where @code{-g} produces DWARF by default, otherwise one may
+try to enforce DWARF by using @code{-gdwarf-4}.
+
+@item compilation options set by @code{set compile-args}
+@end table
+
+@noindent
+You can override compilation options using the following command:
+
+@table @code
+@item set compile-args
+@cindex compile command options override
+Set compilation options used for compiling and injecting code with the
+@code{compile} commands.  These options override any conflicting ones
+from the target architecture and/or options stored during inferior
+compilation.
+
+@item show compile-args
+Displays the current state of compilation options override.
+This does not show all the options actually used during compilation,
+use @ref{set debug compile} for that.
+@end table
+
 @subsection Caveats when using the @code{compile} command
 
 There are a few caveats to keep in mind when using the @code{compile}
@@ -17380,6 +17440,24 @@ Access to those variables will generate a compiler error which @value{GDBN}
 will print to the console.
 @end table
 
+@subsection Compiler search for the @code{compile} command
+
+@value{GDBN} needs to find @value{NGCC} for the inferior being debugged which
+may not be obvious for remote targets of different architecture than where
+@value{GDBN} is running.  Environment variable @code{PATH} (@code{PATH} from
+shell that executed @value{GDBN}, not the one set by @value{GDBN}
+command @code{set environment}).  @xref{Environment}.  @code{PATH} on
+@value{GDBN} host is searched for @value{NGCC} binary matching the
+target architecture and operating system.
+
+Specifically @code{PATH} is searched for binaries matching regular expression
+@code{@var{arch}(-[^-]*)?-@var{os}-gcc} according to the inferior target being
+debugged.  @var{arch} is processor name --- multiarch is supported, so for
+example both @code{i386} and @code{x86_64} targets look for pattern
+@code{(x86_64|i.86)} and both @code{s390} and @code{s390x} targets look
+for pattern @code{s390x?}.  @var{os} is currently supported only for
+pattern @code{linux(-gnu)?}.
+
 @node GDB Files
 @chapter @value{GDBN} Files
 

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [doc patch] compile: missing bits  [Re: [PATCH v2 7/9] compile: New 'compile print']
  2015-04-10  8:09                   ` Jan Kratochvil
@ 2015-04-10  8:31                     ` Eli Zaretskii
  2015-04-10  8:35                       ` [commit] " Jan Kratochvil
  2015-04-10 14:09                     ` Paul_Koning
  1 sibling, 1 reply; 30+ messages in thread
From: Eli Zaretskii @ 2015-04-10  8:31 UTC (permalink / raw)
  To: Jan Kratochvil; +Cc: Paul_Koning, gdb-patches, pmuldoon

> Date: Fri, 10 Apr 2015 10:09:33 +0200
> From: Jan Kratochvil <jan.kratochvil@redhat.com>
> Cc: Paul_Koning@dell.com, gdb-patches@sourceware.org, pmuldoon@redhat.com
> 
> I have just added:
> 	This feature is only relevant for 
> 	platforms where @code{-g} produces DWARF by default, otherwise one may
> 	try to enforce DWARF by using @code{-gdwarf-4}.

That's good enough, thanks.

> > > +Specifically @code{PATH} is searched for binaries matching regular expression
> > > +@code{@var{ARCH}(-[^-]*)?-@var{OS}-gcc} according to the inferior target being
> > > +debugged.  @code{@var{ARCH}} is processor name - multiarch is supported,
> [...]
> > > +for pattern @code{s390x?}.  @code{OS} is currently supported only for
> > >                              ^^^^^^^^^
> > 
> > @var{os}.
> 
> Not sure if @code{@var{os}} is the same as @var{os}, used only @var{os}.

@var{os} without @code was what I meant, sorry for being unclear.

Thanks, this version is fine with me.

^ permalink raw reply	[flat|nested] 30+ messages in thread

* [commit] [doc patch] compile: missing bits  [Re: [PATCH v2 7/9] compile: New 'compile print']
  2015-04-10  8:31                     ` Eli Zaretskii
@ 2015-04-10  8:35                       ` Jan Kratochvil
  0 siblings, 0 replies; 30+ messages in thread
From: Jan Kratochvil @ 2015-04-10  8:35 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: Paul_Koning, gdb-patches, pmuldoon

On Fri, 10 Apr 2015 10:31:02 +0200, Eli Zaretskii wrote:
> Thanks, this version is fine with me.

Checked in:
	e7a8570f75694284ea5bc909f095004f4ef938c6


Jan

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [doc patch] compile: missing bits  [Re: [PATCH v2 7/9] compile: New 'compile print']
  2015-04-10  8:09                   ` Jan Kratochvil
  2015-04-10  8:31                     ` Eli Zaretskii
@ 2015-04-10 14:09                     ` Paul_Koning
  1 sibling, 0 replies; 30+ messages in thread
From: Paul_Koning @ 2015-04-10 14:09 UTC (permalink / raw)
  To: jan.kratochvil; +Cc: eliz, gdb-patches, pmuldoon


> On Apr 10, 2015, at 4:09 AM, Jan Kratochvil <jan.kratochvil@redhat.com> wrote:
> 
> ...
> When some platform is still using -gstabs by default (is there any?) ...

In gcc, yes.  But the one I know of isn’t supported in gdb.

	paul

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [PATCH v2 7/9] compile: New 'compile print'
  2015-04-06 17:41   ` Eli Zaretskii
  2015-04-06 17:49     ` Paul_Koning
@ 2015-04-11 19:20     ` Jan Kratochvil
  1 sibling, 0 replies; 30+ messages in thread
From: Jan Kratochvil @ 2015-04-11 19:20 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: gdb-patches, pmuldoon

On Mon, 06 Apr 2015 19:41:03 +0200, Eli Zaretskii wrote:
> Perhaps "by using the compiler" or "by compiling and running it"?

"by compiling" is not clear to me it uses gcc.  Used the first one.


> > +Alternatively, you can type the expression interactively.\n\
> > +You can invoke this mode when no argument is given to the command\n\
> > +(i.e., \"compile print\" is typed with nothing after it).  An\n\
> > +interactive prompt will be shown allowing you to enter multiple\n\
> > +lines of source code.  Type a line containing \"end\" to indicate\n\
> > +the end of the source code.\n\
> 
> I suggest to rephrase:
> 
>   Alternatively, you can type a multiline expression by invoking
>   this command with no argument.  GDB will then prompt for the
>   expression interactively; type a line containing "end" to
>   indicate the end of the expression.

OK; although the same text was also at the "compile code" command so I have
also updated it in this patch.


Thanks,
Jan

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [PATCH v2 9/9] compile: compile printf: gdbserver support
  2015-04-06 17:43   ` Eli Zaretskii
@ 2015-04-11 19:23     ` Jan Kratochvil
  2015-04-11 19:31       ` Eli Zaretskii
  0 siblings, 1 reply; 30+ messages in thread
From: Jan Kratochvil @ 2015-04-11 19:23 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: gdb-patches, pmuldoon

On Mon, 06 Apr 2015 19:43:22 +0200, Eli Zaretskii wrote:
> > --- a/gdb/doc/gdb.texinfo
> > +++ b/gdb/doc/gdb.texinfo
> > @@ -17246,7 +17246,9 @@ multiple-line editor.
> >  @item compile printf @var{template}, @var{expressions}@dots{}
> >  Compile and execute @code{printf} function call with the compiler
> >  language found as the current language in @value{GDBN}
> > -(@pxref{Languages}).
> > +(@pxref{Languages}).  Inferior executes @code{open_memstream} and
> > +@code{fprintf} instead so that the produced string is printed by
> > +@value{GDBN} and not the inferior.
> 
> Is this really important to say in the manual?
> 
> And if it is, why not simply say that the value is printed by GDB
> itself, not by calling functions in the inferior?

Used:
	The value is printed by @value{GDBN} and not the inferior, inferior
	does not execute specifically the function @code{printf}.


Jan

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [PATCH v2 9/9] compile: compile printf: gdbserver support
  2015-04-11 19:23     ` Jan Kratochvil
@ 2015-04-11 19:31       ` Eli Zaretskii
  0 siblings, 0 replies; 30+ messages in thread
From: Eli Zaretskii @ 2015-04-11 19:31 UTC (permalink / raw)
  To: Jan Kratochvil; +Cc: gdb-patches, pmuldoon

> Date: Sat, 11 Apr 2015 21:23:24 +0200
> From: Jan Kratochvil <jan.kratochvil@redhat.com>
> Cc: gdb-patches@sourceware.org, pmuldoon@redhat.com
> 
> On Mon, 06 Apr 2015 19:43:22 +0200, Eli Zaretskii wrote:
> > > --- a/gdb/doc/gdb.texinfo
> > > +++ b/gdb/doc/gdb.texinfo
> > > @@ -17246,7 +17246,9 @@ multiple-line editor.
> > >  @item compile printf @var{template}, @var{expressions}@dots{}
> > >  Compile and execute @code{printf} function call with the compiler
> > >  language found as the current language in @value{GDBN}
> > > -(@pxref{Languages}).
> > > +(@pxref{Languages}).  Inferior executes @code{open_memstream} and
> > > +@code{fprintf} instead so that the produced string is printed by
> > > +@value{GDBN} and not the inferior.
> > 
> > Is this really important to say in the manual?
> > 
> > And if it is, why not simply say that the value is printed by GDB
> > itself, not by calling functions in the inferior?
> 
> Used:
> 	The value is printed by @value{GDBN} and not the inferior, inferior
> 	does not execute specifically the function @code{printf}.

Fine with me, thanks.

^ permalink raw reply	[flat|nested] 30+ messages in thread

* obsolete: [PATCH v2 0/9] compile: compile print&printf
  2015-04-06 17:26 [PATCH v2 0/9] compile: compile print&printf Jan Kratochvil
                   ` (8 preceding siblings ...)
  2015-04-06 17:27 ` [PATCH v2 6/9] Code cleanup: compile: func_addr -> func_sym Jan Kratochvil
@ 2015-04-11 19:46 ` Jan Kratochvil
  9 siblings, 0 replies; 30+ messages in thread
From: Jan Kratochvil @ 2015-04-11 19:46 UTC (permalink / raw)
  To: gdb-patches; +Cc: Phil Muldoon

obsoleted by:
	[PATCH v3 0/9] compile: compile print&printf
	https://sourceware.org/ml/gdb-patches/2015-04/msg00424.html

^ permalink raw reply	[flat|nested] 30+ messages in thread

end of thread, other threads:[~2015-04-11 19:46 UTC | newest]

Thread overview: 30+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-04-06 17:26 [PATCH v2 0/9] compile: compile print&printf Jan Kratochvil
2015-04-06 17:26 ` [PATCH v2 4/9] compile: Support relocation to GNU-IFUNCs Jan Kratochvil
2015-04-06 17:26 ` [PATCH v2 1/9] Code cleanup: Make parts of print_command_1 public Jan Kratochvil
2015-04-06 17:26 ` [PATCH v2 2/9] compile: Distribute scope, add scope_data Jan Kratochvil
2015-04-06 17:26 ` [PATCH v2 3/9] Code cleanup: compile: Constify some parameters Jan Kratochvil
2015-04-06 17:27 ` [PATCH v2 7/9] compile: New 'compile print' Jan Kratochvil
2015-04-06 17:41   ` Eli Zaretskii
2015-04-06 17:49     ` Paul_Koning
2015-04-06 17:52       ` Jan Kratochvil
2015-04-06 18:00         ` Paul_Koning
2015-04-08 20:03           ` Jan Kratochvil
2015-04-09  7:39             ` Eli Zaretskii
2015-04-09 17:40               ` [doc patch] compile: missing bits [Re: [PATCH v2 7/9] compile: New 'compile print'] Jan Kratochvil
2015-04-09 18:12                 ` Eli Zaretskii
2015-04-10  8:09                   ` Jan Kratochvil
2015-04-10  8:31                     ` Eli Zaretskii
2015-04-10  8:35                       ` [commit] " Jan Kratochvil
2015-04-10 14:09                     ` Paul_Koning
2015-04-08 20:12           ` [PATCH v2 7/9] compile: New 'compile print' Paul_Koning
2015-04-08 20:33             ` Jan Kratochvil
2015-04-06 18:47         ` Jan Kratochvil
2015-04-11 19:20     ` Jan Kratochvil
2015-04-06 17:27 ` [PATCH v2 5/9] compile: Use -Wall, not -w Jan Kratochvil
2015-04-06 17:27 ` [PATCH v2 9/9] compile: compile printf: gdbserver support Jan Kratochvil
2015-04-06 17:43   ` Eli Zaretskii
2015-04-11 19:23     ` Jan Kratochvil
2015-04-11 19:31       ` Eli Zaretskii
2015-04-06 17:27 ` [PATCH v2 8/9] compile: New compile printf Jan Kratochvil
2015-04-06 17:27 ` [PATCH v2 6/9] Code cleanup: compile: func_addr -> func_sym Jan Kratochvil
2015-04-11 19:46 ` obsolete: [PATCH v2 0/9] compile: compile print&printf Jan Kratochvil

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).