drivers: fix symbol exports when map is omitted
Checks
Commit Message
ld exports any global symbol by default if no version script is passed.
As a consequence, the incriminated change let any public symbol leak
out of the driver shared libraries.
Hide again those symbols by providing a default map file which
unexports any global symbol using a local: * catchall statement.
The check on symbols is skipped for this default map file as it is
intentionnally an empty map (see commit b67bdda86cd4 ("devtools: catch
empty symbol maps")) and there is nothing to check in it.
While at it, move Windows specific objects where needed for better
readability.
Fixes: 7dde9c844a37 ("drivers: omit symbol map when unneeded")
Cc: stable@dpdk.org
Reported-by: Luca Boccassi <luca.boccassi@microsoft.com>
Signed-off-by: David Marchand <david.marchand@redhat.com>
---
drivers/meson.build | 70 ++++++++++++++++++++++++---------------------
drivers/version.map | 3 ++
2 files changed, 41 insertions(+), 32 deletions(-)
create mode 100644 drivers/version.map
Comments
On 11/29/2022 2:00 PM, David Marchand wrote:
> ld exports any global symbol by default if no version script is passed.
> As a consequence, the incriminated change let any public symbol leak
> out of the driver shared libraries.
>
> Hide again those symbols by providing a default map file which
> unexports any global symbol using a local: * catchall statement.
>
I assume this will cause warnings for ABI check scripts, how can we
prevent the warnings?
> The check on symbols is skipped for this default map file as it is
> intentionnally an empty map (see commit b67bdda86cd4 ("devtools: catch
> empty symbol maps")) and there is nothing to check in it.
>
How it is skipped, './devtools/check-symbol-maps.sh' still complains
about 'drivers/version.map' for me.
> While at it, move Windows specific objects where needed for better
> readability.
>
+1
> Fixes: 7dde9c844a37 ("drivers: omit symbol map when unneeded")
> Cc: stable@dpdk.org
>
> Reported-by: Luca Boccassi <luca.boccassi@microsoft.com>
> Signed-off-by: David Marchand <david.marchand@redhat.com>
Not tested on Windows, but for Linux:
Tested-by: Ferruh Yigit <ferruh.yigit@amd.com>
On Tue, Nov 29, 2022 at 7:23 PM Ferruh Yigit <ferruh.yigit@amd.com> wrote:
>
> On 11/29/2022 2:00 PM, David Marchand wrote:
> > ld exports any global symbol by default if no version script is passed.
> > As a consequence, the incriminated change let any public symbol leak
> > out of the driver shared libraries.
> >
> > Hide again those symbols by providing a default map file which
> > unexports any global symbol using a local: * catchall statement.
> >
>
> I assume this will cause warnings for ABI check scripts, how can we
> prevent the warnings?
Indeed.
Some options:
- add exhaustive suppression rules in devtools/libabigail.abignore,
- retag the v22.11 release with this fix, but we already announced it
and people started downloading the tarball,
- release a .1 version and compare ABI against it (either in the main
repo, or in the 22.11 stable branch, through for the ABI check in GHA,
it would be simpler to have the tag in the main repo..),
Do you have other ideas?
>
> > The check on symbols is skipped for this default map file as it is
> > intentionnally an empty map (see commit b67bdda86cd4 ("devtools: catch
> > empty symbol maps")) and there is nothing to check in it.
> >
>
> How it is skipped, './devtools/check-symbol-maps.sh' still complains
> about 'drivers/version.map' for me.
I had considered the call check-symbols.sh during build.
But it is true that if you call check-symbol-maps.sh alone, we will
get a warning.
I will exclude it in v2.
>
> > While at it, move Windows specific objects where needed for better
> > readability.
> >
>
> +1
>
> > Fixes: 7dde9c844a37 ("drivers: omit symbol map when unneeded")
> > Cc: stable@dpdk.org
> >
> > Reported-by: Luca Boccassi <luca.boccassi@microsoft.com>
> > Signed-off-by: David Marchand <david.marchand@redhat.com>
>
>
> Not tested on Windows, but for Linux:
> Tested-by: Ferruh Yigit <ferruh.yigit@amd.com>
UNH Windows tests look fine.
On Wed, Nov 30, 2022 at 8:13 AM David Marchand
<david.marchand@redhat.com> wrote:
> > I assume this will cause warnings for ABI check scripts, how can we
> > prevent the warnings?
>
> Indeed.
>
> Some options:
> - add exhaustive suppression rules in devtools/libabigail.abignore,
> - retag the v22.11 release with this fix, but we already announced it
> and people started downloading the tarball,
> - release a .1 version and compare ABI against it (either in the main
> repo, or in the 22.11 stable branch, through for the ABI check in GHA,
> it would be simpler to have the tag in the main repo..),
(let's forget about my concern on GHA, we have the REF_GIT_REPO param,
so we can point at the dpdk-stable repo, and go with a "normal"
release in 22.11 stable branch)
>
> Do you have other ideas?
>
On 11/30/2022 8:27 AM, David Marchand wrote:
> On Wed, Nov 30, 2022 at 8:13 AM David Marchand
> <david.marchand@redhat.com> wrote:
>>> I assume this will cause warnings for ABI check scripts, how can we
>>> prevent the warnings?
>>
>> Indeed.
>>
>> Some options:
>> - add exhaustive suppression rules in devtools/libabigail.abignore,
>> - retag the v22.11 release with this fix, but we already announced it
>> and people started downloading the tarball,
>> - release a .1 version and compare ABI against it (either in the main
>> repo, or in the 22.11 stable branch, through for the ABI check in GHA,
>> it would be simpler to have the tag in the main repo..),
>
> (let's forget about my concern on GHA, we have the REF_GIT_REPO param,
> so we can point at the dpdk-stable repo, and go with a "normal"
> release in 22.11 stable branch)
>
OK to have v22.11.1 stable release with this fix.
On Tue, Nov 29, 2022 at 06:23:21PM +0000, Ferruh Yigit wrote:
> On 11/29/2022 2:00 PM, David Marchand wrote:
> > ld exports any global symbol by default if no version script is passed.
> > As a consequence, the incriminated change let any public symbol leak
> > out of the driver shared libraries.
> >
>
> Not tested on Windows, but for Linux:
just for awareness the default is the opposite on windows symbols are
private by default and have to be explicitly made public.
also, for gcc we could go to the extreme and pass -fvisibility=hidden
and fix out any other symbols that are missed.
if you're really going wild you may consider introducing a macro that
can be expanded to __attribute__((visibility("default"))) combined with
-fvisibility=hidden (as opposed to version.map) the main benefit being
there's only a single source of truth about whether or not the symbol is
public, you don't have to look in 2 places.
(anyway, probably not a popular idea...)
ty
@@ -206,44 +206,50 @@ foreach subpath:subdirs
# now build the shared driver
version_map = '@0@/@1@/version.map'.format(meson.current_source_dir(), drv_path)
- implib = 'lib' + lib_name + '.dll.a'
lk_deps = []
lk_args = []
- if fs.is_file(version_map)
- def_file = custom_target(lib_name + '_def',
- command: [map_to_win_cmd, '@INPUT@', '@OUTPUT@'],
- input: version_map,
- output: '@0@_exports.def'.format(lib_name))
-
- mingw_map = custom_target(lib_name + '_mingw',
- command: [map_to_win_cmd, '@INPUT@', '@OUTPUT@'],
- input: version_map,
- output: '@0@_mingw.map'.format(lib_name))
-
- lk_deps = [version_map, def_file, mingw_map]
- if is_windows
- if is_ms_linker
- lk_args = ['-Wl,/def:' + def_file.full_path()]
- if meson.version().version_compare('<0.54.0')
- lk_args += ['-Wl,/implib:drivers\\' + implib]
- endif
- else
- lk_args = ['-Wl,--version-script=' + mingw_map.full_path()]
+ if not fs.is_file(version_map)
+ version_map = '@0@/version.map'.format(meson.current_source_dir())
+ lk_deps += [version_map]
+ else
+ lk_deps += [version_map]
+ if not is_windows and developer_mode
+ # on unix systems check the output of the
+ # check-symbols.sh script, using it as a
+ # dependency of the .so build
+ lk_deps += custom_target(lib_name + '.sym_chk',
+ command: [check_symbols, version_map, '@INPUT@'],
+ capture: true,
+ input: static_lib,
+ output: lib_name + '.sym_chk')
+ endif
+ endif
+
+ if is_windows
+ if is_ms_linker
+ def_file = custom_target(lib_name + '_def',
+ command: [map_to_win_cmd, '@INPUT@', '@OUTPUT@'],
+ input: version_map,
+ output: '@0@_exports.def'.format(lib_name))
+ lk_deps += def_file
+
+ lk_args = ['-Wl,/def:' + def_file.full_path()]
+ if meson.version().version_compare('<0.54.0')
+ implib = 'lib' + lib_name + '.dll.a'
+ lk_args += ['-Wl,/implib:drivers\\' + implib]
endif
else
- lk_args = ['-Wl,--version-script=' + version_map]
- if developer_mode
- # on unix systems check the output of the
- # check-symbols.sh script, using it as a
- # dependency of the .so build
- lk_deps += custom_target(lib_name + '.sym_chk',
- command: [check_symbols, version_map, '@INPUT@'],
- capture: true,
- input: static_lib,
- output: lib_name + '.sym_chk')
- endif
+ mingw_map = custom_target(lib_name + '_mingw',
+ command: [map_to_win_cmd, '@INPUT@', '@OUTPUT@'],
+ input: version_map,
+ output: '@0@_mingw.map'.format(lib_name))
+ lk_deps += [mingw_map]
+
+ lk_args = ['-Wl,--version-script=' + mingw_map.full_path()]
endif
+ else
+ lk_args = ['-Wl,--version-script=' + version_map]
endif
shared_lib = shared_library(lib_name, sources,
new file mode 100644
@@ -0,0 +1,3 @@
+DPDK_23 {
+ local: *;
+};