mem_offset(), mem_offset64()

Get the offset of a mapped typed memory block

Synopsis:

#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 );

Arguments:

addr
The address of the memory block whose offset and contiguous length you want to get.
fd
The file descriptor that identifies the typed memory object. This must be the descriptor that you used (in a call to mmap()) to establish the mapping that contains addr.
length
The length of the block of memory that you want the offset for.
offset
A pointer to a location where the function can store the offset of the memory block.
contig_len
A pointer to a location where the function can store either length or the length of the largest contiguous block of typed memory that's currently mapped to the calling process starting at addr, whichever is smaller.

Library:

libc

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

Description:

The mem_offset() and mem_offset64() functions set the variable pointed to by offset to the offset (or location), within a typed memory object, of the memory block currently mapped at addr.


Note: If the offset is greater than INT_MAX, mem_offset() gives an error of EOVERFLOW. Use mem_offset64() if this happens.

If you use the offset and contig_len values obtained from calling mem_offset() in a call to mmap() with a file descriptor that refers to the same memory pool as fd (either through the same port or through a different port), the memory region that's mapped must be exactly the same region that was mapped at addr in the address space of the process that called mem_offset().


Note: For best performance results, it is preferable to cache the result of mem_offset(), rather than repeatedly call the function for a given virtual address.

QNX extension

If you specify fd as NOFD, offset is the offset into /dev/mem of addr (i.e. its physical address). If the memory object specified by fd isn't a typed memory object, or specified as NOFD, the call fails.


Note: If the physical address is not 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.

For the NOFD case, mem_offset():

  • Cause the initial copying or zero-filling of the MAP_PRIVATE or MAP_ANON pages.
  • Return -1 (EACCES) for MAP_LAZY pages that are not memory resident yet.

Returns:

0
Success.
-1
An error occurred (errno is set).

Errors:

EACCES
The process hasn't mapped memory at the given address addr.
EBADF
Invalid open file descriptor fildes.
EINVAL
The file descriptor fildes doesn't correspond to the memory object mapped at addr.
ENODEV
The file descriptor fildes isn't connected to a memory object supported by this function.
ENOSYS
The mem_offset() function isn't supported by this implementation.
EOVERFLOW
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.

Examples:

off64_t                 offset;

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

Classification:

mem_offset() is QNX Neutrino; mem_offset64() is Large-file support

Safety:
Cancellation point No
Interrupt handler No
Signal handler Yes
Thread Yes

See also:

mmap(), posix_mem_offset(), posix_mem_offset64()