mirror of
https://github.com/Fennix-Project/Userspace.git
synced 2025-05-28 15:34:26 +00:00
Fix elf interpreter (less broken)
This commit is contained in:
parent
78494d58eb
commit
c20aae9504
@ -16,42 +16,45 @@ typedef __UINT32_TYPE__ Elf64_Word;
|
|||||||
typedef __UINT64_TYPE__ Elf64_Xword;
|
typedef __UINT64_TYPE__ Elf64_Xword;
|
||||||
typedef __INT64_TYPE__ Elf64_Sxword;
|
typedef __INT64_TYPE__ Elf64_Sxword;
|
||||||
|
|
||||||
#define SHT_NULL 0
|
enum SectionHeaderType
|
||||||
#define SHT_PROGBITS 1
|
{
|
||||||
#define SHT_SYMTAB 2
|
SHT_NULL = 0,
|
||||||
#define SHT_STRTAB 3
|
SHT_PROGBITS = 1,
|
||||||
#define SHT_RELA 4
|
SHT_SYMTAB = 2,
|
||||||
#define SHT_HASH 5
|
SHT_STRTAB = 3,
|
||||||
#define SHT_DYNAMIC 6
|
SHT_RELA = 4,
|
||||||
#define SHT_NOTE 7
|
SHT_HASH = 5,
|
||||||
#define SHT_NOBITS 8
|
SHT_DYNAMIC = 6,
|
||||||
#define SHT_REL 9
|
SHT_NOTE = 7,
|
||||||
#define SHT_SHLIB 10
|
SHT_NOBITS = 8,
|
||||||
#define SHT_DYNSYM 11
|
SHT_REL = 9,
|
||||||
#define SHT_INIT_ARRAY 14
|
SHT_SHLIB = 10,
|
||||||
#define SHT_FINI_ARRAY 15
|
SHT_DYNSYM = 11,
|
||||||
#define SHT_PREINIT_ARRAY 16
|
SHT_INIT_ARRAY = 14,
|
||||||
#define SHT_GROUP 17
|
SHT_FINI_ARRAY = 15,
|
||||||
#define SHT_SYMTAB_SHNDX 18
|
SHT_PREINIT_ARRAY = 16,
|
||||||
#define SHT_NUM 19
|
SHT_GROUP = 17,
|
||||||
#define SHT_LOOS 0x60000000
|
SHT_SYMTAB_SHNDX = 18,
|
||||||
#define SHT_GNU_ATTRIBUTES 0x6ffffff5
|
SHT_NUM = 19,
|
||||||
#define SHT_GNU_HASH 0x6ffffff6
|
SHT_LOOS = 0x60000000,
|
||||||
#define SHT_GNU_LIBLIST 0x6ffffff7
|
SHT_GNU_ATTRIBUTES = 0x6ffffff5,
|
||||||
#define SHT_CHECKSUM 0x6ffffff8
|
SHT_GNU_HASH = 0x6ffffff6,
|
||||||
#define SHT_LOSUNW 0x6ffffffa
|
SHT_GNU_LIBLIST = 0x6ffffff7,
|
||||||
#define SHT_SUNW_move 0x6ffffffa
|
SHT_CHECKSUM = 0x6ffffff8,
|
||||||
#define SHT_SUNW_COMDAT 0x6ffffffb
|
SHT_LOSUNW = 0x6ffffffa,
|
||||||
#define SHT_SUNW_syminfo 0x6ffffffc
|
SHT_SUNW_move = 0x6ffffffa,
|
||||||
#define SHT_GNU_verdef 0x6ffffffd
|
SHT_SUNW_COMDAT = 0x6ffffffb,
|
||||||
#define SHT_GNU_verneed 0x6ffffffe
|
SHT_SUNW_syminfo = 0x6ffffffc,
|
||||||
#define SHT_GNU_versym 0x6fffffff
|
SHT_GNU_verdef = 0x6ffffffd,
|
||||||
#define SHT_HISUNW 0x6fffffff
|
SHT_GNU_verneed = 0x6ffffffe,
|
||||||
#define SHT_HIOS 0x6fffffff
|
SHT_GNU_versym = 0x6fffffff,
|
||||||
#define SHT_LOPROC 0x70000000
|
SHT_HISUNW = 0x6fffffff,
|
||||||
#define SHT_HIPROC 0x7fffffff
|
SHT_HIOS = 0x6fffffff,
|
||||||
#define SHT_LOUSER 0x80000000
|
SHT_LOPROC = 0x70000000,
|
||||||
#define SHT_HIUSER 0x8fffffff
|
SHT_HIPROC = 0x7fffffff,
|
||||||
|
SHT_LOUSER = 0x80000000,
|
||||||
|
SHT_HIUSER = 0x8fffffff
|
||||||
|
};
|
||||||
|
|
||||||
#define ELF32_R_SYM(i) ((i) >> 8)
|
#define ELF32_R_SYM(i) ((i) >> 8)
|
||||||
#define ELF32_R_TYPE(i) ((unsigned char)(i))
|
#define ELF32_R_TYPE(i) ((unsigned char)(i))
|
||||||
@ -63,7 +66,10 @@ typedef __INT64_TYPE__ Elf64_Sxword;
|
|||||||
|
|
||||||
#define EI_NIDENT 16
|
#define EI_NIDENT 16
|
||||||
|
|
||||||
enum DynamicArrayTags
|
#define SHN_UNDEF 0
|
||||||
|
#define SHN_ABS 0xfff1
|
||||||
|
|
||||||
|
enum DynamicTags
|
||||||
{
|
{
|
||||||
DT_NULL = 0,
|
DT_NULL = 0,
|
||||||
DT_NEEDED = 1,
|
DT_NEEDED = 1,
|
||||||
@ -287,6 +293,6 @@ typedef struct elf64_sym
|
|||||||
Elf64_Xword st_size;
|
Elf64_Xword st_size;
|
||||||
} Elf64_Sym;
|
} Elf64_Sym;
|
||||||
|
|
||||||
struct Elf64_Dyn *ELFGetDynamicTag(void *ElfFile, enum DynamicArrayTags Tag);
|
struct Elf64_Dyn *ELFGetDynamicTag(void *ElfFile, enum DynamicTags Tag);
|
||||||
|
|
||||||
#endif // !__FENNIX_LIB_ELF_LAZY_RESOLVE_H__
|
#endif // !__FENNIX_LIB_ELF_LAZY_RESOLVE_H__
|
||||||
|
@ -138,7 +138,7 @@ void PrintNL(char *String)
|
|||||||
Print("\n");
|
Print("\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
void *memcpy(void *dest, const void *src, __SIZE_TYPE__ n)
|
void *memcpy(void *dest, const void *src, size_t n)
|
||||||
{
|
{
|
||||||
uint8_t *d = dest;
|
uint8_t *d = dest;
|
||||||
const uint8_t *s = src;
|
const uint8_t *s = src;
|
||||||
@ -147,7 +147,7 @@ void *memcpy(void *dest, const void *src, __SIZE_TYPE__ n)
|
|||||||
return dest;
|
return dest;
|
||||||
}
|
}
|
||||||
|
|
||||||
void *memset(void *s, int c, __SIZE_TYPE__ n)
|
void *memset(void *s, int c, size_t n)
|
||||||
{
|
{
|
||||||
uint8_t *p = s;
|
uint8_t *p = s;
|
||||||
while (n--)
|
while (n--)
|
||||||
@ -161,7 +161,7 @@ int strcmp(const char *l, const char *r)
|
|||||||
return *(unsigned char *)l - *(unsigned char *)r;
|
return *(unsigned char *)l - *(unsigned char *)r;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct Elf64_Dyn *ELFGetDynamicTag(void *ElfFile, enum DynamicArrayTags Tag)
|
struct Elf64_Dyn *ELFGetDynamicTag(void *ElfFile, enum DynamicTags Tag)
|
||||||
{
|
{
|
||||||
Elf64_Ehdr *ELFHeader = (Elf64_Ehdr *)ElfFile;
|
Elf64_Ehdr *ELFHeader = (Elf64_Ehdr *)ElfFile;
|
||||||
|
|
||||||
@ -172,39 +172,72 @@ struct Elf64_Dyn *ELFGetDynamicTag(void *ElfFile, enum DynamicArrayTags Tag)
|
|||||||
if (ItrProgramHeader.p_type == PT_DYNAMIC)
|
if (ItrProgramHeader.p_type == PT_DYNAMIC)
|
||||||
{
|
{
|
||||||
struct Elf64_Dyn *Dynamic = (struct Elf64_Dyn *)((uint8_t *)ElfFile + ItrProgramHeader.p_offset);
|
struct Elf64_Dyn *Dynamic = (struct Elf64_Dyn *)((uint8_t *)ElfFile + ItrProgramHeader.p_offset);
|
||||||
for (__SIZE_TYPE__ i = 0; i < ItrProgramHeader.p_filesz / sizeof(struct Elf64_Dyn); i++)
|
for (size_t i = 0; i < ItrProgramHeader.p_filesz / sizeof(struct Elf64_Dyn); i++)
|
||||||
{
|
{
|
||||||
if (Dynamic[i].d_tag == Tag)
|
if (Dynamic[i].d_tag == Tag)
|
||||||
{
|
|
||||||
// debug("Found dynamic tag %d at %#lx [d_val: %#lx].", Tag, &Dynamic[i], Dynamic[i].d_un.d_val);
|
|
||||||
return &Dynamic[i];
|
return &Dynamic[i];
|
||||||
}
|
|
||||||
if (Dynamic[i].d_tag == DT_NULL)
|
if (Dynamic[i].d_tag == DT_NULL)
|
||||||
{
|
|
||||||
// debug("Reached end of dynamic tag list for tag %d.", Tag);
|
|
||||||
return (void *)0;
|
return (void *)0;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// debug("Dynamic tag %d not found.", Tag);
|
|
||||||
return (void *)0;
|
return (void *)0;
|
||||||
}
|
}
|
||||||
|
|
||||||
Elf64_Sym *ELFGetSymbol(uintptr_t ElfFile, char *SymbolName)
|
Elf64_Shdr *GetELFSheader(Elf64_Ehdr *Header)
|
||||||
{
|
{
|
||||||
struct Elf64_Dyn *symTab = ELFGetDynamicTag((void *)ElfFile, DT_SYMTAB);
|
Elf64_Off SheaderOffset = Header->e_shoff;
|
||||||
struct Elf64_Dyn *strTab = ELFGetDynamicTag((void *)ElfFile, DT_STRTAB);
|
return (Elf64_Shdr *)((uintptr_t)Header + SheaderOffset);
|
||||||
Elf64_Sym *DynSym = (Elf64_Sym *)(ElfFile + symTab->d_un.d_ptr);
|
}
|
||||||
char *dynStr = (char *)(ElfFile + strTab->d_un.d_ptr);
|
|
||||||
|
|
||||||
for (int i = 0; i < symTab->d_un.d_val; i++)
|
Elf64_Shdr *GetELFSection(Elf64_Ehdr *Header, uint64_t Index)
|
||||||
|
{
|
||||||
|
Elf64_Shdr *Sheader = GetELFSheader(Header);
|
||||||
|
return &Sheader[Index];
|
||||||
|
}
|
||||||
|
|
||||||
|
char *GetELFStringTable(Elf64_Ehdr *Header)
|
||||||
|
{
|
||||||
|
if (Header->e_shstrndx == SHN_UNDEF)
|
||||||
|
return NULL;
|
||||||
|
return (char *)Header + GetELFSection(Header, Header->e_shstrndx)->sh_offset;
|
||||||
|
}
|
||||||
|
|
||||||
|
Elf64_Sym *ELFLookupSymbol(Elf64_Ehdr *Header, const char *Name)
|
||||||
|
{
|
||||||
|
Elf64_Shdr *SymbolTable = NULL;
|
||||||
|
Elf64_Shdr *StringTable = NULL;
|
||||||
|
Elf64_Sym *Symbol = NULL;
|
||||||
|
char *String = NULL;
|
||||||
|
|
||||||
|
for (Elf64_Half i = 0; i < Header->e_shnum; i++)
|
||||||
{
|
{
|
||||||
if (strcmp(dynStr + DynSym[i].st_name, SymbolName) == 0)
|
Elf64_Shdr *shdr = GetELFSection(Header, i);
|
||||||
return &DynSym[i];
|
switch (shdr->sh_type)
|
||||||
|
{
|
||||||
|
case SHT_SYMTAB:
|
||||||
|
SymbolTable = shdr;
|
||||||
|
StringTable = GetELFSection(Header, shdr->sh_link);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
PrintNL("ELFGetSymbol: Symbol not found!");
|
|
||||||
return (Elf64_Sym *)0;
|
if (SymbolTable == NULL || StringTable == NULL)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
for (size_t i = 0; i < (SymbolTable->sh_size / sizeof(Elf64_Sym)); i++)
|
||||||
|
{
|
||||||
|
Symbol = (Elf64_Sym *)((uintptr_t)Header + SymbolTable->sh_offset + (i * sizeof(Elf64_Sym)));
|
||||||
|
String = (char *)((uintptr_t)Header + StringTable->sh_offset + Symbol->st_name);
|
||||||
|
|
||||||
|
if (strcmp(String, Name) == 0)
|
||||||
|
return (void *)Symbol;
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
void (*ELF_LAZY_RESOLVE_MAIN(struct LibAddressCollection *Info, long RelIndex))()
|
void (*ELF_LAZY_RESOLVE_MAIN(struct LibAddressCollection *Info, long RelIndex))()
|
||||||
@ -250,22 +283,6 @@ void (*ELF_LAZY_RESOLVE_MAIN(struct LibAddressCollection *Info, long RelIndex))(
|
|||||||
app_BaseAddress = MIN(app_BaseAddress, ItrProgramHeader.p_vaddr);
|
app_BaseAddress = MIN(app_BaseAddress, ItrProgramHeader.p_vaddr);
|
||||||
}
|
}
|
||||||
|
|
||||||
ltoa((long)CurLib->MemoryImage, DbgBuff, 16);
|
|
||||||
Print("lib:mmImg 0x");
|
|
||||||
PrintNL(DbgBuff);
|
|
||||||
|
|
||||||
ltoa((long)CurLib->ParentMemoryImage, DbgBuff, 16);
|
|
||||||
Print("lib:mmImg 0x");
|
|
||||||
PrintNL(DbgBuff);
|
|
||||||
|
|
||||||
ltoa(lib_BaseAddress, DbgBuff, 16);
|
|
||||||
Print("lib:BAddr 0x");
|
|
||||||
PrintNL(DbgBuff);
|
|
||||||
|
|
||||||
ltoa(app_BaseAddress, DbgBuff, 16);
|
|
||||||
Print("lib:BAddr 0x");
|
|
||||||
PrintNL(DbgBuff);
|
|
||||||
|
|
||||||
struct Elf64_Dyn *lib_JmpRel = ELFGetDynamicTag((void *)CurLib->ElfFile, DT_JMPREL);
|
struct Elf64_Dyn *lib_JmpRel = ELFGetDynamicTag((void *)CurLib->ElfFile, DT_JMPREL);
|
||||||
struct Elf64_Dyn *lib_SymTab = ELFGetDynamicTag((void *)CurLib->ElfFile, DT_SYMTAB);
|
struct Elf64_Dyn *lib_SymTab = ELFGetDynamicTag((void *)CurLib->ElfFile, DT_SYMTAB);
|
||||||
struct Elf64_Dyn *lib_StrTab = ELFGetDynamicTag((void *)CurLib->ElfFile, DT_STRTAB);
|
struct Elf64_Dyn *lib_StrTab = ELFGetDynamicTag((void *)CurLib->ElfFile, DT_STRTAB);
|
||||||
@ -339,7 +356,12 @@ void (*ELF_LAZY_RESOLVE_MAIN(struct LibAddressCollection *Info, long RelIndex))(
|
|||||||
Print("SymName: ");
|
Print("SymName: ");
|
||||||
PrintNL(SymName);
|
PrintNL(SymName);
|
||||||
|
|
||||||
Elf64_Sym *LibSym = ELFGetSymbol(CurLib->ElfFile, SymName);
|
Elf64_Sym *LibSym = ELFLookupSymbol(CurLib->ElfFile, SymName);
|
||||||
|
|
||||||
|
Print("LibSym: 0x");
|
||||||
|
ltoa((long)LibSym, DbgBuff, 16);
|
||||||
|
PrintNL(DbgBuff);
|
||||||
|
|
||||||
if (LibSym)
|
if (LibSym)
|
||||||
{
|
{
|
||||||
*GOTEntry = (Elf64_Addr)(CurLib->MemoryImage + LibSym->st_value);
|
*GOTEntry = (Elf64_Addr)(CurLib->MemoryImage + LibSym->st_value);
|
||||||
@ -351,6 +373,7 @@ void (*ELF_LAZY_RESOLVE_MAIN(struct LibAddressCollection *Info, long RelIndex))(
|
|||||||
Lock = 0;
|
Lock = 0;
|
||||||
return (void (*)()) * GOTEntry;
|
return (void (*)()) * GOTEntry;
|
||||||
}
|
}
|
||||||
|
PrintNL("Not found in lib");
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user