mem_offset(), mem_offset64()

Updated: April 19, 2023

Get the physical address of a virtually mapped memory block


#include <sys/mman.h>

int mem_offset( const void * addr,
                int fd,
                size_t length,
                off_t * offset,
                size_t * contig_len );

int mem_offset64( const void * addr,
                  int fd,
                  size_t length,
                  off64_t * offset,
                  size_t * contig_len );


The address of the memory block whose offset and contiguous length you want to get.
This must be NOFD, or the function will fail.
The length of the block of memory that you want the offset for.
A pointer to a location where the function can store the offset of the memory block.
NULL, or a pointer to a location where the function can store either length or the length of the largest contiguous block of memory that's currently mapped to the calling process starting at addr, whichever is smaller.



Use the -l c option to qcc to link against this library. This library is usually included automatically.


The mem_offset() and mem_offset64() functions set the variable pointed to by offset to the offset into /dev/mem of addr (i.e., its physical address). The mem_offset64() function is a large-file support version of mem_offset().

  • In QNX Neutrino 6.6 or later, the large-file support functions and data types appear in the name space only if you define _LARGEFILE64_SOURCE when you compile your code. For more information, see Classification in What's in a Function Description?
  • If the physical address isn't a valid off_t value, mem_offset() will fail with errno set to EOVERFLOW. This is typically the case with many ARM systems, and you should use mem_offset64() to get the physical address.
  • These functions also cause the initial copying or zero-filling of MAP_PRIVATE or MAP_ANON pages.
  • For best performance results, you should cache the result of mem_offset(), rather than repeatedly call the function for a given virtual address.

In QNX Neutrino 7.0 or later, these functions succeed only if the memory in question is locked (either explicitly with an mlock() or mlockall() call, or implicitly, such as when an entire process or system is fully locked).

To get the offset and length of a mapped typed memory block, use posix_mem_offset() or posix_mem_offset64().

Note the difference between mem_offset() and posix_mem_offset():


An error occurred (errno is set).


The process hasn't mapped memory at the given address addr, or the address is of MAP_LAZY pages that aren't yet memory-resident.
(QNX Neutrino 7.0 or later) The memory isn't locked. The returned offset might correspond to the physical address associated with the given virtual one, but don't rely on it for any functionality. The location that contig_len points to might also be updated. These values are transient and are reported back as a debugging/testing aid only.
The file descriptor fd isn't NOFD.
This error is specific to mem_offset() and is returned when the address is too large for the 32-bit off_t; use mem_offset64() instead.


off64_t                 offset;

if(mem_offset64(addr, NOFD, 1, &offset, NULL) == -1)
  /* Error */
  /* offset contains the physical address of the memory
     mapped at addr. */


QNX Neutrino

Cancellation point No
Interrupt handler No
Signal handler Yes
Thread Yes