Fix driver implementation

This commit is contained in:
EnderIce2
2024-07-07 03:14:54 +03:00
parent 3e5177d375
commit 51ea074b60
29 changed files with 3069 additions and 1510 deletions

View File

@ -18,11 +18,13 @@
#include <driver.hpp>
#include <interface/driver.h>
#include <interface/input.h>
#include <memory.hpp>
#include <ints.hpp>
#include <task.hpp>
#include <printf.h>
#include <exec.hpp>
#include <rand.hpp>
#include <cwalk.h>
#include <md5.h>
@ -56,32 +58,30 @@ namespace Driver
continue;
}
Memory::VirtualMemoryArea *dVma = new Memory::VirtualMemoryArea(thisProcess->PageTable);
DriverObject drvObj = {.BaseAddress = 0,
.EntryPoint = 0,
.vma = new Memory::VirtualMemoryArea(thisProcess->PageTable),
.Path = drvNode->Path,
.InterruptHandlers = new std::unordered_map<uint8_t, void *>(),
.DeviceOperations = new std::unordered_map<dev_t, DriverHandlers>(),
.ID = DriverIDCounter};
uintptr_t EntryPoint, BaseAddress;
int err = this->LoadDriverFile(EntryPoint, BaseAddress, dVma, drvNode);
int err = this->LoadDriverFile(drvObj, drvNode);
debug("err = %d (%s)", err, strerror(err));
if (err != 0)
{
error("Failed to load driver %s: %s",
drvNode->Path.c_str(), strerror(err));
delete dVma;
delete drvObj.vma;
delete drvObj.InterruptHandlers;
delete drvObj.DeviceOperations;
continue;
}
Drivers[DriverIDCounter++] = {
.BaseAddress = BaseAddress,
.EntryPoint = EntryPoint,
.vma = dVma,
.Path = drvNode->Path,
.InterruptHandlers = new std::unordered_map<uint8_t, void *>};
debug("gdb: \"0x%lX\" %s", drvObj.BaseAddress, drvObj.Name);
dev_t countr = DriverIDCounter - 1;
const char *drvName;
size_t drvNameLen;
cwk_path_get_basename(drvNode->Path.c_str(), &drvName, &drvNameLen);
strncpy(Drivers[countr].Name, drvName, sizeof(Drivers[countr].Name));
Drivers.insert({DriverIDCounter++, drvObj});
}
}
@ -95,66 +95,54 @@ namespace Driver
foreach (auto &var in Drivers)
{
DriverObject *Drv = &var.second;
size_t dapiPgs = TO_PAGES(sizeof(__driverAPI));
__driverAPI *dApi = (__driverAPI *)Drv->vma->RequestPages(dapiPgs);
debug("Driver API at %#lx-%#lx", dApi, dApi + sizeof(__driverAPI));
DriverObject &Drv = var.second;
fixme("api version");
dApi->APIVersion.Major = 0;
dApi->APIVersion.Minor = 0;
dApi->APIVersion.Patch = 0;
dApi->MajorID = var.first;
dApi->Base = Drv->BaseAddress;
PopulateDriverAPI(dApi);
debug("Calling driver %s at %#lx", Drv->Path.c_str(), Drv->EntryPoint);
int (*DrvInit)(__driverAPI *) = (int (*)(__driverAPI *))Drv->EntryPoint;
Drv->ErrorCode = DrvInit(dApi);
if (Drv->ErrorCode < 0)
debug("Calling driver %s at %#lx", Drv.Path.c_str(), Drv.EntryPoint);
int (*DrvInit)(dev_t) = (int (*)(dev_t))Drv.EntryPoint;
Drv.ErrorCode = DrvInit(Drv.ID);
if (Drv.ErrorCode < 0)
{
KPrint("FATAL: _start() failed for %s: %s",
Drv->Name, strerror(Drv->ErrorCode));
Drv.Name, strerror(Drv.ErrorCode));
error("Failed to load driver %s: %s",
Drv->Path.c_str(), strerror(Drv->ErrorCode));
Drv.Path.c_str(), strerror(Drv.ErrorCode));
Drv->vma->FreeAllPages();
Drv.vma->FreeAllPages();
continue;
}
KPrint("Loading driver %s", Drv->Name);
KPrint("Loading driver %s", Drv.Name);
debug("Calling Probe()=%#lx on driver %s",
Drv->Probe, Drv->Path.c_str());
Drv->ErrorCode = Drv->Probe();
if (Drv->ErrorCode < 0)
Drv.Probe, Drv.Path.c_str());
Drv.ErrorCode = Drv.Probe();
if (Drv.ErrorCode < 0)
{
KPrint("Probe() failed for %s: %s",
Drv->Name, strerror(Drv->ErrorCode));
Drv.Name, strerror(Drv.ErrorCode));
error("Failed to probe driver %s: %s",
Drv->Path.c_str(), strerror(Drv->ErrorCode));
Drv.Path.c_str(), strerror(Drv.ErrorCode));
Drv->vma->FreeAllPages();
Drv.vma->FreeAllPages();
continue;
}
debug("Calling driver Entry()=%#lx function on driver %s",
Drv->Entry, Drv->Path.c_str());
Drv->ErrorCode = Drv->Entry();
if (Drv->ErrorCode < 0)
Drv.Entry, Drv.Path.c_str());
Drv.ErrorCode = Drv.Entry();
if (Drv.ErrorCode < 0)
{
KPrint("Entry() failed for %s: %s",
Drv->Name, strerror(Drv->ErrorCode));
Drv.Name, strerror(Drv.ErrorCode));
error("Failed to initialize driver %s: %s",
Drv->Path.c_str(), strerror(Drv->ErrorCode));
Drv.Path.c_str(), strerror(Drv.ErrorCode));
Drv->vma->FreeAllPages();
Drv.vma->FreeAllPages();
continue;
}
debug("Loaded driver %s", Drv->Path.c_str());
Drv->Initialized = true;
debug("Loaded driver %s", Drv.Path.c_str());
Drv.Initialized = true;
}
}
@ -182,9 +170,6 @@ namespace Driver
}
Drv->InterruptHandlers->clear();
}
delete Drv->vma, Drv->vma = nullptr;
delete Drv->InterruptHandlers, Drv->InterruptHandlers = nullptr;
}
Drivers.clear();
}
@ -212,180 +197,229 @@ namespace Driver
}
}
int Manager::LoadDriverFile(uintptr_t &EntryPoint, uintptr_t &BaseAddress,
Memory::VirtualMemoryArea *dVma, FileNode *rDrv)
int Manager::LoadDriverFile(DriverObject &Drv, FileNode *File)
{
Elf64_Ehdr ELFHeader;
rDrv->Read(&ELFHeader, sizeof(Elf64_Ehdr), 0);
if (ELFHeader.e_type != ET_DYN)
trace("Loading driver %s in memory", File->Name.c_str());
Elf_Ehdr ELFHeader{};
File->Read(&ELFHeader, sizeof(Elf_Ehdr), 0);
AssertReturnError(ELFHeader.e_ident[EI_CLASS] == ELFCLASS64, -ENOEXEC);
AssertReturnError(ELFHeader.e_ident[EI_DATA] == ELFDATA2LSB, -ENOEXEC);
AssertReturnError(ELFHeader.e_ident[EI_OSABI] == ELFOSABI_SYSV, -ENOEXEC);
AssertReturnError(ELFHeader.e_ident[EI_ABIVERSION] == 0, -ENOEXEC);
AssertReturnError(ELFHeader.e_type == ET_DYN, -ENOEXEC);
AssertReturnError(ELFHeader.e_machine == EM_X86_64, -ENOEXEC);
AssertReturnError(ELFHeader.e_version == EV_CURRENT, -ENOEXEC);
AssertReturnError(ELFHeader.e_entry != 0x0, -ENOEXEC);
AssertReturnError(ELFHeader.e_shstrndx != SHN_UNDEF, -ENOEXEC);
Drv.EntryPoint = ELFHeader.e_entry;
size_t segSize = 0;
Elf_Phdr phdr{};
for (Elf_Half i = 0; i < ELFHeader.e_phnum; i++)
{
error("Driver %s is not a shared object", rDrv->Path.c_str());
return -ENOEXEC;
}
trace("Loading driver %s in memory", rDrv->Name.c_str());
BaseAddress = 0;
{
Elf64_Phdr ProgramBreakHeader{};
Elf64_Phdr ProgramHeader;
size_t SegmentsSize = 0;
for (Elf64_Half i = 0; i < ELFHeader.e_phnum; i++)
File->Read(&phdr, sizeof(Elf_Phdr), ELFHeader.e_phoff + (i * sizeof(Elf_Phdr)));
if (phdr.p_type == PT_LOAD || phdr.p_type == PT_DYNAMIC)
{
rDrv->Read(&ProgramHeader, sizeof(Elf64_Phdr), ELFHeader.e_phoff + (i * sizeof(Elf64_Phdr)));
if (ProgramHeader.p_type == PT_LOAD ||
ProgramHeader.p_type == PT_DYNAMIC)
{
if (SegmentsSize < ProgramHeader.p_vaddr + ProgramHeader.p_memsz)
{
SegmentsSize = ProgramHeader.p_vaddr + ProgramHeader.p_memsz;
ProgramBreakHeader = ProgramHeader;
}
}
if (segSize < phdr.p_vaddr + phdr.p_memsz)
segSize = phdr.p_vaddr + phdr.p_memsz;
continue;
}
debug("SegmentsSize: %#lx", SegmentsSize);
/* TODO: Check if this is correct and/or it needs more
complex calculations & allocations */
void *SegmentsAddress = dVma->RequestPages(TO_PAGES(SegmentsSize) + 1);
BaseAddress = (uintptr_t)SegmentsAddress;
debug("BaseAddress: %#lx, End: %#lx (%#lx)", BaseAddress,
BaseAddress + FROM_PAGES(TO_PAGES(SegmentsSize)),
SegmentsSize);
for (Elf64_Half i = 0; i < ELFHeader.e_phnum; i++)
if (phdr.p_type == PT_INTERP)
{
rDrv->Read(&ProgramHeader, sizeof(Elf64_Phdr), ELFHeader.e_phoff + (i * sizeof(Elf64_Phdr)));
switch (ProgramHeader.p_type)
char interp[17];
File->Read(interp, sizeof(interp), phdr.p_offset);
if (strncmp(interp, "/boot/fennix.elf", sizeof(interp)) != 0)
{
case PT_LOAD:
{
/* Because this is ET_DYN, we can load the segments
anywhere we want. */
uintptr_t SegmentDestination = BaseAddress + ProgramHeader.p_vaddr;
if (ProgramHeader.p_memsz == 0)
continue;
debug("Copying PT_LOAD to %#lx-%#lx (%ld file bytes, %ld mem bytes)",
SegmentDestination, SegmentDestination + ProgramHeader.p_memsz,
ProgramHeader.p_filesz, ProgramHeader.p_memsz);
if (ProgramHeader.p_filesz > 0)
{
rDrv->Read(SegmentDestination, ProgramHeader.p_filesz, ProgramHeader.p_offset);
}
if (ProgramHeader.p_memsz - ProgramHeader.p_filesz > 0)
{
void *zAddr = (void *)(SegmentDestination + ProgramHeader.p_filesz);
memset(zAddr, 0, ProgramHeader.p_memsz - ProgramHeader.p_filesz);
}
break;
}
case PT_DYNAMIC:
{
/* PT_DYNAMIC contains the dynamic linking information for the
executable or shared library. */
uintptr_t DynamicSegmentDestination = BaseAddress + ProgramHeader.p_vaddr;
if (ProgramHeader.p_memsz == 0)
continue;
debug("Copying PT_DYNAMIC to %#lx-%#lx (%ld file bytes, %ld mem bytes)",
DynamicSegmentDestination, DynamicSegmentDestination + ProgramHeader.p_memsz,
ProgramHeader.p_filesz, ProgramHeader.p_memsz);
if (ProgramHeader.p_filesz > 0)
{
rDrv->Read(DynamicSegmentDestination, ProgramHeader.p_filesz, ProgramHeader.p_offset);
}
if (ProgramHeader.p_memsz - ProgramHeader.p_filesz > 0)
{
void *zAddr = (void *)(DynamicSegmentDestination + ProgramHeader.p_filesz);
memset(zAddr, 0, ProgramHeader.p_memsz - ProgramHeader.p_filesz);
}
break;
}
default:
{
fixme("Unhandled program header type: %#lx",
ProgramHeader.p_type);
break;
}
error("Interpreter is not /boot/fennix.elf");
return -ENOEXEC;
}
}
}
debug("segSize: %ld", segSize);
Elf64_Phdr ProgramHeader;
for (Elf64_Half i = 0; i < ELFHeader.e_phnum; i++)
Drv.BaseAddress = (uintptr_t)Drv.vma->RequestPages(TO_PAGES(segSize) + 1);
Drv.EntryPoint += Drv.BaseAddress;
debug("Driver %s has entry point %#lx and base %#lx",
File->Name.c_str(), Drv.EntryPoint, Drv.BaseAddress);
Elf64_Shdr sht_strtab{};
Elf64_Shdr sht_symtab{};
Elf_Shdr shstrtab{};
Elf_Shdr shdr{};
__DriverInfo driverInfo{};
File->Read(&shstrtab, sizeof(Elf_Shdr), ELFHeader.e_shoff + (ELFHeader.e_shstrndx * ELFHeader.e_shentsize));
for (Elf_Half i = 0; i < ELFHeader.e_shnum; i++)
{
rDrv->Read(&ProgramHeader, sizeof(Elf64_Phdr), ELFHeader.e_phoff + (i * sizeof(Elf64_Phdr)));
if (i == ELFHeader.e_shstrndx)
continue;
if (ProgramHeader.p_type == PT_DYNAMIC)
File->Read(&shdr, ELFHeader.e_shentsize, ELFHeader.e_shoff + (i * ELFHeader.e_shentsize));
switch (shdr.sh_type)
{
Elf64_Dyn *Dynamic = (Elf64_Dyn *)(BaseAddress + ProgramHeader.p_vaddr);
Elf64_Dyn *RelaSize = nullptr;
Elf64_Dyn *PltRelSize = nullptr;
case SHT_PROGBITS:
break;
case SHT_SYMTAB:
sht_symtab = shdr;
continue;
case SHT_STRTAB:
sht_strtab = shdr;
continue;
case SHT_NULL:
default:
continue;
}
while (Dynamic->d_tag != DT_NULL)
char symName[16];
File->Read(symName, sizeof(symName), shstrtab.sh_offset + shdr.sh_name);
if (strcmp(symName, ".driver.info") != 0)
continue;
File->Read(&driverInfo, sizeof(__DriverInfo), shdr.sh_offset);
/* Perform relocations */
driverInfo.Name = (const char *)(Drv.BaseAddress + (uintptr_t)driverInfo.Name);
driverInfo.Description = (const char *)(Drv.BaseAddress + (uintptr_t)driverInfo.Description);
driverInfo.Author = (const char *)(Drv.BaseAddress + (uintptr_t)driverInfo.Author);
driverInfo.License = (const char *)(Drv.BaseAddress + (uintptr_t)driverInfo.License);
}
for (size_t h = 0; h < (sht_symtab.sh_size / sizeof(Elf64_Sym)); h++)
{
Elf64_Sym symEntry{};
uintptr_t symOffset = sht_symtab.sh_offset + (h * sizeof(Elf64_Sym));
File->Read(&symEntry, sizeof(Elf64_Sym), symOffset);
if (symEntry.st_name == 0)
continue;
char symName[16];
File->Read(symName, sizeof(symName), sht_strtab.sh_offset + symEntry.st_name);
switch (symEntry.st_shndx)
{
case SHN_UNDEF:
case SHN_ABS:
case SHN_LOPROC /* , SHN_LORESERVE and SHN_BEFORE */:
case SHN_AFTER:
case SHN_HIPROC:
case SHN_COMMON:
case SHN_HIRESERVE:
break;
default:
{
debug("shndx: %d", symEntry.st_shndx);
if (strcmp(symName, "DriverEntry") == 0)
Drv.Entry = (int (*)())(Drv.BaseAddress + symEntry.st_value);
else if (strcmp(symName, "DriverFinal") == 0)
Drv.Final = (int (*)())(Drv.BaseAddress + symEntry.st_value);
else if (strcmp(symName, "DriverPanic") == 0)
Drv.Panic = (int (*)())(Drv.BaseAddress + symEntry.st_value);
else if (strcmp(symName, "DriverProbe") == 0)
Drv.Probe = (int (*)())(Drv.BaseAddress + symEntry.st_value);
debug("Found %s at %#lx", symName, symEntry.st_value);
break;
}
}
}
for (Elf_Half i = 0; i < ELFHeader.e_phnum; i++)
{
File->Read(&phdr, sizeof(Elf_Phdr), ELFHeader.e_phoff + (i * sizeof(Elf_Phdr)));
switch (phdr.p_type)
{
case PT_LOAD:
case PT_DYNAMIC:
{
if (phdr.p_memsz == 0)
continue;
uintptr_t dest = Drv.BaseAddress + phdr.p_vaddr;
debug("Copying PHDR %#lx to %#lx-%#lx (%ld file bytes, %ld mem bytes)",
phdr.p_type, dest, dest + phdr.p_memsz,
phdr.p_filesz, phdr.p_memsz);
if (phdr.p_filesz > 0)
File->Read(dest, phdr.p_filesz, phdr.p_offset);
if (phdr.p_memsz - phdr.p_filesz > 0)
{
switch (Dynamic->d_tag)
{
case DT_RELASZ:
RelaSize = Dynamic;
debug("RELA Size: %d", RelaSize->d_un.d_val / sizeof(Elf64_Rela));
void *zero = (void *)(dest + phdr.p_filesz);
memset(zero, 0, phdr.p_memsz - phdr.p_filesz);
}
break;
if (phdr.p_type != PT_DYNAMIC)
break;
Elf64_Dyn *dyn = (Elf64_Dyn *)(Drv.BaseAddress + phdr.p_vaddr);
Elf64_Dyn *relaSize = nullptr;
Elf64_Dyn *pltrelSize = nullptr;
while (dyn->d_tag != DT_NULL)
{
switch (dyn->d_tag)
{
case DT_PLTRELSZ:
PltRelSize = Dynamic;
debug("PLTRELSZ: %d", PltRelSize->d_un.d_val / sizeof(Elf64_Rela));
{
pltrelSize = dyn;
break;
}
case DT_PLTGOT:
{
Elf_Addr *got = (Elf_Addr *)(Drv.BaseAddress + dyn->d_un.d_ptr);
got[1] = 0;
got[2] = 0;
break;
}
case DT_RELASZ:
{
relaSize = dyn;
break;
}
case DT_PLTREL:
{
AssertReturnError(dyn->d_un.d_val == DT_RELA, -ENOEXEC);
break;
}
default:
break;
}
Dynamic++;
dyn++;
}
Dynamic = (Elf64_Dyn *)(BaseAddress + ProgramHeader.p_vaddr);
while (Dynamic->d_tag != DT_NULL)
dyn = (Elf64_Dyn *)(Drv.BaseAddress + phdr.p_vaddr);
while (dyn->d_tag != DT_NULL)
{
switch (Dynamic->d_tag)
switch (dyn->d_tag)
{
case DT_RELA: /* .rela.dyn */
{
if (!RelaSize)
{
error("DT_RELASZ is not set");
break;
}
AssertReturnError(relaSize != nullptr, -ENOEXEC);
Elf64_Rela *Rela = (Elf64_Rela *)(BaseAddress + Dynamic->d_un.d_ptr);
for (size_t i = 0; i < (RelaSize->d_un.d_val / sizeof(Elf64_Rela)); i++)
Elf64_Rela *rela = (Elf64_Rela *)(Drv.BaseAddress + dyn->d_un.d_ptr);
for (size_t i = 0; i < (relaSize->d_un.d_val / sizeof(Elf64_Rela)); i++)
{
Elf64_Rela *r = &Rela[i];
uintptr_t *RelocationAddress = (uintptr_t *)(BaseAddress + r->r_offset);
uintptr_t RelocationTarget = 0;
Elf64_Rela *r = &rela[i];
uintptr_t *reloc = (uintptr_t *)(Drv.BaseAddress + r->r_offset);
uintptr_t relocTarget = 0;
switch (ELF64_R_TYPE(r->r_info))
{
case R_X86_64_GLOB_DAT:
case R_X86_64_JUMP_SLOT:
{
RelocationTarget = BaseAddress;
relocTarget = Drv.BaseAddress;
break;
}
case R_X86_64_RELATIVE:
case R_X86_64_64:
{
RelocationTarget = BaseAddress + r->r_addend;
relocTarget = Drv.BaseAddress + r->r_addend;
break;
}
default:
@ -396,53 +430,40 @@ namespace Driver
}
}
*RelocationAddress = RelocationTarget;
*reloc = relocTarget;
debug("Relocated %#lx to %#lx",
r->r_offset, *RelocationAddress);
r->r_offset, *reloc);
}
break;
}
case DT_PLTREL:
{
if (Dynamic->d_un.d_val != DT_RELA)
error("DT_PLTREL is not DT_RELA");
break;
}
case DT_JMPREL: /* .rela.plt */
{
if (!PltRelSize)
{
error("DT_PLTRELSZ is not set");
break;
}
AssertReturnError(pltrelSize != nullptr, -ENOEXEC);
std::vector<Elf64_Dyn> SymTab = Execute::ELFGetDynamicTag_x86_64(rDrv, DT_SYMTAB);
std::vector<Elf64_Dyn> StrTab = Execute::ELFGetDynamicTag_x86_64(rDrv, DT_STRTAB);
Elf64_Sym *_SymTab = (Elf64_Sym *)((uintptr_t)BaseAddress + SymTab[0].d_un.d_ptr);
char *DynStr = (char *)((uintptr_t)BaseAddress + StrTab[0].d_un.d_ptr);
UNUSED(DynStr);
std::vector<Elf64_Dyn> symtab = Execute::ELFGetDynamicTag_x86_64(File, DT_SYMTAB);
Elf64_Sym *symbols = (Elf64_Sym *)((uintptr_t)Drv.BaseAddress + symtab[0].d_un.d_ptr);
Elf64_Rela *Rela = (Elf64_Rela *)(BaseAddress + Dynamic->d_un.d_ptr);
for (size_t i = 0; i < (PltRelSize->d_un.d_val / sizeof(Elf64_Rela)); i++)
std::vector<Elf64_Dyn> StrTab = Execute::ELFGetDynamicTag_x86_64(File, DT_STRTAB);
char *DynStr = (char *)((uintptr_t)Drv.BaseAddress + StrTab[0].d_un.d_ptr);
Elf64_Rela *rela = (Elf64_Rela *)(Drv.BaseAddress + dyn->d_un.d_ptr);
for (size_t i = 0; i < (pltrelSize->d_un.d_val / sizeof(Elf64_Rela)); i++)
{
Elf64_Rela *r = &Rela[i];
uintptr_t *RelocationAddress = (uintptr_t *)(BaseAddress + r->r_offset);
uintptr_t RelocationTarget = 0;
Elf64_Rela *r = &rela[i];
uintptr_t *reloc = (uintptr_t *)(Drv.BaseAddress + r->r_offset);
switch (ELF64_R_TYPE(r->r_info))
{
case R_X86_64_JUMP_SLOT:
{
Elf64_Xword SymIndex = ELF64_R_SYM(r->r_info);
Elf64_Sym *Sym = _SymTab + SymIndex;
Elf64_Xword symIndex = ELF64_R_SYM(r->r_info);
Elf64_Sym *sym = symbols + symIndex;
#ifdef DEBUG
const char *SymbolName = DynStr + Sym->st_name;
debug("Symbol %s at %#lx", SymbolName, Sym->st_value);
#endif
const char *symName = DynStr + sym->st_name;
debug("Resolving symbol %s", symName);
RelocationTarget = BaseAddress + Sym->st_value;
*reloc = (uintptr_t)GetSymbolByName(symName, driverInfo.Version.APIVersion);
break;
}
default:
@ -452,96 +473,48 @@ namespace Driver
break;
}
}
*RelocationAddress = RelocationTarget;
debug("Relocated %#lx to %#lx",
r->r_offset, *RelocationAddress);
}
break;
}
case DT_SYMTAB:
{
fixme("DT_SYMTAB");
case DT_PLTGOT:
case DT_PLTRELSZ:
case DT_RELASZ:
case DT_PLTREL:
break;
std::vector<Elf64_Dyn> SymTab = Execute::ELFGetDynamicTag_x86_64(rDrv, DT_SYMTAB);
std::vector<Elf64_Dyn> StrTab = Execute::ELFGetDynamicTag_x86_64(rDrv, DT_STRTAB);
Elf64_Sym *_SymTab = (Elf64_Sym *)((uintptr_t)BaseAddress + SymTab[0].d_un.d_ptr);
char *DynStr = (char *)((uintptr_t)BaseAddress + StrTab[0].d_un.d_ptr);
UNUSED(DynStr);
size_t symtabEntrySize = 0;
Elf64_Dyn *entrySizeDyn = Dynamic;
while (entrySizeDyn->d_tag != DT_NULL)
{
if (entrySizeDyn->d_tag == DT_SYMENT)
{
symtabEntrySize = entrySizeDyn->d_un.d_val;
break;
}
entrySizeDyn++;
}
if (symtabEntrySize == 0)
{
fixme("No information about symbol entry size");
break;
}
size_t numSymbols = Dynamic->d_un.d_val / symtabEntrySize;
for (size_t i = 0; i < numSymbols; i++)
{
Elf64_Sym *s = &_SymTab[i];
if (s->st_name == 0)
continue;
#ifdef DEBUG
const char *SymbolName = (const char *)(DynStr + s->st_name);
debug("%d: Symbol %s at %#lx", i, SymbolName, s->st_value);
#endif
/** TODO: search for symbols and link */
/** good use but it will not work only
* if we specify to default visibility but
* this will create more issues :/ */
// if (strcmp(SymbolName, "DriverProbe") == 0)
// {
// Drivers[DriverIDCounter].Probe = (int (*)())(BaseAddress + s->st_value);
// debug("Found probe function at %#lx", Drivers[DriverIDCounter].Probe);
// }
}
break;
}
default:
{
fixme("Unhandled dynamic tag: %#lx",
Dynamic->d_tag);
fixme("Unhandled dynamic tag: %#lx", dyn->d_tag);
break;
}
}
Dynamic++;
dyn++;
}
break;
}
case PT_PHDR:
case PT_INTERP:
break;
default:
{
fixme("Unhandled program header type: %#lx", phdr.p_type);
break;
}
}
}
EntryPoint = ELFHeader.e_entry;
EntryPoint += BaseAddress;
AssertReturnError(driverInfo.Name != nullptr, -EFAULT);
strncpy(Drv.Name, driverInfo.Name, sizeof(Drv.Name));
strncpy(Drv.Description, driverInfo.Description, sizeof(Drv.Description));
strncpy(Drv.Author, driverInfo.Author, sizeof(Drv.Author));
Drv.Version.Major = driverInfo.Version.Major;
Drv.Version.Minor = driverInfo.Version.Minor;
Drv.Version.Patch = driverInfo.Version.Patch;
strncpy(Drv.License, driverInfo.License, sizeof(Drv.License));
debug("Driver %s has entry point %#lx and base %#lx",
rDrv->Path.c_str(), EntryPoint, BaseAddress);
/* FIXME: Do not add to the KernelSymbolTable! */
// Memory::SmartHeap sh(rDrv->Size);
// rDrv->seek(0, SEEK_SET);
// rDrv->read((uint8_t *)sh.Get(), rDrv->Size);
// KernelSymbolTable->AppendSymbols((uintptr_t)sh.Get(), BaseAddress);
return 0;
}
Manager::Manager()
{
}
Manager::Manager() { this->InitializeDaemonFS(); }
Manager::~Manager()
{