我在 Solaris 10 机器上测试了一些声明注释方法。令人惊讶的是,Solaris Studio C 编译器还支持 GCC-hidden-function 属性。
使用 Solaris as/ld 配置的 GCC 正确实现了 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 是
方法
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 使用来自/usr/ccs/bin 的as/ld。 Solaris Studio 版本是 12.3,应用了补丁 (2013/02/04)。
来源
全局开关
为了完整性,功能(和其他符号)的可见性也可能受到其他方式的影响:
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 标准还定义了内部和受保护的符号可见性 - 编译器也可以理解,但通常不太有用。