UbixOS V2 2.0

ld.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 <ubixos/ld.h>
30 #include <ubixos/sched.h>
31 #include <sys/elf.h>
32 #include <ubixos/kpanic.h>
33 #include <lib/kprintf.h>
34 #include <lib/kmalloc.h>
35 #include <vfs/vfs.h>
36 #include <vmm/vmm.h>
37 #include <string.h>
38 #include <assert.h>
39
40 uint32_t ldEnable(const char *interp) {
41 int i = 0x0;
42 int x = 0x0;
43 int rel = 0x0;
44 int sym = 0x0;
45 char *newLoc = 0x0;
46 char *shStr = 0x0;
47 char *dynStr = 0x0;
48 uint32_t *reMap = 0x0;
49 fileDescriptor_t *ldFd = 0x0;
50 Elf_Ehdr *binaryHeader = 0x0;
51 Elf_Phdr *programHeader = 0x0;
52 Elf_Shdr *sectionHeader = 0x0;
53 Elf_Sym *relSymTab = 0x0;
54 Elf_Rel *elfRel = 0x0;
55 Elf_Rela *elfRela = 0x0;
56 Elf_Addr addr;
57
58 /* Open our dynamic linker */
59 ldFd = fopen(interp, "rb");
60
61 if (ldFd == 0x0) {
62 ldFd = fopen("sys:/libexec/ld.so", "rb");
63 if (ldFd == 0x0)
64 return(0x0);
65 }
66
67 fseek(ldFd, 0x0, 0x0);
68 binaryHeader = (Elf32_Ehdr *) kmalloc(sizeof(Elf32_Ehdr));
69
70 assert(binaryHeader);
71 fread(binaryHeader, sizeof(Elf32_Ehdr), 1, ldFd);
72
73 programHeader = (Elf_Phdr *) kmalloc(sizeof(Elf_Phdr) * binaryHeader->e_phnum);
74 assert(programHeader);
75
76 fseek(ldFd, binaryHeader->e_phoff, 0);
77 fread(programHeader, sizeof(Elf_Shdr), binaryHeader->e_phnum, ldFd);
78
79 sectionHeader = (Elf_Shdr *) kmalloc(sizeof(Elf_Shdr) * binaryHeader->e_shnum);
80 assert(sectionHeader);
81 fseek(ldFd, binaryHeader->e_shoff, 0);
82 fread(sectionHeader, sizeof(Elf_Shdr), binaryHeader->e_shnum, ldFd);
83
84 shStr = (char *) kmalloc(sectionHeader[binaryHeader->e_shstrndx].sh_size);
85 fseek(ldFd, sectionHeader[binaryHeader->e_shstrndx].sh_offset, 0);
86 fread(shStr, sectionHeader[binaryHeader->e_shstrndx].sh_size, 1, ldFd);
87
88 for (i = 0x0; i < binaryHeader->e_phnum; i++) {
89 switch (programHeader[i].p_type) {
90 case PT_LOAD:
91 newLoc = (char *) programHeader[i].p_vaddr + LD_START;
92 /*
93 Allocate Memory Im Going To Have To Make This Load Memory With Correct
94 Settings so it helps us in the future
95 */
96 for (x = 0; x < (programHeader[i].p_memsz); x += 0x1000) {
97 /* make r/w or ro */
98 if ((vmm_remapPage(vmm_findFreePage(_current->id), ((programHeader[i].p_vaddr & 0xFFFFF000) + x + LD_START), PAGE_DEFAULT, _current->id, 0)) == 0x0)
99 K_PANIC("vmmRemapPage: ld");
100 memset((void *) ((programHeader[i].p_vaddr & 0xFFFFF000) + x + LD_START), 0x0, 0x1000);
101 }
102 /* Now Load Section To Memory */
103 fseek(ldFd, programHeader[i].p_offset, 0x0);
104 fread(newLoc, programHeader[i].p_filesz, 1, ldFd);
105
106 break;
107 case PT_DYNAMIC:
108 /* Now Load Section To Memory */
109 //fseek(ldFd, programHeader[i].p_offset, 0x0);
110 //fread(newLoc, programHeader[i].p_filesz, 1, ldFd);
111 break;
112 case PT_GNU_STACK:
113 /* Tells us if the stack should be executable. Failsafe to executable
114 until we add checking */
115 break;
116 default:
117 kprintf("Unhandled Header (kernel) : %08x\n", programHeader[i].p_type);
118 break;
119 }
120 }
121
122 for (i = 0x0; i < binaryHeader->e_shnum; i++) {
123 switch (sectionHeader[i].sh_type) {
124 case SHT_STRTAB:
125 if (!strcmp((shStr + sectionHeader[i].sh_name), ".dynstr")) {
126 dynStr = (char *) kmalloc(sectionHeader[i].sh_size);
127 //fseek(ldFd, sectionHeader[i].sh_offset, 0x0);
128 //fread(dynStr, sectionHeader[i].sh_size, 1, ldFd);
129 }
130 break;
131 case SHT_REL:
132 elfRel = (Elf_Rel *) kmalloc(sectionHeader[i].sh_size);
133 //fseek(ldFd, sectionHeader[i].sh_offset, 0x0);
134 //fread(elfRel, sectionHeader[i].sh_size, 1, ldFd);
135
136 for (x = 0x0; x < sectionHeader[i].sh_size / sizeof(Elf_Rel); x++) {
137 rel = ELF32_R_SYM(elfRel[x].r_info);
138 reMap = (uint32_t *) ((uint32_t) LD_START + elfRel[x].r_offset);
139 switch (ELF32_R_TYPE(elfRel[x].r_info)) {
140 case R_386_32:
141 *reMap += ((uint32_t) LD_START + relSymTab[rel].st_value);
142 break;
143 case R_386_PC32:
144 *reMap += ((uint32_t) LD_START + relSymTab[rel].st_value) - (uint32_t) reMap;
145 break;
146 case R_386_RELATIVE:
147 *reMap += (uint32_t) LD_START;
148 break;
149 case R_386_NONE:
150 break;
151 default:
152 kprintf("[0x%X][0x%X](%i)[%s]\n", elfRel[x].r_offset, elfRel[x].r_info, rel, elfGetRelType(ELF32_R_TYPE(elfRel[x].r_info)));
153 kprintf("relTab [%s][0x%X][0x%X]\n", dynStr + relSymTab[rel].st_name, relSymTab[rel].st_value, relSymTab[rel].st_name);
154 break;
155 }
156 }
157 kfree(elfRel);
158 break;
159 case SHT_DYNSYM:
160 relSymTab = (Elf_Sym *) kmalloc(sectionHeader[i].sh_size);
161 fseek(ldFd, sectionHeader[i].sh_offset, 0x0);
162 fread(relSymTab, sectionHeader[i].sh_size, 1, ldFd);
163 sym = i;
164 break;
165 case SHT_PROGBITS:
166 //kprintf("PROGBITS");
167 break;
168 case SHT_HASH:
169 //kprintf("HASH");
170 break;
171 case SHT_DYNAMIC:
172 //kprintf("DYNAMIC");
173 break;
174 case SHT_SYMTAB:
175 //kprintf("SYMTAB");
176 break;
177 default:
178 //kprintf("Invalid: %i]", sectionHeader[i].sh_type);
179 break;
180 }
181 }
182
183 i = binaryHeader->e_entry + LD_START;
184
185 kfree(dynStr);
186 kfree(shStr);
187 kfree(relSymTab);
188 kfree(sectionHeader);
189 kfree(programHeader);
190 kfree(binaryHeader);
191 fclose(ldFd);
192
193 return ((uint32_t) i);
194 }
ELF32_R_TYPE
#define ELF32_R_TYPE(info)
Definition: elf32.h:148
SHT_STRTAB
#define SHT_STRTAB
Definition: elf_common.h:382
fopen
fileDescriptor_t * fopen(const char *file, const char *flags)
Definition: file.c:388
vfs.h
K_PANIC
#define K_PANIC(msg)
Definition: kpanic.h:32
string.h
SHT_PROGBITS
#define SHT_PROGBITS
Definition: elf_common.h:380
PT_GNU_STACK
#define PT_GNU_STACK
Definition: elf_common.h:502
SHT_DYNSYM
#define SHT_DYNSYM
Definition: elf_common.h:390
fileDescriptor
Definition: file.h:62
PT_DYNAMIC
#define PT_DYNAMIC
Definition: elf_common.h:493
fread
size_t fread(void *ptr, size_t size, size_t nmemb, fileDescriptor_t *fd)
Definition: file.c:291
kfree
void kfree(void *baseAddr)
Definition: kmalloc.c:342
strcmp
int strcmp(const char *str1, const char *str2)
assert
#define assert(e)
Definition: assert.h:64
assert.h
vmm.h
R_386_NONE
#define R_386_NONE
Definition: elf_common.h:866
PT_LOAD
#define PT_LOAD
Definition: elf_common.h:492
sched.h
SHT_REL
#define SHT_REL
Definition: elf_common.h:388
LD_START
#define LD_START
Definition: kmod.h:34
kpanic.h
taskStruct::id
pidType id
Definition: sched.h:63
vmm_findFreePage
uint32_t vmm_findFreePage(pidType pid)
Definition: vmm_memory.c:221
SHT_HASH
#define SHT_HASH
Definition: elf_common.h:384
ELF32_R_SYM
#define ELF32_R_SYM(info)
Definition: elf32.h:147
R_386_32
#define R_386_32
Definition: elf_common.h:867
fclose
int fclose(fileDescriptor_t *fd)
Definition: file.c:526
kprintf.h
R_386_PC32
#define R_386_PC32
Definition: elf_common.h:868
PAGE_DEFAULT
#define PAGE_DEFAULT
Definition: paging.h:68
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
ld.h
elfGetRelType
char * elfGetRelType(int)
Definition: elf.c:167
ldEnable
uint32_t ldEnable(const char *interp)
Definition: ld.c:40
_current
kTask_t * _current
Definition: sched.c:50
SHT_SYMTAB
#define SHT_SYMTAB
Definition: elf_common.h:381
Elf32_Ehdr
Definition: elf32.h:55
kmalloc
void * kmalloc(uInt32 len)
Definition: kmalloc.c:241
memset
void * memset(void *dst, int c, size_t length)
SHT_DYNAMIC
#define SHT_DYNAMIC
Definition: elf_common.h:385
kprintf
int kprintf(const char *,...)
Definition: kprintf.c:259
elf.h
kmalloc.h
R_386_RELATIVE
#define R_386_RELATIVE
Definition: elf_common.h:874
fseek
int fseek(fileDescriptor_t *tmpFd, long offset, int whence)
Definition: file.c:326