00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030 #include <ubixos/types.h>
00031 #include <ubixos/kmod.h>
00032 #include <ubixos/sched.h>
00033 #include <ubixos/elf.h>
00034 #include <ubixos/kpanic.h>
00035 #include <ubixos/lists.h>
00036 #include <ubixos/spinlock.h>
00037 #include <lib/kprintf.h>
00038 #include <lib/kmalloc.h>
00039 #include <vfs/vfs.h>
00040 #include <vmm/vmm.h>
00041 #include <string.h>
00042 #include <assert.h>
00043
00044 List_t *List = 0x0;
00045
00046 uInt32 kmod_add(const char *kmod_file, const char *name)
00047 {
00048 uInt32 addr = 0x0;
00049 Item_t *tmp;
00050 kmod_t *kmods;
00051
00052
00053 addr = kmod_load(kmod_file);
00054 if (addr == 0x0)
00055 return 0x0;
00056
00057 if(List == 0x0)
00058 {
00059 List = InitializeList();
00060 }
00061
00062 tmp = CreateItem();
00063 InsertItemAtFront(List, tmp);
00064 kmods = kmalloc(sizeof *kmods);
00065 tmp->data = kmods;
00066 if(kmods == NULL)
00067 {
00068 kprintf("kmod_add: unable to allocate memory!\n");
00069 return 0x0;
00070 }
00071
00072 return 0x0;
00073 }
00074
00075 uInt32 kmod_load(const char *kmod_file) {
00076 int i = 0x0;
00077 int x = 0x0;
00078 int rel = 0x0;
00079 int sym = 0x0;
00080 char *newLoc = 0x0;
00081 char *shStr = 0x0;
00082 char *dynStr = 0x0;
00083 uInt32 *reMap = 0x0;
00084 fileDescriptor *kmod_fd = 0x0;
00085 elfHeader *binaryHeader = 0x0;
00086 elfProgramHeader *programHeader = 0x0;
00087 elfSectionHeader *sectionHeader = 0x0;
00088 elfDynSym *relSymTab = 0x0;
00089 elfPltInfo *elfRel = 0x0;
00090
00091
00092 kmod_fd = fopen(kmod_file,"rb");
00093 if (kmod_fd == 0x0) {
00094 kprintf("Can not open %s\n",kmod_file);
00095 return 0x0;
00096 }
00097
00098
00099 fseek(kmod_fd,0x0,0x0);
00100 binaryHeader = (elfHeader *)kmalloc(sizeof(elfHeader));
00101 if(binaryHeader == 0x0)
00102 {
00103 kprintf("kmod: out of memory\n");
00104 return 0x0;
00105 }
00106
00107 assert(binaryHeader);
00108 fread(binaryHeader,sizeof(elfHeader),1,kmod_fd);
00109
00110 programHeader = (elfProgramHeader *)kmalloc(sizeof(elfProgramHeader)*binaryHeader->ePhnum);
00111 assert(programHeader);
00112 fseek(kmod_fd,binaryHeader->ePhoff,0);
00113 fread(programHeader,sizeof(elfSectionHeader),binaryHeader->ePhnum,kmod_fd);
00114
00115 sectionHeader = (elfSectionHeader *)kmalloc(sizeof(elfSectionHeader)*binaryHeader->eShnum);
00116 assert(sectionHeader);
00117 fseek(kmod_fd,binaryHeader->eShoff,0);
00118 fread(sectionHeader,sizeof(elfSectionHeader),binaryHeader->eShnum,kmod_fd);
00119
00120 shStr = (char *)kmalloc(sectionHeader[binaryHeader->eShstrndx].shSize);
00121 fseek(kmod_fd,sectionHeader[binaryHeader->eShstrndx].shOffset,0);
00122 fread(shStr,sectionHeader[binaryHeader->eShstrndx].shSize,1,kmod_fd);
00123
00124 for (i=0;i<binaryHeader->ePhnum;i++) {
00125 switch (programHeader[i].phType) {
00126 case PT_LOAD:
00127 case PT_DYNAMIC:
00128 newLoc = (char *)programHeader[i].phVaddr + LD_START;
00129
00130
00131
00132
00133 for (x=0;x < ((programHeader[i].phMemsz)+4095);x += 0x1000) {
00134
00135 if ((vmm_remapPage(vmmFindFreePage(_current->id),((programHeader[i].phVaddr & 0xFFFFF000) + x + LD_START),PAGE_DEFAULT)) == 0x0)
00136 kpanic("vmmRemapPage: ld\n");
00137 memset((void *)((programHeader[i].phVaddr & 0xFFFFF000) + x + LD_START),0x0,0x1000);
00138 }
00139
00140 fseek(kmod_fd,programHeader[i].phOffset,0x0);
00141 fread(newLoc,programHeader[i].phFilesz,1,kmod_fd);
00142 break;
00143 case PT_GNU_STACK:
00144
00145
00146 break;
00147 case PT_PAX_FLAGS:
00148
00149 break;
00150 default:
00151 kprintf("Unhandled Header : %08x\n", programHeader[i].phType);
00152 break;
00153 }
00154 }
00155
00156 for (i=0x0;i<binaryHeader->eShnum;i++) {
00157 switch (sectionHeader[i].shType) {
00158 case 3:
00159 if (!strcmp((shStr + sectionHeader[i].shName),".dynstr")) {
00160 dynStr = (char *)kmalloc(sectionHeader[i].shSize);
00161 fseek(kmod_fd,sectionHeader[i].shOffset,0x0);
00162 fread(dynStr,sectionHeader[i].shSize,1,kmod_fd);
00163 }
00164 break;
00165 case 9:
00166 elfRel = (elfPltInfo *)kmalloc(sectionHeader[i].shSize);
00167 fseek(kmod_fd,sectionHeader[i].shOffset,0x0);
00168 fread(elfRel,sectionHeader[i].shSize,1,kmod_fd);
00169
00170 for (x=0x0;x<sectionHeader[i].shSize/sizeof(elfPltInfo);x++) {
00171 rel = ELF32_R_SYM(elfRel[x].pltInfo);
00172 reMap = (uInt32 *)((uInt32)LD_START + elfRel[x].pltOffset);
00173 switch (ELF32_R_TYPE(elfRel[x].pltInfo)) {
00174 case R_386_32:
00175 *reMap += ((uInt32)LD_START + relSymTab[rel].dynValue);
00176 break;
00177 case R_386_PC32:
00178 *reMap += ((uInt32)LD_START + relSymTab[rel].dynValue) - (uInt32)reMap;
00179 break;
00180 case R_386_RELATIVE:
00181 *reMap += (uInt32)LD_START;
00182 break;
00183 default:
00184 kprintf("[0x%X][0x%X](%i)[%s]\n",elfRel[x].pltOffset,elfRel[x].pltInfo,rel,elfGetRelType(ELF32_R_TYPE(elfRel[x].pltInfo)));
00185 kprintf("relTab [%s][0x%X][0x%X]\n",dynStr + relSymTab[rel].dynName,relSymTab[rel].dynValue,relSymTab[rel].dynName);
00186 break;
00187 }
00188 }
00189 kfree(elfRel);
00190 break;
00191 case 11:
00192 relSymTab = (elfDynSym *)kmalloc(sectionHeader[i].shSize);
00193 fseek(kmod_fd,sectionHeader[i].shOffset,0x0);
00194 fread(relSymTab,sectionHeader[i].shSize,1,kmod_fd);
00195 sym = i;
00196 break;
00197 }
00198 }
00199
00200 i = binaryHeader->eEntry + LD_START;
00201
00202 kfree(dynStr);
00203 kfree(shStr);
00204 kfree(relSymTab);
00205 kfree(sectionHeader);
00206 kfree(programHeader);
00207 kfree(binaryHeader);
00208 fclose(kmod_fd);
00209
00210 return((uInt32)i);
00211 }
00212
00213
00214
00215