1 /* $NetBSD: netbsd.cpp,v 1.2 2013/06/20 13:36:48 kiyohara Exp $ */
2 /*
3 * Copyright (c) 2012 KIYOHARA Takashi
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 *
15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
16 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
17 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
18 * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
19 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
20 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
21 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
23 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
24 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
25 * POSSIBILITY OF SUCH DAMAGE.
26 */
27 #include <e32cons.h>
28 #include <e32std.h>
29 #include <f32file.h>
30
31 #include "e32boot.h"
32 #include "elf.h"
33 #include "netbsd.h"
34
35
36 NetBSD *
New(const TDesC & aFilename)37 NetBSD::New(const TDesC &aFilename)
38 {
39 NetBSD *netbsd = NULL;
40 RFs fsSession;
41 RFile file;
42 TInt size;
43 union {
44 Elf32_Ehdr elf;
45 } hdr;
46
47 /* Connect to FileServer Session */
48 User::LeaveIfError(fsSession.Connect());
49
50 User::LeaveIfError(file.Open(fsSession, aFilename, EFileRead));
51 User::LeaveIfError(file.Size(size));
52
53 TPtr hdrBuf((TUint8 *)&hdr, sizeof(hdr));
54 User::LeaveIfError(file.Read(hdrBuf));
55 /* Currently support is ELF only. */
56 if (Mem::Compare((TUint8 *)hdr.elf.e_ident, SELFMAG,
57 (TUint8 *)ELFMAG, SELFMAG) == 0) {
58 netbsd = new (ELeave) ELF(size);
59 } else
60 User::Leave(KErrNotSupported);
61 TInt pos = 0;
62 User::LeaveIfError(file.Seek(ESeekStart, pos));
63
64 TPtr fileBuf(netbsd->Buffer, size);
65 User::LeaveIfError(file.Read(fileBuf));
66 if (fileBuf.Length() != size)
67 User::Leave(KErrNotFound);
68 file.Close();
69
70 /* Close FileServer Session */
71 fsSession.Close();
72
73 netbsd->LoadDescriptor =
74 (struct loaddesc *)PAGE_ALIGN(User::AllocL(ALIGN_SAFE_PAGE_SIZE));
75
76 return netbsd;
77 }
78
79 NetBSD *
New(const TDesC & aFilename,const TDesC & aArgs)80 NetBSD::New(const TDesC &aFilename, const TDesC &aArgs)
81 {
82 NetBSD *netbsd = New(aFilename);
83
84 netbsd->Args = &aArgs;
85
86 return netbsd;
87 }
88
89
90 void
ParseHeader(void)91 ELF::ParseHeader(void)
92 {
93 struct loaddesc *loaddesc = LoadDescriptor;
94 Elf32_Ehdr ehdr;
95 Elf32_Phdr *phdr = NULL;
96 int PhdrSize, i;
97
98 Mem::Copy(&ehdr, Buffer, sizeof(ehdr));
99 PhdrSize = sizeof(Elf32_Phdr) * ehdr.e_phnum;
100 phdr = (Elf32_Phdr *) new (ELeave) TUint8[PhdrSize];
101 Mem::Copy(phdr, Buffer + ehdr.e_phoff, PhdrSize);
102
103 for (i = 0; i < ehdr.e_phnum; i++) {
104 if (phdr[i].p_type != PT_LOAD ||
105 (phdr[i].p_flags & (PF_W | PF_X)) == 0)
106 continue;
107
108 loaddesc->addr = VTOP(phdr[i].p_vaddr);
109 loaddesc->offset = phdr[i].p_offset;
110 loaddesc->size = phdr[i].p_filesz;
111 loaddesc++;
112 }
113 /* Terminate loaddesc. */
114 loaddesc->addr = 0xffffffff;
115 loaddesc->offset = 0xffffffff;
116 loaddesc->size = 0xffffffff;
117
118 EntryPoint = ehdr.e_entry;
119 }
120