Add FIXMEs about misaligned objcode-metas.
[bpt/guile.git] / libguile / objcodes.c
index 6a0a11b..a210553 100644 (file)
@@ -1,18 +1,19 @@
-/* Copyright (C) 2001 Free Software Foundation, Inc.
+/* Copyright (C) 2001, 2009 Free Software Foundation, Inc.
  * 
  * 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.1 of the License, or (at your option) any later version.
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; either version 3 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
+ * 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
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301 USA
  */
 
 #if HAVE_CONFIG_H
 #include <sys/types.h>
 #include <assert.h>
 
+#include <verify.h>
+
 #include "_scm.h"
 #include "vm-bootstrap.h"
 #include "programs.h"
 #include "objcodes.h"
 
-/* nb, the length of the header should be a multiple of 8 bytes */
-#define OBJCODE_COOKIE "GOOF-0.5"
+/* The endianness marker in objcode.  */
+#ifdef WORDS_BIGENDIAN
+# define OBJCODE_ENDIANNESS "BE"
+#else
+# define OBJCODE_ENDIANNESS "LE"
+#endif
+
+#define _OBJCODE_STRINGIFY(x)  # x
+#define OBJCODE_STRINGIFY(x)   _OBJCODE_STRINGIFY (x)
+
+/* The word size marker in objcode.  */
+#define OBJCODE_WORD_SIZE  OBJCODE_STRINGIFY (SIZEOF_VOID_P)
+
+/* The objcode magic header.  */
+#define OBJCODE_COOKIE                                         \
+  "GOOF-0.6-" OBJCODE_ENDIANNESS "-" OBJCODE_WORD_SIZE "---"
+
+/* The length of the header must be a multiple of 8 bytes.  */
+verify (((sizeof (OBJCODE_COOKIE) - 1) & 7) == 0);
+
 
 \f
 /*
@@ -62,17 +83,31 @@ make_objcode_by_mmap (int fd)
 
   addr = mmap (0, st.st_size, PROT_READ, MAP_SHARED, fd, 0);
   if (addr == MAP_FAILED)
-    SCM_SYSERROR;
+    {
+      (void) close (fd);
+      SCM_SYSERROR;
+    }
 
   if (memcmp (addr, OBJCODE_COOKIE, strlen (OBJCODE_COOKIE)))
-    SCM_SYSERROR;
+    {
+      SCM args = scm_list_1 (scm_from_locale_stringn
+                             (addr, strlen (OBJCODE_COOKIE)));
+      (void) close (fd);
+      (void) munmap (addr, st.st_size);
+      scm_misc_error (FUNC_NAME, "bad header on object file: ~s", args);
+    }
 
   data = (struct scm_objcode*)(addr + strlen (OBJCODE_COOKIE));
 
   if (data->len + data->metalen != (st.st_size - sizeof (*data) - strlen (OBJCODE_COOKIE)))
-    scm_misc_error (FUNC_NAME, "bad length header (~a, ~a)",
-                   scm_list_2 (scm_from_size_t (st.st_size),
-                               scm_from_uint32 (sizeof (*data) + data->len + data->metalen)));
+    {
+      (void) close (fd);
+      (void) munmap (addr, st.st_size);
+      scm_misc_error (FUNC_NAME, "bad length header (~a, ~a)",
+                     scm_list_2 (scm_from_size_t (st.st_size),
+                                 scm_from_uint32 (sizeof (*data) + data->len
+                                                  + data->metalen)));
+    }
 
   SCM_NEWSMOB3 (sret, scm_tc16_objcode, addr + strlen (OBJCODE_COOKIE),
                 SCM_PACK (SCM_BOOL_F), fd);
@@ -85,10 +120,10 @@ make_objcode_by_mmap (int fd)
 #undef FUNC_NAME
 
 SCM
-scm_c_make_objcode_slice (SCM parent, scm_t_uint8 *ptr)
+scm_c_make_objcode_slice (SCM parent, const scm_t_uint8 *ptr)
 #define FUNC_NAME "make-objcode-slice"
 {
-  struct scm_objcode *data, *parent_data;
+  const struct scm_objcode *data, *parent_data;
   SCM ret;
 
   SCM_VALIDATE_OBJCODE (1, parent);
@@ -103,6 +138,12 @@ scm_c_make_objcode_slice (SCM parent, scm_t_uint8 *ptr)
                                scm_from_uint32 (parent_data->len),
                                scm_from_uint32 (parent_data->metalen)));
 
+#if 0
+  /* FIXME: We currently generate bytecode where the objcode-meta isn't
+     suitable aligned, which is an issue on some arches (e.g., SPARC).  */
+  assert ((((uintptr_t) ptr) & (__alignof__ (struct scm_objcode) - 1UL)) == 0);
+#endif
+
   data = (struct scm_objcode*)ptr;
   if (data->base + data->len + data->metalen > parent_data->base + parent_data->len + parent_data->metalen)
     abort ();