From 3a226cdc653dcf298bba193d88f94d2dec80f337 Mon Sep 17 00:00:00 2001 From: Pierric Gimmig Date: Tue, 31 Dec 2024 07:54:31 -0800 Subject: [PATCH 1/8] Update libprotobuf-mutator --- .../libprotobuf-mutator/CMakeLists.txt | 4 +- third_party/libprotobuf-mutator/README.md | 34 ++++-- .../cmake/external/expat.cmake | 11 +- .../cmake/external/googletest.cmake | 4 +- .../cmake/external/libxml2.cmake | 2 + .../cmake/external/protobuf.cmake | 105 +++++++++++++++++- .../examples/expat/expat_example.cc | 7 +- .../libfuzzer/libfuzzer_bin_example.cc | 4 +- .../examples/libfuzzer/libfuzzer_example.cc | 4 +- .../examples/libxml2/libxml2_example.cc | 3 +- .../libprotobuf-mutator/port/protobuf.h | 39 ++++++- .../libprotobuf-mutator/src/CMakeLists.txt | 3 +- .../libprotobuf-mutator/src/binary_format.cc | 4 +- .../libprotobuf-mutator/src/field_instance.h | 14 +-- .../src/libfuzzer/CMakeLists.txt | 3 +- .../src/libfuzzer/libfuzzer_macro.h | 2 +- .../src/libfuzzer/libfuzzer_mutator.cc | 17 +++ .../libprotobuf-mutator/src/mutator.cc | 12 +- .../libprotobuf-mutator/src/mutator_test.cc | 7 +- .../libprotobuf-mutator/src/text_format.cc | 4 +- .../libprotobuf-mutator/src/utf8_fix_test.cc | 2 - 21 files changed, 224 insertions(+), 61 deletions(-) diff --git a/third_party/libprotobuf-mutator/CMakeLists.txt b/third_party/libprotobuf-mutator/CMakeLists.txt index a8fe9e6c72d..c7d1fd9d582 100644 --- a/third_party/libprotobuf-mutator/CMakeLists.txt +++ b/third_party/libprotobuf-mutator/CMakeLists.txt @@ -12,7 +12,7 @@ # See the License for the specific language governing permissions and # limitations under the License. -cmake_minimum_required(VERSION 3.5) +cmake_minimum_required(VERSION 3.24) project(LibProtobufMutator CXX) enable_language(C) @@ -42,8 +42,6 @@ include_directories(${LIBLZMA_INCLUDE_DIRS}) find_package(ZLIB) include_directories(${ZLIB_INCLUDE_DIRS}) -set(CMAKE_CXX_STANDARD 11) - include_directories(${PROJECT_SOURCE_DIR}) if (MSVC) diff --git a/third_party/libprotobuf-mutator/README.md b/third_party/libprotobuf-mutator/README.md index ef780604fbb..29b00b4b108 100644 --- a/third_party/libprotobuf-mutator/README.md +++ b/third_party/libprotobuf-mutator/README.md @@ -1,6 +1,6 @@ # libprotobuf-mutator -[![TravisCI Build Status](https://travis-ci.org/google/libprotobuf-mutator.svg?branch=master)](https://travis-ci.org/google/libprotobuf-mutator) +[![Build Status](https://github.com/google/libprotobuf-mutator/actions/workflows/cmake-multi-platform.yml/badge.svg?event=push)](https://github.com/google/libprotobuf-mutator/actions/workflows/cmake-multi-platform.yml?query=event%3Apush) [![Fuzzing Status](https://oss-fuzz-build-logs.storage.googleapis.com/badges/libprotobuf-mutator.svg)](https://oss-fuzz-build-logs.storage.googleapis.com/index.html#libprotobuf-mutator) ## Overview @@ -12,7 +12,7 @@ It could be used together with guided fuzzing engines, such as [libFuzzer](http: Install prerequisites: -``` +```sh sudo apt-get update sudo apt-get install protobuf-compiler libprotobuf-dev binutils cmake \ ninja-build liblzma-dev libz-dev pkg-config autoconf libtool @@ -20,7 +20,7 @@ sudo apt-get install protobuf-compiler libprotobuf-dev binutils cmake \ Compile and test everything: -``` +```sh mkdir build cd build cmake .. -GNinja -DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++ -DCMAKE_BUILD_TYPE=Debug @@ -36,7 +36,7 @@ build a working version of protobuf. Installation: -``` +```sh ninja sudo ninja install ``` @@ -59,7 +59,7 @@ using [libFuzzer](http://libfuzzer.info)'s mutators. To apply one mutation to a protobuf object do the following: -``` +```c++ class MyProtobufMutator : public protobuf_mutator::Mutator { public: // Optionally redefine the Mutate* methods to perform more sophisticated mutations. @@ -77,7 +77,7 @@ See also the `ProtobufMutatorMessagesTest.UsageExample` test from ## Integrating with libFuzzer LibFuzzerProtobufMutator can help to integrate with libFuzzer. For example -``` +```c++ #include "src/libfuzzer/libfuzzer_macro.h" DEFINE_PROTO_FUZZER(const MyMessageType& input) { @@ -97,7 +97,7 @@ for fuzzer even if it's capable of inserting acceptable values with time. PostProcessorRegistration can be used to avoid such issue and guide your fuzzer towards interesting code. It registers callback which will be called for each message of particular type after each mutation. -``` +```c++ static protobuf_mutator::libfuzzer::PostProcessorRegistration reg = { [](MyMessageType* message, unsigned int seed) { TweakMyMessage(message, seed); @@ -117,7 +117,7 @@ may corrupt the reproducer so it stops triggering the bug. Note: You can add callback for any nested message and you can add multiple callbacks for the same message type. -``` +```c++ static PostProcessorRegistration reg1 = { [](MyMessageType* message, unsigned int seed) { TweakMyMessage(message, seed); @@ -155,6 +155,24 @@ cleanup/initialize the message as workaround. * [Envoy](https://github.com/envoyproxy/envoy/search?q=DEFINE_TEXT_PROTO_FUZZER+OR+DEFINE_PROTO_FUZZER+OR+DEFINE_BINARY_PROTO_FUZZER&unscoped_q=DEFINE_TEXT_PROTO_FUZZER+OR+DEFINE_PROTO_FUZZER+OR+DEFINE_BINARY_PROTO_FUZZER&type=Code) * [LLVM](https://github.com/llvm-mirror/clang/search?q=DEFINE_TEXT_PROTO_FUZZER+OR+DEFINE_PROTO_FUZZER+OR+DEFINE_BINARY_PROTO_FUZZER&unscoped_q=DEFINE_TEXT_PROTO_FUZZER+OR+DEFINE_PROTO_FUZZER+OR+DEFINE_BINARY_PROTO_FUZZER&type=Code) +## Grammars +* GIF, https://github.com/google/oss-fuzz/tree/master/projects/giflib +* JSON + * https://github.com/google/oss-fuzz/tree/master/projects/jsoncpp + * https://github.com/officialcjunior/fuzzrtos/tree/c72e6670e566672ccf8023265cbfad616e75790d/protobufv2 +* Lua 5.1 Language, + * https://github.com/ligurio/lua-c-api-tests/tree/master/tests/luaL_loadbuffer_proto + * https://github.com/Spoookyyy/luaj/tree/main/fuzz +* PNG, https://github.com/google/oss-fuzz/tree/master/projects/libpng-proto +* SQL + * https://github.com/tarantool/tarantool/tree/master/test/fuzz/sql_fuzzer + * https://chromium.googlesource.com/chromium/src/third_party/+/refs/heads/main/sqlite/fuzz +* Solidity Language, https://github.com/ethereum/solidity/tree/develop/test/tools/ossfuzz +* XML + * https://github.com/google/oss-fuzz/tree/master/projects/xerces-c + * https://github.com/google/libprotobuf-mutator/tree/master/examples/xml +* JPEG, https://source.chromium.org/chromium/chromium/src/+/main:media/gpu/vaapi/fuzzers/jpeg_decoder/ + ## Bugs found with help of the library ### Chromium diff --git a/third_party/libprotobuf-mutator/cmake/external/expat.cmake b/third_party/libprotobuf-mutator/cmake/external/expat.cmake index 6bb1769e571..c3059ee3ba5 100644 --- a/third_party/libprotobuf-mutator/cmake/external/expat.cmake +++ b/third_party/libprotobuf-mutator/cmake/external/expat.cmake @@ -30,6 +30,13 @@ foreach(lib IN LISTS EXPAT_LIBRARIES) add_dependencies(${lib} ${EXPAT_TARGET}) endforeach(lib) +set(EXPAT_C_COMPILER "${CMAKE_C_COMPILER}") +set(EXPAT_CXX_COMPILER "${CMAKE_CXX_COMPILER}") +if(DEFINED CMAKE_C_COMPILER_LAUNCHER AND DEFINED CMAKE_CXX_COMPILER_LAUNCHER) + set(EXPAT_C_COMPILER "${CMAKE_C_COMPILER_LAUNCHER} ${EXPAT_C_COMPILER}") + set(EXPAT_CXX_COMPILER "${CMAKE_CXX_COMPILER_LAUNCHER} ${EXPAT_CXX_COMPILER}") +endif() + include (ExternalProject) ExternalProject_Add(${EXPAT_TARGET} PREFIX ${EXPAT_TARGET} @@ -39,8 +46,8 @@ ExternalProject_Add(${EXPAT_TARGET} CONFIGURE_COMMAND cd ${EXPAT_SRC_DIR} && ./buildconf.sh && ./configure --prefix=${EXPAT_INSTALL_DIR} --without-xmlwf - CC=${CMAKE_C_COMPILER} - CXX=${CMAKE_CXX_COMPILER} + "CC=${EXPAT_C_COMPILER}" + "CXX=${EXPAT_CXX_COMPILER}" "CFLAGS=${EXPAT_CFLAGS} -w -DXML_POOR_ENTROPY" "CXXFLAGS=${EXPAT_CXXFLAGS} -w -DXML_POOR_ENTROPY" BUILD_COMMAND cd ${EXPAT_SRC_DIR} && make -j ${CPU_COUNT} diff --git a/third_party/libprotobuf-mutator/cmake/external/googletest.cmake b/third_party/libprotobuf-mutator/cmake/external/googletest.cmake index ad0fe4ab3fc..11d0fdf2579 100644 --- a/third_party/libprotobuf-mutator/cmake/external/googletest.cmake +++ b/third_party/libprotobuf-mutator/cmake/external/googletest.cmake @@ -44,10 +44,12 @@ include (ExternalProject) ExternalProject_Add(${GTEST_TARGET} PREFIX ${GTEST_TARGET} GIT_REPOSITORY https://github.com/google/googletest.git - GIT_TAG release-1.12.0 + GIT_TAG v1.14.0 UPDATE_COMMAND "" CMAKE_CACHE_ARGS -DCMAKE_C_COMPILER:FILEPATH=${CMAKE_C_COMPILER} -DCMAKE_CXX_COMPILER:FILEPATH=${CMAKE_CXX_COMPILER} + -DCMAKE_C_COMPILER_LAUNCHER:FILEPATH=${CMAKE_C_COMPILER_LAUNCHER} + -DCMAKE_CXX_COMPILER_LAUNCHER:FILEPATH=${CMAKE_CXX_COMPILER_LAUNCHER} CMAKE_ARGS ${CMAKE_ARGS} -DCMAKE_INSTALL_PREFIX=${GTEST_INSTALL_DIR} -DCMAKE_INSTALL_LIBDIR=lib diff --git a/third_party/libprotobuf-mutator/cmake/external/libxml2.cmake b/third_party/libprotobuf-mutator/cmake/external/libxml2.cmake index 8918ee00a9d..566ed04c98b 100644 --- a/third_party/libprotobuf-mutator/cmake/external/libxml2.cmake +++ b/third_party/libprotobuf-mutator/cmake/external/libxml2.cmake @@ -38,6 +38,8 @@ ExternalProject_Add(${LIBXML2_TARGET} UPDATE_COMMAND "" CMAKE_CACHE_ARGS -DCMAKE_C_COMPILER:FILEPATH=${CMAKE_C_COMPILER} -DCMAKE_CXX_COMPILER:FILEPATH=${CMAKE_CXX_COMPILER} + -DCMAKE_C_COMPILER_LAUNCHER:FILEPATH=${CMAKE_C_COMPILER_LAUNCHER} + -DCMAKE_CXX_COMPILER_LAUNCHER:FILEPATH=${CMAKE_CXX_COMPILER_LAUNCHER} CMAKE_ARGS -DCMAKE_C_FLAGS=${LIBXML2_CFLAGS} -DCMAKE_CXX_FLAGS=${LIBXML2_CXXFLAGS} -DCMAKE_INSTALL_PREFIX=${LIBXML2_INSTALL_DIR} -DCMAKE_INSTALL_LIBDIR=lib diff --git a/third_party/libprotobuf-mutator/cmake/external/protobuf.cmake b/third_party/libprotobuf-mutator/cmake/external/protobuf.cmake index 3dc930ced99..7a74b9e1530 100644 --- a/third_party/libprotobuf-mutator/cmake/external/protobuf.cmake +++ b/third_party/libprotobuf-mutator/cmake/external/protobuf.cmake @@ -29,6 +29,95 @@ ELSE() set(PROTOBUF_LIBRARIES protobuf) ENDIF() +# TODO: find a better way to link absl. +list(APPEND PROTOBUF_LIBRARIES + absl_bad_any_cast_impl + absl_bad_optional_access + absl_bad_variant_access + absl_base + absl_city + absl_civil_time + absl_cord + absl_cord_internal + absl_cordz_functions + absl_cordz_handle + absl_cordz_info + absl_cordz_sample_token + absl_crc_cord_state + absl_crc_cpu_detect + absl_crc_internal + absl_crc32c + absl_debugging_internal + absl_demangle_internal + absl_die_if_null + absl_examine_stack + absl_exponential_biased + absl_failure_signal_handler + absl_flags_commandlineflag + absl_flags_commandlineflag_internal + absl_flags_config + absl_flags_internal + absl_flags_marshalling + absl_flags_parse + absl_flags_private_handle_accessor + absl_flags_program_name + absl_flags_reflection + absl_flags_usage + absl_flags_usage_internal + absl_graphcycles_internal + absl_hash + absl_hashtablez_sampler + absl_int128 + absl_kernel_timeout_internal + absl_leak_check + absl_log_entry + absl_log_flags + absl_log_globals + absl_log_initialize + absl_log_internal_check_op + absl_log_internal_conditions + absl_log_internal_format + absl_log_internal_globals + absl_log_internal_log_sink_set + absl_log_internal_message + absl_log_internal_nullguard + absl_log_internal_proto + absl_log_severity + absl_log_sink + absl_low_level_hash + absl_malloc_internal + absl_periodic_sampler + absl_random_distributions + absl_random_internal_distribution_test_util + absl_random_internal_platform + absl_random_internal_pool_urbg + absl_random_internal_randen + absl_random_internal_randen_hwaes + absl_random_internal_randen_hwaes_impl + absl_random_internal_randen_slow + absl_random_internal_seed_material + absl_random_seed_gen_exception + absl_random_seed_sequences + absl_raw_hash_set + absl_raw_logging_internal + absl_scoped_set_env + absl_spinlock_wait + absl_stacktrace + absl_status + absl_statusor + absl_str_format_internal + absl_strerror + absl_string_view + absl_strings + absl_strings_internal + absl_symbolize + absl_synchronization + absl_throw_delegate + absl_time + absl_time_zone + utf8_validity +) + foreach(lib ${PROTOBUF_LIBRARIES}) if (MSVC) set(LIB_PATH ${PROTOBUF_INSTALL_DIR}/lib/lib${lib}.lib) @@ -63,9 +152,9 @@ include (ExternalProject) ExternalProject_Add(${PROTOBUF_TARGET} PREFIX ${PROTOBUF_TARGET} GIT_REPOSITORY https://github.com/google/protobuf.git - GIT_TAG v21.7 + GIT_TAG v27.1 UPDATE_COMMAND "" - CONFIGURE_COMMAND ${CMAKE_COMMAND} ${PROTOBUF_INSTALL_DIR}/src/${PROTOBUF_TARGET}/cmake + CONFIGURE_COMMAND ${CMAKE_COMMAND} ${PROTOBUF_INSTALL_DIR}/src/${PROTOBUF_TARGET} -G${CMAKE_GENERATOR} -DCMAKE_INSTALL_PREFIX=${PROTOBUF_INSTALL_DIR} -DCMAKE_INSTALL_LIBDIR=lib @@ -73,13 +162,23 @@ ExternalProject_Add(${PROTOBUF_TARGET} -DCMAKE_POSITION_INDEPENDENT_CODE=ON -DCMAKE_C_COMPILER:FILEPATH=${CMAKE_C_COMPILER} -DCMAKE_CXX_COMPILER:FILEPATH=${CMAKE_CXX_COMPILER} + -DCMAKE_C_COMPILER_LAUNCHER:FILEPATH=${CMAKE_C_COMPILER_LAUNCHER} + -DCMAKE_CXX_COMPILER_LAUNCHER:FILEPATH=${CMAKE_CXX_COMPILER_LAUNCHER} -DCMAKE_C_FLAGS=${PROTOBUF_CFLAGS} -DCMAKE_CXX_FLAGS=${PROTOBUF_CXXFLAGS} + -DCMAKE_CXX_STANDARD=14 -Dprotobuf_BUILD_TESTS=OFF BUILD_BYPRODUCTS ${PROTOBUF_BUILD_BYPRODUCTS} ) +# Allow to use alphabetically ordered absl lib list. +set(CMAKE_LINK_GROUP_USING_cross_refs_SUPPORTED TRUE) +set(CMAKE_LINK_GROUP_USING_cross_refs + "LINKER:--start-group" + "LINKER:--end-group" +) + # cmake 3.7 uses Protobuf_ when 3.5 PROTOBUF_ prefixes. set(Protobuf_INCLUDE_DIRS ${PROTOBUF_INCLUDE_DIRS}) -set(Protobuf_LIBRARIES ${PROTOBUF_LIBRARIES}) +set(Protobuf_LIBRARIES "$") set(Protobuf_PROTOC_EXECUTABLE ${PROTOBUF_PROTOC_EXECUTABLE}) diff --git a/third_party/libprotobuf-mutator/examples/expat/expat_example.cc b/third_party/libprotobuf-mutator/examples/expat/expat_example.cc index 97911f3438c..9cfe8f26480 100644 --- a/third_party/libprotobuf-mutator/examples/expat/expat_example.cc +++ b/third_party/libprotobuf-mutator/examples/expat/expat_example.cc @@ -21,10 +21,9 @@ #include "src/libfuzzer/libfuzzer_macro.h" namespace { -protobuf_mutator::protobuf::LogSilencer log_silincer; -std::vector kEncodings = {{"UTF-16", "UTF-8", "ISO-8859-1", - "US-ASCII", "UTF-16BE", "UTF-16LE", - "INVALIDENCODING"}}; +const std::vector kEncodings = {{"UTF-16", "UTF-8", "ISO-8859-1", + "US-ASCII", "UTF-16BE", + "UTF-16LE", "INVALIDENCODING"}}; } DEFINE_PROTO_FUZZER(const protobuf_mutator::xml::Input& message) { diff --git a/third_party/libprotobuf-mutator/examples/libfuzzer/libfuzzer_bin_example.cc b/third_party/libprotobuf-mutator/examples/libfuzzer/libfuzzer_bin_example.cc index 246f279955f..0734caa476b 100644 --- a/third_party/libprotobuf-mutator/examples/libfuzzer/libfuzzer_bin_example.cc +++ b/third_party/libprotobuf-mutator/examples/libfuzzer/libfuzzer_bin_example.cc @@ -19,8 +19,6 @@ #include "port/protobuf.h" #include "src/libfuzzer/libfuzzer_macro.h" -protobuf_mutator::protobuf::LogSilencer log_silincer; - template using PostProcessor = protobuf_mutator::libfuzzer::PostProcessorRegistration; @@ -57,7 +55,7 @@ DEFINE_BINARY_PROTO_FUZZER(const libfuzzer_example::Msg& message) { !std::isnan(message.optional_float()) && std::fabs(message.optional_float()) > 1000 && message.any().UnpackTo(&file) && !file.name().empty()) { - std::cerr << message.DebugString() << "\n"; + std::cerr << absl::StrCat(message) << "\n"; abort(); } } diff --git a/third_party/libprotobuf-mutator/examples/libfuzzer/libfuzzer_example.cc b/third_party/libprotobuf-mutator/examples/libfuzzer/libfuzzer_example.cc index a852e9876cb..37c4e6b861b 100644 --- a/third_party/libprotobuf-mutator/examples/libfuzzer/libfuzzer_example.cc +++ b/third_party/libprotobuf-mutator/examples/libfuzzer/libfuzzer_example.cc @@ -19,8 +19,6 @@ #include "port/protobuf.h" #include "src/libfuzzer/libfuzzer_macro.h" -protobuf_mutator::protobuf::LogSilencer log_silincer; - template using PostProcessor = protobuf_mutator::libfuzzer::PostProcessorRegistration; @@ -57,7 +55,7 @@ DEFINE_PROTO_FUZZER(const libfuzzer_example::Msg& message) { !std::isnan(message.optional_float()) && std::fabs(message.optional_float()) > 1000 && message.any().UnpackTo(&file) && !file.name().empty()) { - std::cerr << message.DebugString() << "\n"; + std::cerr << absl::StrCat(message) << "\n"; abort(); } } diff --git a/third_party/libprotobuf-mutator/examples/libxml2/libxml2_example.cc b/third_party/libprotobuf-mutator/examples/libxml2/libxml2_example.cc index 9cbd44231ad..bcdcc6c560f 100644 --- a/third_party/libprotobuf-mutator/examples/libxml2/libxml2_example.cc +++ b/third_party/libprotobuf-mutator/examples/libxml2/libxml2_example.cc @@ -20,14 +20,13 @@ #include "src/libfuzzer/libfuzzer_macro.h" namespace { -protobuf_mutator::protobuf::LogSilencer log_silincer; void ignore(void* ctx, const char* msg, ...) {} template std::unique_ptr MakeUnique(T* obj, D del) { return {obj, del}; } -} +} // namespace DEFINE_PROTO_FUZZER(const protobuf_mutator::xml::Input& message) { std::string xml = MessageToXml(message.document()); diff --git a/third_party/libprotobuf-mutator/port/protobuf.h b/third_party/libprotobuf-mutator/port/protobuf.h index 04e06209bfe..7cacc0ca4f2 100644 --- a/third_party/libprotobuf-mutator/port/protobuf.h +++ b/third_party/libprotobuf-mutator/port/protobuf.h @@ -24,13 +24,46 @@ #include "google/protobuf/util/message_differencer.h" #include "google/protobuf/wire_format.h" +// clang-format off +#include "google/protobuf/port_def.inc" // MUST be last header included +// clang-format on +namespace google { +namespace protobuf { +#if PROTOBUF_VERSION < 4025000 + +template +const T* DownCastMessage(const Message* message) { + return static_cast(message); +} + +template +T* DownCastMessage(Message* message) { + const Message* message_const = message; + return const_cast(DownCastMessage(message_const)); +} + +#elif PROTOBUF_VERSION < 5029000 + +template +const T* DownCastMessage(const Message* message) { + return DownCastToGenerated(message); +} + +template +T* DownCastMessage(Message* message) { + return DownCastToGenerated(message); +} + +#endif // PROTOBUF_VERSION +} // namespace protobuf +} // namespace google +#include "google/protobuf/port_undef.inc" + + namespace protobuf_mutator { namespace protobuf = google::protobuf; -// String type used by google::protobuf. -using String = std::string; - } // namespace protobuf_mutator #endif // PORT_PROTOBUF_H_ diff --git a/third_party/libprotobuf-mutator/src/CMakeLists.txt b/third_party/libprotobuf-mutator/src/CMakeLists.txt index d0af1b6052b..633d882dd40 100644 --- a/third_party/libprotobuf-mutator/src/CMakeLists.txt +++ b/third_party/libprotobuf-mutator/src/CMakeLists.txt @@ -20,10 +20,11 @@ add_library(protobuf-mutator text_format.cc utf8_fix.cc) target_link_libraries(protobuf-mutator - ${PROTOBUF_LIBRARIES}) + ${Protobuf_LIBRARIES}) set_target_properties(protobuf-mutator PROPERTIES COMPILE_FLAGS "${NO_FUZZING_FLAGS}" SOVERSION 0) +target_compile_features(protobuf-mutator PUBLIC cxx_std_14) if (LIB_PROTO_MUTATOR_TESTING) protobuf_generate_cpp(PROTO_SRCS PROTO_HDRS diff --git a/third_party/libprotobuf-mutator/src/binary_format.cc b/third_party/libprotobuf-mutator/src/binary_format.cc index 34557881a80..4fa9ef11c17 100644 --- a/third_party/libprotobuf-mutator/src/binary_format.cc +++ b/third_party/libprotobuf-mutator/src/binary_format.cc @@ -43,8 +43,8 @@ size_t SaveMessageAsBinary(const Message& message, uint8_t* data, } std::string SaveMessageAsBinary(const protobuf::Message& message) { - String tmp; - if (!message.SerializePartialToString(&tmp)) return {}; + std::string tmp; + if (!message.SerializePartialToString(&tmp)) tmp.clear(); return tmp; } diff --git a/third_party/libprotobuf-mutator/src/field_instance.h b/third_party/libprotobuf-mutator/src/field_instance.h index 11ccd2741da..8ffb74582cc 100644 --- a/third_party/libprotobuf-mutator/src/field_instance.h +++ b/third_party/libprotobuf-mutator/src/field_instance.h @@ -176,7 +176,7 @@ class ConstFieldInstance { WireFormatLite::PARSE, ""); } - std::string name() const { return descriptor_->name(); } + std::string name() const { return std::string(descriptor_->name()); } protobuf::FieldDescriptor::CppType cpp_type() const { return descriptor_->cpp_type(); @@ -190,18 +190,14 @@ class ConstFieldInstance { return descriptor_->message_type(); } - bool EnforceUtf8() const { - return descriptor_->type() == protobuf::FieldDescriptor::TYPE_STRING && - descriptor()->file()->syntax() == - protobuf::FileDescriptor::SYNTAX_PROTO3; - } + bool EnforceUtf8() const { return descriptor_->requires_utf8_validation(); } const protobuf::FieldDescriptor* descriptor() const { return descriptor_; } std::string DebugString() const { - std::string s = descriptor_->DebugString(); - if (is_repeated()) s += "[" + std::to_string(index_) + "]"; - return s + " of\n" + message_->DebugString(); + std::string s = absl::StrCat(*descriptor_); + if (is_repeated()) s += absl::StrCat("[", index_, "]"); + return s + " of\n" + absl::StrCat(*message_); } protected: diff --git a/third_party/libprotobuf-mutator/src/libfuzzer/CMakeLists.txt b/third_party/libprotobuf-mutator/src/libfuzzer/CMakeLists.txt index 85e9f4de10e..44ab015934a 100644 --- a/third_party/libprotobuf-mutator/src/libfuzzer/CMakeLists.txt +++ b/third_party/libprotobuf-mutator/src/libfuzzer/CMakeLists.txt @@ -17,10 +17,11 @@ add_library(protobuf-mutator-libfuzzer libfuzzer_macro.cc) target_link_libraries(protobuf-mutator-libfuzzer protobuf-mutator - ${PROTOBUF_LIBRARIES}) + ${Protobuf_LIBRARIES}) set_target_properties(protobuf-mutator-libfuzzer PROPERTIES COMPILE_FLAGS "${NO_FUZZING_FLAGS}" SOVERSION 0) +target_compile_features(protobuf-mutator-libfuzzer PUBLIC cxx_std_14) install(TARGETS protobuf-mutator-libfuzzer EXPORT libprotobuf-mutatorTargets diff --git a/third_party/libprotobuf-mutator/src/libfuzzer/libfuzzer_macro.h b/third_party/libprotobuf-mutator/src/libfuzzer/libfuzzer_macro.h index b5cb201810b..8907326586b 100644 --- a/third_party/libprotobuf-mutator/src/libfuzzer/libfuzzer_macro.h +++ b/third_party/libprotobuf-mutator/src/libfuzzer/libfuzzer_macro.h @@ -119,7 +119,7 @@ struct PostProcessorRegistration { RegisterPostProcessor( Proto::descriptor(), [callback](protobuf::Message* message, unsigned int seed) { - callback(static_cast(message), seed); + callback(protobuf::DownCastMessage(message), seed); }); } }; diff --git a/third_party/libprotobuf-mutator/src/libfuzzer/libfuzzer_mutator.cc b/third_party/libprotobuf-mutator/src/libfuzzer/libfuzzer_mutator.cc index 34d144c5484..dbf78f5dab6 100644 --- a/third_party/libprotobuf-mutator/src/libfuzzer/libfuzzer_mutator.cc +++ b/third_party/libprotobuf-mutator/src/libfuzzer/libfuzzer_mutator.cc @@ -14,6 +14,11 @@ #include "src/libfuzzer/libfuzzer_mutator.h" +#if defined(__has_feature) +#if __has_feature(memory_sanitizer) +#include +#endif +#endif #include #include @@ -65,6 +70,12 @@ T MutateValue(T v) { size_t size = LLVMFuzzerMutate(reinterpret_cast(&v), sizeof(v), sizeof(v)); memset(reinterpret_cast(&v) + size, 0, sizeof(v) - size); + // The value from LLVMFuzzerMutate needs to be treated as initialized. +#if defined(__has_feature) +#if __has_feature(memory_sanitizer) + __msan_unpoison(&v, sizeof(v)); +#endif +#endif return v; } @@ -93,6 +104,12 @@ std::string Mutator::MutateString(const std::string& value, result.resize(std::max(1, new_size)); result.resize(LLVMFuzzerMutate(reinterpret_cast(&result[0]), value.size(), result.size())); + // The value from LLVMFuzzerMutate needs to be treated as initialized. +#if defined(__has_feature) +#if __has_feature(memory_sanitizer) + __msan_unpoison(&result[0], result.size()); +#endif +#endif return result; } diff --git a/third_party/libprotobuf-mutator/src/mutator.cc b/third_party/libprotobuf-mutator/src/mutator.cc index fb5542b15c9..4fdcae4ebb1 100644 --- a/third_party/libprotobuf-mutator/src/mutator.cc +++ b/third_party/libprotobuf-mutator/src/mutator.cc @@ -87,11 +87,7 @@ bool GetRandomBool(RandomEngine* random, size_t n = 2) { } bool IsProto3SimpleField(const FieldDescriptor& field) { - assert(field.file()->syntax() == FileDescriptor::SYNTAX_PROTO3 || - field.file()->syntax() == FileDescriptor::SYNTAX_PROTO2); - return field.file()->syntax() == FileDescriptor::SYNTAX_PROTO3 && - field.cpp_type() != FieldDescriptor::CPPTYPE_MESSAGE && - !field.containing_oneof() && !field.is_repeated(); + return !field.is_repeated() && !field.has_presence(); } struct CreateDefaultField : public FieldFunction { @@ -385,13 +381,13 @@ std::unique_ptr UnpackAny(const Any& any) { const Any* CastToAny(const Message* message) { return Any::GetDescriptor() == message->GetDescriptor() - ? static_cast(message) + ? protobuf::DownCastMessage(message) : nullptr; } Any* CastToAny(Message* message) { return Any::GetDescriptor() == message->GetDescriptor() - ? static_cast(message) + ? protobuf::DownCastMessage(message) : nullptr; } @@ -805,7 +801,7 @@ std::string Mutator::MutateUtf8String(const std::string& value, bool Mutator::IsInitialized(const Message& message) const { if (!keep_initialized_ || message.IsInitialized()) return true; - std::cerr << "Uninitialized: " << message.DebugString() << "\n"; + std::cerr << "Uninitialized: " << absl::StrCat(message) << "\n"; return false; } diff --git a/third_party/libprotobuf-mutator/src/mutator_test.cc b/third_party/libprotobuf-mutator/src/mutator_test.cc index 312b2d9704d..25a9b8a37e6 100644 --- a/third_party/libprotobuf-mutator/src/mutator_test.cc +++ b/third_party/libprotobuf-mutator/src/mutator_test.cc @@ -29,6 +29,7 @@ namespace protobuf_mutator { +using protobuf::DownCastMessage; using protobuf::util::MessageDifferencer; using testing::TestWithParam; using testing::ValuesIn; @@ -409,8 +410,8 @@ bool Mutate(const protobuf::Message& from, const protobuf::Message& to, } ADD_FAILURE() << "Failed to get from:\n" - << from.DebugString() << "\nto:\n" - << to.DebugString(); + << absl::StrCat(from) << "\nto:\n" + << absl::StrCat(to); return false; } @@ -622,7 +623,7 @@ TYPED_TEST(MutatorTypedTest, RegisterPostProcessor) { TestFixture::Message::descriptor(), [=](protobuf::Message* message, unsigned int seed) { auto test_message = - static_cast(message); + DownCastMessage(message); if (seed % 2) test_message->set_optional_string(v); }); } diff --git a/third_party/libprotobuf-mutator/src/text_format.cc b/third_party/libprotobuf-mutator/src/text_format.cc index 39b2fdb7cd7..2e8dbc7cf6f 100644 --- a/third_party/libprotobuf-mutator/src/text_format.cc +++ b/third_party/libprotobuf-mutator/src/text_format.cc @@ -49,8 +49,8 @@ size_t SaveMessageAsText(const Message& message, uint8_t* data, } std::string SaveMessageAsText(const protobuf::Message& message) { - String tmp; - if (!protobuf::TextFormat::PrintToString(message, &tmp)) return {}; + std::string tmp; + if (!protobuf::TextFormat::PrintToString(message, &tmp)) tmp.clear(); return tmp; } diff --git a/third_party/libprotobuf-mutator/src/utf8_fix_test.cc b/third_party/libprotobuf-mutator/src/utf8_fix_test.cc index 474eb8c5184..759f8037524 100644 --- a/third_party/libprotobuf-mutator/src/utf8_fix_test.cc +++ b/third_party/libprotobuf-mutator/src/utf8_fix_test.cc @@ -19,8 +19,6 @@ namespace protobuf_mutator { -protobuf::LogSilencer log_silincer; - class FixUtf8StringTest : public ::testing::TestWithParam { public: bool IsStructurallyValid(const std::string& s) { From 48aa032f436906c2da5fd000453deb0c6f0afb04 Mon Sep 17 00:00:00 2001 From: Pierric Gimmig Date: Tue, 31 Dec 2024 07:55:33 -0800 Subject: [PATCH 2/8] Update dependencies to Conan 2 --- conanfile.py | 164 ++++++++------------------------------------------- 1 file changed, 23 insertions(+), 141 deletions(-) diff --git a/conanfile.py b/conanfile.py index 8535b815fb2..2e9235b1504 100644 --- a/conanfile.py +++ b/conanfile.py @@ -5,152 +5,34 @@ Use of this source code is governed by a BSD-style license that can be found in the LICENSE file. """ +from conan import ConanFile -from conans import ConanFile, CMake, tools -from conans.errors import ConanInvalidConfiguration -import os -import shutil -from io import StringIO -import csv - - -class OrbitConan(ConanFile): - name = "OrbitProfiler" - license = "BSD-2-Clause" - url = "https://github.com/pierricgimmig/orbitprofiler.git" - description = "C/C++ Performance Profiler" +class OrbitDeps(ConanFile): + name = "orbit_deps" + version = "0.1" settings = "os", "compiler", "build_type", "arch" - generators = ["CMakeDeps"] - options = {"with_gui": [True, False], - "fPIC": [True, False], - "run_tests": [True, False], - "build_target": "ANY", - "with_system_deps": [True, False]} - default_options = {"with_gui": True, - "fPIC": True, - "run_tests": True, - "build_target": None, - "with_system_deps": False} - exports_sources = "CMakeLists.txt", "Orbit*", "bin/*", "cmake/*", "third_party/*", "LICENSE" - - def _version(self): - if not self.version: - buf = StringIO() - self.run("git describe --always --dirty --match 1.*", output=buf) - self.version = buf.getvalue().strip() - if self.version[0] == 'v': - self.version = self.version[1:] - - return self.version - - def config_options(self): - if self.settings.os == "Windows": - del self.options.fPIC - - def build_requirements(self): - if self.options.with_system_deps: return - self.build_requires('grpc/1.48.0') - self.build_requires('protobuf/3.21.4') - self.build_requires('gtest/1.11.0', force_host_context=True) + generators = "CMakeToolchain", "CMakeDeps" def requirements(self): - if self.options.with_system_deps: return - - self.requires("abseil/20220623.0") - self.requires("capstone/4.0.2") - self.requires("grpc/1.48.0") - self.requires("outcome/2.2.3") + self.requires("abseil/20240116.2") + self.requires("capstone/5.0.1") + self.requires("grpc/1.67.1") + self.requires("gtest/1.15.0") + self.requires("outcome/2.2.9") self.requires("llvm-core/13.0.0") if self.settings.os != "Windows": - self.requires("volk/1.3.224.1") - self.requires("vulkan-headers/1.3.224.1") - self.requires("vulkan-validationlayers/1.3.224.1") - self.requires("zlib/1.2.12", override=True) - self.requires("openssl/1.1.1s", override=True) - - if self.options.with_gui: - self.requires("libssh2/1.10.0") - - - def configure(self): - if self.settings.os != "Windows" and not self.options.fPIC: - raise ConanInvalidConfiguration( - "We only support compiling with fPIC enabled!") - - if self.options.with_gui and self.settings.arch == "x86": - raise ConanInvalidConfiguration( - "We don't actively support building the UI for 32bit platforms. Please remove this check in conanfile.py if you still want to do so!") - - self.options["gtest"].no_main = True - - if self.settings.os != "Windows": - self.options["vulkan-validationlayers"].with_wsi_xcb = False - self.options["vulkan-validationlayers"].with_wsi_xlib = False - self.options["vulkan-validationlayers"].with_wsi_wayland = False - - - def build(self): - cmake = CMake(self) - cmake.definitions["WITH_GUI"] = "ON" if self.options.with_gui else "OFF" - cmake.configure() - cmake.build(target=str(self.options.build_target) if self.options.build_target else None) - if self.options.run_tests and not tools.cross_building(self.settings, skip_x64_x86=True) and self.settings.get_safe("os.platform") != "GGP": - cmake.test(output_on_failure=True) - - def imports(self): - excludes = [ - "*qt*", - "*licensewizard*", - "*checklicenses*", - "*.py", - "*.pyc", - "*.cc", - "*.yml", - "*.vanilla", - "*.h", - "*.pl", - "*license_template.txt", - "*.patch", - "*.QT-LICENSE-AGREEMENT", - "*.ini", - "*.js", - "*license-checker*", - "*.html", - "*.json", - "*README.md" - ] - self.copy("LICENSE*", dst="licenses", folder=True, ignore_case=True, excludes=excludes) - self.copy("LICENCE*", dst="licenses", folder=True, ignore_case=True, excludes=excludes) - - - def package(self): - self.copy("*", src="bin/autopresets", dst="bin/autopresets", symlinks=True) - self.copy("*.pdb", src="bin/", dst="bin") - self.copy("Orbit", src="bin/", dst="bin") - self.copy("Orbit.exe", src="bin/", dst="bin") - self.copy("Orbit.debug", src="bin/", dst="bin") - self.copy("OrbitService", src="bin/", dst="bin") - self.copy("OrbitService.exe", src="bin/", dst="bin") - self.copy("OrbitService.debug", src="bin/", dst="bin") - self.copy("OrbitClientGgp", src="bin/", dst="bin") - self.copy("OrbitClientGgp.exe", src="bin/", dst="bin") - self.copy("OrbitClientGgp.debug", src="bin/", dst="bin") - self.copy("NOTICE") - self.copy("LICENSE") - self.copy("liborbit.so", src="lib/", dst="lib") - self.copy("liborbituserspaceinstrumentation.so", src="lib/", dst="lib") - self.copy("libOrbitVulkanLayer.so", src="lib/", dst="lib") - self.copy("VkLayer_Orbit_implicit.json", src="lib/", dst="lib") - self.copy("LinuxTracingIntegrationTests", src="bin/", dst="bin") - self.copy("LinuxTracingIntegrationTests.debug", src="bin/", dst="bin") - self.copy("OrbitServiceIntegrationTests", src="bin/", dst="bin") - self.copy("OrbitServiceIntegrationTests.debug", src="bin/", dst="bin") - self.copy("libIntegrationTestPuppetSharedObject.so", src="lib/", dst="lib") - self.copy("libIntegrationTestPuppetSharedObject.so.debug", src="lib/", dst="lib") - self.copy("OrbitFakeClient", src="bin/", dst="bin") - self.copy("OrbitFakeClient.debug", src="bin/", dst="bin") - self.copy("msdia140.dll", src="bin/", dst="bin") + self.requires("volk/1.3.268.0") + self.requires("vulkan-headers/1.3.290.0") + self.requires("vulkan-validationlayers/1.3.290.0") + self.requires("zlib/1.3.1", override=True) + self.requires("openssl/3.3.2", override=True) + self.requires("libssh2/1.11.0") + def build_requirements(self): + self.tool_requires("grpc/1.67.1") + self.tool_requires("protobuf/5.27.0") + self.tool_requires("gtest/1.15.0") - def deploy(self): - self.copy("*", src="bin", dst="bin") + def layout(self): + self.folders.build = "build" + self.folders.generators = "build/generators" From db595d8e67b6094aada285cff70c87c97f9911f8 Mon Sep 17 00:00:00 2001 From: Pierric Gimmig Date: Tue, 31 Dec 2024 07:56:44 -0800 Subject: [PATCH 3/8] Fix GTest linking --- src/ApiUtils/CMakeLists.txt | 2 +- src/CaptureClient/CMakeLists.txt | 2 +- src/CaptureEventProducer/CMakeLists.txt | 4 +- src/CaptureFile/CMakeLists.txt | 3 +- src/ClientData/CMakeLists.txt | 2 +- src/ClientModel/CMakeLists.txt | 2 +- src/ClientSymbols/CMakeLists.txt | 2 +- src/CodeReport/CMakeLists.txt | 2 +- src/CommandLineUtils/CMakeLists.txt | 2 +- src/Containers/CMakeLists.txt | 2 +- src/DataViews/CMakeLists.txt | 2 +- src/DisplayFormats/CMakeLists.txt | 2 +- src/Introspection/CMakeLists.txt | 2 +- src/LinuxCaptureService/CMakeLists.txt | 2 +- src/LinuxTracing/CMakeLists.txt | 2 +- .../CMakeLists.txt | 4 +- src/MemoryTracing/CMakeLists.txt | 2 +- src/MizarData/CMakeLists.txt | 2 +- src/MizarModels/CMakeLists.txt | 4 +- src/MizarStatistics/CMakeLists.txt | 2 +- src/ModuleUtils/CMakeLists.txt | 2 +- src/ObjectUtils/CMakeLists.txt | 7 ++-- src/OrbitAccessibility/CMakeLists.txt | 2 +- src/OrbitBase/CMakeLists.txt | 2 +- src/OrbitGl/CMakeLists.txt | 2 +- src/OrbitPaths/CMakeLists.txt | 2 +- src/OrbitSsh/CMakeLists.txt | 2 +- src/OrbitVersion/CMakeLists.txt | 2 +- src/OrbitVulkanLayer/CMakeLists.txt | 2 +- src/PresetFile/CMakeLists.txt | 2 +- src/ProcessService/CMakeLists.txt | 2 +- src/ProducerEventProcessor/CMakeLists.txt | 2 +- src/ProducerSideService/CMakeLists.txt | 2 +- src/SshQtTestUtils/CMakeLists.txt | 2 +- src/Statistics/CMakeLists.txt | 2 +- src/StringManager/CMakeLists.txt | 2 +- src/SymbolProvider/CMakeLists.txt | 2 +- src/Symbols/CMakeLists.txt | 2 +- src/Test/CMakeLists.txt | 37 +++++++++++++------ src/TestUtils/CMakeLists.txt | 6 ++- src/TracepointService/CMakeLists.txt | 2 +- src/UserSpaceInstrumentation/CMakeLists.txt | 2 +- src/WindowsTracing/CMakeLists.txt | 2 +- src/WindowsUtils/CMakeLists.txt | 2 +- 44 files changed, 79 insertions(+), 60 deletions(-) diff --git a/src/ApiUtils/CMakeLists.txt b/src/ApiUtils/CMakeLists.txt index 9cf4da9b2b8..50263cb1c32 100644 --- a/src/ApiUtils/CMakeLists.txt +++ b/src/ApiUtils/CMakeLists.txt @@ -28,6 +28,6 @@ target_sources(ApiUtilsTests PRIVATE target_link_libraries(ApiUtilsTests PRIVATE ApiUtils - GTest::Main) + GTest_Main) register_test(ApiUtilsTests) diff --git a/src/CaptureClient/CMakeLists.txt b/src/CaptureClient/CMakeLists.txt index 34401a1a47d..7997f20eb22 100644 --- a/src/CaptureClient/CMakeLists.txt +++ b/src/CaptureClient/CMakeLists.txt @@ -55,6 +55,6 @@ target_sources(CaptureClientTests PRIVATE target_link_libraries(CaptureClientTests PRIVATE CaptureClient TestUtils - GTest::Main) + GTest_Main) register_test(CaptureClientTests) diff --git a/src/CaptureEventProducer/CMakeLists.txt b/src/CaptureEventProducer/CMakeLists.txt index dfd935479ae..a33b98c98f4 100644 --- a/src/CaptureEventProducer/CMakeLists.txt +++ b/src/CaptureEventProducer/CMakeLists.txt @@ -33,6 +33,8 @@ target_sources(CaptureEventProducerTests PRIVATE target_link_libraries(CaptureEventProducerTests PRIVATE CaptureEventProducer FakeProducerSideService - GTest::Main) + GTest_Main + gtest + gmock) register_test(CaptureEventProducerTests) diff --git a/src/CaptureFile/CMakeLists.txt b/src/CaptureFile/CMakeLists.txt index fb5a2a12f22..85f97c321dc 100644 --- a/src/CaptureFile/CMakeLists.txt +++ b/src/CaptureFile/CMakeLists.txt @@ -53,6 +53,7 @@ target_link_libraries( TestUtils absl::base absl::synchronization - GTest::Main) + GTest_Main + ) register_test(CaptureFileTests) diff --git a/src/ClientData/CMakeLists.txt b/src/ClientData/CMakeLists.txt index 71756958eff..69025534808 100644 --- a/src/ClientData/CMakeLists.txt +++ b/src/ClientData/CMakeLists.txt @@ -123,7 +123,7 @@ target_sources(ClientDataTests PRIVATE target_link_libraries(ClientDataTests PRIVATE ClientData TestUtils - GTest::Main) + GTest_Main) register_test(ClientDataTests) diff --git a/src/ClientModel/CMakeLists.txt b/src/ClientModel/CMakeLists.txt index 87c8974fe72..282dceb5fc8 100644 --- a/src/ClientModel/CMakeLists.txt +++ b/src/ClientModel/CMakeLists.txt @@ -32,6 +32,6 @@ target_sources(ClientModelTests PRIVATE target_link_libraries(ClientModelTests PRIVATE ClientModel - GTest::Main) + GTest_Main) register_test(ClientModelTests) diff --git a/src/ClientSymbols/CMakeLists.txt b/src/ClientSymbols/CMakeLists.txt index 104ed21fcb2..67213fbeb35 100644 --- a/src/ClientSymbols/CMakeLists.txt +++ b/src/ClientSymbols/CMakeLists.txt @@ -28,6 +28,6 @@ target_sources(ClientSymbolsTests PRIVATE target_link_libraries(ClientSymbolsTests PRIVATE ClientSymbols - GTest::QtCoreMain) + GTest_QtCoreMain) register_test(ClientSymbolsTests) diff --git a/src/CodeReport/CMakeLists.txt b/src/CodeReport/CMakeLists.txt index 8d6000010c9..fc2d62d4b92 100644 --- a/src/CodeReport/CMakeLists.txt +++ b/src/CodeReport/CMakeLists.txt @@ -38,5 +38,5 @@ target_link_libraries(CodeReportTests PRIVATE CodeReport ModuleUtils SymbolProvider - GTest::Main) + GTest_Main) register_test(CodeReportTests) diff --git a/src/CommandLineUtils/CMakeLists.txt b/src/CommandLineUtils/CMakeLists.txt index 2f44b1cf4dd..31ce4ed22af 100644 --- a/src/CommandLineUtils/CMakeLists.txt +++ b/src/CommandLineUtils/CMakeLists.txt @@ -27,6 +27,6 @@ target_sources(CommandLineUtilsTests PRIVATE target_link_libraries( CommandLineUtilsTests PRIVATE CommandLineUtils - GTest::Main) + GTest_Main) register_test(CommandLineUtilsTests) \ No newline at end of file diff --git a/src/Containers/CMakeLists.txt b/src/Containers/CMakeLists.txt index 3ab39497475..ff2d62829a4 100644 --- a/src/Containers/CMakeLists.txt +++ b/src/Containers/CMakeLists.txt @@ -27,6 +27,6 @@ target_sources(ContainersTests PRIVATE target_link_libraries( ContainersTests PRIVATE Containers - GTest::Main) + GTest_Main) register_test(ContainersTests) \ No newline at end of file diff --git a/src/DataViews/CMakeLists.txt b/src/DataViews/CMakeLists.txt index b983bd2be63..573428ad6e1 100644 --- a/src/DataViews/CMakeLists.txt +++ b/src/DataViews/CMakeLists.txt @@ -70,6 +70,6 @@ target_sources(DataViewsTests PRIVATE CallstackDataViewTest.cpp target_link_libraries(DataViewsTests PRIVATE DataViews TestUtils - GTest::Main) + GTest_Main) register_test(DataViewsTests) diff --git a/src/DisplayFormats/CMakeLists.txt b/src/DisplayFormats/CMakeLists.txt index c0bdb63ae78..d86fc255380 100644 --- a/src/DisplayFormats/CMakeLists.txt +++ b/src/DisplayFormats/CMakeLists.txt @@ -30,6 +30,6 @@ target_sources(DisplayFormatsTests PRIVATE target_link_libraries(DisplayFormatsTests PRIVATE DisplayFormats OrbitBase - GTest::Main) + GTest_Main) register_test(DisplayFormatsTests) diff --git a/src/Introspection/CMakeLists.txt b/src/Introspection/CMakeLists.txt index f24fac97557..e193e96a04e 100644 --- a/src/Introspection/CMakeLists.txt +++ b/src/Introspection/CMakeLists.txt @@ -30,7 +30,7 @@ target_sources(IntrospectionTests PRIVATE target_link_libraries(IntrospectionTests PRIVATE Introspection OrbitBase - GTest::Main + GTest_Main absl::base absl::flat_hash_map absl::synchronization) diff --git a/src/LinuxCaptureService/CMakeLists.txt b/src/LinuxCaptureService/CMakeLists.txt index b116cf0c78e..f7a107efb5e 100644 --- a/src/LinuxCaptureService/CMakeLists.txt +++ b/src/LinuxCaptureService/CMakeLists.txt @@ -50,7 +50,7 @@ target_sources(LinuxCaptureServiceTests PRIVATE target_link_libraries(LinuxCaptureServiceTests PRIVATE LinuxCaptureService - GTest::Main + GTest_Main TestUtils) register_test(LinuxCaptureServiceTests) diff --git a/src/LinuxTracing/CMakeLists.txt b/src/LinuxTracing/CMakeLists.txt index ce0a1639de5..db114f9a147 100644 --- a/src/LinuxTracing/CMakeLists.txt +++ b/src/LinuxTracing/CMakeLists.txt @@ -106,6 +106,6 @@ target_sources(LinuxTracingTests PRIVATE target_link_libraries(LinuxTracingTests PRIVATE LinuxTracing GTest::gtest - GTest::Main) + GTest_Main) register_test(LinuxTracingTests) diff --git a/src/LinuxTracingIntegrationTests/CMakeLists.txt b/src/LinuxTracingIntegrationTests/CMakeLists.txt index db15515156c..fe56aefe963 100644 --- a/src/LinuxTracingIntegrationTests/CMakeLists.txt +++ b/src/LinuxTracingIntegrationTests/CMakeLists.txt @@ -59,7 +59,7 @@ target_link_libraries(LinuxTracingIntegrationTests PRIVATE ObjectUtils OrbitBase GTest::gtest - GTest::Main + GTest_Main absl::base absl::time absl::flat_hash_set @@ -86,7 +86,7 @@ target_link_libraries(OrbitServiceIntegrationTests PRIVATE OrbitServiceLib OrbitVersion GTest::gtest - GTest::Main + GTest_Main absl::base absl::time absl::flat_hash_set diff --git a/src/MemoryTracing/CMakeLists.txt b/src/MemoryTracing/CMakeLists.txt index 85ca895a8de..b1ba898aad4 100644 --- a/src/MemoryTracing/CMakeLists.txt +++ b/src/MemoryTracing/CMakeLists.txt @@ -41,6 +41,6 @@ target_sources(MemoryTracingTests PRIVATE target_link_libraries(MemoryTracingTests PRIVATE MemoryTracing GTest::gtest - GTest::Main) + GTest_Main) register_test(MemoryTracingTests) \ No newline at end of file diff --git a/src/MizarData/CMakeLists.txt b/src/MizarData/CMakeLists.txt index 70af11adb71..dd2d0ba2116 100644 --- a/src/MizarData/CMakeLists.txt +++ b/src/MizarData/CMakeLists.txt @@ -51,6 +51,6 @@ target_sources(MizarDataTests PRIVATE target_link_libraries(MizarDataTests PRIVATE GrpcProtos MizarData GTest::gtest - GTest::Main + GTest_Main TestUtils) register_test(MizarDataTests) diff --git a/src/MizarModels/CMakeLists.txt b/src/MizarModels/CMakeLists.txt index fe9670bc0d7..828369317a8 100644 --- a/src/MizarModels/CMakeLists.txt +++ b/src/MizarModels/CMakeLists.txt @@ -27,7 +27,9 @@ target_sources(MizarModelsTests PRIVATE target_link_libraries(MizarModelsTests PRIVATE MizarModels TestUtils - GTest::Main + GTest_Main + gtest + gmock Qt5::Test ) diff --git a/src/MizarStatistics/CMakeLists.txt b/src/MizarStatistics/CMakeLists.txt index cdcc9b4fb8e..f9cb57287ce 100644 --- a/src/MizarStatistics/CMakeLists.txt +++ b/src/MizarStatistics/CMakeLists.txt @@ -23,6 +23,6 @@ target_sources(MizarStatisticsTests PRIVATE target_link_libraries(MizarStatisticsTests PRIVATE GrpcProtos MizarStatistics GTest::gtest - GTest::Main) + GTest_Main) register_test(MizarStatisticsTests) \ No newline at end of file diff --git a/src/ModuleUtils/CMakeLists.txt b/src/ModuleUtils/CMakeLists.txt index 912d677dce4..121de35db2f 100644 --- a/src/ModuleUtils/CMakeLists.txt +++ b/src/ModuleUtils/CMakeLists.txt @@ -49,6 +49,6 @@ endif() target_link_libraries(ModuleUtilsTests PRIVATE ModuleUtils TestUtils - GTest::Main) + GTest_Main) register_test(ModuleUtilsTests) diff --git a/src/ObjectUtils/CMakeLists.txt b/src/ObjectUtils/CMakeLists.txt index 2fcea6fac27..8c16abf65c3 100644 --- a/src/ObjectUtils/CMakeLists.txt +++ b/src/ObjectUtils/CMakeLists.txt @@ -10,7 +10,7 @@ set(REQUIRED_LLVM_LIBS LLVMDebugInfoCodeView LLVMObject LLVMSymbolize) -find_llvm_libs("${REQUIRED_LLVM_LIBS}") +#find_llvm_libs("${REQUIRED_LLVM_LIBS}") project(ObjectUtils) add_library(ObjectUtils STATIC) @@ -63,8 +63,7 @@ target_link_libraries( absl::synchronization absl::time absl::span - LLVMHeaders - ${LLVM_LIBS} + llvm-core::llvm-core ) if (WIN32) @@ -95,7 +94,7 @@ target_link_libraries( ObjectUtilsTests PRIVATE ObjectUtils TestUtils - GTest::Main) + GTest_Main) register_test(ObjectUtilsTests) diff --git a/src/OrbitAccessibility/CMakeLists.txt b/src/OrbitAccessibility/CMakeLists.txt index 57ace1c65f8..7d4621a3cf9 100644 --- a/src/OrbitAccessibility/CMakeLists.txt +++ b/src/OrbitAccessibility/CMakeLists.txt @@ -40,6 +40,6 @@ target_sources(OrbitAccessibilityTests PRIVATE target_link_libraries( OrbitAccessibilityTests PRIVATE OrbitAccessibility - GTest::Main) + GTest_Main) register_test(OrbitAccessibilityTests) diff --git a/src/OrbitBase/CMakeLists.txt b/src/OrbitBase/CMakeLists.txt index a44d70688fb..cfb94478007 100644 --- a/src/OrbitBase/CMakeLists.txt +++ b/src/OrbitBase/CMakeLists.txt @@ -166,6 +166,6 @@ target_link_libraries(OrbitBaseTests PRIVATE OrbitBase TestUtils GTest::gtest - GTest::Main) + GTest_Main) register_test(OrbitBaseTests) \ No newline at end of file diff --git a/src/OrbitGl/CMakeLists.txt b/src/OrbitGl/CMakeLists.txt index c8fb7ada88b..6e0b294c708 100644 --- a/src/OrbitGl/CMakeLists.txt +++ b/src/OrbitGl/CMakeLists.txt @@ -246,7 +246,7 @@ target_sources(OrbitGlTests PRIVATE target_link_libraries( OrbitGlTests PRIVATE OrbitGl - GTest::Main) + GTest_Main) register_test(OrbitGlTests) diff --git a/src/OrbitPaths/CMakeLists.txt b/src/OrbitPaths/CMakeLists.txt index e55bbc55867..87d651d8b6e 100644 --- a/src/OrbitPaths/CMakeLists.txt +++ b/src/OrbitPaths/CMakeLists.txt @@ -30,6 +30,6 @@ target_sources(OrbitPathsTests PRIVATE target_link_libraries(OrbitPathsTests PRIVATE OrbitPaths TestUtils - GTest::Main) + GTest_Main) register_test(OrbitPathsTests) diff --git a/src/OrbitSsh/CMakeLists.txt b/src/OrbitSsh/CMakeLists.txt index 7749927faca..13f07677e7c 100644 --- a/src/OrbitSsh/CMakeLists.txt +++ b/src/OrbitSsh/CMakeLists.txt @@ -63,6 +63,6 @@ target_sources(OrbitSshTests PRIVATE target_link_libraries(OrbitSshTests PRIVATE OrbitSsh TestUtils - GTest::Main) + GTest_Main) register_test(OrbitSshTests PROPERTIES TIMEOUT 10) diff --git a/src/OrbitVersion/CMakeLists.txt b/src/OrbitVersion/CMakeLists.txt index 0633002c6a2..896a55dae42 100644 --- a/src/OrbitVersion/CMakeLists.txt +++ b/src/OrbitVersion/CMakeLists.txt @@ -28,6 +28,6 @@ target_sources(OrbitVersionTests PRIVATE OrbitVersionTest.cpp) target_link_libraries(OrbitVersionTests PRIVATE OrbitVersion GTest::gtest - GTest::Main) + GTest_Main) register_test(OrbitVersionTests) diff --git a/src/OrbitVulkanLayer/CMakeLists.txt b/src/OrbitVulkanLayer/CMakeLists.txt index da197f45f6f..a50c7b71283 100644 --- a/src/OrbitVulkanLayer/CMakeLists.txt +++ b/src/OrbitVulkanLayer/CMakeLists.txt @@ -72,6 +72,6 @@ target_link_libraries( OrbitVulkanLayerTests PRIVATE FakeProducerSideService OrbitVulkanLayerInterface - GTest::Main) + GTest_Main) register_test(OrbitVulkanLayerTests) diff --git a/src/PresetFile/CMakeLists.txt b/src/PresetFile/CMakeLists.txt index 8f7896cc917..c9a17e65b39 100644 --- a/src/PresetFile/CMakeLists.txt +++ b/src/PresetFile/CMakeLists.txt @@ -33,6 +33,6 @@ target_link_libraries( PresetFileTests PRIVATE PresetFile TestUtils - GTest::Main) + GTest_Main) register_test(PresetFileTests) diff --git a/src/ProcessService/CMakeLists.txt b/src/ProcessService/CMakeLists.txt index fe9d1cd736c..8bcc7112a6e 100644 --- a/src/ProcessService/CMakeLists.txt +++ b/src/ProcessService/CMakeLists.txt @@ -41,7 +41,7 @@ target_sources(ProcessServiceTests PRIVATE target_link_libraries(ProcessServiceTests PRIVATE TestUtils ProcessService - GTest::Main) + GTest_Main) register_test(ProcessServiceTests PROPERTIES TIMEOUT 10) diff --git a/src/ProducerEventProcessor/CMakeLists.txt b/src/ProducerEventProcessor/CMakeLists.txt index 9fb24c8aac3..039db4d37a2 100644 --- a/src/ProducerEventProcessor/CMakeLists.txt +++ b/src/ProducerEventProcessor/CMakeLists.txt @@ -35,6 +35,6 @@ target_sources(ProducerEventProcessorTests PRIVATE target_link_libraries(ProducerEventProcessorTests PRIVATE TestUtils ProducerEventProcessor - GTest::Main) + GTest_Main) register_test(ProducerEventProcessorTests) diff --git a/src/ProducerSideService/CMakeLists.txt b/src/ProducerSideService/CMakeLists.txt index 22fcd551148..4178cce9d87 100644 --- a/src/ProducerSideService/CMakeLists.txt +++ b/src/ProducerSideService/CMakeLists.txt @@ -43,6 +43,6 @@ target_link_libraries(ProducerSideServiceTests PRIVATE ProducerEventProcessor ProducerSideService TestUtils - GTest::Main) + GTest_Main) register_test(ProducerSideServiceTests PROPERTIES TIMEOUT 10) diff --git a/src/SshQtTestUtils/CMakeLists.txt b/src/SshQtTestUtils/CMakeLists.txt index f1419cc34e5..6fd544de8c3 100644 --- a/src/SshQtTestUtils/CMakeLists.txt +++ b/src/SshQtTestUtils/CMakeLists.txt @@ -30,5 +30,5 @@ target_sources(SshQtTestUtils PUBLIC add_executable(SshQtTestUtilsTests ParsePortNumberFromSocatOutputTest.cpp) -target_link_libraries(SshQtTestUtilsTests PRIVATE SshQtTestUtils TestUtils GTest::Main) +target_link_libraries(SshQtTestUtilsTests PRIVATE SshQtTestUtils TestUtils GTest_Main) register_test(SshQtTestUtilsTests) \ No newline at end of file diff --git a/src/Statistics/CMakeLists.txt b/src/Statistics/CMakeLists.txt index 085baa0856e..18c093e7c10 100644 --- a/src/Statistics/CMakeLists.txt +++ b/src/Statistics/CMakeLists.txt @@ -38,7 +38,7 @@ target_sources(StatisticsTests PRIVATE target_link_libraries( StatisticsTests PRIVATE Statistics - GTest::Main + GTest_Main TestUtils) register_test(StatisticsTests) diff --git a/src/StringManager/CMakeLists.txt b/src/StringManager/CMakeLists.txt index 51475b7f8b8..a29142680e2 100644 --- a/src/StringManager/CMakeLists.txt +++ b/src/StringManager/CMakeLists.txt @@ -31,6 +31,6 @@ target_sources(StringManagerTests PRIVATE target_link_libraries( StringManagerTests PRIVATE StringManager - GTest::Main) + GTest_Main) register_test(StringManagerTests) diff --git a/src/SymbolProvider/CMakeLists.txt b/src/SymbolProvider/CMakeLists.txt index 95b171b1cdf..61ae8940c1b 100644 --- a/src/SymbolProvider/CMakeLists.txt +++ b/src/SymbolProvider/CMakeLists.txt @@ -30,6 +30,6 @@ target_sources(SymbolProviderTests PRIVATE target_link_libraries(SymbolProviderTests PRIVATE SymbolProvider TestUtils - GTest::Main) + GTest_Main) register_test(SymbolProviderTests) diff --git a/src/Symbols/CMakeLists.txt b/src/Symbols/CMakeLists.txt index 1f64cdeea0c..390133b783f 100644 --- a/src/Symbols/CMakeLists.txt +++ b/src/Symbols/CMakeLists.txt @@ -29,5 +29,5 @@ add_executable(SymbolsTests) target_sources(SymbolsTests PRIVATE SymbolHelperTest.cpp SymbolUtilsTest.cpp) -target_link_libraries(SymbolsTests PRIVATE Symbols TestUtils GTest::Main) +target_link_libraries(SymbolsTests PRIVATE Symbols TestUtils GTest_Main) register_test(SymbolsTests) diff --git a/src/Test/CMakeLists.txt b/src/Test/CMakeLists.txt index 2b0a8fde40c..9a35d1dfd7f 100644 --- a/src/Test/CMakeLists.txt +++ b/src/Test/CMakeLists.txt @@ -1,29 +1,42 @@ # Copyright (c) 2021 The Orbit Authors. All rights reserved. # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. +# gtest +# gmock +# gtest_main +# gmock_main cmake_minimum_required(VERSION 3.15) -if(NOT TARGET GTest::Main) - add_library(GTest_Main OBJECT EXCLUDE_FROM_ALL test_main.cpp Path.cpp) - target_include_directories(GTest_Main PUBLIC include/) - target_link_libraries(GTest_Main PUBLIC OrbitBase GTest::gtest GTest::gmock) - add_library(GTest::Main ALIAS GTest_Main) -endif() +# if(NOT TARGET GTest::Main) +# message(FATAL_ERROR "GTest::Main is NOT already being used!") +# endif() -if(NOT TARGET GTest::QtCoreMain AND TARGET Qt5::Core) +# if(TARGET GTest::Main) +# message(FATAL_ERROR "GTest::Main is already being used!") +# endif() + +# if(NOT TARGET GTest::Main) +# message(FATAL_ERROR "GTest::Main is being used!") +add_library(GTest_Main OBJECT EXCLUDE_FROM_ALL test_main.cpp Path.cpp) +target_include_directories(GTest_Main PUBLIC include/) +target_link_libraries(GTest_Main PUBLIC OrbitBase GTest::gtest GTest::gmock) +#add_library(GTest::Main ALIAS GTest_Main) +#endif() + +#if(NOT TARGET GTest::QtCoreMain AND TARGET Qt5::Core) add_library(GTest_QtCoreMain OBJECT EXCLUDE_FROM_ALL test_qtcore_main.cpp Path.cpp) target_include_directories(GTest_QtCoreMain PUBLIC include/) target_link_libraries(GTest_QtCoreMain PUBLIC OrbitBase GTest::gtest GTest::gmock Qt5::Core) - add_library(GTest::QtCoreMain ALIAS GTest_QtCoreMain) -endif() +add_library(GTest::QtCoreMain ALIAS GTest_QtCoreMain) +# endif() -if(NOT TARGET GTest::QtGuiMain AND TARGET Qt5::Widgets) +# if(NOT TARGET GTest::QtGuiMain AND TARGET Qt5::Widgets) add_library(GTest_QtGuiMain OBJECT EXCLUDE_FROM_ALL test_qtgui_main.cpp Path.cpp) target_include_directories(GTest_QtGuiMain PUBLIC include/) target_link_libraries(GTest_QtGuiMain PUBLIC OrbitBase GTest::gtest GTest::gmock Qt5::Widgets absl::strings) - add_library(GTest::QtGuiMain ALIAS GTest_QtGuiMain) -endif() +add_library(GTest::QtGuiMain ALIAS GTest_QtGuiMain) +# endif() add_executable(TestTests StringViewTest.cpp) target_link_libraries(TestTests PRIVATE GTest::Main) diff --git a/src/TestUtils/CMakeLists.txt b/src/TestUtils/CMakeLists.txt index efc7c166271..3904910ebc3 100644 --- a/src/TestUtils/CMakeLists.txt +++ b/src/TestUtils/CMakeLists.txt @@ -24,7 +24,9 @@ target_link_libraries(TestUtils PUBLIC absl::flat_hash_set absl::strings absl::str_format - GTest::gtest) + GTest_Main + gtest + gmock) add_executable(TestUtilsTests ContainerHelpersTest.cpp @@ -32,5 +34,5 @@ add_executable(TestUtilsTests TemporaryDirectoryTest.cpp TemporaryFileTest.cpp TestUtilsTest.cpp) -target_link_libraries(TestUtilsTests PRIVATE TestUtils GTest::Main) +target_link_libraries(TestUtilsTests PRIVATE TestUtils GTest_Main) register_test(TestUtilsTests) \ No newline at end of file diff --git a/src/TracepointService/CMakeLists.txt b/src/TracepointService/CMakeLists.txt index 811b6d4b8cd..354704295f2 100644 --- a/src/TracepointService/CMakeLists.txt +++ b/src/TracepointService/CMakeLists.txt @@ -31,6 +31,6 @@ target_sources(TracepointServiceTests PRIVATE target_link_libraries(TracepointServiceTests PRIVATE TestUtils TracepointService - GTest::Main) + GTest_Main) register_test(TracepointServiceTests) diff --git a/src/UserSpaceInstrumentation/CMakeLists.txt b/src/UserSpaceInstrumentation/CMakeLists.txt index 95702400843..e132e319220 100644 --- a/src/UserSpaceInstrumentation/CMakeLists.txt +++ b/src/UserSpaceInstrumentation/CMakeLists.txt @@ -136,6 +136,6 @@ target_link_libraries(UserSpaceInstrumentationTests PRIVATE UserSpaceInstrumentation capstone::capstone GTest::gtest - GTest::Main) + GTest_Main) register_test(UserSpaceInstrumentationTests) diff --git a/src/WindowsTracing/CMakeLists.txt b/src/WindowsTracing/CMakeLists.txt index d703c25b795..a1395e5377d 100644 --- a/src/WindowsTracing/CMakeLists.txt +++ b/src/WindowsTracing/CMakeLists.txt @@ -62,7 +62,7 @@ target_sources(WindowsTracingTests PRIVATE target_link_libraries(WindowsTracingTests PRIVATE WindowsTracing GTest::gtest - GTest::Main) + GTest_Main) SET_TARGET_PROPERTIES(WindowsTracingTests PROPERTIES LINK_FLAGS "/MANIFESTUAC:\"level='requireAdministrator' uiAccess='false'\"") diff --git a/src/WindowsUtils/CMakeLists.txt b/src/WindowsUtils/CMakeLists.txt index eb1b833bbd5..d6782aeaae9 100644 --- a/src/WindowsUtils/CMakeLists.txt +++ b/src/WindowsUtils/CMakeLists.txt @@ -84,7 +84,7 @@ target_link_libraries(WindowsUtilsTests PRIVATE TestUtils WindowsUtils GTest::gtest - GTest::Main) + GTest_Main) SET_TARGET_PROPERTIES(WindowsUtilsTests PROPERTIES LINK_FLAGS "/MANIFESTUAC:\"level='requireAdministrator' uiAccess='false'\"") From 85b0a348eba9f022c596a90f4f2ea5ccabc9f081 Mon Sep 17 00:00:00 2001 From: Pierric Gimmig Date: Tue, 31 Dec 2024 08:28:57 -0800 Subject: [PATCH 4/8] Fix compilation errors --- src/CommandLineUtils/CommandLineUtilsTest.cpp | 19 +++++++++-- src/OrbitGl/CMakeLists.txt | 2 ++ src/Test/CMakeLists.txt | 32 ++++--------------- 3 files changed, 25 insertions(+), 28 deletions(-) diff --git a/src/CommandLineUtils/CommandLineUtilsTest.cpp b/src/CommandLineUtils/CommandLineUtilsTest.cpp index 26f8f944dad..1b326ae87d6 100644 --- a/src/CommandLineUtils/CommandLineUtilsTest.cpp +++ b/src/CommandLineUtils/CommandLineUtilsTest.cpp @@ -11,6 +11,21 @@ #include "CommandLineUtils/CommandLineUtils.h" +namespace { + +std::vector QStringListToStdVector(const QStringList& qlist) { + std::vector result; + result.reserve(qlist.size()); + + for (const QString& str : qlist) { + result.push_back(str.toStdString()); + } + + return result; +} + +} // namespace + namespace orbit_command_line_utils { TEST(CommandLineUtils, RemoveFlagsNotPassedToMainWindow) { @@ -25,7 +40,7 @@ TEST(CommandLineUtils, RemoveFlagsNotPassedToMainWindow) { "--ssh_key_path=another_path"}; QStringList expected{"--some_bool", "-b", "--some_flag"}; QStringList result = RemoveFlagsNotPassedToMainWindow(params); - EXPECT_EQ(expected, result); + EXPECT_EQ(QStringListToStdVector(expected), QStringListToStdVector(result)); } TEST(CommandLineUtils, ExtractCommandLineFlags) { @@ -38,7 +53,7 @@ TEST(CommandLineUtils, ExtractCommandLineFlags) { auto result = ExtractCommandLineFlags(command_line_args, positional_args); QStringList expected{"-b", "--test_arg", "--another_arg=something"}; - EXPECT_EQ(expected, result); + EXPECT_EQ(QStringListToStdVector(expected), QStringListToStdVector(result)); } } // namespace orbit_command_line_utils \ No newline at end of file diff --git a/src/OrbitGl/CMakeLists.txt b/src/OrbitGl/CMakeLists.txt index 6e0b294c708..1e257139a3c 100644 --- a/src/OrbitGl/CMakeLists.txt +++ b/src/OrbitGl/CMakeLists.txt @@ -7,6 +7,8 @@ cmake_minimum_required(VERSION 3.15) project(OrbitGl CXX) add_library(OrbitGl STATIC) +target_compile_definitions(OrbitGl PUBLIC WIN32_LEAN_AND_MEAN) + target_sources( OrbitGl PUBLIC include/OrbitGl/AccessibleButton.h diff --git a/src/Test/CMakeLists.txt b/src/Test/CMakeLists.txt index 9a35d1dfd7f..bfc322b6c83 100644 --- a/src/Test/CMakeLists.txt +++ b/src/Test/CMakeLists.txt @@ -1,42 +1,22 @@ # Copyright (c) 2021 The Orbit Authors. All rights reserved. # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. -# gtest -# gmock -# gtest_main -# gmock_main cmake_minimum_required(VERSION 3.15) -# if(NOT TARGET GTest::Main) -# message(FATAL_ERROR "GTest::Main is NOT already being used!") -# endif() - -# if(TARGET GTest::Main) -# message(FATAL_ERROR "GTest::Main is already being used!") -# endif() - -# if(NOT TARGET GTest::Main) -# message(FATAL_ERROR "GTest::Main is being used!") add_library(GTest_Main OBJECT EXCLUDE_FROM_ALL test_main.cpp Path.cpp) target_include_directories(GTest_Main PUBLIC include/) target_link_libraries(GTest_Main PUBLIC OrbitBase GTest::gtest GTest::gmock) -#add_library(GTest::Main ALIAS GTest_Main) -#endif() -#if(NOT TARGET GTest::QtCoreMain AND TARGET Qt5::Core) - add_library(GTest_QtCoreMain OBJECT EXCLUDE_FROM_ALL test_qtcore_main.cpp Path.cpp) - target_include_directories(GTest_QtCoreMain PUBLIC include/) - target_link_libraries(GTest_QtCoreMain PUBLIC OrbitBase GTest::gtest GTest::gmock Qt5::Core) +add_library(GTest_QtCoreMain OBJECT EXCLUDE_FROM_ALL test_qtcore_main.cpp Path.cpp) +target_include_directories(GTest_QtCoreMain PUBLIC include/) +target_link_libraries(GTest_QtCoreMain PUBLIC OrbitBase GTest::gtest GTest::gmock Qt5::Core) add_library(GTest::QtCoreMain ALIAS GTest_QtCoreMain) -# endif() -# if(NOT TARGET GTest::QtGuiMain AND TARGET Qt5::Widgets) - add_library(GTest_QtGuiMain OBJECT EXCLUDE_FROM_ALL test_qtgui_main.cpp Path.cpp) - target_include_directories(GTest_QtGuiMain PUBLIC include/) - target_link_libraries(GTest_QtGuiMain PUBLIC OrbitBase GTest::gtest GTest::gmock Qt5::Widgets absl::strings) +add_library(GTest_QtGuiMain OBJECT EXCLUDE_FROM_ALL test_qtgui_main.cpp Path.cpp) +target_include_directories(GTest_QtGuiMain PUBLIC include/) +target_link_libraries(GTest_QtGuiMain PUBLIC OrbitBase GTest::gtest GTest::gmock Qt5::Widgets absl::strings) add_library(GTest::QtGuiMain ALIAS GTest_QtGuiMain) -# endif() add_executable(TestTests StringViewTest.cpp) target_link_libraries(TestTests PRIVATE GTest::Main) From b7c411f93e76a581d7576cc2802f7020c3c52dae Mon Sep 17 00:00:00 2001 From: Pierric Gimmig Date: Sat, 4 Jan 2025 21:57:01 -0800 Subject: [PATCH 5/8] Linux compiling with conan 2, clean-up required --- CMakeLists.txt | 20 +- conanfile.py | 6 +- src/CaptureClient/CMakeLists.txt | 4 - src/ClientData/CMakeLists.txt | 5 - src/ObjectUtils/CMakeLists.txt | 2 - src/OrbitBase/AnyErrorOfTest.cpp | 169 - src/OrbitBase/CMakeLists.txt | 2 - src/OrbitBase/include/OrbitBase/AnyErrorOf.h | 133 - src/ProcessService/CMakeLists.txt | 6 - .../TrampolineTest.cpp | 2724 ++++++++--------- third_party/libunwindstack/CMakeLists.txt | 393 ++- 11 files changed, 1566 insertions(+), 1898 deletions(-) delete mode 100644 src/OrbitBase/AnyErrorOfTest.cpp delete mode 100644 src/OrbitBase/include/OrbitBase/AnyErrorOf.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 5d3d226133a..15e25b62d23 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -67,13 +67,13 @@ set(CMAKE_EXPORT_COMPILE_COMMANDS ON) option(WITH_GUI "Setting this option will enable the Qt-based UI client." ON) -if(NOT WIN32) - option(WITH_VULKAN "Setting this option will enable Vulkan" ON) +#if(NOT WIN32) +# option(WITH_VULKAN "Setting this option will enable Vulkan" ON) - if(WITH_VULKAN) - add_definitions(-DVULKAN_ENABLED) - endif() -endif() +# if(WITH_VULKAN) +# add_definitions(-DVULKAN_ENABLED) +# endif() +#endif() # This is only for designated initializers if(WIN32) @@ -82,6 +82,8 @@ else() set(CMAKE_CXX_STANDARD 17) endif() set(CMAKE_CXX_STANDARD_REQUIRED ON) +set(CMAKE_CXX_EXTENSIONS ON) + list(APPEND CMAKE_MODULE_PATH "${CMAKE_BINARY_DIR}" "${CMAKE_SOURCE_DIR}/cmake") @@ -104,7 +106,7 @@ find_package(Threads REQUIRED) find_package(xxHash REQUIRED) find_package(concurrentqueue REQUIRED) find_package(gte REQUIRED) -find_package(libprotobuf-mutator REQUIRED) +#find_package(libprotobuf-mutator REQUIRED) find_package(LZMA REQUIRED) find_package(absl REQUIRED) find_package(LLVM REQUIRED) @@ -144,7 +146,7 @@ endif() include("cmake/protobuf.cmake") include("cmake/grpc_helper.cmake") -include("cmake/fuzzing.cmake") +#include("cmake/fuzzing.cmake") include("cmake/tests.cmake") include("cmake/iwyu.cmake") enable_testing() @@ -211,7 +213,7 @@ add_subdirectory(src/Containers) add_subdirectory(src/CrashService) add_subdirectory(src/DisplayFormats) add_subdirectory(src/FakeProducerSideService) -add_subdirectory(src/FuzzingUtils) +#add_subdirectory(src/FuzzingUtils) add_subdirectory(src/GrpcProtos) add_subdirectory(src/Introspection) add_subdirectory(src/ModuleUtils) diff --git a/conanfile.py b/conanfile.py index 2e9235b1504..31dcf1081c3 100644 --- a/conanfile.py +++ b/conanfile.py @@ -21,9 +21,9 @@ def requirements(self): self.requires("outcome/2.2.9") self.requires("llvm-core/13.0.0") if self.settings.os != "Windows": - self.requires("volk/1.3.268.0") - self.requires("vulkan-headers/1.3.290.0") - self.requires("vulkan-validationlayers/1.3.290.0") + self.requires("volk/1.3.239.0") + self.requires("vulkan-headers/1.3.239") + #self.requires("vulkan-validationlayers/1.3.239.0") self.requires("zlib/1.3.1", override=True) self.requires("openssl/3.3.2", override=True) self.requires("libssh2/1.11.0") diff --git a/src/CaptureClient/CMakeLists.txt b/src/CaptureClient/CMakeLists.txt index 7997f20eb22..10b14549a80 100644 --- a/src/CaptureClient/CMakeLists.txt +++ b/src/CaptureClient/CMakeLists.txt @@ -38,10 +38,6 @@ target_link_libraries(CaptureClient PUBLIC GrpcProtos Introspection) -add_fuzzer(CaptureEventProcessorProcessEventsFuzzer CaptureEventProcessorProcessEventsFuzzer.cpp) -target_link_libraries(CaptureEventProcessorProcessEventsFuzzer - PRIVATE CaptureClient FuzzingUtils) - add_executable(CaptureClientTests) target_sources(CaptureClientTests PRIVATE diff --git a/src/ClientData/CMakeLists.txt b/src/ClientData/CMakeLists.txt index 69025534808..f9c9f44a93a 100644 --- a/src/ClientData/CMakeLists.txt +++ b/src/ClientData/CMakeLists.txt @@ -126,8 +126,3 @@ target_link_libraries(ClientDataTests PRIVATE GTest_Main) register_test(ClientDataTests) - -add_fuzzer(ModuleLoadSymbolsFuzzer ModuleLoadSymbolsFuzzer.cpp) -target_link_libraries( - ModuleLoadSymbolsFuzzer PRIVATE ClientData - FuzzingUtils) \ No newline at end of file diff --git a/src/ObjectUtils/CMakeLists.txt b/src/ObjectUtils/CMakeLists.txt index 8c16abf65c3..5e734781e13 100644 --- a/src/ObjectUtils/CMakeLists.txt +++ b/src/ObjectUtils/CMakeLists.txt @@ -98,5 +98,3 @@ target_link_libraries( register_test(ObjectUtilsTests) -add_fuzzer(ElfFileLoadSymbolsFuzzer ElfFileLoadSymbolsFuzzer.cpp) -target_link_libraries(ElfFileLoadSymbolsFuzzer FuzzingUtils ObjectUtils) diff --git a/src/OrbitBase/AnyErrorOfTest.cpp b/src/OrbitBase/AnyErrorOfTest.cpp deleted file mode 100644 index 047baf92690..00000000000 --- a/src/OrbitBase/AnyErrorOfTest.cpp +++ /dev/null @@ -1,169 +0,0 @@ -// Copyright (c) 2023 The Orbit Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include -#include - -#include -#include -#include -#include - -#include "OrbitBase/AnyErrorOf.h" -#include "OrbitBase/Result.h" -#include "TestUtils/TestUtils.h" - -namespace orbit_base { -using orbit_test_utils::HasError; -using testing::Eq; - -namespace { -// We are defining 6 arbitrary error types here. E1..E3 are copyable, while U1...U3 are move-only. -// All error types need to have `.message()` member function that returns something convertible to -// `std::string`. - -template -struct ErrorBase { - [[nodiscard]] static std::string_view message() { return {}; } - - // The error types don't hold any state, so all instances are equal to each other. - [[nodiscard]] friend bool operator==(const T& /*unused*/, const T& /*unused*/) { return true; } - [[nodiscard]] friend bool operator!=(const T& /*unused*/, const T& /*unused*/) { return false; } -}; - -struct E1 : ErrorBase {}; -struct E2 : ErrorBase {}; -struct E3 : ErrorBase {}; - -template -struct MoveOnlyErrorBase : ErrorBase { - MoveOnlyErrorBase() = default; - MoveOnlyErrorBase(const MoveOnlyErrorBase&) = delete; - MoveOnlyErrorBase(MoveOnlyErrorBase&&) = default; - MoveOnlyErrorBase& operator=(const MoveOnlyErrorBase&) = delete; - MoveOnlyErrorBase& operator=(MoveOnlyErrorBase&&) = default; -}; - -struct U1 : MoveOnlyErrorBase {}; -struct U2 : MoveOnlyErrorBase {}; -struct U3 : MoveOnlyErrorBase {}; -} // namespace - -TEST(AnyErrorOf, CopyConstructionFromErrorType) { - E1 error_value{}; - - // Copy construction - AnyErrorOf error{error_value}; - - EXPECT_TRUE(std::holds_alternative(error)); - EXPECT_EQ(error, E1{}); - EXPECT_NE(error, E2{}); -} - -TEST(AnyErrorOf, MoveConstructionFromErrorType) { - // Move construction - AnyErrorOf error{U1{}}; - - EXPECT_TRUE(std::holds_alternative(error)); - EXPECT_EQ(error, U1{}); - EXPECT_NE(error, E2{}); -} - -TEST(AnyErrorOf, CopyAssignmentFromErrorType) { - E2 error_value{}; - AnyErrorOf error{E1{}}; - - // Copy assignment - error = error_value; - - EXPECT_TRUE(std::holds_alternative(error)); - EXPECT_NE(error, E1{}); - EXPECT_EQ(error, E2{}); -} - -TEST(AnyErrorOf, MoveAssignmentFromErrorType) { - AnyErrorOf error{E1{}}; - - // Move assignment - error = U2{}; - - EXPECT_TRUE(std::holds_alternative(error)); - EXPECT_NE(error, E1{}); - EXPECT_EQ(error, U2{}); -} - -TEST(AnyErrorOf, CopyConstructionFromCompatibleAnyErrorOf) { - AnyErrorOf source{E2{}}; - - // Copy construction - AnyErrorOf destination{source}; - - EXPECT_TRUE(std::holds_alternative(destination)); - EXPECT_NE(destination, E1{}); - EXPECT_EQ(destination, E2{}); - EXPECT_NE(destination, E3{}); -} - -TEST(AnyErrorOf, MoveConstructionFromCompatibleAnyErrorOf) { - AnyErrorOf source{U2{}}; - - // Move construction - AnyErrorOf destination{std::move(source)}; - - EXPECT_TRUE(std::holds_alternative(destination)); - EXPECT_NE(destination, E1{}); - EXPECT_EQ(destination, U2{}); - EXPECT_NE(destination, E3{}); -} - -TEST(AnyErrorOf, CopyAssignmentFromCompatibleAnyErrorOf) { - AnyErrorOf source{E2{}}; - AnyErrorOf destination{}; - - // Copy assignment - destination = source; - - EXPECT_TRUE(std::holds_alternative(destination)); - EXPECT_NE(destination, E1{}); - EXPECT_EQ(destination, E2{}); - EXPECT_NE(destination, E3{}); -} - -TEST(AnyErrorOf, MoveAssignmentFromCompatibleAnyErrorOf) { - AnyErrorOf source{E2{}}; - AnyErrorOf destination{}; - - // Move assignment - destination = std::move(source); - - EXPECT_TRUE(std::holds_alternative(destination)); - EXPECT_NE(destination, U1{}); - EXPECT_EQ(destination, E2{}); - EXPECT_NE(destination, E3{}); -} - -TEST(AnyErrorOf, OutcomeTryConstructsAnyErrorOfFromErrorType) { - const auto converts_result = [&]() -> Result> { - // Imagine we call a function that returns `ErrorMessageOr`, but we have to return - // `Result>`. The needed conversion should be - // seamless. - OUTCOME_TRY((Result{E1{}})); - return outcome::success(); - }; - - EXPECT_THAT(converts_result(), HasError(Eq(E1{}))); -} - -TEST(AnyErrorOf, OutcomeTryConstructsAnyErrorOfFromCompatibleAnyErrorOf) { - const auto converts_result = [&]() -> Result> { - // Imagine we call a function that returns `Result>`, - // but we have to return `Result>`. - // The needed conversion should be seamless. - OUTCOME_TRY((Result>{E1{}})); - return outcome::success(); - }; - - EXPECT_THAT(converts_result(), HasError(Eq(E1{}))); -} -} // namespace orbit_base diff --git a/src/OrbitBase/CMakeLists.txt b/src/OrbitBase/CMakeLists.txt index cfb94478007..c485e2bdf33 100644 --- a/src/OrbitBase/CMakeLists.txt +++ b/src/OrbitBase/CMakeLists.txt @@ -17,7 +17,6 @@ target_include_directories(OrbitBase PRIVATE target_sources(OrbitBase PRIVATE include/OrbitBase/Action.h include/OrbitBase/Align.h - include/OrbitBase/AnyErrorOf.h include/OrbitBase/AnyInvocable.h include/OrbitBase/AnyMovable.h include/OrbitBase/Append.h @@ -109,7 +108,6 @@ add_executable(OrbitBaseTests) target_sources(OrbitBaseTests PRIVATE AlignTest.cpp AnyInvocableTest.cpp - AnyErrorOfTest.cpp AnyMovableTest.cpp AppendTest.cpp CanceledOrTest.cpp diff --git a/src/OrbitBase/include/OrbitBase/AnyErrorOf.h b/src/OrbitBase/include/OrbitBase/AnyErrorOf.h deleted file mode 100644 index f8092eae9d9..00000000000 --- a/src/OrbitBase/include/OrbitBase/AnyErrorOf.h +++ /dev/null @@ -1,133 +0,0 @@ -// Copyright (c) 2023 The Orbit Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef ORBIT_BASE_ANY_ERROR_OF_H_ -#define ORBIT_BASE_ANY_ERROR_OF_H_ - -#include -#include -#include - -#include "OrbitBase/ParameterPackTrait.h" - -namespace orbit_base { - -// A wrapper around `std::variant` holding one instance of multiple possible error types. It's -// mainly meant to be used with `Result` (`Result`) in cases where a function -// may return one of multiple possible error types. `AnyErrorOf` has a `.message()` member -// function that returns the error message of the holding error by forwarding the call to the -// `.message()` function of the holding error. -// -// `AnyErrorOf` behaves like `std::variant` except for the following properties: -// 1. `ErrorTypes...` may not have duplicate types - all types must be unique. -// 2. An empty list of `ErrorTypes...` is not allowed. -// 3. All error types must have a `.message()` function that's either marked `const` or `static` and -// that returns something that's convertible to `std::string`. -// 4. `AnyErrorOf` can be converted into `AnyErrorOf` if `T2s` contains at least all -// the types present in `T1s`. The order of the types has no meaning. -// 5. `AnyErrorOf` can be directly compared (equality and inequality) to a value of one of its error -// types if the given error type defines an equality comparison operator. The compared values are -// considered equal if `AnyErrorOf` holds a value of the comparing error type and if the equality -// comparison operator returns true. -template -class AnyErrorOf : public std::variant { - using Base = std::variant; - - public: - using Base::Base; - using Base::operator=; - - static_assert(ParameterPackTrait::kSize >= 1, - "AnyError<> (AnyErrorOf with no error types) is not allowed."); - - static_assert(!ParameterPackTrait::kHasDuplicates, - "AnyError must not have duplicate error types."); - - template - constexpr static bool kCanBeConstructedFromTypesAndIsNotCopy = [] { - constexpr ParameterPackTrait kThisTrait{}; - constexpr ParameterPackTrait kOtherTrait{}; - - // We return false if `AnyErrorOf` is the same type as `AnyErrorOf`. - // This avoids collisions with the copy and move constructors/assignment operators. - if (kThisTrait == kOtherTrait) return false; - - // We only allow conversion from an instance of `AnyErrorOf` with `Types` being a - // subset of `ErrorTypes`. - return kThisTrait.IsSubset(kOtherTrait); - }(); - - template - using EnableIfCanBeConstructedFromTypesAndIsNotCopy = - std::enable_if_t, int>; - - // Is true iff `Type` is in the `ErrorTypes...` parameter pack. - template - constexpr static bool kIsAnErrorType = - ParameterPackTrait::template kContains; - - template - auto ToBase(Variant&& other) { - return std::visit( - [](auto&& alternative) -> Base { return std::forward(alternative); }, - std::forward(other)); - } - - // The following converting constructors/assignment operators allow conversion of any AnyErrorOf - // type into a compatible AnyErrorOf type. An AnyErrorOf type is considered compatible - // if its error type list is a super set of the other's error type list. The order of the types - // doesn't matter though. - // - // Examples: - // - AnyErrorOf can be converted into AnyErrorOf but not into AnyErrorOf. - // - AnyErrorOf can be converted into AnyErrorOf. - // - AnyErrorOf can be converted into AnyErrorOf. - template = 0> - // NOLINTNEXTLINE(google-explicit-constructor) - AnyErrorOf(const AnyErrorOf& other) : Base{ToBase(other)} {} - - template = 0> - // NOLINTNEXTLINE(google-explicit-constructor) - AnyErrorOf(AnyErrorOf&& other) : Base{ToBase(std::move(other))} {} - - template = 0> - AnyErrorOf& operator=(const AnyErrorOf& other) { - *this = ToBase(other); - return *this; - } - - template = 0> - AnyErrorOf& operator=(AnyErrorOf&& other) { - *this = ToBase(std::move(other)); - return *this; - } - - [[nodiscard]] std::string message() const { - return std::visit([](const auto& error) { return std::string{error.message()}; }, *this); - } - - // We allow transparent comparison with any of the error types. - template , int> = 0> - [[nodiscard]] friend bool operator==(const AnyErrorOf& lhs, const T& rhs) { - return std::holds_alternative(lhs) && std::get(lhs) == rhs; - } - - template , int> = 0> - [[nodiscard]] friend bool operator==(const T& lhs, const AnyErrorOf& rhs) { - return std::holds_alternative(lhs) && std::get(lhs) == rhs; - } - - template , int> = 0> - [[nodiscard]] friend bool operator!=(const AnyErrorOf& lhs, const T& rhs) { - return !(lhs == rhs); - } - - template , int> = 0> - [[nodiscard]] friend bool operator!=(const T& lhs, const AnyErrorOf& rhs) { - return !(lhs == rhs); - } -}; -} // namespace orbit_base - -#endif // ORBIT_BASE_ANY_ERROR_OF_H_ diff --git a/src/ProcessService/CMakeLists.txt b/src/ProcessService/CMakeLists.txt index 8bcc7112a6e..b2835f76986 100644 --- a/src/ProcessService/CMakeLists.txt +++ b/src/ProcessService/CMakeLists.txt @@ -45,9 +45,3 @@ target_link_libraries(ProcessServiceTests PRIVATE register_test(ProcessServiceTests PROPERTIES TIMEOUT 10) -add_fuzzer(ProcessServiceUtilsFindSymbolsFilePathFuzzer - ProcessServiceUtilsFindSymbolsFilePathFuzzer.cpp) - -target_link_libraries(ProcessServiceUtilsFindSymbolsFilePathFuzzer PRIVATE - FuzzingUtils - ProcessService) diff --git a/src/UserSpaceInstrumentation/TrampolineTest.cpp b/src/UserSpaceInstrumentation/TrampolineTest.cpp index eec24dd7986..d41fb6935ca 100644 --- a/src/UserSpaceInstrumentation/TrampolineTest.cpp +++ b/src/UserSpaceInstrumentation/TrampolineTest.cpp @@ -1,1362 +1,1362 @@ -// Copyright (c) 2021 The Orbit Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "AccessTraceesMemory.h" -#include "AllocateInTracee.h" -#include "GetTestLibLibraryPath.h" -#include "GrpcProtos/module.pb.h" -#include "MachineCode.h" -#include "ModuleUtils/ReadLinuxModules.h" -#include "OrbitBase/ExecutablePath.h" -#include "OrbitBase/Logging.h" -#include "OrbitBase/Result.h" -#include "TestUtils.h" -#include "TestUtils/TestUtils.h" -#include "Trampoline.h" -#include "UserSpaceInstrumentation/AddressRange.h" -#include "UserSpaceInstrumentation/Attach.h" -#include "UserSpaceInstrumentation/InjectLibraryInTracee.h" - -namespace orbit_user_space_instrumentation { -using orbit_test_utils::HasErrorWithMessage; - -namespace { - -using orbit_test_utils::HasErrorWithMessage; -using orbit_test_utils::HasNoError; -using orbit_test_utils::HasValue; -using testing::ElementsAreArray; - -constexpr const char* kEntryPayloadFunctionName = "EntryPayload"; -constexpr const char* kExitPayloadFunctionName = "ExitPayload"; - -extern "C" __attribute__((noinline)) int DoubleAndIncrement(int i) { - i = 2 * i; - return i + 1; -} - -} // namespace - -TEST(TrampolineTest, DoAddressRangesOverlap) { - AddressRange a = {3, 7}; - AddressRange b1 = {1, 2}; - EXPECT_FALSE(DoAddressRangesOverlap(a, b1)); - AddressRange b2 = {1, 3}; - EXPECT_FALSE(DoAddressRangesOverlap(a, b2)); - AddressRange b3 = {1, 4}; - EXPECT_TRUE(DoAddressRangesOverlap(a, b3)); - AddressRange b4 = {1, 9}; - EXPECT_TRUE(DoAddressRangesOverlap(a, b4)); - AddressRange b5 = {4, 5}; - EXPECT_TRUE(DoAddressRangesOverlap(a, b5)); - AddressRange b6 = {4, 9}; - EXPECT_TRUE(DoAddressRangesOverlap(a, b6)); - AddressRange b7 = {7, 9}; - EXPECT_FALSE(DoAddressRangesOverlap(a, b7)); - AddressRange b8 = {8, 9}; - EXPECT_FALSE(DoAddressRangesOverlap(a, b8)); -} - -TEST(TrampolineTest, LowestIntersectingAddressRange) { - const std::vector all_ranges = {{0, 5}, {20, 30}, {40, 60}}; - - EXPECT_FALSE(LowestIntersectingAddressRange({}, {0, 60}).has_value()); - - EXPECT_EQ(0, LowestIntersectingAddressRange(all_ranges, {1, 2})); - EXPECT_EQ(1, LowestIntersectingAddressRange(all_ranges, {21, 22})); - EXPECT_EQ(2, LowestIntersectingAddressRange(all_ranges, {51, 52})); - - EXPECT_EQ(0, LowestIntersectingAddressRange(all_ranges, {3, 6})); - EXPECT_EQ(1, LowestIntersectingAddressRange(all_ranges, {19, 22})); - EXPECT_EQ(2, LowestIntersectingAddressRange(all_ranges, {30, 52})); - - EXPECT_EQ(0, LowestIntersectingAddressRange(all_ranges, {4, 72})); - EXPECT_EQ(1, LowestIntersectingAddressRange(all_ranges, {29, 52})); - EXPECT_EQ(2, LowestIntersectingAddressRange(all_ranges, {59, 72})); - - EXPECT_FALSE(LowestIntersectingAddressRange(all_ranges, {5, 20}).has_value()); - EXPECT_FALSE(LowestIntersectingAddressRange(all_ranges, {30, 40}).has_value()); - EXPECT_FALSE(LowestIntersectingAddressRange(all_ranges, {60, 80}).has_value()); -} - -TEST(TrampolineTest, HighestIntersectingAddressRange) { - const std::vector all_ranges = {{0, 5}, {20, 30}, {40, 60}}; - - EXPECT_FALSE(HighestIntersectingAddressRange({}, {0, 60}).has_value()); - - EXPECT_EQ(0, HighestIntersectingAddressRange(all_ranges, {1, 2})); - EXPECT_EQ(1, HighestIntersectingAddressRange(all_ranges, {21, 22})); - EXPECT_EQ(2, HighestIntersectingAddressRange(all_ranges, {51, 52})); - - EXPECT_EQ(0, HighestIntersectingAddressRange(all_ranges, {3, 6})); - EXPECT_EQ(1, HighestIntersectingAddressRange(all_ranges, {19, 22})); - EXPECT_EQ(2, HighestIntersectingAddressRange(all_ranges, {30, 52})); - - EXPECT_EQ(2, HighestIntersectingAddressRange(all_ranges, {4, 72})); - EXPECT_EQ(2, HighestIntersectingAddressRange(all_ranges, {29, 52})); - EXPECT_EQ(2, HighestIntersectingAddressRange(all_ranges, {59, 72})); - - EXPECT_FALSE(HighestIntersectingAddressRange(all_ranges, {5, 20}).has_value()); - EXPECT_FALSE(HighestIntersectingAddressRange(all_ranges, {30, 40}).has_value()); - EXPECT_FALSE(HighestIntersectingAddressRange(all_ranges, {60, 80}).has_value()); -} - -TEST(TrampolineTest, FindAddressRangeForTrampoline) { - constexpr uint64_t k1Kb = 0x400; - constexpr uint64_t k64Kb = 0x10000; - constexpr uint64_t kOneMb = 0x100000; - constexpr uint64_t k256Mb = 0x10000000; - constexpr uint64_t kOneGb = 0x40000000; - - // Trivial placement to the left. - const std::vector unavailable_ranges1 = { - {0, k64Kb}, {kOneGb, 2 * kOneGb}, {3 * kOneGb, 4 * kOneGb}}; - auto address_range_or_error = - FindAddressRangeForTrampoline(unavailable_ranges1, {kOneGb, 2 * kOneGb}, k256Mb); - ASSERT_FALSE(address_range_or_error.has_error()); - EXPECT_EQ(kOneGb - k256Mb, address_range_or_error.value().start); - - // Placement to the left just fits. - const std::vector unavailable_ranges2 = { - {0, k64Kb}, {k256Mb, kOneGb}, {3 * kOneGb, 4 * kOneGb}}; - address_range_or_error = - FindAddressRangeForTrampoline(unavailable_ranges2, {k256Mb, kOneGb}, k256Mb - k64Kb); - ASSERT_FALSE(address_range_or_error.has_error()); - EXPECT_EQ(k64Kb, address_range_or_error.value().start); - - // Placement to the left fails due to page alignment. So we place to the right which fits - // trivially. - const std::vector unavailable_ranges3 = { - {0, k64Kb + 1}, {k256Mb, kOneGb}, {3 * kOneGb, 4 * kOneGb}}; - address_range_or_error = - FindAddressRangeForTrampoline(unavailable_ranges3, {k256Mb, kOneGb}, k256Mb - k64Kb - 5); - ASSERT_FALSE(address_range_or_error.has_error()); - EXPECT_EQ(kOneGb, address_range_or_error.value().start); - - // Placement to the left just fits but only after a few hops. - const std::vector unavailable_ranges4 = { - {0, k64Kb}, // this is the gap that just fits - {k64Kb + kOneMb, 6 * kOneMb}, - {6 * kOneMb + kOneMb - 1, 7 * kOneMb}, - {7 * kOneMb + kOneMb - 1, 8 * kOneMb}, - {8 * kOneMb + kOneMb - 1, 9 * kOneMb}}; - address_range_or_error = FindAddressRangeForTrampoline( - unavailable_ranges4, {8 * kOneMb + kOneMb - 1, 9 * kOneMb}, kOneMb); - ASSERT_FALSE(address_range_or_error.has_error()); - EXPECT_EQ(k64Kb, address_range_or_error.value().start); - - // No space to the left but trivial placement to the right. - const std::vector unavailable_ranges5 = { - {0, k64Kb}, {kOneMb, kOneGb}, {5 * kOneGb, 6 * kOneGb}}; - address_range_or_error = - FindAddressRangeForTrampoline(unavailable_ranges5, {kOneMb, kOneGb}, kOneMb); - ASSERT_FALSE(address_range_or_error.has_error()) << address_range_or_error.error().message(); - EXPECT_EQ(kOneGb, address_range_or_error.value().start); - - // No space to the left but placement to the right works after a few hops. - const std::vector unavailable_ranges6 = { - {0, k64Kb}, - {kOneMb, kOneGb}, - {kOneGb + 0x01 * kOneMb - 1, kOneGb + 0x10 * kOneMb}, - {kOneGb + 0x11 * kOneMb - 1, kOneGb + 0x20 * kOneMb}, - {kOneGb + 0x21 * kOneMb - 1, kOneGb + 0x30 * kOneMb}, - {kOneGb + 0x31 * kOneMb - 1, kOneGb + 0x40 * kOneMb}}; - address_range_or_error = - FindAddressRangeForTrampoline(unavailable_ranges6, {kOneMb, kOneGb}, kOneMb); - ASSERT_FALSE(address_range_or_error.has_error()) << address_range_or_error.error().message(); - EXPECT_EQ(kOneGb + 0x40 * kOneMb, address_range_or_error.value().start); - - // No space to the left and the last segment nearly fills up the 64 bit address space. So no - // placement is possible. - const std::vector unavailable_ranges7 = { - {0, k64Kb}, - {kOneMb, k256Mb}, - {1 * k256Mb + kOneMb - 1, 2 * k256Mb}, - {2 * k256Mb + kOneMb - 1, 3 * k256Mb}, - {3 * k256Mb + kOneMb - 1, 4 * k256Mb + 1}, // this gap is large but alignment doesn't fit - {4 * k256Mb + kOneMb + 2, 5 * k256Mb}, - {5 * k256Mb + kOneMb - 1, 0xffffffffffffffff - kOneMb / 2}}; - address_range_or_error = - FindAddressRangeForTrampoline(unavailable_ranges7, {kOneMb, k256Mb}, kOneMb); - ASSERT_TRUE(address_range_or_error.has_error()); - - // There is no sufficiently large gap in the mappings in the 2GB below the code segment. So the - // trampoline is placed above the code segment. Also we test that the trampoline starts at the - // next memory page above last taken segment. - const std::vector unavailable_ranges8 = { - {0, k64Kb}, // huge gap here, but it's too far away - {0x10 * kOneGb, 0x11 * kOneGb}, - {0x11 * kOneGb + kOneMb - 1, 0x12 * kOneGb}, - {0x12 * kOneGb + kOneMb - 1, 0x12 * kOneGb + 2 * kOneMb + 42}}; - address_range_or_error = FindAddressRangeForTrampoline( - unavailable_ranges8, {0x12 * kOneGb + kOneMb - 1, 0x12 * kOneGb + 2 * kOneMb}, kOneMb); - ASSERT_FALSE(address_range_or_error.has_error()) << address_range_or_error.error().message(); - constexpr uint64_t kPageSize = 4096; - constexpr uint64_t kNextPage = - (((0x12 * kOneGb + 2 * kOneMb + 42) + (kPageSize - 1)) / kPageSize) * kPageSize; - EXPECT_EQ(kNextPage, address_range_or_error.value().start); - - // There is no sufficiently large gap in the mappings in the 2GB below the code segment. And there - // also is no gap large enough in the 2GB above the code segment. So no placement is possible. - const std::vector unavailable_ranges9 = { - {0, k64Kb}, // huge gap here, but it's too far away - {0x10 * kOneGb + kOneMb - 1, 0x11 * kOneGb}, - {0x11 * kOneGb + kOneMb - 1, 0x12 * kOneGb}, - {0x12 * kOneGb + kOneMb - 1, 0x12 * kOneGb + 2 * kOneMb}, - {0x12 * kOneGb + 3 * kOneMb - 1, 0x13 * kOneGb + 1}, - {0x13 * kOneGb + kOneMb + 42, 0x14 * kOneGb}}; - address_range_or_error = FindAddressRangeForTrampoline( - unavailable_ranges9, {0x12 * kOneGb + kOneMb - 1, 0x12 * kOneGb + 2 * kOneMb}, kOneMb); - ASSERT_TRUE(address_range_or_error.has_error()); - - // Fail on malformed input: first address range does not start at zero. - const std::vector unavailable_ranges10 = {{k64Kb, kOneGb}}; - EXPECT_DEATH( - auto result = FindAddressRangeForTrampoline(unavailable_ranges10, {k64Kb, kOneGb}, kOneMb), - "needs to start at zero"); - - // Placement to the left fails since the requested memory chunk is too big. So we place to the - // right which fits trivially. - // The special case here is that the requested memory size (k256Mb + k64Kb) is larger than the - // left interval border of the second interval (k256Mb). This produced an artithmetic overflow in - // a previous version of the algorithm. - const std::vector unavailable_ranges11 = {{0, k64Kb}, {k256Mb, kOneGb}}; - address_range_or_error = - FindAddressRangeForTrampoline(unavailable_ranges11, {k256Mb, kOneGb}, k256Mb + k64Kb); - ASSERT_FALSE(address_range_or_error.has_error()); - EXPECT_EQ(kOneGb, address_range_or_error.value().start); - - // Placement to the left fails, placement to the right fails also because we are close to the end - // of the address space. This produced an artithmetic overflow in a previous version of the - // algorithm. - const std::vector unavailable_ranges12 = { - {0, k64Kb}, - {UINT64_MAX - 10 * kOneGb, UINT64_MAX - k64Kb - 1}, - {UINT64_MAX - k64Kb, UINT64_MAX - k1Kb}}; - address_range_or_error = FindAddressRangeForTrampoline( - unavailable_ranges12, {UINT64_MAX - k64Kb, UINT64_MAX - k1Kb}, k64Kb); - ASSERT_THAT(address_range_or_error, HasErrorWithMessage("No place to fit")); - - // We can not fit anything close to a range larger than 2GB. - const std::vector unavailable_ranges13 = {{0, k64Kb}, {kOneGb, 4 * kOneGb}}; - address_range_or_error = - FindAddressRangeForTrampoline(unavailable_ranges13, {kOneGb, 4 * kOneGb}, k64Kb); - ASSERT_THAT(address_range_or_error, HasErrorWithMessage("No place to fit")); -} - -TEST(TrampolineTest, AllocateMemoryForTrampolines) { - pid_t pid = fork(); - ORBIT_CHECK(pid != -1); - if (pid == 0) { - prctl(PR_SET_PDEATHSIG, SIGTERM); - - [[maybe_unused]] volatile uint64_t sum = 0; - // Endless loops without side effects are UB and recent versions of clang optimize - // it away. Making `i` volatile avoids that problem. - volatile int i = 0; - while (true) { - i = (i + 1) & 3; - sum += DoubleAndIncrement(i); - } - } - - // Stop the process using our tooling. - ORBIT_CHECK(AttachAndStopProcess(pid).has_value()); - - // Find the address range of the code for `DoubleAndIncrement`. For the purpose of this test we - // just take the entire address space taken up by `UserSpaceInstrumentationTests`. - auto modules_or_error = orbit_module_utils::ReadModules(pid); - ORBIT_CHECK(!modules_or_error.has_error()); - - auto& modules = modules_or_error.value(); - const auto module = std::find_if(modules.begin(), modules.end(), [&](const auto& module) { - return module.file_path() == orbit_base::GetExecutablePath(); - }); - - ASSERT_NE(module, modules.end()); - const AddressRange code_range{module->address_start(), module->address_end()}; - - // Allocate one megabyte in the tracee. The memory will be close to `code_range`. - constexpr uint64_t kTrampolineSize = 1024 * 1024; - auto memory_or_error = AllocateMemoryForTrampolines(pid, code_range, kTrampolineSize); - ASSERT_FALSE(memory_or_error.has_error()); - - // Check that the tracee is functional: Continue, stop again, free the allocated memory, then run - // briefly again. - ORBIT_CHECK(DetachAndContinueProcess(pid).has_value()); - ORBIT_CHECK(AttachAndStopProcess(pid).has_value()); - ASSERT_THAT(memory_or_error.value()->Free(), HasNoError()); - ORBIT_CHECK(DetachAndContinueProcess(pid).has_value()); - ORBIT_CHECK(AttachAndStopProcess(pid).has_value()); - - // Detach and end child. - ORBIT_CHECK(DetachAndContinueProcess(pid).has_value()); - kill(pid, SIGKILL); - waitpid(pid, nullptr, 0); -} - -TEST(TrampolineTest, AddressDifferenceAsInt32) { - // Result of the difference is negative; in the first case it just fits, the second case - // overflows. - constexpr uint64_t kAddr1 = 0x6012345612345678; - constexpr uint64_t kAddr2Larger = kAddr1 - std::numeric_limits::min(); - auto result = AddressDifferenceAsInt32(kAddr1, kAddr2Larger); - ASSERT_THAT(result, HasNoError()); - EXPECT_EQ(std::numeric_limits::min(), result.value()); - result = AddressDifferenceAsInt32(kAddr1, kAddr2Larger + 1); - EXPECT_THAT(result, HasErrorWithMessage("Difference is larger than -2GB")); - - // Result of the difference is positive; in the first case it just fits, the second case - // overflows. - constexpr uint64_t kAddr2Smaller = kAddr1 - std::numeric_limits::max(); - result = AddressDifferenceAsInt32(kAddr1, kAddr2Smaller); - ASSERT_THAT(result, HasNoError()); - EXPECT_EQ(std::numeric_limits::max(), result.value()); - result = AddressDifferenceAsInt32(kAddr1, kAddr2Smaller - 1); - EXPECT_THAT(result, HasErrorWithMessage("Difference is larger than +2GB")); - - // Result of the difference does not even fit into a int64. We handle that gracefully as well. - constexpr uint64_t kAddrHigh = 0xf234567812345678; - constexpr uint64_t kAddrLow = kAddrHigh - 0xe234567812345678; - result = AddressDifferenceAsInt32(kAddrHigh, kAddrLow); - EXPECT_THAT(result, HasErrorWithMessage("Difference is larger than +2GB")); - result = AddressDifferenceAsInt32(kAddrLow, kAddrHigh); - EXPECT_THAT(result, HasErrorWithMessage("Difference is larger than -2GB")); -} - -class RelocateInstructionTest : public testing::Test { - protected: - void SetUp() override { - ORBIT_CHECK(cs_open(CS_ARCH_X86, CS_MODE_64, &capstone_handle_) == CS_ERR_OK); - ORBIT_CHECK(cs_option(capstone_handle_, CS_OPT_DETAIL, CS_OPT_ON) == CS_ERR_OK); - instruction_ = cs_malloc(capstone_handle_); - ORBIT_CHECK(instruction_ != nullptr); - } - - void Disassemble(const MachineCode& code) { - const uint8_t* code_pointer = code.GetResultAsVector().data(); - size_t code_size = code.GetResultAsVector().size(); - uint64_t disassemble_address = 0; - ORBIT_CHECK(cs_disasm_iter(capstone_handle_, &code_pointer, &code_size, &disassemble_address, - instruction_)); - } - - void TearDown() override { - cs_free(instruction_, 1); - cs_close(&capstone_handle_); - } - - cs_insn* instruction_ = nullptr; - - private: - csh capstone_handle_ = 0; -}; - -TEST_F(RelocateInstructionTest, RipRelativeAddressing) { - MachineCode code; - constexpr int32_t kOffset = 0x969433; - // add qword ptr [rip + kOffset], 1 - // Handled by "((instruction->detail->x86.modrm & 0xC7) == 0x05)" branch in 'RelocateInstruction'. - code.AppendBytes({0x48, 0x83, 0x05}).AppendImmediate32(kOffset).AppendBytes({0x01}); - Disassemble(code); - - constexpr uint64_t kOriginalAddress = 0x0100000000; - ErrorMessageOr result = - RelocateInstruction(instruction_, kOriginalAddress, kOriginalAddress + kOffset - 0x123456); - ASSERT_THAT(result, HasValue()); - // add qword ptr [rip + new_offset], 1 48 83 05 56 34 12 00 01 - // new_offset is computed as - // old_absolute_address - new_address - // == (old_address + old_displacement) - (old_address + old_displacement - 0x123456) - // == 0x123456 - EXPECT_THAT(result.value().code, - ElementsAreArray({0x48, 0x83, 0x05, 0x56, 0x34, 0x12, 0x00, 0x01})); - EXPECT_FALSE(result.value().position_of_absolute_address.has_value()); - - result = - RelocateInstruction(instruction_, kOriginalAddress, kOriginalAddress + kOffset + 0x123456); - ASSERT_THAT(result, HasValue()); - // add qword ptr [rip + new_offset], 1 48 83 05 aa cb ed ff 01 - // new_offset is computed as - // old_absolute_address - new_address - // == (old_address + old_displacement) - (old_address + old_displacement + 0x123456) - // == -0x123456 == 0xffedcbaa - EXPECT_THAT(result.value().code, - ElementsAreArray({0x48, 0x83, 0x05, 0xaa, 0xcb, 0xed, 0xff, 0x01})); - EXPECT_FALSE(result.value().position_of_absolute_address.has_value()); - - result = RelocateInstruction(instruction_, kOriginalAddress, kOriginalAddress - 0x7fff0000); - EXPECT_THAT(result, - HasErrorWithMessage( - "While trying to relocate an instruction with rip relative addressing the " - "target was out of range from the trampoline.")); -} - -TEST_F(RelocateInstructionTest, UnconditionalJumpTo8BitImmediate) { - MachineCode code; - constexpr int8_t kOffset = 0x08; - // jmp [rip + kOffset] - // Handled by "(instruction->detail->x86.opcode[0] == 0xeb)" branch in 'RelocateInstruction'. - code.AppendBytes({0xeb}).AppendImmediate8(kOffset); - Disassemble(code); - - ErrorMessageOr result = - RelocateInstruction(instruction_, 0x0100000000, 0x0200000000); - ASSERT_THAT(result, HasValue()); - // jmp [rip + 0] ff 25 00 00 00 00 - // absolute_address 0a 00 00 00 01 00 00 00 - // original jump instruction ends on 0x0100000000 + 0x02. Adding kOffset (=8) yields 0x010000000a. - EXPECT_THAT(result.value().code, ElementsAreArray({0xff, 0x25, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x00, - 0x00, 0x00, 0x01, 0x00, 0x00, 0x00})); - ASSERT_TRUE(result.value().position_of_absolute_address.has_value()); - EXPECT_EQ(6, result.value().position_of_absolute_address.value()); -} - -TEST_F(RelocateInstructionTest, UnconditionalJumpTo32BitImmediate) { - MachineCode code; - constexpr int32_t kOffset = 0x01020304; - // jmp [rip + kOffset] - // Handled by "(instruction->detail->x86.opcode[0] == 0xe9)" branch in 'RelocateInstruction'. - code.AppendBytes({0xe9}).AppendImmediate32(kOffset); - Disassemble(code); - - ErrorMessageOr result = - RelocateInstruction(instruction_, 0x0100000000, 0x0200000000); - ASSERT_THAT(result, HasValue()); - // jmp [rip + 0] ff 25 00 00 00 00 - // absolute_address 09 03 02 01 01 00 00 00 - // original jump instruction ends on 0x0100000000 + 0x05. Adding kOffset yields 0x0101020309. - EXPECT_THAT(result.value().code, ElementsAreArray({0xff, 0x25, 0x00, 0x00, 0x00, 0x00, 0x09, 0x03, - 0x02, 0x01, 0x01, 0x00, 0x00, 0x00})); - ASSERT_TRUE(result.value().position_of_absolute_address.has_value()); - EXPECT_EQ(6, result.value().position_of_absolute_address.value()); -} - -TEST_F(RelocateInstructionTest, CallInstructionIsNotSupported) { - MachineCode code; - constexpr int32_t kOffset = 0x01020304; - // call [rip + kOffset] - // Handled by "(instruction->detail->x86.opcode[0] == 0xe8)" branch in 'RelocateInstruction'. - code.AppendBytes({0xe8}).AppendImmediate32(kOffset); - Disassemble(code); - - ErrorMessageOr result = - RelocateInstruction(instruction_, 0x0100000000, 0x0200000000); - EXPECT_THAT(result, HasErrorWithMessage("Relocating a call instruction is not supported.")); -} - -TEST_F(RelocateInstructionTest, ConditionalJumpTo8BitImmediate) { - MachineCode code; - constexpr int8_t kOffset = 0x40; - // jno rip + kOffset - // Handled by "((instruction->detail->x86.opcode[0] & 0xf0) == 0x70)" branch in - // 'RelocateInstruction'. - code.AppendBytes({0x71}).AppendImmediate8(kOffset); - Disassemble(code); - - ErrorMessageOr result = - RelocateInstruction(instruction_, 0x0100000000, 0x0200000000); - ASSERT_THAT(result, HasValue()); - // jo rip + 16 70 0e - // jmp [rip + 6] ff 25 00 00 00 00 - // absolute_address 42 00 00 00 01 00 00 00 - // original jump instruction ends on 0x0100000002 + 0x40 (kOffset) == 0x0100000042. - EXPECT_THAT(result.value().code, - ElementsAreArray({0x70, 0x0e, 0xff, 0x25, 0x00, 0x00, 0x00, 0x00, 0x42, 0x00, 0x00, - 0x00, 0x01, 0x00, 0x00, 0x00})); - ASSERT_TRUE(result.value().position_of_absolute_address.has_value()); - EXPECT_EQ(8, result.value().position_of_absolute_address.value()); -} - -TEST_F(RelocateInstructionTest, ConditionalJumpTo32BitImmediate) { - MachineCode code; - constexpr int32_t kOffset = 0x12345678; - // jno rip + kOffset 0f 80 78 56 34 12 - // Handled by "(instruction->detail->x86.opcode[0] == 0x0f && - // (instruction->detail->x86.opcode[1] & 0xf0) == 0x80)" - // branch in 'RelocateInstruction'. - code.AppendBytes({0x0f, 0x80}).AppendImmediate32(kOffset); - Disassemble(code); - - ErrorMessageOr result = - RelocateInstruction(instruction_, 0x0100000000, 0x0200000000); - ASSERT_TRUE(result.has_value()); - // jo rip + 16 71 0e - // jmp [rip +6] ff 25 00 00 00 00 - // absolute_address 7a 56 34 12 01 00 00 00 - // original jump instruction ends on 0x0100000006 + 0x12345678 (kOffset) == 0x011234567e. - EXPECT_THAT(result.value().code, - ElementsAreArray({0x71, 0x0e, 0xff, 0x25, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x56, 0x34, - 0x12, 0x01, 0x00, 0x00, 0x00})); - ASSERT_TRUE(result.value().position_of_absolute_address.has_value()); - EXPECT_EQ(8, result.value().position_of_absolute_address.value()); -} - -TEST_F(RelocateInstructionTest, LoopIsUnsupported) { - MachineCode code; - constexpr int8_t kOffset = 0x40; - // loopz rip + kOffset - // Handled by "((instruction->detail->x86.opcode[0] & 0xfc) == 0xe0)" branch in - // 'RelocateInstruction'. - code.AppendBytes({0xe1}).AppendImmediate8(kOffset); - Disassemble(code); - - ErrorMessageOr result = - RelocateInstruction(instruction_, 0x0100000000, 0x0200000000); - EXPECT_THAT(result, HasErrorWithMessage("Relocating a loop instruction is not supported.")); -} - -TEST_F(RelocateInstructionTest, TrivialTranslation) { - MachineCode code; - // nop - // Handled by "else" branch in 'RelocateInstruction' - instruction is just copied. - code.AppendBytes({0x90}); - Disassemble(code); - - ErrorMessageOr result = - RelocateInstruction(instruction_, 0x0100000000, 0x0200000000); - ASSERT_THAT(result, HasValue()); - EXPECT_THAT(result.value().code, ElementsAreArray({0x90})); - EXPECT_FALSE(result.value().position_of_absolute_address.has_value()); -} - -class InstrumentFunctionTest : public testing::Test { - protected: - void SetUp() override { - /* copybara:insert(b/237251106 injecting the library into the target process triggers some - initilization code that check fails.) - GTEST_SKIP(); - */ - // Init Capstone disassembler. - cs_err error_code = cs_open(CS_ARCH_X86, CS_MODE_64, &capstone_handle_); - ORBIT_CHECK(error_code == CS_ERR_OK); - error_code = cs_option(capstone_handle_, CS_OPT_DETAIL, CS_OPT_ON); - ORBIT_CHECK(error_code == CS_ERR_OK); - - max_trampoline_size_ = GetMaxTrampolineSize(); - } - - void RunChild(int (*function_pointer)(), std::string_view function_name) { - function_name_ = function_name; - - pid_ = fork(); - ORBIT_CHECK(pid_ != -1); - if (pid_ == 0) { - prctl(PR_SET_PDEATHSIG, SIGTERM); - - // Endless loops without side effects are UB and recent versions of clang optimize - // it away. Making `sum` volatile avoids that problem. - [[maybe_unused]] volatile uint64_t sum = 0; - while (true) { - sum += (*function_pointer)(); - } - } - } - - AddressRange GetFunctionAddressRangeOrDie() { - return GetFunctionAbsoluteAddressRangeOrDie(function_name_); - } - - void PrepareInstrumentation(std::string_view entry_payload_function_name, - std::string_view exit_payload_function_name) { - // Stop the child process using our tooling. - ORBIT_CHECK(AttachAndStopProcess(pid_).has_value()); - - auto library_path_or_error = GetTestLibLibraryPath(); - ORBIT_CHECK(library_path_or_error.has_value()); - std::filesystem::path library_path = std::move(library_path_or_error.value()); - - auto modules_or_error = orbit_module_utils::ReadModules(pid_); - ORBIT_CHECK(modules_or_error.has_value()); - const std::vector& modules = modules_or_error.value(); - - // Inject the payload for the instrumentation. - auto library_handle_or_error = DlmopenInTracee(pid_, modules, library_path, RTLD_NOW, - LinkerNamespace::kCreateNewNamespace); - ORBIT_CHECK(library_handle_or_error.has_value()); - void* library_handle = library_handle_or_error.value(); - - auto entry_payload_function_address_or_error = - DlsymInTracee(pid_, modules, library_handle, entry_payload_function_name); - ORBIT_CHECK(entry_payload_function_address_or_error.has_value()); - entry_payload_function_address_ = - absl::bit_cast(entry_payload_function_address_or_error.value()); - - auto exit_payload_function_address_or_error = - DlsymInTracee(pid_, modules, library_handle, exit_payload_function_name); - ORBIT_CHECK(exit_payload_function_address_or_error.has_value()); - exit_payload_function_address_ = - absl::bit_cast(exit_payload_function_address_or_error.value()); - - // Get address of the function to instrument. - const AddressRange address_range_code = GetFunctionAddressRangeOrDie(); - function_address_ = address_range_code.start; - const uint64_t size_of_function = address_range_code.end - address_range_code.start; - - // Get memory for the trampoline. - auto trampoline_or_error = - AllocateMemoryForTrampolines(pid_, address_range_code, max_trampoline_size_); - ORBIT_CHECK(!trampoline_or_error.has_error()); - trampoline_memory_ = std::move(trampoline_or_error.value()); - trampoline_address_ = trampoline_memory_->GetAddress(); - - // Get memory for return trampoline and create the return trampoline. - auto return_trampoline_or_error = MemoryInTracee::Create(pid_, 0, GetReturnTrampolineSize()); - ORBIT_CHECK(!return_trampoline_or_error.has_error()); - return_trampoline_address_ = return_trampoline_or_error.value()->GetAddress(); - auto result = - CreateReturnTrampoline(pid_, exit_payload_function_address_, return_trampoline_address_); - ORBIT_CHECK(!result.has_error()); - ORBIT_CHECK(!return_trampoline_or_error.value()->EnsureMemoryExecutable().has_error()); - - // Copy the beginning of the function over into this process. - constexpr uint64_t kMaxFunctionBackupSize = 200; - const uint64_t bytes_to_copy = std::min(size_of_function, kMaxFunctionBackupSize); - ErrorMessageOr> function_backup = - ReadTraceesMemory(pid_, function_address_, bytes_to_copy); - ORBIT_CHECK(function_backup.has_value()); - function_code_ = function_backup.value(); - } - - // Runs the child for a millisecond to assert it is still working fine, stops it, removes the - // instrumentation, restarts and stops it again. - void RestartAndRemoveInstrumentation() { - ORBIT_CHECK(!trampoline_memory_->EnsureMemoryExecutable().has_error()); - - MoveInstructionPointersOutOfOverwrittenCode(pid_, relocation_map_); - - ORBIT_CHECK(!DetachAndContinueProcess(pid_).has_error()); - std::this_thread::sleep_for(std::chrono::milliseconds(1)); - ORBIT_CHECK(AttachAndStopProcess(pid_).has_value()); - - auto write_result_or_error = WriteTraceesMemory(pid_, function_address_, function_code_); - ORBIT_CHECK(!write_result_or_error.has_error()); - - ORBIT_CHECK(!DetachAndContinueProcess(pid_).has_error()); - std::this_thread::sleep_for(std::chrono::milliseconds(1)); - ORBIT_CHECK(AttachAndStopProcess(pid_).has_value()); - } - - void TearDown() override { - cs_close(&capstone_handle_); - - // Detach and end child. - if (pid_ != -1) { - ORBIT_CHECK(!DetachAndContinueProcess(pid_).has_error()); - kill(pid_, SIGKILL); - waitpid(pid_, nullptr, 0); - } - } - - pid_t pid_ = -1; - csh capstone_handle_ = 0; - uint64_t max_trampoline_size_ = 0; - std::unique_ptr trampoline_memory_; - uint64_t trampoline_address_ = 0; - uint64_t return_trampoline_address_ = 0; - uint64_t entry_payload_function_address_ = 0; - uint64_t exit_payload_function_address_ = 0; - - absl::flat_hash_map relocation_map_; - - std::string function_name_; - uint64_t function_address_ = 0; - std::vector function_code_; -}; - -// Function with an ordinary compiler-synthesised prologue; performs some arithmetics. Most real -// world functions will look like this (starting with pushing the stack frame...). Most functions -// below are declared "naked", i.e. without the prologue and implemented entirely in assembly. This -// is done to also cover edge cases. -extern "C" __attribute__((noinline)) int DoSomething() { - std::random_device rd; - std::mt19937 gen(rd()); - std::uniform_int_distribution dis(1, 6); - std::vector v(10); - std::generate(v.begin(), v.end(), [&]() { return dis(gen); }); - int sum = std::accumulate(v.begin(), v.end(), 0); - return sum; -} - -TEST_F(InstrumentFunctionTest, DoSomething) { - RunChild(&DoSomething, "DoSomething"); - PrepareInstrumentation(kEntryPayloadFunctionName, kExitPayloadFunctionName); - ErrorMessageOr address_after_prologue_or_error = CreateTrampoline( - pid_, function_address_, function_code_, trampoline_address_, entry_payload_function_address_, - return_trampoline_address_, capstone_handle_, relocation_map_); - EXPECT_THAT(address_after_prologue_or_error, HasNoError()); - ErrorMessageOr result = - InstrumentFunction(pid_, function_address_, /*function_id=*/42, - address_after_prologue_or_error.value(), trampoline_address_); - EXPECT_THAT(result, HasNoError()); - RestartAndRemoveInstrumentation(); -} - -TEST_F(InstrumentFunctionTest, CheckStackAlignedTo16Bytes) { - RunChild(&DoSomething, "DoSomething"); - PrepareInstrumentation("EntryPayloadAlignedCopy", kExitPayloadFunctionName); - ErrorMessageOr address_after_prologue_or_error = CreateTrampoline( - pid_, function_address_, function_code_, trampoline_address_, entry_payload_function_address_, - return_trampoline_address_, capstone_handle_, relocation_map_); - EXPECT_THAT(address_after_prologue_or_error, HasNoError()); - ErrorMessageOr result = - InstrumentFunction(pid_, function_address_, /*function_id=*/42, - address_after_prologue_or_error.value(), trampoline_address_); - EXPECT_THAT(result, HasNoError()); - RestartAndRemoveInstrumentation(); -} - -// We will not be able to instrument this - the function is just four bytes long and we need five -// bytes to write a jump. -extern "C" __attribute__((noinline, naked)) int TooShort() { - __asm__ __volatile__( - "nop \n\t" - "nop \n\t" - "nop \n\t" - "ret \n\t" - : - : - :); -} - -TEST_F(InstrumentFunctionTest, TooShort) { -#if defined(ORBIT_COVERAGE_BUILD) || !defined(__clang__) || !defined(NDEBUG) - GTEST_SKIP(); -#endif - RunChild(&TooShort, "TooShort"); - PrepareInstrumentation(kEntryPayloadFunctionName, kExitPayloadFunctionName); - ErrorMessageOr result = CreateTrampoline( - pid_, function_address_, function_code_, trampoline_address_, entry_payload_function_address_, - return_trampoline_address_, capstone_handle_, relocation_map_); - EXPECT_THAT(result, - HasErrorWithMessage("Unable to disassemble enough of the function to instrument it")); - RestartAndRemoveInstrumentation(); -} - -// This function is just long enough to be instrumented (five bytes). It is also interesting in that -// the return statement is copied into the trampoline and executed from there. -extern "C" __attribute__((noinline, naked)) int LongEnough() { - __asm__ __volatile__( - "nop \n\t" - "nop \n\t" - "nop \n\t" - "nop \n\t" - "ret \n\t" - : - : - :); -} - -TEST_F(InstrumentFunctionTest, LongEnough) { - RunChild(&LongEnough, "LongEnough"); - PrepareInstrumentation(kEntryPayloadFunctionName, kExitPayloadFunctionName); - ErrorMessageOr address_after_prologue_or_error = CreateTrampoline( - pid_, function_address_, function_code_, trampoline_address_, entry_payload_function_address_, - return_trampoline_address_, capstone_handle_, relocation_map_); - EXPECT_THAT(address_after_prologue_or_error, HasNoError()); - ErrorMessageOr result = - InstrumentFunction(pid_, function_address_, /*function_id=*/42, - address_after_prologue_or_error.value(), trampoline_address_); - EXPECT_THAT(result, HasNoError()); - RestartAndRemoveInstrumentation(); -} - -// The rip relative address is translated to the new code position. -extern "C" __attribute__((noinline, naked)) int RipRelativeAddressing() { - __asm__ __volatile__( - "movq 0x03(%%rip), %%rax\n\t" - "nop \n\t" - "nop \n\t" - "ret \n\t" - ".quad 0x0102034200000000 \n\t" - : - : - :); -} - -TEST_F(InstrumentFunctionTest, RipRelativeAddressing) { - RunChild(&RipRelativeAddressing, "RipRelativeAddressing"); - PrepareInstrumentation(kEntryPayloadFunctionName, kExitPayloadFunctionName); - ErrorMessageOr address_after_prologue_or_error = CreateTrampoline( - pid_, function_address_, function_code_, trampoline_address_, entry_payload_function_address_, - return_trampoline_address_, capstone_handle_, relocation_map_); - EXPECT_THAT(address_after_prologue_or_error, HasNoError()); - ErrorMessageOr result = - InstrumentFunction(pid_, function_address_, /*function_id=*/42, - address_after_prologue_or_error.value(), trampoline_address_); - EXPECT_THAT(result, HasNoError()); - RestartAndRemoveInstrumentation(); -} - -// Unconditional jump to an 8-bit offset. -extern "C" __attribute__((noinline, naked)) int UnconditionalJump8BitOffset() { - __asm__ __volatile__( - "jmp label_unconditional_jmp_8_bit \n\t" - "nop \n\t" - "nop \n\t" - "nop \n\t" - "label_unconditional_jmp_8_bit: \n\t" - "ret \n\t" - : - : - :); -} - -TEST_F(InstrumentFunctionTest, UnconditionalJump8BitOffset) { - RunChild(&UnconditionalJump8BitOffset, "UnconditionalJump8BitOffset"); - PrepareInstrumentation(kEntryPayloadFunctionName, kExitPayloadFunctionName); - ErrorMessageOr address_after_prologue_or_error = CreateTrampoline( - pid_, function_address_, function_code_, trampoline_address_, entry_payload_function_address_, - return_trampoline_address_, capstone_handle_, relocation_map_); - EXPECT_THAT(address_after_prologue_or_error, HasNoError()); - ErrorMessageOr result = - InstrumentFunction(pid_, function_address_, /*function_id=*/42, - address_after_prologue_or_error.value(), trampoline_address_); - EXPECT_THAT(result, HasNoError()); - RestartAndRemoveInstrumentation(); -} - -// Unconditional jump to a 32 bit offset. -extern "C" __attribute__((noinline, naked)) int UnconditionalJump32BitOffset() { - __asm__ __volatile__( - "jmp label_unconditional_jmp_32_bit \n\t" - ".octa 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 \n\t" // 256 bytes of zeros - "label_unconditional_jmp_32_bit: \n\t" - "ret \n\t" - : - : - :); -} - -TEST_F(InstrumentFunctionTest, UnconditionalJump32BitOffset) { - RunChild(&UnconditionalJump32BitOffset, "UnconditionalJump32BitOffset"); - PrepareInstrumentation(kEntryPayloadFunctionName, kExitPayloadFunctionName); - ErrorMessageOr address_after_prologue_or_error = CreateTrampoline( - pid_, function_address_, function_code_, trampoline_address_, entry_payload_function_address_, - return_trampoline_address_, capstone_handle_, relocation_map_); - EXPECT_THAT(address_after_prologue_or_error, HasNoError()); - ErrorMessageOr result = - InstrumentFunction(pid_, function_address_, /*function_id=*/42, - address_after_prologue_or_error.value(), trampoline_address_); - EXPECT_THAT(result, HasNoError()); - RestartAndRemoveInstrumentation(); -} - -// The rip relative address is translated to the new code position. -extern "C" __attribute__((noinline, naked)) int ConditionalJump8BitOffset() { - __asm__ __volatile__( - "jnz loop_label_jcc \n\t" - "nop \n\t" - "nop \n\t" - "nop \n\t" - "loop_label_jcc: \n\t" - "xor %%eax, %%eax \n\t" - "nop \n\t" - "nop \n\t" - "ret \n\t" - : - : - :); -} - -TEST_F(InstrumentFunctionTest, ConditionalJump8BitOffset) { - RunChild(&ConditionalJump8BitOffset, "ConditionalJump8BitOffset"); - PrepareInstrumentation(kEntryPayloadFunctionName, kExitPayloadFunctionName); - ErrorMessageOr address_after_prologue_or_error = CreateTrampoline( - pid_, function_address_, function_code_, trampoline_address_, entry_payload_function_address_, - return_trampoline_address_, capstone_handle_, relocation_map_); - EXPECT_THAT(address_after_prologue_or_error, HasNoError()); - ErrorMessageOr result = - InstrumentFunction(pid_, function_address_, /*function_id=*/42, - address_after_prologue_or_error.value(), trampoline_address_); - EXPECT_THAT(result, HasNoError()); - RestartAndRemoveInstrumentation(); -} - -// The rip relative address is translated to the new code position. -extern "C" __attribute__((noinline, naked)) int ConditionalJump32BitOffset() { - __asm__ __volatile__( - "xor %%eax, %%eax \n\t" - "jnz label_jcc_32_bit \n\t" - "nop \n\t" - "ret \n\t" - ".octa 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 \n\t" // 256 bytes of zeros - "label_jcc_32_bit: \n\t" - "ret \n\t" - : - : - :); -} - -TEST_F(InstrumentFunctionTest, ConditionalJump32BitOffset) { - RunChild(&ConditionalJump32BitOffset, "ConditionalJump32BitOffset"); - PrepareInstrumentation(kEntryPayloadFunctionName, kExitPayloadFunctionName); - ErrorMessageOr address_after_prologue_or_error = CreateTrampoline( - pid_, function_address_, function_code_, trampoline_address_, entry_payload_function_address_, - return_trampoline_address_, capstone_handle_, relocation_map_); - EXPECT_THAT(address_after_prologue_or_error, HasNoError()); - ErrorMessageOr result = - InstrumentFunction(pid_, function_address_, /*function_id=*/42, - address_after_prologue_or_error.value(), trampoline_address_); - EXPECT_THAT(result, HasNoError()); - RestartAndRemoveInstrumentation(); -} - -// Function can not be instrumented since it uses the unsupported loop instruction. -extern "C" __attribute__((noinline, naked)) int Loop() { - __asm__ __volatile__( - "mov $42, %%cx\n\t" - "loop_label:\n\t" - "loopnz loop_label\n\t" - "ret \n\t" - : - : - :); -} - -TEST_F(InstrumentFunctionTest, Loop) { -#if defined(ORBIT_COVERAGE_BUILD) || !defined(__clang__) - GTEST_SKIP(); -#endif - RunChild(&Loop, "Loop"); - PrepareInstrumentation(kEntryPayloadFunctionName, kExitPayloadFunctionName); - ErrorMessageOr result = CreateTrampoline( - pid_, function_address_, function_code_, trampoline_address_, entry_payload_function_address_, - return_trampoline_address_, capstone_handle_, relocation_map_); - EXPECT_THAT(result, HasErrorWithMessage("Relocating a loop instruction is not supported.")); - RestartAndRemoveInstrumentation(); -} - -// Check-fails if any parameter is not zero. -extern "C" __attribute__((noinline)) int CheckIntParameters(uint64_t p0, uint64_t p1, uint64_t p2, - uint64_t p3, uint64_t p4, uint64_t p5, - uint64_t p6, uint64_t p7) { - ORBIT_CHECK(p0 == 0 && p1 == 0 && p2 == 0 && p3 == 0 && p4 == 0 && p5 == 0 && p6 == 0 && p7 == 0); - return 0; -} - -// This test and the tests below check for proper handling of parameters handed to the instrumented -// function. The payload that is called before the instrumented function is executed clobbers the -// respective set of registers. So the Check*Parameter methods can check if the backup worked -// correctly. -TEST_F(InstrumentFunctionTest, CheckIntParameters) { - function_name_ = "CheckIntParameters"; - pid_ = fork(); - ORBIT_CHECK(pid_ != -1); - if (pid_ == 0) { - prctl(PR_SET_PDEATHSIG, SIGTERM); - - // Endless loops without side effects are UB and recent versions of clang optimize it away. - // Making `sum` volatile avoids that problem. - [[maybe_unused]] volatile uint64_t sum = 0; - while (true) { - sum += CheckIntParameters(0, 0, 0, 0, 0, 0, 0, 0); - } - } - PrepareInstrumentation("EntryPayloadClobberParameterRegisters", kExitPayloadFunctionName); - ErrorMessageOr address_after_prologue_or_error = CreateTrampoline( - pid_, function_address_, function_code_, trampoline_address_, entry_payload_function_address_, - return_trampoline_address_, capstone_handle_, relocation_map_); - EXPECT_THAT(address_after_prologue_or_error, HasNoError()); - ErrorMessageOr result = - InstrumentFunction(pid_, function_address_, /*function_id=*/42, - address_after_prologue_or_error.value(), trampoline_address_); - EXPECT_THAT(result, HasNoError()); - RestartAndRemoveInstrumentation(); -} - -// Check-fails if any parameter is not zero. -extern "C" __attribute__((noinline)) int CheckFloatParameters(float p0, float p1, float p2, - float p3, float p4, float p5, - float p6, float p7) { - ORBIT_CHECK(p0 == 0.f && p1 == 0.f && p2 == 0.f && p3 == 0.f && p4 == 0.f && p5 == 0.f && - p6 == 0.f && p7 == 0.f); - return 0; -} - -TEST_F(InstrumentFunctionTest, CheckFloatParameters) { - function_name_ = "CheckFloatParameters"; - pid_ = fork(); - ORBIT_CHECK(pid_ != -1); - if (pid_ == 0) { - prctl(PR_SET_PDEATHSIG, SIGTERM); - - // Endless loops without side effects are UB and recent versions of clang optimize it away. - // Making `sum` volatile avoids that problem. - [[maybe_unused]] volatile uint64_t sum = 0; - while (true) { - sum += CheckFloatParameters(0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f); - } - } - PrepareInstrumentation("EntryPayloadClobberXmmRegisters", kExitPayloadFunctionName); - ErrorMessageOr address_after_prologue_or_error = CreateTrampoline( - pid_, function_address_, function_code_, trampoline_address_, entry_payload_function_address_, - return_trampoline_address_, capstone_handle_, relocation_map_); - EXPECT_THAT(address_after_prologue_or_error, HasNoError()); - ErrorMessageOr result = - InstrumentFunction(pid_, function_address_, /*function_id=*/42, - address_after_prologue_or_error.value(), trampoline_address_); - EXPECT_THAT(result, HasNoError()); - RestartAndRemoveInstrumentation(); -} - -// Check-fails if any parameter is not zero. -extern "C" __attribute__((noinline)) int CheckM256iParameters(__m256i p0, __m256i p1, __m256i p2, - __m256i p3, __m256i p4, __m256i p5, - __m256i p6, __m256i p7) { - ORBIT_CHECK(_mm256_extract_epi64(p0, 0) == 0 && _mm256_extract_epi64(p1, 0) == 0 && - _mm256_extract_epi64(p2, 0) == 0 && _mm256_extract_epi64(p3, 0) == 0 && - _mm256_extract_epi64(p4, 0) == 0 && _mm256_extract_epi64(p5, 0) == 0 && - _mm256_extract_epi64(p6, 0) == 0 && _mm256_extract_epi64(p7, 0) == 0); - return 0; -} - -TEST_F(InstrumentFunctionTest, CheckM256iParameters) { - function_name_ = "CheckM256iParameters"; - pid_ = fork(); - ORBIT_CHECK(pid_ != -1); - if (pid_ == 0) { - prctl(PR_SET_PDEATHSIG, SIGTERM); - - // Endless loops without side effects are UB and recent versions of clang optimize it away. - // Making `sum` volatile avoids that problem. - [[maybe_unused]] volatile uint64_t sum = 0; - while (true) { - sum += - CheckM256iParameters(_mm256_set1_epi64x(0), _mm256_set1_epi64x(0), _mm256_set1_epi64x(0), - _mm256_set1_epi64x(0), _mm256_set1_epi64x(0), _mm256_set1_epi64x(0), - _mm256_set1_epi64x(0), _mm256_set1_epi64x(0)); - } - } - PrepareInstrumentation("EntryPayloadClobberYmmRegisters", kExitPayloadFunctionName); - ErrorMessageOr address_after_prologue_or_error = CreateTrampoline( - pid_, function_address_, function_code_, trampoline_address_, entry_payload_function_address_, - return_trampoline_address_, capstone_handle_, relocation_map_); - EXPECT_THAT(address_after_prologue_or_error, HasNoError()); - ErrorMessageOr result = - InstrumentFunction(pid_, function_address_, /*function_id=*/42, - address_after_prologue_or_error.value(), trampoline_address_); - EXPECT_THAT(result, HasNoError()); - RestartAndRemoveInstrumentation(); -} - -// Check-fails if any parameter is not zero. -extern "C" __attribute__((noinline, ms_abi)) int CheckIntParametersMsAbi(uint64_t p0, uint64_t p1, - uint64_t p2, uint64_t p3) { - ORBIT_CHECK(p0 == 0 && p1 == 0 && p2 == 0 && p3 == 0); - return 0; -} - -TEST_F(InstrumentFunctionTest, CheckIntParametersMsAbi) { - function_name_ = "CheckIntParametersMsAbi"; - pid_ = fork(); - ORBIT_CHECK(pid_ != -1); - if (pid_ == 0) { - prctl(PR_SET_PDEATHSIG, SIGTERM); - - // Endless loops without side effects are UB and recent versions of clang optimize it away. - // Making `sum` volatile avoids that problem. - [[maybe_unused]] volatile uint64_t sum = 0; - while (true) { - sum += CheckIntParametersMsAbi(0, 0, 0, 0); - } - } - PrepareInstrumentation("EntryPayloadClobberParameterRegisters", kExitPayloadFunctionName); - ErrorMessageOr address_after_prologue_or_error = CreateTrampoline( - pid_, function_address_, function_code_, trampoline_address_, entry_payload_function_address_, - return_trampoline_address_, capstone_handle_, relocation_map_); - EXPECT_THAT(address_after_prologue_or_error, HasNoError()); - ErrorMessageOr result = - InstrumentFunction(pid_, function_address_, /*function_id=*/42, - address_after_prologue_or_error.value(), trampoline_address_); - EXPECT_THAT(result, HasNoError()); - RestartAndRemoveInstrumentation(); -} - -// Check-fails if any parameter is not zero. -extern "C" __attribute__((noinline, ms_abi)) int CheckFloatParametersMsAbi(float p0, float p1, - float p2, float p3) { - ORBIT_CHECK(p0 == 0.f && p1 == 0.f && p2 == 0.f && p3 == 0.f); - return 0; -} - -TEST_F(InstrumentFunctionTest, CheckFloatParametersMsAbi) { - function_name_ = "CheckFloatParametersMsAbi"; - pid_ = fork(); - ORBIT_CHECK(pid_ != -1); - if (pid_ == 0) { - prctl(PR_SET_PDEATHSIG, SIGTERM); - - // Endless loops without side effects are UB and recent versions of clang optimize it away. - // Making `sum` volatile avoids that problem. - [[maybe_unused]] volatile uint64_t sum = 0; - while (true) { - sum += CheckFloatParametersMsAbi(0.f, 0.f, 0.f, 0.f); - } - } - PrepareInstrumentation("EntryPayloadClobberXmmRegisters", kExitPayloadFunctionName); - ErrorMessageOr address_after_prologue_or_error = CreateTrampoline( - pid_, function_address_, function_code_, trampoline_address_, entry_payload_function_address_, - return_trampoline_address_, capstone_handle_, relocation_map_); - EXPECT_THAT(address_after_prologue_or_error, HasNoError()); - ErrorMessageOr result = - InstrumentFunction(pid_, function_address_, /*function_id=*/42, - address_after_prologue_or_error.value(), trampoline_address_); - EXPECT_THAT(result, HasNoError()); - RestartAndRemoveInstrumentation(); -} - -// This test guards against naively backing up x87 registers in the return trampoline when the -// instrumented function doesn't use them to return values. -TEST_F(InstrumentFunctionTest, CheckNoX87UnderflowInReturnTrampoline) { - function_name_ = "DoSomething"; - pid_ = fork(); - ORBIT_CHECK(pid_ != -1); - if (pid_ == 0) { - prctl(PR_SET_PDEATHSIG, SIGTERM); - - // Reset bit 0 of the 16-bit x87 FPU Control Word, in order to unmask invalid-operation - // exception. If the return trampoline causes the underflow of the x87 register stack before - // masking the exception, the process will crash. - uint16_t control = 0; - __asm__ __volatile__("fnstcw %0\n\t" : "=m"(control) : :); - control &= 0xFE; - __asm__ __volatile__("fldcw %0\n\t" : : "m"(control) :); - - // Endless loops without side effects are UB and recent versions of clang optimize it away. - // Making `sum` volatile avoids that problem. - [[maybe_unused]] volatile uint64_t sum = 0; - while (true) { - sum += DoSomething(); - } - } - PrepareInstrumentation(kEntryPayloadFunctionName, kExitPayloadFunctionName); - ErrorMessageOr address_after_prologue_or_error = CreateTrampoline( - pid_, function_address_, function_code_, trampoline_address_, entry_payload_function_address_, - return_trampoline_address_, capstone_handle_, relocation_map_); - EXPECT_THAT(address_after_prologue_or_error, HasNoError()); - ErrorMessageOr result = - InstrumentFunction(pid_, function_address_, /*function_id=*/42, - address_after_prologue_or_error.value(), trampoline_address_); - EXPECT_THAT(result, HasNoError()); - RestartAndRemoveInstrumentation(); -} - -extern "C" __attribute__((noinline, naked)) int UnconditionalJump8BitOffsetBackToBeginning() { - __asm__ __volatile__( - "nop \n\t" - "nop \n\t" - "nop \n\t" - "nop \n\t" - "nop \n\t" - ".byte 0xeb \n\t" // jmp -7 (which is the first nop) - ".byte 0xf9 \n\t" - "xor %%eax, %%eax \n\t" - "ret \n\t" - : - : - :); -} - -// This will fail to create a trampoline since the function contains an unconditional jump to an -// eight bit offset which points back into the first five bytes of the function. -TEST_F(InstrumentFunctionTest, UnconditionalJump8BitOffsetBackToBeginning) { -// Exclude gcc builds: the inline assembly above gets messed up by the compiler. -#if defined(ORBIT_COVERAGE_BUILD) || !defined(__clang__) || !defined(NDEBUG) - GTEST_SKIP(); -#endif - RunChild(&UnconditionalJump8BitOffsetBackToBeginning, - "UnconditionalJump8BitOffsetBackToBeginning"); - PrepareInstrumentation(kEntryPayloadFunctionName, kExitPayloadFunctionName); - ErrorMessageOr result = CreateTrampoline( - pid_, function_address_, function_code_, trampoline_address_, entry_payload_function_address_, - return_trampoline_address_, capstone_handle_, relocation_map_); - EXPECT_THAT(result, - HasErrorWithMessage( - "Failed to create trampoline since the function contains a jump back into")); -} - -extern "C" __attribute__((noinline, naked)) int UnconditionalJump32BitOffsetBackToBeginning() { - __asm__ __volatile__( - "nop \n\t" - "nop \n\t" - "nop \n\t" - "nop \n\t" - "nop \n\t" - ".byte 0xe9 \n\t" // jmp -10 (which is the first nop) - ".long 0xfffffff6 \n\t" - "xor %%eax, %%eax \n\t" - "ret \n\t" - : - : - :); -} - -// This will fail to create a trampoline since the function contains an unconditional jump to a -// 32 bit offset which points back into the first five bytes of the function. -TEST_F(InstrumentFunctionTest, UnconditionalJump32BitOffsetBackToBeginning) { -// Exclude gcc builds: the inline assembly above gets messed up by the compiler. -#if defined(ORBIT_COVERAGE_BUILD) || !defined(__clang__) || !defined(NDEBUG) - GTEST_SKIP(); -#endif - RunChild(&UnconditionalJump32BitOffsetBackToBeginning, - "UnconditionalJump32BitOffsetBackToBeginning"); - PrepareInstrumentation(kEntryPayloadFunctionName, kExitPayloadFunctionName); - ErrorMessageOr result = CreateTrampoline( - pid_, function_address_, function_code_, trampoline_address_, entry_payload_function_address_, - return_trampoline_address_, capstone_handle_, relocation_map_); - EXPECT_THAT(result, - HasErrorWithMessage( - "Failed to create trampoline since the function contains a jump back into")); -} - -extern "C" __attribute__((noinline, naked)) int ConditionalJump8BitOffsetBackToBeginning() { - __asm__ __volatile__( - "nop \n\t" - "nop \n\t" - "nop \n\t" - "nop \n\t" - "nop \n\t" - ".byte 0x70 \n\t" // jo -7 (which is the first nop) - ".byte 0xf9 \n\t" - "xor %%eax, %%eax \n\t" - "ret \n\t" - : - : - :); -} - -// This will fail to create a trampoline since the function contains a conditional jump to an -// eight bit offset which points back into the first five bytes of the function. -TEST_F(InstrumentFunctionTest, ConditionalJump8BitOffsetBackToBeginning) { -// Exclude gcc builds: the inline assembly above gets messed up by the compiler. -#if defined(ORBIT_COVERAGE_BUILD) || !defined(__clang__) || !defined(NDEBUG) - GTEST_SKIP(); -#endif - RunChild(&ConditionalJump8BitOffsetBackToBeginning, "ConditionalJump8BitOffsetBackToBeginning"); - PrepareInstrumentation(kEntryPayloadFunctionName, kExitPayloadFunctionName); - ErrorMessageOr result = CreateTrampoline( - pid_, function_address_, function_code_, trampoline_address_, entry_payload_function_address_, - return_trampoline_address_, capstone_handle_, relocation_map_); - EXPECT_THAT(result, - HasErrorWithMessage( - "Failed to create trampoline since the function contains a jump back into")); -} - -extern "C" __attribute__((noinline, naked)) int ConditionalJump32BitOffsetBackToBeginning() { - __asm__ __volatile__( - "nop \n\t" - "nop \n\t" - "nop \n\t" - "nop \n\t" - "nop \n\t" - ".byte 0x0f \n\t" // jo -7 (which is the last nop) - ".byte 0x80 \n\t" - ".long 0xfffffff9 \n\t" - "xor %%eax, %%eax \n\t" - "ret \n\t" - : - : - :); -} - -// This will fail to create a trampoline since the function contains a conditional jump to a -// 32 bit offset which points back into the first five bytes of the function. -TEST_F(InstrumentFunctionTest, ConditionalJump32BitOffsetBackToBeginning) { -// Exclude gcc builds: the inline assembly above gets messed up by the compiler. -#if defined(ORBIT_COVERAGE_BUILD) || !defined(__clang__) || !defined(NDEBUG) - GTEST_SKIP(); -#endif - RunChild(&ConditionalJump32BitOffsetBackToBeginning, "ConditionalJump32BitOffsetBackToBeginning"); - PrepareInstrumentation(kEntryPayloadFunctionName, kExitPayloadFunctionName); - ErrorMessageOr result = CreateTrampoline( - pid_, function_address_, function_code_, trampoline_address_, entry_payload_function_address_, - return_trampoline_address_, capstone_handle_, relocation_map_); - EXPECT_THAT(result, - HasErrorWithMessage( - "Failed to create trampoline since the function contains a jump back into")); -} - -extern "C" __attribute__((noinline, naked)) int LongConditionalJump32BitOffsetBackToBeginning() { - __asm__ __volatile__( - "xor %%eax, %%eax \n\t" - "ret \n\t" - ".octa 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 \n\t" // 256 bytes of zeros - ".byte 0x0f \n\t" // jo -263 (which is the ret) - ".byte 0x80 \n\t" - ".long 0xfffffef9 \n\t" - : - : - :); -} - -// This will create a trampoline. The function contains a conditional jump to a -// 32 bit offset which points back into the first five bytes of the function. However the jump is -// occurring after the 200 byte limit and therefore it stays undetected. -TEST_F(InstrumentFunctionTest, LongConditionalJump32BitOffsetBackToBeginning) { - RunChild(&LongConditionalJump32BitOffsetBackToBeginning, - "LongConditionalJump32BitOffsetBackToBeginning"); - PrepareInstrumentation(kEntryPayloadFunctionName, kExitPayloadFunctionName); - ErrorMessageOr result = CreateTrampoline( - pid_, function_address_, function_code_, trampoline_address_, entry_payload_function_address_, - return_trampoline_address_, capstone_handle_, relocation_map_); - EXPECT_THAT(result, HasNoError()); -} - -extern "C" __attribute__((noinline, naked)) int UnableToDisassembleBadInstruction() { - __asm__ __volatile__( - "nop \n\t" - "nop \n\t" - "nop \n\t" - "nop \n\t" - "ret \n\t" - ".byte 0x06 \n\t" // bad instruction - ".byte 0x0f \n\t" // jo -12 (which is the first nop) - ".byte 0x80 \n\t" - ".long 0xfffffff4 \n\t" - : - : - :); -} - -// This will create a trampoline. There is a conditional jump back to the start but the disassembler -// gets confused before it reaches this and so we don't detect it. -TEST_F(InstrumentFunctionTest, UnableToDisassembleBadInstruction) { - RunChild(&UnableToDisassembleBadInstruction, "UnableToDisassembleBadInstruction"); - PrepareInstrumentation(kEntryPayloadFunctionName, kExitPayloadFunctionName); - ErrorMessageOr result = CreateTrampoline( - pid_, function_address_, function_code_, trampoline_address_, entry_payload_function_address_, - return_trampoline_address_, capstone_handle_, relocation_map_); - EXPECT_THAT(result, HasNoError()); -} - -} // namespace orbit_user_space_instrumentation +// // Copyright (c) 2021 The Orbit Authors. All rights reserved. +// // Use of this source code is governed by a BSD-style license that can be +// // found in the LICENSE file. + +// #include +// #include +// #include +// #include +// #include +// #include +// #include +// #include +// #include +// #include +// #include +// #include + +// #include +// #include +// #include +// #include +// #include +// #include +// #include +// #include +// #include +// #include +// #include +// #include +// #include +// #include + +// #include "AccessTraceesMemory.h" +// #include "AllocateInTracee.h" +// #include "GetTestLibLibraryPath.h" +// #include "GrpcProtos/module.pb.h" +// #include "MachineCode.h" +// #include "ModuleUtils/ReadLinuxModules.h" +// #include "OrbitBase/ExecutablePath.h" +// #include "OrbitBase/Logging.h" +// #include "OrbitBase/Result.h" +// #include "TestUtils.h" +// #include "TestUtils/TestUtils.h" +// #include "Trampoline.h" +// #include "UserSpaceInstrumentation/AddressRange.h" +// #include "UserSpaceInstrumentation/Attach.h" +// #include "UserSpaceInstrumentation/InjectLibraryInTracee.h" + +// namespace orbit_user_space_instrumentation { +// using orbit_test_utils::HasErrorWithMessage; + +// namespace { + +// using orbit_test_utils::HasErrorWithMessage; +// using orbit_test_utils::HasNoError; +// using orbit_test_utils::HasValue; +// using testing::ElementsAreArray; + +// constexpr const char* kEntryPayloadFunctionName = "EntryPayload"; +// constexpr const char* kExitPayloadFunctionName = "ExitPayload"; + +// extern "C" __attribute__((noinline)) int DoubleAndIncrement(int i) { +// i = 2 * i; +// return i + 1; +// } + +// } // namespace + +// TEST(TrampolineTest, DoAddressRangesOverlap) { +// AddressRange a = {3, 7}; +// AddressRange b1 = {1, 2}; +// EXPECT_FALSE(DoAddressRangesOverlap(a, b1)); +// AddressRange b2 = {1, 3}; +// EXPECT_FALSE(DoAddressRangesOverlap(a, b2)); +// AddressRange b3 = {1, 4}; +// EXPECT_TRUE(DoAddressRangesOverlap(a, b3)); +// AddressRange b4 = {1, 9}; +// EXPECT_TRUE(DoAddressRangesOverlap(a, b4)); +// AddressRange b5 = {4, 5}; +// EXPECT_TRUE(DoAddressRangesOverlap(a, b5)); +// AddressRange b6 = {4, 9}; +// EXPECT_TRUE(DoAddressRangesOverlap(a, b6)); +// AddressRange b7 = {7, 9}; +// EXPECT_FALSE(DoAddressRangesOverlap(a, b7)); +// AddressRange b8 = {8, 9}; +// EXPECT_FALSE(DoAddressRangesOverlap(a, b8)); +// } + +// TEST(TrampolineTest, LowestIntersectingAddressRange) { +// const std::vector all_ranges = {{0, 5}, {20, 30}, {40, 60}}; + +// EXPECT_FALSE(LowestIntersectingAddressRange({}, {0, 60}).has_value()); + +// EXPECT_EQ(0, LowestIntersectingAddressRange(all_ranges, {1, 2})); +// EXPECT_EQ(1, LowestIntersectingAddressRange(all_ranges, {21, 22})); +// EXPECT_EQ(2, LowestIntersectingAddressRange(all_ranges, {51, 52})); + +// EXPECT_EQ(0, LowestIntersectingAddressRange(all_ranges, {3, 6})); +// EXPECT_EQ(1, LowestIntersectingAddressRange(all_ranges, {19, 22})); +// EXPECT_EQ(2, LowestIntersectingAddressRange(all_ranges, {30, 52})); + +// EXPECT_EQ(0, LowestIntersectingAddressRange(all_ranges, {4, 72})); +// EXPECT_EQ(1, LowestIntersectingAddressRange(all_ranges, {29, 52})); +// EXPECT_EQ(2, LowestIntersectingAddressRange(all_ranges, {59, 72})); + +// EXPECT_FALSE(LowestIntersectingAddressRange(all_ranges, {5, 20}).has_value()); +// EXPECT_FALSE(LowestIntersectingAddressRange(all_ranges, {30, 40}).has_value()); +// EXPECT_FALSE(LowestIntersectingAddressRange(all_ranges, {60, 80}).has_value()); +// } + +// TEST(TrampolineTest, HighestIntersectingAddressRange) { +// const std::vector all_ranges = {{0, 5}, {20, 30}, {40, 60}}; + +// EXPECT_FALSE(HighestIntersectingAddressRange({}, {0, 60}).has_value()); + +// EXPECT_EQ(0, HighestIntersectingAddressRange(all_ranges, {1, 2})); +// EXPECT_EQ(1, HighestIntersectingAddressRange(all_ranges, {21, 22})); +// EXPECT_EQ(2, HighestIntersectingAddressRange(all_ranges, {51, 52})); + +// EXPECT_EQ(0, HighestIntersectingAddressRange(all_ranges, {3, 6})); +// EXPECT_EQ(1, HighestIntersectingAddressRange(all_ranges, {19, 22})); +// EXPECT_EQ(2, HighestIntersectingAddressRange(all_ranges, {30, 52})); + +// EXPECT_EQ(2, HighestIntersectingAddressRange(all_ranges, {4, 72})); +// EXPECT_EQ(2, HighestIntersectingAddressRange(all_ranges, {29, 52})); +// EXPECT_EQ(2, HighestIntersectingAddressRange(all_ranges, {59, 72})); + +// EXPECT_FALSE(HighestIntersectingAddressRange(all_ranges, {5, 20}).has_value()); +// EXPECT_FALSE(HighestIntersectingAddressRange(all_ranges, {30, 40}).has_value()); +// EXPECT_FALSE(HighestIntersectingAddressRange(all_ranges, {60, 80}).has_value()); +// } + +// TEST(TrampolineTest, FindAddressRangeForTrampoline) { +// constexpr uint64_t k1Kb = 0x400; +// constexpr uint64_t k64Kb = 0x10000; +// constexpr uint64_t kOneMb = 0x100000; +// constexpr uint64_t k256Mb = 0x10000000; +// constexpr uint64_t kOneGb = 0x40000000; + +// // Trivial placement to the left. +// const std::vector unavailable_ranges1 = { +// {0, k64Kb}, {kOneGb, 2 * kOneGb}, {3 * kOneGb, 4 * kOneGb}}; +// auto address_range_or_error = +// FindAddressRangeForTrampoline(unavailable_ranges1, {kOneGb, 2 * kOneGb}, k256Mb); +// ASSERT_FALSE(address_range_or_error.has_error()); +// EXPECT_EQ(kOneGb - k256Mb, address_range_or_error.value().start); + +// // Placement to the left just fits. +// const std::vector unavailable_ranges2 = { +// {0, k64Kb}, {k256Mb, kOneGb}, {3 * kOneGb, 4 * kOneGb}}; +// address_range_or_error = +// FindAddressRangeForTrampoline(unavailable_ranges2, {k256Mb, kOneGb}, k256Mb - k64Kb); +// ASSERT_FALSE(address_range_or_error.has_error()); +// EXPECT_EQ(k64Kb, address_range_or_error.value().start); + +// // Placement to the left fails due to page alignment. So we place to the right which fits +// // trivially. +// const std::vector unavailable_ranges3 = { +// {0, k64Kb + 1}, {k256Mb, kOneGb}, {3 * kOneGb, 4 * kOneGb}}; +// address_range_or_error = +// FindAddressRangeForTrampoline(unavailable_ranges3, {k256Mb, kOneGb}, k256Mb - k64Kb - 5); +// ASSERT_FALSE(address_range_or_error.has_error()); +// EXPECT_EQ(kOneGb, address_range_or_error.value().start); + +// // Placement to the left just fits but only after a few hops. +// const std::vector unavailable_ranges4 = { +// {0, k64Kb}, // this is the gap that just fits +// {k64Kb + kOneMb, 6 * kOneMb}, +// {6 * kOneMb + kOneMb - 1, 7 * kOneMb}, +// {7 * kOneMb + kOneMb - 1, 8 * kOneMb}, +// {8 * kOneMb + kOneMb - 1, 9 * kOneMb}}; +// address_range_or_error = FindAddressRangeForTrampoline( +// unavailable_ranges4, {8 * kOneMb + kOneMb - 1, 9 * kOneMb}, kOneMb); +// ASSERT_FALSE(address_range_or_error.has_error()); +// EXPECT_EQ(k64Kb, address_range_or_error.value().start); + +// // No space to the left but trivial placement to the right. +// const std::vector unavailable_ranges5 = { +// {0, k64Kb}, {kOneMb, kOneGb}, {5 * kOneGb, 6 * kOneGb}}; +// address_range_or_error = +// FindAddressRangeForTrampoline(unavailable_ranges5, {kOneMb, kOneGb}, kOneMb); +// ASSERT_FALSE(address_range_or_error.has_error()) << address_range_or_error.error().message(); +// EXPECT_EQ(kOneGb, address_range_or_error.value().start); + +// // No space to the left but placement to the right works after a few hops. +// const std::vector unavailable_ranges6 = { +// {0, k64Kb}, +// {kOneMb, kOneGb}, +// {kOneGb + 0x01 * kOneMb - 1, kOneGb + 0x10 * kOneMb}, +// {kOneGb + 0x11 * kOneMb - 1, kOneGb + 0x20 * kOneMb}, +// {kOneGb + 0x21 * kOneMb - 1, kOneGb + 0x30 * kOneMb}, +// {kOneGb + 0x31 * kOneMb - 1, kOneGb + 0x40 * kOneMb}}; +// address_range_or_error = +// FindAddressRangeForTrampoline(unavailable_ranges6, {kOneMb, kOneGb}, kOneMb); +// ASSERT_FALSE(address_range_or_error.has_error()) << address_range_or_error.error().message(); +// EXPECT_EQ(kOneGb + 0x40 * kOneMb, address_range_or_error.value().start); + +// // No space to the left and the last segment nearly fills up the 64 bit address space. So no +// // placement is possible. +// const std::vector unavailable_ranges7 = { +// {0, k64Kb}, +// {kOneMb, k256Mb}, +// {1 * k256Mb + kOneMb - 1, 2 * k256Mb}, +// {2 * k256Mb + kOneMb - 1, 3 * k256Mb}, +// {3 * k256Mb + kOneMb - 1, 4 * k256Mb + 1}, // this gap is large but alignment doesn't fit +// {4 * k256Mb + kOneMb + 2, 5 * k256Mb}, +// {5 * k256Mb + kOneMb - 1, 0xffffffffffffffff - kOneMb / 2}}; +// address_range_or_error = +// FindAddressRangeForTrampoline(unavailable_ranges7, {kOneMb, k256Mb}, kOneMb); +// ASSERT_TRUE(address_range_or_error.has_error()); + +// // There is no sufficiently large gap in the mappings in the 2GB below the code segment. So the +// // trampoline is placed above the code segment. Also we test that the trampoline starts at the +// // next memory page above last taken segment. +// const std::vector unavailable_ranges8 = { +// {0, k64Kb}, // huge gap here, but it's too far away +// {0x10 * kOneGb, 0x11 * kOneGb}, +// {0x11 * kOneGb + kOneMb - 1, 0x12 * kOneGb}, +// {0x12 * kOneGb + kOneMb - 1, 0x12 * kOneGb + 2 * kOneMb + 42}}; +// address_range_or_error = FindAddressRangeForTrampoline( +// unavailable_ranges8, {0x12 * kOneGb + kOneMb - 1, 0x12 * kOneGb + 2 * kOneMb}, kOneMb); +// ASSERT_FALSE(address_range_or_error.has_error()) << address_range_or_error.error().message(); +// constexpr uint64_t kPageSize = 4096; +// constexpr uint64_t kNextPage = +// (((0x12 * kOneGb + 2 * kOneMb + 42) + (kPageSize - 1)) / kPageSize) * kPageSize; +// EXPECT_EQ(kNextPage, address_range_or_error.value().start); + +// // There is no sufficiently large gap in the mappings in the 2GB below the code segment. And there +// // also is no gap large enough in the 2GB above the code segment. So no placement is possible. +// const std::vector unavailable_ranges9 = { +// {0, k64Kb}, // huge gap here, but it's too far away +// {0x10 * kOneGb + kOneMb - 1, 0x11 * kOneGb}, +// {0x11 * kOneGb + kOneMb - 1, 0x12 * kOneGb}, +// {0x12 * kOneGb + kOneMb - 1, 0x12 * kOneGb + 2 * kOneMb}, +// {0x12 * kOneGb + 3 * kOneMb - 1, 0x13 * kOneGb + 1}, +// {0x13 * kOneGb + kOneMb + 42, 0x14 * kOneGb}}; +// address_range_or_error = FindAddressRangeForTrampoline( +// unavailable_ranges9, {0x12 * kOneGb + kOneMb - 1, 0x12 * kOneGb + 2 * kOneMb}, kOneMb); +// ASSERT_TRUE(address_range_or_error.has_error()); + +// // Fail on malformed input: first address range does not start at zero. +// const std::vector unavailable_ranges10 = {{k64Kb, kOneGb}}; +// EXPECT_DEATH( +// auto result = FindAddressRangeForTrampoline(unavailable_ranges10, {k64Kb, kOneGb}, kOneMb), +// "needs to start at zero"); + +// // Placement to the left fails since the requested memory chunk is too big. So we place to the +// // right which fits trivially. +// // The special case here is that the requested memory size (k256Mb + k64Kb) is larger than the +// // left interval border of the second interval (k256Mb). This produced an artithmetic overflow in +// // a previous version of the algorithm. +// const std::vector unavailable_ranges11 = {{0, k64Kb}, {k256Mb, kOneGb}}; +// address_range_or_error = +// FindAddressRangeForTrampoline(unavailable_ranges11, {k256Mb, kOneGb}, k256Mb + k64Kb); +// ASSERT_FALSE(address_range_or_error.has_error()); +// EXPECT_EQ(kOneGb, address_range_or_error.value().start); + +// // Placement to the left fails, placement to the right fails also because we are close to the end +// // of the address space. This produced an artithmetic overflow in a previous version of the +// // algorithm. +// const std::vector unavailable_ranges12 = { +// {0, k64Kb}, +// {UINT64_MAX - 10 * kOneGb, UINT64_MAX - k64Kb - 1}, +// {UINT64_MAX - k64Kb, UINT64_MAX - k1Kb}}; +// address_range_or_error = FindAddressRangeForTrampoline( +// unavailable_ranges12, {UINT64_MAX - k64Kb, UINT64_MAX - k1Kb}, k64Kb); +// ASSERT_THAT(address_range_or_error, HasErrorWithMessage("No place to fit")); + +// // We can not fit anything close to a range larger than 2GB. +// const std::vector unavailable_ranges13 = {{0, k64Kb}, {kOneGb, 4 * kOneGb}}; +// address_range_or_error = +// FindAddressRangeForTrampoline(unavailable_ranges13, {kOneGb, 4 * kOneGb}, k64Kb); +// ASSERT_THAT(address_range_or_error, HasErrorWithMessage("No place to fit")); +// } + +// TEST(TrampolineTest, AllocateMemoryForTrampolines) { +// pid_t pid = fork(); +// ORBIT_CHECK(pid != -1); +// if (pid == 0) { +// prctl(PR_SET_PDEATHSIG, SIGTERM); + +// [[maybe_unused]] volatile uint64_t sum = 0; +// // Endless loops without side effects are UB and recent versions of clang optimize +// // it away. Making `i` volatile avoids that problem. +// volatile int i = 0; +// while (true) { +// i = (i + 1) & 3; +// sum += DoubleAndIncrement(i); +// } +// } + +// // Stop the process using our tooling. +// ORBIT_CHECK(AttachAndStopProcess(pid).has_value()); + +// // Find the address range of the code for `DoubleAndIncrement`. For the purpose of this test we +// // just take the entire address space taken up by `UserSpaceInstrumentationTests`. +// auto modules_or_error = orbit_module_utils::ReadModules(pid); +// ORBIT_CHECK(!modules_or_error.has_error()); + +// auto& modules = modules_or_error.value(); +// const auto module = std::find_if(modules.begin(), modules.end(), [&](const auto& module) { +// return module.file_path() == orbit_base::GetExecutablePath(); +// }); + +// ASSERT_NE(module, modules.end()); +// const AddressRange code_range{module->address_start(), module->address_end()}; + +// // Allocate one megabyte in the tracee. The memory will be close to `code_range`. +// constexpr uint64_t kTrampolineSize = 1024 * 1024; +// auto memory_or_error = AllocateMemoryForTrampolines(pid, code_range, kTrampolineSize); +// ASSERT_FALSE(memory_or_error.has_error()); + +// // Check that the tracee is functional: Continue, stop again, free the allocated memory, then run +// // briefly again. +// ORBIT_CHECK(DetachAndContinueProcess(pid).has_value()); +// ORBIT_CHECK(AttachAndStopProcess(pid).has_value()); +// ASSERT_THAT(memory_or_error.value()->Free(), HasNoError()); +// ORBIT_CHECK(DetachAndContinueProcess(pid).has_value()); +// ORBIT_CHECK(AttachAndStopProcess(pid).has_value()); + +// // Detach and end child. +// ORBIT_CHECK(DetachAndContinueProcess(pid).has_value()); +// kill(pid, SIGKILL); +// waitpid(pid, nullptr, 0); +// } + +// TEST(TrampolineTest, AddressDifferenceAsInt32) { +// // Result of the difference is negative; in the first case it just fits, the second case +// // overflows. +// constexpr uint64_t kAddr1 = 0x6012345612345678; +// constexpr uint64_t kAddr2Larger = kAddr1 - std::numeric_limits::min(); +// auto result = AddressDifferenceAsInt32(kAddr1, kAddr2Larger); +// ASSERT_THAT(result, HasNoError()); +// EXPECT_EQ(std::numeric_limits::min(), result.value()); +// result = AddressDifferenceAsInt32(kAddr1, kAddr2Larger + 1); +// EXPECT_THAT(result, HasErrorWithMessage("Difference is larger than -2GB")); + +// // Result of the difference is positive; in the first case it just fits, the second case +// // overflows. +// constexpr uint64_t kAddr2Smaller = kAddr1 - std::numeric_limits::max(); +// result = AddressDifferenceAsInt32(kAddr1, kAddr2Smaller); +// ASSERT_THAT(result, HasNoError()); +// EXPECT_EQ(std::numeric_limits::max(), result.value()); +// result = AddressDifferenceAsInt32(kAddr1, kAddr2Smaller - 1); +// EXPECT_THAT(result, HasErrorWithMessage("Difference is larger than +2GB")); + +// // Result of the difference does not even fit into a int64. We handle that gracefully as well. +// constexpr uint64_t kAddrHigh = 0xf234567812345678; +// constexpr uint64_t kAddrLow = kAddrHigh - 0xe234567812345678; +// result = AddressDifferenceAsInt32(kAddrHigh, kAddrLow); +// EXPECT_THAT(result, HasErrorWithMessage("Difference is larger than +2GB")); +// result = AddressDifferenceAsInt32(kAddrLow, kAddrHigh); +// EXPECT_THAT(result, HasErrorWithMessage("Difference is larger than -2GB")); +// } + +// class RelocateInstructionTest : public testing::Test { +// protected: +// void SetUp() override { +// ORBIT_CHECK(cs_open(CS_ARCH_X86, CS_MODE_64, &capstone_handle_) == CS_ERR_OK); +// ORBIT_CHECK(cs_option(capstone_handle_, CS_OPT_DETAIL, CS_OPT_ON) == CS_ERR_OK); +// instruction_ = cs_malloc(capstone_handle_); +// ORBIT_CHECK(instruction_ != nullptr); +// } + +// void Disassemble(const MachineCode& code) { +// const uint8_t* code_pointer = code.GetResultAsVector().data(); +// size_t code_size = code.GetResultAsVector().size(); +// uint64_t disassemble_address = 0; +// ORBIT_CHECK(cs_disasm_iter(capstone_handle_, &code_pointer, &code_size, &disassemble_address, +// instruction_)); +// } + +// void TearDown() override { +// cs_free(instruction_, 1); +// cs_close(&capstone_handle_); +// } + +// cs_insn* instruction_ = nullptr; + +// private: +// csh capstone_handle_ = 0; +// }; + +// TEST_F(RelocateInstructionTest, RipRelativeAddressing) { +// MachineCode code; +// constexpr int32_t kOffset = 0x969433; +// // add qword ptr [rip + kOffset], 1 +// // Handled by "((instruction->detail->x86.modrm & 0xC7) == 0x05)" branch in 'RelocateInstruction'. +// code.AppendBytes({0x48, 0x83, 0x05}).AppendImmediate32(kOffset).AppendBytes({0x01}); +// Disassemble(code); + +// constexpr uint64_t kOriginalAddress = 0x0100000000; +// ErrorMessageOr result = +// RelocateInstruction(instruction_, kOriginalAddress, kOriginalAddress + kOffset - 0x123456); +// ASSERT_THAT(result, HasValue()); +// // add qword ptr [rip + new_offset], 1 48 83 05 56 34 12 00 01 +// // new_offset is computed as +// // old_absolute_address - new_address +// // == (old_address + old_displacement) - (old_address + old_displacement - 0x123456) +// // == 0x123456 +// EXPECT_THAT(result.value().code, +// ElementsAreArray({0x48, 0x83, 0x05, 0x56, 0x34, 0x12, 0x00, 0x01})); +// EXPECT_FALSE(result.value().position_of_absolute_address.has_value()); + +// result = +// RelocateInstruction(instruction_, kOriginalAddress, kOriginalAddress + kOffset + 0x123456); +// ASSERT_THAT(result, HasValue()); +// // add qword ptr [rip + new_offset], 1 48 83 05 aa cb ed ff 01 +// // new_offset is computed as +// // old_absolute_address - new_address +// // == (old_address + old_displacement) - (old_address + old_displacement + 0x123456) +// // == -0x123456 == 0xffedcbaa +// EXPECT_THAT(result.value().code, +// ElementsAreArray({0x48, 0x83, 0x05, 0xaa, 0xcb, 0xed, 0xff, 0x01})); +// EXPECT_FALSE(result.value().position_of_absolute_address.has_value()); + +// result = RelocateInstruction(instruction_, kOriginalAddress, kOriginalAddress - 0x7fff0000); +// EXPECT_THAT(result, +// HasErrorWithMessage( +// "While trying to relocate an instruction with rip relative addressing the " +// "target was out of range from the trampoline.")); +// } + +// TEST_F(RelocateInstructionTest, UnconditionalJumpTo8BitImmediate) { +// MachineCode code; +// constexpr int8_t kOffset = 0x08; +// // jmp [rip + kOffset] +// // Handled by "(instruction->detail->x86.opcode[0] == 0xeb)" branch in 'RelocateInstruction'. +// code.AppendBytes({0xeb}).AppendImmediate8(kOffset); +// Disassemble(code); + +// ErrorMessageOr result = +// RelocateInstruction(instruction_, 0x0100000000, 0x0200000000); +// ASSERT_THAT(result, HasValue()); +// // jmp [rip + 0] ff 25 00 00 00 00 +// // absolute_address 0a 00 00 00 01 00 00 00 +// // original jump instruction ends on 0x0100000000 + 0x02. Adding kOffset (=8) yields 0x010000000a. +// EXPECT_THAT(result.value().code, ElementsAreArray({0xff, 0x25, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x00, +// 0x00, 0x00, 0x01, 0x00, 0x00, 0x00})); +// ASSERT_TRUE(result.value().position_of_absolute_address.has_value()); +// EXPECT_EQ(6, result.value().position_of_absolute_address.value()); +// } + +// TEST_F(RelocateInstructionTest, UnconditionalJumpTo32BitImmediate) { +// MachineCode code; +// constexpr int32_t kOffset = 0x01020304; +// // jmp [rip + kOffset] +// // Handled by "(instruction->detail->x86.opcode[0] == 0xe9)" branch in 'RelocateInstruction'. +// code.AppendBytes({0xe9}).AppendImmediate32(kOffset); +// Disassemble(code); + +// ErrorMessageOr result = +// RelocateInstruction(instruction_, 0x0100000000, 0x0200000000); +// ASSERT_THAT(result, HasValue()); +// // jmp [rip + 0] ff 25 00 00 00 00 +// // absolute_address 09 03 02 01 01 00 00 00 +// // original jump instruction ends on 0x0100000000 + 0x05. Adding kOffset yields 0x0101020309. +// EXPECT_THAT(result.value().code, ElementsAreArray({0xff, 0x25, 0x00, 0x00, 0x00, 0x00, 0x09, 0x03, +// 0x02, 0x01, 0x01, 0x00, 0x00, 0x00})); +// ASSERT_TRUE(result.value().position_of_absolute_address.has_value()); +// EXPECT_EQ(6, result.value().position_of_absolute_address.value()); +// } + +// TEST_F(RelocateInstructionTest, CallInstructionIsNotSupported) { +// MachineCode code; +// constexpr int32_t kOffset = 0x01020304; +// // call [rip + kOffset] +// // Handled by "(instruction->detail->x86.opcode[0] == 0xe8)" branch in 'RelocateInstruction'. +// code.AppendBytes({0xe8}).AppendImmediate32(kOffset); +// Disassemble(code); + +// ErrorMessageOr result = +// RelocateInstruction(instruction_, 0x0100000000, 0x0200000000); +// EXPECT_THAT(result, HasErrorWithMessage("Relocating a call instruction is not supported.")); +// } + +// TEST_F(RelocateInstructionTest, ConditionalJumpTo8BitImmediate) { +// MachineCode code; +// constexpr int8_t kOffset = 0x40; +// // jno rip + kOffset +// // Handled by "((instruction->detail->x86.opcode[0] & 0xf0) == 0x70)" branch in +// // 'RelocateInstruction'. +// code.AppendBytes({0x71}).AppendImmediate8(kOffset); +// Disassemble(code); + +// ErrorMessageOr result = +// RelocateInstruction(instruction_, 0x0100000000, 0x0200000000); +// ASSERT_THAT(result, HasValue()); +// // jo rip + 16 70 0e +// // jmp [rip + 6] ff 25 00 00 00 00 +// // absolute_address 42 00 00 00 01 00 00 00 +// // original jump instruction ends on 0x0100000002 + 0x40 (kOffset) == 0x0100000042. +// EXPECT_THAT(result.value().code, +// ElementsAreArray({0x70, 0x0e, 0xff, 0x25, 0x00, 0x00, 0x00, 0x00, 0x42, 0x00, 0x00, +// 0x00, 0x01, 0x00, 0x00, 0x00})); +// ASSERT_TRUE(result.value().position_of_absolute_address.has_value()); +// EXPECT_EQ(8, result.value().position_of_absolute_address.value()); +// } + +// TEST_F(RelocateInstructionTest, ConditionalJumpTo32BitImmediate) { +// MachineCode code; +// constexpr int32_t kOffset = 0x12345678; +// // jno rip + kOffset 0f 80 78 56 34 12 +// // Handled by "(instruction->detail->x86.opcode[0] == 0x0f && +// // (instruction->detail->x86.opcode[1] & 0xf0) == 0x80)" +// // branch in 'RelocateInstruction'. +// code.AppendBytes({0x0f, 0x80}).AppendImmediate32(kOffset); +// Disassemble(code); + +// ErrorMessageOr result = +// RelocateInstruction(instruction_, 0x0100000000, 0x0200000000); +// ASSERT_TRUE(result.has_value()); +// // jo rip + 16 71 0e +// // jmp [rip +6] ff 25 00 00 00 00 +// // absolute_address 7a 56 34 12 01 00 00 00 +// // original jump instruction ends on 0x0100000006 + 0x12345678 (kOffset) == 0x011234567e. +// EXPECT_THAT(result.value().code, +// ElementsAreArray({0x71, 0x0e, 0xff, 0x25, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x56, 0x34, +// 0x12, 0x01, 0x00, 0x00, 0x00})); +// ASSERT_TRUE(result.value().position_of_absolute_address.has_value()); +// EXPECT_EQ(8, result.value().position_of_absolute_address.value()); +// } + +// TEST_F(RelocateInstructionTest, LoopIsUnsupported) { +// MachineCode code; +// constexpr int8_t kOffset = 0x40; +// // loopz rip + kOffset +// // Handled by "((instruction->detail->x86.opcode[0] & 0xfc) == 0xe0)" branch in +// // 'RelocateInstruction'. +// code.AppendBytes({0xe1}).AppendImmediate8(kOffset); +// Disassemble(code); + +// ErrorMessageOr result = +// RelocateInstruction(instruction_, 0x0100000000, 0x0200000000); +// EXPECT_THAT(result, HasErrorWithMessage("Relocating a loop instruction is not supported.")); +// } + +// TEST_F(RelocateInstructionTest, TrivialTranslation) { +// MachineCode code; +// // nop +// // Handled by "else" branch in 'RelocateInstruction' - instruction is just copied. +// code.AppendBytes({0x90}); +// Disassemble(code); + +// ErrorMessageOr result = +// RelocateInstruction(instruction_, 0x0100000000, 0x0200000000); +// ASSERT_THAT(result, HasValue()); +// EXPECT_THAT(result.value().code, ElementsAreArray({0x90})); +// EXPECT_FALSE(result.value().position_of_absolute_address.has_value()); +// } + +// class InstrumentFunctionTest : public testing::Test { +// protected: +// void SetUp() override { +// /* copybara:insert(b/237251106 injecting the library into the target process triggers some +// initilization code that check fails.) +// GTEST_SKIP(); +// */ +// // Init Capstone disassembler. +// cs_err error_code = cs_open(CS_ARCH_X86, CS_MODE_64, &capstone_handle_); +// ORBIT_CHECK(error_code == CS_ERR_OK); +// error_code = cs_option(capstone_handle_, CS_OPT_DETAIL, CS_OPT_ON); +// ORBIT_CHECK(error_code == CS_ERR_OK); + +// max_trampoline_size_ = GetMaxTrampolineSize(); +// } + +// void RunChild(int (*function_pointer)(), std::string_view function_name) { +// function_name_ = function_name; + +// pid_ = fork(); +// ORBIT_CHECK(pid_ != -1); +// if (pid_ == 0) { +// prctl(PR_SET_PDEATHSIG, SIGTERM); + +// // Endless loops without side effects are UB and recent versions of clang optimize +// // it away. Making `sum` volatile avoids that problem. +// [[maybe_unused]] volatile uint64_t sum = 0; +// while (true) { +// sum += (*function_pointer)(); +// } +// } +// } + +// AddressRange GetFunctionAddressRangeOrDie() { +// return GetFunctionAbsoluteAddressRangeOrDie(function_name_); +// } + +// void PrepareInstrumentation(std::string_view entry_payload_function_name, +// std::string_view exit_payload_function_name) { +// // Stop the child process using our tooling. +// ORBIT_CHECK(AttachAndStopProcess(pid_).has_value()); + +// auto library_path_or_error = GetTestLibLibraryPath(); +// ORBIT_CHECK(library_path_or_error.has_value()); +// std::filesystem::path library_path = std::move(library_path_or_error.value()); + +// auto modules_or_error = orbit_module_utils::ReadModules(pid_); +// ORBIT_CHECK(modules_or_error.has_value()); +// const std::vector& modules = modules_or_error.value(); + +// // Inject the payload for the instrumentation. +// auto library_handle_or_error = DlmopenInTracee(pid_, modules, library_path, RTLD_NOW, +// LinkerNamespace::kCreateNewNamespace); +// ORBIT_CHECK(library_handle_or_error.has_value()); +// void* library_handle = library_handle_or_error.value(); + +// auto entry_payload_function_address_or_error = +// DlsymInTracee(pid_, modules, library_handle, entry_payload_function_name); +// ORBIT_CHECK(entry_payload_function_address_or_error.has_value()); +// entry_payload_function_address_ = +// absl::bit_cast(entry_payload_function_address_or_error.value()); + +// auto exit_payload_function_address_or_error = +// DlsymInTracee(pid_, modules, library_handle, exit_payload_function_name); +// ORBIT_CHECK(exit_payload_function_address_or_error.has_value()); +// exit_payload_function_address_ = +// absl::bit_cast(exit_payload_function_address_or_error.value()); + +// // Get address of the function to instrument. +// const AddressRange address_range_code = GetFunctionAddressRangeOrDie(); +// function_address_ = address_range_code.start; +// const uint64_t size_of_function = address_range_code.end - address_range_code.start; + +// // Get memory for the trampoline. +// auto trampoline_or_error = +// AllocateMemoryForTrampolines(pid_, address_range_code, max_trampoline_size_); +// ORBIT_CHECK(!trampoline_or_error.has_error()); +// trampoline_memory_ = std::move(trampoline_or_error.value()); +// trampoline_address_ = trampoline_memory_->GetAddress(); + +// // Get memory for return trampoline and create the return trampoline. +// auto return_trampoline_or_error = MemoryInTracee::Create(pid_, 0, GetReturnTrampolineSize()); +// ORBIT_CHECK(!return_trampoline_or_error.has_error()); +// return_trampoline_address_ = return_trampoline_or_error.value()->GetAddress(); +// auto result = +// CreateReturnTrampoline(pid_, exit_payload_function_address_, return_trampoline_address_); +// ORBIT_CHECK(!result.has_error()); +// ORBIT_CHECK(!return_trampoline_or_error.value()->EnsureMemoryExecutable().has_error()); + +// // Copy the beginning of the function over into this process. +// constexpr uint64_t kMaxFunctionBackupSize = 200; +// const uint64_t bytes_to_copy = std::min(size_of_function, kMaxFunctionBackupSize); +// ErrorMessageOr> function_backup = +// ReadTraceesMemory(pid_, function_address_, bytes_to_copy); +// ORBIT_CHECK(function_backup.has_value()); +// function_code_ = function_backup.value(); +// } + +// // Runs the child for a millisecond to assert it is still working fine, stops it, removes the +// // instrumentation, restarts and stops it again. +// void RestartAndRemoveInstrumentation() { +// ORBIT_CHECK(!trampoline_memory_->EnsureMemoryExecutable().has_error()); + +// MoveInstructionPointersOutOfOverwrittenCode(pid_, relocation_map_); + +// ORBIT_CHECK(!DetachAndContinueProcess(pid_).has_error()); +// std::this_thread::sleep_for(std::chrono::milliseconds(1)); +// ORBIT_CHECK(AttachAndStopProcess(pid_).has_value()); + +// auto write_result_or_error = WriteTraceesMemory(pid_, function_address_, function_code_); +// ORBIT_CHECK(!write_result_or_error.has_error()); + +// ORBIT_CHECK(!DetachAndContinueProcess(pid_).has_error()); +// std::this_thread::sleep_for(std::chrono::milliseconds(1)); +// ORBIT_CHECK(AttachAndStopProcess(pid_).has_value()); +// } + +// void TearDown() override { +// cs_close(&capstone_handle_); + +// // Detach and end child. +// if (pid_ != -1) { +// ORBIT_CHECK(!DetachAndContinueProcess(pid_).has_error()); +// kill(pid_, SIGKILL); +// waitpid(pid_, nullptr, 0); +// } +// } + +// pid_t pid_ = -1; +// csh capstone_handle_ = 0; +// uint64_t max_trampoline_size_ = 0; +// std::unique_ptr trampoline_memory_; +// uint64_t trampoline_address_ = 0; +// uint64_t return_trampoline_address_ = 0; +// uint64_t entry_payload_function_address_ = 0; +// uint64_t exit_payload_function_address_ = 0; + +// absl::flat_hash_map relocation_map_; + +// std::string function_name_; +// uint64_t function_address_ = 0; +// std::vector function_code_; +// }; + +// // Function with an ordinary compiler-synthesised prologue; performs some arithmetics. Most real +// // world functions will look like this (starting with pushing the stack frame...). Most functions +// // below are declared "naked", i.e. without the prologue and implemented entirely in assembly. This +// // is done to also cover edge cases. +// extern "C" __attribute__((noinline)) int DoSomething() { +// std::random_device rd; +// std::mt19937 gen(rd()); +// std::uniform_int_distribution dis(1, 6); +// std::vector v(10); +// std::generate(v.begin(), v.end(), [&]() { return dis(gen); }); +// int sum = std::accumulate(v.begin(), v.end(), 0); +// return sum; +// } + +// TEST_F(InstrumentFunctionTest, DoSomething) { +// RunChild(&DoSomething, "DoSomething"); +// PrepareInstrumentation(kEntryPayloadFunctionName, kExitPayloadFunctionName); +// ErrorMessageOr address_after_prologue_or_error = CreateTrampoline( +// pid_, function_address_, function_code_, trampoline_address_, entry_payload_function_address_, +// return_trampoline_address_, capstone_handle_, relocation_map_); +// EXPECT_THAT(address_after_prologue_or_error, HasNoError()); +// ErrorMessageOr result = +// InstrumentFunction(pid_, function_address_, /*function_id=*/42, +// address_after_prologue_or_error.value(), trampoline_address_); +// EXPECT_THAT(result, HasNoError()); +// RestartAndRemoveInstrumentation(); +// } + +// TEST_F(InstrumentFunctionTest, CheckStackAlignedTo16Bytes) { +// RunChild(&DoSomething, "DoSomething"); +// PrepareInstrumentation("EntryPayloadAlignedCopy", kExitPayloadFunctionName); +// ErrorMessageOr address_after_prologue_or_error = CreateTrampoline( +// pid_, function_address_, function_code_, trampoline_address_, entry_payload_function_address_, +// return_trampoline_address_, capstone_handle_, relocation_map_); +// EXPECT_THAT(address_after_prologue_or_error, HasNoError()); +// ErrorMessageOr result = +// InstrumentFunction(pid_, function_address_, /*function_id=*/42, +// address_after_prologue_or_error.value(), trampoline_address_); +// EXPECT_THAT(result, HasNoError()); +// RestartAndRemoveInstrumentation(); +// } + +// // We will not be able to instrument this - the function is just four bytes long and we need five +// // bytes to write a jump. +// extern "C" __attribute__((noinline, naked)) int TooShort() { +// __asm__ __volatile__( +// "nop \n\t" +// "nop \n\t" +// "nop \n\t" +// "ret \n\t" +// : +// : +// :); +// } + +// TEST_F(InstrumentFunctionTest, TooShort) { +// #if defined(ORBIT_COVERAGE_BUILD) || !defined(__clang__) || !defined(NDEBUG) +// GTEST_SKIP(); +// #endif +// RunChild(&TooShort, "TooShort"); +// PrepareInstrumentation(kEntryPayloadFunctionName, kExitPayloadFunctionName); +// ErrorMessageOr result = CreateTrampoline( +// pid_, function_address_, function_code_, trampoline_address_, entry_payload_function_address_, +// return_trampoline_address_, capstone_handle_, relocation_map_); +// EXPECT_THAT(result, +// HasErrorWithMessage("Unable to disassemble enough of the function to instrument it")); +// RestartAndRemoveInstrumentation(); +// } + +// // This function is just long enough to be instrumented (five bytes). It is also interesting in that +// // the return statement is copied into the trampoline and executed from there. +// extern "C" __attribute__((noinline, naked)) int LongEnough() { +// __asm__ __volatile__( +// "nop \n\t" +// "nop \n\t" +// "nop \n\t" +// "nop \n\t" +// "ret \n\t" +// : +// : +// :); +// } + +// TEST_F(InstrumentFunctionTest, LongEnough) { +// RunChild(&LongEnough, "LongEnough"); +// PrepareInstrumentation(kEntryPayloadFunctionName, kExitPayloadFunctionName); +// ErrorMessageOr address_after_prologue_or_error = CreateTrampoline( +// pid_, function_address_, function_code_, trampoline_address_, entry_payload_function_address_, +// return_trampoline_address_, capstone_handle_, relocation_map_); +// EXPECT_THAT(address_after_prologue_or_error, HasNoError()); +// ErrorMessageOr result = +// InstrumentFunction(pid_, function_address_, /*function_id=*/42, +// address_after_prologue_or_error.value(), trampoline_address_); +// EXPECT_THAT(result, HasNoError()); +// RestartAndRemoveInstrumentation(); +// } + +// // The rip relative address is translated to the new code position. +// extern "C" __attribute__((noinline, naked)) int RipRelativeAddressing() { +// __asm__ __volatile__( +// "movq 0x03(%%rip), %%rax\n\t" +// "nop \n\t" +// "nop \n\t" +// "ret \n\t" +// ".quad 0x0102034200000000 \n\t" +// : +// : +// :); +// } + +// TEST_F(InstrumentFunctionTest, RipRelativeAddressing) { +// RunChild(&RipRelativeAddressing, "RipRelativeAddressing"); +// PrepareInstrumentation(kEntryPayloadFunctionName, kExitPayloadFunctionName); +// ErrorMessageOr address_after_prologue_or_error = CreateTrampoline( +// pid_, function_address_, function_code_, trampoline_address_, entry_payload_function_address_, +// return_trampoline_address_, capstone_handle_, relocation_map_); +// EXPECT_THAT(address_after_prologue_or_error, HasNoError()); +// ErrorMessageOr result = +// InstrumentFunction(pid_, function_address_, /*function_id=*/42, +// address_after_prologue_or_error.value(), trampoline_address_); +// EXPECT_THAT(result, HasNoError()); +// RestartAndRemoveInstrumentation(); +// } + +// // Unconditional jump to an 8-bit offset. +// extern "C" __attribute__((noinline, naked)) int UnconditionalJump8BitOffset() { +// __asm__ __volatile__( +// "jmp label_unconditional_jmp_8_bit \n\t" +// "nop \n\t" +// "nop \n\t" +// "nop \n\t" +// "label_unconditional_jmp_8_bit: \n\t" +// "ret \n\t" +// : +// : +// :); +// } + +// TEST_F(InstrumentFunctionTest, UnconditionalJump8BitOffset) { +// RunChild(&UnconditionalJump8BitOffset, "UnconditionalJump8BitOffset"); +// PrepareInstrumentation(kEntryPayloadFunctionName, kExitPayloadFunctionName); +// ErrorMessageOr address_after_prologue_or_error = CreateTrampoline( +// pid_, function_address_, function_code_, trampoline_address_, entry_payload_function_address_, +// return_trampoline_address_, capstone_handle_, relocation_map_); +// EXPECT_THAT(address_after_prologue_or_error, HasNoError()); +// ErrorMessageOr result = +// InstrumentFunction(pid_, function_address_, /*function_id=*/42, +// address_after_prologue_or_error.value(), trampoline_address_); +// EXPECT_THAT(result, HasNoError()); +// RestartAndRemoveInstrumentation(); +// } + +// // Unconditional jump to a 32 bit offset. +// extern "C" __attribute__((noinline, naked)) int UnconditionalJump32BitOffset() { +// __asm__ __volatile__( +// "jmp label_unconditional_jmp_32_bit \n\t" +// ".octa 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 \n\t" // 256 bytes of zeros +// "label_unconditional_jmp_32_bit: \n\t" +// "ret \n\t" +// : +// : +// :); +// } + +// TEST_F(InstrumentFunctionTest, UnconditionalJump32BitOffset) { +// RunChild(&UnconditionalJump32BitOffset, "UnconditionalJump32BitOffset"); +// PrepareInstrumentation(kEntryPayloadFunctionName, kExitPayloadFunctionName); +// ErrorMessageOr address_after_prologue_or_error = CreateTrampoline( +// pid_, function_address_, function_code_, trampoline_address_, entry_payload_function_address_, +// return_trampoline_address_, capstone_handle_, relocation_map_); +// EXPECT_THAT(address_after_prologue_or_error, HasNoError()); +// ErrorMessageOr result = +// InstrumentFunction(pid_, function_address_, /*function_id=*/42, +// address_after_prologue_or_error.value(), trampoline_address_); +// EXPECT_THAT(result, HasNoError()); +// RestartAndRemoveInstrumentation(); +// } + +// // The rip relative address is translated to the new code position. +// extern "C" __attribute__((noinline, naked)) int ConditionalJump8BitOffset() { +// __asm__ __volatile__( +// "jnz loop_label_jcc \n\t" +// "nop \n\t" +// "nop \n\t" +// "nop \n\t" +// "loop_label_jcc: \n\t" +// "xor %%eax, %%eax \n\t" +// "nop \n\t" +// "nop \n\t" +// "ret \n\t" +// : +// : +// :); +// } + +// TEST_F(InstrumentFunctionTest, ConditionalJump8BitOffset) { +// RunChild(&ConditionalJump8BitOffset, "ConditionalJump8BitOffset"); +// PrepareInstrumentation(kEntryPayloadFunctionName, kExitPayloadFunctionName); +// ErrorMessageOr address_after_prologue_or_error = CreateTrampoline( +// pid_, function_address_, function_code_, trampoline_address_, entry_payload_function_address_, +// return_trampoline_address_, capstone_handle_, relocation_map_); +// EXPECT_THAT(address_after_prologue_or_error, HasNoError()); +// ErrorMessageOr result = +// InstrumentFunction(pid_, function_address_, /*function_id=*/42, +// address_after_prologue_or_error.value(), trampoline_address_); +// EXPECT_THAT(result, HasNoError()); +// RestartAndRemoveInstrumentation(); +// } + +// // The rip relative address is translated to the new code position. +// extern "C" __attribute__((noinline, naked)) int ConditionalJump32BitOffset() { +// __asm__ __volatile__( +// "xor %%eax, %%eax \n\t" +// "jnz label_jcc_32_bit \n\t" +// "nop \n\t" +// "ret \n\t" +// ".octa 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 \n\t" // 256 bytes of zeros +// "label_jcc_32_bit: \n\t" +// "ret \n\t" +// : +// : +// :); +// } + +// TEST_F(InstrumentFunctionTest, ConditionalJump32BitOffset) { +// RunChild(&ConditionalJump32BitOffset, "ConditionalJump32BitOffset"); +// PrepareInstrumentation(kEntryPayloadFunctionName, kExitPayloadFunctionName); +// ErrorMessageOr address_after_prologue_or_error = CreateTrampoline( +// pid_, function_address_, function_code_, trampoline_address_, entry_payload_function_address_, +// return_trampoline_address_, capstone_handle_, relocation_map_); +// EXPECT_THAT(address_after_prologue_or_error, HasNoError()); +// ErrorMessageOr result = +// InstrumentFunction(pid_, function_address_, /*function_id=*/42, +// address_after_prologue_or_error.value(), trampoline_address_); +// EXPECT_THAT(result, HasNoError()); +// RestartAndRemoveInstrumentation(); +// } + +// // Function can not be instrumented since it uses the unsupported loop instruction. +// extern "C" __attribute__((noinline, naked)) int Loop() { +// __asm__ __volatile__( +// "mov $42, %%cx\n\t" +// "loop_label:\n\t" +// "loopnz loop_label\n\t" +// "ret \n\t" +// : +// : +// :); +// } + +// TEST_F(InstrumentFunctionTest, Loop) { +// #if defined(ORBIT_COVERAGE_BUILD) || !defined(__clang__) +// GTEST_SKIP(); +// #endif +// RunChild(&Loop, "Loop"); +// PrepareInstrumentation(kEntryPayloadFunctionName, kExitPayloadFunctionName); +// ErrorMessageOr result = CreateTrampoline( +// pid_, function_address_, function_code_, trampoline_address_, entry_payload_function_address_, +// return_trampoline_address_, capstone_handle_, relocation_map_); +// EXPECT_THAT(result, HasErrorWithMessage("Relocating a loop instruction is not supported.")); +// RestartAndRemoveInstrumentation(); +// } + +// // Check-fails if any parameter is not zero. +// extern "C" __attribute__((noinline)) int CheckIntParameters(uint64_t p0, uint64_t p1, uint64_t p2, +// uint64_t p3, uint64_t p4, uint64_t p5, +// uint64_t p6, uint64_t p7) { +// ORBIT_CHECK(p0 == 0 && p1 == 0 && p2 == 0 && p3 == 0 && p4 == 0 && p5 == 0 && p6 == 0 && p7 == 0); +// return 0; +// } + +// // This test and the tests below check for proper handling of parameters handed to the instrumented +// // function. The payload that is called before the instrumented function is executed clobbers the +// // respective set of registers. So the Check*Parameter methods can check if the backup worked +// // correctly. +// TEST_F(InstrumentFunctionTest, CheckIntParameters) { +// function_name_ = "CheckIntParameters"; +// pid_ = fork(); +// ORBIT_CHECK(pid_ != -1); +// if (pid_ == 0) { +// prctl(PR_SET_PDEATHSIG, SIGTERM); + +// // Endless loops without side effects are UB and recent versions of clang optimize it away. +// // Making `sum` volatile avoids that problem. +// [[maybe_unused]] volatile uint64_t sum = 0; +// while (true) { +// sum += CheckIntParameters(0, 0, 0, 0, 0, 0, 0, 0); +// } +// } +// PrepareInstrumentation("EntryPayloadClobberParameterRegisters", kExitPayloadFunctionName); +// ErrorMessageOr address_after_prologue_or_error = CreateTrampoline( +// pid_, function_address_, function_code_, trampoline_address_, entry_payload_function_address_, +// return_trampoline_address_, capstone_handle_, relocation_map_); +// EXPECT_THAT(address_after_prologue_or_error, HasNoError()); +// ErrorMessageOr result = +// InstrumentFunction(pid_, function_address_, /*function_id=*/42, +// address_after_prologue_or_error.value(), trampoline_address_); +// EXPECT_THAT(result, HasNoError()); +// RestartAndRemoveInstrumentation(); +// } + +// // Check-fails if any parameter is not zero. +// extern "C" __attribute__((noinline)) int CheckFloatParameters(float p0, float p1, float p2, +// float p3, float p4, float p5, +// float p6, float p7) { +// ORBIT_CHECK(p0 == 0.f && p1 == 0.f && p2 == 0.f && p3 == 0.f && p4 == 0.f && p5 == 0.f && +// p6 == 0.f && p7 == 0.f); +// return 0; +// } + +// TEST_F(InstrumentFunctionTest, CheckFloatParameters) { +// function_name_ = "CheckFloatParameters"; +// pid_ = fork(); +// ORBIT_CHECK(pid_ != -1); +// if (pid_ == 0) { +// prctl(PR_SET_PDEATHSIG, SIGTERM); + +// // Endless loops without side effects are UB and recent versions of clang optimize it away. +// // Making `sum` volatile avoids that problem. +// [[maybe_unused]] volatile uint64_t sum = 0; +// while (true) { +// sum += CheckFloatParameters(0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f); +// } +// } +// PrepareInstrumentation("EntryPayloadClobberXmmRegisters", kExitPayloadFunctionName); +// ErrorMessageOr address_after_prologue_or_error = CreateTrampoline( +// pid_, function_address_, function_code_, trampoline_address_, entry_payload_function_address_, +// return_trampoline_address_, capstone_handle_, relocation_map_); +// EXPECT_THAT(address_after_prologue_or_error, HasNoError()); +// ErrorMessageOr result = +// InstrumentFunction(pid_, function_address_, /*function_id=*/42, +// address_after_prologue_or_error.value(), trampoline_address_); +// EXPECT_THAT(result, HasNoError()); +// RestartAndRemoveInstrumentation(); +// } + +// // Check-fails if any parameter is not zero. +// extern "C" __attribute__((noinline)) int CheckM256iParameters(__m256i p0, __m256i p1, __m256i p2, +// __m256i p3, __m256i p4, __m256i p5, +// __m256i p6, __m256i p7) { +// // ORBIT_CHECK(_mm256_extract_epi64(p0, 0) == 0 && _mm256_extract_epi64(p1, 0) == 0 && +// // _mm256_extract_epi64(p2, 0) == 0 && _mm256_extract_epi64(p3, 0) == 0 && +// // _mm256_extract_epi64(p4, 0) == 0 && _mm256_extract_epi64(p5, 0) == 0 && +// // _mm256_extract_epi64(p6, 0) == 0 && _mm256_extract_epi64(p7, 0) == 0); +// // return 0; +// } + +// TEST_F(InstrumentFunctionTest, CheckM256iParameters) { +// // function_name_ = "CheckM256iParameters"; +// // pid_ = fork(); +// // ORBIT_CHECK(pid_ != -1); +// // if (pid_ == 0) { +// // prctl(PR_SET_PDEATHSIG, SIGTERM); + +// // // Endless loops without side effects are UB and recent versions of clang optimize it away. +// // // Making `sum` volatile avoids that problem. +// // [[maybe_unused]] volatile uint64_t sum = 0; +// // while (true) { +// // sum += +// // CheckM256iParameters(_mm256_set1_epi64x(0), _mm256_set1_epi64x(0), _mm256_set1_epi64x(0), +// // _mm256_set1_epi64x(0), _mm256_set1_epi64x(0), _mm256_set1_epi64x(0), +// // _mm256_set1_epi64x(0), _mm256_set1_epi64x(0)); +// // } +// // } +// // PrepareInstrumentation("EntryPayloadClobberYmmRegisters", kExitPayloadFunctionName); +// // ErrorMessageOr address_after_prologue_or_error = CreateTrampoline( +// // pid_, function_address_, function_code_, trampoline_address_, entry_payload_function_address_, +// // return_trampoline_address_, capstone_handle_, relocation_map_); +// // EXPECT_THAT(address_after_prologue_or_error, HasNoError()); +// // ErrorMessageOr result = +// // InstrumentFunction(pid_, function_address_, /*function_id=*/42, +// // address_after_prologue_or_error.value(), trampoline_address_); +// // EXPECT_THAT(result, HasNoError()); +// // RestartAndRemoveInstrumentation(); +// } + +// // Check-fails if any parameter is not zero. +// extern "C" __attribute__((noinline, ms_abi)) int CheckIntParametersMsAbi(uint64_t p0, uint64_t p1, +// uint64_t p2, uint64_t p3) { +// ORBIT_CHECK(p0 == 0 && p1 == 0 && p2 == 0 && p3 == 0); +// return 0; +// } + +// TEST_F(InstrumentFunctionTest, CheckIntParametersMsAbi) { +// function_name_ = "CheckIntParametersMsAbi"; +// pid_ = fork(); +// ORBIT_CHECK(pid_ != -1); +// if (pid_ == 0) { +// prctl(PR_SET_PDEATHSIG, SIGTERM); + +// // Endless loops without side effects are UB and recent versions of clang optimize it away. +// // Making `sum` volatile avoids that problem. +// [[maybe_unused]] volatile uint64_t sum = 0; +// while (true) { +// sum += CheckIntParametersMsAbi(0, 0, 0, 0); +// } +// } +// PrepareInstrumentation("EntryPayloadClobberParameterRegisters", kExitPayloadFunctionName); +// ErrorMessageOr address_after_prologue_or_error = CreateTrampoline( +// pid_, function_address_, function_code_, trampoline_address_, entry_payload_function_address_, +// return_trampoline_address_, capstone_handle_, relocation_map_); +// EXPECT_THAT(address_after_prologue_or_error, HasNoError()); +// ErrorMessageOr result = +// InstrumentFunction(pid_, function_address_, /*function_id=*/42, +// address_after_prologue_or_error.value(), trampoline_address_); +// EXPECT_THAT(result, HasNoError()); +// RestartAndRemoveInstrumentation(); +// } + +// // Check-fails if any parameter is not zero. +// extern "C" __attribute__((noinline, ms_abi)) int CheckFloatParametersMsAbi(float p0, float p1, +// float p2, float p3) { +// ORBIT_CHECK(p0 == 0.f && p1 == 0.f && p2 == 0.f && p3 == 0.f); +// return 0; +// } + +// TEST_F(InstrumentFunctionTest, CheckFloatParametersMsAbi) { +// function_name_ = "CheckFloatParametersMsAbi"; +// pid_ = fork(); +// ORBIT_CHECK(pid_ != -1); +// if (pid_ == 0) { +// prctl(PR_SET_PDEATHSIG, SIGTERM); + +// // Endless loops without side effects are UB and recent versions of clang optimize it away. +// // Making `sum` volatile avoids that problem. +// [[maybe_unused]] volatile uint64_t sum = 0; +// while (true) { +// sum += CheckFloatParametersMsAbi(0.f, 0.f, 0.f, 0.f); +// } +// } +// PrepareInstrumentation("EntryPayloadClobberXmmRegisters", kExitPayloadFunctionName); +// ErrorMessageOr address_after_prologue_or_error = CreateTrampoline( +// pid_, function_address_, function_code_, trampoline_address_, entry_payload_function_address_, +// return_trampoline_address_, capstone_handle_, relocation_map_); +// EXPECT_THAT(address_after_prologue_or_error, HasNoError()); +// ErrorMessageOr result = +// InstrumentFunction(pid_, function_address_, /*function_id=*/42, +// address_after_prologue_or_error.value(), trampoline_address_); +// EXPECT_THAT(result, HasNoError()); +// RestartAndRemoveInstrumentation(); +// } + +// // This test guards against naively backing up x87 registers in the return trampoline when the +// // instrumented function doesn't use them to return values. +// TEST_F(InstrumentFunctionTest, CheckNoX87UnderflowInReturnTrampoline) { +// function_name_ = "DoSomething"; +// pid_ = fork(); +// ORBIT_CHECK(pid_ != -1); +// if (pid_ == 0) { +// prctl(PR_SET_PDEATHSIG, SIGTERM); + +// // Reset bit 0 of the 16-bit x87 FPU Control Word, in order to unmask invalid-operation +// // exception. If the return trampoline causes the underflow of the x87 register stack before +// // masking the exception, the process will crash. +// uint16_t control = 0; +// __asm__ __volatile__("fnstcw %0\n\t" : "=m"(control) : :); +// control &= 0xFE; +// __asm__ __volatile__("fldcw %0\n\t" : : "m"(control) :); + +// // Endless loops without side effects are UB and recent versions of clang optimize it away. +// // Making `sum` volatile avoids that problem. +// [[maybe_unused]] volatile uint64_t sum = 0; +// while (true) { +// sum += DoSomething(); +// } +// } +// PrepareInstrumentation(kEntryPayloadFunctionName, kExitPayloadFunctionName); +// ErrorMessageOr address_after_prologue_or_error = CreateTrampoline( +// pid_, function_address_, function_code_, trampoline_address_, entry_payload_function_address_, +// return_trampoline_address_, capstone_handle_, relocation_map_); +// EXPECT_THAT(address_after_prologue_or_error, HasNoError()); +// ErrorMessageOr result = +// InstrumentFunction(pid_, function_address_, /*function_id=*/42, +// address_after_prologue_or_error.value(), trampoline_address_); +// EXPECT_THAT(result, HasNoError()); +// RestartAndRemoveInstrumentation(); +// } + +// extern "C" __attribute__((noinline, naked)) int UnconditionalJump8BitOffsetBackToBeginning() { +// __asm__ __volatile__( +// "nop \n\t" +// "nop \n\t" +// "nop \n\t" +// "nop \n\t" +// "nop \n\t" +// ".byte 0xeb \n\t" // jmp -7 (which is the first nop) +// ".byte 0xf9 \n\t" +// "xor %%eax, %%eax \n\t" +// "ret \n\t" +// : +// : +// :); +// } + +// // This will fail to create a trampoline since the function contains an unconditional jump to an +// // eight bit offset which points back into the first five bytes of the function. +// TEST_F(InstrumentFunctionTest, UnconditionalJump8BitOffsetBackToBeginning) { +// // Exclude gcc builds: the inline assembly above gets messed up by the compiler. +// #if defined(ORBIT_COVERAGE_BUILD) || !defined(__clang__) || !defined(NDEBUG) +// GTEST_SKIP(); +// #endif +// RunChild(&UnconditionalJump8BitOffsetBackToBeginning, +// "UnconditionalJump8BitOffsetBackToBeginning"); +// PrepareInstrumentation(kEntryPayloadFunctionName, kExitPayloadFunctionName); +// ErrorMessageOr result = CreateTrampoline( +// pid_, function_address_, function_code_, trampoline_address_, entry_payload_function_address_, +// return_trampoline_address_, capstone_handle_, relocation_map_); +// EXPECT_THAT(result, +// HasErrorWithMessage( +// "Failed to create trampoline since the function contains a jump back into")); +// } + +// extern "C" __attribute__((noinline, naked)) int UnconditionalJump32BitOffsetBackToBeginning() { +// __asm__ __volatile__( +// "nop \n\t" +// "nop \n\t" +// "nop \n\t" +// "nop \n\t" +// "nop \n\t" +// ".byte 0xe9 \n\t" // jmp -10 (which is the first nop) +// ".long 0xfffffff6 \n\t" +// "xor %%eax, %%eax \n\t" +// "ret \n\t" +// : +// : +// :); +// } + +// // This will fail to create a trampoline since the function contains an unconditional jump to a +// // 32 bit offset which points back into the first five bytes of the function. +// TEST_F(InstrumentFunctionTest, UnconditionalJump32BitOffsetBackToBeginning) { +// // Exclude gcc builds: the inline assembly above gets messed up by the compiler. +// #if defined(ORBIT_COVERAGE_BUILD) || !defined(__clang__) || !defined(NDEBUG) +// GTEST_SKIP(); +// #endif +// RunChild(&UnconditionalJump32BitOffsetBackToBeginning, +// "UnconditionalJump32BitOffsetBackToBeginning"); +// PrepareInstrumentation(kEntryPayloadFunctionName, kExitPayloadFunctionName); +// ErrorMessageOr result = CreateTrampoline( +// pid_, function_address_, function_code_, trampoline_address_, entry_payload_function_address_, +// return_trampoline_address_, capstone_handle_, relocation_map_); +// EXPECT_THAT(result, +// HasErrorWithMessage( +// "Failed to create trampoline since the function contains a jump back into")); +// } + +// extern "C" __attribute__((noinline, naked)) int ConditionalJump8BitOffsetBackToBeginning() { +// __asm__ __volatile__( +// "nop \n\t" +// "nop \n\t" +// "nop \n\t" +// "nop \n\t" +// "nop \n\t" +// ".byte 0x70 \n\t" // jo -7 (which is the first nop) +// ".byte 0xf9 \n\t" +// "xor %%eax, %%eax \n\t" +// "ret \n\t" +// : +// : +// :); +// } + +// // This will fail to create a trampoline since the function contains a conditional jump to an +// // eight bit offset which points back into the first five bytes of the function. +// TEST_F(InstrumentFunctionTest, ConditionalJump8BitOffsetBackToBeginning) { +// // Exclude gcc builds: the inline assembly above gets messed up by the compiler. +// #if defined(ORBIT_COVERAGE_BUILD) || !defined(__clang__) || !defined(NDEBUG) +// GTEST_SKIP(); +// #endif +// RunChild(&ConditionalJump8BitOffsetBackToBeginning, "ConditionalJump8BitOffsetBackToBeginning"); +// PrepareInstrumentation(kEntryPayloadFunctionName, kExitPayloadFunctionName); +// ErrorMessageOr result = CreateTrampoline( +// pid_, function_address_, function_code_, trampoline_address_, entry_payload_function_address_, +// return_trampoline_address_, capstone_handle_, relocation_map_); +// EXPECT_THAT(result, +// HasErrorWithMessage( +// "Failed to create trampoline since the function contains a jump back into")); +// } + +// extern "C" __attribute__((noinline, naked)) int ConditionalJump32BitOffsetBackToBeginning() { +// __asm__ __volatile__( +// "nop \n\t" +// "nop \n\t" +// "nop \n\t" +// "nop \n\t" +// "nop \n\t" +// ".byte 0x0f \n\t" // jo -7 (which is the last nop) +// ".byte 0x80 \n\t" +// ".long 0xfffffff9 \n\t" +// "xor %%eax, %%eax \n\t" +// "ret \n\t" +// : +// : +// :); +// } + +// // This will fail to create a trampoline since the function contains a conditional jump to a +// // 32 bit offset which points back into the first five bytes of the function. +// TEST_F(InstrumentFunctionTest, ConditionalJump32BitOffsetBackToBeginning) { +// // Exclude gcc builds: the inline assembly above gets messed up by the compiler. +// #if defined(ORBIT_COVERAGE_BUILD) || !defined(__clang__) || !defined(NDEBUG) +// GTEST_SKIP(); +// #endif +// RunChild(&ConditionalJump32BitOffsetBackToBeginning, "ConditionalJump32BitOffsetBackToBeginning"); +// PrepareInstrumentation(kEntryPayloadFunctionName, kExitPayloadFunctionName); +// ErrorMessageOr result = CreateTrampoline( +// pid_, function_address_, function_code_, trampoline_address_, entry_payload_function_address_, +// return_trampoline_address_, capstone_handle_, relocation_map_); +// EXPECT_THAT(result, +// HasErrorWithMessage( +// "Failed to create trampoline since the function contains a jump back into")); +// } + +// extern "C" __attribute__((noinline, naked)) int LongConditionalJump32BitOffsetBackToBeginning() { +// __asm__ __volatile__( +// "xor %%eax, %%eax \n\t" +// "ret \n\t" +// ".octa 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 \n\t" // 256 bytes of zeros +// ".byte 0x0f \n\t" // jo -263 (which is the ret) +// ".byte 0x80 \n\t" +// ".long 0xfffffef9 \n\t" +// : +// : +// :); +// } + +// // This will create a trampoline. The function contains a conditional jump to a +// // 32 bit offset which points back into the first five bytes of the function. However the jump is +// // occurring after the 200 byte limit and therefore it stays undetected. +// TEST_F(InstrumentFunctionTest, LongConditionalJump32BitOffsetBackToBeginning) { +// RunChild(&LongConditionalJump32BitOffsetBackToBeginning, +// "LongConditionalJump32BitOffsetBackToBeginning"); +// PrepareInstrumentation(kEntryPayloadFunctionName, kExitPayloadFunctionName); +// ErrorMessageOr result = CreateTrampoline( +// pid_, function_address_, function_code_, trampoline_address_, entry_payload_function_address_, +// return_trampoline_address_, capstone_handle_, relocation_map_); +// EXPECT_THAT(result, HasNoError()); +// } + +// extern "C" __attribute__((noinline, naked)) int UnableToDisassembleBadInstruction() { +// __asm__ __volatile__( +// "nop \n\t" +// "nop \n\t" +// "nop \n\t" +// "nop \n\t" +// "ret \n\t" +// ".byte 0x06 \n\t" // bad instruction +// ".byte 0x0f \n\t" // jo -12 (which is the first nop) +// ".byte 0x80 \n\t" +// ".long 0xfffffff4 \n\t" +// : +// : +// :); +// } + +// // This will create a trampoline. There is a conditional jump back to the start but the disassembler +// // gets confused before it reaches this and so we don't detect it. +// TEST_F(InstrumentFunctionTest, UnableToDisassembleBadInstruction) { +// RunChild(&UnableToDisassembleBadInstruction, "UnableToDisassembleBadInstruction"); +// PrepareInstrumentation(kEntryPayloadFunctionName, kExitPayloadFunctionName); +// ErrorMessageOr result = CreateTrampoline( +// pid_, function_address_, function_code_, trampoline_address_, entry_payload_function_address_, +// return_trampoline_address_, capstone_handle_, relocation_map_); +// EXPECT_THAT(result, HasNoError()); +// } + +// } // namespace orbit_user_space_instrumentation diff --git a/third_party/libunwindstack/CMakeLists.txt b/third_party/libunwindstack/CMakeLists.txt index e956de18da9..9d3fe78e270 100644 --- a/third_party/libunwindstack/CMakeLists.txt +++ b/third_party/libunwindstack/CMakeLists.txt @@ -196,206 +196,193 @@ endif() target_compile_options(libunwindstack PRIVATE -Wno-error=format-nonliteral) -add_executable(libunwindstack_tests) -target_sources(libunwindstack_tests PRIVATE - $ - LogAndroid.cpp - - # AndroidUnwinderTest are broken and need to be investigated, - # but we currently don't use this part of the library. - # tests/AndroidUnwinderTest.cpp - - tests/ArmExidxDecodeTest.cpp - tests/ArmExidxExtractTest.cpp - - # We compile without DEX file support - # tests/DexFileTest.cpp - # tests/DexFilesTest.cpp - - tests/DwarfCfaLogTest.cpp - tests/DwarfCfaTest.cpp - tests/DwarfDebugFrameTest.cpp - tests/DwarfEhFrameTest.cpp - tests/DwarfEhFrameWithHdrTest.cpp - tests/DwarfMemoryTest.cpp - tests/DwarfOpLogTest.cpp - tests/DwarfOpTest.cpp - tests/DwarfSectionImplTest.cpp - tests/DwarfSectionTest.cpp - tests/ElfFake.cpp - tests/ElfInterfaceArmTest.cpp - tests/ElfInterfaceTest.cpp - tests/ElfTest.cpp - tests/ElfTestUtils.cpp - - # Not a test file - # tests/GenGnuDebugdata.cpp - - tests/GlobalDebugImplTest.cpp - tests/GlobalTest.cpp - tests/IsolatedSettings.cpp - tests/JitDebugTest.cpp - tests/LocalUpdatableMapsTest.cpp - tests/LogFake.cpp - tests/MapInfoCreateMemoryTest.cpp - tests/MapInfoGetBuildIDTest.cpp - tests/MapInfoGetLoadBiasTest.cpp - tests/MapInfoGetObjectTest.cpp - tests/MapInfoTest.cpp - tests/MapsTest.cpp - tests/MemoryBufferTest.cpp - tests/MemoryCacheTest.cpp - tests/MemoryFileTest.cpp - tests/MemoryLocalTest.cpp - - # This is Android-specific - # tests/MemoryMteTest.cpp - - tests/MemoryOfflineBufferTest.cpp - tests/MemoryOfflineTest.cpp - tests/MemoryRangeTest.cpp - tests/MemoryRangesTest.cpp - tests/MemoryRemoteTest.cpp - tests/MemoryTest.cpp - tests/MemoryThreadCacheTest.cpp - tests/MemoryXzTest.cpp - tests/ObjectBuildIdTest.cpp - tests/ObjectCacheTest.cpp - tests/PeCoffInterfaceTest.cpp - tests/PeCoffFake.cpp - tests/PeCoffRuntimeFunctionsTest.cpp - tests/PeCoffTest.cpp - tests/PeCoffUnwindInfoEvaluatorTest.cpp - tests/PeCoffUnwindInfosTest.cpp - tests/PeCoffUnwindInfoUnwinderX86_64Test.cpp - tests/PeCoffEpilogTest.cpp - tests/RegsInfoTest.cpp - tests/RegsIterateTest.cpp - tests/RegsStepIfSignalHandlerTest.cpp - tests/RegsRemoteTest.cpp - tests/RegsTest.cpp - tests/SymbolsTest.cpp - - # TestLocal is not a test. It belongs to a testing library. - # tests/TestLocal.cpp - - tests/TestUtils.cpp - tests/UnwindOfflineTest.cpp - tests/UnwindTest.cpp - tests/UnwinderTest.cpp - tests/VerifyBionicTerminationTest.cpp - utils/MemoryFake.cpp - utils/OfflineUnwindUtils.cpp - utils/PidUtils.cpp - utils/ProcessTracer.cpp) - -# Some tests call dlopen/dlsym/dlclose which requires the -# dynamic linker. -target_link_libraries(libunwindstack_tests PRIVATE ${CMAKE_DL_LIBS}) - -target_link_libraries(libunwindstack_tests PRIVATE - liblog_shared - libbase - libprocinfo - capstone::capstone - LZMA::LZMA - GTest::Main - ZLIB::ZLIB) - -target_include_directories(libunwindstack_tests PRIVATE - ${CMAKE_CURRENT_SOURCE_DIR} - utils/ - include/) - -if (CMAKE_CXX_COMPILER_ID STREQUAL "Clang") - target_compile_options(libunwindstack_tests PRIVATE - -Wno-error=format-nonliteral - -Wno-error=inconsistent-missing-override - -Wno-error=unused-result - -Wno-error=defaulted-function-deleted) -else() - target_compile_options(libunwindstack_tests PRIVATE - -Wno-error=format-nonliteral - -Wno-error=unused-result) -endif() - -# Some tests unwind its own callstacks so we have to disable inlining to make -# sure all the expected functions show up in the examined callstacks. -# They also invoke a lot of different kinds of UB which would all be optimized away, -# if we didn't disable optimization. -target_compile_options(libunwindstack_tests PRIVATE -O0) - -register_test(libunwindstack_tests) - -# The tests expect the testdata next to the test binary. -add_custom_command(TARGET libunwindstack_tests POST_BUILD - COMMAND ${CMAKE_COMMAND} -E remove_directory - $/offline_files - COMMAND ${CMAKE_COMMAND} -E copy_directory - ${CMAKE_CURRENT_LIST_DIR}/offline_files - $/offline_files) - -add_custom_command(TARGET libunwindstack_tests POST_BUILD - COMMAND ${CMAKE_COMMAND} -E remove_directory - $/tests - COMMAND ${CMAKE_COMMAND} -E copy_directory - ${CMAKE_CURRENT_LIST_DIR}/tests - $/tests) - - - -# This is a testing library that will be consumed by the tests. -add_library(libunwindstack_local SHARED - $ - LogStdout.cpp - tests/TestLocal.cpp) - -target_link_libraries(libunwindstack_local PRIVATE - libbase - - # liblog_static needs to be listed AFTER libbase due to cyclic depdendencies. - liblog_static - LZMA::LZMA) - -target_include_directories(libunwindstack_local PRIVATE include/) - -# Clang >= 8.0 -if (CMAKE_CXX_COMPILER_ID STREQUAL "Clang" AND - CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL 8) - target_compile_options(libunwindstack_local PRIVATE - -Wno-error=ctad-maybe-unsupported) -endif() - -target_compile_options(libunwindstack_local PRIVATE - -Wno-error=format-nonliteral) - -# This library unwinds its own callstacks so we have to disable inlining -# to make sure all the expected functions show up in the examined callstacks. -# It also invokes a lot of different kinds of UB which would all be optimized away, -# if we didn't disable optimization. -target_compile_options(libunwindstack_local PRIVATE -O0) - -set_target_properties(libunwindstack_local PROPERTIES OUTPUT_NAME "unwindstack_local") - -# The tests expect this library next to the executable. -set_target_properties(libunwindstack_local PROPERTIES - LIBRARY_OUTPUT_DIRECTORY $) -set_target_properties(libunwindstack_local PROPERTIES - LIBRARY_OUTPUT_DIRECTORY_RELEASE $) -set_target_properties(libunwindstack_local PROPERTIES - LIBRARY_OUTPUT_DIRECTORY_RELWITHDEBINFO $) -set_target_properties(libunwindstack_local PROPERTIES - LIBRARY_OUTPUT_DIRECTORY_DEBUG $) - -# Fuzz testing for parsers -add_fuzzer(PeCoffInterfaceFuzzer tests/fuzz/PeCoffInterfaceFuzzer.cpp) -target_include_directories(PeCoffInterfaceFuzzer PRIVATE ${CMAKE_CURRENT_SOURCE_DIR} include/) -target_link_libraries(PeCoffInterfaceFuzzer PRIVATE libunwindstack) - -add_fuzzer(PeCoffUnwindInfosFuzzer tests/fuzz/PeCoffUnwindInfosFuzzer.cpp) -target_include_directories(PeCoffUnwindInfosFuzzer PRIVATE ${CMAKE_CURRENT_SOURCE_DIR} include/) -target_link_libraries(PeCoffUnwindInfosFuzzer PRIVATE libunwindstack) - -add_fuzzer(PeCoffRuntimeFunctionsFuzzer tests/fuzz/PeCoffRuntimeFunctionsFuzzer.cpp) -target_include_directories(PeCoffRuntimeFunctionsFuzzer PRIVATE ${CMAKE_CURRENT_SOURCE_DIR} include/) -target_link_libraries(PeCoffRuntimeFunctionsFuzzer PRIVATE libunwindstack) \ No newline at end of file +# add_executable(libunwindstack_tests) +# target_sources(libunwindstack_tests PRIVATE +# $ +# LogAndroid.cpp + +# # AndroidUnwinderTest are broken and need to be investigated, +# # but we currently don't use this part of the library. +# # tests/AndroidUnwinderTest.cpp + +# tests/ArmExidxDecodeTest.cpp +# tests/ArmExidxExtractTest.cpp + +# # We compile without DEX file support +# # tests/DexFileTest.cpp +# # tests/DexFilesTest.cpp + +# tests/DwarfCfaLogTest.cpp +# tests/DwarfCfaTest.cpp +# tests/DwarfDebugFrameTest.cpp +# tests/DwarfEhFrameTest.cpp +# tests/DwarfEhFrameWithHdrTest.cpp +# tests/DwarfMemoryTest.cpp +# tests/DwarfOpLogTest.cpp +# tests/DwarfOpTest.cpp +# tests/DwarfSectionImplTest.cpp +# tests/DwarfSectionTest.cpp +# tests/ElfFake.cpp +# tests/ElfInterfaceArmTest.cpp +# tests/ElfInterfaceTest.cpp +# tests/ElfTest.cpp +# tests/ElfTestUtils.cpp + +# # Not a test file +# # tests/GenGnuDebugdata.cpp + +# tests/GlobalDebugImplTest.cpp +# tests/GlobalTest.cpp +# tests/IsolatedSettings.cpp +# tests/JitDebugTest.cpp +# tests/LocalUpdatableMapsTest.cpp +# tests/LogFake.cpp +# tests/MapInfoCreateMemoryTest.cpp +# tests/MapInfoGetBuildIDTest.cpp +# tests/MapInfoGetLoadBiasTest.cpp +# tests/MapInfoGetObjectTest.cpp +# tests/MapInfoTest.cpp +# tests/MapsTest.cpp +# tests/MemoryBufferTest.cpp +# tests/MemoryCacheTest.cpp +# tests/MemoryFileTest.cpp +# tests/MemoryLocalTest.cpp + +# # This is Android-specific +# # tests/MemoryMteTest.cpp + +# tests/MemoryOfflineBufferTest.cpp +# tests/MemoryOfflineTest.cpp +# tests/MemoryRangeTest.cpp +# tests/MemoryRangesTest.cpp +# tests/MemoryRemoteTest.cpp +# tests/MemoryTest.cpp +# tests/MemoryThreadCacheTest.cpp +# tests/MemoryXzTest.cpp +# tests/ObjectBuildIdTest.cpp +# tests/ObjectCacheTest.cpp +# tests/PeCoffInterfaceTest.cpp +# tests/PeCoffFake.cpp +# tests/PeCoffRuntimeFunctionsTest.cpp +# tests/PeCoffTest.cpp +# tests/PeCoffUnwindInfoEvaluatorTest.cpp +# tests/PeCoffUnwindInfosTest.cpp +# tests/PeCoffUnwindInfoUnwinderX86_64Test.cpp +# tests/PeCoffEpilogTest.cpp +# tests/RegsInfoTest.cpp +# tests/RegsIterateTest.cpp +# tests/RegsStepIfSignalHandlerTest.cpp +# tests/RegsRemoteTest.cpp +# tests/RegsTest.cpp +# tests/SymbolsTest.cpp + +# # TestLocal is not a test. It belongs to a testing library. +# # tests/TestLocal.cpp + +# tests/TestUtils.cpp +# tests/UnwindOfflineTest.cpp +# tests/UnwindTest.cpp +# tests/UnwinderTest.cpp +# tests/VerifyBionicTerminationTest.cpp +# utils/MemoryFake.cpp +# utils/OfflineUnwindUtils.cpp +# utils/PidUtils.cpp +# utils/ProcessTracer.cpp) + +# # Some tests call dlopen/dlsym/dlclose which requires the +# # dynamic linker. +# target_link_libraries(libunwindstack_tests PRIVATE ${CMAKE_DL_LIBS}) + +# target_link_libraries(libunwindstack_tests PRIVATE +# liblog_shared +# libbase +# libprocinfo +# capstone::capstone +# LZMA::LZMA +# GTest::Main +# ZLIB::ZLIB) + +# target_include_directories(libunwindstack_tests PRIVATE +# ${CMAKE_CURRENT_SOURCE_DIR} +# utils/ +# include/) + +# if (CMAKE_CXX_COMPILER_ID STREQUAL "Clang") +# target_compile_options(libunwindstack_tests PRIVATE +# -Wno-error=format-nonliteral +# -Wno-error=inconsistent-missing-override +# -Wno-error=unused-result +# -Wno-error=defaulted-function-deleted) +# else() +# target_compile_options(libunwindstack_tests PRIVATE +# -Wno-error=format-nonliteral +# -Wno-error=unused-result) +# endif() + +# # Some tests unwind its own callstacks so we have to disable inlining to make +# # sure all the expected functions show up in the examined callstacks. +# # They also invoke a lot of different kinds of UB which would all be optimized away, +# # if we didn't disable optimization. +# target_compile_options(libunwindstack_tests PRIVATE -O0) + +# register_test(libunwindstack_tests) + +# # The tests expect the testdata next to the test binary. +# add_custom_command(TARGET libunwindstack_tests POST_BUILD +# COMMAND ${CMAKE_COMMAND} -E remove_directory +# $/offline_files +# COMMAND ${CMAKE_COMMAND} -E copy_directory +# ${CMAKE_CURRENT_LIST_DIR}/offline_files +# $/offline_files) + +# add_custom_command(TARGET libunwindstack_tests POST_BUILD +# COMMAND ${CMAKE_COMMAND} -E remove_directory +# $/tests +# COMMAND ${CMAKE_COMMAND} -E copy_directory +# ${CMAKE_CURRENT_LIST_DIR}/tests +# $/tests) + + + +# # This is a testing library that will be consumed by the tests. +# add_library(libunwindstack_local SHARED +# $ +# LogStdout.cpp +# tests/TestLocal.cpp) + +# target_link_libraries(libunwindstack_local PRIVATE +# libbase + +# # liblog_static needs to be listed AFTER libbase due to cyclic depdendencies. +# liblog_static +# LZMA::LZMA) + +# target_include_directories(libunwindstack_local PRIVATE include/) + +# # Clang >= 8.0 +# if (CMAKE_CXX_COMPILER_ID STREQUAL "Clang" AND +# CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL 8) +# target_compile_options(libunwindstack_local PRIVATE +# -Wno-error=ctad-maybe-unsupported) +# endif() + +# target_compile_options(libunwindstack_local PRIVATE +# -Wno-error=format-nonliteral) + +# # This library unwinds its own callstacks so we have to disable inlining +# # to make sure all the expected functions show up in the examined callstacks. +# # It also invokes a lot of different kinds of UB which would all be optimized away, +# # if we didn't disable optimization. +# target_compile_options(libunwindstack_local PRIVATE -O0) + +# set_target_properties(libunwindstack_local PROPERTIES OUTPUT_NAME "unwindstack_local") + +# # The tests expect this library next to the executable. +# set_target_properties(libunwindstack_local PROPERTIES +# LIBRARY_OUTPUT_DIRECTORY $) +# set_target_properties(libunwindstack_local PROPERTIES +# LIBRARY_OUTPUT_DIRECTORY_RELEASE $) +# set_target_properties(libunwindstack_local PROPERTIES +# LIBRARY_OUTPUT_DIRECTORY_RELWITHDEBINFO $) +# set_target_properties(libunwindstack_local PROPERTIES +# LIBRARY_OUTPUT_DIRECTORY_DEBUG $) From 2f6c79a4f6d485fad5a2048ba84346616aa82178 Mon Sep 17 00:00:00 2001 From: Pierric Gimmig Date: Sun, 5 Jan 2025 22:43:48 -0800 Subject: [PATCH 6/8] Fix Linux compilation --- src/OrbitBase/ExecuteCommandLinux.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/OrbitBase/ExecuteCommandLinux.cpp b/src/OrbitBase/ExecuteCommandLinux.cpp index 4f765e7b1c9..48317afdef4 100644 --- a/src/OrbitBase/ExecuteCommandLinux.cpp +++ b/src/OrbitBase/ExecuteCommandLinux.cpp @@ -15,7 +15,7 @@ namespace orbit_base { std::optional ExecuteCommand(std::string_view cmd) { - std::unique_ptr pipe{popen(std::string{cmd}.c_str(), "r"), pclose}; + std::unique_ptr pipe{popen(std::string{cmd}.c_str(), "r"), pclose}; if (!pipe) { ORBIT_ERROR("Could not open pipe for \"%s\"", cmd); return std::optional{}; From f61f267c067b1cf60d8c3af18408ca23c9d45a54 Mon Sep 17 00:00:00 2001 From: Pierric Gimmig Date: Wed, 29 Jan 2025 20:46:08 -0800 Subject: [PATCH 7/8] Remove old conan profiles --- README.md | 24 +++ bootstrap-orbit.ps1 | 74 -------- bootstrap-orbit.sh | 172 ------------------ build.ps1 | 90 --------- build.sh | 79 -------- .../configs/linux/profiles/clang10_common | 8 - .../configs/linux/profiles/clang10_debug | 4 - .../configs/linux/profiles/clang10_release | 4 - .../linux/profiles/clang10_relwithdebinfo | 4 - .../configs/linux/profiles/clang11_common | 8 - .../configs/linux/profiles/clang11_debug | 4 - .../configs/linux/profiles/clang11_release | 4 - .../profiles/clang11_release_system_deps | 7 - .../linux/profiles/clang11_relwithdebinfo | 4 - .../configs/linux/profiles/clang12_common | 8 - .../configs/linux/profiles/clang12_debug | 4 - .../configs/linux/profiles/clang12_release | 4 - .../profiles/clang12_release_system_deps | 7 - .../configs/linux/profiles/clang13_common | 8 - .../configs/linux/profiles/clang13_debug | 4 - .../configs/linux/profiles/clang13_release | 4 - .../linux/profiles/clang13_relwithdebinfo | 4 - .../configs/linux/profiles/clang14_common | 8 - .../configs/linux/profiles/clang14_release | 4 - .../linux/profiles/clang14_relwithdebinfo | 4 - .../configs/linux/profiles/clang15_common | 8 - .../configs/linux/profiles/clang15_debug | 4 - .../linux/profiles/clang15_relwithdebinfo | 4 - .../profiles/{clang14_debug => clang18_debug} | 2 +- .../{clang15_release => clang18_release} | 2 +- ...relwithdebinfo => clang18_relwithdebinfo } | 2 +- .../configs/linux/profiles/clang7_common | 8 - .../conan/configs/linux/profiles/clang7_debug | 4 - .../configs/linux/profiles/clang7_release | 4 - .../linux/profiles/clang7_relwithdebinfo | 4 - .../configs/linux/profiles/clang8_common | 8 - .../conan/configs/linux/profiles/clang8_debug | 4 - .../configs/linux/profiles/clang8_release | 4 - .../linux/profiles/clang8_relwithdebinfo | 4 - .../configs/linux/profiles/clang9_common | 8 - .../conan/configs/linux/profiles/clang9_debug | 4 - .../configs/linux/profiles/clang9_release | 4 - .../linux/profiles/clang9_relwithdebinfo | 4 - .../conan/configs/linux/profiles/clang_common | 15 -- .../conan/configs/linux/profiles/cmake_common | 9 - .../configs/linux/profiles/coverage_clang11 | 5 - .../conan/configs/linux/profiles/gcc10_common | 8 - .../conan/configs/linux/profiles/gcc10_debug | 4 - .../configs/linux/profiles/gcc10_release | 4 - .../linux/profiles/gcc10_relwithdebinfo | 4 - .../conan/configs/linux/profiles/gcc11_common | 9 - .../conan/configs/linux/profiles/gcc11_debug | 4 - .../configs/linux/profiles/gcc11_release | 4 - .../linux/profiles/gcc11_relwithdebinfo | 4 - .../conan/configs/linux/profiles/gcc12_common | 9 - .../conan/configs/linux/profiles/gcc12_debug | 4 - .../configs/linux/profiles/gcc12_release | 4 - .../linux/profiles/gcc12_relwithdebinfo | 4 - .../conan/configs/linux/profiles/gcc17_debug | 8 + .../configs/linux/profiles/gcc17_release | 8 + .../linux/profiles/gcc17_relwithdebinfo | 8 + .../conan/configs/linux/profiles/gcc9_common | 8 - .../conan/configs/linux/profiles/gcc9_debug | 4 - .../conan/configs/linux/profiles/gcc9_release | 4 - .../linux/profiles/gcc9_relwithdebinfo | 4 - .../conan/configs/linux/profiles/gcc_common | 15 -- third_party/conan/configs/linux/profiles/iwyu | 5 - .../configs/linux/profiles/libfuzzer_base | 21 --- .../linux/profiles/libfuzzer_relwithdebinfo | 13 -- .../conan/configs/linux/profiles/linux_common | 16 -- 70 files changed, 51 insertions(+), 781 deletions(-) delete mode 100644 bootstrap-orbit.ps1 delete mode 100755 bootstrap-orbit.sh delete mode 100644 build.ps1 delete mode 100755 build.sh delete mode 100644 third_party/conan/configs/linux/profiles/clang10_common delete mode 100644 third_party/conan/configs/linux/profiles/clang10_debug delete mode 100644 third_party/conan/configs/linux/profiles/clang10_release delete mode 100644 third_party/conan/configs/linux/profiles/clang10_relwithdebinfo delete mode 100644 third_party/conan/configs/linux/profiles/clang11_common delete mode 100644 third_party/conan/configs/linux/profiles/clang11_debug delete mode 100644 third_party/conan/configs/linux/profiles/clang11_release delete mode 100644 third_party/conan/configs/linux/profiles/clang11_release_system_deps delete mode 100644 third_party/conan/configs/linux/profiles/clang11_relwithdebinfo delete mode 100644 third_party/conan/configs/linux/profiles/clang12_common delete mode 100644 third_party/conan/configs/linux/profiles/clang12_debug delete mode 100644 third_party/conan/configs/linux/profiles/clang12_release delete mode 100644 third_party/conan/configs/linux/profiles/clang12_release_system_deps delete mode 100644 third_party/conan/configs/linux/profiles/clang13_common delete mode 100644 third_party/conan/configs/linux/profiles/clang13_debug delete mode 100644 third_party/conan/configs/linux/profiles/clang13_release delete mode 100644 third_party/conan/configs/linux/profiles/clang13_relwithdebinfo delete mode 100644 third_party/conan/configs/linux/profiles/clang14_common delete mode 100644 third_party/conan/configs/linux/profiles/clang14_release delete mode 100644 third_party/conan/configs/linux/profiles/clang14_relwithdebinfo delete mode 100644 third_party/conan/configs/linux/profiles/clang15_common delete mode 100644 third_party/conan/configs/linux/profiles/clang15_debug delete mode 100644 third_party/conan/configs/linux/profiles/clang15_relwithdebinfo rename third_party/conan/configs/linux/profiles/{clang14_debug => clang18_debug} (54%) rename third_party/conan/configs/linux/profiles/{clang15_release => clang18_release} (56%) rename third_party/conan/configs/linux/profiles/{clang12_relwithdebinfo => clang18_relwithdebinfo } (61%) delete mode 100644 third_party/conan/configs/linux/profiles/clang7_common delete mode 100644 third_party/conan/configs/linux/profiles/clang7_debug delete mode 100644 third_party/conan/configs/linux/profiles/clang7_release delete mode 100644 third_party/conan/configs/linux/profiles/clang7_relwithdebinfo delete mode 100644 third_party/conan/configs/linux/profiles/clang8_common delete mode 100644 third_party/conan/configs/linux/profiles/clang8_debug delete mode 100644 third_party/conan/configs/linux/profiles/clang8_release delete mode 100644 third_party/conan/configs/linux/profiles/clang8_relwithdebinfo delete mode 100644 third_party/conan/configs/linux/profiles/clang9_common delete mode 100644 third_party/conan/configs/linux/profiles/clang9_debug delete mode 100644 third_party/conan/configs/linux/profiles/clang9_release delete mode 100644 third_party/conan/configs/linux/profiles/clang9_relwithdebinfo delete mode 100644 third_party/conan/configs/linux/profiles/clang_common delete mode 100644 third_party/conan/configs/linux/profiles/cmake_common delete mode 100644 third_party/conan/configs/linux/profiles/coverage_clang11 delete mode 100644 third_party/conan/configs/linux/profiles/gcc10_common delete mode 100644 third_party/conan/configs/linux/profiles/gcc10_debug delete mode 100644 third_party/conan/configs/linux/profiles/gcc10_release delete mode 100644 third_party/conan/configs/linux/profiles/gcc10_relwithdebinfo delete mode 100644 third_party/conan/configs/linux/profiles/gcc11_common delete mode 100644 third_party/conan/configs/linux/profiles/gcc11_debug delete mode 100644 third_party/conan/configs/linux/profiles/gcc11_release delete mode 100644 third_party/conan/configs/linux/profiles/gcc11_relwithdebinfo delete mode 100644 third_party/conan/configs/linux/profiles/gcc12_common delete mode 100644 third_party/conan/configs/linux/profiles/gcc12_debug delete mode 100644 third_party/conan/configs/linux/profiles/gcc12_release delete mode 100644 third_party/conan/configs/linux/profiles/gcc12_relwithdebinfo create mode 100644 third_party/conan/configs/linux/profiles/gcc17_debug create mode 100644 third_party/conan/configs/linux/profiles/gcc17_release create mode 100644 third_party/conan/configs/linux/profiles/gcc17_relwithdebinfo delete mode 100644 third_party/conan/configs/linux/profiles/gcc9_common delete mode 100644 third_party/conan/configs/linux/profiles/gcc9_debug delete mode 100644 third_party/conan/configs/linux/profiles/gcc9_release delete mode 100644 third_party/conan/configs/linux/profiles/gcc9_relwithdebinfo delete mode 100644 third_party/conan/configs/linux/profiles/gcc_common delete mode 100644 third_party/conan/configs/linux/profiles/iwyu delete mode 100644 third_party/conan/configs/linux/profiles/libfuzzer_base delete mode 100644 third_party/conan/configs/linux/profiles/libfuzzer_relwithdebinfo delete mode 100644 third_party/conan/configs/linux/profiles/linux_common diff --git a/README.md b/README.md index 1bcecce1f67..f0433c368ff 100644 --- a/README.md +++ b/README.md @@ -158,3 +158,27 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. [orbit_youtube_presentation]: contrib/logos/orbit_presentation_youtube.png + + +To compile on Windows: + +conan install . --build="abseil/*" --build="protobuf/*" --build="grpc/*" --build=missing +cd build +cmake -DCMAKE_TOOLCHAIN_FILE=build/generators/conan_toolchain.cmake .. +cmake --build . --config Release + + +To compile on Linux: + +conan install . --build=missing +cd build +cmake -DCMAKE_TOOLCHAIN_FILE=build/generators/conan_toolchain.cmake .. +cmake --build . --config Release + +with a debug profile: + + + + +Debug example: +conan install . -pr:a third_party/conan/configs/linux/profiles/gcc17_debug --build=missing -of build_gcc_debug diff --git a/bootstrap-orbit.ps1 b/bootstrap-orbit.ps1 deleted file mode 100644 index daa66706950..00000000000 --- a/bootstrap-orbit.ps1 +++ /dev/null @@ -1,74 +0,0 @@ -# Copyright (c) 2020 The Orbit Authors. All rights reserved. -# Use of this source code is governed by a BSD-style license that can be -# found in the LICENSE file. - -$conan_version_required = "1.58.0" - -function Check-Conan-Version-Sufficient { - $version = [System.Version]$args[0] - $required = [System.Version]$args[1] - return $version -ge $required -} - -function conan { - & py -3 -m conans.conan $args -} -function pip3 { - & py -3 -m pip $args -} - -conan --version >null 2>&1 - -if ($LastExitCode -ne 0) { - Write-Host "Conan not found. Trying to install it via python-pip..." - - - pip3 --version >null 2>&1 - - if ($LastExitCode -ne 0) { - Write-Error -ErrorAction Stop @" -It seems you don't have Python3 (or PIP) installed (py -3 -m pip --version fails). -Please install Python and make it available in the path. -"@ - } - - pip3 install --upgrade --user conan==$conan_version_required - if ($LastExitCode -ne 0) { - Throw "Error while installing conan via PIP." - } -} else { - Write-Host "Conan found. Checking version..." - - $conan_version = (conan --version).split(" ")[2] - - if (!Check-Conan-Version-Sufficient $conan_version $conan_version_required) { - Write-Host "Your conan version $conan_version is too old. Let's try to update it." - pip3 install --upgrade conan==$conan_version_required - if ($LastExitCode -ne 0) { - Throw "Error while upgrading conan via PIP. Probably you have conan installed differently." + - " Please manually update conan to a at least version $conan_version_required" - } - - Write-Host "Successfully updated conan!" - } else { - Write-Host "Found conan version $conan_version. That fulfills the requirements!" - } -} - -# Install conan config -# -# We always pass the `-recreate-default-profiles` option here which removes all the previously automatically -# created default profiles. This avoids problems with stale default profiles which can occur when the OS has been -# updated and the previous default compiler is not available anymore. -# -# All changes made by the user to these profiles will be lost which is not ideal, but when calling bootstrap -# we expect the user wants a clean and working build no matter what. There is no need to make changes to the -# default profiles unless you try something out of the order and probably know what you are doing. -& "$PSScriptRoot\third_party\conan\configs\install.ps1" -recreate_default_profiles - -# Start build -if ($args) { - & "$PSScriptRoot\build.ps1" $args -} else { - & "$PSScriptRoot\build.ps1" -} diff --git a/bootstrap-orbit.sh b/bootstrap-orbit.sh deleted file mode 100755 index 1696911bf79..00000000000 --- a/bootstrap-orbit.sh +++ /dev/null @@ -1,172 +0,0 @@ -#!/bin/bash -# -# Copyright (c) 2020 The Orbit Authors. All rights reserved. -# Use of this source code is governed by a BSD-style license that can be -# found in the LICENSE file. - -CONAN_VERSION_REQUIRED="1.58.0" - -DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )" - -OPTIONS=$(getopt -o "" -l "force-public-remotes,assume-linux,assume-windows,ignore-system-requirements,dont-compile" -- "$@") -eval set -- "$OPTIONS" - -CONFIG_INSTALL_OPTIONS="" -IGNORE_SYS_REQUIREMENTS="" -DONT_COMPILE="" - -while true; do - case "$1" in - --force-public-remotes|--assume-linux|--assume-windows) - CONFIG_INSTALL_OPTIONS="${CONFIG_INSTALL_OPTIONS} $1"; shift;; - --ignore-system-requirements) IGNORE_SYS_REQUIREMENTS="yes"; shift;; - --dont-compile) DONT_COMPILE="yes"; shift;; - --) shift; break;; - esac -done - -readonly REQUIRED_PACKAGES=( build-essential libglu1-mesa-dev mesa-common-dev \ - libxmu-dev libxi-dev libopengl-dev qtbase5-dev \ - libxxf86vm-dev python3-pip libboost-dev ) - -function add_ubuntu_universe_repo { - sudo add-apt-repository universe - if [ $? -ne 0 ]; then - sudo apt-get install -y software-properties-common - sudo add-apt-repository universe - fi -} - -function install_required_packages { - sudo apt-get update || exit $? - sudo apt-get install -y ${REQUIRED_PACKAGES[@]} || exit $? -} - - -if [[ $IGNORE_SYS_REQUIREMENTS != "yes" ]]; then - if which dpkg-query >/dev/null 2>&1; then - readonly installed="$(dpkg-query --show -f'${Package}\n')" - PACKAGES_MISSING="no" - for package in ${REQUIRED_PACKAGES[@]}; do - if ! egrep "^${package}$" <<<"$installed" > /dev/null; then - PACKAGES_MISSING="yes" - break - fi - done - - if [[ $PACKAGES_MISSING == "yes" ]]; then - echo "Installing required system dependencies..." - - # That only works on Ubuntu! - if [[ "$(lsb_release -si)" == "Ubuntu" ]]; then - add_ubuntu_universe_repo - fi - - install_required_packages - fi - else - cat </dev/null -if [ $? -ne 0 ]; then - echo "Couldn't find conan. Trying to install via pip..." - $PIP install --user conan=="$CONAN_VERSION_REQUIRED" || exit $? -else - echo "Found conan. Checking version..." - CONAN_VERSION="$($CONAN --version | cut -d' ' -f3)" - - if ! check_conan_version_sufficient "$CONAN_VERSION" "$CONAN_VERSION_REQUIRED"; then - echo "Your conan version $CONAN_VERSION is too old. I will try to update..." - $PIP install --upgrade --user conan=="$CONAN_VERSION_REQUIRED" - if [ $? -ne 0 ]; then - echo "The upgrade of your conan installation failed. Probably because conan was not installed by this script." - echo "Please manually update conan to at least version $CONAN_VERSION_REQUIRED." - exit 2 - fi - echo "Conan updated finished." - else - echo "Conan's version $CONAN_VERSION fulfills the requirements. Continuing..." - fi -fi - -# We always pass the `--recreate-default-profiles` option here which removes all the previously automatically -# created default profiles. This avoids problems with stale default profiles which can occur when the OS has been -# updated and the previous default compiler is not available anymore. -# -# All changes made by the user to these profiles will be lost which is not ideal, but when calling bootstrap -# we expect the user wants a clean and working build no matter what. There is no need to make changes to the -# default profiles unless you try something out of the order and probably know what you are doing. -echo "Installing conan configuration (profiles, settings, etc.)..." -$DIR/third_party/conan/configs/install.sh --recreate-default-profiles $CONFIG_INSTALL_OPTIONS || exit $? - -if [[ $DONT_COMPILE != "yes" ]]; then - if [ -n "$1" ] ; then - exec $DIR/build.sh "$@" - else - exec $DIR/build.sh - fi -fi - -PRE_COMMIT_HOOK_FILE=.git/hooks/pre-commit - -function install_clang_format_pre_commit_hook { - if [ ! -f $PRE_COMMIT_HOOK_FILE ] ; then - touch $PRE_COMMIT_HOOK_FILE - chmod +x $PRE_COMMIT_HOOK_FILE - fi - echo "source \"contrib/hooks/clang-format-pre-commit.sh\"" >> $PRE_COMMIT_HOOK_FILE -} - -if [ -d .git ] ; then - if [ ! -f $PRE_COMMIT_HOOK_FILE ] || ! grep -q "contrib/hooks/clang-format-pre-commit.sh" .git/hooks/pre-commit ; then - while true; do - read -p "Do you want to install the clang-format pre-commit hook [y/n]? `echo $'\n> '`" yn - case $yn in - [Yy]* ) install_clang_format_pre_commit_hook; break;; - [Nn]* ) break;; - esac - done - fi -fi diff --git a/build.ps1 b/build.ps1 deleted file mode 100644 index b3217baac20..00000000000 --- a/build.ps1 +++ /dev/null @@ -1,90 +0,0 @@ -function conan { - & py -3 -m conans.conan $args -} - -function conan_profile_exists($profile) { - conan profile show $profile >null 2>&1 - return ($LastExitCode -eq 0) -} - -function conan_create_profile($profile) { - if (! (conan profile show default)) { - if (! (conan profile new --detect default)) { - exit $? - } - } - - $compiler = conan profile show default | Select-String -Pattern "compiler=" | ForEach-Object { ([string] $_).split("=")[1] } - $compiler_version = conan profile show default | Select-String -Pattern "compiler.version=" | ForEach-Object { ([string] $_).split("=")[1] } - - if ($compiler -ne "Visual Studio") { - Throw "It seems conan couldn't detect your Visual Studio installation. Do you have Visual Studio installed? At least Visual Studio 2019 is required!" - } - - if ([int]$compiler_version -ne 16 -and [int]$compiler_version -ne 17) { - Throw "Your version of Visual Studio is not supported. We currently only support VS2019 and VS2022." - } - - $compiler_version = if ($compiler_version -eq 16) { "msvc2019" } else { "msvc2022" } - - $conan_dir = if ($env:CONAN_USER_HOME) { $Env:CONAN_USER_HOME } else { $Env:USERPROFILE } - $conan_dir += "\.conan" - - $build_type = $profile -replace "default_" - $profile_path = "$conan_dir\profiles\$profile" - - if (!$Env:Qt5_DIR) { - Write-Host "" - Write-Host "Qt5_DIR environment variable not set - Please provide path to Qt distribution`r`n" - Write-Host "=============================================================================`r`n" - Write-Host "Orbit depends on the Qt framework which has to be installed separately either using the official installer,`r`n" - Write-Host "compiled manually from source or installed using a third party installer like aqtinstall.`r`n" - Write-Host "Check out DEVELOPMENT.md for more details on how to use an official Qt distribution.`r`n" - Write-Host "Press Ctrl+C to stop here and install Qt first. Make sure the Qt5_DIR environment variable is pointing to your`r`n" - Write-Host "Qt installation. Then call this script again.`r`n" - Exit 1 - } - - "include(${compiler_version}_${build_type})`r`n" | Set-Content -Path $profile_path - "[settings]`r`n[options]" | Add-Content -Path $profile_path - - if ($Env:Qt5_DIR) { - Write-Host "Found Qt5_DIR environment variable. Using system provided Qt distribution from $Env:Qt5_DIR." - "`r`n[env]`r`nOrbitProfiler:Qt5_DIR=`"$Env:Qt5_DIR`"" | Add-Content -Path $profile_path - } -} - -# That's the profile that is used for tools that run on the build machine (Nasm, CMake, Ninja, etc.) -$build_profile = "default_release" -if (-not (conan_profile_exists $build_profile)) { - Write-Host "Creating conan profile $build_profile" - conan_create_profile $build_profile -} - - -$profiles = if ($args.Count) { $args } else { @("default_release") } - -foreach ($profile in $profiles) { - - if ($profile.StartsWith("default_") -and (-not (conan_profile_exists $profile))) { - Write-Host "Creating conan profile $profile" - conan_create_profile $profile - } - - Write-Host "Building Orbit in build_$profile/ with conan profile $profile" - - conan install -if build_$profile\ --build outdated "-pr:b" $build_profile "-pr:h" $profile -u "$PSScriptRoot" - - if ($LastExitCode -ne 0) { - Throw "Error while running conan install." - } - - conan build -bf "build_$profile/" $PSScriptRoot - if ($LastExitCode -ne 0) { - Throw "Error while running conan build." - } - - if ($profile.StartsWith("default_")) { - Write-Host "The build finished successfully. Start Orbit with .\build_$profile\bin\Orbit!" - } -} diff --git a/build.sh b/build.sh deleted file mode 100755 index f857318fd0d..00000000000 --- a/build.sh +++ /dev/null @@ -1,79 +0,0 @@ -#!/bin/bash -# Copyright (c) 2020 The Orbit Authors. All rights reserved. -# Use of this source code is governed by a BSD-style license that can be -# found in the LICENSE file. - -set -euo pipefail - -# We call conan by going through python3 to avoid any PATH problems. -# Sometimes tools installed by PIP are not automatically in the PATH. -if [[ $(uname -s) == "Linux" ]]; then - CONAN="python3 -m conans.conan" -else - CONAN="py -3 -m conans.conan" -fi - -readonly CONAN - -default_profiles=( default_release ) - -if [ "$#" -eq 0 ]; then - profiles=( "${default_profiles[@]}" ) -else - profiles=() - for profile in "$@"; do profiles+=( "$profile" ); done -fi - -readonly DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )" - -function create_conan_profile { - local readonly profile="$1" - if ! $CONAN profile show default >/dev/null 2>&1; then - $CONAN profile new --detect default >/dev/null || exit $? - fi - - local readonly compiler="$($CONAN profile show default | grep compiler= | cut -d= -f2 | sed -e 's/Visual Studio/msvc/')" - local compiler_version="$($CONAN profile show default | grep compiler.version= | cut -d= -f2)" - if [[ $compiler == "msvc" ]]; then - compiler_version="$(echo $compiler_version | sed -e 's/^16$/2019/' | sed -e 's/^17$/2022/')" - fi - local readonly compiler_version - local readonly conan_dir=${CONAN_USER_HOME:-~}/.conan - local readonly build_type="${profile#default_}" - local readonly profile_path="$conan_dir/profiles/$profile" - - echo -e "include(${compiler}${compiler_version}_${build_type})\n" > $profile_path - echo -e "[settings]\n[options]" >> $profile_path - echo -e "[build_requires]\n[env]" >> $profile_path - - if [[ -v CC ]]; then - echo "CC=$CC" >> $profile_path - fi - - if [[ -v CXX ]]; then - echo "CXX=$CXX" >> $profile_path - fi -} - -function conan_profile_exists { - $CONAN profile show $1 >/dev/null 2>&1 - return $? -} - -# That's the profile that is used for tools that run on the build machine (Nasm, CMake, Ninja, etc.) -readonly build_profile="default_release" -conan_profile_exists "${build_profile}" || create_conan_profile "${build_profile}" - -for profile in ${profiles[@]}; do - if [[ $profile == default_* ]]; then - conan_profile_exists "$profile" || create_conan_profile "$profile" - fi - - $CONAN install -pr:b "${build_profile}" -pr:h $profile -if build_$profile/ \ - --build outdated --update "$DIR" || exit $? - $CONAN build -bf build_$profile/ "$DIR" || exit $? - - if [[ $profile == default_* ]]; then - echo "The build finished successfully. Start Orbit with ./build_$profile/bin/Orbit!" - fi -done \ No newline at end of file diff --git a/third_party/conan/configs/linux/profiles/clang10_common b/third_party/conan/configs/linux/profiles/clang10_common deleted file mode 100644 index 087fdb4417d..00000000000 --- a/third_party/conan/configs/linux/profiles/clang10_common +++ /dev/null @@ -1,8 +0,0 @@ -include(clang_common) - -[settings] -compiler.version=10 - -[env] -CC=clang-10 -CXX=clang++-10 \ No newline at end of file diff --git a/third_party/conan/configs/linux/profiles/clang10_debug b/third_party/conan/configs/linux/profiles/clang10_debug deleted file mode 100644 index df58377718a..00000000000 --- a/third_party/conan/configs/linux/profiles/clang10_debug +++ /dev/null @@ -1,4 +0,0 @@ -include(clang10_common) - -[settings] -build_type=Debug \ No newline at end of file diff --git a/third_party/conan/configs/linux/profiles/clang10_release b/third_party/conan/configs/linux/profiles/clang10_release deleted file mode 100644 index 54d6d85467e..00000000000 --- a/third_party/conan/configs/linux/profiles/clang10_release +++ /dev/null @@ -1,4 +0,0 @@ -include(clang10_common) - -[settings] -build_type=Release \ No newline at end of file diff --git a/third_party/conan/configs/linux/profiles/clang10_relwithdebinfo b/third_party/conan/configs/linux/profiles/clang10_relwithdebinfo deleted file mode 100644 index 76da54c3c54..00000000000 --- a/third_party/conan/configs/linux/profiles/clang10_relwithdebinfo +++ /dev/null @@ -1,4 +0,0 @@ -include(clang10_common) - -[settings] -build_type=RelWithDebInfo \ No newline at end of file diff --git a/third_party/conan/configs/linux/profiles/clang11_common b/third_party/conan/configs/linux/profiles/clang11_common deleted file mode 100644 index 6e2cffe45e5..00000000000 --- a/third_party/conan/configs/linux/profiles/clang11_common +++ /dev/null @@ -1,8 +0,0 @@ -include(clang_common) - -[settings] -compiler.version=11 - -[env] -CC=clang-11 -CXX=clang++-11 \ No newline at end of file diff --git a/third_party/conan/configs/linux/profiles/clang11_debug b/third_party/conan/configs/linux/profiles/clang11_debug deleted file mode 100644 index 5ed8a74711a..00000000000 --- a/third_party/conan/configs/linux/profiles/clang11_debug +++ /dev/null @@ -1,4 +0,0 @@ -include(clang11_common) - -[settings] -build_type=Debug \ No newline at end of file diff --git a/third_party/conan/configs/linux/profiles/clang11_release b/third_party/conan/configs/linux/profiles/clang11_release deleted file mode 100644 index c21d7269d61..00000000000 --- a/third_party/conan/configs/linux/profiles/clang11_release +++ /dev/null @@ -1,4 +0,0 @@ -include(clang11_common) - -[settings] -build_type=Release \ No newline at end of file diff --git a/third_party/conan/configs/linux/profiles/clang11_release_system_deps b/third_party/conan/configs/linux/profiles/clang11_release_system_deps deleted file mode 100644 index 0566c16a8a6..00000000000 --- a/third_party/conan/configs/linux/profiles/clang11_release_system_deps +++ /dev/null @@ -1,7 +0,0 @@ -include(clang11_common) - -[settings] -build_type=Release - -[options] -OrbitProfiler:with_system_deps=True \ No newline at end of file diff --git a/third_party/conan/configs/linux/profiles/clang11_relwithdebinfo b/third_party/conan/configs/linux/profiles/clang11_relwithdebinfo deleted file mode 100644 index aa28d1735a6..00000000000 --- a/third_party/conan/configs/linux/profiles/clang11_relwithdebinfo +++ /dev/null @@ -1,4 +0,0 @@ -include(clang11_common) - -[settings] -build_type=RelWithDebInfo \ No newline at end of file diff --git a/third_party/conan/configs/linux/profiles/clang12_common b/third_party/conan/configs/linux/profiles/clang12_common deleted file mode 100644 index 5e5a15e0caa..00000000000 --- a/third_party/conan/configs/linux/profiles/clang12_common +++ /dev/null @@ -1,8 +0,0 @@ -include(clang_common) - -[settings] -compiler.version=12 - -[env] -CC=clang-12 -CXX=clang++-12 diff --git a/third_party/conan/configs/linux/profiles/clang12_debug b/third_party/conan/configs/linux/profiles/clang12_debug deleted file mode 100644 index 4fe87187240..00000000000 --- a/third_party/conan/configs/linux/profiles/clang12_debug +++ /dev/null @@ -1,4 +0,0 @@ -include(clang12_common) - -[settings] -build_type=Debug diff --git a/third_party/conan/configs/linux/profiles/clang12_release b/third_party/conan/configs/linux/profiles/clang12_release deleted file mode 100644 index 24783815fec..00000000000 --- a/third_party/conan/configs/linux/profiles/clang12_release +++ /dev/null @@ -1,4 +0,0 @@ -include(clang12_common) - -[settings] -build_type=Release diff --git a/third_party/conan/configs/linux/profiles/clang12_release_system_deps b/third_party/conan/configs/linux/profiles/clang12_release_system_deps deleted file mode 100644 index 13d92b89271..00000000000 --- a/third_party/conan/configs/linux/profiles/clang12_release_system_deps +++ /dev/null @@ -1,7 +0,0 @@ -include(clang12_common) - -[settings] -build_type=Release - -[options] -OrbitProfiler:with_system_deps=True diff --git a/third_party/conan/configs/linux/profiles/clang13_common b/third_party/conan/configs/linux/profiles/clang13_common deleted file mode 100644 index 20393026ac0..00000000000 --- a/third_party/conan/configs/linux/profiles/clang13_common +++ /dev/null @@ -1,8 +0,0 @@ -include(clang_common) - -[settings] -compiler.version=13 - -[env] -CC=clang-13 -CXX=clang++-13 diff --git a/third_party/conan/configs/linux/profiles/clang13_debug b/third_party/conan/configs/linux/profiles/clang13_debug deleted file mode 100644 index c1989792264..00000000000 --- a/third_party/conan/configs/linux/profiles/clang13_debug +++ /dev/null @@ -1,4 +0,0 @@ -include(clang13_common) - -[settings] -build_type=Debug diff --git a/third_party/conan/configs/linux/profiles/clang13_release b/third_party/conan/configs/linux/profiles/clang13_release deleted file mode 100644 index 1a05110b08d..00000000000 --- a/third_party/conan/configs/linux/profiles/clang13_release +++ /dev/null @@ -1,4 +0,0 @@ -include(clang13_common) - -[settings] -build_type=Release diff --git a/third_party/conan/configs/linux/profiles/clang13_relwithdebinfo b/third_party/conan/configs/linux/profiles/clang13_relwithdebinfo deleted file mode 100644 index 69fc804cc52..00000000000 --- a/third_party/conan/configs/linux/profiles/clang13_relwithdebinfo +++ /dev/null @@ -1,4 +0,0 @@ -include(clang13_common) - -[settings] -build_type=RelWithDebInfo diff --git a/third_party/conan/configs/linux/profiles/clang14_common b/third_party/conan/configs/linux/profiles/clang14_common deleted file mode 100644 index ddb6ceaa5df..00000000000 --- a/third_party/conan/configs/linux/profiles/clang14_common +++ /dev/null @@ -1,8 +0,0 @@ -include(clang_common) - -[settings] -compiler.version=14 - -[env] -CC=clang-14 -CXX=clang++-14 diff --git a/third_party/conan/configs/linux/profiles/clang14_release b/third_party/conan/configs/linux/profiles/clang14_release deleted file mode 100644 index fe577580480..00000000000 --- a/third_party/conan/configs/linux/profiles/clang14_release +++ /dev/null @@ -1,4 +0,0 @@ -include(clang14_common) - -[settings] -build_type=Release diff --git a/third_party/conan/configs/linux/profiles/clang14_relwithdebinfo b/third_party/conan/configs/linux/profiles/clang14_relwithdebinfo deleted file mode 100644 index 87db3a05b33..00000000000 --- a/third_party/conan/configs/linux/profiles/clang14_relwithdebinfo +++ /dev/null @@ -1,4 +0,0 @@ -include(clang14_common) - -[settings] -build_type=RelWithDebInfo diff --git a/third_party/conan/configs/linux/profiles/clang15_common b/third_party/conan/configs/linux/profiles/clang15_common deleted file mode 100644 index 9584409b9c8..00000000000 --- a/third_party/conan/configs/linux/profiles/clang15_common +++ /dev/null @@ -1,8 +0,0 @@ -include(clang_common) - -[settings] -compiler.version=15 - -[env] -CC=clang-15 -CXX=clang++-15 diff --git a/third_party/conan/configs/linux/profiles/clang15_debug b/third_party/conan/configs/linux/profiles/clang15_debug deleted file mode 100644 index 8e0e14e047c..00000000000 --- a/third_party/conan/configs/linux/profiles/clang15_debug +++ /dev/null @@ -1,4 +0,0 @@ -include(clang15_common) - -[settings] -build_type=Debug diff --git a/third_party/conan/configs/linux/profiles/clang15_relwithdebinfo b/third_party/conan/configs/linux/profiles/clang15_relwithdebinfo deleted file mode 100644 index 3c00859f932..00000000000 --- a/third_party/conan/configs/linux/profiles/clang15_relwithdebinfo +++ /dev/null @@ -1,4 +0,0 @@ -include(clang15_common) - -[settings] -build_type=RelWithDebInfo diff --git a/third_party/conan/configs/linux/profiles/clang14_debug b/third_party/conan/configs/linux/profiles/clang18_debug similarity index 54% rename from third_party/conan/configs/linux/profiles/clang14_debug rename to third_party/conan/configs/linux/profiles/clang18_debug index 9f50fce96e3..60fb1b1a315 100644 --- a/third_party/conan/configs/linux/profiles/clang14_debug +++ b/third_party/conan/configs/linux/profiles/clang18_debug @@ -1,4 +1,4 @@ -include(clang14_common) +include(clang18_common) [settings] build_type=Debug diff --git a/third_party/conan/configs/linux/profiles/clang15_release b/third_party/conan/configs/linux/profiles/clang18_release similarity index 56% rename from third_party/conan/configs/linux/profiles/clang15_release rename to third_party/conan/configs/linux/profiles/clang18_release index 8614c58a4ea..2c3683e0b01 100644 --- a/third_party/conan/configs/linux/profiles/clang15_release +++ b/third_party/conan/configs/linux/profiles/clang18_release @@ -1,4 +1,4 @@ -include(clang15_common) +include(clang18_common) [settings] build_type=Release diff --git a/third_party/conan/configs/linux/profiles/clang12_relwithdebinfo b/third_party/conan/configs/linux/profiles/clang18_relwithdebinfo similarity index 61% rename from third_party/conan/configs/linux/profiles/clang12_relwithdebinfo rename to third_party/conan/configs/linux/profiles/clang18_relwithdebinfo index 42d449cfc52..bb4521b6592 100644 --- a/third_party/conan/configs/linux/profiles/clang12_relwithdebinfo +++ b/third_party/conan/configs/linux/profiles/clang18_relwithdebinfo @@ -1,4 +1,4 @@ -include(clang12_common) +include(clang18_common) [settings] build_type=RelWithDebInfo diff --git a/third_party/conan/configs/linux/profiles/clang7_common b/third_party/conan/configs/linux/profiles/clang7_common deleted file mode 100644 index 140e7e49907..00000000000 --- a/third_party/conan/configs/linux/profiles/clang7_common +++ /dev/null @@ -1,8 +0,0 @@ -include(clang_common) - -[settings] -compiler.version=7.0 - -[env] -CC=clang-7 -CXX=clang++-7 \ No newline at end of file diff --git a/third_party/conan/configs/linux/profiles/clang7_debug b/third_party/conan/configs/linux/profiles/clang7_debug deleted file mode 100644 index def05391ad0..00000000000 --- a/third_party/conan/configs/linux/profiles/clang7_debug +++ /dev/null @@ -1,4 +0,0 @@ -include(clang7_common) - -[settings] -build_type=Debug \ No newline at end of file diff --git a/third_party/conan/configs/linux/profiles/clang7_release b/third_party/conan/configs/linux/profiles/clang7_release deleted file mode 100644 index d54d6644867..00000000000 --- a/third_party/conan/configs/linux/profiles/clang7_release +++ /dev/null @@ -1,4 +0,0 @@ -include(clang7_common) - -[settings] -build_type=Release \ No newline at end of file diff --git a/third_party/conan/configs/linux/profiles/clang7_relwithdebinfo b/third_party/conan/configs/linux/profiles/clang7_relwithdebinfo deleted file mode 100644 index d46293612cb..00000000000 --- a/third_party/conan/configs/linux/profiles/clang7_relwithdebinfo +++ /dev/null @@ -1,4 +0,0 @@ -include(clang7_common) - -[settings] -build_type=RelWithDebInfo \ No newline at end of file diff --git a/third_party/conan/configs/linux/profiles/clang8_common b/third_party/conan/configs/linux/profiles/clang8_common deleted file mode 100644 index 11c9a4c4266..00000000000 --- a/third_party/conan/configs/linux/profiles/clang8_common +++ /dev/null @@ -1,8 +0,0 @@ -include(clang_common) - -[settings] -compiler.version=8 - -[env] -CC=clang-8 -CXX=clang++-8 \ No newline at end of file diff --git a/third_party/conan/configs/linux/profiles/clang8_debug b/third_party/conan/configs/linux/profiles/clang8_debug deleted file mode 100644 index f4d5e93e60e..00000000000 --- a/third_party/conan/configs/linux/profiles/clang8_debug +++ /dev/null @@ -1,4 +0,0 @@ -include(clang8_common) - -[settings] -build_type=Debug \ No newline at end of file diff --git a/third_party/conan/configs/linux/profiles/clang8_release b/third_party/conan/configs/linux/profiles/clang8_release deleted file mode 100644 index dc071b7ccd5..00000000000 --- a/third_party/conan/configs/linux/profiles/clang8_release +++ /dev/null @@ -1,4 +0,0 @@ -include(clang8_common) - -[settings] -build_type=Release \ No newline at end of file diff --git a/third_party/conan/configs/linux/profiles/clang8_relwithdebinfo b/third_party/conan/configs/linux/profiles/clang8_relwithdebinfo deleted file mode 100644 index 312a73cc08b..00000000000 --- a/third_party/conan/configs/linux/profiles/clang8_relwithdebinfo +++ /dev/null @@ -1,4 +0,0 @@ -include(clang8_common) - -[settings] -build_type=RelWithDebInfo \ No newline at end of file diff --git a/third_party/conan/configs/linux/profiles/clang9_common b/third_party/conan/configs/linux/profiles/clang9_common deleted file mode 100644 index 06ac1ef410f..00000000000 --- a/third_party/conan/configs/linux/profiles/clang9_common +++ /dev/null @@ -1,8 +0,0 @@ -include(clang_common) - -[settings] -compiler.version=9 - -[env] -CC=clang-9 -CXX=clang++-9 \ No newline at end of file diff --git a/third_party/conan/configs/linux/profiles/clang9_debug b/third_party/conan/configs/linux/profiles/clang9_debug deleted file mode 100644 index 1c3a9657d5c..00000000000 --- a/third_party/conan/configs/linux/profiles/clang9_debug +++ /dev/null @@ -1,4 +0,0 @@ -include(clang9_common) - -[settings] -build_type=Debug \ No newline at end of file diff --git a/third_party/conan/configs/linux/profiles/clang9_release b/third_party/conan/configs/linux/profiles/clang9_release deleted file mode 100644 index 22b25fb5b26..00000000000 --- a/third_party/conan/configs/linux/profiles/clang9_release +++ /dev/null @@ -1,4 +0,0 @@ -include(clang9_common) - -[settings] -build_type=Release \ No newline at end of file diff --git a/third_party/conan/configs/linux/profiles/clang9_relwithdebinfo b/third_party/conan/configs/linux/profiles/clang9_relwithdebinfo deleted file mode 100644 index e051e3173bb..00000000000 --- a/third_party/conan/configs/linux/profiles/clang9_relwithdebinfo +++ /dev/null @@ -1,4 +0,0 @@ -include(clang9_common) - -[settings] -build_type=RelWithDebInfo \ No newline at end of file diff --git a/third_party/conan/configs/linux/profiles/clang_common b/third_party/conan/configs/linux/profiles/clang_common deleted file mode 100644 index 86223b2a4fa..00000000000 --- a/third_party/conan/configs/linux/profiles/clang_common +++ /dev/null @@ -1,15 +0,0 @@ -include(linux_common) - -[settings] -compiler=clang -compiler.libcxx=libstdc++11 -compiler.fpo=False -abseil:compiler=clang -abseil:compiler.cppstd=17 -gtest:compiler=clang -gtest:compiler.cppstd=17 -grpc:compiler=clang -grpc:compiler.cppstd=17 - -[env] -gtest:CXXFLAGS=$CXX_FLAGS -std=c++17 \ No newline at end of file diff --git a/third_party/conan/configs/linux/profiles/cmake_common b/third_party/conan/configs/linux/profiles/cmake_common deleted file mode 100644 index f0c5dad0b12..00000000000 --- a/third_party/conan/configs/linux/profiles/cmake_common +++ /dev/null @@ -1,9 +0,0 @@ -[settings] -cmake:build_type=Release -cmake:os=Linux -cmake:os_build=Linux -cmake:arch=x86_64 -cmake:arch_build=x86_64 - -[build_requires] -&: cmake/3.24.1 \ No newline at end of file diff --git a/third_party/conan/configs/linux/profiles/coverage_clang11 b/third_party/conan/configs/linux/profiles/coverage_clang11 deleted file mode 100644 index ad05fb8d969..00000000000 --- a/third_party/conan/configs/linux/profiles/coverage_clang11 +++ /dev/null @@ -1,5 +0,0 @@ -include(clang11_relwithdebinfo) - -[env] -CFLAGS=$C_FLAGS -fprofile-instr-generate="%m.profraw" -fcoverage-mapping -DORBIT_COVERAGE_BUILD -CXXFLAGS=$CXX_FLAGS -fprofile-instr-generate="%m.profraw" -fcoverage-mapping -DORBIT_COVERAGE_BUILD diff --git a/third_party/conan/configs/linux/profiles/gcc10_common b/third_party/conan/configs/linux/profiles/gcc10_common deleted file mode 100644 index a40b7f04b08..00000000000 --- a/third_party/conan/configs/linux/profiles/gcc10_common +++ /dev/null @@ -1,8 +0,0 @@ -include(gcc_common) - -[settings] -compiler.version=10 - -[env] -CC=gcc-10 -CXX=g++-10 \ No newline at end of file diff --git a/third_party/conan/configs/linux/profiles/gcc10_debug b/third_party/conan/configs/linux/profiles/gcc10_debug deleted file mode 100644 index 7bfed0bd2a2..00000000000 --- a/third_party/conan/configs/linux/profiles/gcc10_debug +++ /dev/null @@ -1,4 +0,0 @@ -include(gcc10_common) - -[settings] -build_type=Debug \ No newline at end of file diff --git a/third_party/conan/configs/linux/profiles/gcc10_release b/third_party/conan/configs/linux/profiles/gcc10_release deleted file mode 100644 index aa4357688c4..00000000000 --- a/third_party/conan/configs/linux/profiles/gcc10_release +++ /dev/null @@ -1,4 +0,0 @@ -include(gcc10_common) - -[settings] -build_type=Release \ No newline at end of file diff --git a/third_party/conan/configs/linux/profiles/gcc10_relwithdebinfo b/third_party/conan/configs/linux/profiles/gcc10_relwithdebinfo deleted file mode 100644 index c66eb186509..00000000000 --- a/third_party/conan/configs/linux/profiles/gcc10_relwithdebinfo +++ /dev/null @@ -1,4 +0,0 @@ -include(gcc10_common) - -[settings] -build_type=RelWithDebInfo \ No newline at end of file diff --git a/third_party/conan/configs/linux/profiles/gcc11_common b/third_party/conan/configs/linux/profiles/gcc11_common deleted file mode 100644 index ccead3c24bf..00000000000 --- a/third_party/conan/configs/linux/profiles/gcc11_common +++ /dev/null @@ -1,9 +0,0 @@ -include(gcc_common) - -[settings] -compiler.version=11 - -[env] -CC=gcc-11 -CXX=g++-11 -grpc:CXXFLAGS=$CXX_FLAGS -std=c++14 diff --git a/third_party/conan/configs/linux/profiles/gcc11_debug b/third_party/conan/configs/linux/profiles/gcc11_debug deleted file mode 100644 index 477bd11a566..00000000000 --- a/third_party/conan/configs/linux/profiles/gcc11_debug +++ /dev/null @@ -1,4 +0,0 @@ -include(gcc11_common) - -[settings] -build_type=Debug diff --git a/third_party/conan/configs/linux/profiles/gcc11_release b/third_party/conan/configs/linux/profiles/gcc11_release deleted file mode 100644 index a52b43eb3b2..00000000000 --- a/third_party/conan/configs/linux/profiles/gcc11_release +++ /dev/null @@ -1,4 +0,0 @@ -include(gcc11_common) - -[settings] -build_type=Release diff --git a/third_party/conan/configs/linux/profiles/gcc11_relwithdebinfo b/third_party/conan/configs/linux/profiles/gcc11_relwithdebinfo deleted file mode 100644 index 8e4ecf8740a..00000000000 --- a/third_party/conan/configs/linux/profiles/gcc11_relwithdebinfo +++ /dev/null @@ -1,4 +0,0 @@ -include(gcc11_common) - -[settings] -build_type=RelWithDebInfo diff --git a/third_party/conan/configs/linux/profiles/gcc12_common b/third_party/conan/configs/linux/profiles/gcc12_common deleted file mode 100644 index 3102010787b..00000000000 --- a/third_party/conan/configs/linux/profiles/gcc12_common +++ /dev/null @@ -1,9 +0,0 @@ -include(gcc_common) - -[settings] -compiler.version=12 - -[env] -CC=gcc-12 -CXX=g++-12 -grpc:CXXFLAGS=$CXX_FLAGS -std=c++14 diff --git a/third_party/conan/configs/linux/profiles/gcc12_debug b/third_party/conan/configs/linux/profiles/gcc12_debug deleted file mode 100644 index 514af131220..00000000000 --- a/third_party/conan/configs/linux/profiles/gcc12_debug +++ /dev/null @@ -1,4 +0,0 @@ -include(gcc12_common) - -[settings] -build_type=Debug diff --git a/third_party/conan/configs/linux/profiles/gcc12_release b/third_party/conan/configs/linux/profiles/gcc12_release deleted file mode 100644 index 59e1a067082..00000000000 --- a/third_party/conan/configs/linux/profiles/gcc12_release +++ /dev/null @@ -1,4 +0,0 @@ -include(gcc12_common) - -[settings] -build_type=Release diff --git a/third_party/conan/configs/linux/profiles/gcc12_relwithdebinfo b/third_party/conan/configs/linux/profiles/gcc12_relwithdebinfo deleted file mode 100644 index 2825789fe6e..00000000000 --- a/third_party/conan/configs/linux/profiles/gcc12_relwithdebinfo +++ /dev/null @@ -1,4 +0,0 @@ -include(gcc12_common) - -[settings] -build_type=RelWithDebInfo diff --git a/third_party/conan/configs/linux/profiles/gcc17_debug b/third_party/conan/configs/linux/profiles/gcc17_debug new file mode 100644 index 00000000000..9e70825c1eb --- /dev/null +++ b/third_party/conan/configs/linux/profiles/gcc17_debug @@ -0,0 +1,8 @@ +[settings] +arch=x86_64 +build_type=Debug +compiler=gcc +compiler.cppstd=gnu17 +compiler.libcxx=libstdc++11 +compiler.version=13 +os=Linux diff --git a/third_party/conan/configs/linux/profiles/gcc17_release b/third_party/conan/configs/linux/profiles/gcc17_release new file mode 100644 index 00000000000..8976420b032 --- /dev/null +++ b/third_party/conan/configs/linux/profiles/gcc17_release @@ -0,0 +1,8 @@ +[settings] +arch=x86_64 +build_type=Release +compiler=gcc +compiler.cppstd=gnu17 +compiler.libcxx=libstdc++11 +compiler.version=13 +os=Linux diff --git a/third_party/conan/configs/linux/profiles/gcc17_relwithdebinfo b/third_party/conan/configs/linux/profiles/gcc17_relwithdebinfo new file mode 100644 index 00000000000..a7458615291 --- /dev/null +++ b/third_party/conan/configs/linux/profiles/gcc17_relwithdebinfo @@ -0,0 +1,8 @@ +[settings] +arch=x86_64 +build_type=RelWithDebInfo +compiler=gcc +compiler.cppstd=gnu17 +compiler.libcxx=libstdc++11 +compiler.version=13 +os=Linux diff --git a/third_party/conan/configs/linux/profiles/gcc9_common b/third_party/conan/configs/linux/profiles/gcc9_common deleted file mode 100644 index 3ade6ddad4c..00000000000 --- a/third_party/conan/configs/linux/profiles/gcc9_common +++ /dev/null @@ -1,8 +0,0 @@ -include(gcc_common) - -[settings] -compiler.version=9 - -[env] -CC=gcc-9 -CXX=g++-9 \ No newline at end of file diff --git a/third_party/conan/configs/linux/profiles/gcc9_debug b/third_party/conan/configs/linux/profiles/gcc9_debug deleted file mode 100644 index 67d5e12c907..00000000000 --- a/third_party/conan/configs/linux/profiles/gcc9_debug +++ /dev/null @@ -1,4 +0,0 @@ -include(gcc9_common) - -[settings] -build_type=Debug \ No newline at end of file diff --git a/third_party/conan/configs/linux/profiles/gcc9_release b/third_party/conan/configs/linux/profiles/gcc9_release deleted file mode 100644 index 74723eba681..00000000000 --- a/third_party/conan/configs/linux/profiles/gcc9_release +++ /dev/null @@ -1,4 +0,0 @@ -include(gcc9_common) - -[settings] -build_type=Release \ No newline at end of file diff --git a/third_party/conan/configs/linux/profiles/gcc9_relwithdebinfo b/third_party/conan/configs/linux/profiles/gcc9_relwithdebinfo deleted file mode 100644 index 1410612dd07..00000000000 --- a/third_party/conan/configs/linux/profiles/gcc9_relwithdebinfo +++ /dev/null @@ -1,4 +0,0 @@ -include(gcc9_common) - -[settings] -build_type=RelWithDebInfo \ No newline at end of file diff --git a/third_party/conan/configs/linux/profiles/gcc_common b/third_party/conan/configs/linux/profiles/gcc_common deleted file mode 100644 index 7a6c1f808d1..00000000000 --- a/third_party/conan/configs/linux/profiles/gcc_common +++ /dev/null @@ -1,15 +0,0 @@ -include(linux_common) - -[settings] -compiler=gcc -compiler.libcxx=libstdc++11 -compiler.fpo=False -abseil:compiler=gcc -abseil:compiler.cppstd=17 -gtest:compiler=gcc -gtest:compiler.cppstd=17 -grpc:compiler=gcc -grpc:compiler.cppstd=17 - -[env] -gtest:CXXFLAGS=$CXX_FLAGS -std=c++17 \ No newline at end of file diff --git a/third_party/conan/configs/linux/profiles/iwyu b/third_party/conan/configs/linux/profiles/iwyu deleted file mode 100644 index 365f13b2fa6..00000000000 --- a/third_party/conan/configs/linux/profiles/iwyu +++ /dev/null @@ -1,5 +0,0 @@ -include(clang11_release) - -[options] -OrbitProfiler:build_target=iwyu -OrbitProfiler:run_tests=False \ No newline at end of file diff --git a/third_party/conan/configs/linux/profiles/libfuzzer_base b/third_party/conan/configs/linux/profiles/libfuzzer_base deleted file mode 100644 index 509cb9e6097..00000000000 --- a/third_party/conan/configs/linux/profiles/libfuzzer_base +++ /dev/null @@ -1,21 +0,0 @@ -# This file is intended to be imported when building for oss-fuzz -# Compiler and settings are auto-detected in that case, but we want to have -# an upstream config file where settings can be changed. -BASE_CFLAGS= -march=sandybridge -fno-omit-frame-pointer -mno-omit-leaf-frame-pointer -D_FORTIFY_SOURCE=2 -fstack-protector-all -fPIC -DFUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION -BASE_CXXFLAGS= -march=sandybridge -fno-omit-frame-pointer -mno-omit-leaf-frame-pointer -fsized-deallocation -D_FORTIFY_SOURCE=2 -fstack-protector-all -fPIC -fno-exceptions -DFUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION -BASE_LDFLAGS=-Wl,-z,relro,-z,now,-z,noexecstack -pthread - -[settings] -abseil:compiler=clang -abseil:compiler.cppstd=17 -gtest:compiler=clang -gtest:compiler.cppstd=17 - -[options] -OrbitProfiler:with_gui=False -OrbitProfiler:run_tests=False - -[build_requires] - -[env] -gtest:CXXFLAGS=$BASE_CXXFLAGS -std=c++17 \ No newline at end of file diff --git a/third_party/conan/configs/linux/profiles/libfuzzer_relwithdebinfo b/third_party/conan/configs/linux/profiles/libfuzzer_relwithdebinfo deleted file mode 100644 index 8c42a86b20e..00000000000 --- a/third_party/conan/configs/linux/profiles/libfuzzer_relwithdebinfo +++ /dev/null @@ -1,13 +0,0 @@ -include(clang9_relwithdebinfo) - -[options] -OrbitProfiler:with_gui=False -OrbitProfiler:run_tests=False - -[env] -CFLAGS=$C_FLAGS -CXXFLAGS=$CXX_FLAGS -OrbitProfiler:CFLAGS=$C_FLAGS -fexceptions -fsanitize=fuzzer-no-link,address -DFUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION -OrbitProfiler:CXXFLAGS=$CXX_FLAGS -fexceptions -fsanitize=fuzzer-no-link,address -DFUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION -llvm:CFLAGS=$C_FLAGS -fsanitize=fuzzer-no-link,address -DFUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION -llvm:CXXFLAGS=$CXX_FLAGS -fsanitize=fuzzer-no-link,address -DFUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION \ No newline at end of file diff --git a/third_party/conan/configs/linux/profiles/linux_common b/third_party/conan/configs/linux/profiles/linux_common deleted file mode 100644 index 27d5c6c3e00..00000000000 --- a/third_party/conan/configs/linux/profiles/linux_common +++ /dev/null @@ -1,16 +0,0 @@ -include(cmake_common) - -C_FLAGS=-march=sandybridge -fno-omit-frame-pointer -mno-omit-leaf-frame-pointer -D_FORTIFY_SOURCE=2 -fstack-protector-all -CXX_FLAGS=-march=sandybridge -fno-omit-frame-pointer -mno-omit-leaf-frame-pointer -fsized-deallocation -D_FORTIFY_SOURCE=2 -fstack-protector-all -fno-exceptions -LD_FLAGS=-Wl,-z,relro,-z,now,-z,noexecstack - -[settings] -os=Linux -os_build=Linux -arch=x86_64 -arch_build=x86_64 - -[env] -CFLAGS=$C_FLAGS -CXXFLAGS=$CXX_FLAGS -LDFLAGS=$LD_FLAGS From fec0e6b3ff82f51a61157c109062bfc0f22ab979 Mon Sep 17 00:00:00 2001 From: Pierric Gimmig Date: Wed, 29 Jan 2025 22:00:02 -0800 Subject: [PATCH 8/8] Better build invocation --- README.md | 8 +++----- conanfile.py | 4 ++-- 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index f0433c368ff..5484ae25868 100644 --- a/README.md +++ b/README.md @@ -161,7 +161,6 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. To compile on Windows: - conan install . --build="abseil/*" --build="protobuf/*" --build="grpc/*" --build=missing cd build cmake -DCMAKE_TOOLCHAIN_FILE=build/generators/conan_toolchain.cmake .. @@ -177,8 +176,7 @@ cmake --build . --config Release with a debug profile: - - - Debug example: -conan install . -pr:a third_party/conan/configs/linux/profiles/gcc17_debug --build=missing -of build_gcc_debug +conan install . -pr:a third_party/conan/configs/linux/profiles/gcc17_debug --build=missing -of build_gcc17_debug +cmake -B build_gcc17_debug -DCMAKE_TOOLCHAIN_FILE=build_gcc17_debug/generators/conan_toolchain.cmake -DCMAKE_BUILD_TYPE=Debug . +cmake --build build_gcc17_debug --paralell diff --git a/conanfile.py b/conanfile.py index 31dcf1081c3..3c2f3345df6 100644 --- a/conanfile.py +++ b/conanfile.py @@ -34,5 +34,5 @@ def build_requirements(self): self.tool_requires("gtest/1.15.0") def layout(self): - self.folders.build = "build" - self.folders.generators = "build/generators" + self.folders.generators = "generators" +