From: John Hodge Date: Mon, 26 Sep 2011 05:07:53 +0000 (+0800) Subject: Usermode/ld-acess - Adding elf64 support X-Git-Tag: rel0.11~57 X-Git-Url: https://git.ucc.asn.au/?a=commitdiff_plain;h=9867382061f9035d65e118d95fa819c0e615f353;p=tpg%2Facess2.git Usermode/ld-acess - Adding elf64 support - Created stub library file for linking against > Stops ld-acess having to be compiled with -fPIC --- diff --git a/Usermode/Libraries/ld-acess.so_src/Makefile b/Usermode/Libraries/ld-acess.so_src/Makefile index 4b99ecd7..a29dd4b6 100644 --- a/Usermode/Libraries/ld-acess.so_src/Makefile +++ b/Usermode/Libraries/ld-acess.so_src/Makefile @@ -16,9 +16,11 @@ LDFLAGS = -g -T arch/$(ARCHDIR).ld -Map map.txt --export-dynamic 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 diff --git a/Usermode/Libraries/ld-acess.so_src/_stublib.c b/Usermode/Libraries/ld-acess.so_src/_stublib.c new file mode 100644 index 00000000..6107c692 --- /dev/null +++ b/Usermode/Libraries/ld-acess.so_src/_stublib.c @@ -0,0 +1,13 @@ + +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" + diff --git a/Usermode/Libraries/ld-acess.so_src/arch/x86.asm.h b/Usermode/Libraries/ld-acess.so_src/arch/x86.asm.h index 9e452734..a569637d 100644 --- a/Usermode/Libraries/ld-acess.so_src/arch/x86.asm.h +++ b/Usermode/Libraries/ld-acess.so_src/arch/x86.asm.h @@ -10,6 +10,17 @@ _errno: dw 0 [section .text] +[global _start] +[extern SoMain] +_start: + call SoMain + + add esp, 4 + call eax + + push eax + call _exit + ; DEST ; SRC _memcpy: diff --git a/Usermode/Libraries/ld-acess.so_src/arch/x86.ld b/Usermode/Libraries/ld-acess.so_src/arch/x86.ld index eb28d901..648b31e6 100644 --- a/Usermode/Libraries/ld-acess.so_src/arch/x86.ld +++ b/Usermode/Libraries/ld-acess.so_src/arch/x86.ld @@ -1,4 +1,4 @@ -ENTRY(SoMain) +ENTRY(_start) OUTPUT_FORMAT(elf32-i386) SECTIONS { diff --git a/Usermode/Libraries/ld-acess.so_src/arch/x86_64.asm.h b/Usermode/Libraries/ld-acess.so_src/arch/x86_64.asm.h index cffe74c5..fdfe5e99 100644 --- a/Usermode/Libraries/ld-acess.so_src/arch/x86_64.asm.h +++ b/Usermode/Libraries/ld-acess.so_src/arch/x86_64.asm.h @@ -7,6 +7,20 @@ [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: diff --git a/Usermode/Libraries/ld-acess.so_src/arch/x86_64.ld b/Usermode/Libraries/ld-acess.so_src/arch/x86_64.ld index 5dd69023..43b7d077 100644 --- a/Usermode/Libraries/ld-acess.so_src/arch/x86_64.ld +++ b/Usermode/Libraries/ld-acess.so_src/arch/x86_64.ld @@ -1,4 +1,4 @@ -ENTRY(SoMain) +ENTRY(_start) OUTPUT_FORMAT(elf64-x86-64) SECTIONS { diff --git a/Usermode/Libraries/ld-acess.so_src/common.h b/Usermode/Libraries/ld-acess.so_src/common.h index 7d95540a..941baf37 100644 --- a/Usermode/Libraries/ld-acess.so_src/common.h +++ b/Usermode/Libraries/ld-acess.so_src/common.h @@ -37,11 +37,11 @@ typedef struct { 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); @@ -50,7 +50,7 @@ extern char *strcpy(char *dest, const char *src); 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); @@ -66,6 +66,6 @@ extern int close(int fd); 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 diff --git a/Usermode/Libraries/ld-acess.so_src/elf.c b/Usermode/Libraries/ld-acess.so_src/elf.c index b969a19c..c45c4816 100644 --- a/Usermode/Libraries/ld-acess.so_src/elf.c +++ b/Usermode/Libraries/ld-acess.so_src/elf.c @@ -5,11 +5,12 @@ #include "common.h" #include #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 @@ -21,14 +22,220 @@ static const char *csaR_NAMES[] = {"R_386_NONE", "R_386_32", "R_386_PC32", "R_38 #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; @@ -155,7 +362,7 @@ void *ElfRelocate(void *Base, char **envp, char *Filename) 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 @@ -216,7 +423,7 @@ void *ElfRelocate(void *Base, char **envp, char *Filename) 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; @@ -343,7 +550,7 @@ int ElfGetSymbol(void *Base, const char *Name, void **ret) 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 ) { diff --git a/Usermode/Libraries/ld-acess.so_src/elf32.h b/Usermode/Libraries/ld-acess.so_src/elf32.h index 5e43987d..983917bd 100644 --- a/Usermode/Libraries/ld-acess.so_src/elf32.h +++ b/Usermode/Libraries/ld-acess.so_src/elf32.h @@ -1,212 +1,206 @@ -/** - Acess v1 - \file elf32.h - \brief ELF Exeutable Loader -*/ -#ifndef _ELF32_H -#define _ELF32_H - -/** - \struct elf_header_s - \brief ELF File Header -*/ -struct sElf32_Ehdr { - union { - char ident[16]; //!< Identifier Bytes - struct { - Uint32 Ident1; - Uint32 StrTab; - Uint32 HashTable; - Uint32 SymTable; - } misc; - }; - 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 - +/** + 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 - 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) + 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) diff --git a/Usermode/Libraries/ld-acess.so_src/elf64.h b/Usermode/Libraries/ld-acess.so_src/elf64.h new file mode 100644 index 00000000..237b75cb --- /dev/null +++ b/Usermode/Libraries/ld-acess.so_src/elf64.h @@ -0,0 +1,113 @@ +/* + * 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 + diff --git a/Usermode/Libraries/ld-acess.so_src/lib.c b/Usermode/Libraries/ld-acess.so_src/lib.c index 28fb4672..6d66da05 100644 --- a/Usermode/Libraries/ld-acess.so_src/lib.c +++ b/Usermode/Libraries/ld-acess.so_src/lib.c @@ -47,11 +47,21 @@ int strlen(const char *str) 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); diff --git a/Usermode/Libraries/ld-acess.so_src/loadlib.c b/Usermode/Libraries/ld-acess.so_src/loadlib.c index 88297d5f..529e0a00 100644 --- a/Usermode/Libraries/ld-acess.so_src/loadlib.c +++ b/Usermode/Libraries/ld-acess.so_src/loadlib.c @@ -13,7 +13,7 @@ #endif // === PROTOTYPES === -void *IsFileLoaded(char *file); +void *IsFileLoaded(const char *file); int GetSymbolFromBase(void *base, const char *name, void **ret); // === IMPORTS === @@ -30,7 +30,7 @@ char *gsNextAvailString = gsLoadedStrings; //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) @@ -54,10 +54,10 @@ char *FindLibrary(char *DestBuf, char *SoName, char *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**); @@ -98,7 +98,7 @@ void *LoadLibrary(char *SoName, char *SearchDir, char **envp) * \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); @@ -119,7 +119,7 @@ void *IsFileLoaded(char *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; diff --git a/Usermode/Libraries/ld-acess.so_src/main.c b/Usermode/Libraries/ld-acess.so_src/main.c index dfb1b615..ccdf6b42 100644 --- a/Usermode/Libraries/ld-acess.so_src/main.c +++ b/Usermode/Libraries/ld-acess.so_src/main.c @@ -6,10 +6,10 @@ #include "common.h" // === PROTOTYPES === -void *DoRelocate(void *base, char **envp, char *Filename); +void *DoRelocate(void *base, char **envp, const char *Filename); int CallUser(void *Entry, void *SP); -void *ElfRelocate(void *Base, char *envp[], char *Filename); -void *PE_Relocate(void *Base, char *envp[], char *Filename); +void *ElfRelocate(void *Base, char **envp, const char *Filename); +void *PE_Relocate(void *Base, char **envp, const char *Filename); // === Imports === extern void gLinkedBase; @@ -21,7 +21,7 @@ extern tLoadedLib gLoadedLibraries[]; \brief Library entry point \note This is the entrypoint for the library */ -int SoMain(void *base, void *arg1) +void *SoMain(void *base) { void *ret; @@ -50,28 +50,29 @@ int SoMain(void *base, void *arg1) _exit(-1); for(;;); } - - // And call user - //SysDebug("Calling User at 0x%x\n", ret); - CallUser( ret, &arg1 ); - - return 0; + + SysDebug("ld-acess - SoMain: ret = %p", ret); + return ret; } /** \fn int DoRelocate(void *base, char **envp) \brief Relocates an in-memory image */ -void *DoRelocate(void *base, char **envp, char *Filename) +void *DoRelocate(void *base, char **envp, const char *Filename) { + Uint8 *hdr = base; // Load Executable - if(*(Uint32*)base == (0x7F|('E'<<8)|('L'<<16)|('F'<<24))) + if(memcmp(base, "\x7F""ELF", 4) == 0) return ElfRelocate(base, envp, Filename); - if(*(Uint16*)base == ('M'|('Z'<<8))) + if(hdr[0] == 0x7F && hdr[1] == 'E' && hdr[2] == 'L' && hdr[3] == 'F') + return ElfRelocate(base, envp, Filename); + + if(hdr[0] == 'M' && hdr[1] == 'Z') return PE_Relocate(base, envp, Filename); SysDebug("ld-acess - DoRelocate: Unkown file format '0x%x 0x%x 0x%x 0x%x'\n", - *(Uint8*)(base), *(Uint8*)(base+1), *(Uint8*)(base+2), *(Uint8*)(base+3) ); + hdr[0], hdr[1], hdr[2], hdr[3] ); SysDebug("ld-acess - DoRelocate: File '%s'\n", Filename); _exit(-1); for(;;); diff --git a/Usermode/Libraries/ld-acess.so_src/pe.c b/Usermode/Libraries/ld-acess.so_src/pe.c index afcb4cef..d567ed15 100644 --- a/Usermode/Libraries/ld-acess.so_src/pe.c +++ b/Usermode/Libraries/ld-acess.so_src/pe.c @@ -89,9 +89,9 @@ int PE_Relocate(void *Base, char *envp[], char *Filename) } /** - * \fn int PE_GetSymbol(Uint Base, char *Name, Uint *Ret) + * \fn int PE_GetSymbol(Uint Base, const char *Name, Uint *Ret) */ -int PE_GetSymbol(void *Base, char *Name, void **Ret) +int PE_GetSymbol(void *Base, const char *Name, void **Ret) { tPE_DOS_HEADER *dosHdr = Base; tPE_IMAGE_HEADERS *peHeaders;