0

공유 라이브러리 파일의 경우 파일 정의와 심볼 정의의 가상 주소 사이를 변환하는 방법은 무엇입니까? 심볼 테이블의 심볼에 대한 ELF 문서에서파일 오프셋 대 공유 라이브러리의 가상 주소

, 실행 파일과 공유 객체 파일에서

, st_value는 가상 주소를 보유하고 있습니다. 이러한 파일의 기호를 동적 링커에 더 유용하게 만들기 위해 섹션 오프셋 (파일 해석)은 seciton 번호가 관련이없는 가상 주소 (메모리 해석)로 연결됩니다.

하지만 어떻게 파일에서 오프셋을 얻을 수 있습니까? 또는 오프셋이 주어지면 가상 주소 (메모리 해석에 대한 파일 해석)를 어떻게 계산할 수 있습니까?

이와 같은 시나리오를 상상해보십시오. 프로세스 실행 중에 공유 라이브러리에 구현 된 함수, 예를 들어 libx.so를 사용하고 있으며 라이브러리 파일이 vma으로 표시된 영역에 매핑되어 있다고 가정합니다.

//addr holds the value of PC 
offset = (vma->vm_pgoff << PAGE_SIZE) + addr -vma->vm_start; 

지금 알다시피, offset은 라이브러리 파일의 명령어 오프셋을 유지합니다. 이 오프셋을 감안할 때 함수 이름을 알고 싶습니다. 한 가지 방법은 offset에 해당하는 가상 주소를 계산하고 기호 테이블의 st_value과 가상 주소를 비교하는 것입니다. st_value이 오름차순으로 저장되도록 처리 된 경우 st_value_1 < virtual_address < st_value_2은 내가 찾고있는 것이 st_name_1임을 의미합니다. 따라서 문제는 전환에 있습니다. 참고로
는 심볼 테이블 엔트리의 데이터 구조는 다음

typedef struct{ 
    Elf32_Word  st_name; 
    Elf32_Addr  st_value; 
    Elf32_Word  st_size; 
    unsigned char st_info; 
    unsigned char st_other; 
    Elf32_Half  st_shndx; 
}Elf32_Sym; 
+0

GOT 및 PLT를 알고 있습니까? 확실하지는 모르겠지만 귀하의 정확한 질문,하지만 난 강의 [htwsl] (https://software.intel.com/sites/default/files/m/a/1/e/dsohowto.pdf) 일부 이해하는 데 도움이 믿습니다 –

+0

"st_values가 오름차순으로 저장되도록 처리되면 st_value_1 <가상 _ 주소 ysdx

+0

@ysdx ELF 문서에 따르면 데이터 객체의 경우 st_size는 객체에 포함 된 바이트 수입니다. 그러나 나는 그 규칙이 기능을 위해 유지되지 않는다고 생각한다. 함수 인 심볼의 경우 st_size는 신뢰할 수 없으며 함수의 크기를 가져올 수있는 방법을 찾을 수 없습니다. – dudu

답변

0

프로그램 헤더 테이블 PT_LOAD 항목 로더/링커는 가상 어드레스 공간에 ELF 파일의 부분으로 매핑 할 것으로 예상되는 방법을 정의한다. 예를 들어

 
~$ readelf -l /lib/i386-linux-gnu/libc-2.24.so 

Elf file type is DYN (Shared object file) 
Entry point 0x18400 
There are 10 program headers, starting at offset 52 

Program Headers: 
    Type   Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align 
    PHDR   0x000034 0x00000034 0x00000034 0x00140 0x00140 R E 0x4 
    INTERP   0x166374 0x00166374 0x00166374 0x00013 0x00013 R 0x4 
     [Requesting program interpreter: /lib/ld-linux.so.2] 
    LOAD   0x000000 0x00000000 0x00000000 0x1b01c8 0x1b01c8 R E 0x1000 
    LOAD   0x1b0260 0x001b1260 0x001b1260 0x02c74 0x0579c RW 0x1000 
    DYNAMIC  0x1b1db0 0x001b2db0 0x001b2db0 0x000f0 0x000f0 RW 0x4 
    NOTE   0x000174 0x00000174 0x00000174 0x00044 0x00044 R 0x4 
    TLS   0x1b0260 0x001b1260 0x001b1260 0x00008 0x00048 R 0x4 
    GNU_EH_FRAME 0x166388 0x00166388 0x00166388 0x061ec 0x061ec R 0x4 
    GNU_STACK  0x000000 0x00000000 0x00000000 0x00000 0x00000 RW 0x10 
    GNU_RELRO  0x1b0260 0x001b1260 0x001b1260 0x01da0 0x01da0 R 0x1 

그건 (상대) 가상 주소가 0x0005df80 인이 기호

 
    Num: Value Size Type Bind Vis  Ndx Name 
    188: 0005df80 35 FUNC GLOBAL DEFAULT 13 [email protected]@GLIBC_2.1 

을 고려 : 당신은 오프셋 파일 (상대) 가상 메모리 주소 사이의 변환하려면이를 사용해야합니다. 상대적 가상 메모리의 범위 인 첫 번째 PT_LOAD 항목에 속하며 0x00000000에서 0x00000000 + 0x1b01c8까지입니다. 세그먼트 내 오프셋은 Value - VirtAddr = 0x00000000입니다. 따라서 파일 내에 오프셋되어 있기 때문에 PhysAddr + (Value - VirtAddr) = 0005df80입니다.