Exemple #1
0
bfd_vma
bfd_coff_reloc16_get_value (arelent *reloc,
			    struct bfd_link_info *link_info,
			    asection *input_section)
{
  bfd_vma value;
  asymbol *symbol = *(reloc->sym_ptr_ptr);
  /* A symbol holds a pointer to a section, and an offset from the
     base of the section.  To relocate, we find where the section will
     live in the output and add that in.  */

  if (bfd_is_und_section (symbol->section)
      || bfd_is_com_section (symbol->section))
    {
      struct bfd_link_hash_entry *h;

      /* The symbol is undefined in this BFD.  Look it up in the
	 global linker hash table.  FIXME: This should be changed when
	 we convert this stuff to use a specific final_link function
	 and change the interface to bfd_relax_section to not require
	 the generic symbols.  */
      h = bfd_wrapped_link_hash_lookup (input_section->owner, link_info,
					bfd_asymbol_name (symbol),
					FALSE, FALSE, TRUE);
      if (h != (struct bfd_link_hash_entry *) NULL
	  && (h->type == bfd_link_hash_defined
	      || h->type == bfd_link_hash_defweak))
	value = (h->u.def.value
		 + h->u.def.section->output_section->vma
		 + h->u.def.section->output_offset);
      else if (h != (struct bfd_link_hash_entry *) NULL
	       && h->type == bfd_link_hash_common)
	value = h->u.c.size;
      else if (h != (struct bfd_link_hash_entry *) NULL
	       && h->type == bfd_link_hash_undefweak)
	/* This is a GNU extension.  */
	value = 0;
      else
	{
	  if (!((*link_info->callbacks->undefined_symbol)
		(link_info, bfd_asymbol_name (symbol),
		 input_section->owner, input_section, reloc->address,
		 TRUE)))
	    abort ();
	  value = 0;
	}
    }
  else
    {
      value = symbol->value
	+ symbol->section->output_offset
	+ symbol->section->output_section->vma;
    }

  /* Add the value contained in the relocation.  */
  value += reloc->addend;

  return value;
}
Exemple #2
0
uv_err_t UVDBFDPatSection::setFunctionSizes()
{
	//Functions were sorted into modules, but we need a contiguous list to determine sizes
	std::vector<UVDBFDPatFunction *> allSectionFunctions;
	int sectionSize = 0;

	for( std::vector<UVDBFDPatModule *>::iterator iter = m_modules.begin();
			iter != m_modules.end(); ++iter )
	{
		UVDBFDPatModule *module = *iter;
		
		uv_assert_ret(module);
		//std::vector<UVDBFDPatFunction *> m_functions
		allSectionFunctions.insert(allSectionFunctions.end(), module->m_functions.begin(), module->m_functions.end());
	}

	sectionSize = bfd_section_size(m_core->m_bfd, m_section);
	//Iterate over all functions within that section
	for( std::vector<UVDBFDPatFunction *>::iterator iter = allSectionFunctions.begin(); iter != allSectionFunctions.end(); )
	{
		UVDBFDPatFunction *function = NULL;
		std::vector<UVDBFDPatFunction *>::iterator iterStart = iter;
		
		/*
		What if we have a 0 sized symbol in the section?
			Special case: symbol is at the end of the section
		*/
		do
		{
			function = *iter;
			++iter;
			//Get the next size
			//Did we reach the section end?
			if( iter == allSectionFunctions.end() )
			{
				function->m_size = sectionSize - function->m_offset;
				//Even if we still have 0 size, we need to break
				break;
			}
			else
			{
				UVDBFDPatFunction *functionNext = NULL;
			
				functionNext = *iter;
				function->m_size = functionNext->m_offset - function->m_offset;
			}
		}
		while( function->m_size == 0 );
		
		//And set any previously skipped elements from same symbol position
		while( iterStart != iter )
		{
			(*iterStart)->m_size = function->m_size;
			++iterStart;
		}
		
		printf_flirt_debug("early func size %s is 0x%04X\n", bfd_asymbol_name(function->m_bfdAsymbol), function->m_size);
	}
	return UV_ERR_OK;
}
Exemple #3
0
static
long get_sym_offset(char *filename, char *sym) {
    bfd *objfile;
    size_t symtabsize, numsyms, i;
    long offset = -1;
    asymbol **symtab = 0;

    objfile = bfd_openr(filename, 0);
    if (!objfile) goto bail;
    if (!bfd_check_format(objfile, bfd_object)) goto bail;
    /* Get the symbol table */
    symtabsize = bfd_get_symtab_upper_bound(objfile);
    symtab = (asymbol **) malloc (symtabsize);
    if (!symtab) {
	fprintf(stderr, "Out of memory.\n");
	exit(1);
    }
    numsyms = bfd_canonicalize_symtab(objfile, symtab);
    /* Walk the symbol table */
    for (i=0; i < numsyms; i++)
	if (strcmp(bfd_asymbol_name(symtab[i]),sym)==0) {
	    offset = symtab[i]->value + symtab[i]->section->filepos;
	    break;
	}
 bail:
    if (objfile) bfd_close(objfile);
    if (symtab)  free(symtab);
    return offset;
}
Exemple #4
0
void dump_symbols(const char *filename){
	bfd *abfd;
	asymbol *store;
	char *p;
	void *minisyms;
	int symnum,i;
	size_t size;
	int dyn=0;
	int ret;

	abfd=bfd_openr(filename,NULL);
	assert(abfd);
	ret=bfd_check_format(abfd,bfd_object);
	assert(ret);
	if(!(bfd_get_file_flags(abfd)&& HAS_SYMS)){
		bfd_close(abfd);
		return;
	}
	store = bfd_make_empty_symbol(abfd);
	symnum = bfd_read_minisymbols(abfd,dyn,&minisyms,&size);
	assert(symnum>=0);
	p=(char *)minisyms;
	for(i=0;i<symnum;i++){
		asymbol *sym = bfd_minisymbol_to_symbol(abfd,dyn,p,store);
		const char *name = bfd_asymbol_name(sym);
		int value = bfd_asymbol_value(sym);
		printf("%08x %s\n",value,name);
		p+=size;
	}
	free(store);
	free(minisyms);
	bfd_close(abfd);
}
Exemple #5
0
bool keepSymbol(bfd* abfd, asymbol* sym)
{
    if (sym->flags & BSF_DEBUGGING) return false;
    if (bfd_is_target_special_symbol(abfd, sym)) return false;
    if (strncmp(bfd_asymbol_name(sym), ".LANCHOR", 8) == 0) return false;

    return true;
}
int find_symbol_maxcnt (asymbol **symtab, char *name, int max_idx) {
    int i;
    for (i = 0; (symtab[i] != NULL) && (i < max_idx); i++) {
	if (strcmp(bfd_asymbol_name(symtab[i]), name) == 0) {
	    return i;
	}
    }
    return -1;
}
/* utility function to look up a symbol by its name */
int find_symbol (asymbol **symtab, char *name) {
    int i;
    for (i = 0; symtab[i] != NULL; i++) {
	if (strcmp(bfd_asymbol_name(symtab[i]), name) == 0) {
	    return i;
	}
    }
    return -1;
}
Exemple #8
0
static int
elf_read_symbols(elf_reader_t *reader, const char *path, elfread_src_t srcsec)
{
    int i, nsymbols, nfiltered, iflt;
    size_t storage_needed;

    reader->__abfd = bfd_openr(path, NULL);
    if (!reader->__abfd)
        return -1;

    bfd_check_format(reader->__abfd, bfd_object);
    storage_needed = (srcsec == READSYMBOLS_TEXT) ? 
        bfd_get_symtab_upper_bound(reader->__abfd) :
        bfd_get_dynamic_symtab_upper_bound(reader->__abfd);

    if (storage_needed <= 0) {
        return -1;
    }
    
    reader->__symbol_table = (asymbol**)malloc(storage_needed);
    if (!reader->__symbol_table)
        return -1;

    nsymbols = (srcsec == READSYMBOLS_TEXT) ? 
        bfd_canonicalize_symtab(reader->__abfd, reader->__symbol_table) : 
        bfd_canonicalize_dynamic_symtab(reader->__abfd, reader->__symbol_table);

    if (nsymbols < 0)
        return -1;

    nfiltered = 0;
    for (i = 0; i < nsymbols; i++) {
        if (reader->__symbol_table[i]->flags & (BSF_FUNCTION | BSF_GLOBAL))
            nfiltered++;
    }

    reader->symbols = (elf_symbol_t *)malloc(nfiltered * sizeof(elf_symbol_t));
    if (!reader->symbols)
        return -1;

    for (i = 0, iflt = 0; i < nsymbols && iflt < nfiltered; i++) {
        asymbol *is = reader->__symbol_table[i];

        if (is->flags & (BSF_FUNCTION | BSF_GLOBAL)) {
            elf_symbol_t *os = reader->symbols + iflt++;
            os->symbol_name   = (const char *)bfd_asymbol_name(is);
            os->symbol_value  = bfd_asymbol_value(is);
            os->symbol_size   = BFD_GET_SYMBOL_SIZE(is);
            os->symbol_class  = (char)bfd_decode_symclass(is);
        }
    }

    assert(iflt == nfiltered);
    return iflt;
}
/* Get the memory bank parameters by looking at the global symbols
   defined by the linker.  */
static int
sim_get_bank_parameters (SIM_DESC sd, bfd* abfd)
{
  sim_cpu *cpu;
  long symsize;
  long symbol_count, i;
  unsigned size;
  asymbol** asymbols;
  asymbol** current;

  cpu = STATE_CPU (sd, 0);

  symsize = bfd_get_symtab_upper_bound (abfd);
  if (symsize < 0)
    {
      sim_io_eprintf (sd, "Cannot read symbols of program");
      return 0;
    }
  asymbols = (asymbol **) xmalloc (symsize);
  symbol_count = bfd_canonicalize_symtab (abfd, asymbols);
  if (symbol_count < 0)
    {
      sim_io_eprintf (sd, "Cannot read symbols of program");
      return 0;
    }

  size = 0;
  for (i = 0, current = asymbols; i < symbol_count; i++, current++)
    {
      const char* name = bfd_asymbol_name (*current);

      if (strcmp (name, BFD_M68HC11_BANK_START_NAME) == 0)
        {
          cpu->bank_start = bfd_asymbol_value (*current);
        }
      else if (strcmp (name, BFD_M68HC11_BANK_SIZE_NAME) == 0)
        {
          size = bfd_asymbol_value (*current);
        }
      else if (strcmp (name, BFD_M68HC11_BANK_VIRTUAL_NAME) == 0)
        {
          cpu->bank_virtual = bfd_asymbol_value (*current);
        }
    }
  free (asymbols);

  cpu->bank_end = cpu->bank_start + size;
  cpu->bank_shift = 0;
  for (; size > 1; size >>= 1)
    cpu->bank_shift++;

  return 0;
}
Exemple #10
0
static asymbol *lookup_symbol(asymbol ** symbols, int nr_symbols,
			      const char *symbol_name)
{
	int i;

	for (i = 0; i < nr_symbols; i++) {
		asymbol *symbol = symbols[i];

		if (!strcmp(bfd_asymbol_name(symbol), symbol_name))
			return symbol;
	}
	return NULL;
}
Exemple #11
0
/**
 * Obtain the information of dynamic symbol (library call)
 */
dyn_functions_t *get_synthetic_symbols(const char *filename) {
    asymbol** syms = NULL;
    long symcount = 0;
    asymbol** dynsyms = NULL;
    long dynsymcount = 0;
    asymbol* synthsyms = NULL;
    long synthcount = 0;
    long storage;

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

    asm_program_t *prog = new asm_program_t;
    bfd *abfd = initialize_bfd(filename);
    initialize_sections(abfd, prog);
    
    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);
    }

    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) {
	dyn_function_t *temp = new dyn_function_t;
	temp->name = string(bfd_asymbol_name(&(synthsyms[i])));
	temp->addr = bfd_asymbol_value(&(synthsyms[i]));
	ret->push_back(temp);
    }
    if (synthsyms)
	free(synthsyms);
    if (dynsyms)
	free(dynsyms);
    if (syms)
    free(syms);
    bfd_close(abfd);
    return ret;
}
Exemple #12
0
static asymbol *lookup(asymbol **symbols, int nr_symbols, const char *symbol_name)
{
	int i, ret;

	ret = -ENOENT;

	for (i = 0; i < nr_symbols; i++) {
		asymbol *symbol = symbols[i];

		if (!strcmp(bfd_asymbol_name(symbol), symbol_name))
			return symbol;
	}

	return ERR_PTR(ret);
}
Exemple #13
0
/**
 * Load text symbols from the file into supplied table.
 *
 * @param bc		the BFD context pointing to the file
 * @param st		the symbol table where symbols should be added
 */
static void
bfd_util_load_text(bfd_ctx_t *bc, symbols_t *st)
{
	long i;
	asymbol* empty;
	void *p;

	bfd_ctx_check(bc);
	g_assert(st != NULL);

	if (0 == bc->count)
		return;

	mutex_lock_fast(&bc->lock);

	g_assert(bc->symbols != NULL);

	empty = bfd_make_empty_symbol(bc->handle);
	symbols_lock(st);

	for (
		i = 0, p = bc->symbols;
		i < bc->count;
		i++, p = ptr_add_offset(p, bc->symsize)
	) {
		asymbol *sym;
		symbol_info syminfo;

		sym = bfd_minisymbol_to_symbol(bc->handle, bc->dynamic, p, empty);
		bfd_get_symbol_info(bc->handle, sym, &syminfo);

		if ('T' == syminfo.type || 't' == syminfo.type) {
			const char *name = bfd_asymbol_name(sym);

			if (name != NULL && name[0] != '.') {
				void *addr = ulong_to_pointer(syminfo.value);
				symbols_append(st, addr, name);
			}
		}
	}

	symbols_unlock(st);
	mutex_unlock_fast(&bc->lock);
}
Exemple #14
0
/* search symbol */
int get_symbol_pos(const char* symbol_name, bfd* abfd, asymbol** syms, int symnum, char* file_o)
{
  int i;
  int symbol_pos = 0;

  for (i = 0; i < symnum; i++) {
    asymbol *sym = syms[i];
    const char *name = bfd_asymbol_name(sym);
    if (NULL == name || 0 == strlen(name) || '.' == name[0]) continue;
    if (0 == strcmp(name, symbol_name)) {
      LOG("[INFO] %s\n", name);
      int value = bfd_asymbol_value(sym);
      symbol_pos = (int)file_o + abfd->origin + sym->section->filepos + value;
      LOG("Found %s :0x%08X (absolute)\n", name, symbol_pos);
      break;
    }
  }
  return symbol_pos;
}
Exemple #15
0
long locate_dv_func(void) 
{
	asymbol **symbol_table;
	bfd *b = bfd_openr(oracle, NULL);
	if (b == NULL) {
		perror("bfd_openr");
		exit(-1);
	}

	bfd_check_format(b, bfd_object);
	long storage_needed = bfd_get_symtab_upper_bound(b);
	if(storage_needed < 0) {
		fprintf(stderr, "wtf?!\n");
		exit(-1);
	}

	if((symbol_table = (asymbol**)malloc(storage_needed)) == 0) {
		perror("malloc");
		exit(-1);
	}

	int num_symbols;
	if((num_symbols = bfd_canonicalize_symtab(b, symbol_table)) <= 0) {
		fprintf(stderr, "no symbols info\n");
		exit(-1);
	}

	int i;
	for(i = 0; i < num_symbols; i++) {
		char *symname = bfd_asymbol_name(symbol_table[i]);
		void *symaddr = bfd_asymbol_value(symbol_table[i]);
		/* don't even ask why this funciton, for real hardcore: gdb -p <oraclePIDs> */
		if(!strcmp(symname, "kzvtins")) {
			fprintf(stderr, "[%d] symbol \"kzvtins\" at 0x%lx\n", getpid(), 
				(long) symaddr);
			return (long) symaddr;
		}
	}

	return 0;
}
Exemple #16
0
void create_symbol_function_pos(char* file_o, bfd* abfd, asymbol** syms, int symnum)
{
    int i;
    for (i = 0; i < symnum; i++) {
        asymbol *sym = syms[i];
        const char *name = bfd_asymbol_name(sym);
        int value = bfd_asymbol_value(sym);
        symbol_info info;
        if (NULL == name || 0 == strlen(name) || '.' == name[0]) continue;
        LOG("[INFO] %s\n", name);
        bfd_get_symbol_info(abfd, sym, &info);
        /* 定義されたシンボルのみを探す */
        if (!bfd_is_undefined_symclass(info.type)) {
            if (name[0] != '_') {
                int symbol_pos = 0;
                symbol_pos = abfd->origin + sym->section->filepos + value;
                LOG("Found %s :0x%08X (relative), ", name, symbol_pos);
                symbol_pos += (int)file_o;
                LOG("Found %s :0x%08X (absolute)\n", name, symbol_pos);
                add_symbol(name, symbol_pos);
            }
        }
    }
}
SymbolTable::SymbolTable(string path)
{
    //Open the file as binary file descriptor:
    bfd* descr = bfd_openr(path.c_str(), NULL);

    if (!descr)
    {
        throw runtime_error("Failed to open binary file descriptor.");
    }

    //Check the format of the file:
    if (!bfd_check_format(descr, bfd_object))
    {
        bfd_close(descr);
        throw runtime_error("Failed to verify binary format.");
    }

    //Get the size of the symbol table:
    long symbolTableSize = bfd_get_symtab_upper_bound(descr);

    if (symbolTableSize <= 0)
    {
        bfd_close(descr);

        if (symbolTableSize < 0)
        {
            throw runtime_error("Failed to read the upper bound of the symbol table.");
        }
        else
        {
            return;
        }
    }

    //Alloc space for the table:
    asymbol** symbolTable = (asymbol**)malloc(symbolTableSize);

    if (!symbolTable)
    {
        bfd_close(descr);
        throw runtime_error("Failed to allocate space for the symbol table.");
    }

    //Get the number of symbols by canonicalizing the table:
    long symbolTableCount = bfd_canonicalize_symtab(descr, symbolTable);

    if (symbolTableCount < 0)
    {
        bfd_close(descr);
        free(symbolTable);

        throw runtime_error("Failed to read the number of symbols in the symbol table.");
    }

    //Iterate:
    for (int i = 0; i < symbolTableCount; i++)
    {
        //Is there a name?
        if (!symbolTable[i]->name)
        {
            continue;
        }

        //Get the symbol data:
        Symbol* newSymbol = new Symbol(string(bfd_asymbol_name(symbolTable[i])), (pword)bfd_asymbol_value(symbolTable[i]));

        //Check:
        if (!newSymbol)
        {
            throw runtime_error("Failed to allocate space for a symbol.");
        }

        this->table[newSymbol->getName()] = newSymbol;
    }

    //Close the file descriptor and free the table:
    bfd_close(descr);
    free(symbolTable);
}
Exemple #18
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;
}
Exemple #19
0
static bfd_boolean
read_symbol_stabs_debugging_info (bfd *abfd, asymbol **syms, long symcount,
				  void *dhandle, bfd_boolean *pfound)
{
  void *shandle;
  asymbol **ps, **symend;

  shandle = NULL;
  symend = syms + symcount;
  for (ps = syms; ps < symend; ps++)
    {
      symbol_info i;

      bfd_get_symbol_info (abfd, *ps, &i);

      if (i.type == '-')
	{
	  const char *s;
	  char *f;

	  if (shandle == NULL)
	    {
	      shandle = start_stab (dhandle, abfd, FALSE, syms, symcount);
	      if (shandle == NULL)
		return FALSE;
	    }

	  *pfound = TRUE;

	  s = i.name;
	  f = NULL;
	  while (s[strlen (s) - 1] == '\\'
		 && ps + 1 < symend)
	    {
	      char *sc, *n;

	      ++ps;
	      sc = xstrdup (s);
	      sc[strlen (sc) - 1] = '\0';
	      n = concat (sc, bfd_asymbol_name (*ps), (const char *) NULL);
	      free (sc);
	      if (f != NULL)
		free (f);
	      f = n;
	      s = n;
	    }

	  save_stab (i.stab_type, i.stab_desc, i.value, s);

	  if (! parse_stab (dhandle, shandle, i.stab_type, i.stab_desc,
			    i.value, s))
	    {
	      stab_context ();
	      free_saved_stabs ();
	      return FALSE;
	    }

	  /* Don't free f, since I think the stabs code expects
	     strings to hang around.  This should be straightened out.
	     FIXME.  */
	}
    }

  free_saved_stabs ();

  if (shandle != NULL)
    {
      if (! finish_stab (dhandle, shandle))
	return FALSE;
    }

  return TRUE;
}
Exemple #20
0
static debug_type
parse_coff_struct_type (bfd *abfd, struct coff_symbols *symbols,
			struct coff_types *types, int ntype,
			union internal_auxent *pauxent, void *dhandle)
{
  long symend;
  int alloc;
  debug_field *fields;
  int count;
  bfd_boolean done;

  symend = pauxent->x_sym.x_fcnary.x_fcn.x_endndx.l;

  alloc = 10;
  fields = (debug_field *) xmalloc (alloc * sizeof *fields);
  count = 0;

  done = FALSE;
  while (! done
	 && symbols->coff_symno < symend
	 && symbols->symno < symbols->symcount)
    {
      asymbol *sym;
      long this_coff_symno;
      struct internal_syment syment;
      union internal_auxent auxent;
      union internal_auxent *psubaux;
      bfd_vma bitpos = 0, bitsize = 0;

      sym = symbols->syms[symbols->symno];

      if (! bfd_coff_get_syment (abfd, sym, &syment))
	{
	  non_fatal (_("bfd_coff_get_syment failed: %s"),
		     bfd_errmsg (bfd_get_error ()));
	  return DEBUG_TYPE_NULL;
	}

      this_coff_symno = symbols->coff_symno;

      ++symbols->symno;
      symbols->coff_symno += 1 + syment.n_numaux;

      if (syment.n_numaux == 0)
	psubaux = NULL;
      else
	{
	  if (! bfd_coff_get_auxent (abfd, sym, 0, &auxent))
	    {
	      non_fatal (_("bfd_coff_get_auxent failed: %s"),
			 bfd_errmsg (bfd_get_error ()));
	      return DEBUG_TYPE_NULL;
	    }
	  psubaux = &auxent;
	}

      switch (syment.n_sclass)
	{
	case C_MOS:
	case C_MOU:
	  bitpos = 8 * bfd_asymbol_value (sym);
	  bitsize = 0;
	  break;

	case C_FIELD:
	  bitpos = bfd_asymbol_value (sym);
	  bitsize = auxent.x_sym.x_misc.x_lnsz.x_size;
	  break;

	case C_EOS:
	  done = TRUE;
	  break;
	}

      if (! done)
	{
	  debug_type ftype;
	  debug_field f;

	  ftype = parse_coff_type (abfd, symbols, types, this_coff_symno,
				   syment.n_type, psubaux, TRUE, dhandle);
	  f = debug_make_field (dhandle, bfd_asymbol_name (sym), ftype,
				bitpos, bitsize, DEBUG_VISIBILITY_PUBLIC);
	  if (f == DEBUG_FIELD_NULL)
	    return DEBUG_TYPE_NULL;

	  if (count + 1 >= alloc)
	    {
	      alloc += 10;
	      fields = ((debug_field *)
			xrealloc (fields, alloc * sizeof *fields));
	    }

	  fields[count] = f;
	  ++count;
	}
    }

  fields[count] = DEBUG_FIELD_NULL;

  return debug_make_struct_type (dhandle, ntype == T_STRUCT,
				 pauxent->x_sym.x_misc.x_lnsz.x_size,
				 fields);
}
Exemple #21
0
void
sim_disasm_one (void)
{
  static int           last_sym = -1;
  static const char *  prev_filename = "";
  static int           prev_lineno = 0;
  const char *  filename;
  const char *  functionname;
  unsigned int  lineno;
  int           sym, bestaddr;
  int           min, max, i;
  int           save_trace = trace;
  int           mypc = get_reg (pc);

  if (! sim_get_current_source_location (& filename, & functionname, & lineno))
    return;

  trace = 0;

  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;
#ifdef CYCLE_ACCURATE
  printf ("\033[33m %04u %06x: ", (int)(regs.cycle_count % 10000), mypc);
#else
  printf ("\033[33m %06x: ", mypc);

#endif

  max = print_insn_rx (mypc, & info);

  for (i = 0; i < max; i++)
    {
      if (rx_big_endian)
	printf ("%02x", mem_get_qi ((mypc + i) ^ 3));
      else
	printf ("%02x", mem_get_qi (mypc + i));
    }

  do
    {
      printf ("  ");
      i ++;
    }
  while (i < 6);

  printf ("%-16s  ", opbuf);

  printf ("\033[0m\n");
  trace = save_trace;
}
Exemple #22
0
int main(int argc, char *argv[])
{
    bfd *abfd;
    bfd_init();
    abfd = bfd_openr(argv[1], NULL);
    if (abfd == NULL) {
        bfd_perror("bfd_openr");
        exit(1);
    }
    if (! bfd_check_format(abfd, bfd_object)) {
        bfd_perror("bfd_check_format");
    }

    printf("SYMBOL TABLE:\n");
    {
        long storage_needed;
        asymbol **symbol_table;
        long number_of_symbols;
        long i;

        storage_needed = bfd_get_symtab_upper_bound (abfd);

        printf("storage_need=%d\n", storage_needed);

        if (storage_needed < 0) {
            bfd_perror("bfd_get_symtab_upper_bound");
            exit(1);
        }
        if (storage_needed == 0) {
            printf("no symbols\n");
            exit(0);
        }
        symbol_table = (asymbol **)malloc (storage_needed);

        number_of_symbols = bfd_canonicalize_symtab (abfd, symbol_table);
        if (number_of_symbols < 0) {
            bfd_perror("bfd_canonicalize_symtab");
            exit(1);
        }
        for (i = 0; i < number_of_symbols; i++) {
            asymbol *asym = symbol_table[i];
            int symclass = bfd_decode_symclass(asym);
            symbol_info syminfo;
            bfd_symbol_info(asym, &syminfo);
            bfd_print_symbol_vandf(abfd, stdout, asym);
            printf(" 0x%x %s ", symclass,
                   bfd_is_undefined_symclass(symclass) ? "?" : " ");
            printf(" %s ", bfd_asymbol_name(asym));
            printf("%p ", bfd_asymbol_value(asym));

            // printf(" %d ", syminfo.value); /* asymbol_value */
            // printf(" %d ", syminfo.type); /* symclass */
            // printf(" %s ", syminfo.name); /* asymbol_name */
            printf(" %d ", syminfo.stab_type);
            printf(" %d ", syminfo.stab_other);
            printf(" %d ", syminfo.stab_desc);
            // printf(" %s ", syminfo.stab_name);
            printf("\n");
        }
    }
    printf("DYNAMIC SYMBOL TABLE:\n");
    {
        long storage_needed;
        asymbol **symbol_table;
        long number_of_symbols;
        long i;

        storage_needed = bfd_get_dynamic_symtab_upper_bound (abfd);

        printf("storage_need=%d\n", storage_needed);

        if (storage_needed < 0) {
            bfd_perror("bfd_get_symtab_upper_bound");
            exit(1);
        }
        if (storage_needed == 0) {
            printf("no symbols\n");
            exit(0);
        }
        symbol_table = (asymbol **)malloc (storage_needed);

        number_of_symbols = bfd_canonicalize_dynamic_symtab (abfd, symbol_table);
        if (number_of_symbols < 0) {
            bfd_perror("bfd_canonicalize_symtab");
            exit(1);
        }
        for (i = 0; i < number_of_symbols; i++) {
            asymbol *asym = symbol_table[i];
            int symclass = bfd_decode_symclass(asym);
            symbol_info syminfo;
            bfd_symbol_info(asym, &syminfo);
            bfd_print_symbol_vandf(abfd, stdout, asym);
            printf(" 0x%x %s ", symclass,
                   bfd_is_undefined_symclass(symclass) ? "?" : " ");
            printf(" %s ", bfd_asymbol_name(asym));
            printf("%p ", bfd_asymbol_value(asym));

            // printf(" %d ", syminfo.value); /* asymbol_value */
            // printf(" %d ", syminfo.type); /* symclass */
            // printf(" %s ", syminfo.name); /* asymbol_name */
            printf(" %d ", syminfo.stab_type);
            printf(" %d ", syminfo.stab_other);
            printf(" %d ", syminfo.stab_desc);
            // printf(" %s ", syminfo.stab_name);
            printf("\n");
        }
    }
    exit(0);
}
main (int argc, char **argv) {
    bfd *ibfd, *obfd;
    asection *p;
    static asymbol **osympp, **delsympp;
    long symsize, symcount, delsymcount;
    int i;
    int c;
    int idx;
    struct add_reloc_struct *new_reloc;
    struct change_reloc_struct *new_change;
    struct delete_reloc_struct *new_delete;
    struct modify_byte_struct *new_modify;
    struct globalize_sym_struct *new_globalize;

    while ((c = getopt (argc, argv, "a:d:c:m:G:")) != -1) {
	switch (c) {
	    case 'a':
		/* check to see if we have two args: name and loc */
		if ((index(optarg, ',') == NULL) ||
		    (index(optarg, ',') != rindex(optarg, ','))) {
		    fprintf(stderr, "usage: -a argument should be <symbolname>,<location>, not \"%s\"\n", optarg);
		    exit(1);
		}
		/* record the add reloc command in the global array */
		new_reloc = (add_reloc_struct *)malloc(sizeof(add_reloc_struct));
		new_reloc->symbol_name = strndup(optarg, (index(optarg, ',') - optarg));
		new_reloc->loc = strtol(index(optarg, ',') + 1, NULL, 0);
		if (errno == EINVAL) {
		    fprintf(stderr, "the value %s is not a valid location for the add command\n", index(optarg, ',') + 1);
		    exit(1);
		}
		new_reloc->next = additional_relocs;
		additional_relocs = new_reloc;
		break;

	    case 'c':
		/* check to see if we have two args */
		if ((index(optarg, ',') == NULL) ||
		    (index(optarg, ',') != rindex(optarg, ','))) {
		    fprintf(stderr, "usage: -c argument should be <symbolname>,<symbolname>, not \"%s\"\n", optarg);
		    exit(1);
		}
		new_change = (change_reloc_struct *)malloc(sizeof(change_reloc_struct));
		new_change->old_symbol_name = strndup(optarg, strlen(optarg) - strlen(index(optarg, ',')));
		new_change->new_symbol_name = strdup(index(optarg, ',') + 1);
		new_change->next = change_relocs;
		change_relocs = new_change;
		break;

	    case 'd':
		new_delete = (delete_reloc_struct *)malloc(sizeof(delete_reloc_struct));
		new_delete->symbol_name = strdup(optarg);
		new_delete->next = delete_relocs;
		delete_relocs = new_delete;
		break;

	    case 'm':
		if ((index(optarg, '=') == NULL) ||
		    (index(optarg, '=') != rindex(optarg, '='))) {
		    fprintf(stderr, "usage: -m argument should be <location>=<value>, not \"%s\"\n", optarg);
		    exit(1);
		}
		new_modify = (modify_byte_struct *)malloc(sizeof(modify_byte_struct));
		new_modify->location = strtol(optarg, NULL, 0);
		new_modify->value = strtol(index(optarg, '=') + 1, NULL, 0);
		if (new_modify->value > 0xff) {
		    fprintf(stderr, "requested modify value %lx for location %lx exceeds 0xff\n",
			    new_modify->value, new_modify->location);
		    exit(1);
		}
		new_modify->next = modify_bytes;
		modify_bytes = new_modify;
		break;

	    case 'G':
		new_globalize = (globalize_sym_struct *)malloc(sizeof(globalize_sym_struct));
		new_globalize->symbol_name = strdup(optarg);
		new_globalize->next = globalize_syms;
		globalize_syms = new_globalize;
		break;

	    default:
		fprintf(stderr, "unrecognized argument character |%c|\n", c);
	}
    }

    if ((argc - optind) != 2) {
	fprintf(stderr, "usage: fixup_relocs [-a newsymbol,location] [-c oldsymbol,newsymbol] [-d symbol] infile.o outfile.o\n");
	exit(1);
    }

    ibfd = bfd_openr(argv[optind], NULL);
    if (ibfd == NULL) {
	bfd_perror("while opening input object file");
	exit(1);
    }

    /* if I don't do "check_format", there's no data in the bfd object.  wtf? */
    if (!bfd_check_format(ibfd, bfd_object)) {
	fprintf(stderr, "input file %s seems to NOT be an object file! exiting.\n", argv[optind]);
	exit(1);
    }

    obfd = bfd_openw(argv[optind+1], bfd_get_target(ibfd));
    if (obfd == NULL) {
	bfd_perror("while opening output object file");
	exit(1);
    }

    if (!bfd_set_format(obfd, bfd_get_format(ibfd))) {
	bfd_perror("while setting output object file format");
    }

    /* copy a bunch of necessary global stuff */
    bfd_set_start_address(obfd, bfd_get_start_address(ibfd));
    bfd_set_file_flags(obfd, bfd_get_file_flags(ibfd));
    bfd_set_arch_mach(obfd, bfd_get_arch(ibfd), bfd_get_mach(ibfd));
    /* BOZO objcopy sets format again at this point.  why? */

    bfd_map_over_sections (ibfd, setup_section, obfd);

    setup_bfd_headers (ibfd, obfd);

    /* Symbol filtering must happen after the output sections
       have been created, but before their contents are set.  */
    symsize = bfd_get_symtab_upper_bound (ibfd);
    if (symsize < 0) {
	fprintf(stderr, "problem processing %s\n", bfd_get_filename (ibfd));
	return FALSE;
    }

    /* count the added relocations so we can put extra space in the output symbol table for them */
    int reloc_add_cnt, reloc_delete_cnt;
    reloc_add_cnt = 0;
    reloc_delete_cnt = 0;
    for (new_reloc = additional_relocs; new_reloc != NULL; new_reloc = new_reloc->next) {
	reloc_add_cnt++;
    }
    /* the "change" symbols might also not be in the symbol table yet */
    for (new_change = change_relocs; new_change != NULL; new_change = new_change->next) {
	reloc_add_cnt++;
	/* the old symbol may be deleted, also */
	reloc_delete_cnt++;
    }
    for (new_delete = delete_relocs; new_delete != NULL; new_delete = new_delete->next) {
	reloc_delete_cnt++;
    }

    /* filter symbol table in two steps: */
    /* 1) move symbols bound for deletion to the end of the output symbol table array */
    /* 2) truncate the table at the first of those */
    /* this makes it possible to do the reloc processing with the symbol table intact, */
    /* and remove the deleted symbols afterwards, without corrupting the reloc data structures */
    isympp = malloc (symsize);
    osympp = malloc (symsize + reloc_add_cnt * sizeof(asymbol *));
    delsympp = malloc (reloc_delete_cnt * sizeof(asymbol *));
    symcount = bfd_canonicalize_symtab (ibfd, isympp);

    if (symcount < 0) {
	fprintf(stderr, "problem processing %s\n", bfd_get_filename (ibfd));
	return FALSE;
    }

    /* remove any undefined symbols whose relocation entries were deleted or changed */
    int osym_idx, delsym_idx;
    osym_idx = delsym_idx = 0;
    delsymcount = 0;
    for (i = 0; i < symcount; i++) {
	if ((is_delete_reloc(bfd_asymbol_name(isympp[i]), delete_relocs) ||
	     (find_change_reloc(bfd_asymbol_name(isympp[i]), change_relocs) != NULL)) &&
	    (isympp[i]->section != NULL) &&
	    (strcmp(isympp[i]->section->name, BFD_UND_SECTION_NAME) == 0)) {
	    delsympp[delsym_idx++] = isympp[i];
	}
	else {
	    if (is_globalize_sym(bfd_asymbol_name(isympp[i]), globalize_syms)) {
		isympp[i]->flags = BSF_GLOBAL;
	    }
	    osympp[osym_idx++] = isympp[i];
	}
    }
    symcount = osym_idx;
    delsymcount = delsym_idx;
    osympp[symcount] = NULL;

    /* add the symbols for additional relocs to the table */
    int added_symbol_cnt = 0;
    for (new_reloc = additional_relocs; new_reloc != NULL; new_reloc = new_reloc->next) {
	if (find_symbol(osympp, new_reloc->symbol_name) < 0) {
	    /* not yet present, so add it */
	    asymbol *new_sym;
	    new_sym = bfd_make_empty_symbol(obfd);
	    new_sym->name = strdup(new_reloc->symbol_name);
	    new_sym->section = bfd_get_section_by_name (obfd, ".text");
	    new_sym->value = new_reloc->loc;
	    new_sym->flags = BSF_GLOBAL;
	    osympp[symcount + added_symbol_cnt++] = new_sym;
	    osympp[symcount + added_symbol_cnt] = NULL;
	}
    }

    /* do the same for changed relocs */
    for (new_change = change_relocs; new_change != NULL; new_change = new_change->next) {
	if (find_symbol(osympp, new_change->new_symbol_name) < 0) {
	    /* not yet present, so add it */
	    /* since this is a name change, we will reuse the existing address (value field of reloc) */
	    int old_symbol_idx;
	    if ((old_symbol_idx = find_symbol(isympp, new_change->old_symbol_name)) < 0) {
		fprintf(stderr, "change command old symbol name %s not found in symbol table! Exiting.\n", new_change->old_symbol_name);
		exit(1);
	    }
	    asymbol *new_sym;
	    new_sym = bfd_make_empty_symbol(obfd);
	    new_sym->name = strdup(new_change->new_symbol_name);
	    new_sym->section = bfd_und_section_ptr;
	    new_sym->value = isympp[old_symbol_idx]->value;
	    new_sym->flags = BSF_GLOBAL;
	    fprintf(stderr, "adding new symbol %s for change reloc command\n", new_sym->name);
	    osympp[symcount + added_symbol_cnt++] = new_sym;
	    osympp[symcount + added_symbol_cnt] = NULL;
	}
    }

    /* append the soon-to-be deleted symbols to the end of the output symbol table */
    for (i = 0; i < delsymcount; i++) {
	osympp[symcount + added_symbol_cnt + i] = delsympp[i];
    }
    osympp[symcount + added_symbol_cnt + delsymcount] = NULL;

    bfd_set_symtab (obfd, osympp, symcount + added_symbol_cnt + delsymcount);

    /* This has to happen after the symbol table has been set.  */
    bfd_map_over_sections (ibfd, copy_section_relocs_edit, obfd);

    /* now truncate the symbol table to eliminate the deleted symbols */
    osympp[symcount + added_symbol_cnt] = NULL;

    bfd_set_symtab (obfd, osympp, symcount + added_symbol_cnt);
    
    /* now that we've set the relocs and cleaned the symtab, can call this */
    bfd_map_over_sections (ibfd, copy_section_data, obfd);

    bfd_close(obfd);
    bfd_close(ibfd);

    return 0;

}
Exemple #24
0
static void
extra_case (bfd *in_abfd,
            struct bfd_link_info *link_info,
            struct bfd_link_order *link_order,
            arelent *reloc,
            bfd_byte *data,
            unsigned int *src_ptr,
            unsigned int *dst_ptr)
{
  asection * input_section = link_order->u.indirect.section;

  switch (reloc->howto->type)
    {
    case R_IMM8:
      bfd_put_8 (in_abfd,
		 bfd_coff_reloc16_get_value (reloc, link_info, input_section),
		 data + *dst_ptr);
      (*dst_ptr) += 1;
      (*src_ptr) += 1;
      break;

    case R_IMM32:
      /* If no flags are set, assume immediate value.  */
      if (! (*reloc->sym_ptr_ptr)->section->flags)
	{
	  bfd_put_32 (in_abfd,
		      bfd_coff_reloc16_get_value (reloc, link_info,
						  input_section),
		      data + *dst_ptr);
	}
      else
	{
	  bfd_vma dst = bfd_coff_reloc16_get_value (reloc, link_info,
						    input_section);
	  /* Addresses are 23 bit, and the layout of those in a 32-bit
	     value is as follows:
	       1AAAAAAA xxxxxxxx AAAAAAAA AAAAAAAA
	     (A - address bits,  x - ignore).  */
	  dst = (dst & 0xffff) | ((dst & 0xff0000) << 8) | 0x80000000;
	  bfd_put_32 (in_abfd, dst, data + *dst_ptr);
	}
      (*dst_ptr) += 4;
      (*src_ptr) += 4;
      break;

    case R_IMM4L:
      bfd_put_8 (in_abfd,
		 ((bfd_get_8 (in_abfd, data + *dst_ptr) & 0xf0)
		  | (0x0f
		     & bfd_coff_reloc16_get_value (reloc, link_info,
						   input_section))),
		 data + *dst_ptr);
      (*dst_ptr) += 1;
      (*src_ptr) += 1;
      break;

    case R_IMM16:
      bfd_put_16 (in_abfd,
		  bfd_coff_reloc16_get_value (reloc, link_info, input_section),
		  data + *dst_ptr);
      (*dst_ptr) += 2;
      (*src_ptr) += 2;
      break;

    case R_JR:
      {
	bfd_vma dst = bfd_coff_reloc16_get_value (reloc, link_info,
						  input_section);
	bfd_vma dot = (link_order->offset
		       + *dst_ptr
		       + input_section->output_section->vma);
	/* -1L, since we are in the odd byte of the word, and the pc has been
	 * incremented: */
	ptrdiff_t gap = ((ptrdiff_t)(dst - dot) - 1L); 

	if (gap & 1L)
	  abort();
	gap /= 2L;
	if ((gap > 128L) || (gap < -128L))
	  {
	    if (!((*link_info->callbacks->reloc_overflow)
		  (link_info, NULL,
		   bfd_asymbol_name(*reloc->sym_ptr_ptr),
		   reloc->howto->name, reloc->addend, input_section->owner,
		   input_section, reloc->address)))
	      abort();
	  }
	bfd_put_8(in_abfd, gap, (data + *dst_ptr));
	(*dst_ptr)++;
	(*src_ptr)++;
	break;
      }

    case R_DISP7:
      {
	bfd_vma dst = bfd_coff_reloc16_get_value (reloc, link_info,
						  input_section);
	bfd_vma dot = (link_order->offset
		       + *dst_ptr
		       + input_section->output_section->vma);
	/* -1L, since we are in the odd byte of the word, and the pc has been
	 * incremented: */
	ptrdiff_t gap = ((ptrdiff_t)(dst - dot) - 1L);

	if (gap & 1L)
	  abort();
	gap /= 2L;

	if ((gap > 0L) || (gap < -127L))
	  {
	    if (!((*link_info->callbacks->reloc_overflow)
		  (link_info, NULL,
		   bfd_asymbol_name(*reloc->sym_ptr_ptr),
		   reloc->howto->name, reloc->addend, input_section->owner,
		   input_section, reloc->address)))
	      abort();
	  }
	bfd_put_8(in_abfd,
                  (bfd_get_8(in_abfd, data + *dst_ptr) & 0x80) + (-gap & 0x7f),
                  (data + *dst_ptr));
	(*dst_ptr)++;
	(*src_ptr)++;
	break;
      }

    case R_CALLR:
      {
	bfd_vma dst = bfd_coff_reloc16_get_value (reloc, link_info,
						  input_section);
	bfd_vma dot = (link_order->offset
		       + *dst_ptr
		       + input_section->output_section->vma);
	ptrdiff_t gap = ((ptrdiff_t)(dst - dot) - 2L);

	if (gap & 1L)
	  abort();
	if ((gap > 4096L) || (gap < -4095L))
	  {
	    if (!((*link_info->callbacks->reloc_overflow)
		  (link_info, NULL,
		   bfd_asymbol_name(*reloc->sym_ptr_ptr),
		   reloc->howto->name, reloc->addend, input_section->owner,
		   input_section, reloc->address)))
	      abort();
	  }
	gap /= 2L;
	bfd_put_16(in_abfd,
                   ((bfd_get_16(in_abfd, (data + *dst_ptr)) & 0xf000)
		    | (-gap & 0x0fff)),
                   (data + *dst_ptr));
	(*dst_ptr) += 2;
	(*src_ptr) += 2;
	break;
      }

    case R_REL16:
      {
	bfd_vma dst = bfd_coff_reloc16_get_value (reloc, link_info,
						  input_section);
	bfd_vma dot = (link_order->offset
		       + *dst_ptr
		       + input_section->output_section->vma);
	ptrdiff_t gap = ((ptrdiff_t)(dst - dot) - 2L);

	if ((gap > 32767L) || (gap < -32768L))
	  {
	    if (!((*link_info->callbacks->reloc_overflow)
		  (link_info, NULL,
		   bfd_asymbol_name(*reloc->sym_ptr_ptr),
		   reloc->howto->name, reloc->addend, input_section->owner,
		   input_section, reloc->address)))
	      abort();
	  }
	bfd_put_16(in_abfd, (bfd_vma)gap, (data + *dst_ptr));
	(*dst_ptr) += 2;
	(*src_ptr) += 2;
	break;
      }

    default:
      abort();
    }
}
Exemple #25
0
/* ripped off from objdump.c, line 469 */
int compare_symbols(const void *ap, const void *bp)
{
   const asymbol *a = * (const asymbol **) ap;
  const asymbol *b = * (const asymbol **) bp;
  const char *an;
  const char *bn;
  size_t anl;
  size_t bnl;
  bfd_boolean af;
  bfd_boolean bf;
  flagword aflags;
  flagword bflags;

  if (bfd_asymbol_value (a) > bfd_asymbol_value (b))
    return 1;
  else if (bfd_asymbol_value (a) < bfd_asymbol_value (b))
    return -1;

  if (a->section > b->section)
    return 1;
  else if (a->section < b->section)
    return -1;


  an = bfd_asymbol_name (a);
  bn = bfd_asymbol_name (b);
  anl = strlen (an);
  bnl = strlen (bn);

  /* The symbols gnu_compiled and gcc2_compiled convey no real
     information, so put them after other symbols with the same value.  */
  af = (strstr (an, "gnu_compiled") != NULL
	|| strstr (an, "gcc2_compiled") != NULL);
  bf = (strstr (bn, "gnu_compiled") != NULL
	|| strstr (bn, "gcc2_compiled") != NULL);

  if (af && ! bf)
    return 1;
  if (! af && bf)
    return -1;

  /* We use a heuristic for the file name, to try to sort it after
     more useful symbols.  It may not work on non Unix systems, but it
     doesn't really matter; the only difference is precisely which
     symbol names get printed.  */

#define file_symbol(s, sn, snl)			\
  (((s)->flags & BSF_FILE) != 0			\
   || ((sn)[(snl) - 2] == '.'			\
       && ((sn)[(snl) - 1] == 'o'		\
	   || (sn)[(snl) - 1] == 'a')))

  af = file_symbol (a, an, anl);
  bf = file_symbol (b, bn, bnl);

  if (af && ! bf)
    return 1;
  if (! af && bf)
    return -1;


  aflags = a->flags;
  bflags = b->flags;

  if ((aflags & BSF_DEBUGGING) != (bflags & BSF_DEBUGGING))
    {
      if ((aflags & BSF_DEBUGGING) != 0)
	return 1;
      else
	return -1;
    }
  if ((aflags & BSF_FUNCTION) != (bflags & BSF_FUNCTION))
    {
      if ((aflags & BSF_FUNCTION) != 0)
	return -1;
      else
	return 1;
    }
  if ((aflags & BSF_LOCAL) != (bflags & BSF_LOCAL))
    {
      if ((aflags & BSF_LOCAL) != 0)
	return 1;
      else
	return -1;
    }
  if ((aflags & BSF_GLOBAL) != (bflags & BSF_GLOBAL))
    {
      if ((aflags & BSF_GLOBAL) != 0)
	return -1;
      else
	return 1;
    }

  /* Symbols that start with '.' might be section names, so sort them
     after symbols that don't start with '.'.  */
  if (an[0] == '.' && bn[0] != '.')
    return 1;
  if (an[0] != '.' && bn[0] == '.')
    return -1;

  /* Finally, if we can't distinguish them in any other way, try to
     get consistent results by sorting the symbols by name.  */
  return strcmp (an, bn);
}
/* just reloc parts - data comes later */
static void copy_section_relocs_edit (bfd *ibfd, sec_ptr isection, void *obfdarg)
{
    bfd *obfd = obfdarg;
    arelent **relpp;
    long relcount;
    sec_ptr osection;
    bfd_size_type size;
    long relsize;
    flagword flags;


    flags = bfd_get_section_flags (ibfd, isection);
    if ((flags & SEC_GROUP) != 0)
	return;

    osection = isection->output_section;
    size = bfd_get_section_size (isection);

    if (size == 0 || osection == 0)
	return;

    relsize = bfd_get_reloc_upper_bound (ibfd, isection);

    if (relsize <= 0)
    {
	/* not good */
	bfd_perror("attempting to do relocs");
	return;
    }

    relpp = malloc (relsize);

    relcount = bfd_canonicalize_reloc (ibfd, isection, relpp, isympp);

    /* copy each reloc, possibly removing or changing it on the fly */
    arelent **temp_relpp;
    long temp_relcount = 0;
    long i;
    int msg_cnt = 0;
    struct change_reloc_struct *change_ptr;
    struct add_reloc_struct *new_reloc;
    asymbol **osympp;

    /* count new relocs to allocate space in reloc list */
    int reloc_add_cnt;
    reloc_add_cnt = 0;
    for (new_reloc = additional_relocs; new_reloc != NULL; new_reloc = new_reloc->next) {
	reloc_add_cnt++;
    }

    osympp = bfd_get_outsymbols(obfd);

    /* note: cannot run mprobe on osympp b/c the copy contents will sometimes realloc it from internal BFD storage */

    temp_relpp = malloc (relsize + reloc_add_cnt * sizeof(arelent *));
    for (i = 0; i < relcount; i++) {

	if (is_delete_reloc(bfd_asymbol_name(*relpp[i]->sym_ptr_ptr), delete_relocs)) {
	    continue;
	}
	else if ((change_ptr = find_change_reloc(bfd_asymbol_name(*relpp[i]->sym_ptr_ptr), change_relocs)) != NULL) {
	    int sym_idx;
	    sym_idx = find_symbol(osympp, change_ptr->new_symbol_name);
	    if (sym_idx < 0) {
		fprintf(stderr, "internal error: could not find new symbol %s in output symbol table\n", change_ptr->new_symbol_name);
		exit(1);
	    }
	    relpp[i]->sym_ptr_ptr = &(osympp[sym_idx]);
	}
	temp_relpp [temp_relcount++] = relpp [i];
    }

    /* now the additional relocs from the command line */
    if (strcmp(bfd_get_section_name(ibfd, isection), ".text") == 0) {
	add_reloc_struct *add_reloc;
	for (add_reloc = additional_relocs; add_reloc != NULL; add_reloc = add_reloc->next) {
	    arelent *new_reloc;
	    int symbol_idx;

	    new_reloc = malloc(sizeof(*new_reloc));
	    if ((symbol_idx = find_symbol(osympp, add_reloc->symbol_name)) < 0) {
		fprintf(stderr, "could not find symbol %s to perform a relocation! possible internal error\n", add_reloc->symbol_name);
		continue;
	    }
	    new_reloc->sym_ptr_ptr = &osympp[symbol_idx];
	    new_reloc->address = add_reloc->loc;
	    new_reloc->addend = 0;   /* never seemed to be used in my cursory investigation */
	    new_reloc->howto = bfd_reloc_type_lookup(ibfd, BFD_RELOC_32_PCREL);
	    if (new_reloc->howto == NULL) {
		fprintf(stderr, "could not get howto back from bfd subsystem\n");
		exit(1);
	    }

	    temp_relpp[temp_relcount++] = new_reloc;
	}
    }
    temp_relpp[temp_relcount] = NULL;

    relcount = temp_relcount;
    free (relpp);
    relpp = temp_relpp;

    bfd_set_reloc (obfd, osection, relcount == 0 ? NULL : relpp, relcount);
    if (relcount == 0)
	free (relpp);

    mcheck_check_all();

}
Exemple #27
0
void leaky::ReadSymbols(const char *aFileName, u_long aBaseAddress)
{
  int initialSymbols = usefulSymbols;
  if (nullptr == externalSymbols) {
    externalSymbols = (Symbol**) calloc(sizeof(Symbol*),10000);
    Symbol *new_array = new Symbol[10000];
    for (int i = 0; i < 10000; i++) {
      externalSymbols[i] = &new_array[i];
    }
    numExternalSymbols = 10000;
  }
  Symbol** sp = externalSymbols + usefulSymbols;
  lastSymbol = externalSymbols + numExternalSymbols;

  // Create a dummy symbol for the library so, if it doesn't have any
  // symbols, we show it by library.
  (*sp)->Init(aFileName, aBaseAddress);
  NEXT_SYMBOL;

  bfd_boolean kDynamic = (bfd_boolean) false;

  static int firstTime = 1;
  if (firstTime) {
    firstTime = 0;
    bfd_init ();
  }

  bfd* lib = bfd_openr(aFileName, nullptr);
  if (nullptr == lib) {
    return;
  }
  if (!bfd_check_format(lib, bfd_object)) {
    bfd_close(lib);
    return;
  }

  bfd *symbolFile = find_debug_file(lib, aFileName);

  // read mini symbols
  PTR minisyms;
  unsigned int size;
  long symcount = 0;

  if (symbolFile) {
    symcount = bfd_read_minisymbols(symbolFile, kDynamic, &minisyms, &size);
    if (symcount == 0) {
      bfd_close(symbolFile);
    } else {
      bfd_close(lib);
    }
  }
  if (symcount == 0) {
    symcount = bfd_read_minisymbols(lib, kDynamic, &minisyms, &size);
    if (symcount == 0) {
      // symtab is empty; try dynamic symbols
      kDynamic = (bfd_boolean) true;
      symcount = bfd_read_minisymbols(lib, kDynamic, &minisyms, &size);
    }
    symbolFile = lib;
  }

  asymbol* store;
  store = bfd_make_empty_symbol(symbolFile);

  // Scan symbols
  bfd_byte* from = (bfd_byte *) minisyms;
  bfd_byte* fromend = from + symcount * size;
  for (; from < fromend; from += size) {
    asymbol *sym;
    sym = bfd_minisymbol_to_symbol(symbolFile, kDynamic, (const PTR) from, store);

    symbol_info syminfo;
    bfd_get_symbol_info (symbolFile, sym, &syminfo);

//    if ((syminfo.type == 'T') || (syminfo.type == 't')) {
      const char* nm = bfd_asymbol_name(sym);
      if (nm && nm[0]) {
        char* dnm = nullptr;
        if (strncmp("__thunk", nm, 7)) {
          dnm = abi::__cxa_demangle(nm, 0, 0, 0);
        }
        (*sp)->Init(dnm ? dnm : nm, syminfo.value + aBaseAddress);
        if (dnm) {
          free(dnm);
        }
        NEXT_SYMBOL;
      }
//    }
  }

  bfd_close(symbolFile);

  int interesting = sp - externalSymbols;
  if (!quiet) {
    printf("%s provided %d symbols\n", aFileName,
           interesting - initialSymbols);
  }
  usefulSymbols = interesting;
}
Exemple #28
0
void
msp430_trace_one (int mypc)
{
  static int           last_sym = -1;
  static const char *  prev_filename = "";
  static int           prev_lineno = 0;
  const char *  filename;
  const char *  functionname;
  unsigned int  lineno;
  int           sym, bestaddr;
  int           min, max, i;

  if (! msp430_get_current_source_location (mypc, & filename, & functionname, & lineno))
    return;

  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 ++;
	  fprintf
	    (stderr, "========================================"
	     "=====================================\n");
	  fprintf (stderr, "\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]);
      fprintf (stderr, "\033[43;30m%s", bfd_asymbol_name (symtab[min]));
      if (bestaddr != mypc)
	fprintf (stderr, "+%d", mypc - bestaddr);
      fprintf (stderr, ":\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
    }
}
Exemple #29
0
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;
}
Exemple #30
0
int main(int argc, char *argv[])
{
    int i, f, size, symcnt, off;
    unsigned int fingerprint;
    int num_funcs = 0;
    int fancy_output = 0;
    int strip_names = 0;
    bfd *b;
    asymbol **syms;
    unsigned char buf[SIGNATSIZE+4];
    char *nameptr;

    const char *short_options = "fsh";
    struct option long_options[] = {
        {"fancy", no_argument, NULL, 'f'},
        {"strip", no_argument, NULL, 's'},
        {"help",  no_argument, NULL, 'h'},
        {0,       no_argument, NULL, 0}
    };

    while ((i = getopt_long(argc, argv, short_options, long_options, NULL)) != EOF) {
        switch (i) {
            case 'f':
                fancy_output = 1;
                break;
            case 's':
                strip_names = 1;
                break;
            case 'h':
            case '?':
                usage(argv[0]); /* never returns */
            default:
                break;
        }
    }

    if (optind >= argc) {
        usage(argv[0]); /* never returns */
        exit(1);
    }

    while (optind < argc) {
        b = bfd_openr(argv[optind++], 0);
        if (!b) {
            fprintf(stderr, "bfd_openr failed for '%s'\n", argv[optind - 1]);
            continue;
        }

        bfd_check_format(b, bfd_archive);
        bfd_check_format_matches(b, bfd_object, 0);

        if ((bfd_get_file_flags(b) & HAS_SYMS) == 0) {
            fprintf(stderr, (fancy_output) ? "EMPTY" : "No symbols.\n");
            continue;
        }

        size = bfd_get_symtab_upper_bound(b);
        syms = (asymbol **) malloc(size);
        symcnt = bfd_canonicalize_symtab(b, syms);

        for (i = 0; i < symcnt; ++i) {
            if (syms[i]->flags & BSF_FUNCTION) {
                nameptr = (char *)(bfd_asymbol_name(syms[i]));
                if (strip_names!=0) {
                    while (*nameptr == '_') {
                        nameptr++;
                    }
                }
                off = syms[i]->value;
                if (syms[i]->section) {
                    off += syms[i]->section->filepos;
                }

                f = open(argv[optind - 1], O_RDONLY);
                lseek(f, off, SEEK_SET);
                num_funcs++;
                read(f, buf, SIGNATSIZE);
                fingerprint = fnprint_compute(buf);
                close(f);

                // Ignore only NOPs
                if (fingerprint != 0xA120AD5C) {
                    printf("[%s+%d] %s %08X\n", argv[optind - 1], off, nameptr, fingerprint);
                } else {
                    printf("\n");
                }
            }
        }

        if (fancy_output) {
            fprintf(stderr, "%d function%s", num_funcs, PLURAL(num_funcs, "s"));
        } else {
            fprintf(stderr, "[*] %s: (%d function%s)\n", argv[optind - 1], num_funcs, PLURAL(num_funcs, "s"));
        }
    }
    return 0;
}