使用GCC(在Linux上)我可以轻松limit visibility个symbols in shared个库。
我在Solaris(10)上有哪些选择?
这些GCC功能是否也适用于Solaris上的GCC(尤其是使用Solaris链接器/汇编器的GCC)?
Solaris Studio C编译器/链接器是否提供类似的属性/编译指示来控制符号的可见性(即将默认设置为隐藏并将符号明确标记为可见)?
答案 0 :(得分:4)
我在Solaris 10机器上测试了一些声明注释方法。令人惊讶的是,Solaris Studio C编译器还支持GCC隐藏功能属性。
使用Solaris as
/ ld
配置的GCC正确实现了visibiltiy函数属性。
因此,使用GCC函数属性语法应该是最方便/可移植的方法,因为它适用于Linux / GCC,Solaris / GCC和Solaris / Sol-Studio。
请参阅下表,了解将功能可见性设置为隐藏的效果概述。
.dynsym|.symtab System Compiler Visibility nm readelf link-error elfdump ――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――― Linux Fedora 17 gcc-4.7.2 not specified T GLOBAL DEFAULT no Linux Fedora 17 gcc-4.7.2 attr-hidden t -|LOCAL DEFAULT yes Solaris 10 gcc-4.8 not specified GLOB GLOB D no Solaris 10 gcc-4.8 attr-hidden LOCL -|LOCL H yes Solaris 10 cc-12.3 attr-hidden LOCL -|LOCL H yes Solaris 10 cc-12.3 __hidden LOCL -|LOCL H yes
main.c中:
#include <stdio.h>
#include <stdlib.h>
#include "power3.h"
#include "power2.h"
int main(int argc, char **argv)
{
printf("Result: %d\n", power3(atoi(argv[1])));
// should result in a link error when symbol is hidden
printf("Result: %d\n", power2(atoi(argv[1])));
return 0;
}
power2.h:
#ifndef POWER2_H
#define POWER2_H
#if !defined(NO_HIDE)
#if defined(__GNUC__) || defined(FORCE_GCC)
__attribute__((visibility("hidden")))
#warning Using GNU-C function attribute
#elif defined(__SUNPRO_C)
__hidden
#warning Using SUNPRO-C qualifier
#endif
#endif
int
// GCC attribute also possible here
power2(int x);
#endif
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使用as
中的ld
/ /usr/ccs/bin
。 Solaris Studio版本为12.3,已应用修补程序(2013/02/04)。
__hidden
)。第2.9节支持的属性,第40页(__visibility
)。cc(1)
(__hidden
)为了完整性,功能(和其他符号)的可见性也会受到其他方式的影响:
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
ELF标准还定义了内部和受保护的符号可见性 - 编译器也理解这些符号可见性,但一般来说它们不太有用。
答案 1 :(得分:3)
另一种选择是使用版本脚本文件。这适用于Linux,Solaris / GCC和Solaris / CC。
考虑一个共享库,其中只有一个函数power3()
应该是全局可用的。它使用power2()
,它在另一个翻译单元中定义,power2()
应隐藏。
以下版本脚本指定了:
$ cat vscript
{
global: power3;
local: *;
};
您可以使用一个文件在Linux和Solaris上进行链接 - Linux / Solaris似乎理解相同的语法结构。
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 ...
请注意,Solaris上的GCC配置为使用ld
中的as
/ /usr/ccs/bin
。
答案 2 :(得分:2)
无法回答有关Solaris上的gcc可见性,但
在Sun Studio中有
编译器选项-xldscope,代码属性_ global / _hidden
根据http://lists.qt.nokia.com/public/qt-interest/2010-January/017893.html
http://qt.gitorious.org/qt/qt/merge_requests/433:
SunStudio自版本8(CC版本5.5)以来,能够通过链接器选项控制ABI中的符号可见性
-xldscope=[global|symbolic|hidden]
并通过代码“属性”__global,__ symbolic&amp; __hidden。
-xldscope=global maps to GCC's -fvisibility=default
-xldscope=symbolic maps to GCC's -fvisibility=protected
-xldscope=hidden maps to GCC's -fvisibility=hidden
__global maps to GCC's __attribute__((visibility("default"))
__symbolic maps to GCC's __attribute__((visibility("protected"))
__hidden maps to GCC's __attribute__((visibility("hidden"))
Sun的概述:http://www.oracle.com/technetwork/server-storage/solaris/symbol-scope-140496.html
使用Sun Studio C / C ++缩小符号范围Giri Mandalika,2005年5月(2006年3月22日修订)