Elf file: fast loading fap files. Really fast, like x15 times faster.

This commit is contained in:
SG
2023-06-21 17:17:35 +03:00
parent 42056d17b1
commit 1bc9c03f35
8 changed files with 153 additions and 31 deletions

View File

@@ -7,27 +7,22 @@
bool elf_resolve_from_hashtable(
const ElfApiInterface* interface,
const char* name,
uint32_t hash,
Elf32_Addr* address) {
bool result = false;
const HashtableApiInterface* hashtable_interface =
static_cast<const HashtableApiInterface*>(interface);
bool result = false;
uint32_t gnu_sym_hash = elf_gnu_hash(name);
sym_entry key = {
.hash = gnu_sym_hash,
.hash = hash,
.address = 0,
};
auto find_res =
std::lower_bound(hashtable_interface->table_cbegin, hashtable_interface->table_cend, key);
if((find_res == hashtable_interface->table_cend || (find_res->hash != gnu_sym_hash))) {
if((find_res == hashtable_interface->table_cend || (find_res->hash != hash))) {
FURI_LOG_W(
TAG,
"Can't find symbol '%s' (hash %lx) @ %p!",
name,
gnu_sym_hash,
hashtable_interface->table_cbegin);
TAG, "Can't find symbol with hash %lx @ %p!", hash, hashtable_interface->table_cbegin);
result = false;
} else {
result = true;
@@ -36,3 +31,7 @@ bool elf_resolve_from_hashtable(
return result;
}
uint32_t elf_symbolname_hash(const char* s) {
return elf_gnu_hash(s);
}

View File

@@ -19,15 +19,17 @@ struct sym_entry {
/**
* @brief Resolver for API entries using a pre-sorted table with hashes
* @param interface pointer to HashtableApiInterface
* @param name function name
* @param hash gnu hash of function name
* @param address output for function address
* @return true if the table contains a function
*/
bool elf_resolve_from_hashtable(
const ElfApiInterface* interface,
const char* name,
uint32_t hash,
Elf32_Addr* address);
uint32_t elf_symbolname_hash(const char* s);
#ifdef __cplusplus
}
@@ -48,8 +50,10 @@ struct HashtableApiInterface : public ElfApiInterface {
.hash = elf_gnu_hash(#x), .address = (uint32_t)(static_cast<ret_type(*) args_type>(x)) \
}
#define API_VARIABLE(x, var_type) \
sym_entry { .hash = elf_gnu_hash(#x), .address = (uint32_t)(&(x)), }
#define API_VARIABLE(x, var_type) \
sym_entry { \
.hash = elf_gnu_hash(#x), .address = (uint32_t)(&(x)), \
}
constexpr bool operator<(const sym_entry& k1, const sym_entry& k2) {
return k1.hash < k2.hash;