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 arithmetics. i think it's worth opening a gcc bug report. >> When -ffunction-sections is used, ideally GCC should emit one >> __patchable_function_entries (SHF_LINK_ORDER) per .text.foo . >> If the corresponding .text.foo is discarded (--gc-sections, COMDAT, >> /DISCARD/), the linker can discard the associated >> __patchable_function_entries. This can be seen as a lightweight COMDAT >> section group. (A section group adds an extra section and costs 3 words) >> Currently lld (LLVM linker) has implemented such SHF_LINK_ORDER collecting >> features. GNU ld and gold don't have the features. >> >> I have summarized the feature requests in this post >> https://sourceware.org/ml/binutils/2019-11/msg00266.html >> >> gcc -fpatchable-function-entry=2 -ffunction-sections -c a.c >> >> [ 4] .text.f0 PROGBITS 0000000000000000 000040 000009 00 >> AX 0 0 1 >> ### No W flag >> ### One __patchable_function_entries instead of 3. >> [ 5] __patchable_function_entries PROGBITS 0000000000000000 000049 >> 000018 00 A 0 0 1 >> [ 6] .rela__patchable_function_entries RELA 0000000000000000 >> 000280 000048 18 I 13 5 8 >> [ 7] .text.f1 PROGBITS 0000000000000000 000061 000009 00 >> AX 0 0 1 >> [ 8] .text.f2 PROGBITS 0000000000000000 00006a 000009 00 >> AX 0 0 1 > > Emitting a __patchable_function_entries for each function may waste > object file sizes (64 bytes per function on ELF64). If zeros are > allowed, emitting a single __patchable_function_entries should be fine. > > If we do want to emit unique sections, the condition should be either > -ffunction-sections or COMDAT is used. again it's worth raising a gcc bug i think. there is another known issue: aarch64 -mbranch-protect=bti (and presumably x86_64 -fcf-protection=branch) has to add landing pad at the begining of each indirectly called function so the patchable nops can only come after that. https://gcc.gnu.org/bugzilla/show_bug.cgi?id=92424 no matter how this gets resolved i think this will require documentation changes too.