2011-04-05 2 views
13

lddlibc.so.6에 따라 다르지만, libc.so.5 또는 libc.so.7이 아닌지 어떻게 알 수 있습니까?ldd 출력 이해하기

libc.so.6 => /lib64/libc.so.6 (0x00000034f4000000) 
/lib64/ld-linux-x86-64.so.2 (0x00000034f3c00000) 

답변

17

그것은 응용 프로그램 바이너리 자체의 내부 기록 (컴파일시에 지정, 더 정확히 ld 함께 할 링크 단계에서) :

$ readelf -d /bin/echo 

Dynamic section at offset 0x5f1c contains 21 entries: 
    Tag  Type       Name/Value 
0x00000001 (NEEDED)      Shared library: [libc.so.6] 
... 

(ELF는 정보를 저장하지 방법에 대한 몇 가지 추가 열이 있습니다 .

: 동적 섹션에서하지만 당신은 그 libc.so.6으로 인해 SONAME.6 접미사)

또는 ELF 파일 형식에 대한 지식없이로 하드 코드 볼 수 있습니다 찾으려면

$ strings /bin/echo |grep libc.so 
libc.so.6 

, 링커 (가 편집의 마지막 단계에서 수행됩니다) 라이브러리를 찾을 않는 방법, gcc 옵션 -Wl,--verbose을 사용 (이 ld에 옵션 --verbose를 전달하는 GCC 요청) :

$ gcc a.c -Wl,--verbose 

... 
attempt to open /usr/lib/gcc/i686-pc-linux-gnu/4.4.4/libc.so failed 
attempt to open /usr/lib/gcc/i686-pc-linux-gnu/4.4.4/libc.a failed 
attempt to open /usr/lib/gcc/i686-pc-linux-gnu/4.4.4/libc.so failed 
attempt to open /usr/lib/gcc/i686-pc-linux-gnu/4.4.4/libc.a failed 
attempt to open /usr/lib/gcc/i686-pc-linux-gnu/4.4.4/../../../libc.so succeeded 
opened script file /usr/lib/gcc/i686-pc-linux-gnu/4.4.4/../../../libc.so 
opened script file /usr/lib/gcc/i686-pc-linux-gnu/4.4.4/../../../libc.so 
attempt to open /lib/libc.so.6 succeeded 
/lib/libc.so.6 

링커 .digit 접미사에 대해 아무것도 모르는 경우 libLIBNAME.solibLIBNAME.a을 열려고 시도하는 모든 라이브러리 검색 디렉토리를 반복합니다. 여기서 LIBNAME은 -l 옵션 이후의 문자열입니다. (기본적으로 -lc 옵션이 추가됩니다).

처음 성공한 것은 /usr/lib/libc.so이며 그 자체는 라이브러리가 아니라 링커 스크립트 (텍스트 파일)입니다. 다음은 전형적인 libc.so 스크립트의 내용입니다 :

$ cat /usr/lib/libc.so 
/* GNU ld script 
    Use the shared library, but some functions are only in 
    the static library, so try that secondarily. */ 
OUTPUT_FORMAT(elf32-i386) 
GROUP (/lib/libc.so.6 /usr/lib/libc_nonshared.a AS_NEEDED (/lib/ld-linux.so.2)) 

그래서, 스크립트 /usr/lib/libc.so 실제 라이브러리보다 일찍 발견하고,이 스크립트는이 경우, libc.so.6을 연결됩니다 어떤 파일 말한다. 일반적인 경우

, lib___.solib___.so.3.4.5 같은 몇 가지 버전으로 심볼릭 링크와 lib___.so.3.4.5 또 다른 심볼릭 링크하지 lib___.so뿐만 lib___.so.3.4-ld 링크를 말한다 lib___.so.3.4.5 채워 SONAME 필드가있다. .3.4 이름은 바이너리의 NEEDED 필드에 기록됩니다.

+0

'0x00000001 (NEEDED) '의 의미는 무엇입니까? –

+0

'ldconfig'가'libc.so.6'를'libc.so.6.x'의 최신 버전에 링크하고'lib.so'를'libc.so.x '의 최신 버전에 링크하는 것이 사실입니까? '? 그리고'lib.so'가'lib.so.7'에 링크되었다고 가정하면,'gcc -l lib.so ...'에 의해 생성 된 바이너리는'lib.so.7'에 의존 할 것입니다, 그렇습니까? –

+1

+1 유용한 정보를 많이 포함하도록 답을 편집하십시오. 이것은 고전적인 SO 게시물입니다. 감사. –

4

http://www.sco.com/developers/gabi/latest/ch5.dynamic.html#dynamic_section

각 동적 태그의 의미를 가지고 있습니다. 1은이 경우에 DT_NEEDED 태그 의미입니다 나타내는

typedef struct { 
    Elf32_Sword d_tag; 
    union { 
     Elf32_Word d_val; 
     Elf32_Addr d_ptr; 
    } d_un; 
} Elf32_Dyn; 

구조 라이브러리의 이름을 찾을 수 d_val 노동 조합이 유효하고이 DT_STRTAB 테이블에 생 노동 조합의 구성원에 의해 지정된 오프셋에서 찾아 가지고 그 바이너리/SO 에 달려있다.