Show
Ignore:
Timestamp:
05/01/08 15:13:46 (7 months ago)
Author:
mwhitworth
Message:

Extend module loading code, add ModuleFindSymbol function.

Files:
1 modified

Legend:

Unmodified
Added
Removed
  • Whitix/branches/hybrid/kernel/module.c

    r378 r379  
    2020#include <elf.h> 
    2121#include <error.h> 
     22#include <malloc.h> 
     23#include <module.h> 
    2224#include <i386/i386.h> 
     25#include <i386/virtual.h> 
     26#include <slab.h> 
    2327#include <sys.h> 
     28 
     29#define MODULE_START    0xD8000000 
     30#define MODULE_END              0xE0000000 
     31 
     32void* ModuleSymbolFind(struct Module* module, const char* symName, int type) 
     33{ 
     34        int i; 
     35        struct ElfSymbol* symbol; 
     36 
     37        for (i=1; i<module->symTableSize/(sizeof(struct ElfSymbol)); i++) 
     38        { 
     39                symbol=&module->symTable[i]; 
     40 
     41                if (symbol->symIndex == STN_UNDEF) 
     42                        continue; 
     43 
     44                if (ELF_ST_TYPE(symbol->symInfo) != type) 
     45                        continue; 
     46 
     47                if (strcmp(symName, module->strTable+symbol->symName)) 
     48                        continue; 
     49 
     50                /* Handle data? */ 
     51                return (module->textAddr+symbol->symValue); 
     52        } 
     53 
     54        return NULL; 
     55} 
    2456 
    2557int ModuleAdd(void* data, unsigned long length, int flags) 
    2658{ 
    2759        struct ElfHeader* elfHeader=(struct ElfHeader*)data; 
     60        struct Module* module; 
     61        struct ElfSectionHeader* sectionHeaders; 
     62        DWORD loadAddr=(DWORD)data; 
     63        int i; 
    2864 
    29         if (ElfCheckHeader(elfHeader, ELF_REL)) 
     65        if (!ELF_HEAD_CHECK(elfHeader) || (elfHeader->fileType != ELF_REL) || (elfHeader->shEntrySize != sizeof(struct ElfSectionHeader))) 
    3066                return -EINVAL; 
     67         
     68        /* Get basic information about the module. */ 
     69        module=(struct Module*)malloc(sizeof(struct Module)); 
     70        module->loadAddr=loadAddr; 
    3171 
    32          
    33         /* Find the init and exit functions. */ 
    34          
     72        /* Iterate through section headers. */ 
     73        sectionHeaders=(struct ElfSectionHeader*)((char*)data+elfHeader->shOffset); 
    3574 
    36         /* Call ModuleInit */ 
     75        for (i=0; i<elfHeader->shEntries; i++) 
     76        { 
     77                if (sectionHeaders[i].shFlags & SEC_FLAGS_EXEC) 
     78                        module->textAddr=loadAddr+sectionHeaders[i].shOffset; 
     79 
     80                /* Save the symbol table off for resolving later. */ 
     81                if (sectionHeaders[i].shType == SEC_TYPE_SYMTAB) 
     82                { 
     83                        module->symTable=loadAddr+sectionHeaders[i].shOffset; 
     84                        module->symTableSize=sectionHeaders[i].shSize; 
     85                } 
     86 
     87                if (sectionHeaders[i].shType == SEC_TYPE_STRTAB) 
     88                        module->strTable=loadAddr+sectionHeaders[i].shOffset; 
     89        } 
     90 
     91        /* Resolve entries in the module file. */ 
     92 
     93        /* Find the init and exit functions, using the symbol and string table addresses. */ 
     94        int (*modInit)(void); 
     95 
     96        modInit=ModuleSymbolFind(module, "ModuleInit", STT_FUNC); 
     97 
     98        printf("modInit = %#X\n", modInit); 
     99 
     100        if (modInit) 
     101                /* Call ModuleInit */ 
     102                printf("ret = %d\n", (*modInit)()); 
    37103 
    38104        return 0; 
     
    41107int SysModuleAdd(void* data, unsigned long length) 
    42108{ 
    43         /* Copy in data from userspace. */ 
    44         return ModuleAdd(data, length, 0); 
     109        void* kData; 
     110 
     111        /* Check data is ok to access. */ 
     112 
     113        kData=(void*)VirtMapPhysRange(MODULE_START, MODULE_END, PAGE_ALIGN_UP(length) >> PAGE_SHIFT, 3); 
     114 
     115        memcpy(kData, data, length); 
     116 
     117        return ModuleAdd(kData, length, 0); 
    45118} 
    46119