summaryrefslogtreecommitdiff
path: root/fs/elf.c
blob: f9f479c045edd519cc08fc0c842f3d6f183a848b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
#include <stdint.h>
#include "ext2.h"
#include "lib/logger/log.h"

#define FOOLOS_MODULE_NAME "elf"
#define EI_NIDENT 16


typedef uint32_t Elf32_Addr;
typedef uint32_t Elf32_Off;
typedef uint16_t Elf32_Section;
typedef uint16_t Elf32_Versym;
typedef unsigned char Elf_Byte;
typedef uint16_t Elf32_Half;
typedef int32_t Elf32_Sword;
typedef uint32_t Elf32_Word;
typedef int64_t Elf32_Sxword;
typedef uint64_t Elf32_Xword;


typedef struct
{

        unsigned char   e_ident[EI_NIDENT];
        Elf32_Half      e_type;
        Elf32_Half      e_machine;
        Elf32_Word      e_version;
        Elf32_Addr      e_entry;
        Elf32_Off       e_phoff;
        Elf32_Off       e_shoff;
        Elf32_Word      e_flags;
        Elf32_Half      e_ehsize;
        Elf32_Half      e_phentsize;
        Elf32_Half      e_phnum;
        Elf32_Half      e_shentsize;
        Elf32_Half      e_shnum;
        Elf32_Half      e_shstrndx;

}
Elf32_Ehdr;


typedef struct {
       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;
} Elf32_Shdr;

typedef struct {

       Elf32_Word      p_type;
       Elf32_Off       p_offset;
       Elf32_Addr      p_vaddr;
       Elf32_Addr      p_paddr;
       Elf32_Word      p_filesz;
       Elf32_Word      p_memsz;
       Elf32_Word      p_flags;
       Elf32_Word      p_align;
} 
Elf32_Phdr;

// returns elf entry point
uint32_t load_elf(char *name, uint32_t *alloc)
{
    uint32_t ext2_ramimage= fs_get_root_ext2_ramimage();

    int inode_nr=ext2_filename_to_inode(ext2_ramimage,name);
    if(inode_nr<1)return 0;

    //TODO: load ELF binary and move this to own compilation unit
    
    //load binary
//    uint32_t vaddr=0x08048000;
    uint32_t vaddr=0x08000000;

    log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"loading %s",name);
    ext2_check(ext2_ramimage);
    ext2_inode_content(ext2_ramimage,inode_nr,vaddr,0x100000); // load 1mb;
    log(FOOLOS_MODULE_NAME,FOOLOS_LOG_DEBUG,"ELF File loaded to final destination.");

    Elf32_Ehdr *elf;
    elf=vaddr;

    if(elf->e_ident[0]!=0x7f||elf->e_ident[1]!='E'||elf->e_ident[2]!='L'||elf->e_ident[3]!='F')
	panic(FOOLOS_MODULE_NAME,"ELF mismatch!?");

    
    /*
    log(FOOLOS_MODULE_NAME, FOOLOS_LOG_INFO, 
	    "elf id: class=%d, data=%d, version=%d osabi=%d abiv=%d ",
	    elf->e_ident[4],elf->e_ident[5],elf->e_ident[6],
	    elf->e_ident[7],elf->e_ident[8]);

    log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"elf type: 0x%04x",elf->e_type);
    log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"elf machine: 0x%04x",elf->e_machine);
    log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"elf version: %d",elf->e_version);
    log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"elf entry: 0x%08X",elf->e_entry);
    log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"elf ph-offset: 0x%08X",elf->e_phoff);
    log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"elf sh-offset: 0x%08X",elf->e_shoff);
    log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"elf flags: 0x%08X",elf->e_flags);
    log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"elf eh-size (bytes): %d",elf->e_ehsize);

    log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"elf ph-ent-size(bytes): %d",elf->e_phentsize);
    log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"elf ph-num: %d",elf->e_phnum);

    log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"elf sh-ent-size(byte): %d",elf->e_shentsize);
    log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"elf sh-num: %d",elf->e_shnum);

    log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"elf sh-strndx: %d",elf->e_shstrndx);
    */

    // iterate over section headers
    for(int phidx=0;phidx<elf->e_phnum;phidx++)
    {	
	Elf32_Phdr *phdr=vaddr+elf->e_phoff+phidx*elf->e_phentsize;

	if(phidx==0)
	{
	    log(FOOLOS_MODULE_NAME,FOOLOS_LOG_DEBUG,"text: 0x%08X-0x%08X",phdr->p_vaddr,phdr->p_vaddr+phdr->p_filesz);
	}

	if(phidx==1)
	{


	    /*
	    log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"-- PROGRAMM HEADER %d --",phidx+1);
	    log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"p-type: %d",phdr->p_type);
	    log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"p-offset: 0x%08X",phdr->p_offset);
	    log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"p-vaddr: 0x%08X",phdr->p_vaddr);
	    log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"p-filesz: 0x%08X",phdr->p_filesz);
	    log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"p-memsz: 0x%08X",phdr->p_memsz);
	    */
	    
	    
	    log(FOOLOS_MODULE_NAME,FOOLOS_LOG_DEBUG,"data: 0x%08X-0x%08X",phdr->p_vaddr,phdr->p_vaddr+phdr->p_filesz);
	    log(FOOLOS_MODULE_NAME,FOOLOS_LOG_DEBUG,"bss: 0x%08X-0x%08X",phdr->p_vaddr+phdr->p_filesz,phdr->p_vaddr+phdr->p_memsz);

	    // let's copy the rw- data block
	    uint32_t *data=vaddr+phdr->p_offset;
	    for(uint32_t *addr=phdr->p_vaddr; addr<=phdr->p_vaddr+phdr->p_filesz; addr++)
	    {
		*addr=*data;
		data++;
	    }

	    // let's zero init bss and set alloc (heap) just right after it! 
	    for(uint32_t *addr=phdr->p_vaddr+phdr->p_filesz; addr<=phdr->p_vaddr+phdr->p_memsz; addr++)
	    {
		*addr=0;
	    }

	    *alloc=phdr->p_vaddr+phdr->p_memsz;
	}


    }

    return elf->e_entry;

}