This is the mail archive of the
binutils@sources.redhat.com
mailing list for the binutils project.
Re: Special names tha ld needs to recognize for hppa64-hp-hpux11.X
- From: law at redhat dot com
- To: "John David Anglin" <dave at hiauly1 dot hia dot nrc dot ca>
- Cc: binutils at sources dot redhat dot com
- Date: Tue, 12 Feb 2002 09:43:06 -0700
- Subject: Re: Special names tha ld needs to recognize for hppa64-hp-hpux11.X
- Reply-to: law at redhat dot com
In message <200202120240.g1C2eWJ5023010@hiauly1.hia.nrc.ca>, "John David
Anglin
" writes:
> > Hmmm, what is the scope of do_exitcu? global or file-local?
>
> It's local.
OK. That's probably the key to the varying behavior; the number of problems
I had with local function symbols was significant.
> That's definitely strange as the HP compiler is definitely passing a
> pointer to an .opd entry for do_excite when it calls ___stdio_unsup_1.
OK. I was wrong -- I just found the code which special cases the address
of a local function and creates a .opd entry for it
elf64-hppa.c::allocate_global_data_opd.
/* If we are creating a shared library, took the address of a local
function or might export this function from this object file, then
we have to create an opd descriptor. */
else if (x->info->shared
|| h == NULL
|| h->dynindx == -1
|| ((h->root.type == bfd_link_hash_defined
|| h->root.type == bfd_link_hash_defweak)
&& h->root.u.def.section->output_section != NULL))
I'm pretty sure the case where "h == NULL" is the local symbol check. I
believe the h->dynindx == -1 verifies that we haven't created a dynamic
symbol (which would indicate that we've already got a .opd for this symbol).
This allocates space for the .opd entry, but doesn't initialize it. But
verifying that we've created the .opd space is probably the first step
in debugging this problem.
In theory you should be able to set up a simple test for this and either
trace through that routine for a local function symbol that's had its
address taken.
In your example code there's a fundamental code generation difference between
GCC and HPC.
GCC puts the address of the function into the constant pool, so we have
two instructions to get the address of the pool entry, and a third insn
to extract the data (ie, the address of the .opd descriptor). You should
have an FPTR64 relocation for g in the constant pool.
HP's compiler avoids a level of indirection by constructing the address
of the opd inline.
If you provide a stub "f" function in your example and compile it down to
an executable, you can find "g" in the opd table. First you run nm on the
resulting binary to find the actual address of "g". Then you run objdump -s
on the executable. Find the .opd section in the output, then search it for
the address of "g". An opd entry looks like this where each entry is an
8 byte quantity:
0
0
&function
dlt value
I just did this and it looks like we've got a .opd entry for "g".
The .data section contains the address of the .opd entry, so it's likely
the constant pool entry is OK.
The .dlt section contains the address of the constant pool entry in the
.data section. So it's probably OK.
And main references the .dlt entry in the instructions to load the
address of "g" to pass to "f".
Looking at it under the debugger, everything seems fine. Ugh. You'll
probably need to go through these steps with your larger example to
figure out where things go wrong.
jeff