Bug 28603 - Incorrect branch offset from the start of a function after enable LTO
Summary: Incorrect branch offset from the start of a function after enable LTO
Status: UNCONFIRMED
Alias: None
Product: binutils
Classification: Unclassified
Component: ld (show other bugs)
Version: 2.35.1
: P2 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2021-11-18 06:52 UTC by Eason Lai
Modified: 2021-12-22 05:16 UTC (History)
1 user (show)

See Also:
Host: x86_64
Target: ARM CM4
Build: arm-none-eabi-gcc
Last reconfirmed:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Eason Lai 2021-11-18 06:52:53 UTC
After enabling LTO, the branch offset is incorrect in SVC_Handler of a FreeRTOS+CM4 project.

Here is the simple code and assembler output. The branch address is offset 2 bytes from foo function and bypass the push instruction. It causes problem when returning from foo function.
==========================================================
void SVC_Handler(void)
{
    __asm volatile (
                    "    cpsid i    \n"
                    "    blx   foo  \n"
                    "    cpsie i    \n"
                /* ..... code removed ... */
}

000010b0 <SVC_Handler>:
000010b0:    b672         cpsid   i
000010b2:    f7ff f892    bl  000001da <foo+0x2>    <<<---- this causes problem
000010b6:    b662         cpsie   i


000001d8: <foo>:
000001d8:    e92d 4178    stmdb    sp!, {r3, r4, r5, r6, r8, lr}
000001dc:    f001 f8e8    bl  000013b0 <__foo2_veneer>
==========================================================

If I change the blx to bl or insert push/pop, the result will be OK.
==========================================================
void SVC_Handler(void)
{
    __asm volatile (
                    "    cpsid i    \n"
                    "    bl    foo  \n"
                    "    cpsie i    \n"
                /* ..... code removed ... */
}

000010b0 <SVC_Handler>:
000010b0:    b672         cpsid   i
000010b2:    f7ff f892    bl  000001d8 <foo>
000010b6:    b662         cpsie   i


000001d8: <foo>:
000001d8:    e92d 4178    stmdb    sp!, {r3, r4, r5, r6, r8, lr}
000001dc:    f001 f8e8    bl  000013b0 <__foo2_veneer>
==========================================================

void SVC_Handler(void)
{
    __asm volatile (
                    "    cpsid i    \n"
                    "    push  {lr} \n"
                    "    blx   foo  \n"
                    "    pop   {lr} \n"
                    "    cpsie i    \n"
                /* ..... code removed ... */
}
Comment 1 Eason Lai 2021-11-25 06:26:39 UTC
I have tried to reproduce the issue by creating a simple code for reference, but no lucky. If anyone else could give me hint which part of linker may causes this problem, I will try deep dive the source code and find I can help or not. Thank you.
Comment 2 Eason Lai 2021-12-08 09:07:38 UTC
Could anyone take a look? or any suggestion? Thanks.
Comment 3 Nick Clifton 2021-12-15 12:57:17 UTC
(In reply to Eason Lai from comment #1)
> I have tried to reproduce the issue by creating a simple code for reference,
> but no lucky. If anyone else could give me hint which part of linker may
> causes this problem, I will try deep dive the source code and find I can
> help or not. Thank you.

Is this ARM/AArch64 code that you are talking about ?

If so then the code you will want to look at is in the bfd/ directory, specifically the elf32-arm.c and/or elfxx-aarch64.c files.  Look for the functions which are used to resolve relocations.

It is strange that LTO is causing this problem.  I am not sure why this would cause the effect that you are seeing.  Is it possible that the bad code still has a relocation associated with it which would put the correct address into place when the program is loaded ?

Cheers
  Nick
Comment 4 Eason Lai 2021-12-22 05:16:42 UTC
(In reply to Nick Clifton from comment #3)
> (In reply to Eason Lai from comment #1)
> > I have tried to reproduce the issue by creating a simple code for reference,
> > but no lucky. If anyone else could give me hint which part of linker may
> > causes this problem, I will try deep dive the source code and find I can
> > help or not. Thank you.
> 
> Is this ARM/AArch64 code that you are talking about ?
> 
> If so then the code you will want to look at is in the bfd/ directory,
> specifically the elf32-arm.c and/or elfxx-aarch64.c files.  Look for the
> functions which are used to resolve relocations.
> 
> It is strange that LTO is causing this problem.  I am not sure why this
> would cause the effect that you are seeing.  Is it possible that the bad
> code still has a relocation associated with it which would put the correct
> address into place when the program is loaded ?
> 
> Cheers
>   Nick

Thanks for reply.
I am using ARM CM4 and no relocation when the program is loaded. 

I have checked the elf32-arm.c, and it is a large file and not easy to figure out the problem by non-professionals like me. If any professional can help on this, I will really really appreciate it. Thank you very much.