Update source code example
This commit is contained in:
parent
7a4ad4454e
commit
a06b1a915a
7 changed files with 79 additions and 37 deletions
|
@ -1,3 +1,4 @@
|
||||||
- Add a sample of geenrated code?
|
- Add a sample of geenrated code?
|
||||||
- Explicitly tell that we only support unwinding, and this only for a few
|
- Explicitly tell that we only support unwinding, and this only for a few
|
||||||
registers
|
registers
|
||||||
|
- Make consistant -ise / -ize (eg. optimize)
|
||||||
|
|
|
@ -43,12 +43,6 @@ Under supervision of Francesco Zappa-Nardelli\\
|
||||||
%% Fiche de synthèse %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
%% Fiche de synthèse %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
\input{fiche_synthese}
|
\input{fiche_synthese}
|
||||||
|
|
||||||
%% Abstract %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
|
||||||
\begin{abstract}
|
|
||||||
\todo{Is there a need for an abstract, given the presence above of the
|
|
||||||
``fiche de synthèse''?}
|
|
||||||
\end{abstract}
|
|
||||||
|
|
||||||
%% Table of contents %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
%% Table of contents %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
\tableofcontents
|
\tableofcontents
|
||||||
|
|
||||||
|
@ -185,34 +179,52 @@ valid from its start IP to the start IP of the next row, or the end IP of the
|
||||||
FDE if it is the last row.
|
FDE if it is the last row.
|
||||||
|
|
||||||
\begin{minipage}{0.45\textwidth}
|
\begin{minipage}{0.45\textwidth}
|
||||||
\lstinputlisting[language=C, firstline=3, lastline=12]
|
\lstinputlisting[language=C, firstline=3, lastline=12,
|
||||||
|
caption={Original C},label={lst:ex1_c}]
|
||||||
{src/fib7/fib7.c}
|
{src/fib7/fib7.c}
|
||||||
\end{minipage} \hfill \begin{minipage}{0.45\textwidth}
|
\end{minipage} \hfill \begin{minipage}{0.45\textwidth}
|
||||||
\lstinputlisting[language=C]{src/fib7/fib7.fde}
|
\lstinputlisting[language=C,caption={Processed DWARF},label={lst:ex1_dw}]
|
||||||
|
{src/fib7/fib7.fde}
|
||||||
|
\lstinputlisting[language=C,caption={Raw DWARF},label={lst:ex1_dwraw}]
|
||||||
|
{src/fib7/fib7.raw_fde}
|
||||||
\end{minipage}
|
\end{minipage}
|
||||||
|
|
||||||
For instance, the C source code above, when compiled with \lstbash{gcc -O0
|
\begin{minipage}{0.45\textwidth}
|
||||||
-fomit-frame-pointer}, gives the table at its right. During the function
|
\lstinputlisting[language={[x86masm]Assembler},lastline=11,
|
||||||
prelude, \ie{} for $\mhex{675} \leq \reg{rip} < \mhex{679}$, the stack frame
|
caption={Generated assembly},label={lst:ex1_asm}]
|
||||||
only contains the return address, thus the CFA is 8 bytes above \reg{rsp}
|
{src/fib7/fib7.s}
|
||||||
(which was the value of \reg{rsp} before the call), and the return address is
|
\end{minipage} \hfill \begin{minipage}{0.45\textwidth}
|
||||||
precisely at \reg{rsp}. Then, 9 integers of 8 bytes each (8 for \lstc{fibo},
|
\lstinputlisting[language={[x86masm]Assembler},firstline=12,
|
||||||
one for \lstc{pos}) are allocated on the stack, which puts the CFA 80 bytes
|
firstnumber=last]
|
||||||
above \reg{rsp}, and the return address still 8 bytes below the CFA\@. Then, by
|
{src/fib7/fib7.s}
|
||||||
the end of the function, the local variables are discarded and \reg{rsp} is
|
\end{minipage}
|
||||||
reset to its value from the first row.
|
|
||||||
|
|
||||||
However, DWARF data isn't actually stored as a table in the binary files. The
|
For instance, the C source code in Listing~\ref{lst:ex1_c} above, when compiled
|
||||||
first row has the location of the first IP in the FDE, and must define at least
|
with \lstbash{gcc -O1 -fomit-frame-pointer -fno-stack-protector}, yields the
|
||||||
its CFA\@. Then, when all relevant registers are defined, it is possible to
|
assembly code in Listing~\ref{lst:ex1_asm}. When interpreting the generated
|
||||||
define a new row by providing a location offset (\eg{} here $4$), and the new
|
\ehframe{} with \lstbash{readelf -wF}, we obtain the (slightly edited)
|
||||||
row is defined as a clone of the previous one, which can then be altered (\eg{}
|
Listing~\ref{lst:ex1_dw}. During the function prelude, \ie{} for $\mhex{615}
|
||||||
here by setting \lstc{CFA} to $\reg{rsp} + 80$). This means that every line is
|
\leq \reg{rip} < \mhex{619}$, the stack frame only contains the return address,
|
||||||
defined \wrt{} the previous one, and that the IPs of the successive rows cannot
|
thus the CFA is 8 bytes above \reg{rsp} (which was the value of \reg{rsp}
|
||||||
be determined before evaluating every row before. Thus, unwinding a frame from
|
before the call), and the return address is precisely at \reg{rsp}. Then, 9
|
||||||
an IP close to the end of the frame will require evaluating pretty much every
|
integers of 8 bytes each (8 for \lstc{fibo}, one for \lstc{pos}) are allocated
|
||||||
DWARF row in the table before reaching the relevant information, slowing down
|
on the stack, which puts the CFA 80 bytes above \reg{rsp}, and the return
|
||||||
drastically the unwinding process.
|
address still 8 bytes below the CFA\@. Then, by the end of the function, the
|
||||||
|
local variables are discarded and \reg{rsp} is reset to its value from the
|
||||||
|
first row.
|
||||||
|
|
||||||
|
However, DWARF data isn't actually stored as a table in the binary files, but
|
||||||
|
is instead stored as in Listing~\ref{lst:ex1_dwraw}. The first row has the
|
||||||
|
location of the first IP in the FDE, and must define at least its CFA\@. Then,
|
||||||
|
when all relevant registers are defined, it is possible to define a new row by
|
||||||
|
providing a location offset (\eg{} here $4$), and the new row is defined as a
|
||||||
|
clone of the previous one, which can then be altered (\eg{} here by setting
|
||||||
|
\lstc{CFA} to $\reg{rsp} + 80$). This means that every line is defined \wrt{}
|
||||||
|
the previous one, and that the IPs of the successive rows cannot be determined
|
||||||
|
before evaluating every row before. Thus, unwinding a frame from an IP close to
|
||||||
|
the end of the frame will require evaluating pretty much every DWARF row in the
|
||||||
|
table before reaching the relevant information, slowing down drastically the
|
||||||
|
unwinding process.
|
||||||
|
|
||||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
\subsection{How big are FDEs?}
|
\subsection{How big are FDEs?}
|
||||||
|
@ -565,6 +577,7 @@ The major drawback of this approach, without any particular care taken, is the
|
||||||
space waste.
|
space waste.
|
||||||
|
|
||||||
\begin{table}[h]
|
\begin{table}[h]
|
||||||
|
\centering
|
||||||
\begin{tabular}{r r r r r r}
|
\begin{tabular}{r r r r r r}
|
||||||
\toprule
|
\toprule
|
||||||
\thead{Shared object} & \thead{Original \\ program size}
|
\thead{Shared object} & \thead{Original \\ program size}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
all: fib7.bin
|
all: fib7.bin
|
||||||
|
|
||||||
fib7.bin: fib7.c
|
fib7.bin: fib7.c
|
||||||
gcc -O1 $< -o $@
|
gcc -fomit-frame-pointer -fno-stack-protector -O1 $< -o $@
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
int fib7() {
|
void fib7() {
|
||||||
int fibo[8];
|
int fibo[8];
|
||||||
fibo[0] = 1;
|
fibo[0] = 1;
|
||||||
fibo[1] = 1;
|
fibo[1] = 1;
|
||||||
|
@ -8,10 +8,10 @@ int fib7() {
|
||||||
fibo[pos] =
|
fibo[pos] =
|
||||||
fibo[pos - 1]
|
fibo[pos - 1]
|
||||||
+ fibo[pos - 2];
|
+ fibo[pos - 2];
|
||||||
return fibo[7];
|
printf("%d\n", fibo[7]);
|
||||||
}
|
}
|
||||||
|
|
||||||
int main(void) {
|
int main(void) {
|
||||||
printf("%d\n", fib7());
|
fib7();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
[...] FDE [...] pc=675..6f3
|
[...] FDE [...] pc=615..65a
|
||||||
LOC CFA ra
|
LOC CFA ra
|
||||||
0000000000000675 rsp+8 c-8
|
0000000000000615 rsp+8 c-8
|
||||||
0000000000000679 rsp+80 c-8
|
0000000000000619 rsp+48 c-8
|
||||||
00000000000006f2 rsp+8 c-8
|
0000000000000659 rsp+8 c-8
|
||||||
|
|
7
report/src/fib7/fib7.raw_fde
Normal file
7
report/src/fib7/fib7.raw_fde
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
[...] FDE [...] pc=615..65a
|
||||||
|
DW_CFA_def_cfa: r7 (rsp) ofs 8
|
||||||
|
DW_CFA_offset: r16 (rip) at cfa-8
|
||||||
|
DW_CFA_advance_loc: 4 to 0619
|
||||||
|
DW_CFA_def_cfa_offset: 48
|
||||||
|
DW_CFA_advance_loc1: 64 to 0659
|
||||||
|
DW_CFA_def_cfa_offset: 8
|
21
report/src/fib7/fib7.s
Normal file
21
report/src/fib7/fib7.s
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
0000000000000615 <fib7>:
|
||||||
|
615: sub $0x28,%rsp ; Alloc stack
|
||||||
|
619: movl $0x1,(%rsp) ; fibo[0]
|
||||||
|
620: movl $0x1,0x4(%rsp) ; fibo[1]
|
||||||
|
627:
|
||||||
|
; Begin for loop
|
||||||
|
628: mov %rsp,%rax
|
||||||
|
62b: lea 0x18(%rax),%rcx
|
||||||
|
62f: mov (%rax),%edx
|
||||||
|
631: add 0x4(%rax),%edx
|
||||||
|
634: mov %edx,0x8(%rax)
|
||||||
|
637: add $0x4,%rax
|
||||||
|
63b: cmp %rcx,%rax
|
||||||
|
63e: jne 62f <fib7+0x1a>
|
||||||
|
; End for loop
|
||||||
|
640: mov 0x1c(%rsp),%esi
|
||||||
|
644: lea 0xb9(%rip),%rdi
|
||||||
|
64b: mov $0x0,%eax
|
||||||
|
650: callq 520 <printf@plt>
|
||||||
|
655: add $0x28,%rsp ; Restore rsp
|
||||||
|
659: retq
|
Loading…
Reference in a new issue