2016-07-28 3 views
-1

64 비트 Linux x86입니다. syscall 기능을 사용하여 mmap syscall을 실행해야합니다. mmap 콜 번호는 9이다 : 그러나C - syscall - 64 비트 포인터

printf("mmap-1: %lli\n", syscall(9, 0, 10, 3, 2 | 32, -1, 0)); 
printf("mmap-2: %lli\n", mmap(  0, 10, 3, 2 | 32, -1, 0)); 

, 내가 그것을 실행할 때 syscall 함수가 잘못된 결과를 제공합니다.

mmap-1: 2236940288 
mmap-2: 140503502090240 

mmap-1: 3425849344 
mmap-2: 140612065181696 

mmap-1: 249544704 
mmap-2: 139625341366272 

mmap 잘 작동하지만 "주소"Segmentation faultsyscall 결과를 반환했습니다. syscall의 값은 32 비트 또는 그 이상으로 캐스팅 된 것으로 보입니다.

내가 뭘 잘못하고 있니?

+1

맨 페이지에서 볼 수있는 한,'syscall'은'long long'이나 포인터가 아닌'int'를 반환합니다 ...?!? – DevSolar

+0

'syscall()'의 반환 값에 대한 맨 페이지에서 반환 값은 호출되는 시스템 호출에 의해 정의됩니다. 일반적으로 0 반환 값은 성공을 나타냅니다. -1 반환 값 은 오류를 나타내며 오류 코드는 errno에 저장됩니다 .' 당신은 [여기] (http://stackoverflow.com/questions/26828461/how-do-i-get-the-output-of-a-linux-system-call-in-cc)를보고 싶을 수도 있고 [here] (http://man7.org/linux/man-pages/man2/syscall.2.html)에서 자세한 정보를 얻을 수 있습니다. –

+0

@DevSolar 그렇습니다. 현재'gcc'를 사용하고 있습니다 만, Node.js gyp 컴파일러를 사용하는 다른 프로젝트에서는'syscall'이 64 비트 값을 반환하고 모든 것이 잘 작동한다고 생각합니다. 어떤 경우에도 "64 비트"시스템 콜을 실행하는 올바른 방법은 무엇입니까? – Vad

답변

-1

는 문제의 원인을 찾았 내가 -std=c99 옵션을 gcc를 실행하고,이 문제를 해결 제거 :

mmap-1: 139975263928320 
mmap-2: 139975263924224 

내 생각을, -std=99int syscall()로하고 그것없이 콜을 정의 그것의 long syscall().

+0

아니요,'syscall' 함수는 ** C 함수가 아닙니다 **. 그것은 POSIX 함수이므로 매개 변수와 리턴 타입은 C99로 바뀌지 않는 POSIX 표준에 따라 달라집니다. –

+0

@ LưuVĩnhPhúc 잘'gcc' 인수에서'-std = c99'를 제거 했으므로 64 비트 값 – Vad

+0

을 I로 반환합니다 잘못된 형식 지정자를 사용하는 것은 정의되지 않은 동작이므로 아무것도 할 수 없습니다. 'printf'는 variadic 함수이며 타입에 대해 아무 것도 모르기 때문에 사용자가 올바른 포맷을 사용해야합니다 –

-1

syscall()에 첫 번째 매개 변수 에 0 (NULL)을 전달하는 대신 이전에 선언 한 포인터를 전달하십시오. 이렇게하면 mmap에 의해 매핑 된 메모리에 액세스 할 수 있습니다. mmap 함수 선언 :

void *mmap(void *addr, size_t length, int prot, int flags, int fd, off_t offset);