Signed-off-by: Ron Brender <ron.brender@gmail.com>
[dwarf-doc.git] / dwarf5 / latexdoc / examples.tex
index e118105..95e53fe 100644 (file)
@@ -1,11 +1,11 @@
 \chapter{Examples (Informative)}
-\label{app:examplesinformative}F
+\label{app:examplesinformative}
 
 The following sections provide examples that illustrate
 various aspects of the DWARF debugging information format.
 
 
-\section{ Compilation Units and Abbreviations Table Example}F
+\section{Compilation Units and Abbreviations Table Example}
 \label{app:compilationunitsandabbreviationstableexample}
 
 
@@ -354,33 +354,33 @@ in Figure \refersec{fig:fortranarrayexampledwarfdescription}.
 1\$: \DWTAGarraytype
         ! No name, default (Fortran) ordering, default stride
         \DWATtype(reference to REAL)
-        \DWATassociated(expression= ! Test 'ptr\_assoc' \nolink{flag}
+        \DWATassociated(expression=    ! Test 'ptr\_assoc' \nolink{flag}
             \DWOPpushobjectaddress
-            \DWOPlitn              ! where n == offset(ptr\_assoc)
+            \DWOPlitn                ! where n == offset(ptr\_assoc)
             \DWOPplus
             \DWOPderef
-            \DWOPlitone              ! mask for 'ptr\_assoc' \nolink{flag}
+            \DWOPlitone                  ! mask for 'ptr\_assoc' \nolink{flag}
             \DWOPand)
         \DWATdatalocation(expression= ! Get raw data address
             \DWOPpushobjectaddress
-            \DWOPlitn              ! where n == offset(base)
+            \DWOPlitn                ! where n == offset(base)
             \DWOPplus
-            \DWOPderef)            ! Type of index of array 'ap'
+            \DWOPderef)                ! Type of index of array 'ap'
 2\$:     \DWTAGsubrangetype
             ! No name, default stride
             \DWATtype(reference to INTEGER)
             \DWATlowerbound(expression=
                 \DWOPpushobjectaddress
-                \DWOPlitn          ! where n ==
-                                    !   offset(desc, dims) +
-                                    !   offset(dims\_str, lower\_bound)
+                \DWOPlitn             ! where n ==
+                                         !   offset(desc, dims) +
+                                         !   offset(dims\_str, lower\_bound)
                 \DWOPplus
                 \DWOPderef)
             \DWATupperbound(expression=
                 \DWOPpushobjectaddress
-                \DWOPlitn          ! where n ==
-                                    !   offset(desc, dims) +
-                                    !   offset(dims\_str, upper\_bound)
+                \DWOPlitn            ! where n ==
+                                        !   offset(desc, dims) +
+                                        !   offset(dims\_str, upper\_bound)
                 \DWOPplus
                 \DWOPderef)
             !  Note: for the m'th dimension, the second operator becomes
@@ -414,14 +414,14 @@ in Figure \refersec{fig:fortranarrayexampledwarfdescription}.
 6\$: \DWTAGarraytype
         ! No name, default (Fortran) ordering, default stride
         \DWATtype(reference to 3\$)
-        \DWATallocated(expression=     ! Test 'ptr\_alloc' \nolink{flag}
+        \DWATallocated(expression=       ! Test 'ptr\_alloc' \nolink{flag}
             \DWOPpushobjectaddress
             \DWOPlitn                  ! where n == offset(ptr\_alloc)
             \DWOPplus
             \DWOPderef
-            \DWOPlittwo                  ! Mask for 'ptr\_alloc' \nolink{flag}
+            \DWOPlittwo                    ! Mask for 'ptr\_alloc' \nolink{flag}
             \DWOPand)
-        \DWATdatalocation(expression= ! Get raw data address
+        \DWATdatalocation(expression=   ! Get raw data address
             \DWOPpushobjectaddress
             \DWOPlitn                  ! where n == offset(base)
             \DWOPplus
@@ -732,38 +732,38 @@ Figure~\refersec{fig:assumedrankdwarf}.
          \DWATtype(reference to real)
          \DWATrank(expression=
              \DWOPpushobjectaddress
-             \DWOPlitn                ! offset of rank in descriptor>
+             \DWOPlitn                        ! offset of rank in descriptor
              \DWOPplus
              \DWOPderef)
          \DWATdatalocation(expression=
              \DWOPpushobjectaddress
-             \DWOPlitn                ! offset of data in descriptor>
+             \DWOPlitn                        ! offset of data in descriptor
              \DWOPplus
              \DWOPderef)
 11\$:    \DWTAGgenericsubrange
              \DWATtype(reference to integer)
              \DWATlowerbound(expression=
              !   Looks up the lower bound of dimension i.
-             !   Operation                           ! Stack effect
-             !   (implicit)                          ! i                                                                     
-                 \DWOPlitn                          ! i sizeof(dim)
-                 \DWOPmul                           ! dim[i]
-                 \DWOPlitn                          ! dim[i] offsetof(dim)
-                 \DWOPplus                          ! dim[i]+offset
-                 \DWOPpushobjectaddress           ! dim[i]+offsetof(dim) objptr
-                 \DWOPplus                          ! objptr.dim[i]
-                 \DWOPlitn                          ! objptr.dim[i] offsetof(lb)
-                 \DWOPplus                          ! objptr.dim[i].lowerbound
-                 \DWOPderef)                        ! *objptr.dim[i].lowerbound
+             !   Operation                       ! Stack effect
+             !   (implicit)                      ! i                                                                     
+                 \DWOPlitn                    ! i sizeof(dim)
+                 \DWOPmul                       ! dim[i]
+                 \DWOPlitn                    ! dim[i] offsetof(dim)
+                 \DWOPplus                      ! dim[i]+offset
+                 \DWOPpushobjectaddress       ! dim[i]+offsetof(dim) objptr
+                 \DWOPplus                      ! objptr.dim[i]
+                 \DWOPlitn                    ! objptr.dim[i] offsetof(lb)
+                 \DWOPplus                      ! objptr.dim[i].lowerbound
+                 \DWOPderef)                    ! *objptr.dim[i].lowerbound
              \DWATupperbound(expression=
              !   Looks up the upper bound of dimension i.
-                 \DWOPlitn                          ! sizeof(dim)
+                 \DWOPlitn                    ! sizeof(dim)
                  \DWOPmul
-                 \DWOPlitn                          ! offsetof(dim)
+                 \DWOPlitn                    ! offsetof(dim)
                  \DWOPplus
                  \DWOPpushobjectaddress
                  \DWOPplus
-                 \DWOPlitn                          ! offset of upperbound in dim
+                 \DWOPlitn                    ! offset of upperbound in dim
                  \DWOPplus
                  \DWOPderef)
              \DWATbytestride(expression=
@@ -2606,3 +2606,207 @@ X<Z<int>> z;
 \caption{C++ template alias example \#2: DWARF description}
 \label{fig:ctemplatealiasexample2dwarf}
 \end{figure}
+
+\clearpage
+\section{Implicit Pointer Examples}
+\label{app:implicitpointerexamples}
+If the compiler determines that the value of an object is
+constant (either throughout the program, or within a specific
+range), it may choose to materialize that constant only when
+used, rather than store it in memory or in a register. The
+\DWOPimplicitvalue{} operation can be used to describe such a
+value. Sometimes, the value may not be constant, but still can be
+easily rematerialized when needed. A DWARF expression terminating
+in \DWOPstackvalue{} can be used for this case. The compiler may
+also eliminate a pointer value where the target of the pointer
+resides in memory, and the \DWOPstackvalue{} operator may be used
+to rematerialize that pointer value. In other cases, the compiler
+will eliminate a pointer to an object that itself needs to be
+materialized. Since the location of such an object cannot be
+represented as a memory address, a DWARF expression cannot give
+either the location or the actual value or a pointer variable
+that would refer to that object. The \DWOPimplicitpointer{}
+operation can be used to describe the pointer, and the debugging
+information entry to which its first operand refers describes the
+value of the dereferenced object. A DWARF consumer will not be
+able to show the location or the value of the pointer variable,
+but it will be able to show the value of the dereferenced
+pointer.
+
+Consider the \addtoindex{C} source shown in 
+Figure \refersec{fig:cimplicitpointerexample1source}.
+Assume that the function \texttt{foo} is not inlined,
+that the argument x is passed in register 5, and that the
+function \texttt{foo} is optimized by the compiler into just 
+an increment of the volatile variable \texttt{v}. Given these
+assumptions a possible DWARF description is shown in
+Figure \refersec{fig:cimplicitpointerexample1dwarf}.
+
+\begin{figure}[h]
+\begin{lstlisting}
+struct S { short a; char b, c; };
+volatile int v;
+void foo (int x)
+{
+    struct S s = { x, x + 2, x + 3 };
+    char *p = &s.b;
+    s.a++;
+    v++;
+}
+int main ()
+{
+    foo (v+1);
+    return 0;
+}
+\end{lstlisting}
+\caption{C implicit pointer example \#1: source}
+\label{fig:cimplicitpointerexample1source}
+\end{figure}
+
+\begin{figure}[h]
+\addtoindexx{implicit pointer example \#1}
+\begin{dwflisting}
+\begin{alltt}
+1\$: \DWTAGstructuretype
+        \DWATname("S")
+        \DWATbytesize(4)
+10\$:    \DWTAGmember
+            \DWATname("a")
+            \DWATtype(reference to "short int")
+            \DWATdatamemberlocation(constant 0)
+11\$:    \DWTAGmember
+            \DWATname("b")
+            \DWATtype(reference to "char")
+            \DWATdatamemberlocation(constant 2)
+12\$:    \DWTAGmember
+            \DWATname("c")
+            \DWATtype(reference to "char")
+            \DWATdatamemberlocation(constant 3)
+2\$: \DWTAGsubprogram
+        \DWATname("foo")
+20\$:    \DWTAGformalparameter
+            \DWATname("x")
+            \DWATtype(reference to "int")
+            \DWATlocation(\DWOPregfive)
+21\$:    \DWTAGvariable
+            \DWATname("s")
+            \DWATlocation(expression=
+                \DWOPbregfive(1) \DWOPstackvalue \DWOPpiece(2)
+                \DWOPbregfive(2) \DWOPstackvalue \DWOPpiece(1)
+                \DWOPbregfive(3) \DWOPstackvalue \DWOPpiece(1))
+22\$:    \DWTAGvariable
+            \DWATname("p")
+            \DWATtype(reference to "char *")
+            \DWATlocation(expression=
+            \DWOPimplicitpointer(reference to 21\$, 2))
+\end{alltt}
+\end{dwflisting}
+\caption{C implicit pointer example \#1: DWARF description}
+\label{fig:cimplicitpointerexample1dwarf}
+\end{figure}
+
+In Figure \refersec{fig:cimplicitpointerexample1dwarf},
+even though variables \texttt{s} and \texttt{p} are both optimized 
+away completely, this DWARF description still allows a debugger to 
+print the value of the variable \texttt{s}, namely \texttt{(2, 3, 4)}. 
+Similarly, because the variable \texttt{s} does not live in
+memory, there is nothing to print for the value of \texttt{p}, but the 
+debugger should still be able to show that \texttt{p[0]} is 3, 
+\texttt{p[1]} is 4, \texttt{p[-1]} is 0 and \texttt{p[-2]} is 2.
+
+\needlines{6}
+As a further example, consider the C source 
+shown in Figure \refersec{fig:cimplicitpointerexample2source}. Make
+the following assumptions about how the code is compiled:
+\begin{itemize}
+\item The function \texttt{foo} is inlined
+into function \texttt{main}
+\item The body of the main function is optimized to just
+three blocks of instructions which each increment the volatile
+variable \texttt{v}, followed by a block of instructions to return 0 from
+the function
+\item Label \texttt{label0} is at the start of the main
+function, \texttt{label1} follows the first \texttt{v++} block, 
+\texttt{label2} follows the second \texttt{v++} block and 
+\texttt{label3} is at the end of the main function
+\item Variable \texttt{b} is optimized away completely, as it isn't used
+\item The string literal \texttt{"opq"} is optimized away as well
+\end{itemize}
+Given these assumptions a possible DWARF description is shown in
+Figure \refersec{fig:cimplicitpointerexample2dwarf}.
+
+\begin{figure}[h]
+\begin{lstlisting}
+static const char *b = "opq";
+volatile int v;
+static inline void foo (int *p)
+{
+    (*p)++;
+    v++;
+    p++;
+    (*p)++;
+    v++;
+}
+int main ()
+{
+    int a[2] = { 1, 2 };
+    v++;
+    foo (a);
+    return a[0] + a[1] - 5;
+}
+\end{lstlisting}
+\caption{C implicit pointer example \#2: source}
+\label{fig:cimplicitpointerexample2source}
+\end{figure}
+
+\begin{figure}[h]
+\addtoindexx{implicit pointer example \#2}
+\begin{dwflisting}
+\begin{alltt}
+1\$: \DWTAGvariable
+        \DWATname("b")
+        \DWATtype(reference to "const char *")
+        \DWATlocation(expression=
+            \DWOPimplicitpointer(reference to 2$, 0))
+2\$: \DWTAGdwarfprocedure
+        \DWATlocation(expression=
+            \DWOPimplicitvalue(4, \{'o', 'p', 'q', '\slash0'\}))
+3\$: \DWTAGsubprogram
+        \DWATname("foo")
+        \DWATinline(\DWINLdeclaredinlined)
+30\$:    \DWTAGformalparameter
+            \DWATname("p")
+            \DWATtype(reference to "int *")
+4\$: \DWTAGsubprogram
+        \DWATname("main")
+40\$:  \DWTAGvariable
+            \DWATname("a")
+            \DWATtype(reference to "int[2]")
+            \DWATlocation(location list 98$)
+41\$:    \DWTAGinlinedsubroutine
+            \DWATabstractorigin(reference to 3$)
+42\$:        \DWTAGformalparameter
+            \DWATabstractorigin(reference to 30$)
+            \DWATlocation(location list 99$)
+
+! .debug_loc section
+98\$:<label0 in main> .. <label1 in main>
+        \DWOPlitone \DWOPstackvalue \DWOPpiece(4)
+        \DWOPlittwo \DWOPstackvalue \DWOPpiece(4)
+    <label1 in main> .. <label2 in main>
+        \DWOPlittwo \DWOPstackvalue \DWOPpiece(4)
+        \DWOPlittwo \DWOPstackvalue \DWOPpiece(4)
+    <label2 in main> .. <label3 in main>
+        \DWOPlittwo \DWOPstackvalue \DWOPpiece(4)
+        \DWOPlitthree \DWOPstackvalue \DWOPpiece(4)
+    0 .. 0
+99\$:<label1 in main> .. <label2 in main>
+        \DWOPimplicitpointer(reference to 40\$, 0)
+    <label2 in main> .. <label3 in main>
+        \DWOPimplicitpointer(reference to 40\$, 4)
+    0 .. 0
+\end{alltt}
+\end{dwflisting}
+\caption{C implicit pointer example \#2: DWARF description}
+\label{fig:cimplicitpointerexample2dwarf}
+\end{figure}