Bug 31619 - sh: fdpic linker breaks function pointer equality
Summary: sh: fdpic linker breaks function pointer equality
Status: UNCONFIRMED
Alias: None
Product: binutils
Classification: Unclassified
Component: ld (show other bugs)
Version: unspecified
: P2 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2024-04-08 15:18 UTC by Rich Felker
Modified: 2024-04-08 15:58 UTC (History)
0 users

See Also:
Host:
Target:
Build:
Last reconfirmed:


Attachments
proposed fix (728 bytes, patch)
2024-04-08 15:18 UTC, Rich Felker
Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Rich Felker 2024-04-08 15:18:54 UTC
Created attachment 15453 [details]
proposed fix

The sh linker's handling of function descriptors seems to be based on a mistaken idea that the linker can create "canonical" function descriptors for dynamic symbols, which provide the definition of the public address of a function. This is not what the ABI document specifies, and is simply not possible, because the linker logic to create these function descriptors does not preserve enough information for a dynamic linker to find the descriptors it created and associate them with symbol names.

The issue came up as part of work on fdpic support for xtensa, where the same confusion arose and it was noted that neither the WIP xtensa fdpic support, nor the existing sh fdpic support, was doing the right (or even workable) thing.

On SH, the bug has two layers:

1. The SYMBOL_FUNCDESC_LOCAL macro wrongly checks whether the symbol is defined locally, rather than whether it is externally visible. Whenever the symbol is externally visible (outside the executable/DSO being created), the output must preserve any R_SH_FUNCDESC relocation for the dynamic linker to see.

2. sh_elf_relocate_section wrongly "optimizes" FUNCDESC relocations that would call locally, but which SYMBOL_FUNCDESC_LOCAL says can't have their addresses defined locally, to be section-based rather than symbolic. This makes it so that, even if the first issue is fixed, the output is still broken.

I have a proposed patch (attached) fixing both.

Note that, even with these, GCC will not do the right thing because it emits R_SH_GOTOFFFUNCDESC relocations rather than R_SH_GOTFUNCDESC relocations when the symbol is locally defined. This can be worked around for testing by passing -fPIC to GCC so that it generates code suitable for use in a shared library. I will be submitting a separate patch for GCC to fix the default main-program behavior.