Comment 6 for bug 1421389

Revision history for this message
Pulin Shah (pulin) wrote :

I've successfully patched ld to produce the correct output for the scenario described in the original bug report. Details and "patch" follow.

To illustrate the issue, here is some output from readelf of the object file containing the problematic symbol:

ABI header:
Attribute Section: aeabi
File Attributes
  Tag_conformance: "2.06"
  Tag_CPU_name: "Cortex-M3"
  Tag_CPU_arch: v7
  Tag_CPU_arch_profile: Microcontroller
  Tag_THUMB_ISA_use: Thumb-2
  Tag_PCS_config: Bare platform
  Tag_ABI_PCS_GOT_use: direct
  Tag_ABI_PCS_wchar_t: 2
  Tag_ABI_align_needed: 8-byte
  Tag_ABI_align_preserved: 8-byte, except leaf SP
  Tag_ABI_enum_size: forced to int
  Tag_CPU_unaligned_access: v6
  Tag_DIV_use: Not allowed

Symbol table entry:
   Num: Value Size Type Bind Vis Ndx Name
    61: 000000a9 74 FUNC LOCAL DEFAULT 12 ThumbFunc1

Relocation entry:
 Offset Info Type Sym. Value Symbol's Name
0000008a 00003d35 R_ARM_THM_ALU_PREL_11_ 000000a9 ThumbFunc1

As you can see from the symbol table entry, the symbol "ThumbFunc1" is listed as a "FUNC" type with the LSB set for its value. This should be enough to indicate to the linker that the symbol is a thumb function.

According to the ABI,
 - a relocation entry of type R_ARM_THM_ALU_PREL_11_0 should calculate the relocation value via "((S + A) | T) – Pa"
 - "T is 1 if the target symbol S has type STT_FUNC and the symbol addresses a Thumb instruction"
 - ld is clearly not checking the type of the symbol for whether it is a function and additionally if it is a Thumb function

In this case, the symbol is provided by an object with appropriate information for the linker to determine it is a Thumb function and should be setting the LSB accordingly.

In order to correct this behavior, I applied the following patch:

diff a/binutils/bfd/elf32-arm.c b/binutils/bfd/elf32-arm.c
8663a8664,8667
> if (st_type == STT_FUNC &&
> (using_thumb_only(globals) || branch_type == ST_BRANCH_TO_THUMB))
> value |= 1;
>

Adding the check above, the linker now sets the LSB correctly for relocation entries of this type.

Any feedback you have would be appreciated.