Linux, GNU GCC, ld, 버전 스크립트 및 ELF 이진 형식 — 어떻게 작동합니까?


13

Linux의 라이브러리 버전 관리 및 모든 기능을 작동시키는 방법에 대해 자세히 배우려고합니다. 컨텍스트는 다음과 같습니다.

- 나는 동일한 인터페이스를 노출 동적 라이브러리의 두 가지 버전을 가지고 말을 libsome1.so하고 libsome2.so.

-응용 프로그램이에 연결되어 libsome1.so있습니다.

-이 응용 프로그램은 libdl.so다른 모듈을 동적으로로드 하는 데 사용 됩니다 (예 :) libmagic.so.

-이제 libmagic.so연결되어 libsome2.so있습니다. 분명히 링커 스크립트를 사용하여에서 심볼을 숨기지 않으면 libmagic.so런타임시 인터페이스에 libsome2.so대한 모든 호출 이로 해결됩니다 libsome1.so. 이는 libVersion()매크로 값과 비교하여 반환 된 값을 확인하여 확인할 수 있습니다 LIB_VERSION.

-다음으로 libmagic.so정의 libmagic.so하고 내보내는 3을 제외한 모든 심볼을 숨기는 링커 스크립트 로 컴파일하고 링크하려고 합니다. 이 작품 ... 또는 적어도 libVersion()LIB_VERSION값이 일치 (그리고 버전이없는 일을보고).

-그러나 일부 데이터 구조가 디스크에 직렬화되면 일부 손상이 발견되었습니다. 응용 프로그램 디렉토리 libsome1.so에서를 가리키고 그 자리에서 소프트 링크를 삭제 하고 만들면 libsome2.so모든 것이 예상대로 작동하고 동일한 손상이 발생하지 않습니다.

도움이 될 수는 없지만 런타임 링커의 심볼 해상도가 약간 충돌하여 발생할 수 있다고 생각합니다. 나는 libsome2.so모든 기호를 높이기 위해 링크를 시도하는 것과 같은 많은 것을 시도했습니다 symbol@@VER_2(명령은 nm -CD libsome2.so여전히 기호를 표시 symbol하고 있기 때문에 혼란 스럽습니다 symbol@@VER_2) ... 도움!!!!!!


마지막 접근 방식은 내가 시작했을 것입니다. 그리고 나는 부패가 아마도 약간의 혼동 일 것이라는 데 동의합니다. 슬프게도 나는 당신에게 답이 없습니다.
RobotHumans 12

tbh 나는 확실히 말할만큼 충분히 이해하지 못하지만 이것은 그렇게 잘 할 수 있습니다. 우리가 옮기기를 원하면 신고하십시오.
xenoterracide

1
앱에서 RTLD_LOCALand RTLD_DEEPBINDdlopen 플래그를 사용해보십시오 . 지금 테스트 할 시간이 없지만 맨 페이지를 기반으로 작동해야합니다.
stribika

답변:


13

이것은 귀하의 질문에 정확하게 대답하지는 않지만 ...

우선, ELF는 Linux가 실행 파일 (프로그램), 공유 라이브러리 및 소프트웨어를 컴파일 할 때 발견되는 중간 파일 인 객체 파일에 사용하는 사양입니다. 개체 파일은 .o로 끝나고 공유 라이브러리는 .so로 끝나고 그 뒤에 마침표로 구분 된 0 개 이상의 숫자가 나오며 실행 파일의 확장자는 정상적으로 없습니다.

공유 라이브러리의 이름을 지정하는 데 일반적으로 세 가지 형식이 있으며 첫 번째 형식은 .so로 끝납니다. 예를 들어 readline이라는 라이브러리는 libreadline.so라는 파일에 저장되며 / lib, / usr / lib 또는 / usr / local / lib 중 하나에 있습니다. 해당 파일은 -lreadline과 같은 옵션으로 소프트웨어를 컴파일 할 때 위치합니다. -l은 컴파일러에게 다음 라이브러리와 링크하도록 지시합니다. 라이브러리는 때때로 변경되므로 사용되지 않게되어 라이브러리에 SONAME이라는 것이 포함됩니다. readline의 SONAME은 libreadline의 두 번째 버전 주 버전 인 libreadline.so.2처럼 보일 수 있습니다. 호환 가능하고 소프트웨어를 다시 컴파일 할 필요가없는 많은 마이너 버전의 readline이있을 수도 있습니다. 작은 버전의 readline은 libreadline.so.2.14로 이름이 지정 될 수 있습니다. 일반적으로 libreadline. 이 경우 가장 최근의 주요 readline libreadline.so.2에 대한 심볼릭 링크 일뿐입니다. libreadline.so.2는 실제로 사용중인 파일 인 libreadline.so.2.14에 대한 심볼릭 링크입니다.

라이브러리의 SONAME은 라이브러리 파일 자체에 포함됩니다. libreadline.so.2.14 파일 내부에는 문자열 libreadline.so.2가 있습니다. 프로그램이 컴파일되고 readline과 링크되면, libreadline.so 파일을 찾아서 그 안에 포함 된 SONAME을 읽습니다. 나중에 프로그램이 실제로 실행될 때 libreadline.so뿐만 아니라 libreadline.so.2도로드됩니다. 왜냐하면 처음 링크되었을 때 읽은 SONAME이기 때문입니다. 이를 통해 시스템에 호환되지 않는 여러 버전의 readline이 설치 될 수 있으며 각 프로그램은 연결된 주요 버전을로드합니다. 또한 readline을 2.17로 업그레이드 할 때 기존 라이브러리와 함께 libreadline.so.2.17을 설치하고 libreadline.so.2 기호 링크를 libreadline.so.2.13에서 libreadline.so.2.17로 이동하면

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.