// === Library/Symbol Manipulation ==
extern void *LoadLibrary(const char *Filename, const char *SearchDir, char **envp);
extern void AddLoaded(const char *File, void *base);
-extern void *GetSymbol(const char *name);
-extern int GetSymbolFromBase(void *base, const char *name, void **ret);
+extern void *GetSymbol(const char *name, size_t *size);
+extern int GetSymbolFromBase(void *base, const char *name, void **ret, size_t *size);
// === Library Functions ===
extern char *strcpy(char *dest, const char *src);
extern int strcmp(const char *s1, const char *s2);
extern int strlen(const char *str);
extern int file_exists(const char *filename);
+extern void *memcpy(void *dest, const void *src, size_t len);
// === System Calls ===
extern void _exit(int retval);
extern int close(int fd);
// === ELF Loader ===
-extern int ElfGetSymbol(void *Base, const char *name, void **ret);
+extern void *ElfRelocate(void *Base, char **envp, const char *Filename);
+extern int ElfGetSymbol(void *Base, const char *name, void **ret, size_t *Size);
// === PE Loader ===
-extern int PE_GetSymbol(void *Base, const char *Name, void **ret);
+extern void *PE_Relocate(void *Base, char **envp, const char *Filename);
+extern int PE_GetSymbol(void *Base, const char *Name, void **ret, size_t *Size);
#endif
// === PROTOTYPES ===
void *ElfRelocate(void *Base, char **envp, const char *Filename);
- int ElfGetSymbol(void *Base, const char *Name, void **Ret);
+ int ElfGetSymbol(void *Base, const char *Name, void **Ret, size_t *Size);
void *Elf32Relocate(void *Base, char **envp, const char *Filename);
- int Elf32GetSymbol(void *Base, const char *Name, void **Ret);
+ int Elf32GetSymbol(void *Base, const char *Name, void **Ret, size_t *Size);
#ifdef SUPPORT_ELF64
void *Elf64Relocate(void *Base, char **envp, const char *Filename);
- int Elf64GetSymbol(void *Base, const char *Name, void **Ret);
+ int Elf64GetSymbol(void *Base, const char *Name, void **Ret, size_t *Size);
#endif
Uint32 ElfHashString(const char *name);
/**
* \fn int ElfGetSymbol(Uint Base, const char *name, void **ret)
*/
-int ElfGetSymbol(void *Base, const char *Name, void **ret)
+int ElfGetSymbol(void *Base, const char *Name, void **ret, size_t *Size)
{
Elf32_Ehdr *hdr = Base;
switch(hdr->e_ident[4])
{
case ELFCLASS32:
- return Elf32GetSymbol(Base, Name, ret);
+ return Elf32GetSymbol(Base, Name, ret, Size);
#ifdef SUPPORT_ELF64
case ELFCLASS64:
- return Elf64GetSymbol(Base, Name, ret);
+ return Elf64GetSymbol(Base, Name, ret, Size);
#endif
default:
SysDebug("ld-acess - ElfRelocate: Unknown file class %i", hdr->e_ident[4]);
DEBUGS(" elf_relocate: DYNAMIC Symbol Table 0x%x (0x%x)",
dynamicTab[j].d_val, dynamicTab[j].d_val + iBaseDiff);
if(iBaseDiff != 0) dynamicTab[j].d_val += iBaseDiff;
- dynsymtab = (void*)(dynamicTab[j].d_val);
+ dynsymtab = (void*)(intptr_t)dynamicTab[j].d_val;
break;
// --- String Table ---
case DT_STRTAB:
DEBUGS(" elf_relocate: DYNAMIC String Table 0x%x (0x%x)",
dynamicTab[j].d_val, dynamicTab[j].d_val + iBaseDiff);
if(iBaseDiff != 0) dynamicTab[j].d_val += iBaseDiff;
- dynstrtab = (void*)(dynamicTab[j].d_val);
+ dynstrtab = (void*)(intptr_t)dynamicTab[j].d_val;
break;
// --- Hash Table --
case DT_HASH:
if(iBaseDiff != 0) dynamicTab[j].d_val += iBaseDiff;
- iSymCount = ((Elf32_Word*)(dynamicTab[j].d_val))[1];
+ iSymCount = ((Elf32_Word*)(intptr_t)dynamicTab[j].d_val)[1];
break;
}
}
if(dynsymtab == NULL) {
SysDebug("ld-acess.so - WARNING: No Dynamic Symbol table in %p, returning", hdr);
- return (void *) hdr->entrypoint + iBaseDiff;
+ return (void *)(intptr_t) (hdr->entrypoint + iBaseDiff);
}
// === Add to loaded list (can be imported now) ===
{
// Standard 32 Bit Relocation (S+A)
case R_386_32:
- val = (intptr_t) GetSymbol( Sym );
+ val = (intptr_t) GetSymbol(Sym, NULL);
DEBUGS(" elf_doRelocate: R_386_32 *0x%x += 0x%x('%s')",
ptr, val, Sym);
*ptr = val + addend;
// 32 Bit Relocation wrt. Offset (S+A-P)
case R_386_PC32:
DEBUGS(" elf_doRelocate: '%s'", Sym);
- val = (intptr_t) GetSymbol( Sym );
+ val = (intptr_t) GetSymbol(Sym, NULL);
DEBUGS(" elf_doRelocate: R_386_PC32 *0x%x = 0x%x + 0x%x - 0x%x",
ptr, *ptr, val, (intptr_t)ptr );
*ptr = val + addend - (intptr_t)ptr;
case R_386_GLOB_DAT:
case R_386_JMP_SLOT:
DEBUGS(" elf_doRelocate: '%s'", Sym);
- val = (intptr_t) GetSymbol( Sym );
+ val = (intptr_t) GetSymbol( Sym, NULL );
DEBUGS(" elf_doRelocate: %s *0x%x = 0x%x", csaR_NAMES[type], ptr, val);
*ptr = val;
break;
DEBUGS(" elf_doRelocate: R_386_RELATIVE *0x%x = 0x%x + 0x%x", ptr, iBaseDiff, addend);
*ptr = iBaseDiff + addend;
break;
-
+
+ case R_386_COPY: {
+ size_t size;
+ void *src = GetSymbol(Sym, &size);
+ DEBUGS(" elf_doRelocate_386: R_386_COPY (%p, %p, %i)", ptr, val, size);
+ memcpy(ptr, src, size);
+ break; }
+
default:
SysDebug("elf_doRelocate_386: Unknown relocation %i", type);
break;
// (S + A) | T
case R_ARM_GLOB_DAT:
case R_ARM_JUMP_SLOT:
- val = (intptr_t)GetSymbol(Sym);
+ val = (intptr_t)GetSymbol(Sym, NULL);
*ptr = val + addend;
break;
default:
}
DEBUGS("ElfRelocate: RETURN 0x%x", hdr->entrypoint + iBaseDiff);
- return (void*)hdr->entrypoint + iBaseDiff;
+ return (void*)(intptr_t)( hdr->entrypoint + iBaseDiff );
}
-int Elf32GetSymbol(void *Base, const char *Name, void **ret)
+int Elf32GetSymbol(void *Base, const char *Name, void **ret, size_t *Size)
{
Elf32_Ehdr *hdr = Base;
Elf32_Sym *symtab;
i = pBuckets[ iNameHash ];
if(symtab[i].shndx != SHN_UNDEF && strcmp(dynstrtab + symtab[i].nameOfs, Name) == 0) {
*ret = (void*) (intptr_t) symtab[ i ].value + iBaseDiff;
+ if(Size) *Size = symtab[i].size;
return 1;
}
i = pChains[i];
if(symtab[i].shndx != SHN_UNDEF && strcmp(dynstrtab + symtab[ i ].nameOfs, Name) == 0) {
*ret = (void*)(intptr_t)symtab[ i ].value + iBaseDiff;
+ if(Size) *Size = symtab[i].size;
return 1;
}
}
case R_X86_64_NONE:
break;
case R_X86_64_64:
- *(uint64_t*)ptr = (uint64_t)GetSymbol(symname) + addend;
- break;
- case R_X86_64_COPY:
+ *(uint64_t*)ptr = (uint64_t)GetSymbol(symname, NULL) + addend;
break;
+ case R_X86_64_COPY: {
+ size_t size;
+ void *sym = GetSymbol(symname, &size);
+ memcpy(ptr, sym, size);
+ } break;
case R_X86_64_GLOB_DAT:
- *(uint64_t*)ptr = (uint64_t)GetSymbol(symname);
+ *(uint64_t*)ptr = (uint64_t)GetSymbol(symname, NULL);
break;
case R_X86_64_JUMP_SLOT:
- *(uint64_t*)ptr = (uint64_t)GetSymbol(symname);
+ *(uint64_t*)ptr = (uint64_t)GetSymbol(symname, NULL);
break;
case R_X86_64_RELATIVE:
*(uint64_t*)ptr = (intptr_t)Base + addend;
return (void *)(hdr->e_entry + baseDiff);
}
-int Elf64GetSymbol(void *Base, const char *Name, void **Ret)
+int Elf64GetSymbol(void *Base, const char *Name, void **Ret, size_t *Size)
{
Elf64_Ehdr *hdr = Base;
Elf64_Sym *symtab;
i = pBuckets[ iNameHash ];
if(symtab[i].st_shndx != SHN_UNDEF && strcmp(dynstrtab + symtab[i].st_name, Name) == 0) {
*Ret = (void*) (intptr_t) symtab[i].st_value + iBaseDiff;
+ if(Size) *Size = symtab[i].st_size;
DEBUGS("%s = %p", Name, *Ret);
return 1;
}
i = pChains[i];
if(symtab[i].st_shndx != SHN_UNDEF && strcmp(dynstrtab + symtab[i].st_name, Name) == 0) {
*Ret = (void*)(intptr_t)symtab[i].st_value + iBaseDiff;
+ if(Size) *Size = symtab[i].st_size;
DEBUGS("%s = %p", Name, *Ret);
return 1;
}
// === PROTOTYPES ===
void *IsFileLoaded(const char *file);
- int GetSymbolFromBase(void *base, const char *name, void **ret);
+ int GetSymbolFromBase(void *base, const char *name, void **ret, size_t *size);
// === IMPORTS ===
extern const struct {
\fn Uint GetSymbol(const char *name)
\brief Gets a symbol value from a loaded library
*/
-void *GetSymbol(const char *name)
+void *GetSymbol(const char *name, size_t *Size)
{
int i;
void *ret;
//SysDebug(" GetSymbol: Trying 0x%x, '%s'",
// gLoadedLibraries[i].Base, gLoadedLibraries[i].Name);
- if(GetSymbolFromBase(gLoadedLibraries[i].Base, name, &ret)) return ret;
+ if(GetSymbolFromBase(gLoadedLibraries[i].Base, name, &ret, Size)) return ret;
}
SysDebug("GetSymbol: === Symbol '%s' not found ===", name);
return 0;
\fn int GetSymbolFromBase(Uint base, char *name, Uint *ret)
\breif Gets a symbol from a specified library
*/
-int GetSymbolFromBase(void *base, const char *name, void **ret)
+int GetSymbolFromBase(void *base, const char *name, void **ret, size_t *Size)
{
uint8_t *hdr = base;
if(hdr[0] == 0x7F && hdr[1] == 'E' && hdr[2] == 'L' && hdr[3] == 'F')
- return ElfGetSymbol(base, name, ret);
+ return ElfGetSymbol(base, name, ret, Size);
if(hdr[0] == 'M' && hdr[1] == 'Z')
- return PE_GetSymbol(base, name, ret);
+ return PE_GetSymbol(base, name, ret, Size);
SysDebug("Unknown type at %p (%02x %02x %02x %02x)", base,
hdr[0], hdr[1], hdr[2], hdr[3]);
return 0;
#endif\r
\r
// === PROTOTYPES ===\r
- int PE_Relocate(void *Base, char **envp, char *Filename);\r
+void *PE_Relocate(void *Base, char **envp, const char *Filename);\r
char *PE_int_GetTrueFile(char *file);\r
int PE_int_GetForwardSymbol(char *Fwd, void **Value);\r
\r
// === CODE ===\r
-int PE_Relocate(void *Base, char *envp[], char *Filename)\r
+void *PE_Relocate(void *Base, char **envp, const char *Filename)\r
{\r
tPE_DOS_HEADER *dosHdr = Base;\r
tPE_IMAGE_HEADERS *peHeaders;\r
void *symPtr = 0;\r
name = (void*)( iBase + importTab[j] );\r
DEBUGS(" PE_Relocate: Import Name '%s', Hint 0x%x\n", name->Name, name->Hint);\r
- if( GetSymbolFromBase(pLibBase, name->Name, symPtr) == 0 ) {\r
+ if( GetSymbolFromBase(pLibBase, name->Name, symPtr, NULL) == 0 )\r
+ {\r
SysDebug("Unable to find symbol '%s' in library '%s'\n", name->Name, impDir[i].DLLName);\r
return 0;\r
}\r
\r
DEBUGS("PE_Relocate: RETURN 0x%x\n", iBase + peHeaders->OptHeader.EntryPoint);\r
\r
- return iBase + peHeaders->OptHeader.EntryPoint;\r
+ return (void*)( iBase + peHeaders->OptHeader.EntryPoint );\r
}\r
\r
/**\r
* \fn int PE_GetSymbol(Uint Base, const char *Name, Uint *Ret)\r
*/\r
-int PE_GetSymbol(void *Base, const char *Name, void **Ret)\r
+int PE_GetSymbol(void *Base, const char *Name, void **Ret, size_t *Size)\r
{\r
tPE_DOS_HEADER *dosHdr = Base;\r
tPE_IMAGE_HEADERS *peHeaders;\r
return PE_int_GetForwardSymbol(fwd, Ret);\r
}\r
*Ret = (void*)retVal;\r
+ if(Size) *Size = 0;\r
return 1;\r
}\r
}\r
DEBUGS(" PE_int_GetForwardSymbol: Get '%s' from '%s'\n", sym, libname);\r
\r
libbase = LoadLibrary(libname, DLL_BASE_PATH, NULL);\r
- ret = GetSymbolFromBase(libbase, sym, Value);\r
+ ret = GetSymbolFromBase(libbase, sym, Value, NULL);\r
if(!ret) {\r
SysDebug(" PE_int_GetForwardSymbol: Unable to find '%s' in '%s'\n", sym, libname);\r
+ return 0;\r
}\r
Fwd[i] = '.';\r
return ret;\r