* [parisc-linux] Non-bootable kernel problems
@ 2000-07-12 23:35 Richard Hirst
2000-07-13 17:14 ` Paul Bame
0 siblings, 1 reply; 17+ messages in thread
From: Richard Hirst @ 2000-07-12 23:35 UTC (permalink / raw)
To: parisc-linux
Current cvs kernel source doesn't boot. Looks like a linker problem
or bits of the kernel loaded in the wrong place to me...
I added the following to the end of net/ipv4/devinet.c:
void check_devinet(void)
{
printk("** devinet_sysctl.devinet_root_dir = %p\n", devinet_sysctl.devinet_root_dir);
printk("** devinet_sysctl.devinet_root_dir[0].procname = %p\n", devinet_sysctl.devinet_root_dir[0].procname);
printk("** devinet_sysctl.devinet_root_dir[0].procname = %s\n", devinet_sysctl.devinet_root_dir[0].procname);
}
and then added a call to check_devinet() to init/main.c() just after
printk(linux_banner). It should report procname as "net" from the table
in net/ipv4/devinet.c, but:
Linux version 2.3.99-pre8 (rhirst@rhirst.linuxcare.com) (gcc version 2.96.0614) #660 Thu Jul 13 00:21:59 BST 2000
** devinet_sysctl.devinet_root_dir = c0279814
** devinet_sysctl.devinet_root_dir[0].procname = c0143228
** devinet_sysctl.devinet_root_dir[0].procname = Multiply assigned logical unit
pagetable_init
Someone else can pick it up now while I sleep ;-)
Richard
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [parisc-linux] Non-bootable kernel problems
2000-07-12 23:35 [parisc-linux] Non-bootable kernel problems Richard Hirst
@ 2000-07-13 17:14 ` Paul Bame
2000-07-13 18:46 ` David Huggins-Daines
0 siblings, 1 reply; 17+ messages in thread
From: Paul Bame @ 2000-07-13 17:14 UTC (permalink / raw)
To: Alan Modra; +Cc: parisc-linux
More info on this one -- and yes it's the old problem come back to
haunt us.
Witness two functions:
static void * a2(void) {
return (void *)&devinet_sysctl.devinet_root_dir;
}
static void * a3(void) {
return (void *)&devinet_sysctl;
}
And their return values:
a3 c028b22c a2 c0289574
a2 should be c028b574 -- it's off by 0x2000 as Richard noted earlier.
a3() is OK and a2() is broken.
Here's disassembly from vmlinux via objdump:
c021b27c <a2>:
c021b27c: 2b 6f 00 00 addil 1e000,dp,%r1
c021b280: e8 40 c0 00 bv r0(rp)
c021b284: 34 3c 2a e9 ldo -a8c(r1),ret0
c021b288 <a3>:
c021b288: 2b 6f 00 00 addil 1e000,dp,%r1
c021b28c: e8 40 c0 00 bv r0(rp)
c021b290: 34 3c 24 58 ldo 122c(r1),ret0
The two ldo instructions should be showing a difference of 0x348 -- the
ofset of the member within the struct which I calculated separately. As
shown, the offsets differ by 0x2348. This code is hosed.
The object file says:
00000000 <a2>:
0: 2b 60 00 00 addil 0,dp,%r1
0: R_PARISC_DPREL21L .data+0x78
4: e8 40 c0 00 bv r0(rp)
8: 34 3c 00 00 ldo 0(r1),ret0
8: R_PARISC_DPREL14R .data+0x3c0
Disassembly of section .text.a3:
00000000 <a3>:
0: 2b 60 00 00 addil 0,dp,%r1
0: R_PARISC_DPREL21L .data+0x78
4: e8 40 c0 00 bv r0(rp)
8: 34 3c 00 00 ldo 0(r1),ret0
8: R_PARISC_DPREL14R .data+0x78
I think this code is right, because 0x3c0-0x78 is 0x348. I think this
makes this a linker problem. The off-by-0x2000 is suspicious
since the ldo offset is 14 bits and 2^14 = 0x2000.
For completeness here's what came out of the compiler, which looks cool
to me:
a1:
.PROC
.CALLINFO FRAME=0,NO_CALLS
.ENTRY
addil LR'devinet_sysctl-$global$,%r27
bv %r0(%r2)
ldw RR'devinet_sysctl-$global$+844(%r1),%r28
.EXIT
.PROCEND
a2:
.PROC
.CALLINFO FRAME=0,NO_CALLS
.ENTRY
addil LR'devinet_sysctl-$global$,%r27
bv %r0(%r2)
ldo RR'devinet_sysctl-$global$+840(%r1),%r28
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [parisc-linux] Non-bootable kernel problems
2000-07-13 17:14 ` Paul Bame
@ 2000-07-13 18:46 ` David Huggins-Daines
2000-07-13 21:14 ` David Huggins-Daines
0 siblings, 1 reply; 17+ messages in thread
From: David Huggins-Daines @ 2000-07-13 18:46 UTC (permalink / raw)
To: Paul Bame; +Cc: Alan Modra, parisc-linux
Paul Bame <bame@noam.fc.hp.com> writes:
> I think this code is right, because 0x3c0-0x78 is 0x348. I think this
> makes this a linker problem. The off-by-0x2000 is suspicious
> since the ldo offset is 14 bits and 2^14 = 0x2000.
It looks like binutils is incorrectly treating those fields as
unsigned, or has an off by one error, or something similar. The
reason why the version with the extra check and panic() makes it work
is because this makes gcc cleverly load the offset in the struct in
two steps. note:
devinet.c.1.3:
#warning Take this test out when GCC is fixed
if ((unsigned)&devinet_sysctl.devinet_root_dir <= (unsigned)&devinet_sysctl.devinet_vars) {
panic(__FILE__ ": probable gcc bug");
}
devinet_sysctl.sysctl_header =
register_sysctl_table(devinet_sysctl.devinet_root_dir, 0);
devinet.s.1.3:
addil LR'devinet_sysctl-$global$,%r27
ldo RR'devinet_sysctl-$global$+4(%r1),%r3 ; &devinet_sysctl.devinet_vars (offset 4)
ldo 836(%r3),%r19 ; &devinet_sysctl.devinet_root_dir (offset 840)
comb,>> %r19,%r3,.L2613
copy %r19,%r26 ; arg 0 of register_sysctl_table
ldil LR'.LC44,%r26
.CALL ARGW0=GR
bl panic,%r2
ldo RR'.LC44(%r26),%r26
.L2613:
.CALL ARGW0=GR,ARGW1=GR
bl register_sysctl_table,%r2
nop
relevant bits of hppa-linux-objdump -S vmlinux for 1.3:
c02ae538: 2b 6f 00 00 addil 1e000,dp,%r1
c02ae53c: 34 23 24 e0 ldo 1270(r1),r3
c02ae540: 34 73 06 88 ldo 344(r3),r19
c02ae544: 88 73 a0 18 cmpb,>> r19,r3,c02ae558 <.L2613>
c02ae548: 08 13 02 5a copy r19,r26
Note:
$ printf "%x\n" $((0x1270+0x344))
15b4
devinet.c.1.4:
devinet_sysctl.sysctl_header =
register_sysctl_table(devinet_sysctl.devinet_root_dir, 0);
devinet.s.1.4:
addil LR'devinet_sysctl-$global$,%r27
ldi 0,%r25
ldo RR'devinet_sysctl-$global$+840(%r1),%r4
.CALL ARGW0=GR,ARGW1=GR
bl register_sysctl_table,%r2
copy %r4,%r26
relevant bits of hppa-linux-objdump -S vmlinux for 1.4:
c02ae534: 2b 6f 00 00 addil 1e000,dp,%r1
c02ae538: 34 19 00 00 ldi 0,r25
c02ae53c: 34 24 2b 69 ldo -a4c(r1),r4
c02ae540: e8 5f 08 15 b,l c02ad950 <.Lfe1+0x118>,rp
c02ae544: 08 04 02 5a copy r4,r26
Note:
$ printf "%x\n" -0xa4c
fffff5b4
(and of course, the low 13 bits of that are 0x15b4)
I'm looking at the relevant binutils code right now.
--
dhd@linuxcare.com, http://www.linuxcare.com/
Linuxcare. Support for the revolution.
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [parisc-linux] Non-bootable kernel problems
2000-07-13 21:14 ` David Huggins-Daines
@ 2000-07-13 19:20 ` Jeffrey A Law
2000-07-14 16:10 ` David Huggins-Daines
2000-07-13 23:45 ` David Huggins-Daines
1 sibling, 1 reply; 17+ messages in thread
From: Jeffrey A Law @ 2000-07-13 19:20 UTC (permalink / raw)
To: David Huggins-Daines; +Cc: Paul Bame, Alan Modra, parisc-linux
In message <87sntd20mo.fsf@linuxcare.com>you write:
> David Huggins-Daines <dhd@linuxcare.com> writes:
>
> > It looks like binutils is incorrectly treating those fields as
> > unsigned, or has an off by one error, or something similar. The
>
> No. My mistake. binutils is doing the right thing, the problem is
> that, due to the way the LR' and RR' field selectors work, there is a
> bad interaction between cases in which the DPREL21L and DPREL14R (or
> any 21L and 14R relocations actually) are "split" like this, and ld
> -r, which tends to increase the addends to a point where LR' and RR'
> have different effects (LR' expects RR' to be positive, but it isn't).
> Then during final relocation, the wrong thing happens.
How/why is ld -r changing the addends? That seems wrong at first glance.
You might look at how the HP SOM tools handle addends during ld -r;
I suspect they don't change.
To the best of my knowledge GCC is using LR/RR in the prescribed way.
jeff
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [parisc-linux] Non-bootable kernel problems
2000-07-13 18:46 ` David Huggins-Daines
@ 2000-07-13 21:14 ` David Huggins-Daines
2000-07-13 19:20 ` Jeffrey A Law
2000-07-13 23:45 ` David Huggins-Daines
0 siblings, 2 replies; 17+ messages in thread
From: David Huggins-Daines @ 2000-07-13 21:14 UTC (permalink / raw)
To: Paul Bame; +Cc: Alan Modra, parisc-linux
David Huggins-Daines <dhd@linuxcare.com> writes:
> It looks like binutils is incorrectly treating those fields as
> unsigned, or has an off by one error, or something similar. The
No. My mistake. binutils is doing the right thing, the problem is
that, due to the way the LR' and RR' field selectors work, there is a
bad interaction between cases in which the DPREL21L and DPREL14R (or
any 21L and 14R relocations actually) are "split" like this, and ld
-r, which tends to increase the addends to a point where LR' and RR'
have different effects (LR' expects RR' to be positive, but it isn't).
Then during final relocation, the wrong thing happens.
So it would appear that this is a problem with GCC, but I'm not really
sure.
I'll have a better explanation once I work through the failure modes
and come up with a good short testcase.
--
dhd@linuxcare.com, http://www.linuxcare.com/
Linuxcare. Support for the revolution.
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [parisc-linux] Non-bootable kernel problems
2000-07-13 21:14 ` David Huggins-Daines
2000-07-13 19:20 ` Jeffrey A Law
@ 2000-07-13 23:45 ` David Huggins-Daines
2000-07-14 0:44 ` Alan Modra
1 sibling, 1 reply; 17+ messages in thread
From: David Huggins-Daines @ 2000-07-13 23:45 UTC (permalink / raw)
To: Paul Bame; +Cc: Alan Modra, parisc-linux
Okay, this is my final word on this for today, I promise that if I
send any more mail on it, it will include a patch :-)
David Huggins-Daines <dhd@linuxcare.com> writes:
> No. My mistake. binutils is doing the right thing, the problem is
> that, due to the way the LR' and RR' field selectors work, there is a
> bad interaction between cases in which the DPREL21L and DPREL14R (or
> any 21L and 14R relocations actually) are "split" like this, and ld
> -r, which tends to increase the addends to a point where LR' and RR'
> have different effects (LR' expects RR' to be positive, but it isn't).
> Then during final relocation, the wrong thing happens.
>
> I'll have a better explanation once I work through the failure modes
> and come up with a good short testcase.
Here is a small program that calculates RR' and LR' fields based on a
RELA according to the definitions in the PA-RISC ELF supplement:
#!/usr/bin/perl -w
use strict;
sub RND($) {
my $x = shift;
return (($x + 0x1000) & ~0x1fff);
}
sub R($) {
my $x = shift;
return $x & 0x7ff;
}
sub L($) {
my $x = shift;
return $x & ~0x7ff;
}
sub LR($$) {
my ($x, $a) = @_;
return L($x + RND($a));
}
sub RR($$) {
my ($x, $a) = @_;
return R($x + RND($a)) + ($a - RND($a));
}
while (<>) {
my ($value, $addend) = map hex, split;
my $lr = LR $value, $addend;
my $rr = RR $value, $addend;
printf "LR(%x, %x) = %x ; RR(%x, %x) = %x ; LR + RR = %x\n",
$value, $addend, $lr, $value, $addend, $rr, $lr + $rr;
}
__END__
Now, we see that in net/ipv4/devinet.o we have:
24: 2b 60 00 00 addil 0,dp,%r1
24: R_PARISC_DPREL21L .data+0x78
28: 34 19 00 00 ldi 0,r25
2c: 34 24 00 00 ldo 0(r1),r4
2c: R_PARISC_DPREL14R .data+0x3c0
Then, in net/ipv4/ipv4.o (which is produced by running ld -r on the
objects in that directory) we see that the addends have been increased:
b9c: 2b 60 00 00 addil 0,dp,%r1
b9c: R_PARISC_DPREL21L .data+0xd5c
ba0: 34 19 00 00 ldi 0,r25
ba4: 34 24 00 00 ldo 0(r1),r4
ba4: R_PARISC_DPREL14R .data+0x10a4
So, let's feed these addends to that script:
[dhd@tarwebok] ~/src/parisc/binutils-2.10$ perl test-broken-relocs.pl
0 78
LR(0, 78) = 0 ; RR(0, 78) = 78 ; LR + RR = 78
0 3c0
LR(0, 3c0) = 0 ; RR(0, 3c0) = 3c0 ; LR + RR = 3c0
In this case, you can see that everything is fine, because the LR
fields will contain the same values for both relocations.
But now, let's see what happens after we relink it:
[dhd@tarwebok] ~/src/parisc/binutils-2.10$ perl test-broken-relocs.pl
0 d5c
LR(0, d5c) = 0 ; RR(0, d5c) = d5c ; LR + RR = d5c
0 10a4
LR(0, 10a4) = 2000 ; RR(0, 10a4) = fffff0a4 ; LR + RR = 10a4
As you can see, now the LR fields are out of sync, and we get a
negative offset in the LDO instruction even though the addend + value
is still well within the range of a 14-bit signed field.
As far as I can tell, the ABI and possibly the instruction set are
broken by design by using an addition instead of a logical OR to fill
in the low bits of an immediate value [1]. But we have to cope with
this somehow.
> So it would appear that this is a problem with GCC, but I'm not really
> sure.
As far as I can tell, we can either fix this in GCC or in the linker.
I don't know if the linker is able to associate paired 21L and 14R
relocations, but if it were, I assume that it would be fairly easy to
make sure that they stay "in sync" with each other when linking with -r.
However, it could be argued that the real problem is that GCC always
omits the addend when outputting addil instructions for referring to
global data. For example, this C code:
struct foo {
int a[192];
int b;
};
struct foo f = {
{}, 42
}, g = {
{}, 666
};
int a(void* foo)
{
}
int main()
{
a(&f.a[145]);
a(&f.b);
a(&g.b);
return;
}
Generates the following assembly code (edited for length and content):
main:
.PROC
.CALLINFO FRAME=64,CALLS,SAVE_RP
.ENTRY
stw %r2,-20(%r30)
ldo 64(%r30),%r30
addil LR'f-$global$,%r27 ; look ma, no addend
.CALL ARGW0=GR
bl a,%r2
ldo RR'f-$global$+580(%r1),%r26 ; but we have one here!
addil LR'f-$global$,%r27 ; no addend
.CALL ARGW0=GR
bl a,%r2
ldo RR'f-$global$+768(%r1),%r26 ; addend
addil LR'g-$global$,%r27 ; no addend
.CALL ARGW0=GR
bl a,%r2
ldo RR'g-$global$+768(%r1),%r26 ; addend
ldw -84(%r30),%r2
bv %r0(%r2)
ldo -64(%r30),%r30
.EXIT
.PROCEND
I don't see any good reason why GCC cannot put the addends on the
ADDIL instructions as well. Manually munging the assembly code and
assembling it certainly produces correct output, and in fact doing the
same to net/ipv4/devinet.s in the kernel:
--- devinet.s~ Thu Jul 13 19:40:55 2000
+++ devinet.s Thu Jul 13 19:41:16 2000
@@ -2806,7 +2806,7 @@
.CALL ARGW0=GR
bl register_netdevice_notifier,%r2
ldo RR'ip_netdev_notifier-$global$(%r1),%r26
- addil LR'devinet_sysctl-$global$,%r27
+ addil LR'devinet_sysctl-$global$+840,%r27
ldi 0,%r25
ldo RR'devinet_sysctl-$global$+840(%r1),%r4
.CALL ARGW0=GR,ARGW1=GR
Fixes the non-booting problems :P
Of course, it would be a nice optimization if the above code could
reuse %r1 for different parts of the same structure, if it were of an
appropriate size. However GCC does not appear to do anything of the
sort, and reading the RTL dumps indicates that the addends are
actually present in the insns all the way up until final output (this
is the RTX for the ADDIL in the .27.dbr dump from the above program):
(insn 8 35 45 (set (reg:SI 1 %r1)
(high:SI (const:SI (plus:SI (symbol_ref:SI ("f"))
(const_int 580 [0x244]))))) 84 {post_std+6} (nil)
(expr_list:REG_EQUIV (high:SI (const:SI (plus:SI (symbol_ref:SI ("f"))
(const_int 580 [0x244]))))
(nil)))
Implementing the fix is left as an exercise to the writer (argh).
--
dhd@linuxcare.com, http://www.linuxcare.com/
Linuxcare. Support for the revolution.
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [parisc-linux] Non-bootable kernel problems
2000-07-13 23:45 ` David Huggins-Daines
@ 2000-07-14 0:44 ` Alan Modra
2000-07-14 16:02 ` Jeffrey A Law
0 siblings, 1 reply; 17+ messages in thread
From: Alan Modra @ 2000-07-14 0:44 UTC (permalink / raw)
To: David Huggins-Daines; +Cc: Paul Bame, Alan Modra, parisc-linux
On 13 Jul 2000, David Huggins-Daines wrote:
> Okay, this is my final word on this for today, I promise that if I
> send any more mail on it, it will include a patch :-)
Nice bit of debugging, David. Have a look in
gcc/config/pa/pa.c:output_global_address
/* How bogus. The compiler is apparently responsible for
rounding the constant if it uses an LR field selector.
The linker and/or assembler seem a better place since
they have to do this kind of thing already.
If we fail to do this, HP's optimizing linker may eliminate
an addil, but not update the ldw/stw/ldo instruction that
uses the result of the addil. */
if (round_constant)
offset = ((offset + 0x1000) & ~0x1fff);
Zap these two lines, and I think the problem will go away.
Alan Modra
--
Linuxcare. Support for the Revolution.
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [parisc-linux] Non-bootable kernel problems
2000-07-14 0:44 ` Alan Modra
@ 2000-07-14 16:02 ` Jeffrey A Law
2000-07-14 16:02 ` David Huggins-Daines
0 siblings, 1 reply; 17+ messages in thread
From: Jeffrey A Law @ 2000-07-14 16:02 UTC (permalink / raw)
To: Alan Modra; +Cc: David Huggins-Daines, Paul Bame, Alan Modra, parisc-linux
In message <Pine.LNX.4.21.0007141038590.15538-100000@front.linuxcare.com.au>y
ou write:
> On 13 Jul 2000, David Huggins-Daines wrote:
>
> > Okay, this is my final word on this for today, I promise that if I
> > send any more mail on it, it will include a patch :-)
>
> Nice bit of debugging, David. Have a look in
> gcc/config/pa/pa.c:output_global_address
>
> /* How bogus. The compiler is apparently responsible for
> rounding the constant if it uses an LR field selector.
>
> The linker and/or assembler seem a better place since
> they have to do this kind of thing already.
>
> If we fail to do this, HP's optimizing linker may eliminate
> an addil, but not update the ldw/stw/ldo instruction that
> uses the result of the addil. */
> if (round_constant)
> offset = ((offset + 0x1000) & ~0x1fff);
>
> Zap these two lines, and I think the problem will go away.
But that's totally the wrong thing to do as it will break hpux.
The linker is the problem.
jeff
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [parisc-linux] Non-bootable kernel problems
2000-07-14 16:02 ` Jeffrey A Law
@ 2000-07-14 16:02 ` David Huggins-Daines
2000-07-14 16:37 ` Jeffrey A Law
0 siblings, 1 reply; 17+ messages in thread
From: David Huggins-Daines @ 2000-07-14 16:02 UTC (permalink / raw)
To: law; +Cc: Alan Modra, Paul Bame, Alan Modra, parisc-linux
Jeffrey A Law <law@cygnus.com> writes:
> In message <Pine.LNX.4.21.0007141038590.15538-100000@front.linuxcare.com.au>y
> ou write:
> > Zap these two lines, and I think the problem will go away.
> But that's totally the wrong thing to do as it will break hpux.
>
> The linker is the problem.
I've conditionalized it on the existence of GNU ld, is that okay?
--
dhd@linuxcare.com, http://www.linuxcare.com/
Linuxcare. Support for the revolution.
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [parisc-linux] Non-bootable kernel problems
2000-07-13 19:20 ` Jeffrey A Law
@ 2000-07-14 16:10 ` David Huggins-Daines
2000-07-14 16:39 ` Jeffrey A Law
0 siblings, 1 reply; 17+ messages in thread
From: David Huggins-Daines @ 2000-07-14 16:10 UTC (permalink / raw)
To: law; +Cc: Paul Bame, Alan Modra, parisc-linux
Jeffrey A Law <law@cygnus.com> writes:
> How/why is ld -r changing the addends? That seems wrong at first glance.
The relocations in question are specified as <.data+0xf00>, and thus,
as far as I can tell, it has to change the addends since there is no
symbol value within .data that it can update.
--
dhd@linuxcare.com, http://www.linuxcare.com/
Linuxcare. Support for the revolution.
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [parisc-linux] Non-bootable kernel problems
2000-07-14 16:02 ` David Huggins-Daines
@ 2000-07-14 16:37 ` Jeffrey A Law
0 siblings, 0 replies; 17+ messages in thread
From: Jeffrey A Law @ 2000-07-14 16:37 UTC (permalink / raw)
To: David Huggins-Daines; +Cc: Alan Modra, Paul Bame, Alan Modra, parisc-linux
In message <87lmz4zoma.fsf@linuxcare.com>you write:
> Jeffrey A Law <law@cygnus.com> writes:
>
> > In message <Pine.LNX.4.21.0007141038590.15538-100000@front.linuxcare.co
> m.au>y
> > ou write:
> > > Zap these two lines, and I think the problem will go away.
> > But that's totally the wrong thing to do as it will break hpux.
> >
> > The linker is the problem.
>
> I've conditionalized it on the existence of GNU ld, is that okay?
No, because you're working around a bug in GNU-ld. GCC is following
the defined behavior for the PA32 ABI.
jeff
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [parisc-linux] Non-bootable kernel problems
2000-07-14 16:10 ` David Huggins-Daines
@ 2000-07-14 16:39 ` Jeffrey A Law
2000-07-14 18:53 ` David Huggins-Daines
0 siblings, 1 reply; 17+ messages in thread
From: Jeffrey A Law @ 2000-07-14 16:39 UTC (permalink / raw)
To: David Huggins-Daines; +Cc: Paul Bame, Alan Modra, parisc-linux
In message <87hf9szo9j.fsf@linuxcare.com>you write:
> Jeffrey A Law <law@cygnus.com> writes:
>
> > How/why is ld -r changing the addends? That seems wrong at first glance.
>
> The relocations in question are specified as <.data+0xf00>, and thus,
> as far as I can tell, it has to change the addends since there is no
> symbol value within .data that it can update.
Either we need to avoid merging the section symbols to avoid twiddling
the addend, or we need to avoid reducing relocs to section symbols to
begin with.
jeff
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [parisc-linux] Non-bootable kernel problems
2000-07-14 16:39 ` Jeffrey A Law
@ 2000-07-14 18:53 ` David Huggins-Daines
2000-07-14 20:40 ` David Huggins-Daines
2000-07-15 1:31 ` [parisc-linux] Non-bootable kernel problems Alan Modra
0 siblings, 2 replies; 17+ messages in thread
From: David Huggins-Daines @ 2000-07-14 18:53 UTC (permalink / raw)
To: law; +Cc: Alan Modra, parisc-linux
Jeffrey A Law <law@cygnus.com> writes:
> Either we need to avoid merging the section symbols to avoid twiddling
> the addend, or we need to avoid reducing relocs to section symbols to
> begin with.
We only reduce relocations to section symbols for static data. It
seems that every other platform I've investigated (Sparc, PowerPC,
Alpha) does the same thing, so, while I think it would be possible to
not reduce them on PA, I'm not sure what the unintended side effects
would be.
As for not merging section symbols ... I'm not sure how that would be
done, but if it's the only option I guess we can figure it out.
Alan: any thoughts on this?
--
dhd@linuxcare.com, http://www.linuxcare.com/
Linuxcare. Support for the revolution.
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [parisc-linux] Non-bootable kernel problems
2000-07-14 18:53 ` David Huggins-Daines
@ 2000-07-14 20:40 ` David Huggins-Daines
2000-07-14 22:14 ` GAS fix for reloc problems (was Re: [parisc-linux] Non-bootable kernel problems) David Huggins-Daines
2000-07-15 1:31 ` [parisc-linux] Non-bootable kernel problems Alan Modra
1 sibling, 1 reply; 17+ messages in thread
From: David Huggins-Daines @ 2000-07-14 20:40 UTC (permalink / raw)
To: law; +Cc: Alan Modra, parisc-linux
David Huggins-Daines <dhd@linuxcare.com> writes:
> Jeffrey A Law <law@cygnus.com> writes:
>
> > Either we need to avoid merging the section symbols to avoid twiddling
> > the addend, or we need to avoid reducing relocs to section symbols to
> > begin with.
>
> We only reduce relocations to section symbols for static data. It
> seems that every other platform I've investigated (Sparc, PowerPC,
> Alpha) does the same thing
Wait. I'm wrong. PowerPC doesn't:
static struct foo {
int a;
int b;
} a = {
a: 42,
b: 69
};
int main()
{
gar(&a.b);
...
}
Compiles to:
4c: 3d 20 00 00 lis r9,0
4e: R_PPC_ADDR16_HA a+0x4
50: 38 69 00 04 addi r3,r9,4
52: R_PPC_ADDR16_LO a+0x4
Okay, I'll investigate this approach.
--
dhd@linuxcare.com, http://www.linuxcare.com/
Linuxcare. Support for the revolution.
^ permalink raw reply [flat|nested] 17+ messages in thread
* GAS fix for reloc problems (was Re: [parisc-linux] Non-bootable kernel problems)
2000-07-14 20:40 ` David Huggins-Daines
@ 2000-07-14 22:14 ` David Huggins-Daines
2000-07-15 8:33 ` Alan Modra
0 siblings, 1 reply; 17+ messages in thread
From: David Huggins-Daines @ 2000-07-14 22:14 UTC (permalink / raw)
To: law; +Cc: Alan Modra, parisc-linux
David Huggins-Daines <dhd@linuxcare.com> writes:
> David Huggins-Daines <dhd@linuxcare.com> writes:
>
> > Jeffrey A Law <law@cygnus.com> writes:
> >
> > > Either we need to avoid merging the section symbols to avoid twiddling
> > > the addend, or we need to avoid reducing relocs to section symbols to
> > > begin with.
> Okay, I'll investigate this approach.
Done. PA-RISC porters, update your binutils-2.10 and GCC. (again :-)
Here's the patch, which I've committed to puffin CVS (I've
reverted the incorrect GCC changes):
2000-07-14 David Huggins-Daines <dhd@linuxcare.com>
* config/tc-hppa.c (hppa_fix_adjustable): Reject reductions of
sym-sym2 expressions as well as LR% and RR% fields on ELF targets
as well.
Index: tc-hppa.c
===================================================================
RCS file: /home/cvs/parisc/binutils-2.10/gas/config/tc-hppa.c,v
retrieving revision 1.12
retrieving revision 1.13
diff -u -r1.12 -r1.13
--- tc-hppa.c 2000/07/11 14:02:15 1.12
+++ tc-hppa.c 2000/07/14 21:48:42 1.13
@@ -8369,10 +8369,25 @@
/* Reject reductions of symbols in 32bit relocs. */
if (fixp->fx_r_type == R_HPPA && hppa_fix->fx_r_format == 32)
return 0;
+#endif
/* Reject reductions of symbols in sym1-sym2 expressions when
the fixup will occur in a CODE subspace.
+ NOTE: We want to reject these for ELF targets as well, because
+ otherwise we will lose in the case of 21L and 14R
+ relocations. (FIXME: will this break ELF64 targets?)
+
+ This is because, since the symbols are reduced, the linker has no
+ choice but to manipulate the addends when coalescing input .data
+ sections. Because the 32-bit ABI requires the compiler to
+ pre-round LR% field selectors, this means we end up with
+ different addends for the left and right relocations. Because of
+ the way LR% and RR% field selectors work, it's possible that the
+ RR% field will turn negative without the LR% field being rounded
+ accordingly, and your Linux kernel crashes mysteriously.
+ - dhd@linuxcare.com, 2000-07-14
+
XXX FIXME: Long term we probably want to reject all of these;
for example reducing in the debug section would lose if we ever
supported using the optimizing hp linker. */
@@ -8386,12 +8401,14 @@
}
/* We can't adjust any relocs that use LR% and RR% field selectors.
- That confuses the HP linker. */
+ That confuses the HP linker.
+
+ FIXME: do we actually need to do this for ELF32/GNU ld as well?
+ What about ELF64? */
if (hppa_fix->fx_r_field == e_lrsel
|| hppa_fix->fx_r_field == e_rrsel
|| hppa_fix->fx_r_field == e_nlrsel)
return 0;
-#endif
/* Reject reductions of symbols in DLT relative relocs,
relocations with plabels. */
--
dhd@linuxcare.com, http://www.linuxcare.com/
Linuxcare. Support for the revolution.
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [parisc-linux] Non-bootable kernel problems
2000-07-14 18:53 ` David Huggins-Daines
2000-07-14 20:40 ` David Huggins-Daines
@ 2000-07-15 1:31 ` Alan Modra
1 sibling, 0 replies; 17+ messages in thread
From: Alan Modra @ 2000-07-15 1:31 UTC (permalink / raw)
To: David Huggins-Daines; +Cc: Jeffrey A Law, parisc-linux
On 14 Jul 2000, David Huggins-Daines wrote:
> Alan: any thoughts on this?
My first thoughts when I read Jeff's email about my proposed removal of
the gcc hack for the hpux linker were along the lines of "two wrongs don't
make a right, so it's not surprising that ld -r is tripped up". That was
late last night just before I went to bed, and I'm glad I didn't reply
then, as Jeff is quite correct. The way those LR and RR field selectors
work means that a reloc addend cannot be modified under any circumstances.
Even if the gcc hack was removed, the linker would still do the wrong
thing with certain cases of one instruction with LR selector combined with
multiple instructions using RR selectors. Gross.
I'm not sure why the assembler is specifying the relocs against a sections
symbols - it's something I've noticed on x86 for a long time, and never
bothered to figure out why, as it didn't cause any problem. I'll have a
look.
Regards, Alan Modra
--
Linuxcare. Support for the Revolution.
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: GAS fix for reloc problems (was Re: [parisc-linux] Non-bootable kernel problems)
2000-07-14 22:14 ` GAS fix for reloc problems (was Re: [parisc-linux] Non-bootable kernel problems) David Huggins-Daines
@ 2000-07-15 8:33 ` Alan Modra
0 siblings, 0 replies; 17+ messages in thread
From: Alan Modra @ 2000-07-15 8:33 UTC (permalink / raw)
To: David Huggins-Daines; +Cc: parisc-linux
On 14 Jul 2000, David Huggins-Daines wrote:
> Done. PA-RISC porters, update your binutils-2.10 and GCC. (again :-)
Just a note on the patch. This particular bug existed in the elf hppa
assembler long before anyone tried porting linux to parisc - it's not
specific to the kernel. David's fix may just happen to cure some userland
problems too.
--
Linuxcare. Support for the Revolution.
^ permalink raw reply [flat|nested] 17+ messages in thread
end of thread, other threads:[~2000-07-15 8:32 UTC | newest]
Thread overview: 17+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2000-07-12 23:35 [parisc-linux] Non-bootable kernel problems Richard Hirst
2000-07-13 17:14 ` Paul Bame
2000-07-13 18:46 ` David Huggins-Daines
2000-07-13 21:14 ` David Huggins-Daines
2000-07-13 19:20 ` Jeffrey A Law
2000-07-14 16:10 ` David Huggins-Daines
2000-07-14 16:39 ` Jeffrey A Law
2000-07-14 18:53 ` David Huggins-Daines
2000-07-14 20:40 ` David Huggins-Daines
2000-07-14 22:14 ` GAS fix for reloc problems (was Re: [parisc-linux] Non-bootable kernel problems) David Huggins-Daines
2000-07-15 8:33 ` Alan Modra
2000-07-15 1:31 ` [parisc-linux] Non-bootable kernel problems Alan Modra
2000-07-13 23:45 ` David Huggins-Daines
2000-07-14 0:44 ` Alan Modra
2000-07-14 16:02 ` Jeffrey A Law
2000-07-14 16:02 ` David Huggins-Daines
2000-07-14 16:37 ` Jeffrey A Law
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.