Started to copy the import tool from libunbin.
authorRichard W.M. Jones <rich@annexia.org>
Tue, 10 Jun 2008 21:50:48 +0000 (21:50 +0000)
committerRichard W.M. Jones <rich@annexia.org>
Tue, 10 Jun 2008 21:50:48 +0000 (21:50 +0000)
Makefile.in
README
cil-tools/.depend [new file with mode: 0644]
cil-tools/Makefile.in [new file with mode: 0644]
cil-tools/bitmatch-import-prefix.h [new file with mode: 0644]
cil-tools/bitmatch_import_c.ml [new file with mode: 0644]
cil-tools/ext3.c [new file with mode: 0644]
configure.ac

index ff5945b..b535b7a 100644 (file)
@@ -32,11 +32,17 @@ OCAMLOPTPACKAGES =
 
 OCAMLDOCFLAGS  = -html -sort
 
+SUBDIRS                =
+ifneq ($(pkg_cil),no)
+SUBDIRS                += cil-tools
+endif
+
 EXAMPLES       = $(patsubst %.ml,%,$(wildcard examples/*.ml))
 
 TESTS          = $(patsubst %.ml,%,$(wildcard tests/*.ml))
 
 all:   bitmatch.cma bitmatch.cmxa pa_bitmatch.cmo
+       @for d in $(SUBDIRS); do $(MAKE) -C $$d $@; done
 
 bitmatch.cma: bitmatch_types.cmo bitmatch_config.cmo bitmatch.cmo
        $(OCAMLFIND) ocamlc -a -o $@ $^
@@ -62,6 +68,7 @@ test: pa_bitmatch.cmo bitmatch.cma
          $$f; \
          if [ $$? -ne 0 ]; then exit 1; fi; \
        done
+       @for d in $(SUBDIRS); do $(MAKE) -C $$d $@; done
 
 examples: pa_bitmatch.cmo bitmatch.cma
        @for f in $(EXAMPLES); do \
@@ -70,6 +77,7 @@ examples: pa_bitmatch.cmo bitmatch.cma
            -package unix -linkpkg -I . bitmatch.cma $$f.ml -o $$f; \
          if [ $$? -ne 0 ]; then exit 1; fi; \
        done
+       @for d in $(SUBDIRS); do $(MAKE) -C $$d $@; done
 
 print-tests: pa_bitmatch.cmo
        @for f in $(TESTS); do \
@@ -92,11 +100,13 @@ clean:
        rm -f core *~ *.cmi *.cmo *.cmx *.cma *.cmxa *.a *.o
        rm -f tests/*~ tests/*.cmi tests/*.cmo $(TESTS)
        rm -f examples/*~ examples/*.cmi examples/*.cmo $(EXAMPLES)
+       @for d in $(SUBDIRS); do $(MAKE) -C $$d $@; done
 
 distclean: clean
        rm -rf autom4te.cache
        rm -f config.log config.status
        rm -f config.h Makefile META bitmatch_config.ml
+       @for d in $(SUBDIRS); do $(MAKE) -C $$d $@; done
 
 # Documentation.
 
@@ -113,6 +123,7 @@ install:
        ocamlfind install bitmatch META *.mli *.cmx *.cma *.cmxa *.a \
                bitmatch.cmi \
                pa_bitmatch.cmo
+       @for d in $(SUBDIRS); do $(MAKE) -C $$d $@; done
 
 # Standard rules.
 
@@ -124,6 +135,7 @@ install:
        $(OCAMLFIND) ocamlopt $(OCAMLOPTFLAGS) $(OCAMLOPTPACKAGES) -c $<
 
 depend: .depend
+       @for d in $(SUBDIRS); do $(MAKE) -C $$d $@; done
 
 .depend: bitmatch.ml bitmatch.mli
        rm -f .depend
diff --git a/README b/README
index e6da02d..d0c8b13 100644 (file)
--- a/README
+++ b/README
@@ -3,7 +3,11 @@ License: LGPLv2+ with OCaml linking exception.
 
 Please see the html subdirectory for developer documentation.
 
-The only dependencies are OCaml >= 3.10.0, camlp4, ocamldoc, and findlib.
+The only requirements are OCaml >= 3.10.0, camlp4, ocamldoc, and findlib.
+
+If you optionally have CIL (http://cil.sourceforge.net/) installed
+then there are some nice extra tools for converting C header files
+into matchable OCaml structures.
 
 To build:
 
diff --git a/cil-tools/.depend b/cil-tools/.depend
new file mode 100644 (file)
index 0000000..20be473
--- /dev/null
@@ -0,0 +1,2 @@
+bitmatch_import_c.cmo: ../bitmatch.cmi 
+bitmatch_import_c.cmx: ../bitmatch.cmx 
diff --git a/cil-tools/Makefile.in b/cil-tools/Makefile.in
new file mode 100644 (file)
index 0000000..c66dd21
--- /dev/null
@@ -0,0 +1,82 @@
+# Bitmatch syntax extension.
+# Copyright (C) 2008 Red Hat Inc., Richard W.M. Jones
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301  USA
+#
+# $Id: Makefile.in 81 2008-05-21 09:59:21Z richard.wm.jones $
+
+PACKAGE                = @PACKAGE_NAME@
+VERSION                = @PACKAGE_VERSION@
+
+OCAMLFIND      = @OCAMLFIND@
+OCAMLMKLIB     = @OCAMLMKLIB@
+OCAMLDOC       = @OCAMLDOC@
+INSTALL                = @INSTALL@
+
+OCAMLCFLAGS    = -g
+OCAMLCPACKAGES = -package unix,str,extlib,cil -I ..
+OCAMLCLIBS     = $(OCAMLCPACKAGES) -linkpkg ../bitmatch.cma
+OCAMLOPTFLAGS  =
+OCAMLOPTPACKAGES = $(OCAMLCPACKAGES)
+OCAMLOPTLIBS   = $(OCAMLOPTPACKAGES) -linkpkg ../bitmatch.cmxa
+
+OCAMLDOCFLAGS  = -html -sort
+
+all:           bitmatch-import-c bitmatch-import-c.opt
+
+bitmatch-import-c: bitmatch_import_c.cmo
+       $(OCAMLFIND) ocamlc $(OCAMLCFLAGS) $(OCAMLCLIBS) $< -o $@
+
+bitmatch-import-c.opt: bitmatch_import_c.cmx
+       $(OCAMLFIND) ocamlopt $(OCAMLOPTFLAGS) $(OCAMLOPTLIBS) $< -o $@
+
+test:
+
+examples:
+
+# Clean.
+
+clean:
+       rm -f core *~ *.cmi *.cmo *.cmx *.cma *.cmxa *.a *.o
+
+distclean: clean
+
+# Install.
+
+install:
+
+# Standard rules.
+
+.mli.cmi:
+       $(OCAMLFIND) ocamlc $(OCAMLCFLAGS) $(OCAMLCPACKAGES) -c $<
+.ml.cmo:
+       $(OCAMLFIND) ocamlc $(OCAMLCFLAGS) $(OCAMLCPACKAGES) -c $<
+.ml.cmx:
+       $(OCAMLFIND) ocamlopt $(OCAMLOPTFLAGS) $(OCAMLOPTPACKAGES) -c $<
+
+depend: .depend
+
+.depend: $(wildcard *.ml) $(wildcard *.mli)
+       rm -f .depend
+       $(OCAMLFIND) ocamldep $(OCAMLCPACKAGES) $^ > $@
+
+ifeq ($(wildcard .depend),.depend)
+include .depend
+endif
+
+.PHONY: depend dist check-manifest dpkg doc \
+       print-examples print-tests examples test
+
+.SUFFIXES:      .cmo .cmi .cmx .ml .mli .mll
diff --git a/cil-tools/bitmatch-import-prefix.h b/cil-tools/bitmatch-import-prefix.h
new file mode 100644 (file)
index 0000000..d7f769a
--- /dev/null
@@ -0,0 +1,9 @@
+/* This file is automagically prefixed to all .ubd files
+ * and provides some macros that we need for CIL.
+ */
+
+#define BITMATCH_IMPORT(name) __bitmatch_import_##name
+#define BITMATCH_CONSTANT_STRING(name,val) \
+  char *__bitmatch_constant_##name = val
+#define BITMATCH_CONSTANT_INT32(name,val) \
+  int __bitmatch_constant_##name = val
diff --git a/cil-tools/bitmatch_import_c.ml b/cil-tools/bitmatch_import_c.ml
new file mode 100644 (file)
index 0000000..7587fc4
--- /dev/null
@@ -0,0 +1,150 @@
+(* Import a C header file.
+ * Copyright (C) 2008 Red Hat Inc., Richard W.M. Jones
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * $Id$
+ *)
+
+open Printf
+open ExtList
+open ExtString
+open Cil
+
+let () =
+  (* Parse command line arguments. *)
+  let debug = ref false in
+  let save_temps = ref false in
+  let version () =
+    printf "bitmatch-import-c %s" Bitmatch.version;
+    exit 1
+  in
+
+  let argspec = Arg.align [
+    "--debug", Arg.Set debug,
+      " Debug messages";
+    "-save-temps", Arg.Set save_temps,
+      " Save temporary files";
+    "--version", Arg.Unit version,
+      " Display version and exit";
+  ] in
+
+  let input_file = ref None in
+  let anon_fun str =
+    match !input_file with
+    | None -> input_file := Some str
+    | Some _ ->
+       eprintf "bitmatch-import-c: only give a single input file\n";
+       exit 1
+  in
+  let usage_msg = "\
+
+bitmatch-import-c: Import C structures and constants and
+  generate bitmatching functions from them.  Please see the
+  manual page bitmatch-import-c(1) for more information.
+
+OPTIONS" in
+
+  Arg.parse argspec anon_fun usage_msg;
+
+  let debug = !debug in
+  let save_temps = !save_temps in
+  let input_file =
+    match !input_file with
+    | Some f -> f
+    | None ->
+       eprintf "bitmatch-import-c: no input file specified\n";
+       exit 1 in
+
+  (* Grab the file and pass it to the preprocessor, and then read the
+   * C code into memory using CIL.
+   *)
+  msvcMode := false;
+  Cil.initCIL ();
+
+  (* XXX Unavoidable tmp exploit here.  Fix? *)
+  let tmp, delete_tmp =
+    if not save_temps then (
+      let tmp = Filename.temp_file (Filename.temp_dir_name) ".i" in
+      tmp, fun () -> try Unix.unlink tmp with Unix.Unix_error _ -> ()
+    ) else (
+      let tmp = Filename.chop_extension input_file ^ ".i" in
+      tmp, fun () -> (* -save-temps, so do nothing *) ()
+    ) in
+
+  let cmd =
+    sprintf "cpp -include bitmatch-import-prefix.h %s > %s"
+      (Filename.quote input_file) (Filename.quote tmp) in
+  if debug then prerr_endline cmd;
+  if Sys.command cmd <> 0 then (
+    eprintf "%s: command failed\n" cmd;
+    delete_tmp ();
+    exit 1
+  );
+
+  (* Why does Frontc.parse return a continuation ...? *)
+  let file = (Frontc.parse tmp) () in
+  delete_tmp ();
+
+  (* Find out which structures, #defines, etc. are to be imported.
+   * (cf. the macros in bitmatch-import-prefix.h)
+   *)
+  let constants =
+    List.filter_map (
+      function
+      | GVar ({vname = vname; vtype = vtype},
+             { init = Some (SingleInit vinit) },
+             loc)
+         when String.starts_with vname "__bitmatch_constant_" ->
+         let vname = String.sub vname 20 (String.length vname - 20) in
+
+         (* Do constant folding on the initializer and then calculate
+          * its compile-time value.
+          *)
+         let vinit =
+           match isInteger (constFold true vinit) with
+           | Some i -> i
+           | None ->
+               Errormsg.error
+                 "%a: non-constant initializer: %a" d_loc loc d_exp vinit;
+               -1L in
+
+         Some (vname, vinit, loc)
+      | _ -> None
+    ) file.globals in
+  let structs =
+    List.filter_map (
+      function
+      | GType ({tname = tname; ttype = ttype}, loc)
+         when String.starts_with tname "__bitmatch_import_" ->
+         let tname = String.sub tname 18 (String.length tname - 18) in
+         Some (tname, ttype, loc)
+      | _ -> None
+    ) file.globals in
+
+  if !Errormsg.hadErrors then exit 1;
+
+  (* If debugging, print out the imports. *)
+  if debug then (
+    List.iter (
+      fun (vname, vinit, loc) ->
+       Errormsg.log "%a: import %s as constant 0x%LX\n" d_loc loc vname vinit;
+    ) constants;
+    List.iter (
+      fun (tname, ttype, loc) ->
+       Errormsg.log "%a: import %s as %a\n" d_loc loc tname d_type ttype;
+    ) structs;
+  );
+
diff --git a/cil-tools/ext3.c b/cil-tools/ext3.c
new file mode 100644 (file)
index 0000000..ba35518
--- /dev/null
@@ -0,0 +1,24 @@
+/* This is an example import file, showing how to import the ext3
+ * superblock automatically from Linux header files.
+ *
+ * Use: bitmatch-import-c ext3.c
+ *
+ * Tip: Add the --debug flag to that command line to see what's going on.
+ */
+
+/* These are required by Linux in order to get the little/big-endian
+ * notations present in the Linux kernel header files.  Any other
+ * defines needed can go here.
+ */
+#define __CHECKER__      1
+#define __CHECK_ENDIAN__ 1
+
+/* Include files necessary to get the structure(s) and constant(s) we're
+ * interested in.
+ */
+#include <linux/magic.h>
+#include <linux/ext3_fs.h>
+
+/* This tells the importer program what structures and constants to import. */
+typedef struct ext3_super_block BITMATCH_IMPORT(ext3_super_block);
+BITMATCH_CONSTANT_INT32 (ext3_super_magic, EXT3_SUPER_MAGIC);
index ab88542..a964a9e 100644 (file)
@@ -29,7 +29,7 @@ test "x$U" != "x" && AC_MSG_ERROR(Compiler not ANSI compliant)
 
 AC_PROG_CC_C_O
 
-dnl Check for endianness.
+dnl Check for native endianness.
 AC_C_BIGENDIAN(
   [NATIVEENDIAN=BigEndian],
   [NATIVEENDIAN=LittleEndian],
@@ -51,7 +51,11 @@ if test "x$CAMLP4OF" = "xno"; then
     AC_MSG_ERROR([You must have camlp4 installed])
 fi
 
+dnl Check for CIL (optional)
+AC_CHECK_OCAML_PKG(cil)
+AC_SUBST(pkg_cil)
+
 dnl Produce output files.
 AC_CONFIG_HEADERS([config.h])
-AC_CONFIG_FILES([Makefile META bitmatch_config.ml])
+AC_CONFIG_FILES([Makefile META bitmatch_config.ml cil-tools/Makefile])
 AC_OUTPUT