OpenCores
URL https://opencores.org/ocsvn/amber/amber/trunk

Subversion Repositories amber

[/] [amber/] [trunk/] [sw/] [boot-loader-serial/] [elfsplitter.c] - Blame information for rev 83

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 csantifort
/*----------------------------------------------------------------
2
//                                                              //
3
//  elfsplitter.c                                               //
4
//                                                              //
5
//  This file is part of the Amber project                      //
6
//  http://www.opencores.org/project,amber                      //
7
//                                                              //
8
//  Description                                                 //
9
//  Used by the boot loader to split an elf file and copy it    //
10
//  to the correct memory locations ready for execution.        //
11
//                                                              //
12
//  Author(s):                                                  //
13
//      - Conor Santifort, csantifort.amber@gmail.com           //
14
//                                                              //
15
//////////////////////////////////////////////////////////////////
16
//                                                              //
17
// Copyright (C) 2010 Authors and OPENCORES.ORG                 //
18
//                                                              //
19
// This source file may be used and distributed without         //
20
// restriction provided that this copyright statement is not    //
21
// removed from the file and that any derivative work contains  //
22
// the original copyright notice and the associated disclaimer. //
23
//                                                              //
24
// This source file is free software; you can redistribute it   //
25
// and/or modify it under the terms of the GNU Lesser General   //
26
// Public License as published by the Free Software Foundation; //
27
// either version 2.1 of the License, or (at your option) any   //
28
// later version.                                               //
29
//                                                              //
30
// This source is distributed in the hope that it will be       //
31
// useful, but WITHOUT ANY WARRANTY; without even the implied   //
32
// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR      //
33
// PURPOSE.  See the GNU Lesser General Public License for more //
34
// details.                                                     //
35
//                                                              //
36
// You should have received a copy of the GNU Lesser General    //
37
// Public License along with this source; if not, download it   //
38
// from http://www.opencores.org/lgpl.shtml                     //
39
//                                                              //
40
----------------------------------------------------------------*/
41
 
42
/*
43
ELF File Structure
44
A single segment usually consist of several sections. E.g., a loadable
45
read-only segment could contain sections for executable code, read-only
46
data, and symbols for the dynamic linker. Relocatable files have section
47
header tables. Executable files have program header tables. Shared object
48
files have both. Sections are intended for further processing by a linker,
49
while the segments are intended to be mapped into memory.
50
*/
51
 
52
/* #define DEBUG */
53
 
54
#define EI_NIDENT 16
55
 
56
#define SHT_NULL                0                /* sh_type */
57
#define SHT_PROGBITS            1
58
#define SHT_SYMTAB              2
59
#define SHT_STRTAB              3
60
#define SHT_RELA                4
61
#define SHT_HASH                5
62
#define SHT_DYNAMIC             6
63
#define SHT_NOTE                7
64
#define SHT_NOBITS              8
65
#define SHT_REL                 9
66
#define SHT_SHLIB               10
67
#define SHT_DYNSYM              11
68
#define SHT_UNKNOWN12           12
69
#define SHT_UNKNOWN13           13
70
#define SHT_INIT_ARRAY          14
71
#define SHT_FINI_ARRAY          15
72
#define SHT_PREINIT_ARRAY       16
73
#define SHT_GROUP               17
74
#define SHT_SYMTAB_SHNDX        18
75
#define SHT_NUM                 19
76
 
77
 
78
/* Main ELF Header Table */
79
typedef struct {
80
   unsigned char  e_ident[EI_NIDENT]; /* bytes 0 to 15  */
81
   unsigned short e_e_type;           /* bytes 15 to 16 */
82
   unsigned short e_machine;          /* bytes 17 to 18 */
83
   unsigned int   e_version;          /* bytes 19 to 22 */
84
   unsigned int   e_entry;            /* bytes 23 to 26 */
85
   unsigned int   e_phoff;            /* bytes 27 to 30 */
86
   unsigned int   e_shoff;            /* bytes 31 to 34 */
87
   unsigned int   e_flags;            /* bytes 35 to 38 */
88
   unsigned short e_ehsize;           /* bytes 39 to 40 */
89
   unsigned short e_phentsize;        /* bytes 41 to 42 */
90
   unsigned short e_phnum;            /* bytes 43 to 44 (2B to 2C) */
91
   unsigned short e_shentsize;        /* bytes 45 to 46 */
92
   unsigned short e_shnum;            /* bytes 47 to 48 */
93
   unsigned short e_shstrndx;         /* bytes 49 to 50 */
94
} ElfHeader;
95
 
96
 
97
/* Program Headers */
98
typedef struct {
99
   unsigned int p_type;     /* entry type */
100
   unsigned int p_offset;   /* file offset */
101
   unsigned int p_vaddr;    /* virtual address */
102
   unsigned int p_paddr;    /* physical address */
103
   unsigned int p_filesz;   /* file size */
104
   unsigned int p_memsz;    /* memory size */
105
   unsigned int p_flags;    /* entry flags */
106
   unsigned int p_align;    /* memory/file alignment */
107
} Elf32_Phdr;
108
 
109
 
110
/* Section Headers */
111
typedef struct {
112
   unsigned int sh_name;        /* section name - index into string table */
113
   unsigned int sh_type;        /* SHT_... */
114
   unsigned int sh_flags;       /* SHF_... */
115
   unsigned int sh_addr;        /* virtual address */
116
   unsigned int sh_offset;      /* file offset */
117
   unsigned int sh_size;        /* section size */
118
   unsigned int sh_link;        /* misc info */
119
   unsigned int sh_info;        /* misc info */
120
   unsigned int sh_addralign;   /* memory alignment */
121
   unsigned int sh_entsize;     /* entry size if table */
122
} Elf32_Shdr;
123
 
124
 
125
/*
126
PROGBITS: This holds program contents including code, data, and debugger information.
127
NOBITS: Like PROGBITS. However, it occupies no space.
128
SYMTAB and DYNSYM: These hold symbol table.
129
STRTAB: This is a string table, like the one used in a.out.
130
REL and RELA:  These hold relocation information.
131
DYNAMIC and HASH: This holds information related to dynamic linking.
132
*/
133
 
134
#define SHT_NULL                0                /* sh_type */
135
#define SHT_PROGBITS            1
136
#define SHT_SYMTAB              2
137
#define SHT_STRTAB              3
138
#define SHT_RELA                4
139
#define SHT_HASH                5
140
#define SHT_DYNAMIC             6
141
#define SHT_NOTE                7
142
#define SHT_NOBITS              8
143
#define SHT_REL                 9
144
#define SHT_SHLIB               10
145
#define SHT_DYNSYM              11
146
#define SHT_UNKNOWN12           12
147
#define SHT_UNKNOWN13           13
148
#define SHT_INIT_ARRAY          14
149
#define SHT_FINI_ARRAY          15
150
#define SHT_PREINIT_ARRAY       16
151
#define SHT_GROUP               17
152
#define SHT_SYMTAB_SHNDX        18
153
#define SHT_NUM                 19
154
 
155
 
156
 
157
char SHT_NAME[80];
158
 
159 25 csantifort
#ifdef _PRINT_IT
160 2 csantifort
char* pSHT ( int sh_type )
161
{
162
   switch (sh_type) {
163
      case SHT_NULL         : strcpy(SHT_NAME, "SHT_NULL"); break;
164
      case SHT_PROGBITS     : strcpy(SHT_NAME, "SHT_PROGBITS"); break;
165
      case SHT_SYMTAB       : strcpy(SHT_NAME, "SHT_SYMTAB"); break;
166
      case SHT_STRTAB       : strcpy(SHT_NAME, "SHT_STRTAB"); break;
167
      case SHT_RELA         : strcpy(SHT_NAME, "SHT_RELA"); break;
168
      case SHT_HASH         : strcpy(SHT_NAME, "SHT_HASH"); break;
169
      case SHT_DYNAMIC      : strcpy(SHT_NAME, "SHT_DYNAMIC"); break;
170
      case SHT_NOTE         : strcpy(SHT_NAME, "SHT_NOTE"); break;
171
      case SHT_NOBITS       : strcpy(SHT_NAME, "SHT_NOBITS"); break;
172
      case SHT_REL          : strcpy(SHT_NAME, "SHT_REL"); break;
173
      case SHT_SHLIB        : strcpy(SHT_NAME, "SHT_SHLIB"); break;
174
      case SHT_DYNSYM       : strcpy(SHT_NAME, "SHT_DYNSYM"); break;
175
      case SHT_UNKNOWN12    : strcpy(SHT_NAME, "SHT_UNKNOWN12"); break;
176
      case SHT_UNKNOWN13    : strcpy(SHT_NAME, "SHT_UNKNOWN13"); break;
177
      case SHT_INIT_ARRAY   : strcpy(SHT_NAME, "SHT_INIT_ARRAY"); break;
178
      case SHT_FINI_ARRAY   : strcpy(SHT_NAME, "SHT_FINI_ARRAY"); break;
179
      case SHT_PREINIT_ARRAY: strcpy(SHT_NAME, "SHT_PREINIT_ARRAY"); break;
180
      case SHT_GROUP        : strcpy(SHT_NAME, "SHT_GROUP"); break;
181
      case SHT_SYMTAB_SHNDX : strcpy(SHT_NAME, "SHT_SYMTAB_SHNDX"); break;
182
      case SHT_NUM          : strcpy(SHT_NAME, "SHT_NUM"); break;
183
      default: strcpy(SHT_NAME, "???"); break;
184
   }
185
   return &SHT_NAME[0];
186
}
187 25 csantifort
#endif
188 2 csantifort
 
189
 
190
 
191
int elfsplitter (unsigned int base, unsigned int size)
192
{
193
   unsigned char *buf;
194
   unsigned int length,d,i,gp_ptr=0;
195
   unsigned int bss_start=0,bss_end=0;
196
   unsigned int StringSectionOffset;
197
   unsigned int StringSectionOffsetFound = 0;
198
 
199
   char tmp[6] = {0x0, 0x0, 0x0, 0x0, 0x0, 0x0 };
200
   unsigned int j, k;
201
   int m;
202
   ElfHeader *elfHeader;
203
   Elf32_Phdr *elfProgram;
204
   Elf32_Shdr *elfSection;
205
 
206
   buf=(unsigned char*)base;
207
 
208
#ifdef DEBUG   
209
   printf("Debug: size = %d\n",size);
210
#endif
211
 
212
   elfHeader=(ElfHeader*)buf;
213
 
214
#ifdef DEBUG   
215
//    printf("Call strncpy\n");
216
//    strncpy(tmp, (char*)elfHeader->e_ident+1, 3);
217
//    printf("Debug: elfHeader->e_ident= %s\n",tmp);
218
   printf("Debug: elfHeader->e_machine= 0x%x\n",elfHeader->e_machine);
219
#endif
220
 
221
 
222
   if(strncmp((char*)elfHeader->e_ident+1,"ELF",3)) {
223
 
224
      printf("ERROR: Not an ELF file.\n");
225
      return(1);
226
   }
227
 
228
   if(elfHeader->e_machine != 40) {
229
      printf("ERROR: ELF file not targetting correct processor type\n");
230
      return(1);
231
   }
232
 
233
#ifdef DEBUG   
234
   printf("Debug: elfHeader->e_phnum=0x%x\n",elfHeader->e_phnum);
235
#endif
236
 
237
   for(i=0;i<elfHeader->e_phnum;++i) {
238
      elfProgram           = (Elf32_Phdr*)(buf+elfHeader->e_phoff+elfHeader->e_phentsize*i);
239
      length=elfProgram->p_vaddr+elfProgram->p_memsz;
240
#ifdef DEBUG   
241
      printf("Debug: Program Length=0x%x\n",length);
242
#endif
243
   }
244
 
245
 
246
   /* Find the location in the file of the string section
247
      containing the section names
248
   */
249
   for(i=0;i<elfHeader->e_shnum;++i) {
250
      elfSection=(Elf32_Shdr*)(buf+elfHeader->e_shoff+elfHeader->e_shentsize*i);
251
      if (elfSection->sh_type == SHT_STRTAB && !StringSectionOffsetFound) {
252
         StringSectionOffset      = elfSection->sh_offset;
253
         StringSectionOffsetFound = 1;
254
         }
255
      }
256
 
257
   for(i=0;i<elfHeader->e_shnum;++i) {
258
      elfSection=(Elf32_Shdr*)(buf+elfHeader->e_shoff+elfHeader->e_shentsize*i);
259
 
260
#ifdef _PRINT_IT
261
        if (elfSection->sh_type != SHT_NULL) {
262
          printf("Section name %s\n", (char*)(buf+StringSectionOffset+elfSection->sh_name));
263
          printf("Type %s, Size 0x%x, Start address 0x%08x, File offset 0x%x\n",
264
              pSHT(elfSection->sh_type),
265
              elfSection->sh_size,
266
              elfSection->sh_addr,
267
              elfSection->sh_offset);
268
           }
269
#endif
270
 
271
        /* section with non-zero bits, can be either text or data */
272
        if (elfSection->sh_type == SHT_PROGBITS && elfSection->sh_size != 0) {
273
            for (j=0; j<elfSection->sh_size; j=j+4) {
274
               k = j + elfSection->sh_offset;
275
               *(unsigned int*)(elfSection->sh_addr + j)  =
276
                    (buf[k+3] << 24) | (buf[k+2] << 16) | (buf[k+1] << 8) | (buf[k+0]);
277
#ifdef _PRINT_IT
278
               if (j%0x1000 == 0) {
279
                     printf("@%08x %02x%02x%02x%02x\n",
280
                      (elfSection->sh_addr + j),        /* use word addresses */
281
                      buf[k+3], buf[k+2], buf[k+1], buf[k+0]);
282
                    }
283
#endif
284
               }
285
           }
286
 
287
        if (elfSection->sh_type == SHT_NOBITS && elfSection->sh_size != 0) {
288
#ifdef _PRINT_IT
289
            printf("// .bss Dump Zeros\n");
290
#endif
291
            for (j=elfSection->sh_offset; j<elfSection->sh_offset+elfSection->sh_size; j=j+4) {
292
               *(unsigned int*) (j + elfSection->sh_addr - elfSection->sh_offset) = 0;
293
#ifdef _PRINT_IT
294
               printf("@%08x 00000000\n",
295
               (j + elfSection->sh_addr - elfSection->sh_offset)); /* use word addresses */
296
#endif
297
               }
298
           }
299
 
300
 
301
   }
302
 
303
   return 0;
304
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.