2 * AcessNative Dynamic Linker
3 * - By John Hodge (thePowersGang)
6 * - Provides binary loading and type abstraction
9 #define _POSIX_C_SOURCE 200809L // needed for strdup
15 #define LIBRARY_PATH "$$$$../Usermode/Output/x86_64/Libs"
18 typedef struct sBinary {
27 extern void *Elf_Load(int fd);
28 extern uintptr_t ElfRelocate(void *Base);
29 extern int ElfGetSymbol(void *Base, char *Name, uintptr_t *ret, size_t *size);
30 extern int ciNumBuiltinSymbols;
31 extern tSym caBuiltinSymbols[];
35 void Binary_AddToList(const char *Filename, void *Base, tBinFmt *Format);
38 tBinFmt gElf_FormatDef = {
39 // .Mask = 0xFFFFFFFF,
40 // .Magic = "\x7F""ELF",
43 .Relocate = ElfRelocate,
44 .GetSymbol = ElfGetSymbol
46 tBinary *gLoadedBinaries;
49 char *Binary_LocateLibrary(const char *Name)
51 char *envPath = getenv("ACESS_LIBRARY_PATH");
52 int nameLen = strlen(Name);
55 if( strcmp(Name, "libld-acess.so") == 0 ) {
56 return strdup("libld-acess.so");
59 // Try the environment ACESS_LIBRARY_PATH
60 if( envPath && envPath[0] != '\0' )
62 int len = strlen(envPath)+1+nameLen+1;
69 fd = acess__SysOpen(tmp, 4); // OPENFLAG_EXEC
77 int len = strlen(LIBRARY_PATH)+1+nameLen+1;
80 strcpy(tmp, LIBRARY_PATH);
85 printf("Binary_LocateLibrary: tmp = '%s'\n", tmp);
88 fd = acess__SysOpen(tmp, 4); // OPENFLAG_EXEC
96 fprintf(stderr, "Unable to locate library '%s'\n", Name);
102 void *Binary_LoadLibrary(const char *Name)
106 int (*entry)(void *,int,char*[],char**) = NULL;
109 path = Binary_LocateLibrary(Name);
111 printf("Binary_LoadLibrary: path = '%s'\n", path);
117 ret = Binary_Load(path, (uintptr_t*)&entry);
118 if( ret != (void*)-1 )
119 Debug("LOADED '%s' to %p (Entry=%p)", path, ret, entry);
123 printf("Binary_LoadLibrary: ret = %p, entry = %p\n", ret, entry);
126 char *argv[] = {NULL};
128 printf("Calling '%s' entry point %p\n", Name, entry);
130 entry(ret, 0, argv, gEnvP);
136 void *Binary_Load(const char *Filename, uintptr_t *EntryPoint)
139 uint32_t dword = 0xFA17FA17;
144 // Ignore loading ld-acess
145 if( strcmp(Filename, "libld-acess.so") == 0 ) {
152 for(bin = gLoadedBinaries; bin; bin = bin->Next)
154 if( strcmp(Filename, bin->Path) == 0 ) {
160 fd = acess__SysOpen(Filename, 2|1); // Execute and Read
162 // TODO: Handle libary directories
163 perror("Opening binary");
167 acess__SysRead(fd, &dword, 4);
168 acess__SysSeek(fd, 0, ACESS_SEEK_SET);
170 if( memcmp(&dword, "\x7F""ELF", 4) == 0 ) {
171 fmt = &gElf_FormatDef;
174 fprintf(stderr, "Unknown executable format (0x%08x)\n", dword);
180 printf("fmt->Load(0x%x)...\n", fd);
185 printf("fmt->Load(0x%x): %p\n", fd, ret);
191 Binary_AddToList(Filename, ret, fmt);
193 entry = fmt->Relocate(ret);
195 printf("fmt->Relocate(%p): %p\n", ret, (void*)entry);
205 Binary_SetReadyToUse(ret);
210 void Binary_AddToList(const char *Filename, void *Base, tBinFmt *Format)
212 tBinary *bin = malloc(sizeof(tBinary) + strlen(Filename) + 1);
214 bin->Format = Format;
215 strcpy(bin->Path, Filename);
218 bin->Next = gLoadedBinaries;
219 gLoadedBinaries = bin;
222 void Binary_SetReadyToUse(void *Base)
225 for(bin = gLoadedBinaries; bin; bin = bin->Next)
227 if( bin->Base != Base ) continue ;
232 int Binary_GetSymbol(const char *SymbolName, uintptr_t *Value, size_t *Size, void *IgnoreBase)
237 //printf("Binary_GetSymbol: (SymbolName='%s', Value=%p)\n",
238 // SymbolName, Value);
241 // - Placed first to override smartarses that define their own versions
243 for( i = 0; i < ciNumBuiltinSymbols; i ++ )
245 if( strcmp(caBuiltinSymbols[i].Name, SymbolName) == 0 ) {
246 *Value = (uintptr_t)caBuiltinSymbols[i].Value;
252 // Search list of loaded binaries
253 for(bin = gLoadedBinaries; bin; bin = bin->Next)
255 if( bin->Base == IgnoreBase ) continue ;
256 if( !bin->Ready ) continue;
257 //printf(" Binary_GetSymbol: bin = %p{%p, %s}\n", bin, bin->Base, bin->Path);
258 if( bin->Format->GetSymbol(bin->Base, (char*)SymbolName, Value, Size) )
262 //printf("Binary_GetSymbol: RETURN 0, not found\n");
263 printf("--- ERROR: Unable to find symbol '%s'\n", SymbolName);