MIPS bfd_get_relocated_section_contents broken

Camm Maguire camm@enhanced.com
Wed Jun 19 11:25:00 GMT 2002


Greetings!  To summarize the progress thus far,
bfd_get_relocated_section_contents works just fine for relocating and
executing dynamically loaded object files (so far) on

i386
s390
m68k
arm
ppc

at least.  This is for gcl, which works by opening its own binary file
as a bfd, building a hash table of its symbols, then opening objects
to be loaded as bfd's, setting the symbols therein to the values in
the main executable adjusted for the new section vma, and then
performing bfd_get_relocated_section_contents.  The memory image thus
created is then executed, after cache clearing operations.

There are several difficulties with MIPS.  The first seems treatable
-- it is the _gp_disp issue.  I've just added the following snippet to
by symbol redefinition code, and I can at least handle the HI16 and
LO16 reloc types:

In the running program:

  if ((v=bfd_canonicalize_symtab(bself,q))<0)
    FEerror("Cannot canonicalize self's symtab");
  for (u=0;u<v;u++) {
    if (!strcmp(q[u]->name,"_gp_disp")) {
      struct bfd_link_hash_entry *h;
      if (!(h=bfd_link_hash_lookup(link_info.hash,q[u]->name,true,true,true)))
	FEerror("Cannot make new hash entry");
      h->type=bfd_link_hash_defined;
      if (!q[u]->section)
	FEerror("Symbol is missing section");
      h->u.def.value=q[u]->value+q[u]->section->vma;
      h->u.def.section=q[u]->section;
    }
  }

For the object to be loaded:

  if ((v=bfd_canonicalize_symtab(b,q))<0)
    FEerror("cannot canonicalize symtab");
  for (u=0;u<v;u++) {

    struct bfd_link_hash_entry *h;

    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,false,false,true))) 
      continue;

    if (h->type!=bfd_link_hash_defined) 
      FEerror("Undefined symbol");
      
    if (h->u.def.section) {
      q[u]->value=h->u.def.value+h->u.def.section->vma;
      q[u]->flags|=BSF_WEAK;
      if (!strcmp(q[u]->name,"_gp_disp")) {
	q[u]->section=b->sections;
	_bfd_set_gp_value(b,q[u]->value);
      }
    } else 
      FEerror("Symbol without section");

  }


(I need to redefine the section for the _gp_disp symbol in the object
so the bfd routines will lookup the section owner correctly and find
the gp value when _bfd_get_gp_value is called.)


The problem is with R_MIPS_GOT16.  From the comments, it seems as if
this routine was never completed.  The function mips_elf_got16_reloc
just bails completely unless producing relocateable output:

   This implementation suffices for the assembler, but the linker does
   not yet know how to create global offset tables.  */

static bfd_reloc_status_type
mips_elf_got16_reloc (abfd, reloc_entry, symbol, data, input_section,
		      output_bfd, error_message)
     bfd *abfd;
     arelent *reloc_entry;
     asymbol *symbol;
     PTR data;
     asection *input_section;
     bfd *output_bfd;
     char **error_message;
{
  /* If we're relocating, and this an external symbol, we don't want
     to change anything.  */
  if (output_bfd != (bfd *) NULL
      && (symbol->flags & BSF_SECTION_SYM) == 0
      && reloc_entry->addend == 0)
    {
      reloc_entry->address += input_section->output_offset;
      return bfd_reloc_ok;
    }

  /* If we're relocating, and this is a local symbol, we can handle it
     just like HI16.  */
  if (output_bfd != (bfd *) NULL
      && (symbol->flags & BSF_SECTION_SYM) != 0)
    return mips_elf_hi16_reloc (abfd, reloc_entry, symbol, data,
				input_section, output_bfd, error_message);

  abort ();
}

I run into the abort() early on.  I've tried just as a test adding the
following at the top:

  if (output_bfd == (bfd *)NULL)
    output_bfd = symbol->section->output_section->owner;

This gets me past "conventional" symbols, but fails with function
calls (compiled with -mlong-calls), as the section here is the
undefined section.  If I don't compile with -mlong-calls, the function
calls get relocated with a generic routine, (R_MIPS_CALL16), but this
triggers an overflow in my application, as the running section vma's
are all less than the newly loaded object section vma's.

Any suggestions, most appreciated!

Take care,



-- 
Camm Maguire			     			camm@enhanced.com
==========================================================================
"The earth is but one country, and mankind its citizens."  --  Baha'u'llah



More information about the Binutils mailing list