Откажитесь от неиспользованных символов от dlopen()'ed .so

У меня есть набор общих библиотек (Intel MKL), которые распространяются только в двоичном виде. Библиотека верхнего уровня "runtime", libmkl_rt.so, ссылки на мой исполняемый файл и виден с ldd:

...
libmkl_rt.so => /var/task/lib/libmkl_rt.so (0x00007f8049a1f000)
...

Тем не менее, другие, такие как libmkl_avx.soЯ полагаю, загружаются динамически dlopen(), поскольку исполняемый файл выдает ошибку о том, что библиотеки отсутствуют, если не найдены, но не видны с ldd,

Эти библиотеки большие (> 100 МБ), и это единственный исполняемый файл в моем контейнере, использующий их. Я предполагаю, что исполняемый файл не вызывает каждую из функций в этих библиотеках, поэтому я хотел бы уменьшить их, сначала определив, какие функции вызываются, а затем только сохраняя их.

Как я могу:

  1. Определите, какие символы в динамически загружаемых общих библиотеках фактически используются?
  2. Извлечь только эти символы в "тонкую" копию библиотеки?

Есть ли инструменты для этого?

1 ответ

Решение

Определите, какие символы в динамически загружаемых общих библиотеках фактически используются?

Вы можете запустить свою программу под LD_DEBUG=bindings LD_BIND_NOW=1 и посмотреть, какие символы из libmkl_avx.so были связаны.

Извлечь только эти символы в "тонкую" копию библиотеки?

К сожалению, это невозможно по тем же причинам, по которым вы не можете переставлять функции в исполняемых файлах. Как только код связан, все внутренние goto и глобальные переменные расположены фиксированно и не могут быть изменены. Даже правильная разборка связанного кода (для определения границ функций и графа вызовов) является неразрешимой проблемой (такие инструменты, как IDA, используют эвристику для ее облегчения, но проблема остается).

Это не должно быть большой проблемой, потому что ОС будет загружать только те кодовые страницы, которые фактически используются вашим приложением.

Другие вопросы по тегам