EnderIce2 201ace7eec
refactor(userspace): build using cmake
Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2025-03-15 23:05:17 +00:00

132 lines
2.6 KiB
C

/*
This file is part of Fennix C Library.
Fennix C Library is free software: you can redistribute it and/or
modify it under the terms of the GNU General Public License as
published by the Free Software Foundation, either version 3 of
the License, or (at your option) any later version.
Fennix C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Fennix C Library. If not, see <https://www.gnu.org/licenses/>.
*/
#include <bits/libc.h>
#include <sys/types.h>
#include <stdint.h>
#include <stddef.h>
#include <errno.h>
#include "elf.h"
#include "misc.h"
void *memset(void *s, int c, size_t n)
{
uint8_t *p = s;
while (n--)
*p++ = c;
return s;
}
void *memcpy(void *dest, const void *src, size_t n)
{
uint8_t *d = dest;
const uint8_t *s = src;
while (n--)
*d++ = *s++;
return dest;
}
size_t strlen(const char *s)
{
const char *p = s;
while (*p)
p++;
return p - s;
}
char *strcpy(char *dest, const char *src)
{
char *d = dest;
while ((*d++ = *src++))
;
return dest;
}
int strcmp(const char *l, const char *r)
{
while (*l && *l == *r)
{
l++;
r++;
}
return *l - *r;
}
char *strcat(char *dest, const char *src)
{
char *d = dest;
while (*d)
d++;
while ((*d++ = *src++))
;
return dest;
}
unsigned long elf_hash(const unsigned char *name)
{
unsigned long hash = 0, high;
while (*name)
{
hash = (hash << 4) + *name++;
if ((high = hash & 0xF0000000))
hash ^= high >> 24;
hash &= ~high;
}
return hash;
}
uint32_t gnu_hash(const char *name)
{
uint32_t hash = 5381;
for (; *name; name++)
{
hash = (hash << 5) + hash + (unsigned char)(*name); // hash * 33 + c
}
return hash;
}
Elf64_Sym *find_symbol(const char *name, uint32_t *hash_table, Elf64_Sym *symtab, const char *strtab)
{
/* Symbol Hash Table
|-------------------|
| nbucket |
|-------------------|
| nchain |
|-------------------|
| bucket[0] |
| . . . |
|bucket[nbucket - 1]|
|-------------------|
| chain[0] |
| . . . |
| chain[nchain - 1] |
|-------------------|
*/
unsigned long h = elf_hash(name); // or gnu_hash(name)
unsigned long bucket = h % hash_table[0]; // hash_table[0] = nbucket
for (unsigned long i = hash_table[2 + bucket];
i != STN_UNDEF;
i = hash_table[2 + hash_table[0] + i])
{
if (!strcmp(&strtab[symtab[i].st_name], name))
return &symtab[i];
}
return NULL;
}