netbsd.cpp revision 1.1 1 /* $NetBSD: netbsd.cpp,v 1.1 2013/04/28 12:11:26 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 *
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
80 void
81 ELF::ParseHeader(void)
82 {
83 struct loaddesc *loaddesc = LoadDescriptor;
84 Elf32_Ehdr ehdr;
85 Elf32_Phdr *phdr = NULL;
86 int PhdrSize, i;
87
88 Mem::Copy(&ehdr, Buffer, sizeof(ehdr));
89 PhdrSize = sizeof(Elf32_Phdr) * ehdr.e_phnum;
90 phdr = (Elf32_Phdr *) new (ELeave) TUint8[PhdrSize];
91 Mem::Copy(phdr, Buffer + ehdr.e_phoff, PhdrSize);
92
93 for (i = 0; i < ehdr.e_phnum; i++) {
94 if (phdr[i].p_type != PT_LOAD ||
95 (phdr[i].p_flags & (PF_W | PF_X)) == 0)
96 continue;
97
98 loaddesc->addr = VTOP(phdr[i].p_vaddr);
99 loaddesc->offset = phdr[i].p_offset;
100 loaddesc->size = phdr[i].p_filesz;
101 loaddesc++;
102 }
103 /* Terminate loaddesc. */
104 loaddesc->addr = 0xffffffff;
105 loaddesc->offset = 0xffffffff;
106 loaddesc->size = 0xffffffff;
107
108 EntryPoint = ehdr.e_entry;
109 }
110