include ../Makefile.tpl
# create libld-acess.so
-$(_XBIN): $(_BIN)
+$(_XBIN): $(_OBJPREFIX)_stublib.o
@echo [LD] -o -shared libld-acess.so
- @$(LD) $(LDFLAGS) -shared -o $@ $(OBJ)
+ $(LD) -shared -o $@ $<
+# @$(LD) $(LDFLAGS) -o $@ $(OBJ)
+
# Override .ao to look in the object prefix for the source
%.ao: %.asm
--- /dev/null
+
+int _errno;
+
+#define SYSCALL0(name,num) void name(void){}
+#define SYSCALL1(name,num) void name(void){}
+#define SYSCALL2(name,num) void name(void){}
+#define SYSCALL3(name,num) void name(void){}
+#define SYSCALL4(name,num) void name(void){}
+#define SYSCALL5(name,num) void name(void){}
+#define SYSCALL6(name,num) void name(void){}
+
+#include "arch/syscalls.s.h"
+
_errno: dw 0
[section .text]
+[global _start]
+[extern SoMain]
+_start:
+ call SoMain
+
+ add esp, 4
+ call eax
+
+ push eax
+ call _exit
+
; DEST
; SRC
_memcpy:
-ENTRY(SoMain)
+ENTRY(_start)
OUTPUT_FORMAT(elf32-i386)
SECTIONS {
[bits 64]
[section .text]
+[global _start]
+[extern SoMain]
+_start:
+ pop rdi
+ call SoMain
+
+ mov rdi, [rsp]
+ mov rsi, [rsp+8]
+ mov rdx, [rsp+16]
+ call rax
+
+ mov rdi, rax
+ call _exit
+
; DEST
; SRC
_memcpy:
-ENTRY(SoMain)
+ENTRY(_start)
OUTPUT_FORMAT(elf64-x86-64)
SECTIONS {
extern tLoadedLib gLoadedLibraries[MAX_LOADED_LIBRARIES];
// === Main ===
-extern void *DoRelocate(void *Base, char **envp, char *Filename);
+extern void *DoRelocate(void *Base, char **envp, const char *Filename);
// === Library/Symbol Manipulation ==
-extern void *LoadLibrary(char *filename, char *SearchDir, char **envp);
-extern void AddLoaded(char *File, void *base);
+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 char *strcat(char *dest, const char *src);
extern int strcmp(const char *s1, const char *s2);
extern int strlen(const char *str);
-extern int file_exists(char *filename);
+extern int file_exists(const char *filename);
// === System Calls ===
extern void _exit(int retval);
extern int ElfGetSymbol(void *Base, const char *name, void **ret);
// === PE Loader ===
-extern int PE_GetSymbol(void *Base, char *Name, void **ret);
+extern int PE_GetSymbol(void *Base, const char *Name, void **ret);
#endif
#include "common.h"
#include <stdint.h>
#include "elf32.h"
+#include "elf64.h"
-#define DEBUG 0
+#define DEBUG 1
#if DEBUG
-# define DEBUGS(v...) SysDebug(v)
+# define DEBUGS(v...) SysDebug("ld-acess - " v)
#else
# define DEBUGS(...)
#endif
#endif
// === PROTOTYPES ===
-Uint32 ElfHashString(const char *name);
+void *ElfRelocate(void *Base, char **envp, const char *Filename);
+void *Elf32Relocate(void *Base, char **envp, const char *Filename);
+void *Elf64Relocate(void *Base, char **envp, const char *Filename);
+Uint32 ElfHashString(const char *name);
// === CODE ===
/**
- \fn int ElfRelocate(void *Base, char **envp, char *Filename)
- \brief Relocates a loaded ELF Executable
-*/
-void *ElfRelocate(void *Base, char **envp, char *Filename)
+ * \fn int ElfRelocate(void *Base, char **envp, const char *Filename)
+ * \brief Relocates a loaded ELF Executable
+ */
+void *ElfRelocate(void *Base, char **envp, const char *Filename)
+{
+ Elf32_Ehdr *hdr = Base;
+
+ switch(hdr->e_ident[4])
+ {
+ case ELFCLASS32:
+ return Elf32Relocate(Base, envp, Filename);
+ case ELFCLASS64:
+ return Elf64Relocate(Base, envp, Filename);
+ default:
+ SysDebug("ld-acess - ElfRelocate: Unknown file class %i", hdr->e_ident[4]);
+ return NULL;
+ }
+}
+
+void *Elf64Relocate(void *Base, char **envp, const char *Filename)
+{
+ int i;
+ Elf64_Ehdr *hdr = Base;
+ Elf64_Phdr *phtab;
+ Elf64_Dyn *dyntab;
+ Elf64_Addr compiledBase = -1, baseDiff;
+ Elf64_Sym *symtab = NULL;
+ char *strtab = NULL;
+ Elf64_Word *hashtab = NULL;
+ Elf64_Rel *rel = NULL;
+ int rel_count = 0;
+ Elf64_Rela *rela = NULL;
+ int rela_count = 0;
+ void *pltrel = NULL;
+ int plt_size = 0, plt_type = 0;
+
+ DEBUGS("Elf64Relocate: e_ident = '%.16s'", hdr->e_ident);
+ DEBUGS("Elf64Relocate: e_phoff = %i, e_phnum = %i",
+ hdr->e_phoff, hdr->e_phnum);
+
+ // Scan for the dynamic table (and find the compiled base)
+ phtab = Base + hdr->e_phoff;
+ for( i = 0; i < hdr->e_phnum; i ++ )
+ {
+ if(phtab[i].p_type == PT_DYNAMIC)
+ dyntab = (void *)phtab[i].p_vaddr;
+ if(phtab[i].p_type == PT_LOAD && compiledBase > phtab[i].p_vaddr)
+ compiledBase = phtab[i].p_vaddr;
+ }
+
+ baseDiff = (Elf64_Addr)Base - compiledBase;
+
+ DEBUGS("baseDiff = %p", baseDiff);
+
+ if(dyntab == NULL) {
+ SysDebug(" Elf64Relocate: No PT_DYNAMIC segment in image %p, returning", Base);
+ return (void *)(hdr->e_entry + baseDiff);
+ }
+
+ dyntab = (void *)((Elf64_Addr)dyntab + baseDiff);
+
+ // Parse the dynamic table (first pass)
+ // - Search for String, Symbol and Hash tables
+ for(i = 0; dyntab[i].d_tag != DT_NULL; i ++)
+ {
+ switch(dyntab[i].d_tag)
+ {
+ case DT_SYMTAB:
+ dyntab[i].d_un.d_ptr += baseDiff;
+ symtab = (void *)dyntab[i].d_un.d_ptr;
+ break;
+ case DT_STRTAB:
+ dyntab[i].d_un.d_ptr += baseDiff;
+ strtab = (void *)dyntab[i].d_un.d_ptr;
+ break;
+ case DT_HASH:
+ dyntab[i].d_un.d_ptr += baseDiff;
+ hashtab = (void *)dyntab[i].d_un.d_ptr;
+ break;
+ }
+ }
+
+ if( !symtab || !strtab || !hashtab ) {
+ SysDebug("ld-acess - Elf64Relocate: Missing Symbol, string or hash table");
+ return NULL;
+ }
+
+ // Ready for symbol use
+ AddLoaded( Filename, Base );
+
+ // Second pass on dynamic table
+ for(i = 0; dyntab[i].d_tag != DT_NULL; i ++)
+ {
+ switch(dyntab[i].d_tag)
+ {
+ case DT_SONAME: break;
+
+ case DT_NEEDED: {
+ char *libPath = strtab + dyntab[i].d_un.d_val;
+ if(LoadLibrary(libPath, NULL, envp) == 0) {
+ SysDebug("ld-acess - Elf64Relocate: Unable to load '%s'", libPath);
+ return NULL;
+ }
+ } break;
+
+ // Relocation entries
+ case DT_REL:
+ dyntab[i].d_un.d_ptr += baseDiff;
+ rel = (void *)dyntab[i].d_un.d_ptr;
+ break;
+ case DT_RELSZ:
+ rel_count = dyntab[i].d_un.d_val / sizeof(Elf64_Rel);
+ break;
+ case DT_RELENT:
+ if( dyntab[i].d_un.d_val != sizeof(Elf64_Rel) ) {
+ SysDebug("ld-acess - Elf64Relocate: DT_RELENT(%i) != sizeof(Elf64_Rel)(%i)",
+ dyntab[i].d_un.d_val, sizeof(Elf64_Rel));
+ return NULL;
+ }
+ break;
+ case DT_RELA:
+ dyntab[i].d_un.d_ptr += baseDiff;
+ rela = (void *)dyntab[i].d_un.d_ptr;
+ break;
+ case DT_RELASZ:
+ rela_count = dyntab[i].d_un.d_val / sizeof(Elf64_Rela);
+ break;
+ case DT_RELAENT:
+ if( dyntab[i].d_un.d_val != sizeof(Elf64_Rela) ) {
+ SysDebug("ld-acess - Elf64Relocate: DT_RELAENT(%i) != sizeof(Elf64_Rela)(%i)",
+ dyntab[i].d_un.d_val, sizeof(Elf64_Rela));
+ return NULL;
+ }
+ break;
+ case DT_JMPREL:
+ dyntab[i].d_un.d_ptr += baseDiff;
+ pltrel = (void *)dyntab[i].d_un.d_ptr;
+ break;
+ case DT_PLTREL:
+ plt_type = dyntab[i].d_un.d_val;
+ break;
+ case DT_PLTRELSZ:
+ plt_size = dyntab[i].d_un.d_val;
+ break;
+ }
+ }
+
+ // Relocation function
+ void _Elf64DoReloc(Elf64_Xword r_info, void *ptr, Elf64_Sxword addend)
+ {
+ int sym = ELF64_R_SYM(r_info);
+ int type = ELF64_R_TYPE(r_info);
+ const char *symname = strtab + symtab[sym].st_name;
+ switch( type )
+ {
+ case R_X86_64_NONE:
+ break;
+ case R_X86_64_64:
+ *(uint64_t*)ptr = (uint64_t)GetSymbol(symname) + addend;
+ break;
+ default:
+ SysDebug("ld-acess - _Elf64DoReloc: Unknown relocation type %i", type);
+ }
+ }
+
+ if( rel )
+ {
+ for( i = 0; i < rel_count; i ++ )
+ {
+ uint64_t *ptr = (void *)( rel[i].r_offset + baseDiff );
+ _Elf64DoReloc( rel[i].r_info, ptr, *ptr);
+ }
+ }
+
+ if( rela )
+ {
+ for( i = 0; i < rela_count; i ++ )
+ {
+ _Elf64DoReloc( rela[i].r_info, (void *)( rela[i].r_offset + baseDiff ), rela[i].r_addend );
+ }
+ }
+
+ if( pltrel && plt_type )
+ {
+ if( plt_type == DT_REL ) {
+ Elf64_Rel *plt = pltrel;
+ int count = plt_size / sizeof(Elf64_Rel);
+ for( i = 0; i < count; i ++ )
+ {
+ uint64_t *ptr = (void *)( plt[i].r_offset + baseDiff );
+ _Elf64DoReloc( plt[i].r_info, ptr, *ptr);
+ }
+ }
+ else {
+ Elf64_Rela *plt = pltrel;
+ int count = plt_size / sizeof(Elf64_Rela);
+ for( i = 0; i < count; i ++ )
+ {
+ _Elf64DoReloc( plt[i].r_info, (void *)(plt[i].r_offset + baseDiff), plt[i].r_addend);
+ }
+ }
+ }
+
+ return (void *)(hdr->e_entry + baseDiff);
+}
+
+void *Elf32Relocate(void *Base, char **envp, const char *Filename)
{
Elf32_Ehdr *hdr = Base;
Elf32_Phdr *phtab;
DEBUGS(" Required Library '%s'", libPath);
if(LoadLibrary(libPath, NULL, envp) == 0) {
#if DEBUG
- DEBUGS(" elf_relocate: Unable to load '%s'", libPath);
+ DEBUGS(" elf_relocate: Unable to load '%s'", libPath);
#else
SysDebug("Unable to load required library '%s'", libPath);
#endif
DEBUGS(" elf_doRelocate: #%i: '%s'", sym, symname);
val = (intptr_t) GetSymbol( symname );
DEBUGS(" elf_doRelocate: R_386_PC32 *0x%x = 0x%x + 0x%x - 0x%x",
- ptr, *ptr, val, (Uint)ptr );
+ ptr, *ptr, val, (intptr_t)ptr );
*ptr = val + addend - (intptr_t)ptr;
//*ptr = val + addend - ((Uint)ptr - iBaseDiff);
break;
if(phtab[i].Type == PT_LOAD && iBaseDiff > phtab[i].VAddr)
iBaseDiff = phtab[i].VAddr;
if( phtab[i].Type == PT_DYNAMIC ) {
- dynTab = (void*)phtab[i].VAddr;
+ dynTab = (void*)(intptr_t)phtab[i].VAddr;
}
}
if( !dynTab ) {
-/**\r
- Acess v1\r
- \file elf32.h\r
- \brief ELF Exeutable Loader\r
-*/\r
-#ifndef _ELF32_H\r
-#define _ELF32_H\r
-\r
-/**\r
- \struct elf_header_s\r
- \brief ELF File Header\r
-*/\r
-struct sElf32_Ehdr {\r
- union {\r
- char ident[16]; //!< Identifier Bytes\r
- struct {\r
- Uint32 Ident1;\r
- Uint32 StrTab;\r
- Uint32 HashTable;\r
- Uint32 SymTable;\r
- } misc;\r
- };\r
- Uint16 filetype; //!< File Type\r
- Uint16 machine; //!< Machine / Arch\r
- Uint32 version; //!< Version (File?)\r
- Uint32 entrypoint; //!< Entry Point\r
- Uint32 phoff; //!< Program Header Offset\r
- Uint32 shoff; //!< Section Header Offset\r
- Uint32 flags; //!< Flags\r
- Uint16 headersize; //!< Header Size\r
- Uint16 phentsize; //!< Program Header Entry Size\r
- Uint16 phentcount; //!< Program Header Entry Count\r
- Uint16 shentsize; //!< Section Header Entry Size\r
- Uint16 shentcount; //!< Section Header Entry Count\r
- Uint16 shstrindex; //!< Section Header String Table Index\r
-};\r
-\r
-/**\r
- \name Executable Types\r
- \{\r
-*/\r
-#define ET_NONE 0 //!< NULL Type\r
-#define ET_REL 1 //!< Relocatable (Object)\r
-#define ET_EXEC 2 //!< Executable\r
-#define ET_DYN 3 //!< Dynamic Library\r
-#define ET_CORE 4 //!< Core?\r
-#define ET_LOPROC 0xFF00 //!< Low Impl Defined\r
-#define ET_HIPROC 0xFFFF //!< High Impl Defined\r
-//! \}\r
-\r
-/**\r
- \name Section IDs\r
- \{\r
-*/\r
-#define SHN_UNDEF 0 //!< Undefined Section\r
-#define SHN_LORESERVE 0xFF00 //!< Low Reserved\r
-#define SHN_LOPROC 0xFF00 //!< Low Impl Defined\r
-#define SHN_HIPROC 0xFF1F //!< High Impl Defined\r
-#define SHN_ABS 0xFFF1 //!< Absolute Address (Base: 0, Size: -1)\r
-#define SHN_COMMON 0xFFF2 //!< Common\r
-#define SHN_HIRESERVE 0xFFFF //!< High Reserved\r
-//! \}\r
-\r
-/**\r
- \enum eElfSectionTypes\r
- \brief ELF Section Types\r
-*/\r
-enum eElfSectionTypes {\r
- SHT_NULL, //0\r
- SHT_PROGBITS, //1\r
- SHT_SYMTAB, //2\r
- SHT_STRTAB, //3\r
- SHT_RELA, //4\r
- SHT_HASH, //5\r
- SHT_DYNAMIC, //6\r
- SHT_NOTE, //7\r
- SHT_NOBITS, //8\r
- SHT_REL, //9\r
- SHT_SHLIB, //A\r
- SHT_DYNSYM, //B\r
- SHT_LAST, //C\r
- SHT_LOPROC = 0x70000000,\r
- SHT_HIPROC = 0x7fffffff,\r
- SHT_LOUSER = 0x80000000,\r
- SHT_HIUSER = 0xffffffff\r
-};\r
-\r
-#define SHF_WRITE 0x1\r
-#define SHF_ALLOC 0x2\r
-#define SHF_EXECINSTR 0x4\r
-#define SHF_MASKPROC 0xf0000000\r
-\r
-struct sElf32_Shent {\r
- Uint32 name;\r
- Uint32 type;\r
- Uint32 flags;\r
- Uint32 address;\r
- Uint32 offset;\r
- Uint32 size;\r
- Uint32 link;\r
- Uint32 info;\r
- Uint32 addralign;\r
- Uint32 entsize;\r
-}; //sizeof = 40\r
-\r
+/**
+ Acess v1
+ \file elf32.h
+ \brief ELF Exeutable Loader
+*/
+#ifndef _ELF32_H
+#define _ELF32_H
+
+#define ELFCLASS32 1
+
+/**
+ \struct elf_header_s
+ \brief ELF File Header
+*/
+struct sElf32_Ehdr {
+ Uint8 e_ident[16]; //!< Identifier Bytes
+ Uint16 filetype; //!< File Type
+ Uint16 machine; //!< Machine / Arch
+ Uint32 version; //!< Version (File?)
+ Uint32 entrypoint; //!< Entry Point
+ Uint32 phoff; //!< Program Header Offset
+ Uint32 shoff; //!< Section Header Offset
+ Uint32 flags; //!< Flags
+ Uint16 headersize; //!< Header Size
+ Uint16 phentsize; //!< Program Header Entry Size
+ Uint16 phentcount; //!< Program Header Entry Count
+ Uint16 shentsize; //!< Section Header Entry Size
+ Uint16 shentcount; //!< Section Header Entry Count
+ Uint16 shstrindex; //!< Section Header String Table Index
+};
+
+/**
+ \name Executable Types
+ \{
+*/
+#define ET_NONE 0 //!< NULL Type
+#define ET_REL 1 //!< Relocatable (Object)
+#define ET_EXEC 2 //!< Executable
+#define ET_DYN 3 //!< Dynamic Library
+#define ET_CORE 4 //!< Core?
+#define ET_LOPROC 0xFF00 //!< Low Impl Defined
+#define ET_HIPROC 0xFFFF //!< High Impl Defined
+//! \}
+
+/**
+ \name Section IDs
+ \{
+*/
+#define SHN_UNDEF 0 //!< Undefined Section
+#define SHN_LORESERVE 0xFF00 //!< Low Reserved
+#define SHN_LOPROC 0xFF00 //!< Low Impl Defined
+#define SHN_HIPROC 0xFF1F //!< High Impl Defined
+#define SHN_ABS 0xFFF1 //!< Absolute Address (Base: 0, Size: -1)
+#define SHN_COMMON 0xFFF2 //!< Common
+#define SHN_HIRESERVE 0xFFFF //!< High Reserved
+//! \}
+
+/**
+ \enum eElfSectionTypes
+ \brief ELF Section Types
+*/
+enum eElfSectionTypes {
+ SHT_NULL, //0
+ SHT_PROGBITS, //1
+ SHT_SYMTAB, //2
+ SHT_STRTAB, //3
+ SHT_RELA, //4
+ SHT_HASH, //5
+ SHT_DYNAMIC, //6
+ SHT_NOTE, //7
+ SHT_NOBITS, //8
+ SHT_REL, //9
+ SHT_SHLIB, //A
+ SHT_DYNSYM, //B
+ SHT_LAST, //C
+ SHT_LOPROC = 0x70000000,
+ SHT_HIPROC = 0x7fffffff,
+ SHT_LOUSER = 0x80000000,
+ SHT_HIUSER = 0xffffffff
+};
+
+#define SHF_WRITE 0x1
+#define SHF_ALLOC 0x2
+#define SHF_EXECINSTR 0x4
+#define SHF_MASKPROC 0xf0000000
+
+struct sElf32_Shent {
+ Uint32 name;
+ Uint32 type;
+ Uint32 flags;
+ Uint32 address;
+ Uint32 offset;
+ Uint32 size;
+ Uint32 link;
+ Uint32 info;
+ Uint32 addralign;
+ Uint32 entsize;
+}; //sizeof = 40
+
struct elf_sym_s {
Uint32 nameOfs;
- Uint32 value; //Address\r
- Uint32 size;\r
- Uint8 info;\r
- Uint8 other;\r
- Uint16 shndx;\r
-};\r
-#define STN_UNDEF 0 // Undefined Symbol\r
-\r
-enum {\r
- PT_NULL, //0\r
- PT_LOAD, //1\r
- PT_DYNAMIC, //2\r
- PT_INTERP, //3\r
- PT_NOTE, //4\r
- PT_SHLIB, //5\r
- PT_PHDR, //6\r
- PT_LOPROC = 0x70000000,\r
- PT_HIPROC = 0x7fffffff\r
-};\r
-\r
-struct sElf32_Phdr {\r
- Uint32 Type;\r
- Uint Offset;\r
- Uint VAddr;\r
- Uint PAddr;\r
- Uint32 FileSize;\r
- Uint32 MemSize;\r
- Uint32 Flags;\r
- Uint32 Align;\r
-};\r
-\r
-struct elf32_rel_s {\r
- Uint32 r_offset;\r
- Uint32 r_info;\r
-};\r
-\r
-struct elf32_rela_s {\r
- Uint32 r_offset;\r
- Uint32 r_info;\r
- Sint32 r_addend;\r
-};\r
-\r
-enum {\r
- R_386_NONE=0, // none\r
- R_386_32, // S+A\r
- R_386_PC32, // S+A-P\r
- R_386_GOT32, // G+A-P\r
- R_386_PLT32, // L+A-P\r
- R_386_COPY, // none\r
- R_386_GLOB_DAT, // S\r
- R_386_JMP_SLOT, // S\r
- R_386_RELATIVE, // B+A\r
- R_386_GOTOFF, // S+A-GOT\r
- R_386_GOTPC, // GOT+A-P\r
- R_386_LAST // none\r
-};\r
-\r
-#define ELF32_R_SYM(i) ((i)>>8) // Takes an info value and returns a symbol index\r
-#define ELF32_R_TYPE(i) ((i)&0xFF) // Takes an info value and returns a type\r
-#define ELF32_R_INFO(s,t) (((s)<<8)+((t)&0xFF)) // Takes a type and symbol index and returns an info value\r
-\r
-struct elf32_dyn_s {\r
- Uint16 d_tag;\r
- Uint32 d_val; //Also d_ptr\r
-};\r
-\r
-enum {\r
- DT_NULL, //!< Marks End of list\r
- DT_NEEDED, //!< Offset in strtab to needed library\r
- DT_PLTRELSZ, //!< Size in bytes of PLT\r
- DT_PLTGOT, //!< Address of PLT/GOT\r
- DT_HASH, //!< Address of symbol hash table\r
- DT_STRTAB, //!< String Table address\r
- DT_SYMTAB, //!< Symbol Table address\r
- DT_RELA, //!< Relocation table address\r
- DT_RELASZ, //!< Size of relocation table\r
- DT_RELAENT, //!< Size of entry in relocation table\r
- DT_STRSZ, //!< Size of string table\r
- DT_SYMENT, //!< Size of symbol table entry\r
- DT_INIT, //!< Address of initialisation function\r
- DT_FINI, //!< Address of termination function\r
- DT_SONAME, //!< String table offset of so name\r
- DT_RPATH, //!< String table offset of library path\r
- DT_SYMBOLIC,//!< Reverse order of symbol searching for library, search libs first then executable\r
- DT_REL, //!< Relocation Entries (Elf32_Rel instead of Elf32_Rela)\r
- DT_RELSZ, //!< Size of above table (bytes)\r
- DT_RELENT, //!< Size of entry in above table\r
- DT_PLTREL, //!< Relocation entry of PLT\r
- DT_DEBUG, //!< Debugging Entry - Unknown contents\r
- DT_TEXTREL, //!< Indicates that modifcations to a non-writeable segment may occur\r
- DT_JMPREL, //!< Address of PLT only relocation entries\r
- DT_LOPROC = 0x70000000, //!< Low Definable\r
- DT_HIPROC = 0x7FFFFFFF //!< High Definable\r
-};\r
-\r
-typedef struct sElf32_Ehdr Elf32_Ehdr;\r
-typedef struct sElf32_Phdr Elf32_Phdr;\r
-typedef struct sElf32_Shent Elf32_Shent;\r
-typedef struct elf_sym_s elf_symtab;\r
-typedef struct elf_sym_s Elf32_Sym;\r
-typedef struct elf32_rel_s Elf32_Rel;\r
-typedef struct elf32_rela_s Elf32_Rela;\r
-typedef struct elf32_dyn_s Elf32_Dyn;\r
-\r
-#endif // defined(_EXE_ELF_H)\r
+ Uint32 value; //Address
+ Uint32 size;
+ Uint8 info;
+ Uint8 other;
+ Uint16 shndx;
+};
+#define STN_UNDEF 0 // Undefined Symbol
+
+enum {
+ PT_NULL, //0
+ PT_LOAD, //1
+ PT_DYNAMIC, //2
+ PT_INTERP, //3
+ PT_NOTE, //4
+ PT_SHLIB, //5
+ PT_PHDR, //6
+ PT_LOPROC = 0x70000000,
+ PT_HIPROC = 0x7fffffff
+};
+
+struct sElf32_Phdr {
+ Uint32 Type;
+ Uint Offset;
+ Uint VAddr;
+ Uint PAddr;
+ Uint32 FileSize;
+ Uint32 MemSize;
+ Uint32 Flags;
+ Uint32 Align;
+};
+
+struct elf32_rel_s {
+ Uint32 r_offset;
+ Uint32 r_info;
+};
+
+struct elf32_rela_s {
+ Uint32 r_offset;
+ Uint32 r_info;
+ Sint32 r_addend;
+};
+
+enum {
+ R_386_NONE=0, // none
+ R_386_32, // S+A
+ R_386_PC32, // S+A-P
+ R_386_GOT32, // G+A-P
+ R_386_PLT32, // L+A-P
+ R_386_COPY, // none
+ R_386_GLOB_DAT, // S
+ R_386_JMP_SLOT, // S
+ R_386_RELATIVE, // B+A
+ R_386_GOTOFF, // S+A-GOT
+ R_386_GOTPC, // GOT+A-P
+ R_386_LAST // none
+};
+
+#define ELF32_R_SYM(i) ((i)>>8) // Takes an info value and returns a symbol index
+#define ELF32_R_TYPE(i) ((i)&0xFF) // Takes an info value and returns a type
+#define ELF32_R_INFO(s,t) (((s)<<8)+((t)&0xFF)) // Takes a type and symbol index and returns an info value
+
+struct elf32_dyn_s {
+ Uint16 d_tag;
+ Uint32 d_val; //Also d_ptr
+};
+
+enum {
+ DT_NULL, //!< Marks End of list
+ DT_NEEDED, //!< Offset in strtab to needed library
+ DT_PLTRELSZ, //!< Size in bytes of PLT
+ DT_PLTGOT, //!< Address of PLT/GOT
+ DT_HASH, //!< Address of symbol hash table
+ DT_STRTAB, //!< String Table address
+ DT_SYMTAB, //!< Symbol Table address
+ DT_RELA, //!< Relocation table address
+ DT_RELASZ, //!< Size of relocation table
+ DT_RELAENT, //!< Size of entry in relocation table
+ DT_STRSZ, //!< Size of string table
+ DT_SYMENT, //!< Size of symbol table entry
+ DT_INIT, //!< Address of initialisation function
+ DT_FINI, //!< Address of termination function
+ DT_SONAME, //!< String table offset of so name
+ DT_RPATH, //!< String table offset of library path
+ DT_SYMBOLIC,//!< Reverse order of symbol searching for library, search libs first then executable
+ DT_REL, //!< Relocation Entries (Elf32_Rel instead of Elf32_Rela)
+ DT_RELSZ, //!< Size of above table (bytes)
+ DT_RELENT, //!< Size of entry in above table
+ DT_PLTREL, //!< Relocation entry of PLT
+ DT_DEBUG, //!< Debugging Entry - Unknown contents
+ DT_TEXTREL, //!< Indicates that modifcations to a non-writeable segment may occur
+ DT_JMPREL, //!< Address of PLT only relocation entries
+ DT_LOPROC = 0x70000000, //!< Low Definable
+ DT_HIPROC = 0x7FFFFFFF //!< High Definable
+};
+
+typedef struct sElf32_Ehdr Elf32_Ehdr;
+typedef struct sElf32_Phdr Elf32_Phdr;
+typedef struct sElf32_Shent Elf32_Shent;
+typedef struct elf_sym_s elf_symtab;
+typedef struct elf_sym_s Elf32_Sym;
+typedef struct elf32_rel_s Elf32_Rel;
+typedef struct elf32_rela_s Elf32_Rela;
+typedef struct elf32_dyn_s Elf32_Dyn;
+
+#endif // defined(_EXE_ELF_H)
--- /dev/null
+/*
+ * Acess2 Dynamic Linker
+ *
+ * elf64.h
+ */
+
+#ifndef _ELF64_H_
+#define _ELF64_H_
+
+#define ELFCLASS64 2
+
+typedef uint16_t Elf64_Half;
+typedef uint32_t Elf64_Word;
+typedef uint64_t Elf64_Addr;
+typedef uint64_t Elf64_Off;
+typedef uint64_t Elf64_Xword;
+typedef int64_t Elf64_Sxword;
+
+typedef struct
+{
+ unsigned char e_ident[16];
+ Elf64_Half e_type;
+ Elf64_Half e_machine;
+ Elf64_Word e_version;
+ Elf64_Addr e_entry;
+ Elf64_Off e_phoff;
+ Elf64_Off e_shoff;
+ Elf64_Word e_flags;
+ Elf64_Half e_ehsize;
+ Elf64_Half e_phentsize;
+ Elf64_Half e_phnum;
+ Elf64_Half e_shentsize;
+ Elf64_Half e_shnum;
+ Elf64_Half e_shstrndx;
+} Elf64_Ehdr;
+
+typedef struct
+{
+ Elf64_Word sh_name;
+ Elf64_Word sh_type;
+ Elf64_Xword sh_flags;
+ Elf64_Addr sh_addr;
+ Elf64_Off sh_offset;
+ Elf64_Xword sh_size;
+ Elf64_Word sh_link;
+ Elf64_Word sh_info;
+ Elf64_Xword sh_addralign;
+ Elf64_Xword sh_entsize;
+} Elf64_Shdr;
+
+typedef struct
+{
+ Elf64_Word p_type;
+ Elf64_Word p_flags;
+ Elf64_Off p_offset;
+ Elf64_Addr p_vaddr;
+ Elf64_Addr p_paddr;
+ Elf64_Xword p_filesz;
+ Elf64_Xword p_memsz;
+ Elf64_Xword p_align;
+} Elf64_Phdr;
+
+typedef struct
+{
+ Elf64_Sxword d_tag;
+ union {
+ Elf64_Xword d_val;
+ Elf64_Addr d_ptr;
+ } d_un;
+} Elf64_Dyn;
+
+typedef struct
+{
+ Elf64_Word st_name;
+ uint8_t st_info;
+ uint8_t st_other;
+ Elf64_Half st_shndx;
+ Elf64_Addr st_value;
+ Elf64_Xword st_size;
+} Elf64_Sym;
+
+typedef struct
+{
+ Elf64_Addr r_offset;
+ Elf64_Xword r_info;
+} Elf64_Rel;
+
+typedef struct
+{
+ Elf64_Addr r_offset;
+ Elf64_Xword r_info;
+ Elf64_Sxword r_addend;
+} Elf64_Rela;
+
+#define ELF64_R_SYM(info) ((info) >> 32)
+#define ELF64_R_TYPE(info) ((info) & 0xFFFFFFFF)
+
+enum eElf64_RelocTypes_x86_64
+{
+ R_X86_64_NONE,
+ R_X86_64_64, // 64, S + A
+ R_X86_64_PC32, // 32, S + A - P
+ R_X86_64_GOT32, // 32, G + A
+ R_X86_64_PLT32, // 32, L + A - P
+ R_X86_64_COPY,
+ R_X86_64_GLOB_DAT, // 64, S
+ R_X86_64_JUMP_SLOT, // 64, S
+ R_X86_64_RELATIVE, // 64, B + A
+ // TODO: Rest
+};
+
+#endif
+
return len;
}
+int memcmp(const void *p1, const void *p2, int len)
+{
+ const char *b1 = p1, *b2 = p2;
+ while(len --)
+ {
+ if(b1 != b2) return b1 - b2;
+ }
+ return 0;
+}
+
/**
* \fn int file_exists(char *filename)
* \brief Checks if a file exists
*/
-int file_exists(char *filename)
+int file_exists(const char *filename)
{
int fd;
//fd = open(filename, OPENFLAG_READ);
#endif
// === PROTOTYPES ===
-void *IsFileLoaded(char *file);
+void *IsFileLoaded(const char *file);
int GetSymbolFromBase(void *base, const char *name, void **ret);
// === IMPORTS ===
//tLoadLib *gpLoadedLibraries = NULL;
// === CODE ===
-char *FindLibrary(char *DestBuf, char *SoName, char *ExtraSearchDir)
+const char *FindLibrary(char *DestBuf, const char *SoName, const char *ExtraSearchDir)
{
// -- #1: Executable Specified
if(ExtraSearchDir)
/**
*/
-void *LoadLibrary(char *SoName, char *SearchDir, char **envp)
+void *LoadLibrary(const char *SoName, const char *SearchDir, char **envp)
{
char sTmpName[1024];
- char *filename;
+ const char *filename;
void *base;
void (*fEntry)(void *, int, char *[], char**);
* \fn Uint IsFileLoaded(char *file)
* \brief Determine if a file is already loaded
*/
-void *IsFileLoaded(char *file)
+void *IsFileLoaded(const char *file)
{
int i;
DEBUGS("IsFileLoaded: (file='%s')", file);
* \fn void AddLoaded(char *File, Uint base)
* \brief Add a file to the loaded list
*/
-void AddLoaded(char *File, void *base)
+void AddLoaded(const char *File, void *base)
{
int i, length;
char *name = gsNextAvailString;
#include "common.h"\r
\r
// === PROTOTYPES ===\r
-void *DoRelocate(void *base, char **envp, char *Filename);\r
+void *DoRelocate(void *base, char **envp, const char *Filename);\r
int CallUser(void *Entry, void *SP);\r
-void *ElfRelocate(void *Base, char *envp[], char *Filename);\r
-void *PE_Relocate(void *Base, char *envp[], char *Filename);\r
+void *ElfRelocate(void *Base, char **envp, const char *Filename);\r
+void *PE_Relocate(void *Base, char **envp, const char *Filename);\r
\r
// === Imports ===\r
extern void gLinkedBase;\r
\brief Library entry point\r
\note This is the entrypoint for the library\r
*/\r
-int SoMain(void *base, void *arg1)\r
+void *SoMain(void *base)\r
{\r
void *ret;\r
\r
_exit(-1);\r
for(;;);\r
}\r
- \r
- // And call user\r
- //SysDebug("Calling User at 0x%x\n", ret);\r
- CallUser( ret, &arg1 );\r
- \r
- return 0;\r
+\r
+ SysDebug("ld-acess - SoMain: ret = %p", ret); \r
+ return ret;\r
}\r
\r
/**\r
\fn int DoRelocate(void *base, char **envp)\r
\brief Relocates an in-memory image\r
*/\r
-void *DoRelocate(void *base, char **envp, char *Filename)\r
+void *DoRelocate(void *base, char **envp, const char *Filename)\r
{\r
+ Uint8 *hdr = base;\r
// Load Executable\r
- if(*(Uint32*)base == (0x7F|('E'<<8)|('L'<<16)|('F'<<24)))\r
+ if(memcmp(base, "\x7F""ELF", 4) == 0)\r
return ElfRelocate(base, envp, Filename);\r
- if(*(Uint16*)base == ('M'|('Z'<<8)))\r
+ if(hdr[0] == 0x7F && hdr[1] == 'E' && hdr[2] == 'L' && hdr[3] == 'F')\r
+ return ElfRelocate(base, envp, Filename);\r
+\r
+ if(hdr[0] == 'M' && hdr[1] == 'Z')\r
return PE_Relocate(base, envp, Filename);\r
\r
SysDebug("ld-acess - DoRelocate: Unkown file format '0x%x 0x%x 0x%x 0x%x'\n",\r
- *(Uint8*)(base), *(Uint8*)(base+1), *(Uint8*)(base+2), *(Uint8*)(base+3) );\r
+ hdr[0], hdr[1], hdr[2], hdr[3] );\r
SysDebug("ld-acess - DoRelocate: File '%s'\n", Filename);\r
_exit(-1);\r
for(;;);\r
}\r
\r
/**\r
- * \fn int PE_GetSymbol(Uint Base, char *Name, Uint *Ret)\r
+ * \fn int PE_GetSymbol(Uint Base, const char *Name, Uint *Ret)\r
*/\r
-int PE_GetSymbol(void *Base, char *Name, void **Ret)\r
+int PE_GetSymbol(void *Base, const char *Name, void **Ret)\r
{\r
tPE_DOS_HEADER *dosHdr = Base;\r
tPE_IMAGE_HEADERS *peHeaders;\r