[RFC PATCH 0/1] Wrong structure alignment due to compiler attribute "section"

Dave Martin Dave.Martin at arm.com
Wed Mar 4 06:35:40 PST 2015


On Wed, Mar 04, 2015 at 12:40:34PM +0100, sanfilippo wrote:
> On 03.03.2015 15:41, Dave Martin wrote:
> 
> Dave,
> 
> thanks for your response.
> 
> >For the element _size_ issue, I'm confused.  On 32-bit, that
> >structure is clearly 196 bytes in size, with the alignment requirement
> >of void * (4 bytes)... so there's no clear reason why the linker
> >shouldn't be inserting extra padding.
> >
> >I can't reproduce this with my current tools (upstream binutils-2.24,
> >gcc-4.9.2).
> >
> >
> >Can you try to track down where this discrepancy is coming from?
> >
> >i.e.,
> >
> >  * If you're juggling with multiple kernel trees, make sure there
> >    are not differences between them that could be causing this, such
> >    as changes to linker scripts or header files that are involved
> >    in building these arrays.
> 
> I can reproduce this with a vanilla kernel (3.19) from kernel.org.
> What I do is:
> 
> - configure the kernel with mvebu_v5_defconfig
> - compile it
> 
> However this issue occurs (so far) only with this special toolchain:
> http://www.plugcomputer.org/405/us/gplugd/tool-chain/arm-marvell-linux-gnueabi.tar.bz2
> 
> If you like you can try this yourself. I am sure that you will get
> the same results.

Not really ;)  Please see what you can find out first (see below).

> 
> I tried the same with three other toolchains but with those the
> problem did not occur. I also tried other kernel configurations with
> that "problematic" toolchain, but also the problem did not occur any
> more.
> 
> So I think its either a bug in that compiler/linker or the current
> solution in vmlinux.lds.h does not work correct under some special
> circumstances.
> 
> >
> >  * See what the input to the assembler looks like, with regard to
> >    .align directives.
> >
> >  * See what the alignment of the affected sections is in each individual
> >    .o file.
> 
> Not sure what exactly I should check here. Could you be a bit more precise?
> 
> >  * See what __alignof__(struct of_device_id) evaluates to.
> 
> It evaluates to "4" even for the bad case.

Try

rm drivers/clk/mvebu/kirkwood.o
make ARCH=arm KBUILD_CFLAGS_KERNEL=-save-temps drivers/clk/mvebu/kirkwood.o

(abuse of KBUILD_CFLAGS_KERNEL here, but it's empty by default, and
I'm too lazy to copy-paste command lines...)


The compiler will split out the compiled assembly code in kirkwood.s:

Look for ".align" directives between the start of the affected section
and the start of the next section (next .section directive).

Here, we just have .align 2, which is the expected correct value
(i.e., align __of_table_mv88f6180_clk on a 2^2 = 4 byte boundary).

A different value here may indicate a bug in the compiler, because
you observed that gcc _thinks_ that __alignof__ is 4 for the struct
in this section even in the failing case.


	.section	__clk_of_table,"a",%progbits
	.align	2
	.type	__of_table_mv88f6180_clk, %object
	.size	__of_table_mv88f6180_clk, 196
__of_table_mv88f6180_clk:
	.space	64
	.ascii	"marvell,mv88f6180-core-clock\000"
	.space	99
	.word	kirkwood_clk_init
	.type	__of_table_kirkwood_clk, %object
	.size	__of_table_kirkwood_clk, 196
__of_table_kirkwood_clk:
	.space	64
	.ascii	"marvell,kirkwood-core-clock\000"
	.space	100
	.word	kirkwood_clk_init
	.section	.rodata.str1.8,"aMS",%progbits,1


Also try:

	arm-linux-gnueabi-objdump --headers drivers/clk/mvebu/kirkwood.o

Sections:
Idx Name          Size      VMA       LMA       File off  Algn

	[...]

  9 __clk_of_table 00000188  00000000  00000000  00000434  2**2
                  CONTENTS, ALLOC, LOAD, RELOC, READONLY, DATA

The "Algn" column should be 2**2.  If it's not, but the assembly
code generated by the compiler looks correct, then there may be
a bug in the assembler.


If the .o file looks correct, it's possible that there is another
.o file containing data for this section that specifies a different
alignment.o -- try git grep CLK_OF_DECLARE to find the affected
files.

It's also worth looking at __clk_of_table_end in drivers/clk/clk.o.
That gets merged in at the end of the same section, so if its
alignment is higher for some reason, that might be causing the
problem.


Cheers
---Dave




More information about the linux-arm-kernel mailing list