런타임에 호출되는 공유 라이브러리를 로드하기 위해 및 함수를 dll.c
사용하는 소스 파일이 있다고 가정해 보겠습니다 .dlopen
dlsym
F.so
dll.c
견적을 some_function()
내고 F.so
정의를 내리세요 some_function()
.
아래 그림은 다음 prog
과 같이 얻은 실행 가능한 객체 라고 가정합니다.
linux> gcc -rdynamic -o prog dll.c -ldl
so 부분에는 프로그램이 로드되고 호출을 시작할 때 해결해야 하는 .text
참조가 포함되어 있습니다.some_function()
F.so
some_function()
내 질문은 다음과 같습니다
참조를 확인할 수 있도록 RAM(실행 파일이 메모리에 복사되는 부분)의
.text
부분( 포함된 부분)some_function()
을 동적 링커에 의해 수정해야 하는 것 같습니다. 제가 이해한 것이 맞습니까?some_function()
동적 링커가
.text
RAM의 일부를 수정해야 하는 경우 어떻게 수행합니까? 내가 이해한 바에 따르면.text
섹션은 RAM의 읽기 전용 세그먼트입니다. 읽기 전용 세그먼트를 읽기 전용이라고 하면 어떻게 수정합니까?
답변1
다이어그램에 누락된 ELF의 두 가지 기능인 GOT(전역 오프셋 테이블)와 PLT(프로시저 연결 테이블)가 동적 연결에 사용됩니다. GOT는 다양한 용도로 사용되는 오프셋 테이블이고 PLT는 간접 점프에 사용되는 프로시저 스텁 테이블입니다. GOT는 일반적으로 읽기-쓰기입니다. PLT는 읽기-쓰기 또는 읽기 전용일 수 있습니다(그런 다음 GOT 항목 또는 개별 PLT 관련 GOT로 지원됨).
이를 통해 동적 링커는 읽기 전용 데이터를 건드리지 않고도 기호 주소를 업데이트할 수 있습니다.
일부 오래된 바이너리에서는 읽기 전용 세그먼트의 재배치 데이터를 수정해야 합니다. 이는 동적 링커에서는 문제가 되지 않지만 이는 메모리의 해당 메모리 영역을 더 이상 프로세스 간에 공유할 수 없음을 의미합니다.
바라보다공유 라이브러리를 작성하는 방법더 알아보기.
답변2
A.1
.text
CPU에 따라 코드의 호출 부분은 some_function()
일종의 간접 호출이 됩니다. 런타임에 주소를 계산하고 효율성을 위해 결과를 캐싱할 수도 있습니다. 이를 .text
통해 불변성을 유지하고 공유할 수 있게 됩니다. 코드는 일반적으로 약간 더 크고 느립니다.
A2
이 가정은 틀렸기 때문에 문제가 발생하지 않습니다. 그러나 커널이 메모리 페이지를 복사하고 다른 읽기/쓰기/실행 속성을 제공하고 새 페이지를 동일한 주소에 매핑하는 것을 막을 수는 없습니다. 예를 들어 ptrace
시스템 호출을 통해 이 작업을 수행할 수 있으며 디버거에서 소프트웨어 중단점을 설정하는 데 사용할 수 있습니다.