[U-Boot] ARM: problem with linker option -pie

Hi all,
I've found solution which solves problem of empty command table. Actually the problem is -pie linker option. I removed it and added -fPIC flag to compiler options. Because relocation with such changes fails, I set TEXT_BASE equal to runtime calculated relocation address. And it works! All commands are there.
There is this dummy patch:
diff --git a/arch/arm/config.mk b/arch/arm/config.mk index 4e165bf..2046c32 100644 --- a/arch/arm/config.mk +++ b/arch/arm/config.mk @@ -33,7 +33,7 @@ STANDALONE_LOAD_ADDR = 0xc100000 endif endif
-PLATFORM_CPPFLAGS += -DCONFIG_ARM -D__ARM__ +PLATFORM_CPPFLAGS += -DCONFIG_ARM -D__ARM__ -fPIC
# Explicitly specifiy 32-bit ARM ISA since toolchain default can be -mthumb: PLATFORM_CPPFLAGS += $(call cc-option,-marm,) @@ -67,5 +67,4 @@ LDSCRIPT := $(SRCTREE)/$(CPUDIR)/u-boot.lds
# needed for relocation ifndef CONFIG_NAND_SPL -PLATFORM_LDFLAGS += -pie endif
And there is small patch for debugging command table:
diff --git a/common/hush.c b/common/hush.c index 2188fd4..be92968 100644 --- a/common/hush.c +++ b/common/hush.c @@ -1675,6 +1675,10 @@ static int run_pipe_real(struct pipe *pi) /* Look up command in command table */
+ printf("%s %d: cmd_tbl_s: %X, cmd_tbl_e: %X, len: %d\n", + __func__, __LINE__, + &__u_boot_cmd_start, &__u_boot_cmd_end, + &__u_boot_cmd_end - &__u_boot_cmd_start); if ((cmdtp = find_cmd(child->argv[i])) == NULL) { printf ("Unknown command '%s' - try 'help'\n", child->argv[i]); return -1; /* give up after bad command */
Also I did one test with linker script. I defined variable in start.S:
.globl _cmd_start _cmd_start: .word __u_boot_cmd_start
__u_boot_cmd_start is exported in linker script. Without my patch, disassembled elf looks like this:
<...> 57e00048 <_cmd_start>: 57e00048: 00000000 .word 0x00000000 <...>
while with patch applied:
<..> 57fcb048 <_cmd_start>: 57fcb048: 57fea2b0 .word 0x57fea2b0 <..>
Also disassembling u-boot-spl shows good result because there isn't -pie linker option. It's interesting, because if I define .word __u_boot_cmd_start - _start, then *offset* is calculated correctly. So, I assume, with -pie, linker doesn't export variables correctly and in my case pointer to command table is always null.
Eric, could your please test your board in the same way I have described and find out whether it helps? This could be toolchain version dependent and other people may not have this problem.
Darius.

Dear Darius Augulis,
In message 4CCC8206.40206@gmail.com you wrote:
I've found solution which solves problem of empty command table. Actually the problem is -pie linker option. I removed it and added -fPIC flag to compiler options. Because relocation with such changes fails, I set TEXT_BASE equal to runtime calculated relocation address. And it works! All commands are there.
Sorry, but this is not a solution. You may use this as momentary workaround if you need a running system, but it cannot go into mainline.
Best regards,
Wolfgang Denk

Hi Wolfgang,
On 10/30/2010 11:43 PM, Wolfgang Denk wrote:
Dear Darius Augulis,
In message4CCC8206.40206@gmail.com you wrote:
I've found solution which solves problem of empty command table. Actually the problem is -pie linker option. I removed it and added -fPIC flag to compiler options. Because relocation with such changes fails, I set TEXT_BASE equal to runtime calculated relocation address. And it works! All commands are there.
Sorry, but this is not a solution. You may use this as momentary workaround if you need a running system, but it cannot go into mainline.
Of course not. I just wanted inform that -pie is not working. Actually I don't know how to fix it correctly. It's may be interesting for more people, especially who wrote relocation code. At least one person except me in this list faced the same problem. Maybe somebody could do test with different compiler/binutils versions and figure out whether is it depended or not. I have only single ARM toolchain and can't do such test yet.
Darius.
Best regards,
Wolfgang Denk

Dear Darius Augulis,
In message 4CCC85B4.6060102@gmail.com you wrote:
Sorry, but this is not a solution. You may use this as momentary workaround if you need a running system, but it cannot go into mainline.
Of course not. I just wanted inform that -pie is not working. Actually I don't know how to fix it correctly. It's may be interesting for more people, especially who wrote relocation code.
Which exact tool chain are you using?
Do you have a chance to build with ELDK 4.2?
Or, if your code is all in mainline (or you are willing to send me patches), would you test an image that I compile for you, using LDK 4.2?
Best regards,
Wolfgang Denk

Le 30/10/2010 23:17, Wolfgang Denk a écrit :
Dear Darius Augulis,
In message4CCC85B4.6060102@gmail.com you wrote:
Sorry, but this is not a solution. You may use this as momentary workaround if you need a running system, but it cannot go into mainline.
Of course not. I just wanted inform that -pie is not working. Actually I don't know how to fix it correctly. It's may be interesting for more people, especially who wrote relocation code.
Which exact tool chain are you using?
Do you have a chance to build with ELDK 4.2?
Or, if your code is all in mainline (or you are willing to send me patches), would you test an image that I compile for you, using LDK 4.2?
Best regards,
Wolfgang Denk
I would really like it if someone, especially Alexander or Darius or both, could build u-boot and send me the whole u-boot ELF binary (not the raw binary) along with the commit ID of the source tree they built and the exact version of binutils they use, so that I can look up and compare the whole things. It could be a change in the relocation code of binutils, for instance; but I can't find out without the ELF binaries.
I don't need the -fPIC version; the one with -pie alone is the one I need.
Amicalement,

All,
Thanks to Wolfgang and Alexander who offered help offline in order to track down the issue. Currently we know that the ELDK 4.2 toolchain "works" and the CodeSourcery 4.4.1 (arm-2010q1-202) "does not work".
A preliminary test of both the ELDK and the CS toolchains on a small program which uses one each of const, initialized and uninitialized globals shows that while the EABI version has moved from 4 to 5, and the code generator has changed, both toolchains generate the same number of relocations for the same locations, albeit in a different order; so at least we know that all required fixups are present with both chains.
On u-boot, the overall number of relocations is smaller with the CS toolchain but apparently this is due to the code generator generating less literals per function.
Tomorrow (sorry : later this morning) I'll build the OpenRD binaries with both toolchains and test it.
Meanwhile, I would still like Alexander to add printf()s to then nand init functions so that we know at which address they think they nand_chip should be written to, and compare that to the printf() that shows at which address nand_chip is supposed to be read.
Amicalement,

Le 31/10/2010 01:31, Albert ARIBAUD a écrit :
All,
I can now reproduce the issue using ELDK 4.2 ("works") and CS arm-2010q1-202 ("does not work") toolchains on openrd_base and current tip of master plus Alexander's RFC patch. CS toolchain emits lots of warnings about type-punned pointer dereferencing, though none in nand code, and I think these are not related to our issue.
I will now analyze the patch code to see if it contains relocations that should have applied but did not, or if it misses relocations altogether. My currently favored bet right now is that BSS may have gotten its own relocation table in later toolchains, but that's only a bet.
Amicalement,

Dear Albert ARIBAUD,
CS toolchain emits lots of warnings about type-punned pointer dereferencing, though none in nand code, and I think these are not related to our issue.
Same with gcc 4.3.5
I will now analyze the patch code to see if it contains relocations that should have applied but did not, or if it misses relocations altogether. My currently favored bet right now is that BSS may have gotten its own relocation table in later toolchains, but that's only a bet.
u-boot.bin is 257KiB with 4.2.4 but only 251KiB with 4.3.5 ! Either its much better optimised or the relocation info shrunk which _might_ indicate something is missing in it...
Compiled with 4.3.5 last output is the "DRAM: 64 MiB" message. Then silence.
I suppose you don't need u-boot.elf from me, if otherwise, ping me:)
Best Regards, Reinhard

Hi Reinhart,
Le 31/10/2010 09:40, Reinhard Meyer a écrit :
Dear Albert ARIBAUD,
CS toolchain emits lots of warnings about type-punned pointer dereferencing, though none in nand code, and I think these are not related to our issue.
Same with gcc 4.3.5
I will now analyze the patch code to see if it contains relocations that should have applied but did not, or if it misses relocations altogether. My currently favored bet right now is that BSS may have gotten its own relocation table in later toolchains, but that's only a bet.
u-boot.bin is 257KiB with 4.2.4 but only 251KiB with 4.3.5 ! Either its much better optimised or the relocation info shrunk which _might_ indicate something is missing in it...
From what I see, the code generator emits "denser" code, which *could* result in a smaller relocation table, but that depends if the denser code does uses less literals (they're what makes the size of relocation tables). So I have to dive into some sample functions and see for myself; the fact that the linker obviously reorders code within .text does not help me much. :/
Compiled with 4.3.5 last output is the "DRAM: 64 MiB" message. Then silence.
I suppose you don't need u-boot.elf from me, if otherwise, ping me:)
I'm ok now that I have a non-working toolchain to play with. :)
Best Regards, Reinhard
Amicalement,

Dear Reinhard Meyer,
In message 4CCD2B7C.3040804@emk-elektronik.de you wrote:
u-boot.bin is 257KiB with 4.2.4 but only 251KiB with 4.3.5 ! Either its much better optimised or the relocation info shrunk which _might_ indicate something is missing in it...
Compiled with 4.3.5 last output is the "DRAM: 64 MiB" message. Then silence.
Confirmed: the tx25 board which runs fine when built with ELDK hangs after the DRAM message as well.
Best regards,
Wolfgang Denk

Dear Albert ARIBAUD,
In message 4CCD26B7.8090503@free.fr you wrote:
I can now reproduce the issue using ELDK 4.2 ("works") and CS arm-2010q1-202 ("does not work") toolchains on openrd_base and current tip of master plus Alexander's RFC patch. CS toolchain emits lots of warnings about type-punned pointer dereferencing, though none in nand code, and I think these are not related to our issue.
These are indeed unrelated.
I will now analyze the patch code to see if it contains relocations that should have applied but did not, or if it misses relocations altogether. My currently favored bet right now is that BSS may have gotten its own relocation table in later toolchains, but that's only a bet.
Hm.... probably not BSS as such, but eventually the linker treats segments without "LOAD" attribute differently?
Best regards,
Wolfgang Denk

Le 31/10/2010 10:24, Wolfgang Denk a écrit :
I will now analyze the patch code to see if it contains relocations that should have applied but did not, or if it misses relocations altogether. My currently favored bet right now is that BSS may have gotten its own relocation table in later toolchains, but that's only a bet.
Hm.... probably not BSS as such, but eventually the linker treats segments without "LOAD" attribute differently?
The first test I did with a sample program which contains the three types of static scope objects: const, initialized and uninitialized, and I checked that the inititialized one lands in BSS which has NOBITS while explicitely initialized objects land in data sections with PROGBITS -- that's akin to the LOAD attribute.
Both the ELDK 4.2 and the CS toolchains' linkers treat all three object types the same way with respect to relocation, and emit relocations to the uninitialized object, so not having LOAD attribute is irrelevant -- BTW if it was, BSS relocation would never have worked.
Best regards,
Wolfgang Denk
Amicalement,

Dear Albert ARIBAUD,
In message 4CCD3A6F.7040303@free.fr you wrote:
The first test I did with a sample program which contains the three types of static scope objects: const, initialized and uninitialized, and I checked that the inititialized one lands in BSS which has NOBITS while explicitely initialized objects land in data sections with PROGBITS -- that's akin to the LOAD attribute.
Thanks for checking.
Both the ELDK 4.2 and the CS toolchains' linkers treat all three object types the same way with respect to relocation, and emit relocations to the uninitialized object, so not having LOAD attribute is irrelevant -- BTW if it was, BSS relocation would never have worked.
Yes, I know. My speculation was that suchbehaviour (or linker options to adjust it) might have changed in more recent versions of gcc/binutils.
BTW: I would like to point out that so far we're blaming GCC, which is not exaclt correct, as we always tested GCC+Binutils combos. For completeness, we should separate compilation and linking and test for example ELDK's gcc with CS's ld, and vice versa. Hope I will find some time later this night. Hope the ghosts won't make too much of a noise.
Best regards,
Wolfgang Denk

Le 31/10/2010 11:35, Wolfgang Denk a écrit :
Dear Albert ARIBAUD,
In message4CCD3A6F.7040303@free.fr you wrote:
The first test I did with a sample program which contains the three types of static scope objects: const, initialized and uninitialized, and I checked that the inititialized one lands in BSS which has NOBITS while explicitely initialized objects land in data sections with PROGBITS -- that's akin to the LOAD attribute.
Thanks for checking.
Both the ELDK 4.2 and the CS toolchains' linkers treat all three object types the same way with respect to relocation, and emit relocations to the uninitialized object, so not having LOAD attribute is irrelevant -- BTW if it was, BSS relocation would never have worked.
Yes, I know. My speculation was that suchbehaviour (or linker options to adjust it) might have changed in more recent versions of gcc/binutils.
Understood. Apparently it hasn't as such.
BTW: I would like to point out that so far we're blaming GCC, which is not exaclt correct, as we always tested GCC+Binutils combos. For completeness, we should separate compilation and linking and test for example ELDK's gcc with CS's ld, and vice versa. Hope I will find some time later this night. Hope the ghosts won't make too much of a noise.
Correct, gcc and binutils are different things. In my (admittedly simple) test I'd looked at both toe .o files and the elf binaries, so either stage seems ok; and you're correct that 'cross-building' one gcc with the other linker is a useful set of tests to perform.
For the sake of completeness, as a reminder, the -pie option is a pure linker option: the gcc stage is the same whether ELF relocation is generated or not; that would *slightly* weight toward the linker as a culprit, but let's not haste to conclusions especially with such a weird issue.
I'll try 'cross-building' either this morning or in the early afternoon.
Best regards,
Wolfgang Denk
Amicalement,

Le 31/10/2010 11:57, Albert ARIBAUD a écrit :
I'll try 'cross-building' either this morning or in the early afternoon.
Linking the CodeSourcery objects with the ELDK 4.2 linker gives a functional u-boot with no "bad BSS" warning.
Seems like we can narrow down on binutils as I suspected.
I'll try the reverse (ELDK objects and CS linker) to see if the issue is seen then.
Amicalement,

Le 31/10/2010 12:30, Albert ARIBAUD a écrit :
Le 31/10/2010 11:57, Albert ARIBAUD a écrit :
I'll try 'cross-building' either this morning or in the early afternoon.
Linking the CodeSourcery objects with the ELDK 4.2 linker gives a functional u-boot with no "bad BSS" warning.
Seems like we can narrow down on binutils as I suspected.
... or maybe not.
Cross-building with one gcc and the other ld leads to the following obvious observation:
ELDK gcc plus ELDK or CS ld produces 3899 or 3898 .rel.dyn entries respectively whereas CS gcc plus CS or ELDK produces 949 or 950 .rel.dyn entries respectively, and I don't see a two-third drop in the number of literals which require relocation that would explain this difference.
Since changing the linker leaves almost the same relocation entry count, but changing gcc radically changes it, I now suspect the gcc part of the build rather than the ld.
One possible track is the use of -fPIE or -fpie while compiling and linking, I'm investigating this right now.
Amicalement,

On 10/31/2010 12:17 AM, Wolfgang Denk wrote:
Dear Darius Augulis,
In message4CCC85B4.6060102@gmail.com you wrote:
Sorry, but this is not a solution. You may use this as momentary workaround if you need a running system, but it cannot go into mainline.
Of course not. I just wanted inform that -pie is not working. Actually I don't know how to fix it correctly. It's may be interesting for more people, especially who wrote relocation code.
Which exact tool chain are you using?
I use toolchain from Buildroot compiled from sources on my ubuntu 10.04 host. I have made some testing today:
gcc 4.4.5 + binutils 2.19 - works ok gcc 4.2.4 + binutils 2.19 - works ok gcc 4.4.5 + binutils 2.20.1 - fails gcc 4.2.4 + binutils 2.20.1 - fails gcc 4.4.5 + binutils 2.20 - fails
Results show that it doesn't depend on compiler version and depends only on binutils - v2.20 and higher versions doesn't work.
Darius.
Do you have a chance to build with ELDK 4.2?
Or, if your code is all in mainline (or you are willing to send me patches), would you test an image that I compile for you, using LDK 4.2?
Best regards,
Wolfgang Denk

Hello Darius,
Darius Augulis wrote:
I've found solution which solves problem of empty command table. Actually the problem is -pie linker option. I removed it and added -fPIC flag to compiler options. Because relocation with such changes fails, I set TEXT_BASE equal to runtime calculated relocation address. And it works! All commands are there.
Which toolchain do you use?
Can you try ELDK-4.2, seems to me newer gcc have problems with -pie
bye, Heiko
participants (5)
-
Albert ARIBAUD
-
Darius Augulis
-
Heiko Schocher
-
Reinhard Meyer
-
Wolfgang Denk