1 |
4 |
mcupro |
/* 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 |
|
|
/*modified by Liwei 2007-8-29*/
|
6 |
|
|
#include<stdio.h>
|
7 |
|
|
#include<stdlib.h>
|
8 |
|
|
#include<string.h>
|
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)(unsigned short)((((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 struct
|
25 |
|
|
{
|
26 |
|
|
unsigned char e_ident[EI_NIDENT];
|
27 |
|
|
unsigned short e_e_type ;
|
28 |
|
|
unsigned short e_machine ;
|
29 |
|
|
unsigned long e_version ;
|
30 |
|
|
unsigned long e_entry ;
|
31 |
|
|
unsigned long e_phoff ;
|
32 |
|
|
unsigned long e_shoff ;
|
33 |
|
|
unsigned long e_flags ;
|
34 |
|
|
unsigned short e_ehsize ;
|
35 |
|
|
unsigned short e_phentsize ;
|
36 |
|
|
unsigned short e_phnum ;
|
37 |
|
|
unsigned short e_shentsize ;
|
38 |
|
|
unsigned short e_shnum ;
|
39 |
|
|
unsigned short e_shstrndx ;
|
40 |
|
|
}
|
41 |
|
|
ElfHeader ;
|
42 |
|
|
|
43 |
|
|
typedef struct
|
44 |
|
|
{
|
45 |
|
|
unsigned long p_type ;
|
46 |
|
|
unsigned long p_offset ;
|
47 |
|
|
unsigned long p_vaddr ;
|
48 |
|
|
unsigned long p_paddr ;
|
49 |
|
|
unsigned long p_filesz ;
|
50 |
|
|
unsigned long p_memsz ;
|
51 |
|
|
unsigned long p_flags ;
|
52 |
|
|
unsigned long p_align ;
|
53 |
|
|
}
|
54 |
|
|
Elf32_Phdr ;
|
55 |
|
|
|
56 |
|
|
typedef struct
|
57 |
|
|
{
|
58 |
|
|
unsigned long sh_name ;
|
59 |
|
|
unsigned long sh_type ;
|
60 |
|
|
unsigned long sh_flags ;
|
61 |
|
|
unsigned long sh_addr ;
|
62 |
|
|
unsigned long sh_offset ;
|
63 |
|
|
unsigned long sh_size ;
|
64 |
|
|
unsigned long sh_link ;
|
65 |
|
|
unsigned long sh_info ;
|
66 |
|
|
unsigned long sh_addralign ;
|
67 |
|
|
unsigned long sh_entsize ;
|
68 |
|
|
}
|
69 |
|
|
Elf32_Shdr ;
|
70 |
|
|
|
71 |
|
|
typedef struct
|
72 |
|
|
{
|
73 |
|
|
unsigned long ri_gprmask ;
|
74 |
|
|
unsigned long ri_cprmask[4];
|
75 |
|
|
unsigned long ri_gp_value ;
|
76 |
|
|
}
|
77 |
|
|
ELF_RegInfo ;
|
78 |
|
|
|
79 |
|
|
#define PT_MIPS_REGINFO 0x70000000
|
80 |
|
|
#define SHT_MIPS_REGINFO 0x70000006
|
81 |
|
|
|
82 |
|
|
void set_low(unsigned char*ptr,unsigned long address,unsigned long value)
|
83 |
|
|
{
|
84 |
|
|
unsigned long opcode ;
|
85 |
|
|
opcode=*(unsigned long*)(ptr+address);
|
86 |
|
|
opcode=ntohl(opcode);
|
87 |
|
|
opcode=(opcode&0xffff0000)|(value&0xffff);
|
88 |
|
|
opcode=ntohl(opcode);
|
89 |
|
|
*(unsigned long*)(ptr+address)=opcode ;
|
90 |
|
|
}
|
91 |
|
|
|
92 |
|
|
/*the two functions listed between are added by Liwei 2007-8-29*/
|
93 |
|
|
char HEX[]="0123456789ABCDEF" ;
|
94 |
|
|
char hex[]="0123456789abcdef" ;
|
95 |
|
|
unsigned char hex2byte( char hex_char)
|
96 |
|
|
{
|
97 |
|
|
unsigned char i ;
|
98 |
|
|
for(i=0;i<16;++i)if(HEX[i]==hex_char)return i ;
|
99 |
|
|
for(i=0;i<16;++i)if(hex[i]==hex_char)return i ;
|
100 |
|
|
return 0 ;
|
101 |
|
|
}
|
102 |
|
|
unsigned int par2u32(char*par)
|
103 |
|
|
{
|
104 |
|
|
unsigned int i,ret=0 ;
|
105 |
|
|
if(par==NULL)return ;
|
106 |
|
|
if((0==strncmp(par,"0x",2))||(0==strncmp(par,"0X",2)))
|
107 |
|
|
for(i=2;;++i) {if(par[i]=='\0')return ret ; ret=ret*16+hex2byte(par[i]);}
|
108 |
|
|
else
|
109 |
|
|
for(i=0;;++i) {if(par[i]=='\0')return ret ; ret=ret*10+hex2byte(par[i]);}
|
110 |
|
|
return 0 ;
|
111 |
|
|
}
|
112 |
|
|
/****************************/
|
113 |
|
|
|
114 |
|
|
int main(int argc,char*argv[])
|
115 |
|
|
{
|
116 |
|
|
FILE*infile,*outfile,*txtfile ;
|
117 |
|
|
unsigned char*buf,*code ;
|
118 |
|
|
long size,stack_pointer;
|
119 |
|
|
long stack_limit=0 ;
|
120 |
|
|
unsigned long length,d,i,gp_ptr=0,gp_ptr_backup=0 ;
|
121 |
|
|
unsigned long bss_start=0,bss_end=0 ;
|
122 |
|
|
|
123 |
|
|
ElfHeader*elfHeader ;
|
124 |
|
|
Elf32_Phdr*elfProgram ;
|
125 |
|
|
ELF_RegInfo*elfRegInfo ;
|
126 |
|
|
Elf32_Shdr*elfSection ;
|
127 |
|
|
(void)argc ;
|
128 |
|
|
(void)argv ;
|
129 |
|
|
// printf(">%s<=>%d<\n",argv[1],par2u32((char*)argv[1]));//Liwei 2007-8.29
|
130 |
|
|
// printf(">%s<=>%d<\n",argv[2],par2u32((char*)argv[2]));//Liwei 2007-8.29
|
131 |
|
|
// printf("argc = %d\n",argc);
|
132 |
|
|
if (argc>=3)
|
133 |
|
|
stack_limit=((par2u32((char*)argv[1]) - par2u32((char*)argv[2])));//alig 4
|
134 |
|
|
/* added by Liwei 2007_8_29 */
|
135 |
|
|
/*usage example :
|
136 |
|
|
convert_sp 0x800 0xf0
|
137 |
|
|
the sp_pointer is limited and set as (0x800 - 0xf0)
|
138 |
|
|
0x800 is your instructions space lenth while 0xf0 is your stack lenth
|
139 |
|
|
but make sure your instructions space is big enough...
|
140 |
|
|
comment by Liwei
|
141 |
|
|
*/
|
142 |
|
|
printf("test.axf -> code.txt & test.bin\n");
|
143 |
|
|
infile=fopen("test.axf","rb");
|
144 |
|
|
if(infile==NULL)
|
145 |
|
|
{
|
146 |
|
|
printf("Can't open test.axf");
|
147 |
|
|
return 0 ;
|
148 |
|
|
}
|
149 |
|
|
buf=(unsigned char*)malloc(BUF_SIZE);
|
150 |
|
|
size=(int)fread(buf,1,BUF_SIZE,infile);
|
151 |
|
|
fclose(infile);
|
152 |
|
|
code=(unsigned char*)malloc(BUF_SIZE);
|
153 |
|
|
memset(code,0,BUF_SIZE);
|
154 |
|
|
|
155 |
|
|
elfHeader=(ElfHeader*)buf ;
|
156 |
|
|
if(strncmp((char*)elfHeader->e_ident+1,"ELF",3))
|
157 |
|
|
{
|
158 |
|
|
printf("Error: Not an ELF file!\n");
|
159 |
|
|
printf("Use the gccmips_elf.zip from opencores/projects/plasma!\n");
|
160 |
|
|
return-1 ;
|
161 |
|
|
}
|
162 |
|
|
|
163 |
|
|
elfHeader->e_entry=ntohl(elfHeader->e_entry);
|
164 |
|
|
elfHeader->e_phoff=ntohl(elfHeader->e_phoff);
|
165 |
|
|
elfHeader->e_shoff=ntohl(elfHeader->e_shoff);
|
166 |
|
|
elfHeader->e_flags=ntohl(elfHeader->e_flags);
|
167 |
|
|
elfHeader->e_phentsize=ntohs(elfHeader->e_phentsize);
|
168 |
|
|
elfHeader->e_phnum=ntohs(elfHeader->e_phnum);
|
169 |
|
|
elfHeader->e_shentsize=ntohs(elfHeader->e_shentsize);
|
170 |
|
|
elfHeader->e_shnum=ntohs(elfHeader->e_shnum);
|
171 |
|
|
printf("Entry=0x%x ",elfHeader->e_entry);
|
172 |
|
|
length=0 ;
|
173 |
|
|
|
174 |
|
|
for(i=0;i<elfHeader->e_phnum;++i)
|
175 |
|
|
{
|
176 |
|
|
elfProgram=(Elf32_Phdr*)(buf+elfHeader->e_phoff+
|
177 |
|
|
elfHeader->e_phentsize*i);
|
178 |
|
|
elfProgram->p_type=ntohl(elfProgram->p_type);
|
179 |
|
|
elfProgram->p_offset=ntohl(elfProgram->p_offset);
|
180 |
|
|
elfProgram->p_vaddr=ntohl(elfProgram->p_vaddr);
|
181 |
|
|
elfProgram->p_filesz=ntohl(elfProgram->p_filesz);
|
182 |
|
|
elfProgram->p_memsz=ntohl(elfProgram->p_memsz);
|
183 |
|
|
elfProgram->p_flags=ntohl(elfProgram->p_flags);
|
184 |
|
|
|
185 |
|
|
elfProgram->p_vaddr-=elfHeader->e_entry ;
|
186 |
|
|
|
187 |
|
|
if(elfProgram->p_type==PT_MIPS_REGINFO)
|
188 |
|
|
{
|
189 |
|
|
elfRegInfo=(ELF_RegInfo*)(buf+elfProgram->p_offset);
|
190 |
|
|
gp_ptr=ntohl(elfRegInfo->ri_gp_value);
|
191 |
|
|
}
|
192 |
|
|
if(elfProgram->p_vaddr<BUF_SIZE)
|
193 |
|
|
{
|
194 |
|
|
/* printf("[0x%x,0x%x,0x%x,0x%x,0x%x]\n", elfProgram->p_vaddr, */
|
195 |
|
|
/* elfProgram->p_offset, elfProgram->p_filesz, elfProgram->p_memsz, */
|
196 |
|
|
/* elfProgram->p_flags); */
|
197 |
|
|
memcpy(code+elfProgram->p_vaddr,buf+elfProgram->p_offset,
|
198 |
|
|
elfProgram->p_filesz);
|
199 |
|
|
length=elfProgram->p_vaddr+elfProgram->p_filesz ;
|
200 |
|
|
/* printf("length = %d 0x%x\n", length, length); */
|
201 |
|
|
}
|
202 |
|
|
}
|
203 |
|
|
|
204 |
|
|
for(i=0;i<elfHeader->e_shnum;++i)
|
205 |
|
|
{
|
206 |
|
|
elfSection=(Elf32_Shdr*)(buf+elfHeader->e_shoff+
|
207 |
|
|
elfHeader->e_shentsize*i);
|
208 |
|
|
elfSection->sh_name=ntohl(elfSection->sh_name);
|
209 |
|
|
elfSection->sh_type=ntohl(elfSection->sh_type);
|
210 |
|
|
elfSection->sh_addr=ntohl(elfSection->sh_addr);
|
211 |
|
|
elfSection->sh_offset=ntohl(elfSection->sh_offset);
|
212 |
|
|
elfSection->sh_size=ntohl(elfSection->sh_size);
|
213 |
|
|
|
214 |
|
|
if(elfSection->sh_type==SHT_MIPS_REGINFO)
|
215 |
|
|
{
|
216 |
|
|
elfRegInfo=(ELF_RegInfo*)(buf+elfSection->sh_offset);
|
217 |
|
|
gp_ptr=ntohl(elfRegInfo->ri_gp_value);
|
218 |
|
|
}
|
219 |
|
|
if(elfSection->sh_type==SHT_PROGBITS)
|
220 |
|
|
{
|
221 |
|
|
/* printf("elfSection->sh_addr=0x%x\n", elfSection->sh_addr); */
|
222 |
|
|
if(elfSection->sh_addr>gp_ptr_backup)
|
223 |
|
|
gp_ptr_backup=elfSection->sh_addr ;
|
224 |
|
|
}
|
225 |
|
|
if(elfSection->sh_type==SHT_NOBITS)
|
226 |
|
|
{
|
227 |
|
|
if(bss_start==0)
|
228 |
|
|
{
|
229 |
|
|
bss_start=elfSection->sh_addr ;
|
230 |
|
|
}
|
231 |
|
|
bss_end=elfSection->sh_addr+elfSection->sh_size ;
|
232 |
|
|
}
|
233 |
|
|
}
|
234 |
|
|
|
235 |
|
|
if(length>bss_start-elfHeader->e_entry)
|
236 |
|
|
{
|
237 |
|
|
length=bss_start-elfHeader->e_entry ;
|
238 |
|
|
}
|
239 |
|
|
if(bss_start==length)
|
240 |
|
|
{
|
241 |
|
|
bss_start=length ;
|
242 |
|
|
bss_end=length+4 ;
|
243 |
|
|
}
|
244 |
|
|
if(gp_ptr==0)
|
245 |
|
|
gp_ptr=gp_ptr_backup+0x7ff0 ;
|
246 |
|
|
|
247 |
|
|
/* #if 0 */
|
248 |
|
|
/*Initialize the $gp register for sdata and sbss */
|
249 |
|
|
printf("gp_ptr=0x%x ",gp_ptr);
|
250 |
|
|
/*modify the first opcodes in boot.asm */
|
251 |
|
|
/*modify the lui opcode */
|
252 |
|
|
set_low(code,0,gp_ptr>>16);
|
253 |
|
|
/*modify the ori opcode */
|
254 |
|
|
set_low(code,4,gp_ptr&0xffff);
|
255 |
|
|
|
256 |
|
|
/*Clear .sbss and .bss */
|
257 |
|
|
printf("sbss=0x%x bss_end=0x%x\nlength=0x%x ",bss_start,bss_end,length);
|
258 |
|
|
set_low(code,8,bss_start>>16);
|
259 |
|
|
set_low(code,12,bss_start&0xffff);
|
260 |
|
|
set_low(code,16,bss_end>>16);
|
261 |
|
|
set_low(code,20,bss_end&0xffff);
|
262 |
|
|
|
263 |
|
|
/*Set stack pointer */
|
264 |
|
|
if(elfHeader->e_entry<0x10000000)
|
265 |
|
|
stack_pointer=bss_end+512 ;
|
266 |
|
|
else
|
267 |
|
|
stack_pointer=bss_end+1024*4 ;
|
268 |
|
|
|
269 |
|
|
if(stack_limit)stack_pointer=(stack_pointer<stack_limit)?stack_pointer:stack_limit;
|
270 |
|
|
//added by Liwei 2007-8-29
|
271 |
|
|
stack_pointer&=~7 ;
|
272 |
|
|
printf("SP=0x%x\n",stack_pointer);
|
273 |
|
|
set_low(code,24,stack_pointer>>16);
|
274 |
|
|
set_low(code,28,stack_pointer&0xffff);
|
275 |
|
|
/* #endif */
|
276 |
|
|
|
277 |
|
|
/*write out test.bin */
|
278 |
|
|
outfile=fopen("test.bin","wb");
|
279 |
|
|
fwrite(code,length,1,outfile);
|
280 |
|
|
fclose(outfile);
|
281 |
|
|
|
282 |
|
|
|
283 |
|
|
/*write out code.txt */
|
284 |
|
|
txtfile=fopen("code.txt","w");
|
285 |
|
|
for(i=0;i<=length;i+=4)
|
286 |
|
|
{
|
287 |
|
|
d=ntohl(*(unsigned long*)(code+i));
|
288 |
|
|
fprintf(txtfile,"%8.8x\n",d);
|
289 |
|
|
}
|
290 |
|
|
fclose(txtfile);
|
291 |
|
|
free(buf);
|
292 |
|
|
printf("\n");
|
293 |
|
|
return 0 ;
|
294 |
|
|
}
|