Esempio n. 1
0
/*
** Utility routine: bfd_pic30_report_memory_sections()
**
** - show memory usage of sections in user-defined regions
*/ 
static void
bfd_pic30_report_memory_sections (const char *region, asection *sect,
                                  FILE *fp) {
  file_ptr start = sect->vma;
  unsigned int opb = bfd_octets_per_byte (output_bfd);
  bfd_size_type total = sect->_raw_size / opb; /* ignore phantom bytes */

  if (PIC30_IS_MEMORY_ATTR(sect)) {
    const char *c1, *c2;
    struct pic30_section *s;
    unsigned int n;

    /* loop through the list of memory-type sections */
    for (s = user_memory_sections; s != NULL; s = s->next) {
      if (!s->file || !s->sec) continue;
      if (strcmp((char *)s->file, region) != 0) continue;
      
      c1 = (const char *) s->sec;  /* name is stored here! */
      c2 = strchr(c1, '%');        /* avoid the %n terminator */
      n = c2 ? c2 - c1 : strlen(c1);
      if (strncmp(c1, sect->name, n) == 0) {
        char *c, *name = xmalloc(strlen(sect->name) + 1);
        strcpy(name, sect->name);  /* make a local copy of the name */
        c = strchr(name, '%');
        if (c) *c = '\x0';         /* remove the %n terminator */
        
        fprintf(fp, "%-24s%#10lx%#36lx  (%ld)\n", name, start, total, total);
        external_memory_used += total;
        free(name);
        break;
      }
    }
  }
  return;
} /* static void bfd_pic30_report_memory_sections (...)*/
Esempio n. 2
0
/**
 * Obtain data from the .bss section(s).
 * The section(s) are identified by having ALLOC flag but
 * not LOAD nor READONLY flags.
 * The return value is in the form [(address, value),...,...].
 * Note that the value elements will always be zeros.
 * FIXME: Use a reasonable data structure.
 */
memory_data_t *
get_bssdata(asm_program_t *prog) {
    vector<memory_cell_data_t *> *bssdata = new vector<memory_cell_data_t *>();

    bfd *abfd = prog->abfd;

    unsigned int opb = bfd_octets_per_byte(abfd);
    assert(opb == 1);

    for(asection *section = abfd->sections;
        section != (asection *)  NULL; section = section->next){

        if(!(!(section->flags & SEC_READONLY) &&
             (section->flags & SEC_ALLOC) &&
             !(section->flags & SEC_LOAD))
            ) continue;
        bfd_vma datasize = bfd_get_section_size_before_reloc(section);
        if(datasize == 0) continue;
        bfd_vma start_addr = section->vma;
        bfd_vma end_addr = start_addr + datasize/opb;
        for (bfd_vma itr = start_addr; itr < end_addr; itr++) {
            memory_cell_data_t *mcd = (memory_cell_data_t *)
                xalloc((size_t) 1, (size_t) sizeof(memory_cell_data_t));
            mcd->address = itr;
            mcd->value = 0;
            bssdata->push_back(mcd);
        }
    }
    return bssdata;
}
Esempio n. 3
0
struct disassemble_info* new_disasm_info( struct bfd* abfd )
{
    struct disassemble_info *di =
      (struct disassemble_info *) malloc( sizeof(struct disassemble_info) );
    if ( !di )
        error_exit( "failed to allocate disassemble_info" );

    init_disassemble_info( di, stdout, (fprintf_ftype) fprintf );

    di->flavour = bfd_get_flavour( abfd );
    di->arch = bfd_get_arch( abfd );
    di->mach = bfd_get_mach( abfd );
    di->octets_per_byte = bfd_octets_per_byte( abfd );
    di->disassembler_needs_relocs = FALSE;

    di->buffer = NULL;
    di->symtab = NULL;

    if ( bfd_big_endian( abfd ) )
        di->display_endian = di->endian = BFD_ENDIAN_BIG;
    else if ( bfd_little_endian ( abfd ) )
        di->display_endian = di->endian = BFD_ENDIAN_LITTLE;

    disassemble_init_for_target( di );

    return di;
}
Esempio n. 4
0
map<address_t, asm_function_t *>
get_stripped_binary_functions(bfd *abfd)
{
  // For a stripped binary, we  treat an executable section as a
  // function. 
  unsigned int opb = bfd_octets_per_byte(abfd);
  print_debug("warning", "no symbol table. disassembling each section");
  map<address_t, asm_function_t *> ret;
  for(asection *section = abfd->sections; section != (asection *) NULL; 
      section = section->next){
    if(!(section->flags & SEC_CODE)) continue;
    bfd_size_type datasize = 0;
    datasize = bfd_get_section_size_before_reloc (section);
    if (datasize == 0)
      continue;      
    asm_function_t *f = new asm_function_t;
    f->start_addr =  section->vma;
    f->end_addr = section->vma + datasize / opb;
    ostringstream os;
    os << "section_" << hex << section->vma;
    f->name = os.str();
    ret.insert(pair<address_t, asm_function_t *>(f->start_addr, f));
  }
  return ret;
}
Esempio n. 5
0
static void
initialize_sections(asm_program_t *prog, bfd_vma base)
{
  bfd_vma offset = 0;
  struct disassemble_info *disasm_info = &prog->disasm_info;
  assert(prog);
  bfd *abfd = prog->abfd;
  unsigned int opb = bfd_octets_per_byte(abfd);
  disasm_info->octets_per_byte = opb;
  init_disasm_info(prog);
  section_t **nextseg = &prog->segs;
  asection *section;

  /* Set to NULL in case there are zero segments. */
  *nextseg = NULL;

  /* Look for the section loaded into the lowest memory address */
  if (base != -1) {

    offset = base - asmir_get_base_address(prog);
    //fprintf(stderr, "Adjusting by %Lx\n", offset);
  }

  for(section = abfd->sections; section; section = section->next) {
    section_t *seg;
    bfd_byte *data;
    bfd_vma datasize = bfd_get_section_size_before_reloc(section);

    if(datasize == 0) continue;

    section->vma += offset;
    data = bfd_alloc2(abfd, datasize, sizeof(bfd_byte));
    bfd_get_section_contents(abfd, section, data, 0, datasize);
    seg = bfd_alloc(abfd, sizeof(section_t));
    seg->data = data;
    seg->datasize = datasize;
    seg->start_addr = section->vma;
    seg->end_addr = section->vma + datasize/opb;
    seg->section = section;
    seg->is_code = !!(section->flags & SEC_CODE);


    seg->next = NULL;
    *nextseg = seg;
    nextseg = &seg->next;
  }

}
Esempio n. 6
0
static void init_disasm_info(bfd *abfd, struct disassemble_info *disasm_info)
{
    init_disassemble_info (disasm_info, stdout, (fprintf_ftype) fprintf);
    disasm_info->flavour = bfd_get_flavour (abfd);
    disasm_info->arch = bfd_get_arch (abfd);
    disasm_info->mach = bfd_get_mach (abfd);
    disasm_info->octets_per_byte = bfd_octets_per_byte (abfd);
    disasm_info->disassembler_needs_relocs = FALSE;

    if (bfd_big_endian (abfd))
        disasm_info->display_endian = disasm_info->endian = BFD_ENDIAN_BIG;
    else if (bfd_little_endian (abfd))
        disasm_info->display_endian = disasm_info->endian = BFD_ENDIAN_LITTLE;

    disassemble_init_for_target(disasm_info);
    disasm_info->read_memory_func = my_read_memory;
}
Esempio n. 7
0
address_t get_last_segment_address(const char *filename, 
				   address_t addr)
{
  bfd *abfd = initialize_bfd(filename);
  unsigned int opb = bfd_octets_per_byte(abfd);

  address_t ret = addr;
  for(asection *section = abfd->sections; 
      section != (asection *)  NULL; section = section->next){

    bfd_vma datasize = bfd_get_section_size_before_reloc(section);
    if(datasize == 0) continue;

    address_t start = section->vma;
    address_t end = section->vma + datasize/opb;
    if(addr >= start && addr <= end)
      return end;
  }
  return ret;
}
Esempio n. 8
0
void init_disasm_info(bfd *abfd, struct disassemble_info *disasm_info)
{
  init_disassemble_info (disasm_info, stdout, (fprintf_ftype) fprintf);
  disasm_info->flavour = bfd_get_flavour (abfd);
  disasm_info->arch = bfd_get_arch (abfd);
  disasm_info->mach = bfd_get_mach (abfd);
  //disasm_info->disassembler_options = disassembler_options;
  disasm_info->octets_per_byte = bfd_octets_per_byte (abfd);
  //disasm_info->skip_zeroes = DEFAULT_SKIP_ZEROES;
  //disasm_info->skip_zeroes_at_end = DEFAULT_SKIP_ZEROES_AT_END;
  disasm_info->disassembler_needs_relocs = FALSE;

  if (bfd_big_endian (abfd))
    disasm_info->display_endian = disasm_info->endian = BFD_ENDIAN_BIG;
  else if (bfd_little_endian (abfd))
    disasm_info->display_endian = disasm_info->endian = BFD_ENDIAN_LITTLE;

  disassemble_init_for_target(disasm_info);

  disasm_info->read_memory_func = my_read_memory;
}
Esempio n. 9
0
/*
** Utility routine: bfd_pic30_report_data_sections()
*/ 
static void
bfd_pic30_report_data_sections (asection *sect, FILE *fp) {
  file_ptr start = sect->vma;
  unsigned int opb = bfd_octets_per_byte (output_bfd);
  bfd_size_type total = sect->_raw_size / opb; /* ignore phantom bytes */

  if (REPORT_AS_DATA(sect))
    {
      unsigned int gaps;
      char *name, *c;
      struct bfd_link_hash_entry *h = (struct bfd_link_hash_entry *) NULL;

      /* make a local copy of the name */
      name = xmalloc(strlen(sect->name) + strlen(GAP_ID) + 1);
      strcpy(name, sect->name);

      strcat(name, GAP_ID);
      h = bfd_link_hash_lookup (link_info.hash, name, FALSE, FALSE, TRUE);

      if (h == (struct bfd_link_hash_entry *) NULL)
        gaps = 0;
      else
        gaps = h->u.def.value / opb; /* ignore phantom bytes */

      /* clean the name of GAP_ID or %n.GAPID */
      c = strchr(name, '%');
      if (c) *c = '\x0';

      fprintf( fp, "%-24s%#10lx%#20x%#16lx  (%ld)\n", name,
             start, gaps, total, total);
      data_memory_used += total;

      free(name);
    }

  return;
} /* static void bfd_pic30_report_data_sections (...)*/
Esempio n. 10
0
/**
 * Obtain data from the section with readonly flags.
 * I.e. ALLOC, READONLY, and LOAD flags are set.
 * FIXME: Use a reasonable data structure.
 */
memory_data_t *
get_rodata(asm_program_t *prog) {
    vector<memory_cell_data_t *> *rodata = new vector<memory_cell_data_t *>();

    bfd *abfd = prog->abfd;

    unsigned int opb = bfd_octets_per_byte(abfd);
    assert(opb == 1);

    for(asection *section = abfd->sections;
        section != (asection *)  NULL; section = section->next){

        if(!((section->flags & SEC_READONLY) &&
             (section->flags & SEC_ALLOC) &&
             (section->flags & SEC_LOAD))
            ) continue;
        bfd_byte *data = NULL;
        bfd_vma datasize = bfd_get_section_size_before_reloc(section);
        if(datasize == 0) continue;
        data = (bfd_byte *) xalloc((size_t) datasize, (size_t)
                                   sizeof(bfd_byte));
        bfd_get_section_contents(abfd, section, data, 0, datasize);
        bfd_vma start_addr = section->vma;
        bfd_vma end_addr = start_addr + datasize/opb;
        for (bfd_vma itr = start_addr; itr < end_addr; itr++) {
            memory_cell_data_t *mcd = (memory_cell_data_t *)
                xalloc((size_t) 1, (size_t) sizeof(memory_cell_data_t));
            mcd->address = itr;
            mcd->value = data[itr-start_addr];
            rodata->push_back(mcd);
        }
        free(data);
    }
    /* FIXMEO: close the BFD */
    return rodata;
}
Esempio n. 11
0
// FIXME: the memory that gets allocated here is never freed.
void
initialize_sections(bfd *abfd, asm_program_t *prog)
{
  struct disassemble_info *disasm_info = &prog->disasm_info;
  unsigned int opb = bfd_octets_per_byte(abfd);
  disasm_info->octets_per_byte = opb;
  init_disasm_info(prog);
  Segment *segs = NULL;

  for(asection *section = abfd->sections; 
      section != (asection *)  NULL; section = section->next){
    Segment *seg, *ts;

    int is_code = 0;
    bfd_byte *data = NULL;

    bfd_vma datasize = bfd_get_section_size_before_reloc(section);
    if(datasize == 0) continue;

    data = (bfd_byte *) xalloc((size_t) datasize, (size_t)
			       sizeof(bfd_byte));
    bfd_get_section_contents(abfd, section, data, 0, datasize);
    seg = (Segment *) xalloc(1, sizeof(Segment));
    seg->data = data;
    seg->datasize = datasize;
    seg->start_addr = section->vma;
    seg->end_addr = section->vma + datasize/opb;
    seg->section = section;
    if(section->flags & SEC_CODE == 0)
      is_code = 0;
    else
      is_code = 1;
    seg->is_code = is_code;
    if(is_code){
      /*seg->status = (unsigned char *)
	xalloc((seg->end_addr - seg->start_addr), sizeof(char)); */
      /*
      seg->insts = (Instruction **) xalloc((seg->end_addr - 
					    seg->start_addr),
					   sizeof(Instruction *));
       //init_disasm_info(&disasm_info, seg);
      for(bfd_vma pc = seg->start_addr; pc < seg->end_addr; ++pc){
	Instruction *inst = get_inst_of(prog, pc, seg);
	// DJB: Hack for stmxcsr and ldmxcsr instrs as found
	// in atphttpd instr 806a36e
	//if(inst->opcode[0] == 0xae && inst->opcode[1] == 0xf)
	//  inst->length++;
	seg->insts[pc - seg->start_addr] = inst;
      }
      */
      seg->next = NULL;
      if(segs == NULL)
	segs = seg;
      else{
	ts = segs;
	while(ts->next != NULL)
	  ts = ts->next;
	ts->next = seg;
      }
    }
    prog->sections[seg->start_addr] = seg;
  }
  prog->segs = segs;
}
Esempio n. 12
0
void init_disassemble(){
	abfd = malloc(sizeof(bfd));
	init_disassemble_info (&disasm_info, stdout, (fprintf_ftype) fprintf);
	disasm_info.print_address_func = objdump_print_address;
	disasm_info.symbol_at_address_func = objdump_symbol_at_address;

	/*
	 * choose arch infor since we will select different disassemble function.
	 */
	generic_arch_t* arch_instance = get_arch_instance("");
	machine = arch_instance->arch_name;	
	const bfd_arch_info_type *info = bfd_scan_arch (machine);
	if (info == NULL){
        	//fatal (_("Can't use supplied machine %s"), machine);
		printf("Can't use supplied machine %s\n", machine);
		return;
	}

	abfd->arch_info = info;
	
	/*
	 * endian selection
	 */
	if (endian != BFD_ENDIAN_UNKNOWN)
	{
		struct bfd_target *xvec;

		xvec = xmalloc (sizeof (struct bfd_target));
		//memcpy (xvec, abfd->xvec, sizeof (struct bfd_target));
		xvec->byteorder = endian;
		abfd->xvec = xvec;
	}
	/* Get a disassemble function according to the arch and endian of abfd */
	disassemble_fn = disassembler (abfd);
	if(!disassemble_fn)
	{
      /*
	non_fatal (_("Can't disassemble for architecture %s\n"),
                 bfd_printable_arch_mach (bfd_get_arch (abfd), 0));
	*/
		printf("Can't disassemble for architecture %s\n", bfd_printable_arch_mach (bfd_get_arch (abfd), 0));
		exit_status = 1;
		return;
	}

	disasm_info.flavour = bfd_get_flavour (abfd);
	disasm_info.arch = bfd_get_arch (abfd);
	disasm_info.mach = bfd_get_mach (abfd);
	disasm_info.disassembler_options = disassembler_options;
	disasm_info.octets_per_byte = bfd_octets_per_byte (abfd);
	disasm_info.skip_zeroes = DEFAULT_SKIP_ZEROES;
	disasm_info.skip_zeroes_at_end = DEFAULT_SKIP_ZEROES_AT_END;
	disasm_info.disassembler_needs_relocs = FALSE;

#if 1
	if (bfd_big_endian (abfd))
		disasm_info.display_endian = disasm_info.endian = BFD_ENDIAN_BIG;
	else if (bfd_little_endian (abfd))
		disasm_info.display_endian = disasm_info.endian = BFD_ENDIAN_LITTLE;
	else
 /* ??? Aborting here seems too drastic.  We could default to big or little
       instead.  */
	disasm_info.endian = BFD_ENDIAN_UNKNOWN;
#endif
	/* set the default endianess is BFD_ENDIAN_LITTLE */
	disasm_info.display_endian = disasm_info.endian = BFD_ENDIAN_LITTLE;
	disasm_info.symtab = sorted_syms;
	disasm_info.symtab_size = sorted_symcount;
	disasm_info.read_memory_func = disasm_read_memory;
	free (sorted_syms);
}
Esempio n. 13
0
uv_err_t UVDBfdInstructionIterator::init() {
    bfd *a_bfd = NULL;

    uv_assert_ret(m_obj);
    uv_assert_ret(m_obj->m_bfd);
    a_bfd = m_obj->m_bfd;

    //Needs to be an object or an archive
    if( !bfd_check_format(a_bfd, bfd_object)
            && !bfd_check_format(a_bfd, bfd_archive) )
    {
        //bfd_close(a_bfd);
        printf("bad file\n");
        return UV_DEBUG(UV_ERR_GENERAL);
    }
    printf("BFD open and is object\n");

    /*
    Standard disassemblers.  Disassemble one instruction at the given
    target address.  Return number of octets processed.
    typedef int (*disassembler_ftype) (bfd_vma, disassemble_info *);
    */
    g_disassembler_function = disassembler(a_bfd);
    if( !g_disassembler_function ) {
        printf("failed \n");
        return UV_DEBUG(UV_ERR_GENERAL);
    }

    memset(&m_disasm_info, 0, sizeof(m_disasm_info));
    init_disassemble_info(&m_disasm_info, stdout, (fprintf_ftype) fprintf);
    m_disasm_info.flavour = bfd_get_flavour (a_bfd);
    m_disasm_info.arch = bfd_get_arch (a_bfd);
    m_disasm_info.mach = bfd_get_mach (a_bfd);
    m_disasm_info.disassembler_options = NULL;
    m_disasm_info.octets_per_byte = bfd_octets_per_byte(a_bfd);
    m_disasm_info.skip_zeroes = 0;
    m_disasm_info.skip_zeroes_at_end = 0;
    m_disasm_info.disassembler_needs_relocs = FALSE;
    m_disasm_info.display_endian = m_disasm_info.endian = BFD_ENDIAN_BIG;

    //Don't care
    m_disasm_info.application_data = NULL;
    m_disasm_info.print_address_func = objdump_print_address;
    m_disasm_info.symbol_at_address_func = objdump_symbol_at_address;

    disassemble_init_for_target(&m_disasm_info);

    //Wonder if these can be NULL?
    m_disasm_info.symtab = NULL;
    m_disasm_info.symtab_size = 0;

    /*
    This won't work since we want to step on our own accord
    bfd_map_over_sections(a_bfd, disassemble_section, &disasm_info);
    */
#if 0
    void
    bfd_map_over_sections (bfd *abfd,
                           void (*operation) (bfd *, asection *, void *),
                           void *user_storage)
    {
        asection *sect;
        unsigned int i = 0;

        for (sect = abfd->sections; sect != NULL; i++, sect = sect->next)
            (*operation) (abfd, sect, user_storage);

        if (i != abfd->section_count)	/* Debugging */
            abort ();
    }
Esempio n. 14
0
/**
 * Get length of instruction at the current PC.
 *
 * @param value      the PC value.
 *
 * @return  length of instruction at PC address.
 *
 * @ingroup RuntimeAPI
 */
int CBTF_GetInstrLength(uint64_t pcvalue)
{
//fprintf(stderr, "ENTERED CBTF_GetInstrLength\n");
#if defined(__linux) && (defined(__i386) || defined(__x86_64))
    
    disassemble_info   disinfo;
    disassembler_ftype disassemble_fn;

    initdisassembler();

//fprintf(stderr, "CBTF_GetInstrLength CALLS INIT_DISASSEMBLE_INFO\n");
    INIT_DISASSEMBLE_INFO(disinfo, stdout, fprintf);

    disinfo.flavour = bfd_get_flavour (abfd);
    disinfo.arch = bfd_get_arch (abfd);
    //disinfo.mach = bfd_get_mach (abfd);
    disinfo.mach = bfd_mach_i386_i386;
    disinfo.octets_per_byte = bfd_octets_per_byte (abfd);
    if (bfd_big_endian (abfd))
      disinfo.display_endian = disinfo.endian = BFD_ENDIAN_BIG;
    else if (bfd_little_endian (abfd))
      disinfo.display_endian = disinfo.endian = BFD_ENDIAN_LITTLE;
    else
      disinfo.endian = BFD_ENDIAN_UNKNOWN;
    disinfo.buffer_length = 8;

    unsigned char* ptr = (unsigned char*) pcvalue;

    disinfo.buffer_vma = pcvalue;
    disinfo.buffer = ptr;
    disinfo.fprintf_func=(fprintf_ftype) dummyprint;

//fprintf(stderr, "CBTF_GetInstrLength CALLS print_insn_i386 with addr %#lx\n",pcvalue);
    int insbytes = print_insn_i386(pcvalue, &disinfo);

//fprintf(stderr,"CBTF_GetInstrLength returns length %d\n",insbytes);
    return insbytes;

#elif defined(__linux) && defined(__powerpc__)

    /*
       FROM: http://www.ibm.com/developerworks/library/l-ppc/
       All PowerPCs (including 64-bit implementations) use fixed-length 32-bit instructions
    */
    return 0x4;


#elif defined(__linux) && defined(__powerpc64__)
    /*
       FROM: http://www.ibm.com/developerworks/library/l-ppc/
       All PowerPCs (including 64-bit implementations) use fixed-length 32-bit instructions
    */
    return 0x4;


#elif defined(__linux) && defined(__ia64)

    /* IA64 bundles are 128 bits. The caller must find the address
       of the bundle that contains the exception address and
       add this return value to it prior to updating the context PC.
    */
    return 0x10;

#elif defined(__linux) && defined(__aarch64__)
    /*
       FROM: Arm architecture wiki page
       Armv8 (and also including 64-bit implementations) use fixed-length 32-bit instructions
    */
    return 0x4;

#elif defined(__linux) && defined(__arm__)
    /*
       FROM: Arm architecture wiki page
       Armv7 (and also including 64-bit implementations) use fixed-length 32-bit instructions
    */
    return 0x4;


#else
#error "Platform/OS Combination Unsupported!"
#endif
}