Merge "Misc fixes for ld.mcld to build most run-tests.sh"
diff --git a/build/tools/build-host-prebuilts.sh b/build/tools/build-host-prebuilts.sh
index 2d05a3e..e546ae0 100755
--- a/build/tools/build-host-prebuilts.sh
+++ b/build/tools/build-host-prebuilts.sh
@@ -242,7 +242,7 @@
     if [ "$TRY64" = "yes" ]; then
         case $SYSTEM in
             darwin-x86|linux-x86)
-                SYSNAME=${SYSTEM%%x86}x86-64
+                SYSNAME=${SYSTEM%%x86}x86_64
                 ;;
             windows)
                 SYSNAME=windows-x86_64
@@ -288,7 +288,7 @@
         for TOOLCHAIN_NAME in $TOOLCHAIN_NAMES; do
             echo "Building $SYSNAME toolchain for $ARCH architecture: $TOOLCHAIN_NAME"
             run $BUILDTOOLS/build-gcc.sh "$SRC_DIR" "$NDK_DIR" $TOOLCHAIN_NAME $TOOLCHAIN_FLAGS
-            fail_panic "Could not build $TOOLCHAIN_NAME-$SYSTEM!"
+            fail_panic "Could not build $TOOLCHAIN_NAME-$SYSNAME!"
         done
     done
 
@@ -300,9 +300,13 @@
     for LLVM_VERSION in $LLVM_VERSION_LIST; do
         echo "Building $SYSNAME clang/llvm-$LLVM_VERSION"
         run $BUILDTOOLS/build-llvm.sh "$SRC_DIR" "$NDK_DIR" "llvm-$LLVM_VERSION" $TOOLCHAIN_FLAGS $POLLY_FLAGS $CHECK_FLAG
-        fail_panic "Could not build llvm for $SYSTEM"
+        fail_panic "Could not build llvm for $SYSNAME"
     done
 
+    # Deploy ld.mcld
+    $PROGDIR/deploy-host-mcld.sh --package-dir=$PACKAGE_DIR --systems=$SYSNAME
+    fail_panic "Could not deploy ld.mcld for $SYSNAME"
+
     # We're done for this system
 done
 
diff --git a/build/tools/build-llvm.sh b/build/tools/build-llvm.sh
index 328205f..0b98c91 100755
--- a/build/tools/build-llvm.sh
+++ b/build/tools/build-llvm.sh
@@ -45,6 +45,9 @@
 PACKAGE_DIR=
 register_var_option "--package-dir=<path>" PACKAGE_DIR "Create archive tarball in specific directory"
 
+WINE=wine
+register_var_option "--wine=<path>" WINE "WINE needed to run llvm-config.exe for building mclinker with --mingw"
+
 POLLY=no
 do_polly_option () { POLLY=yes; }
 register_option "--with-polly" do_polly_option "Enable Polyhedral optimizations for LLVM"
@@ -267,9 +270,21 @@
 cd $LLVM_BUILD_OUT && run make install $MAKE_FLAGS
 fail_panic "Couldn't install llvm toolchain to $TOOLCHAIN_BUILD_PREFIX"
 
-# Build mclinker only against default the LLVM version, once
-# mclinker isn't mingw-ready yet.  ToDo
-if [ "$TOOLCHAIN" = "llvm-$DEFAULT_LLVM_VERSION" -a "$MINGW" != "yes" ] ; then
+# create llvm-config wrapper if needed.
+# llvm-config is invoked by other llvm projects (eg. mclinker/configure)
+# to figure out flags and libs dependencies.  Unfortunately in canadian-build
+# llvm-config[.exe] may not run directly.  Create a wrapper.
+LLVM_CONFIG=llvm-config
+if [ "$MINGW" = "yes" ] ; then
+    LLVM_CONFIG=llvm-config.sh
+    cat > $TOOLCHAIN_BUILD_PREFIX/bin/$LLVM_CONFIG <<EOF
+$WINE \`dirname \$0\`/llvm-config.exe "\$@"
+EOF
+    chmod 0755 $TOOLCHAIN_BUILD_PREFIX/bin/$LLVM_CONFIG
+fi
+
+# build mclinker only against default the LLVM version, once
+if [ "$TOOLCHAIN" = "llvm-$DEFAULT_LLVM_VERSION" -a "$DARWIN" != "yes" ] ; then
     dump "Copy     : mclinker source"
     MCLINKER_SRC_DIR=$BUILD_OUT/mclinker
     mkdir -p $MCLINKER_SRC_DIR
@@ -288,10 +303,9 @@
 
     run $MCLINKER_SRC_DIR/configure \
         --prefix=$TOOLCHAIN_BUILD_PREFIX \
-        --with-llvm-config=$TOOLCHAIN_BUILD_PREFIX/bin/llvm-config \
+        --with-llvm-config=$TOOLCHAIN_BUILD_PREFIX/bin/$LLVM_CONFIG \
         --host=$ABI_CONFIGURE_HOST \
-        --build=$ABI_CONFIGURE_BUILD \
-        --with-bug-report-url=$DEFAULT_ISSUE_TRACKER_URL
+        --build=$ABI_CONFIGURE_BUILD
     fail_panic "Couldn't configure mclinker"
 
     dump "Building : mclinker"
diff --git a/build/tools/deploy-host-mcld.sh b/build/tools/deploy-host-mcld.sh
new file mode 100755
index 0000000..2ba8356
--- /dev/null
+++ b/build/tools/deploy-host-mcld.sh
@@ -0,0 +1,99 @@
+#!/bin/sh
+#
+# Copyright (C) 2013 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# Rebuild the host GCC toolchain binaries from sources.
+#
+# NOTE: this script does not rebuild gdb, see build-host-gdb.sh for this.
+#
+
+# include common function and variable definitions
+. `dirname $0`/prebuilt-common.sh
+
+PROGRAM_PARAMETERS=""
+PROGRAM_DESCRIPTION="\
+This program is used to deploy mclinker (ld.mcld) to GCC directories.
+Although ld.mcld depends on lots of LLVM modules and is built in
+build-llvm.sh to reduce long LLVM compilation time, it can be used as
+a drop-in replacement for ld.bfd and ld.gold in GCC.
+
+Running after completion of both build-llvm.sh and build-[host-]gcc.sh,
+this script copy toolchains/llvm-$DEFAULT_LLVM_VERSION/prebuilt/$SYSTEM/bin/ld.mcld[.exe]
+to be sibling of ld in all GCC directories with same HOST_OS and bitness,
+ie. {linux, darwin, windows} x {64, 32}
+
+If --systems isn't specified, this script discovers all ld.mcld[.exe] in
+toolchains/llvm-$DEFAULT_LLVM_VERSION
+
+Note that one copy of ld.mcld serves all GCC {4.7, 4.6, 4.4.3} x {arm, x86, mips}.
+GCC passes -m flag for ld.mcld to figure out the right target.
+"
+
+PACKAGE_DIR=
+register_var_option "--package-dir=<path>" PACKAGE_DIR "Create archive tarball in specific directory"
+
+SYSTEMS=
+register_var_option "--systems=<list>" SYSTEMS "List of host systems to deply ld.mcld for"
+
+extract_parameters "$@"
+
+if [ "$PACKAGE_DIR" ]; then
+    mkdir -p "$PACKAGE_DIR"
+    fail_panic "Could not create package directory: $PACKAGE_DIR"
+fi
+
+if [ -z "$SYSTEMS" ]; then
+    # find all ld.mcld
+    ALL_MCLDS=`find toolchains/llvm-$DEFAULT_LLVM_VERSION -name "ld.mcld*"`
+
+    for MCLD in $ALL_MCLDS; do
+        # compute SYSTEM of this ld.mcld
+        SYSTEM=${MCLD%%/bin/*}
+        SYSTEM=${SYSTEM##*prebuilt/}
+        SYSTEMS=$SYSTEMS" $SYSTEM"
+    done
+fi
+
+for SYSTEM in $SYSTEMS; do
+    HOST_EXE=
+    if [ "$SYSTEM" != "${SYSTEM%%windows*}" ] ; then
+        HOST_EXE=.exe
+    fi
+
+    MCLD=toolchains/llvm-$DEFAULT_LLVM_VERSION/prebuilt/$SYSTEM/bin/ld.mcld$HOST_EXE
+    test -f "$MCLD" || fail_panic "Could not find $MCLD"
+
+    # find all GNU ld with the same SYSTEM
+    ALL_LDS=`find . \( -name "*-ld" -o -name "ld" -o -name "*-ld.exe" -o -name "ld.exe" \) | grep $SYSTEM/`
+
+    ALL_LD_MCLDS=
+    for LD in $ALL_LDS; do
+        LD_NOEXE=${LD%%.exe}
+        LD_MCLD=${LD_NOEXE}.mcld$HOST_EXE
+        run rm -f "$LD_MCLD"
+        run cp -a "$MCLD" "$LD_MCLD"
+        ALL_LD_MCLDS=$ALL_LD_MCLDS" $LD_MCLD"
+    done
+
+    # package
+    if [ "$PACKAGE_DIR" ]; then
+        ARCHIVE="ld.mcld-$SYSTEM.tar.bz2"
+        #echo $ARCHIVE
+        echo  "Packaging $ARCHIVE"
+        pack_archive "$PACKAGE_DIR/$ARCHIVE" "$ANDROID_NDK_ROOT" $ALL_LD_MCLDS
+    fi
+done
+
+dump "Done."
diff --git a/build/tools/package-release.sh b/build/tools/package-release.sh
index 332d70e..0479ad8 100755
--- a/build/tools/package-release.sh
+++ b/build/tools/package-release.sh
@@ -482,6 +482,9 @@
             unpack_prebuilt llvm-$LLVM_VERSION-$SYSTEM "$DSTDIR" "$DSTDIR64"
         done
 
+        # Unpack ld.mcld
+        unpack_prebuilt ld.mcld-$SYSTEM "$DSTDIR" "$DSTDIR64"
+
         # Unpack prebuilt ndk-stack and other host tools
         unpack_prebuilt ndk-stack-$SYSTEM "$DSTDIR" "$DSTDIR64" "yes"
         unpack_prebuilt ndk-make-$SYSTEM "$DSTDIR" "$DSTDIR64"
diff --git a/build/tools/toolchain-patches/mclinker/0003-Fix-mingw-build.patch b/build/tools/toolchain-patches/mclinker/0003-Fix-mingw-build.patch
new file mode 100644
index 0000000..03e71c6
--- /dev/null
+++ b/build/tools/toolchain-patches/mclinker/0003-Fix-mingw-build.patch
@@ -0,0 +1,615 @@
+From 9a50212671d7df41e624421c16ff67c5ebff1062 Mon Sep 17 00:00:00 2001
+From: Andrew Hsieh <andrewhsieh@google.com>
+Date: Wed, 27 Feb 2013 16:34:52 +0800
+Subject: [PATCH] Fix mingw build
+
+Change-Id: I11f3ac34154aa5cd1f2d4f9630f877e5bf0e5f6a
+---
+ debug/Makefile.am                  |    1 +
+ include/mcld/LD/Diagnostic.h       |    6 +
+ include/mcld/LD/DiagnosticEngine.h |    1 +
+ include/mcld/LD/MsgHandler.h       |    7 ++
+ include/mcld/Support/FileHandle.h  |    2 +
+ include/mcld/Support/mingw/mman.h  |   55 +++++++++++
+ lib/LD/Diagnostic.cpp              |    5 +
+ lib/Support/FileHandle.cpp         |    4 +
+ lib/Support/FileSystem.cpp         |    3 +
+ lib/Support/Path.cpp               |   10 ++-
+ lib/Support/Space.cpp              |   14 +++
+ lib/Support/Unix/FileSystem.inc    |   20 ++++
+ lib/Support/Unix/PathV3.inc        |   10 ++
+ lib/Support/mingw/mman.inc         |  180 ++++++++++++++++++++++++++++++++++++
+ lib/Support/raw_ostream.cpp        |    2 +-
+ lib/Target/GNULDBackend.cpp        |    4 +
+ lib/Target/Mips/MipsLDBackend.cpp  |    4 +
+ m4/llvm.m4                         |    2 +-
+ optimized/Makefile.am              |    1 +
+ tools/llvm-mcld/llvm-mcld.cpp      |    2 +-
+ 20 files changed, 329 insertions(+), 4 deletions(-)
+ create mode 100644 include/mcld/Support/mingw/mman.h
+ create mode 100644 lib/Support/mingw/mman.inc
+
+diff --git a/debug/Makefile.am b/debug/Makefile.am
+index e41d1aa..cf8442a 100644
+--- a/debug/Makefile.am
++++ b/debug/Makefile.am
+@@ -174,6 +174,7 @@ SOURCE = ${LIBDIR}/ADT/StringEntry.cpp \
+ 	${LIBDIR}/Support/Windows/FileSystem.inc \
+ 	${LIBDIR}/Support/Windows/PathV3.inc \
+ 	${LIBDIR}/Support/Windows/System.inc \
++	${LIBDIR}/Support/mingw/mman.inc \
+ 	${LIBDIR}/CodeGen/MCLDTargetMachine.cpp \
+ 	${LIBDIR}/CodeGen/MCLinker.cpp \
+ 	${LIBDIR}/Object/ObjectLinker.cpp \
+diff --git a/include/mcld/LD/Diagnostic.h b/include/mcld/LD/Diagnostic.h
+index 5e7d436..2b125db 100644
+--- a/include/mcld/LD/Diagnostic.h
++++ b/include/mcld/LD/Diagnostic.h
+@@ -64,6 +64,12 @@ public:
+     return (unsigned int)m_Engine.state().ArgumentVals[pIdx];
+   }
+ 
++  unsigned long long getArgULongLong(unsigned int pIdx) const {
++    assert(getArgKind(pIdx) == DiagnosticEngine::ak_ulonglong &&
++           "Invalid argument accessor!");
++    return (unsigned long long)m_Engine.state().ArgumentVals[pIdx];
++  }
++
+   bool getArgBool(unsigned int pIdx) const {
+     assert(getArgKind(pIdx) == DiagnosticEngine::ak_bool &&
+            "Invalid argument accessor!");
+diff --git a/include/mcld/LD/DiagnosticEngine.h b/include/mcld/LD/DiagnosticEngine.h
+index 9d24c7a..f3d3b3c 100644
+--- a/include/mcld/LD/DiagnosticEngine.h
++++ b/include/mcld/LD/DiagnosticEngine.h
+@@ -53,6 +53,7 @@ public:
+     ak_c_string,    // const char *
+     ak_sint,        // int
+     ak_uint,        // unsigned int
++    ak_ulonglong,   // unsigned long long, (eg. size_t in 64-bit)
+     ak_bool         // bool
+   };
+ 
+diff --git a/include/mcld/LD/MsgHandler.h b/include/mcld/LD/MsgHandler.h
+index c89f744..9b1ed80 100644
+--- a/include/mcld/LD/MsgHandler.h
++++ b/include/mcld/LD/MsgHandler.h
+@@ -103,6 +103,13 @@ operator<<(const MsgHandler& pHandler, unsigned long pValue)
+ }
+ 
+ inline const MsgHandler &
++operator<<(const MsgHandler& pHandler, unsigned long long pValue)
++{
++  pHandler.addTaggedVal(pValue, DiagnosticEngine::ak_ulonglong);
++  return pHandler;
++}
++
++inline const MsgHandler &
+ operator<<(const MsgHandler& pHandler, bool pValue)
+ {
+   pHandler.addTaggedVal(pValue, DiagnosticEngine::ak_bool);
+diff --git a/include/mcld/Support/FileHandle.h b/include/mcld/Support/FileHandle.h
+index ce43e0f..4130c7a 100644
+--- a/include/mcld/Support/FileHandle.h
++++ b/include/mcld/Support/FileHandle.h
+@@ -58,12 +58,14 @@ public:
+     ReadOwner   = S_IRUSR,
+     WriteOwner  = S_IWUSR,
+     ExeOwner    = S_IXUSR,
++#if !defined(_WIN32)
+     ReadGroup   = S_IRGRP,
+     WriteGroup  = S_IWGRP,
+     ExeGroup    = S_IXGRP,
+     ReadOther   = S_IROTH,
+     WriteOther  = S_IWOTH,
+     ExeOther    = S_IXOTH,
++#endif
+     System      = 0xFFFFFFFF
+   };
+ 
+diff --git a/include/mcld/Support/mingw/mman.h b/include/mcld/Support/mingw/mman.h
+new file mode 100644
+index 0000000..96f68b2
+--- /dev/null
++++ b/include/mcld/Support/mingw/mman.h
+@@ -0,0 +1,55 @@
++/*
++ * sys/mman.h
++ * mman-win32
++ */
++
++#ifndef _SYS_MMAN_H_
++#define _SYS_MMAN_H_
++
++#ifndef _WIN32_WINNT		// Allow use of features specific to Windows XP or later.                   

++#define _WIN32_WINNT 0x0501	// Change this to the appropriate value to target other versions of Windows.

++#endif						

++
++/* All the headers include this file. */
++#ifndef _MSC_VER
++#include <_mingw.h>
++#endif
++
++#include <sys/types.h>
++
++#ifdef __cplusplus
++extern "C" {
++#endif
++
++#define PROT_NONE       0
++#define PROT_READ       1
++#define PROT_WRITE      2
++#define PROT_EXEC       4
++
++#define MAP_FILE        0
++#define MAP_SHARED      1
++#define MAP_PRIVATE     2
++#define MAP_TYPE        0xf
++#define MAP_FIXED       0x10
++#define MAP_ANONYMOUS   0x20
++#define MAP_ANON        MAP_ANONYMOUS
++
++#define MAP_FAILED      ((void *)-1)
++
++/* Flags for msync. */
++#define MS_ASYNC        1
++#define MS_SYNC         2
++#define MS_INVALIDATE   4
++
++void*   mmap(void *addr, size_t len, int prot, int flags, int fildes, off_t off);
++int     munmap(void *addr, size_t len);
++int     mprotect(void *addr, size_t len, int prot);
++int     msync(void *addr, size_t len, int flags);
++int     mlock(const void *addr, size_t len);
++int     munlock(const void *addr, size_t len);
++
++#ifdef __cplusplus
++};
++#endif
++
++#endif /*  _SYS_MMAN_H_ */
+diff --git a/lib/LD/Diagnostic.cpp b/lib/LD/Diagnostic.cpp
+index 786a68b..b596a94 100644
+--- a/lib/LD/Diagnostic.cpp
++++ b/lib/LD/Diagnostic.cpp
+@@ -157,6 +157,11 @@ void Diagnostic::format(const char* pBegin, const char* pEnd,
+         llvm::raw_string_ostream(pOutStr) << val;
+         break;
+       }
++      case DiagnosticEngine::ak_ulonglong: {
++        unsigned long long val = getArgULongLong(arg_no);
++        llvm::raw_string_ostream(pOutStr) << val;
++        break;
++      }
+       case DiagnosticEngine::ak_bool: {
+         bool val = getArgBool(arg_no);
+         if (val)
+diff --git a/lib/Support/FileHandle.cpp b/lib/Support/FileHandle.cpp
+index 437e741..52c68a3 100644
+--- a/lib/Support/FileHandle.cpp
++++ b/lib/Support/FileHandle.cpp
+@@ -18,7 +18,11 @@
+ #endif
+ 
+ #include <sys/stat.h>
++#if defined(HAVE_SYS_MMAN_H)
+ #include <sys/mman.h>
++#elif defined(_WIN32)
++#include <mcld/Support/mingw/mman.h>
++#endif
+ 
+ #if defined(_MSC_VER)
+ #include <io.h>
+diff --git a/lib/Support/FileSystem.cpp b/lib/Support/FileSystem.cpp
+index fb2633d..7084a9a 100644
+--- a/lib/Support/FileSystem.cpp
++++ b/lib/Support/FileSystem.cpp
+@@ -27,3 +27,6 @@ using namespace mcld::sys::fs;
+ #include "Windows/FileSystem.inc"
+ #include "Windows/PathV3.inc" 
+ #endif 
++#if defined(_WIN32)
++#include "mingw/mman.inc"
++#endif
+\ No newline at end of file
+diff --git a/lib/Support/Path.cpp b/lib/Support/Path.cpp
+index d359162..2f439de 100644
+--- a/lib/Support/Path.cpp
++++ b/lib/Support/Path.cpp
+@@ -78,12 +78,20 @@ Path& Path::append(const Path& pPath)
+     unsigned int new_size = old_size + pPath.native().size();
+ 
+     m_PathName.resize(new_size);
+-    strcpy(const_cast<char*>(m_PathName.data()+old_size), pPath.native().data());
++#if defined(MCLD_ON_WIN32)
++    wcscpy(const_cast<ValueType*>(m_PathName.data()+old_size), pPath.native().data());
++#else
++    strcpy(const_cast<ValueType*>(m_PathName.data()+old_size), pPath.native().data());
++#endif
+   }
+   //first path is a,second path is b
+   else if(this->string()[this->native().size()-1] != separator &&
+           pPath.string()[0] != separator) {
++#if defined(MCLD_ON_WIN32)
++    m_PathName.append(L"\\");
++#else
+     m_PathName.append("/");
++#endif
+     m_PathName.append(pPath.native());
+   }
+   // a/,b or a,/b just append
+diff --git a/lib/Support/Space.cpp b/lib/Support/Space.cpp
+index 6ec2c53..db5ad03 100644
+--- a/lib/Support/Space.cpp
++++ b/lib/Support/Space.cpp
+@@ -16,6 +16,20 @@ using namespace mcld;
+ 
+ //===----------------------------------------------------------------------===//
+ // constant data
++#if defined(_WIN32)
++#include <windows.h>
++int getpagesize (void) 
++{
++  static int _pagesize = 0;
++  if (! _pagesize) 
++  {
++    SYSTEM_INFO sysinfo;
++    GetSystemInfo (&sysinfo);
++    _pagesize = sysinfo.dwPageSize;
++  }
++  return _pagesize;
++}
++#endif
+ static const off_t PageSize = getpagesize();
+ 
+ //===----------------------------------------------------------------------===//
+diff --git a/lib/Support/Unix/FileSystem.inc b/lib/Support/Unix/FileSystem.inc
+index ce6d0df..96d1e10 100644
+--- a/lib/Support/Unix/FileSystem.inc
++++ b/lib/Support/Unix/FileSystem.inc
+@@ -36,12 +36,32 @@ int open(const Path& pPath, int pOFlag, int pPerm)
+ 
+ ssize_t pread(int pFD, void* pBuf, size_t pCount, size_t pOffset)
+ {
++#if !defined(_WIN32)
+   return ::pread(pFD, pBuf, pCount, pOffset);
++#else
++  off_t curr_pos = lseek (pFD, 0, SEEK_CUR);
++  if (lseek (pFD, pOffset, SEEK_SET) != pOffset)
++    return -1;
++  ssize_t retval = read (pFD, pBuf, pCount);
++  if (lseek (pFD, curr_pos, SEEK_SET) != curr_pos)
++    return -1;
++  return retval;    
++#endif
+ }
+ 
+ ssize_t pwrite(int pFD, const void* pBuf, size_t pCount, size_t pOffset)
+ {
++#if !defined(_WIN32)
+   return ::pwrite(pFD, pBuf, pCount, pOffset);
++#else
++  off_t curr_pos = lseek (pFD, 0, SEEK_CUR);
++  if (lseek (pFD, pOffset, SEEK_SET) != pOffset)
++    return -1;
++  ssize_t retval = write (pFD, pBuf, pCount);
++  if (lseek (pFD, curr_pos, SEEK_SET) != curr_pos)
++    return -1;
++  return retval;    
++#endif
+ }
+ 
+ int ftruncate(int pFD, size_t pLength)
+diff --git a/lib/Support/Unix/PathV3.inc b/lib/Support/Unix/PathV3.inc
+index 1506e94..65ba267 100644
+--- a/lib/Support/Unix/PathV3.inc
++++ b/lib/Support/Unix/PathV3.inc
+@@ -20,6 +20,10 @@
+ #include <stack>
+ #include <unistd.h>
+ 
++#if defined(_WIN32)
++#include <limits.h>
++#endif
++
+ namespace mcld{
+ namespace sys{
+ namespace fs{
+@@ -154,14 +158,19 @@ void status(const Path& p, FileStatus& pFileStatus)
+     pFileStatus.setType(CharacterFile);
+   else if(S_ISFIFO(path_stat.st_mode))
+     pFileStatus.setType(FifoFile);
++#if !defined(_WIN32)
+   else if(S_ISSOCK(path_stat.st_mode))
+     pFileStatus.setType(SocketFile);
++#endif    
+   else
+     pFileStatus.setType(TypeUnknown);
+ }
+ 
+ void symlink_status(const Path& p, FileStatus& pFileStatus)
+ {
++#if defined(_WIN32)
++  pFileStatus.setType(FileNotFound);
++#else
+   struct stat path_stat;
+   if(lstat(p.c_str(), &path_stat)!= 0)
+   {
+@@ -188,6 +197,7 @@ void symlink_status(const Path& p, FileStatus& pFileStatus)
+     pFileStatus.setType(SocketFile);
+   else
+     pFileStatus.setType(TypeUnknown);
++#endif
+ }
+ 
+ /// read_dir - return true if we read one entry
+diff --git a/lib/Support/mingw/mman.inc b/lib/Support/mingw/mman.inc
+new file mode 100644
+index 0000000..be4be5b
+--- /dev/null
++++ b/lib/Support/mingw/mman.inc
+@@ -0,0 +1,180 @@
++

++#include <windows.h>

++#include <errno.h>

++#include <io.h>

++

++#include "mcld/Support/mingw/mman.h"

++

++#ifndef FILE_MAP_EXECUTE

++#define FILE_MAP_EXECUTE    0x0020

++#endif /* FILE_MAP_EXECUTE */

++

++static int __map_mman_error(const DWORD err, const int deferr)

++{

++    if (err == 0)

++        return 0;

++    //TODO: implement

++    return err;

++}

++

++static DWORD __map_mmap_prot_page(const int prot)

++{

++    DWORD protect = 0;

++    

++    if (prot == PROT_NONE)

++        return protect;

++        

++    if ((prot & PROT_EXEC) != 0)

++    {

++        protect = ((prot & PROT_WRITE) != 0) ? 

++                    PAGE_EXECUTE_READWRITE : PAGE_EXECUTE_READ;

++    }

++    else

++    {

++        protect = ((prot & PROT_WRITE) != 0) ?

++                    PAGE_READWRITE : PAGE_READONLY;

++    }

++    

++    return protect;

++}

++

++static DWORD __map_mmap_prot_file(const int prot)

++{

++    DWORD desiredAccess = 0;

++    

++    if (prot == PROT_NONE)

++        return desiredAccess;

++        

++    if ((prot & PROT_READ) != 0)

++        desiredAccess |= FILE_MAP_READ;

++    if ((prot & PROT_WRITE) != 0)

++        desiredAccess |= FILE_MAP_WRITE;

++    if ((prot & PROT_EXEC) != 0)

++        desiredAccess |= FILE_MAP_EXECUTE;

++    

++    return desiredAccess;

++}

++

++void* mmap(void *addr, size_t len, int prot, int flags, int fildes, off_t off)

++{

++    HANDLE fm, h;

++    

++    void * map = MAP_FAILED;

++    

++#ifdef _MSC_VER

++#pragma warning(push)

++#pragma warning(disable: 4293)

++#endif

++

++    const DWORD dwFileOffsetLow = (sizeof(off_t) <= sizeof(DWORD)) ? 

++                    (DWORD)off : (DWORD)(off & 0xFFFFFFFFL);

++    const DWORD dwFileOffsetHigh = (sizeof(off_t) <= sizeof(DWORD)) ?

++                    (DWORD)0 : (DWORD)((off >> 32) & 0xFFFFFFFFL);

++    const DWORD protect = __map_mmap_prot_page(prot);

++    const DWORD desiredAccess = __map_mmap_prot_file(prot);

++

++    const off_t maxSize = off + (off_t)len;

++

++    const DWORD dwMaxSizeLow = (sizeof(off_t) <= sizeof(DWORD)) ? 

++                    (DWORD)maxSize : (DWORD)(maxSize & 0xFFFFFFFFL);

++    const DWORD dwMaxSizeHigh = (sizeof(off_t) <= sizeof(DWORD)) ?

++                    (DWORD)0 : (DWORD)((maxSize >> 32) & 0xFFFFFFFFL);

++

++#ifdef _MSC_VER

++#pragma warning(pop)

++#endif

++

++    errno = 0;

++    

++    if (len == 0 

++        /* Unsupported flag combinations */

++        || (flags & MAP_FIXED) != 0

++        /* Usupported protection combinations */

++        || prot == PROT_EXEC)

++    {

++        errno = EINVAL;

++        return MAP_FAILED;

++    }

++    

++    h = ((flags & MAP_ANONYMOUS) == 0) ? 

++                    (HANDLE)_get_osfhandle(fildes) : INVALID_HANDLE_VALUE;

++

++    if ((flags & MAP_ANONYMOUS) == 0 && h == INVALID_HANDLE_VALUE)

++    {

++        errno = EBADF;

++        return MAP_FAILED;

++    }

++

++    fm = CreateFileMapping(h, NULL, protect, dwMaxSizeHigh, dwMaxSizeLow, NULL);

++

++    if (fm == NULL)

++    {

++        errno = __map_mman_error(GetLastError(), EPERM);

++        return MAP_FAILED;

++    }

++  

++    map = MapViewOfFile(fm, desiredAccess, dwFileOffsetHigh, dwFileOffsetLow, len);

++

++    CloseHandle(fm);

++  

++    if (map == NULL)

++    {

++        errno = __map_mman_error(GetLastError(), EPERM);

++        return MAP_FAILED;

++    }

++

++    return map;

++}

++

++int munmap(void *addr, size_t len)

++{

++    if (UnmapViewOfFile(addr))

++        return 0;

++        

++    errno =  __map_mman_error(GetLastError(), EPERM);

++    

++    return -1;

++}

++

++int mprotect(void *addr, size_t len, int prot)

++{

++    DWORD newProtect = __map_mmap_prot_page(prot);

++    DWORD oldProtect = 0;

++    

++    if (VirtualProtect(addr, len, newProtect, &oldProtect))

++        return 0;

++    

++    errno =  __map_mman_error(GetLastError(), EPERM);

++    

++    return -1;

++}

++

++int msync(void *addr, size_t len, int flags)

++{

++    if (FlushViewOfFile(addr, len))

++        return 0;

++    

++    errno =  __map_mman_error(GetLastError(), EPERM);

++    

++    return -1;

++}

++

++int mlock(const void *addr, size_t len)

++{

++    if (VirtualLock((LPVOID)addr, len))

++        return 0;

++        

++    errno =  __map_mman_error(GetLastError(), EPERM);

++    

++    return -1;

++}

++

++int munlock(const void *addr, size_t len)

++{

++    if (VirtualUnlock((LPVOID)addr, len))

++        return 0;

++        

++    errno =  __map_mman_error(GetLastError(), EPERM);

++    

++    return -1;

++}

+diff --git a/lib/Support/raw_ostream.cpp b/lib/Support/raw_ostream.cpp
+index e294bc3..836438b 100644
+--- a/lib/Support/raw_ostream.cpp
++++ b/lib/Support/raw_ostream.cpp
+@@ -12,7 +12,7 @@
+ # include <unistd.h>
+ #endif
+ 
+-#if defined(_MSC_VER)
++#if defined(_WIN32)
+ #include <io.h>
+ #ifndef STDIN_FILENO
+ # define STDIN_FILENO 0
+diff --git a/lib/Target/GNULDBackend.cpp b/lib/Target/GNULDBackend.cpp
+index 3e8915d..67c28cf 100644
+--- a/lib/Target/GNULDBackend.cpp
++++ b/lib/Target/GNULDBackend.cpp
+@@ -37,6 +37,10 @@
+ #include <mcld/LD/StubFactory.h>
+ #include <mcld/Object/ObjectBuilder.h>
+ 
++#if defined(_WIN32)
++  #define bzero(b,l) (memset((b), 0, (l)), (void)0)
++#endif
++
+ using namespace mcld;
+ 
+ //===--------------------------------------------------------------------===//
+diff --git a/lib/Target/Mips/MipsLDBackend.cpp b/lib/Target/Mips/MipsLDBackend.cpp
+index 8a62bd3..2f8f2fa 100644
+--- a/lib/Target/Mips/MipsLDBackend.cpp
++++ b/lib/Target/Mips/MipsLDBackend.cpp
+@@ -27,6 +27,10 @@
+ #include <mcld/Target/OutputRelocSection.h>
+ #include <mcld/Object/ObjectBuilder.h>
+ 
++#if defined(_WIN32)
++  #define bzero(b,l) (memset((b), 0, (l)), (void)0)
++#endif
++
+ using namespace mcld;
+ 
+ //===----------------------------------------------------------------------===//
+diff --git a/m4/llvm.m4 b/m4/llvm.m4
+index 42c9f58..a8732ad 100644
+--- a/m4/llvm.m4
++++ b/m4/llvm.m4
+@@ -111,7 +111,7 @@ AC_DEFUN([CHECK_LLVM],
+ 			*-*-win32*)
+ 				llvm_cv_platform_type="Win32" ;;
+ 			*-*-mingw*)
+-				llvm_cv_platform_type="Win32" ;;
++				llvm_cv_platform_type="Unix" ;;
+ 			*-*-haiku*)
+ 				llvm_cv_platform_type="Unix" ;;
+ 			*-unknown-eabi*)
+diff --git a/optimized/Makefile.am b/optimized/Makefile.am
+index 2e5df69..efd46dc 100644
+--- a/optimized/Makefile.am
++++ b/optimized/Makefile.am
+@@ -173,6 +173,7 @@ SOURCE = ${LIBDIR}/ADT/StringEntry.cpp \
+ 	${LIBDIR}/Support/Windows/FileSystem.inc \
+ 	${LIBDIR}/Support/Windows/PathV3.inc \
+ 	${LIBDIR}/Support/Windows/System.inc \
++	${LIBDIR}/Support/mingw/mman.inc \
+ 	${LIBDIR}/CodeGen/MCLDTargetMachine.cpp \
+ 	${LIBDIR}/CodeGen/MCLinker.cpp \
+ 	${LIBDIR}/Object/ObjectLinker.cpp \
+diff --git a/tools/llvm-mcld/llvm-mcld.cpp b/tools/llvm-mcld/llvm-mcld.cpp
+index 1f77ed1..68eebf0 100644
+--- a/tools/llvm-mcld/llvm-mcld.cpp
++++ b/tools/llvm-mcld/llvm-mcld.cpp
+@@ -45,7 +45,7 @@
+ # include <unistd.h>
+ #endif
+ 
+-#if defined(_MSC_VER)
++#if defined(_WIN32)
+ #include <io.h>
+ #ifndef STDIN_FILENO
+ # define STDIN_FILENO 0
+-- 
+1.7.7.3
+