Ограничение видимости символа коллективной библиотеки в Solaris

С GCC (в Linux) я могу легко ограничить видимость символы в общих библиотеках.

Каковы мои варианты в Solaris (10)?

Поддерживаются ли эти функции GCC с GCC на Solaris (особенно с GCC, который использует компоновщик/сборщик Solaris)?

И делает ли C-компилятор/компоновщик Solaris Studio аналогичные атрибуты/прагмы для управления видимостью символов (т.е. для установки по умолчанию скрытых и явно обозначающих символы как видимых)?

3 ответа

Невозможно ответить на gcc-видимость в Solaris, но

В 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" и "__hidden" кода кода.

-xldscope=global maps to GCC -fvisibility=default 
-xldscope=symbolic maps to GCC -fvisibility=protected 
-xldscope=hidden maps to GCC -fvisibility=hidden
__global maps to GCC __attribute__((visibility("default")) 
__symbolic maps to GCC __attribute__((visibility("protected")) 
__hidden maps to GCC __attribute__((visibility("hidden"))

И есть обзор от Sun: http://www.oracle.com/technetwork/server-storage/solaris/symbol-scope-140496.html

Сокращение объема символа с помощью Sun Studio C/С++ от Giri Mandalika, май 2005 г. (пересмотрено 22 марта 2006 г.)


Я тестировал некоторые методы аннотации объявлений на машине Solaris 10. Удивительно, что компилятор Solaris Studio C также поддерживает атрибут скрытой функции GCC.

GCC, сконфигурированный с помощью Solaris as/ld, корректно реализует атрибут функции 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;
}
</stdlib.h></stdio.h>

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).

Источники

Глобальные коммутаторы

Для полноты видимости функций (и других символов) также могут влиять другие средства:

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 также определяет внутренние и защищенные видимости символов, которые также понимаются компиляторами, но которые в целом менее полезны.


Другой вариант - использовать файлы версии script. Это работает в Linux, Solaris/GCC и Solaris/CC.

Пример

Рассмотрим общую библиотеку, где доступна только функция power3(). Он использует power2(), который определен в другой единицы перевода, а power2() должен быть скрыт.

В следующей версии script указано следующее:

$ 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 ...

Обратите внимание, что GCC на Solaris настроен на использование ld/as от /usr/ccs/bin.

licensed under cc by-sa 3.0 with attribution.