On Wed, Jun 9, 2021 at 6:48 AM Michael Matz <
ma...@suse.de> wrote:
>
> Hello,
Hello:)
> On Wed, 9 Jun 2021, 'Fāng-ruì Sòng' via Generic System V Application
> Binary Interface wrote:
>
> > I was confused by GCC's -fno-semantic-interposition. It means address
> > interposition is still possible (i.e. taking the address of a function
> > does not use the local alias).
> > Semantic interposition is disabled (i.e. interposition cannot change
> > the semantics).
> >
> > It seems that **not using** a local alias for variable access is
> > intended by GCC -fno-semantic-interposition.
> >
> > If variable access/function address uses a local alias as well,
> > -fno-semantic-interposition -shared -Bsymbolic would not have worse
> > code generation than -fpie -pie.
>
> And would break existing binaries containing copy relocs.
>
> Btw: I have a hunch that you are concentrating too much on a single
> solution to your initial problem (as you said it is was a complaint from a
> user about clang's slowness). Your solution to that is to completely
> change the symbol interposition rules of ELF. Are you sure it's the only
> way? E.g. _what_ is slow without the change? Is it symbol lookup itself,
> or the impossibility to inline functions because of interposition
> requirements?
The sheer number of symbol lookups R_*_JUMP_SLOT/R_X86_64_64 and a few
R_*_GLOB_DAT was the **main reason** behind
the Fedora clang's slowness (and Linus' rant).
I rebuilt my dynamically linked Clang with -Wl,-Bsymbolic-functions
(80+% fewer symbol lookups) and my Linux kernel x86-64 defconfig build
with clang is more than 15% faster.
The reason is likely because there are too many small files and the
ld.so time takes a significant portion of a short-lived process.
Reducing the number of dynamic relocations (either fixing
STV_PROTECTED or using a variant of -Bsymbolic-functions) is the only
direction for such applications.
-fno-semantic-interposition contributed an extra 3% boost on some
benchmarks, but not for my Linux kernel build.
> Because for both I can envision different solutions that aren't turning
> interposition off. Because I like interposition, in fact I think it's a
> very good feature of ELF.
>
> But e.g. interposition could be limited to symbols where it traditionally
> has it's uses: C symbols. It could for instance be switched off for C++
> class methods (at which point the vtable references could then also become
> non-symbolic). It could also be switched off for functions resulting from
> template instantiation.
For C++, vague-linkage definitions (inline functions, template
instantiations, etc) don't suppress inlining in GCC.
inline void foo() {}
void bar() { foo() }
Interposition on foo does not guarantee to work.
IIUC GCC -fno-semantic-interposition applies to non-vague-linkage
external linkage definitions.
Hmmm, making -fno-semantic-interposition default for all C++ symbols
(C++ has the one definition rule) would be useful.
Doing that for C will be a plus. For example, there was a large cost
for CPython (27%).
I know some users do LD_PRELOAD. But more often the LD_PRELOAD usage
applies to an undefined symbol
(
https://maskray.me/blog/2021-05-16-elf-interposition-and-bsymbolic#interaction-with-ld_preload).
It is very rare that a user replaces a STB_GLOBAL STV_DEFAULT
function. Such tricks, when rarely applied, are to work around some
bad software.
For such cases the software should just be re-built without aggressive
symbolic link options.
On Mach-O, some tricks like -flat_namespace are needed to allow interposition.
IIUC Solaris does allow interposition to override direct bindings.
> If you were to propose that, and where also proposing to make that default
> for a distro I would be in your camp probably. But I would not consider
> making anything switching off interposition globally the default for our
> distro.
>
> (GNU ld has collected bits of pieces of such approaches over time, e.g.
> -Bsymbolic-functions and --dynamic-list-{data,cpp-new,cpp-typeinfo}, but
> none of them really match what would be ideal)
Yep:) I'd even say --dynamic-list-{data,cpp-new,cpp-typeinfo} has zero
use in the wild.
> > As of why protected symbols cannot be used, because protected symbols
> > have been made very broken in GCC/binutils, some time circa 2016, more
> > so on x86. If someone wants to know more details,
>
> >
https://maskray.me/blog/2021-01-09-copy-relocations-canonical-plt-entries-and-protected
>
> Yes, copy relocations should be phased out, no disagreement here.
> Canonical PLT entries: as well for protected functions, for default ones:
> hmm.
>
> But we must deal with the problem of existing uses of these undesirable
> features.
>
> > -fvisibility=protected is too coarse-grained. An option not applying to
> > weak symbols might be more useful. Due to copy relocations, a variant
> > not applying to variables would be useful as well.
>
> I once hacked something for GCC that made all functions protected, i.e.
> -fvisbility-functions=protected, in order to get the inlining benefit from
> the associated non-preemptability. Then I realized that -fpie gave me
> essentially the same semantics (for what I wanted) :)
My idea is that -fvisibility=protected -fpic is very similar to -fpie,
but it cannot be used due to copy relocations and canonical PLT
entries.
The slightly inferior -fno-semantic-interposition -fpic is also
similar to -fpie, just not optimization global variables (which should
not matter for performance anyway).
-fno-semantic-interposition works well with
-fvisibility-inlindes-hidden, when users don't want pointer equality
for functions. As my article says, such property is rarely leveraged.
It is difficult to guarantee on Windows anyway.
However, -fpie also optimizes TLS, which makes it not suitable for
-shared linking.
I think the -fvisibility variant should exclude variables and exclude
weak definitions.
If you still insist on C symbols interposable by default, I think you
may make that -f option g++/CXXFLAGS only...
If you change your mind in the future, you can apply that -f option to
gcc/CFLAGS as well..
Such an option will be mostly suitable as the distribution default.
https://maskray.me/blog/2021-01-09-copy-relocations-canonical-plt-entries-and-protected#protected-function-symbols-and-canonical-plt-entries
The GNU ld aarch64 and x86's rejection on this code should be fixed:
__attribute__((visibility("protected"))) void *foo () {
return (void *)foo;
}
% gcc -fpic -shared b.c -fuse-ld=bfd b.c -o b.so
/usr/bin/ld.bfd: /tmp/cc3Ay0Gh.o: relocation R_X86_64_PC32 against
protected symbol `foo' can not be used when making a shared object
/usr/bin/ld.bfd: final link failed: bad value
collect2: error: ld returned 1 exit status
% gcc -shared -fuse-ld=bfd -fpic b.c -o b.so
/usr/bin/ld.bfd: /tmp/ccXdBqMf.o: relocation
R_AARCH64_ADR_PREL_PG_HI21 against symbol `foo' which may bind
externally can not be used when making a shared object; recompile with
-fPIC
/tmp/ccXdBqMf.o: in function `foo':
a.c:(.text+0x0): dangerous relocation: unsupported relocation
collect2: error: ld returned 1 exit status
The diagnostic was to make a fragile glibc feature (acked by multiple
glibc developers): copy relocation on protected symbols.
Unfortunately it applies to function symbols as well.
>
> Ciao,
> Michael.
>
> --
> You received this message because you are subscribed to the Google Groups "Generic System V Application Binary Interface" group.
> To unsubscribe from this group and stop receiving emails from it, send an email to
generic-abi...@googlegroups.com.
> To view this discussion on the web visit
https://groups.google.com/d/msgid/generic-abi/alpine.LSU.2.22.394.2106091309100.3803%40wotan.suse.de.