public inbox for systemtap@sourceware.org
 help / color / mirror / Atom feed
* debuginfoless static user probes
@ 2010-04-12  3:41 Stan Cox
  2010-04-12 16:11 ` Frank Ch. Eigler
  0 siblings, 1 reply; 10+ messages in thread
From: Stan Cox @ 2010-04-12  3:41 UTC (permalink / raw)
  To: SystemTap List

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

This patch implements adding info to the .probes section to access probe 
arguments and since the probe address is also in the .probes section this 
means no debuginfo is required for a process("proc").mark("mark") probe.  So 
here is a patch to implement that and also to implement not needing debuginfo 
for .mark probes.  The diffs are large but some of this is mechanical.  I put 
'#####' comments in the patch.  Comments?

[-- Attachment #2: stap.diff --]
[-- Type: text/plain, Size: 25097 bytes --]

The .probes section format is now:
%rcx %rsi %rdi 
seven__test
UPB1
pointer to seven__test
count of probe arguments
probe address
pointer to argument asm string

diff --git a/includes/sys/sdt.h b/includes/sys/sdt.h
index 7490678..e2700b1 100644
--- a/includes/sys/sdt.h
+++ b/includes/sys/sdt.h
@@ -25,23 +25,6 @@
    on having a writable .probes section to put the enabled variables in. */
 #define ALLOCSEC "\"aw\""
 
-/* An allocated section .probes that holds the probe names and addrs. */
-#define STAP_PROBE_DATA_(probe,guard,arg)		\
-  __asm__ volatile (".section .probes," ALLOCSEC "\n"	\
-		    "\t.balign 8\n"			\
-		    "1:\n\t.asciz " #probe "\n"         \
-		    "\t.balign 4\n"                     \
-		    "\t.int " #guard "\n"		\
-		    "\t.balign 8\n"			\
-		    STAP_PROBE_ADDR("1b\n")             \
-		    "\t.balign 8\n"                     \
-		    STAP_PROBE_ADDR(#arg "\n")		\
-		    "\t.int 0\n"			\
-		    "\t.previous\n")
-
-#define STAP_PROBE_DATA(probe, guard, arg)	\
-  STAP_PROBE_DATA_(#probe,guard,arg)
-
 #if defined STAP_HAS_SEMAPHORES
 #define STAP_SEMAPHORE(probe)	\
   if (__builtin_expect ( probe ## _semaphore , 0))
@@ -51,6 +34,25 @@
 
 #if ! defined EXPERIMENTAL_KPROBE_SDT
 
+/* An allocated section .probes that holds the probe names and addrs. */
+#define STAP_PROBE_DATA_(probe,guard,argc)	\
+  __asm__ volatile ("\t.balign 8\n"			\
+		    "1:\n\t.asciz " #probe "\n"		\
+  		    "\t.balign 8\n"			\
+		    "\t.int " #guard "\n"		\
+		    "\t.balign 8\n"			\
+  		    STAP_PROBE_ADDR ("1b\n")		\
+		    "\t.balign 8\n"			\
+		    STAP_PROBE_ADDR (#argc "\n")	\
+                    "\t.balign 8\n"                     \
+                    STAP_PROBE_ADDR("2f\n")          	\
+                    "\t.balign 8\n"                     \
+                    STAP_PROBE_ADDR("3b\n")		\
+		    "\t.int 0\n"			\
+		    "\t.previous\n")
+#define STAP_PROBE_DATA(probe, guard, argc)	\
+  STAP_PROBE_DATA_(#probe,guard,argc)
+
 /* These baroque macros are used to create a unique label. */
 #define STAP_CONCAT(a,b) a ## b
 #define STAP_LABEL_PREFIX(p) _stapprobe1_ ## p
@@ -78,7 +80,7 @@
 #define STAP_NOP "\tnop 0 "
 #endif
 
-#define STAP_UPROBE_GUARD 0x31425250
+#define STAP_UPROBE_GUARD 0x31425055
 
 #ifndef STAP_SDT_VOLATILE /* allow users to override */
 #if (__GNUC__ >= 4 && __GNUC_MINOR__ >= 5 \
@@ -90,18 +92,22 @@
 #define STAP_SDT_VOLATILE volatile
 #endif
 #endif
+
 #define STAP_PROBE_(probe)			\
 do {						\
-  STAP_PROBE_DATA(probe,STAP_UPROBE_GUARD,2f);	\
-  __asm__ volatile ("2:\n"			\
-		    STAP_NOP);			\
+  __asm__ volatile (".section .probes," ALLOCSEC "\n"	\
+		    "\t.balign 8\n");			\
+  STAP_PROBE_DATA(probe,STAP_UPROBE_GUARD,0);	\
+  __asm__ volatile ("2:\n" STAP_NOP);			\
 } while (0)
 
 #define STAP_PROBE1_(probe,label,parm1)			\
 do STAP_SEMAPHORE(probe) {				\
-  STAP_SDT_VOLATILE __typeof__((parm1)) arg1 = parm1;	\
+  STAP_SDT_VOLATILE __typeof__((parm1)) arg1 = parm1;		\
   STAP_UNINLINE;					\
-  STAP_PROBE_DATA(probe,STAP_UPROBE_GUARD,2f);		\
-  __asm__ volatile ("2:\n"				\
-		    STAP_NOP "/* %0 */" :: "g"(arg1));	\
+  __asm__ volatile (".section .probes," ALLOCSEC "\n"	\
+		    "\t.balign 8\n"			\
+		    "3:\n\t.asciz \"%0\"" :: "g" (arg1));	\
+  STAP_PROBE_DATA(probe,STAP_UPROBE_GUARD,1);	\
+  __asm__ volatile ("2:\n" STAP_NOP);	\
  } while (0)

...
 
 #else /* ! defined EXPERIMENTAL_KPROBE_SDT */
@@ -240,11 +264,32 @@ extern long int syscall (long int __sysno, ...) __THROW;
 # endif
 # if defined EXPERIMENTAL_KPROBE_SDT
 # define STAP_SYSCALL __NR_getegid
-# define STAP_GUARD 0x32425250
+# define STAP_GUARD 0x3142504b
 # endif
 
 #include <sys/syscall.h>
 
+/* An allocated section .probes that holds the probe names and addrs. */
+#define STAP_PROBE_DATA_(probe,guard,argc)	\
+  __asm__ volatile (".section .probes," ALLOCSEC "\n"	\
+		    "\t.balign 8\n"			\
+		    "1:\n\t.asciz " #probe "\n"		\
+		    "\t.balign 8\n"			\
+		    "\t.int " #guard "\n"		\
+		    "\t.balign 8\n"			\
+		    STAP_PROBE_ADDR ("1b\n")		\
+		    "\t.balign 8\n"			\
+		    STAP_PROBE_ADDR (#argc "\n")	\
+		    "\t.balign 8\n"			\
+		    STAP_PROBE_ADDR ("0\n")		\
+		    "\t.balign 8\n"			\
+		    STAP_PROBE_ADDR ("0\n")		\
+		    "\t.int 0\n"			\
+		    "\t.previous\n")
+
+#define STAP_PROBE_DATA(probe, guard, argc)	\
+  STAP_PROBE_DATA_(#probe,guard,argc)
+
 #define STAP_PROBE_(probe)			\
 do STAP_SEMAPHORE(probe) {			\
   STAP_PROBE_DATA(probe,STAP_GUARD,0);		\

##### Add byte register variants

diff --git a/tapset/i386/registers.stp b/tapset/i386/registers.stp
index c1e98ac..1a118bc 100644
--- a/tapset/i386/registers.stp
+++ b/tapset/i386/registers.stp
@@ -12,12 +12,16 @@ function _stp_register_regs() {
 
 	/* Same order as pt_regs */
 	_reg_offsets["ebx"] =  0		_reg_offsets["bx"] =  0
+			      			_reg_offsets["bl"] =  0
 	_reg_offsets["ecx"] =  4		_reg_offsets["cx"] =  4
+			      			_reg_offsets["cl"] =  4
 	_reg_offsets["edx"] =  8		_reg_offsets["dx"] =  8
+			      			_reg_offsets["dl"] =  8
 	_reg_offsets["esi"] = 12		_reg_offsets["si"] = 12
 	_reg_offsets["edi"] = 16		_reg_offsets["di"] = 16
 	_reg_offsets["ebp"] = 20		_reg_offsets["bp"] = 20
 	_reg_offsets["eax"] = 24		_reg_offsets["ax"] = 24
+			      			_reg_offsets["al"] = 24
 	_reg_offsets["xds"] = 28		_reg_offsets["ds"] = 28
 	_reg_offsets["xes"] = 32		_reg_offsets["es"] = 32
 	_reg_offsets["xfs"] = 36		_reg_offsets["fs"] = 36

##### Add byte register variants

diff --git a/tapset/x86_64/registers.stp b/tapset/x86_64/registers.stp
index e7abb18..ae5a639 100644
--- a/tapset/x86_64/registers.stp
+++ b/tapset/x86_64/registers.stp
@@ -2,21 +2,35 @@ global _reg_offsets, _r32_offsets, _stp_regs_registered
 
 function _stp_register_regs() {
 	/* Same order as pt_regs */
-	_reg_offsets["r15"] = 0
-	_reg_offsets["r14"] = 8
-	_reg_offsets["r13"] = 16
-	_reg_offsets["r12"] = 24
+	_reg_offsets["r15"] = 0		_reg_offsets["r15d"] = 0
+	_reg_offsets["r15w"] = 0	_reg_offsets["r15b"] = 0
+	_reg_offsets["r14"] = 8		_reg_offsets["r14d"] = 8
+	_reg_offsets["r14w"] = 8	_reg_offsets["r14b"] = 8
+	_reg_offsets["r13"] = 16	_reg_offsets["r13d"] = 16
+	_reg_offsets["r13w"] = 16	_reg_offsets["r13b"] = 16
+	_reg_offsets["r12"] = 24	_reg_offsets["r12d"] = 24
+	_reg_offsets["r12w"] = 24	_reg_offsets["r12b"] = 24
 	_reg_offsets["rbp"] = 32	_reg_offsets["bp"] = 32
 	_reg_offsets["rbx"] = 40	_reg_offsets["bx"] = 40
-	_reg_offsets["r11"] = 48
-	_reg_offsets["r10"] = 56
-	_reg_offsets["r9"]  = 64
-	_reg_offsets["r8"]  = 72
+			      		_reg_offsets["bl"] = 40
+	_reg_offsets["r11"] = 48	_reg_offsets["r11d"] = 48
+	_reg_offsets["r11w"] = 48	_reg_offsets["r11b"] = 48
+	_reg_offsets["r10"] = 56	_reg_offsets["r10d"] = 56
+	_reg_offsets["r10w"] = 56	_reg_offsets["r10b"] = 56
+	_reg_offsets["r9"]  = 64	_reg_offsets["r9d"]  = 64
+	_reg_offsets["r9w"]  = 64	_reg_offsets["r9b"]  = 64
+	_reg_offsets["r8"]  = 72	_reg_offsets["r8d"]  = 72
+	_reg_offsets["r8w"]  = 72	_reg_offsets["r8b"]  = 72
 	_reg_offsets["rax"] = 80	_reg_offsets["ax"] = 80
+			      		_reg_offsets["al"] = 80
 	_reg_offsets["rcx"] = 88	_reg_offsets["cx"] = 88
+			      		_reg_offsets["cl"] = 88
 	_reg_offsets["rdx"] = 96	_reg_offsets["dx"] = 96
+			      		_reg_offsets["dl"] = 96
 	_reg_offsets["rsi"] = 104	_reg_offsets["si"] = 104
+			      		_reg_offsets["sil"] = 104
 	_reg_offsets["rdi"] = 112	_reg_offsets["di"] = 112
+			      		_reg_offsets["dil"] = 112
 	_reg_offsets["orig_rax"] = 120	_reg_offsets["orig_ax"] = 120
 	_reg_offsets["rip"] = 128	_reg_offsets["ip"] = 128
 	_reg_offsets["xcs"] = 136	_reg_offsets["cs"] = 136

diff --git a/tapsets.cxx b/tapsets.cxx
index 7b04f79..fb78f34 100644
--- a/tapsets.cxx
+++ b/tapsets.cxx

##### rename have_reg_args to have_kprobe

@@ -3914,17 +3914,21 @@ dwarf_derived_probe_group::emit_module_exit (systemtap_session& s)
 struct sdt_var_expanding_visitor: public var_expanding_visitor
 {
   sdt_var_expanding_visitor(string & process_name, string & probe_name,
-			    int arg_count, bool have_reg_args):
+			    string & arg_string,
+			    int arg_count, bool have_kprobe):
     process_name (process_name), probe_name (probe_name),
-    have_reg_args (have_reg_args),
+    have_kprobe (have_kprobe),
     arg_count (arg_count)
   {
-    assert(!have_reg_args || (arg_count >= 0 && arg_count <= 10));
+    tokenize(arg_string, arg_tokens, " ");
+
+    assert(!have_kprobe || (arg_count >= 0 && arg_count <= 10));
   }
   string & process_name;
   string & probe_name;
-  bool have_reg_args;
+  bool have_kprobe;
   int arg_count;
+  vector<string> arg_tokens;
 
   void visit_target_symbol (target_symbol* e);
   void visit_defined_op (defined_op* e);

##### we now handle uprobe $arg case

@@ -3946,14 +3950,6 @@ sdt_var_expanding_visitor::visit_target_symbol (target_symbol *e)
           return;
         }
 
-      if (!startswith(e->base_name, "$arg") || ! have_reg_args)
-        {
-          // NB: uprobes-based sdt.h; $argFOO gets resolved later.
-          // XXX: We don't even know the arg_count in this case.
-          provide(e);
-          return;
-        }
-
       int argno = 0;
       try
         {

##### parse the asm arg string then create stap ops to access either RX or D(RX)

@@ -3965,56 +3961,123 @@ sdt_var_expanding_visitor::visit_target_symbol (target_symbol *e)
         }
       if (argno < 1 || argno > arg_count)
         throw semantic_error("invalid argument number", e->tok);
-
       bool lvalue = is_active_lvalue(e);
+      bool arg_in_memory = false;
       functioncall *fc = new functioncall;
+      binary_expression *be = new binary_expression;
 
-      // First two args are hidden: 1. pointer to probe name 2. task id
-      if (arg_count < 2)
+      if (!startswith(e->base_name, "$arg") || ! have_kprobe)
         {
-          fc->function = "ulong_arg";
-          fc->type = pe_long;
-          fc->tok = e->tok;
-          literal_number* num = new literal_number(argno + 2);
-          num->tok = e->tok;
-          fc->args.push_back(num);
-        }
-      else				// args passed as a struct
-        {
-          fc->function = "user_long";
-          fc->tok = e->tok;
-          binary_expression *be = new binary_expression;
-          be->tok = e->tok;
-          functioncall *get_arg1 = new functioncall;
-          get_arg1->function = "pointer_arg";
-          get_arg1->tok = e->tok;
-          literal_number* num = new literal_number(3);
-          num->tok = e->tok;
-          get_arg1->args.push_back(num);
-
-          be->left = get_arg1;
-          be->op = "+";
-          literal_number* inc = new literal_number((argno - 1) * 8);
-          inc->tok = e->tok;
-          be->right = inc;
-          fc->args.push_back(be);
-        }
+	  string reg;
+	  string disp_str;
+	  int disp = 0;
+          // NB: uprobes-based sdt.h; $argFOO gets resolved later.
 
-      if (lvalue)
-        *(target_symbol_setter_functioncalls.top()) = fc;
+	  string tok = arg_tokens[argno-1];
+	  bool bad_asm_op = false;
+
+	  for (unsigned i = 0; i < tok.length(); i++)
+	    // Recognize: %R | (%R) | N(%R)
+	    switch (tok[i])
+	      {
+	      case '-':
+	      case '1' ... '9':
+		{
+		  disp_str = tok.substr(i,tok.find('(',i)-i);
+		  i += disp_str.length();
+		  disp = lex_cast<int>(disp_str);
+		  arg_in_memory = true;
+		  break;
+		}
+	      case '(':
+		arg_in_memory = true;
+		break;
+	      case ')':
+		break;
+	      case '%':
+		{
+		  reg = tok.substr(i+1,tok.find(')',i)-i-1);
+		  i += reg.length();
+		  break;
+		}
+	      default:
+		bad_asm_op = true;
+	      }
+          if (reg.length() == 0 || bad_asm_op)
+            throw semantic_error("Unsupported assembler operand while accessing " + probe_name + " " + e->base_name, e->tok);
+
+	  fc->function = "user_long";
+	  fc->tok = e->tok;
+	  be->tok = e->tok;
+	  functioncall *get_arg1 = new functioncall;
+	  get_arg1->function = "register";
+	  get_arg1->tok = e->tok;
+	  literal_string* reg_arg = new literal_string(reg);
+	  reg_arg->tok = e->tok;
+	  get_arg1->args.push_back(reg_arg);
+
+	  be->left = get_arg1;
+	  be->op = "+";
+	  literal_number* inc = new literal_number(disp);
+	  inc->tok = e->tok;
+	  be->right = inc;
+	  fc->args.push_back(be);
+        }
 
-      if (e->components.empty())
+      else if (have_kprobe)
+	{
+	  // First two args are hidden: 1. pointer to probe name 2. task id
+	  if (arg_count < 2)
+	    {
+	      fc->function = "ulong_arg";
+	      fc->type = pe_long;
+	      fc->tok = e->tok;
+	      literal_number* num = new literal_number(argno + 2);
+	      num->tok = e->tok;
+	      fc->args.push_back(num);
+	    }
+	  else				// args passed as a struct
+	    {
+	      fc->function = "user_long";
+	      fc->tok = e->tok;
+	      binary_expression *be = new binary_expression;
+	      be->tok = e->tok;
+	      functioncall *get_arg1 = new functioncall;
+	      get_arg1->function = "pointer_arg";
+	      get_arg1->tok = e->tok;
+	      literal_number* num = new literal_number(3);
+	      num->tok = e->tok;
+	      get_arg1->args.push_back(num);
+
+	      be->left = get_arg1;
+	      be->op = "+";
+	      literal_number* inc = new literal_number((argno - 1) * 8);
+	      inc->tok = e->tok;
+	      be->right = inc;
+	      fc->args.push_back(be);
+	    }
+	  if (lvalue)
+	    *(target_symbol_setter_functioncalls.top()) = fc;
+	}
+      
+      if (e->components.empty()) // We have a scalar
         {
           if (e->addressof)
             throw semantic_error("cannot take address of sdt variable", e->tok);
 
-          provide(fc);
+	  if (have_kprobe || arg_in_memory)
+	    provide(fc);
+	  else
+	    provide(be);
           return;
         }
       cast_op *cast = new cast_op;
       cast->base_name = "@cast";
       cast->tok = e->tok;
-      cast->operand = fc;
+      if (have_kprobe || arg_in_memory)
+	cast->operand = fc;
+      else
+	cast->operand = be;
       cast->components = e->components;
       cast->type = probe_name + "_arg" + lex_cast(argno);
       cast->module = process_name;
@@ -4034,7 +4097,7 @@ sdt_var_expanding_visitor::visit_target_symbol (target_symbol *e)
 void
 sdt_var_expanding_visitor::visit_defined_op (defined_op *e)
 {
-  if (! have_reg_args) // for uprobes, pass @defined through to dwarf synthetic probe's own var-expansion
+  if (! have_kprobe) // for uprobes, pass @defined through to dwarf synthetic probe's own var-expansion
     provide (e);
   else
     var_expanding_visitor::visit_defined_op (e);

##### most of this is just supporting both old and new probes sections

@@ -4052,8 +4115,10 @@ struct sdt_query : public base_query
 private:
   enum probe_types
     {
-      uprobe_type = 0x31425250, // "PRB1"
-      kprobe_type = 0x32425250, // "PRB2"
+      uprobe1_type = 0x31425250, // "PRB1"
+      uprobe2_type = 0x31425055, // "UPB1"
+      kprobe1_type = 0x32425250, // "PRB2"
+      kprobe2_type = 0x3142504b  // "KPB1"
     } probe_type;
 
   probe * base_probe;
@@ -4067,7 +4132,9 @@ private:
   Elf_Data *pdata;
   size_t probe_scn_offset;
   size_t probe_scn_addr;
-  uint64_t probe_arg;
+  uint64_t arg_count;
+  uint64_t pc;
+  string arg_string;
   string probe_name;
 
   bool init_probe_scn();
@@ -4076,6 +4143,8 @@ private:
   void convert_probe(probe *base);
   void record_semaphore(vector<derived_probe *> & results, unsigned start);
   probe* convert_location();
+  bool have_uprobe() {return probe_type == uprobe1_type || probe_type == uprobe2_type;}
+  bool have_kprobe() {return probe_type == kprobe1_type || probe_type == kprobe2_type;}
 };
 
 
@@ -4100,7 +4169,7 @@ sdt_query::handle_query_module()
 
   while (get_next_probe())
     {
-      if (probe_type != uprobe_type
+      if (! have_uprobe()
 	  && !probes_handled.insert(probe_name).second)
         continue;
 
@@ -4109,10 +4178,12 @@ sdt_query::handle_query_module()
 	  clog << "matched probe_name " << probe_name << " probe_type ";
 	  switch (probe_type)
 	    {
-	    case uprobe_type:
-	      clog << "uprobe at 0x" << hex << probe_arg << dec << endl;
+	    case uprobe1_type:
+	    case uprobe2_type:
+	      clog << "uprobe at 0x" << hex << pc << dec << endl;
 	      break;
-	    case kprobe_type:
+	    case kprobe1_type:
+	    case kprobe2_type:
 	      clog << "kprobe" << endl;
 	      break;
 	    }
@@ -4122,22 +4193,23 @@ sdt_query::handle_query_module()
       probe *new_base = convert_location();
       probe_point *new_location = new_base->locations[0];
 
-      bool have_reg_args = false;
-      if (probe_type == kprobe_type)
+      bool kprobe_found = false;
+      if (have_kprobe())
         {
           convert_probe(new_base);
-          have_reg_args = true;
+          kprobe_found = true;
         }
 
       // Expand the local variables in the probe body
       sdt_var_expanding_visitor svv (module_val, probe_name,
-                                     probe_arg, // XXX: whoa, isn't this 'arg_count'?
-                                     have_reg_args);
+				     arg_string,
+                                     arg_count,
+                                     kprobe_found);
       svv.replace (new_base->body);
 
       unsigned i = results.size();
 
-      if (probe_type == kprobe_type)
+      if (have_kprobe())
         derive_probes(sess, new_base, results);
 
       else

##### just wire in a uprobe_derived_probe "by hand" to avoid needeing debuginfo
##### TODO the old iterate_over_modules method is still needed for version I

@@ -4149,9 +4221,30 @@ sdt_query::handle_query_module()
               params[c->functor] = c->arg;
             }
 
-          dwarf_query q(new_base, new_location, dw, params, results, "", "");
-          q.has_mark = true; // enables mid-statement probing
-          dw.iterate_over_modules(&query_module, &q);
+	  dwarf_query q(new_base, new_location, dw, params, results, "", "");
+	  q.has_mark = true; // enables mid-statement probing
+#if 0
+	  dw.iterate_over_modules(&query_module, &q);
+#else
+
+	  Dwarf_Addr bias;
+	  Elf* elf = (dwarf_getelf (dwfl_module_getdwarf (q.dw.mod_info->mod, &bias))
+		      ?: dwfl_module_getelf (q.dw.mod_info->mod, &bias));
+
+	  GElf_Ehdr ehdr_mem;
+	  GElf_Ehdr* em = gelf_getehdr (elf, &ehdr_mem);
+	  string section;
+	  if ((em->e_type == ET_EXEC))
+	    section = ".absolute";
+	  else if (em->e_type == ET_DYN)
+	    section = ".dynamic";
+	  uprobe_derived_probe* p =
+	    new uprobe_derived_probe ("", "", 0, q.module_val, section /*".absolute"*/,
+				     q.statement_num_val, q.statement_num_val,
+				     q, 0);
+	  results.push_back (p);
+	  sess.unwindsym_modules.insert ("kernel");
+#endif
         }
 
       record_semaphore(results, i);
@@ -4204,7 +4297,7 @@ sdt_query::init_probe_scn()
 	  if (strcmp (elf_strptr (elf, shstrndx, shdr->sh_name),
 		      ".probes") == 0)
 	    have_probes = true;
-	    break;
+	  break;
 	}
     }
 
##### get next probe from either v1 or v2

@@ -4234,17 +4327,12 @@ sdt_query::get_next_probe()
 
   while (probe_scn_offset < pdata->d_size)
     {
-      struct probe_entry
-      {
-	__uint64_t name;
-	__uint64_t arg;
-      }  *pbe;
       __uint32_t *type = (__uint32_t*) ((char*)pdata->d_buf + probe_scn_offset);
       probe_type = (enum probe_types)*type;
-      if (probe_type != uprobe_type && probe_type != kprobe_type)
+      if (! have_uprobe() && ! have_kprobe())
 	{
 	  // Unless this is a mangled .probes section, this happens
-	  // because the name of the probe comes first, followed by
+	  // because the name of the probe comes first, followed by	
 	  // the sentinel.
 	  if (sess.verbose > 5)
 	    clog << "got unknown probe_type: 0x" << hex << probe_type
@@ -4252,18 +4340,51 @@ sdt_query::get_next_probe()
 	  probe_scn_offset += sizeof(__uint32_t);
 	  continue;
 	}
-      probe_scn_offset += sizeof(__uint32_t);
-      probe_scn_offset += probe_scn_offset % sizeof(__uint64_t);
-      pbe = (struct probe_entry*) ((char*)pdata->d_buf + probe_scn_offset);
-      if (pbe->name == 0)
-	return false;
-      probe_name = (char*)((char*)pdata->d_buf + pbe->name - (char*)probe_scn_addr);
-      probe_arg = pbe->arg;
+      if (probe_type == uprobe1_type || probe_type == kprobe1_type)
+	{
+	  struct probe_entry
+	  {
+	    __uint64_t name;
+	    __uint64_t arg;
+	  }  *pbe;
+
+	  probe_scn_offset += sizeof(__uint32_t);
+	  probe_scn_offset += probe_scn_offset % sizeof(__uint64_t);
+	  pbe = (struct probe_entry*) ((char*)pdata->d_buf + probe_scn_offset);
+	  if (pbe->name == 0)
+	    return false;
+	  probe_name = (char*)((char*)pdata->d_buf + pbe->name - (char*)probe_scn_addr);
+	  if (probe_type == uprobe1_type)
+	    {
+	      pc = pbe->arg;
+	      arg_count = 0;
+	    }
+	  else if (probe_type == kprobe1_type)
+	    arg_count = pbe->arg;
+	  probe_scn_offset += sizeof (struct probe_entry);
+	}
+      else if (probe_type == uprobe2_type || probe_type == kprobe2_type)
+	{
+	  struct probe_entry
+	  {
+	    __uint64_t type;
+	    __uint64_t name;
+	    __uint64_t arg_count;
+	    __uint64_t pc;
+	    __uint64_t arg_string;
+	  }  *pbe;
+	  pbe = (struct probe_entry*) ((char*)pdata->d_buf + probe_scn_offset);
+	  probe_name = (char*)((char*)pdata->d_buf + pbe->name - (char*)probe_scn_addr);
+	  arg_count = pbe->arg_count;
+	  pc = pbe->pc;
+	  if (pbe->arg_string)
+	    arg_string = (char*)((char*)pdata->d_buf + pbe->arg_string - (char*)probe_scn_addr);
+	  probe_scn_offset += sizeof (struct probe_entry);
+	}
       if (sess.verbose > 4)
 	clog << "saw .probes " << probe_name
-	     << "@0x" << hex << probe_arg << dec << endl;
+	     << "@0x" << hex << pc << dec << endl;
 
-      probe_scn_offset += sizeof (struct probe_entry);
       if ((mark_name == probe_name)
 	  || (dw.name_has_wildcard (mark_name)
 	      && dw.function_name_matches_pattern (probe_name, mark_name)))
@@ -4298,7 +4419,7 @@ sdt_query::convert_probe (probe *base)
 
   // XXX: Does this also need to happen for i386 under x86_64 stap?
 #ifdef __i386__
-  if (probe_type == kprobe_type)
+  if (have_kprobe())
     {
       functioncall *rp = new functioncall;
       rp->function = "regparm";
@@ -4313,9 +4434,9 @@ sdt_query::convert_probe (probe *base)
     }
 #endif
 
-  if (probe_type == kprobe_type)
+  if (have_kprobe())
     {
-      // Generate: if (arg2 != kprobe_type) next;
+      // Generate: if (arg2 != kprobe2_type) next;
       if_statement *istid = new if_statement;
       istid->thenblock = new next_statement;
       istid->elseblock = NULL;
@@ -4333,7 +4454,7 @@ sdt_query::convert_probe (probe *base)
       arg2->args.push_back(num);
 
       betid->left = arg2;
-      literal_number* littid = new literal_number(kprobe_type);
+      literal_number* littid = new literal_number(probe_type);
       littid->tok = b->tok;
       betid->right = littid;
       istid->condition = betid;
@@ -4389,17 +4510,19 @@ sdt_query::convert_location ()
 
         switch (probe_type)
           {
-          case uprobe_type:
+          case uprobe1_type:
+          case uprobe2_type:
             if (sess.verbose > 3)
               clog << "probe_type == uprobe_type, use statement addr: 0x"
-                << hex << probe_arg << dec << endl;
+		   << hex << pc << dec << endl;
             // process("executable").statement(probe_arg)
             derived_loc->components[i] =
               new probe_point::component(TOK_STATEMENT,
-                                         new literal_number(probe_arg, true));
+                                         new literal_number(pc, true));
             break;
 
-	  case kprobe_type:
+	  case kprobe1_type:
+	  case kprobe2_type:
 	    if (sess.verbose > 3)
 	      clog << "probe_type == kprobe_type" << endl;
 	    // kernel.function("*getegid*")
@@ -4412,7 +4535,7 @@ sdt_query::convert_location ()
           default:
             if (sess.verbose > 3)
               clog << "probe_type == use_uprobe_no_dwarf, use label name: "
-                << "_stapprobe1_" << mark_name << endl;
+		   << "_stapprobe1_" << mark_name << endl;
             // process("executable").function("*").label("_stapprobe1_MARK_NAME")
             derived_loc->components[i] =
               new probe_point::component(TOK_FUNCTION, new literal_string("*"));
@@ -4423,7 +4546,7 @@ sdt_query::convert_location ()
           }
       }
     else if (derived_loc->components[i]->functor == TOK_PROCESS
-             && probe_type == kprobe_type)
+             && have_kprobe())
       {
         derived_loc->components[i] = new probe_point::component(TOK_KERNEL);
       }
@@ -4998,7 +5121,7 @@ uprobe_derived_probe_group::emit_module_decls (systemtap_session& s)
               s.op->line() << " .procname=" << lex_cast_qstring(p->module) << ",";
               s.op->line() << " .callback=&stap_uprobe_process_found,";
             }
-          if (p->section != ".absolute") // ET_DYN 
+          else if (p->section != ".absolute") // ET_DYN 
             {
 	      if (p->has_library && p->sdt_semaphore_addr != 0)
 		s.op->line() << " .procname=\"" << p->path << "\", ";

##### not shown is sdt_misc.exp  which uses an old format
##### sdt.h that is squirrelled away in /testsuite to build and test with.


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

end of thread, other threads:[~2010-05-25 13:37 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2010-04-12  3:41 debuginfoless static user probes Stan Cox
2010-04-12 16:11 ` Frank Ch. Eigler
2010-04-22 13:41   ` Stan Cox
2010-05-04 17:45     ` Stan Cox
2010-05-04 19:09       ` Frank Ch. Eigler
2010-05-04 21:07         ` David Smith
2010-05-06  0:24         ` Roland McGrath
2010-05-10 17:48         ` Stan Cox
2010-05-21 18:37           ` Stan Cox
2010-05-25 20:10             ` Stan Cox

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).