Пример #1
0
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);
}
Пример #2
0
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);
    }
}