+
+static int elf_find_section(char *map, const char *section, unsigned int *offset, unsigned int *size)
+{
+ int clazz = map[EI_CLASS];
+
+ if (clazz == ELFCLASS32)
+ return elf32_find_section(map, section, offset, size);
+ else if (clazz == ELFCLASS64)
+ return elf64_find_section(map, section, offset, size);
+
+ ULOG_ERR("unknown elf format %d\n", clazz);
+
+ return -1;
+}
+
+static struct module_node *
+alloc_module_node(const char *name, struct module *m, bool is_alias)
+{
+ struct module_node *mn;
+ char *_name;
+
+ mn = calloc_a(sizeof(*mn),
+ &_name, strlen(name) + 1);
+ if (mn) {
+ mn->avl.key = strcpy(_name, name);
+ mn->m = m;
+ mn->is_alias = is_alias;
+ avl_insert(&modules, &mn->avl);
+ m->refcnt += 1;
+ }
+ return mn;
+}
+
+static struct module *
+alloc_module(const char *name, const char * const *aliases, int naliases, const char *depends, int size)
+{
+ struct module *m;
+ char *_name, *_dep;
+ char **_aliases;
+ int i, len_aliases;
+
+ len_aliases = naliases * sizeof(aliases[0]);
+ for (i = 0; i < naliases; i++)
+ len_aliases += strlen(aliases[i]) + 1;
+ m = calloc_a(sizeof(*m),
+ &_name, strlen(name) + 1,
+ &_dep, depends ? strlen(depends) + 2 : 0,
+ &_aliases, len_aliases);
+ if (!m)
+ return NULL;
+
+ m->name = strcpy(_name, name);
+ m->opts = 0;
+
+ if (depends) {
+ m->depends = strcpy(_dep, depends);
+ while (*_dep) {
+ if (*_dep == ',')
+ *_dep = '\0';
+ _dep++;
+ }
+ }
+ m->size = size;
+ m->naliases = naliases;
+ if (naliases == 0)
+ m->aliases = NULL;
+ else {
+ char *ptr = (char *)_aliases + naliases * sizeof(_aliases[0]);
+ int len;
+
+ i = 0;
+ do {
+ len = strlen(aliases[i]) + 1;
+ memcpy(ptr, aliases[i], len);
+ _aliases[i] = ptr;
+ ptr += len;
+ i++;
+ } while (i < naliases);
+ m->aliases = _aliases;
+ }
+
+ m->refcnt = 0;
+ alloc_module_node(m->name, m, false);
+ for (i = 0; i < m->naliases; i++)
+ alloc_module_node(m->aliases[i], m, true);
+
+ return m;
+}
+
+static void free_module(struct module *m)
+{
+ if (m->opts)
+ free(m->opts);
+ free(m);
+}