From: david.jander@protonic.nl (David Jander)
To: linux-arm-kernel@lists.infradead.org
Subject: GCC 4.6.x miscompiling arm-linux?
Date: Mon, 10 Sep 2012 17:16:54 +0200 [thread overview]
Message-ID: <20120910171654.1d4972b2@archvile> (raw)
Hi all,
This probably is a GCC problem, but I am not entirely sure, and since I
stumbled upon this issue while debugging a kernel driver, it may have
something to do with how linux handles io-memory.
The symptoms became apparent when compiling latest mainline linux kernel for
the Freescale i.MX28 SoC, building the flexcan driver
(drivers/net/can/flexcan.c), using OSELAS.Toolchain GCC-4.6.2 for arm5te.
In the function flexcan_chip_start(), at line 775:
...
if (priv->devtype_data->hw_ver >= 10)
flexcan_write(0x0, ®s->rxfgmask);
...
The if() argument is false, but the CPU nevertheless crashes on a bus-error
writing to register ®s->rxfgmask!! The catch is, that in assembly, this
register is being _read_ conditionally, and then written _always_. Since this
register does not exist on the i.MX28 (hw_ver == 3), the CPU crashes.
I have no idea why GCC thinks it can do such a thing to a volatile memory
address. I have been able to reduce the code to just this bit:
/* Structure of the hardware registers */
struct flexcan_regs {
unsigned int mcr;
unsigned int rxfgmask;
};
#define flexcan_read(a) (*(volatile unsigned int *)(a))
#define flexcan_write(v,a) (*(volatile unsigned int *)(a) = (v))
int flexcan_chip_start(int ver, struct flexcan_regs *regs)
{
flexcan_write(0, ®s->mcr);
if (ver >= 10)
flexcan_write(0, ®s->rxfgmask);
return 0;
}
With GCC 4.6.x, using just "-Os", this compiles to:
...
.text
.align 2
.global flexcan_chip_start
.type flexcan_chip_start, %function
flexcan_chip_start:
@ args = 0, pretend = 0, frame = 0
@ frame_needed = 0, uses_anonymous_args = 0
@ link register save eliminated.
mov r3, #0
cmp r0, #9
str r3, [r1, #0]
ldrle r3, [r1, #4]
mov r0, #0
str r3, [r1, #4]
bx lr
.size flexcan_chip_start, .-flexcan_chip_start
.ident "GCC: (OSELAS.Toolchain-2011.11.1) 4.6.2"
.section .note.GNU-stack,"",%progbits
Notice the ldrle instruction followed by str. The "str r3, [r1, #4]" is always
executed, which would do no harm if it was a regular piece of RAM, but in this
case it is a non-existent peripheral register!
Is there a new way to tell this to the compiler? Am I missing something? Or it
this a GCC bug, and should I spam their respective mailing lists with this?
Any hint appreciated.
Best regards,
--
David Jander
Protonic Holland.
next reply other threads:[~2012-09-10 15:16 UTC|newest]
Thread overview: 20+ messages / expand[flat|nested] mbox.gz Atom feed top
2012-09-10 15:16 David Jander [this message]
2012-09-10 17:11 ` GCC 4.6.x miscompiling arm-linux? Matthew Leach
2012-09-11 7:27 ` David Jander
2012-09-11 7:54 ` David Jander
2012-09-11 8:11 ` Mikael Pettersson
2012-09-11 8:49 ` David Jander
2012-09-11 9:41 ` Mikael Pettersson
2012-09-11 10:37 ` David Jander
2012-09-11 11:35 ` Mikael Pettersson
2012-09-11 11:52 ` David Jander
2012-09-11 12:53 ` Mikael Pettersson
2012-09-11 13:43 ` David Jander
2012-09-11 14:10 ` Mikael Pettersson
2012-09-13 8:38 ` David Jander
2012-09-11 8:48 ` Sascha Hauer
2012-09-11 9:31 ` David Jander
2012-09-11 10:29 ` Michael Olbrich
2012-09-11 10:33 ` Matthew Leach
2012-09-11 10:42 ` David Jander
2012-09-11 13:07 ` Michael Olbrich
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20120910171654.1d4972b2@archvile \
--to=david.jander@protonic.nl \
--cc=linux-arm-kernel@lists.infradead.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).