2016-07-28 6 views
-1

Я на 64-разрядной версии Linux x86. Мне нужно выполнить команду mmap с помощью функции syscall. mmap число системных вызовов 9:C - syscall - 64-bit - pointer

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 работает просто отлично, но "адрес" вернулся syscall результат в Segmentation fault. Значения от syscall кажутся отлитыми до 32 бит или что-то в этом роде.

Что я делаю неправильно?

+1

Насколько я могу видеть на странице man, 'syscall' возвращает' int', а не 'long long' или указатель ...?!? – DevSolar

+0

Из справочной страницы о возвращаемом значении 'syscall()' Возвращаемое значение определяется вызываемым системным вызовом. В общий, возвращаемое значение 0 указывает на успех. Значение возврата -1 -1 указывает на ошибку, а код ошибки хранится в errno.'. Вы можете посмотреть [здесь] (http://stackoverflow.com/questions/26828461/how-do-i-get-the-output-of-a-linux-system-call-in-cc) и [здесь] (http://man7.org/linux/man-pages/man2/syscall.2.html) для получения дополнительной информации. –

+0

@DevSolar Это правда, я использую 'gcc' сейчас, однако, в другом проекте с использованием Node.js gyp-компилятора. Я думаю, что' syscall' вернул 64-битное значение, и все работает нормально. В любом случае, какой правильный способ выполнить «64-разрядный» syscall? – Vad

ответ

-1

Нашли причину проблемы: я бегу gcc с -std=c99 вариант, убрав его решить эту проблему:

mmap-1: 139975263928320 
mmap-2: 139975263924224 

Я думаю, -std=99 определяет системный вызов, как int syscall() и без него его long syscall().

+0

нет, функция 'syscall' ** не ** функция C. Это функция POSIX, поэтому параметры и тип возвращаемого значения зависят от стандарта POSIX, который не изменяется с C99 –

+0

@ LưuVĩnhPhúc. Я удалил '-std = c99' из аргументов' gcc' и теперь возвращает 64-битные значения – Vad

+0

как I сказал, используя неправильный спецификатор формата - это неопределенное поведение, все может случиться. 'printf' - это вариационная функция и ничего не знает о типе, поэтому требуется, чтобы пользователь использовал правильный формат –

-1

В своем syscall() вместо передачи в 0 (NULL) для первого параметра, addr, передайте некоторый указатель, который вы указали ранее. Таким образом, вы можете получить доступ к памяти, отображаемой mmap. mmap объявление функции:

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