PROBLEM DESCRIPTION under certain circumstances, Thumb interworking code is not generated correctlyby GNU LD. it is full of NULLs. with arm-elf-ld: - if you have --gc-sections enabled - if you have asm in ARM mode with -mthumb-interwork - asm code contains an "ax" section .VhaInit with instructions - if you have a C file in Thumb mode -mthumb with -mthumb-interwork - if asm code is positioned before C generated code using --section-start whereas .text is positioned later with -Ttext - if you prevent garbage-collection of .VhaInit using instructions from .text to access .VhaInit then, the thumb interworking code is zero. WORKAROUND the interworking code is generated correctly if you place -Ttext before --section-start.
i narrowed down the exact situation when Thumb interworking code is zero. - when you position any section, say .data, before you position .text using --section-start or -Tdata for other sections and -Ttext for .text, - when Thumb interworking is enabled - when --gc-sections is enabled at that time, Thumb interworking code is zero. it does not matter if the offending section is finally garbage collected or not. WORKAROUND - position .text before .data/other section on ld command line.
Created attachment 2820 [details] Makefile, 2 assembly files, C file to reproduce the error when: - --gc-sections is enabled - .data and .text are in 2 separate files, and - .data is positioned first using -Tdata, and - .text is positioned after using -Ttext, then: Thumb interworking code is zero
Created attachment 2821 [details] Makefile, 2 assembly files, C file to prevent the error when: - --gc-sections is enabled - .data and .text are in 2 separate files, and - .text is positioned first using -Ttext, and - .data is positioned after using -Tdata, then: Thumb interworking code is CORRECT!
Hi Aaron, I think that this is another problem that is fixed in the current binutils sources. Please could you try them out and let me know if the problem is still there. Cheers Nick
hello Nick: i was a bit busy with official work, so i could not get back to you. i will try the latest binutils and let you know what i find. Aaron
Nick: pls see bug6726 for a few queries. Aaron
Subject: Re: Thumb interworking code zero when another section is positioned before positioning .text Hi Aaron, > how do i build binutils from source for ARM? > i followed instructions on http://www.gnuarm.com/support.html Well those instructions should work, although obviously you can stop once you have built and installed your new set of binutils. > # cd [binutils-build] > # [binutils-source]/configure --target=arm-elf --prefix=[toolchain-prefix] > # --enable-interwork --enable-multilib > # make all install > > i found this to be incorrect. so, i changed it to: > --program-prefix=arm-elf --prefix=${HOME}/local --target=arm-elf > > however, i get a message that i am building for arm-unknown-elf. > what should i do? Is that a problem ? The config.sub script automatically expands "arm-elf" into "arm-unknown-elf". This is OK. The middle part of the triplet is the manufacturer's name and "unknown" is a perfectly common value. The binutils should still build correctly. >> I should also point out that you should not be invoking the linker directly. > > however, if i use GCC to link, i will not be able to position the > objects and libraries in the order i want. OK, but please be careful to construct the linker command line correctly. (I mentioned using gcc to drive the linker because quiet a few bug reports that we receive are due to people trying to run the linker directly and not appreciating the work that gcc does in constructing the command line). Cheers Nick
hello Nick: i just tested using latest GNUARM distribution from GNUARM.org. no, the problem has not been fixed in binutils 2.18. this is the distribution i used for testing: binutils-2.18, gcc-4.2.2-c-c++, newlib-1.15.0 (reentrant), insight-6.7.1, setup.exe [102MB] from: http://www.gnuarm.org/files.html Aaron
Nick: first of all, the problem is not fixed in binutils-2.18, the latest stable release. as suggested by you, i attempted to get the latest sources from CVS. i am not sure that the CVS checkout completed correctly. i then downloaded 2.18.50 from the FTP server that was made available today. i was able to download and build binutils-2.18.50 that was released today. after building it, i verified that the bug described in this report has been fixed. also, i confirmed that problem in bug6726 has also been fixed.
just to clarify, the problem is fixed in binutils-2.18.50 that was downloaded from ftp://sourceware.org/pub/binutils/snapshots. today morning's snapshot was used. thank you, Cygnus, RedHat.
Subject: Re: Thumb interworking code zero when another section is positioned before positioning .text Hi Aaron, > thank you, Cygnus, RedHat. Just a quick note - it is the FSF that you should be thanking, not Cygnus or RedHat. The binutils is an FSF project not a Red Hat one. Cheers Nick PS. Yes, I do work for Red Hat, but I am allowed to donate some of my time to the FSF, including the binutils project.
with Michael Fischer's persistence and after checking again using binutils-2.18.50, i came to the conclusion that the problem described in this bug is not yet fixed. a note has been sent to Nick Clifton. the bug is being reopened.
since Michael Fischer of Yagarto was persistent, we have found another bug in the generated Interworking code when GC is enabled and -Ttext is positioned before -Tdata on the LD command line. the problem is in binutils-2.18.50, the latest snapshot released from GNU. pls see below for details in all relevant releases. >now I have made some test with 2.18.50 and here are my results. >[...] >Please can you take a look at it? > i was able to build binutils-2.18.50 yesterday and used arm-elf-ld on the test program t3. its good that you checked with me again. i have found one more problem with binutils-2.18.50. the Interworking code that is generated is not correct, or, at least, it is positioned incorrectly. see below for details. PROCEDURE FOR REPRODUCING ERROR ZERO INTERWORKING CODE USING binutils-2.17 with binutils-2.17 you can see that Thumb interworking code is positioned AFTER our code. also, with 2.17, the interworking code is ZERO. Command Line $ arm-elf-ld -v GNU ld version 2.17 $ make arm-elf-as -mno-fpu -march=armv4t -mcpu=arm7tdmi -mthumb-interwork -EL -o FirstAsm.o FirstAsm.s arm-elf-as -mno-fpu -march=armv4t -mcpu=arm7tdmi -mthumb-interwork -EL -o SecondAsm.o SecondAsm.s arm-elf-gcc -O0 -march=armv4t -mcpu=arm7tdmi -mthumb-interwork -mthumb -c -o ThirdC.o ThirdC.c arm-elf-ld --gc-sections --entry=_istart --defsym ResetHandler=0x400c0000 -Tdata 0x20000000 -Ttext 0x20000080 -o FinalProgram.elf FirstAsm.o SecondAsm.o ThirdC.o arm-elf-objdump -S FinalProgram.elf > FinalProgram.lst arm-elf-objdump --all FinalProgram.elf > FinalProgram.sym $ Interworking Code 20000080 <_istart>: [...] 20000088 <_af>: [...] 20000098 <f>: [...] 200000b8 <___af_from_thumb>: 200000b8: 0000 lsls r0, r0, #0 ... 200000bc <___af_change_to_arm>: 200000bc: 00000000 andeq r0, r0, r0 200000c0 <__f_from_arm>: ... CORRECTLY POSITIONED INTERWORKING CODE USING binutils-2.17 if, in the command line for arm-elf-ld, we position -Ttext BEFORE other command line options, interworking code is correctly positioned and not ZERO. Command Line $ arm-elf-ld -v GNU ld version 2.17 $ make arm-elf-as -mno-fpu -march=armv4t -mcpu=arm7tdmi -mthumb-interwork -EL -o FirstAsm.o FirstAsm.s arm-elf-as -mno-fpu -march=armv4t -mcpu=arm7tdmi -mthumb-interwork -EL -o SecondAsm.o SecondAsm.s arm-elf-gcc -O0 -march=armv4t -mcpu=arm7tdmi -mthumb-interwork -mthumb -c -o ThirdC.o ThirdC.c arm-elf-ld --gc-sections --entry=_istart --defsym ResetHandler=0x400c0000 -Ttext 0x20000080 -Tdata 0x20000000 -o FinalProgram.elf FirstAsm.o SecondAsm.o ThirdC.o arm-elf-objdump -S FinalProgram.elf > FinalProgram.lst arm-elf-objdump --all FinalProgram.elf > FinalProgram.sym $ Interworking Code 20000080 <_istart>: [...] 20000088 <_af>: [...] 20000098 <f>: [...] 200000b8 <___af_from_thumb>: 200000b8: 4778 bx pc 200000ba: 46c0 nop (mov r8, r8) 200000bc <___af_change_to_arm>: 200000bc: eafffff1 b 20000088 <_af> 200000c0 <__f_from_arm>: 200000c0: e59fc000 ldr ip, [pc, #0] ; 200000c8 <__f_from_arm+0x8> 200000c4: e12fff1c bx ip 200000c8: 20000099 mulcs r0, r9, r0 ZERO INTERWORKING CODE USING binutils-2.18 here, if -Ttext is positioned before -Tdata on the command line and if GC is enabled (bug6727), again Thumb interworking code is zero. the same problem that exists with binutils-2.17 also remains in binutils-2.18. Command Line $ arm-elf-ld -v GNU ld (GNU Binutils) 2.18 $ make arm-elf-as -mno-fpu -march=armv4t -mcpu=arm7tdmi -mthumb-interwork -EL -o FirstAsm.o FirstAsm.s Assembler messages: option `-mno-fpu' is deprecated: use either -mfpu=softfpa or -mfpu=softvfp arm-elf-as -mno-fpu -march=armv4t -mcpu=arm7tdmi -mthumb-interwork -EL -o SecondAsm.o SecondAsm.s Assembler messages: option `-mno-fpu' is deprecated: use either -mfpu=softfpa or -mfpu=softvfp arm-elf-gcc -O0 -march=armv4t -mcpu=arm7tdmi -mthumb-interwork -mthumb -c -o ThirdC.o ThirdC.c arm-elf-ld --gc-sections --entry=_istart --defsym ResetHandler=0x400c0000 -Tdata 0x20000000 -Ttext 0x20000080 -o FinalProgram.elf FirstAsm.o SecondAsm.o ThirdC.o arm-elf-objdump -S FinalProgram.elf > FinalProgram.lst arm-elf-objdump --all FinalProgram.elf > FinalProgram.sym $ Interworking Code 20000080 <_istart>: [...] 20000088 <_af>: [...] 20000098 <f>: [...] 200000b8 <___af_from_thumb>: 200000b8: 0000 lsls r0, r0, #0 ... 200000bc <___af_change_to_arm>: 200000bc: 00000000 andeq r0, r0, r0 200000c0 <__f_from_arm>: ... INCORRECTLY POSITIONED INTERWORKING CODE USING binutils-2.18.50 with binutils-2.18.50, the latest snapshot release, if -Ttext is positioned AFTER -Tdata, Interworking code is generated, but not positioned correctly. Command Line $ arm-elf-ld -v GNU ld (GNU Binutils) 2.18.50.20080729 $ make arm-elf-as -mno-fpu -march=armv4t -mcpu=arm7tdmi -mthumb-interwork -EL -o FirstAsm.o FirstAsm.s Assembler messages: option `-mno-fpu' is deprecated: use either -mfpu=softfpa or -mfpu=softvfp arm-elf-as -mno-fpu -march=armv4t -mcpu=arm7tdmi -mthumb-interwork -EL -o SecondAsm.o SecondAsm.s Assembler messages: option `-mno-fpu' is deprecated: use either -mfpu=softfpa or -mfpu=softvfp arm-elf-gcc -O0 -march=armv4t -mcpu=arm7tdmi -mthumb-interwork -mthumb -c -o ThirdC.o ThirdC.c arm-elf-ld --gc-sections --entry=_istart --defsym ResetHandler=0x400c0000 -Tdata 0x20000000 -Ttext 0x20000080 -o FinalProgram.elf FirstAsm.o SecondAsm.o ThirdC.o arm-elf-objdump -S FinalProgram.elf > FinalProgram.lst arm-elf-objdump --all FinalProgram.elf > FinalProgram.sym $ Interworking Code 20000080 <___af_from_thumb>: [...] 20000098 <_istart>: [...] 200000a0 <_af>: [...] 200000b0 <f>: [...] 200000d0 <__f_from_arm>: ... CORRECTLY POSITIONED INTERWORKING CODE USING binutils-2.18.50 with binutils-2.18.50, if -Ttext is positioned BEFORE -Tdata, Interworking code is generated correctly but positioned wrongly. Command Line $ arm-elf-ld -v GNU ld (GNU Binutils) 2.18.50.20080729 $ make arm-elf-as -mno-fpu -march=armv4t -mcpu=arm7tdmi -mthumb-interwork -EL -o FirstAsm.o FirstAsm.s Assembler messages: option `-mno-fpu' is deprecated: use either -mfpu=softfpa or -mfpu=softvfp arm-elf-as -mno-fpu -march=armv4t -mcpu=arm7tdmi -mthumb-interwork -EL -o SecondAsm.o SecondAsm.s Assembler messages: option `-mno-fpu' is deprecated: use either -mfpu=softfpa or -mfpu=softvfp arm-elf-gcc -O0 -march=armv4t -mcpu=arm7tdmi -mthumb-interwork -mthumb -c -o ThirdC.o ThirdC.c arm-elf-ld --gc-sections --entry=_istart --defsym ResetHandler=0x400c0000 -Ttext 0x20000080 -Tdata 0x20000000 -o FinalProgram.elf FirstAsm.o SecondAsm.o ThirdC.o arm-elf-objdump -S FinalProgram.elf > FinalProgram.lst arm-elf-objdump --all FinalProgram.elf > FinalProgram.sym $ Interworking Code 20000080 <___af_from_thumb>: 20000080: b540 push {r6, lr} 20000082: 4e03 ldr r6, [pc, #12] (20000090 <___af_from_thumb+0x10>) 20000084: 46fe mov lr, pc 20000086: 4730 bx r6 20000088: e8bd4040 pop {r6, lr} 2000008c: e12fff1e bx lr 20000090: 200000a0 .word 0x200000a0 20000094: 00000000 .word 0x00000000 [...] 20000098 <_istart>: [...] 200000a0 <_af>: [...] 200000b0 <f>: [...] 200000d0 <__f_from_arm>: 200000d0: e59fc000 ldr ip, [pc, #0] ; 200000d8 <__f_from_arm+0x8> 200000d4: e12fff1c bx ip 200000d8: 200000b1 .word 0x200000b1 CONCLUSION the problem in bug6727 is not fixed in binutils-2.18 or binutils-2.18.50 also. i will update the bug with this information. Aaron
Created attachment 2910 [details] Improve interworking bfd selection
Hi Aaron, Right, it took some doing but I think that I have a fix for this problem. The cause of the misbehaviour is that the linker is writing out the arm-to-thumb stubs before they have actually been initialised with code. This in turn is happening because the stubs are attached to an input file that is processed before the file that actually needs the stubs. (The stubs are generated on an as-needed basis as each input file is processed). The attached patch "fixes" this problem by making sure that the last viable input file is selected as the file to which the stubs are attached. I used fixed in quotes because this is not really a very reliable solution. It is still possible for some other part of the linker to re-order the input files after the file to hold the interworking stubs has been selected. In such a situation this bug will reappear. The proper solution is to use a similar method to the arm-eabi port and create a special, fake, linker stubs input file which is not attached to the normal input files list, but which is magically added to the output at the appropriate time. I am not doing that however as it is far too likely to introduce new bugs. So - please let me know if the uploaded patch works for you, and if it does I will check it in and close this issue. (For now...:) Cheers Nick
hello Nick: i do not know how to use patches and need to learn how first. also, after applying your patch, a build of binutils is needed which really takes days for me as we have frequent power cuts. besides that, i am a little busy at work and in the middle of something that will not allow me enough bandwidth. my situation should improve within a few weeks and at that time i will be able to spend more time with this bug. at present, i will continue to use GCC4.1.1 as everything works well with the workarounds that i have. btw, thank you for spending your time so unstintingly to fix these obscure problems. your time and selflessness is sincerely appreciated. Aaron
Hi Aaron, OK then. I have checked the patch into the sources so it will be in the next official release of the binutils. Cheers Nick PS. For the record this is the ChangeLog entry I included when I checked the patch in: ld/ChangeLog PR 6727 * emultempl/armelf.em (arm_elf_set_bfd_for_interworking): Scan all input sections in all input bfds and always select the last suitable one, so that interworking stubs are always processed after all other input sections. (arm_elf_before_allocation): Remove redundant use of output_has_begun flag.
sorry for getting back to you after such a long time. i have been reassigned to another job and am not working on the ARM assignment now, maybe later. that's why, i will not be able to follow up on GCC now. however, thank you very much for all your help and cooperation. it is priceless. thank you and have a nice day. cheers! Aaron -- { FLORIST : Ah Sam in San Mateo, California near 25 Ave } { the best spice in the world is Jerk Seasoning from Jamaica }