diff --git a/Makefile b/Makefile index 9f5f3565af611cf15f60957b08f8cb7fceadb148..30fe556eed04564ce892d67ca5566e8a576ff9ca 100644 --- a/Makefile +++ b/Makefile @@ -14,7 +14,7 @@ SUBDIRS := miosix ## List here your source files (both .s, .c and .cpp) ## SRC := \ -main.cpp elf_program.cpp svc.s +main.cpp elf_program.cpp ## ## List here additional static libraries with relative path diff --git a/app_template/Makefile b/app_template/Makefile index c6c18b62c10a80de4eb33525cce743dd3fd532af..dd38e874d9c142289fa8f6abf7d23b1e0bd7a856 100644 --- a/app_template/Makefile +++ b/app_template/Makefile @@ -27,6 +27,7 @@ all: $(OBJ) crt0.o $(CXX) $(LFLAGS) -o main.elf $(OBJ) crt0.o $(LINK_LIBS) $(SZ) main.elf @perl finalstage.pl main.elf --strip-sectheader + @xxd -i main.elf | sed 's/unsigned char/const unsigned char __attribute__((aligned(8)))/' > prog3.h clean: -rm $(OBJ) crt0.o main.elf main.map diff --git a/app_template/main.c b/app_template/main.c index 1172683998576fa974d4061175aecd7355e27a93..6f422421c0ba352b03230e433bc5ac9e24ddf5cd 100644 --- a/app_template/main.c +++ b/app_template/main.c @@ -8,15 +8,13 @@ int mystrlen(const char *s) return result; } -//int youShouldNotSeeThisInTheElfFile=0; -//int *youShouldNotSeeThisInTheElfFile2=&youShouldNotSeeThisInTheElfFile; +int a=0; +int *b=&a; int main() { - //FIXME: without static code fails!! static const char str[]="Hello world\n"; - //youShouldNotSeeThisInTheElfFile=write(1,str,mystrlen(str)); - //return *youShouldNotSeeThisInTheElfFile2; - write(1,str,mystrlen(str)); - return 0; +// return write(1,str,mystrlen(str)); + a=write(1,str,mystrlen(str)); + return *b; } diff --git a/app_template/prog3.h b/app_template/prog3.h new file mode 100644 index 0000000000000000000000000000000000000000..8bf2457df8f5772794dc314b8f21138eef2c8418 --- /dev/null +++ b/app_template/prog3.h @@ -0,0 +1,36 @@ +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, 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, + 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, 0x26, 0xf8, 0x03, 0x78, 0x23, 0xb1, 0x00, 0x23, 0x01, 0x33, + 0xc2, 0x5c, 0x00, 0x2a, 0xfb, 0xd1, 0x18, 0x46, 0x70, 0x47, 0x00, 0xbf, + 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, + 0x0c, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x01, 0x23, 0x00, 0xdf, + 0x02, 0x23, 0x00, 0xdf, 0x70, 0x47, 0x00, 0x00, 0x78, 0x00, 0x00, 0x10, + 0x02, 0x04, 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, 0x78, 0x00, 0x00, 0x10, + 0x80, 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, 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 = 396; diff --git a/elf_program.cpp b/elf_program.cpp index 1e370dd3340ae93f6a1462d8ea0a4dbb39422d4f..4b21a33ad73f366278888d20358a874482471b75 100644 --- a/elf_program.cpp +++ b/elf_program.cpp @@ -36,6 +36,10 @@ using namespace std; static const int MAX_PROCESS_IMAGE_SIZE=20*1024; static const int MIN_PROCESS_STACK_SIZE=2*1024; +///\internal Enable/disable debugging +#define DBG iprintf +//#define DBG(x,...) ; + ///By convention, in an elf file for Miosix, the data segment starts @ this addr static const unsigned int DATA_START=0x10000000; @@ -78,7 +82,7 @@ bool ElfProgram::validateHeader(unsigned int size) bool codeSegmentPresent=false; bool dataSegmentPresent=false; bool dynamicSegmentPresent=false; - int dataSegmentSize; + int dataSegmentSize=0; const Elf32_Phdr *phdr=getProgramHeaderTable(); for(int i=0;i<getNumOfProgramHeaderEntries();i++,phdr++) { @@ -109,7 +113,8 @@ bool ElfProgram::validateHeader(unsigned int size) 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; + unsigned 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; @@ -139,8 +144,8 @@ bool ElfProgram::validateDynamicSegment(const Elf32_Phdr *dynamic, const Elf32_Dyn *dyn= reinterpret_cast<const Elf32_Dyn*>(getElfBase()+dynamic->p_offset); const int dynSize=dynamic->p_memsz/sizeof(Elf32_Dyn); - Elf32_Addr dtRel; - Elf32_Word dtRelsz; + Elf32_Addr dtRel=0; + Elf32_Word dtRelsz=0; unsigned int hasRelocs=0; for(int i=0;i<dynSize;i++,dyn++) { @@ -209,8 +214,8 @@ void ProcessImage::load(ElfProgram& program) 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; + Elf32_Addr dtRel=0; + Elf32_Word dtRelsz=0; bool hasRelocs=false; for(int i=0;i<program.getNumOfProgramHeaderEntries();i++,phdr++) { @@ -259,21 +264,28 @@ void ProcessImage::load(ElfProgram& program) { const Elf32_Rel *rel=reinterpret_cast<const Elf32_Rel*>(base+dtRel); const int relSize=dtRelsz/sizeof(Elf32_Rel); + const unsigned int base=reinterpret_cast<unsigned int>(image); + DBG("Relocations -- start (process RAM image @ 0x%x)\n",base); for(int i=0;i<relSize;i++,rel++) { + unsigned int offset=(rel->r_offset-DATA_START)/4; switch(ELF32_R_TYPE(rel->r_info)) { case R_ARM_ABS32: + DBG("R_ARM_ABS32 offset 0x%x from 0x%x to 0x%x\n", + offset*4,image[offset],image[offset]+base); + image[offset]+=base; + break; case R_ARM_RELATIVE: - { - unsigned int offset=(rel->r_offset-DATA_START)/4; - image[offset]+=reinterpret_cast<unsigned int>(image); + DBG("R_ARM_RELATIVE offset 0x%x from 0x%x to 0x%x\n", + offset*4,image[offset],image[offset]+base-DATA_START); + image[offset]+=base-DATA_START; break; - } default: break; } } + DBG("Relocations -- end\n"); } } diff --git a/elf_types.h b/elf_types.h index 48d242dcf88f5afc2a3d0a118066fbc2c87ea5e8..126c7e41bd1fd72fa039ac1694130195749eb405 100644 --- a/elf_types.h +++ b/elf_types.h @@ -62,21 +62,21 @@ struct Elf32_Ehdr } __attribute__((packed)); // Values for e_type -static const int ET_NONE = 0; // Unknown type -static const int ET_REL = 1; // Relocatable -static const int ET_EXEC = 2; // Executable -static const int ET_DYN = 3; // Shared object -static const int ET_CORE = 4; // Core file +static const Elf32_Half ET_NONE = 0; // Unknown type +static const Elf32_Half ET_REL = 1; // Relocatable +static const Elf32_Half ET_EXEC = 2; // Executable +static const Elf32_Half ET_DYN = 3; // Shared object +static const Elf32_Half ET_CORE = 4; // Core file // Values for e_version -static const int EV_CURRENT = 1; +static const Elf32_Word EV_CURRENT = 1; // Values for e_machine -static const int EM_ARM = 0x28; +static const Elf32_Half EM_ARM = 0x28; // Values for e_flags -static const int EF_ARM_EABI_MASK = 0x05000000; -static const int EF_HAS_ENTRY_POINT = 2; +static const Elf32_Word EF_ARM_EABI_MASK = 0x05000000; +static const Elf32_Word EF_HAS_ENTRY_POINT = 2; /* * Elf program header @@ -94,16 +94,16 @@ struct Elf32_Phdr } __attribute__((packed)); // Values for p_type -static const int PT_NULL = 0; // Unused array entry -static const int PT_LOAD = 1; // Loadable segment -static const int PT_DYNAMIC = 2; // Segment is the dynamic section with relocs -static const int PT_INTERP = 3; // Shared library interpreter -static const int PT_NOTE = 4; // Auxiliary information +static const Elf32_Word PT_NULL = 0; // Unused array entry +static const Elf32_Word PT_LOAD = 1; // Loadable segment +static const Elf32_Word PT_DYNAMIC = 2; // Segment is the dynamic section +static const Elf32_Word PT_INTERP = 3; // Shared library interpreter +static const Elf32_Word PT_NOTE = 4; // Auxiliary information // Values for p_flags -static const int PF_X = 0x1; // Execute -static const int PF_W = 0x2; // Write -static const int PF_R = 0x4; // Read +static const Elf32_Word PF_X = 0x1; // Execute +static const Elf32_Word PF_W = 0x2; // Write +static const Elf32_Word PF_R = 0x4; // Read /* * Entries of the DYNAMIC segment @@ -159,8 +159,8 @@ struct Elf32_Rel // Possible values for ELF32_R_TYPE(r_info) -static const int R_ARM_NONE = 0; -static const int R_ARM_ABS32 = 2; -static const int R_ARM_RELATIVE = 23; +static const unsigned char R_ARM_NONE = 0; +static const unsigned char R_ARM_ABS32 = 2; +static const unsigned char R_ARM_RELATIVE = 23; #endif //ELF_TYPES_H diff --git a/main.cpp b/main.cpp index d24ff7793b7494663bd031290bb0db9ddd9d862c..c9ec82b97fd3aa92ba96379c1453a6f9176d530e 100644 --- a/main.cpp +++ b/main.cpp @@ -3,13 +3,11 @@ #include <cassert> #include "miosix.h" #include "elf_program.h" -#include "prog2.h" +#include "app_template/prog3.h" using namespace std; using namespace miosix; -extern "C" void syscallSupercazzola(int a, int b, int c); - Thread *svcHandler=0; Thread *blocked=0; @@ -40,13 +38,13 @@ void svcHandlerThread(void *) iprintf("Exit %d\n",sp.getFirstParameter()); break; case 2: - iprintf("Write called %d %x %d\n", - sp.getFirstParameter(), - sp.getSecondParameter(), - sp.getThirdParameter()); - write(sp.getFirstParameter(), +// iprintf("Write called %d %x %d\n", +// sp.getFirstParameter(), +// sp.getSecondParameter(), +// sp.getThirdParameter()); + sp.setReturnValue(write(sp.getFirstParameter(), (const char*)sp.getSecondParameter(), - sp.getThirdParameter()); + sp.getThirdParameter())); blocked->wakeup(); break; } @@ -78,12 +76,8 @@ int main() 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_impl.h b/miosix/arch/cortexM3_stm32f2/common/interfaces-impl/portability_impl.h index 5da3a2bb3f137def8cc57d355c0ff6d185afd73c..908a1e762d3075dd220e1fb895c031d808c8a938 100644 --- a/miosix/arch/cortexM3_stm32f2/common/interfaces-impl/portability_impl.h +++ b/miosix/arch/cortexM3_stm32f2/common/interfaces-impl/portability_impl.h @@ -181,6 +181,14 @@ public: */ unsigned int getThirdParameter() const { return registers[2]; } + /** + * Set the value that will be returned by the syscall. Invalidates + * parameters so must be called only after the syscall parameteres have + * been read. + * \param ret value that will be returned by the syscall. + */ + void setReturnValue(unsigned int ret) { registers[0]=ret; } + /** * Invalidate the object. Meant to be called after the syscall has been * serviced diff --git a/svc.s b/svc.s deleted file mode 100644 index 056d89eabf9d5ecafa1c393f1c4144d573e6153e..0000000000000000000000000000000000000000 --- a/svc.s +++ /dev/null @@ -1,16 +0,0 @@ - -.syntax unified -.cpu cortex-m3 -.thumb - -.section .text - -/** - * syscallSupercazzola - */ -.global syscallSupercazzola -.type syscallSupercazzola, %function -syscallSupercazzola: - movs r3, #1 - svc 0 - bx lr