This source file includes following definitions.
- find_section
- find_symbol
- find_symbol_inflat
- relocate_section
- dump_symtable
- dump_section
- print_offs
- get_flat_string
- align4
- add_div0_arm
- elfloader_load
1
2
3
4
5
6
7
8
9
10 #include <stddef.h>
11 #include <string.h>
12 #include <stdio.h>
13 #include <stdlib.h>
14 #include <fcntl.h>
15
16 #include "myio.h"
17 #include "elfflt.h"
18
19 #define DEBUGPRINTF(...) do {} while (0)
20
21 const int SYMB_SIZE = 60;
22
23 struct relevant_section bss, data, rodata, text;
24
25 static const unsigned char elf_magic_header[] =
26 {0x7f, 0x45, 0x4c, 0x46,
27 0x01,
28 0x01,
29 0x01,
30 };
31
32
33
34
35
36
37 unsigned int symtaboff = 0, symtabsize;
38 unsigned int strtaboff = 0, strtabsize;
39
40
41 char* flat_buf;
42 flat_hdr* flat;
43
44 uint32_t flat_reloc_count;
45 reloc_record_t* flat_reloc;
46 reloc_record_t* flat_reloc_cur;
47
48 uint32_t flat_import_count;
49 import_record_t* flat_import_buf;
50 import_record_t* flat_import_cur;
51
52 char* flag_sym_display=0;
53 int flag_unsafe_sym=0;
54
55
56 static
57 struct relevant_section* find_section(int idx)
58 {
59 if(idx == bss.number)
60 return &bss;
61 if(idx == data.number)
62 return &data;
63 if(idx == text.number)
64 return &text;
65 if(idx == rodata.number)
66 return &rodata;
67 return NULL;
68 }
69
70
71
72
73 static int last_found_symidx = -1;
74
75 static struct elf32_sym*
76 find_symbol(const char *symbol)
77 {
78 static struct elf32_sym s;
79 unsigned int a;
80 char name[SYMB_SIZE];
81 struct relevant_section *sect;
82 int ret;
83
84 last_found_symidx=-1;
85
86 for(a = symtaboff; a < symtaboff + symtabsize; a += sizeof(s)) {
87 ret = b_seek_read(a, (char *)&s, sizeof(s));
88 if (ret < 0) return NULL;
89
90 last_found_symidx++;
91 if(s.st_name != 0) {
92 ret = b_seek_read(strtaboff + s.st_name, name, sizeof(name));
93 name[sizeof(name)-1]=0;
94 if (ret < 0) return NULL;
95
96 if(strcmp(name, symbol) == 0) {
97 sect = find_section(s.st_shndx);
98 if (!sect)
99 return NULL;
100 return &s;
101 }
102 }
103 }
104 return NULL;
105 }
106
107
108 static uint32_t
109 find_symbol_inflat(const char *symbol, struct relevant_section *have_to_be_sect)
110 {
111 struct elf32_sym* s;
112 struct relevant_section *sect;
113
114 s = find_symbol(symbol);
115 if ( !s ) {
116 if ( FLAG_WARNSYMBOL )
117 PRINTERR(stderr, "Warning: not found '%s' symbol\n", symbol);
118 return 0;
119 }
120 sect = find_section(s->st_shndx);
121 if ( sect==0 ) {
122 if ( FLAG_WARNSYMBOL )
123 PRINTERR(stderr, "Warning: unknown section of '%s' symbol\n",symbol);
124 return 0;
125 }
126 if ( have_to_be_sect && have_to_be_sect->number != sect->number ) {
127 if ( FLAG_WARNSYMBOL )
128 PRINTERR(stderr, "Warning: wrong section of '%s' symbol - %s while required %s\n",
129 symbol, sect->name, have_to_be_sect->name );
130 return 0;
131 }
132
133 return sect->flat_offset + s->st_value;
134 }
135
136
137 static int
138 relocate_section( struct relevant_section* base_sect)
139 {
140
141 struct elf32_rela rela;
142 struct elf32_sym s;
143 unsigned int a;
144 char name[SYMB_SIZE];
145 struct relevant_section *tgtsect;
146 int ret;
147
148 if ( FLAG_VERBOSE )
149 printf(">> elf2flt: relocate %s\n", base_sect->name);
150
151 if ( base_sect->size <= 0 )
152 return ELFFLT_OK;
153
154 int rel_size = sizeof(struct elf32_rel);
155 unsigned int rel_section = base_sect->relaoff;
156 unsigned int rel_sect_size = base_sect->relasize;
157
158 int relidx=0;
159 int rv = ELFFLT_OK;
160
161 for(a = rel_section; a < rel_section + rel_sect_size; a += rel_size, relidx++) {
162 ret = b_seek_read(a, (char *)&rela, rel_size);
163 if ( FLAG_VERBOSE )
164 printf("rel_load %x: offs=0x%x, info=0x%x [type=%d]\n",a,rela.r_offset, rela.r_info, ELF32_R_TYPE(rela.r_info));
165 if (ret < 0) return ELFFLT_INPUT_ERROR;
166
167 if (ELF32_R_TYPE(rela.r_info) == R_ARM_V4BX)
168 continue;
169
170 int symidx = ELF32_R_SYM(rela.r_info);
171 if ( symidx*sizeof(struct elf32_sym) >= symtabsize ) {
172 PRINTERR(stderr, "elf2flt unknown symbolidx #%d for relocation %s:%d\n", symidx, base_sect->name,relidx);
173 return ELFFLT_INPUT_ERROR;
174 }
175 ret = b_seek_read((symtaboff +
176 sizeof(struct elf32_sym) * symidx),
177 (char *)&s, sizeof(s));
178 if (ret < 0) return ELFFLT_INPUT_ERROR;
179
180 ret = b_seek_read( strtaboff + s.st_name, name, sizeof(name));
181 name[sizeof(name)-1]=0;
182 if (ret < 0) return ELFFLT_INPUT_ERROR;
183
184 if ( s.st_shndx == 0 )
185 {
186 if ( !flag_sym_display ) {
187 int num_syms = 1+ symtabsize / sizeof(struct elf32_sym);
188 flag_sym_display = malloc( num_syms);
189 memset(flag_sym_display,0, num_syms);
190 }
191
192 int importidx=find_import_symbol(name);
193 if (importidx==0 ) {
194 if ( flag_sym_display[symidx] )
195 continue;
196 flag_sym_display[symidx]=1;
197
198 PRINTERR(stderr, "elf2flt unknown symbol: '%s'\n", name);
199 rv = ELFFLT_SYMBOL_NOT_FOUND;
200 continue;
201 }
202 if ( stoplist_check(name) )
203 { flag_unsafe_sym=1; }
204
205 ret = apply_import( base_sect, &rela, importidx, &s);
206 if (ret != ELFFLT_OK) return ret;
207 }
208 else
209 {
210 tgtsect = find_section( s.st_shndx );
211
212 if ( !tgtsect ) {
213 PRINTERR(stderr, "elf2flt unknown segment %d for name: '%s'\n", s.st_shndx, name);
214 return ELFFLT_SEGMENT_NOT_FOUND;
215 }
216
217 ret = apply_realloc( base_sect, &rela, tgtsect, &s, relidx );
218 if (ret != ELFFLT_OK) return ret;
219 }
220 }
221 return rv;
222 }
223
224
225
226 void dump_symtable()
227 {
228 struct elf32_sym s;
229 unsigned int a;
230 int ret;
231
232 printf("\n\nDump symbols [0x%x .. +0x%x]\n",symtaboff, symtabsize);
233 for(a = symtaboff; a < symtaboff + symtabsize; a += sizeof(s))
234 {
235 ret = b_seek_read(a, (char *)&s, sizeof(s));
236 if (ret < 0) return ;
237
238 char name[SYMB_SIZE];
239 memset(name,0, sizeof(name));
240 ret = b_seek_read(strtaboff + s.st_name, name, sizeof(name)-2);
241
242 printf("SYMBOL %x [%02x: %-15s] - value=0x%x, size=%d, info=0x%x, section=%d\n", a, s.st_name, name, s.st_value, s.st_size, s.st_info, s.st_shndx);
243 }
244 }
245
246 void dump_section(char* name, unsigned char *ptr, int size )
247 {
248 printf("\n\nDump %s",name);
249
250 int i;
251 for(i=0;i<size;i++)
252 {
253 if ((i % 16)==0 ) {printf("\n%06x: ",i);}
254 if ((i % 16)==8 ) {printf("| ");}
255 printf("%02x ",ptr[i]);
256 }
257 printf("\n");
258 }
259
260 static
261 void print_offs(char *prefix, uint32_t offs, char* postfix)
262 {
263 int secoffs = 0;
264 char* sect="unkn";
265
266 if ( !offs ) {
267 printf("%s 0x00000000 %s",prefix, postfix);
268 return;
269 }
270
271 if ( offs >=flat->entry && offs<flat->data_start )
272 { sect="text"; secoffs=flat->entry;}
273 else if ( offs >=flat->data_start && offs<flat->reloc_start )
274 { sect="data"; secoffs=flat->data_start;}
275 else if ( offs >=flat->reloc_start && offs<(flat->reloc_start+flat->bss_size) )
276 { sect="bss"; secoffs=flat->reloc_start;}
277 printf("%s 0x%08x (%s+0x%08x)%s",prefix, offs,sect,offs-secoffs,postfix);
278 }
279
280
281 char* get_flat_string( int32_t offs )
282 {
283 static char buf[200];
284
285 if ( offs <0 )
286 {
287 sprintf(buf," LANGID %d",-offs);
288 return buf;
289 }
290
291 if ( (uint32_t)offs >=flat->reloc_start || (uint32_t)offs<flat->data_start )
292 return "";
293
294 strncpy( buf, flat_buf+offs, sizeof(buf)-1);
295 buf[sizeof(buf)-1]=0;
296 return buf;
297 }
298
299
300
301 static int
302 align4(int size)
303 {
304 if (size%4==0)
305 return 0;
306 return (4-size%4);
307 }
308
309
310
311 unsigned char div0_arm[12] = { 0x00, 0xc0, 0x9f, 0xe5, 0x1c, 0xff, 0x2f, 0xe1, 0x00, 0x00, 0x00, 0x00 };
312
313
314
315
316
317
318 uint32_t offs_div0_from_arm = 0;
319 uint32_t offs_divsi3_skip_div0_test = 0;
320 uint32_t offs__aeabi_uidiv = 0;
321
322
323
324 int add_div0_arm()
325 {
326 struct elf32_sym* s;
327 int rv;
328 int symidx;
329
330 s = find_symbol("__div0");
331 symidx = last_found_symidx;
332 if ( !s) return ELFFLT_OK;
333
334 if (s->st_shndx != text.number) {
335 PRINTERR(stderr,"__div0 should be .text symbol\n");
336 return ELFFLT_UNHANDLED_RELOC;
337 }
338
339
340
341
342
343
344
345
346
347 struct elf32_rela rela;
348 rela.r_info = symidx <<8;
349 rela.r_info |= R_ARM_ABS32;
350 rela.r_offset = text.size+8;
351 rela.r_addend = 0;
352
353
354 offs_div0_from_arm = text.size;
355 memcpy( flat_buf+text.flat_offset+offs_div0_from_arm, div0_arm, sizeof(div0_arm) );
356 text.size+=sizeof(div0_arm);
357
358
359 rv = apply_realloc( &text, &rela, &text, s, -1);
360
361
362 s = find_symbol(".divsi3_skip_div0_test");
363 if ( s && s->st_shndx == text.number ) {
364 offs_divsi3_skip_div0_test = text.flat_offset + s->st_value + 0x114;
365 }
366 s = find_symbol("__aeabi_uidiv");
367 if ( s && s->st_shndx == text.number ) {
368 offs__aeabi_uidiv = text.flat_offset + s->st_value + 0xec;
369 }
370
371 return rv;
372 }
373
374
375
376
377 int
378 elfloader_load(char* fltfile)
379 {
380 struct elf32_ehdr ehdr;
381 struct elf32_shdr shdr;
382 struct elf32_shdr strtable;
383 unsigned int strs;
384 unsigned int shdrptr;
385 unsigned int nameptr;
386 char name[12];
387
388 uint32_t i;
389 unsigned short shdrnum, shdrsize;
390
391 int ret;
392
393
394 ret = b_seek_read( 0, (char *)&ehdr, sizeof(ehdr));
395 if (ret != sizeof(ehdr)) return ELFFLT_INPUT_ERROR;
396
397 if(memcmp(ehdr.e_ident, elf_magic_header, sizeof(elf_magic_header)) != 0) {
398 PRINTERR(stderr, "ELF header problems\n");
399 return ELFFLT_BAD_ELF_HEADER;
400 }
401
402 if ( FLAG_VERBOSE )
403 printf ("Grab section header\n");
404
405
406 shdrptr = ehdr.e_shoff;
407 ret = b_seek_read( shdrptr, (char *)&shdr, sizeof(shdr));
408 if (ret != sizeof(shdr)) return ELFFLT_INPUT_ERROR;
409
410 shdrsize = ehdr.e_shentsize;
411 shdrnum = ehdr.e_shnum;
412
413 if ( FLAG_VERBOSE )
414 printf ("Grab string table section\n");
415
416
417 ret = b_seek_read( ehdr.e_shoff + shdrsize * ehdr.e_shstrndx,
418 (char *)&strtable, sizeof(strtable));
419 if (ret != sizeof(strtable)) return ELFFLT_INPUT_ERROR;
420 strs = strtable.sh_offset;
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435 text.size = text.relasize = data.size = data.relasize =
436 rodata.size = rodata.relasize = symtabsize = strtabsize = 0;
437
438 bss.number = data.number = rodata.number = text.number = -1;
439
440 shdrptr = ehdr.e_shoff;
441 for(i = 0; i < shdrnum; ++i) {
442
443 ret = b_seek_read( shdrptr, (char *)&shdr, sizeof(shdr));
444 DEBUGPRINTF("==shdrptr=0x%x, sizeof=%d; size=0x%x\n",shdrptr,sizeof(shdr),shdrsize );
445 if (ret != sizeof(shdr)) { PRINTERR(stderr, "input error at %s:%d :loaded%d",__FILE__,__LINE__,ret);return ELFFLT_INPUT_ERROR;}
446
447
448 nameptr = strs + shdr.sh_name;
449 DEBUGPRINTF("==nameptr=%x(%x+%x), size=%d\n",nameptr,strs,shdr.sh_name,sizeof(name) );
450 ret = b_seek_read( nameptr, name, sizeof(name));
451 if (ret != sizeof(name)) {PRINTERR(stderr, "input error at %s:%d",__FILE__,__LINE__); return ELFFLT_INPUT_ERROR;}
452
453 DEBUGPRINTF("==shdrptr=0x%x, sizeof=%d; size=0x%x\n",shdrptr,sizeof(shdr),shdrsize );
454 if ( FLAG_DUMP_SECTIONS )
455 printf ("Section #%d: %-15s [section header 0x%x, offset=0x%x, size %d, vma=0x%x]\n",i,name,shdrptr,
456 shdr.sh_offset,shdr.sh_size, shdr.sh_addr);
457
458 if(strncmp(name, ".text", 5) == 0) {
459 text.number = i;
460 text.offset = shdr.sh_offset;
461 text.size = shdr.sh_size;
462 text.base_addr = shdr.sh_addr;
463 } else if(strncmp(name, ".rel.text", 9) == 0) {
464 text.relaoff = shdr.sh_offset;
465 text.relasize = shdr.sh_size;
466 } else if(strncmp(name, ".data", 5) == 0) {
467 data.number = i;
468 data.offset = shdr.sh_offset;
469 data.size = shdr.sh_size;
470 data.base_addr = shdr.sh_addr;
471 } else if(strncmp(name, ".rodata", 7) == 0) {
472 rodata.number = i;
473 rodata.offset = shdr.sh_offset;
474 rodata.size = shdr.sh_size;
475 rodata.base_addr = shdr.sh_addr;
476 } else if(strncmp(name, ".rel.rodata", 11) == 0) {
477 rodata.relaoff = shdr.sh_offset;
478 rodata.relasize = shdr.sh_size;
479 } else if(strncmp(name, ".rel.data", 9) == 0) {
480 data.relaoff = shdr.sh_offset;
481 data.relasize = shdr.sh_size;
482 } else if(strncmp(name, ".rela.", 6) == 0) {
483 PRINTERR(stderr,"RELA relocs are not supported.");
484 return ELFFLT_INPUT_ERROR;
485 } else if(strncmp(name, ".symtab", 7) == 0) {
486 symtaboff = shdr.sh_offset;
487 symtabsize = shdr.sh_size;
488 } else if(strncmp(name, ".strtab", 7) == 0) {
489 strtaboff = shdr.sh_offset;
490 strtabsize = shdr.sh_size;
491 } else if(strncmp(name, ".bss", 4) == 0) {
492 bss.size = shdr.sh_size;
493 bss.number = i;
494 bss.offset = 0;
495 }
496
497 shdrptr += shdrsize;
498 }
499
500 if(symtabsize == 0) {
501 PRINTERR(stderr,"No symbol table found.");
502 return ELFFLT_NO_SYMTAB;
503 }
504 if(strtabsize == 0) {
505 PRINTERR(stderr,"No strings table found.");
506 return ELFFLT_NO_STRTAB;
507 }
508 if(text.size == 0) {
509 PRINTERR(stderr, "No .text segment found.");
510 return ELFFLT_NO_TEXT;
511 }
512
513 if ( (text.relasize + rodata.relasize+ data.relasize) <=0 ) {
514 PRINTERR(stderr,"Found no reloc sections. Please link with -r -d options.\n");
515 return ELFFLT_UNHANDLED_RELOC;
516 }
517
518 if (bss.size) {
519 bss.address = (char *)malloc(bss.size);
520 if (!bss.address) return ELFFLT_OUTPUT_ERROR;
521 }
522 if (data.size) {
523 data.address = (char *)malloc(data.size);
524 if (!data.address) return ELFFLT_OUTPUT_ERROR;
525 }
526 if (text.size) {
527 text.address = (char *)malloc(text.size);
528 if (!text.address) return ELFFLT_OUTPUT_ERROR;
529 }
530 if (rodata.size) {
531 rodata.address = (char *)malloc(rodata.size);
532 if (!rodata.address) return ELFFLT_OUTPUT_ERROR;
533 }
534
535 rodata.name=".rodata";
536 bss.name=".bss";
537 text.name=".text";
538 data.name=".data";
539
540 b_seek_read(text.offset, text.address, text.size);
541 b_seek_read(data.offset, data.address, data.size);
542 b_seek_read(rodata.offset, rodata.address, rodata.size);
543
544 if ( FLAG_DUMP_SOURCE ) {
545 dump_section( text.name, (unsigned char *)text.address, text.size );
546 dump_section( data.name, (unsigned char *)data.address, data.size );
547 dump_section( rodata.name, (unsigned char *)rodata.address, rodata.size );
548 }
549
550 if ( FLAG_DUMP_SYMBOLS ) {
551 dump_symtable();
552 }
553
554 if ( FLAG_DUMP_SYMBOLS || FLAG_DUMP_SOURCE || FLAG_VERBOSE )
555 printf("\n\n");
556
557 if ( FLAG_VERBOSE )
558 printf ("Prepare flat\n");
559
560 int div0hack_size = sizeof(div0_arm);
561
562 int flatmainsize = sizeof(flat_hdr)+text.size+div0hack_size+data.size+rodata.size;
563 int flatrelocsize = text.relasize+rodata.relasize+data.relasize;
564
565
566
567 flatmainsize += align4(text.size) + align4(data.size) + align4(rodata.size);
568
569 flat_buf=malloc( flatmainsize+flatrelocsize );
570 if ( !flat_buf) { PRINTERR(stderr, "fail to malloc flat buf\n"); return ELFFLT_OUTPUT_ERROR;}
571 memset(flat_buf, 0, flatmainsize+flatrelocsize);
572
573
574
575 flat_import_buf=malloc( flatrelocsize* sizeof(import_record_t)/sizeof(reloc_record_t) );
576 if ( !flat_import_buf) { PRINTERR(stderr, "fail to malloc flat import buf\n"); return ELFFLT_OUTPUT_ERROR;}
577 memset(flat_import_buf, 0, flatrelocsize);
578
579
580
581 flat = (flat_hdr*) flat_buf;
582
583 if ( FLAG_VERBOSE )
584 printf(">>elf2flt: load segments\n");
585 int offset=sizeof(flat_hdr);
586 text.flat_offset = offset;
587 memcpy( flat_buf+offset, text.address, text.size );
588 DEBUGPRINTF("load .txt to %x (%x->%x)\n",offset,text.size,text.size+align4(text.size));
589 offset+=text.size+div0hack_size+align4(text.size);
590
591 rodata.flat_offset = offset;
592 DEBUGPRINTF("load .rodata to %x (%x->%x)\n",offset,rodata.size,rodata.size+align4(rodata.size));
593 memcpy( flat_buf+offset, rodata.address, rodata.size );
594 offset+=rodata.size+align4(rodata.size);
595
596 data.flat_offset = offset;
597 DEBUGPRINTF("load .data to %x (%x->%x)\n",offset,data.size,data.size+align4(data.size));
598 memcpy( flat_buf+offset, data.address, data.size );
599 offset+=data.size+align4(data.size);
600
601 bss.flat_offset = offset;
602 DEBUGPRINTF(".bss to %x (%x)\n",offset,bss.size);
603 DEBUGPRINTF("result=%x\n", flatmainsize);
604
605
606 flat->magic = FLAT_MAGIC_NUMBER;
607 flat->rev = FLAT_VERSION;
608 flat->entry = text.flat_offset;
609 flat->data_start = rodata.flat_offset;
610
611 flat->bss_size = bss.size;
612 flat->reloc_start = flatmainsize;
613 flat_reloc_count = 0;
614
615 flat->import_start = 0;
616 flat_import_count = 0;
617
618 flat_reloc = (reloc_record_t*)(flat_buf+flatmainsize);
619 flat_reloc_cur = flat_reloc;
620
621 flat_import_cur = flat_import_buf;
622
623
624 add_div0_arm();
625
626 flag_unsafe_sym = 0;
627
628
629 ret = relocate_section( &text);
630 if(ret != ELFFLT_OK)
631 return ret;
632 ret = relocate_section( &rodata);
633 if(ret != ELFFLT_OK)
634 return ret;
635 ret = relocate_section( &data);
636 if(ret != ELFFLT_OK)
637 return ret;
638
639 if ( flag_unsafe_sym )
640 return ELFFLT_UNSAFE_SYMBOL;
641
642 flat->import_start = flat->reloc_start+flat_reloc_count*sizeof(reloc_record_t);
643
644
645
646 if ( FLAG_VERBOSE )
647 printf(">>elf2flt: lookup entry symbols\n");
648
649 flat->_module_info_offset = find_symbol_inflat("_module_info", &data );
650 if ( flat->_module_info_offset <=0 ) {
651 PRINTERR(stderr, "No or invalid section of _module_info. This symbol should be initialized as ModuleInfo structure.\n");
652 return ELFFLT_NO_MODULEINFO;
653 }
654
655 ModuleInfo* _module_info = (ModuleInfo*) (flat_buf + flat->_module_info_offset);
656 if ( _module_info->magicnum != MODULEINFO_V1_MAGICNUM )
657 {
658 PRINTERR(stderr, "Wrong _module_info->magicnum value. Please check correct filling of this structure\n");
659 return ELFFLT_NO_MODULEINFO;
660 }
661 if ( _module_info->sizeof_struct != sizeof(ModuleInfo) )
662 {
663 PRINTERR(stderr, "Wrong _module_info->sizeof_struct value. Please check correct filling of this structure\n");
664 return ELFFLT_NO_MODULEINFO;
665 }
666
667
668
669
670
671
672 uint32_t *new_import_buf = malloc(flat_import_count*3*sizeof(uint32_t));
673 uint32_t new_import_cnt = 0;
674 int process = 1;
675 while (process)
676 {
677 process = 0;
678 for (i=0; i<flat_import_count; i++)
679 {
680 if (flat_import_buf[i].offs != 0)
681 {
682 process = 1;
683 int cnt = 0;
684 uint32_t idx = flat_import_buf[i].importidx;
685 new_import_buf[new_import_cnt++] = idx;
686 int pcnt = new_import_cnt;
687 uint32_t j;
688 for (j=0; j<flat_import_count; j++)
689 {
690 if (flat_import_buf[j].importidx == idx)
691 {
692 new_import_buf[new_import_cnt++] = flat_import_buf[j].offs;
693 flat_import_buf[j].offs = 0;
694 cnt++;
695 }
696 }
697 new_import_buf[pcnt] = (cnt << 24) | new_import_buf[pcnt];
698 }
699 }
700 }
701
702 flat->import_size = new_import_cnt*sizeof(uint32_t);
703
704 if ( FLAG_DUMP_FLT_HEADERS ) {
705 printf("\nFLT Headers:\n");
706 printf("->entry 0x%x (size %d)\n", flat->entry, flat->data_start - flat->entry );
707 printf("->data_start 0x%x (size %d)\n", flat->data_start, flat->reloc_start - flat->data_start );
708 printf("->bss_start 0x%x (size %d)\n", flat->reloc_start, flat->bss_size );
709 printf("->reloc_start 0x%x (size %d)\n", flat->reloc_start, flat_reloc_count*sizeof(reloc_record_t) );
710 printf("->import_start 0x%x (size %d %d)\n", flat->import_start, flat->import_size, flat_import_count*sizeof(import_record_t) );
711 printf("\n");
712
713 printf("\nModule info:\n");
714 printf("->Module Name: %s\n", get_flat_string(_module_info->moduleName) );
715 printf("->Module Ver: %d.%d\n", _module_info->module_version.major, _module_info->module_version.minor );
716
717 char* branches_str[] = {"any branch","CHDK", "CHDK_DE", "CHDK_SDM", "PRIVATEBUILD"};
718 int branch = (_module_info->chdk_required_branch>REQUIRE_CHDK_PRIVATEBUILD) ?
719 REQUIRE_CHDK_PRIVATEBUILD : _module_info->chdk_required_branch;
720 printf("->Require: %s-build%d. ", branches_str[branch], _module_info->chdk_required_ver );
721 if ( _module_info->chdk_required_platfid == 0 )
722 printf("Any platform.\n");
723 else
724 printf(" Platform #%d only.\n", _module_info->chdk_required_platfid );
725
726 print_offs("->lib = ", _module_info->lib,"\n");
727
728
729
730
731 }
732
733 if ( FLAG_DUMP_FLAT ) {
734 dump_section( "FLT_header", (unsigned char*)flat_buf, sizeof(flat_hdr) );
735 dump_section( "FLT_text", (unsigned char*)flat_buf+flat->entry, flat->data_start-flat->entry );
736 dump_section( "FLT_data", (unsigned char*)flat_buf+flat->data_start, flat->reloc_start-flat->data_start);
737
738
739 printf("\nDump relocations 0x%x (size=%d):\n",flat->reloc_start,flat_reloc_count*sizeof(reloc_record_t));
740 for( i = 0; i< flat_reloc_count; i++)
741 {
742 print_offs("Offs: ",*(uint32_t*)(flat_buf+flat->reloc_start+i*sizeof(reloc_record_t)), "\n");
743 }
744
745 printf("\nDump imports 0x%x (size=%d):\n",flat->import_start,new_import_cnt*sizeof(uint32_t));
746 for (i = 0; i< new_import_cnt;)
747 {
748 uint32_t idx = new_import_buf[i++];
749 int cnt = new_import_buf[i] >> 24;
750 int j;
751 for (j=0; j<cnt; j++)
752 {
753 uint32_t offs = new_import_buf[i++] & 0x00FFFFFF;
754 print_offs((j==0)?"Offs: ":" ",offs,"");
755 int addend = *(uint32_t*)(flat_buf+offs);
756 printf(" = sym_%08x[%s]+0x%x\n",idx,get_import_symbol(idx),addend);
757 }
758 }
759 }
760
761 int filesize = flat->import_start + flat->import_size;
762
763 printf("\n\nOutput file %s (size=%d bytes)\n",fltfile,filesize);
764
765 int output_fd = open(fltfile,O_WRONLY|O_CREAT|O_TRUNC|O_BINARY,0777);
766 i = write(output_fd, flat_buf, flat->import_start);
767 i = write(output_fd, new_import_buf, new_import_cnt*sizeof(uint32_t));
768 close(output_fd);
769 free(new_import_buf);
770
771 return ELFFLT_OK;
772 }
773