libc.so는 표준 C라이브러리를 모듈화 한 파일이다. 솔라리스에서 C 컴파일러로 컴파일 되었다면, 정적으로 컴파일하지 않는한 libc.so파일을 로드하게 된다. [# ldd /usr/bin/ls]를 해보면 가장 기본적인 명령어인 ls조차도 libc.so를 읽도록 되어있는것을 알 수 있다. 간단히 말해 솔라리스에서 작동하는 모든 프로그램은 libc.so를 사용하고 있다고 해도 과언은 아니다. (/sbin 아래의 파일들은 예외다)
솔라리스 10 x86 u6에는 3가지의 libc.so 파일이 있다. /lib/libc.so.1, /usr/lib/libc/libc_hwcap1.so.1, /usr/lib/libc/libc_hwcap2.so.1 이 그것. 같은 라이브러리를 3개나 만든건 최신 CPU의 명령셋을 지원해 성능을 향상시킬 목적으로 만든것이다. (hwcap은 HardWare CAPabilities의 약어이다)
주) 아래의 내용을 테스트하려면 [테스트용시스템]에서 하는 것이 좋다.
root@wl ~ # df -k
...
/usr/lib/libc/libc_hwcap1.so.1
50423874 7450881 42468755 15% /lib/libc.so.1
...
root@wl ~ # umount /lib/libc.so.1
root@wl ~ # file /lib/libc.so.1 /usr/lib/libc/libc_*
/lib/libc.so.1: ELF 32-비트 LSB 동적 lib 80386 버전 1, 동적으로 링크됨, 분리 안됨, 디버깅 정보를 사용할 수 없음
/usr/lib/libc/libc_hwcap1.so.1: ELF 32-비트 LSB 동적 lib 80386 버전 1
[SSE MMX CMOV SEP FPU], 동적으로 링크됨, 분리 안됨, 디버깅 정보를 사용할 수 없음
/usr/lib/libc/libc_hwcap2.so.1: ELF 32-비트 LSB 동적 lib 80386 버전 1
[SSE2 SSE MMX CMOV AMD_SYSC FPU], 동적으로 링크됨, 분리 안됨, 디버깅 정보를 사용할 수 없음
root@wl ~ # isainfo -v
32-bit i386 applications
pause sse2 sse fxsr mmx cmov sep cx8 tsc fpu
root@wl ~ # cat /usr/include/sys/auxv_386.h
...
#define AV_386_SSE 0x00800 /* SSE insns and regs */
#define AV_386_SSE2 0x01000 /* SSE2 insns and regs */
...
root@wl ~ #
wl시스템은 [pause sse2 sse fxsr mmx cmov sep cx8 tsc fpu] 을 지원하고 이에 맞춰서 /usr/lib/libc/libc_hwcap1.so.1 가 선택되었다.
CMOV
CMOV: conditional move 라는 어셈블리 명령이다.
CMP EAX, EBX
JBE skip
MOV EAX, EBX
skip:
→
CMP EAX, EBX
CMOVA EAX, EBX
CMOVA 는 conditional move if above 라는 뜻의 명령어이다. 위 예제는 EAX와 EBX중 작은 것을 취하는 내용이다.
SEP,AMD_SYSC
※ SEP
Intel CPU에는 SYSENTER,SYSEXIT 명령셋(어셈블리언어 명령어)이 추가되어있다. 이 명령셋은 Fast System Call(SEP)라 부르며 인텔 펜티엄 2 이상에서 사용 가능하다. (Fast System Call을 사용하기 위해서는 SEP(SYSENTER Present)비트가 반드시 셋 되어있어야 한다)
※ AMD_SYSC
AMD System Call 의 약어. AMD사가 SYSCALL,SYSRET 명령셋을 자사의 CPU에 맞도록 향상시킨 명령셋이다.
※ 쉽게 말해 빠른 시스템콜 호출을 위해 CPU제조사는 독자적인 명령셋을 개발했고 그것이 Intel CPU에서는 SEP, AMD CPU에서는 AMD_SYSC이다. 그리고 솔라리스10 에서는 이를 감지해 사용한다.
libc.so 마운트와 해제
root@wl ~ # df -k
/usr/lib/libc/libc_hwcap1.so.1
50423874 7450881 42468755 15% /lib/libc.so.1
root@wl ~ # ls -al /usr/lib/libc/libc_hwcap1.so.1 /lib/libc.so.1 1)
-rwxr-xr-x 1 root bin 1087992 9월 18일 02:00 /lib/libc.so.1
-rwxr-xr-x 1 root bin 1087992 9월 18일 02:00 /usr/lib/libc/libc_hwcap1.so.1
root@wl ~ # digest -a md5 /usr/lib/libc/libc_hwcap1.so.1
30fc278a5f38f9141be68b1d83ae70f0
root@wl ~ # digest -a md5 /lib/libc.so.1
30fc278a5f38f9141be68b1d83ae70f0
root@wl ~ # umount /lib/libc.so.1 2)
root@wl ~ # ls -al /usr/lib/libc/libc_hwcap1.so.1 /lib/libc.so.1 3)
-rwxr-xr-x 1 root bin 1083760 9월 18일 01:59 /lib/libc.so.1
-rwxr-xr-x 1 root bin 1087992 9월 18일 02:00 /usr/lib/libc/libc_hwcap1.so.1
root@wl ~ # mount -O -F lofs /usr/lib/libc/libc_hwcap1.so.1 /lib/libc.so.1 4)
1) 두 파일이 같은 파일임을 알 수 있다. 시스템에 따라 /usr/lib/libc/libc_hwcap2.so.1 와 연결되어있을 수 있다. 그렇다면 이 예제에서는 파라메터를 바꿔서 시험해봐야 한다. 2) 마운트를 해제한다. 3) 두 파일이 다른 파일임을 알 수 있다. 파일 용량부터 차이난다. 원래 있는 파일을 지우지 않기 위해 lofs를 이용해 마운트한 것이다. 4) 다시 원래대로 복구한다.
※ lofs로 마운트 해서 마운트 한것 처럼 보이지만, 실제로는 그냥 파일이다.