$OpenBSD: patch-v8_src_base_platform_platform-openbsd_cc,v 1.3 2016/02/15 18:07:53 robert Exp $
--- v8/src/base/platform/platform-openbsd.cc.orig.port	Wed Jan 20 21:02:45 2016
+++ v8/src/base/platform/platform-openbsd.cc	Fri Jan 22 19:58:59 2016
@@ -2,26 +2,41 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-// Platform-specific code for OpenBSD and NetBSD goes here. For the
-// POSIX-compatible parts, the implementation is in platform-posix.cc.
+// Platform-specific code for Linux goes here. For the POSIX-compatible
+// parts, the implementation is in platform-posix.cc.
 
 #include <pthread.h>
 #include <semaphore.h>
 #include <signal.h>
+#include <stdio.h>
 #include <stdlib.h>
 #include <sys/resource.h>
-#include <sys/syscall.h>
 #include <sys/time.h>
-#include <sys/types.h>
 
+// Ubuntu Dapper requires memory pages to be marked as
+// executable. Otherwise, OS raises an exception when executing code
+// in that page.
 #include <errno.h>
 #include <fcntl.h>      // open
 #include <stdarg.h>
 #include <strings.h>    // index
 #include <sys/mman.h>   // mmap & munmap
 #include <sys/stat.h>   // open
+#include <sys/types.h>  // mmap & munmap
 #include <unistd.h>     // sysconf
 
+// GLibc on ARM defines mcontext_t has a typedef for 'struct sigcontext'.
+// Old versions of the C library <signal.h> didn't define the type.
+#if defined(__ANDROID__) && !defined(__BIONIC_HAVE_UCONTEXT_T) && \
+    (defined(__arm__) || defined(__aarch64__)) && \
+    !defined(__BIONIC_HAVE_STRUCT_SIGCONTEXT)
+#include <asm/sigcontext.h>  // NOLINT
+#endif
+
+#if defined(LEAK_SANITIZER)
+#include <sanitizer/lsan_interface.h>
+#endif
+
 #include <cmath>
 
 #undef MAP_TYPE
@@ -29,26 +44,87 @@
 #include "src/base/macros.h"
 #include "src/base/platform/platform.h"
 
+#if V8_OS_NACL
+#if !defined(MAP_NORESERVE)
+// PNaCL doesn't have this, so we always grab all of the memory, which is bad.
+#define MAP_NORESERVE 0
+#endif
+#else
+#include <sys/syscall.h>
+#endif
 
 namespace v8 {
 namespace base {
 
 
+#ifdef __arm__
+
+bool OS::ArmUsingHardFloat() {
+  // GCC versions 4.6 and above define __ARM_PCS or __ARM_PCS_VFP to specify
+  // the Floating Point ABI used (PCS stands for Procedure Call Standard).
+  // We use these as well as a couple of other defines to statically determine
+  // what FP ABI used.
+  // GCC versions 4.4 and below don't support hard-fp.
+  // GCC versions 4.5 may support hard-fp without defining __ARM_PCS or
+  // __ARM_PCS_VFP.
+
+#define GCC_VERSION (__GNUC__ * 10000                                          \
+                     + __GNUC_MINOR__ * 100                                    \
+                     + __GNUC_PATCHLEVEL__)
+#if GCC_VERSION >= 40600
+#if defined(__ARM_PCS_VFP)
+  return true;
+#else
+  return false;
+#endif
+
+#elif GCC_VERSION < 40500
+  return false;
+
+#else
+#if defined(__ARM_PCS_VFP)
+  return true;
+#elif defined(__ARM_PCS) || defined(__SOFTFP__) || defined(__SOFTFP) || \
+      !defined(__VFP_FP__)
+  return false;
+#else
+#error "Your version of GCC does not report the FP ABI compiled for."          \
+       "Please report it on this issue"                                        \
+       "http://code.google.com/p/v8/issues/detail?id=2140"
+
+#endif
+#endif
+#undef GCC_VERSION
+}
+
+#endif  // def __arm__
+
+
 const char* OS::LocalTimezone(double time, TimezoneCache* cache) {
+#if V8_OS_NACL
+  // Missing support for tm_zone field.
+  return "";
+#else
   if (std::isnan(time)) return "";
   time_t tv = static_cast<time_t>(std::floor(time/msPerSecond));
   struct tm* t = localtime(&tv);  // NOLINT(runtime/threadsafe_fn)
-  if (NULL == t) return "";
+  if (!t || !t->tm_zone) return "";
   return t->tm_zone;
+#endif
 }
 
 
 double OS::LocalTimeOffset(TimezoneCache* cache) {
+#if V8_OS_NACL
+  // Missing support for tm_zone field.
+  return 0;
+#else
   time_t tv = time(NULL);
   struct tm* t = localtime(&tv);  // NOLINT(runtime/threadsafe_fn)
   // tm_gmtoff includes any daylight savings offset, so subtract it.
   return static_cast<double>(t->tm_gmtoff * msPerSecond -
                              (t->tm_isdst > 0 ? 3600 * msPerSecond : 0));
+#endif
 }
 
 
@@ -58,7 +134,7 @@ void* OS::Allocate(const size_t requested,
   const size_t msize = RoundUp(requested, AllocateAlignment());
   int prot = PROT_READ | PROT_WRITE | (is_executable ? PROT_EXEC : 0);
   void* addr = OS::GetRandomMmapAddr();
-  void* mbase = mmap(addr, msize, prot, MAP_PRIVATE | MAP_ANON, -1, 0);
+  void* mbase = mmap(addr, msize, prot, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
   if (mbase == MAP_FAILED) return NULL;
   *allocated = msize;
   return mbase;
@@ -91,19 +167,20 @@ std::vector<OS::SharedLibraryAddress> OS::GetSharedLib
       // the beginning of the filename or the end of the line.
       do {
         c = getc(fp);
-      } while ((c != EOF) && (c != '\n') && (c != '/'));
+      } while ((c != EOF) && (c != '\n') && (c != '/') && (c != '['));
       if (c == EOF) break;  // EOF: Was unexpected, just exit.
 
       // Process the filename if found.
-      if (c == '/') {
-        ungetc(c, fp);  // Push the '/' back into the stream to be read below.
+      if ((c == '/') || (c == '[')) {
+        // Push the '/' or '[' back into the stream to be read below.
+        ungetc(c, fp);
 
         // Read to the end of the line. Exit if the read fails.
         if (fgets(lib_name, kLibNameLen, fp) == NULL) break;
 
         // Drop the newline character read by fgets. We do not need to check
         // for a zero-length string because we know that we at least read the
-        // '/' character.
+        // '/' or '[' character.
         lib_name[strlen(lib_name) - 1] = '\0';
       } else {
         // No library name found, just record the raw address range.
@@ -135,21 +212,27 @@ void OS::SignalCodeMovingGC() {
   // it. This injects a GC marker into the stream of events generated
   // by the kernel and allows us to synchronize V8 code log and the
   // kernel log.
-  int size = sysconf(_SC_PAGESIZE);
+  long size = sysconf(_SC_PAGESIZE);  // NOLINT(runtime/int)
   FILE* f = fopen(OS::GetGCFakeMMapFile(), "w+");
   if (f == NULL) {
     OS::PrintError("Failed to open %s\n", OS::GetGCFakeMMapFile());
     OS::Abort();
   }
-  void* addr = mmap(NULL, size, PROT_READ | PROT_EXEC, MAP_PRIVATE,
-                    fileno(f), 0);
-  DCHECK(addr != MAP_FAILED);
+  void* addr = mmap(OS::GetRandomMmapAddr(), size,
+#if V8_OS_NACL
+                    // The Native Client port of V8 uses an interpreter,
+                    // so code pages don't need PROT_EXEC.
+                    PROT_READ,
+#else
+                    PROT_READ | PROT_EXEC,
+#endif
+                    MAP_PRIVATE, fileno(f), 0);
+  DCHECK_NE(MAP_FAILED, addr);
   OS::Free(addr, size);
   fclose(f);
 }
 
 
-
 // Constants used for mmap.
 static const int kMmapFd = -1;
 static const int kMmapFdOffset = 0;
@@ -170,7 +253,7 @@ VirtualMemory::VirtualMemory(size_t size, size_t align
   void* reservation = mmap(OS::GetRandomMmapAddr(),
                            request_size,
                            PROT_NONE,
-                           MAP_PRIVATE | MAP_ANON | MAP_NORESERVE,
+                           MAP_PRIVATE | MAP_ANONYMOUS | MAP_NORESERVE,
                            kMmapFd,
                            kMmapFdOffset);
   if (reservation == MAP_FAILED) return;
@@ -199,6 +282,9 @@ VirtualMemory::VirtualMemory(size_t size, size_t align
 
   address_ = static_cast<void*>(aligned_base);
   size_ = aligned_size;
+#if defined(LEAK_SANITIZER)
+  __lsan_register_root_region(address_, size_);
+#endif
 }
 
 
@@ -223,16 +309,19 @@ void VirtualMemory::Reset() {
 
 
 bool VirtualMemory::Commit(void* address, size_t size, bool is_executable) {
+  CHECK(InVM(address, size));
   return CommitRegion(address, size, is_executable);
 }
 
 
 bool VirtualMemory::Uncommit(void* address, size_t size) {
+  CHECK(InVM(address, size));
   return UncommitRegion(address, size);
 }
 
 
 bool VirtualMemory::Guard(void* address) {
+  CHECK(InVM(address, OS::CommitPageSize()));
   OS::Guard(address, OS::CommitPageSize());
   return true;
 }
@@ -242,26 +331,36 @@ void* VirtualMemory::ReserveRegion(size_t size) {
   void* result = mmap(OS::GetRandomMmapAddr(),
                       size,
                       PROT_NONE,
-                      MAP_PRIVATE | MAP_ANON | MAP_NORESERVE,
+                      MAP_PRIVATE | MAP_ANONYMOUS | MAP_NORESERVE,
                       kMmapFd,
                       kMmapFdOffset);
 
   if (result == MAP_FAILED) return NULL;
 
+#if defined(LEAK_SANITIZER)
+  __lsan_register_root_region(result, size);
+#endif
   return result;
 }
 
 
 bool VirtualMemory::CommitRegion(void* base, size_t size, bool is_executable) {
+#if V8_OS_NACL
+  // The Native Client port of V8 uses an interpreter,
+  // so code pages don't need PROT_EXEC.
+  int prot = PROT_READ | PROT_WRITE;
+#else
   int prot = PROT_READ | PROT_WRITE | (is_executable ? PROT_EXEC : 0);
+#endif
   if (MAP_FAILED == mmap(base,
                          size,
                          prot,
-                         MAP_PRIVATE | MAP_ANON | MAP_FIXED,
+                         MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED,
                          kMmapFd,
                          kMmapFdOffset)) {
     return false;
   }
+
   return true;
 }
 
@@ -270,20 +369,22 @@ bool VirtualMemory::UncommitRegion(void* base, size_t 
   return mmap(base,
               size,
               PROT_NONE,
-              MAP_PRIVATE | MAP_ANON | MAP_NORESERVE | MAP_FIXED,
+              MAP_PRIVATE | MAP_ANONYMOUS | MAP_NORESERVE | MAP_FIXED,
               kMmapFd,
               kMmapFdOffset) != MAP_FAILED;
 }
 
 
 bool VirtualMemory::ReleaseRegion(void* base, size_t size) {
+#if defined(LEAK_SANITIZER)
+  __lsan_unregister_root_region(base, size);
+#endif
   return munmap(base, size) == 0;
 }
 
 
 bool VirtualMemory::HasLazyCommits() {
-  // TODO(alph): implement for the platform.
-  return false;
+  return true;
 }
 
 }  // namespace base
