Flipper Zero Firmware
Loading...
Searching...
No Matches
api_hashtable.h
1#pragma once
2
3#include <flipper_application/elf/elf_api_interface.h>
4
5#include <stdint.h>
6
7#ifdef __cplusplus
8extern "C" {
9#endif
10
14struct sym_entry {
15 uint32_t hash;
16 uint32_t address;
17};
18
26bool elf_resolve_from_hashtable(
27 const ElfApiInterface* interface,
28 uint32_t hash,
29 Elf32_Addr* address);
30
31uint32_t elf_symbolname_hash(const char* s);
32
33#ifdef __cplusplus
34}
35
36#include <array>
37#include <algorithm>
38
44struct HashtableApiInterface : public ElfApiInterface {
45 const sym_entry *table_cbegin, *table_cend;
46};
47
48#define API_METHOD(x, ret_type, args_type) \
49 sym_entry { \
50 .hash = elf_gnu_hash(#x), .address = (uint32_t)(static_cast<ret_type(*) args_type>(x)) \
51 }
52
53#define API_VARIABLE(x, var_type) \
54 sym_entry { \
55 .hash = elf_gnu_hash(#x), .address = (uint32_t)(&(x)), \
56 }
57
58constexpr bool operator<(const sym_entry& k1, const sym_entry& k2) {
59 return k1.hash < k2.hash;
60}
61
67constexpr uint32_t elf_gnu_hash(const char* s) {
68 uint32_t h = 0x1505;
69 for(unsigned char c = *s; c != '\0'; c = *++s) {
70 h = (h << 5) + h + c;
71 }
72 return h;
73}
74
75/* Compile-time check for hash collisions in API table.
76 * Usage: static_assert(!has_hash_collisions(api_methods), "Hash collision detected");
77 */
78template <std::size_t N>
79constexpr bool has_hash_collisions(const std::array<sym_entry, N>& api_methods) {
80 for(std::size_t i = 0; i < (N - 1); ++i) {
81 if(api_methods[i].hash == api_methods[i + 1].hash) {
82 return true;
83 }
84 }
85
86 return false;
87}
88
89#endif
Interface for ELF loader to resolve symbols.
Definition elf_api_interface.h:9
Symbol table entry.
Definition api_hashtable.h:14