diff --git a/gdb/gdbserver/ChangeLog b/gdb/gdbserver/ChangeLog
index 7ce2690..31120c5 100644
--- a/gdb/gdbserver/ChangeLog
+++ b/gdb/gdbserver/ChangeLog
@@ -1,5 +1,30 @@
 2016-03-12  Marcin KoÅ›cielnicki  <koriakin@0x04.net>
 
+	* linux-aarch64-ipa.c: Rename gdb_agent_get_raw_reg to get_raw_reg.
+	* linux-amd64-ipa.c: Ditto.
+	* linux-i386-ipa.c: Ditto.
+	* 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): Ditto.
+	(symbol_list): Ditto.
+	(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): Ditto for get_raw_reg_ptr
+	(get_get_tsv_func_addr): Ditto for get_trace_state_variable_value_ptr.
+	(get_set_tsv_func_addr): Ditto for set_trace_state_variable_value_ptr.
+	* tracepoint.h: Rename gdb_agent_get_raw_reg to get_raw_reg.
+
+2016-03-12  Marcin KoÅ›cielnicki  <koriakin@0x04.net>
+
 	* remote-utils.c (look_up_one_symbol): Remove own_buf, handle 'v'
 	packets.
 	(relocate_instruction): Remove own_buf.
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/tracepoint.c b/gdb/gdbserver/tracepoint.c
index 383fb71..061e161 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);
