static void
copy_sections (bfd *abfd, asection *sect, void *data)
{
  asymbol **symbol_table = data;
  bfd_byte *sect_data, *sect_data_got;
  struct cleanup *cleanups;
  struct bfd_link_info link_info;
  struct bfd_link_order link_order;
  CORE_ADDR inferior_addr;
  struct link_hash_table_cleanup_data cleanup_data;

  if ((bfd_get_section_flags (abfd, sect) & (SEC_ALLOC | SEC_LOAD))
      != (SEC_ALLOC | SEC_LOAD))
    return;

  if (bfd_get_section_size (sect) == 0)
    return;

  /* Mostly a copy of bfd_simple_get_relocated_section_contents which GDB
     cannot use as it does not report relocations to undefined symbols.  */
  memset (&link_info, 0, sizeof (link_info));
  link_info.output_bfd = abfd;
  link_info.input_bfds = abfd;
  link_info.input_bfds_tail = &abfd->link.next;

  cleanup_data.abfd = abfd;
  cleanup_data.link_next = abfd->link.next;

  abfd->link.next = NULL;
  link_info.hash = bfd_link_hash_table_create (abfd);

  cleanups = make_cleanup (link_hash_table_free, &cleanup_data);
  link_info.callbacks = &link_callbacks;

  memset (&link_order, 0, sizeof (link_order));
  link_order.next = NULL;
  link_order.type = bfd_indirect_link_order;
  link_order.offset = 0;
  link_order.size = bfd_get_section_size (sect);
  link_order.u.indirect.section = sect;

  sect_data = xmalloc (bfd_get_section_size (sect));
  make_cleanup (xfree, sect_data);

  sect_data_got = bfd_get_relocated_section_contents (abfd, &link_info,
						      &link_order, sect_data,
						      FALSE, symbol_table);

  if (sect_data_got == NULL)
    error (_("Cannot map compiled module \"%s\" section \"%s\": %s"),
	   bfd_get_filename (abfd), bfd_get_section_name (abfd, sect),
	   bfd_errmsg (bfd_get_error ()));
  gdb_assert (sect_data_got == sect_data);

  inferior_addr = bfd_get_section_vma (abfd, sect);
  if (0 != target_write_memory (inferior_addr, sect_data,
				bfd_get_section_size (sect)))
    error (_("Cannot write compiled module \"%s\" section \"%s\" "
	     "to inferior memory range %s-%s."),
	   bfd_get_filename (abfd), bfd_get_section_name (abfd, sect),
	   paddress (target_gdbarch (), inferior_addr),
	   paddress (target_gdbarch (),
		     inferior_addr + bfd_get_section_size (sect)));

  do_cleanups (cleanups);
}
Beispiel #2
0
int build_symbol_table_bfd ( char *oname ) {

    int u,v;
    asymbol **q;

    bfd_init();
    if ( ! ( exe_bfd = bfd_openr ( oname, 0 ) ) ) {
        fprintf ( stderr, "Cannot open %s.\n", oname );
        exit ( 0 );
    }
    
    if ( ! bfd_check_format ( exe_bfd, bfd_object ) ) {
        fprintf ( stderr, "I'm not an object.\n" );
        exit ( 0 );
    }
    
    if ( !(link_info.hash = bfd_link_hash_table_create ( exe_bfd ) ) ) {
        fprintf ( stderr, "Cannot make hash table.\n" );
        exit ( 0 );
    }
    
    if ( !bfd_link_add_symbols ( exe_bfd, &link_info ) ) {
        fprintf ( stderr, "Cannot add self symbols\n.\n" );
        exit ( 0 );
    }
    
    if ( ( u = bfd_get_symtab_upper_bound ( exe_bfd ) ) < 0 ) {
        fprintf ( stderr, "Cannot get self's symtab upper bound.\n" );
        exit ( 0 );
    }
    
    fprintf ( stderr, "Allocating symbol table (%d bytes)\n", u );
    q = (asymbol **) malloc ( u );

    if ( ( v = bfd_canonicalize_symtab ( exe_bfd, q ) ) < 0 ) {
        fprintf ( stderr, "Cannot canonicalize self's symtab.\n" );
        exit ( 0 );
    }

#ifdef _WIN32        
    for ( u=0; u < v; u++ ) {
        char *c;
        if ( ( c = (char *) strstr ( q[u]->name, "_" ) ) ) {
            struct bfd_link_hash_entry *h;
            if ( ( h = bfd_link_hash_lookup ( link_info.hash,
                                                q[u]->name, MY_BFD_TRUE,MY_BFD_TRUE,MY_BFD_TRUE ) ) ) {
                h->type=bfd_link_hash_defined;
                if ( !q[u]->section )
                    fprintf ( stderr, "Symbol is missing section.\n" );
                h->u.def.value   = q[u]->value + q[u]->section->vma;
                h->u.def.section = q[u]->section;
                fprintf ( stderr, "Processed %s\n", q[u]->name );
            } else {
                fprintf ( stderr, "Cannot make new hash entry.\n" );
            }
        }
    }
#else    
    for (u=0;u<v;u++) {
        char *c;
        if ((c=(char *)strstr(q[u]->name,"@@GLIBC\n" ))) {
            struct bfd_link_hash_entry *h;
            *c=0;
            if (!(h=bfd_link_hash_lookup(link_info.hash,q[u]->name,MY_BFD_TRUE,MY_BFD_TRUE,MY_BFD_TRUE)))
                fprintf ( stderr, "Cannot make new hash entry.\n" );
            h->type=bfd_link_hash_defined;
            if (!q[u]->section)
                fprintf ( stderr, "Symbol is missing section.\n" );
            h->u.def.value=q[u]->value+q[u]->section->vma;
            h->u.def.section=q[u]->section;
            *c='@';
        }
    }
#endif        
    bfd_close ( exe_bfd );
    free(q);
    return 0;
    
}