使用 GCC(在 Linux 上),我可以轻松地限制共享库中符号的可见性。
我在 Solaris (10) 上有哪些选择?
这些 GCC 功能是否也适用于 Solaris 上的 GCC(尤其是使用 Solaris 链接器/汇编器的 GCC)?
Solaris Studio C 编译器/链接器是否提供类似的属性/pragma 来控制符号的可见性(即,将默认设置为隐藏并将符号显式标记为可见)?
我已经在 Solaris 10 机器上测试了一些声明注释方法。令人惊讶的是,Solaris Studio C 编译器还支持 GCC-hidden-function 属性。
使用 Solaris as
/配置的 GCCld
正确实现了 visibiltiy 函数属性。
因此,使用 GCC 函数属性语法应该是最方便/便携的方法,因为它适用于 Linux/GCC、Solaris/GCC 和 Solaris/Sol-Studio。
有关将功能可见性设置为隐藏的效果的概述,请参见下表。
.dynsym|.symtab 系统编译器可见性 nm readelf 链接错误 精灵转储 ―――――――――――――――――――――――――――――――――――――――――――――――― ―――――――――――――――――――――――――――――――― Linux Fedora 17 gcc-4.7.2 未指定 T GLOBAL DEFAULT no Linux Fedora 17 gcc-4.7.2 attr-hidden t -|LOCAL DEFAULT 是 未指定 Solaris 10 gcc-4.8 GLOB GLOB D 否 Solaris 10 gcc-4.8 attr-hidden LOCL -|LOCL H 是 Solaris 10 cc-12.3 attr-hidden LOCL -|LOCL H 是 Solaris 10 cc-12.3 __hidden LOCL -|LOCL H 是
主.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;
}
电源2.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
电源3.h:
#ifndef POWER3_H
#define POWER3_H
int power3(int x);
#endif
电源3.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
from /usr/ccs/bin
。Solaris Studio 版本为 12.3,应用了补丁 (2013/02/04)。
__hidden
)。第 2.9 节支持的属性,第 40 页 ( __visibility
)。cc(1)
(__hidden
)为了完整起见,功能(和其他符号)的可见性也可能受到其他方式的影响:
GCC-method Sol等效效果 ―――――――――――――――――――――――――――――――――――――――――――――――― ―――――――――――――――――――――――――――――――――― #pragma GCC 可见性 push(hidden) - push/pop 之间的一切 #pragma GCC visibility pop - 隐藏默认可见性 #pragma GCC 可见性推送(默认) - ~ 默认为默认可见性 #pragma GCC 可见性弹出 - -fvisibility=hidden -xldscope=hidden 设置默认可见性 -fvisibility=default -xldscope=global 一个翻译单元
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-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
from /usr/ccs/bin
。
无法回答有关 Solaris 上 gcc 可见性的问题,但是
在太阳工作室有
编译器选项 -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 & __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
Giri Mandalika 使用 Sun Studio C/C++ 缩小符号范围,2005 年 5 月(2006 年 3 月 22 日修订)