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); }
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; }