visibility("hidden")
특성 에서 오브젝트 파일을 억제하지 심볼을 수행하고 심볼 nm
의해 추출되는 것을 방지 할 수 없다. 은 동적 링커에게 심볼이 포함되어있는 공유 라이브러리 외부에서 심볼을 호출 할 수 없다고 지시합니다.
은 소스 파일
file.c
이 예 기능을 포함 고려해
int f_b1(){
return 21 ;
}
int f_b3(){
return f_b1() ;
}
파일을 컴파일
gcc -c -o file.o file.c
실행 nm file.o
이 기호를 나열합니다. 출력 :
0000000000000000 T f_b1
000000000000000b T f_b3
기호에 대한 자세한 내용은 objdump -t file.o
을 실행하십시오. 출력 : 여기에 우리가 f_b1
및 f_b3
는 .text
섹션에서 글로벌 (g) 함수 (F)는 것을 볼
file.o: file format elf64-x86-64
SYMBOL TABLE:
0000000000000000 l df *ABS* 0000000000000000 file.c
0000000000000000 l d .text 0000000000000000 .text
0000000000000000 l d .data 0000000000000000 .data
0000000000000000 l d .bss 0000000000000000 .bss
0000000000000000 l d .note.GNU-stack 0000000000000000 .note.GNU-stack
0000000000000000 l d .eh_frame 0000000000000000 .eh_frame
0000000000000000 l d .comment 0000000000000000 .comment
0000000000000000 g F .text 000000000000000b f_b1
000000000000000b g F .text 000000000000000b f_b3
.
지금과 같이 파일을 수정 : 다시
__attribute__((visibility ("hidden"))) int f_b1(void){
return 21 ;
}
__attribute__((visibility ("hidden"))) int f_b3(void){
return f_b1() ;
}
실행 objdump
을 : 기호 f_b1
및 f_b3
지금 .hidden
표시된다는 점을 제외하고
file.o: file format elf64-x86-64
SYMBOL TABLE:
0000000000000000 l df *ABS* 0000000000000000 file.c
0000000000000000 l d .text 0000000000000000 .text
0000000000000000 l d .data 0000000000000000 .data
0000000000000000 l d .bss 0000000000000000 .bss
0000000000000000 l d .note.GNU-stack 0000000000000000 .note.GNU-stack
0000000000000000 l d .eh_frame 0000000000000000 .eh_frame
0000000000000000 l d .comment 0000000000000000 .comment
0000000000000000 g F .text 000000000000000b .hidden f_b1
000000000000000b g F .text 000000000000000b .hidden f_b3
출력은 동일합니다. 그것들은 여전히 외부 (전역) 링키지를 가지고 있으며,이를 포함하고있는 라이브러리 내의 다른 모듈로부터 예제를 위해 정적으로 호출 될 수 있지만 은 그 라이브러리 외부에서 동적으로 호출 될 수 없습니다. 같이 동적 연결에서 f_b1
및 f_b3
을 은폐하려는 경우
그래서하는 에 공유 라이브러리, 당신은 visibility ("hidden")
를 사용할 수 있습니다.당신이 정적 라이브러리에 정적 연결에서 f_b1
및 f_b3
을 은폐하려는 경우
, 당신은 모든 것을 수행 할 visibility
속성을 사용할 수 없습니다.
정적 라이브러리의 경우 외부 연결 대신 내부에 을 부여하는 기호 만 "숨길"수 있습니다. 이를 수행하는 방법은 표준 static
키워드를 접두사로 사용하는 것입니다. 하지만 내부 연결은 기호가 인 경우에만 컴파일 단위로 표시됩니다. 다른 모듈에서 참조 할 수 없습니다. 그것은 링커가 전혀 사용할 수 없습니다. 이 같은 다시
수정 file.c
:
static int f_b1(void){
return 21 ;
}
static int f_b3(void){
return f_b1() ;
}
그리고 다시 objump
을 실행
file.o: file format elf64-x86-64
SYMBOL TABLE:
0000000000000000 l df *ABS* 0000000000000000 file.c
0000000000000000 l d .text 0000000000000000 .text
0000000000000000 l d .data 0000000000000000 .data
0000000000000000 l d .bss 0000000000000000 .bss
0000000000000000 l F .text 000000000000000b f_b1
000000000000000b l F .text 000000000000000b f_b3
0000000000000000 l d .note.GNU-stack 0000000000000000 .note.GNU-stack
0000000000000000 l d .eh_frame 0000000000000000 .eh_frame
0000000000000000 l d .comment 0000000000000000 .comment
당신은 f_b1
및 f_b3
여전히 .text
섹션의 함수로보고되는 것을 볼 수 있지만 지금 (l)로 분류되며 글로벌이 아닙니다. 그것이 내부 연결입니다. 실행 nm file.o
출력은 다음과 같습니다 대신 'T'플래그 의 것을 제외
원본 파일과 동일
0000000000000000 t f_b1
000000000000000b t f_b3
, 우리가 지금 '를 t'플래그가 있습니다. 두 플래그는 기호가 .text
섹션에 있음을 의미하지만 'T'는 전역이고 't'는 로컬임을 나타냅니다.
분명히, nm
이 (가) 에 번으로 표시된 파일을보고 싶다고 생각됩니다. 심볼이 file.o
인 경우 nm file.o
이 심볼을보고하지만 그 존재 여부는 정적 또는 동적 연결에 대해 표시 여부와 관계가 없음을 이해해야합니다.
는 사라
함수 기호,합니다 (static
키워드로 여전히) 다시 한번 을 file.c
를 컴파일 활성화 최적화 이번에 만들려면 : gcc -c -O1 -o file.o file.c
지금을 objdump
보고서 :
file.o: file format elf64-x86-64
SYMBOL TABLE:
0000000000000000 l df *ABS* 0000000000000000 file.c
0000000000000000 l d .text 0000000000000000 .text
0000000000000000 l d .data 0000000000000000 .data
0000000000000000 l d .bss 0000000000000000 .bss
0000000000000000 l d .note.GNU-stack 0000000000000000 .note.GNU-stack
0000000000000000 l d .comment 0000000000000000 .comment
f_b1
및 f_b3
은 사라지고 nm file.o
은 전혀보고하지 않습니다. 왜? static
은 컴파일러에게이 기호를 컴파일 할 파일 내에서 이라고 만 호출 할 수 있으므로 최적화는 거기에서 을 참조 할 필요가 없다고 결정합니다. 그래서 컴파일러은 오브젝트 코드에서 제거합니다. 그러나 그들이 최적화없이 링커에게 보이지 않았다면 최적화 할 수 없었습니다.
결론 : nm
이 기호를 추출 할 수 있는지 여부는 중요하지 않습니다. 기호가 로컬/내부이면 정적 또는 동적으로 연결할 수 없습니다. 기호가 .hidden
으로 표시되면 을 동적으로 링크 할 수 없습니다. visibility("hidden")
을 사용하여 .hidden
기호를 표시 할 수 있습니다. 표준 static
키워드를 사용하여 로컬/내부 기호를 만드십시오.
위대한 설명입니다. –
오브젝트 파일 이름도 숨길 수 있습니까? 내'nm' 명령은 이와 같이 출력합니다. '''b.o : 0000000000000000 T는 f_b2 0000000000000010 T f_b3 c.o : '''나뿐만 아니라,'b.o 및 c.o' 이름을 숨길하고 싶습니다. 고마워 .. –
예 : 'strip -s file.o'을 실행하십시오. 'man strip'을보세요. 모든 심볼을 제거하면 오브젝트 파일을 디버깅 할 수 없습니다. –