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

Subversion Repositories amber

[/] [amber/] [trunk/] [sw/] [tools/] [amber-elfsplitter.c] - Blame information for rev 2

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

Line No. Rev Author Line
1 2 csantifort
/*----------------------------------------------------------------
2
//                                                              //
3
//  amber-elfsplitter                                           //
4
//                                                              //
5
//  This file is part of the Amber project                      //
6
//  http://www.opencores.org/project,amber                      //
7
//                                                              //
8
//  Description                                                 //
9
//  Read in a binary elf file and write it out in               //
10
//  in Verilog readmem format.                                  //
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
/*
44
ELF File Structure
45
A single segment usually consist of several sections. E.g., a loadable
46
read-only segment could contain sections for executable code, read-only
47
data, and symbols for the dynamic linker. Relocatable files have section
48
header tables. Executable files have program header tables. Shared object
49
files have both. Sections are intended for further processing by a linker,
50
while the segments are intended to be mapped into memory.
51
*/
52
 
53
 
54
/* #define DEBUG */
55
 
56
#include <stdio.h>
57
#include <stdlib.h>
58
#include <string.h>
59
 
60
#define BUF_SIZE (1024*1024*8)
61
#define EI_NIDENT 16
62
 
63
#define SHT_NULL                0                /* sh_type */
64
#define SHT_PROGBITS            1
65
#define SHT_SYMTAB              2
66
#define SHT_STRTAB              3
67
#define SHT_RELA                4
68
#define SHT_HASH                5
69
#define SHT_DYNAMIC             6
70
#define SHT_NOTE                7
71
#define SHT_NOBITS              8
72
#define SHT_REL                 9
73
#define SHT_SHLIB               10
74
#define SHT_DYNSYM              11
75
#define SHT_UNKNOWN12           12
76
#define SHT_UNKNOWN13           13
77
#define SHT_INIT_ARRAY          14
78
#define SHT_FINI_ARRAY          15
79
#define SHT_PREINIT_ARRAY       16
80
#define SHT_GROUP               17
81
#define SHT_SYMTAB_SHNDX        18
82
#define SHT_NUM                 19
83
 
84
 
85
/* Main ELF Header Table */
86
typedef struct {
87
   unsigned char  e_ident[EI_NIDENT]; /* bytes 0 to 15  */
88
   unsigned short e_e_type;           /* bytes 15 to 16 */
89
   unsigned short e_machine;          /* bytes 17 to 18 */
90
   unsigned int   e_version;          /* bytes 19 to 22 */
91
   unsigned int   e_entry;            /* bytes 23 to 26 */
92
   unsigned int   e_phoff;            /* bytes 27 to 30 */
93
   unsigned int   e_shoff;            /* bytes 31 to 34 */
94
   unsigned int   e_flags;            /* bytes 35 to 38 */
95
   unsigned short e_ehsize;           /* bytes 39 to 40 */
96
   unsigned short e_phentsize;        /* bytes 41 to 42 */
97
   unsigned short e_phnum;            /* bytes 43 to 44 (2B to 2C) */
98
   unsigned short e_shentsize;        /* bytes 45 to 46 */
99
   unsigned short e_shnum;            /* bytes 47 to 48 */
100
   unsigned short e_shstrndx;         /* bytes 49 to 50 */
101
} ElfHeader;
102
 
103
 
104
/* Program Headers */
105
typedef struct {
106
   unsigned int p_type;     /* entry type */
107
   unsigned int p_offset;   /* file offset */
108
   unsigned int p_vaddr;    /* virtual address */
109
   unsigned int p_paddr;    /* physical address */
110
   unsigned int p_filesz;   /* file size */
111
   unsigned int p_memsz;    /* memory size */
112
   unsigned int p_flags;    /* entry flags */
113
   unsigned int p_align;    /* memory/file alignment */
114
} Elf32_Phdr;
115
 
116
 
117
/* Section Headers */
118
typedef struct {
119
   unsigned int sh_name;        /* section name - index into string table */
120
   unsigned int sh_type;        /* SHT_... */
121
   unsigned int sh_flags;       /* SHF_... */
122
   unsigned int sh_addr;        /* virtual address */
123
   unsigned int sh_offset;      /* file offset */
124
   unsigned int sh_size;        /* section size */
125
   unsigned int sh_link;        /* misc info */
126
   unsigned int sh_info;        /* misc info */
127
   unsigned int sh_addralign;   /* memory alignment */
128
   unsigned int sh_entsize;     /* entry size if table */
129
} Elf32_Shdr;
130
 
131
int fsize(FILE *f);
132
 
133
void set_low(unsigned char *ptr,unsigned int address,unsigned int value)
134
{
135
   unsigned int opcode;
136
   opcode=*(unsigned int*)(ptr+address);
137
//    opcode=switch_endian_long(opcode);
138
   opcode=(opcode&0xffff0000)|(value&0xffff);
139
//    opcode=switch_endian_long(opcode);
140
   *(unsigned int*)(ptr+address)=opcode;
141
}
142
 
143
/*
144
PROGBITS: This holds program contents including code, data, and debugger information.
145
NOBITS: Like PROGBITS. However, it occupies no space.
146
SYMTAB and DYNSYM: These hold symbol table.
147
STRTAB: This is a string table, like the one used in a.out.
148
REL and RELA:  These hold relocation information.
149
DYNAMIC and HASH: This holds information related to dynamic linking.
150
*/
151
 
152
#define SHT_NULL                0                /* sh_type */
153
#define SHT_PROGBITS            1
154
#define SHT_SYMTAB              2
155
#define SHT_STRTAB              3
156
#define SHT_RELA                4
157
#define SHT_HASH                5
158
#define SHT_DYNAMIC             6
159
#define SHT_NOTE                7
160
#define SHT_NOBITS              8
161
#define SHT_REL                 9
162
#define SHT_SHLIB               10
163
#define SHT_DYNSYM              11
164
#define SHT_UNKNOWN12           12
165
#define SHT_UNKNOWN13           13
166
#define SHT_INIT_ARRAY          14
167
#define SHT_FINI_ARRAY          15
168
#define SHT_PREINIT_ARRAY       16
169
#define SHT_GROUP               17
170
#define SHT_SYMTAB_SHNDX        18
171
#define SHT_NUM                 19
172
 
173
 
174
 
175
char SHT_NAME[80];
176
 
177
char* pSHT ( int sh_type )
178
{
179
   switch (sh_type) {
180
      case SHT_NULL         : strcpy(SHT_NAME, "SHT_NULL"); break;
181
      case SHT_PROGBITS     : strcpy(SHT_NAME, "SHT_PROGBITS"); break;
182
      case SHT_SYMTAB       : strcpy(SHT_NAME, "SHT_SYMTAB"); break;
183
      case SHT_STRTAB       : strcpy(SHT_NAME, "SHT_STRTAB"); break;
184
      case SHT_RELA         : strcpy(SHT_NAME, "SHT_RELA"); break;
185
      case SHT_HASH         : strcpy(SHT_NAME, "SHT_HASH"); break;
186
      case SHT_DYNAMIC      : strcpy(SHT_NAME, "SHT_DYNAMIC"); break;
187
      case SHT_NOTE         : strcpy(SHT_NAME, "SHT_NOTE"); break;
188
      case SHT_NOBITS       : strcpy(SHT_NAME, "SHT_NOBITS"); break;
189
      case SHT_REL          : strcpy(SHT_NAME, "SHT_REL"); break;
190
      case SHT_SHLIB        : strcpy(SHT_NAME, "SHT_SHLIB"); break;
191
      case SHT_DYNSYM       : strcpy(SHT_NAME, "SHT_DYNSYM"); break;
192
      case SHT_UNKNOWN12    : strcpy(SHT_NAME, "SHT_UNKNOWN12"); break;
193
      case SHT_UNKNOWN13    : strcpy(SHT_NAME, "SHT_UNKNOWN13"); break;
194
      case SHT_INIT_ARRAY   : strcpy(SHT_NAME, "SHT_INIT_ARRAY"); break;
195
      case SHT_FINI_ARRAY   : strcpy(SHT_NAME, "SHT_FINI_ARRAY"); break;
196
      case SHT_PREINIT_ARRAY: strcpy(SHT_NAME, "SHT_PREINIT_ARRAY"); break;
197
      case SHT_GROUP        : strcpy(SHT_NAME, "SHT_GROUP"); break;
198
      case SHT_SYMTAB_SHNDX : strcpy(SHT_NAME, "SHT_SYMTAB_SHNDX"); break;
199
      case SHT_NUM          : strcpy(SHT_NAME, "SHT_NUM"); break;
200
      default: strcpy(SHT_NAME, "???"); break;
201
   }
202
   return &SHT_NAME[0];
203
}
204
 
205
 
206
 
207
int main(int argc,char *argv[])
208
{
209
   FILE *infile,*outfile;
210
   unsigned char *buf;
211
   int buf_size;
212
   unsigned int length,i;
213
   unsigned int StringSectionOffset;
214
   unsigned int StringSectionOffsetFound = 0;
215
 
216
   char filename_mem[80], filename_nopath[80];
217
   char tmp[6] = {0x0, 0x0, 0x0, 0x0, 0x0, 0x0 };
218
   FILE *file_mem;
219
   unsigned int j, k;
220
   int m;
221
   ElfHeader *elfHeader;
222
   Elf32_Phdr *elfProgram;
223
   Elf32_Shdr *elfSection;
224
   int stack_ptr16KB_flag=1;  /*  permanently switch on the -sp16k option */
225
   char* ptr=argv[1];
226
 
227
   int infile_size;
228
 
229
   if (argc<2){
230
      printf("%s ERROR: no input file specified. Quitting\n", argv[0]);
231
      exit(1);
232
      }
233
 
234
 
235
   infile=fopen(argv[1],"rb");
236
   if(infile==NULL) {
237
      printf("%s ERROR: Can't open %s. Quitting\n", argv[0], argv[1]);
238
      exit(1);
239
   }
240
   infile_size = fsize(infile);
241
 
242
   buf=(unsigned char*)malloc(infile_size);
243
   buf_size=fread(buf,1,infile_size,infile);
244
   fclose(infile);
245
 
246
   if ( buf_size != infile_size ) {
247
      fprintf(stderr, "%s ERROR: Input %s file length is %d bytes long, buffer read buf_size %d\n",
248
      argv[0], argv[1], infile_size, buf_size);
249
      exit(1);
250
      }
251
 
252
 
253
   if ( infile_size > 0x1000000 ) {
254
      fprintf(stderr, "%s WARNING: Input %s file length is %d bytes long, greater than boot-loader can handle \n",
255
      argv[0], argv[1], infile_size);
256
      }
257
 
258
   elfHeader=(ElfHeader*)buf;
259
 
260
#ifdef DEBUG   
261
   strncpy(tmp, (char*)elfHeader->e_ident+1, 3);
262
   printf("Debug: elfHeader->e_ident= %s\n",tmp);
263
   printf("Debug: elfHeader->e_machine= 0x%x\n",elfHeader->e_machine);
264
#endif
265
 
266
 
267
   if(strncmp((char*)elfHeader->e_ident+1,"ELF",3)) {
268
 
269
      printf("%s ERROR: Not an ELF file.\n", argv[0]);
270
      printf("Use the correct cross compiler for mips. Quitting\n");
271
      exit(1);
272
   }
273
 
274
   if(elfHeader->e_machine != 40) {
275
      printf("%s ERROR: Invalid ELF file.\n", argv[0]);
276
      exit(1);
277
   }
278
 
279
#ifdef DEBUG   
280
   printf("Debug: elfHeader->e_phnum=0x%x\n",elfHeader->e_phnum);
281
#endif
282
 
283
   for(i=0;i<elfHeader->e_phnum;++i) {
284
      elfProgram           = (Elf32_Phdr*)(buf+elfHeader->e_phoff+elfHeader->e_phentsize*i);
285
 
286
      length=elfProgram->p_vaddr+elfProgram->p_memsz;
287
#ifdef DEBUG   
288
      printf("Debug: Program Length=0x%x\n",length);
289
#endif
290
   }
291
 
292
 
293
   /* Find the location in the file of the string section
294
      containing the section names
295
   */
296
   for(i=0;i<elfHeader->e_shnum;++i) {
297
      elfSection=(Elf32_Shdr*)(buf+elfHeader->e_shoff+elfHeader->e_shentsize*i);
298
      if (elfSection->sh_type == SHT_STRTAB && !StringSectionOffsetFound) {
299
         StringSectionOffset      = elfSection->sh_offset;
300
         StringSectionOffsetFound = 1;
301
         }
302
      }
303
 
304
   for(i=0;i<elfHeader->e_shnum;++i) {
305
      elfSection=(Elf32_Shdr*)(buf+elfHeader->e_shoff+elfHeader->e_shentsize*i);
306
 
307
        if (elfSection->sh_type != SHT_NULL) {
308
          printf("// Section name %s\n", (char*)(buf+StringSectionOffset+elfSection->sh_name));
309
          printf("//  Type %s, Size 0x%x, Start address 0x%08x, File offset 0x%x\n",
310
              pSHT(elfSection->sh_type),
311
              elfSection->sh_size,
312
              elfSection->sh_addr,
313
              elfSection->sh_offset);
314
           }
315
 
316
        /* section with non-zero bits, can be either text or data */
317
        if (elfSection->sh_type == SHT_PROGBITS && elfSection->sh_size != 0) {
318
            for (j=0; j<elfSection->sh_size; j=j+4) {
319
               k = j + elfSection->sh_offset;
320
               printf("@%08x %02x%02x%02x%02x\n",
321
                      (elfSection->sh_addr + j),        /* use word addresses */
322
                      buf[k+3], buf[k+2], buf[k+1], buf[k+0]);
323
               }
324
           }
325
 
326
        if (elfSection->sh_type == SHT_NOBITS && elfSection->sh_size != 0) {
327
            printf("// .bss Dump Zeros\n");
328
            for (j=elfSection->sh_offset; j<elfSection->sh_offset+elfSection->sh_size; j=j+4) {
329
               printf("@%08x 00000000\n",
330
               (j + elfSection->sh_addr - elfSection->sh_offset)); /* use word addresses */
331
               }
332
           }
333
 
334
 
335
   }
336
 
337
   free(buf);
338
 
339
   return 0;
340
}
341
 
342
 
343
 
344
/* Return the buf_size of a file in bytes */
345
int fsize( FILE *f )
346
{
347
    int end;
348
 
349
    /* Set current position at end of file */
350
    fseek( f, 0, SEEK_END );
351
 
352
    /* File size in bytes */
353
    end = ftell( f );
354
 
355
    /* Set current position at start of file */
356
    fseek( f, 0, SEEK_SET );
357
 
358
    return end;
359
}
360
 
361
 
362
 

powered by: WebSVN 2.1.0

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