예제 #1
0
파일: trace.c 프로젝트: ChrisG0x20/gdb
int
msp430_get_current_source_location (int mypc,
				    const char **  pfilename,
				    const char **  pfunctionname,
				    unsigned int * plineno)
{
  static int   initted = 0;

  if (current_bfd == NULL)
    {
      printf("no bfd\n");
      return 0;
    }

  if (!initted)
    {
      int storage;
      asection * s;

      initted = 1;
      memset (& info, 0, sizeof (info));
      INIT_DISASSEMBLE_INFO (info, stdout, op_printf);
      info.read_memory_func = sim_dis_read;
      info.arch = bfd_get_arch (current_bfd);
      info.mach = bfd_get_mach (current_bfd);
      if (info.mach == 0)
	info.arch = bfd_arch_msp430;

      disassemble_init_for_target (& info);

      storage = bfd_get_symtab_upper_bound (current_bfd);
      if (storage > 0)
	{
	  symtab = (asymbol **) xmalloc (storage);
	  symcount = bfd_canonicalize_symtab (current_bfd, symtab);
	  symcount = remove_useless_symbols (symtab, symcount);
	  qsort (symtab, symcount, sizeof (asymbol *), compare_symbols);
	}

      for (s = current_bfd->sections; s; s = s->next)
	{
	  if (s->flags & SEC_CODE || code_section == 0)
	    {
	      code_section = s;
	      code_base = bfd_section_lma (current_bfd, s);
	      break;
	    }
	}
    }

  *pfilename = *pfunctionname = NULL;
  *plineno = 0;

  bfd_find_nearest_line
    (current_bfd, code_section, symtab, mypc - code_base,
     pfilename, pfunctionname, plineno);

  return 1;
}
예제 #2
0
파일: trace.c 프로젝트: bminor/binutils-gdb
void
sim_disasm_one (void)
{
  static int initted = 0;
  static asymbol **symtab = 0;
  static int symcount = 0;
  static int last_sym = -1;
  static struct disassemble_info info;
  int storage, sym, bestaddr;
  int min, max, i;
  static asection *code_section = 0;
  static bfd_vma code_base = 0;
  asection *s;
  int save_trace = trace;

  static const char *prev_filename = "";
  static int prev_lineno = 0;
  const char *filename;
  const char *functionname;
  unsigned int lineno;

  int mypc = get_reg (pc);

  if (current_bfd == 0)
    return;

  trace = 0;

  if (!initted)
    {
      initted = 1;
      memset (&info, 0, sizeof (info));
      INIT_DISASSEMBLE_INFO (info, stdout, op_printf);
      info.read_memory_func = sim_dis_read;
      info.arch = bfd_get_arch (current_bfd);
      info.mach = bfd_get_mach (current_bfd);
      if (info.mach == 0)
	{
	  info.arch = bfd_arch_m32c;
	  info.mach = default_machine;
	}
      disassemble_init_for_target (&info);

      storage = bfd_get_symtab_upper_bound (current_bfd);
      if (storage > 0)
	{
	  symtab = (asymbol **) malloc (storage);
	  symcount = bfd_canonicalize_symtab (current_bfd, symtab);
	  symcount = remove_useless_symbols (symtab, symcount);
	  qsort (symtab, symcount, sizeof (asymbol *), compare_symbols);
	}
      for (s = current_bfd->sections; s; s = s->next)
	{
	  if (s->flags & SEC_CODE || code_section == 0)
	    {
	      code_section = s;
	      code_base = bfd_section_lma (current_bfd, s);
	      break;
	    }
	}
    }

  filename = functionname = 0;
  lineno = 0;
  if (bfd_find_nearest_line
      (current_bfd, code_section, symtab, mypc - code_base, &filename,
       &functionname, &lineno))
    {
      if (filename && functionname && lineno)
	{
	  if (lineno != prev_lineno || strcmp (prev_filename, filename))
	    {
	      char *the_line = load_file_and_line (filename, lineno);
	      const char *slash = strrchr (filename, '/');
	      if (!slash)
		slash = filename;
	      else
		slash++;
	      printf
		("========================================"
		 "=====================================\n");
	      printf ("\033[37;41m %s:%d: \033[33;40m %s\033[K\033[0m\n",
		      slash, lineno, the_line);
	    }
	  prev_lineno = lineno;
	  prev_filename = filename;
	}
    }

  {
    min = -1;
    max = symcount;
    while (min < max - 1)
      {
	bfd_vma sa;
	sym = (min + max) / 2;
	sa = bfd_asymbol_value (symtab[sym]);
	/*printf("checking %4d %08x %s\n",
	   sym, sa, bfd_asymbol_name (symtab[sym])); */
	if (sa > mypc)
	  max = sym;
	else if (sa < mypc)
	  min = sym;
	else
	  {
	    min = sym;
	    break;
	  }
      }
    if (min != -1 && min != last_sym)
      {
	bestaddr = bfd_asymbol_value (symtab[min]);
	printf ("\033[43;30m%s", bfd_asymbol_name (symtab[min]));
	if (bestaddr != mypc)
	  printf ("+%d", mypc - bestaddr);
	printf (":\t\t\t\033[0m\n");
	last_sym = min;
#if 0
	if (trace == 1)
	  if (strcmp (bfd_asymbol_name (symtab[min]), "abort") == 0
	      || strcmp (bfd_asymbol_name (symtab[min]), "exit") == 0)
	    trace = 0;
#endif
      }
  }

  opbuf[0] = 0;
  printf ("\033[33m%06x: ", mypc);
  max = print_insn_m32c (mypc, &info);
  for (i = 0; i < max; i++)
    printf ("%02x", mem_get_qi (mypc + i));
  for (; i < 6; i++)
    printf ("  ");
  printf ("%-16s  ", opbuf);

  printf ("\033[0m\n");
  trace = save_trace;
}
예제 #3
0
vine_symbols_t * get_symbols_of_file(const char *filename)
{
    asymbol** syms = NULL;
    long symcount = 0;
    long sorted_symcount = 0;
    asymbol** dynsyms = NULL;
    long dynsymcount = 0;

    asymbol* synthsyms = NULL;
    long synthcount = 0;
    long storage;

    vector<vine_symbol_t *> *ret = new vector<vine_symbol_t *>();

//     asm_program_t *prog = new asm_program_t;
//     printf("initializing bfd\n\n");
    bfd *abfd = initialize_bfd(filename);
//     printf("done\n\n");
//     printf("initializing sections...\n\n");
//     initialize_sections(abfd, prog);
//     printf("done\n\n");
    asymbol *sym;

    if (bfd_get_file_flags (abfd) & HAS_SYMS) {
	storage = bfd_get_symtab_upper_bound (abfd);


	assert (storage >= 0);
	if (storage > 0)
	    syms = (asymbol**) xmalloc(storage);
	symcount = bfd_canonicalize_symtab (abfd, syms);
	assert (symcount >= 0);
	sorted_symcount = remove_useless_symbols(syms, symcount);
	qsort(syms, sorted_symcount, sizeof(asymbol *), compare_symbols);
	for(int i= 0; i < sorted_symcount; i++){
	  vine_symbol_t *temp = new vine_symbol_t;
	  temp->name = string(bfd_asymbol_name((syms[i])));

	  temp->addr = bfd_asymbol_value((syms[i]));
	  sym = syms[i];
	  temp->is_function = (sym->flags & BSF_FUNCTION) != 0;
	  temp->is_dynamic = 0;
	  ret->push_back(temp);
	}
    }

    storage = bfd_get_dynamic_symtab_upper_bound (abfd);

    if (storage > 0) {
	dynsyms = (asymbol**) xmalloc(storage);
	dynsymcount = bfd_canonicalize_dynamic_symtab (abfd, dynsyms);
    }


    synthcount = bfd_get_synthetic_symtab (abfd, symcount, syms,
					   dynsymcount, dynsyms, &synthsyms);
    if (synthcount < 0)
        synthcount = 0;

    for (int i=0; i<synthcount; i++) {
      vine_symbol_t *temp = new vine_symbol_t;
      temp->name = string(bfd_asymbol_name(&(synthsyms[i])));
      temp->addr = bfd_asymbol_value(&(synthsyms[i]));

      temp->is_function = (synthsyms[i].flags & BSF_FUNCTION) != 0;
      temp->is_dynamic = 1;
      ret->push_back(temp);
    }
    if (synthsyms)
	free(synthsyms);
    if (dynsyms)
	free(dynsyms);
    if (syms)
    free(syms);
    bfd_close(abfd);
    return ret;
}
예제 #4
0
map<address_t, asm_function_t *>
identify_functions(const map<address_t, section_t *> sections, bfd *abfd)
{
  map<address_t, asm_function_t *> funcs;
  //set<asm_function_t *> funcs;
  long storage_needed;
  asymbol **symtbl;
  long symcount, sorted_symcount;
  /* 
     We could identify function boundries in stripped binaries by
     looking for the function prologue. TBD.
   */ 
  if(!(bfd_get_file_flags(abfd) & HAS_SYMS)){
    return get_stripped_binary_functions( abfd);
    //fatal("identify_functions", 
	  //"No support for stripped binaries (yet)");
  }

  //assert(bfd_get_flavour(abfd) == bfd_target_elf_flavour);
  /*
    instead of handling only elf format binary, allow other types 
    with a warning -- pongsin
  */
  if (bfd_get_flavour(abfd) != bfd_target_elf_flavour)
      cerr << "Warning! The binary is not in ELF format. " 
	   << "Other formats haven't been thoroughly tested."
	   << endl;

  storage_needed = bfd_get_symtab_upper_bound(abfd);
  if(storage_needed <= 0){
    fatal("identify_functions", "symbol table damaged");
  }
  
  symtbl = (asymbol **) xmalloc(storage_needed);
  symcount = bfd_canonicalize_symtab(abfd, symtbl);
  if(symcount <= 0)
    fatal("initialize_symtable", "symbol table damaged");

  sorted_symcount = remove_useless_symbols(symtbl, symcount);
  qsort(symtbl, sorted_symcount, sizeof(asymbol *), compare_symbols);
  
  long i, place;
  asymbol *sym, *nextsym;

  for(i = 0; i < sorted_symcount; i++){
    sym = symtbl[i];
    /*    if(sym->name != NULL){
      printf("name: %s %u F:%x\n", sym->name, sym->flags & BSF_FUNCTION,
    sym->flags);
    } */
    if(sym->flags & BSF_FUNCTION){
      asm_function_t *f = new asm_function_t;
      f->start_addr = sym->section->vma + sym->value;
      f->name = sym->name;
      //      memcpy(&(s->symbol), sym, sizeof(asymbol));
      place = i;
      // FIXME: this still doesn't do the right thing for _init on ARM
      // also, this doesn't work for the last symbol
      while(place < sorted_symcount && (bfd_asymbol_value(sym) >=
				bfd_asymbol_value(symtbl[place])) )
	place++;
      nextsym = symtbl[place];

      // FIXME: We could approximate end_addr better, eg, by looking at where
      // the section ends.
      /* end addrress is approximation. the last valid address
	 may be before this value */
      f->end_addr =  nextsym->value + nextsym->section->vma;

      //bfd_symbol_info(sym, &(s->info));
      // end_addr so far is really the start_addr of the next function
      // subtract one if possible.
      if(f->end_addr != f->start_addr)
	f->end_addr--;
      
      if(funcs.find(f->start_addr) != funcs.end()){
	asm_function_t *old = funcs[f->start_addr];
	// Replace old functions with the new one if the new
	// one is bigger.
	if( (f->end_addr - f->start_addr) >
	    (old->end_addr - old->start_addr)){
	  funcs[f->start_addr] =  f;
	}
      } else {
	funcs[f->start_addr] = f;
      }
    }
  }
   free(symtbl);  
   return funcs;
}