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:
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: arch_profile: Microcontroller ISA_use: Thumb-2 PCS_GOT_ use: direct PCS_wchar_ t: 2 align_needed: 8-byte align_preserved : 8-byte, except leaf SP enum_size: forced to int unaligned_ access: v6
Attribute Section: aeabi
File Attributes
Tag_conformance: "2.06"
Tag_CPU_name: "Cortex-M3"
Tag_CPU_arch: v7
Tag_CPU_
Tag_THUMB_
Tag_PCS_config: Bare platform
Tag_ABI_
Tag_ABI_
Tag_ABI_
Tag_ABI_
Tag_ABI_
Tag_CPU_
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: ALU_PREL_ 11_ 000000a9 ThumbFunc1
Offset Info Type Sym. Value Symbol's Name
0000008a 00003d35 R_ARM_THM_
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, ALU_PREL_ 11_0 should calculate the relocation value via "((S + A) | T) – Pa"
- a relocation entry of type R_ARM_THM_
- "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 thumb_only( globals) || branch_type == ST_BRANCH_ TO_THUMB) )
8663a8664,8667
> if (st_type == STT_FUNC &&
> (using_
> 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.