# New Ticket Created by  Jürgen Bömmels 
# Please include the string:  [perl #18072]
# in the subject line of all future correspondence about this issue. 
# <URL: http://rt.perl.org/rt2/Ticket/Display.html?id=18072 >


A PackFile created with a diffrent version of core.ops leads to
strange not easy to find errors. Therefor a fingerprint of core.ops is
entered to the packfile.

The fingerprint of the core.ops file is generated out of signatures of
the operations (comments and implementation details dont contribute).
This is relativ easy, because the complete parsing of core.ops is done
in OpsFile.pm.

I implemented in a really hacky way: abusing the padding bytes. But
this way it can be implemented *now*. When the named segments are in,
the fingerprint will go to a segment on its own. (Now I can only use
10 bytes of the 16 byte MD5-Hash, but hey we don't want to make
cryptography).

bye
b.



-- attachment  1 ------------------------------------------------------
url: http://rt.perl.org/rt2/attach/40500/32674/273ee1/fingerprint.diff

Index: MANIFEST
===================================================================
RCS file: /cvs/public/parrot/MANIFEST,v
retrieving revision 1.239
diff -u -r1.239 MANIFEST
--- MANIFEST	23 Oct 2002 05:33:39 -0000	1.239
+++ MANIFEST	24 Oct 2002 01:05:08 -0000
@@ -199,6 +199,7 @@
 examples/pxs/PQt.C
 examples/pxs/QtHelloWorld.pasm
 exceptions.c
+fingerprint_c.pl
 global_setup.c
 hash.c
 headers.c
Index: MANIFEST.SKIP
===================================================================
RCS file: /cvs/public/parrot/MANIFEST.SKIP,v
retrieving revision 1.6
diff -u -r1.6 MANIFEST.SKIP
--- MANIFEST.SKIP	4 Sep 2002 03:48:26 -0000	1.6
+++ MANIFEST.SKIP	24 Oct 2002 01:05:08 -0000
@@ -18,6 +18,8 @@
 
 ^core_ops\.c$
 ^core_ops_prederef\.c$
+^core_ops_cg\.c$
+^fingerprint\.c$
 
 ^lib/Parrot/Jit\.pm$
 ^lib/Parrot/PMC\.pm$
Index: fingerprint_c.pl
===================================================================
RCS file: fingerprint_c.pl
diff -N fingerprint_c.pl
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ fingerprint_c.pl	24 Oct 2002 01:05:08 -0000
@@ -0,0 +1,74 @@
+#! perl -w
+
+use strict;
+use lib 'lib';
+use Digest::MD5 qw(md5_hex);
+use Data::Dumper;
+use Parrot::OpLib::core;
+
+my $len = 10;
+my $fingerprint = md5_hex join "\n", map {
+  join '_', $_->{NAME}, @{$_->{ARGS}}
+} @$Parrot::OpLib::core::ops;
+
+print << "EOF";
+/*
+ * !!!!!!!   DO NOT EDIT THIS FILE   !!!!!!!
+ *
+ * This file is generated automatically from 'core.ops' 
+ * by $0.
+ *
+ * Any changes made here will be lost!
+ *
+ */
+
+#include <string.h>
+#include <parrot/packfile.h>
+
+EOF
+
+if (-e 'DEVELOPING') {
+
+print "/* $fingerprint */\n";
+print "static const unsigned char fingerprint[] = {\n";
+for my $i (0..$len-1) {
+  print '    0x', substr ($fingerprint, $i*2, 2), ",\n";
+}
+print "};\n";
+
+print << "EOF";
+
+int
+PackFile_check_fingerprint (void *cursor)
+{
+    return memcmp (cursor, fingerprint, $len) == 0;
+}
+
+size_t
+PackFile_write_fingerprint (void *cursor)
+{
+    memcpy (cursor, fingerprint, $len);
+    return $len;
+}
+EOF
+
+} else { # !DEVELOPING  
+
+  print << 'EOF';
+/* fingerprint checking is only in enabled in development versions */
+
+int
+PackFile_check_fingerprint (void *cursor)
+{
+    return 1;
+}
+
+size_t
+PackFile_write_fingerprint (void *cursor) 
+{
+    memset (cursor, 0, $len);
+    return $len;
+}
+EOF
+
+} # endif DEVELOPING
Index: assemble.pl
===================================================================
RCS file: /cvs/public/parrot/assemble.pl,v
retrieving revision 1.93
diff -u -r1.93 assemble.pl
--- assemble.pl	18 Oct 2002 21:18:33 -0000	1.93
+++ assemble.pl	24 Oct 2002 01:05:10 -0000
@@ -427,6 +427,7 @@
 use Parrot::Types; # For pack_op()
 use Parrot::OpLib::core;
 use Parrot::Config;
+use Digest::MD5 qw(md5_hex);
 
 =head2 Assembler class
 
@@ -828,6 +829,17 @@
 
 =cut
 
+sub _fingerprint {
+  my $fingerprint = md5_hex join "\n", map {
+    join '_', $_->{NAME}, @{$_->{ARGS}}
+  } @$Parrot::OpLib::core::ops;
+  my @arr = ();
+  for my $i (0..9) {
+    push @arr, hex substr ($fingerprint, $i*2, 2);
+  }
+  return @arr;
+}
+
 sub output_bytecode {
     my $self = shift;
     my $wordsize;
@@ -847,20 +859,7 @@
 
         flags       => 0x00, # unsigned char flags
         floattype   => 0x00, # unsigned char floattype
-        pad         => [
-            0x19, # unsigned char pad[0]
-            0x40, # unsigned char pad[1]
-
-            0xe4, # unsigned char pad[2]
-            0x73, # unsigned char pad[3]
-            0x09, # unsigned char pad[4]
-            0x08, # unsigned char pad[5]
-
-            0x00, # unsigned char pad[6]
-            0x00, # unsigned char pad[7]
-            0x00, # unsigned char pad[8]
-            0x00  # unsigned char pad[9]
-        ],
+        pad         => [ _fingerprint ],
 
         magic       => 0x0131_55a1, # opcode_t magic
         opcodetype  => 0x5045_524c, # opcode_t opcodetype
Index: packout.c
===================================================================
RCS file: /cvs/public/parrot/packout.c,v
retrieving revision 1.12
diff -u -r1.12 packout.c
--- packout.c	11 Oct 2002 01:46:31 -0000	1.12
+++ packout.c	24 Oct 2002 01:05:10 -0000
@@ -85,6 +85,9 @@
     self->header->flags = 0;
     self->header->floattype = 0;
 
+    /* write the fingerprint */
+    PackFile_write_fingerprint (self->header->pad);
+
     /* Pack the header */
     mem_sys_memcopy(cursor, self->header, PACKFILE_HEADER_BYTES);
     cursor += PACKFILE_HEADER_BYTES / sizeof(opcode_t);
Index: packfile.c
===================================================================
RCS file: /cvs/public/parrot/packfile.c,v
retrieving revision 1.57
diff -u -r1.57 packfile.c
--- packfile.c	11 Oct 2002 01:46:31 -0000	1.57
+++ packfile.c	24 Oct 2002 01:05:11 -0000
@@ -333,6 +333,13 @@
      */
     header->magic = PackFile_fetch_op(self, cursor++);
 
+    /* check the fingerprint */
+    if (!PackFile_check_fingerprint (header->pad)) {
+        PIO_eprintf(NULL, "PackFile_unpack: Bytecode not valid for this "
+                    "interpreter\n");
+        return 0;
+    }
+
     /*
      * The magic and opcodetype fields are in native byteorder.
      */
Index: config/gen/makefiles/root.in
===================================================================
RCS file: /cvs/public/parrot/config/gen/makefiles/root.in,v
retrieving revision 1.46
diff -u -r1.46 root.in
--- config/gen/makefiles/root.in	21 Oct 2002 08:47:06 -0000	1.46
+++ config/gen/makefiles/root.in	24 Oct 2002 01:05:11 -0000
@@ -51,7 +51,7 @@
 GEN_HEADERS = $(INC)/vtable.h $(INC)/oplib/core_ops.h \
 $(INC)/oplib/core_ops_prederef.h
 
-GEN_SOURCES = core_ops.c core_ops_prederef.c
+GEN_SOURCES = core_ops.c core_ops_prederef.c fingerprint.c
 
 GEN_MODULES = lib/Parrot/Jit.pm lib/Parrot/OpLib/core.pm
 
@@ -100,7 +100,7 @@
 	 embed$(O) warnings$(O)  ${cg_o} \
 	 packout$(O) byteorder$(O) debug$(O) smallobject$(O) \
 	 headers$(O) dod$(O) method_util$(O) \
-	 misc$(O) spf_render$(O) spf_vtable$(O)
+	 misc$(O) spf_render$(O) spf_vtable$(O) fingerprint$(O)
 
 O_FILES = $(INTERP_O_FILES) \
 	      $(IO_O_FILES) \
@@ -265,8 +265,8 @@
 # Parrot Dump
 #
 
-#$(PDUMP) : pdump$(O) packfile$(O)
-#	$(LINK) ${ld_out}$(PDUMP) $(LINKFLAGS) pdump$(O) packfile$(O) string$(O) chartype$(O) memory$(O) $(C_LIBS)
+$(PDUMP) : pdump$(O) packdump$(O) $(O_FILES) $(O_DIRS)
+	$(LINK) ${ld_out}$(PDUMP) pdump$(O) packdump$(O) $(LINKFLAGS) $(O_FILES) $(C_LIBS)
 
 
 ###############################################################################
@@ -279,6 +279,9 @@
 
 lib/Parrot/OpLib/core.pm : $(OPS_FILES) ops2pm.pl lib/Parrot/OpsFile.pm lib/Parrot/Op.pm
 	$(PERL) ops2pm.pl $(OPS_FILES)
+
+fingerprint.c : fingerprint_c.pl lib/Parrot/OpLib/core.pm
+	$(PERL) fingerprint_c.pl > fingerprint.c
 
 ###############################################################################
 #
Index: .cvsignore
===================================================================
RCS file: /cvs/public/parrot/.cvsignore,v
retrieving revision 1.22
diff -u -r1.22 .cvsignore
--- .cvsignore	23 Oct 2002 03:01:20 -0000	1.22
+++ .cvsignore	24 Oct 2002 01:12:17 -0000
@@ -5,6 +5,7 @@
 core_ops.c
 core_ops_prederef.c
 disassemble
+fingerprint.c
 libparrot.a
 libparrot.def
 Makefile

Reply via email to