__patchable_function_entries is flawed

Fangrui Song i@maskray.me
Fri Jan 10 06:28:00 GMT 2020

On 2020-01-09, Fangrui Song wrote:
>On 2020-01-08, Fangrui Song wrote:
>>On 2020-01-07, Szabolcs Nagy wrote:
>>>On 07/01/2020 07:25, Fangrui Song wrote:
>>>>On 2020-01-06, Fangrui Song wrote:
>>>>>The addresses of NOPs are collected in a section named __patchable_function_entries.
>>>>>A __patchable_function_entries entry is relocated by a symbolic relocation (e.g. R_X86_64_64, R_AARCH64_ABS64, R_PPC64_ADDR64).
>>>>>In -shared or -pie mode, the linker will create a dynamic relocation (non-preemptible: relative relocation (e.g. R_X86_64_RELATIVE);
>>>>>preemptible: symbolic relocation (e.g. R_X86_64_64)).
>>>>>In either case, the section contents will be modified at runtime.
>>>>>Thus, the section should have the SHF_WRITE flag to avoid text relocations (DF_TEXTREL).
>>>pie/pic should either imply writable __patchable_function_entries,
>>>or __patchable_function_entries should be documented to be offsets
>>>from some base address in the module: the users of it have to modify
>>>.text and do lowlevel hacks so they should be able to handle such
>>>i think it's worth opening a gcc bug report.
>>https://gcc.gnu.org/bugzilla/show_bug.cgi?id=93194 patch posted to gcc-patches.
>>PC-relative relocation types (R_X86_64_64, R_AARCH64_PREL64,
>>R_PPC64_REL64) can avoid dynamic relocations, and avoid the need for
>>SHF_WRITE. Unfortunately, it seems we cannot re-interpret
>>__patchable_function_entries. I have found 2 other problems with the
>>current __patchable_function_entries. Perhaps we need a new design.
>>* https://gcc.gnu.org/bugzilla/show_bug.cgi?id=93197
>> __patchable_function_entries will always be collected by --gc-sections
>> (.tmp_vmlinux1 is not linked with --gc-sections, so it appears that
>> the Linux kernel is not affected.)
>> I think the solution requires a GNU ld and gold side fix:
>> https://sourceware.org/bugzilla/show_bug.cgi?id=24526
>> If you clang>=8, you can play with clang -fstack-size-section -c a.cc
>> Basically I think __patchable_function_entry has to behave like .stack_sizes .
>>* https://gcc.gnu.org/bugzilla/show_bug.cgi?id=93195
>> __patchable_function_entries should consider comdat groups.
>> It can cause linker failures (GNU ld, gold and lld). It is fairly
>> easy to trigger with C++ inline.
>> (OK, the Linux kernel does not speak C++.)
>> (Clang's function multi-versioning implementation uses comdat, even in
>> C. I don't have an example with GCC. My GCC __attribute__((target(..))) is broken.)
>>The two issues make -fpatchable-function-entry useless for user
>>applications. I still hope we can make the solution more general, not
>>restricted to the Linux kernel. We've already implemented enough GCC
>>options for dynamic ftrace (with regs) and live patching: -mfentry
>>-mnop-mcount -mrecord-mcount -mhotpatch -fpatchable-function-entry.
>>FWIW I am working on a clang/llvm patch https://reviews.llvm.org/D72215
>>I have tried resolving these problems.
>>("o" (SHF_LINK_ORDER+sh_link) is not recognized by GNU as.)
>The LLVM 10.0 release branch is scheduled next week. I want to
>contribute my clang -fpatchable-function-entry patches before that
>(already approved), so that clang built Linux people can play with it
>with Clang 10.0 .
>Can we agree on the syntax of the new option before 2020-01-15?
>We can reuse the option name, just overload the value by adding the
>third argument, "pcrel":
>If "pcrel" is seen, GCC should emit the __patchable_function_entries
>section which contains PC-relative addresses, instead of absolute
>addresses. This is backward compatible.
>  % stage1-gcc/xgcc -B stage1-gcc -fpatchable-function-entry=1,a -xc /dev/null
>  cc1: error: invalid arguments for ‘-fpatchable_function_entry’
>(OK, another bug: incorrect option name in the diagnostic.)
>I can teach Clang to only recognize the pcrel form.
>The function attribute does not need any change: __attribute__((patchable_function_entry(N,M)))

Some architectures do not have a PC-relative relocation type of pointer
size, e.g. MIPS has R_MIPS_PC32 (GNU extension) but not R_MIPS_PC64, and
.quad foo-. is not representable.

Making -fpatchable-function-entry=2,0 absolute by default is fine (I
will teach Clang to emit such __patchable_function_entries table). Just
wanted to mention that on most other architectures PC-relative is

More information about the Gcc mailing list