]> rtime.felk.cvut.cz Git - fpga/plasma.git/blob - tools/convert.c
Local copy of Plasma MIPS project.
[fpga/plasma.git] / tools / convert.c
1 //convert.c by Steve Rhoads 4/26/01
2 //Now uses the ELF format (get gccmips_elf.zip)
3 //set $gp and zero .sbss and .bss
4 //Reads test.axf and creates code.txt
5 #include <stdio.h>
6 #include <stdlib.h>
7 #include <string.h>
8
9 #define BUF_SIZE (1024*1024*4) 
10 /*Assumes running on PC little endian*/
11 #ifndef USE_BIG_ENDIAN
12 #define ntohl(A) (((A)>>24)|(((A)&0x00ff0000)>>8)|(((A)&0xff00)<<8)|((A)<<24))
13 #define ntohs(A) (uint16)((((A)&0xff00)>>8)|((A)<<8))
14 #else
15 #define ntohl(A) A
16 #define ntohs(A) A
17 #endif
18
19 #define EI_NIDENT 16
20 #define SHT_PROGBITS 1
21 #define SHT_STRTAB 3
22 #define SHT_NOBITS 8
23
24 typedef unsigned int   uint32;
25 typedef unsigned short uint16;
26 typedef unsigned char  uint8;
27
28 typedef struct
29 {
30    uint8 e_ident[EI_NIDENT];
31    uint16 e_e_type;
32    uint16 e_machine;
33    uint32 e_version;
34    uint32 e_entry;
35    uint32 e_phoff;
36    uint32 e_shoff;
37    uint32 e_flags;
38    uint16 e_ehsize;
39    uint16 e_phentsize;
40    uint16 e_phnum;
41    uint16 e_shentsize;
42    uint16 e_shnum;
43    uint16 e_shstrndx;
44 } ElfHeader;
45
46 typedef struct
47 {
48    uint32 p_type;
49    uint32 p_offset;
50    uint32 p_vaddr;
51    uint32 p_paddr;
52    uint32 p_filesz;
53    uint32 p_memsz;
54    uint32 p_flags;
55    uint32 p_align;
56 } Elf32_Phdr;
57
58 typedef struct
59 {
60    uint32 sh_name;
61    uint32 sh_type;
62    uint32 sh_flags;
63    uint32 sh_addr;
64    uint32 sh_offset;
65    uint32 sh_size;
66    uint32 sh_link;
67    uint32 sh_info;
68    uint32 sh_addralign;
69    uint32 sh_entsize;
70 } Elf32_Shdr;
71
72 typedef struct 
73 {
74    uint32 ri_gprmask;
75    uint32 ri_cprmask[4];
76    uint32 ri_gp_value;
77 } ELF_RegInfo;
78
79 #define PT_MIPS_REGINFO  0x70000000
80 #define SHT_MIPS_REGINFO 0x70000006
81
82 void set_low(uint8 *ptr, uint32 address, uint32 value)
83 {
84    uint32 opcode;
85    opcode = *(uint32 *)(ptr + address);
86    opcode = ntohl(opcode);
87    opcode = (opcode & 0xffff0000) | (value & 0xffff);
88    opcode = ntohl(opcode);
89    *(uint32 *)(ptr + address) = opcode;
90 }
91
92 int main(int argc, char *argv[])
93 {
94    FILE *infile, *outfile, *txtfile;
95    uint8 *buf, *code;
96    long size, stack_pointer;
97    uint32 length, d, i, gp_ptr = 0, gp_ptr_backup = 0;
98    uint32 bss_start = 0, bss_end = 0;
99
100    ElfHeader *elfHeader;
101    Elf32_Phdr *elfProgram;
102    ELF_RegInfo *elfRegInfo;
103    Elf32_Shdr *elfSection;
104    (void)argc; 
105    (void)argv;
106    (void)stack_pointer;
107
108    printf("test.axf -> code.txt & test.bin\n");
109    infile = fopen("test.axf", "rb");
110    if(infile == NULL)
111    {
112       printf("Can't open test.axf");
113       return 0;
114    }
115    buf = (uint8*)malloc(BUF_SIZE);
116    size = (int)fread(buf, 1, BUF_SIZE, infile);
117    fclose(infile);
118    code = (uint8*)malloc(BUF_SIZE);
119    memset(code, 0, BUF_SIZE);
120
121    elfHeader = (ElfHeader *)buf;
122    if(strncmp((char*)elfHeader->e_ident + 1, "ELF", 3))
123    {
124       printf("Error:  Not an ELF file!\n");
125       printf("Use the gccmips_elf.zip from opencores/projects/plasma!\n");
126       return -1;
127    }
128
129    elfHeader->e_entry = ntohl(elfHeader->e_entry);
130    elfHeader->e_phoff = ntohl(elfHeader->e_phoff);
131    elfHeader->e_shoff = ntohl(elfHeader->e_shoff);
132    elfHeader->e_flags = ntohl(elfHeader->e_flags);
133    elfHeader->e_phentsize = ntohs(elfHeader->e_phentsize);
134    elfHeader->e_phnum = ntohs(elfHeader->e_phnum);
135    elfHeader->e_shentsize = ntohs(elfHeader->e_shentsize);
136    elfHeader->e_shnum = ntohs(elfHeader->e_shnum);
137    printf("Entry=0x%x ", elfHeader->e_entry);
138    length = 0;
139
140    for(i = 0; i < elfHeader->e_phnum; ++i)
141    {
142       elfProgram = (Elf32_Phdr *)(buf + elfHeader->e_phoff +
143                          elfHeader->e_phentsize * i);
144       elfProgram->p_type = ntohl(elfProgram->p_type);
145       elfProgram->p_offset = ntohl(elfProgram->p_offset);
146       elfProgram->p_vaddr = ntohl(elfProgram->p_vaddr);
147       elfProgram->p_filesz = ntohl(elfProgram->p_filesz);
148       elfProgram->p_memsz = ntohl(elfProgram->p_memsz);
149       elfProgram->p_flags = ntohl(elfProgram->p_flags);
150
151       elfProgram->p_vaddr -= elfHeader->e_entry;
152
153       if(elfProgram->p_type == PT_MIPS_REGINFO)
154       {
155          elfRegInfo = (ELF_RegInfo*)(buf + elfProgram->p_offset);
156          gp_ptr = ntohl(elfRegInfo->ri_gp_value);
157       }
158       if(elfProgram->p_vaddr < BUF_SIZE)
159       {
160          //printf("[0x%x,0x%x,0x%x,0x%x,0x%x]\n", elfProgram->p_vaddr,
161          //   elfProgram->p_offset, elfProgram->p_filesz, elfProgram->p_memsz,
162          //   elfProgram->p_flags);
163          memcpy(code + elfProgram->p_vaddr, buf + elfProgram->p_offset,
164                  elfProgram->p_filesz);
165          length = elfProgram->p_vaddr + elfProgram->p_filesz;
166          //printf("length = %d 0x%x\n", length, length);
167       }
168    }
169
170    for(i = 0; i < elfHeader->e_shnum; ++i)
171    {
172       elfSection = (Elf32_Shdr *)(buf + elfHeader->e_shoff +
173                          elfHeader->e_shentsize * i);
174       elfSection->sh_name = ntohl(elfSection->sh_name);
175       elfSection->sh_type = ntohl(elfSection->sh_type);
176       elfSection->sh_addr = ntohl(elfSection->sh_addr);
177       elfSection->sh_offset = ntohl(elfSection->sh_offset);
178       elfSection->sh_size = ntohl(elfSection->sh_size);
179
180       if(elfSection->sh_type == SHT_MIPS_REGINFO)
181       {
182          elfRegInfo = (ELF_RegInfo*)(buf + elfSection->sh_offset);
183          gp_ptr = ntohl(elfRegInfo->ri_gp_value);
184       }
185       if(elfSection->sh_type == SHT_PROGBITS)
186       {
187          //printf("elfSection->sh_addr=0x%x\n", elfSection->sh_addr);
188          if(elfSection->sh_addr > gp_ptr_backup)
189             gp_ptr_backup = elfSection->sh_addr;
190       }
191       if(elfSection->sh_type == SHT_NOBITS)
192       {
193          if(bss_start == 0)
194          {
195             bss_start = elfSection->sh_addr;
196          }
197          bss_end = elfSection->sh_addr + elfSection->sh_size;
198       }
199    }
200
201    if(length > bss_start - elfHeader->e_entry)
202    {
203       length = bss_start - elfHeader->e_entry;
204    }
205    if(bss_start == length)
206    {
207       bss_start = length;
208       bss_end = length + 4;
209    }
210    if(gp_ptr == 0)
211       gp_ptr = gp_ptr_backup + 0x7ff0;
212
213 #if 0
214    /*Initialize the $gp register for sdata and sbss */
215    printf("gp_ptr=0x%x ", gp_ptr);
216    /*modify the first opcodes in boot.asm */
217    /*modify the lui opcode */
218    set_low(code, 0, gp_ptr >> 16);
219    /*modify the ori opcode */
220    set_low(code, 4, gp_ptr & 0xffff);
221
222    /*Clear .sbss and .bss */
223    printf("sbss=0x%x bss_end=0x%x\nlength=0x%x ", bss_start, bss_end, length);
224    set_low(code, 8, bss_start >> 16);
225    set_low(code, 12, bss_start & 0xffff);
226    set_low(code, 16, bss_end >> 16);
227    set_low(code, 20, bss_end & 0xffff);
228
229    /*Set stack pointer */
230    if(elfHeader->e_entry < 0x10000000)
231       stack_pointer = bss_end + 512;
232    else
233       stack_pointer = bss_end + 1024 * 4;
234    stack_pointer &= ~7;
235    printf("SP=0x%x\n", stack_pointer);
236    set_low(code, 24, stack_pointer >> 16);
237    set_low(code, 28, stack_pointer & 0xffff);
238 #endif
239
240    /*write out test.bin */
241    outfile = fopen("test.bin", "wb");
242    fwrite(code, length, 1, outfile);
243    fclose(outfile);
244
245    /*write out code.txt */
246    txtfile = fopen("code.txt", "w");
247    for(i = 0; i <= length; i += 4)
248    {
249       d = ntohl(*(uint32 *)(code + i));
250       fprintf(txtfile, "%8.8x\n", d);
251    }
252    fclose(txtfile);
253    free(buf);
254    printf("length=%d=0x%x\n", length, length);
255
256    return 0;
257 }
258