"Hello World" program core dumps with GHC 4.08.1 on HPUX 10.2
0
BENNETT,ANDY (HP-Unitedkingdom,ex1)
andy_bennett at hp.com
Wed Mar 28 08:52:49 EST 2001
> Phew. I've just got around to trying this, and the initial
> results are
> as expected: gcc 2.95.2 causes the generated program to crash, whereas
> gcc 2.7.2.1 worked.
>
> There are some obvious differences in the code generated by
> 2.95.2. Try
> the following program:
>
> extern void f(void);
> void g(void) { void (*h)(void) = f; }
>
> compile it with gcc 2.95.2 and gcc 2.7.2. In the 2.95.2
> version, there
> is an extra indirection for f: the compiler generates some kind of
> static constant for it. That's what is causing GHC trouble. I assume
> this is the shared library support you were talking about before?
>
> Is there any way to stop gcc doing this, or do we just have to accept
> the extra indirection for every jump?
This took a bit of investigating, but there is a good reason, in theory, for
the change in behaviour. Consider the following:
#include <stdio.h>
void f() {}
void (*g(void))(void) { return f; }
int main(void) {
printf("g() = %x\n", g());
return 0;
}
With gcc-2.7.2.3 we get g() being (I'm getting the assembler from gdb post
link phase):
0x228c <g>: ldil L'0x40001000,%ret0
0x2290 <g+4>: bv %r0(%rp)
0x2294 <g+8>: ldo 0xf2(%ret0),%ret0
This is what you spoke of, with no indirection. With gcc-2.95.2:
0x2280 <g>: ldil L'0x40001000,%r19
0x2284 <g+4>: bv %r0(%rp)
0x2288 <g+8>: ldw 0xc0(%r19),%ret0
It has an extra indirection because it is using the deferred plabel table.
Unfortunately, gcc-2.95.2 has not done quite the right thing for the linker.
With the HP C compiler:
0x20f8 <g>: addil L'-0x800,%dp,%r1
0x20fc <g+4>: bv %r0(%rp)
0x2100 <g+8>: ldw 0x7c4(%r1),%ret0
and by activating the linker 'fastaccess' optimisation we see the whole
point of the indirection is to make the access very local to the data
pointer (%dp), in fact, close enough to make it a single load operation:
0x20b8 <g>: bv %r0(%rp)
0x20bc <g+4>: ldw -0x3c(%dp),%ret0
Providing the value is in primary cache (there is 1Mb of this on the latest
PA chips), the load is no more costly than the 'ldo' and there is no longer
a register dependence to potentially prevent out of order execution.
There may be some other dld benefits, but ld seemed capable of getting the
fixups right whether or not the addresses were getting loaded directly or
not.
It still doesn't explain why your version of gcc-2.7.2 does not generate
procedure labels when shared libraries are linked. However, I think the
greater issue is how to deal with this behaviour since I don't think it is
going to go away.
I can see two solutions:
1. Leave it be and use the work around I originally suggested to handle
procedure labels if they occur.
2. (Disgusting cludge) Let the evil mangler loose on the generated
tables.
Currently, the deferred table that gcc generates in the $DATA$
sub-space,
contains entries of the form:
.word P%<name of function>
It is these that provide the indirections. The PLT itself is produced
by
the linker. If the assembler sees field selectors, P%, LP% or RP%
(P',
LP' or RP' are synonyms) in directive or assembler mnemonic
arguments,
it means it should produce a fixup to create a pointer to the
corresponding PLT entry instead of using the actual address.
So, if the mangler replaced P%, LP% and RP% with F%, L% and R%
respectively (' versions also), for all pointers that we going to
ONLY
"goto *" to we could completely discard the procedure label stuff.
This will only work if there was no chance of any of ghc generated
code getting mixed up with system routines in the respect of these
new
function pointers. That is, in pointer comparisons (F%a == P%a, for
example) or non-"goto *" function calls (a()). Of course, putting any
ghc generated code in a shared library would still be impossible,
linking
with shared libraries would be providing proper procedure labels were
used in those contexts.
I hope this makes some sense.
> > > That sounds reasonable: you could try adding NSUBSPA to the
> > > T_MOVE_DIRVS
> > > declaration for HPPA in the mangler and see if that makes a
> > > difference.
> >
> > I'll give it a spin.
>
> did it work?
I only had the time for a quick play with this, and no, not as yet.
Irrespective of mangler modifications, I think there might be a bug in the
GNU assembler with respect to subspaces which gets shown up following the .s
file shuffling of the happy parser modules. That is, following a .NSUBSPA
line, any subsequent .SUBSPA lines reselect the first identically named
subspace, not the last created one.
I will keep trying, if I have the time.
Regards,
Andy.
More information about the Glasgow-haskell-bugs
mailing list