Bug 6727 - Thumb interworking code zero when another section is positioned before positioning .text
Summary: Thumb interworking code zero when another section is positioned before positi...
Status: RESOLVED FIXED
Alias: None
Product: binutils
Classification: Unclassified
Component: ld (show other bugs)
Version: 2.17
: P2 normal
Target Milestone: ---
Assignee: unassigned
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2008-07-08 07:51 UTC by Aaron P. D'Souza
Modified: 2008-11-05 10:53 UTC (History)
1 user (show)

See Also:
Host: CYGWIN_NT-5.1 jenny 1.5.25(0.156/4/2) 2008-06-12 19:34 i686 Cygw
Target: ARM ELF arm7tdmi armv4t
Build:
Last reconfirmed:


Attachments
Makefile, 2 assembly files, C file to reproduce the error (717 bytes, text/plain)
2008-07-08 08:19 UTC, Aaron P. D'Souza
Details
Makefile, 2 assembly files, C file to prevent the error (802 bytes, text/plain)
2008-07-08 08:24 UTC, Aaron P. D'Souza
Details
Improve interworking bfd selection (633 bytes, patch)
2008-08-15 10:47 UTC, Nick Clifton
Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Aaron P. D'Souza 2008-07-08 07:51:04 UTC
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.
Comment 1 Aaron P. D'Souza 2008-07-08 08:07:30 UTC
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.
Comment 2 Aaron P. D'Souza 2008-07-08 08:19:52 UTC
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
Comment 3 Aaron P. D'Souza 2008-07-08 08:24:01 UTC
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!
Comment 4 Nick Clifton 2008-07-09 12:12:55 UTC
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
Comment 5 Aaron P. D'Souza 2008-07-15 03:13:07 UTC
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
Comment 6 Aaron P. D'Souza 2008-07-17 10:12:06 UTC
Nick:

pls see bug6726 for a few queries.

Aaron
Comment 7 Nick Clifton 2008-07-21 15:53:25 UTC
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
Comment 8 Aaron P. D'Souza 2008-07-23 09:28:02 UTC
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
Comment 9 Aaron P. D'Souza 2008-07-23 15:16:39 UTC
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.
Comment 10 Aaron P. D'Souza 2008-07-23 15:20:47 UTC
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.
Comment 11 Nick Clifton 2008-07-23 17:42:04 UTC
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.

Comment 12 Aaron P. D'Souza 2008-07-30 11:40:56 UTC
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.
Comment 13 Aaron P. D'Souza 2008-07-30 11:43:10 UTC
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
Comment 14 Nick Clifton 2008-08-15 10:47:42 UTC
Created attachment 2910 [details]
Improve interworking bfd selection
Comment 15 Nick Clifton 2008-08-15 10:54:55 UTC
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
Comment 16 Aaron P. D'Souza 2008-08-25 13:19:21 UTC
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
Comment 17 Nick Clifton 2008-08-26 11:13:19 UTC
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.
Comment 18 Aaron P. D'Souza 2008-11-05 10:53:56 UTC
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 }