#include <e32cons.h>
#include <e32std.h>
#include <f32file.h>
#include "e32boot.h"
#include "elf.h"
#include "netbsd.h"
NetBSD *
NetBSD::New(const TDesC &aFilename)
{
NetBSD *netbsd = NULL;
RFs fsSession;
RFile file;
TInt size;
union {
Elf32_Ehdr elf;
} hdr;
User::LeaveIfError(fsSession.Connect());
User::LeaveIfError(file.Open(fsSession, aFilename, EFileRead));
User::LeaveIfError(file.Size(size));
TPtr hdrBuf((TUint8 *)&hdr, sizeof(hdr));
User::LeaveIfError(file.Read(hdrBuf));
if (Mem::Compare((TUint8 *)hdr.elf.e_ident, SELFMAG,
(TUint8 *)ELFMAG, SELFMAG) == 0) {
netbsd = new (ELeave) ELF(size);
} else
User::Leave(KErrNotSupported);
TInt pos = 0;
User::LeaveIfError(file.Seek(ESeekStart, pos));
TPtr fileBuf(netbsd->Buffer, size);
User::LeaveIfError(file.Read(fileBuf));
if (fileBuf.Length() != size)
User::Leave(KErrNotFound);
file.Close();
fsSession.Close();
netbsd->LoadDescriptor =
(struct loaddesc *)PAGE_ALIGN(User::AllocL(ALIGN_SAFE_PAGE_SIZE));
return netbsd;
}
NetBSD *
NetBSD::New(const TDesC &aFilename, const TDesC &aArgs)
{
NetBSD *netbsd = New(aFilename);
netbsd->Args = &aArgs;
return netbsd;
}
void
ELF::ParseHeader(void)
{
struct loaddesc *loaddesc = LoadDescriptor;
Elf32_Ehdr ehdr;
Elf32_Phdr *phdr = NULL;
int PhdrSize, i;
Mem::Copy(&ehdr, Buffer, sizeof(ehdr));
PhdrSize = sizeof(Elf32_Phdr) * ehdr.e_phnum;
phdr = (Elf32_Phdr *) new (ELeave) TUint8[PhdrSize];
Mem::Copy(phdr, Buffer + ehdr.e_phoff, PhdrSize);
for (i = 0; i < ehdr.e_phnum; i++) {
if (phdr[i].p_type != PT_LOAD ||
(phdr[i].p_flags & (PF_W | PF_X)) == 0)
continue;
loaddesc->addr = VTOP(phdr[i].p_vaddr);
loaddesc->offset = phdr[i].p_offset;
loaddesc->size = phdr[i].p_filesz;
loaddesc++;
}
loaddesc->addr = 0xffffffff;
loaddesc->offset = 0xffffffff;
loaddesc->size = 0xffffffff;
EntryPoint = ehdr.e_entry;
}