Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- //dont wait an app from me, here source perhaps it can help to get all pieces togeher, now all is up to you
- #include <stdio.h>
- #include <stdlib.h>
- #include <kernel.h>
- #include <system_service.h>
- #include <orbis2d.h>
- #include <orbisPad.h>
- #include <orbisAudio.h>
- #include <modplayer.h>
- #include <ps4link.h>
- #include <debugnet.h>
- #include <orbissys.h>
- #include <string.h>
- #include <elfloader.h>
- #include <ps4/error.h>
- typedef struct OrbisGlobalConf
- {
- Orbis2dConfig *conf;
- OrbisPadConfig *confPad;
- OrbisAudioConfig *confAudio;
- ps4LinkConfiguration *confLink;
- int orbisLinkFlag;
- }OrbisGlobalConf;
- OrbisGlobalConf globalConf;
- //IV0002-NPXS29040_00-ORBISLINK0000000
- size_t sceLibcHeapSize = 256 * 1024 * 1024;
- typedef struct Ps4MemoryProtected
- {
- void *writable;
- void *executable;
- size_t size;
- }Ps4MemoryProtected;
- int ps4MemoryProtectedCreate(Ps4MemoryProtected **memory, size_t size)
- {
- int executableHandle, writableHandle;
- Ps4MemoryProtected *m;
- long pageSize = 0x4000;//sysconf(_SC_PAGESIZE);
- if(memory == NULL)
- return PS4_ERROR_ARGUMENT_PRIMARY_MISSING;
- if(size == 0)
- return PS4_ERROR_ARGUMENT_SIZE_NULL;
- m = (Ps4MemoryProtected *)malloc(sizeof(Ps4MemoryProtected));
- if(m == NULL)
- return PS4_ERROR_OUT_OF_MEMORY;
- m->size = (size / pageSize + 1) * pageSize; // align to pageSize
- m->executable = mmap(NULL, m->size, 7, 0x1000, -1, 0);
- if(m->executable == MAP_FAILED)
- goto e1;
- m->writable = m->executable;
- if(m->writable == MAP_FAILED)
- goto e1;
- *memory = m;
- return PS4_OK;
- e1:
- free(m);
- return PS4_ERROR_OUT_OF_MEMORY; // make error codes proper errnos ... everywhere ... meh
- }
- int ps4MemoryProtectedDestroy(Ps4MemoryProtected *memory)
- {
- int r = 0;
- if(memory == NULL)
- return -1;
- r |= munmap(memory->writable, memory->size);
- r |= munmap(memory->executable, memory->size);
- free(memory);
- return r;
- }
- int ps4MemoryProtectedGetWritableAddress(Ps4MemoryProtected *memory, void **address)
- {
- if(memory == NULL)
- return PS4_ERROR_ARGUMENT_PRIMARY_MISSING;
- if(address == NULL)
- return PS4_ERROR_ARGUMENT_OUT_MISSING;
- *address = memory->writable;
- return PS4_OK;
- }
- int ps4MemoryProtectedGetExecutableAddress(Ps4MemoryProtected *memory, void **address)
- {
- if(memory == NULL)
- return PS4_ERROR_ARGUMENT_PRIMARY_MISSING;
- if(address == NULL)
- return PS4_ERROR_ARGUMENT_OUT_MISSING;
- *address = memory->executable;
- return PS4_OK;
- }
- int ps4MemoryProtectedGetSize(Ps4MemoryProtected *memory, size_t *size)
- {
- if(memory == NULL)
- return PS4_ERROR_ARGUMENT_PRIMARY_MISSING;
- if(size == NULL)
- return PS4_ERROR_ARGUMENT_OUT_MISSING;
- *size = memory->size;
- return PS4_OK;
- }
- void orbisMemorySet(void *p,unsigned char value,int size)
- {
- unsigned char *buf=(unsigned char *)p;
- //for(i=0;i<size;i++)
- //{
- // buf[i]=value;
- //}
- debugNetPrintf(3,"[ORBISLINK] orbisMemorySet before memset\n");
- memset(buf,value,size);
- debugNetPrintf(3,"[ORBISLINK] orbisMemorySet after memset\n");
- }
- void orbisMemoryCopy(void *to,void *from,size_t size)
- {
- debugNetPrintf(DEBUG,"[ORBISLINK] orbisMemoryCopy before memcpy\n");
- memcpy(to,from,size);
- debugNetPrintf(DEBUG,"[ORBISLINK] orbisMemoryCopy after memcpy\n");
- }
- /* Defines */
- #define elfRelocationSymbol __ELFN(R_SYM)
- #define elfRelocationType __ELFN(R_TYPE)
- #define elfRelocationInfo __ELFN(R_INFO)
- #define elfSymbolBind __ELFN(ST_BIND)
- #define elfSymbolType __ELFN(ST_TYPE)
- #define elfSymbolInfo __ELFN(ST_INFO)
- #define elfIsElf(e) IS_ELF(*elfHeader(e)) // FIXME: Null deref
- #define elfClass(e) (e == NULL ? 0 : e->data[4])
- #define elfEncoding(e) (e == NULL ? 0 : e->data[5])
- #define elfVersion(e) (e == NULL ? 0 : e->data[6])
- #define elfABI(e) (e == NULL ? 0 : e->data[7])
- /* Constants */
- enum{ ELF_MAXIMAL_STRING_LENGTH = 4096 };
- /* Type */
- typedef struct Elf // FIXME: We could cache a lot of offsets here to inc. performance
- {
- uint8_t *data;
- size_t size; // FIXME: Do more checks on size
- }
- Elf;
- size_t elfGetSize(Elf *elf)
- {
- return elf->size;
- }
- uint8_t *elfGetData(Elf *elf)
- {
- return elf->data;
- }
- /* --- elf header --- */
- ElfHeader *elfHeader(Elf *elf)
- {
- if(!elf)
- return NULL;
- return (ElfHeader *)elf->data;
- }
- uint64_t elfEntry(Elf *elf)
- {
- if(!elf)
- return 0;
- ElfHeader *h = elfHeader(elf);
- if(!h)
- return 0;
- return h->e_entry;
- }
- uint64_t elfLargestAlignment(Elf *elf) //ignore ...
- {
- uint16_t index = 0;
- uint64_t alignment = 0;
- while(1)
- {
- ElfSegment *h = elfSegment(elf, &index, ELF_SEGMENT_ATTRIBUTE_TYPE, PT_LOAD);
- if(!h)
- break;
- // FIXME: Tired of bogus 2MB alignment -> ignore
- if(alignment < h->p_align && h->p_align < 0x200000)
- alignment = h->p_align;
- ++index;
- }
- return alignment;
- }
- size_t elfMemorySize(Elf *elf)
- {
- ElfSection *sections;
- ElfSegment *segments;
- uint16_t size;
- uint16_t length;
- uint16_t index;
- size_t memorySize = 0;
- if(!elf)
- return 0;
- segments = elfSegments(elf, &size, &length);
- if(segments)
- {
- for(index = 0; index < length; ++index)
- {
- ElfSegment *s = (ElfSegment *)((uint8_t *)segments + index * size);
- if(memorySize < s->p_paddr + s->p_memsz)
- memorySize = s->p_paddr + s->p_memsz;
- }
- }
- else
- {
- length = 0;
- sections = elfSections(elf, &size, &length);
- if(!sections)
- return 0;
- for(index = 0; index < length; ++index)
- {
- ElfSection *s = (ElfSection *)((uint8_t *)sections + index * size);
- if(memorySize < s->sh_addr + s->sh_size)
- memorySize = s->sh_addr + s->sh_size;
- }
- }
- return memorySize;
- }
- /* --- elf section header --- */
- char *elfSectionStrings(Elf *elf, uint64_t *size)
- {
- ElfHeader *h;
- uint16_t i;
- ElfSection *s;
- h = elfHeader(elf);
- i = h->e_shstrndx;
- s = elfSection(elf, &i, ELF_SECTION_ATTRIBUTE_NONE, 0);
- if(size)
- *size = s->sh_size;
- return (char *)elf->data + s->sh_offset;
- }
- uint64_t elfSectionAttribute(ElfSection *elfSection, ElfSectionAttribute attribute)
- {
- switch(attribute)
- {
- case ELF_SECTION_ATTRIBUTE_NAME:
- return elfSection->sh_name;
- case ELF_SECTION_ATTRIBUTE_TYPE:
- return elfSection->sh_type;
- case ELF_SECTION_ATTRIBUTE_FLAGS:
- return elfSection->sh_flags;
- case ELF_SECTION_ATTRIBUTE_ADDRESS:
- return elfSection->sh_addr;
- case ELF_SECTION_ATTRIBUTE_OFFSET:
- return elfSection->sh_offset;
- case ELF_SECTION_ATTRIBUTE_SIZE:
- return elfSection->sh_size;
- case ELF_SECTION_ATTRIBUTE_LINK:
- return elfSection->sh_link;
- case ELF_SECTION_ATTRIBUTE_INFO:
- return elfSection->sh_info;
- case ELF_SECTION_ATTRIBUTE_MEMORY_ALIGNMENT:
- return elfSection->sh_addralign;
- case ELF_SECTION_ATTRIBUTE_ENTRY_SIZE:
- return elfSection->sh_entsize;
- default:
- break;
- }
- return 0;
- }
- ElfSection *elfSections(Elf *elf, uint16_t *size, uint16_t *length)
- {
- ElfHeader *h;
- if(!elf)
- return NULL;
- h = elfHeader(elf);
- if(h->e_shoff == 0)
- return NULL;
- if(size != NULL)
- *size = h->e_shentsize;
- if(length != NULL)
- *length = h->e_shnum;
- return (ElfSection *)(elf->data + h->e_shoff);
- }
- ElfSection *elfSection(Elf *elf, uint16_t *index, ElfSectionAttribute attribute, uint64_t value)
- {
- uint16_t size;
- uint16_t length;
- ElfSection *h, *t;
- uint16_t i = 0;
- if(!index)
- index = &i;
- h = elfSections(elf, &size, &length);
- if(!h)
- return NULL;
- for(; *index < length; ++(*index))
- {
- t = (ElfSection *)((uint8_t *)h + *index * size);
- if(attribute == ELF_SECTION_ATTRIBUTE_NONE || elfSectionAttribute(t, attribute) == value)
- return t;
- }
- return NULL;
- }
- ElfSection *elfSectionByName(Elf *elf, char *name)
- {
- uint64_t size;
- char *mem = elfSectionStrings(elf, &size);
- uint32_t offset = elfStringToOffset(mem, size, name);
- ElfSection *sh = elfSection(elf, NULL, ELF_SECTION_ATTRIBUTE_NAME, offset);
- return sh;
- }
- /* --- elf segment header --- */
- uint64_t elfSegmentAttribute(ElfSegment *elfSegment, ElfSegmentAttribute attribute)
- {
- switch(attribute)
- {
- case ELF_SEGMENT_ATTRIBUTE_TYPE:
- return elfSegment->p_type;
- case ELF_SEGMENT_ATTRIBUTE_FLAGS:
- return elfSegment->p_flags;
- case ELF_SEGMENT_ATTRIBUTE_OFFSET:
- return elfSegment->p_offset;
- case ELF_SEGMENT_ATTRIBUTE_VIRTUAL_ADDRESS:
- return elfSegment->p_vaddr;
- case ELF_SEGMENT_ATTRIBUTE_PHYSICAL_ADDRESS:
- return elfSegment->p_paddr;
- case ELF_SEGMENT_ATTRIBUTE_FILE_SIZE:
- return elfSegment->p_filesz;
- case ELF_SEGMENT_ATTRIBUTE_MEMORY_SIZE:
- return elfSegment->p_memsz;
- case ELF_SEGMENT_ATTRIBUTE_ALIGNMENT:
- return elfSegment->p_align;
- default:
- break;
- }
- return 0;
- }
- ElfSegment *elfSegments(Elf *elf, uint16_t *size, uint16_t *length)
- {
- ElfHeader *h;
- if(!elf)
- return NULL;
- h = elfHeader(elf);
- if(h->e_phoff == 0)
- return NULL;
- if(size != NULL)
- *size = h->e_phentsize;
- if(length != NULL)
- *length = h->e_phnum;
- return (ElfSegment *)(elf->data + h->e_phoff);
- }
- ElfSegment *elfSegment(Elf *elf, uint16_t *index, ElfSegmentAttribute attribute, uint64_t value)
- {
- uint16_t size;
- uint16_t length;
- ElfSegment *h, *t;
- uint16_t i = 0;
- if(!index)
- index = &i;
- h = elfSegments(elf, &size, &length);
- if(!h)
- return NULL;
- for(; *index < length; ++(*index))
- {
- t = (ElfSegment *)((uint8_t *)h + *index * size);
- if(attribute == ELF_SEGMENT_ATTRIBUTE_NONE || elfSegmentAttribute(t, attribute) == value)
- return t;
- }
- return NULL;
- }
- /* --- elf dynamic section --- */
- uint64_t elfDynamicAttribute(ElfDynamic *elfDynamic, ElfDynamicAttribute attribute)
- {
- switch(attribute)
- {
- case ELF_DYNAMIC_ATTRIBUTE_TAG:
- return elfDynamic->d_tag;
- case ELF_DYNAMIC_ATTRIBUTE_VALUE:
- return elfDynamic->d_un.d_val;
- case ELF_DYNAMIC_ATTRIBUTE_POINTER:
- return elfDynamic->d_un.d_ptr;
- default:
- break;
- }
- return 0;
- }
- uint16_t elfDynamicsLength(ElfDynamic *dyn)
- {
- uint16_t i = 0;
- if(dyn != NULL)
- for(;dyn->d_tag != DT_NULL; ++dyn)
- ++i;
- return i;
- }
- ElfDynamic *elfDynamics(Elf *elf, uint16_t *size, uint16_t *length)
- {
- ElfSection *h;
- ElfSegment *h2;
- if(!elf)
- return NULL;
- if((h = elfSection(elf, NULL, ELF_SECTION_ATTRIBUTE_TYPE, SHT_DYNAMIC)))
- {
- if(size != NULL)
- *size = h->sh_entsize;
- if(length != NULL)
- *length = h->sh_size / h->sh_entsize;
- return (ElfDynamic *)(elf->data + h->sh_offset);
- }
- else if((h2 = elfSegment(elf, NULL, ELF_SEGMENT_ATTRIBUTE_TYPE, PT_DYNAMIC)))
- {
- if(size != NULL)
- *size = sizeof(ElfDynamic);
- if(length != NULL) //h2->p_filesz / sizeof(ElfDynamic);
- *length = elfDynamicsLength((ElfDynamic *)(elf->data + h2->p_offset));
- return (ElfDynamic *)(elf->data + h2->p_offset);
- }
- return NULL;
- }
- ElfDynamic *elfDynamic(Elf *elf, uint16_t *index, ElfDynamicAttribute attribute, uint64_t value)
- {
- uint16_t size;
- uint16_t length;
- ElfDynamic *h, *t;
- uint16_t i = 0;
- if(!index)
- index = &i;
- h = elfDynamics(elf, &size, &length);
- if(!h)
- return NULL;
- for(; *index < length; ++(*index))
- {
- t = (ElfDynamic *)((uint8_t *)h + *index * size);
- if(attribute == ELF_DYNAMIC_ATTRIBUTE_NONE || elfDynamicAttribute(t, attribute) == value)
- return t;
- }
- return NULL;
- }
- ElfDynamic *elfLoadedDynamics(Elf *elf, uint16_t *size, uint16_t *length)
- {
- //ElfSection *h;
- ElfSegment *h2;
- if(!elf)
- return NULL;
- if((h2 = elfSegment(elf, NULL, ELF_SEGMENT_ATTRIBUTE_TYPE, PT_DYNAMIC)))
- {
- if(size != NULL)
- *size = sizeof(ElfDynamic);
- if(length != NULL)
- *length = elfDynamicsLength((ElfDynamic *)h2->p_vaddr);
- return (ElfDynamic *)h2->p_vaddr;
- }
- return NULL;
- }
- ElfDynamic *elfLoadedDynamic(Elf *elf, uint16_t *index, ElfDynamicAttribute attribute, uint64_t value)
- {
- uint16_t size;
- uint16_t length;
- ElfDynamic *h, *t;
- uint16_t i = 0;
- if(!index)
- index = &i;
- h = elfLoadedDynamics(elf, &size, &length);
- if(!h)
- return NULL;
- for(; *index < length; ++(*index))
- {
- t = (ElfDynamic *)((uint8_t *)h + *index * size);
- if(attribute == ELF_DYNAMIC_ATTRIBUTE_NONE || elfDynamicAttribute(t, attribute) == value)
- return t;
- }
- return NULL;
- }
- /* --- elf string tables --- */
- char *elfStringFromIndex(char *mem, uint64_t size, uint32_t index)
- {
- uint64_t i, j = 0;
- if(!mem)
- return NULL;
- if(index == 0)
- return mem;
- for(i = 0; i < size - 1; ++i)
- if(mem[i] == '\0' && ++j == index)
- return mem + i + 1;
- return NULL;
- }
- char *elfStringFromOffset(char *mem, uint64_t size, uint32_t offset)
- {
- if(!mem || offset >= size)
- return NULL;
- return mem + offset;
- }
- uint32_t elfStringToOffset(char *mem, uint64_t size, char *str)
- {
- uint64_t i, j;
- if(!str)
- return 0;
- for(i = 0; i < size; ++i)
- {
- for(j = 0; j < ELF_MAXIMAL_STRING_LENGTH && mem[i + j] == str[j]; ++j)
- if(str[j] == '\0')
- return i;
- }
- return 0;
- }
- uint32_t elfStringToIndex(char *mem, uint64_t size, char *str)
- {
- uint64_t index, i, j;
- if(!str)
- return 0;
- index = 0;
- for(i = 0; i < size; ++i)
- {
- for(j = 0; j < ELF_MAXIMAL_STRING_LENGTH && mem[i + j] == str[j]; ++j)
- if(str[j] == '\0')
- return index;
- if(mem[i] == '\0')
- index++;
- }
- return 0;
- }
- /* --- elf relocations --- */
- uint64_t elfAddendRelocationAttribute(ElfAddendRelocation *elfAddendRelocation, ElfAddendRelocationAttribute attribute)
- {
- switch(attribute)
- {
- case ELF_ADDEND_RELOCATION_ATTRIBUTE_INFO:
- return elfAddendRelocation->r_info;
- case ELF_ADDEND_RELOCATION_ATTRIBUTE_OFFSET:
- return elfAddendRelocation->r_offset;
- case ELF_ADDEND_RELOCATION_ATTRIBUTE_ADDEND:
- return elfAddendRelocation->r_addend;
- default:
- break;
- }
- return 0;
- }
- ElfAddendRelocation *elfAddendRelocations(Elf *elf, char *name, uint16_t *size, uint16_t *length)
- {
- ElfSection *h;
- h = elfSectionByName(elf, name);
- if(!h || h->sh_type != SHT_RELA)
- return NULL;
- if(size != NULL)
- *size = h->sh_entsize;
- if(length != NULL)
- *length = h->sh_size / h->sh_entsize;
- return (ElfAddendRelocation *)(elf->data + h->sh_offset);
- }
- // FIXME this is not performant, better to pass in the base ElfAddendRelocation *, size and length
- /*
- ElfAddendRelocation *elfAddendRelocation(Elf *elf, char *name, uint16_t *index, ElfAddendRelocationAttribute attribute, uint64_t value)
- {
- uint16_t size;
- uint16_t length;
- ElfAddendRelocation *h, *t;
- uint16_t i = 0;
- if(!index)
- index = &i;
- h = elfAddendRelocations(elf, name, &size, &length);
- if(!h)
- return NULL;
- for(; *index < length; ++(*index))
- {
- t = (ElfAddendRelocation *)((uint8_t *)h + *index * size);
- if(attribute == ElfAddendRelocationAttributeNone || elfAddendRelocationAttribute(t, attribute) == value)
- return t;
- }
- return NULL;
- }
- */
- /* --- elf symbols --- */
- uint64_t elfSymbolAttribute(ElfSymbol *elfSymbol, ElfSymbolAttribute attribute)
- {
- switch(attribute)
- {
- case ELF_SYMBOL_ATTRIBUTE_NAME:
- return elfSymbol->st_name;
- case ELF_SYMBOL_ATTRIBUTE_INFO:
- return elfSymbol->st_info;
- case ELF_SYMBOL_ATTRIBUTE_UNUSED:
- return elfSymbol->st_other;
- case ELF_SYMBOL_ATTRIBUTE_SECTION_INDEX:
- return elfSymbol->st_shndx;
- case ELF_SYMBOL_ATTRIBUTE_VALUE:
- return elfSymbol->st_value;
- case ELF_SYMBOL_ATTRIBUTE_SIZE:
- return elfSymbol->st_size;
- default:
- break;
- }
- return 0;
- }
- ElfSymbol *elfSymbols(Elf *elf, char *name, uint16_t *size, uint16_t *length)
- {
- ElfSection *h;
- h = elfSectionByName(elf, name);
- if(!h || (h->sh_type != SHT_SYMTAB && h->sh_type != SHT_DYNSYM))
- return NULL;
- if(size != NULL)
- *size = h->sh_entsize;
- if(length != NULL)
- *length = h->sh_size / h->sh_entsize;
- return (ElfSymbol *)(elf->data + h->sh_offset);
- }
- /*
- ElfSymbol *elfSymbol(Elf *elf, char *name, uint16_t *index, ElfSymbolAttribute attribute, uint64_t value)
- {
- uint16_t size;
- uint16_t length;
- ElfSymbol *h, *t;
- uint16_t i = 0;
- if(!index)
- index = &i;
- h = elfSymbols(elf, name, &size, &length);
- if(!h)
- return NULL;
- for(; *index < length; ++(*index))
- {
- t = (ElfSymbol *)((uint8_t *)h + *index * size);
- if(attribute == ElfSymbolAttributeNone || elfSymbolAttribute(t, attribute) == value)
- return t;
- }
- return NULL;
- }*/
- /* actions */
- Elf *elfCreate(void *data, size_t size)
- {
- Elf *elf, t;
- if(data == NULL)
- return NULL;
- t.data = data;
- t.size = size;
- if(!elfIsElf(&t))
- return NULL;
- elf = malloc(sizeof(Elf));
- if(elf==NULL)
- {
- debugNetPrintf(DEBUG,"[ORBISLINK] elfCreate error malloc return null\n");
- return NULL;
- }
- elf->data = (uint8_t *)data;
- elf->size = size;
- return elf;
- }
- Elf *elfCreateLocal(void *elfl, void *data, size_t size)
- {
- Elf *elf, t;
- if(elfl == NULL || data == NULL)
- return NULL;
- t.data = data;
- t.size = size;
- if(!elfIsElf(&t))
- return NULL;
- elf = (Elf *)elfl;
- elf->data = (uint8_t *)data;
- elf->size = size;
- return elf;
- }
- Elf *elfCreateLocalUnchecked(void *elfl, void *data, size_t size)
- {
- Elf *elf;
- if(elfl == NULL || data == NULL)
- return NULL;
- elf = (Elf *)elfl;
- elf->data = (uint8_t *)data;
- elf->size = size;
- return elf;
- }
- void *elfDestroy(Elf *elf)
- {
- void *data;
- if(elf == NULL)
- return NULL;
- if(elf->data!=NULL)
- {
- //debugNetPrintf(3,"data %x\n",elf->data);
- //data = elf->data;
- munmap(elf->data,elf->size);
- //free(elf->data);
- }
- return elf;
- }
- void elfDestroyAndFree(Elf *elf)
- {
- void *d;
- if(elf == NULL)
- return;
- //debugNetPrintf(3,"elf %x\n",elf);
- d = elfDestroy(elf);
- //debugNetPrintf(3,"d %x\n",d);
- if(d)
- free(d);
- }
- /* --- --- */
- int elfLoaderIsLoadable(Elf *elf)
- {
- ElfHeader *h;
- if(!elfIsElf(elf))
- return 0;
- h = elfHeader(elf);
- return elfClass(elf) == ELFCLASS64 &&
- elfEncoding(elf) == ELFDATA2LSB &&
- elfVersion(elf) == EV_CURRENT &&
- (elfABI(elf) == ELFOSABI_SYSV || elfABI(elf) == ELFOSABI_FREEBSD) &&
- h->e_type == ET_DYN &&
- h->e_phoff != 0 &&
- h->e_shoff != 0 &&
- h->e_machine == EM_X86_64 &&
- h->e_version == EV_CURRENT;
- }
- int elfLoaderInstantiate(Elf *elf, void *memory)
- {
- ElfSection *sections;
- ElfSegment *segments;
- uint16_t size;
- uint16_t length;
- uint16_t index;
- if(elf == NULL)
- return ELF_LOADER_RETURN_ELF_NULL;
- if(memory == NULL)
- return ELF_LOADER_RETURN_NO_WRITABLE_MEMORY;
- segments = elfSegments(elf, &size, &length);
- if(segments)
- {
- debugNetPrintf(DEBUG,"[ORBISLINK] elfLoaderInstantiate in segments length=%d\n",length);
- for(index = 0; index < length; ++index)
- {
- ElfSegment *s = (ElfSegment *)((uint8_t *)segments + index * size);
- if(s->p_filesz)
- {
- debugNetPrintf(DEBUG,"[ORBISLINK] elfLoaderInstantiate before elfLoaderInstantiate memcpy %p %p %d\n",(char *)memory + s->p_paddr,elf->data + s->p_offset,s->p_filesz);
- orbisMemoryCopy((char *)memory + s->p_paddr, elf->data + s->p_offset, s->p_filesz);
- debugNetPrintf(DEBUG,"[ORBISLINK] elfLoaderInstantiate after elfLoaderInstantiate memcpy\n");
- }
- if(s->p_memsz - s->p_filesz)
- { //memset((char *)memory + s->p_paddr + s->p_filesz, 0, s->p_memsz - s->p_filesz);
- debugNetPrintf(DEBUG,"[ORBISLINK] elfLoaderInstantiate before elfLoaderInstantiate orbisMemorySet\n");
- orbisMemorySet((char *)memory + s->p_paddr + s->p_filesz,0,s->p_memsz - s->p_filesz);
- debugNetPrintf(DEBUG,"[ORBISLINK] elfLoaderInstantiate after elfLoaderInstantiate orbisMemorySet\n");
- }
- }
- }
- else
- {
- length = 0;
- sections = elfSections(elf, &size, &length);
- if(!sections)
- return 0;
- for(index = 0; index < length; ++index)
- {
- ElfSection *s = (ElfSection *)((uint8_t *)sections + index * size);
- if(!(s->sh_flags & SHF_ALLOC))
- continue;
- if(s->sh_size)
- {
- orbisMemoryCopy((char *)memory + s->sh_addr, elf->data + s->sh_offset, s->sh_size);
- debugNetPrintf(DEBUG,"[ORBISLINK] elfLoaderInstantiate after elfLoaderInstantiate second memcpy\n");
- }
- }
- }
- return ELF_LOADER_RETURN_OK;
- }
- int elfLoaderRelativeAddressIsExecutable(Elf *elf, int64_t address)
- {
- ElfSection *sections;
- ElfSegment *segments;
- uint16_t size;
- uint16_t length;
- uint16_t index;
- if(elf == NULL)
- return 0;
- segments = elfSegments(elf, &size, &length);
- if(segments)
- {
- for(index = 0; index < length; ++index)
- {
- ElfSegment *s = (ElfSegment *)((uint8_t *)segments + index * size);
- if(address >= s->p_paddr && address <= s->p_paddr + s->p_memsz)
- return s->p_flags & PF_X;
- }
- }
- else
- {
- length = 0;
- sections = elfSections(elf, &size, &length);
- if(!sections)
- return ELF_LOADER_RETURN_NO_SECTIONS_OR_SEGMENTS;
- for(index = 0; index < length; ++index)
- {
- ElfSection *s = (ElfSection *)((uint8_t *)sections + index * size);
- if(address >= s->sh_addr && address <= s->sh_addr + s->sh_size)
- return s->sh_flags & SHF_EXECINSTR;
- }
- }
- return 1; // FIXME: Recheck
- }
- // FIXME: Implement ps4 aware relocation for functions using dlsym
- int elfLoaderRelocate(Elf *elf, void *writable, void *executable)
- {
- int i, j;
- uint16_t relocationSize = 0;
- uint16_t relocationsLength = 0;
- ElfAddendRelocation *relocations;
- uint16_t dynamicSymbolSize = 0;
- uint16_t dynamicSymbolsLength = 0;
- ElfSymbol *dynamicSymbols;
- char *r1 = ".rela.dyn";
- char *r2 = ".rela.plt";
- char *rel[2] = {r1, r2};
- if(elf == NULL)
- return ELF_LOADER_RETURN_ELF_NULL;
- if(writable == NULL)
- return ELF_LOADER_RETURN_NO_WRITABLE_MEMORY;
- if(executable == NULL)
- return ELF_LOADER_RETURN_NO_EXECUTABLE_MEMORY;
- dynamicSymbols = elfSymbols(elf, ".dynsym", &dynamicSymbolSize, &dynamicSymbolsLength);
- //symbols = elfSymbols(elf, ".symtab", &symbolSize, &symbolsLength);
- for(j = 0; j < sizeof(rel) / sizeof(rel[0]); ++j)
- {
- relocationsLength = 0;
- relocations = elfAddendRelocations(elf, rel[j], &relocationSize, &relocationsLength);
- for(i = 0; i < relocationsLength; ++i)
- {
- ElfSymbol *symbol;
- ElfAddendRelocation *relocation = (ElfAddendRelocation *)(((uint8_t *)relocations) + relocationSize * i);
- uint16_t relocationType = (uint16_t)elfRelocationType(relocation->r_info);
- uint16_t relocationSymbol = (uint16_t)elfRelocationSymbol(relocation->r_info);
- uint8_t **offset = (uint8_t **)((uint8_t *)writable + relocation->r_offset);
- int64_t value = 0;
- switch(relocationType)
- {
- case R_X86_64_RELATIVE:
- value = relocation->r_addend;
- break;
- case R_X86_64_64:
- symbol = (ElfSymbol *)(((uint8_t *)dynamicSymbols) + dynamicSymbolSize * relocationSymbol);
- value = symbol->st_value + relocation->r_addend;
- break;
- case R_X86_64_JMP_SLOT:
- case R_X86_64_GLOB_DAT:
- symbol = (ElfSymbol *)(((uint8_t *)dynamicSymbols) + dynamicSymbolSize * relocationSymbol);
- value = symbol->st_value;
- break;
- default:
- return ELF_LOADER_RETURN_UNKNOWN_RELOCATION;
- }
- if(elfLoaderRelativeAddressIsExecutable(elf, value))
- *offset = (uint8_t *)executable + value;
- else
- *offset = (uint8_t *)writable + value;
- }
- }
- return ELF_LOADER_RETURN_OK;
- }
- int elfLoaderLoad(Elf *elf, void *writable, void *executable)
- {
- int r = ELF_LOADER_RETURN_OK;
- if(elf == NULL)
- return ELF_LOADER_RETURN_ELF_NULL;
- if(writable == NULL)
- return ELF_LOADER_RETURN_NO_WRITABLE_MEMORY;
- if(executable == NULL)
- return ELF_LOADER_RETURN_NO_EXECUTABLE_MEMORY;
- if(!elfLoaderIsLoadable(elf))
- return ELF_LOADER_RETURN_IS_NOT_LOADABLE;
- if((r = elfLoaderInstantiate(elf, writable)) != ELF_LOADER_RETURN_OK)
- {
- debugNetPrintf(DEBUG,"[ORBISLINK] elfLoaderLoad after elfLoaderInstantiate error return=%d\n",r);
- return r;
- }
- debugNetPrintf(DEBUG,"[ORBISLINK] elfLoaderLoad after elfLoaderInstantiate return=%d\n",r);
- r = elfLoaderRelocate(elf, writable, executable);
- debugNetPrintf(DEBUG,"[ORBISLINK] elfLoaderLoad after elfLoaderRelocate return=%d\n",r);
- return r;
- }
- extern ps4LinkConfiguration *configuration;
- typedef int (*ElfMain)(int argc, char **argv);
- typedef void (*ElfProcessMain)(void *arg);
- typedef void (*ElfProcessExit)(int ret);
- typedef void (*ElfProcessFree)(void *m, void *t);
- typedef struct ElfRunUserArgument
- {
- ElfMain main;
- Ps4MemoryProtected *memory;
- }
- ElfRunUserArgument;
- void *orbisUserMain(void *arg)
- {
- ElfRunUserArgument *argument = (ElfRunUserArgument *)arg;
- globalConf.confLink=configuration;
- //ps4LinkConfiguration *shared_conf=configuration;
- char pointer_conf[256];
- sprintf(pointer_conf,"%p",&globalConf);
- debugNetPrintf(DEBUG,"[ORBISLINK] orbisUserMain Configuration pointer %p, pointer_conf string %s\n",&globalConf,pointer_conf);
- char *elfName = "elf";
- char *elfArgv[3] = { elfName, pointer_conf, NULL };
- int elfArgc = 2;
- int r;
- if(argument == NULL)
- return NULL;
- r = argument->main(elfArgc, elfArgv);
- ps4MemoryProtectedDestroy(argument->memory);
- //ps4MemoryDestroy(argument->memory);
- free(argument);
- debugNetPrintf(DEBUG,"[ORBISLINK] orbisUserMain return (user): %i\n", r);
- return NULL;
- }
- int orbisUserRun(Elf *elf)
- {
- //pthread_t thread;
- ScePthread thread;
- int ret;
- ElfRunUserArgument *argument;
- void *writable, *executable;
- int r;
- if(elf == NULL)
- return -1;
- debugNetPrintf(DEBUG,"[ORBISLINK] orbisUserRun malloc for argument\n");
- argument = (ElfRunUserArgument *)malloc(sizeof(ElfRunUserArgument));
- if(argument == NULL)
- {
- elfDestroyAndFree(elf);
- debugNetPrintf(DEBUG,"[ORBISLINK] orbisUserRun argument is NULL\n");
- return -1;
- }
- debugNetPrintf(DEBUG,"[ORBISLINK] orbisUserRun after malloc for argument\n");
- if(ps4MemoryProtectedCreate(&argument->memory, elfMemorySize(elf)) != 0)
- //if(ps4MemoryCreate(&argument->memory, elfMemorySize(elf)) != PS4_OK)
- {
- free(argument);
- elfDestroyAndFree(elf);
- debugNetPrintf(DEBUG,"[ORBISLINK] orbisUserRun after elfDestroyAndFree\n");
- return -1;
- }
- debugNetPrintf(DEBUG,"[ORBISLINK] orbisUserRun after ps4MemoryProtectedCreate\n");
- argument->main = NULL;
- ps4MemoryProtectedGetWritableAddress(argument->memory, &writable);
- debugNetPrintf(DEBUG,"[ORBISLINK] orbisUserRun after ps4MemoryProtectedGetWritableAddress writable=%p\n",writable);
- ps4MemoryProtectedGetExecutableAddress(argument->memory, &executable);
- debugNetPrintf(DEBUG,"[ORBISLINK] orbisUserRun after ps4MemoryProtectedGetExecutableAddress executable=%p\n",executable);
- r = elfLoaderLoad(elf, writable, executable);
- //r = elfLoaderLoad(elf, ps4MemoryGetAddress(argument->memory), ps4MemoryGetAddress(argument->memory));
- debugNetPrintf(DEBUG,"[ORBISLINK] orbisUserRun after elfLoaderLoad return r=%d readable=%p executable=%p\n",r,writable,executable);
- if(r == ELF_LOADER_RETURN_OK)
- {
- argument->main = (ElfMain)((uint8_t *)executable + elfEntry(elf));
- debugNetPrintf(DEBUG,"[ORBISLINK] orbisUserRun after set argument->main %p \n",argument->main);
- }
- //elfDestroyAndFree(elf); // we don't need the "file" anymore but if i leave this line i got a memory crash
- debugNetPrintf(DEBUG,"[ORBISLINK] orbisUserRun after elfDestroyAndFree \n");
- if(argument->main != NULL)
- { //pthread_create(&thread, NULL, elfLoaderUserMain, argument);
- ret=scePthreadCreate(&thread, NULL, orbisUserMain, argument, "elf_user_thid");
- if(ret==0)
- {
- debugNetPrintf(DEBUG,"[ORBISLINK] New user elf thread UID: 0x%08X\n", thread);
- }
- else
- {
- debugNetPrintf(DEBUG,"[ORBISLINK] New user elf thread could not create error: 0x%08X\n", ret);
- scePthreadCancel(thread);
- //ps4LinkFinish();
- return PS4_NOT_OK;
- }
- }
- else
- {
- ps4MemoryProtectedDestroy(argument->memory);
- free(argument);
- debugNetPrintf(DEBUG,"[ORBISLINK]orbisUserRun argument->main is released\n");
- return -1;
- }
- return PS4_OK;
- }
- Elf * orbisReadElfFromHost(char *path)
- {
- int fd; //descriptor to manage file from host0
- int filesize;//variable to control file size
- uint8_t *buf=NULL;//buffer for read from host0 file
- Elf *elf;//elf to create from buf
- //we open file in read only from host0 ps4sh include the full path with host0:/.......
- fd=ps4LinkOpen(path,O_RDONLY,0);
- //If we can't open file from host0 print the error and return
- if(fd<0)
- {
- debugNetPrintf(DEBUG,"[ORBISLINK] ps4LinkOpen returned error opening file %d\n",fd);
- return NULL;
- }
- //Seek to final to get file size
- filesize=ps4LinkLseek(fd,0,SEEK_END);
- //If we get an error print it and return
- if(filesize<0)
- {
- debugNetPrintf(DEBUG,"[ORBISLINK] ps4LinkSeek returned error %d\n",fd);
- ps4LinkClose(fd);
- return NULL;
- }
- //Seek back to start
- ps4LinkLseek(fd,0,SEEK_SET);
- //Reserve memory for read buffer
- //buf=malloc(filesize);
- //char buf[filesize];
- debugNetPrintf(DEBUG,"[ORBISLINK] before orbisSysMmap\n");
- buf=mmap(NULL,filesize,0x01|0x02,0x1000|0x0002,-1,0);
- if(buf==MAP_FAILED)
- {
- debugNetPrintf(DEBUG,"[ORBISLINK] mmap returned error tryng one more time\n");
- buf=mmap(NULL,filesize,0x01|0x02,0x1000|0x0002,-1,0);
- if(buf==MAP_FAILED)
- {
- debugNetPrintf(DEBUG,"[ORBISLINK] mmap returned error again\n");
- ps4LinkClose(fd);
- return NULL;
- }
- }
- //Read filsesize bytes to buf
- int numread=ps4LinkRead(fd,buf,filesize);
- //if we don't get filesize bytes we are in trouble
- if(numread!=filesize)
- {
- sleep(1);
- debugNetPrintf(DEBUG,"[ORBISLINK] ps4LinkRead returned error %d\n",numread);
- sleep(1);
- ps4LinkClose(fd);
- return NULL;
- }
- //Close file
- ps4LinkClose(fd);
- //create elf from elfloader code from hitodama :P
- elf = elfCreate((void*)buf, filesize);
- //check is it is loadable
- if(!elfLoaderIsLoadable(elf))
- {
- debugNetPrintf(DEBUG,"[ORBISLINK] elf %s is not loadable\n",path);
- //free(buf);
- elfDestroy(elf);
- elf = NULL;
- }
- return elf;
- }
- void orbisExecUserElf()
- {
- Elf *elf=NULL;
- debugNetPrintf(DEBUG,"[ORBISLINK] orbisExecUserElf called\n");
- elf=orbisReadElfFromHost("host0:homebrew.elf");
- if(elf==NULL)
- {
- debugNetPrintf(DEBUG,"[ORBISLINK] orbisExecUserElf we can't create elf\n");
- return;
- }
- debugNetPrintf(DEBUG,"[ORBISLINK] orbisExecUserElf ready to run elf\n");
- orbisUserRun(elf);
- return;
- }
- void finishOrbisLinkApp()
- {
- orbisAudioFinish();
- orbisPadFinish();
- orbis2dFinish();
- ps4LinkFinish();
- }
- void initOrbisLinkApp()
- {
- int ret;
- int jailbreak_out=-1;
- //jailbreak_out=orbisSysJailBreak();
- globalConf.orbisLinkFlag=0;
- ret=ps4LinkInit("192.168.1.3",0x4711,0x4712,0x4712,3);
- if(!ret)
- {
- ps4LinkFinish();
- return;
- }
- while(!ps4LinkRequestsIsConnected())
- {
- }
- //debugNetPrintf(DEBUG,"[ORBISLINK] orbisSysJailBreak returned %d\n",jailbreak_out);
- debugNetPrintf(DEBUG,"[ORBISLINK] Initialized and connected from pc/mac ready to receive commands\n");
- ret=orbisPadInit();
- if(ret==1)
- {
- globalConf.confPad=orbisPadGetConf();
- ret=orbis2dInit();
- debugNetPrintf(DEBUG,"[ORBISLINK] orbis2dInit return %x \n",ret);
- if(ret==1)
- {
- globalConf.conf=orbis2dGetConf();
- ret=orbisAudioInit();
- if(ret==1)
- {
- ret=orbisAudioInitChannel(ORBISAUDIO_CHANNEL_MAIN,1024,48000,ORBISAUDIO_FORMAT_S16_STEREO);
- sleep(1);
- debugNetPrintf(DEBUG,"[ORBISLINK] orbisAudioInitChannel return %x \n",ret);
- sleep(1);
- globalConf.confAudio=orbisAudioGetConf();
- }
- }
- }
- //hide orbislink splash
- //sceSystemServiceHideSplashScreen();
- }
- int main()
- {
- initOrbisLinkApp();
- debugNetPrintf(DEBUG,"[ORBISLINK]Loading homebrew.elf from host\n");
- orbisExecUserElf();
- while(!globalConf.orbisLinkFlag)
- {
- }
- finishOrbisLinkApp();
- exit(0);
- return 0;
- }
Add Comment
Please, Sign In to add comment