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]

[PATCH]PR 4886: validate debuginfo based on build-id


The patch is to provide sanity check of debuginfo(PR 4886) based on
build-id, as described in
http://fedoraproject.org/wiki/Releases/FeatureBuildId.

There are some requisites for it to work:
	binutils-2.17.50.0.17 or later
	Kernel 2.6.23 or later
	elfutils 0.128 or later (compilation required)
Otherwise, the check will be skipped.

Already done some tests on x86/x86_64, relocate/non-relocate kernel.

Any comment/reply are welcome.

Regards,
Wenji


diff --git a/main.cxx b/main.cxx
index 05a137b..8cb8163 100644
--- a/main.cxx
+++ b/main.cxx
@@ -318,6 +318,7 @@ main (int argc, char * const argv [])
   s.unoptimized = false;
   s.suppress_warnings = false;
   s.listing_mode = false;
+  s.build_id_len = 0;
 
 #ifdef ENABLE_PROLOGUES
   s.prologue_searching = true;
diff --git a/session.h b/session.h
index 734c8d7..43b26d3 100644
--- a/session.h
+++ b/session.h
@@ -178,6 +178,10 @@ struct systemtap_session
   void print_error (const semantic_error& e);
   void print_warning (const std::string& w, const token* tok = 0);
 
+  //build-id for validating debuginfo
+  unsigned char *build_id_bits;
+  GElf_Addr  build_id_vaddr;
+  int build_id_len;
   // reNB: new POD members likely need to be explicitly cleared in the ctor.
 };
 
diff --git a/tapsets.cxx b/tapsets.cxx
index 21c9fb5..28d11b4 100644
--- a/tapsets.cxx
+++ b/tapsets.cxx
@@ -3796,6 +3796,32 @@ validate_module_elf (Dwfl_Module *mod, const char *name,  base_query *q)
          << " ELF machine " << expect_machine
          << " (code " << elf_machine << ")"
          << "\n";
+
+  //extract build-id from kernel debuginfo file 
+  int build_id_len = 0;
+  unsigned char *build_id_bits;
+  GElf_Addr build_id_vaddr; 	
+
+  //FIXME: currently just verify kernel debug file
+  if (!q->dw.module_name.compare("kernel") && 
+      (build_id_len=dwfl_module_build_id(mod,
+					(const unsigned char **)&build_id_bits,
+					 &build_id_vaddr)) > 0) 
+  {
+	q->sess.build_id_len = build_id_len;
+	void *copy = malloc(build_id_len);
+        q->sess.build_id_bits = (unsigned char *)memcpy(copy,
+						       build_id_bits,
+						       build_id_len);
+	q->sess.build_id_vaddr = build_id_vaddr;
+
+	if (q->sess.verbose > 2) {
+	   clog << "Found build-id in " << debug_filename
+		<< ", length " << q->sess.build_id_len;
+	   clog	<< ", end at 0x" << hex << q->sess.build_id_vaddr 
+		<< dec << endl;	
+	}
+  }
 }
 
 static int
diff --git a/translate.cxx b/translate.cxx
index 215d7ff..fcf8247 100644
--- a/translate.cxx
+++ b/translate.cxx
@@ -1109,12 +1109,68 @@ c_unparser::emit_module_init ()
                 << ");";
   o->newline() << "rc = -EINVAL;";
   o->newline(-1) << "}";
-
-  // XXX: perform buildid-based checking if able
-
+  
   o->newline(-1) << "}";
   o->newline() << "if (rc) goto out;";
 
+  // perform buildid-based checking if able
+  if (session->build_id_len > 0) {
+  	o->newline() << "{";
+  	//initialize data for matching build-id
+        o->newline(1) << "unsigned char *build_id_bits = \"";
+        for (int j = 0; j < session->build_id_len; j++)
+                o->line() << "\\x"
+                          << hex << (unsigned short)*(session->build_id_bits+j)
+                          << dec;
+        o->line() << "\";";
+
+	o->newline() << "unsigned long build_id_start, build_id_stop = "
+		     << " (unsigned long) 0x"
+		     << hex << session->build_id_vaddr << dec
+		     << ";";
+
+	o->newline() << "build_id_start = build_id_stop - "
+		     << session->build_id_len << ";";
+
+        //the address should be bigger than "_stext" address
+        //NB: _stext is the relocation name
+	o->newline() << "if (build_id_start < _stp_module_relocate(\"kernel\"" 
+		     << " ,\"_stext\" , 0)) {";
+	o->newline(1) << "_stp_error(\"Incorrect __start_notes address\");";
+  	o->newline() << "rc = -EINVAL;";
+	o->newline() << "goto out;";
+	o->newline(-1) << "}";
+
+        //compare build-id
+ 	o->newline() << "if (memcmp(build_id_bits" 
+		     << ", (unsigned char *) build_id_start"
+		     << ", " <<	session->build_id_len
+		     << ")) {";
+	o->newline(1) << "_stp_printf(\"Expected build-id:\\n\");";
+	o->newline() << "for (i=0;i<"
+		     <<  session->build_id_len
+		     <<  ";i++)";
+	o->newline(1) << "_stp_printf(\" 0x%x\","
+		      << "*(build_id_bits+i));";
+
+	o->newline(-1) << "_stp_printf(\"\\nActual build-id:\\n\");";
+	o->newline() << "for (i=0;i<"
+		     <<  session->build_id_len
+		     <<  ";i++)";
+	 o->newline(1) << "_stp_printf(\" 0x%x\","
+		       << "*((unsigned char *)(build_id_start+i)));";
+
+	 o->newline(-1) << "_stp_printf(\"\\n\");";
+	 o->newline() << "_stp_print_flush();";
+	 o->newline() << "_stp_error(\"build-id mismatch between "
+		      << "debuginfo and kernel\");";
+  	 o->newline() << "rc = -EINVAL;";
+  	 o->newline() << "goto out;";
+	 o->newline(-1) << "}";
+
+  	 o->newline(-1) << "}";
+  }
+  
   o->newline() << "(void) probe_point;";
   o->newline() << "(void) i;";
   o->newline() << "(void) j;";


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