在Solaris x86平台上覆盖mapfile中的hwcap_2

在Solaris x86平台上覆盖mapfile中的hwcap_2,x86,linker,solaris,solaris-studio,suncc,X86,Linker,Solaris,Solaris Studio,Suncc,我们有一个保护运行时路径的库。如果cpu功能可用,则采用更快的代码路径。我们正在尝试在Solaris 11.3上添加AVX2代码路径 在没有AVX2的旧的下层机器上,我们遇到了: $ ./cryptest.exe v ld.so.1: cryptest.exe: fatal: cryptest.exe: hardware capability (CA_SUNW_HW_2) unsupported: 0x40 [ AVX2 ] Killed 我们有一个映射文件,可以清除运行时功能检测带来的功能

我们有一个保护运行时路径的库。如果cpu功能可用,则采用更快的代码路径。我们正在尝试在Solaris 11.3上添加AVX2代码路径

在没有AVX2的旧的下层机器上,我们遇到了:

$ ./cryptest.exe v
ld.so.1: cryptest.exe: fatal: cryptest.exe: hardware capability (CA_SUNW_HW_2) unsupported: 0x40  [ AVX2 ]
Killed
我们有一个映射文件,可以清除运行时功能检测带来的功能。它在
CA_SUNW_HW_1
和AESNI、CLMUL、SSE4.2、SSE4.1和SSE3中运行良好:

$ cat cryptopp.mapfile
hwcap_1 = SSE SSE2 OVERRIDE;
我们需要清除
hwcap_2
的上限。根据Sun的说法,我们应该能够使用空任务来清除上限:

如果使用“=”运算符,则指定的值将替换以前的值,并且“排除”将重置为0。此外,使用“=”将覆盖从输入文件处理收集的任何功能

然后在文档的后面:

要完全消除输出对象中的给定功能,只需使用“=”运算符和空值列表即可

因此,我们添加了一个空的
hwcap_2
,以消除该功能:

$ cat cryptopp.mapfile
hwcap_1 = SSE SSE2 OVERRIDE;
hwcap_2 = ;
但它会导致相同的运行时错误

我们在上发现了一个错误报告,但它有一个Autools解决方案,而不是mapfile修复

如何在Solaris x86上清除映射文件中的AVX和AVX2功能


设置
hwcap_2=0在链接时产生以下结果:

ld: fatal: cryptopp.mapfile: 4: unknown segment attribute: 0
make: *** [GNUmakefile:1084: cryptest.exe] Error 2
我们不能使用
hwcap_2=SSE SSE2
,因为
SSE
hwcap_1
中的
hwcap_2
AV2_386_RDSEED
AV2_386_ADX
相冲突


以下是使用mapfile的完整链接命令:

$ CXX=/opt/solarisstudio12.4/bin/CC make
/opt/solarisstudio12.4/bin/CC -o cryptest.exe -DNDEBUG -g -xO3 -template=no%extd
ef adhoc.o test.o bench1.o bench2.o bench3.o datatest.o dlltest.o fipsalgt.o val
idat0.o validat1.o validat2.o validat3.o validat4.o validat5.o validat6.o valida
t7.o validat8.o validat9.o validat10.o regtest1.o regtest2.o regtest3.o regtest4
.o ./libcryptopp.a -xarch=sse2 -xarch=ssse3 -xarch=sse4_1 -xarch=sse4_2 -xarch=a
es -xarch=avx -xarch=avx2 -M cryptopp.mapfile -lnsl -lsocket
$
链接器包含
-xarch
选项(由映射文件删除)的原因是,手册告诉我们链接命令必须包含所有
-xarch
选项。所以我们没有选择省略它


下面是


在我看来,您的地图文件不完整。链接到的示例如下所示:

要完全消除输出对象中的给定功能,只需使用“=”运算符和空值列表即可。例如,以下内容禁止输入对象提供的任何硬件功能:

   $mapfile_version 2
   CAPABILITY {
           HW = ;
   };
但您的地图文件是:

hwcap_1 = SSE SSE2 OVERRIDE;
hwcap_2 = ;
编辑:

此外,根据解析链接器映射的@jww检查,未记录的值
V0x0
用于删除版本1映射文件的硬件功能:

hwcap_1 = SSE SSE2 OVERRIDE;
hwcap_2 = V0x0;

在我看来,您的地图文件不完整。链接到的示例如下所示:

要完全消除输出对象中的给定功能,只需使用“=”运算符和空值列表即可。例如,以下内容禁止输入对象提供的任何硬件功能:

   $mapfile_version 2
   CAPABILITY {
           HW = ;
   };
但您的地图文件是:

hwcap_1 = SSE SSE2 OVERRIDE;
hwcap_2 = ;
编辑:

此外,根据解析链接器映射的@jww检查,未记录的值
V0x0
用于删除版本1映射文件的硬件功能:

hwcap_1 = SSE SSE2 OVERRIDE;
hwcap_2 = V0x0;

@jww好吧,在opensolaris
ld
源代码中生成错误的那一行可以在中找到,这是旧的opensolaris
ld
,因此在当前的solaris11中可能会有所不同,但我怀疑它是否有太大的变化。在源代码中有一个
DBG_ENABLED
标志,请参阅Awesome,再次感谢。已在处签入。@jww已编辑。很高兴能提供帮助。@jww好的,在OpenSolaris
ld
源代码中生成错误的那一行可以在中找到,这是旧的OpenSolaris
ld
,因此在当前的Solaris 11中可能会有所不同,但我怀疑它是否有太大的变化。在源代码中有一个
DBG_ENABLED
标志,请参阅Awesome,再次感谢。已在处签入。@jww已编辑。很高兴能帮忙。