У програмуванні завантажувач () — це частина операційної системи, відповідальна за завантаження програм і бібліотек. Це один із найважливіших етапів процесу запуску програми, оскільки він розміщує програми в пам'яті та готує їх до виконання. Завантаження програми передбачає або відображення файла в пам'ять, або копіювання вмісту виконуваного файлу, що містить інструкції програми, у пам'ять, після чого виконуються інші необхідні підготовчі завдання для підготовки виконуваного файлу до запуску. Після завершення завантаження операційна система запускає програму, передаючи керування завантаженому коду програми.

Усі операційні системи, що підтримують завантаження програм, мають завантажувачі, за винятком вузькоспеціалізованих комп'ютерних систем, які мають лише фіксований набір спеціалізованих програм. Вбудовані системи зазвичай не мають завантажувачів, натомість код виконується безпосередньо з ROM або подібного носія. Під час завантаження операційної системи використовується спеціалізований початковий завантажувач. У багатьох операційних системах завантажувач постійно перебуває в пам'яті, хоча деякі операційні системи, що підтримують віртуальну пам'ять, можуть дозволяти розміщувати завантажувач в сторінках пам'яті, які можуть бути вивантажені.

У випадку операційних систем, що підтримують віртуальну пам'ять, завантажувач може фактично не копіювати вміст виконуваних файлів у пам'ять, а натомість лише повідомляти підсистемі віртуальної пам'яті, що існує відображення між областю пам'яті, виділеною для розміщення коду запущеної програми, та вмістом відповідного виконуваного файлу. (Див. Відображення файла в пам'ять.) Після цього підсистема віртуальної пам'яті отримує інформацію про те, що сторінки цієї області пам'яті потрібно заповнювати за потреби, якщо і коли виконання програми фактично досягне цих областей незаповненої пам'яті. Це може означати, що частини коду програми фактично не копіюються в пам'ять доти, доки вони не будуть використані, а невикористовуваний код може взагалі ніколи не завантажуватися в пам'ять.

Обов'язки У Unix та Unix-подібних системах завантажувач є обробником системного виклику execve(). Завдання завантажувача Unix включають: перевірку (дозволи, вимоги до пам'яті тощо); відображення файла із диска в оперативну пам'ять; копіювання аргументів командного рядка у віртуальну пам'ять; ініціалізацію регістрів (наприклад, вказівника стека); перехід до точки входу програми (_start).

У Windows 7 та новіших версіях завантажувачем є функція LdrInitializeThunk, що міститься в ntdll.dll і виконує такі дії: ініціалізація структур у самій DLL (тобто критичних секцій, списків модулів); перевірка виконуваного файлу, який потрібно завантажити; створення купи (за допомогою функції RtlCreateHeap); виділення блоку змінних середовища та блоку PATH; додавання виконуваного файлу та NTDLL до списку модулів (двозв'язного списку); завантаження KERNEL32.DLL для отримання кількох важливих функцій, наприклад BaseThreadInitThunk; рекурсивне завантаження імпортів виконуваного файлу (тобто динамічно компонованих бібліотек) (перевірка імпортів імпортованих бібліотек, їхніх імпортів і так далі); у режимі налагодження — виклик системної точки зупину; ініціалізація DLL; збирання сміття; виклик NtContinue з параметром контексту, переданим функції завантажувача (тобто перехід до RtlUserThreadStart, яка запустить виконуваний файл).

Завантажувачі з переміщенням Деякі операційні системи потребують переміщувальних завантажувачів, які коригують адреси (вказівники) у виконуваному файлі, щоб компенсувати відмінності в адресі, з якої починається завантаження. Операційні системи, які потребують переміщувальних завантажувачів, — це ті, у яких програма не завжди завантажується в одне й те саме місце у (віртуальному) адресному просторі, а вказівники є абсолютними адресами, а не зміщеннями від базової адреси програми. Деякими добре відомими прикладами є OS/360 компанії IBM для мейнфреймів System/360 та її наступники, зокрема z/OS для мейнфреймів z/Architecture.

Динамічні компонувальники Завантажувачі динамічного компонування є іншим типом завантажувачів, які завантажують і компонують спільні бібліотеки (такі як файли .so, файли .dll або файли .dylib) із уже завантаженими запущеними програмами.

Якщо такі спільні бібліотеки можуть спільно використовуватися кількома процесами, причому лише одна копія спільного коду може перебувати за різними (віртуальними) адресами в адресному просторі кожного процесу, код у спільній бібліотеці має бути переміщуваним, тобто бібліотека повинна використовувати лише внутрішні адреси, відносні до самої себе або до бази сегмента коду. Деякі процесори мають інструкції, які можуть використовувати самовідносні посилання на код для полегшення цього.

Див. також Видалення мертвого коду Декорація імен Динамічний лінкер Переміщуваність (інформатика) Статична бібліотека Сумісність за помилками Dynamic-link library DLL hell

Примітки