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 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.