https://sourceware.org/bugzilla/show_bug.cgi?id=21523
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 error: 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: https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;a=blob;f=bfd/elf32-arm.c;h=1725c222696b846c29cefdea1fd414d88626839f;hb=HEAD#l10487 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: https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;a=commit;f=bfd/elf32-arm.c;h=b6518b3871859f9eeb7653bf2f3baaa43fa0a5d0 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 true: 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. Thanks -- You are receiving this mail because: You are on the CC list for the bug. _______________________________________________ bug-binutils mailing list bug-binutils@gnu.org https://lists.gnu.org/mailman/listinfo/bug-binutils