diff --git a/CHANGELOG.md b/CHANGELOG.md index 6dd8cf4bb..43484793f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -20,7 +20,7 @@ - The VMM now uses it's own CR4 instead of the CR4 provided by the Host OS. - The VMM now uses it's own RFLAGS instead of the RFLAGS provided by the Host OS. - The VMM now uses it's own EFER MSR instead of the EFER MSR provided by the Host OS. -- New vCPU APIs that provide that ability to pass around a "void *" for extension +- New vCPU APIs that provide that ability to pass around a "user_data *" for extension support - Support for "-O3" optimizations - Support for SSE/AVX code in the VMM @@ -34,6 +34,12 @@ - AppVeyor support - Clang Tidy 3.8 support - Clang / LLVM 3.8 and 3.9 support +- libc / libcxx / libcxxabi / bfcrt / bfunwind all loaded as shared libraries +- VMCS unit tests +- Intrinsics / VMCS namespace logic that provides useful functions / definitions + found in the Intel manual +- Libcxx unit tests +- VMCall support ### Changed - The VMCS state classes are now shared by pointer (i.e. shared_ptr) @@ -64,6 +70,7 @@ use the subclasses instead, or inherit manually - The vCPU dispatch, halt and promote functions have been removed as they were specific to Intel. +- GCC 5.x support for cross compilation (native still supported) ## [1.0.0] - 2016-27-04 ### Added diff --git a/bfcxx/README.md b/bfcxx/README.md index 7cc2747d8..9fbabf70c 100644 --- a/bfcxx/README.md +++ b/bfcxx/README.md @@ -15,7 +15,7 @@ Bareflank leverages [libc++](http://libcxx.llvm.org) to provide support for the - [std::map](http://www.cplusplus.com/reference/map/map/) ## [Input/Output](http://www.cplusplus.com/reference/iolibrary/) -\ +- [std::cout](http://www.cplusplus.com/reference/iostream/cout/) ## [Multi-threading](http://www.cplusplus.com/reference/multithreading/) \ diff --git a/bfvmm/include/exit_handler/exit_handler_intel_x64.h b/bfvmm/include/exit_handler/exit_handler_intel_x64.h index 714af2f2f..90e48860e 100644 --- a/bfvmm/include/exit_handler/exit_handler_intel_x64.h +++ b/bfvmm/include/exit_handler/exit_handler_intel_x64.h @@ -128,7 +128,6 @@ class exit_handler_intel_x64 private: #ifdef INCLUDE_LIBCXX_UNITTESTS - void unittest_1001_containers_array() const; void unittest_1002_containers_vector() const; void unittest_1003_containers_deque() const; @@ -140,6 +139,8 @@ class exit_handler_intel_x64 void unittest_1009_containers_set() const; void unittest_100A_containers_map() const; + void unittest_1100_io_cout() const; + void unittest_1101_io_manipulators() const; #endif private: diff --git a/bfvmm/include/exit_handler/exit_handler_intel_x64_unittests.h b/bfvmm/include/exit_handler/exit_handler_intel_x64_unittests.h new file mode 100644 index 000000000..dd7964baa --- /dev/null +++ b/bfvmm/include/exit_handler/exit_handler_intel_x64_unittests.h @@ -0,0 +1,41 @@ +// +// Bareflank Hypervisor +// +// Copyright (C) 2015 Assured Information Security, Inc. +// Author: Rian Quinn +// Author: Brendan Kerrigan +// +// 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 + +#ifndef EXIT_HANDLER_INTEL_X64_UNITTESTS_H +#define EXIT_HANDLER_INTEL_X64_UNITTESTS_H + +#include + +#include +#include + +inline void +expect_true_with_args(bool cond, const char *func, int line) +{ if (!cond) throw std::runtime_error("unittest failed ["_s + std::to_string(line) + "]: "_s + func); } + +inline void +expect_false_with_args(bool cond, const char *func, int line) +{ if (cond) throw std::runtime_error("unittest failed ["_s + std::to_string(line) + "]: "_s + func); } + +#define expect_true(a) expect_true_with_args(a, __FUNC__, __LINE__); +#define expect_false(a) expect_false_with_args(a, __FUNC__, __LINE__); + +#endif diff --git a/bfvmm/src/exit_handler/src/Makefile.bf b/bfvmm/src/exit_handler/src/Makefile.bf index 5a067ea01..11f501e09 100644 --- a/bfvmm/src/exit_handler/src/Makefile.bf +++ b/bfvmm/src/exit_handler/src/Makefile.bf @@ -33,6 +33,7 @@ else endif ifeq ($(INCLUDE_LIBCXX_UNITTESTS), yes) + CROSS_DEFINES+=INCLUDE_LIBCXX_UNITTESTS NATIVE_DEFINES+=INCLUDE_LIBCXX_UNITTESTS endif @@ -72,6 +73,8 @@ SOURCES+=exit_handler_intel_x64.cpp SOURCES+=exit_handler_intel_x64_entry.cpp SOURCES+=exit_handler_intel_x64_support.asm SOURCES+=exit_handler_intel_x64_unittests.cpp +SOURCES+=exit_handler_intel_x64_unittests_containers.cpp +SOURCES+=exit_handler_intel_x64_unittests_io.cpp INCLUDE_PATHS+=./ INCLUDE_PATHS+=%HYPER_ABS%/include/ diff --git a/bfvmm/src/exit_handler/src/exit_handler_intel_x64_unittests.cpp b/bfvmm/src/exit_handler/src/exit_handler_intel_x64_unittests.cpp index 33ca0bf4d..3bea1a565 100644 --- a/bfvmm/src/exit_handler/src/exit_handler_intel_x64_unittests.cpp +++ b/bfvmm/src/exit_handler/src/exit_handler_intel_x64_unittests.cpp @@ -19,42 +19,16 @@ // License along with this library; if not, write to the Free Software // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -#include - -#include -#include +#include #ifndef INCLUDE_LIBCXX_UNITTESTS void exit_handler_intel_x64::handle_vmcall_unittest(vmcall_registers_t ®s) -{ - (void) regs; -} +{ (void) regs; } #else -#include -#include -#include -#include -#include -#include -#include -#include -#include - -static void -expect_true_with_args(bool cond, const char *func, int line) -{ if (!cond) throw std::runtime_error("unittest failed ["_s + std::to_string(line) + "]: "_s + func); } - -static void -expect_false_with_args(bool cond, const char *func, int line) -{ if (cond) throw std::runtime_error("unittest failed ["_s + std::to_string(line) + "]: "_s + func); } - -#define expect_true(a) expect_true_with_args(a, __FUNC__, __LINE__); -#define expect_false(a) expect_false_with_args(a, __FUNC__, __LINE__); - void exit_handler_intel_x64::handle_vmcall_unittest(vmcall_registers_t ®s) { @@ -70,502 +44,13 @@ exit_handler_intel_x64::handle_vmcall_unittest(vmcall_registers_t ®s) case 0x1008: unittest_1008_containers_priority_queue(); break; case 0x1009: unittest_1009_containers_set(); break; case 0x100A: unittest_100A_containers_map(); break; + + case 0x1100: unittest_1100_io_cout(); break; + case 0x1101: unittest_1101_io_manipulators(); break; + default: throw std::runtime_error("unknown unit test #"); } } -void -exit_handler_intel_x64::unittest_1001_containers_array() const -{ - auto myarray = std::array({0, 1, 2, 3}); - auto myarray2 = std::array({0, 1, 2, 3}); - - auto total = 0; - for (auto iter = myarray.begin(); iter != myarray.end(); iter++) - total += *iter; - - auto rtotal = 0; - for (auto iter = myarray.rbegin(); iter != myarray.rend(); iter++) - rtotal += *iter; - - auto ctotal = 0; - for (auto iter = myarray.cbegin(); iter != myarray.cend(); iter++) - ctotal += *iter; - - auto crtotal = 0; - for (auto iter = myarray.crbegin(); iter != myarray.crend(); iter++) - crtotal += *iter; - - expect_true(total == 6); - expect_true(rtotal == 6); - expect_true(ctotal == 6); - expect_true(crtotal == 6); - - expect_true(myarray.size() == 4); - expect_true(myarray.max_size() == 4); - expect_false(myarray.empty()); - - expect_true(myarray.at(0) == 0); - expect_true(myarray.at(3) == 3); - expect_true(myarray.front() == 0); - expect_true(myarray.back() == 3); - expect_true(myarray.data() != nullptr); - - myarray.fill(0); - myarray.swap(myarray2); - - expect_true(std::get<0>(myarray) == 0); - expect_true(std::get<3>(myarray) == 3); - - expect_false(myarray == myarray2); - expect_true(myarray != myarray2); - expect_false(myarray < myarray2); - expect_true(myarray > myarray2); - expect_false(myarray <= myarray2); - expect_true(myarray >= myarray2); -} - -void -exit_handler_intel_x64::unittest_1002_containers_vector() const -{ - auto myvector = std::vector({0, 1, 2, 3}); - auto myvector2 = std::vector({0, 1, 2, 3}); - - myvector = myvector2; - - auto total = 0; - for (auto iter = myvector.begin(); iter != myvector.end(); iter++) - total += *iter; - - auto rtotal = 0; - for (auto iter = myvector.rbegin(); iter != myvector.rend(); iter++) - rtotal += *iter; - - auto ctotal = 0; - for (auto iter = myvector.cbegin(); iter != myvector.cend(); iter++) - ctotal += *iter; - - auto crtotal = 0; - for (auto iter = myvector.crbegin(); iter != myvector.crend(); iter++) - crtotal += *iter; - - expect_true(total == 6); - expect_true(rtotal == 6); - expect_true(ctotal == 6); - expect_true(crtotal == 6); - - expect_true(myvector.size() == 4); - expect_true(myvector.max_size() >= 4); - myvector.resize(4); - expect_true(myvector.capacity() >= 4); - expect_false(myvector.empty()); - myvector.reserve(4); - myvector.shrink_to_fit(); - - expect_true(myvector.at(0) == 0); - expect_true(myvector.at(3) == 3); - expect_true(myvector.front() == 0); - expect_true(myvector.back() == 3); - expect_true(myvector.data() != nullptr); - - myvector.assign(4, 0); - myvector.push_back(4); - myvector.pop_back(); - myvector.insert(myvector.begin(), 0); - myvector.erase(myvector.begin()); - myvector.clear(); - myvector.swap(myvector2); - myvector2.emplace(myvector.begin()); - myvector2.emplace_back(); - - myvector.get_allocator(); - - expect_false(myvector == myvector2); - expect_true(myvector != myvector2); - expect_false(myvector < myvector2); - expect_true(myvector > myvector2); - expect_false(myvector <= myvector2); - expect_true(myvector >= myvector2); - - std::swap(myvector, myvector2); -} - -void -exit_handler_intel_x64::unittest_1003_containers_deque() const -{ - auto mydeque = std::deque({0, 1, 2, 3}); - auto mydeque2 = std::deque({0, 1, 2, 3}); - - mydeque = mydeque2; - - auto total = 0; - for (auto iter = mydeque.begin(); iter != mydeque.end(); iter++) - total += *iter; - - auto rtotal = 0; - for (auto iter = mydeque.rbegin(); iter != mydeque.rend(); iter++) - rtotal += *iter; - - auto ctotal = 0; - for (auto iter = mydeque.cbegin(); iter != mydeque.cend(); iter++) - ctotal += *iter; - - auto crtotal = 0; - for (auto iter = mydeque.crbegin(); iter != mydeque.crend(); iter++) - crtotal += *iter; - - expect_true(total == 6); - expect_true(rtotal == 6); - expect_true(ctotal == 6); - expect_true(crtotal == 6); - - expect_true(mydeque.size() == 4); - expect_true(mydeque.max_size() >= 4); - mydeque.resize(4); - expect_false(mydeque.empty()); - mydeque.shrink_to_fit(); - - expect_true(mydeque.at(0) == 0); - expect_true(mydeque.at(3) == 3); - expect_true(mydeque.front() == 0); - expect_true(mydeque.back() == 3); - - mydeque.assign(4, 0); - mydeque.push_back(4); - mydeque.pop_back(); - mydeque.push_front(4); - mydeque.pop_front(); - mydeque.insert(mydeque.begin(), 0); - mydeque.erase(mydeque.begin()); - mydeque.clear(); - mydeque.swap(mydeque2); - mydeque2.emplace(mydeque.begin()); - mydeque2.emplace_back(); - mydeque2.emplace_front(); - - mydeque.get_allocator(); - - expect_false(mydeque == mydeque2); - expect_true(mydeque != mydeque2); - expect_false(mydeque < mydeque2); - expect_true(mydeque > mydeque2); - expect_false(mydeque <= mydeque2); - expect_true(mydeque >= mydeque2); - - std::swap(mydeque, mydeque2); -} - -void -exit_handler_intel_x64::unittest_1004_containers_forward_list() const -{ - auto mylist = std::forward_list({0, 1, 2, 3}); - auto mylist2 = std::forward_list({0, 1, 2, 3}); - - mylist = mylist2; - - mylist.insert_after(mylist.before_begin(), 10); - mylist.erase_after(mylist.begin()); - mylist.insert_after(mylist.cbefore_begin(), 10); - mylist.erase_after(mylist.cbegin()); - - auto total = 0; - for (auto iter = mylist.begin(); iter != mylist.end(); iter++) - total += *iter; - - auto ctotal = 0; - for (auto iter = mylist.cbegin(); iter != mylist.cend(); iter++) - ctotal += *iter; - - expect_true(total == 6); - expect_true(ctotal == 6); - - expect_true(mylist.max_size() >= 4); - expect_false(mylist.empty()); - - expect_true(mylist.front() == 0); - - mylist.assign(4, 0); - mylist.push_front(4); - mylist.pop_front(); - mylist.clear(); - mylist.swap(mylist2); - mylist.resize(4); - mylist2.emplace_front(); - mylist2.emplace_after(mylist.begin()); - - mylist.get_allocator(); - - expect_false(mylist == mylist2); - expect_true(mylist != mylist2); - expect_false(mylist < mylist2); - expect_true(mylist > mylist2); - expect_false(mylist <= mylist2); - expect_true(mylist >= mylist2); - - mylist.splice_after(mylist.before_begin(), mylist2); - mylist.remove(0); - mylist.unique(); - mylist.merge(mylist2, std::greater()); - mylist.sort(std::greater()); - mylist.reverse(); - - std::swap(mylist, mylist2); -} - -void -exit_handler_intel_x64::unittest_1005_containers_list() const -{ - auto mylist = std::list({0, 1, 2, 3}); - auto mylist2 = std::list({0, 1, 2, 3}); - - mylist = mylist2; - - auto total = 0; - for (auto iter = mylist.begin(); iter != mylist.end(); iter++) - total += *iter; - - auto rtotal = 0; - for (auto iter = mylist.rbegin(); iter != mylist.rend(); iter++) - rtotal += *iter; - - auto ctotal = 0; - for (auto iter = mylist.cbegin(); iter != mylist.cend(); iter++) - ctotal += *iter; - - auto crtotal = 0; - for (auto iter = mylist.crbegin(); iter != mylist.crend(); iter++) - crtotal += *iter; - - expect_true(total == 6); - expect_true(rtotal == 6); - expect_true(ctotal == 6); - expect_true(crtotal == 6); - - expect_true(mylist.size() == 4); - expect_true(mylist.max_size() >= 4); - expect_false(mylist.empty()); - - expect_true(mylist.front() == 0); - expect_true(mylist.back() == 3); - - mylist.assign(4, 0); - mylist.push_back(4); - mylist.pop_back(); - mylist.push_front(4); - mylist.pop_front(); - mylist.insert(mylist.begin(), 0); - mylist.erase(mylist.begin()); - mylist.clear(); - mylist.resize(4); - mylist.swap(mylist2); - mylist2.emplace(mylist.begin()); - mylist2.emplace_back(); - mylist2.emplace_front(); - - mylist.get_allocator(); - - expect_false(mylist == mylist2); - expect_true(mylist != mylist2); - expect_false(mylist < mylist2); - expect_true(mylist > mylist2); - expect_false(mylist <= mylist2); - expect_true(mylist >= mylist2); - - mylist.splice(mylist.begin(), mylist2); - mylist.remove(0); - mylist.unique(); - mylist.merge(mylist2, std::greater()); - mylist.sort(std::greater()); - mylist.reverse(); - - std::swap(mylist, mylist2); -} - -void -exit_handler_intel_x64::unittest_1006_containers_stack() const -{ - auto mystack = std::stack({0, 1, 2, 3}); - auto mystack2 = std::stack({0, 1, 2, 3}); - - expect_true(mystack.size() == 4); - expect_false(mystack.empty()); - - expect_true(mystack.top() == 3); - - mystack.push(4); - mystack.emplace(); - mystack.pop(); - mystack.swap(mystack2); - - expect_false(mystack == mystack2); - expect_true(mystack != mystack2); - expect_false(mystack < mystack2); - expect_true(mystack > mystack2); - expect_false(mystack <= mystack2); - expect_true(mystack >= mystack2); - - std::swap(mystack, mystack2); -} - -void -exit_handler_intel_x64::unittest_1007_containers_queue() const -{ - auto myqueue = std::queue({0, 1, 2, 3}); - auto myqueue2 = std::queue({0, 1, 2, 3}); - - expect_true(myqueue.size() == 4); - expect_false(myqueue.empty()); - - expect_true(myqueue.front() == 0); - expect_true(myqueue.back() == 3); - - myqueue.push(4); - myqueue.emplace(); - myqueue.pop(); - myqueue.swap(myqueue2); - - expect_false(myqueue == myqueue2); - expect_true(myqueue != myqueue2); - expect_false(myqueue < myqueue2); - expect_true(myqueue > myqueue2); - expect_false(myqueue <= myqueue2); - expect_true(myqueue >= myqueue2); - - std::swap(myqueue, myqueue2); -} - -void -exit_handler_intel_x64::unittest_1008_containers_priority_queue() const -{ - int myints[] = {0, 1, 2, 3}; - - auto myqueue = std::priority_queue(myints, myints + 4); - auto myqueue2 = std::priority_queue(myints, myints + 4); - - expect_true(myqueue.size() == 4); - expect_false(myqueue.empty()); - - expect_true(myqueue.top() == 3); - - myqueue.push(4); - myqueue.emplace(); - myqueue.pop(); - myqueue.swap(myqueue2); - - std::swap(myqueue, myqueue2); -} - -void -exit_handler_intel_x64::unittest_1009_containers_set() const -{ - auto myset = std::set({0, 1, 2, 3}); - auto myset2 = std::set({0, 1, 2, 3}); - - myset = myset2; - - auto total = 0; - for (auto iter = myset.begin(); iter != myset.end(); iter++) - total += *iter; - - auto rtotal = 0; - for (auto iter = myset.rbegin(); iter != myset.rend(); iter++) - rtotal += *iter; - - auto ctotal = 0; - for (auto iter = myset.cbegin(); iter != myset.cend(); iter++) - ctotal += *iter; - - auto crtotal = 0; - for (auto iter = myset.crbegin(); iter != myset.crend(); iter++) - crtotal += *iter; - - expect_true(total == 6); - expect_true(rtotal == 6); - expect_true(ctotal == 6); - expect_true(crtotal == 6); - - expect_true(myset.size() == 4); - expect_true(myset.max_size() >= 4); - expect_false(myset.empty()); - - myset.insert(myset.begin(), 0); - myset.erase(myset.begin()); - myset.clear(); - myset.swap(myset2); - myset2.emplace(); - myset2.emplace_hint(myset.begin()); - - myset.key_comp(); - myset.value_comp(); - - expect_true(myset.find(0) != myset.end()); - expect_true(myset.count(0) == 1); - expect_true(myset.lower_bound(0) != myset.end()); - expect_true(myset.upper_bound(0) != myset.end()); - myset.equal_range(0); - - myset.get_allocator(); -} - -void -exit_handler_intel_x64::unittest_100A_containers_map() const -{ - auto mymap = std::map(); - auto mymap2 = std::map(); - - mymap2[0] = 0; - mymap2[1] = 1; - mymap2[2] = 2; - mymap2[3] = 3; - - mymap = mymap2; - - auto total = 0; - for (auto iter = mymap.begin(); iter != mymap.end(); iter++) - total += iter->second; - - auto rtotal = 0; - for (auto iter = mymap.rbegin(); iter != mymap.rend(); iter++) - rtotal += iter->second; - - auto ctotal = 0; - for (auto iter = mymap.cbegin(); iter != mymap.cend(); iter++) - ctotal += iter->second; - - auto crtotal = 0; - for (auto iter = mymap.crbegin(); iter != mymap.crend(); iter++) - crtotal += iter->second; - - expect_true(total == 6); - expect_true(rtotal == 6); - expect_true(ctotal == 6); - expect_true(crtotal == 6); - - expect_true(mymap.size() == 4); - expect_true(mymap.max_size() >= 4); - expect_false(mymap.empty()); - - expect_true(mymap.at(0) == 0); - expect_true(mymap.at(3) == 3); - - mymap.insert(std::pair(4, 4)); - mymap.erase(4); - mymap.clear(); - mymap.swap(mymap2); - mymap2.emplace(); - mymap2.emplace_hint(mymap.begin(), std::pair(4, 4)); - - mymap.key_comp(); - mymap.value_comp(); - - expect_true(mymap.find(0) != mymap.end()); - expect_true(mymap.count(0) == 1); - expect_true(mymap.lower_bound(0) != mymap.end()); - expect_true(mymap.upper_bound(0) != mymap.end()); - mymap.equal_range(0); - - mymap.get_allocator(); -} - #endif diff --git a/bfvmm/src/exit_handler/src/exit_handler_intel_x64_unittests_containers.cpp b/bfvmm/src/exit_handler/src/exit_handler_intel_x64_unittests_containers.cpp new file mode 100644 index 000000000..46349addd --- /dev/null +++ b/bfvmm/src/exit_handler/src/exit_handler_intel_x64_unittests_containers.cpp @@ -0,0 +1,580 @@ +// +// Bareflank Hypervisor +// +// Copyright (C) 2015 Assured Information Security, Inc. +// Author: Rian Quinn +// Author: Brendan Kerrigan +// +// 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 + +#include + +#ifdef INCLUDE_LIBCXX_UNITTESTS + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +void +exit_handler_intel_x64::unittest_1001_containers_array() const +{ + std::array myarray = {{0, 1, 2, 3}}; + std::array myarray2 = {{0, 1, 2, 3}}; + + auto total = 0; + for (auto iter = myarray.begin(); iter != myarray.end(); iter++) + total += *iter; + + auto rtotal = 0; + for (auto iter = myarray.rbegin(); iter != myarray.rend(); iter++) + rtotal += *iter; + + auto ctotal = 0; + for (auto iter = myarray.cbegin(); iter != myarray.cend(); iter++) + ctotal += *iter; + + auto crtotal = 0; + for (auto iter = myarray.crbegin(); iter != myarray.crend(); iter++) + crtotal += *iter; + + expect_true(total == 6); + expect_true(rtotal == 6); + expect_true(ctotal == 6); + expect_true(crtotal == 6); + + expect_true(myarray.size() == 4); + expect_true(myarray.max_size() == 4); + expect_false(myarray.empty()); + + expect_true(myarray.at(0) == 0); + expect_true(myarray.at(3) == 3); + expect_true(myarray.front() == 0); + expect_true(myarray.back() == 3); + expect_true(myarray.data() != nullptr); + + myarray.fill(0); + myarray.swap(myarray2); + + expect_true(std::get<0>(myarray) == 0); + expect_true(std::get<3>(myarray) == 3); + + expect_false(myarray == myarray2); + expect_true(myarray != myarray2); + expect_false(myarray < myarray2); + expect_true(myarray > myarray2); + expect_false(myarray <= myarray2); + expect_true(myarray >= myarray2); +} + +void +exit_handler_intel_x64::unittest_1002_containers_vector() const +{ + auto myvector = std::vector({0, 1, 2, 3}); + auto myvector2 = std::vector({0, 1, 2, 3}); + + auto total = 0; + for (auto iter = myvector.begin(); iter != myvector.end(); iter++) + total += *iter; + + auto rtotal = 0; + for (auto iter = myvector.rbegin(); iter != myvector.rend(); iter++) + rtotal += *iter; + + auto ctotal = 0; + for (auto iter = myvector.cbegin(); iter != myvector.cend(); iter++) + ctotal += *iter; + + auto crtotal = 0; + for (auto iter = myvector.crbegin(); iter != myvector.crend(); iter++) + crtotal += *iter; + + expect_true(total == 6); + expect_true(rtotal == 6); + expect_true(ctotal == 6); + expect_true(crtotal == 6); + + expect_true(myvector.size() == 4); + expect_true(myvector.max_size() >= 4); + myvector.resize(4); + expect_true(myvector.capacity() >= 4); + expect_false(myvector.empty()); + myvector.reserve(4); + myvector.shrink_to_fit(); + + expect_true(myvector.at(0) == 0); + expect_true(myvector.at(3) == 3); + expect_true(myvector.front() == 0); + expect_true(myvector.back() == 3); + expect_true(myvector.data() != nullptr); + + myvector.assign(4, 0); + myvector = myvector2; + + myvector.push_back(4); + myvector.pop_back(); + myvector = myvector2; + + myvector.insert(myvector.begin(), 0); + myvector.erase(myvector.begin()); + myvector = myvector2; + + myvector.swap(myvector2); + std::swap(myvector, myvector2); + + myvector.emplace(myvector.begin()); + myvector.emplace_back(); + myvector = myvector2; + + expect_true(myvector == myvector2); + expect_false(myvector != myvector2); + expect_false(myvector < myvector2); + expect_false(myvector > myvector2); + expect_true(myvector <= myvector2); + expect_true(myvector >= myvector2); + myvector = myvector2; + + myvector.get_allocator(); + myvector.clear(); +} + +void +exit_handler_intel_x64::unittest_1003_containers_deque() const +{ + std::deque mydeque = {{0, 1, 2, 3}}; + std::deque mydeque2 = {{0, 1, 2, 3}}; + + auto total = 0; + for (auto iter = mydeque.begin(); iter != mydeque.end(); iter++) + total += *iter; + + auto rtotal = 0; + for (auto iter = mydeque.rbegin(); iter != mydeque.rend(); iter++) + rtotal += *iter; + + auto ctotal = 0; + for (auto iter = mydeque.cbegin(); iter != mydeque.cend(); iter++) + ctotal += *iter; + + auto crtotal = 0; + for (auto iter = mydeque.crbegin(); iter != mydeque.crend(); iter++) + crtotal += *iter; + + expect_true(total == 6); + expect_true(rtotal == 6); + expect_true(ctotal == 6); + expect_true(crtotal == 6); + + expect_true(mydeque.size() == 4); + expect_true(mydeque.max_size() >= 4); + mydeque.resize(4); + expect_false(mydeque.empty()); + mydeque.shrink_to_fit(); + + expect_true(mydeque.at(0) == 0); + expect_true(mydeque.at(3) == 3); + expect_true(mydeque.front() == 0); + expect_true(mydeque.back() == 3); + + mydeque.assign(4, 0); + mydeque = mydeque2; + + mydeque.push_back(4); + mydeque.pop_back(); + mydeque = mydeque2; + + mydeque.push_front(4); + mydeque.pop_front(); + mydeque = mydeque2; + + mydeque.insert(mydeque.begin(), 0); + mydeque.erase(mydeque.begin()); + mydeque = mydeque2; + + mydeque.swap(mydeque2); + std::swap(mydeque, mydeque2); + + mydeque.emplace(mydeque.begin()); + mydeque.emplace_back(); + mydeque.emplace_front(); + mydeque = mydeque2; + + expect_true(mydeque == mydeque2); + expect_false(mydeque != mydeque2); + expect_false(mydeque < mydeque2); + expect_false(mydeque > mydeque2); + expect_true(mydeque <= mydeque2); + expect_true(mydeque >= mydeque2); + mydeque = mydeque2; + + mydeque.get_allocator(); + mydeque.clear(); +} + +void +exit_handler_intel_x64::unittest_1004_containers_forward_list() const +{ + std::forward_list mylist = {{0, 1, 2, 3}}; + std::forward_list mylist2 = {{0, 1, 2, 3}}; + + mylist.insert_after(mylist.before_begin(), 10); + mylist.erase_after(mylist.before_begin()); + mylist.insert_after(mylist.cbefore_begin(), 10); + mylist.erase_after(mylist.cbefore_begin()); + mylist = mylist2; + + auto total = 0; + for (auto iter = mylist.begin(); iter != mylist.end(); iter++) + total += *iter; + + auto ctotal = 0; + for (auto iter = mylist.cbegin(); iter != mylist.cend(); iter++) + ctotal += *iter; + + expect_true(total == 6); + expect_true(ctotal == 6); + + expect_true(mylist.max_size() >= 4); + expect_false(mylist.empty()); + mylist.resize(4); + + expect_true(mylist.front() == 0); + + mylist.assign(4, 0); + mylist = mylist2; + + mylist.push_front(4); + mylist.pop_front(); + mylist = mylist2; + + mylist.swap(mylist2); + std::swap(mylist, mylist2); + + mylist.emplace_front(); + mylist.emplace_after(mylist.begin()); + mylist = mylist2; + + expect_true(mylist == mylist2); + expect_false(mylist != mylist2); + expect_false(mylist < mylist2); + expect_false(mylist > mylist2); + expect_true(mylist <= mylist2); + expect_true(mylist >= mylist2); + mylist = mylist2; + + mylist.splice_after(mylist.before_begin(), mylist2); + mylist.remove(0); + mylist.unique(); + mylist.merge(mylist2, std::greater()); + mylist.sort(std::greater()); + mylist.reverse(); + mylist = mylist2; + + mylist.get_allocator(); + mylist.clear(); +} + +void +exit_handler_intel_x64::unittest_1005_containers_list() const +{ + std::list mylist = {{0, 1, 2, 3}}; + std::list mylist2 = {{0, 1, 2, 3}}; + + auto total = 0; + for (auto iter = mylist.begin(); iter != mylist.end(); iter++) + total += *iter; + + auto rtotal = 0; + for (auto iter = mylist.rbegin(); iter != mylist.rend(); iter++) + rtotal += *iter; + + auto ctotal = 0; + for (auto iter = mylist.cbegin(); iter != mylist.cend(); iter++) + ctotal += *iter; + + auto crtotal = 0; + for (auto iter = mylist.crbegin(); iter != mylist.crend(); iter++) + crtotal += *iter; + + expect_true(total == 6); + expect_true(rtotal == 6); + expect_true(ctotal == 6); + expect_true(crtotal == 6); + + expect_true(mylist.size() == 4); + expect_true(mylist.max_size() >= 4); + expect_false(mylist.empty()); + mylist.resize(4); + + expect_true(mylist.front() == 0); + expect_true(mylist.back() == 3); + + mylist.assign(4, 0); + mylist = mylist2; + + mylist.push_back(4); + mylist.pop_back(); + mylist = mylist2; + + mylist.push_front(4); + mylist.pop_front(); + mylist = mylist2; + + mylist.insert(mylist.begin(), 0); + mylist.erase(mylist.begin()); + mylist = mylist2; + + mylist.swap(mylist2); + std::swap(mylist, mylist2); + + mylist.emplace(mylist.begin()); + mylist.emplace_back(); + mylist.emplace_front(); + mylist = mylist2; + + expect_true(mylist == mylist2); + expect_false(mylist != mylist2); + expect_false(mylist < mylist2); + expect_false(mylist > mylist2); + expect_true(mylist <= mylist2); + expect_true(mylist >= mylist2); + mylist = mylist2; + + mylist.splice(mylist.begin(), mylist2); + mylist.remove(0); + mylist.unique(); + mylist.merge(mylist2, std::greater()); + mylist.sort(std::greater()); + mylist.reverse(); + mylist = mylist2; + + mylist.get_allocator(); + mylist.clear(); +} + +void +exit_handler_intel_x64::unittest_1006_containers_stack() const +{ + std::stack mystack{{0, 1, 2, 3}}; + std::stack mystack2{{0, 1, 2, 3}}; + + expect_true(mystack.size() == 4); + expect_false(mystack.empty()); + + expect_true(mystack.top() == 3); + + mystack.push(4); + mystack.pop(); + + mystack.emplace(); + mystack.pop(); + + mystack.swap(mystack2); + std::swap(mystack, mystack2); + + expect_true(mystack == mystack2); + expect_false(mystack != mystack2); + expect_false(mystack < mystack2); + expect_false(mystack > mystack2); + expect_true(mystack <= mystack2); + expect_true(mystack >= mystack2); +} + +void +exit_handler_intel_x64::unittest_1007_containers_queue() const +{ + std::queue myqueue{{0, 1, 2, 3}}; + std::queue myqueue2{{0, 1, 2, 3}}; + + expect_true(myqueue.size() == 4); + expect_false(myqueue.empty()); + + expect_true(myqueue.front() == 0); + expect_true(myqueue.back() == 3); + + myqueue.emplace(); + myqueue.push(1); + myqueue.push(2); + myqueue.push(3); + + myqueue.pop(); + myqueue.pop(); + myqueue.pop(); + myqueue.pop(); + + myqueue.swap(myqueue2); + std::swap(myqueue, myqueue2); + + expect_true(myqueue == myqueue2); + expect_false(myqueue != myqueue2); + expect_false(myqueue < myqueue2); + expect_false(myqueue > myqueue2); + expect_true(myqueue <= myqueue2); + expect_true(myqueue >= myqueue2); +} + +void +exit_handler_intel_x64::unittest_1008_containers_priority_queue() const +{ + int myints[] = {0, 1, 2, 3}; + + auto myqueue = std::priority_queue(myints, myints + 4); + auto myqueue2 = std::priority_queue(myints, myints + 4); + + expect_true(myqueue.size() == 4); + expect_false(myqueue.empty()); + + expect_true(myqueue.top() == 3); + + myqueue.emplace(); + myqueue.push(1); + myqueue.push(2); + myqueue.push(3); + + myqueue.pop(); + myqueue.pop(); + myqueue.pop(); + myqueue.pop(); + + myqueue.swap(myqueue2); + std::swap(myqueue, myqueue2); +} + +void +exit_handler_intel_x64::unittest_1009_containers_set() const +{ + auto myset = std::set({0, 1, 2, 3}); + auto myset2 = std::set({0, 1, 2, 3}); + + auto total = 0; + for (auto iter = myset.begin(); iter != myset.end(); iter++) + total += *iter; + + auto rtotal = 0; + for (auto iter = myset.rbegin(); iter != myset.rend(); iter++) + rtotal += *iter; + + auto ctotal = 0; + for (auto iter = myset.cbegin(); iter != myset.cend(); iter++) + ctotal += *iter; + + auto crtotal = 0; + for (auto iter = myset.crbegin(); iter != myset.crend(); iter++) + crtotal += *iter; + + expect_true(total == 6); + expect_true(rtotal == 6); + expect_true(ctotal == 6); + expect_true(crtotal == 6); + + expect_true(myset.size() == 4); + expect_true(myset.max_size() >= 4); + expect_false(myset.empty()); + + myset.insert(myset.begin(), 0); + myset.erase(myset.begin()); + myset = myset2; + + myset.swap(myset2); + myset.swap(myset2); + + myset.emplace(); + myset.emplace_hint(myset.begin()); + myset = myset2; + + myset.key_comp(); + myset.value_comp(); + + expect_true(myset.find(0) != myset.end()); + expect_true(myset.count(0) == 1); + expect_true(myset.lower_bound(0) != myset.end()); + expect_true(myset.upper_bound(0) != myset.end()); + myset.equal_range(0); + + myset.get_allocator(); + myset.clear(); +} + +void +exit_handler_intel_x64::unittest_100A_containers_map() const +{ + auto mymap = std::map(); + auto mymap2 = std::map(); + + mymap2[0] = 0; + mymap2[1] = 1; + mymap2[2] = 2; + mymap2[3] = 3; + + mymap = mymap2; + + auto total = 0; + for (auto iter = mymap.begin(); iter != mymap.end(); iter++) + total += iter->second; + + auto rtotal = 0; + for (auto iter = mymap.rbegin(); iter != mymap.rend(); iter++) + rtotal += iter->second; + + auto ctotal = 0; + for (auto iter = mymap.cbegin(); iter != mymap.cend(); iter++) + ctotal += iter->second; + + auto crtotal = 0; + for (auto iter = mymap.crbegin(); iter != mymap.crend(); iter++) + crtotal += iter->second; + + expect_true(total == 6); + expect_true(rtotal == 6); + expect_true(ctotal == 6); + expect_true(crtotal == 6); + + expect_true(mymap.size() == 4); + expect_true(mymap.max_size() >= 4); + expect_false(mymap.empty()); + + expect_true(mymap.at(0) == 0); + expect_true(mymap.at(3) == 3); + + mymap.insert(std::pair(4, 4)); + mymap.erase(4); + mymap = mymap2; + + mymap.swap(mymap2); + mymap.swap(mymap2); + + mymap.emplace(); + mymap.emplace_hint(mymap.begin(), std::pair(4, 4)); + mymap = mymap2; + + mymap.key_comp(); + mymap.value_comp(); + + expect_true(mymap.find(0) != mymap.end()); + expect_true(mymap.count(0) == 1); + expect_true(mymap.lower_bound(0) != mymap.end()); + expect_true(mymap.upper_bound(0) != mymap.end()); + mymap.equal_range(0); + + mymap.get_allocator(); + mymap.clear(); +} + +#endif diff --git a/bfvmm/src/exit_handler/src/exit_handler_intel_x64_unittests_io.cpp b/bfvmm/src/exit_handler/src/exit_handler_intel_x64_unittests_io.cpp new file mode 100644 index 000000000..83ec34757 --- /dev/null +++ b/bfvmm/src/exit_handler/src/exit_handler_intel_x64_unittests_io.cpp @@ -0,0 +1,88 @@ +// +// Bareflank Hypervisor +// +// Copyright (C) 2015 Assured Information Security, Inc. +// Author: Rian Quinn +// Author: Brendan Kerrigan +// +// 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 + +#include + +#ifdef INCLUDE_LIBCXX_UNITTESTS + +#include +#include + +void +exit_handler_intel_x64::unittest_1100_io_cout() const +{ + std::cout << "hello world" << std::endl; + std::cout << 10 << std::endl; + std::cout << 10U << std::endl; + std::cout << 10L << std::endl; + std::cout << 10UL << std::endl; + std::cout << view_as_pointer(10UL) << std::endl; +} + +void +exit_handler_intel_x64::unittest_1101_io_manipulators() const +{ + std::cout << std::boolalpha << true << '\n'; + std::cout << std::boolalpha << false << '\n'; + std::cout << std::noboolalpha << true << '\n'; + std::cout << std::noboolalpha << false << '\n'; + + std::cout << std::noshowbase << 3.14 << '\n'; + std::cout << std::noshowpoint << 3.14 << '\n'; + std::cout << std::noshowpos << 3.14 << '\n'; + std::cout << std::noskipws << 3.14 << '\n'; + std::cout << std::nounitbuf << 3.14 << '\n'; + std::cout << std::nouppercase << 3.14 << '\n'; + + std::cout << std::showbase << 3.14 << '\n'; + std::cout << std::showpoint << 3.14 << '\n'; + std::cout << std::showpos << 3.14 << '\n'; + std::cout << std::skipws << 3.14 << '\n'; + std::cout << std::unitbuf << 3.14 << '\n'; + std::cout << std::uppercase << 3.14 << '\n'; + + std::cout << std::hex << 1 << '\n'; + std::cout << std::hex << 11 << '\n'; + std::cout << std::oct << 1 << '\n'; + std::cout << std::oct << 11 << '\n'; + std::cout << std::dec << 1 << '\n'; + std::cout << std::dec << 11 << '\n'; + std::cout << std::setbase(10) << 1 << '\n'; + std::cout << std::setbase(10) << 11 << '\n'; + + std::cout << std::scientific << 3.14 << '\n'; + std::cout << std::setprecision(2) << 3.14 << '\n'; + + std::cout << std::fixed << 3.14 << '\n'; + std::cout << std::fixed << 3.14 << '\n'; + + std::cout << std::internal << 42 << '\n'; + std::cout << std::left << 42 << '\n'; + std::cout << std::right << 42 << '\n'; + + std::cout << std::setfill('0') << std::setw(10) << 10 << std::endl; + + std::cout << std::endl; + std::cout << std::ends; + std::cout << std::flush; +} + +#endif diff --git a/bfvmm/src/exit_handler/test/Makefile.bf b/bfvmm/src/exit_handler/test/Makefile.bf index c393cdcac..88a417097 100644 --- a/bfvmm/src/exit_handler/test/Makefile.bf +++ b/bfvmm/src/exit_handler/test/Makefile.bf @@ -27,6 +27,11 @@ TARGET_NAME:=test TARGET_TYPE:=bin TARGET_COMPILER:=native +ifeq ($(INCLUDE_LIBCXX_UNITTESTS), yes) + CROSS_DEFINES+=INCLUDE_LIBCXX_UNITTESTS + NATIVE_DEFINES+=INCLUDE_LIBCXX_UNITTESTS +endif + ################################################################################ # Compiler Flags ################################################################################ diff --git a/bfvmm/src/exit_handler/test/test_exit_handler_intel_x64.cpp b/bfvmm/src/exit_handler/test/test_exit_handler_intel_x64.cpp index 647056b99..28fbea761 100644 --- a/bfvmm/src/exit_handler/test/test_exit_handler_intel_x64.cpp +++ b/bfvmm/src/exit_handler/test/test_exit_handler_intel_x64.cpp @@ -370,12 +370,21 @@ exit_handler_intel_x64_ut::test_vm_exit_reason_vmcall_unittest() ehlr.m_state_save->rax = VMCALL_UNITTEST; ehlr.m_state_save->rdx = VMCALL_MAGIC_NUMBER; +#ifdef INCLUDE_LIBCXX_UNITTESTS + RUN_UNITTEST_WITH_MOCKS(mocks, [&] + { + this->expect_no_exception([&]{ ehlr.dispatch(); }); + this->expect_true(ehlr.m_state_save->rip == g_rip); + this->expect_true(ec_sign(ehlr.m_state_save->rdx) == BF_VMCALL_FAILURE); + }); +#else RUN_UNITTEST_WITH_MOCKS(mocks, [&] { this->expect_no_exception([&]{ ehlr.dispatch(); }); this->expect_true(ehlr.m_state_save->rip == g_rip); this->expect_true(ec_sign(ehlr.m_state_save->rdx) == BF_VMCALL_SUCCESS); }); +#endif } void diff --git a/bfvmm/src/memory_manager/src/memory_manager_x64.cpp b/bfvmm/src/memory_manager/src/memory_manager_x64.cpp index c0c33d549..6d38eb905 100644 --- a/bfvmm/src/memory_manager/src/memory_manager_x64.cpp +++ b/bfvmm/src/memory_manager/src/memory_manager_x64.cpp @@ -266,9 +266,6 @@ memory_manager_x64::descriptors() const memory_descriptor_list list; std::lock_guard guard(g_add_md_mutex); - expects(m_phys_to_virt_map.size() == m_virt_to_phys_map.size()); - expects(m_virt_to_attr_map.size() == m_virt_to_phys_map.size()); - for (const auto &p : m_virt_to_phys_map) { auto virt = p.first; diff --git a/tools/tests/test_hypervisor.sh b/tools/tests/test_hypervisor.sh index f5c2bdf71..20bd879e4 100755 --- a/tools/tests/test_hypervisor.sh +++ b/tools/tests/test_hypervisor.sh @@ -29,6 +29,8 @@ CC='\033[1;36m' CG='\033[1;32m' CE='\033[0m' +export INCLUDE_LIBCXX_UNITTESTS=yes + # ------------------------------------------------------------------------------ # Tests # ------------------------------------------------------------------------------ @@ -105,6 +107,9 @@ vmcall_unittest() { ARGS="unittest 0x1008" make vmcall ARGS="unittest 0x1009" make vmcall ARGS="unittest 0x100A" make vmcall + ARGS="unittest 0x1100" make vmcall + ARGS="unittest 0x1101" make vmcall + echo -e "" make driver_unload > /dev/null 2>&1 } @@ -137,13 +142,13 @@ vmcall_data_unformatted() { echo -e "$CC""testing:$CB vmcall_data_unformatted$CE" make driver_load > /dev/null 2>&1 make quick - sudo rm -Rf /tmp/test_indata.txt - sudo rm -Rf /tmp/test_outdata.txt + rm -Rf /tmp/test_indata.txt + rm -Rf /tmp/test_outdata.txt echo "hello world" > /tmp/test_indata.txt ARGS="data unformatted /tmp/test_indata.txt /tmp/test_outdata.txt" make vmcall if cmp -s "/tmp/test_indata.txt" "/tmp/test_outdata.txt"; then - sudo rm -Rf /tmp/test_indata.txt - sudo rm -Rf /tmp/test_outdata.txt + rm -Rf /tmp/test_indata.txt + rm -Rf /tmp/test_outdata.txt else echo "ERROR: binary files do not match" exit 1