UbixOS  2.0
elf.c
Go to the documentation of this file.
1 /*-
2  * Copyright (c) 2002-2018 The UbixOS Project.
3  * All rights reserved.
4  *
5  * This was developed by Christopher W. Olsen for the UbixOS Project.
6  *
7  * Redistribution and use in source and binary forms, with or without modification, are permitted
8  * provided that the following conditions are met:
9  *
10  * 1) Redistributions of source code must retain the above copyright notice, this list of
11  * conditions, the following disclaimer and the list of authors.
12  * 2) Redistributions in binary form must reproduce the above copyright notice, this list of
13  * conditions, the following disclaimer and the list of authors in the documentation and/or
14  * other materials provided with the distribution.
15  * 3) Neither the name of the UbixOS Project nor the names of its contributors may be used to
16  * endorse or promote products derived from this software without specific prior written
17  * permission.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
20  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
21  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
22  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
23  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
24  * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
26  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27  */
28 
29 #include <sys/elf.h>
30 #include <ubixos/sched.h>
31 #include <ubixos/kpanic.h>
32 #include <lib/kmalloc.h>
33 #include <vmm/vmm.h>
34 #include <lib/kprintf.h>
35 #include <string.h>
36 
37 int elf_load_file(kTask_t *p, const char *file, uint32_t *addr, uint32_t *entry) {
38  int ret = 0;
39 
40  int i = 0x0;
41  int x = 0x0;
42  int numsegs = 0x0;
43 
44  uint32_t base_addr = 0x0;
45  uint32_t real_base_addr = 0x0;
46 
47  Elf32_Ehdr *binaryHeader = 0x0;
48  Elf32_Phdr *programHeader = 0x0;
49 
50  fileDescriptor_t *exec_fd = 0x0;
51 
52  exec_fd = fopen(file, "r");
53 
54  if (exec_fd == 0x0)
55  return (-1);
56 
57  /* Load the ELF header */
58  if ((binaryHeader = (Elf32_Ehdr *) kmalloc(sizeof(Elf32_Ehdr))) == 0x0)
59  K_PANIC("malloc failed!");
60 
61  fread(binaryHeader, sizeof(Elf32_Ehdr), 1, exec_fd);
62 
63  /* Check If App Is A Real Application */
64  if ((binaryHeader->e_ident[1] != 'E') && (binaryHeader->e_ident[2] != 'L') && (binaryHeader->e_ident[3] != 'F')) {
65  ret = -1;
66  goto failed;
67  }
68 
69  if (binaryHeader->e_type == ET_DYN)
70  real_base_addr = *addr;
71  else if (binaryHeader->e_type == ET_EXEC)
72  real_base_addr = 0x0;
73  else {
74  ret = -1;
75  goto failed;
76  }
77 
78  /* Load The Program Header(s) */
79  if ((programHeader = (Elf32_Phdr *) kmalloc(sizeof(Elf32_Phdr) * binaryHeader->e_phnum)) == 0x0)
80  K_PANIC("malloc failed!");
81 
82  fseek(exec_fd, binaryHeader->e_phoff, 0);
83 
84  fread(programHeader, (sizeof(Elf32_Phdr) * binaryHeader->e_phnum), 1, exec_fd);
85 
86  for (numsegs = 0x0, i = 0x0; i < binaryHeader->e_phnum; i++) {
87  switch (programHeader[i].p_type) {
88  case PT_LOAD:
89  /*
90  Allocate Memory Im Going To Have To Make This Load Memory With Correct
91  Settings so it helps us in the future
92  */
93  for (x = 0x0; x < (programHeader[i].p_memsz + 0xFFF); x += 0x1000) {
94 
95  /* Make readonly and read/write */
96  if (vmm_remapPage(vmm_findFreePage(_current->id), ((programHeader[i].p_vaddr & 0xFFFFF000) + x + real_base_addr), PAGE_DEFAULT, _current->id, 0x0) == 0x0)
97  K_PANIC("Error: Remap Page Failed");
98 
99  memset((void *) ((programHeader[i].p_vaddr & 0xFFFFF000) + x + real_base_addr), 0x0, 0x1000);
100  }
101 
102  /* Now Load Section To Memory */
103  fseek(exec_fd, programHeader[i].p_offset, 0);
104  fread((void *) programHeader[i].p_vaddr + real_base_addr, programHeader[i].p_filesz, 1, exec_fd);
105 
106  if ((programHeader[i].p_flags & 0x2) != 0x2) {
107  for (x = 0x0; x < (programHeader[i].p_memsz); x += 0x1000) {
108  if ((vmm_setPageAttributes((programHeader[i].p_vaddr & 0xFFFFF000) + x + real_base_addr, PAGE_PRESENT | PAGE_USER)) != 0x0)
109  K_PANIC("vmm_setPageAttributes failed");
110  }
111  }
112  if (numsegs == 0x0)
113  base_addr = programHeader[i].p_vaddr + real_base_addr; //(programHeader[i].p_vaddr & 0xFFFFF000) + real_base_addr;
114  numsegs++;
115  break;
116  }
117  }
118 
119  *addr = base_addr;
120 
121  *entry = binaryHeader->e_entry + real_base_addr;
122 
123  failed:
124 
125  /* Close The Open File */
126  fclose(exec_fd);
127 
128  /* Free Binary Header Memory */
129  if (binaryHeader != 0x0)
130  kfree(binaryHeader);
131 
132  /* Free Program Header Memory */
133  if (programHeader != 0x0)
134  kfree(programHeader);
135 
136  return (ret);
137 }
138 
139 const struct {
140  char *elfTypeName;
142 } elfType[] = { { "ET_NONE", 0 }, { "ET_REL", 1 }, { "ET_EXEC", 2 }, { "ET_DYN", 3 }, { "ET_CORE", 4 }, { "ET_LOPROC", 0xff00 }, { "ET_HIPROC", 0xffff }, };
143 
144 const struct {
145  char *phTypeName;
146  uInt32 id;
147 } elfPhType[] = { { "PT_NULL", 0 }, { "PT_LOAD", 1 }, { "PT_DYNAMIC", 2 }, { "PT_INTERP", 3 }, { "PT_NOTE", 4 }, { "PT_SHLIB", 5 }, { "PT_PHDR", 6 }, { "PT_LOPROC", 0x70000000 }, { "PT_HIPROC", 0x7fffffff }, };
148 
149 const struct {
150  char *shTypeName;
151  uInt32 id;
152 } elfShType[] = { { "SHT_NULL", 0 }, { "SHT_PROGBITS", 1 }, { "SHT_SYMTAB", 2 }, { "SHT_STRTAB", 3 }, { "SHT_RELA", 4 }, { "SHT_HASH", 5 }, { "SHT_DYNAMIC", 6 }, { "SHT_NOTE", 7 }, { "SHT_NOBITS", 8 }, { "SHT_REL", 9 }, { "SHT_SHLIB", 10 }, { "SHT_DYNSYM", 11 }, };
153 
154 const struct {
155  char *relTypeName;
156  uInt32 id;
157 } elfRelType[] = { { "R_386_NONE", 0 }, { "R_386_32", 1 }, { "R_386_PC32", 2 }, { "R_386_GOT32", 3 }, { "R_386_PLT32", 4 }, { "R_386_COPY", 5 }, { "R_386_GLOB_DAT", 6 }, { "R_386_JMP_SLOT", 7 }, { "R_386_RELATIVE", 8 }, { "R_386_GOTOFF", 9 }, { "R_386_GOTPC", 10 }, };
158 
159 char *elfGetShType(int shType) {
160  return ((char *) elfShType[shType].shTypeName);
161 }
162 
163 char *elfGetPhType(int phType) {
164  return ((char *) elfPhType[phType].phTypeName);
165 }
166 
167 char *elfGetRelType(int relType) {
168  return ((char *) elfRelType[relType].relTypeName);
169 }
170 
171 /***
172  END
173  ***/
174 
taskStruct
Definition: sched.h:62
uInt32
unsigned long int uInt32
Definition: objgfx30.h:49
fopen
fileDescriptor_t * fopen(const char *file, const char *flags)
Definition: file.c:395
Elf32_Ehdr::e_phoff
Elf32_Off e_phoff
Definition: elf32.h:61
K_PANIC
#define K_PANIC(msg)
Definition: kpanic.h:32
Elf32_Phdr::p_memsz
Elf32_Word p_memsz
Definition: elf32.h:112
string.h
Elf32_Ehdr::e_ident
unsigned char e_ident[EI_NIDENT]
Definition: elf32.h:56
fileDescriptor
Definition: file.h:62
ET_DYN
#define ET_DYN
Definition: elf_common.h:192
fread
size_t fread(void *ptr, size_t size, size_t nmemb, fileDescriptor_t *fd)
Definition: file.c:297
file
Definition: descrip.h:67
kfree
void kfree(void *baseAddr)
Definition: kmalloc.c:342
vmm.h
elfTypeName
char * elfTypeName
Definition: elf.c:140
ET_EXEC
#define ET_EXEC
Definition: elf_common.h:191
PT_LOAD
#define PT_LOAD
Definition: elf_common.h:492
sched.h
Elf32_Phdr::p_vaddr
Elf32_Addr p_vaddr
Definition: elf32.h:109
shTypeName
char * shTypeName
Definition: elf.c:150
kpanic.h
taskStruct::id
pidType id
Definition: sched.h:63
vmm_findFreePage
uint32_t vmm_findFreePage(pidType pid)
Definition: vmm_memory.c:221
elf_load_file
int elf_load_file(kTask_t *p, const char *file, uint32_t *addr, uint32_t *entry)
Definition: elf.c:37
phTypeName
char * phTypeName
Definition: elf.c:145
vmm_setPageAttributes
int vmm_setPageAttributes(uint32_t, uint16_t)
Definition: setpageattributes.c:39
fclose
int fclose(fileDescriptor_t *fd)
Definition: file.c:533
kprintf.h
Elf32_Ehdr::e_entry
Elf32_Addr e_entry
Definition: elf32.h:60
PAGE_DEFAULT
#define PAGE_DEFAULT
Definition: paging.h:68
Elf32_Phdr
Definition: elf32.h:106
vmm_remapPage
int vmm_remapPage(uint32_t, uint32_t, uint16_t, pidType, int haveLock)
Definition: paging.c:199
uint32_t
__uint32_t uint32_t
Definition: types.h:46
elfRelType
const struct @28 elfRelType[]
elfPhType
const struct @26 elfPhType[]
elfType
const struct @25 elfType[]
_current
kTask_t * _current
Definition: sched.c:50
Elf32_Ehdr
Definition: elf32.h:55
elfShType
const struct @27 elfShType[]
kmalloc
void * kmalloc(uInt32 len)
Definition: kmalloc.c:241
memset
void * memset(void *dst, int c, size_t length)
PAGE_USER
#define PAGE_USER
Definition: paging.h:57
Elf32_Ehdr::e_type
Elf32_Half e_type
Definition: elf32.h:57
id
uInt32 id
Definition: elf.c:141
elf.h
PAGE_PRESENT
#define PAGE_PRESENT
Definition: paging.h:55
kmalloc.h
elfGetRelType
char * elfGetRelType(int relType)
Definition: elf.c:167
elfGetPhType
char * elfGetPhType(int phType)
Definition: elf.c:163
elfGetShType
char * elfGetShType(int shType)
Definition: elf.c:159
Elf32_Ehdr::e_phnum
Elf32_Half e_phnum
Definition: elf32.h:66
relTypeName
char * relTypeName
Definition: elf.c:155
fseek
int fseek(fileDescriptor_t *tmpFd, long offset, int whence)
Definition: file.c:332