공유 라이브러리를 사용하는 C 프로그램이 있다고 가정해 보겠습니다.
공유 라이브러리를 변경하고 다시 빌드하면 해당 라이브러리를 사용하는 모든 프로그램은 다음에 실행될 때 자동으로 해당 변경 사항을 받게 됩니다. 정적 라이브러리의 경우 변경 사항은 프로그램이 새 버전의 라이브러리로 다시 컴파일된 후에만 표시됩니다.
일부 공유 라이브러리 함수의 코드를 변경하거나(메서드 시그니처를 변경하지 않고) 새 함수를 추가하는 등의 경우 함수의 주소가 변경됩니다.
공유 라이브러리를 사용하는 프로그램이 재컴파일이나 재링크 없이 어떻게 이러한 기능을 다시 찾을 수 있습니까? 주소가 변경된 경우.
답변1
.so
모든 라이브러리는 내보낸 함수와 위치 목록을 유지하기 때문입니다.
따라서 광범위하게 말하면 프로그램이 공유 라이브러리에서 함수를 가져오려고 하면 다단계 프로세스가 발생합니다. 즉, 내보낸 이름 목록을 읽고, 함수 이름을 찾고, 해당 주소를 가져오고, .so
해당 주소에 있는 파일을 읽습니다.
이러한 주소를 직접 찾으려면 여기에서 읽어보세요.https://en.wikipedia.org/wiki/Executable_and_Linkable_Format
답변2
공유 라이브러리의 헤더에는 함수의 이름과 주소를 포함하는 테이블이 있습니다. 따라서 메인 프로그램이 함수를 호출하려고 할 때 테이블을 조회하고 해당 주소로 점프합니다(필요한 경우 적절한 매개변수 사용).
답변3
기존 답변에 추가: 실행 파일은 동적 로더를 사용하여 공유 라이브러리 .so 파일을 찾고, 초기화 기능을 실행하고, 다음 표를 얻습니다.상징(예: 함수 이름/깨진 서명)에는 함수 주소가 포함되어 있습니다. 그런 다음 공유 라이브러리의 함수를 사용할 때마다 링커 단계에서 사용되는 함수 포인터의 값이 변경됩니다.
따라서 비결은 프로그램이 이러한 함수를 사용하기 위해 고정 주소를 사용하지 않는다는 것입니다. 아직 정의되지 않은 주소가 있는 함수 포인터 목록이 있고 동적 링커는 라이브러리 자체에서 함수의 실제 주소를 다음 위치에 채웁니다. 실행 시간.