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: Special names tha ld needs to recognize for hppa64-hp-hpux11.X


 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


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