267555d1bc7e8a2d26c2d10dce235f2a1bc7a55c
[tpg/acess2.git] / Usermode / Libraries / ld-acess.so_src / loadlib.c
1 /*\r
2  AcessOS 1 - Dynamic Loader\r
3  By thePowersGang\r
4 */\r
5 #include "common.h"\r
6 \r
7 #define DEBUG   0\r
8 \r
9 #if DEBUG\r
10 # define DEBUGS(v...)   SysDebug(v)\r
11 #else\r
12 # define DEBUGS(v...)   \r
13 #endif\r
14 \r
15 // === PROTOTYPES ===\r
16 Uint    IsFileLoaded(char *file);
17  int    GetSymbolFromBase(Uint base, char *name, Uint *ret);\r
18 \r
19 // === GLOABLS ===\r
20 #define MAX_LOADED_LIBRARIES    64\r
21 #define MAX_STRINGS_BYTES       4096\r
22 struct {\r
23         Uint    Base;\r
24         char    *Name;\r
25 }       gLoadedLibraries[MAX_LOADED_LIBRARIES];\r
26 char    gsLoadedStrings[MAX_STRINGS_BYTES];\r
27 char    *gsNextAvailString = gsLoadedStrings;\r
28 //tLoadLib      *gpLoadedLibraries = NULL;\r
29 \r
30 // === CODE ===\r
31 Uint LoadLibrary(char *filename, char *SearchDir, char **envp)\r
32 {\r
33         char    sTmpName[1024] = "/Acess/Libs/";\r
34         Uint    iArg;\r
35         void    (*fEntry)(int, int, char *[], char**);\r
36         \r
37         DEBUGS("LoadLibrary: (filename='%s', envp=0x%x)\n", filename, envp);\r
38         \r
39         // Create Temp Name\r
40         strcpy(&sTmpName[12], filename);\r
41         DEBUGS(" LoadLibrary: sTmpName='%s'\n", sTmpName);\r
42         \r
43         if( (iArg = IsFileLoaded(sTmpName)) )\r
44                 return iArg;\r
45         \r
46         // Load Library\r
47         iArg = SysLoadBin(sTmpName, (Uint*)&fEntry);\r
48         if(iArg == 0) {\r
49                 DEBUGS("LoadLibrary: RETURN 0\n");\r
50                 return 0;\r
51         }\r
52         \r
53         DEBUGS(" LoadLibrary: iArg=0x%x, iEntry=0x%x\n", iArg, fEntry);\r
54         \r
55         // Load Symbols\r
56         fEntry = (void*)DoRelocate( iArg, envp, sTmpName );\r
57         \r
58         // Call Entrypoint\r
59         DEBUGS(" LoadLibrary: '%s' Entry 0x%x\n", filename, fEntry);\r
60         fEntry(iArg, 0, NULL, envp);\r
61         \r
62         DEBUGS("LoadLibrary: RETURN 1\n");\r
63         return iArg;\r
64 }
65 \r
66 /**\r
67  * \fn Uint IsFileLoaded(char *file)\r
68  * \brief Determine if a file is already loaded\r
69  */\r
70 Uint IsFileLoaded(char *file)\r
71 {\r
72          int    i;\r
73         DEBUGS("IsFileLoaded: (file='%s')\n", file);\r
74         for( i = 0; i < MAX_LOADED_LIBRARIES; i++ )\r
75         {\r
76                 if(gLoadedLibraries[i].Base == 0)       break;  // Last entry has Base set to NULL\r
77                 if(strcmp(gLoadedLibraries[i].Name, file) == 0) {\r
78                         DEBUGS("IsFileLoaded: Found %i (0x%x)\n", i, gLoadedLibraries[i].Base);\r
79                         return gLoadedLibraries[i].Base;\r
80                 }\r
81         }\r
82         DEBUGS("IsFileLoaded: Not Found\n");\r
83         return 0;\r
84 }\r
85 \r
86 /**\r
87  * \fn void AddLoaded(char *File, Uint base)\r
88  * \brief Add a file to the loaded list\r
89  */
90 void AddLoaded(char *File, Uint base)
91 {\r
92          int    i, length;\r
93         char    *name = gsNextAvailString;\r
94         \r
95         DEBUGS("AddLoaded: (File='%s', base=0x%x)", File, base);\r
96         \r
97         // Find a free slot\r
98         for( i = 0; i < MAX_LOADED_LIBRARIES; i ++ )\r
99         {\r
100                 if(gLoadedLibraries[i].Base == 0)       break;\r
101         }\r
102         if(i == MAX_LOADED_LIBRARIES) {\r
103                 SysDebug("ERROR - ld-acess.so has run out of load slots!");\r
104                 return;\r
105         }\r
106         \r
107         // Check space in string buffer\r
108         length = strlen(File);\r
109         if(&name[length+1] >= &gsLoadedStrings[MAX_STRINGS_BYTES]) {\r
110                 SysDebug("ERROR - ld-acess.so has run out of string buffer memory!");\r
111                 return;\r
112         }\r
113         \r
114         // Set information\r
115         gLoadedLibraries[i].Base = base;\r
116         strcpy(name, File);\r
117         gLoadedLibraries[i].Name = name;\r
118         gsNextAvailString = &name[length+1];\r
119         DEBUGS("'%s' (0x%x) loaded as %i\n", name, base, i);\r
120         return;
121 }\r
122 \r
123 /**\r
124  * \fn void Unload(Uint Base)\r
125  */\r
126 void Unload(Uint Base)\r
127 {       \r
128          int    i, j;\r
129          int    id;\r
130         char    *str;\r
131         for( id = 0; id < MAX_LOADED_LIBRARIES; id++ )\r
132         {\r
133                 if(gLoadedLibraries[id].Base == Base)   break;\r
134         }\r
135         if(id == MAX_LOADED_LIBRARIES)  return;\r
136         \r
137         // Unload Binary\r
138         SysUnloadBin( Base );\r
139         // Save String Pointer\r
140         str = gLoadedLibraries[id].Name;\r
141         \r
142         // Compact Loaded List\r
143         j = id;\r
144         for( i = j + 1; i < MAX_LOADED_LIBRARIES; i++, j++ )\r
145         {\r
146                 if(gLoadedLibraries[i].Base == 0)       break;\r
147                 // Compact String\r
148                 strcpy(str, gLoadedLibraries[i].Name);\r
149                 str += strlen(str)+1;\r
150                 // Compact Entry\r
151                 gLoadedLibraries[j].Base = gLoadedLibraries[i].Base;\r
152                 gLoadedLibraries[j].Name = str;\r
153         }\r
154         \r
155         // NULL Last Entry\r
156         gLoadedLibraries[j].Base = 0;\r
157         gLoadedLibraries[j].Name = NULL;\r
158         // Save next string\r
159         gsNextAvailString = str;\r
160 }\r
161 \r
162 /**
163  \fn Uint GetSymbol(char *name)
164  \brief Gets a symbol value from a loaded library
165 */
166 Uint GetSymbol(char *name)
167 {\r
168          int    i;
169         Uint    ret;\r
170         for(i=0;i<sizeof(gLoadedLibraries)/sizeof(gLoadedLibraries[0]);i++)\r
171         {\r
172                 if(gLoadedLibraries[i].Base == 0)       break;
173 //              SysDebug(" GetSymbol: Trying 0x%x\n", gLoadedLibraries[i]);
174                 if(GetSymbolFromBase(gLoadedLibraries[i].Base, name, &ret))     return ret;\r
175         }\r
176         SysDebug("GetSymbol: === Symbol '%s' not found ===\n", name);\r
177         return 0;
178 }
179
180 /**
181  \fn int GetSymbolFromBase(Uint base, char *name, Uint *ret)
182  \breif Gets a symbol from a specified library
183 */
184 int GetSymbolFromBase(Uint base, char *name, Uint *ret)
185 {
186         if(*(Uint32*)base == (0x7F|('E'<<8)|('L'<<16)|('F'<<24)))
187                 return ElfGetSymbol(base, name, ret);
188         if(*(Uint16*)base == ('M'|('Z'<<8)))
189                 return PE_GetSymbol(base, name, ret);
190         return 0;
191 }
192

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