示例#1
0
static int
pre_dl(DECL_ARGS)
{

	print_offs("6n", 0);
	return 1;
}
示例#2
0
static int
pre_bl(DECL_ARGS)
{
	size_t		 icol;

	/*
	 * print_offs() will increase the -offset to account for
	 * a possible enclosing .It, but any enclosed .It blocks
	 * just nest and do not add up their indentation.
	 */
	if (n->norm->Bl.offs) {
		print_offs(n->norm->Bl.offs, 0);
		Bl_stack[Bl_stack_len++] = 0;
	}

	switch (n->norm->Bl.type) {
	case LIST_enum:
		n->norm->Bl.count = 0;
		return 1;
	case LIST_column:
		break;
	default:
		return 1;
	}

	if (n->child != NULL) {
		print_line(".TS", MMAN_nl);
		for (icol = 0; icol < n->norm->Bl.ncols; icol++)
			print_word("l");
		print_word(".");
	}
	outflags |= MMAN_nl;
	return 1;
}
示例#3
0
static int
pre_dl(DECL_ARGS)
{

	print_offs("6n");
	return(1);
}
示例#4
0
static int
pre_bd(DECL_ARGS)
{
	outflags &= ~(MMAN_PP | MMAN_sp | MMAN_br);

	if (DISP_unfilled == n->norm->Bd.type ||
	    DISP_literal  == n->norm->Bd.type)
		print_line(".nf", 0);
	if (0 == n->norm->Bd.comp && NULL != n->parent->prev)
		outflags |= MMAN_sp;
	print_offs(n->norm->Bd.offs, 1);
	return 1;
}
示例#5
0
int main(int argc, char **argv)
{

    if ( argc < 2 )
    {
        printf("fltdump.exe filename.flt [-f]\n  -f = dump content of FLAT sections\n");
        return 1;
    }
    
    if ( argc > 2 && argv[2][0]=='-' && argv[2][1]=='f' )
	  { FLAG_DUMP_FLAT=1;}

    char* filename_flt = argv[1];

    int rv;
    if ( (rv=b_file_preload(filename_flt)) <= 0 )
    {
        fprintf(stderr, "Error load file '%s': loaded %d\n",filename_flt,rv);
        return 1;
    }


	flat = (struct flat_hdr*) b_get_buf();
	flat_buf = (unsigned char*)b_get_buf();

    char magic[5];          // "CFLA"
	memcpy(magic,flat->magic,4);
	magic[4]=0;


	printf("\nFLT Headers:\n");
	printf("->magic        %s (flat rev.%d)\n", magic, flat->rev );

	if ( memcmp(magic,FLAT_MAGIC_NUMBER,4) ) {
		printf("This is not CHDK-FLAT!\n");
		return 1;
	}	

	if ( flat->rev != FLAT_VERSION )
	{
		printf("Bad FLAT revision! It is %d while should be %d\n", flat->rev, FLAT_VERSION);
	}

	int flat_reloc_count;
	flat_reloc_count = (flat->import_start-flat->reloc_start)/sizeof(uint32_t);
	int flat_import_count;
	flat_import_count = (flat->file_size-flat->import_start)/sizeof(uint32_t);


	printf("->entry(.text) 0x%x (size %d)\n", flat->entry, flat->data_start - flat->entry );
	printf("->data_start   0x%x (size %d)\n", flat->data_start,  flat->bss_start - flat->data_start );
	printf("->bss_start    0x%x (size %d)\n", flat->bss_start, flat->reloc_start - flat->bss_start );
	printf("->reloc_start  0x%x (size %d)\n", flat->reloc_start, flat->import_start - flat->reloc_start );
	printf("->import_start 0x%x (size %d)\n", flat->import_start, flat->file_size - flat->import_start );
    printf("\n");

	if ( flat->rev == FLAT_VERSION )
	{
		struct ModuleInfo* _module_info = (struct ModuleInfo*)(flat_buf + flat->_module_info_offset);
		if ( _module_info->magicnum != MODULEINFO_V1_MAGICNUM ) 
		{
		  printf("Malformed module info - bad magicnum!\n");
		  return 1;
		}
		if ( _module_info->sizeof_struct != sizeof(struct ModuleInfo) ) 
		{
		  printf("Malformed module info - bad sizeof!\n");
		  return 1;
		}


		printf("\nModule info:\n");
		printf("->Module Name: %s\n", get_flat_string(_module_info->moduleName) );
		printf("->Module Ver: %d.%d\n", _module_info->module_version.major, _module_info->module_version.minor );
		
		char* branches_str[] = {"any branch","CHDK", "CHDK_DE", "CHDK_SDM", "PRIVATEBUILD"};
		int branch = (_module_info->chdk_required_branch>REQUIRE_CHDK_PRIVATEBUILD) ? 
							REQUIRE_CHDK_PRIVATEBUILD : _module_info->chdk_required_branch;
		printf("->Require: %s-build%d. ", branches_str[branch], _module_info->chdk_required_ver );
		if ( _module_info->chdk_required_platfid == 0 )
		  	printf("Any platform.\n");
		else
		  	printf(" Platform #%d only.\n", _module_info->chdk_required_platfid );
	    printf("->Description: %s\n", get_flat_string(_module_info->description) );
    	print_offs("->lib                 = ", (int)_module_info->lib,"\n");
	    //print_offs("->_module_loader()    = ", (int)_module_info->loader,"\n");
	    //print_offs("->_module_unloader()  = ", (int)_module_info->unloader,"\n");
	    //print_offs("->_module_can_unload()= ", (int)_module_info->can_unload,"\n");
	    //print_offs("->_module_exit_alt()  = ", (int)_module_info->exit_alt,"\n");
	}
		
	if ( !FLAG_DUMP_FLAT )
	  return 0;

    dump_section( "FLT_header", flat_buf, sizeof(struct flat_hdr) );
    dump_section( "FLT_text", flat_buf+flat->entry, flat->data_start-flat->entry );
    dump_section( "FLT_data", flat_buf+flat->data_start, flat->bss_start-flat->data_start);
    dump_section( "FLT_bss",  flat_buf+flat->bss_start, flat->reloc_start-flat->bss_start );

	int i;
    printf("\nDump relocations 0x%x (size=%d):\n",flat->reloc_start,flat_reloc_count*sizeof(uint32_t));
    for( i = 0; i< flat_reloc_count; i++)
        print_offs("Offs: ",*(int*)(flat_buf+flat->reloc_start+i*sizeof(uint32_t)),"\n");

    printf("\nDump imports 0x%x (size=%d):\n",flat->import_start,flat_import_count*sizeof(uint32_t));
    uint32_t *new_import_buf = (uint32_t*)(flat_buf+flat->import_start);
    for( i = 0; i< flat_import_count; i++)
    {
        uint32_t idx = new_import_buf[i++];
        int cnt = new_import_buf[i] >> 24;
        int j;
        for (j=0; j<cnt; j++)
        {
            uint32_t offs = new_import_buf[i++] & 0x00FFFFFF;
            print_offs((j==0)?"Offs: ":"      ",offs,"");
		    int addend = *(uint32_t*)(flat_buf+offs);
		    printf(" = sym_%08x[%s]+0x%x\n",idx,get_import_symbol(idx),addend);
        }
	}

	return 0;

}
示例#6
0
/*---------------------------------------------------------------------------*/
int
elfloader_load(char* filename, char* fltfile)
{
  struct elf32_ehdr ehdr;
  struct elf32_shdr shdr;
  struct elf32_shdr strtable;
  unsigned int strs;
  unsigned int shdrptr;
  unsigned int nameptr;
  char name[12];
  
  int i;
  unsigned short shdrnum, shdrsize;

  int ret;

  /* Ensure that we have a correct and compatible ELF header. */
  ret = b_seek_read( 0, (char *)&ehdr, sizeof(ehdr));
  if (ret != sizeof(ehdr)) return ELFFLT_INPUT_ERROR;

  if(memcmp(ehdr.e_ident, elf_magic_header, sizeof(elf_magic_header)) != 0) {
    	PRINTERR(stderr, "ELF header problems\n");
    return ELFFLT_BAD_ELF_HEADER;
  }

  if ( FLAG_VERBOSE )
    	printf ("Grab section header\n");

  // Grab the section header.
  shdrptr = ehdr.e_shoff;
  ret = b_seek_read( shdrptr, (char *)&shdr, sizeof(shdr));
  if (ret != sizeof(shdr)) return ELFFLT_INPUT_ERROR;
  
  shdrsize = ehdr.e_shentsize;
  shdrnum = ehdr.e_shnum;

  if ( FLAG_VERBOSE )
    	printf ("Grab string table section\n");

  // Grab the string table section for the names of the sections. 
  ret = b_seek_read( ehdr.e_shoff + shdrsize * ehdr.e_shstrndx,
                             (char *)&strtable, sizeof(strtable));
  if (ret != sizeof(strtable)) return ELFFLT_INPUT_ERROR;
  strs = strtable.sh_offset;

  /* Parse segments headers to releavant_section entries.
		.text = actual code from the ELF file
		.data = initialized data
		.rodata = contains read-only data
		.bss = segment holds the size of the unitialized data segment
		.rel.text, .rel.data = relocation information for the contents 
					of the ".text" and ".data" segments, respectively.
		.symtab = symbol table for this file
		.strtab = points to the actual string names used by the symbol table.
  */


  // Zero size is indicator of unitialized (not found) section
  text.size = text.relasize = data.size = data.relasize =
    rodata.size = rodata.relasize = symtabsize = strtabsize = 0;

  bss.number = data.number = rodata.number = text.number = -1;
                
  shdrptr = ehdr.e_shoff;
  for(i = 0; i < shdrnum; ++i) {

    ret = b_seek_read( shdrptr, (char *)&shdr, sizeof(shdr));
	DEBUGPRINTF("==shdrptr=0x%x, sizeof=%d; size=0x%x\n",shdrptr,sizeof(shdr),shdrsize );
    if (ret != sizeof(shdr)) { PRINTERR(stderr, "input error at %s:%d :loaded%d",__FILE__,__LINE__,ret);return ELFFLT_INPUT_ERROR;}
    
    /* The name of the section is contained in the strings table. */
    nameptr = strs + shdr.sh_name;
	DEBUGPRINTF("==nameptr=%x(%x+%x), size=%d\n",nameptr,strs,shdr.sh_name,sizeof(name) );
    ret = b_seek_read( nameptr, name, sizeof(name));
    if (ret != sizeof(name)) {PRINTERR(stderr, "input error at %s:%d",__FILE__,__LINE__); return ELFFLT_INPUT_ERROR;}

	DEBUGPRINTF("==shdrptr=0x%x, sizeof=%d; size=0x%x\n",shdrptr,sizeof(shdr),shdrsize );
	if ( FLAG_DUMP_SECTIONS )
		printf ("Section #%d: %-15s [section header 0x%x, offset=0x%x, size %d, vma=0x%x]\n",i,name,shdrptr,
													shdr.sh_offset,shdr.sh_size, shdr.sh_addr);

    if(strncmp(name, ".text", 5) == 0) {
      text.number = i;
      text.offset = shdr.sh_offset;
      text.size = shdr.sh_size;
	  text.base_addr = shdr.sh_addr;
    } else if(strncmp(name, ".rel.text", 9) == 0) {
      text.relaoff = shdr.sh_offset;
      text.relasize = shdr.sh_size;
    } else if(strncmp(name, ".data", 5) == 0) {
      data.number = i;
      data.offset = shdr.sh_offset;
      data.size = shdr.sh_size;
	  data.base_addr = shdr.sh_addr;
    } else if(strncmp(name, ".rodata", 7) == 0) {
      rodata.number = i;
      rodata.offset = shdr.sh_offset;
      rodata.size = shdr.sh_size;
	  rodata.base_addr = shdr.sh_addr;
    } else if(strncmp(name, ".rel.rodata", 11) == 0) {
      rodata.relaoff = shdr.sh_offset;
      rodata.relasize = shdr.sh_size;
    } else if(strncmp(name, ".rel.data", 9) == 0) {
      data.relaoff = shdr.sh_offset;
      data.relasize = shdr.sh_size;
    } else if(strncmp(name, ".rela.", 6) == 0) {
      PRINTERR(stderr,"RELA relocs are not supported.");
      return ELFFLT_INPUT_ERROR;
    } else if(strncmp(name, ".symtab", 7) == 0) {
      symtaboff = shdr.sh_offset;
      symtabsize = shdr.sh_size;
    } else if(strncmp(name, ".strtab", 7) == 0) {
      strtaboff = shdr.sh_offset;
      strtabsize = shdr.sh_size;
    } else if(strncmp(name, ".bss", 4) == 0) {
      bss.size = shdr.sh_size;
      bss.number = i;
      bss.offset = 0;
    }

    shdrptr += shdrsize;
  }

  if(symtabsize == 0) {
    PRINTERR(stderr,"No symbol table found.");
    return ELFFLT_NO_SYMTAB;
  }
  if(strtabsize == 0) {
    PRINTERR(stderr,"No strings table found.");
    return ELFFLT_NO_STRTAB;
  }
  if(text.size == 0) {
    PRINTERR(stderr, "No .text segment found.");
  	return ELFFLT_NO_TEXT;
  }

  if ( (text.relasize + rodata.relasize+ data.relasize) <=0 ) {
      PRINTERR(stderr,"Found no reloc sections. Please link with -r -d options.\n");
      return ELFFLT_UNHANDLED_RELOC;
  }

  if (bss.size) {
    bss.address = (char *)malloc(bss.size);
    if (!bss.address) return ELFFLT_OUTPUT_ERROR;
  }
  if (data.size) {
    data.address = (char *)malloc(data.size);
    if (!data.address) return ELFFLT_OUTPUT_ERROR;
  }
  if (text.size) {
    text.address = (char *)malloc(text.size);
    if (!text.address) return ELFFLT_OUTPUT_ERROR;
  }
  if (rodata.size) {
    rodata.address =  (char *)malloc(rodata.size);
    if (!rodata.address) return ELFFLT_OUTPUT_ERROR;
  }

  rodata.name=".rodata";
  bss.name=".bss";
  text.name=".text";
  data.name=".data";



  b_seek_read(text.offset, text.address, text.size);
  b_seek_read(data.offset, data.address, data.size);
  b_seek_read(rodata.offset, rodata.address, rodata.size);

  if ( FLAG_DUMP_SOURCE ) {
    dump_section( text.name, (unsigned char *)text.address, text.size );
    dump_section( data.name, (unsigned char *)data.address, data.size );
    dump_section( rodata.name, (unsigned char *)rodata.address, rodata.size );
  }

  if ( FLAG_DUMP_SYMBOLS ) {
    dump_symtable();
  }

  if ( FLAG_DUMP_SYMBOLS || FLAG_DUMP_SOURCE || FLAG_VERBOSE )
	 printf("\n\n");

  if ( FLAG_VERBOSE )
   	 printf ("Prepare flat\n");

  int div0hack_size = sizeof(div0_arm);

  int flatmainsize = sizeof(struct flat_hdr)+text.size+div0hack_size+data.size+rodata.size+bss.size;  
  int flatrelocsize = text.relasize+rodata.relasize+data.relasize;


  // Take to account aligning to int32 each section  
  flatmainsize += align4(text.size) + align4(data.size) + align4(rodata.size) + align4(bss.size);
  
  flat_buf=malloc( flatmainsize+flatrelocsize );      
  if ( !flat_buf) { PRINTERR(stderr, "fail to malloc flat buf\n"); return ELFFLT_OUTPUT_ERROR;}
  memset(flat_buf, 0, flatmainsize+flatrelocsize);
  
  //import is subset of full reloc list, so same count is enough
  // but apply multiplier to take into account difference between sizeofs
  flat_import_buf=malloc( flatrelocsize* sizeof(import_record_t)/sizeof(reloc_record_t) );      		
  if ( !flat_import_buf) { PRINTERR(stderr, "fail to malloc flat import buf\n"); return ELFFLT_OUTPUT_ERROR;}
  memset(flat_import_buf, 0, flatrelocsize);

  // Fill flat with sections aligned to int32

  flat = (struct flat_hdr*) flat_buf;

  if ( FLAG_VERBOSE )
      printf(">>elf2flt: load segments\n");
  int offset=sizeof(struct flat_hdr);
  text.flat_offset = offset;
  memcpy( flat_buf+offset, text.address, text.size );
  DEBUGPRINTF("load .txt to %x (%x->%x)\n",offset,text.size,text.size+align4(text.size));
  offset+=text.size+div0hack_size+align4(text.size);


  rodata.flat_offset = offset;
  DEBUGPRINTF("load .rodata to %x (%x->%x)\n",offset,rodata.size,rodata.size+align4(rodata.size));
  memcpy( flat_buf+offset, rodata.address, rodata.size );
  offset+=rodata.size+align4(rodata.size);

  data.flat_offset = offset;
  DEBUGPRINTF("load .data to %x (%x->%x)\n",offset,data.size,data.size+align4(data.size));
  memcpy( flat_buf+offset, data.address, data.size );
  offset+=data.size+align4(data.size);

  bss.flat_offset = offset;
  DEBUGPRINTF(".bss to %x (%x->%x)\n",offset,bss.size,bss.size+align4(bss.size));
  DEBUGPRINTF("result=%x\n",  flatmainsize);

  // Initialize flat headers
  memcpy(flat->magic, FLAT_MAGIC_NUMBER, sizeof(flat->magic));       // Set magic (CHDK_FLAT)
  flat->rev = FLAT_VERSION;
  flat->entry = text.flat_offset;
  flat->data_start = rodata.flat_offset;
  flat->bss_start = bss.flat_offset;  
  flat->reloc_start = flatmainsize;
  flat_reloc_count = 0;

  flat->import_start = 0;
  flat_import_count = 0;
  
  flat_reloc = (reloc_record_t*)(flat_buf+flatmainsize);  
  flat_reloc_cur = flat_reloc;

  flat_import_cur = flat_import_buf;

  // _div0_arm hack
  add_div0_arm();

  flag_unsafe_sym = 0;

  // Do relocations
  ret = relocate_section( &text);
  if(ret != ELFFLT_OK)
      return ret;  
  ret = relocate_section( &rodata);
  if(ret != ELFFLT_OK)
      return ret;
  ret = relocate_section( &data);
  if(ret != ELFFLT_OK)
      return ret;

  if ( flag_unsafe_sym )
      return ELFFLT_UNSAFE_SYMBOL;

  flat->import_start = flat->reloc_start+flat_reloc_count*sizeof(reloc_record_t);

  // Init offsets to the entry symbols
                  
  if ( FLAG_VERBOSE )
   	  printf(">>elf2flt: lookup entry symbols\n");

  flat->_module_info_offset = find_symbol_inflat("_module_info", &data );
  if ( flat->_module_info_offset <=0 ) {
    PRINTERR(stderr, "No or invalid section of _module_info. This symbol should be initialized as ModuleInfo structure.\n");
    return ELFFLT_NO_MODULEINFO;
  }

  struct ModuleInfo* _module_info = (struct ModuleInfo*) (flat_buf + flat->_module_info_offset);
  if ( _module_info->magicnum != MODULEINFO_V1_MAGICNUM ) 
  {
    PRINTERR(stderr, "Wrong _module_info->magicnum value. Please check correct filling of this structure\n");
    return ELFFLT_NO_MODULEINFO;
  }
  if ( _module_info->sizeof_struct != sizeof(struct ModuleInfo) ) 
  {
    PRINTERR(stderr, "Wrong _module_info->sizeof_struct value. Please check correct filling of this structure\n");
    return ELFFLT_NO_MODULEINFO;
  }

  // Group import relocations
  //  Input = array of offset/index pairs - one for each address to be relocated to a core CHDK symbol
  //  Output = list of entries of the form:
  //        Index, Offset1 | (N<<24), Offset2, ..., OffsetN
  //  where each offset is a reference to the same core CHDK symbol
  uint32_t *new_import_buf = malloc(flat_import_count*3*sizeof(uint32_t));
  uint32_t new_import_cnt = 0;
  int process = 1;
  while (process)
  {
      process = 0;
      for (i=0; i<flat_import_count; i++)
      {
          if (flat_import_buf[i].offs != 0)
          {
              process = 1;
              int cnt = 0;
              uint32_t idx = flat_import_buf[i].importidx;
              new_import_buf[new_import_cnt++] = idx;
              int pcnt = new_import_cnt;
              int j;
              for (j=0; j<flat_import_count; j++)
              {
                  if (flat_import_buf[j].importidx == idx)
                  {
                      new_import_buf[new_import_cnt++] = flat_import_buf[j].offs;
                      flat_import_buf[j].offs = 0;
                      cnt++;
                  }
              }
              new_import_buf[pcnt] = (cnt << 24) | new_import_buf[pcnt];
          }
      }
  }

  flat->file_size = flat->import_start+new_import_cnt*sizeof(uint32_t);

  if ( FLAG_DUMP_FLT_HEADERS ) {
	printf("\nFLT Headers:\n");
	printf("->entry        0x%x (size %d)\n", flat->entry, flat->data_start - flat->entry );
	printf("->data_start   0x%x (size %d)\n", flat->data_start,  flat->bss_start - flat->data_start );
	printf("->bss_start    0x%x (size %d)\n", flat->bss_start,   flat->reloc_start - flat->bss_start );
	printf("->reloc_start  0x%x (size %d)\n", flat->reloc_start, flat_reloc_count*sizeof(reloc_record_t) );
	printf("->import_start 0x%x (size %d %d)\n", flat->import_start, flat->file_size-flat->import_start, flat_import_count*sizeof(import_record_t) );
    printf("\n");

	printf("\nModule info:\n");
	printf("->Module Name: %s\n", get_flat_string(_module_info->moduleName) );
	printf("->Module Ver: %d.%d\n", _module_info->module_version.major, _module_info->module_version.minor );

	char* branches_str[] = {"any branch","CHDK", "CHDK_DE", "CHDK_SDM", "PRIVATEBUILD"};
	int branch = (_module_info->chdk_required_branch>REQUIRE_CHDK_PRIVATEBUILD) ? 
						REQUIRE_CHDK_PRIVATEBUILD : _module_info->chdk_required_branch;
	printf("->Require: %s-build%d. ", branches_str[branch], _module_info->chdk_required_ver );
	if ( _module_info->chdk_required_platfid == 0 )
	  	printf("Any platform.\n");
	else
	  	printf(" Platform #%d only.\n", _module_info->chdk_required_platfid );
	printf("->Description: %s\n", get_flat_string(_module_info->description) );
	print_offs("->lib                 = ", (int)_module_info->lib,"\n");
	//print_offs("->_module_loader()    = ", (int)_module_info->loader,"\n");
	//print_offs("->_module_unloader()  = ", (int)_module_info->unloader,"\n");
	//print_offs("->_module_can_unload()= ", (int)_module_info->can_unload,"\n");
	//print_offs("->_module_exit_alt()  = ", (int)_module_info->exit_alt,"\n");
  }

  if ( FLAG_DUMP_FLAT ) {
    dump_section( "FLT_header", (unsigned char*)flat_buf, sizeof(struct flat_hdr) );
    dump_section( "FLT_text", (unsigned char*)flat_buf+flat->entry, flat->data_start-flat->entry );
    dump_section( "FLT_data", (unsigned char*)flat_buf+flat->data_start, flat->bss_start-flat->data_start);
    dump_section( "FLT_bss",  (unsigned char*)flat_buf+flat->bss_start, flat->reloc_start-flat->bss_start );

    printf("\nDump relocations 0x%x (size=%d):\n",flat->reloc_start,flat_reloc_count*sizeof(reloc_record_t));
    for( i = 0; i< flat_reloc_count; i++)
    {
        print_offs("Offs: ",*(int*)(flat_buf+flat->reloc_start+i*sizeof(reloc_record_t)), "\n");
    }

    printf("\nDump imports 0x%x (size=%d):\n",flat->import_start,new_import_cnt*sizeof(uint32_t));
    for (i = 0; i< new_import_cnt;)
    {
        uint32_t idx = new_import_buf[i++];
        int cnt = new_import_buf[i] >> 24;
        int j;
        for (j=0; j<cnt; j++)
        {
            uint32_t offs = new_import_buf[i++] & 0x00FFFFFF;
            print_offs((j==0)?"Offs: ":"      ",offs,"");
		    int addend = *(uint32_t*)(flat_buf+offs);
		    printf(" = sym_%08x[%s]+0x%x\n",idx,get_import_symbol(idx),addend);
        }
    }
  }

  int filesize = flat->file_size;

  printf("\n\nOutput file %s (size=%d bytes)\n",fltfile,filesize);

  int output_fd = open(fltfile,O_WRONLY|O_CREAT|O_TRUNC|O_BINARY,0777);
  i = write(output_fd, flat_buf, flat->import_start);
  i = write(output_fd, new_import_buf, new_import_cnt*sizeof(uint32_t));
  close(output_fd);

  return ELFFLT_OK;
}