918
|
1 /*
|
|
2 load spu elf file into memory with proper alignment.
|
|
3 */
|
|
4
|
|
5 #include <stdio.h>
|
|
6 #include <stdlib.h>
|
|
7 #include <unistd.h>
|
|
8 #include <fcntl.h>
|
|
9 #include <elf.h>
|
|
10 #include "types.h"
|
|
11 #include <alloca.h>
|
|
12 #include <malloc.h>
|
|
13 #include <strings.h>
|
|
14
|
|
15
|
|
16 static int
|
|
17 read_file(int fd, unsigned char *buf, int size)
|
|
18 {
|
|
19 int i = 0;
|
|
20 do {
|
|
21 int j = read(fd,buf+i,size-i);
|
|
22 if (j<0) return j;
|
|
23 i+=j;
|
|
24 } while( i< size ) ;
|
|
25 return i;
|
|
26 }
|
|
27
|
|
28 static memaddr
|
|
29 load_elf1(int fd)
|
|
30 {
|
|
31 Elf32_Ehdr header;
|
|
32
|
|
33 if (read_file(fd, (unsigned char *)&header, sizeof(header))<0) return 0;
|
|
34
|
|
35 if (header.e_ident[EI_CLASS]==ELFCLASS32) printf("32bit\n");
|
|
36 printf("entry %0lx\n", (unsigned long)header.e_entry);
|
|
37 printf("program header %0lx ", (unsigned long)header.e_phoff);
|
|
38 printf("length %0lx\n", (unsigned long)header.e_phentsize);
|
|
39 printf("section header %0lx ", (unsigned long)header.e_shoff);
|
|
40 printf("length %0lx\n", (unsigned long)header.e_shentsize);
|
|
41 printf("e_shstrndx %ld\n", (unsigned long)header.e_shstrndx);
|
|
42
|
|
43 int num = header.e_shnum;
|
|
44 Elf32_Shdr section[num] ;
|
|
45
|
|
46 lseek(fd,header.e_shoff + (sizeof(Elf32_Shdr )*(header.e_shstrndx)),SEEK_SET);
|
|
47 if (read_file(fd, (unsigned char *)§ion[0], sizeof(Elf32_Shdr))<0) return 0;
|
|
48 unsigned char *text = (unsigned char *)alloca(section[0].sh_size);
|
|
49 lseek(fd,section[0].sh_offset,SEEK_SET);
|
|
50 if (read_file(fd, text, section[0].sh_size)<0) return 0;
|
|
51 // for(int i=0;i<section.sh_size;i++) putchar(text[i]);
|
|
52
|
|
53 lseek(fd,header.e_shoff,SEEK_SET);
|
|
54 if (read_file(fd, (unsigned char *)§ion[0], sizeof(Elf32_Shdr)*num)<0) return 0;
|
|
55 long min = 0x7fffffff;
|
|
56 long max = 0;
|
|
57
|
|
58 for(int i=0; i< num; i++) {
|
|
59 if (section[i].sh_flags & SHF_ALLOC) {
|
|
60 int adr = section[i].sh_addr;
|
|
61 if (min>adr) min = adr;
|
|
62 adr += section[i].sh_size ;
|
|
63 if (max<adr) max = adr;
|
|
64 }
|
|
65 printf("section %d ",i) ;
|
|
66 printf(" sh_name %s\n",text+section[i].sh_name) ;
|
|
67 printf(" sh_name %lx ",(unsigned long)section[i].sh_name) ;
|
|
68 printf(" sh_type %lx ",(unsigned long)section[i].sh_type) ;
|
|
69 printf(" sh_addr %lx ",(unsigned long)section[i].sh_addr) ;
|
|
70 printf(" sh_offset %lx ",(unsigned long)section[i].sh_offset) ;
|
|
71 printf(" sh_size %lx\n",(unsigned long)section[i].sh_size) ;
|
|
72 }
|
|
73 printf("\nmax %lx min %lx\n",max,min) ;
|
|
74
|
|
75 #if 0
|
|
76 unsigned char *code = (unsigned char*)malloc(max-min);
|
|
77 #else
|
|
78 unsigned char *code ;
|
|
79 posix_memalign((void**)&code,16,max-min);
|
|
80 #endif
|
|
81
|
|
82 bzero(code,max-min);
|
|
83 printf("bzero %lx\n", (unsigned long)code) ;
|
|
84
|
|
85 long poffset = -1;
|
|
86 unsigned char *addr = code;
|
|
87 unsigned long size = 0;
|
|
88 for(int i=0; i< num; i++) {
|
|
89 if ((section[i].sh_flags & SHF_ALLOC) && (section[i].sh_type!=SHT_NOBITS)) {
|
|
90 printf("loading %lx %lx\n",
|
|
91 (unsigned long)(section[i].sh_addr),
|
|
92 (unsigned long)section[i].sh_size) ;
|
|
93 long offset = (unsigned long)(section[i].sh_addr-min)-
|
|
94 (unsigned long)section[i].sh_offset;
|
|
95 if (offset!=poffset) {
|
|
96 if (addr && size) {
|
|
97 printf(" reading %lx %lx\n",
|
|
98 (unsigned long)addr,
|
|
99 (unsigned long)size) ;
|
|
100 if (read_file(fd, addr, size)<0) return 0;
|
|
101 }
|
|
102 // there is a hole
|
|
103 printf(" hole %0x = %0x - %0x\n", offset-poffset, offset, poffset);
|
|
104 poffset = offset;
|
|
105 lseek(fd,section[i].sh_offset,SEEK_SET);
|
|
106 addr = code + (section[i].sh_addr-min);
|
|
107 }
|
|
108 unsigned char *last =
|
|
109 code + (section[i].sh_addr-min+section[i].sh_size);
|
|
110 size = last - addr;
|
|
111 }
|
|
112 }
|
|
113 printf(" last reading %lx %lx\n",
|
|
114 (unsigned long)addr,
|
|
115 (unsigned long)size) ;
|
|
116 if (read_file(fd, addr, size)<0) return 0;
|
|
117 return (memaddr)code;
|
|
118 }
|
|
119
|
|
120 static memaddr
|
|
121 load_elf(const char *name)
|
|
122 {
|
|
123 Elf32_Ehdr header;
|
|
124
|
|
125 int fd = open(name,O_RDONLY);
|
|
126 if (fd<0) return 0;
|
|
127 memaddr addr = load_elf1(fd);
|
|
128 close(fd);
|
|
129 return addr;
|
|
130 }
|
|
131
|
|
132 int
|
|
133 main(int ac, char *av[])
|
|
134 {
|
|
135 load_elf(av[1]);
|
|
136 return 0;
|
|
137 }
|
|
138
|
|
139
|