make sdl.hidd build against recent iconv-aware sdls
[tangerine.git] / arch / i386-darwin / bootstrap / octave / parseelf.m
blob0800b957a65b364e2b8320eb8844d1b1ba82f5ce
1 function object=parseelf(path)
2 fid = fopen(path,'r');
3 %elf header
4 object.elf_header=readheader(fid);
5 %program header
6 if object.elf_header.e_phoff > 0
7         fseek(fid,object.elf_header.e_phoff);
8         object.program_headers = readprogramheaders(fid,object.elf_header.e_phentsize,object.elf_header.e_phnum);
9 end
10 %section headers
11 if object.elf_header.e_shoff > 0
12         fseek(fid,object.elf_header.e_shoff);
13         object.section_headers = readsectionheaders(fid,object.elf_header.e_shentsize,object.elf_header.e_shnum);
14         object.strtabindex=find([object.section_headers.sh_type]==3);
15         object.symtabindex=find([object.section_headers.sh_type]==2);
16         %get strtabs
17         if numel(object.strtabindex)>0
18                 object.strtabs={object.section_headers(object.strtabindex).strings};
19                 object.stroffsets={object.section_headers(object.strtabindex).stroffsets};
20         end
21         %fill in section names
22         if object.elf_header.e_shstrndx>0
23           fprintf('getting section names...\n')
24                 snamesindex = find(object.strtabindex==(object.elf_header.e_shstrndx+1));
25                 object.section_names = object.strtabs{snamesindex};
26                 snameoffsets = object.stroffsets{snamesindex};
27                 for i=1:numel(object.section_headers)
28                         object.section_headers(i).name = getname(object,snamesindex,object.section_headers(i).sh_name);
29                 end
30                 object.section_headers(1).name = 'UNDEF';
31         end
32         %get symbols and fill in names
33         if numel(object.symtabindex)>0
34                 object.symtabs={object.section_headers(object.symtabindex).symbols};
35                 %find .strtab
36                 strtabindex=find(cellfun(@(c)(numel(c)==1&&c==1),strfind({object.section_headers.name},'.strtab')));
37                 if numel(strtabindex)==1                
38                   strtabindex = find(object.strtabindex==strtabindex);
39                   fprintf('getting symbol names...\n')
40                   for i=1:numel(object.symtabs)
41                     for j=1:numel(object.symtabs{i})
42                       object.symtabs{i}(j).name = getname(object,strtabindex,object.symtabs{i}(j).st_name);
43                       shindex = object.symtabs{i}(j).st_shndx;
44                       if (shindex > 0)
45                         object.symtabs{i}(j).abs_offset = object.symtabs{i}(j).st_value + object.section_headers(shindex+1).sh_offset;
46                         object.symtabs{i}(j).section_name = object.section_headers(shindex+1).name;
47                       else
48                         object.symtabs{i}(j).abs_offset = -1;
49                 end
50               end
51             end
52           end
53         end
54 end
55 fclose(fid);
57 function name=getname(object,tabindex,sh_name)
58 if sh_name <=0
59         name = '';
60         return;
61 end
62 snameoffsets = object.stroffsets{tabindex};
63 nameindex=max(find(sh_name>=snameoffsets));
64 nameoffset=sh_name-snameoffsets(nameindex)+1;
65 str = object.strtabs{tabindex}{nameindex};
66 name = str(nameoffset:end);
68 function sheaders = readsectionheaders(fid,s,n)
69 fprintf('reading sections... ');fflush(stdout);
70 for i=1:n
71 fprintf(' %i ',i);fflush(stdout);
72 pos = ftell(fid);
73 sheaders(i).sh_name=fread(fid,1,'int32');
74 sheaders(i).sh_type=fread(fid,1,'int32');
75 sheaders(i).sh_flags=fread(fid,1,'int32');
76 sheaders(i).sh_addr=fread(fid,1,'int32');
77 sheaders(i).sh_offset=fread(fid,1,'int32');
78 sheaders(i).sh_size=fread(fid,1,'int32');
79 sheaders(i).sh_link=fread(fid,1,'int32');
80 sheaders(i).sh_info=fread(fid,1,'int32');
81 sheaders(i).sh_addralign=fread(fid,1,'int32');
82 sheaders(i).sh_entsize=fread(fid,1,'int32');
83 switch(sheaders(i).sh_type)
84         case 0
85                 sheaders(i).typestr = 'null';
86         case 1
87                 sheaders(i).typestr = 'progbits';
88         case 2
89                 sheaders(i).typestr = 'symtab';
90         case 3
91                 sheaders(i).typestr = 'strtab';
92         case 4
93                 sheaders(i).typestr = 'rela';
94         case 5
95                 sheaders(i).typestr = 'hash';
96         case 6
97                 sheaders(i).typestr = 'danymic';
98         case 7
99                 sheaders(i).typestr = 'note';
100         case 8
101                 sheaders(i).typestr = 'nobits';
102         case 9
103                 sheaders(i).typestr = 'rel';
104         case 10
105                 sheaders(i).typestr = 'shlib';
106         case 11
107                 sheaders(i).typestr = 'dynsym';
108         otherwise
109                 sheaders(i).typestr = 'unknown';
111 if sheaders(i).sh_type == 3
112   fprintf('str ');fflush(stdout);
113         fseek(fid,sheaders(i).sh_offset+1);
114         [sheaders(i).strings,sheaders(i).stroffsets] = readstrings(fid,sheaders(i).sh_offset+sheaders(i).sh_size);
115 fseek(fid,pos+s);
116 elseif sheaders(i).sh_type == 2
117   fprintf('sym ');fflush(stdout);
118         fseek(fid,sheaders(i).sh_offset);
119         sheaders(i).symbols = readsymbols(fid,sheaders(i).sh_offset+sheaders(i).sh_size);
121 fseek(fid,pos+s);
123 fprintf('done\n');fflush(stdout);
125 function symbols = readsymbols(fid,end_offset)
126         symbols = [];
127         do
128                 symbol.st_name = fread(fid,1,'int32');
129                 symbol.st_value = fread(fid,1,'int32');
130                 symbol.st_size = fread(fid,1,'int32');
131                 symbol.st_info = fread(fid,1,'uchar');
132                 symbol.st_other = fread(fid,1,'uchar');
133                 symbol.st_shndx = fread(fid,1,'int16');
134                 if isempty(symbols)
135                         symbols = symbol;
136                 else
137                         symbols(end+1) = symbol;                        
138                 end
139         until ftell(fid)>=end_offset
141 function [strings,offsets] = readstrings(fid,end_offset)
142         strings = {};
143         offsets = [];
144         offset=1;
145         do
146                 str = '';
147                 offsets(end+1) = offset;
148                 %TODO: use fscanf('%s',1);
149                 while   (c = char(fread(fid,1,'uchar'))) != 0
150                         str(end+1) = c;
151                         offset = offset + 1;
152                 end
153                 offset = offset + 1;
154                 strings{end+1} = str;
155         until ftell(fid)>=end_offset
157 function pheaders = readprogramheaders(fid,s,n)
158 fprintf('reading program headers... ');fflush(stdout);
159 for i=1:n
160 fprintf('%i, ',i);fflush(stdout);
161 pos = ftell(fid);
162 pheaders(i).p_type=fread(fid,1,'int32');
163 pheaders(i).p_offsset=fread(fid,1,'int32');
164 pheaders(i).p_vaddr=fread(fid,1,'int32');
165 pheaders(i).p_paddr=fread(fid,1,'int32');
166 pheaders(i).p_filesz=fread(fid,1,'int32');
167 pheaders(i).p_memsz=fread(fid,1,'int32');
168 pheaders(i).p_flags=fread(fid,1,'int32');
169 pheaders(i).p_align=fread(fid,1,'int32');
170 fseek(fid,pos+s)
172 fprintf('done\n');fflush(stdout);
174 function header=readheader(fid)
175 fprintf('reading elf-header...\n');fflush(stdout);
176 header.e_ident=fread(fid,16,'uchar');
177 header.e_type=fread(fid,1,'int16');
178 header.e_machine=fread(fid,1,'int16');
179 header.e_version=fread(fid,1,'int32');
180 header.e_entry=fread(fid,1,'int32');
181 header.e_phoff=fread(fid,1,'int32');
182 header.e_shoff=fread(fid,1,'int32');
183 header.e_flags=fread(fid,1,'int32');
184 header.e_ehsize=fread(fid,1,'int16');
185 header.e_phentsize=fread(fid,1,'int16');
186 header.e_phnum=fread(fid,1,'int16');
187 header.e_shentsize=fread(fid,1,'int16');
188 header.e_shnum=fread(fid,1,'int16');
189 header.e_shstrndx=fread(fid,1,'int16');
190 switch header.e_type
191         case 0
192                 header.typestr = 'none';
193         case 1
194                 header.typestr = 'relocatable';
195         case 2
196                 header.typestr = 'executable';
197         case 3
198                 header.typestr = 'shared object-file';
199         case 4
200                 header.typestr = 'core dump';
201         otherwise
202                 header.typestr = 'unknown';
204 switch header.e_machine
205         case 0
206                 header.machinestr = 'none';
207         case 1
208                 header.machinestr = 'at&t we 32100';
209         case 2
210                 header.machinestr = 'SPARC';
211         case 3
212                 header.machinestr = 'Intel';
213         case 4
214                 header.machinestr = 'M68000';
215         case 5
216                 header.machinestr = 'M88000';
217         case 7
218                 header.machinestr = 'i80860';
219         case 8
220                 header.machinestr = 'MIPS RS3000 Big-Endian';
221         case 10
222                 header.machinestr = 'MIPS RS4000 Little-Endian';
223         case {11,12,13,14,15,16}
224                 header.machinestr = 'reserved';
225         otherwise
226                 header.machinestr = 'unknown';
228 switch header.e_version
229         case 0
230                 header.versionstr = 'invalid';
231         case 1
232                 header.versionstr = 'current';
233         otherwise
234                 header.versionstr = 'unknown';
236 if all(header.e_ident(1:4)==[0x7f 'ELF']')
237         header.magicstate = 'ok';
238 else
239         header.magicstate = 'invalid';
241 switch header.e_ident(5)
242         case 0
243                 header.classstr = 'invalid';
244         case 1
245                 header.classstr = '32bit';
246         case 2
247                 header.classstr = '64bit';
248         otherwise
249                 header.versionstr = 'unknown';
251 switch header.e_ident(6)
252         case 0
253                 header.datastr = 'invalid';
254         case 1
255                 header.datastr = 'lsb';
256         case 2
257                 header.datastr = 'msb';
258         otherwise
259                 header.versionstr = 'unknown';