This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [PATCH] Fix default_binds_local_p_2 for extern protected data


On 30/09/15 14:47, Bernd Schmidt wrote:
On 09/17/2015 11:15 AM, Szabolcs Nagy wrote:
ping 2.

this patch is needed for working visibility ("protected")
attribute for extern data on targets using default_binds_local_p_2.
https://gcc.gnu.org/ml/gcc-patches/2015-07/msg01871.html

I hesitate to review this one since I don't think I understand the
issues on the various affected arches well enough. It looks like Jakub
had some input on the earlier changes, maybe he could take a look? Or
maybe rth knows best. Adding Ccs.

It would help to have examples of code generation demonstrating the
problem and how you would solve it. Input from the s390 maintainers
whether this is correct for their port would also be appreciated.


consider the TU

  __attribute__((visibility("protected"))) int n;

  int f () { return n; }

if n "binds_local" then gcc -O -fpic -S is like

        .text
        .align  2
        .global f
        .arch armv8-a+fp+simd
        .type   f, %function
f:
        adrp    x0, n
        ldr     w0, [x0, #:lo12:n]
        ret
        .size   f, .-f
        .protected      n
        .comm   n,4,4

so 'n' is a direct reference, not accessed through
the GOT ('n' will be in the .bss of the dso).
this is the current behavior.

if i remove the protected visibility attribute
then the access goes through GOT:

        .text
        .align  2
        .global f
        .arch armv8-a+fp+simd
        .type   f, %function
f:
        adrp    x0, _GLOBAL_OFFSET_TABLE_
        ldr     x0, [x0, #:gotpage_lo15:n]
        ldr     w0, [x0]
        ret
        .size   f, .-f
        .comm   n,4,4

protected visibility means the definition cannot
be overridden by another module, but it should
still allow extern references.

if the main module references such an object then
(as an implementation detail) it may use copy
relocation against it, which places 'n' in the
main module and the dynamic linker should make
sure that references to 'n' point there.

this is only possible if references to 'n' go
through the GOT (i.e. it should not be "binds_local").

this got fixed on x86 (there are explanations in
pr65248, pr55012), but the default_binds_local_p
logic is not fixed.

Needs a further binutils patch too to emit R_*_GLOB_DAT
instead of R_*_RELATIVE relocs for protected data.
The glibc elf/tst-protected1a and elf/tst-protected1b
tests depend on this.

What is the consequence of not having this binutils patch? Is the gcc
patch and improvement, a null, or are there situations where it causes
regressions without the binutils patch?


does not cause regressions.

binutils also assumed that extern protected data is
local so it did not emit the R_*_GLOB_DAT relocations
for it which means there is no symbolic GOT entry that
the dynamic-linker can update, so the behavior is the
same as before.

glibc dynamic linker also failed to handle this case
with similar effect.

so for correct behavior new gcc, new binutils and new
glibc are needed, if any one is old that results the old
behavior.

binutils trunk and glibc-2.22 have the fix for aarch64
and arm (and x86 and various other arches).

Tested ARM and AArch64 targets.

Tested how, with or without this binutils patch?


with old and new binutils as well.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]