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
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))
20 #define SHT_PROGBITS 1
24 typedef unsigned int uint32;
25 typedef unsigned short uint16;
26 typedef unsigned char uint8;
30 uint8 e_ident[EI_NIDENT];
79 #define PT_MIPS_REGINFO 0x70000000
80 #define SHT_MIPS_REGINFO 0x70000006
82 void set_low(uint8 *ptr, uint32 address, uint32 value)
85 opcode = *(uint32 *)(ptr + address);
86 opcode = ntohl(opcode);
87 opcode = (opcode & 0xffff0000) | (value & 0xffff);
88 opcode = ntohl(opcode);
89 *(uint32 *)(ptr + address) = opcode;
92 int main(int argc, char *argv[])
94 FILE *infile, *outfile, *txtfile;
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;
100 ElfHeader *elfHeader;
101 Elf32_Phdr *elfProgram;
102 ELF_RegInfo *elfRegInfo;
103 Elf32_Shdr *elfSection;
108 printf("test.axf -> code.txt & test.bin\n");
109 infile = fopen("test.axf", "rb");
112 printf("Can't open test.axf");
115 buf = (uint8*)malloc(BUF_SIZE);
116 size = (int)fread(buf, 1, BUF_SIZE, infile);
118 code = (uint8*)malloc(BUF_SIZE);
119 memset(code, 0, BUF_SIZE);
121 elfHeader = (ElfHeader *)buf;
122 if(strncmp((char*)elfHeader->e_ident + 1, "ELF", 3))
124 printf("Error: Not an ELF file!\n");
125 printf("Use the gccmips_elf.zip from opencores/projects/plasma!\n");
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);
140 for(i = 0; i < elfHeader->e_phnum; ++i)
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);
151 elfProgram->p_vaddr -= elfHeader->e_entry;
153 if(elfProgram->p_type == PT_MIPS_REGINFO)
155 elfRegInfo = (ELF_RegInfo*)(buf + elfProgram->p_offset);
156 gp_ptr = ntohl(elfRegInfo->ri_gp_value);
158 if(elfProgram->p_vaddr < BUF_SIZE)
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);
170 for(i = 0; i < elfHeader->e_shnum; ++i)
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);
180 if(elfSection->sh_type == SHT_MIPS_REGINFO)
182 elfRegInfo = (ELF_RegInfo*)(buf + elfSection->sh_offset);
183 gp_ptr = ntohl(elfRegInfo->ri_gp_value);
185 if(elfSection->sh_type == SHT_PROGBITS)
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;
191 if(elfSection->sh_type == SHT_NOBITS)
195 bss_start = elfSection->sh_addr;
197 bss_end = elfSection->sh_addr + elfSection->sh_size;
201 if(length > bss_start - elfHeader->e_entry)
203 length = bss_start - elfHeader->e_entry;
205 if(bss_start == length)
208 bss_end = length + 4;
211 gp_ptr = gp_ptr_backup + 0x7ff0;
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);
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);
229 /*Set stack pointer */
230 if(elfHeader->e_entry < 0x10000000)
231 stack_pointer = bss_end + 512;
233 stack_pointer = bss_end + 1024 * 4;
235 printf("SP=0x%x\n", stack_pointer);
236 set_low(code, 24, stack_pointer >> 16);
237 set_low(code, 28, stack_pointer & 0xffff);
240 /*write out test.bin */
241 outfile = fopen("test.bin", "wb");
242 fwrite(code, length, 1, outfile);
245 /*write out code.txt */
246 txtfile = fopen("code.txt", "w");
247 for(i = 0; i <= length; i += 4)
249 d = ntohl(*(uint32 *)(code + i));
250 fprintf(txtfile, "%8.8x\n", d);
254 printf("length=%d=0x%x\n", length, length);