Usermode/ld-acess - Fixing elf64 support (and x86-64)
[tpg/acess2.git] / Usermode / Libraries / ld-acess.so_src / loadlib.c
index 5cfa26e..9a1bc10 100644 (file)
-/*\r
- AcessOS 1 - Dynamic Loader\r
- By thePowersGang\r
-*/\r
-#include "common.h"\r
-\r
-#define DEBUG  0\r
-\r
-#if DEBUG\r
-# define DEBUGS(v...)  SysDebug(v)\r
-#else\r
-# define DEBUGS(v...)  \r
-#endif\r
-\r
-// === CONSTANTS ===\r
-#define        MAX_LOADED_LIBRARIES    64\r
-#define        MAX_STRINGS_BYTES       4096\r
-#define        SYSTEM_LIB_DIR  "/Acess/Libs/"\r
-\r
-// === PROTOTYPES ===\r
-Uint   IsFileLoaded(char *file);
- int   GetSymbolFromBase(Uint base, char *name, Uint *ret);\r
-\r
-// === GLOABLS ===\r
-struct {\r
-       Uint    Base;\r
-       char    *Name;\r
-}      gLoadedLibraries[MAX_LOADED_LIBRARIES];\r
-char   gsLoadedStrings[MAX_STRINGS_BYTES];\r
-char   *gsNextAvailString = gsLoadedStrings;\r
-//tLoadLib     *gpLoadedLibraries = NULL;\r
-\r
-// === CODE ===\r
-char *FindLibrary(char *DestBuf, char *SoName, char *ExtraSearchDir)\r
-{      \r
-       // -- #1: Executable Specified\r
-       if(ExtraSearchDir)\r
-       {\r
-               strcpy(DestBuf, ExtraSearchDir);\r
-               strcat(DestBuf, "/");\r
-               strcat(DestBuf, SoName);\r
-               if(file_exists(DestBuf))        return DestBuf;\r
-       }\r
-       \r
-       // -- #2: System\r
-       strcpy(DestBuf, SYSTEM_LIB_DIR);\r
-       strcat(DestBuf, SoName);\r
-       if(file_exists(DestBuf))        return DestBuf;\r
-       \r
-       // -- #3: Current Directory\r
-       if(file_exists(SoName)) return SoName;\r
-       \r
-       return NULL;\r
-}\r
-\r
-/**\r
- */\r
-Uint LoadLibrary(char *SoName, char *SearchDir, char **envp)\r
-{\r
-       char    sTmpName[1024];\r
-       char    *filename;\r
-       Uint    iArg;\r
-       void    (*fEntry)(int, int, char *[], char**);\r
-       \r
-       DEBUGS("LoadLibrary: (filename='%s', envp=0x%x)\n", filename, envp);\r
-       \r
-       // Create Temp Name\r
-       filename = FindLibrary(sTmpName, SoName, SearchDir);\r
-       if(filename == NULL) {\r
-               DEBUGS("LoadLibrary: RETURN 0\n");\r
-               return 0;\r
-       }\r
-       DEBUGS(" LoadLibrary: filename='%s'\n", filename);\r
-       \r
-       if( (iArg = IsFileLoaded(filename)) )\r
-               return iArg;\r
-       \r
-       // Load Library\r
-       iArg = SysLoadBin(filename, (Uint*)&fEntry);\r
-       if(iArg == 0) {\r
-               DEBUGS("LoadLibrary: RETURN 0\n");\r
-               return 0;\r
-       }\r
-       \r
-       DEBUGS(" LoadLibrary: iArg=0x%x, iEntry=0x%x\n", iArg, fEntry);\r
-       \r
-       // Load Symbols\r
-       fEntry = (void*)DoRelocate( iArg, envp, filename );\r
-       \r
-       // Call Entrypoint\r
-       DEBUGS(" LoadLibrary: '%s' Entry 0x%x\n", SoName, fEntry);\r
-       fEntry(iArg, 0, NULL, envp);\r
-       \r
-       DEBUGS("LoadLibrary: RETURN 1\n");\r
-       return iArg;\r
+/*
+ AcessOS 1 - Dynamic Loader
+ By thePowersGang
+*/
+#include "common.h"
+
+#define DEBUG  1
+
+#if DEBUG
+# define DEBUGS(v...)  SysDebug(v)
+#else
+# define DEBUGS(v...)  
+#endif
+
+// === PROTOTYPES ===
+void   *IsFileLoaded(const char *file);
+ int   GetSymbolFromBase(void *base, const char *name, void **ret);
+
+// === IMPORTS ===
+extern const struct {
+       void    *Value;
+       char    *Name;
+}      caLocalExports[];
+extern const int       ciNumLocalExports;
+
+// === GLOABLS ===
+tLoadedLib     gLoadedLibraries[MAX_LOADED_LIBRARIES];
+char   gsLoadedStrings[MAX_STRINGS_BYTES];
+char   *gsNextAvailString = gsLoadedStrings;
+//tLoadLib     *gpLoadedLibraries = NULL;
+
+// === CODE ===
+const char *FindLibrary(char *DestBuf, const char *SoName, const char *ExtraSearchDir)
+{      
+       // -- #1: Executable Specified
+       if(ExtraSearchDir)
+       {
+               strcpy(DestBuf, ExtraSearchDir);
+               strcat(DestBuf, "/");
+               strcat(DestBuf, SoName);
+               if(file_exists(DestBuf))        return DestBuf;
+       }
+       
+       // -- #2: System
+       strcpy(DestBuf, SYSTEM_LIB_DIR);
+       strcat(DestBuf, SoName);
+       if(file_exists(DestBuf))        return DestBuf;
+       
+       // -- #3: Current Directory
+       if(file_exists(SoName)) return SoName;
+       
+       return NULL;
+}
+
+/**
+ */
+void *LoadLibrary(const char *SoName, const char *SearchDir, char **envp)
+{
+       char    sTmpName[1024];
+       const char      *filename;
+       void    *base;
+       void    (*fEntry)(void *, int, char *[], char**);
+       
+       DEBUGS("LoadLibrary: (SoName='%s', SearchDir='%s', envp=0x%x)", SoName, SearchDir, envp);
+       
+       // Create Temp Name
+       filename = FindLibrary(sTmpName, SoName, SearchDir);
+       if(filename == NULL) {
+               DEBUGS("LoadLibrary: RETURN 0");
+               return 0;
+       }
+       DEBUGS(" LoadLibrary: filename='%s'", filename);
+       
+       if( (base = IsFileLoaded(filename)) )
+               return base;
+
+       DEBUGS(" LoadLibrary: SysLoadBin()");   
+       // Load Library
+       base = SysLoadBin(filename, (void**)&fEntry);
+       if(!base) {
+               DEBUGS("LoadLibrary: RETURN 0");
+               return 0;
+       }
+       
+       DEBUGS(" LoadLibrary: iArg=%p, iEntry=0x%x", base, fEntry);
+       
+       // Load Symbols
+       fEntry = DoRelocate( base, envp, filename );
+       
+       // Call Entrypoint
+       DEBUGS(" LoadLibrary: '%s' Entry 0x%x", SoName, fEntry);
+       fEntry(base, 0, NULL, envp);
+       
+       DEBUGS("LoadLibrary: RETURN 1");
+       return base;
+}
+
+/**
+ * \fn Uint IsFileLoaded(char *file)
+ * \brief Determine if a file is already loaded
+ */
+void *IsFileLoaded(const char *file)
+{
+        int    i;
+       DEBUGS("IsFileLoaded: (file='%s')", file);
+       for( i = 0; i < MAX_LOADED_LIBRARIES; i++ )
+       {
+               if(gLoadedLibraries[i].Base == 0)       break;  // Last entry has Base set to NULL
+               DEBUGS(" strcmp('%s', '%s')", gLoadedLibraries[i].Name, file);
+               if(strcmp(gLoadedLibraries[i].Name, file) == 0) {
+                       DEBUGS("IsFileLoaded: Found %i (0x%x)", i, gLoadedLibraries[i].Base);
+                       return gLoadedLibraries[i].Base;
+               }
+       }
+       DEBUGS("IsFileLoaded: Not Found");
+       return 0;
 }
-\r
-/**\r
- * \fn Uint IsFileLoaded(char *file)\r
- * \brief Determine if a file is already loaded\r
- */\r
-Uint IsFileLoaded(char *file)\r
-{\r
-        int    i;\r
-       DEBUGS("IsFileLoaded: (file='%s')", file);\r
-       for( i = 0; i < MAX_LOADED_LIBRARIES; i++ )\r
-       {\r
-               if(gLoadedLibraries[i].Base == 0)       break;  // Last entry has Base set to NULL\r
-               DEBUGS(" strcmp('%s', '%s')", gLoadedLibraries[i].Name, file);\r
-               if(strcmp(gLoadedLibraries[i].Name, file) == 0) {\r
-                       DEBUGS("IsFileLoaded: Found %i (0x%x)", i, gLoadedLibraries[i].Base);\r
-                       return gLoadedLibraries[i].Base;\r
-               }\r
-       }\r
-       DEBUGS("IsFileLoaded: Not Found");\r
-       return 0;\r
-}\r
-\r
-/**\r
- * \fn void AddLoaded(char *File, Uint base)\r
- * \brief Add a file to the loaded list\r
+
+/**
+ * \fn void AddLoaded(char *File, Uint base)
+ * \brief Add a file to the loaded list
  */
-void AddLoaded(char *File, Uint base)
-{\r
-        int    i, length;\r
-       char    *name = gsNextAvailString;\r
-       \r
-       DEBUGS("AddLoaded: (File='%s', base=0x%x)", File, base);\r
-       \r
-       // Find a free slot\r
-       for( i = 0; i < MAX_LOADED_LIBRARIES; i ++ )\r
-       {\r
-               if(gLoadedLibraries[i].Base == 0)       break;\r
-       }\r
-       if(i == MAX_LOADED_LIBRARIES) {\r
-               SysDebug("ERROR - ld-acess.so has run out of load slots!");\r
-               return;\r
-       }\r
-       \r
-       // Check space in string buffer\r
-       length = strlen(File);\r
-       if(&name[length+1] >= &gsLoadedStrings[MAX_STRINGS_BYTES]) {\r
-               SysDebug("ERROR - ld-acess.so has run out of string buffer memory!");\r
-               return;\r
-       }\r
-       \r
-       // Set information\r
-       gLoadedLibraries[i].Base = base;\r
-       strcpy(name, File);\r
-       gLoadedLibraries[i].Name = name;\r
-       gsNextAvailString = &name[length+1];\r
-       DEBUGS("'%s' (0x%x) loaded as %i\n", name, base, i);\r
+void AddLoaded(const char *File, void *base)
+{
+        int    i, length;
+       char    *name = gsNextAvailString;
+       
+       DEBUGS("AddLoaded: (File='%s', base=0x%x)", File, base);
+       
+       // Find a free slot
+       for( i = 0; i < MAX_LOADED_LIBRARIES; i ++ )
+       {
+               if(gLoadedLibraries[i].Base == 0)       break;
+       }
+       if(i == MAX_LOADED_LIBRARIES) {
+               SysDebug("ERROR - ld-acess.so has run out of load slots!");
+               return;
+       }
+       
+       // Check space in string buffer
+       length = strlen(File);
+       if(&name[length+1] >= &gsLoadedStrings[MAX_STRINGS_BYTES]) {
+               SysDebug("ERROR - ld-acess.so has run out of string buffer memory!");
+               return;
+       }
+       
+       // Set information
+       gLoadedLibraries[i].Base = base;
+       strcpy(name, File);
+       gLoadedLibraries[i].Name = name;
+       gsNextAvailString = &name[length+1];
+       DEBUGS("'%s' (0x%x) loaded as %i", name, base, i);
        return;
-}\r
-\r
-/**\r
- * \fn void Unload(Uint Base)\r
- */\r
-void Unload(Uint Base)\r
-{      \r
-        int    i, j;\r
-        int    id;\r
-       char    *str;\r
-       for( id = 0; id < MAX_LOADED_LIBRARIES; id++ )\r
-       {\r
-               if(gLoadedLibraries[id].Base == Base)   break;\r
-       }\r
-       if(id == MAX_LOADED_LIBRARIES)  return;\r
-       \r
-       // Unload Binary\r
-       SysUnloadBin( Base );\r
-       // Save String Pointer\r
-       str = gLoadedLibraries[id].Name;\r
-       \r
-       // Compact Loaded List\r
-       j = id;\r
-       for( i = j + 1; i < MAX_LOADED_LIBRARIES; i++, j++ )\r
-       {\r
-               if(gLoadedLibraries[i].Base == 0)       break;\r
-               // Compact String\r
-               strcpy(str, gLoadedLibraries[i].Name);\r
-               str += strlen(str)+1;\r
-               // Compact Entry\r
-               gLoadedLibraries[j].Base = gLoadedLibraries[i].Base;\r
-               gLoadedLibraries[j].Name = str;\r
-       }\r
-       \r
-       // NULL Last Entry\r
-       gLoadedLibraries[j].Base = 0;\r
-       gLoadedLibraries[j].Name = NULL;\r
-       // Save next string\r
-       gsNextAvailString = str;\r
-}\r
-\r
+}
+
 /**
- \fn Uint GetSymbol(char *name)
+ * \fn void Unload(Uint Base)
+ */
+void Unload(void *Base)
+{      
+        int    i, j;
+        int    id;
+       char    *str;
+       for( id = 0; id < MAX_LOADED_LIBRARIES; id++ )
+       {
+               if(gLoadedLibraries[id].Base == Base)   break;
+       }
+       if(id == MAX_LOADED_LIBRARIES)  return;
+       
+       // Unload Binary
+       SysUnloadBin( Base );
+       // Save String Pointer
+       str = gLoadedLibraries[id].Name;
+       
+       // Compact Loaded List
+       j = id;
+       for( i = j + 1; i < MAX_LOADED_LIBRARIES; i++, j++ )
+       {
+               if(gLoadedLibraries[i].Base == 0)       break;
+               // Compact String
+               strcpy(str, gLoadedLibraries[i].Name);
+               str += strlen(str)+1;
+               // Compact Entry
+               gLoadedLibraries[j].Base = gLoadedLibraries[i].Base;
+               gLoadedLibraries[j].Name = str;
+       }
+       
+       // NULL Last Entry
+       gLoadedLibraries[j].Base = 0;
+       gLoadedLibraries[j].Name = NULL;
+       // Save next string
+       gsNextAvailString = str;
+}
+
+/**
+ \fn Uint GetSymbol(const char *name)
  \brief Gets a symbol value from a loaded library
 */
-Uint GetSymbol(char *name)
-{\r
+void *GetSymbol(const char *name)
+{
         int    i;
-       Uint    ret;\r
-       for(i=0;i<sizeof(gLoadedLibraries)/sizeof(gLoadedLibraries[0]);i++)\r
-       {\r
-               if(gLoadedLibraries[i].Base == 0)       break;\r
+       void    *ret;
+       
+       //SysDebug("ciNumLocalExports = %i", ciNumLocalExports);
+       for(i=0;i<ciNumLocalExports;i++)
+       {
+               if( strcmp(caLocalExports[i].Name, name) == 0 )
+                       return caLocalExports[i].Value;
+       }
+       
+       // Entry 0 is ld-acess, ignore it
+       for(i = 1; i < MAX_LOADED_LIBRARIES; i ++)
+       {
+               if(gLoadedLibraries[i].Base == 0)       break;
                
-               //SysDebug(" GetSymbol: Trying 0x%x, '%s'\n",\r
+               //SysDebug(" GetSymbol: Trying 0x%x, '%s'",
                //      gLoadedLibraries[i].Base, gLoadedLibraries[i].Name);
-               if(GetSymbolFromBase(gLoadedLibraries[i].Base, name, &ret))     return ret;\r
-       }\r
-       SysDebug("GetSymbol: === Symbol '%s' not found ===\n", name);\r
+               if(GetSymbolFromBase(gLoadedLibraries[i].Base, name, &ret))     return ret;
+       }
+       SysDebug("GetSymbol: === Symbol '%s' not found ===", name);
        return 0;
 }
 
@@ -216,12 +225,13 @@ Uint GetSymbol(char *name)
  \fn int GetSymbolFromBase(Uint base, char *name, Uint *ret)
  \breif Gets a symbol from a specified library
 */
-int GetSymbolFromBase(Uint base, char *name, Uint *ret)
+int GetSymbolFromBase(void *base, const char *name, void **ret)
 {
        if(*(Uint32*)base == (0x7F|('E'<<8)|('L'<<16)|('F'<<24)))
                return ElfGetSymbol(base, name, ret);
        if(*(Uint16*)base == ('M'|('Z'<<8)))
                return PE_GetSymbol(base, name, ret);
+       SysDebug("Unknown type at %p", base);
        return 0;
 }
 

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