diff options
author | somov <somov@yandex-team.ru> | 2022-02-10 16:45:47 +0300 |
---|---|---|
committer | Daniil Cherednik <dcherednik@yandex-team.ru> | 2022-02-10 16:45:47 +0300 |
commit | a5950576e397b1909261050b8c7da16db58f10b1 (patch) | |
tree | 7ba7677f6a4c3e19e2cefab34d16df2c8963b4d4 /contrib/libs/libc_compat/ubuntu_14/README.md | |
parent | 81eddc8c0b55990194e112b02d127b87d54164a9 (diff) | |
download | ydb-a5950576e397b1909261050b8c7da16db58f10b1.tar.gz |
Restoring authorship annotation for <somov@yandex-team.ru>. Commit 1 of 2.
Diffstat (limited to 'contrib/libs/libc_compat/ubuntu_14/README.md')
-rw-r--r-- | contrib/libs/libc_compat/ubuntu_14/README.md | 182 |
1 files changed, 91 insertions, 91 deletions
diff --git a/contrib/libs/libc_compat/ubuntu_14/README.md b/contrib/libs/libc_compat/ubuntu_14/README.md index f7b17a40cc..63dd8a22d9 100644 --- a/contrib/libs/libc_compat/ubuntu_14/README.md +++ b/contrib/libs/libc_compat/ubuntu_14/README.md @@ -1,91 +1,91 @@ -## Общие соображения - -В библиотеку добавлены реализации символов, появившихся в `libc.so.6` Ubuntu -14.04 с момента Ubuntu 12.04. - -Если какой-либо объектный файл ссылается на один из таких символов, то при -компоновке этот символ будет взят из нашей библиотеки. В противном случае, -компоновщик сослался бы на такой символ из `libc.so.6`, добавив к исполняемому -файлу зависимость от новой версии динамической библиотеки (`GLIBC_2.16`, -`GLIBC_2.17` или `GLIBC_2.18`). Такой исполняемый файл не может быть запущен на -Ubuntu 12.04, даже если ни один из новых символов не используется в runtime. - -На Ubuntu 14.04 или более новых, в случае если процесс загружает `libc.so.6`, мы -будем в runtime иметь две реализации символов, нашу и libc. Но все добавленные -функции не имеют какого-либо состояния и никакими деталями внутренней реализации -не связаны с другими. Нет разницы, какую из реализаций использовать, и даже -попеременное использование различных реализаций в одном и том же контексте не -должно приводить к некорректной работе. - -В какой-то момент этот слой совместимости будет отключен: https://st.yandex-team.ru/DEVTOOLS-7436 - -### Разделяемая реализация - -Была идея оформить новые реализации так, чтобы в случае их наличия и в -загруженной libc динамический компоновщик выбирал для всех ссылок одну -реализацию. - -По всей видимости, для этого требуется собирать исполняемый файл как PIE. Только -в этом случае для наших реализаций будут сгенерированы дополнительные PLT -прослойки и вызовы наших реализаций будут проходить через них. - -Но в этом случае вообще все вызовы будут происходить таким образом и это -повлияет на производительность. Ухудшения производительности, наверное, можно -избежать, явно указав, какие символы в исполняемом файле должны быть публичными, -но сейчас нет способа сделать это в одном месте, учитывая, что в некоторых -случаях этот список должен дополняться. - -## `getauxval` и `secure_getenv` - -Функция `getauxval` требует загрузки и хранения «Auxiliary Vector» (см. -[здесь](https://refspecs.linuxfoundation.org/LSB_1.3.0/IA64/spec/auxiliaryvector.html)). - -Эти данные доступны в момент запуска процесса. libc из новых Ubuntu сохраняет -эти данные и предоставляет реализацию `getauxval`. В этом случае наша реализация -перенаправляет вызовы `getauxval` в libc, получив при старте исполняемого файла -соответствующий указатель. - -Если реализация libc недоступна (на старых Ubuntu или если libc не загружена), -то эти данные можно получить, прочитав `/proc/self/auxv`. Это также делается -один раз при старте. - -В обоих случаях, статически инициализируется синглтон `NUbuntuCompat::TGlibc`, -который производит эти действия в конструкторе. - -`secure_getenv` использует одно из значений `getauxval`, поэтому к нему всё это -также относится. - -Каждый метод новой libc реализован в отдельном объектом файле. `TGlibc` также -находится в отдельном файле, и ссылки на неё стоят только в местах использования. -Если при компоновке не понадобились ни `getauxval`, ни `secure_getenv`, то -объектный файл с `TGlibc` тоже не будет выбран компоновщиком, и в этом случае -никакой лишней статической инициализации выполняться не будет. - -## Патч libc.so - -Чтобы иметь возможность использовать `getauxval` (точнее его реализацию -`__getauxval`) из новой libc, если таковая уже используется процессом, -библиотека совместимости объявляет этот символ у себя как внешний и слабый. При -загрузке динамический компоновщик устанавливает значение этого символа из libc -или `nullptr`, если его там нет. Наша реализация `getauxval` проверяет -доступность реализации libc, просто сравнивая указатель с `nullptr`. - -В Аркадии также есть код, который подобным образом работает с символом -`__cxa_thread_atexit_impl`. - -Однако, если компоновать такую программу с использованием новой libc, то к таким -символам и самой программе будет приписано требование соответствующей (новой) -версии libc. Чтобы этого не произошло, при сборке с этой библиотекой -совместимости используется патченный вариант `libc.so.6`, где у таких символов -удалена версия. - -Также, файлы, проверяющие, что доступна реализация из libc, должны быть собраны -как PIC. В противном случае вместо значения, заполненного динамическим -компоновщиком, компилятор ещё на стадии компиляции использует `nullptr` и -проверка никогда не срабатывает. - -## Упоминания - -Идея о возможности добавить слой совместимости была взята из ClickHouse. -* [https://clickhouse.tech/](https://clickhouse.tech/) -* [https://wiki.yandex-team.ru/clickhouse/](https://wiki.yandex-team.ru/clickhouse/) +## Общие соображения + +В библиотеку добавлены реализации символов, появившихся в `libc.so.6` Ubuntu +14.04 с момента Ubuntu 12.04. + +Если какой-либо объектный файл ссылается на один из таких символов, то при +компоновке этот символ будет взят из нашей библиотеки. В противном случае, +компоновщик сослался бы на такой символ из `libc.so.6`, добавив к исполняемому +файлу зависимость от новой версии динамической библиотеки (`GLIBC_2.16`, +`GLIBC_2.17` или `GLIBC_2.18`). Такой исполняемый файл не может быть запущен на +Ubuntu 12.04, даже если ни один из новых символов не используется в runtime. + +На Ubuntu 14.04 или более новых, в случае если процесс загружает `libc.so.6`, мы +будем в runtime иметь две реализации символов, нашу и libc. Но все добавленные +функции не имеют какого-либо состояния и никакими деталями внутренней реализации +не связаны с другими. Нет разницы, какую из реализаций использовать, и даже +попеременное использование различных реализаций в одном и том же контексте не +должно приводить к некорректной работе. + +В какой-то момент этот слой совместимости будет отключен: https://st.yandex-team.ru/DEVTOOLS-7436 + +### Разделяемая реализация + +Была идея оформить новые реализации так, чтобы в случае их наличия и в +загруженной libc динамический компоновщик выбирал для всех ссылок одну +реализацию. + +По всей видимости, для этого требуется собирать исполняемый файл как PIE. Только +в этом случае для наших реализаций будут сгенерированы дополнительные PLT +прослойки и вызовы наших реализаций будут проходить через них. + +Но в этом случае вообще все вызовы будут происходить таким образом и это +повлияет на производительность. Ухудшения производительности, наверное, можно +избежать, явно указав, какие символы в исполняемом файле должны быть публичными, +но сейчас нет способа сделать это в одном месте, учитывая, что в некоторых +случаях этот список должен дополняться. + +## `getauxval` и `secure_getenv` + +Функция `getauxval` требует загрузки и хранения «Auxiliary Vector» (см. +[здесь](https://refspecs.linuxfoundation.org/LSB_1.3.0/IA64/spec/auxiliaryvector.html)). + +Эти данные доступны в момент запуска процесса. libc из новых Ubuntu сохраняет +эти данные и предоставляет реализацию `getauxval`. В этом случае наша реализация +перенаправляет вызовы `getauxval` в libc, получив при старте исполняемого файла +соответствующий указатель. + +Если реализация libc недоступна (на старых Ubuntu или если libc не загружена), +то эти данные можно получить, прочитав `/proc/self/auxv`. Это также делается +один раз при старте. + +В обоих случаях, статически инициализируется синглтон `NUbuntuCompat::TGlibc`, +который производит эти действия в конструкторе. + +`secure_getenv` использует одно из значений `getauxval`, поэтому к нему всё это +также относится. + +Каждый метод новой libc реализован в отдельном объектом файле. `TGlibc` также +находится в отдельном файле, и ссылки на неё стоят только в местах использования. +Если при компоновке не понадобились ни `getauxval`, ни `secure_getenv`, то +объектный файл с `TGlibc` тоже не будет выбран компоновщиком, и в этом случае +никакой лишней статической инициализации выполняться не будет. + +## Патч libc.so + +Чтобы иметь возможность использовать `getauxval` (точнее его реализацию +`__getauxval`) из новой libc, если таковая уже используется процессом, +библиотека совместимости объявляет этот символ у себя как внешний и слабый. При +загрузке динамический компоновщик устанавливает значение этого символа из libc +или `nullptr`, если его там нет. Наша реализация `getauxval` проверяет +доступность реализации libc, просто сравнивая указатель с `nullptr`. + +В Аркадии также есть код, который подобным образом работает с символом +`__cxa_thread_atexit_impl`. + +Однако, если компоновать такую программу с использованием новой libc, то к таким +символам и самой программе будет приписано требование соответствующей (новой) +версии libc. Чтобы этого не произошло, при сборке с этой библиотекой +совместимости используется патченный вариант `libc.so.6`, где у таких символов +удалена версия. + +Также, файлы, проверяющие, что доступна реализация из libc, должны быть собраны +как PIC. В противном случае вместо значения, заполненного динамическим +компоновщиком, компилятор ещё на стадии компиляции использует `nullptr` и +проверка никогда не срабатывает. + +## Упоминания + +Идея о возможности добавить слой совместимости была взята из ClickHouse. +* [https://clickhouse.tech/](https://clickhouse.tech/) +* [https://wiki.yandex-team.ru/clickhouse/](https://wiki.yandex-team.ru/clickhouse/) |