From 0b510e10f02229267537d7c12bb12ed7bf42d7c0 Mon Sep 17 00:00:00 2001 From: Alex Date: Mon, 20 Mar 2023 06:56:49 +0200 Subject: [PATCH] Almost working elf interpreter --- libc/ElfInterpreter/ld.c | 398 ++++++++++++++++++++++++++++++++-- libc/ElfInterpreter/resolve.c | 344 ----------------------------- 2 files changed, 384 insertions(+), 358 deletions(-) delete mode 100644 libc/ElfInterpreter/resolve.c diff --git a/libc/ElfInterpreter/ld.c b/libc/ElfInterpreter/ld.c index d334463..fcce1a8 100644 --- a/libc/ElfInterpreter/ld.c +++ b/libc/ElfInterpreter/ld.c @@ -35,21 +35,371 @@ uintptr_t KernelCTL(enum KCtl Command, uint64_t Arg1, uint64_t Arg2, uint64_t Ar return syscall5(_KernelCTL, Command, Arg1, Arg2, Arg3, Arg4); } -// bool ELFAddLazyResolverToGOT(void *ElfFile, void *MemoryImage, LibAddressCollection *Libs) -// { -// struct Elf64_Dyn *Dyn = (struct Elf64_Dyn *)ELFGetDynamicTag(ElfFile, DT_PLTGOT); -// if (!Dyn) -// return false; +struct LibAddressCollection +{ + char Name[32]; + __UINTPTR_TYPE__ *ElfFile; + __UINTPTR_TYPE__ *MemoryImage; + __UINTPTR_TYPE__ *ParentElfFile; + __UINTPTR_TYPE__ *ParentMemoryImage; + struct LibAddressCollection *Next; + char Valid; +}; -// Elf64_Addr *GOT = (Elf64_Addr *)Dyn->d_un.d_ptr; +#define MIN(a, b) (((a) < (b)) ? (a) : (b)) +#define MAX(a, b) (((a) > (b)) ? (a) : (b)) -// for (size_t i = 0; i < 16; i++) -// debug("GOT[%d]: %#lx (val: %#lx)", i, &GOT[i], GOT[i]); +static char Lock = 0; -// GOT[1] = (uintptr_t)Libs; -// GOT[2] = (uintptr_t)ElfLazyResolver; -// return true; -// } +__attribute__((naked, used, no_stack_protector)) void ELF_LAZY_RESOLVE_STUB() +{ + while (Lock == 1) + ; + __asm__ __volatile__("mfence\n"); + Lock = 1; + __asm__ __volatile__("pop %r11\n" + "pop %r10\n" + + "push %rdi\n" + "push %rsi\n" + "push %rdx\n" + "push %rcx\n" + "push %r8\n" + "push %r9\n" + + "mov %r11, %rdi\n" + "mov %r10, %rsi\n" + + "call ELF_LAZY_RESOLVE_MAIN\n" + + "mov %rax, %r11\n" + + "pop %r9\n" + "pop %r8\n" + "pop %rcx\n" + "pop %rdx\n" + "pop %rsi\n" + "pop %rdi\n" + + "jmp *%r11\n"); +} + +long abs(long i) { return i < 0 ? -i : i; } + +void swap(char *x, char *y) +{ + char t = *x; + *x = *y; + *y = t; +} + +char *reverse(char *Buffer, int i, int j) +{ + while (i < j) + swap(&Buffer[i++], &Buffer[j--]); + return Buffer; +} + +char *ltoa(long Value, char *Buffer, int Base) +{ + if (Base < 2 || Base > 32) + return Buffer; + + long n = abs(Value); + int i = 0; + + while (n) + { + int r = n % Base; + if (r >= 10) + Buffer[i++] = 65 + (r - 10); + else + Buffer[i++] = 48 + r; + n = n / Base; + } + + if (i == 0) + Buffer[i++] = '0'; + + if (Value < 0 && Base == 10) + Buffer[i++] = '-'; + + Buffer[i] = '\0'; + return reverse(Buffer, 0, i - 1); +} + +static inline void PutCharToKernelConsole(char c) +{ + __asm__ __volatile__("syscall" + : + : "a"(1), "D"(c), "S"(0) + : "rcx", "r11", "memory"); +} + +void *memcpy(void *dest, const void *src, __SIZE_TYPE__ n) +{ + __UINT8_TYPE__ *d = dest; + const __UINT8_TYPE__ *s = src; + while (n--) + *d++ = *s++; + return dest; +} + +int strcmp(const char *l, const char *r) +{ + for (; *l == *r && *l; l++, r++) + ; + return *(unsigned char *)l - *(unsigned char *)r; +} + +Elf64_Sym *ELFGetSymbol(__UINTPTR_TYPE__ *ElfFile, char *SymbolName) +{ + struct Elf64_Dyn *_SymTab = ELFGetDynamicTag(ElfFile, DT_SYMTAB); + struct Elf64_Dyn *_StrTab = ELFGetDynamicTag(ElfFile, DT_STRTAB); + Elf64_Sym *DynSym = (Elf64_Sym *)(ElfFile + _SymTab->d_un.d_ptr); + char *DynStr = (char *)(ElfFile + _StrTab->d_un.d_ptr); + + for (int i = 0; i < _SymTab->d_un.d_val; i++) + { + if (strcmp(DynStr + DynSym[i].st_name, SymbolName) == 0) + return &DynSym[i]; + } + return (Elf64_Sym *)0; +} + +void Print(char *String) +{ + for (short i = 0; String[i] != '\0'; i++) + PutCharToKernelConsole(String[i]); +} + +void PrintNL(char *String) +{ + for (short i = 0; String[i] != '\0'; i++) + PutCharToKernelConsole(String[i]); + + PutCharToKernelConsole('\n'); +} + +void (*ELF_LAZY_RESOLVE_MAIN(struct LibAddressCollection *Info, long RelIndex))() +{ + if (Info) + { + struct LibAddressCollection *tmp = Info; + PrintNL("________________"); + // The last entry is the null entry (Valid == false) which determines the end of the list. + while (tmp->Valid) + { + Print("-- "); + Print(tmp->Name); + PrintNL(" --"); + __UINTPTR_TYPE__ BaseAddress = __UINTPTR_MAX__; + + Elf64_Phdr ItrProgramHeader; + + for (Elf64_Half i = 0; i < ((Elf64_Ehdr *)tmp->ElfFile)->e_phnum; i++) + { + memcpy(&ItrProgramHeader, (__UINT8_TYPE__ *)tmp->ElfFile + ((Elf64_Ehdr *)tmp->ElfFile)->e_phoff + ((Elf64_Ehdr *)tmp->ElfFile)->e_phentsize * i, sizeof(Elf64_Phdr)); + BaseAddress = MIN(BaseAddress, ItrProgramHeader.p_vaddr); + } + + char LibAddressBuffer[32]; + ltoa(tmp->MemoryImage, LibAddressBuffer, 16); + Print("MemoryImage: 0x"); + PrintNL(LibAddressBuffer); + + char BaseAddressBuffer[32]; + ltoa(BaseAddress, BaseAddressBuffer, 16); + Print("BaseAddress: 0x"); + PrintNL(BaseAddressBuffer); + + struct Elf64_Dyn *_JmpRel = ELFGetDynamicTag(tmp->ElfFile, DT_JMPREL); + struct Elf64_Dyn *_SymTab = ELFGetDynamicTag(tmp->ElfFile, DT_SYMTAB); + struct Elf64_Dyn *_StrTab = ELFGetDynamicTag(tmp->ElfFile, DT_STRTAB); + + if (!_JmpRel) + { + PrintNL("No DT_JMPREL"); + goto RetryNextLib; + } + else if (RelIndex >= _JmpRel->d_un.d_val / sizeof(Elf64_Rela)) + { + PrintNL("RelIndex is greater than the number of relocations"); + goto RetryNextLib; + } + + if (!_SymTab) + { + PrintNL("No DT_SYMTAB"); + goto RetryNextLib; + } + + if (!_StrTab) + { + PrintNL("No DT_STRTAB"); + goto RetryNextLib; + } + + if (!_JmpRel && !_SymTab && !_StrTab) + goto RetryNextLib; + + char JmpRel_d_ptr[32]; + ltoa(_JmpRel->d_un.d_ptr, JmpRel_d_ptr, 16); + Print("JmpRel_d_ptr: 0x"); + PrintNL(JmpRel_d_ptr); + + char SymTab_d_ptr[32]; + ltoa(_SymTab->d_un.d_ptr, SymTab_d_ptr, 16); + Print("SymTab_d_ptr: 0x"); + PrintNL(SymTab_d_ptr); + + char StrTab_d_ptr[32]; + ltoa(_StrTab->d_un.d_ptr, StrTab_d_ptr, 16); + Print("StrTab_d_ptr: 0x"); + PrintNL(StrTab_d_ptr); + + Elf64_Rela *JmpRel = tmp->MemoryImage + (_JmpRel->d_un.d_ptr - BaseAddress); + Elf64_Sym *SymTab = tmp->MemoryImage + (_SymTab->d_un.d_ptr - BaseAddress); + char *DynStr = tmp->MemoryImage + (_StrTab->d_un.d_ptr - BaseAddress); + + Elf64_Rela *Rel = JmpRel + RelIndex; + // Elf64_Rela *Rel = &JmpRel[RelIndex]; + Elf64_Addr *GOTEntry = (Elf64_Addr *)(tmp->MemoryImage + Rel->r_offset); + + int RelType = ELF64_R_TYPE(Rel->r_info); + + char RelBuffer[32]; + ltoa(Rel, RelBuffer, 16); + Print("Rel: 0x"); + PrintNL(RelBuffer); + + char LibRelInfoBuffer[32]; + ltoa(Rel->r_info, LibRelInfoBuffer, 16); + Print(" Rel->r_info: 0x"); + PrintNL(LibRelInfoBuffer); + + char LibRelOffsetBuffer[32]; + ltoa(Rel->r_offset, LibRelOffsetBuffer, 16); + Print(" Rel->r_offset: 0x"); + PrintNL(LibRelOffsetBuffer); + + char LibRelAddEntBuffer[32]; + ltoa(Rel->r_addend, LibRelAddEntBuffer, 16); + Print(" Rel->r_addend: 0x"); + PrintNL(LibRelAddEntBuffer); + + char RelIndexBuffer[32]; + ltoa(RelIndex, RelIndexBuffer, 16); + Print("RelIndex: 0x"); + PrintNL(RelIndexBuffer); + + char GotAddressBuffer[32]; + ltoa(GOTEntry, GotAddressBuffer, 16); + Print("GOTEntry: 0x"); + PrintNL(GotAddressBuffer); + + if (GOTEntry && GOTEntry < 0x10000000) + { + char GotInsideBuffer[32]; + ltoa(*GOTEntry, GotInsideBuffer, 16); + Print("*GOTEntry: 0x"); + PrintNL(GotInsideBuffer); + } + + switch (RelType) + { + case R_X86_64_NONE: + { + PrintNL("R_X86_64_NONE"); + + if (*GOTEntry == 0) + { + PrintNL("GOTEntry is 0"); + break; + } + Lock = 0; + return (void (*)()) * GOTEntry; + } + case R_X86_64_JUMP_SLOT: + { + PrintNL("R_X86_64_JUMP_SLOT"); + int SymIndex = ELF64_R_SYM(Rel->r_info); + Elf64_Sym *Sym = SymTab + SymIndex; + // Elf64_Sym *Sym = &SymTab[SymIndex]; + + if (Sym->st_name) + { + char *SymName = DynStr + Sym->st_name; + PrintNL(SymName); + + Elf64_Sym *LibSym = ELFGetSymbol(tmp->ElfFile, SymName); + if (LibSym) + { + *GOTEntry = (Elf64_Addr)(tmp->MemoryImage + LibSym->st_value); + Lock = 0; + return (void (*)()) * GOTEntry; + } + } + break; + } + default: + { + char RelTypeBuffer[32]; + ltoa(RelType, RelTypeBuffer, 10); + Print("RelType not supported "); + PrintNL(RelTypeBuffer); + break; + } + } + + RetryNextLib: + tmp = tmp->Next; + } + } + + Lock = 0; + __asm__ __volatile__("mfence\n"); + + char SNotFound[32]; + Print("Symbol index "); + ltoa(RelIndex, SNotFound, 10); + Print(SNotFound); + PrintNL(" not found"); + int ExitCode = 0x51801; + syscall1(_Exit, ExitCode); + __builtin_unreachable(); +} + +bool ELFAddLazyResolverToGOT(void *ElfFile, void *MemoryImage, struct LibAddressCollection *Libs) +{ + struct Elf64_Dyn *Dyn = (struct Elf64_Dyn *)ELFGetDynamicTag(ElfFile, DT_PLTGOT); + if (!Dyn) + return false; + + Elf64_Addr *GOT = (Elf64_Addr *)Dyn->d_un.d_ptr; + + // for (size_t i = 0; i < 16; i++) + // { + // char Itr[32]; + // char LibAddressBuffer[32]; + // char LibValueBuffer[32]; + // ltoa(i, Itr, 10); + // ltoa(&GOT[i], LibAddressBuffer, 16); + // ltoa(GOT[i], LibValueBuffer, 16); + + // Print("GOT["); + // Print(Itr); + // Print("]: 0x"); + // Print(LibAddressBuffer); + // Print(" (val: 0x"); + // Print(LibValueBuffer); + // PrintNL(")"); + // } + + GOT[1] = (uintptr_t)Libs; + GOT[2] = (uintptr_t)ELF_LAZY_RESOLVE_STUB; + return true; +} /* This function is a mess and needs to be cleaned up. */ /* @@ -332,8 +682,9 @@ struct InterpreterIPCDataLibrary typedef struct { char Path[256]; + void *ElfFile; void *MemoryImage; - struct InterpreterIPCDataLibrary Libraries[256]; + struct InterpreterIPCDataLibrary Libraries[64]; } InterpreterIPCData; /* Actual load */ @@ -365,5 +716,24 @@ int ld_load(int argc, char *argv[], char *envp[]) IPC(IPC_DELETE, IPC_TYPE_MessagePassing, IPC_ID, 0, NULL, 0); FreePages((uintptr_t)IPCBuffer, PagesForStruct); - return *(int *)IPCBuffer; + + Elf64_Ehdr *ELFHeader = (Elf64_Ehdr *)IPCBuffer->MemoryImage; + + /* ... */ + + struct LibAddressCollection *LibsForLazyResolver = (struct LibAddressCollection *)RequestPages(sizeof(struct LibAddressCollection) / PageSize + 1); + /* + TODO: Add libraries to LibsForLazyResolver + This can be done by calling the kernel to load the libraries, and then adding them to the LibsForLazyResolver struct. + Kernel has a thread for loading libraries. If the lib is already loaded, it will return the address of the loaded lib. + */ + + if (!ELFAddLazyResolverToGOT(IPCBuffer->ElfFile, IPCBuffer->MemoryImage, LibsForLazyResolver)) + { + for (size_t i = 0; i < 35; i++) + syscall2(_Print, "Failed to add lazy resolver to GOT\n"[i], 0); + return -0xE1F; + } + + return ((int (*)(int, char *[], char *[]))ELFHeader->e_entry)(argc, argv, envp); } diff --git a/libc/ElfInterpreter/resolve.c b/libc/ElfInterpreter/resolve.c deleted file mode 100644 index 565fa95..0000000 --- a/libc/ElfInterpreter/resolve.c +++ /dev/null @@ -1,344 +0,0 @@ -#include "elf.h" - -struct LibAddressCollection -{ - char Name[32]; - __UINTPTR_TYPE__ *ElfFile; - __UINTPTR_TYPE__ *MemoryImage; - __UINTPTR_TYPE__ *ParentElfFile; - __UINTPTR_TYPE__ *ParentMemoryImage; - struct LibAddressCollection *Next; - char Valid; -}; - -#define MIN(a, b) (((a) < (b)) ? (a) : (b)) -#define MAX(a, b) (((a) > (b)) ? (a) : (b)) - -static char Lock = 0; - -__attribute__((naked, used, no_stack_protector)) void ELF_LAZY_RESOLVE_STUB() -{ - while (Lock == 1) - ; - __asm__ __volatile__("mfence\n"); - Lock = 1; - __asm__ __volatile__("pop %r11\n" - "pop %r10\n" - - "push %rdi\n" - "push %rsi\n" - "push %rdx\n" - "push %rcx\n" - "push %r8\n" - "push %r9\n" - - "mov %r11, %rdi\n" - "mov %r10, %rsi\n" - - "call ELF_LAZY_RESOLVE_MAIN\n" - - "mov %rax, %r11\n" - - "pop %r9\n" - "pop %r8\n" - "pop %rcx\n" - "pop %rdx\n" - "pop %rsi\n" - "pop %rdi\n" - - "jmp *%r11\n"); -} - -long abs(long i) { return i < 0 ? -i : i; } - -void swap(char *x, char *y) -{ - char t = *x; - *x = *y; - *y = t; -} - -char *reverse(char *Buffer, int i, int j) -{ - while (i < j) - swap(&Buffer[i++], &Buffer[j--]); - return Buffer; -} - -char *ltoa(long Value, char *Buffer, int Base) -{ - if (Base < 2 || Base > 32) - return Buffer; - - long n = abs(Value); - int i = 0; - - while (n) - { - int r = n % Base; - if (r >= 10) - Buffer[i++] = 65 + (r - 10); - else - Buffer[i++] = 48 + r; - n = n / Base; - } - - if (i == 0) - Buffer[i++] = '0'; - - if (Value < 0 && Base == 10) - Buffer[i++] = '-'; - - Buffer[i] = '\0'; - return reverse(Buffer, 0, i - 1); -} - -static inline void PutCharToKernelConsole(char c) -{ - __asm__ __volatile__("syscall" - : - : "a"(1), "D"(c), "S"(0) - : "rcx", "r11", "memory"); -} - -void *memcpy(void *dest, const void *src, __SIZE_TYPE__ n) -{ - __UINT8_TYPE__ *d = dest; - const __UINT8_TYPE__ *s = src; - while (n--) - *d++ = *s++; - return dest; -} - -int strcmp(const char *l, const char *r) -{ - for (; *l == *r && *l; l++, r++) - ; - return *(unsigned char *)l - *(unsigned char *)r; -} - -Elf64_Sym *ELFGetSymbol(__UINTPTR_TYPE__ *ElfFile, char *SymbolName) -{ - struct Elf64_Dyn *_SymTab = ELFGetDynamicTag(ElfFile, DT_SYMTAB); - struct Elf64_Dyn *_StrTab = ELFGetDynamicTag(ElfFile, DT_STRTAB); - Elf64_Sym *DynSym = (Elf64_Sym *)(ElfFile + _SymTab->d_un.d_ptr); - char *DynStr = (char *)(ElfFile + _StrTab->d_un.d_ptr); - - for (int i = 0; i < _SymTab->d_un.d_val; i++) - { - if (strcmp(DynStr + DynSym[i].st_name, SymbolName) == 0) - return &DynSym[i]; - } - return (Elf64_Sym *)0; -} - -void Print(char *String) -{ - for (short i = 0; String[i] != '\0'; i++) - PutCharToKernelConsole(String[i]); -} - -void PrintNL(char *String) -{ - for (short i = 0; String[i] != '\0'; i++) - PutCharToKernelConsole(String[i]); - - PutCharToKernelConsole('\n'); -} - -long RelTmpIndex = 0xdead; - -void *SymbolNotFound() -{ - // TODO: Print the symbol name and the library name. - // TODO: This should go to the stderr. - char Buffer[32]; - - Print("Symbol index "); - ltoa(RelTmpIndex, Buffer, 10); - Print(Buffer); - PrintNL(" not found"); - return (void *)0xdeadbeef; -} - -void (*ELF_LAZY_RESOLVE_MAIN(struct LibAddressCollection *Info, long RelIndex))() -{ - RelTmpIndex = RelIndex; - if (Info) - { - struct LibAddressCollection *tmp = Info; - PrintNL("________________"); - // The last entry is the null entry (Valid == false) which determines the end of the list. - while (tmp->Valid) - { - Print("-- "); - Print(tmp->Name); - PrintNL(" --"); - __UINTPTR_TYPE__ BaseAddress = __UINTPTR_MAX__; - - Elf64_Phdr ItrProgramHeader; - - for (Elf64_Half i = 0; i < ((Elf64_Ehdr *)tmp->ElfFile)->e_phnum; i++) - { - memcpy(&ItrProgramHeader, (__UINT8_TYPE__ *)tmp->ElfFile + ((Elf64_Ehdr *)tmp->ElfFile)->e_phoff + ((Elf64_Ehdr *)tmp->ElfFile)->e_phentsize * i, sizeof(Elf64_Phdr)); - BaseAddress = MIN(BaseAddress, ItrProgramHeader.p_vaddr); - } - - char LibAddressBuffer[32]; - ltoa(tmp->MemoryImage, LibAddressBuffer, 16); - Print("MemoryImage: 0x"); - PrintNL(LibAddressBuffer); - - char BaseAddressBuffer[32]; - ltoa(BaseAddress, BaseAddressBuffer, 16); - Print("BaseAddress: 0x"); - PrintNL(BaseAddressBuffer); - - struct Elf64_Dyn *_JmpRel = ELFGetDynamicTag(tmp->ElfFile, DT_JMPREL); - struct Elf64_Dyn *_SymTab = ELFGetDynamicTag(tmp->ElfFile, DT_SYMTAB); - struct Elf64_Dyn *_StrTab = ELFGetDynamicTag(tmp->ElfFile, DT_STRTAB); - - if (!_JmpRel) - { - PrintNL("No DT_JMPREL"); - goto RetryNextLib; - } - else if (RelIndex >= _JmpRel->d_un.d_val / sizeof(Elf64_Rela)) - { - PrintNL("RelIndex is greater than the number of relocations"); - goto RetryNextLib; - } - - if (!_SymTab) - { - PrintNL("No DT_SYMTAB"); - goto RetryNextLib; - } - - if (!_StrTab) - { - PrintNL("No DT_STRTAB"); - goto RetryNextLib; - } - - if (!_JmpRel && !_SymTab && !_StrTab) - goto RetryNextLib; - - char JmpRel_d_ptr[32]; - ltoa(_JmpRel->d_un.d_ptr, JmpRel_d_ptr, 16); - Print("JmpRel_d_ptr: 0x"); - PrintNL(JmpRel_d_ptr); - - char SymTab_d_ptr[32]; - ltoa(_SymTab->d_un.d_ptr, SymTab_d_ptr, 16); - Print("SymTab_d_ptr: 0x"); - PrintNL(SymTab_d_ptr); - - char StrTab_d_ptr[32]; - ltoa(_StrTab->d_un.d_ptr, StrTab_d_ptr, 16); - Print("StrTab_d_ptr: 0x"); - PrintNL(StrTab_d_ptr); - - Elf64_Rela *JmpRel = tmp->MemoryImage + (_JmpRel->d_un.d_ptr - BaseAddress); - Elf64_Sym *SymTab = tmp->MemoryImage + (_SymTab->d_un.d_ptr - BaseAddress); - char *DynStr = tmp->MemoryImage + (_StrTab->d_un.d_ptr - BaseAddress); - - Elf64_Rela *Rel = JmpRel + RelIndex; - // Elf64_Rela *Rel = &JmpRel[RelIndex]; - Elf64_Addr *GOTEntry = (Elf64_Addr *)(tmp->MemoryImage + Rel->r_offset); - - int RelType = ELF64_R_TYPE(Rel->r_info); - - char RelBuffer[32]; - ltoa(Rel, RelBuffer, 16); - Print("Rel: 0x"); - PrintNL(RelBuffer); - - char LibRelInfoBuffer[32]; - ltoa(Rel->r_info, LibRelInfoBuffer, 16); - Print(" Rel->r_info: 0x"); - PrintNL(LibRelInfoBuffer); - - char LibRelOffsetBuffer[32]; - ltoa(Rel->r_offset, LibRelOffsetBuffer, 16); - Print(" Rel->r_offset: 0x"); - PrintNL(LibRelOffsetBuffer); - - char LibRelAddEntBuffer[32]; - ltoa(Rel->r_addend, LibRelAddEntBuffer, 16); - Print(" Rel->r_addend: 0x"); - PrintNL(LibRelAddEntBuffer); - - char RelIndexBuffer[32]; - ltoa(RelIndex, RelIndexBuffer, 16); - Print("RelIndex: 0x"); - PrintNL(RelIndexBuffer); - - char GotAddressBuffer[32]; - ltoa(GOTEntry, GotAddressBuffer, 16); - Print("GOTEntry: 0x"); - PrintNL(GotAddressBuffer); - - if (GOTEntry && GOTEntry < 0x10000000) - { - char GotInsideBuffer[32]; - ltoa(*GOTEntry, GotInsideBuffer, 16); - Print("*GOTEntry: 0x"); - PrintNL(GotInsideBuffer); - } - - switch (RelType) - { - case R_X86_64_NONE: - { - PrintNL("R_X86_64_NONE"); - - if (*GOTEntry == 0) - { - PrintNL("GOTEntry is 0"); - break; - } - Lock = 0; - return (void (*)()) * GOTEntry; - } - case R_X86_64_JUMP_SLOT: - { - PrintNL("R_X86_64_JUMP_SLOT"); - int SymIndex = ELF64_R_SYM(Rel->r_info); - Elf64_Sym *Sym = SymTab + SymIndex; - // Elf64_Sym *Sym = &SymTab[SymIndex]; - - if (Sym->st_name) - { - char *SymName = DynStr + Sym->st_name; - PrintNL(SymName); - - Elf64_Sym *LibSym = ELFGetSymbol(tmp->ElfFile, SymName); - if (LibSym) - { - *GOTEntry = (Elf64_Addr)(tmp->MemoryImage + LibSym->st_value); - Lock = 0; - return (void (*)()) * GOTEntry; - } - } - break; - } - default: - { - char RelTypeBuffer[32]; - ltoa(RelType, RelTypeBuffer, 10); - Print("RelType not supported "); - PrintNL(RelTypeBuffer); - break; - } - } - - RetryNextLib: - tmp = tmp->Next; - } - } - - Lock = 0; - __asm__ __volatile__("mfence\n"); - return SymbolNotFound; -}