This is the mail archive of the
binutils@sources.redhat.com
mailing list for the binutils project.
Re: Odd code generated by binutils assembler for x86
- From: "H . J . Lu" <hjl at lucon dot org>
- To: Teemu Torma <teemu at torma dot org>
- Cc: gcc at gcc dot gnu dot org, binutils at sources dot redhat dot com,amodra at bigpond dot net dot au
- Date: Mon, 25 Mar 2002 15:27:43 -0800
- Subject: Re: Odd code generated by binutils assembler for x86
- References: <1017086913.16579.1.camel@lara.torma.org>
On Mon, Mar 25, 2002 at 09:08:31PM +0100, Teemu Torma wrote:
> Dear H. J. Lu,
>
> I think I found a problem in binutils assembler for x86. I tested
> with 2.11.93.0.2 and 2.12.90.0.3.
>
> The attached foo.s is generated by Mandrake 8.2 g++ 2.96, by compiling
> with options -O2 -fPIC -march=i686 -mcpu=i686 (if using i585, the
> generated code is different and it works). But anyway, the assembler
> seems to generate wrong code.
>
> The problem is that the setup of linker offset table is done in each
> function as
>
> call .LPR0
> addl $_GLOBAL_OFFSET_TABLE_, %ebx
>
> and the .LPR0 is generated near the beginning of file as
>
> .LPR0:
> movl (%esp), %ebx
> ret
>
> However, after assembler, the objdump --dissasemble-all shows (after
> c++filt)
>
> [This is .LPR0]
> 00000000 <ft_ID_Key::~ft_ID_Key(void)-0x4>:
> 0: 8b 1c 24 mov (%esp,1),%ebx
> 3: c3 ret
>
> 00000004 <ft_ID_Key::~ft_ID_Key(void)>:
> 4: 55 push %ebp
> 5: 89 e5 mov %esp,%ebp
> 7: 57 push %edi
> 8: 56 push %esi
> 9: 53 push %ebx
> a: 83 ec 14 sub $0x14,%esp
> [The next is call to .LPR0, fine]
> d: e8 ee ff ff ff call 0
> <ft_ID_Key::~ft_ID_Key(void)-0x4>
> 12: 81 c3 02 00 00 00 add $0x2,%ebx
>
> ...but later on, with the other methods it looks like
>
> 00000000 <ft_ID_Key::ft_ID_Key(fc_String const &)>:
> 0: 55 push %ebp
> 1: 89 e5 mov %esp,%ebp
> 3: 57 push %edi
> 4: 56 push %esi
> 5: 53 push %ebx
>
> 6: 83 ec 18 sub $0x18,%esp
> [This call looks really odd.... it should call .LPR0]
> 9: e8 fc ff ff ff call a <ft_ID_Key::ft_ID_Key(fc_String
> const &)+0xa>
> e: 81 c3 02 00 00 00 add $0x2,%ebx
>
> The odd part is that this one file is the only one that shows this
> behaviour. It is part of a big library, and all the other object
> files seem to be correct, but not this one. I tried playing with
> optimization levels, debug information and small code rearrangements,
> but I did not get proper output for this file.
>
The problem is gcc emits:
.section .gnu.linkonce.t._._9ft_ID_Key,"ax",@progbits
.align 16
.LPR0:
movl (%esp), %ebx
ret
.weak _._9ft_ID_Key
.type _._9ft_ID_Key,@function
_._9ft_ID_Key:
.LFB1:
pushl %ebp
.LCFI0:
movl %esp, %ebp
.LCFI1:
pushl %edi
.LCFI2:
pushl %esi
.LCFI3:
pushl %ebx
.LCFI4:
subl $20, %esp
.LCFI5:
call .LPR0
...
.section .gnu.linkonce.t.__tf9ft_ID_Key,"ax",@progbits
.align 16
.weak __tf9ft_ID_Key
.type __tf9ft_ID_Key,@function
__tf9ft_ID_Key:
.LFB2:
pushl %ebp
.LCFI7:
movl %esp, %ebp
.LCFI8:
pushl %esi
.LCFI9:
pushl %ebx
.LCFI10:
call .LPR0
That is instead of generating
.LPR0:
movl (%esp), %ebx
ret
for each function in the linkonce section, gcc uses one
.LPR0:
movl (%esp), %ebx
ret
in a linkonce section for the whole file. But the linker may discard
that linkonce section where the .LPR0 code is in in the final binary.
As the result, the current link will complain
call .LPR0
with something like
warning: relocation against removed section ...
and keep going. They will be turned into something like "call 0". Most
of time, it is ok. But in your case, it is not. Personally, I believe
it is a gcc bug.
Alan, should we make it a fatal error instead of just a warning? I
don't believe it is safe at all now.
Teemu, could you please file a gcc bug report with your testcase?
Thanks.
H.J.