xref: /netbsd/sys/arch/epoc32/stand/e32boot/exe/netbsd.cpp (revision 781c2fb3)
1*781c2fb3Skiyohara /*	$NetBSD: netbsd.cpp,v 1.2 2013/06/20 13:36:48 kiyohara Exp $	*/
268122621Skiyohara /*
368122621Skiyohara  * Copyright (c) 2012 KIYOHARA Takashi
468122621Skiyohara  * All rights reserved.
568122621Skiyohara  *
668122621Skiyohara  * Redistribution and use in source and binary forms, with or without
768122621Skiyohara  * modification, are permitted provided that the following conditions
868122621Skiyohara  * are met:
968122621Skiyohara  * 1. Redistributions of source code must retain the above copyright
1068122621Skiyohara  *    notice, this list of conditions and the following disclaimer.
1168122621Skiyohara  * 2. Redistributions in binary form must reproduce the above copyright
1268122621Skiyohara  *    notice, this list of conditions and the following disclaimer in the
1368122621Skiyohara  *    documentation and/or other materials provided with the distribution.
1468122621Skiyohara  *
1568122621Skiyohara  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
1668122621Skiyohara  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
1768122621Skiyohara  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
1868122621Skiyohara  * DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
1968122621Skiyohara  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
2068122621Skiyohara  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
2168122621Skiyohara  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2268122621Skiyohara  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
2368122621Skiyohara  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
2468122621Skiyohara  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
2568122621Skiyohara  * POSSIBILITY OF SUCH DAMAGE.
2668122621Skiyohara  */
2768122621Skiyohara #include <e32cons.h>
2868122621Skiyohara #include <e32std.h>
2968122621Skiyohara #include <f32file.h>
3068122621Skiyohara 
3168122621Skiyohara #include "e32boot.h"
3268122621Skiyohara #include "elf.h"
3368122621Skiyohara #include "netbsd.h"
3468122621Skiyohara 
3568122621Skiyohara 
3668122621Skiyohara NetBSD *
3768122621Skiyohara NetBSD::New(const TDesC &aFilename)
3868122621Skiyohara {
3968122621Skiyohara 	NetBSD *netbsd = NULL;
4068122621Skiyohara 	RFs fsSession;
4168122621Skiyohara 	RFile file;
4268122621Skiyohara 	TInt size;
4368122621Skiyohara 	union {
4468122621Skiyohara 		Elf32_Ehdr elf;
4568122621Skiyohara 	} hdr;
4668122621Skiyohara 
4768122621Skiyohara 	/* Connect to FileServer Session */
4868122621Skiyohara 	User::LeaveIfError(fsSession.Connect());
4968122621Skiyohara 
5068122621Skiyohara 	User::LeaveIfError(file.Open(fsSession, aFilename, EFileRead));
5168122621Skiyohara 	User::LeaveIfError(file.Size(size));
5268122621Skiyohara 
5368122621Skiyohara 	TPtr hdrBuf((TUint8 *)&hdr, sizeof(hdr));
5468122621Skiyohara 	User::LeaveIfError(file.Read(hdrBuf));
5568122621Skiyohara 	/* Currently support is ELF only. */
5668122621Skiyohara 	if (Mem::Compare((TUint8 *)hdr.elf.e_ident, SELFMAG,
5768122621Skiyohara 					(TUint8 *)ELFMAG, SELFMAG) == 0) {
5868122621Skiyohara 		netbsd = new (ELeave) ELF(size);
5968122621Skiyohara 	} else
6068122621Skiyohara 		User::Leave(KErrNotSupported);
6168122621Skiyohara 	TInt pos = 0;
6268122621Skiyohara 	User::LeaveIfError(file.Seek(ESeekStart, pos));
6368122621Skiyohara 
6468122621Skiyohara 	TPtr fileBuf(netbsd->Buffer, size);
6568122621Skiyohara 	User::LeaveIfError(file.Read(fileBuf));
6668122621Skiyohara 	if (fileBuf.Length() != size)
6768122621Skiyohara 		User::Leave(KErrNotFound);
6868122621Skiyohara 	file.Close();
6968122621Skiyohara 
7068122621Skiyohara 	/* Close FileServer Session */
7168122621Skiyohara 	fsSession.Close();
7268122621Skiyohara 
7368122621Skiyohara 	netbsd->LoadDescriptor =
7468122621Skiyohara 	    (struct loaddesc *)PAGE_ALIGN(User::AllocL(ALIGN_SAFE_PAGE_SIZE));
7568122621Skiyohara 
7668122621Skiyohara 	return netbsd;
7768122621Skiyohara }
7868122621Skiyohara 
79*781c2fb3Skiyohara NetBSD *
80*781c2fb3Skiyohara NetBSD::New(const TDesC &aFilename, const TDesC &aArgs)
81*781c2fb3Skiyohara {
82*781c2fb3Skiyohara 	NetBSD *netbsd = New(aFilename);
83*781c2fb3Skiyohara 
84*781c2fb3Skiyohara 	netbsd->Args = &aArgs;
85*781c2fb3Skiyohara 
86*781c2fb3Skiyohara 	return netbsd;
87*781c2fb3Skiyohara }
88*781c2fb3Skiyohara 
8968122621Skiyohara 
9068122621Skiyohara void
9168122621Skiyohara ELF::ParseHeader(void)
9268122621Skiyohara {
9368122621Skiyohara 	struct loaddesc *loaddesc = LoadDescriptor;
9468122621Skiyohara 	Elf32_Ehdr ehdr;
9568122621Skiyohara 	Elf32_Phdr *phdr = NULL;
9668122621Skiyohara 	int PhdrSize, i;
9768122621Skiyohara 
9868122621Skiyohara 	Mem::Copy(&ehdr, Buffer, sizeof(ehdr));
9968122621Skiyohara 	PhdrSize = sizeof(Elf32_Phdr) * ehdr.e_phnum;
10068122621Skiyohara 	phdr = (Elf32_Phdr *) new (ELeave) TUint8[PhdrSize];
10168122621Skiyohara 	Mem::Copy(phdr, Buffer + ehdr.e_phoff, PhdrSize);
10268122621Skiyohara 
10368122621Skiyohara 	for (i = 0; i < ehdr.e_phnum; i++) {
10468122621Skiyohara 		if (phdr[i].p_type != PT_LOAD ||
10568122621Skiyohara 		    (phdr[i].p_flags & (PF_W | PF_X)) == 0)
10668122621Skiyohara 			continue;
10768122621Skiyohara 
10868122621Skiyohara 		loaddesc->addr = VTOP(phdr[i].p_vaddr);
10968122621Skiyohara 		loaddesc->offset = phdr[i].p_offset;
11068122621Skiyohara 		loaddesc->size = phdr[i].p_filesz;
11168122621Skiyohara 		loaddesc++;
11268122621Skiyohara 	}
11368122621Skiyohara 	/* Terminate loaddesc. */
11468122621Skiyohara 	loaddesc->addr = 0xffffffff;
11568122621Skiyohara 	loaddesc->offset = 0xffffffff;
11668122621Skiyohara 	loaddesc->size = 0xffffffff;
11768122621Skiyohara 
11868122621Skiyohara 	EntryPoint = ehdr.e_entry;
11968122621Skiyohara }
120