Michael Matz committed Nov 18, 2015 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 \chapter{Linker Optimization} This chapter describes optimizations which may be performed by linker. \section{Combine GOTPLT and GOT Slots} In the small and medium models, when there are both PLT and GOT references to the same function symbol, normally linker creates a GOTPLT slot for PLT entry and a GOT slot for GOT reference. A run-time JUMP_SLOT relocation is created to update the GOTPLT slot and a run-time GLOB_DAT relocation is created to update the GOT slot. Both JUMP_SLOT and GLOB_DAT relocations apply the same symbol value to GOTPLT and GOT slots, respectively, at run-time. As an optimization, linker may combine GOTPLT and GOT slots into a single GOT slot and remove the run-time JUMP_SLOT relocation. It replaces the regular PLT entry: \begin{figure}[H] \Hrule \caption{Procedure Linkage Table Entry Via GOTPLT Slot} \label{gotplt_plt} \begin{footnotesize} \begin{verbatim} .PLT: jmp [GOTPLT slot] pushq relocation index jmp .PLT0 \end{verbatim} \end{footnotesize} \Hrule \end{figure} \noindent with an GOT PLT entry with an indirect jump via the GOT slot: \indent \begin{figure}[H] \Hrule \caption{Procedure Linkage Table Entry Via GOT Slot} \label{got_plt} \begin{footnotesize} \begin{verbatim} .PLT: jmp [GOT slot] nop \end{verbatim} \end{footnotesize} \Hrule \end{figure} \noindent and resolves the PLT reference to the GOT PLT entry. Indirect \code{jmp} is an 5-byte instruction. \code{nop} can be encoded as a 3-byte instruction or a 11-byte instruction for 8-byte or 16-byte PLT slot. A separate PLT with 8-byte slots may be used for this optimization. \indent This optimization isn't applicable to the \texttt{STT_GNU_IFUNC} symbols since their GOTPLT slots are resolved to the selected implementation and their GOT slots are resolved to their PLT entries. This optimization must be avoided if pointer equality is needed since the symbol value won't be cleared in this case and the dynamic linker won't update the GOT slot. Otherwise, the resulting binary will get into an infinite loop at run-time. Michael Matz committed Nov 18, 2015 64 65 66 67 68 69 70 71 72 73 74 \section{Optimize GOTPCRELX Relocations} \label{opt_gotpcrelx} The \xARCH instruction encoding supports converting certain instructions on memory operand with \texttt{R_X86_64_GOTPCRELX} or \texttt{R_X86_64_REX_GOTPCRELX} relocations against symbol, \texttt{foo}, into a different form on immediate operand if \texttt{foo} is defined locally. \begin{description} Michael Matz committed Jan 29, 2018 75 76 \item[\textindex{Convert call and jmp}] Convert memory operand of \code{call} and \code{jmp} into Michael Matz committed Nov 18, 2015 77 78 79 80 immediate operand. \begin{table}[H] \Hrule Michael Matz committed Jan 29, 2018 81 \caption{Call and Jmp Conversion} Michael Matz committed Nov 18, 2015 82 83 84 85 86 87 88 89 \begin{center} \small\code{ \begin{tabular}{l|l} \multicolumn{1}{c}{Memory Operand} & \multicolumn{1}{c}{Immediate Operand} \\ \hline call *[email protected](\%rip) & nop call foo \\ call *[email protected](\%rip) & call foo nop \\ jmp *[email protected](\%rip) & jmp foo nop \\ Michael Matz committed Jan 29, 2018 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 \end{tabular} } \end{center} \Hrule \end{table} \item[\textindex{Convert mov}] Convert memory operand of \code{mov} into immediate operand. When position-independent code is disabled and \texttt{foo} is defined locally in the lower 32-bit address space, memory operand in \code{mov} can be converted into immediate operand. Otherwise, \code{mov} must be changed to \code{lea}. \begin{table}[H] \Hrule \caption{Mov Conversion} \begin{center} \small\code{ \begin{tabular}{l|l} \multicolumn{1}{c}{Memory Operand} & \multicolumn{1}{c}{Immediate Operand} \\ \hline mov [email protected](\%rip), \%reg & mov \$foo, \%reg \\ Michael Matz committed Nov 18, 2015 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 mov [email protected](\%rip), \%reg & lea foo(\%rip), \%reg \\ \end{tabular} } \end{center} \Hrule \end{table} \item[\textindex{Convert Test and Binop}] Convert memory operand of \code{test} and \code{binop} into immediate operand, where \code{binop} is one of \code{adc}, \code{add}, \code{and}, \code{cmp}, \code{or}, \code{sbb}, \code{sub}, \code{xor} instructions, when position-independent code is disabled. \begin{table}[H] \Hrule \caption{Test and Binop Conversion} \begin{center} \small\code{ \begin{tabular}{l|l} \multicolumn{1}{c}{Memory Operand} & \multicolumn{1}{c}{Immediate Operand} \\ \hline test \%reg, [email protected](\%rip) & test \$foo, \%reg \\ binop [email protected](\%rip), \%reg & binop \\$foo, \%reg \\ \end{tabular} } \end{center} \Hrule \end{table} \end{description}