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 main ( int argc, char ** argv ) { int init_address=-1; int max_align = 0; unsigned long curr_size = 0; bfd *obj_bfd = NULL; bfd_error_type myerr; unsigned u = 0, v = 0; asymbol **q = NULL; asection *s = NULL; static struct bfd_link_callbacks link_callbacks; static struct bfd_link_order link_order; void *current = NULL; void *cfd_self = NULL; void *cfd_start = NULL; int cfd_size = 0; void *the_start = NULL; void *start_address = NULL; void *m = NULL; fprintf ( stderr, "In BFD fast load test. Reloc_howto_type size %d\n", sizeof ( rhtt ) ); if ( argc < 3 ) { fprintf ( stderr, "Need an executable (eg raw_gcl.exe) and an object file as arguments.\n" ); } else { memset ( &link_info, 0, sizeof (link_info) ); memset ( &link_order, 0, sizeof (link_order) ); memset ( &link_callbacks, 0, sizeof (link_callbacks) ); fprintf ( stderr, "BUILDING EXECUTABLE SYMBOL TABLE FOR %s \n", argv[1] ); build_symbol_table_bfd ( argv[1] ); link_callbacks.add_archive_element=madd_archive_element; link_callbacks.multiple_definition=mmultiple_definition; link_callbacks.multiple_common=mmultiple_common; link_callbacks.add_to_set=madd_to_set; link_callbacks.constructor=mconstructor; link_callbacks.warning=mwarning; link_callbacks.undefined_symbol=mundefined_symbol; link_callbacks.reloc_overflow=mreloc_overflow; link_callbacks.reloc_dangerous=mreloc_dangerous; link_callbacks.unattached_reloc=munattached_reloc; link_callbacks.notice = mnotice; link_info.callbacks = &link_callbacks; link_order.type = bfd_indirect_link_order; fprintf ( stderr, "OPENING OBJECT FILE %s\n", argv[2] ); if ( ! ( obj_bfd = bfd_openr ( argv[2], 0 ) ) ) { fprintf ( stderr, "Cannot open bfd.\n" ); } if ( ( myerr = bfd_get_error () ) && myerr != 3 ) { fprintf ( stderr, "Unknown bfd error code on openr %s %d\n.", argv[2], myerr ); } fflush ( stderr ); if ( ! bfd_check_format ( obj_bfd, bfd_object ) ) { fprintf ( stderr, "Unknown bfd format %s.\n", argv[2] ); } if ( ( myerr = bfd_get_error () ) && myerr != 3 ) { fprintf ( stderr, "Unknown bfd error code on check_format %s\n", argv[2] ); } bfd_set_error(0); current = NULL; fprintf ( stderr, "CALCULATING CURRENT, MAX_ALIGN and ALLOCATING \n\n" ); for ( s= obj_bfd->sections;s;s=s->next) { s->owner = obj_bfd; s->output_section = ( s->flags & SEC_ALLOC) ? s : obj_bfd->sections; s->output_offset=0; if (!(s->flags & SEC_ALLOC)) continue; if (max_align<s->alignment_power) max_align=s->alignment_power; current=round_up(current,1<<s->alignment_power); current+=s->_raw_size; fprintf ( stderr, "Section %s: owner = %x, output_offset = %x, " "output_section = %x (%s)\n", s->name, s->owner, s->output_offset, s->output_section, s->output_section->name ); } fprintf ( stderr, "1\n"); curr_size=(unsigned long)current; max_align=1<<max_align; cfd_self = 0; cfd_start = 0; cfd_size = curr_size + (max_align > sizeof(char *) ? max_align :0); cfd_start = (void *) malloc ( cfd_size ); the_start = start_address = cfd_start; fprintf ( stderr, "ALLOCATED %d bytes \n\n", cfd_size ); fprintf ( stderr, "max_align = %d, current = %d, cfd_self = %x, " "cfd_size = %x, cfd_start = %x\n", max_align, current, cfd_self, cfd_size, cfd_start ); start_address = ROUND_UP ( start_address, max_align ); cfd_size = cfd_size - ( start_address - the_start ); cfd_start = (void *) start_address; fprintf ( stderr, "max_align = %d, current = %d, cfd_self = %x, " "cfd_size = %x, cfd_start = %x\n", max_align, current, cfd_self, cfd_size, cfd_start ); memset ( cfd_start, 0, cfd_size ); for ( m = start_address, s = obj_bfd->sections; s; s=s->next ) { if (!(s->flags & SEC_ALLOC)) continue; m=round_up(m,1<<s->alignment_power); s->output_section->vma=(unsigned long)m; m+=s->_raw_size; fprintf ( stderr, "Section address %x\n", s ); fprintf ( stderr, "m loop Section %s: owner = %x, output_offset = %x, " "output_section = %x (%s), vma = %x, m = %x\n", s->name, s->owner, s->output_offset, s->output_section, s->output_section->name, s->output_section->vma, m ); } fprintf ( stderr, "\n\nDOING SOMETHING WITH THE HASHED SYMBOLS\n\n" ); if ((u=bfd_get_symtab_upper_bound(obj_bfd))<0) fprintf ( stderr, "Cannot get symtab uppoer bound.\n" ); q = (asymbol **) alloca ( u ); if ( ( v = bfd_canonicalize_symtab ( obj_bfd, q ) ) < 0 ) fprintf ( stderr, "cannot canonicalize symtab.\n" ); fprintf ( stderr, "u = %d, v = %d\n", u, v ); for (u=0;u<v;u++) { struct bfd_link_hash_entry *h; fprintf ( stderr, "u loop q[%d]->name = %s\n", u, q[u]->name ); if (!strncmp("init_",q[u]->name,5)) { init_address=q[u]->value; continue; } if (!(h=bfd_link_hash_lookup(link_info.hash,q[u]->name, MY_BFD_FALSE, MY_BFD_FALSE, MY_BFD_TRUE))) continue; if (h->type!=bfd_link_hash_defined) fprintf ( stderr, "Undefined symbol.\n" ); if (h->u.def.section) { q[u]->value=h->u.def.value+h->u.def.section->vma; q[u]->flags|=BSF_WEAK; } else fprintf ( stderr, "Symbol without section.\n" ); } fprintf ( stderr, "\n\nDOING RELOCATIONS\n\n", cfd_size ); fflush ( stderr ); for ( s = obj_bfd->sections; s; s = s->next ) { fprintf ( stderr, "s->name %s, s->flags = %x\n", s->name, s->flags ); if ( ! ( s->flags & SEC_LOAD ) ) continue; link_order.u.indirect.section=s; fprintf ( stderr, "About to get reloc section contents\n" ); fprintf ( stderr, "obj_bfd = %x, section %s, s->output_section = %x, q = %x\n", obj_bfd, s->name, s->output_section, q); fflush ( stderr ); if (!bfd_get_relocated_section_contents(obj_bfd, &link_info,&link_order, (void *)(unsigned long)s->output_section->vma,0,q)) fprintf ( stderr, "Cannot get relocated section contents\n"); } bfd_close ( obj_bfd ); printf("start address -T %x \n", cfd_start); } }