Skip to content
Merged
Show file tree
Hide file tree
Changes from 24 commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
8e37d80
Create initial implementation of `__remill_sync_hyper_call`
tetsuo-cpp Jul 27, 2022
a416078
Fill in a few more cases
tetsuo-cpp Jul 28, 2022
24e29a3
Merge remote-tracking branch 'origin/master' into alex/x86-sync-hyper…
tetsuo-cpp Aug 4, 2022
e58a2f2
Use `state.addr_to_load` for LGDT and LIDT operands
tetsuo-cpp Aug 4, 2022
d53129d
Fix variable names
tetsuo-cpp Aug 8, 2022
41862cb
Cross-compile the Remill runtimes
tetsuo-cpp Aug 9, 2022
fcd24b2
Create temp variable for `lgdt` and `lidt` handling
tetsuo-cpp Aug 10, 2022
a544677
Add intrinsics for SPARC emulate instruction calls
tetsuo-cpp Aug 10, 2022
72035aa
Create intrinsics for remaining hyper calls
tetsuo-cpp Aug 10, 2022
295da65
Remove `__remill_sync_hyper_call` implementations in tests
tetsuo-cpp Aug 10, 2022
0abe52a
Create the target triple based on the provided arch
tetsuo-cpp Aug 10, 2022
09f16b7
Provide ARCH parameter for SPARC archs
tetsuo-cpp Aug 10, 2022
2d85bb0
CMake formatting
tetsuo-cpp Aug 10, 2022
1b3bbe6
Switch the conditions around
tetsuo-cpp Aug 10, 2022
03f764c
Adjust target triple
tetsuo-cpp Aug 10, 2022
65ccf60
Cross-compile the hyper calls and then link them into the runtime
tetsuo-cpp Aug 12, 2022
76e48b1
Cleanup
tetsuo-cpp Aug 12, 2022
85eebbe
Prefix int types with namespace
tetsuo-cpp Aug 12, 2022
a8c4174
Include `<limits>`
tetsuo-cpp Aug 14, 2022
20a749c
Fix `lgdt` and `lidt` handling
tetsuo-cpp Aug 14, 2022
79657e6
Mark new intrinsics as "used"
tetsuo-cpp Aug 14, 2022
9c8cf03
Add placeholder intrinsic definitions to tests
tetsuo-cpp Aug 14, 2022
db18a75
Complete list of intrinsic definitions
tetsuo-cpp Aug 14, 2022
f33de27
Merge remote-tracking branch 'origin/master' into alex/x86-sync-hyper…
tetsuo-cpp Aug 14, 2022
35a9723
Mark hyper call definition with `always_inline`
tetsuo-cpp Aug 19, 2022
e49e709
Use `_BitInt` if available
tetsuo-cpp Aug 19, 2022
de9e5e5
Merge remote-tracking branch 'origin/master' into alex/x86-sync-hyper…
tetsuo-cpp Aug 22, 2022
b93978a
Use `__builtin_unreachable` instead of `abort`
tetsuo-cpp Aug 22, 2022
0574f2a
Leave comment explaining `always_inline` attribute
tetsuo-cpp Aug 22, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 21 additions & 4 deletions cmake/BCCompiler.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,10 @@ function(add_runtime target_name)
set(state "${macro_parameter}")
continue()

elseif("${macro_parameter}" STREQUAL "ARCH")
set(state "${macro_parameter}")
continue()

elseif("${macro_parameter}" STREQUAL "DEPENDENCIES")
set(state "${macro_parameter}")
continue()
Expand Down Expand Up @@ -127,6 +131,9 @@ function(add_runtime target_name)

set(install_destination "${macro_parameter}")

elseif("${state}" STREQUAL "ARCH")
set(arch "${macro_parameter}")

elseif("${state}" STREQUAL "DEPENDENCIES")
list(APPEND dependency_list "${macro_parameter}")

Expand All @@ -143,6 +150,10 @@ function(add_runtime target_name)
message(SEND_ERROR "No source files specified.")
endif()

# Append the hyper call function to the source list.
set(hyper_call_source "${REMILL_LIB_DIR}/Arch/Runtime/HyperCall.cpp")
list(APPEND source_file_list ${hyper_call_source})

foreach(source_file ${source_file_list})
get_filename_component(source_file_name "${source_file}" NAME)
get_filename_component(absolute_source_file_path "${source_file}" ABSOLUTE)
Expand All @@ -164,9 +175,15 @@ function(add_runtime target_name)
set(additional_windows_settings "-D_ALLOW_COMPILER_AND_STL_VERSION_MISMATCH")
endif()

if (${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
set(target_decl "-target" "x86_64-apple-macosx11.0.0")
endif()
# The hyper call implementation contains inline assembly for each architecture so we'll need to
# cross-compile for the runtime architecture.
if(${source_file} STREQUAL ${hyper_call_source})
set(target_decl "-target" "${arch}-none-eabi")
elseif(${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
set(target_decl "-target" "x86_64-apple-macosx11.0.0")
else()
unset(target_decl)
endif()


add_custom_command(OUTPUT "${absolute_output_file_path}"
Expand All @@ -192,7 +209,7 @@ function(add_runtime target_name)

add_custom_target("${target_name}" ALL DEPENDS "${absolute_target_path}")
set_property(TARGET "${target_name}" PROPERTY LOCATION "${absolute_target_path}")

if(REMILL_ENABLE_INSTALL_TARGET)
if(DEFINED install_destination)
install(FILES "${absolute_target_path}" DESTINATION "${install_destination}")
Expand Down
29 changes: 29 additions & 0 deletions include/remill/Arch/Runtime/Builtin.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
/*
* Copyright (c) 2022 Trail of Bits, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

#pragma once

#ifndef __has_include
# define __has_include(...) 0
#endif

#ifndef __has_builtin
# define __has_builtin(...) 0
#endif

#ifndef __is_identifier
# define __is_identifier(...) 1
#endif
13 changes: 10 additions & 3 deletions include/remill/Arch/Runtime/Float.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,11 @@

#pragma once

#include <cfloat>
#include "Builtin.h"

#if __has_include(<cfloat>)
# include <cfloat>
#endif

// Windows doesn't have the following macros defined
#ifndef _SW_INEXACT
Expand All @@ -33,8 +37,11 @@
# define _RC_CHOP 0x00000300 // chop
#endif

#include <cfenv>
#include <cmath>
#if __has_include(<cfenv>)
# include <cfenv>
#endif

#include "Math.h"

// macOS does not have this flag
#ifndef __FE_DENORM
Expand Down
2 changes: 1 addition & 1 deletion include/remill/Arch/Runtime/HyperCall.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@

#pragma once

#include <cstdint>
#include "Int.h"

class SyncHyperCall {
public:
Expand Down
101 changes: 101 additions & 0 deletions include/remill/Arch/Runtime/Int.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
/*
* Copyright (c) 2022 Trail of Bits, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

#pragma once

#include "Builtin.h"

#if __has_include(<cstdint>)
# include <cstdint>
#elif __has_include(<cinttypes>)
# include <cinttypes>
#else

#define REMILL_CUSTOM_INT_TYPES 1

using size_t = decltype(sizeof(int));

template <size_t kDesiredSize, typename... Ts>
struct TypeSelector;

template <size_t kDesiredSize, size_t kXorSize, typename... Ts>
struct TypeSelectorImpl;

template <size_t kDesiredSize, size_t kXorSize, typename T, typename... Ts>
struct TypeSelectorImpl<kDesiredSize, kXorSize, T, Ts...>
: public TypeSelector<kDesiredSize, Ts...> {};

template <size_t kDesiredSize, typename T, typename... Ts>
struct TypeSelectorImpl<kDesiredSize, 0, T, Ts...> {
using Type = T;
};

template <size_t kDesiredSize>
struct TypeSelector<kDesiredSize> {
using Type = void;
};

template <size_t kDesiredSize, typename T, typename... Ts>
struct TypeSelector<kDesiredSize, T, Ts...>
: public TypeSelectorImpl<kDesiredSize, sizeof(T) ^ kDesiredSize, T, Ts...> {};

using int8_t = signed char;
using uint8_t = unsigned char;
using int16_t = TypeSelector<2, short, int, long, long long>::Type;
using uint16_t = TypeSelector<2, unsigned short, unsigned, unsigned long, unsigned long long>::Type;
using int32_t = TypeSelector<4, int, long, long long>::Type;
using uint32_t = TypeSelector<4, unsigned, unsigned long, unsigned long long>::Type;
using int64_t = TypeSelector<8, int, long, long long>::Type;
using uint64_t = TypeSelector<8, unsigned, unsigned long, unsigned long long>::Type;

#endif // cstint, cinttypes

#if !defined(REMILL_DISABLE_INT128)
#if defined(__x86_64__) || defined(__i386__) || defined(_M_X86) || defined (__arm__)
typedef unsigned uint128_t __attribute__((mode(TI)));
typedef int int128_t __attribute__((mode(TI)));
#elif defined(__aarch64__)
typedef __uint128_t uint128_t;
typedef __int128_t int128_t;
#elif defined(__sparc__)
typedef __uint128_t uint128_t;
typedef __int128_t int128_t;
#elif defined(__is_identifier) && __is_identifier(_ExtInt)
typedef unsigned _ExtInt(128) uint128_t;
typedef signed _ExtInt(128) int128_t;
#else
#error "Unable to identify u/int128 type."
#endif

static_assert(sizeof(int128_t) == 16, "Invalid size for `int128_t`.");
static_assert(sizeof(uint128_t) == 16, "Invalid size for `uint128_t`.");
#endif // `!defined(REMILL_DISABLE_INT128)`

#ifdef REMILL_CUSTOM_INT_TYPES
namespace std {
inline namespace __remill {
using size_t = ::size_t;
using uint8_t = ::uint8_t;
using uint16_t = ::uint16_t;
using uint32_t = ::uint32_t;
using uint64_t = ::uint64_t;
using int8_t = ::int8_t;
using int16_t = ::int16_t;
using int32_t = ::int32_t;
using int64_t = ::int64_t;
} // namespace __remill
} // namespace std
#endif // REMILL_CUSTOM_INT_TYPES
109 changes: 109 additions & 0 deletions include/remill/Arch/Runtime/Intrinsics.h
Original file line number Diff line number Diff line change
Expand Up @@ -196,9 +196,11 @@ __remill_compare_exchange_memory_32(Memory *, addr_t addr, uint32_t &expected,
__remill_compare_exchange_memory_64(Memory *, addr_t addr, uint64_t &expected,
uint64_t desired);

#if !defined(REMILL_DISABLE_INT128)
[[gnu::used]] extern Memory *
__remill_compare_exchange_memory_128(Memory *, addr_t addr, uint128_t &expected,
uint128_t &desired);
#endif

[[gnu::used]] extern Memory *__remill_fetch_and_add_8(Memory *, addr_t addr,
uint8_t &value);
Expand Down Expand Up @@ -303,4 +305,111 @@ __remill_write_io_port_16(Memory *, addr_t, uint16_t);
[[gnu::used, gnu::const]] extern Memory *
__remill_write_io_port_32(Memory *, addr_t, uint32_t);

// More specific hyper calls.
[[gnu::used, gnu::const]] extern Memory *__remill_x86_set_segment_es(Memory *);

[[gnu::used, gnu::const]] extern Memory *__remill_x86_set_segment_ss(Memory *);

[[gnu::used, gnu::const]] extern Memory *__remill_x86_set_segment_ds(Memory *);

[[gnu::used, gnu::const]] extern Memory *__remill_x86_set_segment_fs(Memory *);

[[gnu::used, gnu::const]] extern Memory *__remill_x86_set_segment_gs(Memory *);

[[gnu::used, gnu::const]] extern Memory *__remill_x86_set_debug_reg(Memory *);

[[gnu::used, gnu::const]] extern Memory *
__remill_x86_set_control_reg_0(Memory *);

[[gnu::used, gnu::const]] extern Memory *
__remill_x86_set_control_reg_1(Memory *);

[[gnu::used, gnu::const]] extern Memory *
__remill_x86_set_control_reg_2(Memory *);

[[gnu::used, gnu::const]] extern Memory *
__remill_x86_set_control_reg_3(Memory *);

[[gnu::used, gnu::const]] extern Memory *
__remill_x86_set_control_reg_4(Memory *);

[[gnu::used, gnu::const]] extern Memory *__remill_amd64_set_debug_reg(Memory *);

[[gnu::used, gnu::const]] extern Memory *
__remill_amd64_set_control_reg_0(Memory *);

[[gnu::used, gnu::const]] extern Memory *
__remill_amd64_set_control_reg_1(Memory *);

[[gnu::used, gnu::const]] extern Memory *
__remill_amd64_set_control_reg_2(Memory *);

[[gnu::used, gnu::const]] extern Memory *
__remill_amd64_set_control_reg_3(Memory *);

[[gnu::used, gnu::const]] extern Memory *
__remill_amd64_set_control_reg_4(Memory *);

[[gnu::used, gnu::const]] extern Memory *
__remill_amd64_set_control_reg_8(Memory *);

[[gnu::used, gnu::const]] extern Memory *
__remill_aarch64_emulate_instruction(Memory *);

[[gnu::used, gnu::const]] extern Memory *
__remill_aarch32_emulate_instruction(Memory *);

[[gnu::used, gnu::const]] extern Memory *
__remill_aarch32_check_not_el2(Memory *);

[[gnu::used, gnu::const]] extern Memory *
__remill_sparc_set_asi_register(Memory *);

[[gnu::used, gnu::const]] extern Memory *
__remill_sparc_unimplemented_instruction(Memory *);

[[gnu::used, gnu::const]] extern Memory *
__remill_sparc_unhandled_dcti(Memory *);

[[gnu::used, gnu::const]] extern Memory *
__remill_sparc_window_underflow(Memory *);

[[gnu::used, gnu::const]] extern Memory *__remill_sparc_trap_cond_a(Memory *);

[[gnu::used, gnu::const]] extern Memory *__remill_sparc_trap_cond_n(Memory *);

[[gnu::used, gnu::const]] extern Memory *__remill_sparc_trap_cond_ne(Memory *);

[[gnu::used, gnu::const]] extern Memory *__remill_sparc_trap_cond_e(Memory *);

[[gnu::used, gnu::const]] extern Memory *__remill_sparc_trap_cond_g(Memory *);

[[gnu::used, gnu::const]] extern Memory *__remill_sparc_trap_cond_le(Memory *);

[[gnu::used, gnu::const]] extern Memory *__remill_sparc_trap_cond_ge(Memory *);

[[gnu::used, gnu::const]] extern Memory *__remill_sparc_trap_cond_l(Memory *);

[[gnu::used, gnu::const]] extern Memory *__remill_sparc_trap_cond_gu(Memory *);

[[gnu::used, gnu::const]] extern Memory *__remill_sparc_trap_cond_leu(Memory *);

[[gnu::used, gnu::const]] extern Memory *__remill_sparc_trap_cond_cc(Memory *);

[[gnu::used, gnu::const]] extern Memory *__remill_sparc_trap_cond_cs(Memory *);

[[gnu::used, gnu::const]] extern Memory *__remill_sparc_trap_cond_pos(Memory *);

[[gnu::used, gnu::const]] extern Memory *__remill_sparc_trap_cond_neg(Memory *);

[[gnu::used, gnu::const]] extern Memory *__remill_sparc_trap_cond_vc(Memory *);

[[gnu::used, gnu::const]] extern Memory *__remill_sparc_trap_cond_vs(Memory *);

[[gnu::used, gnu::const]] extern Memory *
__remill_sparc32_emulate_instruction(Memory *);

[[gnu::used, gnu::const]] extern Memory *
__remill_sparc64_emulate_instruction(Memory *);

} // extern C
Loading