Почему UPX ломает скомпилированные приложения SBCL?

Это в основном глупый вопрос, поскольку UPX (инструмент, который извлекает лишние байты из ваших исполняемых файлов) экономит крошечное пространство по сравнению со встроенным сжатием в инструменте buildapp.

Очень маленькое демо-приложение создает файл размером 42 мегабайта. Понятно, так как среда SBCL не крошечная.

Проходя --compress-core возможность buildapp сжимает это до 9.2MB.

Я подумал, что попробую добавить UPX к полученному двоичному файлу, и экономия составит всего несколько байт: 9994288 -> 9871360

Однако полученный файл больше не запускается - он просто переходит в SBCL REPL (без ошибок, как будто я только что запустил sbcl от руки), и некоторые осмотры показывают, что функций, составляющих мою тестовую программу, больше не существует.

Что UPX сделал с двоичным файлом, который привел к этой поломке?

1 ответ

Это не может быть ответом, но может служить подсказкой: я обнаружил, что если вы добавите что-либо, даже один байт, в конец исполняемого файла SBCL, созданного с помощью sb-ext:save-lisp-and-die, тогда все определения исчезнут, как вы и описали.

Возможно, SBCL создает исполняемые файлы, добавляя ядро ​​(которое содержит ваши определения) к копии двоичного файла SBCL ELF (или PE в Windows), а также некоторые метаданные в конце, чтобы SBCL все еще мог найти начало ядра, даже если оно добавлено. в исполняемый файл.

Если вы редактируете исполняемый файл, созданный с save-lisp-and-dieвы обнаружите, что он заканчивается строкой "LCBS" (SBCL в обратном направлении), которая, кажется, поддерживает мою теорию. "LCBS", вероятно, служит магическим числом, давая SBCL знать, что да, этот исполняемый файл содержит собственное ядро.

UPX сжимает исполняемые файлы, возможно, включая это магическое число в конце. Когда SBCL открывает свое сжатие UPX на диске, в конце он не находит "LCBS", поэтому он предполагает, что к исполняемому файлу не добавлено ядро.

Я не могу объяснить, почему стандартная библиотека, кажется, все еще там, если это так. Может быть, SBCL загружает /usr/lib/sbcl/sbcl.core (или его эквивалент в Windows) в этом случае. Это можно проверить, переместив исполняемый файл на компьютер, на котором SBCL не установлен, и посмотрев, работает ли он вообще, и если да, то есть ли у вас car, cdr, list, так далее.

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