2 meinOS - A unix-like x86 microkernel operating system
3 Copyright (C) 2008 Janosch Gräf <janosch.graef@gmx.net>
5 This program is free software: you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation, either version 3 of the License, or
8 (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program. If not, see <http://www.gnu.org/licenses/>.
19 #include <sys/types.h>
28 int elf_validate(elf_header_t
*header
) {
29 if (header
->ident
[EI_MAG0
]!=ELFMAG0
|| header
->ident
[EI_MAG1
]!=ELFMAG1
|| header
->ident
[EI_MAG2
]!=ELFMAG2
|| header
->ident
[EI_MAG3
]!=ELFMAG3
) return -1;
30 if (header
->machine
!=EM_386
) return -1;
31 if (header
->ident
[EI_CLASS
]!=ELFCLASS32
) return -1;
32 if (header
->ident
[EI_DATA
]!=ELFDATA2LSB
) return -1;
33 if (header
->ident
[EI_VERSION
]!=header
->version
) return -1;
38 * Loads an ELF segment in address space
39 * @param memaddr Destination address in memory
40 * @param memsize Size in memory
41 * @param fileaddr Source address in file (absolute)
42 * @param filesize Size in file
43 * @param addrspace User address space
44 * @param writable If segment is writeable
46 int elf_loadseg(void *memaddr
,size_t memsize
,void *fileaddr
,size_t filesize
,addrspace_t
*addrspace
,int writable
) {
49 if (memaddr
<(void*)USERDATA_ADDRESS
) return -1;
50 if (memuser_load_addrspace(addrspace
)==-1) return -1;
51 for (i
=0;i
<memsize
;i
+=PAGE_SIZE
) {
52 if (memuser_alloc_at(addrspace
,memaddr
+i
,i
<filesize
?paging_getphysaddr(fileaddr
+i
):NULL
,writable
)==-1) return -1;
54 if (filesize
<memsize
) memset(memaddr
+filesize
,0,memsize
-filesize
);
59 * Loads an ELF file in an address space
60 * @param addrspace Address space
61 * @param file Pointer to ELF file
62 * @param filesize Size of ELF file
65 void *elf_load(addrspace_t
*addrspace
,void *file
,size_t filesize
) {
66 elf_header_t
*header
= file
;
67 elf_progheader_t
*progheader
;
71 if (elf_validate(header
)==-1) return NULL
;
73 entrypoint
= (void*)(header
->entry
);
74 progheader
= file
+header
->phoff
;
76 for (i
=0;i
<header
->phnum
;i
++) {
77 if (progheader
[i
].type
==PT_LOAD
) {
78 if (elf_loadseg((void*)(progheader
[i
].vaddr
),progheader
[i
].memsz
,file
+progheader
[i
].offset
,progheader
[i
].filesz
,addrspace
,(progheader
[i
].flags
&PF_W
)==PF_W
?1:0)==-1) return NULL
;