Quantcast
Channel: Active questions tagged gcc - Stack Overflow
Viewing all articles
Browse latest Browse all 22000

mmap behaviour changed after OS upgrade?

$
0
0

After a major OS upgrade this C code behaviour has changed:

...if ((fd = open(argv[1], O_RDWR | O_SYNC)) == -1)    FATAL;printf("character device %s opened.\n", argv[1]);fflush(stdout);/* map one page */map_base = mmap(0xe0000000, MAP_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);if (map_base == (void *)-1)    FATAL;printf("Memory mapped at address %p.\n", map_base);...

With a binary inherited from an old OS, "old mmap" returns a virtual address 0x7fb20d725000. If I rebuild the same C file on a new OS, it returns 0xe0000000 which seems to be a physical, and subsequent code - which uses this returned address - now fails with a segmentation fault.

How to force mmap to work as before without downgrading the OS or using old binary? Any modern flags for gcc or mmap itself?

Run a code example below with sudo ./test /dev/zero 0x01000000 : (/dev/zero instead of a real device gives the same results)

#include <stdint.h>#include <stdio.h>#include <stdlib.h>#include <unistd.h>#include <byteswap.h>#include <string.h>#include <errno.h>#include <signal.h>#include <fcntl.h>#include <ctype.h>#include <termios.h>#include <sys/types.h>#include <sys/mman.h>/* ltoh: little to host *//* htol: little to host */#if __BYTE_ORDER == __LITTLE_ENDIAN#define ltohl(x)       (x)#define ltohs(x)       (x)#define htoll(x)       (x)#define htols(x)       (x)#elif __BYTE_ORDER == __BIG_ENDIAN#define ltohl(x)     __bswap_32(x)#define ltohs(x)     __bswap_16(x)#define htoll(x)     __bswap_32(x)#define htols(x)     __bswap_16(x)#endif#define FATAL do { fprintf(stderr, "Error at line %d, file %s (%d) [%s]\n", __LINE__, __FILE__, errno, strerror(errno)); exit(1); } while(0)#define MAP_SIZE (16*1024*1024UL)#define MAP_MASK (MAP_SIZE - 1)int main(int argc, char **argv){    int fd;    void *map_base, *virt_addr;    uint32_t read_result, writeval;    off_t target;    char *device;    if (argc != 3) {        fprintf(stderr,"\nUsage:\t%s <device> <address> [[type] data]\n""\tdevice  : character device to access\n""\taddress : memory address to access\n\n",            argv[0]);        exit(1);    }    device = strdup(argv[1]);    target = strtoul(argv[2], 0, 0);    fprintf("argc = %d, device: %s, address: 0x%08x\n", argc, device, (unsigned int)target);    if ((fd = open(argv[1], O_RDWR | O_SYNC)) == -1)        FATAL;    fprintf(stdout, "character device %s opened.\n", argv[1]);      fflush(stdout);    /* map one page */    map_base = mmap(0xe0000000, MAP_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);    if (map_base == (void *)-1)        FATAL;    fprintf(stdout, "Memory mapped at address %p.\n", map_base);      fflush(stdout);    /* calculate the virtual address to be accessed */    virt_addr = map_base + target;    /* read only */    read_result = *((uint32_t *) virt_addr);    /* swap 32-bit endianess if host is not little-endian */    read_result = ltohl(read_result);    printf("Read 32-bit value at address 0x%08x (%p): 0x%08x\n",                (unsigned int)target, virt_addr, (unsigned int)read_result);    if (munmap(map_base, MAP_SIZE) == -1)        FATAL;    close(fd);    return 0;}

Viewing all articles
Browse latest Browse all 22000

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>