Bug 16604 - linker adds padding before rodata but doesn't adjust symbol
Summary: linker adds padding before rodata but doesn't adjust symbol
Status: RESOLVED INVALID
Alias: None
Product: binutils
Classification: Unclassified
Component: ld (show other bugs)
Version: 2.24
: P2 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2014-02-18 19:42 UTC by Joe Eykholt
Modified: 2014-02-25 04:54 UTC (History)
2 users (show)

See Also:
Host:
Target:
Build:
Last reconfirmed:


Attachments
archive of small program reproducing alignment issue (1.49 KB, application/x-gzip)
2014-02-18 19:42 UTC, Joe Eykholt
Details
archive of program with objects and executable (4.67 KB, application/x-gzip)
2014-02-21 18:58 UTC, Joe Eykholt
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Joe Eykholt 2014-02-18 19:42:42 UTC
Created attachment 7426 [details]
archive of small program reproducing alignment issue

A program that has an const char array initialized to {1, 2, 3, 4} sees the data as {0, 1, 2, 3} after linking.  It is thought that the linker must be padding with zeros without fixing the symbol offset, or something like that.  

Several things have to be true for this to happen.  It's very strange:
*  The program is cross-compiled for Cortex-M3.  Native x86 programs don't have this issue.
*  The program needs to be optimized for size, -Os.  The data file, too!
*  Specify -fdata-sections.


Attached is an archive with four very small files:
   dl.c contains the array initialization.  One 4-byte array, one long.
   dlm.c contains a main program just to reference the data.
   mod.ld is a linker script.
   Makefile.  Do make clean debug to build, and then display dlarray with
   gdb.  It'll show up as starting with 0 instead of 1.  Like this:
 
$ make clean debug
rm -f dl *.o
arm-none-eabi-gcc -mthumb -mcpu=cortex-m3 -mlittle-endian  -g  -Os  -fdata-sections -c -o dlm.o dlm.c
arm-none-eabi-gcc -mthumb -mcpu=cortex-m3 -mlittle-endian  -g  -Os  -fdata-sections -c -o dl.o dl.c
arm-none-eabi-gcc --version
arm-none-eabi-gcc (GCC) 4.6.1
Copyright (C) 2011 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

arm-none-eabi-ld --version
GNU ld (GNU Binutils) 2.21.1
Copyright 2011 Free Software Foundation, Inc.
This program is free software; you may redistribute it under the terms of
the GNU General Public License version 3 or (at your option) a later version.
This program has absolutely no warranty.
arm-none-eabi-gcc -g --static -Wl,-static -Wl,--cref -nostartfiles  -Wl,-T mod.ld -o dl dlm.o dl.o

Cross Reference Table

Symbol                                            File
_start                                            dlm.o
check                                             dlm.o
dlarray                                           dl.o
                                                  dlm.o
dlarray_size                                      dl.o
main                                              dlm.o
arm-none-eabi-gdb dl
GNU gdb (GDB) 7.3.1
Copyright (C) 2011 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "--host=i686-pc-linux-gnu --target=arm-none-eabi".
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>...
/home/jre/.gdbinit:2: Error in sourced command file:
No symbol table is loaded.  Use the "file" command.
Reading symbols from /home/jre/x/reloc/dl...done.
(gdb) x/4bu dlarray
0x8020056 <dlarray>:	0	1	2	3

If I change any of the essential elements of this, the array is correctly
shown by gdb as:

(gdb) x/4bu dlarray
0x8020088 <dlarray>:	1	2	3	4

I know I can work around this one instance in several ways, but I'm 
worried that -Os could cause similar but hard-to-diagnose problems 
throughout our large program if the root cause isn't known.
Comment 1 Joe Eykholt 2014-02-18 20:55:40 UTC
Also tried this with binutils 2.24 and had the same result.
Comment 2 Nick Clifton 2014-02-21 14:14:02 UTC
Hi Joe,

  I tried to reproduce this problem using the mainline versions of gcc, gdb and the binutils, but this failed.  (Ie the array contained the correct values).

  Please could you upload the dl.o and dlm.o object files and the broken dl executable so that I can have a look at them ?

Cheers
  Nick
Comment 3 Joe Eykholt 2014-02-21 18:58:19 UTC
Created attachment 7433 [details]
archive of program with objects and executable
Comment 4 Joe Eykholt 2014-02-21 18:59:18 UTC
Thank you very much for looking at this issue!  I attached a new .tgz with the objects.
Comment 5 Alan Modra 2014-02-22 02:34:27 UTC
This does not look like a linker problem. dl_array is linked at 0x8020057.  The symbol and debug info reflect this fact.  Now, examining dl_array under gdb looks at 0x8020056.  This is wrong, so perhaps this is a gdb bug, triggered by you putting .rodata into .text, an executable section.  Recall that arm uses the low bit of executable symbol addresses as a flag to mark thumb code.
Comment 6 Joe Eykholt 2014-02-22 04:56:11 UTC
Alan, thanks very much for explaining what I'm seeing in gdb.
This isn't the first time I've been confused or misled by 
way ARM uses the low-order bit of the PC.  

I was using gdb here to see the layout of the program without actually
downloading it but I'll look at it with objdump instead now.  Maybe my
problem can be avoided with a better linker script.   I believed I was
really getting the wrong data from the array in the program, not just from gdb,
so let me re-investigate that.  It seems unlikely at this point that
this is due to a ld problem.
Comment 7 Joe Eykholt 2014-02-25 04:52:47 UTC
After further investigation, my original problem is not linker-related or compiler-related, so this can be closed.  

Thanks to those who looked into this issue.
Comment 8 Joe Eykholt 2014-02-25 04:53:48 UTC
Not a bug.