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