2011-10-11 7 views
5

여러 프로그램을 작성했으며 64 비트에서 컴파일 할 때 메모리 매핑 세그먼트 (예 : 공유 객체 및 공유 메모리가 유지되는 위치)가 다음과 같습니다. 항상 7f9aca84a000-7fff88400000 어딘가에 있지만 정확히 같은 것은 아닙니다.ELF64/x86_64 및 메모리 매핑 세그먼트 시작 주소 (공유 객체)

x86_64 아키텍처 (ELF64)에서이 메모리 세그먼트의 고정 시작 주소가 있는지 또는이 세그먼트의 최대 및 최소 범위가 무엇인지 알고 싶습니다.

여기 제가이 질문을하는 이유입니다. Tru64 UNIX에서 Linux로 시스템을 마이그레이션하고 있습니다. 이 시스템은 IPC Sys V 공유 메모리의 복잡한 고정 메모리 맵핑을 사용했으며이 세그먼트 내의 구조에서 다른 구조로 이동하는 체인 된 목록을 사용합니다. 이 코드 조각의 크기와 복잡성, 그리고 우리가 가진 제한된 시간으로 공유 메모리의 시작을 고정시키는 확실한 방법을 찾고자합니다 (세그먼트를 첨부 할 특정 주소의 shmat를 효과적으로 사용합니다)). 64 비트로 가상 주소 공간이 너무 커서 (48 비트 유효 주소) "안전한"고정 주소를 선택하는 것이 32 비트보다 훨씬 쉽고 위험 부담이 적습니다.

답변

4

x86-64 메모리 매핑 레이아웃은 arch/x86/mm/mmap.c에 정의되어 있습니다. 보시다시피 하향식과 상향식의 두 가지 전략이 사용됩니다.

기본값 인 하향식 할당입니다. 스택의 최대 범위 (스택 rlimit에 정의 된대로) 아래 128MB에서 시작하여 임의의 오프셋으로 조정 한 후 거기에서 메모리에 후속 매핑을 할당합니다.

바텀 업 할당이 대체입니다. 다음 중 하나 인 경우에 사용됩니다.

  • 스택 rlimit는 무제한입니다.
  • 이 프로세스는 성격 집합이 ADDR_COMPAT_LAYOUT입니다. 또는
  • vm.legacy_va_layout sysctl이 0이 아닙니다.

상향식 할당에서는 매핑 된 영역에 점진적으로 상위 주소가 할당되고 TASK_SIZE/3에서 시작하여 임의 오프셋으로 조정됩니다. x86-64의 TASK_SIZE0x800000000000이므로 상향식 할당은 0x2AAAAAAAAAAA에서 시작됩니다.

두 할당 전략 중 하나라도 적용되어야하는 고정 된 매핑에 적합한 구멍을 제안합니다. 2 * TASK_SIZE/3 - 0x500000000000을 사용합니다.

+0

그런 통찰력을 가져 주셔서 감사합니다. 내가 지적한 모든 정보를 둘러 볼 것입니다. – Huygens

+0

우리 출발 주소를 알 수 없습니까? – sdkie

3

나는 당신에게 직접적인 답을하지는 못했지만, 높은 메모리 범위 밖에있는 메모리를 성공적으로 매핑 해 보았습니다. 예를 들면 :

#include <stdio.h> 
#include <sys/mman.h> 
#include <stdint.h> 

#define ADDRESS 0x700000000 

int main(int argc, char *argv[]) { 
    uint64_t *map = mmap((void *)ADDRESS, 4096, PROT_READ | PROT_WRITE, MAP_FIXED | MAP_PRIVATE | MAP_ANONYMOUS, 0, 0); 

    map[0] = 64; 

    printf("Value: %lu\n", map[0]); 

    munmap(map, 4096); 

    return 0; 
} 

이 나는 ​​순간에 커널 소스를 통해 볼 시간이 없어 두려워,하지만 난 확실히 나중에 살펴볼 것이다. 나는 항상이 질문에 대한 답이 무엇인지 궁금해했습니다. . .

+0

정보를 주셔서 감사합니다. 비슷한 기법이 System V IPC 코드에서 사용되었습니다. shmat을 호출 할 때 특별한 주소를 설정했습니다. man page extract를 참조하십시오 : shmaddr이 NULL이 아니고 shmflg에 SHM_RND가 지정되면 shmaddr과 같은 주소에서 SHMLBA의 가장 가까운 배수로 반올림됩니다. 그렇지 않으면 shmaddr은 접속이 발생하는 페이지 정렬 주소 여야합니다. – Huygens

+0

어려운 점은 제안한 주소 (예 : 0x700000000)와 같은 적절한 주소를 확인하는 것입니다. 그리고 우리는 우리의 선택을 명확하게 정당화 할 수 있기를 바랍니다. – Huygens

4

mmaped 세그먼트의 고정 시작 주소가 있습니까?

아니오 Linux는 ASLR (Address Space Layout Randomization)을 지원합니다. 이는 프로그램의 주소에 임의성 요소가 있음을 의미합니다. 이것은 몇몇 악용 사례가 성공할 가능성을 낮추는 것입니다. 더욱이, 일부 커널 패치는 PaX, exec-shield 등을 생각할 때 다른 ASLR 전략을 구현합니다.

따라서 고정 주소를 사용하려면 MAP_FIXED @Ethereal 권장대로.