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


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

[binutils-gdb] gdbserver/IPA: Export some functions via global function pointers.


https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=1cda1512689aabb36588a01370002632a0c8e560

commit 1cda1512689aabb36588a01370002632a0c8e560
Author: Marcin KoÅ?cielnicki <koriakin@0x04.net>
Date:   Fri Mar 11 15:51:29 2016 +0100

    gdbserver/IPA: Export some functions via global function pointers.
    
    On powerpc64, qSymbol for a function returns the function code address,
    and not the descriptor address.  Since we emit code calling gdb_collect
    and some other functions, we need the descriptor (no way to know the
    proper TOC address without it).  To get the descriptor address, make
    global function pointer variables in the IPA pointing to the relevant
    functions and read them instead of asking for them directly via qSymbol.
    
    gdb/gdbserver/ChangeLog:
    
    	* linux-aarch64-ipa.c: Rename gdb_agent_get_raw_reg to get_raw_reg.
    	* linux-amd64-ipa.c: Likewise.
    	* linux-i386-ipa.c: Likewise.
    	* linux-s390-ipa.c: Likewise.
    	* tracepoint.c: IPA-export gdb_collect_ptr instead of gdb_collect,
    	ditto for get_raw_reg_ptr, get_trace_state_variable_value_ptr,
    	set_trace_state_variable_value_ptr.
    	(struct ipa_sym_addresses): Likewise.
    	(symbol_list): Likewise.
    	(install_fast_tracepoint): Dereference gdb_collect_ptr instead of
    	accessing gdb_collect directly.
    	(gdb_collect_ptr_type): New typedef.
    	(get_raw_reg_ptr_type): New typedef.
    	(get_trace_state_variable_value_ptr_type): New typedef.
    	(set_trace_state_variable_value_ptr_type): New typedef.
    	(gdb_collect_ptr): New global.
    	(get_raw_reg_ptr): New global.
    	(get_trace_state_variable_value_ptr): New global.
    	(set_trace_state_variable_value_ptr): New global.
    	(get_raw_reg_func_addr): Dereference get_raw_reg_ptr instead of
    	accessing get_raw_reg directly.
    	(get_get_tsv_func_addr): Likewise for
    	get_trace_state_variable_value_ptr.
    	(get_set_tsv_func_addr): Likewise for
    	set_trace_state_variable_value_ptr.
    	* tracepoint.h: Rename gdb_agent_get_raw_reg to get_raw_reg.

Diff:
---
 gdb/gdbserver/ChangeLog           | 29 ++++++++++++++
 gdb/gdbserver/linux-aarch64-ipa.c |  4 +-
 gdb/gdbserver/linux-amd64-ipa.c   |  4 +-
 gdb/gdbserver/linux-i386-ipa.c    |  4 +-
 gdb/gdbserver/linux-s390-ipa.c    |  4 +-
 gdb/gdbserver/tracepoint.c        | 83 ++++++++++++++++++++++++++++++---------
 gdb/gdbserver/tracepoint.h        |  3 +-
 7 files changed, 103 insertions(+), 28 deletions(-)

diff --git a/gdb/gdbserver/ChangeLog b/gdb/gdbserver/ChangeLog
index 35d5bb2..644a810 100644
--- a/gdb/gdbserver/ChangeLog
+++ b/gdb/gdbserver/ChangeLog
@@ -1,3 +1,32 @@
+2016-03-30  Marcin KoÅ?cielnicki  <koriakin@0x04.net>
+
+	* linux-aarch64-ipa.c: Rename gdb_agent_get_raw_reg to get_raw_reg.
+	* linux-amd64-ipa.c: Likewise.
+	* linux-i386-ipa.c: Likewise.
+	* linux-s390-ipa.c: Likewise.
+	* tracepoint.c: IPA-export gdb_collect_ptr instead of gdb_collect,
+	ditto for get_raw_reg_ptr, get_trace_state_variable_value_ptr,
+	set_trace_state_variable_value_ptr.
+	(struct ipa_sym_addresses): Likewise.
+	(symbol_list): Likewise.
+	(install_fast_tracepoint): Dereference gdb_collect_ptr instead of
+	accessing gdb_collect directly.
+	(gdb_collect_ptr_type): New typedef.
+	(get_raw_reg_ptr_type): New typedef.
+	(get_trace_state_variable_value_ptr_type): New typedef.
+	(set_trace_state_variable_value_ptr_type): New typedef.
+	(gdb_collect_ptr): New global.
+	(get_raw_reg_ptr): New global.
+	(get_trace_state_variable_value_ptr): New global.
+	(set_trace_state_variable_value_ptr): New global.
+	(get_raw_reg_func_addr): Dereference get_raw_reg_ptr instead of
+	accessing get_raw_reg directly.
+	(get_get_tsv_func_addr): Likewise for
+	get_trace_state_variable_value_ptr.
+	(get_set_tsv_func_addr): Likewise for
+	set_trace_state_variable_value_ptr.
+	* tracepoint.h: Rename gdb_agent_get_raw_reg to get_raw_reg.
+
 2016-03-30  Simon Marchi  <simon.marchi@ericsson.com>
 
 	* tracepoint.c (cmd_qtenable_disable): Remove whitespace.
diff --git a/gdb/gdbserver/linux-aarch64-ipa.c b/gdb/gdbserver/linux-aarch64-ipa.c
index f1eaa70..00cbf3e 100644
--- a/gdb/gdbserver/linux-aarch64-ipa.c
+++ b/gdb/gdbserver/linux-aarch64-ipa.c
@@ -133,8 +133,8 @@ supply_fast_tracepoint_registers (struct regcache *regcache,
 		     + (aarch64_ft_collect_regmap[i] * FT_CR_SIZE));
 }
 
-IP_AGENT_EXPORT_FUNC ULONGEST
-gdb_agent_get_raw_reg (const unsigned char *raw_regs, int regnum)
+ULONGEST
+get_raw_reg (const unsigned char *raw_regs, int regnum)
 {
   if (regnum >= AARCH64_NUM_FT_COLLECT_GREGS)
     return 0;
diff --git a/gdb/gdbserver/linux-amd64-ipa.c b/gdb/gdbserver/linux-amd64-ipa.c
index 2dca943..70889d2 100644
--- a/gdb/gdbserver/linux-amd64-ipa.c
+++ b/gdb/gdbserver/linux-amd64-ipa.c
@@ -69,8 +69,8 @@ supply_fast_tracepoint_registers (struct regcache *regcache,
 		     ((char *) buf) + x86_64_ft_collect_regmap[i]);
 }
 
-IP_AGENT_EXPORT_FUNC ULONGEST
-gdb_agent_get_raw_reg (const unsigned char *raw_regs, int regnum)
+ULONGEST
+get_raw_reg (const unsigned char *raw_regs, int regnum)
 {
   if (regnum >= X86_64_NUM_FT_COLLECT_GREGS)
     return 0;
diff --git a/gdb/gdbserver/linux-i386-ipa.c b/gdb/gdbserver/linux-i386-ipa.c
index 4860012..7159eee 100644
--- a/gdb/gdbserver/linux-i386-ipa.c
+++ b/gdb/gdbserver/linux-i386-ipa.c
@@ -95,8 +95,8 @@ supply_fast_tracepoint_registers (struct regcache *regcache,
     }
 }
 
-IP_AGENT_EXPORT_FUNC ULONGEST
-gdb_agent_get_raw_reg (const unsigned char *raw_regs, int regnum)
+ULONGEST
+get_raw_reg (const unsigned char *raw_regs, int regnum)
 {
   /* This should maybe be allowed to return an error code, or perhaps
      better, have the emit_reg detect this, and emit a constant zero,
diff --git a/gdb/gdbserver/linux-s390-ipa.c b/gdb/gdbserver/linux-s390-ipa.c
index d804188..cd4fadd 100644
--- a/gdb/gdbserver/linux-s390-ipa.c
+++ b/gdb/gdbserver/linux-s390-ipa.c
@@ -261,8 +261,8 @@ supply_fast_tracepoint_registers (struct regcache *regcache,
       supply_register (regcache, i, ((char *) buf) + s390_regmap[i]);
 }
 
-IP_AGENT_EXPORT_FUNC ULONGEST
-gdb_agent_get_raw_reg (const unsigned char *raw_regs, int regnum)
+ULONGEST
+get_raw_reg (const unsigned char *raw_regs, int regnum)
 {
   int offset;
   if (regnum >= s390_regnum)
diff --git a/gdb/gdbserver/tracepoint.c b/gdb/gdbserver/tracepoint.c
index 7c20612..83d1830 100644
--- a/gdb/gdbserver/tracepoint.c
+++ b/gdb/gdbserver/tracepoint.c
@@ -108,7 +108,7 @@ trace_vdebug (const char *fmt, ...)
 # define gdb_trampoline_buffer_end IPA_SYM_EXPORTED_NAME (gdb_trampoline_buffer_end)
 # define gdb_trampoline_buffer_error IPA_SYM_EXPORTED_NAME (gdb_trampoline_buffer_error)
 # define collecting IPA_SYM_EXPORTED_NAME (collecting)
-# define gdb_collect IPA_SYM_EXPORTED_NAME (gdb_collect)
+# define gdb_collect_ptr IPA_SYM_EXPORTED_NAME (gdb_collect_ptr)
 # define stop_tracing IPA_SYM_EXPORTED_NAME (stop_tracing)
 # define flush_trace_buffer IPA_SYM_EXPORTED_NAME (flush_trace_buffer)
 # define about_to_request_buffer_space IPA_SYM_EXPORTED_NAME (about_to_request_buffer_space)
@@ -126,11 +126,11 @@ trace_vdebug (const char *fmt, ...)
 # define traceframe_write_count IPA_SYM_EXPORTED_NAME (traceframe_write_count)
 # define traceframes_created IPA_SYM_EXPORTED_NAME (traceframes_created)
 # define trace_state_variables IPA_SYM_EXPORTED_NAME (trace_state_variables)
-# define get_raw_reg IPA_SYM_EXPORTED_NAME (get_raw_reg)
-# define get_trace_state_variable_value \
-  IPA_SYM_EXPORTED_NAME (get_trace_state_variable_value)
-# define set_trace_state_variable_value \
-  IPA_SYM_EXPORTED_NAME (set_trace_state_variable_value)
+# define get_raw_reg_ptr IPA_SYM_EXPORTED_NAME (get_raw_reg_ptr)
+# define get_trace_state_variable_value_ptr \
+  IPA_SYM_EXPORTED_NAME (get_trace_state_variable_value_ptr)
+# define set_trace_state_variable_value_ptr \
+  IPA_SYM_EXPORTED_NAME (set_trace_state_variable_value_ptr)
 # define ust_loaded IPA_SYM_EXPORTED_NAME (ust_loaded)
 # define helper_thread_id IPA_SYM_EXPORTED_NAME (helper_thread_id)
 # define cmd_buf IPA_SYM_EXPORTED_NAME (cmd_buf)
@@ -150,7 +150,7 @@ struct ipa_sym_addresses
   CORE_ADDR addr_gdb_trampoline_buffer_end;
   CORE_ADDR addr_gdb_trampoline_buffer_error;
   CORE_ADDR addr_collecting;
-  CORE_ADDR addr_gdb_collect;
+  CORE_ADDR addr_gdb_collect_ptr;
   CORE_ADDR addr_stop_tracing;
   CORE_ADDR addr_flush_trace_buffer;
   CORE_ADDR addr_about_to_request_buffer_space;
@@ -168,9 +168,9 @@ struct ipa_sym_addresses
   CORE_ADDR addr_traceframe_write_count;
   CORE_ADDR addr_traceframes_created;
   CORE_ADDR addr_trace_state_variables;
-  CORE_ADDR addr_get_raw_reg;
-  CORE_ADDR addr_get_trace_state_variable_value;
-  CORE_ADDR addr_set_trace_state_variable_value;
+  CORE_ADDR addr_get_raw_reg_ptr;
+  CORE_ADDR addr_get_trace_state_variable_value_ptr;
+  CORE_ADDR addr_set_trace_state_variable_value_ptr;
   CORE_ADDR addr_ust_loaded;
   CORE_ADDR addr_ipa_tdesc_idx;
 };
@@ -187,7 +187,7 @@ static struct
   IPA_SYM(gdb_trampoline_buffer_end),
   IPA_SYM(gdb_trampoline_buffer_error),
   IPA_SYM(collecting),
-  IPA_SYM(gdb_collect),
+  IPA_SYM(gdb_collect_ptr),
   IPA_SYM(stop_tracing),
   IPA_SYM(flush_trace_buffer),
   IPA_SYM(about_to_request_buffer_space),
@@ -205,9 +205,9 @@ static struct
   IPA_SYM(traceframe_write_count),
   IPA_SYM(traceframes_created),
   IPA_SYM(trace_state_variables),
-  IPA_SYM(get_raw_reg),
-  IPA_SYM(get_trace_state_variable_value),
-  IPA_SYM(set_trace_state_variable_value),
+  IPA_SYM(get_raw_reg_ptr),
+  IPA_SYM(get_trace_state_variable_value_ptr),
+  IPA_SYM(set_trace_state_variable_value_ptr),
   IPA_SYM(ust_loaded),
   IPA_SYM(ipa_tdesc_idx),
 };
@@ -3068,6 +3068,7 @@ install_fast_tracepoint (struct tracepoint *tpoint, char *errbuf)
 {
   CORE_ADDR jentry, jump_entry;
   CORE_ADDR trampoline;
+  CORE_ADDR collect;
   ULONGEST trampoline_size;
   int err = 0;
   /* The jump to the jump pad of the last fast tracepoint
@@ -3082,6 +3083,13 @@ install_fast_tracepoint (struct tracepoint *tpoint, char *errbuf)
       return 0;
     }
 
+  if (read_inferior_data_pointer (ipa_sym_addrs.addr_gdb_collect_ptr,
+				  &collect))
+    {
+      error ("error extracting gdb_collect_ptr");
+      return 1;
+    }
+
   jentry = jump_entry = get_jump_space_head ();
 
   trampoline = 0;
@@ -3090,7 +3098,7 @@ install_fast_tracepoint (struct tracepoint *tpoint, char *errbuf)
   /* Install the jump pad.  */
   err = install_fast_tracepoint_jump_pad (tpoint->obj_addr_on_target,
 					  tpoint->address,
-					  ipa_sym_addrs.addr_gdb_collect,
+					  collect,
 					  ipa_sym_addrs.addr_collecting,
 					  tpoint->orig_size,
 					  &jentry,
@@ -5856,6 +5864,25 @@ gdb_collect (struct tracepoint *tpoint, unsigned char *regs)
     }
 }
 
+/* These global variables points to the corresponding functions.  This is
+   necessary on powerpc64, where asking for function symbol address from gdb
+   results in returning the actual code pointer, instead of the descriptor
+   pointer.  */
+
+typedef void (*gdb_collect_ptr_type) (struct tracepoint *, unsigned char *);
+typedef ULONGEST (*get_raw_reg_ptr_type) (const unsigned char *, int);
+typedef LONGEST (*get_trace_state_variable_value_ptr_type) (int);
+typedef void (*set_trace_state_variable_value_ptr_type) (int, LONGEST);
+
+EXTERN_C_PUSH
+IP_AGENT_EXPORT_VAR const gdb_collect_ptr_type gdb_collect_ptr = gdb_collect;
+IP_AGENT_EXPORT_VAR const get_raw_reg_ptr_type get_raw_reg_ptr = get_raw_reg;
+IP_AGENT_EXPORT_VAR const get_trace_state_variable_value_ptr_type
+  get_trace_state_variable_value_ptr = get_trace_state_variable_value;
+IP_AGENT_EXPORT_VAR const set_trace_state_variable_value_ptr_type
+  set_trace_state_variable_value_ptr = set_trace_state_variable_value;
+EXTERN_C_POP
+
 #endif
 
 #ifndef IN_PROCESS_AGENT
@@ -5863,19 +5890,39 @@ gdb_collect (struct tracepoint *tpoint, unsigned char *regs)
 CORE_ADDR
 get_raw_reg_func_addr (void)
 {
-  return ipa_sym_addrs.addr_get_raw_reg;
+  CORE_ADDR res;
+  if (read_inferior_data_pointer (ipa_sym_addrs.addr_get_raw_reg_ptr, &res))
+    {
+      error ("error extracting get_raw_reg_ptr");
+      return 0;
+    }
+  return res;
 }
 
 CORE_ADDR
 get_get_tsv_func_addr (void)
 {
-  return ipa_sym_addrs.addr_get_trace_state_variable_value;
+  CORE_ADDR res;
+  if (read_inferior_data_pointer (
+	ipa_sym_addrs.addr_get_trace_state_variable_value_ptr, &res))
+    {
+      error ("error extracting get_trace_state_variable_value_ptr");
+      return 0;
+    }
+  return res;
 }
 
 CORE_ADDR
 get_set_tsv_func_addr (void)
 {
-  return ipa_sym_addrs.addr_set_trace_state_variable_value;
+  CORE_ADDR res;
+  if (read_inferior_data_pointer (
+	ipa_sym_addrs.addr_set_trace_state_variable_value_ptr, &res))
+    {
+      error ("error extracting set_trace_state_variable_value_ptr");
+      return 0;
+    }
+  return res;
 }
 
 static void
diff --git a/gdb/gdbserver/tracepoint.h b/gdb/gdbserver/tracepoint.h
index e30f4f7..df815ef 100644
--- a/gdb/gdbserver/tracepoint.h
+++ b/gdb/gdbserver/tracepoint.h
@@ -163,8 +163,7 @@ int agent_mem_read_string (struct eval_agent_expr_context *ctx,
 
 /* The prototype the get_raw_reg function in the IPA.  Each arch's
    bytecode compiler emits calls to this function.  */
-IP_AGENT_EXPORT_FUNC ULONGEST gdb_agent_get_raw_reg
-  (const unsigned char *raw_regs, int regnum);
+ULONGEST get_raw_reg (const unsigned char *raw_regs, int regnum);
 
 /* Returns the address of the get_raw_reg function in the IPA.  */
 CORE_ADDR get_raw_reg_func_addr (void);


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