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

Subversion Repositories mips789

[/] [mips789/] [branches/] [avendor/] [CTool/] [convert_sp.c] - Blame information for rev 10

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

Line No. Rev Author Line
1 10 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)
108
    {
109
        if(par[i]=='\0')return ret ;
110
        ret=ret*16+hex2byte(par[i]);
111
    }
112
    else
113
    for(i=0;;++i)
114
    {
115
        if(par[i]=='\0')return ret ;
116
        ret=ret*10+hex2byte(par[i]);
117
    }
118
    return 0 ;
119
}
120
/****************************/
121
 
122
int main(int argc,char*argv[])
123
{
124
    FILE*infile,*outfile,*txtfile ;
125
    unsigned char*buf,*code ;
126
    long size,stack_pointer ;
127
    long stack_limit=0 ;
128
    unsigned long length,d,i,gp_ptr=0,gp_ptr_backup=0 ;
129
    unsigned long bss_start=0,bss_end=0 ;
130
 
131
    ElfHeader*elfHeader ;
132
    Elf32_Phdr*elfProgram ;
133
    ELF_RegInfo*elfRegInfo ;
134
    Elf32_Shdr*elfSection ;
135
    (void)argc ;
136
    (void)argv ;
137
    //    printf(">%s<=>%d<\n",argv[1],par2u32((char*)argv[1]));//Liwei 2007-8.29
138
    //   printf(">%s<=>%d<\n",argv[2],par2u32((char*)argv[2]));//Liwei 2007-8.29
139
    // printf("argc = %d\n",argc);
140
    if(argc>=3)
141
    stack_limit=((par2u32((char*)argv[1])-par2u32((char*)argv[2])));
142
    //alig 4
143
    /* added by Liwei  2007_8_29 */
144
    /*usage example :
145
                       convert_sp 0x800 0xf0
146
                       the sp_pointer is limited and set as (0x800 - 0xf0)
147
                       0x800 is your instructions space lenth while 0xf0 is your stack lenth
148
                       but make sure your instructions space is big enough...
149
                       comment by Liwei
150
                       */
151
    printf("test.axf -> code.txt & test.bin\n");
152
    infile=fopen("test.axf","rb");
153
    if(infile==NULL)
154
    {
155
        printf("Can't open test.axf");
156
        return 0 ;
157
    }
158
    buf=(unsigned char*)malloc(BUF_SIZE);
159
    size=(int)fread(buf,1,BUF_SIZE,infile);
160
    fclose(infile);
161
    code=(unsigned char*)malloc(BUF_SIZE);
162
    memset(code,0,BUF_SIZE);
163
 
164
    elfHeader=(ElfHeader*)buf ;
165
    if(strncmp((char*)elfHeader->e_ident+1,"ELF",3))
166
    {
167
        printf("Error:  Not an ELF file!\n");
168
        printf("Use the gccmips_elf.zip from opencores/projects/plasma!\n");
169
        return-1 ;
170
    }
171
 
172
    elfHeader->e_entry=ntohl(elfHeader->e_entry);
173
    elfHeader->e_phoff=ntohl(elfHeader->e_phoff);
174
    elfHeader->e_shoff=ntohl(elfHeader->e_shoff);
175
    elfHeader->e_flags=ntohl(elfHeader->e_flags);
176
    elfHeader->e_phentsize=ntohs(elfHeader->e_phentsize);
177
    elfHeader->e_phnum=ntohs(elfHeader->e_phnum);
178
    elfHeader->e_shentsize=ntohs(elfHeader->e_shentsize);
179
    elfHeader->e_shnum=ntohs(elfHeader->e_shnum);
180
    printf("Entry=0x%x ",elfHeader->e_entry);
181
    length=0 ;
182
 
183
    for(i=0;i<elfHeader->e_phnum;++i)
184
    {
185
        elfProgram=(Elf32_Phdr*)(buf+elfHeader->e_phoff+
186
        elfHeader->e_phentsize*i);
187
        elfProgram->p_type=ntohl(elfProgram->p_type);
188
        elfProgram->p_offset=ntohl(elfProgram->p_offset);
189
        elfProgram->p_vaddr=ntohl(elfProgram->p_vaddr);
190
        elfProgram->p_filesz=ntohl(elfProgram->p_filesz);
191
        elfProgram->p_memsz=ntohl(elfProgram->p_memsz);
192
        elfProgram->p_flags=ntohl(elfProgram->p_flags);
193
 
194
        elfProgram->p_vaddr-=elfHeader->e_entry ;
195
 
196
        if(elfProgram->p_type==PT_MIPS_REGINFO)
197
        {
198
            elfRegInfo=(ELF_RegInfo*)(buf+elfProgram->p_offset);
199
            gp_ptr=ntohl(elfRegInfo->ri_gp_value);
200
        }
201
        if(elfProgram->p_vaddr<BUF_SIZE)
202
        {
203
            /* printf("[0x%x,0x%x,0x%x,0x%x,0x%x]\n", elfProgram->p_vaddr, */
204
            /*    elfProgram->p_offset, elfProgram->p_filesz, elfProgram->p_memsz, */
205
            /*    elfProgram->p_flags); */
206
            memcpy(code+elfProgram->p_vaddr,buf+elfProgram->p_offset,
207
            elfProgram->p_filesz);
208
            length=elfProgram->p_vaddr+elfProgram->p_filesz ;
209
            /* printf("length = %d 0x%x\n", length, length); */
210
        }
211
    }
212
 
213
    for(i=0;i<elfHeader->e_shnum;++i)
214
    {
215
        elfSection=(Elf32_Shdr*)(buf+elfHeader->e_shoff+
216
        elfHeader->e_shentsize*i);
217
        elfSection->sh_name=ntohl(elfSection->sh_name);
218
        elfSection->sh_type=ntohl(elfSection->sh_type);
219
        elfSection->sh_addr=ntohl(elfSection->sh_addr);
220
        elfSection->sh_offset=ntohl(elfSection->sh_offset);
221
        elfSection->sh_size=ntohl(elfSection->sh_size);
222
 
223
        if(elfSection->sh_type==SHT_MIPS_REGINFO)
224
        {
225
            elfRegInfo=(ELF_RegInfo*)(buf+elfSection->sh_offset);
226
            gp_ptr=ntohl(elfRegInfo->ri_gp_value);
227
        }
228
        if(elfSection->sh_type==SHT_PROGBITS)
229
        {
230
            /* printf("elfSection->sh_addr=0x%x\n", elfSection->sh_addr); */
231
            if(elfSection->sh_addr>gp_ptr_backup)
232
            gp_ptr_backup=elfSection->sh_addr ;
233
        }
234
        if(elfSection->sh_type==SHT_NOBITS)
235
        {
236
            if(bss_start==0)
237
            {
238
                bss_start=elfSection->sh_addr ;
239
            }
240
            bss_end=elfSection->sh_addr+elfSection->sh_size ;
241
        }
242
    }
243
 
244
    if(length>bss_start-elfHeader->e_entry)
245
    {
246
        length=bss_start-elfHeader->e_entry ;
247
    }
248
    if(bss_start==length)
249
    {
250
        bss_start=length ;
251
        bss_end=length+4 ;
252
    }
253
    if(gp_ptr==0)
254
    gp_ptr=gp_ptr_backup+0x7ff0 ;
255
 
256
    /* #if 0 */
257
    /*Initialize the $gp register for sdata and sbss */
258
    printf("gp_ptr=0x%x ",gp_ptr);
259
    /*modify the first opcodes in boot.asm */
260
    /*modify the lui opcode */
261
    set_low(code,0,gp_ptr>>16);
262
    /*modify the ori opcode */
263
    set_low(code,4,gp_ptr&0xffff);
264
 
265
    /*Clear .sbss and .bss */
266
    printf("sbss=0x%x bss_end=0x%x\nlength=0x%x ",bss_start,bss_end,length);
267
    set_low(code,8,bss_start>>16);
268
    set_low(code,12,bss_start&0xffff);
269
    set_low(code,16,bss_end>>16);
270
    set_low(code,20,bss_end&0xffff);
271
 
272
    /*Set stack pointer */
273
    if(elfHeader->e_entry<0x10000000)
274
    stack_pointer=bss_end+512 ;
275
    else
276
    stack_pointer=bss_end+1024*4 ;
277
 
278
    if(stack_limit)stack_pointer=(stack_pointer<stack_limit)?stack_pointer:stack_limit ;
279
    //added by Liwei 2007-8-29
280
    stack_pointer&=~7 ;
281
    printf("SP=0x%x\n",stack_pointer);
282
    set_low(code,24,stack_pointer>>16);
283
    set_low(code,28,stack_pointer&0xffff);
284
    /* #endif */
285
 
286
    /*write out test.bin */
287
    outfile=fopen("test.bin","wb");
288
    fwrite(code,length,1,outfile);
289
    fclose(outfile);
290
 
291
 
292
    /*write out code.txt */
293
    txtfile=fopen("code.txt","w");
294
    for(i=0;i<=length;i+=4)
295
    {
296
        d=ntohl(*(unsigned long*)(code+i));
297
        fprintf(txtfile,"%8.8x\n",d);
298
    }
299
    fclose(txtfile);
300
    free(buf);
301
    printf("\n");
302
    return 0 ;
303
}

powered by: WebSVN 2.1.0

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