Linux 에서 동적 라 이브 러 리 내 보 내기 제어

리 눅 스에 서 동적 라 이브 러 리 는 확실히 프로그램 에 좋 은 확장 성 을 가 져 왔 고 메모리 사용량 을 줄 였 지만 이것 은 대가 가 있다.예 를 들 면:
#include 
int main(int argc, char *argv[])
{
       printf(“hello
”); return 0; }

printf 가 glibc 에서 정 의 된 것 을 알 고 있 습 니 다.동적 라 이브 러 리 가 적용 되 지 않 고 glibc 를 프로 세 스 에 정적 으로 연결 하면 printf 함수 의 주 소 는 컴 파일 할 때 이미 알 고 있 습 니 다.간단 한 주소 로 이동 하면 함수 호출 이 가능 합 니 다.
그러나 동적 라 이브 러 리 를 사용 하면 프로그램 컴 파일 단계 에서 컴 파일 러 는 printf 의 함수 주 소 를 알 수 없습니다.동적 라 이브 러 리 가 불 러 온 메모리 주 소 는 무 작위 이기 때 문 입 니 다.그렇다면 동적 라 이브 러 리 의 경우 printf 에 대해 어떻게 주 소 를 찾 습 니까?
프로그램 이 실 행 될 때 printf 를 호출 할 때 프로그램 은 linker 에 처리 권 을 맡 기 고 실행 파일 과 연 결 된 동적 라 이브 러 리 에서 printf 의 함수 주 소 를 찾 습 니 다.linker 는 printf 가 구체 적 으로 어떤 동적 라 이브 러 리 에 있 는 지 모 르 기 때문에 전체 실행 파일 과 동적 라 이브 러 리 범위 내 에서 찾 을 것 입 니 다.더 나 쁜 것 은 C+프로그램 에서 기호의 이름 은 클래스+함수 이름 입 니 다.이 로 인해 문자열 을 비교 할 때 문자열 이 끝 날 때 까지 결 과 를 얻 을 수 있 습 니 다.
이 로 인해 프로 세 스 가 시작 되 는 과정 에서 기호 찾기 가 대부분의 시간 을 차지 하 게 되 었 다.리 눅 스 KDE 프로 세 스 가 시 작 될 때 기호 찾기 는 프로 세 스 가 시작 되 는 시간의 80%를 차지 하기 도 합 니 다.
따라서 상기 상황 에 대해 다음 과 같은 최적화 해결 방안 이 있다.
1.내 보 내기 기호의 수량 감소
동적 라 이브 러 리 컴 파일 과 생 성 시 기본 모든 함수 와 전역 변 수 는 내 보 냅 니 다.실제 적 으로 많은 함수 들 이 동적 라 이브 러 리 내부 에서 만 사용 되 고 동적 라 이브 러 리 에서 불필요 한 내 보 내기 기 호 를 제거 함으로써 동적 라 이브 러 리 가 링크 를 할 때 찾 는 기호 수량 을 줄 이 고 동적 라 이브 러 리 링크 의 속 도 를 가속 화 할 수 있 습 니 다.
ld 의 ld--retain-symbols-file--version-script 두 가지 옵션 을 사용 하여 구현 할 수 있 습 니 다.기호 파일 을 내 보 냅 니 다.예 를 들 어 symbol 은 func 1 과 같은 함수 만 내 보 냅 니 다.ld 의--retain-symbols-file 사용 하기 인 자 는 static section 에서 func 1 이외 의 모든 함 수 를 취소 할 수 있 습 니 다.이 때 컴 파일 된.so 파일 static section 에 readelf 로 보 세 요.nm 로 보 세 요.so 파일 은 내 보 내기 함 수 를 찾 을 수 없습니다.그러나 이것 은 결코 완전 하지 않다.다이나믹 섹 션 에 서 는 모든 기호 가 내 보 내 지 는 것 을 볼 수 있 기 때문이다.dynsym section 에서 도 내 보 내지 못 하 게 하려 면 script 파일 을 하나 더 만들어 야 합 니 다.global 과 local 을 지정 하여 global 에서 내 보 낼 함 수 를 지정 합 니 다.간단 한 형식 은 다음 과 같 습 니 다.
VERSION{VER_1.0{global:함수 이름 내 보 내기;local: *;};}ld 에서 사용 하기--version-script 파일 을 로드 하려 면 옵션 을 선택 하 십시오.다 끝 난 후에 readelf 를 사용 하여 static 과 dynamic section 을 관찰 한 결과 지정 한 함수 이름 즉 기호 만 내 보 냈 습 니 다.예:ld-shared--retain-symbols-file 심 볼 릭 파일--version-script 스 크 립 트 파일-o 동적 라 이브 러 리 파일.so filename
2.기호의 길 이 를 줄인다.
3.prelink 사용
여기 서 따로 질문 을 하나 더 하 겠 습 니 다.재 미 있 는 것 입 니 다.
gcc-fivisibility=hidden 은 링크 할 때 만 들 어 오 는 c 파일 에 만 작용 하고 o 파일 에 대해 서 는 역할 을 하지 않 습 니 다.예 를 들 어 test.c test 1.c 는 다음 명령 을 사용 합 니 다. gcc-shared-fivisibility=hidden-osts.so test.c test 1.c 와 명령 gcc -c test.c test1.c  gcc-shared-fivisibility=hidden-osts.so test.o test 1.o 에서 생 성 된 test.so 의 대응 가능성 은 다 릅 니 다."readelf-s test.so"를 사용 하여 확인 한 결과 첫 번 째 로 기대 하 는 목적 을 달성 하면 두 개의 c 파일 중의 functions 를 HIDDEN 으로 설정 하고 두 번 째 는 안 됩 니 다.-fivisibility=hidden 은 작용 하지 않 습 니 다.gcc-shared-fivisibility=hidden-o test.so test.o test 1.c 로 생 성 된 so 를 사용 하면 test 1.c 의 함수 가 HIDDEN 이지 만 test.o 의 함 수 는 DEFAULT 임 을 발견 할 수 있 습 니 다.

좋은 웹페이지 즐겨찾기