This is the mail archive of the systemtap@sourceware.org mailing list for the systemtap 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]

Re: [PATCH]Systemtap IA64 Runtime support


On Thu, Oct 27, 2005 at 01:53:43PM -0700, Roland McGrath wrote:
> Please clean up your patches so they don't touch unrelated lines with
> random whitespace changes.
> 
> Don't use unadorned "inline", that defines globals.  For inlines in a
> header for the kernel, use "static inline".  
> 
> For the ia64 register accessors, is it really advantageous to inline those?
> Perhaps the functions should be in the runtime proper rather than inlined
> by the macros.

Hi Roland,
	All the above are very valid feedback. Here is the modified patch.
And please let me know if you find any thing wrong and thanks for your review.

========================================================================
 runtime/copy.c          |   12 +++++++
 runtime/current.c       |   41 ++++++++++++++++++++++++
 runtime/loc2c-runtime.h |   47 +++++++++++++++++++++++++++-
 runtime/regs.c          |   80 ++++++++++++++++++++++++++++++++++++++++++++++++
 runtime/regs.h          |   14 +++++++-
 runtime/runtime.h       |   23 ++++++++++++-
 runtime/stack.c         |   65 +++++++++++++++++++++++++++++++++++++++
 runtime/sym.c           |   14 ++++++--
 tapsets.cxx             |   13 +++++++
 translate.cxx           |    4 +-
 10 files changed, 304 insertions(+), 9 deletions(-)

Index: src/runtime/copy.c
===================================================================
--- src.orig/runtime/copy.c
+++ src/runtime/copy.c
@@ -1,3 +1,12 @@
+/* Copy from user space functions
+ * Copyright (C) 2005 Intel Corporation.
+ *
+ * This file is part of systemtap, and is free software.  You can
+ * redistribute it and/or modify it under the terms of the GNU General
+ * Public License (GPL); either version 2, or (at your option) any
+ * later version.
+ */
+
 #ifndef _COPY_C_ /* -*- linux-c -*- */
 #define _COPY_C_
 
@@ -77,6 +86,9 @@ do {									   \
 #elif defined (__powerpc64__)
 #define __stp_strncpy_from_user(dst,src,count,res) \
 	do { res = __strncpy_from_user(dst, src, count); } while(0)
+#elif defined (__ia64__)
+#define __stp_strncpy_from_user(dst,src,count,res) \
+	do { res = __strncpy_from_user(dst, src, count); } while(0)
 #endif
 
 /** Copy a NULL-terminated string from userspace.
Index: src/runtime/current.c
===================================================================
--- src.orig/runtime/current.c
+++ src/runtime/current.c
@@ -1,3 +1,12 @@
+/* Functions to access the members of pt_regs struct
+ * Copyright (C) 2005 Intel Corporation.
+ *
+ * This file is part of systemtap, and is free software.  You can
+ * redistribute it and/or modify it under the terms of the GNU General
+ * Public License (GPL); either version 2, or (at your option) any
+ * later version.
+ */
+
 #ifndef _CURRENT_C_ /* -*- linux-c -*- */
 #define _CURRENT_C_
 
@@ -31,6 +40,8 @@ unsigned long _stp_ret_addr (struct pt_r
 	return regs->esp;
 #elif defined (__powerpc64__)
 	return REG_LINK(regs);
+#elif defined (__ia64__)
+	return regs->b0;
 #else
 	#error Unimplemented architecture
 #endif
@@ -99,6 +110,36 @@ void _stp_sprint_regs(String str, struct
         _stp_sprintf(str,"CR2: %016lx CR3: %016lx CR4: %016lx\n", cr2, cr3, cr4);
 }
 
+#elif defined (__ia64__)
+void _stp_sprint_regs(String str, struct pt_regs * regs)
+{
+     unsigned long ip = regs->cr_iip + ia64_psr(regs)->ri;
+
+	_stp_sprintf(str, "\nPid: %d, CPU %d, comm: %20s\n", current->pid,
+		smp_processor_id(), current->comm);
+	_stp_sprintf(str, "psr : %016lx ifs : %016lx ip  : [<%016lx>]  \n",
+		regs->cr_ipsr, regs->cr_ifs, ip);
+	_stp_sprintf(str, "unat: %016lx pfs : %016lx rsc : %016lx\n",
+		regs->ar_unat, regs->ar_pfs, regs->ar_rsc);
+	_stp_sprintf(str, "rnat: %016lx bsps: %016lx pr  : %016lx\n",
+		regs->ar_rnat, regs->ar_bspstore, regs->pr);
+	_stp_sprintf(str, "ldrs: %016lx ccv : %016lx fpsr: %016lx\n",
+		regs->loadrs, regs->ar_ccv, regs->ar_fpsr);
+	_stp_sprintf(str, "csd : %016lx ssd : %016lx\n",
+		regs->ar_csd, regs->ar_ssd);
+	_stp_sprintf(str, "b0  : %016lx b6  : %016lx b7  : %016lx\n",
+		regs->b0, regs->b6, regs->b7);
+	_stp_sprintf(str, "f6  : %05lx%016lx f7  : %05lx%016lx\n",
+		regs->f6.u.bits[1], regs->f6.u.bits[0],
+		regs->f7.u.bits[1], regs->f7.u.bits[0]);
+	_stp_sprintf(str, "f8  : %05lx%016lx f9  : %05lx%016lx\n",
+		regs->f8.u.bits[1], regs->f8.u.bits[0],
+		regs->f9.u.bits[1], regs->f9.u.bits[0]);
+	_stp_sprintf(str, "f10 : %05lx%016lx f11 : %05lx%016lx\n",
+		regs->f10.u.bits[1], regs->f10.u.bits[0],
+		regs->f11.u.bits[1], regs->f11.u.bits[0]);
+}
+
 #elif defined (__i386__)
 
 /** Write the registers to a string.
Index: src/runtime/loc2c-runtime.h
===================================================================
--- src.orig/runtime/loc2c-runtime.h
+++ src/runtime/loc2c-runtime.h
@@ -1,4 +1,11 @@
-/* target operations */
+/* target operations
+ * Copyright (C) 2005 Intel Corporation.
+ *
+ * This file is part of systemtap, and is free software.  You can
+ * redistribute it and/or modify it under the terms of the GNU General
+ * Public License (GPL); either version 2, or (at your option) any
+ * later version.
+ */
 
 #include <linux/types.h>
 #define intptr_t long
@@ -50,6 +57,13 @@
 #define dwarf_register_6(regs)	regs->esi
 #define dwarf_register_7(regs)	regs->edi
 
+#elif defined __ia64__
+#undef fetch_register
+#undef store_register
+
+#define fetch_register(regno)		ia64_fetch_register(regno, c->regs)
+#define store_register(regno, value)	ia64_store_register(regno, c->regs, value)
+
 #elif defined __x86_64__
 
 #define dwarf_register_0(regs)	regs->rax
@@ -113,6 +127,37 @@
       goto deref_fault;							      \
   })
 
+#elif defined __ia64__								
+#define deref(size, addr)						\
+  ({									\
+     int _bad = 0;							\
+     intptr_t _v=0;							\
+	switch (size){							\
+	case 1: __get_user_size(_v, addr, 1, _bad); break; 		\
+	case 2: __get_user_size(_v, addr, 2, _bad); break;  		\
+	case 4: __get_user_size(_v, addr, 4, _bad); break;  		\
+	case 8: __get_user_size(_v, addr, 8, _bad); break;  		\
+	default: __get_user_unknown(); break;				\
+	}								\
+    if (_bad)  								\
+	goto deref_fault;						\
+     _v;								\
+   })
+
+#define store_deref(size, addr, value)					\
+  ({									\
+    int _bad=0;								\
+	switch (size){							\
+	case 1: __put_user_size(value, addr, 1, _bad); break;		\
+	case 2: __put_user_size(value, addr, 2, _bad); break;		\
+	case 4: __put_user_size(value, addr, 4, _bad); break;		\
+	case 8: __put_user_size(value, addr, 8, _bad); break;		\
+	default: __put_user_unknown(); break;				\
+	}								\
+    if (_bad)								\
+	   goto deref_fault;						\
+   })
+
 #elif defined __powerpc64__
 
 #define deref(size, addr)						      \
Index: src/runtime/regs.c
===================================================================
--- /dev/null
+++ src/runtime/regs.c
@@ -0,0 +1,80 @@
+/* register access functions
+ * Copyright (C) 2005 Intel Corporation.
+ *
+ * This file is part of systemtap, and is free software.  You can
+ * redistribute it and/or modify it under the terms of the GNU General
+ * Public License (GPL); either version 2, or (at your option) any
+ * later version.
+ */
+
+#ifndef _REG_C_ /* -*- linux-c -*- */
+#define _REG_C_
+
+#if defined __ia64__
+
+struct ia64_stap_get_arbsp_param {
+	unsigned long ip;
+	unsigned long *address;
+};
+
+static void ia64_stap_get_arbsp(struct unw_frame_info *info, void *arg)
+{
+	unsigned long ip;
+	struct ia64_stap_get_arbsp_param *lp = arg;
+
+	do {
+		unw_get_ip(info, &ip);
+		if (ip == 0)
+			break;
+		if (ip == lp->ip) {
+			unw_get_bsp(info, (unsigned long*)&lp->address);
+			return;
+		}
+	} while (unw_unwind(info) >= 0);
+	lp->address = 0;
+}
+
+static long ia64_fetch_register(int regno, struct pt_regs *pt_regs)
+{
+	struct ia64_stap_get_arbsp_param pa;
+
+	if (regno < 32 || regno > 127)
+		return 0;
+
+	pa.ip = pt_regs->cr_iip;
+	unw_init_running(ia64_stap_get_arbsp, &pa);
+	if (pa.address == 0)
+		return 0;
+
+	return *ia64_rse_skip_regs(pa.address, regno-32);
+}
+
+static void ia64_store_register(int regno,
+		struct pt_regs *pt_regs,
+		unsigned long value)
+{
+	struct ia64_stap_get_arbsp_param pa;
+	unsigned long rsc_save = 0;
+
+	if (regno < 32 || regno > 127)
+		return;
+
+	pa.ip = pt_regs->cr_iip;
+	unw_init_running(ia64_stap_get_arbsp, &pa);
+	if (pa.address == 0)
+		return;
+	*ia64_rse_skip_regs(pa.address, regno-32) = value;
+	//Invalidate all stacked registers outside the current frame
+	asm volatile( "mov %0=ar.rsc;;\n\t"
+			"mov ar.rsc=0;;\n\t"
+			"{\n\tloadrs;;\n\t\n\t\n\t}\n\t"
+			"mov ar.rsc=%1\n\t"
+			:"=r" (rsc_save):"r" (rsc_save):"memory");
+
+	return;
+}
+
+#endif /* if defined __ia64__ */
+
+
+#endif /* _REG_C_ */
Index: src/runtime/regs.h
===================================================================
--- src.orig/runtime/regs.h
+++ src/runtime/regs.h
@@ -1,7 +1,15 @@
+/* common register includes used in multiple modules
+ * Copyright (C) 2005 Intel Corporation.
+ *
+ * This file is part of systemtap, and is free software.  You can
+ * redistribute it and/or modify it under the terms of the GNU General
+ * Public License (GPL); either version 2, or (at your option) any
+ * later version.
+ */
+
 #ifndef _REGS_H_ /* -*- linux-c -*- */
 #define _REGS_H_
 
-/* common register includes used in multiple modules */
 
 #ifdef __x86_64__
 
@@ -13,6 +21,10 @@
 #define REG_IP(regs) regs->eip
 #define REG_SP(regs) regs->esp
 
+#elif defined (__ia64__)
+#define REG_IP(regs)    ((regs)->cr_iip +ia64_psr(regs)->ri)
+#define REG_SP(regs)    ((regs)->r12)
+
 #elif defined (__powerpc64__)
 
 #define REG_IP(regs) regs->nip
Index: src/runtime/runtime.h
===================================================================
--- src.orig/runtime/runtime.h
+++ src/runtime/runtime.h
@@ -1,5 +1,6 @@
 /* main header file
  * Copyright (C) 2005 Red Hat Inc.
+ * Copyright (C) 2005 Intel Corporation.
  *
  * This file is part of systemtap, and is free software.  You can
  * redistribute it and/or modify it under the terms of the GNU General
@@ -121,15 +122,31 @@ static const char * _stp_kallsyms_lookup
 
 
 
+#ifdef __ia64__	
+  struct fnptr func_entry, *pfunc_entry;
+#endif
 int init_module (void)
 {
   _stp_kta = (int (*)(unsigned long))kallsyms_lookup_name("__kernel_text_address");
 
-  if (stap_num_symbols > 0)
-    _stp_kallsyms_lookup = & _stp_kallsyms_lookup_tabled;
-  else
+  if (stap_num_symbols > 0) {
+	_stp_kallsyms_lookup = & _stp_kallsyms_lookup_tabled;
+  } else {
+#ifdef __ia64__
+/* Refer to Ia-64 Softeware Conventions and Runtime Architecture Guide
+ * Chapter 8.3 about indirect call, A function pointer must pointer to
+ * a descriptor that contains both the address of the function entry 
+ * point and the gp register value for the target function.
+ */
+        func_entry.gp = ((struct fnptr *) kallsyms_lookup_name)->gp;
+        func_entry.ip = kallsyms_lookup_name("kallsyms_lookup");
+        _stp_kallsyms_lookup = (const char * (*)(unsigned long,unsigned long *,unsigned long *,char **,char *))&func_entry;
+
+#else
     _stp_kallsyms_lookup = (const char * (*)(unsigned long,unsigned long *,unsigned long *,char **,char *))
       kallsyms_lookup_name("kallsyms_lookup");
+#endif
+	}
 
   return _stp_transport_init();
 }
Index: src/runtime/stack.c
===================================================================
--- src.orig/runtime/stack.c
+++ src/runtime/stack.c
@@ -1,3 +1,12 @@
+/* Stack tracing functions
+ * Copyright (C) 2005 Intel Corporation.
+ *
+ * This file is part of systemtap, and is free software.  You can
+ * redistribute it and/or modify it under the terms of the GNU General
+ * Public License (GPL); either version 2, or (at your option) any
+ * later version.
+ */
+
 #ifndef _STACK_C_ /* -*- linux-c -*- */
 #define _STACK_C_
 
@@ -38,6 +47,62 @@ static void __stp_stack_sprint (String s
 	}
 }
 
+#elif defined (__ia64__)
+struct dump_para{
+  unsigned long *sp;
+  String str;
+};
+
+static void __stp_show_stack_sym(struct unw_frame_info *info, void *arg)
+{
+   unsigned long ip, skip=1;
+   String str = ((struct dump_para*)arg)->str;
+   struct pt_regs *regs = container_of(((struct dump_para*)arg)->sp, struct pt_regs, r12);
+
+	do {
+		unw_get_ip(info, &ip);
+		if (ip == 0) break;
+                if (skip){
+			if (ip == REG_IP(regs))
+				skip = 0;
+                        else continue;
+                }
+		_stp_string_cat(str, " ");
+		_stp_symbol_sprint(str, ip);
+		_stp_string_cat (str, "\n");
+        } while (unw_unwind(info) >= 0);
+}
+
+static void __stp_show_stack_addr(struct unw_frame_info *info, void *arg)
+{
+   unsigned long ip, skip=1;
+   String str = ((struct dump_para*)arg)->str;
+   struct pt_regs *regs = container_of(((struct dump_para*)arg)->sp, struct pt_regs, r12);	
+
+	do {
+		unw_get_ip(info, &ip);
+		if (ip == 0) break;
+		if (skip){
+			if (ip == REG_IP(regs))
+				skip = 0;
+			continue;
+		}
+		_stp_sprintf (str, "%lx ", ip);
+	} while (unw_unwind(info) >= 0);
+}
+
+static void __stp_stack_sprint (String str, unsigned long *stack, int verbose, int levels)
+{
+  struct dump_para para;
+
+	para.str = str;
+	para.sp  = stack; 
+	if (verbose)
+	    unw_init_running(__stp_show_stack_sym, &para);
+        else
+	    unw_init_running(__stp_show_stack_addr, &para);
+}
+
 #elif  defined (__i386__)
 
 static inline int valid_stack_ptr(struct thread_info *tinfo, void *p)
Index: src/runtime/sym.c
===================================================================
--- src.orig/runtime/sym.c
+++ src/runtime/sym.c
@@ -1,3 +1,12 @@
+/* Symbolic lookup functions
+ * Copyright (C) 2005 Intel Corporation.
+ *
+ * This file is part of systemtap, and is free software.  You can
+ * redistribute it and/or modify it under the terms of the GNU General
+ * Public License (GPL); either version 2, or (at your option) any
+ * later version.
+ */
+
 #ifndef _SYM_C_ /* -*- linux-c -*- */
 #define _SYM_C_
 
@@ -25,10 +34,9 @@ String _stp_symbol_sprint (String str, u
 
         name = _stp_kallsyms_lookup(address, &size, &offset, &modname, namebuf);
 
-	_stp_sprintf (str, "0x%lx", address);
-
 	if (name) {		
-		if (modname)
+		_stp_sprintf (str, "0x%lx", address);
+		if (modname && *modname)
 			_stp_sprintf (str, " : %s+%#lx/%#lx [%s]", name, offset, size, modname);
 		else
 			_stp_sprintf (str, " : %s+%#lx/%#lx", name, offset, size);
Index: src/tapsets.cxx
===================================================================
--- src.orig/tapsets.cxx
+++ src/tapsets.cxx
@@ -1,5 +1,6 @@
 // tapset resolution
 // Copyright (C) 2005 Red Hat Inc.
+// Copyright (C) 2005 Intel Corporation.
 //
 // This file is part of systemtap, and is free software.  You can
 // redistribute it and/or modify it under the terms of the GNU General
@@ -1760,6 +1761,17 @@ query_func_info (Dwarf_Addr entrypc,
 	}
       else
 	{
+#ifdef __ia64__
+	// In IA64 platform function probe point is set at its
+	// entry point rather than prologue end pointer, and in
+	// IA64 prologue end point also is not computed in such way
+	if (q->sess.verbose)
+	   clog << "querying entrypc of function '"
+		<< fi.name << "'" << endl;
+	   query_statement (fi.name, fi.decl_file, fi.decl_line, 
+		&fi.die, entrypc, q);
+
+#else
 	  if (q->sess.verbose)
 	    clog << "querying prologue-end of function '" 
 		 << fi.name << "'" << endl;
@@ -1770,6 +1782,7 @@ query_func_info (Dwarf_Addr entrypc,
 
 	  query_statement (fi.name, fi.decl_file, fi.decl_line, 
 			   &fi.die, fi.prologue_end, q);
+#endif
 	}
     }
   catch (semantic_error &e)
Index: src/translate.cxx
===================================================================
--- src.orig/translate.cxx
+++ src/translate.cxx
@@ -1,5 +1,6 @@
 // translation pass
 // Copyright (C) 2005 Red Hat Inc.
+// Copyright (C) 2005 Intel Corporation
 //
 // This file is part of systemtap, and is free software.  You can
 // redistribute it and/or modify it under the terms of the GNU General
@@ -2452,7 +2453,7 @@ translate_pass (systemtap_session& s)
       s.op->newline() << "#define MAXNESTING 30";
       s.op->newline() << "#endif";
       s.op->newline() << "#ifndef MAXSTRINGLEN";
-      s.op->newline() << "#define MAXSTRINGLEN 128";
+      s.op->newline() << "#define MAXSTRINGLEN 256";
       s.op->newline() << "#endif";
       s.op->newline() << "#ifndef MAXTRYLOCK";
       s.op->newline() << "#define MAXTRYLOCK 20";
@@ -2477,6 +2478,7 @@ translate_pass (systemtap_session& s)
       s.op->newline() << "#include \"runtime.h\"";
       s.op->newline() << "#include \"current.c\"";
       s.op->newline() << "#include \"stack.c\"";
+      s.op->newline() << "#include \"regs.c\"";
       s.op->newline() << "#include <linux/string.h>";
       s.op->newline() << "#include <linux/timer.h>";
       s.op->newline() << "#endif";


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