// Inside the enclave we don't have the rtld to do symbol lookups for us. So, we must manually compute
// the name->address mappings at compile time and then let the SGX ELF loader apply the relocs itself.
//
// Because there are quite a few symbols we might want to look up, the final file is generated using a script.
// This is just a template.
//

#ifndef AVIAN_SGX_DISPATCH_TABLE_H
#define AVIAN_SGX_DISPATCH_TABLE_H

#include <string>
#include <map>
#include <avian/common.h>

using namespace std;

extern "C" {
// EXTERNS HERE
}

namespace {
    struct entry {
        const char *name;
        const void *addr;
    } entries[] = {
// ENTRIES HERE
            { NULL, NULL }
    };

    static int symbol_table_size = -1;

    static int comparator(const void *e1, const void *e2) {
        const struct entry *entry1 = static_cast<const struct entry*>(e1);
        const struct entry *entry2 = static_cast<const struct entry*>(e2);
        return strcmp(entry1->name, entry2->name);
    }
}

extern "C" const void *dlsym(void *handle, const char *name) {
    if (symbol_table_size == -1) {
        symbol_table_size = 0;
        while (entries[symbol_table_size].name) symbol_table_size++;
    }
    struct entry key = {name, NULL};
    struct entry *result = (struct entry *) bsearch(&key, entries, symbol_table_size, sizeof(struct entry), comparator);
    if (result) {
        return result->addr;
    } else {
        return NULL;
    }
}

#endif //AVIAN_SGX_DISPATCH_TABLE_H