CHDK_DE Vorschauversion  Trunk Rev. 6014
 Alle Datenstrukturen Dateien Funktionen Variablen Typdefinitionen Aufzählungen Aufzählungswerte Makrodefinitionen
elfflt.c-Dateireferenz
#include <stddef.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include "myio.h"
#include "elfflt.h"
+ Include-Abhängigkeitsdiagramm für elfflt.c:

gehe zum Quellcode dieser Datei

Makrodefinitionen

#define DEBUGPRINTF(...)   do {} while (0)
 

Funktionen

static struct relevant_sectionfind_section (int idx)
 
static struct elf32_symfind_symbol (const char *symbol)
 
static uint32_t find_symbol_inflat (const char *symbol, struct relevant_section *have_to_be_sect)
 
static int relocate_section (struct relevant_section *base_sect)
 
void dump_symtable ()
 
void dump_section (char *name, unsigned char *ptr, int size)
 
static void print_offs (char *prefix, uint32_t offs, char *postfix)
 
char * get_flat_string (int32_t offs)
 
static int align4 (int size)
 
int add_div0_arm ()
 
int elfloader_load (char *fltfile)
 Load and relocate an ELF file. Mehr ...
 

Variablen

const int SYMB_SIZE = 60
 
struct relevant_section bss
data rodata 
text
 
static const unsigned char elf_magic_header []
 
unsigned int symtaboff = 0
 
unsigned int symtabsize
 
unsigned int strtaboff = 0
 
unsigned int strtabsize
 
char * flat_buf
 
flat_hdrflat
 
uint32_t flat_reloc_count
 
reloc_record_tflat_reloc
 
reloc_record_tflat_reloc_cur
 
uint32_t flat_import_count
 
import_record_tflat_import_buf
 
import_record_tflat_import_cur
 
char * flag_sym_display =0
 
int flag_unsafe_sym =0
 
static int last_found_symidx = -1
 
unsigned char div0_arm [12] = { 0x00, 0xc0, 0x9f, 0xe5, 0x1c, 0xff, 0x2f, 0xe1, 0x00, 0x00, 0x00, 0x00 }
 
uint32_t offs_div0_from_arm = 0
 
uint32_t offs_divsi3_skip_div0_test = 0
 
uint32_t offs__aeabi_uidiv = 0
 

Makro-Dokumentation

#define DEBUGPRINTF (   ...)    do {} while (0)

Definiert in Zeile 19 der Datei elfflt.c.

Dokumentation der Funktionen

int add_div0_arm ( )

Definiert in Zeile 324 der Datei elfflt.c.

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  if ( (text.size - s->st_value) != 3 ) {
341  PRINTERR(stderr,"Warning! At %s __div0 is not on the end of .text. Doesn't check such case\n", filename_elf);
342  }
343  */
344 
345 
346  // Prepare reloc used in added func
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  // Append new func to the end of .text
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  // Apply reloc
359  rv = apply_realloc( &text, &rela, &text, s, -1);
360 
361  // Detect allowed to patch points
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 }
static int align4 ( int  size)
static

Definiert in Zeile 302 der Datei elfflt.c.

303 {
304  if (size%4==0)
305  return 0;
306  return (4-size%4);
307 }
void dump_section ( char *  name,
unsigned char *  ptr,
int  size 
)

Definiert in Zeile 246 der Datei elfflt.c.

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 }
void dump_symtable ( )

Definiert in Zeile 226 der Datei elfflt.c.

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 }
int elfloader_load ( char *  fltfile)

Load and relocate an ELF file.

Definiert in Zeile 378 der Datei elfflt.c.

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  /* Ensure that we have a correct and compatible ELF header. */
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  // Grab the section header.
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  // Grab the string table section for the names of the sections.
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  /* Parse segments headers to releavant_section entries.
423  .text = actual code from the ELF file
424  .data = initialized data
425  .rodata = contains read-only data
426  .bss = segment holds the size of the unitialized data segment
427  .rel.text, .rel.data = relocation information for the contents
428  of the ".text" and ".data" segments, respectively.
429  .symtab = symbol table for this file
430  .strtab = points to the actual string names used by the symbol table.
431  */
432 
433 
434  // Zero size is indicator of unitialized (not found) section
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  /* The name of the section is contained in the strings table. */
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 
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  // Take to account aligning to int32 each section
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  //import is subset of full reloc list, so same count is enough
574  // but apply multiplier to take into account difference between sizeofs
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  // Fill flat with sections aligned to int32
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  // Initialize flat headers
607  flat->rev = FLAT_VERSION;
608  flat->entry = text.flat_offset;
609  flat->data_start = rodata.flat_offset;
610  //flat->bss_start = bss.flat_offset;
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);
620 
622 
623  // _div0_arm hack
624  add_div0_arm();
625 
626  flag_unsafe_sym = 0;
627 
628  // Do relocations
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 
643 
644  // Init offsets to the entry symbols
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 
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  // Group import relocations
668  // Input = array of offset/index pairs - one for each address to be relocated to a core CHDK symbol
669  // Output = list of entries of the form:
670  // Index, Offset1 | (N<<24), Offset2, ..., OffsetN
671  // where each offset is a reference to the same core CHDK symbol
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;
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) ?
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  //printf("->Description: %s\n", get_flat_string(_module_info->description) );
726  print_offs("->lib = ", _module_info->lib,"\n");
727  //print_offs("->_module_loader() = ", _module_info->loader,"\n");
728  //print_offs("->_module_unloader() = ", _module_info->unloader,"\n");
729  //print_offs("->_module_can_unload()= ", _module_info->can_unload,"\n");
730  //print_offs("->_module_exit_alt() = ", _module_info->exit_alt,"\n");
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  //dump_section( "FLT_bss", (unsigned char*)flat_buf+flat->reloc_start, flat->bss_size );
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 
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 }
static struct relevant_section* find_section ( int  idx)
static

Definiert in Zeile 57 der Datei elfflt.c.

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 }
static struct elf32_sym* find_symbol ( const char *  symbol)
static

Definiert in Zeile 76 der Datei elfflt.c.

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 
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 
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 }
static uint32_t find_symbol_inflat ( const char *  symbol,
struct relevant_section have_to_be_sect 
)
static

Definiert in Zeile 109 der Datei elfflt.c.

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 }
char* get_flat_string ( int32_t  offs)

Definiert in Zeile 281 der Datei elfflt.c.

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 }
static void print_offs ( char *  prefix,
uint32_t  offs,
char *  postfix 
)
static

Definiert in Zeile 261 der Datei elfflt.c.

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 }
static int relocate_section ( struct relevant_section base_sect)
static

Definiert in Zeile 138 der Datei elfflt.c.

139 {
140  /* section_beg_ptr added; runtime start address of current section */
141  struct elf32_rela rela; /* Now used both for rel and rela data! */
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);
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);
215  }
216 
217  ret = apply_realloc( base_sect, &rela, tgtsect, &s, relidx /*addr - symsect->address*/);
218  if (ret != ELFFLT_OK) return ret;
219  }
220  }
221  return rv;
222 }

Variablen-Dokumentation

unsigned char div0_arm[12] = { 0x00, 0xc0, 0x9f, 0xe5, 0x1c, 0xff, 0x2f, 0xe1, 0x00, 0x00, 0x00, 0x00 }

Definiert in Zeile 311 der Datei elfflt.c.

const unsigned char elf_magic_header[]
static
Initialisierung:
=
{0x7f, 0x45, 0x4c, 0x46,
0x01,
0x01,
0x01,
}

Definiert in Zeile 25 der Datei elfflt.c.

char* flag_sym_display =0

Definiert in Zeile 52 der Datei elfflt.c.

int flag_unsafe_sym =0

Definiert in Zeile 53 der Datei elfflt.c.

flat_hdr* flat

Definiert in Zeile 42 der Datei elfflt.c.

char* flat_buf

Definiert in Zeile 41 der Datei elfflt.c.

import_record_t* flat_import_buf

Definiert in Zeile 49 der Datei elfflt.c.

uint32_t flat_import_count

Definiert in Zeile 48 der Datei elfflt.c.

import_record_t* flat_import_cur

Definiert in Zeile 50 der Datei elfflt.c.

reloc_record_t* flat_reloc

Definiert in Zeile 45 der Datei elfflt.c.

uint32_t flat_reloc_count

Definiert in Zeile 44 der Datei elfflt.c.

reloc_record_t* flat_reloc_cur

Definiert in Zeile 46 der Datei elfflt.c.

int last_found_symidx = -1
static

Definiert in Zeile 73 der Datei elfflt.c.

uint32_t offs__aeabi_uidiv = 0

Definiert in Zeile 320 der Datei elfflt.c.

uint32_t offs_div0_from_arm = 0

Definiert in Zeile 318 der Datei elfflt.c.

uint32_t offs_divsi3_skip_div0_test = 0

Definiert in Zeile 319 der Datei elfflt.c.

unsigned int strtaboff = 0

Definiert in Zeile 38 der Datei elfflt.c.

unsigned int strtabsize

Definiert in Zeile 38 der Datei elfflt.c.

const int SYMB_SIZE = 60

Definiert in Zeile 21 der Datei elfflt.c.

unsigned int symtaboff = 0

Definiert in Zeile 37 der Datei elfflt.c.

unsigned int symtabsize

Definiert in Zeile 37 der Datei elfflt.c.

struct relevant_section bss data rodata text

Definiert in Zeile 23 der Datei elfflt.c.