This is the mail archive of the
binutils@sources.redhat.com
mailing list for the binutils project.
RE: -gc-sections for elf32-dlx and possible buglette in elf32-target.h
- From: "Dave Korn" <dk at artimi dot com>
- To: "'Daniel Jacobowitz'" <drow at mvista dot com>
- Cc: <binutils at sources dot redhat dot com>
- Date: Thu, 29 Jan 2004 15:51:28 -0000
- Subject: 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....