Fixing KMod support
authorJohn Hodge <[email protected]>
Fri, 16 Mar 2012 08:02:27 +0000 (16:02 +0800)
committerJohn Hodge <[email protected]>
Fri, 16 Mar 2012 08:02:27 +0000 (16:02 +0800)
- Combined user and kernel ELF relocation code
- Enabled -ffreestanding for Kernel
- NOTE: Possible race condition in kernel relocation

KernelLand/Kernel/Makefile
KernelLand/Kernel/arch/x86/kpanic.c
KernelLand/Kernel/arch/x86/mm_virt.c
KernelLand/Kernel/bin/elf.c
KernelLand/Kernel/binary.c
KernelLand/Kernel/vfs/mmap.c
Usermode/Libraries/ld-acess.so_src/elf.c
Usermode/Libraries/ld-acess.so_src/elf32.h

index da0ecb7..81a2928 100644 (file)
@@ -24,7 +24,7 @@ endif
 ASFLAGS         += -D ARCHDIR_IS_$(ARCHDIR)=1 -D PLATFORM_is_$(PLATFORM)=1
 CPPFLAGS       += -I./include -I./arch/$(ARCHDIR)/include -D_MODULE_NAME_=\"Kernel\"
 CPPFLAGS       += -D ARCH=$(ARCH) -D ARCHDIR=$(ARCHDIR) -D PLATFORM=\"$(PLATFORM)\" -D ARCHDIR_IS_$(ARCHDIR)=1 -D PLATFORM_is_$(PLATFORM)=1
-CPPFLAGS       += -D KERNEL_VERSION=$(KERNEL_VERSION)
+CPPFLAGS       += -D KERNEL_VERSION=$(KERNEL_VERSION) -ffreestanding
 CFLAGS         += -Wall -fno-stack-protector -Wstrict-prototypes -g
 CFLAGS         += -Wshadow -Wpointer-arith -Wcast-align -Wwrite-strings -Wmissing-prototypes -Wmissing-declarations -Wredundant-decls -Wnested-externs -Winline -Wuninitialized
 CFLAGS          += -O3
index 3e2ccac..bf18aa8 100644 (file)
@@ -87,7 +87,7 @@ void KernelPanic_SetMode(void)
        if( giKP_Pos )  return ;
        
        // Restore VGA 0xB8000 text mode
-       #if 1
+       #if 0
        for( i = 0; i < NUM_REGVALUES; i++ )
        {
                // Reset Flip-Flop
@@ -153,4 +153,10 @@ void KernelPanic_PutChar(char Ch)
                giKP_Pos ++;
                break;
        }
+       #if 0
+       {
+               char    s[2] = {Ch,0};
+               VT_int_PutString(gpVT_CurTerm, s);
+       }
+       #endif
 }
index c17b57b..e96b627 100644 (file)
@@ -441,7 +441,8 @@ int MM_Map(tVAddr VAddr, tPAddr PAddr)
        //ENTER("xVAddr xPAddr", VAddr, PAddr);
        // Sanity check
        if( PAddr & 0xFFF || VAddr & 0xFFF ) {
-               Log_Warning("MM_Virt", "MM_Map - Physical or Virtual Addresses are not aligned");
+               Log_Warning("MM_Virt", "MM_Map - Physical or Virtual Addresses are not aligned (0x%P and %p)",
+                       PAddr, VAddr);
                //LEAVE('i', 0);
                return 0;
        }
index 8f51290..31178e3 100644 (file)
@@ -5,7 +5,21 @@
 #define DEBUG  0\r
 #include <acess.h>\r
 #include <binary.h>\r
-#include "elf.h"\r
+\r
+#define _COMMON_H\r
+#define SysDebug(...)  LOG(v)\r
+#define DISABLE_ELF64\r
+void   *GetSymbol(const char *Name, size_t *Size);\r
+void   *GetSymbol(const char *Name, size_t *Size) { Uint val; Binary_GetSymbol(Name, &val); if(Size)*Size=0; return (void*)val; };\r
+#define AddLoaded(a,b) do{}while(0)\r
+#define LoadLibrary(a,b,c)     0\r
+#if __STDC_HOSTED__\r
+#warning "Hosted? why!"\r
+#else\r
+#warning "freestanding - outstanding!"\r
+#endif\r
+\r
+#include "../../../Usermode/Libraries/ld-acess.so_src/elf.c"\r
 \r
 #define DEBUG_WARN     1\r
 \r
@@ -14,9 +28,7 @@ tBinary       *Elf_Load(int fp);
 tBinary        *Elf_Load64(int fp, Elf64_Ehdr *hdr);\r
 tBinary        *Elf_Load32(int fp, Elf32_Ehdr *hdr);\r
  int   Elf_Relocate(void *Base);\r
- int   Elf_Relocate32(void *Base);\r
- int   Elf_GetSymbol(void *Base, const char *Name, Uint *ret);\r
- int   Elf_Int_DoRelocate(Uint r_info, Uint32 *ptr, Uint32 addend, Elf32_Sym *symtab, Uint base);\r
+ int   Elf_GetSymbol(void *Base, const char *Name, Uint *Ret);\r
 Uint   Elf_Int_HashString(const char *str);\r
 \r
 // === GLOBALS ===\r
@@ -283,361 +295,12 @@ tBinary *Elf_Load32(int FD, Elf32_Ehdr *Header)
        return ret;\r
 }\r
 \r
-// --- ELF RELOCATION ---\r
 int Elf_Relocate(void *Base)\r
 {\r
-       Elf64_Ehdr      *hdr = Base;\r
-       \r
-       switch( hdr->e_ident[EI_CLASS] )\r
-       {\r
-       case ELFCLASS32:\r
-               return Elf_Relocate32(Base);\r
-       case ELFCLASS64:\r
-               return 0;\r
-       default:\r
-               return 1;\r
-       }\r
-}\r
-\r
-\r
-/**\r
- * \brief Relocates a loaded ELF Executable\r
- */\r
-int Elf_Relocate32(void *Base)\r
-{\r
-       Elf32_Ehdr      *hdr = Base;\r
-       Elf32_Phdr      *phtab;\r
-        int    i, j;   // Counters\r
-       char    *libPath;\r
-       Uint    iRealBase = -1;\r
-       Uint    iBaseDiff;\r
-        int    iSegmentCount;\r
-        int    iSymCount = 0;\r
-       Elf32_Rel       *rel = NULL;\r
-       Elf32_Rela      *rela = NULL;\r
-       Uint32  *pltgot = NULL;\r
-       void    *plt = NULL;\r
-       Uint32  *ptr;\r
-        int    relSz=0, relEntSz=8;\r
-        int    relaSz=0, relaEntSz=8;\r
-        int    pltSz=0, pltType=0;\r
-       Elf32_Dyn       *dynamicTab = NULL;     // Dynamic Table Pointer\r
-       char    *dynstrtab = NULL;      // .dynamic String Table\r
-       Elf32_Sym       *dynsymtab = NULL;\r
-        int    bFailed = 0;\r
-       \r
-       ENTER("pBase", Base);\r
-       \r
-       // Parse Program Header to get Dynamic Table\r
-       phtab = (void *)( (tVAddr)Base + hdr->phoff );\r
-       iSegmentCount = hdr->phentcount;\r
-       for(i = 0; i < iSegmentCount; i ++ )\r
-       {\r
-               // Determine linked base address\r
-               if(phtab[i].Type == PT_LOAD && iRealBase > phtab[i].VAddr)\r
-                       iRealBase = phtab[i].VAddr;\r
-               \r
-               // Find Dynamic Section\r
-               if(phtab[i].Type == PT_DYNAMIC) {\r
-                       if(dynamicTab) {\r
-                               Log_Warning("ELF", "Elf_Relocate - Multiple PT_DYNAMIC segments\n");\r
-                               continue;\r
-                       }\r
-                       dynamicTab = (void *) (tVAddr) phtab[i].VAddr;\r
-                       j = i;  // Save Dynamic Table ID\r
-                       break;\r
-               }\r
-       }\r
-       \r
-       // Check if a PT_DYNAMIC segement was found\r
-       if(!dynamicTab) {\r
-               Log_Warning("ELF", "Elf_Relocate: No PT_DYNAMIC segment in image, returning\n");\r
-               LEAVE('x', 0);\r
-               return 0;\r
-       }\r
-       \r
-       // Page Align real base\r
-       iRealBase &= ~0xFFF;\r
-       \r
-       // Adjust "Real" Base\r
-       iBaseDiff = (Uint)Base - iRealBase;\r
-       // Adjust Dynamic Table\r
-       dynamicTab = (void *) ((Uint)dynamicTab + iBaseDiff);\r
-       \r
-       // === Get Symbol table and String Table ===\r
-       for( j = 0; dynamicTab[j].d_tag != DT_NULL; j++)\r
-       {\r
-               switch(dynamicTab[j].d_tag)\r
-               {\r
-               // --- Symbol Table ---\r
-               case DT_SYMTAB:\r
-                       dynamicTab[j].d_val += iBaseDiff;\r
-                       dynsymtab = (void*) (tVAddr) dynamicTab[j].d_val;\r
-                       hdr->misc.SymTable = dynamicTab[j].d_val;       // Saved in unused bytes of ident\r
-                       break;\r
-               \r
-               // --- String Table ---\r
-               case DT_STRTAB:\r
-                       dynamicTab[j].d_val += iBaseDiff;\r
-                       dynstrtab = (void*) (tVAddr) dynamicTab[j].d_val;\r
-                       break;\r
-               \r
-               // --- Hash Table --\r
-               case DT_HASH:\r
-                       dynamicTab[j].d_val += iBaseDiff;\r
-                       iSymCount = ((Uint*)((tVAddr)dynamicTab[j].d_val))[1];\r
-                       hdr->misc.HashTable = dynamicTab[j].d_val;      // Saved in unused bytes of ident\r
-                       break;\r
-               }\r
-       }\r
-\r
-       if( !dynsymtab && iSymCount > 0 ) {\r
-               Log_Warning("ELF", "Elf_Relocate: No Dynamic symbol table, but count >0");\r
-               return 0;\r
-       }\r
-\r
-       // Alter Symbols to true base\r
-       for(i = 0; i < iSymCount; i ++)\r
-       {\r
-               dynsymtab[i].value += iBaseDiff;\r
-               dynsymtab[i].nameOfs += (Uint)dynstrtab;\r
-               //LOG("Sym '%s' = 0x%x (relocated)\n", dynsymtab[i].name, dynsymtab[i].value);\r
-       }\r
-       \r
-       // === Add to loaded list (can be imported now) ===\r
-       //Binary_AddLoaded( (Uint)Base );\r
-\r
-       // === Parse Relocation Data ===\r
-       for( j = 0; dynamicTab[j].d_tag != DT_NULL; j++)\r
-       {\r
-               switch(dynamicTab[j].d_tag)\r
-               {\r
-               // --- Shared Library Name ---\r
-               case DT_SONAME:\r
-                       LOG(".so Name '%s'\n", dynstrtab+dynamicTab[j].d_val);\r
-                       break;\r
-               // --- Needed Library ---\r
-               case DT_NEEDED:\r
-                       libPath = dynstrtab + dynamicTab[j].d_val;\r
-                       Log_Notice("ELF", "%p - Required Library '%s' (Ignored in kernel mode)\n", Base, libPath);\r
-                       break;\r
-               // --- PLT/GOT ---\r
-               case DT_PLTGOT: pltgot = (void*)(iBaseDiff+dynamicTab[j].d_val);        break;\r
-               case DT_JMPREL: plt = (void*)(iBaseDiff+dynamicTab[j].d_val);   break;\r
-               case DT_PLTREL: pltType = dynamicTab[j].d_val;  break;\r
-               case DT_PLTRELSZ:       pltSz = dynamicTab[j].d_val;    break;\r
-               \r
-               // --- Relocation ---\r
-               case DT_REL:    rel = (void*)(iBaseDiff + dynamicTab[j].d_val); break;\r
-               case DT_RELSZ:  relSz = dynamicTab[j].d_val;    break;\r
-               case DT_RELENT: relEntSz = dynamicTab[j].d_val; break;\r
-               \r
-               case DT_RELA:   rela = (void*)(iBaseDiff + dynamicTab[j].d_val);        break;\r
-               case DT_RELASZ: relaSz = dynamicTab[j].d_val;   break;\r
-               case DT_RELAENT:        relaEntSz = dynamicTab[j].d_val;        break;\r
-               }\r
-       }\r
-       \r
-       // Parse Relocation Entries\r
-       if(rel && relSz)\r
-       {\r
-               j = relSz / relEntSz;\r
-               for( i = 0; i < j; i++ )\r
-               {\r
-                       ptr = (void*)(iBaseDiff + rel[i].r_offset);\r
-                       if( !Elf_Int_DoRelocate(rel[i].r_info, ptr, *ptr, dynsymtab, (Uint)Base) ) {\r
-                               bFailed = 1;\r
-                       }\r
-               }\r
-       }\r
-       // Parse Relocation Entries\r
-       if(rela && relaSz)\r
-       {\r
-               j = relaSz / relaEntSz;\r
-               for( i = 0; i < j; i++ )\r
-               {\r
-                       ptr = (void*)(iBaseDiff + rela[i].r_offset);\r
-                       if( !Elf_Int_DoRelocate(rela[i].r_info, ptr, rela[i].r_addend, dynsymtab, (Uint)Base) ) {\r
-                               bFailed = 1;\r
-                       }\r
-               }\r
-       }\r
-       \r
-       // === Process PLT (Procedure Linkage Table) ===\r
-       if(plt && pltSz)\r
-       {\r
-               if(pltType == DT_REL)\r
-               {\r
-                       Elf32_Rel       *pltRel = plt;\r
-                       j = pltSz / sizeof(Elf32_Rel);\r
-                       LOG("PLT Rel - plt = %p, pltSz = %i (%i ents)", plt, pltSz, j);\r
-                       for(i = 0; i < j; i++)\r
-                       {\r
-                               ptr = (void*)(iBaseDiff + pltRel[i].r_offset);\r
-                               if( !Elf_Int_DoRelocate(pltRel[i].r_info, ptr, *ptr, dynsymtab, (Uint)Base) ) {\r
-                                       bFailed = 1;\r
-                               }\r
-                       }\r
-               }\r
-               else\r
-               {\r
-                       Elf32_Rela      *pltRela = plt;\r
-                       j = pltSz / sizeof(Elf32_Rela);\r
-                       LOG("PLT RelA - plt = %p, pltSz = %i (%i ents)", plt, pltSz, j);\r
-                       for(i=0;i<j;i++)\r
-                       {\r
-                               ptr = (void*)(iBaseDiff + pltRela[i].r_offset);\r
-                               if( !Elf_Int_DoRelocate(pltRela[i].r_info, ptr, pltRela[i].r_addend, dynsymtab, (Uint)Base) ) {\r
-                                       bFailed = 1;\r
-                               }\r
-                       }\r
-               }\r
-       }\r
-       \r
-       if(bFailed) {\r
-               LEAVE('i', 0);\r
-               return 0;\r
-       }\r
-       \r
-       LEAVE('x', 1);\r
-       return 1;\r
-}\r
-\r
-/**\r
- * \fn void Elf_Int_DoRelocate(Uint r_info, Uint32 *ptr, Uint32 addend, Elf32_Sym *symtab, Uint base)\r
- * \brief Performs a relocation\r
- * \param r_info       Field from relocation entry\r
- * \param ptr  Pointer to location of relocation\r
- * \param addend       Value to add to symbol\r
- * \param symtab       Symbol Table\r
- * \param base Base of loaded binary\r
- */\r
-int Elf_Int_DoRelocate(Uint r_info, Uint32 *ptr, Uint32 addend, Elf32_Sym *symtab, Uint base)\r
-{\r
-       Uint    val;\r
-        int    type = ELF32_R_TYPE(r_info);\r
-        int    sym = ELF32_R_SYM(r_info);\r
-       char    *sSymName = symtab[sym].name;\r
-       \r
-       //LogF("Elf_Int_DoRelocate: (r_info=0x%x, ptr=0x%x, addend=0x%x, .., base=0x%x)\n",\r
-       //      r_info, ptr, addend, base);\r
-       \r
-       switch( type )\r
-       {\r
-       // Standard 32 Bit Relocation (S+A)\r
-       case R_386_32:\r
-               if( !Elf_GetSymbol((void*)base, sSymName, &val) )       // Search this binary first\r
-                       if( !Binary_GetSymbol( sSymName, &val ) )\r
-                               return 0;\r
-               LOG("%08x R_386_32 *0x%x += 0x%x('%s')", r_info, ptr, val, sSymName);\r
-               *ptr = val + addend;\r
-               break;\r
-               \r
-       // 32 Bit Relocation wrt. Offset (S+A-P)\r
-       case R_386_PC32:\r
-               if( !Elf_GetSymbol( (void*)base, sSymName, &val ) )\r
-                       if( !Binary_GetSymbol( sSymName, &val ) )\r
-                               return 0;\r
-               LOG("%08x R_386_PC32 *0x%x = 0x%x + 0x%x('%s') - 0x%x", r_info, ptr, *ptr, val, sSymName, (Uint)ptr );\r
-               // TODO: Check if it needs the true value of ptr or the compiled value\r
-               // NOTE: Testing using true value\r
-               *ptr = val + addend - (Uint)ptr;\r
-               break;\r
-\r
-       // Absolute Value of a symbol (S)\r
-       case R_386_GLOB_DAT:\r
-               if( !Elf_GetSymbol( (void*)base, sSymName, &val ) )\r
-                       if( !Binary_GetSymbol( sSymName, &val ) )\r
-                               return 0;\r
-               LOG("%08x R_386_GLOB_DAT *0x%x = 0x%x (%s)", r_info, ptr, val, sSymName);\r
-               *ptr = val;\r
-               break;\r
-       \r
-       // Absolute Value of a symbol (S)\r
-       case R_386_JMP_SLOT:\r
-               if( !Elf_GetSymbol( (void*)base, sSymName, &val ) )\r
-                       if( !Binary_GetSymbol( sSymName, &val ) )\r
-                               return 0;\r
-               LOG("%08x R_386_JMP_SLOT *0x%x = 0x%x (%s)", r_info, ptr, val, sSymName);\r
-               *ptr = val;\r
-               break;\r
-\r
-       // Base Address (B+A)\r
-       case R_386_RELATIVE:\r
-               LOG("%08x R_386_RELATIVE *0x%x = 0x%x + 0x%x", r_info, ptr, base, addend);\r
-               *ptr = base + addend;\r
-               break;\r
-               \r
-       default:\r
-               LOG("Rel 0x%x: 0x%x,%i", ptr, sym, type);\r
-               break;\r
-       }\r
-       return 1;\r
+       return  ElfRelocate(Base, (char**){NULL}, "") != NULL;\r
 }\r
-\r
-/**\r
- * \fn int Elf_GetSymbol(void *Base, const char *name, Uint *ret)\r
- * \brief Get a symbol from the loaded binary\r
- */\r
 int Elf_GetSymbol(void *Base, const char *Name, Uint *ret)\r
 {\r
-       Elf32_Ehdr      *hdr = (void*)Base;\r
-       Elf32_Sym       *symtab;\r
-        int    nbuckets = 0;\r
-        int    iSymCount = 0;\r
-        int    i;\r
-       Uint    *pBuckets;\r
-       Uint    *pChains;\r
-       Uint    iNameHash;\r
-\r
-       if(!Base)       return 0;\r
-\r
-       pBuckets = (void *) hdr->misc.HashTable;\r
-       symtab = (void *) hdr->misc.SymTable;\r
-       \r
-       nbuckets = pBuckets[0];\r
-       iSymCount = pBuckets[1];\r
-       pBuckets = &pBuckets[2];\r
-       pChains = &pBuckets[ nbuckets ];\r
-       \r
-       // Get hash\r
-       iNameHash = Elf_Int_HashString(Name);\r
-       iNameHash %= nbuckets;\r
-\r
-       // Check Bucket\r
-       i = pBuckets[ iNameHash ];\r
-       if(symtab[i].shndx != SHN_UNDEF && strcmp(symtab[i].name, Name) == 0) {\r
-               if(ret) *ret = symtab[ i ].value;\r
-               return 1;\r
-       }\r
-       \r
-       // Walk Chain\r
-       while(pChains[i] != STN_UNDEF)\r
-       {\r
-               i = pChains[i];\r
-               if(symtab[i].shndx != SHN_UNDEF && strcmp(symtab[ i ].name, Name) == 0) {\r
-                       if(ret) *ret = symtab[ i ].value;\r
-                       return 1;\r
-               }\r
-       }\r
-       return 0;\r
+       return ElfGetSymbol(Base, Name, (void**)ret, NULL);\r
 }\r
 \r
-/**\r
- * \fn Uint Elf_Int_HashString(char *str)\r
- * \brief Hash a string in the ELF format\r
- * \param str  String to hash\r
- * \return Hash value\r
- */\r
-Uint Elf_Int_HashString(const char *str)\r
-{\r
-       Uint    h = 0, g;\r
-       while(*str)\r
-       {\r
-               h = (h << 4) + *str++;\r
-               if( (g = h & 0xf0000000) )\r
-                       h ^= g >> 24;\r
-               h &= ~g;\r
-       }\r
-       return h;\r
-}\r
index 5213bf2..e72de28 100644 (file)
@@ -406,7 +406,10 @@ tVAddr Binary_MapIn(tBinary *Binary, const char *Path, tVAddr LoadMin, tVAddr Lo
                        for( i = 0; i < Binary->NumSections; i ++ )
                        {
                                tVAddr  addr = Binary->LoadSections[i].Virtual - Binary->Base + base;
-                               if( Binary_int_CheckMemFree( addr, Binary->LoadSections[i].MemSize ) )
+                               size_t  size = Binary->LoadSections[i].MemSize;
+                               if( addr + size > LoadMax )
+                                       break;
+                               if( Binary_int_CheckMemFree( addr, size ) )
                                        break;
                        }
                        // If space was found, break
@@ -425,13 +428,16 @@ tVAddr Binary_MapIn(tBinary *Binary, const char *Path, tVAddr LoadMin, tVAddr Lo
        }
        
        // Map Executable In
-       fd = VFS_OpenInode(Binary->MountID, Binary->Inode, VFS_OPENFLAG_READ);
+       if( Binary->MountID )
+               fd = VFS_OpenInode(Binary->MountID, Binary->Inode, VFS_OPENFLAG_READ);
+       else
+               fd = VFS_Open(Path, VFS_OPENFLAG_READ);
        for( i = 0; i < Binary->NumSections; i ++ )
        {
                tBinarySection  *sect = &Binary->LoadSections[i];
                Uint    protflags, mapflags;
                tVAddr  addr = sect->Virtual - Binary->Base + base;
-               LOG("%i - %p to offset 0x%llx (%x)", i, addr, sect->Offset, sect->Flags);
+               LOG("%i - %p, 0x%x bytes from offset 0x%llx (%x)", i, addr, sect->FileSize, sect->Offset, sect->Flags);
 
                protflags = MMAP_PROT_READ;
                mapflags = MMAP_MAP_FIXED;
@@ -508,7 +514,14 @@ tBinary *Binary_DoLoad(tMount MountID, tInode Inode, const char *Path)
        ENTER("iMountID XInode sPath", MountID, Inode, Path);
        
        // Open File
-       fp = VFS_OpenInode(MountID, Inode, VFS_OPENFLAG_READ);
+       if( MountID )
+       {
+               fp = VFS_OpenInode(MountID, Inode, VFS_OPENFLAG_READ);
+       }
+       else
+       {
+               fp = VFS_Open(Path, VFS_OPENFLAG_READ);
+       }
        if(fp == -1) {
                LOG("Unable to load file, access denied");
                LEAVE('n');
@@ -697,6 +710,7 @@ void *Binary_LoadKernel(const char *File)
                int fd = VFS_Open(File, VFS_OPENFLAG_READ);
                tFInfo  info;
                if(fd == -1) {
+                       LOG("Opening failed");
                        LEAVE('n');
                        return NULL;
                }
@@ -704,6 +718,7 @@ void *Binary_LoadKernel(const char *File)
                mount_id = info.mount;
                inode = info.inode;
                VFS_Close(fd);
+               LOG("Mount %i, Inode %lli", mount_id, inode);
        }
        
        // Check if the binary has already been loaded
@@ -714,6 +729,7 @@ void *Binary_LoadKernel(const char *File)
                        pKBinary = pKBinary->Next )
                {
                        if(pKBinary->Info == pBinary) {
+                               LOG("Already loaded");
                                LEAVE('p', pKBinary->Base);
                                return pKBinary->Base;
                        }
@@ -728,6 +744,7 @@ void *Binary_LoadKernel(const char *File)
                return NULL;
        }
        
+       LOG("Loaded as %p", pBinary);
        // --------------
        // Now pBinary is valid (either freshly loaded or only user mapped)
        // So, map it into kernel space
@@ -736,19 +753,14 @@ void *Binary_LoadKernel(const char *File)
        // Reference Executable (Makes sure that it isn't unloaded)
        pBinary->ReferenceCount ++;
 
-       Binary_MapIn(pBinary, File, KLIB_LOWEST, KLIB_HIGHEST);
-
-       // Relocate Library
-       if( !Binary_Relocate( (void*)base ) )
-       {
-               Log_Warning("Binary", "Relocation of '%s' failed, unloading", File);
-               Binary_Unload( (void*)base );
-               Binary_Dereference( pBinary );
+       base = Binary_MapIn(pBinary, File, KLIB_LOWEST, KLIB_HIGHEST);
+       if( base == 0 ) {
                LEAVE('n');
                return 0;
        }
-       
-       // Add to list (relocator must look at itself manually, not via Binary_GetSymbol)
+
+       // Add to list
+       // TODO: Could this cause race conditions if a binary isn't fully loaded when used
        pKBinary = malloc(sizeof(*pKBinary));
        pKBinary->Base = (void*)base;
        pKBinary->Info = pBinary;
@@ -757,6 +769,16 @@ void *Binary_LoadKernel(const char *File)
        glLoadedKernelLibs = pKBinary;
        SHORTREL( &glKBinListLock );
        
+       // Relocate Library
+       if( !Binary_Relocate( (void*)base ) )
+       {
+               Log_Warning("Binary", "Relocation of '%s' failed, unloading", File);
+               Binary_Unload( (void*)base );
+               Binary_Dereference( pBinary );
+               LEAVE('n');
+               return 0;
+       }
+       
        LEAVE('p', base);
        return (void*)base;
 }
@@ -772,7 +794,7 @@ Uint Binary_Relocate(void *Base)
        Uint32  ident = *(Uint32*) Base;
        tBinaryType     *bt = gRegBinTypes;
        
-       for(; bt; bt = bt->Next)
+       for( ; bt; bt = bt->Next)
        {
                if( (ident & bt->Mask) == (Uint)bt->Ident )
                        return bt->Relocate( (void*)Base);
@@ -862,15 +884,23 @@ Uint Binary_FindSymbol(void *Base, const char *Name, Uint *Val)
  */
 int Binary_int_CheckMemFree( tVAddr _start, size_t _len )
 {
+       ENTER("p_start x_len", _start, _len);
+
        _len += _start & (PAGE_SIZE-1);
        _len = (_len + PAGE_SIZE - 1) & ~(PAGE_SIZE-1);
        _start &= ~(PAGE_SIZE-1);
+       LOG("_start = %p, _len = 0x%x", _start, _len);
        for( ; _len > PAGE_SIZE; _len -= PAGE_SIZE, _start += PAGE_SIZE ) {
-               if( MM_GetPhysAddr(_start) != 0 )
+               if( MM_GetPhysAddr(_start) != 0 ) {
+                       LEAVE('i', 1);
                        return 1;
+               }
        }
-       if( _len == PAGE_SIZE && MM_GetPhysAddr(_start) != 0 )
+       if( _len == PAGE_SIZE && MM_GetPhysAddr(_start) != 0 ) {
+               LEAVE('i', 1);
                return 1;
+       }
+       LEAVE('i', 0);
        return 0;
 }
 
index 9fe9282..6128869 100644 (file)
@@ -93,14 +93,13 @@ void *VFS_MMap(void *DestHint, size_t Length, int Protection, int Flags, int FD,
        if( !pb || pb->BaseOffset > pagenum )
        {
                void    *old_pb = pb;
-               pb = malloc( sizeof(tVFS_MMapPageBlock) );
+               pb = calloc( 1, sizeof(tVFS_MMapPageBlock) );
                if(!pb) {
                        Mutex_Release( &h->Node->Lock );
                        LEAVE_RET('n', NULL);
                }
                pb->Next = old_pb;
                pb->BaseOffset = pagenum - pagenum % MMAP_PAGES_PER_BLOCK;
-               memset(pb->PhysAddrs, 0, sizeof(pb->PhysAddrs));
                if(prev)
                        prev->Next = pb;
                else
@@ -194,7 +193,6 @@ void *VFS_MMap(void *DestHint, size_t Length, int Protection, int Flags, int FD,
                                memset(pb->PhysAddrs, 0, sizeof(pb->PhysAddrs));
                                oldpb->Next = pb;
                        }
-                       pagenum = 0;
                }
        }
        
index 995d5ea..bbe45d6 100644 (file)
@@ -18,9 +18,9 @@
 # define       DEBUGS(...)     
 #endif
 
-//#if BITS > 32
+#ifndef DISABLE_ELF64
 # define SUPPORT_ELF64
-//#endif
+#endif
 
 // === CONSTANTS ===
 #if DEBUG
@@ -33,6 +33,8 @@ void  *ElfRelocate(void *Base, char **envp, const char *Filename);
  int   ElfGetSymbol(void *Base, const char *Name, void **Ret, size_t *Size);
 void   *Elf32Relocate(void *Base, char **envp, const char *Filename);
  int   Elf32GetSymbol(void *Base, const char *Name, void **Ret, size_t *Size);
+void   elf_doRelocate_386(uint32_t r_info, uint32_t *ptr, Elf32_Addr addend, int type, int bRela, const char *Sym, intptr_t iBaseDiff);
+void   elf_doRelocate_arm(uint32_t r_info, uint32_t *ptr, Elf32_Addr addend, int type, int bRela, const char *Sym, intptr_t iBaseDiff);
 #ifdef SUPPORT_ELF64
 void   *Elf64Relocate(void *Base, char **envp, const char *Filename);
  int   Elf64GetSymbol(void *Base, const char *Name, void **Ret, size_t *Size);
@@ -199,6 +201,7 @@ void *Elf32Relocate(void *Base, char **envp, const char *Filename)
        char    *dynstrtab = NULL;      // .dynamic String Table
        Elf32_Sym       *dynsymtab;
        void    (*do_relocate)(uint32_t t_info, uint32_t *ptr, Elf32_Addr addend, int Type, int bRela, const char *Sym, intptr_t iBaseDiff);
+       auto void _doRelocate(uint32_t r_info, uint32_t *ptr, int bRela, Elf32_Addr addend);
        
        DEBUGS("ElfRelocate: (Base=0x%x)", Base);
        
@@ -206,7 +209,7 @@ void *Elf32Relocate(void *Base, char **envp, const char *Filename)
        
        
        // Parse Program Header to get Dynamic Table
-       phtab = Base + hdr->phoff;
+       phtab = (void*)( (uintptr_t)Base + hdr->phoff );
        iSegmentCount = hdr->phentcount;
        for(i=0;i<iSegmentCount;i++)
        {
@@ -420,20 +423,19 @@ void *Elf32Relocate(void *Base, char **envp, const char *Filename)
 int Elf32GetSymbol(void *Base, const char *Name, void **ret, size_t *Size)
 {
        Elf32_Ehdr      *hdr = Base;
-       Elf32_Sym       *symtab;
+       Elf32_Sym       *symtab = NULL;
         int    nbuckets = 0;
-//      int    iSymCount = 0;
-        int    i;
-       Elf32_Word      *pBuckets;
+       Elf32_Word      *pBuckets = NULL;
        Elf32_Word      *pChains;
        uint32_t        iNameHash;
-       const char      *dynstrtab;
+       const char      *dynstrtab = NULL;
        uintptr_t       iBaseDiff = -1;
        Elf32_Phdr      *phtab;
        Elf32_Dyn       *dynTab = NULL;
+        int    i;
 
        // Locate the tables
-       phtab = (void*)( Base + hdr->phoff );
+       phtab = (void*)( (uintptr_t)Base + hdr->phoff );
        for( i = 0; i < hdr->phentcount; i ++ )
        {
                if(phtab[i].Type == PT_LOAD && iBaseDiff > phtab[i].VAddr)
@@ -466,6 +468,19 @@ int Elf32GetSymbol(void *Base, const char *Name, void **ret, size_t *Size)
                }
        }
        
+       if( !symtab ) {
+               SysDebug("ERRO - No DT_SYMTAB in %p", Base);
+               return 0;
+       }
+       if( !pBuckets ) {
+               SysDebug("ERRO - No DT_HASH in %p", Base);
+               return 0;
+       }
+       if( !dynstrtab ) {
+               SysDebug("ERRO - No DT_STRTAB in %p", Base);
+               return 0;
+       }
+
        nbuckets = pBuckets[0];
 //     iSymCount = pBuckets[1];
        pBuckets = &pBuckets[2];
@@ -478,7 +493,7 @@ int Elf32GetSymbol(void *Base, const char *Name, void **ret, size_t *Size)
        // Walk Chain
        i = pBuckets[ iNameHash ];
        if(symtab[i].shndx != SHN_UNDEF && strcmp(dynstrtab + symtab[i].nameOfs, Name) == 0) {
-               *ret = (void*) (intptr_t) symtab[ i ].value + iBaseDiff;
+               *ret = (void*)( (uintptr_t) symtab[ i ].value + iBaseDiff );
                if(Size)        *Size = symtab[i].size;
                return 1;
        }
@@ -487,7 +502,7 @@ int Elf32GetSymbol(void *Base, const char *Name, void **ret, size_t *Size)
        {
                i = pChains[i];
                if(symtab[i].shndx != SHN_UNDEF && strcmp(dynstrtab + symtab[ i ].nameOfs, Name) == 0) {
-                       *ret = (void*)(intptr_t)symtab[ i ].value + iBaseDiff;
+                       *ret = (void*)( (uintptr_t)symtab[ i ].value + iBaseDiff );
                        if(Size)        *Size = symtab[i].size;
                        return 1;
                }
@@ -745,7 +760,7 @@ int Elf64GetSymbol(void *Base, const char *Name, void **Ret, size_t *Size)
                 int    j;
                
                // Locate the tables
-               phtab = (void*)( Base + hdr->e_phoff );
+               phtab = (void*)( (intptr_t)Base + hdr->e_phoff );
                for( i = 0; i < hdr->e_phnum; i ++ )
                {
                        if(phtab[i].p_type == PT_LOAD && iBaseDiff > phtab[i].p_vaddr)
@@ -792,7 +807,7 @@ int Elf64GetSymbol(void *Base, const char *Name, void **Ret, size_t *Size)
        // Walk Chain
        i = pBuckets[ iNameHash ];
        if(symtab[i].st_shndx != SHN_UNDEF && strcmp(dynstrtab + symtab[i].st_name, Name) == 0) {
-               *Ret = (void*) (intptr_t) symtab[i].st_value + iBaseDiff;
+               *Ret = (void*)( (intptr_t)symtab[i].st_value + iBaseDiff );
                if(Size)        *Size = symtab[i].st_size;
                DEBUGS("%s = %p", Name, *Ret);
                return 1;
@@ -802,7 +817,7 @@ int Elf64GetSymbol(void *Base, const char *Name, void **Ret, size_t *Size)
        {
                i = pChains[i];
                if(symtab[i].st_shndx != SHN_UNDEF && strcmp(dynstrtab + symtab[i].st_name, Name) == 0) {
-                       *Ret = (void*)(intptr_t)symtab[i].st_value + iBaseDiff;
+                       *Ret = (void*)((intptr_t)symtab[i].st_value + iBaseDiff);
                        if(Size)        *Size = symtab[i].st_size;
                        DEBUGS("%s = %p", Name, *Ret);
                        return 1;
index 3018a89..2e9c1c4 100644 (file)
@@ -133,6 +133,10 @@ enum {
        PT_HIPROC = 0x7fffffff
 };
 
+#define PF_X   1
+#define PF_W   2
+#define PF_R   4
+
 struct sElf32_Phdr {
        Elf32_Word      Type;
        Elf32_Off       Offset;

UCC git Repository :: git.ucc.asn.au