공유 객체 파일과 재배치 가능 파일의 차이점은 무엇입니까?

공유 객체 파일과 재배치 가능 파일의 차이점은 무엇입니까?

https://linux-audit.com/elf-binaries-on-linux-understanding-and-analytic/ 설명하다

유형 필드는 파일이 어떤 용도로 사용되는지 알려줍니다. 몇 가지 일반적인 파일 형식이 있습니다.

CORE (value 4)
DYN (Shared object file), for libraries (value 3)
EXEC (Executable file), for binaries (value 2)
REL (Relocatable file), before linked into an executable file (value 1)

https://unix.stackexchange.com/a/476157/674커널 모듈이 REL임을 나타냅니다. 왜 DYN 대신 REL을 사용합니까?

DYN과 REL의 차이점은 무엇입니까?

감사해요.

답변1

바라보다시스템 V ABI, ELF 형식에 대한 사양이 포함되어 있습니다. 그것은 말한다

다양한 대상 파일에 대한 재배치 항목은 멤버를 약간 다르게 해석합니다 r_offset.

  • 재배치 가능한 파일에서는 r_offset섹션 오프셋을 저장합니다. 즉, 재배치 섹션 자체는 파일의 다른 섹션을 수정하는 방법을 설명합니다. 재배치 오프셋은 두 번째 섹션 내의 저장 위치를 ​​지정합니다.

  • 실행파일과 공유객체에 r_offset가상주소를 저장합니다. 이러한 파일에 대한 재배치 항목을 동적 링커에 더 유용하게 만들기 위해 섹션 오프셋(파일 해석)이 가상 주소(메모리 해석)로 대체됩니다.

재배치 가능한 파일은 여전히 ​​완전히 재배치 가능한 반면, 공유 객체는 연결 프로세스를 계속 진행하며 대부분 재배치되었습니다. 공유 객체는 해당 코드가 위치 독립적인 경우에만 재배치 가능합니다(예를 들어GCC의 옵션으로 -fPIC구축 되었습니다).

커널 모듈은 위치 독립적이지 않고 재배치 가능해야 하므로 재배치 가능한 파일로 제공됩니다.

답변2

Linux는 커널에서 동적 개체를 처리하기 위해 ELF 방법을 사용하지 않습니다. 대신 Linux는 a.out. .o커널에 연결되어 로드되는 재배치 가능한 파일(파일과 유사)이 있습니다 .

1980년대 중반에 도입된 방법은 다음을 수행하는 프로그램을 호출하거나 사용자 공간 데몬이 다음을 수행하도록 하여 이와 같이 작동합니다.

  • 드라이버 파일 또는 .o여러 파일을 통해 연결된 파일을 가져오고 드라이버를 로드 주소 0에 연결하는 최종 연결 단계(사용)를 수행합니다. 이는 COMMON 변수가 출력에 나타나지 않기 때문에 필요합니다..old -o driver -r *.oldsize

  • 이제 size생성된 파일을 호출하여 드라이버에 필요한 크기를 가져옵니다.

  • 개방형 모듈은 드라이버를 로드하고 ioctl.

  • 드라이버를 로드하는 모듈은 kmem_alloc()커널의 텍스트, 데이터 및 bss 섹션을 호출하고 반환합니다.kmem_alloc()ioctl

  • linker( ld)를 다시 호출하되 이제 모듈 로딩 드라이버가 반환한 주소에 드라이버를 연결합니다.

  • 모듈 로드 드라이버에 대한 다른 호출을 사용하여 커널 할당 주소에 연결된 드라이버 변형을 로드하고 드라이버 내용을 할당된 공간에 배치하도록 드라이버에 지시합니다.

  • 이제 로드된 드라이버를 사용할 준비가 되었습니다.

ELF 접근 방식을 사용하는 커널을 보려면 Solaris 커널을 살펴보는 것이 좋습니다.

예를 들어 Solaris용으로 로드된 첫 번째 파일은 두 개의 공유 "라이브러리"에 의존하는 파일 /platform/i86pc/kernel/amd64/unix로 표시되는 입니다 . excutable표준 ELF 도구를 사용하여 나열할 수 있습니다 dump.

dump -Lv /platform/i86pc/kernel/amd64/unix  

/platform/i86pc/kernel/amd64/unix:

  **** DYNAMIC SECTION INFORMATION ****
.dynamic:
[INDEX] Tag         Value
[1]     NEEDED          genunix
[2]     NEEDED          dtracestubs
[3]     HASH            0xfffffffffb8c1040
[4]     STRTAB          0xfffffffffb8e4e10
[5]     STRSZ           0xf584
[6]     SYMTAB          0xfffffffffb8c9fc0
[7]     SYMENT          0x18
[8]     CHECKSUM        0x4445
[9]     TEXTREL         0
[10]    RELA            0xfffffffffb8f4398
[11]    RELASZ          0x16470
[12]    RELAENT         0x18
[13]    FEATURE_1       PARINIT
[14]    SUNW_CAP        0xfffffffffb8a37a8
[15]    FLAGS           TEXTREL
[16]    FLAGS_1         [ NOHDR ]
[17]    SUNW_STRPAD     0x200
[18]    SUNW_LDMACH     EM_AMD64

file /platform/i86pc/kernel/unix        
/platform/i86pc/kernel/unix:       ELF 32-bit LSB executable 80386 Version 1, dynamically linked, not stripped, no debugging information available

여기에서 볼 수 있듯이 기본 커널이 의존하는 공유 라이브러리는 genunix및 입니다 dtracestubs.

따라서 Solaris 커널을 부팅하려면 ELF를 이해하고 커널이 의존하는 공유 객체를 로드하고 연결할 수 있는 부트 로더가 필요합니다.

참고: Solaris에는 커널 동적 링커가 있으므로 동적으로 드라이버를 로드하는 데 필요한 단계가 더 적습니다.

관련 정보