동적 링커는 런타임 시 참조를 어떻게 확인합니까? [폐쇄]

동적 링커는 런타임 시 참조를 어떻게 확인합니까? [폐쇄]

런타임에 호출되는 공유 라이브러리를 로드하기 위해 및 함수를 dll.c사용하는 소스 파일이 있다고 가정해 보겠습니다 .dlopendlsymF.so

dll.c견적을 some_function()내고 F.so정의를 내리세요 some_function().

아래 그림은 다음 prog과 같이 얻은 실행 가능한 객체 라고 가정합니다.

linux> gcc -rdynamic -o prog dll.c -ldl

여기에 이미지 설명을 입력하세요.

so 부분에는 프로그램이 로드되고 호출을 시작할 때 해결해야 하는 .text참조가 포함되어 있습니다.some_function()F.sosome_function()

내 질문은 다음과 같습니다

  1. 참조를 확인할 수 있도록 RAM(실행 파일이 메모리에 복사되는 부분)의 .text부분( 포함된 부분) some_function()을 동적 링커에 의해 수정해야 하는 것 같습니다. 제가 이해한 것이 맞습니까?some_function()

  2. 동적 링커가 .textRAM의 일부를 수정해야 하는 경우 어떻게 수행합니까? 내가 이해한 바에 따르면 .text섹션은 RAM의 읽기 전용 세그먼트입니다. 읽기 전용 세그먼트를 읽기 전용이라고 하면 어떻게 수정합니까?

답변1

다이어그램에 누락된 ELF의 두 가지 기능인 GOT(전역 오프셋 테이블)와 PLT(프로시저 연결 테이블)가 동적 연결에 사용됩니다. GOT는 다양한 용도로 사용되는 오프셋 테이블이고 PLT는 간접 점프에 사용되는 프로시저 스텁 테이블입니다. GOT는 일반적으로 읽기-쓰기입니다. PLT는 읽기-쓰기 또는 읽기 전용일 수 있습니다(그런 다음 GOT 항목 또는 개별 PLT 관련 GOT로 지원됨).

이를 통해 동적 링커는 읽기 전용 데이터를 건드리지 않고도 기호 주소를 업데이트할 수 있습니다.

일부 오래된 바이너리에서는 읽기 전용 세그먼트의 재배치 데이터를 수정해야 합니다. 이는 동적 링커에서는 문제가 되지 않지만 이는 메모리의 해당 메모리 영역을 더 이상 프로세스 간에 공유할 수 없음을 의미합니다.

바라보다공유 라이브러리를 작성하는 방법더 알아보기.

답변2

A.1

.textCPU에 따라 코드의 호출 부분은 some_function()일종의 간접 호출이 됩니다. 런타임에 주소를 계산하고 효율성을 위해 결과를 캐싱할 수도 있습니다. 이를 .text통해 불변성을 유지하고 공유할 수 있게 됩니다. 코드는 일반적으로 약간 더 크고 느립니다.

A2

이 가정은 틀렸기 때문에 문제가 발생하지 않습니다. 그러나 커널이 메모리 페이지를 복사하고 다른 읽기/쓰기/실행 속성을 제공하고 새 페이지를 동일한 주소에 매핑하는 것을 막을 수는 없습니다. 예를 들어 ptrace시스템 호출을 통해 이 작업을 수행할 수 있으며 디버거에서 소프트웨어 중단점을 설정하는 데 사용할 수 있습니다.

관련 정보