Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add limited, experimental support for MinGW and Clang #469

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@
## Requirements

- Visual Studio 2017 15.7 or higher
- There is limited support for MinGW and Clang. See [README_MINGW_CLANG.md](README_MINGW_CLANG.md)
- Windows SDK 10.0.17134 or higher
- WDK 10.0.17134 or higher (driver only)
- VC++ 2017 Libs for Spectre (x86 and x64)
Expand Down
21 changes: 21 additions & 0 deletions README_MINGW_CLANG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# Support for MinGW/Clang

There is limited, experimental support for building BlackBone with MinGW (GCC) and Clang on Windows. Read the following hints carefully before attempting to use it.


## General

* You must **build with CMake**, by using the directory with the top-level CMakeLists.txt as source directory.
* **Only the library and Samples** work with MinGW/Clang. I have not attempted to make the driver or the unit tests compile. I have not even tried if the library works with an MSVC-compiled driver.
* **Only 64-bit builds** are supported. Even if it compiles under 32-bit, it may crash at runtime. This is because BlackBone uses the Rewolf-WOW64Ext library when running under Wow64, and that contains inline ASM code that only works in MSVC right now. No idea about 32-bit builds on 32-bit Windows.
* **Syscall support is disabled.** This means anything in the *Blackbone/Syscalls* directory won't work. That's because syscalls in BlackBone require ASM code that was written in MASM syntax, which neither MinGW nor Clang support.


## MinGW (GCC) Specifics

* It was tested with **MinGW GCC 10.0.3 from MSYS2**. GCC 8.1.0 did also work at some point, but YMMV.


## Clang Specifics

* It was tested with **Clang 12.0.0 from MSYS2**. Earlier versions may or may not work.
348 changes: 348 additions & 0 deletions src/3rd_party/reactos-atl/LICENSE-GPL.txt

Large diffs are not rendered by default.

504 changes: 504 additions & 0 deletions src/3rd_party/reactos-atl/LICENSE-LGPL.txt

Large diffs are not rendered by default.

6 changes: 6 additions & 0 deletions src/3rd_party/reactos-atl/README.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
These headers are taken from ReactOS:

https://github.com/reactos/reactos/tree/master/sdk/lib/atl

They are only used when compiling with MinGW/Clang, because the standard ATL
headers are only compatible with MSVC.
13 changes: 13 additions & 0 deletions src/3rd_party/reactos-atl/atl/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@

add_library(atl_classes INTERFACE)
if(DBG)
#target_compile_definitions(atl_classes INTERFACE _DEBUG) # HACK & FIXME: CORE-17505
endif()

target_include_directories(atl_classes INTERFACE
$<$<COMPILE_LANGUAGE:CXX>:${CMAKE_CURRENT_SOURCE_DIR}>)

target_compile_definitions(atl_classes INTERFACE
"$<$<AND:$<COMPILE_LANGUAGE:CXX>,$<NOT:$<BOOL:$<TARGET_PROPERTY:WITH_CXX_EXCEPTIONS>>>>:_ATL_NO_EXCEPTIONS>")

target_link_libraries(atl_classes INTERFACE pseh)
194 changes: 194 additions & 0 deletions src/3rd_party/reactos-atl/atl/atlalloc.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,194 @@
/*
* ReactOS ATL
*
* Copyright 2009 Andrew Hill <[email protected]>
* Copyright 2016 Mark Jansen
*
* 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.
*
* 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
*/

#pragma once

class CCRTAllocator
{
public:
static void* Allocate(_In_ size_t size)
{
return malloc(size);
}

static void* Reallocate(_In_opt_ void* ptr, _In_ size_t size)
{
return realloc(ptr, size);
}

static void Free(_In_opt_ void* ptr)
{
free(ptr);
}
};

class CLocalAllocator
{
public:
static void* Allocate(_In_ size_t size)
{
return ::LocalAlloc(LMEM_FIXED, size);
}

static void* Reallocate(_In_opt_ void* ptr, _In_ size_t size)
{
if (!ptr)
return Allocate(size);
if (size == 0)
{
Free(ptr);
return NULL;
}
return ::LocalReAlloc(ptr, size, 0);
}

static void Free(_In_opt_ void* ptr)
{
::LocalFree(ptr);
}
};

class CGlobalAllocator
{
public:
static void* Allocate(_In_ size_t size)
{
return ::GlobalAlloc(GMEM_FIXED, size);
}

static void* Reallocate(_In_opt_ void* ptr, _In_ size_t size)
{
if (!ptr)
return Allocate(size);
if (size == 0)
{
Free(ptr);
return NULL;
}
return ::GlobalReAlloc(ptr, size, 0);
}

static void Free(_In_opt_ void* ptr)
{
GlobalFree(ptr);
}
};


template<class T, class Allocator = CCRTAllocator>
class CHeapPtr
{
public:
CHeapPtr() :
m_pData(NULL)
{
}

explicit CHeapPtr(T *lp) :
m_pData(lp)
{
}

explicit CHeapPtr(CHeapPtr<T, Allocator> &lp)
{
m_pData = lp.Detach();
}

~CHeapPtr()
{
Free();
}

CHeapPtr<T, Allocator>& operator = (CHeapPtr<T, Allocator> &lp)
{
if (lp.m_pData != m_pData)
Attach(lp.Detach());
return *this;
}

bool AllocateBytes(_In_ size_t nBytes)
{
ATLASSERT(m_pData == NULL);
m_pData = static_cast<T*>(Allocator::Allocate(nBytes));
return m_pData != NULL;
}

bool ReallocateBytes(_In_ size_t nBytes)
{
T* newData = static_cast<T*>(Allocator::Reallocate(m_pData, nBytes));
if (newData == NULL)
return false;
m_pData = newData;
return true;
}

bool Allocate(_In_ size_t nElements = 1)
{
return AllocateBytes(nElements * sizeof(T));
}

bool Reallocate(_In_ size_t nElements)
{
return ReallocateBytes(nElements * sizeof(T));
}

void Free()
{
if (m_pData)
{
Allocator::Free(m_pData);
m_pData = NULL;
}
}

void Attach(T *lp)
{
Allocator::Free(m_pData);
m_pData = lp;
}

T *Detach()
{
T *saveP = m_pData;
m_pData = NULL;
return saveP;
}

T **operator &()
{
ATLASSERT(m_pData == NULL);
return &m_pData;
}

operator T* () const
{
return m_pData;
}

T* operator->() const
{
return m_pData;
}

public:
T *m_pData;
};

Loading