diff options
Diffstat (limited to 'com32/elflink/elf_utils.c')
-rw-r--r-- | com32/elflink/elf_utils.c | 70 |
1 files changed, 70 insertions, 0 deletions
diff --git a/com32/elflink/elf_utils.c b/com32/elflink/elf_utils.c new file mode 100644 index 00000000..be320772 --- /dev/null +++ b/com32/elflink/elf_utils.c @@ -0,0 +1,70 @@ +#include <stdlib.h> +#include <errno.h> + +#include "elf_utils.h" + +unsigned long elf_hash(const unsigned char *name) { + unsigned long h = 0; + unsigned long g; + + while (*name) { + h = (h << 4) + *name++; + if ((g = h & 0xF0000000)) + h ^= g >> 24; + + h &= ~g; + } + + return h; +} + +unsigned long elf_gnu_hash(const unsigned char *name) { + unsigned long h = 5381; + unsigned char c; + + for (c = *name; c != '\0'; c = *++name) { + h = h * 33 + c; + } + + return h & 0xFFFFFFFF; +} + + +struct memalign_info { + void *start_addr; + char data[0]; +}; + +int elf_malloc(void **memptr, size_t alignment, size_t size) { + void *start_addr = NULL; + struct memalign_info *info; + + if ((alignment & (alignment - 1)) != 0) + return EINVAL; + if (alignment % sizeof(void*) != 0) + return EINVAL; + + start_addr = malloc(size + (alignment > sizeof(struct memalign_info) ? + alignment : sizeof(struct memalign_info))); + + if (start_addr == NULL) + return ENOMEM; + + + info = (struct memalign_info*)(start_addr - + ((unsigned long)start_addr % alignment) + + alignment - sizeof(struct memalign_info)); + + info->start_addr = start_addr; + + *memptr = info->data; + + return 0; +} + +void elf_free(void *memptr) { + struct memalign_info *info = (struct memalign_info*)(memptr - + sizeof(struct memalign_info)); + + free(info->start_addr); +} |