Skip to content

Commit

Permalink
Merge pull request #222 from ceeac/macos-compile
Browse files Browse the repository at this point in the history
Fix compilation on macOS 10.13 (High Sierra)
  • Loading branch information
ceeac authored Apr 30, 2019
2 parents 50add78 + fb5a86b commit 29f2db4
Show file tree
Hide file tree
Showing 11 changed files with 108 additions and 64 deletions.
12 changes: 11 additions & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,18 @@ install:
- docker run -d --name build-env -v $(pwd):/home/boomerang/boomerang/ -v /home/travis/.ccache/:/home/boomerang/.ccache ceeac/boomerang-build-env:$TARGET tail -f /dev/null

matrix:
allow_failures:
- os: osx
include:
- os: osx
osx_image: xcode10
install:
before_script:
- HOMEBREW_NO_INSTALL_CLEANUP=1 HOMEBREW_NO_AUTO_UPDATE=1 brew install qt capstone bison flex ccache
- mkdir build && cd build
script:
- cmake -DQt5_DIR=$(brew --prefix qt5)/lib/cmake/Qt5/ -DFLEX_EXECUTABLE=$(brew --prefix flex)/bin/flex -DBISON_EXECUTABLE=$(brew --prefix bison)/bin/bison -DBOOMERANG_BUILD_UNIT_TESTS=ON ..
- make -j$(sysctl -n hw.ncpu) && make test
- env:
- TARGET="source-check"
before_script:
Expand Down Expand Up @@ -44,7 +55,6 @@ matrix:
lcov --list coverage.info"
- echo "Uploading CodeCov reports" && bash <(curl -s https://codecov.io/bash) -X gcov -X coveragepy -X xcode -F unittests -s "$(pwd)/build" || echo \"CodeCov coverage report generation failed!\"


before_script:
- docker exec -t build-env bash -c "cd boomerang &&
mkdir build &&
Expand Down
1 change: 1 addition & 0 deletions Changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ v0.5.0 (in development)
- Feature: Added support for Symbol Provider plugins.
- Feature: Added support for Decoder plugins.
- Feature: Added support for FrontEnd plugins.
- Feature: Added support for compiling on macOS (10.13+).
- Improved: Performance of decoding x86 instructions.
- Improved: General processing of overlapped registers (not just hard-coded ones).
- Improved: Better high level code output quality for x86 binaries due to more instructions being recognized.
Expand Down
40 changes: 25 additions & 15 deletions Readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@ it is currently recommended to build the development version (`develop`) of the

## Building

| **Build status** | Linux | Windows | Test Coverage |
|------------------|-------|---------|---------------|
| **Build status** | Linux/macOS | Windows | Test Coverage |
|------------------|-------------|---------|---------------|
| **develop** | [![Travis CI](https://api.travis-ci.com/BoomerangDecompiler/boomerang.svg?branch=develop)](https://travis-ci.com/BoomerangDecompiler/boomerang/branches) | [![Appveyor](https://ci.appveyor.com/api/projects/status/pg2bw7kxse1t7cx8/branch/develop?svg=true)](https://ci.appveyor.com/project/ceeac/boomerang/branch/develop) | [![codecov](https://codecov.io/gh/BoomerangDecompiler/boomerang/branch/develop/graph/badge.svg)](https://codecov.io/gh/BoomerangDecompiler/boomerang/branch/develop) |
| **master** | [![Travis CI](https://api.travis-ci.com/BoomerangDecompiler/boomerang.svg?branch=master)](https://travis-ci.com/BoomerangDecompiler/boomerang/branches) | [![Appveyor](https://ci.appveyor.com/api/projects/status/pg2bw7kxse1t7cx8/branch/master?svg=true)](https://ci.appveyor.com/project/ceeac/boomerang/branch/master) | [![codecov](https://codecov.io/gh/BoomerangDecompiler/boomerang/branch/master/graph/badge.svg)](https://codecov.io/gh/BoomerangDecompiler/boomerang/branch/master) |

Expand All @@ -22,13 +22,13 @@ it is currently recommended to build the development version (`develop`) of the

- A 64 bit operating system (32 bit might or might not work, but it is not supported.)
- A C++17 compiler (GCC 7+, Clang 6+, MSVC 2017+ are known to work)
- [CMake 3.8+](https://cmake.org/download/)
- [CMake](https://cmake.org/download/) 3.8+
- [Qt5](https://www.qt.io/download-open-source/) (Qt 5.11+ is known to work, earlier versions should also work)
- [Capstone 3.0.5+](http://www.capstone-engine.org/)
- [GNU bison 3.0+](https://www.gnu.org/software/bison/) (3.0.5+ is recommended)
- [GNU flex 2.6+](https://github.com/westes/flex)
- [CCache 3.2+](https://ccache.samba.org/download.html) (optional, for recompilation speed)
- [Doxygen 1.8+](http://www.doxygen.nl/) (optional, for documentation)
- [Capstone](http://www.capstone-engine.org/) 3.0.5+
- [GNU bison](https://www.gnu.org/software/bison/) 3.0+ (3.0.5+ is recommended)
- [GNU flex](https://github.com/westes/flex) 2.6+
- [CCache](https://ccache.samba.org/download.html) 3.2+ (optional, for recompilation speed)
- [Doxygen](http://www.doxygen.nl/) 1.8+ (optional, for documentation)
- [Python 3](https://www.python.org/downloads/) (optional, for regression tests)


Expand All @@ -42,13 +42,28 @@ sudo apt-get install git build-essential cmake qt5-default libcapstone-dev flex
cd YOUR_FAVOURITE_DEVELOPMENT_DIRECTORY
git clone https://github.com/BoomerangDecompiler/boomerang.git
cd boomerang && mkdir build && cd build
cmake .. && make && sudo make install
cmake .. && make -j$(nproc) && sudo make install
```

### Building on macOS

To build Boomerang on macOS, you need at least macOS 10.13 or later, and XCode 10 or later.
The recommended way of installing Boomerang and its dependencies outlined below is via [Homebrew](brew.sh), although other methods might also work (untested).
After installing XCode, execute the following commands in a terminal window:

```bash
/usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)" # Install Homebrew
brew install git cmake qt capstone flex bison # Install dependencies
cd YOUR_FAVOURITE_DEVELOPMENT_DIRECTORY
git clone https://github.com/BoomerangDecompiler/boomerang.git
cd boomerang && mkdir build && cd build
cmake -DQt5_DIR=$(brew --prefix qt5)/lib/cmake/Qt5/ -DFLEX_EXECUTABLE=$(brew --prefix flex)/bin/flex -DBISON_EXECUTABLE=$(brew --prefix bison)/bin/bison ..
make -j$(sysctl -n hw.ncpu) && make install
```

### Building on Windows

To compile on Windows using Visual Studio, you can follow the following guide. Note that the build procedure
To compile on Windows using Visual Studio 2017, you can follow the following guide. Note that the build procedure
for other IDEs or compilers (e.g. MinGW) is not covered in this guide.

- Install Visual Studio 2017 (e.g the free [Community Edition](https://visualstudio.microsoft.com/vs/community/)).
Expand All @@ -65,11 +80,6 @@ for other IDEs or compilers (e.g. MinGW) is not covered in this guide.
- Done!


### Building on macOS

Building on macOS is currently not officially supported. However, pull requests on this matter are welcome. See also [Issue #39](https://github.com/BoomerangDecompiler/boomerang/issues/39).


## Testing

### Unit tests
Expand Down
2 changes: 1 addition & 1 deletion src/boomerang-plugins/decoder/csx86/CapstoneX86Decoder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,7 @@ SharedExp operandToExp(const cs::cs_x86_op &operand)
case cs::X86_OP_IMM: {
return Const::get(Address(operand.imm));
}
default: LOG_ERROR("Unknown x86 instruction operand type %1", operand.type); break;
default: LOG_ERROR("Unknown x86 instruction operand type %1", (int)operand.type); break;
}
return nullptr;
}
Expand Down
2 changes: 1 addition & 1 deletion src/boomerang-plugins/decoder/ppc/CapstonePPCDecoder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,7 @@ SharedExp operandToExp(const cs::cs_ppc_op &operand)
Const::get(operand.mem.disp)))
->simplifyArith();
}
default: LOG_ERROR("Unknown ppc instruction operand type %1", operand.type); break;
default: LOG_ERROR("Unknown ppc instruction operand type %1", (int)operand.type); break;
}

return nullptr;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -235,7 +235,7 @@ SharedExp CapstoneSPARCDecoder::operandToExp(const cs::cs_insn *instruction, int
memExp = Binary::get(opPlus, memExp, Const::get(operand.mem.disp));
return Location::memOf(memExp)->simplifyArith();
}
default: LOG_ERROR("Unknown sparc instruction operand type %1", operand.type); break;
default: LOG_ERROR("Unknown sparc instruction operand type %1", (int)operand.type); break;
}

return nullptr;
Expand Down
60 changes: 44 additions & 16 deletions src/boomerang/ssl/exp/Const.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -129,65 +129,93 @@ bool Const::equalNoSubscript(const Exp &o) const
int Const::getInt() const
{
if (std::get_if<int>(&m_value) != nullptr) {
return std::get<int>(m_value);
return *std::get_if<int>(&m_value);
}
else if (std::get_if<QWord>(&m_value) != nullptr) {
return (int)std::get<QWord>(m_value);
return (int)*std::get_if<QWord>(&m_value);
}
else {
return (int)std::get<double>(m_value);
else if (std::get_if<double>(&m_value) != nullptr) {
return (int)*std::get_if<double>(&m_value);
}

LOG_FATAL("Bad variant access (currently held index %1)", m_value.index());
return 0;
}


QWord Const::getLong() const
{
return std::get<QWord>(m_value);
if (std::get_if<QWord>(&m_value) != nullptr) {
return *std::get_if<QWord>(&m_value);
}

LOG_FATAL("Bad variant access (currently held index %1)", m_value.index());
return 0;
}


double Const::getFlt() const
{
return std::get<double>(m_value);
if (std::get_if<double>(&m_value) != nullptr) {
return *std::get_if<double>(&m_value);
}

LOG_FATAL("Bad variant access (currently held index %1)", m_value.index());
return 0.0;
}


QString Const::getStr() const
{
if (std::get_if<QString>(&m_value) != nullptr) {
return std::get<QString>(m_value);
return *std::get_if<QString>(&m_value);
}
else {
return std::get<const char *>(m_value);
else if (std::get_if<const char *>(&m_value) != nullptr) {
return *std::get_if<const char *>(&m_value);
}

LOG_FATAL("Bad variant access (currently held index %1)", m_value.index());
return "";
}


const char *Const::getRawStr() const
{
if (std::get_if<const char *>(&m_value) != nullptr) {
return std::get<const char *>(m_value);
return *std::get_if<const char *>(&m_value);
}
else {
return qPrintable(std::get<QString>(m_value));
else if (std::get_if<QString>(&m_value) != nullptr) {
return qPrintable(*std::get_if<QString>(&m_value));
}

LOG_FATAL("Bad variant access (currently held index %1)", m_value.index());
return nullptr;
}


Address Const::getAddr() const
{
if (std::get_if<QWord>(&m_value) != nullptr) {
return Address(static_cast<Address::value_type>(std::get<QWord>(m_value)));
return Address(static_cast<Address::value_type>(*std::get_if<QWord>(&m_value)));
}
else {
return Address(static_cast<Address::value_type>(std::get<int>(m_value)));
else if (std::get_if<int>(&m_value) != nullptr) {
return Address(static_cast<Address::value_type>(*std::get_if<int>(&m_value)));
}

LOG_FATAL("Bad variant access (currently held index %1)", m_value.index());
return Address::INVALID;
}


QString Const::getFuncName() const
{
return std::get<Function *>(m_value)->getName();
if (std::get_if<Function *>(&m_value) != nullptr) {
assert(*std::get_if<Function *>(&m_value) != nullptr);
return (*std::get_if<Function *>(&m_value))->getName();
}

LOG_FATAL("Bad variant access (currently held index %1)", m_value.index());
return "";
}


Expand Down
14 changes: 7 additions & 7 deletions src/boomerang/ssl/type/ArrayType.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,15 +10,15 @@
#include "ArrayType.h"


ArrayType::ArrayType(SharedType baseType, size_t length)
ArrayType::ArrayType(SharedType baseType, uint64 length)
: Type(TypeClass::Array)
, m_baseType(baseType)
, m_length(length)
{
}


std::shared_ptr<ArrayType> ArrayType::get(SharedType p, size_t length)
std::shared_ptr<ArrayType> ArrayType::get(SharedType p, uint64 length)
{
return std::make_shared<ArrayType>(p, length);
}
Expand All @@ -36,7 +36,7 @@ bool ArrayType::isUnbounded() const
}


size_t ArrayType::convertLength(SharedType b) const
uint64 ArrayType::convertLength(SharedType b) const
{
// MVE: not sure if this is always the right thing to do
if (m_length != ARRAY_UNBOUNDED) {
Expand Down Expand Up @@ -131,7 +131,7 @@ SharedType ArrayType::meetWith(SharedType other, bool &changed, bool useHighestP
auto otherArr = other->as<ArrayType>();
SharedType newBase = m_baseType->clone()->meetWith(otherArr->m_baseType, changed,
useHighestPtr);
size_t newLength = m_length;
uint64 newLength = m_length;

if (*newBase != *m_baseType) {
changed = true;
Expand Down Expand Up @@ -160,8 +160,8 @@ SharedType ArrayType::meetWith(SharedType other, bool &changed, bool useHighestP
* based on new BaseType
*/
if (isCompatible(*other, false)) { // compatible with all ?
size_t bitsize = m_baseType->getSize();
size_t new_size = other->getSize();
Type::Size bitsize = m_baseType->getSize();
Type::Size new_size = other->getSize();

if (m_baseType->isComplete() && !other->isComplete()) {
// complete types win
Expand All @@ -183,7 +183,7 @@ SharedType ArrayType::meetWith(SharedType other, bool &changed, bool useHighestP
return std::const_pointer_cast<Type>(this->shared_from_this());
}

size_t new_length = m_length;
uint64 new_length = m_length;

if (m_length != ARRAY_UNBOUNDED) {
new_length = (m_length * bitsize) / new_size;
Expand Down
12 changes: 6 additions & 6 deletions src/boomerang/ssl/type/ArrayType.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,14 @@
* computing aliases.. as such, we give them a very large bound
* and hope that no-one tries to alias beyond them
*/
#define ARRAY_UNBOUNDED 9999999
#define ARRAY_UNBOUNDED ((uint64)9999999)


class BOOMERANG_API ArrayType : public Type
{
public:
/// Create a new array type of fixed length
explicit ArrayType(SharedType baseType, size_t length = ARRAY_UNBOUNDED);
explicit ArrayType(SharedType baseType, uint64 length = ARRAY_UNBOUNDED);

ArrayType(const ArrayType &other) = default;
ArrayType(ArrayType &&other) = default;
Expand All @@ -35,7 +35,7 @@ class BOOMERANG_API ArrayType : public Type
ArrayType &operator=(ArrayType &&other) = default;

public:
static std::shared_ptr<ArrayType> get(SharedType p, size_t length = ARRAY_UNBOUNDED);
static std::shared_ptr<ArrayType> get(SharedType p, uint64 length = ARRAY_UNBOUNDED);

public:
/// \copydoc Type::operator==
Expand Down Expand Up @@ -68,7 +68,7 @@ class BOOMERANG_API ArrayType : public Type
void setBaseType(SharedType b);

/// \returns the number of elements in this array.
size_t getLength() const { return m_length; }
uint64 getLength() const { return m_length; }
void setLength(unsigned n) { m_length = n; }

/// \returns true iff we do not know the length of the array (yet)
Expand All @@ -81,9 +81,9 @@ class BOOMERANG_API ArrayType : public Type
private:
/// \returns the new number of elements that fit in this array when converting
/// the base type to \p newBaseType
size_t convertLength(SharedType newBaseType) const;
uint64 convertLength(SharedType newBaseType) const;

private:
SharedType m_baseType;
size_t m_length = 0; ///< number of elements in this array
uint64 m_length = 0; ///< number of elements in this array
};
23 changes: 9 additions & 14 deletions src/boomerang/util/log/Log.h
Original file line number Diff line number Diff line change
Expand Up @@ -153,22 +153,17 @@ class BOOMERANG_API Log
QString collectArg(const QString &msg, const Type &ty);
QString collectArg(const QString &msg, const RTL *r);
QString collectArg(const QString &msg, const LocationSet *l);

QString collectArg(const QString &msg, char arg) { return msg.arg(arg); }
QString collectArg(const QString &msg, sint16 arg) { return msg.arg(arg); }
QString collectArg(const QString &msg, sint32 arg) { return msg.arg(arg); }
QString collectArg(const QString &msg, sint64 arg) { return msg.arg(arg); }

QString collectArg(const QString &msg, uint8 arg) { return msg.arg(arg); }
QString collectArg(const QString &msg, uint16 arg) { return msg.arg(arg); }
QString collectArg(const QString &msg, uint32 arg) { return msg.arg(arg); }
QString collectArg(const QString &msg, uint64 arg) { return msg.arg(arg); }

QString collectArg(const QString &msg, float arg) { return msg.arg(arg); }
QString collectArg(const QString &msg, double arg) { return msg.arg(arg); }

QString collectArg(const QString &msg, Address addr);

// Integral or floating point PODs
template<typename Arg,
typename std::enable_if<
std::is_integral<Arg>::value || std::is_floating_point<Arg>::value, int>::type = 0>
QString collectArg(const QString &msg, Arg arg)
{
return msg.arg(arg);
}

template<typename Arg>
QString collectArgs(const QString &msg, Arg arg)
{
Expand Down
4 changes: 2 additions & 2 deletions tests/unit-tests/boomerang-plugins/loader/MicroX86DisTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -253,7 +253,7 @@ void MicroX86DisTest::testMicroDis1()

if (size >= 0x40) {
deb_str << "Not handled instruction at offset "
<< HostAddress(p).value() - HostAddress(pent_hello_text).value() << '\n';
<< (uint64)(HostAddress(p).value() - HostAddress(pent_hello_text).value()) << '\n';
qDebug() << deb;
QVERIFY(size != 0x40);
return;
Expand All @@ -262,7 +262,7 @@ void MicroX86DisTest::testMicroDis1()
int expected = lengths[i++];

if (expected != size) {
deb_str << "At offset " << HostAddress(p).value() - HostAddress(pent_hello_text).value() << " ("
deb_str << "At offset " << (uint64)(HostAddress(p).value() - HostAddress(pent_hello_text).value()) << " ("
<< static_cast<int>(*(p + 0)) << " "
<< static_cast<int>(*(p + 1)) << " "
<< static_cast<int>(*(p + 2)) << " "
Expand Down

0 comments on commit 29f2db4

Please sign in to comment.