\begin{frame}
\frametitle{Библиотеки}
\begin{itemize}
    \item<1->Виды библиотек:
    \begin{itemize}
        \item<2->статические - становятся частью исполняемого файла;
        \item<3->динамические - хранятся отдельно от исполняемого файла
        \begin{itemize}
            \item<4->загружаются при запуске приложения или по требованию.
        \end{itemize}
    \end{itemize}
\end{itemize}
\end{frame}

\begin{frame}
\frametitle{Динамические библиотеки}
\begin{itemize}
    \item<1->Особенность динамических библиотек - могут быть загружены
         по разным адресам
    \begin{itemize}
        \item<2->как код библиотеки обращается к своим коду и данным?
        \item<3->как код приложения обращается к библиотеке?
        \item<4->как код библиотек обращается к коду и данным других библиотек?
    \end{itemize}
\end{itemize}
\end{frame}

\begin{frame}
\frametitle{Компоновщик}
\begin{itemize}
    \item<1->Компоновщик (linker, link editor) - программа, которая "связывает"
         бинарные файлы вместе и генерирует исполняемый файл
    \begin{itemize}
        \item<2->в момент компиляции адреса функций/переменных могут быть не
             известны;
        \item<3->компилятор просто оставляет "пустое место", а компоновщик
             записывает в него адрес.
    \end{itemize}
\end{itemize}
\end{frame}

\begin{frame}
\frametitle{Динамический компоновщик}
\begin{itemize}
    \item<1->Адреса функций/переменных из динамических библиотек не известны
    \begin{itemize}
        \item<2->компилятор/статический компоновщик оставляют "пустые места";
        \item<3->динамический компоновщик должен записать в них адреса,
             после того как библиотека была загружена.
    \end{itemize}
\end{itemize}
\end{frame}

\begin{frame}
\frametitle{Загрузка ELF файла с динамическими библиотеками}
\begin{itemize}
    \item<1->ELF файл загружается как обычно
    \begin{itemize}
        \item<2->ищем Program Header-ы с типом PT\_LOAD и
             загружаем их в память.
    \end{itemize}
    \item<3->Смотрим в Program Header с типом PT\_INTERP
    \begin{itemize}
        \item<4->там хранится имя файла динамического компоновщика;
        \item<5->загружаем его в память в дополнение к программе.
    \end{itemize}
    \item<6->Передаем управление \emph{динамическому компоновщику}.
\end{itemize}
\end{frame}

\begin{frame}
\frametitle{Поиск динамических библиотек}
\begin{itemize}
    \item<1->Исполняемый файл должен хранить информацию о динамических
         библиотеках
    \begin{itemize}
        \item<2->например, ELF Program Header с типом PT\_DYNAMIC указывает,
             где в файле хранится эта информация;
        \item<3->динамический компоновщик загружает \emph{все} требуемые
             зависимости в память.
    \end{itemize}
\end{itemize}
\end{frame}

\begin{frame}
\frametitle{Редактирование связей}
\begin{itemize}
    \item<1->Исполняемый файл и динамические библиотеки хранят список обращений
         к внешним сущностям
    \begin{itemize}
        \item<2->вызовы функций из других (и не только) библиотек;
        \item<3->обращения к переменным (и не только) из других библиотек;
        \item<4->динамический компоновщик находит адреса и записывает их в
             определенные места в памяти.
    \end{itemize}
\end{itemize}
\end{frame}

\begin{frame}
\frametitle{GOT}
\begin{itemize}
    \item<1->ELF формат использует Global Offset Table (GOT)
    \begin{itemize}
        \item<2->код, обращающийся к переменной, знает относительный адрес GOT
             и номер записи в ней, соответствующей этой переменной;
        \item<3->компилятор генерирует код, который берет адрес из GOT;
        \item<4->динамический компоновщик записывает в GOT правильные адреса
             при загрузке.
    \end{itemize}
\end{itemize}
\end{frame}

\begin{frame}
\frametitle{PLT}
\begin{itemize}
    \item<1->ELF формат также использует Procedure Linkage Table (PLT)
    \begin{itemize}
        \item<2->код обращающийся к функции знает относительный адрес PLT
             и номер "заглушки" в ней, соответствующей этой переменной;
        \item<3->компилятор генерирует код, который вызывает "заглушку" из PLT
             вместо реальной функции;
        \item<4->динамический компоновщик может изменять PLT, а может изменять
             GOT, к которой "заглушка" из PLT обращается.
    \end{itemize}
\end{itemize}
\end{frame}
