-/*\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
- 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"
+#include <stdint.h>
+#include <acess/sys.h>
+
+#define DEBUG 0
+
+#if DEBUG
+# define DEBUGS(v...) SysDebug(v)
+#else
+# define DEBUGS(v...)
+#endif
+
+// === PROTOTYPES ===
+void *IsFileLoaded(const char *file);
+
+// === IMPORTS ===
+extern const struct {
+ void *Value;
+ char *Name;
+} caLocalExports[];
+extern const int ciNumLocalExports;
+extern char **gEnvP;
+extern char gLinkedBase[];
+
+// === 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=%p)", 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, fEntry=%p", base, fEntry);
+
+ // Load Symbols
+ fEntry = DoRelocate( base, envp, filename );
+ if( !fEntry ) {
+ return 0;
+ }
+
+ // Call Entrypoint
+ DEBUGS(" LoadLibrary: '%s' Entry %p", SoName, fEntry);
+ fEntry(base, 0, NULL, gEnvP);
+
+ 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);
+
+ // Applications link against either libld-acess.so or ld-acess.so
+ if( strcmp(file, "/Acess/Libs/libld-acess.so") == 0
+ || strcmp(file, "/Acess/Libs/ld-acess.so") == 0 )
+ {
+ DEBUGS("IsFileLoaded: Found local (%p)", &gLinkedBase);
+ return &gLinkedBase;
+ }
+
+ 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 (%p)", i, gLoadedLibraries[i].Base);
+ return gLoadedLibraries[i].Base;
+ }
+ }
+ DEBUGS("IsFileLoaded: Not Found");
+ return 0;