This is the mail archive of the binutils@sources.redhat.com mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

RE: -gc-sections for elf32-dlx and possible buglette in elf32-target.h


> -----Original Message-----
> From: Daniel Jacobowitz  
> Sent: 29 January 2004 14:52
> To: Dave Korn
> Cc: binutils

> >   And this is where it dies, because it turns out that 
> h->sym has the 
> > value 0xffffffff, which is not a legal pointer to a symbol!
> 
> What's your derived hash table entry look like?  If the 
> standard hash table entry is at the beginning, like every 
> other target, this should work fine.

  Yep, I basically ripped it out of elf32-ppc.c, renamed it and hacked it
up.  In fact, since I haven't added any meaningful data members to it yet,
it's a bit superfluous - I could have used the generic elf hashtable - but I
believe it ought to be correct:

---snip---
/* Override default elf link hashtable entry */
struct elf_dlx_link_hash_entry
{
  struct elf_link_hash_entry elf;
  unsigned int f00dface;
};
#define elf_dlx_hash_entry(ent) ((struct elf_dlx_link_hash_entry *) (ent))

/* DLX ELF linker hash table overrides default generic elf hashtable  */
struct elf_dlx_link_hash_table
{
  struct elf_link_hash_table elf;
  unsigned int f00dface;
};
/* Get the DLX ELF linker hash table from a link_info structure.  */
#define elf_dlx_hash_table(p) \
  ((struct elf_dlx_link_hash_table *) (p)->hash)

/* Create an entry in a DLX ELF linker hash table.  */

static struct bfd_hash_entry *
elf_dlx_link_hash_newfunc (entry, table, string)
     struct bfd_hash_entry *entry;
     struct bfd_hash_table *table;
     const char *string;
{
  /* Allocate the structure if it has not already been allocated by a
     subclass.  */
  if (entry == NULL)
    {
      entry = bfd_hash_allocate (table,
				 sizeof (struct elf_dlx_link_hash_entry));
      if (entry == NULL)
	return entry;
    }

  /* Call the allocation method of the superclass.  */
  entry = _bfd_elf_link_hash_newfunc (entry, table, string);
  if (entry != NULL)
    {
      /* here, if we had any members to init, we could use */
      /* elf_dlx_hash_entry (entry)->member = value; */
        elf_dlx_hash_entry (entry)->f00dface = 0xf00dface;
      /* but we currently don't. */
    }

  return entry;
}

/* Create a DLX ELF linker hash table.  */
static struct bfd_link_hash_table *
elf_dlx_link_hash_table_create (abfd)
     bfd *abfd;
{
  struct elf_dlx_link_hash_table *ret;

  ret = ((struct elf_dlx_link_hash_table *)
	 bfd_malloc (sizeof (struct elf_dlx_link_hash_table)));
  if (ret == NULL)
    return NULL;

  if (! _bfd_elf_link_hash_table_init (&ret->elf, abfd,
				       elf_dlx_link_hash_newfunc))
    {
      free (ret);
      return NULL;
    }
  /*  here is where we'd init members of ret if we had any. */
  ret->f00dface = 0xf00dface;
  return &ret->elf.root;
}
---snip---
 
> >   So what I was hoping someone could explain to me is why this 
> > comparison between the info->hash->creator and the input_bfd->xvec 
> > should be a test for generic/non-generic hashtable, and whether my 
> > assumption that this clause should *not* be active in elf 
> targets is correct.
> 
> No, your assumption is not correct, I think.
 
  Well, you're more likely to know than me!  However what's confusing me is
how this bit of code in linker.c / _bfd_generic_link_output_symbols:

	      if (info->hash->creator == input_bfd->xvec)
		{
            if (h->sym != (asymbol *) NULL)
		    *sym_ptr = sym = h->sym;
		}

can possibly be valid.  The code a few lines above it initialises the h
pointer like this:

	  if (sym->udata.p != NULL)
	    h = (struct generic_link_hash_entry *) sym->udata.p;

  Now the generic link hash entry looks like this:

struct generic_link_hash_entry
{
  struct bfd_link_hash_entry root;
  /* Whether this symbol has been written out.  */
  bfd_boolean written;
  /* Symbol from input BFD.  */
  asymbol *sym;
};

  And the elf_link_hash_entry looks like this:

struct elf_link_hash_entry
{
  struct bfd_link_hash_entry root;

  long indx;

  /* Symbol index as a dynamic symbol.  Initialized to -1, and remains
     -1 if this is not a dynamic symbol.  */
  long dynindx;

[ ....more snipped.... ]
};


  And so when it attempts to dereference h->sym, what it actually gets is
the dynindx member, which as promised has been inited to -1.

  So, I've been making one further assumption here, and maybe this one is
incorrect and the cause of my confusion, so here it is:  I assume that the
udata.p members of all the symbol structures are supposed to point to a hash
entry of whatever derived type we're using, rather than some auxiliary
generic linker hash table that also exists.  And I'm led to assume that this
happens because I've #defined some of the backend overrideables, but not a
consistent set of them.


    cheers, 
      DaveK
-- 
Can't think of a witty .sigline today....
 









Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]