Pointers and Addresses

Oracle Solaris uses a technique called virtual memory to provide each user process with its own virtual view of the memory resources on your system. A virtual view of memory resources is referred to as an address space. An address space associates a range of address values with a set of translations that the operating system and hardware use to convert each virtual address to a corresponding physical memory location. The range of address values are[0 ... 0xffffffff] for a 32-bit address space and [0 ... 0xffffffffffffffff] for a 64-bit address space. Pointers in D are data objects that store an integer virtual address value and associate it with a D type that describes the format of the data stored at the corresponding memory location.

You can declare a D variable to be of pointer type by first specifying the type of the referenced data and then appending an asterisk (*) to the type name to indicate you want to declare a pointer type. For example:

int *p;

The preceding declaration declares a D global variable named p that is a pointer to an integer. This declaration means that p itself is an integer of size 32 or 64-bits whose value is the address of another integer located somewhere in memory. Because the compiled form of your D code is executed at probe firing time inside the operating system kernel itself, D pointers are typically pointers associated with the kernel's address space. You can use the isainfo -b command to determine the number of bits used for pointers by the active operating system kernel. For more information about the isainfo command, see isainfo(1).

If you want to create a pointer to a data object inside of the kernel, you can compute its address using the & operator. For example, the operating system kernel source code declares an int kmem_flags tunable. You could trace the address of this int by tracing the result of applying the & operator to the name of that object in D.

trace(&`kmem_flags);

The * operator can be used to refer to the object addressed by the pointer, and acts as the inverse of the & operator. For example, the following two D code fragments are equivalent in meaning:

p = &`kmem_flags;                               trace(`kmem_flags);
trace(*p);

The left fragment creates a D global variable pointer p. Because the kmem_flags object is of type int, the type of the result of &`kmem_flags is int * (that is, pointer to int). The left fragment traces the value of *p, which follows the pointer back to the data object kmem_flags. This fragment is therefore the same as the right fragment, which simply traces the value of the data object directly using its name.