[U-Boot] [PATCH] examples/standalone: Remove relocation compile flags for PowerPC

Previously, standalone applications were compiled with gcc flags that produced relocatable executables on the PowerPC architecture (eg with the -mrelocatable and -fPIC flags). There's no reason for these applications to be fully relocatable at this time since no relocation fixups are performed on standalone applications.
Additionally, removing the gcc relocation flags results in the entry point of applications residing at the base of the image. When a standalone application was relocatable, the entry point was generally located at an offset into the image which was confusing and prone to errors.
This change moves the entry point of PowerPC standalone applications from 0x40004 (usually) to 0x40000.
Signed-off-by: Peter Tyser ptyser@xes-inc.com --- I tested this on an 8548-based board and it worked as described above. It wouldn't hurt if a few others tried it out to validate that the new entry point is always 0x40000.
examples/standalone/Makefile | 8 ++++++++ 1 files changed, 8 insertions(+), 0 deletions(-)
diff --git a/examples/standalone/Makefile b/examples/standalone/Makefile index 6ea3b93..0c8dbe7 100644 --- a/examples/standalone/Makefile +++ b/examples/standalone/Makefile @@ -72,6 +72,14 @@ gcclibdir := $(shell dirname `$(CC) -print-libgcc-file-name`)
CPPFLAGS += -I..
+# For PowerPC there's no need to compile standalone applications as a +# relocatable executable. The relocation data is not needed, and +# also causes the entry point of the standalone application to be +# inconsistent. +ifeq ($(ARCH),powerpc) +CFLAGS := $(filter-out $(RELFLAGS),$(CFLAGS)) +endif + all: $(obj).depend $(OBJS) $(LIB) $(SREC) $(BIN) $(ELF)
#########################################################################

Peter Tyser wrote:
Previously, standalone applications were compiled with gcc flags that produced relocatable executables on the PowerPC architecture (eg with the -mrelocatable and -fPIC flags). There's no reason for these applications to be fully relocatable at this time since no relocation fixups are performed on standalone applications.
This didn't work for me. The entry point for my application in 401b4. Here's the build output:
make[1]: Entering directory `/home/b04825/git/u-boot.4737/examples/standalone' powerpc-linux-gnu-gcc -g -Os -mrelocatable -fPIC -ffixed-r14 -meabi -D__KERNEL__ -DTEXT_BASE=0xeff80000 -DRESET_VECTOR_ADDRESS=0xeffffffc -I/home/b04825/git/u-boot.4737/include -fno-builtin -ffreestanding -nostdinc -isystem /opt/freescale/usr/local/gcc-4.3.74-eglibc-2.8.74-6/powerpc-linux-gnu/bin/../lib/gcc/powerpc-linux-gnu/4.3.2/include -pipe -DCONFIG_PPC -D__powerpc__ -ffixed-r2 -Wa,-me500 -msoft-float -mno-string -mspe=yes -mno-spe -Wall -Wstrict-prototypes -fno-stack-protector -o flash_wp.o flash_wp.c -c powerpc-linux-gnu-ar crv libstubs.a ppc_longjmp.o ppc_setjmp.o stubs.o r - ppc_longjmp.o r - ppc_setjmp.o r - stubs.o powerpc-linux-gnu-ld -g -Ttext 0x40000 \ -o hello_world -e hello_world hello_world.o libstubs.a \ -L/opt/freescale/usr/local/gcc-4.3.74-eglibc-2.8.74-6/powerpc-linux-gnu/bin/../lib/gcc/powerpc-linux-gnu/4.3.2 -lgcc powerpc-linux-gnu-objcopy -O srec hello_world hello_world.srec 2>/dev/null powerpc-linux-gnu-ld -g -Ttext 0x40000 \ -o flash_wp -e flash_wp flash_wp.o libstubs.a \ -L/opt/freescale/usr/local/gcc-4.3.74-eglibc-2.8.74-6/powerpc-linux-gnu/bin/../lib/gcc/powerpc-linux-gnu/4.3.2 -lgcc powerpc-linux-gnu-objcopy -O srec flash_wp flash_wp.srec 2>/dev/null powerpc-linux-gnu-ld -g -Ttext 0x40000 \ -o sched -e sched sched.o libstubs.a \ -L/opt/freescale/usr/local/gcc-4.3.74-eglibc-2.8.74-6/powerpc-linux-gnu/bin/../lib/gcc/powerpc-linux-gnu/4.3.2 -lgcc powerpc-linux-gnu-objcopy -O srec sched sched.srec 2>/dev/null powerpc-linux-gnu-objcopy -O binary hello_world hello_world.bin 2>/dev/null powerpc-linux-gnu-objcopy -O binary flash_wp flash_wp.bin 2>/dev/null powerpc-linux-gnu-objcopy -O binary sched sched.bin 2>/dev/null make[1]: Leaving directory `/home/b04825/git/u-boot.4737/examples/standalone'

Timur Tabi wrote:
Peter Tyser wrote:
Previously, standalone applications were compiled with gcc flags that produced relocatable executables on the PowerPC architecture (eg with the -mrelocatable and -fPIC flags). There's no reason for these applications to be fully relocatable at this time since no relocation fixups are performed on standalone applications.
This didn't work for me. The entry point for my application in 401b4.
So if I comment-out the ifeq, like this:
#ifeq ($(ARCH),powerpc) CFLAGS := $(filter-out $(RELFLAGS),$(CFLAGS)) #endif
and build, I get these errors:
powerpc-linux-gnu-ld: libstubs.a(ppc_longjmp.o): compiled with -mrelocatable and linked with modules compiled normally powerpc-linux-gnu-ld: failed to merge target specific data of file libstubs.a(ppc_longjmp.o) powerpc-linux-gnu-ld: libstubs.a(ppc_setjmp.o): compiled with -mrelocatable and linked with modules compiled normally powerpc-linux-gnu-ld: failed to merge target specific data of file libstubs.a(ppc_setjmp.o)

On Tue, 2010-06-15 at 14:05 -0500, Timur Tabi wrote:
Timur Tabi wrote:
Peter Tyser wrote:
Previously, standalone applications were compiled with gcc flags that produced relocatable executables on the PowerPC architecture (eg with the -mrelocatable and -fPIC flags). There's no reason for these applications to be fully relocatable at this time since no relocation fixups are performed on standalone applications.
This didn't work for me. The entry point for my application in 401b4.
So if I comment-out the ifeq, like this:
#ifeq ($(ARCH),powerpc) CFLAGS := $(filter-out $(RELFLAGS),$(CFLAGS)) #endif
and build, I get these errors:
powerpc-linux-gnu-ld: libstubs.a(ppc_longjmp.o): compiled with -mrelocatable and linked with modules compiled normally powerpc-linux-gnu-ld: failed to merge target specific data of file libstubs.a(ppc_longjmp.o) powerpc-linux-gnu-ld: libstubs.a(ppc_setjmp.o): compiled with -mrelocatable and linked with modules compiled normally powerpc-linux-gnu-ld: failed to merge target specific data of file libstubs.a(ppc_setjmp.o)
Can you do a 'make clean', then recompile?
Thanks, Peter

On Tue, 2010-06-15 at 14:20 -0500, Timur Tabi wrote:
Peter Tyser wrote:
Can you do a 'make clean', then recompile?
That *was* with a 'make clean'.
Just to be sure, where did the output in your first email come from? It looked like a successful compile, but libstubs wasn't recompiled (I didn't see it in your pasted output). What changed between that 1st email and the 2nd email?
For reference, this is the relevant part of the build I see on my end: make[1]: Entering directory `/home/ptyser/u-boot/u-boot/examples/standalone' powerpc-linux-gcc -g -Os -D__KERNEL__ -DTEXT_BASE=0xfff80000 -I/home/ptyser/u-boot/u-boot/include -fno-builtin -ffreestanding -nostdinc -isystem /opt/xes/devkit/ppc/eldk_gcc4.2.2-glibc20070515T2025/bin/../lib/gcc/powerpc-linux/4.2.2/include -pipe -DCONFIG_PPC -D__powerpc__ -ffixed-r2 -Wa,-me500 -msoft-float -mno-string -mspe=yes -mno-spe -Wall -Wstrict-prototypes -fno-stack-protector \ -o hello_world.o hello_world.c -c powerpc-linux-gcc -g -Os -D__KERNEL__ -DTEXT_BASE=0xfff80000 -I/home/ptyser/u-boot/u-boot/include -fno-builtin -ffreestanding -nostdinc -isystem /opt/xes/devkit/ppc/eldk_gcc4.2.2-glibc20070515T2025/bin/../lib/gcc/powerpc-linux/4.2.2/include -pipe -DCONFIG_PPC -D__powerpc__ -ffixed-r2 -Wa,-me500 -msoft-float -mno-string -mspe=yes -mno-spe -Wall -Wstrict-prototypes -fno-stack-protector \ -o stubs.o stubs.c -c powerpc-linux-ar crv libstubs.a stubs.o a - stubs.o powerpc-linux-ld -g -Ttext 0x40000 \ -o hello_world -e hello_world hello_world.o libstubs.a \ -L/opt/xes/devkit/ppc/eldk_gcc4.2.2-glibc20070515T2025/bin/../lib/gcc/powerpc-linux/4.2.2 -lgcc ....
ptyser@petert u-boot $ readelf -h examples/standalone/hello_world ELF Header: Magic: 7f 45 4c 46 01 02 01 00 00 00 00 00 00 00 00 00 Class: ELF32 Data: 2's complement, big endian Version: 1 (current) OS/ABI: UNIX - System V ABI Version: 0 Type: EXEC (Executable file) Machine: PowerPC Version: 0x1 Entry point address: 0x40000 Start of program headers: 52 (bytes into file) Start of section headers: 265304 (bytes into file) Flags: 0x0 Size of this header: 52 (bytes) Size of program headers: 32 (bytes) Number of program headers: 2 Size of section headers: 40 (bytes) Number of section headers: 15 Section header string table index: 12
Could you paste similar output from what you're seeing?
Thanks, Peter

On Tue, 2010-06-15 at 14:05 -0500, Timur Tabi wrote:
Timur Tabi wrote:
Peter Tyser wrote:
Previously, standalone applications were compiled with gcc flags that produced relocatable executables on the PowerPC architecture (eg with the -mrelocatable and -fPIC flags). There's no reason for these applications to be fully relocatable at this time since no relocation fixups are performed on standalone applications.
This didn't work for me. The entry point for my application in 401b4.
So if I comment-out the ifeq, like this:
#ifeq ($(ARCH),powerpc) CFLAGS := $(filter-out $(RELFLAGS),$(CFLAGS)) #endif
Was commenting out the 'ifeq' above necessary? It shouldn't be, so my first question would be why it was needed.
Best, Peter

Peter Tyser wrote:
Was commenting out the 'ifeq' above necessary? It shouldn't be, so my first question would be why it was needed.
Probably because I was using an older U-Boot. When I switch to the latest code, it compiles fine.
However, my entry point is not at 40000:
$ nm -n examples/standalone/flash_wp 00040000 t command_exit 000400c4 t is_locked 00040184 T flash_wp 000403d0 T dummy
'flash_wp' should be at 40000. command_exit and is_locked are two functions in my code. command_exit, however, is not the first function, it's the third.

On Tue, 2010-06-15 at 14:45 -0500, Timur Tabi wrote:
Peter Tyser wrote:
Was commenting out the 'ifeq' above necessary? It shouldn't be, so my first question would be why it was needed.
Probably because I was using an older U-Boot. When I switch to the latest code, it compiles fine.
However, my entry point is not at 40000:
$ nm -n examples/standalone/flash_wp 00040000 t command_exit 000400c4 t is_locked 00040184 T flash_wp 000403d0 T dummy
'flash_wp' should be at 40000. command_exit and is_locked are two functions in my code. command_exit, however, is not the first function, it's the third.
I think by default its not possible to guarantee function order in gcc's output if a file contains multiple functions. We could create a basic linker script... I think we could also do it with some gcc/ld-foo like:
--- a/examples/standalone/Makefile +++ b/examples/standalone/Makefile @@ -78,6 +78,7 @@ CPPFLAGS += -I.. # inconsistent. ifeq ($(ARCH),powerpc) CFLAGS := $(filter-out $(RELFLAGS),$(CFLAGS)) +CFLAGS += -fno-toplevel-reorder endif
all: $(obj).depend $(OBJS) $(LIB) $(SREC) $(BIN) $(ELF) @@ -88,7 +89,7 @@ $(LIB): $(obj).depend $(LIBOBJS)
$(ELF): $(obj)%: $(obj)%.o $(LIB) - $(LD) -g -Ttext $(STANDALONE_LOAD_ADDR) \ + $(LD) -g -Ttext $(STANDALONE_LOAD_ADDR) -sort-common \ -o $@ -e $(SYM_PREFIX)$(notdir $(<:.o=)) $< $(LIB) \ -L$(gcclibdir) -lgcc
Could you try the above change with your flash_wp test case? Or make the flash_wp app public? It should put the first function at the base of the image in theory.
Best, Peter

Dear Peter Tyser,
In message 1276632905.32134.1535.camel@petert you wrote:
I think by default its not possible to guarantee function order in gcc's output if a file contains multiple functions. We could create a basic
Correct. If you check for example the "timer" example program (build for some 8xx system, say TQM860L) you can see that it's sufficient to have a forward declaration for a static function before the real code that the C compiler will place the code for this function in front, whichis probably not what you want here.
linker script... I think we could also do it with some gcc/ld-foo like:
--- a/examples/standalone/Makefile +++ b/examples/standalone/Makefile @@ -78,6 +78,7 @@ CPPFLAGS += -I.. # inconsistent. ifeq ($(ARCH),powerpc) CFLAGS := $(filter-out $(RELFLAGS),$(CFLAGS)) +CFLAGS += -fno-toplevel-reorder endif
This alone is sufficient to "fix" for example the aforementioned "timer" example program.
Without:
... 00040428 T strcmp 000400e8 T timer 00040000 t timer_handler 00040318 T tstc 00040398 T udelay ...
With:
... 00040428 T strcmp 00040000 T timer 000402b8 t timer_handler 00040318 T tstc 00040398 T udelay ...
all: $(obj).depend $(OBJS) $(LIB) $(SREC) $(BIN) $(ELF) @@ -88,7 +89,7 @@ $(LIB): $(obj).depend $(LIBOBJS)
$(ELF): $(obj)%: $(obj)%.o $(LIB)
$(LD) -g -Ttext $(STANDALONE_LOAD_ADDR) \
$(LD) -g -Ttext $(STANDALONE_LOAD_ADDR) -sort-common \ -o $@ -e $(SYM_PREFIX)$(notdir $(<:.o=)) $< $(LIB) \ -L$(gcclibdir) -lgcc
I'm not sure if this is needed.
Could you try the above change with your flash_wp test case? Or make the flash_wp app public? It should put the first function at the base of the image in theory.
I think the "timer" code is sufficient to show the problem, and that your fix helps. If Timur confirms it's working for his secret code too we should apply this.
Thanks a lot!
Best regards,
Wolfgang Denk

<snip>
all: $(obj).depend $(OBJS) $(LIB) $(SREC) $(BIN) $(ELF) @@ -88,7 +89,7 @@ $(LIB): $(obj).depend $(LIBOBJS)
$(ELF): $(obj)%: $(obj)%.o $(LIB)
$(LD) -g -Ttext $(STANDALONE_LOAD_ADDR) \
$(LD) -g -Ttext $(STANDALONE_LOAD_ADDR) -sort-common \ -o $@ -e $(SYM_PREFIX)$(notdir $(<:.o=)) $< $(LIB) \ -L$(gcclibdir) -lgcc
I'm not sure if this is needed.
Agreed, in fact, I'm not sure why I even put that in there in the first place after re-reading ld's man page:)
Could you try the above change with your flash_wp test case? Or make the flash_wp app public? It should put the first function at the base of the image in theory.
I think the "timer" code is sufficient to show the problem, and that your fix helps. If Timur confirms it's working for his secret code too we should apply this.
Do you want this rolled into the first patch, or sent as a follow-up?
Best, Peter

Dear Peter,
In message 1276634341.32134.1541.camel@petert you wrote:
I think the "timer" code is sufficient to show the problem, and that your fix helps. If Timur confirms it's working for his secret code too we should apply this.
Do you want this rolled into the first patch, or sent as a follow-up?
Please roll it into one patch. Thanks!
Best regards,
Wolfgang Denk
-- DENX Software Engineering GmbH, MD: Wolfgang Denk & Detlev Zundel HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany Phone: (+49)-8142-66989-10 Fax: (+49)-8142-66989-80 Email: wd@denx.de It is easier to change the specification to fit the program than vice versa.

On Tue, 2010-06-15 at 22:51 +0200, Wolfgang Denk wrote:
Dear Peter,
In message 1276634341.32134.1541.camel@petert you wrote:
I think the "timer" code is sufficient to show the problem, and that your fix helps. If Timur confirms it's working for his secret code too we should apply this.
Do you want this rolled into the first patch, or sent as a follow-up?
Please roll it into one patch. Thanks!
It looks like the -fno-toplevel-reorder flag is only available in gcc >= 4.2 (http://gcc.gnu.org/gcc-4.2/changes.html released May 2007). So, do we add support to U-Boot to conditionally check for the gcc version like Linux to know when to use -fno-toplevel-reorder? Or do we use a linker script that would support more versions of gcc at the cost of more complexity?
Best, Peter

On Tue, Jun 15, 2010 at 10:37 PM, Peter Tyser ptyser@xes-inc.com wrote:
It looks like the -fno-toplevel-reorder flag is only available in gcc >= 4.2 (http://gcc.gnu.org/gcc-4.2/changes.html released May 2007). So, do we add support to U-Boot to conditionally check for the gcc version like Linux to know when to use -fno-toplevel-reorder? Or do we use a linker script that would support more versions of gcc at the cost of more complexity?
What happens if you use the flag on earlier versions of gcc? If the flag is just silently ignored, then maybe it's not such a big deal to always include it, and just add a comment saying that it only works on gcc 4.2 or higher?

Dear Timur Tabi,
In message AANLkTild0OSohtPUQpqwsrZSAxPtCqnb_C2S0WTvIh1a@mail.gmail.com you wrote:
we add support to U-Boot to conditionally check for the gcc version like Linux to know when to use -fno-toplevel-reorder? =A0Or do we use a linker script that would support more versions of gcc at the cost of more complexity?
What happens if you use the flag on earlier versions of gcc? If the flag is just silently ignored, then maybe it's not such a big deal to always include it, and just add a comment saying that it only works on gcc 4.2 or higher?
It raises an error.
Best regards,
Wolfgang Denk

Dear Timur Tabi,
In message 20100616145133.BBDE7D81C69@gemini.denx.de I wrote:
we add support to U-Boot to conditionally check for the gcc version like Linux to know when to use -fno-toplevel-reorder? =A0Or do we use a linker script that would support more versions of gcc at the cost of more complexity?
What happens if you use the flag on earlier versions of gcc? If the flag is just silently ignored, then maybe it's not such a big deal to always include it, and just add a comment saying that it only works on gcc 4.2 or higher?
It raises an error.
AFAICT you did not reply to this, and the problem is still unsolved.
Do you still have this on your list?
Best regards,
Wolfgang Denk

On Fri, Sep 10, 2010 at 2:49 PM, Wolfgang Denk wd@denx.de wrote:
AFAICT you did not reply to this, and the problem is still unsolved.
Do you still have this on your list?
Sorry, I'm confused. What exactly do you want me to do? Since you applied Peter's patch, the problem has gone away for me.

On Fri, 2010-09-10 at 14:53 -0500, Timur Tabi wrote:
On Fri, Sep 10, 2010 at 2:49 PM, Wolfgang Denk wd@denx.de wrote:
AFAICT you did not reply to this, and the problem is still unsolved.
Do you still have this on your list?
Sorry, I'm confused. What exactly do you want me to do? Since you applied Peter's patch, the problem has gone away for me.
Wolfgang applied the "examples/standalone: Remove relocation compile flags for PowerPC" patch. That patch should remove the few bytes of relocation cruft that bumped up the first function address by a few bytes in standalone images.
However, I think there's still the issue that if there are multiple functions in a standalone application there's no guarantee the entry point function will be at the base of the image. eg if the app were:
int helper_func() { code()... }
int entry_point() { // application entry point }
The entry point wouldn't be at the base of the image, it'd be offset by the size of helper_func(), and it would jump around depending on compiler version, flags, etc.
My last question on the issue was: It looks like the -fno-toplevel-reorder flag is only available in gcc >= 4.2 (http://gcc.gnu.org/gcc-4.2/changes.html released May 2007). So, do we add support to U-Boot to conditionally check for the gcc version like Linux to know when to use -fno-toplevel-reorder? Or do we use a linker script that would support more versions of gcc at the cost of more complexity?
I never heard back about the preferred method. I'd personally lean towards checking for compiler version and using the gcc version check + -fno-toplevel-reorder.
Best, Peter

Dear Peter Tyser,
In message 1284149249.26713.2926.camel@petert you wrote:
Sorry, I'm confused. What exactly do you want me to do? Since you applied Peter's patch, the problem has gone away for me.
However, I think there's still the issue that if there are multiple functions in a standalone application there's no guarantee the entry point function will be at the base of the image. eg if the app were:
That's my understanding as well.
My last question on the issue was: It looks like the -fno-toplevel-reorder flag is only available in gcc >= 4.2 (http://gcc.gnu.org/gcc-4.2/changes.html released May 2007). So, do we add support to U-Boot to conditionally check for the gcc version like Linux to know when to use -fno-toplevel-reorder? Or do we use a linker script that would support more versions of gcc at the cost of more complexity?
I never heard back about the preferred method. I'd personally lean towards checking for compiler version and using the gcc version check + -fno-toplevel-reorder.
Given the fact that GCC 4.2 is already pretty old I also tend to add a gcc version check with -fno-toplevel-reorder instead of increasing the complexity of the linker scripts.
Best regards,
Wolfgang Denk

Using -fno-toplevel-reorder causes gcc to not reorder functions. This ensures that an application's entry point will be the first function in the application's source file.
This change, along with commit 620bbba524fbaa26971a5004793010b169824f1b should cause a standalone application's entry point to be at the base of the compiled binary. Previously, the entry point could change depending on gcc version and flags.
Note -fno-toplevel-reorder is only available in gcc version 4.2 or greater.
Signed-off-by: Peter Tyser ptyser@xes-inc.com --- I didn't have a version of gcc < 4.2. The change is pretty trivial so it should work, but it'd be appreciated if someone with an old toolchain installed could give the patch a shot.
examples/standalone/Makefile | 5 +++++ 1 files changed, 5 insertions(+), 0 deletions(-)
diff --git a/examples/standalone/Makefile b/examples/standalone/Makefile index 5f1f800..c2dd514 100644 --- a/examples/standalone/Makefile +++ b/examples/standalone/Makefile @@ -82,6 +82,11 @@ CFLAGS := $(filter-out $(RELFLAGS),$(CFLAGS)) CPPFLAGS := $(filter-out $(RELFLAGS),$(CPPFLAGS)) endif
+# We don't want gcc reordering functions if possible. This ensures that an +# application's entry point will be the first function in the application's +# source file. +CFLAGS += $(call cc-option,-fno-toplevel-reorder) + all: $(obj).depend $(OBJS) $(LIB) $(SREC) $(BIN) $(ELF)
#########################################################################

On Sun, Sep 12, 2010 at 17:38, Peter Tyser ptyser@xes-inc.com wrote:
Using -fno-toplevel-reorder causes gcc to not reorder functions. This ensures that an application's entry point will be the first function in the application's source file.
This change, along with commit 620bbba524fbaa26971a5004793010b169824f1b should cause a standalone application's entry point to be at the base of the compiled binary. Previously, the entry point could change depending on gcc version and flags.
Note -fno-toplevel-reorder is only available in gcc version 4.2 or greater.
Signed-off-by: Peter Tyser ptyser@xes-inc.com
I didn't have a version of gcc < 4.2. The change is pretty trivial so it should work, but it'd be appreciated if someone with an old toolchain installed could give the patch a shot.
Since I was writing a standalone test program today, I manually tested against an older u-boot and arm gcc 4.4.1. Worked fine. You can add my tested-by if you feel that's sufficient.
I wonder if this is the right way to fix this. It seems a bit subtle. I thought of two other possible workarounds - have the Makefile use mkimage as part of the output so the entry point is embedded in the mkimage file, or redo the programs to have a main() as entry and write a crt0.S equivalent and have the entry location for that fixed in a linker file.

Hi Andrew,
On Sun, 2010-09-12 at 21:00 -0500, Andrew Dyer wrote:
On Sun, Sep 12, 2010 at 17:38, Peter Tyser ptyser@xes-inc.com wrote:
Using -fno-toplevel-reorder causes gcc to not reorder functions. This ensures that an application's entry point will be the first function in the application's source file.
This change, along with commit 620bbba524fbaa26971a5004793010b169824f1b should cause a standalone application's entry point to be at the base of the compiled binary. Previously, the entry point could change depending on gcc version and flags.
Note -fno-toplevel-reorder is only available in gcc version 4.2 or greater.
Signed-off-by: Peter Tyser ptyser@xes-inc.com
I didn't have a version of gcc < 4.2. The change is pretty trivial so it should work, but it'd be appreciated if someone with an old toolchain installed could give the patch a shot.
Since I was writing a standalone test program today, I manually tested against an older u-boot and arm gcc 4.4.1. Worked fine. You can add my tested-by if you feel that's sufficient. I wonder if this is the right way to fix this. It seems a bit subtle. I thought of two other possible workarounds - have the Makefile use mkimage as part of the output so the entry point is embedded in the mkimage file, or redo the programs to have a main() as entry and write a crt0.S equivalent and have the entry location for that fixed in a linker file.
Thanks for testing. I agree this isn't the most elegant solution, but its one big advantage is simplicity in my mind. Creating/maintaining a crt0.S and/or link script for each CPU architecture seems like overkill for a simple (deprecated?) application interface to me. I was under the impression the preferred application interface going forward was the one enabled by CONFIG_API in examples/api. It uses the crt0 solution, but only supports ppc and arm right now.
Using a uImage format for apps seems like a fine solution too. Do others have a preference?
I agree we should be using main() as the entry point either way. I'll add that to the TODO list. If we did go with -fno-toplevel-reorder I could add the following to each application to make it clear what's going on: /* Define main() protoype first to ensure its the first function in the image */ int main(int argc, char * const argv[]);
Best, Peter

Hi Peter,
I agree we should be using main() as the entry point either way. I'll add that to the TODO list. If we did go with -fno-toplevel-reorder I could add the following to each application to make it clear what's going on: /* Define main() protoype first to ensure its the first function in the image */
when linked with -fno-toplevel-reorder
int main(int argc, char * const argv[]);
This would be appreciated.
Cheers Detlev

Dear Peter Tyser,
In message 1284331129-12911-1-git-send-email-ptyser@xes-inc.com you wrote:
Using -fno-toplevel-reorder causes gcc to not reorder functions. This ensures that an application's entry point will be the first function in the application's source file.
This change, along with commit 620bbba524fbaa26971a5004793010b169824f1b should cause a standalone application's entry point to be at the base of the compiled binary. Previously, the entry point could change depending on gcc version and flags.
Note -fno-toplevel-reorder is only available in gcc version 4.2 or greater.
Signed-off-by: Peter Tyser ptyser@xes-inc.com
I didn't have a version of gcc < 4.2. The change is pretty trivial so it should work, but it'd be appreciated if someone with an old toolchain installed could give the patch a shot.
examples/standalone/Makefile | 5 +++++ 1 files changed, 5 insertions(+), 0 deletions(-)
Applied, thanks.
Best regards,
Wolfgang Denk

Wolfgang Denk wrote:
I think the "timer" code is sufficient to show the problem, and that your fix helps. If Timur confirms it's working for his secret code too we should apply this.
Doing this at the top of my source file:
static int __flash_wp(int argc, char *argv[]);
int flash_wp(int argc, char *argv[]) { return __flash_wp(argc, argv); }
and then adding this line:
CFLAGS += -fno-toplevel-reorder
was all I needed to get my entry point to appear at 40000 without needing to define any more forward references or caring about the order of the functions in the file.

Dear Timur Tabi,
In message 4C17E4F2.70309@freescale.com you wrote:
Doing this at the top of my source file:
static int __flash_wp(int argc, char *argv[]);
int flash_wp(int argc, char *argv[]) { return __flash_wp(argc, argv); }
and then adding this line:
CFLAGS += -fno-toplevel-reorder
was all I needed to get my entry point to appear at 40000 without needing to define any more forward references or caring about the order of the functions in the file.
I think the "static int __flash_wp()" thing is not even needed assuming that flash_wp() is the first function in your file.
Best regards,
Wolfgang Denk

Wolfgang Denk wrote:
I think the "static int __flash_wp()" thing is not even needed assuming that flash_wp() is the first function in your file.
That's the thing -- I don't want flash_wp() to be the first function in my file. I would then need a forward reference to all the other functions in my file, and I hate doing that.

Dear Timur Tabi,
In message 4C17EA8D.9080606@freescale.com you wrote:
Wolfgang Denk wrote:
I think the "static int __flash_wp()" thing is not even needed assuming that flash_wp() is the first function in your file.
That's the thing -- I don't want flash_wp() to be the first function in my file. I would then need a forward reference to all the other functions in my file, and I hate doing that.
OK - but then please don't claim that such a construct was necessary.
Best regards,
Wolfgang Denk

From: Peter Tyser ptyser@xes-inc.com
Previously, standalone applications were compiled with gcc flags that produced relocatable executables on the PowerPC architecture (eg with the -mrelocatable and -fPIC flags). There's no reason for these applications to be fully relocatable at this time since no relocation fixups are performed on standalone applications.
Additionally, removing the gcc relocation flags results in the entry point of applications residing at the base of the image. When a standalone application was relocatable, the entry point was generally located at an offset into the image which was confusing and prone to errors.
This change moves the entry point of PowerPC standalone applications from 0x40004 (usually) to 0x40000.
Signed-off-by: Peter Tyser ptyser@xes-inc.com Signed-off-by: Wolfgang Denk wd@denx.de ---
It seems we need to cleanup a few more make variables (+AFLAGS, CPPFLAGS)
examples/standalone/Makefile | 10 ++++++++++ 1 files changed, 10 insertions(+), 0 deletions(-)
diff --git a/examples/standalone/Makefile b/examples/standalone/Makefile index 6ea3b93..5f1f800 100644 --- a/examples/standalone/Makefile +++ b/examples/standalone/Makefile @@ -72,6 +72,16 @@ gcclibdir := $(shell dirname `$(CC) -print-libgcc-file-name`)
CPPFLAGS += -I..
+# For PowerPC there's no need to compile standalone applications as a +# relocatable executable. The relocation data is not needed, and +# also causes the entry point of the standalone application to be +# inconsistent. +ifeq ($(ARCH),powerpc) +AFLAGS := $(filter-out $(RELFLAGS),$(AFLAGS)) +CFLAGS := $(filter-out $(RELFLAGS),$(CFLAGS)) +CPPFLAGS := $(filter-out $(RELFLAGS),$(CPPFLAGS)) +endif + all: $(obj).depend $(OBJS) $(LIB) $(SREC) $(BIN) $(ELF)
#########################################################################

In message 1276631305-30648-1-git-send-email-wd@denx.de you wrote:
From: Peter Tyser ptyser@xes-inc.com
Previously, standalone applications were compiled with gcc flags that produced relocatable executables on the PowerPC architecture (eg with the -mrelocatable and -fPIC flags). There's no reason for these applications to be fully relocatable at this time since no relocation fixups are performed on standalone applications.
Additionally, removing the gcc relocation flags results in the entry point of applications residing at the base of the image. When a standalone application was relocatable, the entry point was generally located at an offset into the image which was confusing and prone to errors.
This change moves the entry point of PowerPC standalone applications from 0x40004 (usually) to 0x40000.
Signed-off-by: Peter Tyser ptyser@xes-inc.com Signed-off-by: Wolfgang Denk wd@denx.de
It seems we need to cleanup a few more make variables (+AFLAGS, CPPFLAGS)
examples/standalone/Makefile | 10 ++++++++++ 1 files changed, 10 insertions(+), 0 deletions(-)
Applied to "next".
Best regards,
Wolfgang Denk
participants (5)
-
Andrew Dyer
-
Detlev Zundel
-
Peter Tyser
-
Timur Tabi
-
Wolfgang Denk