2 AcessOS 1 - Dynamic Loader
\r
10 # define DEBUGS(v...) SysDebug(v)
\r
12 # define DEBUGS(v...)
\r
15 // === PROTOTYPES ===
\r
16 Uint IsFileLoaded(char *file);
17 int GetSymbolFromBase(Uint base, char *name, Uint *ret);
\r
20 #define MAX_LOADED_LIBRARIES 64
\r
21 #define MAX_STRINGS_BYTES 4096
\r
25 } gLoadedLibraries[MAX_LOADED_LIBRARIES];
\r
26 char gsLoadedStrings[MAX_STRINGS_BYTES];
\r
27 char *gsNextAvailString = gsLoadedStrings;
\r
28 //tLoadLib *gpLoadedLibraries = NULL;
\r
31 Uint LoadLibrary(char *filename, char *SearchDir, char **envp)
\r
33 char sTmpName[1024] = "/Acess/Libs/";
\r
35 void (*fEntry)(int, int, char *[], char**);
\r
37 DEBUGS("LoadLibrary: (filename='%s', envp=0x%x)\n", filename, envp);
\r
40 strcpy(&sTmpName[12], filename);
\r
41 DEBUGS(" LoadLibrary: sTmpName='%s'\n", sTmpName);
\r
43 if( (iArg = IsFileLoaded(sTmpName)) )
\r
47 iArg = SysLoadBin(sTmpName, (Uint*)&fEntry);
\r
49 DEBUGS("LoadLibrary: RETURN 0\n");
\r
53 DEBUGS(" LoadLibrary: iArg=0x%x, iEntry=0x%x\n", iArg, fEntry);
\r
56 fEntry = (void*)DoRelocate( iArg, envp, sTmpName );
\r
59 DEBUGS(" LoadLibrary: '%s' Entry 0x%x\n", filename, fEntry);
\r
60 fEntry(iArg, 0, NULL, envp);
\r
62 DEBUGS("LoadLibrary: RETURN 1\n");
\r
67 * \fn Uint IsFileLoaded(char *file)
\r
68 * \brief Determine if a file is already loaded
\r
70 Uint IsFileLoaded(char *file)
\r
73 DEBUGS("IsFileLoaded: (file='%s')", file);
\r
74 for( i = 0; i < MAX_LOADED_LIBRARIES; i++ )
\r
76 if(gLoadedLibraries[i].Base == 0) break; // Last entry has Base set to NULL
\r
77 DEBUGS(" strcmp('%s', '%s')", gLoadedLibraries[i].Name, file);
\r
78 if(strcmp(gLoadedLibraries[i].Name, file) == 0) {
\r
79 DEBUGS("IsFileLoaded: Found %i (0x%x)", i, gLoadedLibraries[i].Base);
\r
80 return gLoadedLibraries[i].Base;
\r
83 DEBUGS("IsFileLoaded: Not Found");
\r
88 * \fn void AddLoaded(char *File, Uint base)
\r
89 * \brief Add a file to the loaded list
\r
91 void AddLoaded(char *File, Uint base)
94 char *name = gsNextAvailString;
\r
96 DEBUGS("AddLoaded: (File='%s', base=0x%x)", File, base);
\r
99 for( i = 0; i < MAX_LOADED_LIBRARIES; i ++ )
\r
101 if(gLoadedLibraries[i].Base == 0) break;
\r
103 if(i == MAX_LOADED_LIBRARIES) {
\r
104 SysDebug("ERROR - ld-acess.so has run out of load slots!");
\r
108 // Check space in string buffer
\r
109 length = strlen(File);
\r
110 if(&name[length+1] >= &gsLoadedStrings[MAX_STRINGS_BYTES]) {
\r
111 SysDebug("ERROR - ld-acess.so has run out of string buffer memory!");
\r
116 gLoadedLibraries[i].Base = base;
\r
117 strcpy(name, File);
\r
118 gLoadedLibraries[i].Name = name;
\r
119 gsNextAvailString = &name[length+1];
\r
120 DEBUGS("'%s' (0x%x) loaded as %i\n", name, base, i);
\r
125 * \fn void Unload(Uint Base)
\r
127 void Unload(Uint Base)
\r
132 for( id = 0; id < MAX_LOADED_LIBRARIES; id++ )
\r
134 if(gLoadedLibraries[id].Base == Base) break;
\r
136 if(id == MAX_LOADED_LIBRARIES) return;
\r
139 SysUnloadBin( Base );
\r
140 // Save String Pointer
\r
141 str = gLoadedLibraries[id].Name;
\r
143 // Compact Loaded List
\r
145 for( i = j + 1; i < MAX_LOADED_LIBRARIES; i++, j++ )
\r
147 if(gLoadedLibraries[i].Base == 0) break;
\r
149 strcpy(str, gLoadedLibraries[i].Name);
\r
150 str += strlen(str)+1;
\r
152 gLoadedLibraries[j].Base = gLoadedLibraries[i].Base;
\r
153 gLoadedLibraries[j].Name = str;
\r
157 gLoadedLibraries[j].Base = 0;
\r
158 gLoadedLibraries[j].Name = NULL;
\r
159 // Save next string
\r
160 gsNextAvailString = str;
\r
164 \fn Uint GetSymbol(char *name)
165 \brief Gets a symbol value from a loaded library
167 Uint GetSymbol(char *name)
171 for(i=0;i<sizeof(gLoadedLibraries)/sizeof(gLoadedLibraries[0]);i++)
\r
173 if(gLoadedLibraries[i].Base == 0) break;
\r
175 //SysDebug(" GetSymbol: Trying 0x%x, '%s'\n",
\r
176 // gLoadedLibraries[i].Base, gLoadedLibraries[i].Name);
177 if(GetSymbolFromBase(gLoadedLibraries[i].Base, name, &ret)) return ret;
\r
179 SysDebug("GetSymbol: === Symbol '%s' not found ===\n", name);
\r
184 \fn int GetSymbolFromBase(Uint base, char *name, Uint *ret)
185 \breif Gets a symbol from a specified library
187 int GetSymbolFromBase(Uint base, char *name, Uint *ret)
189 if(*(Uint32*)base == (0x7F|('E'<<8)|('L'<<16)|('F'<<24)))
190 return ElfGetSymbol(base, name, ret);
191 if(*(Uint16*)base == ('M'|('Z'<<8)))
192 return PE_GetSymbol(base, name, ret);