Index: ELF/Relocations.cpp =================================================================== --- ELF/Relocations.cpp +++ ELF/Relocations.cpp @@ -464,8 +464,14 @@ return Expr; } if (Body.getVisibility() != STV_DEFAULT) { - error(S.getLocation(RelOff) + ": cannot preempt symbol '" + toString(Body) + - "' defined in " + toString(Body.File)); + // Default visibility is the only one that allows us to preempt the symbol + // with a dummy plt or copy relocation. If the symbol has any other + // visibility the .so can refer to it directly and the dynamic linker will + // not be able to do anything about it. + error(S.getLocation(RelOff) + + ": cannot preempt non-default visibility symbol '" + toString(Body) + + "' defined in " + toString(Body.File) + + ".\n The executable has to use a got or plt to refer to it."); return Expr; } if (Body.isObject()) { Index: test/ELF/copy-errors.s =================================================================== --- test/ELF/copy-errors.s +++ test/ELF/copy-errors.s @@ -9,7 +9,8 @@ call bar -// CHECK: {{.*}}.o:(.text+0x1): cannot preempt symbol 'bar' defined in {{.*}}.so +// CHECK: {{.*}}.o:(.text+0x1): cannot preempt non-default visibility symbol 'bar' defined in {{.*}}.so +// CHECK-NEXT: The executable has to use a got or plt to refer to it. call zed // CHECK: symbol 'zed' defined in {{.*}}.so is missing type