From 1cc81ff824788f127e6ff76f0be1c1d51b03b238 Mon Sep 17 00:00:00 2001 From: Terraneo Federico <fede.tft@hotmail.it> Date: Wed, 14 Mar 2012 17:34:38 +0100 Subject: [PATCH] Continuing process implementation --- ELF.h | 98 ----------------- app_template/Makefile | 41 ++++++++ app_template/crt0.s | 49 +++++++++ app_template/finalstage.pl | 74 +++++++++++++ app_template/main.c | 17 +++ app_template/miosix.ld | 64 ++++++++++++ elf_program.cpp | 22 ++++ elf_program.h | 95 +++++++++++++++++ elf_types.h | 127 +++++++++++++++++++++++ main.cpp | 38 ++++++- miosix_np_2/nbproject/configurations.xml | 9 ++ prog1.h | 26 ++--- test_driver.cpp | 46 ++++++++ 13 files changed, 592 insertions(+), 114 deletions(-) delete mode 100644 ELF.h create mode 100644 app_template/Makefile create mode 100644 app_template/crt0.s create mode 100644 app_template/finalstage.pl create mode 100644 app_template/main.c create mode 100644 app_template/miosix.ld create mode 100644 elf_program.cpp create mode 100644 elf_program.h create mode 100644 elf_types.h create mode 100644 test_driver.cpp diff --git a/ELF.h b/ELF.h deleted file mode 100644 index 74eed133..00000000 --- a/ELF.h +++ /dev/null @@ -1,98 +0,0 @@ -/* - * File: ELF.h - * Author: lr - * - * Created on March 3, 2012, 3:31 PM - */ - -#ifndef ELF_H -#define ELF_H - -#define EI_NIDENT 16 - -typedef unsigned long elf32_word; -typedef signed long elf32_sword; -typedef unsigned short elf32_half; -typedef unsigned long elf32_off; -typedef unsigned long elf32_addr; - -struct elf32_ehdr { - unsigned char e_ident[EI_NIDENT]; /* ident bytes */ - elf32_half e_type; /* file type */ - elf32_half e_machine; /* target machine */ - elf32_word e_version; /* file version */ - elf32_addr e_entry; /* start address */ - elf32_off e_phoff; /* phdr file offset */ - elf32_off e_shoff; /* shdr file offset */ - elf32_word e_flags; /* file flags */ - elf32_half e_ehsize; /* sizeof ehdr */ - elf32_half e_phentsize; /* sizeof phdr */ - elf32_half e_phnum; /* number phdrs */ - elf32_half e_shentsize; /* sizeof shdr */ - elf32_half e_shnum; /* number shdrs */ - elf32_half e_shstrndx; /* shdr string index */ -}; - -// Values for e_type -#define ET_NONE 0 /* Unknown type. */ -#define ET_REL 1 /* Relocatable. */ -#define ET_EXEC 2 /* Executable. */ -#define ET_DYN 3 /* Shared object. */ -#define ET_CORE 4 /* Core file. */ - -//values for e_machine - -struct elf32_shdr { - elf32_word sh_name; - elf32_word sh_type; - elf32_word sh_flags; - elf32_addr sh_addr; - elf32_off sh_offset; - elf32_word sh_size; - elf32_word sh_link; - elf32_word sh_info; - elf32_word sh_addralign; - elf32_word sh_entsize; -}; - -// sh_type -#define SHT_NULL 0 /* inactive */ -#define SHT_PROGBITS 1 /* program defined information */ -#define SHT_SYMTAB 2 /* symbol table section */ -#define SHT_STRTAB 3 /* string table section */ -#define SHT_RELA 4 /* relocation section with addends*/ -#define SHT_HASH 5 /* symbol hash table section */ -#define SHT_DYNAMIC 6 /* dynamic section */ -#define SHT_NOTE 7 /* note section */ -#define SHT_NOBITS 8 /* no space section */ -#define SHT_REL 9 /* relation section without addends */ -#define SHT_SHLIB 10 /* reserved - purpose unknown */ -#define SHT_DYNSYM 11 /* dynamic symbol table section */ -#define SHT_LOPROC 0x70000000 /* reserved range for processor */ -#define SHT_HIPROC 0x7fffffff /* specific section header types */ -#define SHT_LOUSER 0x80000000 /* reserved range for application */ -#define SHT_HIUSER 0xffffffff /* specific indexes */ - -struct elf32_rel { - elf32_addr r_offset; - elf32_word r_info; -}; - -struct elf32_rela { - elf32_addr r_offset; - elf32_word r_info; - elf32_sword r_addend; -}; - -struct elf32_sym { - elf32_word st_name; - elf32_addr st_value; - elf32_word st_size; - unsigned char st_info; - unsigned char st_other; - elf32_half st_shndx; -}; - - -#endif /* ELF_H */ - diff --git a/app_template/Makefile b/app_template/Makefile new file mode 100644 index 00000000..c6c18b62 --- /dev/null +++ b/app_template/Makefile @@ -0,0 +1,41 @@ +## +## Makefile for writing PROGRAMS for the Miosix embedded OS +## TFT:Terraneo Federico Technlogies +## + +SRC := \ +main.cpp + +## Replaces both "foo.cpp"-->"foo.o" and "foo.c"-->"foo.o" +OBJ := $(addsuffix .o, $(basename $(SRC))) + +AS := arm-miosix-eabi-as +CC := arm-miosix-eabi-gcc +CXX := arm-miosix-eabi-g++ +SZ := arm-miosix-eabi-size + +AFLAGS := -mcpu=cortex-m3 -mthumb +CFLAGS := -mcpu=cortex-m3 -mthumb -mfix-cortex-m3-ldrd -fpic -msingle-pic-base \ + -ffunction-sections -O2 -Wall -c +CXXFLAGS := $(CFLAGS) +LFLAGS := -mcpu=cortex-m3 -mthumb -mfix-cortex-m3-ldrd -fpic -msingle-pic-base \ + -Wl,--gc-sections,-Map,main.map,-T./miosix.ld,-n,-pie -O2 -nostdlib + +LINK_LIBS := -Wl,--start-group -lstdc++ -lc -lm -lgcc -Wl,--end-group + +all: $(OBJ) crt0.o + $(CXX) $(LFLAGS) -o main.elf $(OBJ) crt0.o $(LINK_LIBS) + $(SZ) main.elf + @perl finalstage.pl main.elf --strip-sectheader + +clean: + -rm $(OBJ) crt0.o main.elf main.map + +%.o: %.s + $(AS) $(AFLAGS) $< -o $@ + +%.o : %.c + $(CC) $(CFLAGS) $< -o $@ + +%.o : %.cpp + $(CXX) $(CXXFLAGS) $< -o $@ diff --git a/app_template/crt0.s b/app_template/crt0.s new file mode 100644 index 00000000..410735cb --- /dev/null +++ b/app_template/crt0.s @@ -0,0 +1,49 @@ +/* + * Startup script for writing PROGRAMS for the Miosix embedded OS + * TFT:Terraneo Federico Technlogies + */ + +.syntax unified +.cpu cortex-m3 +.thumb + +.section .text + +/** + * _start, program entry point + */ +.global _start +.type _start, %function +_start: + /* TODO: .ctor */ + bl main + /* TODO: .dtor */ + bl _exit + +/** + * _exit, terminate process + * \param r0 exit value + */ +.section .text._exit +.global _exit +.type _exit, %function +_exit: + movs r3, #1 + svc 0 + +/** + * write, write to file + * \param fd file descriptor + * \param buf data to be written + * \param len buffer length + * \return number of written bytes or -1 if errors + */ +.section .text.write +.global write +.type write, %function +write: + movs r3, #2 + svc 0 + bx lr + +.end diff --git a/app_template/finalstage.pl b/app_template/finalstage.pl new file mode 100644 index 00000000..0ee2afcf --- /dev/null +++ b/app_template/finalstage.pl @@ -0,0 +1,74 @@ +#!/usr/bin/perl +## Copyright 2012 by Terraneo Federico +## Released under the GPLv3 +## +## This program is used to perform the last transformations on the +## generated elf file to make it suitable to be loaded by the Miosix +## kernel. It also optionally removes the elf file's section header +## as it is not needed for executing the program and increases the +## binary's size +use warnings; +use strict; + +sub slurpin +{ + my $name=shift; + open(my $file, '<', $name) or die "Can't open input file $name"; + binmode($file); + my $result; + $result.=$_ while(<$file>); + close($file); + return $result; +} + +sub slurpout +{ + my ($name, $data)=@_; + open(my $file, '>', $name) or die "Can't open output file $name"; + binmode($file); + print $file $data; + close($file); +} + +die "perl finalstage.pl file.elf [--strip-sectheader]" unless($#ARGV>=0); +my $filename=$ARGV[0]; +my $strip=($#ARGV>0 && ($ARGV[1] eq '--strip-sectheader')); + +my $elf=slurpin($filename); + +# For some unknown reason passing -fpie to gnu ld causes the elf file to be +# marked as a shared library, correct this by writing ET_EXEC (0x02) to +# e_type in the elf header +substr($elf,16,2,"\x02\x00"); + +if($strip) +{ + # Find the address in the file of the .shstrtab section which marks the + # beginning of the part to cut, as the file ends with this string table + # followed by the section header + sub find_sectheader_start + { + my $filename=shift; + my @lines=split("\n",`arm-miosix-eabi-readelf -S $filename`); + foreach $_ (@lines) + { + s/^.*]//; # Remove [NN] fileld that may contain spaces + my @tokenized=split /\s+/; + my $numtokens=@tokenized; + next unless($numtokens>6); + return hex $tokenized[4] if($tokenized[1] eq ".shstrtab"); + } + return 0; + } + + my $elfend=find_sectheader_start($filename); + die "Already stripped" if($elfend==0); + my $elf2=substr($elf,0,$elfend); + $elf=$elf2; + substr($elf,32,4,"\x00\x00\x00\x00");# Clear e_shoff in elf header + substr($elf,46,2,"\x00\x00"); # Clear e_shentsize in elf header + substr($elf,48,2,"\x00\x00"); # Clear e_shnum in elf header + substr($elf,50,2,"\x00\x00"); # Clear e_shstrndx in elf header +} + +slurpout($filename,$elf); diff --git a/app_template/main.c b/app_template/main.c new file mode 100644 index 00000000..7831e417 --- /dev/null +++ b/app_template/main.c @@ -0,0 +1,17 @@ + +#include <unistd.h> + +int mystrlen(const char *s) +{ + int result=0; + while(*s++) result++; + return result; +} + +int main() +{ + //FIXME: without static code fails!! + static const char str[]="Hello world\n"; + write(1,str,mystrlen(str)); + return 0; +} diff --git a/app_template/miosix.ld b/app_template/miosix.ld new file mode 100644 index 00000000..b4cb6575 --- /dev/null +++ b/app_template/miosix.ld @@ -0,0 +1,64 @@ +/* + * Linker script for writing PROGRAMS for the Miosix embedded OS + * TFT:Terraneo Federico Technlogies + */ + +OUTPUT_FORMAT("elf32-littlearm") +OUTPUT_ARCH(arm) +ENTRY(_start) + +SECTIONS +{ + /* Here starts the first elf segment, that stays in flash */ + . = 0 + SIZEOF_HEADERS; + + .text : ALIGN(8) + { + *(.text) + *(.text.*) + *(.gnu.linkonce.t.*) + } + + .dynamic : { *(.dynamic) } + .rel.data : { *(.rel.data .rel.data.* .rel.gnu.linkonce.d.*) } + .rel.got : { *(.rel.got) } + + /* Here starts the second segment, that is copied in RAM and relocated */ + . = 0x10000000; + + .got : { *(.got.plt) *(.igot.plt) *(.got) *(.igot) } + + /* FIXME: The compiler insists in addressing rodata relative to r9 */ + .rodata : ALIGN(8) + { + *(.rodata) + *(.rodata.*) + *(.gnu.linkonce.r.*) + } + + .data : ALIGN(8) + { + *(.data) + *(.data.*) + *(.gnu.linkonce.d.*) + } + + .bss : ALIGN(8) + { + *(.bss) + *(.bss.*) + *(.gnu.linkonce.b.*) + *(COMMON) + } + + /* These are removed since are unused and increase binary size */ + /DISCARD/ : + { + *(.interp) + *(.dynsym) + *(.dynstr) + *(.hash) + *(.comment) + *(.ARM.attributes) + } +} diff --git a/elf_program.cpp b/elf_program.cpp new file mode 100644 index 00000000..f95e30cd --- /dev/null +++ b/elf_program.cpp @@ -0,0 +1,22 @@ + +#include "elf_program.h" + +using namespace std; + +// +// class ElfProgram +// + +ElfProgram::ElfProgram(const unsigned int *elf, int size) : elf(elf), size(size) +{ + //TODO: Perform validation +} + +// +// class ProcessImage +// + +void ProcessImage::load(ElfProgram& program) +{ + +} diff --git a/elf_program.h b/elf_program.h new file mode 100644 index 00000000..f8a2aa80 --- /dev/null +++ b/elf_program.h @@ -0,0 +1,95 @@ + +#include <utility> +#include "elf_types.h" + +#ifndef ELF_PROGRAM_H +#define ELF_PROGRAM_H + +/** + * This class represents an elf file. + */ +class ElfProgram +{ +public: + /** + * Constructor + * \param elf pointer to the elf file's content. Ownership of the data + * remains of the caller, that is, the pointer is not deleted by this + * class. This is done to allow passing a pointer directly to a location + * in the microcontroller's FLASH memory, in order to avoid copying the + * elf in RAM + * \param size size of the content of the elf file + */ + ElfProgram(const unsigned int *elf, int size); + + /** + * \return the a pointer to the elf header + */ + const Elf32_Ehdr *getElfHeader() const + { + return reinterpret_cast<const Elf32_Ehdr*>(elf); + } + + /** + * \return the already relocated value of the entry point + */ + unsigned int getEntryPoint() const + { + unsigned int base=reinterpret_cast<unsigned int>(elf); + return base+getElfHeader()->e_entry; + } + + /** + * \return an array of struct Elf32_Phdr + */ + const Elf32_Phdr *getProgramHeaderTable() const + { + unsigned int base=reinterpret_cast<unsigned int>(elf); + return reinterpret_cast<const Elf32_Phdr*>(base+getElfHeader()->e_phoff); + } + + /** + * \return the number of entries in the program header table + */ + int getNumOfProgramHeaderEntries() const + { + return getElfHeader()->e_phnum; + } + +private: + const unsigned int * const elf; //Pointer to the content of the elf file + const int size; //Size of the content of the elf file +}; + +/** + * This class represent the RAM image of a process. + */ +class ProcessImage +{ +public: + /** + * Constructor, creates an empty process image. + */ + ProcessImage() : image(0), size(0) {} + + /** + * Starting from the content of the elf program, create an image in RAM of + * the process, including copying .data, zeroing .bss and performing + * relocations + */ + void load(ElfProgram& program); + + /** + * Destructor. Deletes the process image memory. + */ + ~ProcessImage(); + +private: + ProcessImage(const ProcessImage&); + ProcessImage& operator= (const ProcessImage&); + + unsigned int *image; //Pointer to the process image in RAM + unsigned int size; //Size of the process image +}; + +#endif //ELF_PROGRAM_H diff --git a/elf_types.h b/elf_types.h new file mode 100644 index 00000000..7b97bb7e --- /dev/null +++ b/elf_types.h @@ -0,0 +1,127 @@ +/* + * File: ELF.h + * Author: lr + * + * Created on March 3, 2012, 3:31 PM + */ + +#ifndef ELF_TYPES_H +#define ELF_TYPES_H + +typedef unsigned long Elf32_Word; +typedef signed long Elf32_Sword; +typedef unsigned short Elf32_Half; +typedef unsigned long Elf32_Off; +typedef unsigned long Elf32_Addr; + +static const int EI_NIDENT=16; + +struct Elf32_Ehdr +{ + unsigned char e_ident[EI_NIDENT]; // Ident bytes + Elf32_Half e_type; // File type, any of the ET_* constants + Elf32_Half e_machine; // Target machine + Elf32_Word e_version; // File version + Elf32_Addr e_entry; // Start address + Elf32_Off e_phoff; // Phdr file offset + Elf32_Off e_shoff; // Shdr file offset + Elf32_Word e_flags; // File flags + Elf32_Half e_ehsize; // Sizeof ehdr + Elf32_Half e_phentsize; // Sizeof phdr + Elf32_Half e_phnum; // Number phdrs + Elf32_Half e_shentsize; // Sizeof shdr + Elf32_Half e_shnum; // Number shdrs + Elf32_Half e_shstrndx; // Shdr string index +} __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 + +struct Elf32_Phdr +{ + Elf32_Word p_type; // Program header type, any of the PH_* constants + Elf32_Off p_offset; // Segment start offset in file + Elf32_Addr p_vaddr; // Segment virtual address + Elf32_Addr p_paddr; // Segment physical address + Elf32_Word p_filesz; // Segment size in file + Elf32_Word p_memsz; // Segment size in memory + Elf32_Word p_flags; // Segment flasgs, any of the PF_* constants + Elf32_Word p_align; // Segment alignment requirements +} __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 + +// 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 + +//FIXME: cleanup +#define R_ARM_NONE 0 /* No reloc */ +#define R_ARM_PC24 1 /* PC relative 26 bit branch */ +#define R_ARM_ABS32 2 /* Direct 32 bit */ +#define R_ARM_REL32 3 /* PC relative 32 bit */ +#define R_ARM_PC13 4 +#define R_ARM_ABS16 5 /* Direct 16 bit */ +#define R_ARM_ABS12 6 /* Direct 12 bit */ +#define R_ARM_THM_ABS5 7 +#define R_ARM_ABS8 8 /* Direct 8 bit */ +#define R_ARM_SBREL32 9 +#define R_ARM_THM_PC22 10 +#define R_ARM_THM_PC8 11 +#define R_ARM_AMP_VCALL9 12 +#define R_ARM_SWI24 13 +#define R_ARM_THM_SWI8 14 +#define R_ARM_XPC25 15 +#define R_ARM_THM_XPC22 16 +#define R_ARM_TLS_DTPMOD32 17 /* ID of module containing symbol */ +#define R_ARM_TLS_DTPOFF32 18 /* Offset in TLS block */ +#define R_ARM_TLS_TPOFF32 19 /* Offset in static TLS block */ +#define R_ARM_COPY 20 /* Copy symbol at runtime */ +#define R_ARM_GLOB_DAT 21 /* Create GOT entry */ +#define R_ARM_JUMP_SLOT 22 /* Create PLT entry */ +#define R_ARM_RELATIVE 23 /* Adjust by program base */ +#define R_ARM_GOTOFF 24 /* 32 bit offset to GOT */ +#define R_ARM_GOTPC 25 /* 32 bit PC relative offset to GOT */ +#define R_ARM_GOT32 26 /* 32 bit GOT entry */ +#define R_ARM_PLT32 27 /* 32 bit PLT address */ +#define R_ARM_ALU_PCREL_7_0 32 +#define R_ARM_ALU_PCREL_15_8 33 +#define R_ARM_ALU_PCREL_23_15 34 +#define R_ARM_LDR_SBREL_11_0 35 +#define R_ARM_ALU_SBREL_19_12 36 +#define R_ARM_ALU_SBREL_27_20 37 +#define R_ARM_GNU_VTENTRY 100 +#define R_ARM_GNU_VTINHERIT 101 +#define R_ARM_THM_PC11 102 /* thumb unconditional branch */ +#define R_ARM_THM_PC9 103 /* thumb conditional branch */ +#define R_ARM_TLS_GD32 104 /* PC-rel 32 bit for global dynamic + thread local data */ +#define R_ARM_TLS_LDM32 105 /* PC-rel 32 bit for local dynamic + thread local data */ +#define R_ARM_TLS_LDO32 106 /* 32 bit offset relative to TLS + block */ +#define R_ARM_TLS_IE32 107 /* PC-rel 32 bit for GOT entry of + static TLS block offset */ +#define R_ARM_TLS_LE32 108 /* 32 bit offset relative to static + TLS block */ +#define R_ARM_RXPC25 249 +#define R_ARM_RSBREL32 250 +#define R_ARM_THM_RPC22 251 +#define R_ARM_RREL32 252 +#define R_ARM_RABS22 253 +#define R_ARM_RPC24 254 +#define R_ARM_RBASE 255 +/* Keep this the last entry. */ +#define R_ARM_NUM 256 + +#endif //ELF_TYPES_H diff --git a/main.cpp b/main.cpp index c820fbad..57160e13 100644 --- a/main.cpp +++ b/main.cpp @@ -1,7 +1,8 @@ #include <cstdio> +#include <cassert> #include "miosix.h" -#include "ELF.h" +#include "elf_types.h" #include "prog1.h" using namespace std; @@ -67,14 +68,45 @@ 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); svcHandler=Thread::create(svcHandlerThread,2048); - const elf32_ehdr *elf=reinterpret_cast<const elf32_ehdr*>(main_elf); + 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; + 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); diff --git a/miosix_np_2/nbproject/configurations.xml b/miosix_np_2/nbproject/configurations.xml index 4d098f31..f4670461 100644 --- a/miosix_np_2/nbproject/configurations.xml +++ b/miosix_np_2/nbproject/configurations.xml @@ -2,6 +2,10 @@ <configurationDescriptor version="80"> <logicalFolder name="root" displayName="root" projectFiles="true" kind="ROOT"> <df name="miosix_np_2" root=".."> + <df name="app_template"> + <in>crt0.s</in> + <in>main.c</in> + </df> <df name="miosix"> <df name="arch"> <df name="arm7_lpc2000"> @@ -306,8 +310,13 @@ </df> <df name="miosix_np_2"> </df> + <in>elf_program.cpp</in> + <in>elf_program.h</in> + <in>elf_types.h</in> <in>main.cpp</in> + <in>prog1.h</in> <in>svc.s</in> + <in>test_driver.cpp</in> </df> <logicalFolder name="ExternalFiles" displayName="Important Files" diff --git a/prog1.h b/prog1.h index 000891f6..cb2de8eb 100644 --- a/prog1.h +++ b/prog1.h @@ -4,26 +4,26 @@ const unsigned char main_elf[] = { 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, 0x90, 0x00, 0x00, 0x00, - 0x90, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x28, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, - 0x00, 0x00, 0x00, 0x10, 0x0c, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, - 0x06, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, - 0xf0, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x00, 0x00, 0xf0, 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, + 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, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x0c, 0xf8, 0x00, 0xf0, 0x1a, 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, 0xe0, 0x00, 0x00, 0xf0, 0x01, 0x23, 0x00, 0xdf, - 0x02, 0x23, 0x00, 0xdf, 0x70, 0x47, 0x00, 0x00, 0x48, 0x65, 0x6c, 0x6c, - 0x6f, 0x20, 0x77, 0x6f, 0x72, 0x6c, 0x64, 0x0a, 0x00, 0x00, 0x00, 0x00, - 0x15, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x10, 0xbd, 0x00, 0xbf, 0x10, 0x00, 0x00, 0x00, 0x01, 0x23, 0x00, 0xdf, + 0x02, 0x23, 0x00, 0xdf, 0x70, 0x47, 0x00, 0x00, 0x15, 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, 0xf0, 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 }; -unsigned int main_elf_len = 308; +unsigned int main_elf_len = 312; diff --git a/test_driver.cpp b/test_driver.cpp new file mode 100644 index 00000000..918ea261 --- /dev/null +++ b/test_driver.cpp @@ -0,0 +1,46 @@ + +#include <iostream> +#include <fstream> +#include "elf_program.h" + +using namespace std; + +int main() +{ + ifstream in("example.elf",ios::binary); + in.seekg(0,ios::end); + const int size=in.tellg(); + in.seekg(0,ios::beg); + const int alignedSize=(size+3) & ~3; + unsigned int *elfFileData=new unsigned int[alignedSize/4]; + in.read(reinterpret_cast<char*>(elfFileData),size); + + ElfProgram program(elfFileData,size); + cout<<"Elf info:"<<endl + <<"base address = "<<elfFileData<<endl + <<"entry (file relative) = "<<program.getElfHeader()->e_entry<<endl + <<"entry (relocated) = "<<program.getEntryPoint()<<endl; + + const Elf32_Phdr *hdr=program.getProgramHeaderTable(); + for(int i=0;i<program.getNumOfProgramHeaderEntries();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); + } +} -- GitLab