Pointers and Addresses
The Solaris Operating System 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 on memory resources is referred to as
an address space, which associates a range of address values (either [0 ... 0xffffffff] for
a 32-bit address space or [0 ... 0xffffffffffffffff] for a 64-bit address space) with
a set of translations that the operating system and hardware use to
convert each virtual address to a corresponding physical memory location. 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, the declaration:
int *p;
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(1) -b command to determine the number of bits
used for pointers by the active operating system kernel.
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-hand 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-hand 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-hand fragment,
which simply traces the value of the data object directly using its
name.