From 20a4604b48a921322d8a70bce781ffa579e29445 Mon Sep 17 00:00:00 2001
From: Jon Turney <jon.turney@dronecode.org.uk>
Date: Wed, 5 Feb 2014 13:44:01 +0000
Subject: [PATCH 07/29] Build PECOFF/DWARF dump_syms for MinGW

- Substitute MapViewOfFile() for mmap()
- Link dump_syms_dwarf with ws2_32 as ntoh functions are used

v2:
Add needed include of windows.h

Signed-off-by: Jon Turney <jon.turney@dronecode.org.uk>
---
 Makefile.am                          |  6 ++----
 src/common/pecoff/dump_symbols-inl.h | 40 ++++++++++++++++++++++++++++++------
 2 files changed, 36 insertions(+), 10 deletions(-)

diff --git a/Makefile.am b/Makefile.am
index 009aa90d..61545454 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -381,13 +381,11 @@ endif
 endif LINUX_HOST
 
 if WINDOWS_HOST
-if !MINGW_HOST
 if !DISABLE_TOOLS
 bin_PROGRAMS += \
 	src/tools/windows/dump_syms_dwarf/dump_syms
 endif
 endif
-endif
 
 ## Tests
 if !DISABLE_PROCESSOR
@@ -789,7 +787,6 @@ src_tools_linux_md2core_minidump_2_core_unittest_LDADD = \
 endif LINUX_HOST
 
 if WINDOWS_HOST
-if !MINGW_HOST
 if !DISABLE_TOOLS
 src_tools_windows_dump_syms_dwarf_dump_syms_SOURCES = \
 	src/common/dwarf_cfi_to_module.cc \
@@ -805,7 +802,8 @@ src_tools_windows_dump_syms_dwarf_dump_syms_SOURCES = \
 	src/common/pecoff/pecoffutils.cc \
 	src/common/pecoff/pecoff_file_id.cc \
 	src/tools/windows/dump_syms_dwarf/dump_syms.cc
-endif
+src_tools_windows_dump_syms_dwarf_dump_syms_LDADD = \
+	$(SOCKET_LIBS)
 endif
 endif
 
diff --git a/src/common/pecoff/dump_symbols-inl.h b/src/common/pecoff/dump_symbols-inl.h
index 23955f6a..661097d2 100644
--- a/src/common/pecoff/dump_symbols-inl.h
+++ b/src/common/pecoff/dump_symbols-inl.h
@@ -39,7 +39,11 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
+#ifndef _WIN32
 #include <sys/mman.h>
+#else
+#include <windows.h>
+#endif
 #include <sys/stat.h>
 #include <unistd.h>
 #include <libgen.h>
@@ -111,13 +115,37 @@ class MmapWrapper {
   ~MmapWrapper() {
     if (is_set_ && base_ != NULL) {
       assert(size_ > 0);
+#ifndef _WIN32
       munmap(base_, size_);
+#else
+      UnmapViewOfFile(base_);
+      CloseHandle(hMap_);
+#endif
     }
   }
-  void set(void *mapped_address, size_t mapped_size) {
+  void *set(int obj_fd, size_t mapped_size) {
+#ifndef _WIN32
+    void *mapped_address = mmap(NULL, mapped_size,
+          PROT_READ | PROT_WRITE, MAP_PRIVATE, obj_fd, 0);
+    if (mapped_address == MAP_FAILED)
+      return NULL;
+#else
+    HANDLE h = (HANDLE)_get_osfhandle(obj_fd);
+    hMap_ = CreateFileMapping(h, NULL, PAGE_READONLY,0, 0, NULL);
+    // XXX: should also use SEC_IMAGE_NO_EXECUTE on Windows 6.2 or later
+    if (!hMap_) {
+      return NULL;
+    }
+    void *mapped_address = MapViewOfFile(hMap_, FILE_MAP_READ, 0, 0, 0);
+    if (!mapped_address) {
+      CloseHandle(hMap_);
+      return NULL;
+    }
+#endif
     is_set_ = true;
     base_ = mapped_address;
     size_ = mapped_size;
+    return mapped_address;
   }
   void release() {
     assert(is_set_);
@@ -130,6 +158,9 @@ class MmapWrapper {
   bool is_set_;
   void *base_;
   size_t size_;
+#ifdef _WIN32
+  HANDLE hMap_;
+#endif
 };
 
 #ifndef NO_STABS_SUPPORT
@@ -330,15 +361,12 @@ bool LoadFile(const string& obj_file, MmapWrapper* map_wrapper,
             obj_file.c_str(), strerror(errno));
     return false;
   }
-  void *obj_base = mmap(NULL, st.st_size,
-                        PROT_READ | PROT_WRITE, MAP_PRIVATE, obj_fd, 0);
-  if (obj_base == MAP_FAILED) {
+  *header = map_wrapper->set(obj_fd, st.st_size);
+  if (!(*header)) {
     fprintf(stderr, "Failed to mmap file '%s': %s\n",
             obj_file.c_str(), strerror(errno));
     return false;
   }
-  map_wrapper->set(obj_base, st.st_size);
-  *header = obj_base;
   return true;
 }
 
-- 
2.15.0

