내 공유 라이브러리에 중복된 기호(외견상!)가 있는 이유는 무엇입니까(그리고 어떻게)?

내 공유 라이브러리에 중복된 기호(외견상!)가 있는 이유는 무엇입니까(그리고 어떻게)?

내보낸 공유 라이브러리 기호의 단순 목록에서 어떤 라이브러리가 어떤 기호를 내보냈는지 알아내야 합니다. 목록에는 각 기호를 수동으로 상호 참조할 만큼 충분한 기호(20개 정도)만 있습니다.

나는 이것이 유용한 결과를 생성하는 것 같다는 것을 알았습니다 . 두 번째 열에 나열된 주소가 포함된 행을 nm -A -D -f sysv <library-name>검색할 수 있었습니다 . FUNC그래서 의 모든 항목에 대해 이 명령을 실행하여 /usr/lib파일로 리디렉션합니다.

놀랍게도 파일을 구문 분석하는 스크립트에서 내가 수행한 온전성 검사에서 중복된 기호가 보고되었습니다! 조사 끝에 발견된라이브러리가 중복된 기호를 내보내는 것 같나요? ! ?

나는 일부 쉘 스크립트를 사용하여 이것을 확인했고 내가 사용한 명령을 이것으로 변경할 수 있었습니다 (기술적으로) 선:

readlink -f /lib/* /usr/lib/* \
  | grep -F .so. | sort | uniq \
  | while read x; do nm -A -D -f sysv $x; done \
  | grep FUNC | cut -d'|' -f1 | sort -g | uniq -c | sort -g \
  | sed -n '/^ \+1/!{s/^ \+[0-9]\+ \+//p}' | sed 's/ //g' \
  | tr '\n' '\v' \
  | sed ':1;s/\([^ ]\+\):\([^\v$]\+\)\v\1:/\1:\2|/g;t1' \
  | tr '\v' '\n' \
  | while IFS=: read -a x; do \
     nm -A -D -f sysv "${x[0]}" | grep ":\\(${x[1]//|/\\|}\\).*FUNC"; \
  done

위 명령을 실행하면 디스크가 짧은 시간 동안 탐색하게 됩니다. 필요한 경우 청크로 분할하여 임시 파일로 리디렉션할 수 있습니다. 반품출력 범위가 매우 넓습니다.(~150열).

나는 원래 내가 사용하고 있던 Debian Squeeze chroot에서 원본 스크립트를 실행했지만, chroot가 제대로 작동하는지 알아보기 위해 호기심으로 호스트 시스템에서 위 스크립트를 실행했습니다.

흠... chroot는 90개가 넘는 중복 항목을 보고하지만 내 호스트(Arch) 시스템에는 약 267개가 있는 것 같습니다.

이 명령은 nmgrep의 출력을 통해 작동하므로 결과는 약간 복잡하지만 다음과 같습니다.

/usr/lib/libasound.so.2.0.0:snd_pcm_hw_params_get_access|00043700|   T  |              FUNC|00000037|     |.text
/usr/lib/libasound.so.2.0.0:snd_pcm_hw_params_get_access|000436c0|   T  |              FUNC|0000003c|     |.text
/usr/lib/libasound.so.2.0.0:snd_pcm_hw_params_get_access_mask|000458f0|   T  |              FUNC|00000058|     |.text
/usr/lib/libasound.so.2.0.0:snd_pcm_hw_params_get_buffer_size|000432a0|   T  |              FUNC|00000037|     |.text
/usr/lib/libasound.so.2.0.0:snd_pcm_hw_params_get_buffer_size|00043260|   T  |              FUNC|0000003c|     |.text
/usr/lib/libasound.so.2.0.0:snd_pcm_hw_params_get_buffer_size_max|00044ff0|   T  |              FUNC|0000003c|     |.text
/usr/lib/libasound.so.2.0.0:snd_pcm_hw_params_get_buffer_size_max|00045030|   T  |              FUNC|00000037|     |.text
/usr/lib/libasound.so.2.0.0:snd_pcm_hw_params_get_buffer_size_min|000453c0|   T  |              FUNC|00000037|     |.text
/usr/lib/libasound.so.2.0.0:snd_pcm_hw_params_get_buffer_size_min|00045380|   T  |              FUNC|0000003c|     |.text

각 기호에는 두 개가 있습니다.주소가 다릅니다, 예, 하지만... 저는 동적 연결이 기호 이름을 통해 작동한다고 생각했습니다. 그게 전부입니다. 나를 더욱 혼란스럽게 만드는 것은 (위 목록에서 오른쪽으로 스크롤하면) 기호가 모두 FUNC해당 .text섹션의 유형이라는 것입니다.

이곳 뒤에서 어떤 재미있는 마술이 일어나는지 알아보고 싶어서 이 글을 올립니다. (시스템이 실행 중이기 때문에...)

누군가 좋은 아이디어가 있다면 약 600줄의 텍스트를 덤프할 수 있습니다. Pastebin은 더 이상 인기가 없는 것 같고 GitHub를 사용하지 않습니다. 전체 출력을 기꺼이 공유하겠습니다.

답변1

제공된 정보 nm가 불완전하기 때문에 이러한 기호가 중복됩니다. 문제의 기호에는 버전이 지정됩니다. 다음 명령을 사용하여 볼 수 있습니다 objdump -T.

0000000000059d00 g    DF .text  0000000000000044 (ALSA_0.9)   snd_pcm_hw_params_get_access
0000000000056040 g    DF .text  000000000000004b  ALSA_0.9.0rc4 snd_pcm_hw_params_get_access

또는 nm옵션 --with-symbol-versions:

/usr/lib/x86_64-linux-gnu/libasound.so.2.0.0:snd_pcm_hw_params_get_access|0000000000059d00|   T  |              FUNC|0000000000000044|     |.text@ALSA_0.9
/usr/lib/x86_64-linux-gnu/libasound.so.2.0.0:snd_pcm_hw_params_get_access|0000000000056040|   T  |              FUNC|000000000000004b|     |.text@@ALSA_0.9.0rc4

바이너리는 특정 버전과 심볼릭 링크되어 있으며 링크되면 올바른 버전을 얻게 됩니다. 이를 통해 이전 버전과의 호환성을 유지하면서 API를 변경할 수 있습니다.

관련 정보