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

Subversion Repositories amber

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

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 61 csantifort
   unsigned char *inbuf;
211
   unsigned char *outbuf;
212 2 csantifort
   int buf_size;
213
   unsigned int length,i;
214
   unsigned int StringSectionOffset;
215
   unsigned int StringSectionOffsetFound = 0;
216 61 csantifort
   unsigned int outP;
217
 
218 2 csantifort
   char filename_mem[80], filename_nopath[80];
219
   char tmp[6] = {0x0, 0x0, 0x0, 0x0, 0x0, 0x0 };
220
   FILE *file_mem;
221 61 csantifort
   unsigned int j, k, last_k;
222 2 csantifort
   int m;
223
   ElfHeader *elfHeader;
224
   Elf32_Phdr *elfProgram;
225
   Elf32_Shdr *elfSection;
226
   int stack_ptr16KB_flag=1;  /*  permanently switch on the -sp16k option */
227
   char* ptr=argv[1];
228
 
229
   int infile_size;
230 61 csantifort
   int boffset;
231
   int max_out = 0;
232 2 csantifort
 
233
   if (argc<2){
234
      printf("%s ERROR: no input file specified. Quitting\n", argv[0]);
235
      exit(1);
236
      }
237
 
238
 
239
   infile=fopen(argv[1],"rb");
240
   if(infile==NULL) {
241
      printf("%s ERROR: Can't open %s. Quitting\n", argv[0], argv[1]);
242
      exit(1);
243
   }
244
   infile_size = fsize(infile);
245
 
246 61 csantifort
   inbuf =(unsigned char*)malloc(infile_size);
247
   outbuf=(unsigned char*)malloc(infile_size*2);
248
   buf_size=fread(inbuf,1,infile_size,infile);
249 2 csantifort
   fclose(infile);
250
 
251
   if ( buf_size != infile_size ) {
252
      fprintf(stderr, "%s ERROR: Input %s file length is %d bytes long, buffer read buf_size %d\n",
253
      argv[0], argv[1], infile_size, buf_size);
254
      exit(1);
255
      }
256
 
257
 
258
   if ( infile_size > 0x1000000 ) {
259
      fprintf(stderr, "%s WARNING: Input %s file length is %d bytes long, greater than boot-loader can handle \n",
260
      argv[0], argv[1], infile_size);
261
      }
262
 
263 61 csantifort
   elfHeader=(ElfHeader*)inbuf;
264 2 csantifort
 
265
#ifdef DEBUG   
266
   strncpy(tmp, (char*)elfHeader->e_ident+1, 3);
267
   printf("Debug: elfHeader->e_ident= %s\n",tmp);
268
   printf("Debug: elfHeader->e_machine= 0x%x\n",elfHeader->e_machine);
269
#endif
270
 
271
 
272
   if(strncmp((char*)elfHeader->e_ident+1,"ELF",3)) {
273
 
274
      printf("%s ERROR: Not an ELF file.\n", argv[0]);
275
      printf("Use the correct cross compiler for mips. Quitting\n");
276
      exit(1);
277
   }
278
 
279
   if(elfHeader->e_machine != 40) {
280
      printf("%s ERROR: Invalid ELF file.\n", argv[0]);
281
      exit(1);
282
   }
283
 
284
#ifdef DEBUG   
285
   printf("Debug: elfHeader->e_phnum=0x%x\n",elfHeader->e_phnum);
286
#endif
287
 
288
   for(i=0;i<elfHeader->e_phnum;++i) {
289 61 csantifort
      elfProgram           = (Elf32_Phdr*)(inbuf+elfHeader->e_phoff+elfHeader->e_phentsize*i);
290 2 csantifort
 
291
      length=elfProgram->p_vaddr+elfProgram->p_memsz;
292
#ifdef DEBUG   
293
      printf("Debug: Program Length=0x%x\n",length);
294
#endif
295
   }
296
 
297
 
298
   /* Find the location in the file of the string section
299
      containing the section names
300
   */
301
   for(i=0;i<elfHeader->e_shnum;++i) {
302 61 csantifort
      elfSection=(Elf32_Shdr*)(inbuf+elfHeader->e_shoff+elfHeader->e_shentsize*i);
303 2 csantifort
      if (elfSection->sh_type == SHT_STRTAB && !StringSectionOffsetFound) {
304
         StringSectionOffset      = elfSection->sh_offset;
305
         StringSectionOffsetFound = 1;
306
         }
307
      }
308
 
309
   for(i=0;i<elfHeader->e_shnum;++i) {
310 61 csantifort
      elfSection=(Elf32_Shdr*)(inbuf+elfHeader->e_shoff+elfHeader->e_shentsize*i);
311 2 csantifort
 
312 61 csantifort
        /* Get the byte offset and use it to word-align the data */
313
        boffset = elfSection->sh_offset & 3;
314
 
315 2 csantifort
        if (elfSection->sh_type != SHT_NULL) {
316 61 csantifort
          printf("// Section name %s\n", (char*)(inbuf+StringSectionOffset+elfSection->sh_name));
317
          printf("//  Type %s, Size 0x%x, Start address 0x%08x, File offset 0x%x, boffset %d\n",
318 2 csantifort
              pSHT(elfSection->sh_type),
319
              elfSection->sh_size,
320
              elfSection->sh_addr,
321 61 csantifort
              elfSection->sh_offset,
322
              boffset);
323 2 csantifort
           }
324 61 csantifort
 
325 2 csantifort
 
326
        /* section with non-zero bits, can be either text or data */
327
        if (elfSection->sh_type == SHT_PROGBITS && elfSection->sh_size != 0) {
328 61 csantifort
            for (j=0; j<elfSection->sh_size; j++) {
329 2 csantifort
               k = j + elfSection->sh_offset;
330 61 csantifort
               outP = elfSection->sh_addr + j;
331
               outbuf[outP] = inbuf[k];
332
               if (outP > max_out) max_out = outP;
333 2 csantifort
               }
334
           }
335
 
336 61 csantifort
 
337 2 csantifort
        if (elfSection->sh_type == SHT_NOBITS && elfSection->sh_size != 0) {
338
            printf("// .bss Dump Zeros\n");
339 61 csantifort
            for (j=0; j<elfSection->sh_size; j++) {
340
               outP = j + elfSection->sh_addr;
341
               outbuf[outP] = 0;
342
               if (outP > max_out) max_out = outP;
343 2 csantifort
               }
344
           }
345 61 csantifort
   }
346 2 csantifort
 
347
 
348 61 csantifort
   for(j=0;j<max_out+3;j=j+4) {
349
        printf("@%08x %02x%02x%02x%02x\n", j, outbuf[j+3], outbuf[j+2], outbuf[j+1], outbuf[j+0]);
350
        }
351
 
352
   free(inbuf);
353
   free(outbuf);
354 2 csantifort
 
355
   return 0;
356
}
357
 
358
 
359
 
360
/* Return the buf_size of a file in bytes */
361
int fsize( FILE *f )
362
{
363
    int end;
364
 
365
    /* Set current position at end of file */
366
    fseek( f, 0, SEEK_END );
367
 
368
    /* File size in bytes */
369
    end = ftell( f );
370
 
371
    /* Set current position at start of file */
372
    fseek( f, 0, SEEK_SET );
373
 
374
    return end;
375
}
376
 
377
 
378
 

powered by: WebSVN 2.1.0

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