UbixOS  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:395
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:297
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:533
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:332