Re: Fwd: [PATCH v2] PE/COFF: Implement visibility attribute via .drectve
LIU Hao <[email protected]>
| Newsgroups | gmane.comp.gcc.patches |
|---|---|
| Message-ID | <[email protected]> |
在 2026-8-9 22:45, Oleg Tolmatcev 写道: > ---------- Forwarded message --------- > От: Oleg Tolmatcev <[email protected]> > Date: вс, 9 авг. 2026 г. в 16:43 > Subject: [PATCH v2] PE/COFF: Implement visibility attribute via .drectve > To: <[email protected]> > Cc: Oleg Tolmatcev <[email protected]> > > > On PE/COFF targets (MinGW, Cygwin), the visibility attribute was > previously ignored with a warning. This patch makes it functional > by emitting -exclude-symbols directives into the .drectve section, > matching Clang's behavior. The GNU linker already reads and > respects these directives during auto-export, so hidden/internal > symbols are now correctly excluded from DLL exports. > > gcc/ChangeLog: > > * config/mingw/winnt.cc (i386_pe_drectve_name): New. > (i386_pe_assemble_visibility): Emit -exclude-symbols > directives into .drectve for VISIBILITY_HIDDEN and > VISIBILITY_INTERNAL instead of warning. Use the external > symbol spelling for 32-bit PE names. > > gcc/testsuite/ChangeLog: > > * gcc.target/i386/visibility-hidden-mingw.c: New test. > * gcc.target/i386/visibility-hidden-mingw-32.c: New test. > > Signed-off-by: Oleg Tolmatcev <[email protected]> > --- > gcc/config/mingw/winnt.cc | 38 +++++++++++++++---- > .../i386/visibility-hidden-mingw-32.c | 12 ++++++ > .../gcc.target/i386/visibility-hidden-mingw.c | 24 ++++++++++++ > 3 files changed, 66 insertions(+), 8 deletions(-) > create mode 100644 gcc/testsuite/gcc.target/i386/visibility-hidden-mingw-32.c > create mode 100644 gcc/testsuite/gcc.target/i386/visibility-hidden-mingw.c > > diff --git a/gcc/config/mingw/winnt.cc b/gcc/config/mingw/winnt.cc > index 66d7450652..2e06b0e814 100644 > --- a/gcc/config/mingw/winnt.cc > +++ b/gcc/config/mingw/winnt.cc > @@ -254,20 +254,42 @@ i386_pe_maybe_mangle_decl_assembler_name (tree > decl, tree id) > > #endif > > +/* Return the symbol spelling used by .drectve exclude-symbols directives. > + This is the external name without the user label prefix, while preserving > + calling-convention decoration such as fastcall's leading '@' or a > + stdcall suffix. */ > + > +static const char * > +i386_pe_drectve_name (tree id) > +{ > + const char *name = targetm.strip_name_encoding (IDENTIFIER_POINTER (id)); > + size_t prefix_len = strlen (user_label_prefix); > + > + if (prefix_len != 0 > + && strncmp (name, user_label_prefix, prefix_len) == 0) > + name += prefix_len; > + > + return name; > +} > + > /* Emit an assembler directive to set symbol for DECL visibility to > the visibility type VIS, which must not be VISIBILITY_DEFAULT. > - As for PE there is no hidden support in gas, we just warn for > - user-specified visibility attributes. */ > + Emit a -exclude-symbols directive into .drectve, compatible with > + what Clang emits for hidden visibility on PE/COFF. */ > > void > -i386_pe_assemble_visibility (tree decl, int) > +i386_pe_assemble_visibility (tree decl, int vis) > { > - if (!decl > - || !lookup_attribute ("visibility", DECL_ATTRIBUTES (decl))) > + if (!decl) > return; > - if (!DECL_ARTIFICIAL (decl)) > - warning (OPT_Wattributes, "visibility attribute not supported " > - "in this configuration; ignored"); > + > + if (vis == VISIBILITY_HIDDEN || vis == VISIBILITY_INTERNAL) > + { > + tree id = DECL_ASSEMBLER_NAME (decl); > + const char *name = i386_pe_drectve_name (id); > + drectve_section (); > + fprintf (asm_out_file, "\t.ascii \" -exclude-symbols:%s\"\n", name); > + } > } > > #if !defined (TARGET_AARCH64_MS_ABI) > diff --git a/gcc/testsuite/gcc.target/i386/visibility-hidden-mingw-32.c > b/gcc/testsuite/gcc.target/i386/visibility-hidden-mingw-32.c > new file mode 100644 > index 0000000000..a952c71a01 > --- /dev/null > +++ b/gcc/testsuite/gcc.target/i386/visibility-hidden-mingw-32.c > @@ -0,0 +1,12 @@ > +/* { dg-do compile { target i?86-*-mingw32* i?86-*-cygwin* } } */ > +/* { dg-options "-fvisibility=hidden" } */ > + > +void some_cdecl (int, int) {} > +void __attribute__((stdcall)) some_stdcall (int, int) {} > +void __attribute__((fastcall)) some_fastcall (int, int) {} > + > +/* Hidden visibility on 32-bit PE/COFF drops the user label prefix in > + .drectve, but keeps stdcall and fastcall decoration. */ > +/* { dg-final { scan-assembler {-exclude-symbols:some_cdecl} } } */ > +/* { dg-final { scan-assembler {-exclude-symbols:some_stdcall@8} } } */ > +/* { dg-final { scan-assembler {-exclude-symbols:@some_fastcall@8} } } */ > diff --git a/gcc/testsuite/gcc.target/i386/visibility-hidden-mingw.c > b/gcc/testsuite/gcc.target/i386/visibility-hidden-mingw.c > new file mode 100644 > index 0000000000..12d792631d > --- /dev/null > +++ b/gcc/testsuite/gcc.target/i386/visibility-hidden-mingw.c > @@ -0,0 +1,24 @@ > +/* { dg-do link { target *-*-mingw* *-*-cygwin* } } */ > +/* { dg-require-dll "" } */ > +/* { dg-options "-shared -fvisibility=hidden > -Wl,--output-def,visibility-hidden-mingw.def" } */ > + > +void __attribute__((visibility("default"))) exported_func(void) {} > +void hidden_func(void) {} > +void __attribute__((visibility("hidden"))) explicit_hidden_func(void) {} > +void __attribute__((visibility("internal"))) internal_func(void) {} > + > +/* exported_func has default visibility, so it should be exported. */ > +/* { dg-final { scan-file visibility-hidden-mingw.def > "(?n)^\\s*exported_func(?:\\s+@\[0-9\]+)?$" } } */ > + > +/* hidden_func gets hidden from -fvisibility=hidden, so it should not be > + auto-exported. */ > +/* { dg-final { scan-file-not visibility-hidden-mingw.def > "(?n)^\\s*hidden_func(?:\\s+@\[0-9\]+)?$" } } */ > + > +/* explicit_hidden_func is explicitly hidden, so it should not be > + auto-exported. */ > +/* { dg-final { scan-file-not visibility-hidden-mingw.def > "(?n)^\\s*explicit_hidden_func(?:\\s+@\[0-9\]+)?$" } } */ > + > +/* internal_func has internal visibility, so it should not be > auto-exported. */ > +/* { dg-final { scan-file-not visibility-hidden-mingw.def > "(?n)^\\s*internal_func(?:\\s+@\[0-9\]+)?$" } } */ > + > +/* { dg-final { remove-build-file "visibility-hidden-mingw.def" } } */ > -- > 2.55.0.windows.3 I have tested this change on {x86_64,i686}-w64-mingw32 and both look good to me. Thanks. -- Best regards, LIU Hao
OpenPGP_signature.asc
(application/pgp-signature, 840 B)
-----BEGIN PGP SIGNATURE----- wsF5BAABCAAjFiEEYmSQWY4DEzq4FUs4hfveZl3ogBsFAmp5qJAFAwAAAAAACgkQhfveZl3ogBt/ EQ//YDvdlSJ8qQ5wfwrD6nCwcUizy3D9/aF0oIF98NQtmJeKeFV60IY4vmU1zepqXAI+icWzRU6U KUzZBMm0f29MPnpi3/jrpq79Cn+Pf5CUw+YIksiuFlcOn24Y+CfGdgwplZnWyzNXwnTyzor8OYV0 ykcC32QTGQJEsZTyh2MlE8NFJh6hooxmuRAJ4cAGmr3bCfsjKxae1o4JKjjFTGo2gzBPqcq4Mxfu abwJGSKEUTOiEm+5+xJWku3m9ApLfn7Dpm2tsW5sB61xZd9yUBuOxyxrG+cqkVCeI53ZwK0kWY3z KwdYAGoXzqSZwUHusZFZzIYuk9WaT1/Thi5twqVytOr2ZyGLDbpAI5XwnpyRZbO+CmqYOjaK4Bt6 n1LCCUlDCpwGWDl5AYxktUoFwI1ex+Z5SBzSnn10A1reGBD4wMnmHiU8dEPxgE8Q16lzxc64MZdL PhYhsdCahX/sOr5ku3Aro35N9DCOTxrjeWS+FU0gI0lIp7EsSUhyyRiyPu/ILQA9qXviEB0EHwTO VlG1MLYsC1nPvS3TqUVGueLqoAwr6uoipEjXFCwuK0HFC6SBtWFA3j7T+gcBnN51m3hC8pxgi9HN euMHFncb701K3tLwvlV4w3czjtgpq5tMI6DnMCmC+8YxElGk+lbIuinpObhHGnVDaXCTtH6PezzR /T8= =odGb -----END PGP SIGNATURE-----