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

Darius Augulis
2010-10-30T20:37:26Z

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.