# 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  ***/