Linker 限制Solaris上共享库符号的可见性

Linker 限制Solaris上共享库符号的可见性,linker,shared-libraries,solaris,visibility,Linker,Shared Libraries,Solaris,Visibility,使用GCC(在Linux上),我可以轻松地创建库 我在Solaris(10)上有哪些选项 这些GCC功能是否也适用于Solaris上的GCC(特别是使用Solaris链接器/汇编程序的GCC) Solaris Studio C编译器/链接器是否提供了类似的属性/杂注来控制符号的可见性(即,将默认值设置为隐藏并显式将符号标记为可见)?无法回答有关Solaris上gcc可见性的问题,但是 太阳工作室里有 编译器选项-xldscope,代码属性_global/_hidden 据 : 自版本8(CC版本

使用GCC(在Linux上),我可以轻松地创建库

我在Solaris(10)上有哪些选项

这些GCC功能是否也适用于Solaris上的GCC(特别是使用Solaris链接器/汇编程序的GCC)


Solaris Studio C编译器/链接器是否提供了类似的属性/杂注来控制符号的可见性(即,将默认值设置为隐藏并显式将符号标记为可见)?

无法回答有关Solaris上gcc可见性的问题,但是

太阳工作室里有

编译器选项-xldscope,代码属性_global/_hidden

:

自版本8(CC版本5.5)以来,SunStudio已经能够通过链接器选项控制ABI中的符号可见性

通过代码“属性”\uuuu全局、\uuuu符号和\uuuu隐藏

这里有来自Sun的概述:

Giri Mandalika于2005年5月用Sun Studio C/C++缩小符号范围(2006年3月22日修订)


我已经在Solaris 10机器上测试了一些声明注释方法。令人惊讶的是,Solaris Studio C编译器还支持GCC隐藏函数属性

将Solaris
配置为
/
ld
的GCC正确地实现了visibility函数属性

因此,使用GCC函数属性语法应该是最方便/可移植的方法,因为它适用于Linux/GCC、Solaris/GCC和Solaris/Sol Studio

有关将函数可见性设置为隐藏的效果的概述,请参见下表

结果 power3.h:

#ifndef POWER3_H
#define POWER3_H
int power3(int x);
#endif
power3.c

#include "power3.h"
#include "power2.h"
int power3(int x)
{
  return power2(x)*x;
}
生成命令:

cc -g   -c -o main.o main.c
cc  -g -fpic -c -o power3.po power3.c
cc  -g -fpic -c -o power2.po power2.c
cc -shared -fpic -o libpower.so power3.po power2.po
cc -L$PWD -Wl,-R$PWD
自省:

在Linux下:

nm libpower.so | grep power
readelf --dyn-sym libpower.so | grep power
readelf -s libpower.so | grep 'FUNC.*power'
在Solaris下:

/usr/ccs/bin/nm libpower.so | grep 'FUNC.*power'
/usr/ccs/bin/elfdump -N .dynsym libpower.so | grep 'FUNC.*power'
elfdump -N .symtab libpower.so | grep 'FUNC.*power'
系统详细信息:

Solaris 10系统是一台SPARC机器,GCC使用
作为
/
ld
来自
/usr/ccs/bin
。Solaris Studio版本为12.3,应用了修补程序(2013/02/04)

来源
  • 。第2.2节链接器作用域说明符,第32页(
    \uu hidden
    )。第2.9节支持的属性,第40页(
    \u可见性
  • Solaris Studio 12.3 cc手册页,
    cc(1)
    \uu hidden
  • Giri Mandalika,2005/2006
全局交换机 为了完整性,功能(和其他符号)的可见性也可能受到其他方式的影响:

GCC-method Sol equivalent effect ―――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――― #pragma GCC visibility push(hidden) - everything between push/pop #pragma GCC visibility pop - has default visibility hidden #pragma GCC visibility push(default) - ~ default to default-visibility #pragma GCC visibility pop - -fvisibility=hidden -xldscope=hidden sets default visibility of -fvisibility=default -xldscope=global a translation unit GCC法溶胶等效效应 ―――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――― #pragma GCC可见性推送(隐藏)-推送/弹出之间的所有内容 #pragma GCC可见性弹出-隐藏了默认可见性 #pragma GCC可见性推送(默认)-~默认为默认可见性 #布拉格语- -fvisibility=hidden-xldscope=hidden设置的默认可见性 -fvisibility=默认值-xldscope=全局a翻译单位
ELF标准还定义了内部和受保护的符号可见性-编译器也理解这些,但通常不太有用。

另一个选项是使用版本脚本文件。这适用于Linux、Solaris/GCC和Solaris/CC

例子 考虑一个共享库,其中只有函数
power3()
应该是全局可用的。它使用另一个翻译单元中定义的
power2()
,并且应该隐藏
power2()

以下版本脚本指定了这一点:

$ cat vscript
{
  global: power3;
  local: *;
};
您可以使用一个文件在Linux和Solaris上进行链接—Linux/Solaris似乎理解相同的语法结构

生成命令 系统编译器链接命令 ――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――― Linux Fedora 17 gcc-4.7.2 cc-shared-Wl,--version脚本,vscript-fpic-o libpower.so。。。 Solaris 10 gcc-4.8*gcc-shared-Wl,-M,vscript-fpic-o libpower.so。。。 Solaris 10 cc 12.3 cc-shared-M vscript-fpic-o libpower.so。。。
请注意,Solaris上的GCC配置为使用
ld
/
作为
/usr/ccs/bin

中的
Solaris Studio版本支持GCC属性的一个子集,并且该子集随着版本的增加而增加,因此,如果在可能使用不同版本的编译器编译的代码库中执行此操作,则可能需要检查Studio版本。例如,
\uuuu属性((可见性(“默认”))
的行为似乎与编译器手册中显示的
\uu全局
不同。当使用
-xldscope=hidden
时,后者仍然将其导出为全局符号,但前者似乎等同于根本不指定属性。奇怪的是,当使用该属性和
-xldscope=hidden
编译w/out链接时,GNU nm将该符号视为全局符号,但在将其链接到库中后,符号变成了本地符号,我不完全确定原因。它可以工作,我喜欢这是可能的,但我完全希望
-xldscope=hidden
至少部分等同于这样做。编译器手册声称它是一个链接器标志,但我通过运行单独的编译/链接步骤(每个步骤都有这个标志)进行测试;编译步骤使用该标志,但链接步骤不会向链接器传递任何不同的内容。
cc -g   -c -o main.o main.c
cc  -g -fpic -c -o power3.po power3.c
cc  -g -fpic -c -o power2.po power2.c
cc -shared -fpic -o libpower.so power3.po power2.po
cc -L$PWD -Wl,-R$PWD
nm libpower.so | grep power
readelf --dyn-sym libpower.so | grep power
readelf -s libpower.so | grep 'FUNC.*power'
/usr/ccs/bin/nm libpower.so | grep 'FUNC.*power'
/usr/ccs/bin/elfdump -N .dynsym libpower.so | grep 'FUNC.*power'
elfdump -N .symtab libpower.so | grep 'FUNC.*power'
GCC-method Sol equivalent effect ―――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――― #pragma GCC visibility push(hidden) - everything between push/pop #pragma GCC visibility pop - has default visibility hidden #pragma GCC visibility push(default) - ~ default to default-visibility #pragma GCC visibility pop - -fvisibility=hidden -xldscope=hidden sets default visibility of -fvisibility=default -xldscope=global a translation unit
$ cat vscript
{
  global: power3;
  local: *;
};
System Compiler Link command ――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――― Linux Fedora 17 gcc-4.7.2 cc -shared -Wl,--version-script,vscript -fpic -o libpower.so ... Solaris 10 gcc-4.8* gcc -shared -Wl,-M,vscript -fpic -o libpower.so ... Solaris 10 cc 12.3 cc -shared -M vscript -fpic -o libpower.so ...