EnglishРусский Map

Win32 - единственный стабильный ABI в Linux

title
Win32 - единственный стабильный ABI в Linux
type
summary
summary
Glibc 2.36 сломала игры в Linux, убрав DT_HASH; Win32 через Wine остаётся единственным стабильным ABI в Linux
tags
linux, abi, elf, wine, glibc
created
2026-04-08
updated
2026-07-29
lang
ru
translation_of
win32-stable-abi
source_updated
2026-07-29
translated
2026-09-01
translator
lllm/antigravity/gemini-3.7-flash-high

В августе 2022 года в glibc 2.36 вышло изменение, сломавшее игры с модулем EOS от Easy Anti-Cheat под Linux. Причина: glibc перестала генерировать секции DT_HASH в своих динамических библиотеках, оставив только более новую DT_GNU_HASH. Программы, которые обходили старую хеш-таблицу для подсчёта символов - вполне разумное решение, поскольку DT_HASH входит в SYSV generic ABI, - начали падать.

Поломка не ограничилась античитом. Проблемы возникли и у libstrangle (ограничителя кадров с открытым исходным кодом), и у Shovel Knight. Ожидалось, что с переходом дистрибутивов на новую glibc сбоев станет ещё больше.

Две хеш-таблицы

Бинарные файлы ELF могут содержать два типа хеш-таблиц символов. DT_HASH определена в SYSV generic ABI и задокументирована: у неё фиксированная структура, а количество символов можно прочитать напрямую из заголовка. DT_GNU_HASH - изобретение glibc/GNU: поиск быстрее, таблицы компактнее, но формат не задокументирован и лишён части возможностей. Чтобы узнать число символов из DT_GNU_HASH, приходится парсить всю таблицу целиком.

Годами glibc генерировала обе. В релизе 2.36 секцию DT_HASH убрали из собственных библиотек glibc. Обоснование: glibc помечает себя как ELFOSABI_GNU, поэтому формально не обязана следовать требованию generic ABI о наличии DT_HASH. Экономия составила около 16 КБ на библиотеку - меньше 1% от общего размера.

Почему дистрибутивы только усугубили ситуацию

Большинство дистрибутивов Linux собирали GCC с флагом --with-linker-hash-style=gnu, который указывает компоновщику генерировать только DT_GNU_HASH. Это осталось ещё с тех времён, когда хеш-таблица GNU только появилась, а компоновщик по умолчанию создавал только sysv. Дистрибутивы включили этот флаг ради прироста производительности и так и не вернули всё обратно. Сам GNU ld по умолчанию использует --hash-style=both (генерируя обе таблицы), а mold - --hash-style=sysv. Но флаг GCC в дистрибутивах переопределяет настройку компоновщика по умолчанию, поэтому на практике большинство бинарников в Linux содержат только DT_GNU_HASH.

Clang через определение дистрибутива копирует поведение локального GCC, распространяя этот выбор ещё дальше.

Правило ядра, которое glibc игнорирует

У Линуса Торвальдса есть постоянное правило для ядра Linux: менять ABI можно до тех пор, пока никто этого не заметил, но как только обнаруживается поломка, изменение считается регрессией и откатывается. Ядро считает видимое пользователю поведение контрактом стабильности независимо от того, что написано в спецификации.

В glibc подход другой. Мейнтейнеры glibc заявили, что DT_HASH никогда не была частью их ABI, информация по-прежнему доступна в другом формате, а дистрибутивам следует решать проблему самостоятельно. Поломку реального софта посчитали виной самих программ, которые полагались на незадокументированную структуру.

Итог

Вывод автора: Win32 через Wine - единственный стабильный ABI в Linux. Wine стремится не ломать приложения для Windows. Ядро Linux гарантирует сохранность userspace. Но glibc - прослойка между ними - таких обещаний не даёт, а ведь именно на этом уровне разработчикам игр стабильность нужнее всего. Выпуск игры под Windows с расчётом на Wine в Linux даёт разработчикам более надёжный контракт, чем сборка нативных бинарников под Linux.

См. также win32-weird-shaped-windows как пример стабильности модели программирования Win32: те же API для регионов из Windows 95 сегодня работают точно так же.

radv-win32-port - зеркальная ситуация. В Windows задокументированный интерфейс WDDM2 достаточно стабилен, чтобы поверх него можно было написать сторонний драйвер Vulkan, но находящиеся под ним закрытые blob'ы драйверов поставляются согласованной парой UMD/KMD без каких-либо гарантий обратной совместимости, поэтому внешнему драйверу не на что надёжно опереться. starling-desktop показывает, как выглядит выбор стороны Linux: полугодовалое десктопное окружение, заявленный тест которого - запуск чужих бинарников (Chrome на Wayland, Zoom на X11), ни один из которых о нём даже не слышал.