Templated lambdas aren't a thing in C++11 :(

This commit is contained in:
Jeremy Rifkin 2025-01-26 14:52:31 -06:00
parent 76a21d266a
commit b705afba69
No known key found for this signature in database
GPG Key ID: 19AA8270105E8EB4
2 changed files with 60 additions and 50 deletions

View File

@ -54,7 +54,15 @@ namespace detail {
Result<std::uintptr_t, internal_error> elf::get_module_image_base() { Result<std::uintptr_t, internal_error> elf::get_module_image_base() {
// get image base // get image base
auto impl = [this]<std::size_t Bits>() -> Result<std::uintptr_t, internal_error> { if(is_64) {
return get_module_image_base_impl<64>();
} else {
return get_module_image_base_impl<32>();
}
}
template<std::size_t Bits>
Result<std::uintptr_t, internal_error> elf::get_module_image_base_impl() {
static_assert(Bits == 32 || Bits == 64, "Unexpected Bits argument"); static_assert(Bits == 32 || Bits == 64, "Unexpected Bits argument");
using PHeader = typename std::conditional<Bits == 32, Elf32_Phdr, Elf64_Phdr>::type; using PHeader = typename std::conditional<Bits == 32, Elf32_Phdr, Elf64_Phdr>::type;
auto header = get_header_info(); auto header = get_header_info();
@ -78,12 +86,6 @@ namespace detail {
} }
// Apparently some objects like shared objects can end up missing this header. 0 as a base seems correct. // Apparently some objects like shared objects can end up missing this header. 0 as a base seems correct.
return 0; return 0;
};
if(is_64) {
return impl.operator()<64>();
} else {
return impl.operator()<32>();
}
} }
template<typename T, typename std::enable_if<std::is_integral<T>::value, int>::type> template<typename T, typename std::enable_if<std::is_integral<T>::value, int>::type>
@ -99,7 +101,15 @@ namespace detail {
if(header) { if(header) {
return header.unwrap(); return header.unwrap();
} }
auto impl = [this]<std::size_t Bits>() -> Result<header_info, internal_error> { if(is_64) {
return get_header_info_impl<64>();
} else {
return get_header_info_impl<32>();
}
}
template<std::size_t Bits>
Result<elf::header_info, internal_error> elf::get_header_info_impl() {
static_assert(Bits == 32 || Bits == 64, "Unexpected Bits argument"); static_assert(Bits == 32 || Bits == 64, "Unexpected Bits argument");
using Header = typename std::conditional<Bits == 32, Elf32_Ehdr, Elf64_Ehdr>::type; using Header = typename std::conditional<Bits == 32, Elf32_Ehdr, Elf64_Ehdr>::type;
auto loaded_header = load_bytes<Header>(file, 0); auto loaded_header = load_bytes<Header>(file, 0);
@ -119,12 +129,6 @@ namespace detail {
info.e_shentsize = file_header.e_shentsize; info.e_shentsize = file_header.e_shentsize;
header = info; header = info;
return header.unwrap(); return header.unwrap();
};
if(is_64) {
return impl.operator()<64>();
} else {
return impl.operator()<32>();
}
} }
} }
} }

View File

@ -32,13 +32,19 @@ namespace detail {
public: public:
static NODISCARD Result<elf, internal_error> open_elf(const std::string& object_path); static NODISCARD Result<elf, internal_error> open_elf(const std::string& object_path);
public:
Result<std::uintptr_t, internal_error> get_module_image_base(); Result<std::uintptr_t, internal_error> get_module_image_base();
private:
template<std::size_t Bits>
Result<std::uintptr_t, internal_error> get_module_image_base_impl();
private: private:
template<typename T, typename std::enable_if<std::is_integral<T>::value, int>::type = 0> template<typename T, typename std::enable_if<std::is_integral<T>::value, int>::type = 0>
T byteswap_if_needed(T value, bool elf_is_little); T byteswap_if_needed(T value, bool elf_is_little);
Result<header_info, internal_error> get_header_info(); Result<header_info, internal_error> get_header_info();
template<std::size_t Bits>
Result<header_info, internal_error> get_header_info_impl();
}; };
} }
} }