add failover to naive location assumptions

This commit is contained in:
Jake Hillion 2024-08-23 14:40:09 +01:00
parent b7b9ac1536
commit cf60abd324
8 changed files with 67 additions and 209 deletions

View File

@ -1,223 +1,33 @@
AddChildrenTest.InheritancePolymorphic
ClangTypeParserTest.MemberAlignment
ClangTypeParserTest.SimpleStruct
DrgnParserTest.ClassTemplateInt
DrgnParserTest.Container
DrgnParserTest.TemplateEnumValue
DrgnParserTest.TemplateEnumValueGaps
DrgnParserTest.TemplateEnumValueNegative
OidIntegration.alignment_wrapper_member_alignment
OidIntegration.alignment_wrapper_member_lower
OidIntegration.alignment_wrapper_member_override
OidIntegration.alignment_wrapper_struct
OidIntegration.alignment_wrapper_two_members
OidIntegration.alignment_wrapper_union_member
OidIntegration.anonymous_anon_struct
OidIntegration.anonymous_anon_typedef
OidIntegration.anonymous_anon_union
OidIntegration.anonymous_nested_anon_struct
OidIntegration.anonymous_regular_struct
OidIntegration.arrays_member_int0
OidIntegration.arrays_member_int10
OidIntegration.arrays_multidim
OidIntegration.arrays_multidim_legacy
OidIntegration.bitfields_enum
OidIntegration.bitfields_mixed
OidIntegration.bitfields_single
OidIntegration.bitfields_straddle_bytes
OidIntegration.bitfields_within_bytes
OidIntegration.bitfields_zero_bits
OidIntegration.cycles_raw_ptr
OidIntegration.cycles_raw_ptr_wrapped
OidIntegration.cycles_shared_ptr
OidIntegration.cycles_unique_ptr
OidIntegration.enums_params_scoped_enum_val
OidIntegration.enums_params_scoped_enum_val_cast
OidIntegration.enums_params_scoped_enum_val_gaps
OidIntegration.enums_params_scoped_enum_val_negative
OidIntegration.enums_params_unscoped_enum_val_cast
OidIntegration.fbstring_empty
OidIntegration.fbstring_heap_allocated
OidIntegration.fbstring_inline
OidIntegration.fbstring_string_pooled_unique
OidIntegration.folly_f14_fast_map_a
OidIntegration.folly_f14_fast_set_a
OidIntegration.folly_f14_node_map_a
OidIntegration.folly_f14_node_set_a
OidIntegration.folly_f14_value_map_a
OidIntegration.folly_f14_value_set_a
OidIntegration.folly_f14_vector_map_a
OidIntegration.folly_f14_vector_set_a
OidIntegration.folly_small_vector_int_always_heap
OidIntegration.folly_small_vector_int_default_empty
OidIntegration.folly_small_vector_int_default_inlined
OidIntegration.folly_small_vector_int_default_overflow
OidIntegration.folly_small_vector_vector_3_empty
OidIntegration.folly_small_vector_vector_3_inlined
OidIntegration.folly_small_vector_vector_3_overflow
OidIntegration.folly_sorted_vector_map_int_int_empty
OidIntegration.folly_sorted_vector_map_int_int_reserve
OidIntegration.folly_sorted_vector_map_int_int_some
OidIntegration.ignored_member
OidIntegration.ignored_roottype
OidIntegration.ignored_subtype
OidIntegration.inheritance_access_private
OidIntegration.inheritance_access_protected
OidIntegration.inheritance_access_public
OidIntegration.inheritance_access_public_as_base
OidIntegration.inheritance_multiple_a
OidIntegration.inheritance_polymorphic_a_as_a
DrgnParserTest.Typedef
DrgnParserTest.Using
OidIntegration.inheritance_polymorphic_b_as_a
OidIntegration.inheritance_polymorphic_b_as_b
OidIntegration.inheritance_polymorphic_c_as_a
OidIntegration.inheritance_polymorphic_c_as_b
OidIntegration.inheritance_polymorphic_c_as_c
OidIntegration.inheritance_polymorphic_diamond_child_as_child
OidIntegration.inheritance_polymorphic_diamond_child_as_middle1
OidIntegration.inheritance_polymorphic_diamond_child_as_middle1_root
OidIntegration.inheritance_polymorphic_diamond_child_as_middle2
OidIntegration.inheritance_polymorphic_diamond_child_as_middle2_root
OidIntegration.inheritance_polymorphic_diamond_middle1_as_middle1
OidIntegration.inheritance_polymorphic_diamond_middle1_as_root
OidIntegration.inheritance_polymorphic_diamond_middle2_as_middle2
OidIntegration.inheritance_polymorphic_diamond_middle2_as_root
OidIntegration.inheritance_polymorphic_diamond_root_as_root
OidIntegration.inheritance_polymorphic_non_dynamic_base_a_as_a
OidIntegration.inheritance_polymorphic_non_dynamic_base_a_no_polymorphic
OidIntegration.inheritance_polymorphic_non_dynamic_base_b_as_a
OidIntegration.inheritance_polymorphic_non_dynamic_base_b_as_b
OidIntegration.inheritance_polymorphic_non_dynamic_base_b_no_polymorphic
OidIntegration.inheritance_polymorphic_non_dynamic_base_c_as_a
OidIntegration.inheritance_polymorphic_non_dynamic_base_c_as_b
OidIntegration.inheritance_polymorphic_non_dynamic_base_c_as_c
OidIntegration.inheritance_polymorphic_non_dynamic_base_c_no_polymorphic
OidIntegration.multi_arg_tb_all_fail_crashes
OidIntegration.multi_arg_tb_fail_first_arg
OidIntegration.namespaces_queue
OidIntegration.namespaces_stack
OidIntegration.packed_a
OidIntegration.padding_bool_padding
OidIntegration.padding_nested_padding
OidIntegration.pointers_feature_config
OidIntegration.pointers_feature_flag_disabled
OidIntegration.pointers_incomplete_containing_struct
OidIntegration.pointers_incomplete_containing_struct_no_follow
OidIntegration.pointers_incomplete_shared_ptr
OidIntegration.pointers_incomplete_shared_ptr_null
OidIntegration.pointers_incomplete_unique_ptr
OidIntegration.pointers_incomplete_unique_ptr_null
OidIntegration.pointers_struct_primitive_ptrs
OidIntegration.pointers_struct_primitive_ptrs_no_follow
OidIntegration.pointers_struct_primitive_ptrs_null
OidIntegration.pointers_struct_vector_ptr
OidIntegration.pointers_struct_vector_ptr_no_follow
OidIntegration.pointers_struct_vector_ptr_null
OidIntegration.pointers_vector_of_pointers
OidIntegration.primitives_long_double
OidIntegration.simple_class
OidIntegration.simple_struct
OidIntegration.simple_union
OidIntegration.sorted_vector_set_no_ints
OidIntegration.sorted_vector_set_some_ints
OidIntegration.std_array_uint64_length_0
OidIntegration.std_array_uint64_length_1
OidIntegration.std_array_uint64_length_8
OidIntegration.std_array_vector_length_1
OidIntegration.std_array_vector_length_2
OidIntegration.std_conditional_a
OidIntegration.std_deque_del_allocator_a
OidIntegration.std_deque_deque_int_empty
OidIntegration.std_deque_deque_int_some
OidIntegration.std_deque_int_empty
OidIntegration.std_deque_int_some
OidIntegration.std_list_del_allocator_a
OidIntegration.std_list_int_empty
OidIntegration.std_list_int_some
OidIntegration.std_list_list_int_empty
OidIntegration.std_list_list_int_some
OidIntegration.std_list_struct_some
OidIntegration.std_map_custom_comparator_a
OidIntegration.std_multimap_custom_comparator_a
OidIntegration.std_multiset_custom_comparator_a
OidIntegration.std_optional_uint64_empty
OidIntegration.std_optional_uint64_present
OidIntegration.std_optional_vector_empty
OidIntegration.std_optional_vector_present
OidIntegration.std_pair_uint64_uint32
OidIntegration.std_pair_uint64_uint64
OidIntegration.std_pair_vector_vector
OidIntegration.std_priority_queue_adapter_deque_empty
OidIntegration.std_priority_queue_adapter_deque_some
OidIntegration.std_priority_queue_int_empty
OidIntegration.std_priority_queue_int_some
OidIntegration.std_queue_adapter_vector_empty
OidIntegration.std_queue_adapter_vector_some
OidIntegration.std_queue_int_empty
OidIntegration.std_queue_int_some
OidIntegration.std_queue_queue_int_empty
OidIntegration.std_queue_queue_int_some
OidIntegration.std_reference_wrapper_int
OidIntegration.std_reference_wrapper_vector
OidIntegration.std_set_custom_comparator_a
OidIntegration.std_smart_ptr_shared_ptr_const_uint64_empty
OidIntegration.std_smart_ptr_shared_ptr_const_vector_empty
OidIntegration.std_smart_ptr_shared_ptr_uint64_empty
OidIntegration.std_smart_ptr_shared_ptr_uint64_present
OidIntegration.std_smart_ptr_shared_ptr_vector_empty
OidIntegration.std_smart_ptr_shared_ptr_vector_present
OidIntegration.std_smart_ptr_shared_ptr_void_empty
OidIntegration.std_smart_ptr_shared_ptr_void_present
OidIntegration.std_smart_ptr_unique_ptr_const_uint64_empty
OidIntegration.std_smart_ptr_unique_ptr_const_vector_empty
OidIntegration.std_smart_ptr_unique_ptr_uint64_empty
OidIntegration.std_smart_ptr_unique_ptr_uint64_present
OidIntegration.std_smart_ptr_unique_ptr_vector_empty
OidIntegration.std_smart_ptr_unique_ptr_vector_present
OidIntegration.std_smart_ptr_unique_ptr_void_empty
OidIntegration.std_smart_ptr_unique_ptr_void_present
OidIntegration.std_smart_ptr_weak_ptr_int64_empty
OidIntegration.std_smart_ptr_weak_ptr_int64_expired
OidIntegration.std_smart_ptr_weak_ptr_int64_expired_chase
OidIntegration.std_smart_ptr_weak_ptr_int64_present
OidIntegration.std_smart_ptr_weak_ptr_int64_present_chase
OidIntegration.std_smart_ptr_weak_ptr_int64_void_empty
OidIntegration.std_stack_adapter_vector_empty
OidIntegration.std_stack_adapter_vector_some
OidIntegration.std_stack_int_empty
OidIntegration.std_stack_int_some
OidIntegration.std_stack_stack_int_empty
OidIntegration.std_stack_stack_int_some
OidIntegration.std_string_empty
OidIntegration.std_string_heap_allocated
OidIntegration.std_string_sso
OidIntegration.std_tuple_uint64_uint64
OidIntegration.std_unordered_map_custom_operator_a
OidIntegration.std_unordered_multimap_custom_operator_a
OidIntegration.std_unordered_multiset_custom_operator_a
OidIntegration.std_unordered_set_custom_operator_a
OidIntegration.std_variant_256_params_256
OidIntegration.std_variant_256_params_empty
OidIntegration.std_variant_char_int64_1
OidIntegration.std_variant_char_int64_2
OidIntegration.std_variant_empty
OidIntegration.std_variant_optional
OidIntegration.std_variant_vector_int_1
OidIntegration.std_variant_vector_int_2
OidIntegration.std_vector_del_allocator_a
OidIntegration.std_vector_int_empty
OidIntegration.std_vector_int_some
OidIntegration.std_vector_reserve
OidIntegration.std_vector_struct_some
OidIntegration.std_vector_vector_int_empty
OidIntegration.std_vector_vector_int_some
OidIntegration.templates_int
OidIntegration.templates_two
OidIntegration.templates_value
OidIntegration.templates_vector
OidIntegration.typedefed_parent_multilevel_typedef_parent
OidIntegration.typedefed_parent_simple_typedef_parent
OidIntegration.typedefs_anonymous
OidIntegration.typedefs_c_style
OidIntegration.typedefs_container
OidIntegration.typedefs_using
OidIntegration.unions_alignment
OidIntegration.unions_int
OidIntegration.unions_tagged_int
@ -225,11 +35,3 @@ OidIntegration.unions_tagged_unordered_map
OidIntegration.unions_tagged_vector
OidIntegration.unions_unordered_map
OidIntegration.unions_vector
OilIntegration.folly_f14_fast_map_a
OilIntegration.folly_f14_fast_set_a
OilIntegration.folly_f14_node_map_a
OilIntegration.folly_f14_node_set_a
OilIntegration.folly_f14_value_map_a
OilIntegration.folly_f14_value_set_a
OilIntegration.folly_f14_vector_map_a
OilIntegration.folly_f14_vector_set_a

View File

@ -34,7 +34,7 @@
mkOidPackage =
llvmPackages:
with pkgs;
pkgs.llvmPackages.stdenv.mkDerivation rec {
llvmPackages.stdenv.mkDerivation rec {
name = "oid";
src = self;
@ -60,6 +60,7 @@
buildInputs = [
llvmPackages.libclang
llvmPackages.llvm
llvmPackages.openmp
boost
bzip2
@ -85,8 +86,6 @@
sqlite
tomlplusplus
zstd
llvmPackages.openmp # should match the stdenv clang version, see: https://github.com/NixOS/nixpkgs/issues/79818
];
cmakeFlags = [

View File

@ -50,10 +50,11 @@ std::optional<uintptr_t> FuncDesc::Arg::findAddress(
if (auto* err = drgn_object_locate(&locator, &modifiedRegs, &object)) {
LOG(ERROR) << "Error while finding address of argument: " << err->message;
drgn_error_destroy(err);
return std::nullopt;
} else {
return object.address;
}
return object.address;
return oi::detail::arch::naiveReadArgument(*regs, index);
}
std::optional<uint8_t> FuncDesc::getArgumentIndex(const std::string& arg,

View File

@ -110,7 +110,8 @@ struct FuncDesc {
};
struct Arg final : virtual TargetObject {
struct drgn_object_locator locator;
uint8_t index;
drgn_object_locator locator;
~Arg() final {
drgn_object_locator_deinit(&locator);

View File

@ -40,7 +40,7 @@
DEFINE_TYPE_VERSION(PaddingInfo, 120, 3)
DEFINE_TYPE_VERSION(struct drgn_location_description, 32, 2)
DEFINE_TYPE_VERSION(struct drgn_object_locator, 72, 2)
DEFINE_TYPE_VERSION(FuncDesc::Arg, 128, 2)
DEFINE_TYPE_VERSION(FuncDesc::Arg, 136, 3)
DEFINE_TYPE_VERSION(FuncDesc::Retval, 56, 2)
DEFINE_TYPE_VERSION(FuncDesc::Range, 16, 2)
DEFINE_TYPE_VERSION(FuncDesc, 104, 4)

View File

@ -26,4 +26,6 @@ void setProgramCounter(user_regs_struct& regs, uintptr_t pc);
std::optional<uintptr_t> getReturnValueAddress(const user_regs_struct&);
std::optional<uintptr_t> naiveReadArgument(const user_regs_struct&, uint8_t idx);
} // namespace oi::detail::arch

View File

@ -31,6 +31,33 @@ void setProgramCounter(user_regs_struct& regs, uintptr_t pc) {
regs.pc = pc;
}
std::optional<uintptr_t> naiveReadArgument(const user_regs_struct&, uint8_t idx) {
/*
* The ARM64 argument passing practices are surprisingly well documented. The
* PDF I am using here is
* https://github.com/ARM-software/abi-aa/releases/download/2023Q3/aapcs32.pdf
* from https://github.com/ARM-software/abi-aa/releases/tag/2023Q3. Relevant
* information appears to be in §6.8.2.
*
* This is an extremely naïve estimation of register placement. It is expected
* to work when all preceding arguments (this, arg0, arg.., argIdx) are:
* - Pointers. Pointers are all placed in general purpose registers incrementing
* as expected.
* - >16 byte by-value structures. These are defined to be placed on the stack and
* have a pointer placed in a general purpose registers, so increment in the
* same wayi.
*
* Any other types, including floats, will mess up our indexing. Looking at the
* types of all the preceding arguments could get us a lot closer. For now, we
* rely on OID correctly restoring the process if we get this wrong, and might
* produce garbage data.
*/
if (idx < 8)
return regs.regs[idx];
return std::nullopt;
}
} // namespace oi::detail::arch
#endif

View File

@ -31,6 +31,32 @@ void setProgramCounter(user_regs_struct& regs, uintptr_t pc) {
regs.rip = pc;
}
std::optional<uintptr_t> naiveReadArgument(const user_regs_struct& regs, uint8_t idx) {
/*
* This function is based on the information available at
* http://6.s081.scripts.mit.edu/sp18/x86-64-architecture-guide.html. I have
* no idea under which conditions these registers are selected. We rely on the
* fact that OID will safely exit if incorrect, potentially producing some
* incorrect data but otherwise leaving the process unharmed.
*/
switch (idx) {
case 0:
return regs.rdi;
case 1:
return regs.rsi;
case 2:
return regs.rdx;
case 3:
return regs.rcx;
case 4:
return regs.r8;
case 5:
return regs.r9;
default:
return std::nullopt;
}
}
} // namespace oi::detail::arch
#endif