diff --git a/Makefile b/Makefile index ff704950e17d5d22aa54f7338ad8df0698c43625..9f5f3565af611cf15f60957b08f8cb7fceadb148 100644 --- a/Makefile +++ b/Makefile @@ -14,7 +14,7 @@ SUBDIRS := miosix ## List here your source files (both .s, .c and .cpp) ## SRC := \ -main.cpp svc.s +main.cpp elf_program.cpp svc.s ## ## List here additional static libraries with relative path diff --git a/app_template/main.c b/app_template/main.c index 89100a112ba3ebba1b76c1d5ea227175a30a1a69..1172683998576fa974d4061175aecd7355e27a93 100644 --- a/app_template/main.c +++ b/app_template/main.c @@ -8,13 +8,15 @@ int mystrlen(const char *s) return result; } -int youShouldNotSeeThisInTheElfFile=0; -int *youShouldNotSeeThisInTheElfFile2=&youShouldNotSeeThisInTheElfFile; +//int youShouldNotSeeThisInTheElfFile=0; +//int *youShouldNotSeeThisInTheElfFile2=&youShouldNotSeeThisInTheElfFile; int main() { //FIXME: without static code fails!! static const char str[]="Hello world\n"; - youShouldNotSeeThisInTheElfFile=write(1,str,mystrlen(str)); - return *youShouldNotSeeThisInTheElfFile2; + //youShouldNotSeeThisInTheElfFile=write(1,str,mystrlen(str)); + //return *youShouldNotSeeThisInTheElfFile2; + write(1,str,mystrlen(str)); + return 0; } diff --git a/elf_program.cpp b/elf_program.cpp index 93bdeba8e13cea45256cc83541d91f738dfcbba6..1e370dd3340ae93f6a1462d8ea0a4dbb39422d4f 100644 --- a/elf_program.cpp +++ b/elf_program.cpp @@ -1,3 +1,29 @@ +/*************************************************************************** + * Copyright (C) 2012 by Terraneo Federico * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * As a special exception, if other files instantiate templates or use * + * macros or inline functions from this file, or you compile this file * + * and link it with other works to produce a work based on this file, * + * this file does not by itself cause the resulting work to be covered * + * by the GNU General Public License. However the source code for this * + * file must still be made available in accordance with the GNU General * + * Public License. This exception does not invalidate any other reasons * + * why a work based on this file might be covered by the GNU General * + * Public License. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, see <http://www.gnu.org/licenses/> * + ***************************************************************************/ #include "elf_program.h" #include <stdexcept> @@ -21,7 +47,8 @@ ElfProgram::ElfProgram(const unsigned int *elf, unsigned int size) : elf(elf) { //Trying to follow the "full recognition before processing" approach, //(http://www.cs.dartmouth.edu/~sergey/langsec/occupy/FullRecognition.jpg) - //all of the elf fields that will later be used are checked in advance + //all of the elf fields that will later be used are checked in advance. + //Unused fields are unchecked, so when using new fields, add new checks if(validateHeader(size)==false) throw runtime_error("Bad file"); } @@ -30,9 +57,10 @@ bool ElfProgram::validateHeader(unsigned int size) //Validate ELF header //Note: this code assumes a little endian elf and a little endian ARM CPU if(size<sizeof(Elf32_Ehdr)) return false; - static const char magic[EI_NIDENT]={0x7f,'E','L','F',1,1,1}; - if(memcmp(elf,magic,EI_NIDENT)) throw runtime_error("Unrecognized format"); const Elf32_Ehdr *ehdr=getElfHeader(); + static const char magic[EI_NIDENT]={0x7f,'E','L','F',1,1,1}; + if(memcmp(ehdr->e_ident,magic,EI_NIDENT)) + throw runtime_error("Unrecognized format"); if(ehdr->e_type!=ET_EXEC) throw runtime_error("Not an executable"); if(ehdr->e_machine!=EM_ARM) throw runtime_error("Wrong CPU arch"); if(ehdr->e_version!=EV_CURRENT) return false; @@ -50,8 +78,8 @@ bool ElfProgram::validateHeader(unsigned int size) bool codeSegmentPresent=false; bool dataSegmentPresent=false; bool dynamicSegmentPresent=false; - const Elf32_Phdr *phdr=getProgramHeaderTable(); int dataSegmentSize; + const Elf32_Phdr *phdr=getProgramHeaderTable(); for(int i=0;i<getNumOfProgramHeaderEntries();i++,phdr++) { //The third condition does not imply the other due to 32bit wraparound @@ -63,14 +91,6 @@ bool ElfProgram::validateHeader(unsigned int size) switch(phdr->p_type) { - case PT_DYNAMIC: - if(dynamicSegmentPresent) return false; //Two dynamic segments? - dynamicSegmentPresent=true; - //DYNAMIC segment *must* come after data segment - if(dataSegmentPresent==false) return false; - if(validateDynamicSegment(phdr,size,dataSegmentSize)==false) - return false; - break; case PT_LOAD: if(phdr->p_flags & ~(PF_R | PF_W | PF_X)) return false; if(!(phdr->p_flags & PF_R)) return false; @@ -78,22 +98,31 @@ bool ElfProgram::validateHeader(unsigned int size) throw runtime_error("File violates W^X"); if(phdr->p_flags & PF_X) { - if(codeSegmentPresent) return false; //Two code segments? + if(codeSegmentPresent) return false; //Can't apper twice codeSegmentPresent=true; if(ehdr->e_entry<phdr->p_offset || ehdr->e_entry>phdr->p_offset+phdr->p_filesz || phdr->p_filesz!=phdr->p_memsz) return false; } - if(phdr->p_flags & PF_W) + if((phdr->p_flags & PF_W) && !(phdr->p_flags & PF_X)) { if(dataSegmentPresent) return false; //Two data segments? dataSegmentPresent=true; + if(phdr->p_memsz<phdr->p_filesz) return false; int maxSize=MAX_PROCESS_IMAGE_SIZE-MIN_PROCESS_STACK_SIZE; if(phdr->p_memsz>=maxSize) throw runtime_error("Data segment too big"); dataSegmentSize=phdr->p_memsz; } break; + case PT_DYNAMIC: + if(dynamicSegmentPresent) return false; //Two dynamic segments? + dynamicSegmentPresent=true; + //DYNAMIC segment *must* come after data segment + if(dataSegmentPresent==false) return false; + if(validateDynamicSegment(phdr,size,dataSegmentSize)==false) + return false; + break; default: //Ignoring other segments break; @@ -106,9 +135,9 @@ bool ElfProgram::validateHeader(unsigned int size) bool ElfProgram::validateDynamicSegment(const Elf32_Phdr *dynamic, unsigned int size, unsigned int dataSegmentSize) { - unsigned int base=reinterpret_cast<unsigned int>(elf); + unsigned int base=getElfBase(); const Elf32_Dyn *dyn= - reinterpret_cast<const Elf32_Dyn*>(base+dynamic->p_offset); + reinterpret_cast<const Elf32_Dyn*>(getElfBase()+dynamic->p_offset); const int dynSize=dynamic->p_memsz/sizeof(Elf32_Dyn); Elf32_Addr dtRel; Elf32_Word dtRelsz; @@ -158,6 +187,7 @@ bool ElfProgram::validateDynamicSegment(const Elf32_Phdr *dynamic, case R_ARM_RELATIVE: if(rel->r_offset<DATA_START) return false; if(rel->r_offset>DATA_START+dataSegmentSize-4) return false; + if(rel->r_offset & 0x3) return false; break; default: throw runtime_error("Unexpected relocation type"); @@ -175,7 +205,76 @@ void ProcessImage::load(ElfProgram& program) { if(image) delete[] image; - + //TODO: add in elf file a field with the true image size + image=new unsigned int[MAX_PROCESS_IMAGE_SIZE/4]; + const unsigned int base=program.getElfBase(); + const Elf32_Phdr *phdr=program.getProgramHeaderTable(); + Elf32_Addr dtRel; + Elf32_Word dtRelsz; + bool hasRelocs=false; + for(int i=0;i<program.getNumOfProgramHeaderEntries();i++,phdr++) + { + switch(phdr->p_type) + { + case PT_LOAD: + if((phdr->p_flags & PF_W) && !(phdr->p_flags & PF_X)) + { + const char *dataSegmentInFile= + reinterpret_cast<const char*>(base+phdr->p_offset); + char *dataSegmentInMem=reinterpret_cast<char*>(image); + memcpy(dataSegmentInMem,dataSegmentInFile,phdr->p_filesz); + dataSegmentInMem+=phdr->p_filesz; + memset(dataSegmentInMem,0,phdr->p_memsz-phdr->p_filesz); + } + break; + case PT_DYNAMIC: + { + const Elf32_Dyn *dyn=reinterpret_cast<const Elf32_Dyn*> + (base+phdr->p_offset); + const int dynSize=phdr->p_memsz/sizeof(Elf32_Dyn); + for(int i=0;i<dynSize;i++,dyn++) + { + switch(dyn->d_tag) + { + case DT_REL: + hasRelocs=true; + dtRel=dyn->d_un.d_ptr; + break; + case DT_RELSZ: + hasRelocs=true; + dtRelsz=dyn->d_un.d_val; + break; + default: + break; + } + } + break; + } + default: + //Ignoring other segments + break; + } + } + if(hasRelocs) + { + const Elf32_Rel *rel=reinterpret_cast<const Elf32_Rel*>(base+dtRel); + const int relSize=dtRelsz/sizeof(Elf32_Rel); + for(int i=0;i<relSize;i++,rel++) + { + switch(ELF32_R_TYPE(rel->r_info)) + { + case R_ARM_ABS32: + case R_ARM_RELATIVE: + { + unsigned int offset=(rel->r_offset-DATA_START)/4; + image[offset]+=reinterpret_cast<unsigned int>(image); + break; + } + default: + break; + } + } + } } ProcessImage::~ProcessImage() diff --git a/elf_program.h b/elf_program.h index 7d51eb5db6f14b999f3cbaf4aad44ecfd3a64046..0dcb4eb142806c8766835a343214650dd2e7e969 100644 --- a/elf_program.h +++ b/elf_program.h @@ -1,3 +1,29 @@ +/*************************************************************************** + * Copyright (C) 2012 by Terraneo Federico * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * As a special exception, if other files instantiate templates or use * + * macros or inline functions from this file, or you compile this file * + * and link it with other works to produce a work based on this file, * + * this file does not by itself cause the resulting work to be covered * + * by the GNU General Public License. However the source code for this * + * file must still be made available in accordance with the GNU General * + * Public License. This exception does not invalidate any other reasons * + * why a work based on this file might be covered by the GNU General * + * Public License. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, see <http://www.gnu.org/licenses/> * + ***************************************************************************/ #include <utility> #include "elf_types.h" @@ -56,6 +82,14 @@ public: return getElfHeader()->e_phnum; } + /** + * \return a number representing the elf base address in memory + */ + unsigned int getElfBase() const + { + return reinterpret_cast<unsigned int>(elf); + } + private: /** * \param size elf file size @@ -95,6 +129,11 @@ public: */ void load(ElfProgram& program); + /** + * \return a pointer to the base of the program image + */ + unsigned int *getProcessBasePointer() const { return image; } + /** * \return the size of the process image, or zero if it is not valid */ diff --git a/elf_types.h b/elf_types.h index 8f985c4038742b70ee96b4c8efa856b339d9c57e..48d242dcf88f5afc2a3d0a118066fbc2c87ea5e8 100644 --- a/elf_types.h +++ b/elf_types.h @@ -1,23 +1,48 @@ -/* - * File: ELF.h - * Author: lr - * - * Created on March 3, 2012, 3:31 PM - */ +/*************************************************************************** + * Copyright (C) 2012 by Luigi Rucco and Terraneo Federico * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * As a special exception, if other files instantiate templates or use * + * macros or inline functions from this file, or you compile this file * + * and link it with other works to produce a work based on this file, * + * this file does not by itself cause the resulting work to be covered * + * by the GNU General Public License. However the source code for this * + * file must still be made available in accordance with the GNU General * + * Public License. This exception does not invalidate any other reasons * + * why a work based on this file might be covered by the GNU General * + * Public License. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, see <http://www.gnu.org/licenses/> * + ***************************************************************************/ #include <inttypes.h> #ifndef ELF_TYPES_H #define ELF_TYPES_H +// elf-specific types typedef uint32_t Elf32_Word; typedef int32_t Elf32_Sword; typedef uint16_t Elf32_Half; typedef uint32_t Elf32_Off; typedef uint32_t Elf32_Addr; +// Size of e_ident in the elf header static const int EI_NIDENT=16; +/* + * Elf header + */ struct Elf32_Ehdr { unsigned char e_ident[EI_NIDENT]; // Ident bytes @@ -53,6 +78,9 @@ static const int EM_ARM = 0x28; static const int EF_ARM_EABI_MASK = 0x05000000; static const int EF_HAS_ENTRY_POINT = 2; +/* + * Elf program header + */ struct Elf32_Phdr { Elf32_Word p_type; // Program header type, any of the PH_* constants @@ -77,12 +105,15 @@ static const int PF_X = 0x1; // Execute static const int PF_W = 0x2; // Write static const int PF_R = 0x4; // Read +/* + * Entries of the DYNAMIC segment + */ struct Elf32_Dyn { - Elf32_Sword d_tag; + Elf32_Sword d_tag; // Type of entry union { - Elf32_Word d_val; - Elf32_Addr d_ptr; + Elf32_Word d_val; // Value of entry, if number + Elf32_Addr d_ptr; // Value of entry, if offset into the file } d_un; } __attribute__((packed)); @@ -113,6 +144,9 @@ static const int DT_TEXTREL = 22; static const int DT_JMPREL = 23; static const int DT_BINDNOW = 24; +/* + * Relocation entries + */ struct Elf32_Rel { Elf32_Addr r_offset; diff --git a/main.cpp b/main.cpp index 57160e135ea11954aec013765f885e816af3f257..d24ff7793b7494663bd031290bb0db9ddd9d862c 100644 --- a/main.cpp +++ b/main.cpp @@ -2,8 +2,8 @@ #include <cstdio> #include <cassert> #include "miosix.h" -#include "elf_types.h" -#include "prog1.h" +#include "elf_program.h" +#include "prog2.h" using namespace std; using namespace miosix; @@ -68,34 +68,6 @@ void ledThread(void *) } } -void loadPhdr(const Elf32_Ehdr *elf) -{ - assert(elf->e_phentsize==sizeof(Elf32_Phdr)); - unsigned int base=reinterpret_cast<unsigned int>(elf); - const Elf32_Phdr *hdr=reinterpret_cast<const Elf32_Phdr*>(base+elf->e_phoff); - for(int i=0;i<elf->e_phnum;i++,hdr++) - { - switch(hdr->p_type) - { - case PT_DYNAMIC: - printf("Entry %d is dynamic\n",i); - break; - case PT_LOAD: - printf("Entry %d is load\n",i); - break; - default: - printf("Unexpected\n"); - } - printf("Offset in file=%d\n",hdr->p_offset); - printf("Virtual address=%d\n",hdr->p_vaddr); - printf("Physical address=%d\n",hdr->p_paddr); - printf("Size in file=%d\n",hdr->p_filesz); - printf("Size in memory=%d\n",hdr->p_memsz); - printf("Flags=%d\n",hdr->p_flags); - printf("Align=%d\n",hdr->p_align); - } -} - int main() { Thread::create(ledThread,STACK_MIN); @@ -103,15 +75,15 @@ int main() getchar(); - const Elf32_Ehdr *elf=reinterpret_cast<const Elf32_Ehdr*>(main_elf); - loadPhdr(elf); - unsigned int base=reinterpret_cast<unsigned int>(main_elf); - base+=elf->e_entry; - void (*elfentry)(void*)=reinterpret_cast<void (*)(void*)>(base); - iprintf("elf base address = %p\n",main_elf); - iprintf("elf entry is = %p\n",elf->e_entry); - iprintf("elf entry (absolute) is = %p\n",elfentry); - - Thread::create(elfentry,2048); + ElfProgram prog(reinterpret_cast<const unsigned int*>(main_elf),main_elf_len); + ProcessImage pi; + pi.load(prog); + + void *(*entry)(void*)=reinterpret_cast<void *(*)(void*)>(prog.getEntryPoint()); + iprintf("elf base address = 0x%x\n",prog.getElfBase()); + iprintf("elf entry (rebased) = 0x%x\n",prog.getEntryPoint()); + iprintf("base pointer = %p\n",pi.getProcessBasePointer()); + + Thread::createWithGotBase(entry,2048,1,0,0,pi.getProcessBasePointer()); for(;;) Thread::sleep(1000); } diff --git a/miosix/arch/cortexM3_stm32f2/common/interfaces-impl/portability.cpp b/miosix/arch/cortexM3_stm32f2/common/interfaces-impl/portability.cpp index 721fe8b8ac6d81ee926702c829a9acecfadd861e..0e938acb2c4a0701540d13e87fbc34b5091f073f 100644 --- a/miosix/arch/cortexM3_stm32f2/common/interfaces-impl/portability.cpp +++ b/miosix/arch/cortexM3_stm32f2/common/interfaces-impl/portability.cpp @@ -190,6 +190,26 @@ void initCtxsave(unsigned int *ctxsave, void *(*pc)(void *), unsigned int *sp, //leaving the content of r4-r11 uninitialized } +void initCtxsave(unsigned int *ctxsave, void *(*pc)(void *), unsigned int *sp, + void *argv, unsigned int gotBase) +{ + unsigned int *stackPtr=sp; + stackPtr--; //Stack is full descending, so decrement first + *stackPtr=0x01000000; stackPtr--; //--> xPSR + *stackPtr=reinterpret_cast<unsigned long>( + &miosix::Thread::threadLauncher); stackPtr--; //--> pc + *stackPtr=0xffffffff; stackPtr--; //--> lr + *stackPtr=0; stackPtr--; //--> r12 + *stackPtr=0; stackPtr--; //--> r3 + *stackPtr=0; stackPtr--; //--> r2 + *stackPtr=reinterpret_cast<unsigned long >(argv); stackPtr--; //--> r1 + *stackPtr=reinterpret_cast<unsigned long >(pc); //--> r0 + + ctxsave[0]=reinterpret_cast<unsigned long>(stackPtr); //--> psp + ctxsave[6]=gotBase; //r9 + //leaving the content of r4-r11 uninitialized +} + void IRQportableStartKernel() { //Enable fault handlers diff --git a/miosix/arch/cortexM3_stm32f2/common/interfaces-impl/portability_impl.h b/miosix/arch/cortexM3_stm32f2/common/interfaces-impl/portability_impl.h index d01c03f1e9e973fc2e29dda53d915221f040da45..5da3a2bb3f137def8cc57d355c0ff6d185afd73c 100644 --- a/miosix/arch/cortexM3_stm32f2/common/interfaces-impl/portability_impl.h +++ b/miosix/arch/cortexM3_stm32f2/common/interfaces-impl/portability_impl.h @@ -194,6 +194,9 @@ private: friend void ISR_yield(); }; +void initCtxsave(unsigned int *ctxsave, void *(*pc)(void *), unsigned int *sp, + void *argv, unsigned int gotBase); + #endif //WITH_PROCESSES /** diff --git a/miosix/config/Makefile.inc b/miosix/config/Makefile.inc index f963354d242dabe0ace48b36f436175ae24299c6..4fdf4fdcefb7bb391cbec456c841c9789ebdb294 100644 --- a/miosix/config/Makefile.inc +++ b/miosix/config/Makefile.inc @@ -13,13 +13,13 @@ ## architecture ## #OPT_BOARD := lpc2138_miosix_board -OPT_BOARD := stm32f103ze_stm3210e-eval +#OPT_BOARD := stm32f103ze_stm3210e-eval #OPT_BOARD := stm32f103ve_mp3v2 #OPT_BOARD := stm32f100rb_stm32vldiscovery #OPT_BOARD := stm32f103ve_strive_mini #OPT_BOARD := stm32f103ze_redbull_v2 #OPT_BOARD := stm32f407vg_stm32f4discovery -#OPT_BOARD := stm32f207ig_stm3220g-eval +OPT_BOARD := stm32f207ig_stm3220g-eval ## ## Optimization flags, choose one. diff --git a/miosix/kernel/kernel.cpp b/miosix/kernel/kernel.cpp index a53c9c0585a75984c3ab036efab0a53073a1047a..9d0f4ba1927b49442ee76347dbf0caa2930d9fd3 100644 --- a/miosix/kernel/kernel.cpp +++ b/miosix/kernel/kernel.cpp @@ -366,6 +366,75 @@ Thread *Thread::create(void (*startfunc)(void *), unsigned int stacksize, stacksize,priority,argv,options); } +Thread *Thread::createWithGotBase(void *(*startfunc)(void *), + unsigned int stacksize, + Priority priority, void *argv, + unsigned short options,unsigned int *gotBase) +{ + //Check to see if input parameters are valid + if(priority.validate()==false || stacksize<STACK_MIN) + { + errorHandler(INVALID_PARAMETERS); + return NULL; + } + //If stacksize is not divisible by 4, round it to a number divisible by 4 + stacksize &= ~0x3; + + //Allocate memory for the thread, return if fail + unsigned int *base; + Thread *thread; + #ifdef __NO_EXCEPTIONS + base=new int[(stacksize+WATERMARK_LEN+CTXSAVE_ON_STACK)/4]; + thread=new Thread(base,stacksize); + #else //__NO_EXCEPTIONS + try { + base=new unsigned int[(stacksize+WATERMARK_LEN+CTXSAVE_ON_STACK)/4]; + } catch(std::bad_alloc&) + { + errorHandler(OUT_OF_MEMORY); + return NULL;//Error + } + try { + thread=new Thread(base,stacksize); + } catch(std::bad_alloc&) + { + delete[] base; + errorHandler(OUT_OF_MEMORY); + return NULL;//Error + } + #endif //__NO_EXCEPTIONS + + //Fill watermark and stack + memset(base, WATERMARK_FILL, WATERMARK_LEN); + base+=WATERMARK_LEN/sizeof(unsigned int); + memset(base, STACK_FILL, stacksize); + + //On some architectures some registers are saved on the stack, therefore + //initCtxsave *must* be called after filling the stack. + unsigned int *topOfStack= + thread->watermark+(stacksize+WATERMARK_LEN+CTXSAVE_ON_STACK)/4; + miosix_private::initCtxsave(thread->ctxsave,startfunc,topOfStack,argv, + (unsigned int)gotBase); + + if((options & JOINABLE)==0) thread->flags.IRQsetDetached(); + + //Add thread to thread list + { + //Handling the list of threads, critical section is required + PauseKernelLock lock; + if(Scheduler::PKaddThread(thread,priority)==false) + { + //Reached limit on number of threads + delete thread; + return NULL; + } + } + #ifdef SCHED_TYPE_EDF + if(isKernelRunning()) yield(); //The new thread might have a closer deadline + #endif //SCHED_TYPE_EDF + return thread; +} + void Thread::yield() { miosix_private::doYield(); diff --git a/miosix/kernel/kernel.h b/miosix/kernel/kernel.h index 63c4d96cf69b2797ddc5eab76954beb193250d3f..27653175ecefea0a1a3a936f0dc70eec66a82d97 100644 --- a/miosix/kernel/kernel.h +++ b/miosix/kernel/kernel.h @@ -466,6 +466,11 @@ public: static Thread *create(void (*startfunc)(void *), unsigned int stacksize, Priority priority=Priority(), void *argv=NULL, unsigned short options=DEFAULT); + + static Thread *createWithGotBase(void *(*startfunc)(void *), + unsigned int stacksize, + Priority priority, void *argv, + unsigned short options,unsigned int *gotBase); /** * When called, suggests the kernel to pause the current thread, and run @@ -924,6 +929,9 @@ private: //Needs threadLauncher friend void miosix_private::initCtxsave(unsigned int *ctxsave, void *(*pc)(void *), unsigned int *sp, void *argv); + //Needs threadLauncher + friend void miosix_private::initCtxsave(unsigned int *ctxsave, + void *(*pc)(void *), unsigned int *sp, void *argv,unsigned int gotBase); //Needs access to priority, savedPriority, mutexLocked and flags. friend class Mutex; //Needs access to flags diff --git a/prog1.h b/prog1.h index cb2de8ebce3bdf56703bf94776388a6400a3c6e1..b993810f85b4d1cd867557f9cc4dbda4c16cb08b 100644 --- a/prog1.h +++ b/prog1.h @@ -1,29 +1,36 @@ -const unsigned char main_elf[] = { +const unsigned char __attribute__((aligned(8))) main_elf[] = { 0x7f, 0x45, 0x4c, 0x46, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x28, 0x00, 0x01, 0x00, 0x00, 0x00, 0x99, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x05, 0x34, 0x00, 0x20, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x98, 0x00, 0x00, 0x00, - 0x98, 0x00, 0x00, 0x00, 0x98, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, - 0x80, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x18, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, - 0x00, 0x00, 0x00, 0x10, 0x20, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, + 0x98, 0x00, 0x00, 0x00, 0x98, 0x00, 0x00, 0x00, 0x78, 0x00, 0x00, 0x00, + 0x78, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x10, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, + 0x00, 0x00, 0x00, 0x10, 0x7c, 0x00, 0x00, 0x00, 0x84, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, - 0xe0, 0x00, 0x00, 0x00, 0xe0, 0x00, 0x00, 0x00, 0xe0, 0x00, 0x00, 0x00, - 0x38, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, + 0x24, 0x01, 0x00, 0x00, 0x14, 0x00, 0x00, 0x10, 0x14, 0x00, 0x00, 0x10, + 0x50, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x0c, 0xf8, - 0x00, 0xf0, 0x1a, 0xf8, 0x03, 0x78, 0x23, 0xb1, 0x00, 0x23, 0x01, 0x33, + 0x00, 0xf0, 0x26, 0xf8, 0x03, 0x78, 0x23, 0xb1, 0x00, 0x23, 0x01, 0x33, 0xc2, 0x5c, 0x00, 0x2a, 0xfb, 0xd1, 0x18, 0x46, 0x70, 0x47, 0x00, 0xbf, - 0x10, 0xb5, 0x06, 0x4c, 0x4c, 0x44, 0x20, 0x46, 0xff, 0xf7, 0xf0, 0xff, - 0x21, 0x46, 0x02, 0x46, 0x01, 0x20, 0x00, 0xf0, 0x07, 0xf8, 0x00, 0x20, - 0x10, 0xbd, 0x00, 0xbf, 0x10, 0x00, 0x00, 0x00, 0x01, 0x23, 0x00, 0xdf, - 0x02, 0x23, 0x00, 0xdf, 0x70, 0x47, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, + 0x10, 0xb5, 0x0a, 0x4c, 0x4c, 0x44, 0x20, 0x46, 0xff, 0xf7, 0xf0, 0xff, + 0x21, 0x46, 0x02, 0x46, 0x01, 0x20, 0x00, 0xf0, 0x13, 0xf8, 0x06, 0x4b, + 0x06, 0x4a, 0x59, 0xf8, 0x03, 0x30, 0x59, 0xf8, 0x02, 0x20, 0x1b, 0x68, + 0x10, 0x60, 0x18, 0x68, 0x10, 0xbd, 0x00, 0xbf, 0x68, 0x00, 0x00, 0x00, + 0x10, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x01, 0x23, 0x00, 0xdf, + 0x02, 0x23, 0x00, 0xdf, 0x70, 0x47, 0x00, 0x00, 0x78, 0x00, 0x00, 0x10, + 0x02, 0x03, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x10, 0x17, 0x00, 0x00, 0x00, + 0x10, 0x00, 0x00, 0x10, 0x17, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x10, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x10, + 0x78, 0x00, 0x00, 0x10, 0x15, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x11, 0x00, 0x00, 0x00, 0xf8, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, + 0x18, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48, 0x65, 0x6c, 0x6c, - 0x6f, 0x20, 0x77, 0x6f, 0x72, 0x6c, 0x64, 0x0a, 0x00, 0x00, 0x00, 0x00 + 0x00, 0x00, 0x00, 0x00, 0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x20, 0x77, 0x6f, + 0x72, 0x6c, 0x64, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; -unsigned int main_elf_len = 312; +unsigned int main_elf_len = 396; diff --git a/test_driver.cpp b/test_driver.cpp index 074b254ffd8a89b36cdf85c29f3fc9353b7fc5a1..33ce17376ac524b642233e6bd4a286df972c537e 100644 --- a/test_driver.cpp +++ b/test_driver.cpp @@ -21,4 +21,6 @@ int main() <<"base address = "<<elfFileData<<endl <<"entry (file relative) = "<<program.getElfHeader()->e_entry<<endl <<"entry (relocated) = "<<program.getEntryPoint()<<endl; + ProcessImage pi; + pi.load(program); }