[Top][All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Bug ld/21523] New: Relocation for R_ARM_THM_ALU_PREL_11_0 is not calcul

From: clegg89 at gmail dot com
Subject: [Bug ld/21523] New: Relocation for R_ARM_THM_ALU_PREL_11_0 is not calculated correctly
Date: Thu, 25 May 2017 17:56:56 +0000


            Bug ID: 21523
           Summary: Relocation for R_ARM_THM_ALU_PREL_11_0 is not
                    calculated correctly
           Product: binutils
           Version: 2.26
            Status: UNCONFIRMED
          Severity: normal
          Priority: P2
         Component: ld
          Assignee: unassigned at sourceware dot org
          Reporter: clegg89 at gmail dot com
  Target Milestone: ---

I am using the gcc-arm-none-eabi version 6-2017-q1-update, which uses LD
version 2.26.

I am attempting to link in some vendor libraries along with my own source code.
The libraries were compiled with a different toolchain (IAR), but contain ARM
ELF Relocatable object files. Using arm-none-eabi-objdump I am able to view the
contents of the object files just fine.

For the must part I am able to link correctly, however I get a single link

relocation truncated to fit: R_ARM_THM_ALU_PREL_11_0

This relocation is used by the ADR instruction to provide an offset from the
PC. Based on where the symbol ends up in relation to the relocation, the ADR
may be either an ADD or SUB immediate instruction from PC. The link appears
only to work correctly in the case of an ADD.

I traced the error down to the elf32_arm_final_link_relocate. Specifically this
case statement:


Here the addend and relocation value are calculated correctly:

  relocation -= Pa (input_section->output_section->vma
        + input_section->output_offset
        + rel->r_offset);

However then the value is assigned incorrectly:

  value = relocation;

This should be:

  value = abs(relocation);

It was originally written this way but changed for some reason. The commit that
changed it was:


I am not sure why the abs() was considered useless in this case. The commit
message mentions warnings from clang.

Regardless, the assignment without the abs() call will cause the linker to
think an overflow has occurred when one has not. If the resulting relocation is
negative, and no abs() is performed, the following overflow check will trigger
a false error for negative values:

  if (value >= 0x1000)
    return bfd_reloc_overflow;

Not only that, but the following check performed later will never evaluate to

  if (relocation < 0)
    insn |= 0xa00000;

Proposed solution would be to change back to:

  value = abs(relocation);

Please let me know if anymore information is needed. I can try to generate a
simple example which demonstrates the problem if needed.


You are receiving this mail because:
You are on the CC list for the bug.

reply via email to

[Prev in Thread] Current Thread [Next in Thread]