Renamed ld-acess.so_src directory to ld-acess_src
[tpg/acess2.git] / AcessNative / ld-acess_src / binary.c
1 /*
2  * AcessNative
3  */
4 #include "common.h"
5 #include <stdint.h>
6 #include <stdio.h>
7 #include <string.h>
8
9 #define LIBRARY_PATH    "../Usermode/Output/i386/Libs"
10
11 // === TYPES ===
12 typedef struct sBinary {
13         struct sBinary  *Next;
14         void    *Base;
15          int    Ready;
16         tBinFmt *Format;
17         char    Path[];
18 }       tBinary;
19
20 // === IMPORTS ===
21 extern void     *Elf_Load(FILE *FP);
22 extern uintptr_t        Elf_Relocate(void *Base);
23 extern int      Elf_GetSymbol(void *Base, char *Name, uintptr_t *ret);
24 extern int      ciNumBuiltinSymbols;
25 extern tSym     caBuiltinSymbols[];
26
27 // === PROTOTYPES ===
28 void    Binary_AddToList(const char *Filename, void *Base, tBinFmt *Format);
29
30 // === GLOBALS ===
31 tBinFmt gElf_FormatDef = {
32 //      .Mask = 0xFFFFFFFF,
33 //      .Magic = "\x7F""ELF",
34         .Name = "ELF32",
35         .Load = Elf_Load,
36         .Relocate = Elf_Relocate,
37         .GetSymbol = Elf_GetSymbol
38         };
39 tBinary *gLoadedBinaries;
40
41 // === CODE ===
42 char *Binary_LocateLibrary(const char *Name)
43 {
44         char    *envPath = getenv("ACESS_LIBRARY_PATH");
45          int    nameLen = strlen(Name);
46         FILE    *fp;
47         
48         if( strcmp(Name, "libld-acess.so") == 0 ) {
49                 return strdup("libld-acess.so");
50         }
51         
52         // Try the environment ACESS_LIBRARY_PATH
53         if( envPath && envPath[0] != '\0' )
54         {
55                  int    len = strlen(envPath)+1+nameLen+1;
56                 char    tmp[len];
57
58                 strcpy(tmp, envPath);
59                 strcat(tmp, "/");
60                 strcat(tmp, Name);
61                 
62                 fp = fopen(tmp, "r");
63                 if(fp) {
64                         fclose(fp);
65                         return strdup(tmp);
66                 }
67         }               
68
69         {
70                  int    len = strlen(LIBRARY_PATH)+1+nameLen+1;
71                 char    tmp[len];
72
73                 strcpy(tmp, LIBRARY_PATH);
74                 strcat(tmp, "/");
75                 strcat(tmp, Name);
76                 
77                 printf("Binary_LocateLibrary: tmp = '%s'\n", tmp);
78
79                 fp = fopen(tmp, "r");
80                 if(fp) {
81                         fclose(fp);
82                         return strdup(tmp);
83                 }
84         }               
85
86         fprintf(stderr, "Unable to locate library '%s'\n", Name);
87
88         return NULL;
89 }
90
91 void *Binary_LoadLibrary(const char *Name)
92 {
93         char    *path;
94         void    *ret;
95          int    (*entry)(int,char*[],char**) = NULL;
96
97         // Find File
98         path = Binary_LocateLibrary(Name);
99         printf("Binary_LoadLibrary: path = '%s'\n", path);
100         if( !path ) {
101                 return NULL;
102         }
103
104         ret = Binary_Load(path, (uintptr_t*)&entry);
105         free(path);
106         
107         printf("Binary_LoadLibrary: ret = %p, entry = %p\n", ret, entry);
108         if( entry ) {
109                 char    *argv[] = {NULL};
110                 printf("Calling '%s' entry point %p\n", Name, entry);
111                 entry(0, argv, NULL);
112         }
113
114         return ret;
115 }
116
117 void *Binary_Load(const char *Filename, uintptr_t *EntryPoint)
118 {
119         FILE    *fp;
120         uint32_t        dword;
121         void    *ret;
122         uintptr_t       entry = 0;
123         tBinFmt *fmt;
124
125         // Ignore loading ld-acess
126         if( strcmp(Filename, "libld-acess.so") == 0 ) {
127                 *EntryPoint = 0;
128                 return (void*)-1;
129         }
130
131         {
132                 tBinary *bin;
133                 for(bin = gLoadedBinaries; bin; bin = bin->Next)
134                 {
135                         if( strcmp(Filename, bin->Path) == 0 ) {
136                                 return bin->Base;
137                         }
138                 }
139         }
140
141         fp = fopen(Filename, "r");
142         if( !fp ) {
143                 // TODO: Handle libary directories
144                 perror("Opening binary");
145                 return NULL;
146         }
147
148         fread(&dword, 1, 4, fp);
149         fseek(fp, 0, SEEK_SET);
150         printf("dword = %08x\n", dword);
151         
152         if( memcmp(&dword, "\x7F""ELF", 4) == 0 ) {
153                 fmt = &gElf_FormatDef;
154         }
155         else {
156                 fclose(fp);
157                 return NULL;
158         }
159         
160         printf("fmt->Load(%p)...\n", fp);
161         ret = fmt->Load(fp);
162         printf("fmt->Load(%p): %p\n", fp, ret);
163         if( !ret ) {
164                 fclose(fp);
165                 return NULL;
166         }
167         
168         Binary_AddToList(Filename, ret, fmt);
169
170         entry = fmt->Relocate(ret);
171         printf("fmt->Relocate(%p): %p\n", ret, (void*)entry);
172         if( !entry ) {
173                 // TODO: Clean up
174                 return NULL;
175         }
176         
177         if( EntryPoint )
178                 *EntryPoint = entry;
179
180         fclose(fp);
181
182         Binary_SetReadyToUse(ret);
183
184         return ret;
185 }
186
187 void Binary_AddToList(const char *Filename, void *Base, tBinFmt *Format)
188 {
189         tBinary *bin = malloc(sizeof(tBinary) + strlen(Filename) + 1);
190         bin->Base = Base;
191         bin->Format = Format;
192         strcpy(bin->Path, Filename);
193         bin->Ready = 0;
194         
195         bin->Next = gLoadedBinaries;
196         gLoadedBinaries = bin;
197 }
198
199 void Binary_SetReadyToUse(void *Base)
200 {
201         tBinary *bin;
202         for(bin = gLoadedBinaries; bin; bin = bin->Next)
203         {
204                 if( bin->Base != Base ) continue ;
205                 bin->Ready = 1;
206         }
207 }
208
209 int Binary_GetSymbol(const char *SymbolName, uintptr_t *Value)
210 {
211          int    i;
212         tBinary *bin;
213         
214         printf("Binary_GetSymbol: (SymbolName='%s', Value=%p)\n",
215                 SymbolName, Value);
216
217         // Search builtins
218         // - Placed first to override smartarses that define their own versions
219         //   of system calls
220         for( i = 0; i < ciNumBuiltinSymbols; i ++ )
221         {
222                 if( strcmp(caBuiltinSymbols[i].Name, SymbolName) == 0 ) {
223                         *Value = (uintptr_t)caBuiltinSymbols[i].Value;
224                         return 1;
225                 }
226         }
227         
228         // TODO: Search list of loaded binaries
229         for(bin = gLoadedBinaries; bin; bin = bin->Next)
230         {
231                 if( !bin->Ready )       continue;
232                 printf(" Binary_GetSymbol: bin = %p{%p, %s}\n", bin, bin->Base, bin->Path);
233                 if( bin->Format->GetSymbol(bin->Base, (char*)SymbolName, Value) )
234                         return 1;
235         }
236
237         printf("Binary_GetSymbol: RETURN 0, not found\n");
238         
239         return 0;
240 }

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