kmod.c

Go to the documentation of this file.
00001 /*****************************************************************************************
00002  Copyright (c) 2002-2005 The UbixOS Project
00003  All rights reserved.
00004 
00005  Redistribution and use in source and binary forms, with or without modification, are
00006  permitted provided that the following conditions are met:
00007 
00008  Redistributions of source code must retain the above copyright notice, this list of
00009  conditions, the following disclaimer and the list of authors.  Redistributions in binary
00010  form must reproduce the above copyright notice, this list of conditions, the following
00011  disclaimer and the list of authors in the documentation and/or other materials provided
00012  with the distribution. Neither the name of the UbixOS Project nor the names of its
00013  contributors may be used to endorse or promote products derived from this software
00014  without specific prior written permission.
00015 
00016  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
00017  EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
00018  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
00019  THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
00020  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
00021  OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
00022  HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
00023  TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
00024  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00025 
00026  $Id: kmod_8c-source.html 88 2016-01-12 00:11:29Z reddawg $
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   /* Open kernel module */
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   /* load module header */
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         Allocate Memory Im Going To Have To Make This Load Memory With Correct
00131         Settings so it helps us in the future
00132         */
00133         for (x=0;x < ((programHeader[i].phMemsz)+4095);x += 0x1000) {
00134           /* make r/w or ro */
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         /* Now Load Section To Memory */
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         /* Tells us if the stack should be executable.  Failsafe to executable
00145            until we add checking */
00146         break;
00147       case PT_PAX_FLAGS:
00148         /* Not sure... */
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  END
00215  ***/

Generated on Fri Dec 15 11:18:55 2006 for UbixOS V2 by  doxygen 1.4.7