Процесс уменьшения размера исполняемого файла
Я создаю шестнадцатеричный файл для работы 9X_arm на процессоре ARM, размер которого не должен 9X_embedded-control превышать 32 КБ. В настоящее время он намного 9X_arm больше, и я подумал, может ли кто-нибудь 9X_embedded дать совет о том, как лучше всего его уменьшить?
Вот 9X_embedded-control что я уже сделал
- Я проверил размер, чтобы определить размер шестнадцатеричного файла.
- Затем снова "size", чтобы увидеть, насколько велик каждый из объектных файлов, которые используются для создания шестнадцатеричных файлов. Похоже, что большая часть размера поступает из внешних библиотек.
- Затем я использовал readelf, чтобы увидеть, какие функции занимают больше всего памяти.
- Я просмотрел код, чтобы узнать, могу ли я исключить вызовы этих функций.
Вот где я застрял, есть 9X_embedded-systems некоторые функции, которые я не вызываю 9X_embedded-control напрямую (например, _vfprintf), и я не могу 9X_embedded-control найти, что вызывает это, поэтому я могу 9X_arm удалить вызов (поскольку я думаю, что он 9X_arm мне не нужен).
Итак, что делать дальше?
Ответ 9X_embedded-control на ответы:
- Как я вижу, вызываются функции, которые занимают много памяти. Однако я не могу найти, что это вызывает.
- Я хочу опустить эти функции (если возможно), но не могу найти, что их вызывает! Я полагаю, может быть вызван из любого количества библиотечных функций.
- Компоновщик работает должным образом, я думаю, он включает только соответствующие файлы библиотеки. Как узнать, включены ли только соответствующие функции? Вы можете установить для этого флаг или что-то в этом роде?
- Я использую GCC
- возможно, вы уже знаете это, может быть, это поможет: http://www.muppetlabs.com/~breadbox/software/tiny/teensy.html< ...
Ответ #1
Ответ на вопрос: Процесс уменьшения размера исполняемого файла
Общий список:
- Убедитесь, что параметры отладки компилятора и компоновщика отключены.
- Скомпилировать и связать со всеми включенными параметрами размера (-Os в gcc)
- Запустите
strip
для исполняемого файла - Создайте файл карты и проверьте размеры ваших функций. Вы можете либо заставить свой компоновщик сгенерировать ваш файл карты (
-M
при использовании ld), либо вы можете использовать objdump в конечном исполняемом файле (обратите внимание, что это будет работать только с незарезанным исполняемым файлом!) Это фактически не решит проблему , но он позволит вам узнать о самых серьезных нарушителях. - Используйте
nm
, чтобы исследовать символы, вызываемые из каждого из ваших объектных файлов. Это должно помочь определить, кто вызывает функции, которые вы не хотите вызывать.
В исходном вопросе был подвопрос 9X_embedded о включении только соответствующих функций. gcc
будет 9X_embedded-control включать все функции в каждом используемом 9X_embedded-systems объектном файле. Другими словами, если у 9X_embedded вас есть объектный файл, содержащий 10 функций, все 9X_embedded 10 функций будут включены в ваш исполняемый 9X_embedded-systems файл, даже если одна из них фактически вызвана.
Стандартные 9X_arm библиотеки (например, libc) разделяют функции 9X_arm на множество отдельных объектных файлов, которые 9X_embedded-systems затем архивируются. Затем исполняемый файл 9X_arm связывается с архивом. Разбивая на множество 9X_embedded объектных файлов, компоновщик может включать 9X_embedded только те функции, которые фактически вызываются. (предполагается, что 9X_embedded-systems вы статически связываете)
Нет причин, по 9X_embedded-systems которым вы не можете проделать тот же трюк. Конечно, вы 9X_embedded можете возразить, что если функции не вызываются, вы, вероятно, можете 9X_embedded-control удалить их самостоятельно.
Если вы статически 9X_arm связываетесь с другими библиотеками, вы 9X_arm можете запускать перечисленные выше инструменты 9X_embedded-systems и поверх них, чтобы убедиться, что они следуют 9X_arm аналогичным правилам.
- Если вы собираетесь исследовать символы, ...
Ответ #2
Ответ на вопрос: Процесс уменьшения размера исполняемого файла
Еще одна оптимизация, которая может сэкономить 9X_embedded-control вам работу, - это -ffunction-section, -Wl, - gc-section, если 9X_embedded-systems вы используете GCC. Тем не менее, хорошей 9X_embedded цепочке инструментов не нужно сообщать об 9X_embedded этом.
Explanation: GNU ld связывает разделы, и 9X_embedded-control GCC генерирует один раздел для каждой единицы 9X_embedded перевода, если вы не укажете иное. Но в 9X_embedded C++ узлы в графе зависимостей являются объектами 9X_embedded и функциями.
Ответ #3
Ответ на вопрос: Процесс уменьшения размера исполняемого файла
В глубоко встроенных проектах я всегда стараюсь 9X_embedded-systems избегать использования каких-либо стандартных 9X_embedded-systems библиотечных функций. Даже простые функции, такие 9X_arm как strtol(), увеличивают размер двоичного 9X_embedded файла. Если возможно, просто избегайте этих 9X_embedded-control звонков.
В большинстве глубоко встраиваемых 9X_embedded-control проектов вам не требуется универсальная 9X_embedded-control функция printf() или динамическое выделение 9X_embedded-systems памяти (многие контроллеры имеют 32 КБ или 9X_embedded-control меньше ОЗУ).
Вместо использования «printf()» я 9X_embedded использую очень простой пользовательский 9X_embedded «printf()», эта функция может печатать числа 9X_arm только в шестнадцатеричном или десятичном 9X_embedded-systems формате, не более того. Большинство структур 9X_arm данных предварительно выделяются во время 9X_embedded компиляции.
Ответ #4
Ответ на вопрос: Процесс уменьшения размера исполняемого файла
Просто чтобы перепроверить и задокументировать 9X_embedded-control для использования в будущем, но используете 9X_embedded-systems ли вы инструкции Thumb? Это 16-битные версии 9X_embedded-control обычных инструкций. Иногда вам могут понадобиться 9X_embedded-control 2 16-битные инструкции, поэтому это не сэкономит 9X_arm 50% пространства кода.
Хороший компоновщик 9X_embedded должен выполнять только необходимые функции. Однако 9X_embedded-systems вам могут потребоваться настройки компилятора 9X_embedded-systems и компоновки для функций пакета для индивидуального 9X_embedded связывания.
Ответ #5
Ответ на вопрос: Процесс уменьшения размера исполняемого файла
У Andrew EdgeCombe отличный список, но если 9X_embedded вы действительно хотите очистить каждый 9X_arm последний байт, sstrip - хороший инструмент, которого 9X_embedded нет в списке, и который может сократить 9X_embedded еще несколько килобайт.
Например, при запуске 9X_embedded самого strip
it can shave off ~2kB.
Из старого README (см. комментарии 9X_embedded-systems в верхней части файла с косвенным исходным 9X_embedded кодом this):
sstrip - это небольшая утилита, которая 9X_arm удаляет содержимое в конце ELF-файл, не 9X_embedded-systems являющийся частью образа памяти программы.
Большинство 9X_embedded-systems исполняемых файлов ELF построены как с таблицей 9X_embedded-control заголовков программы, так и с таблица 9X_arm заголовков раздела. Однако для того, чтобы ОС 9X_arm для загрузки, связывания и выполнения программы. sstrip 9X_embedded-systems пытается извлечь заголовок ELF, таблицу 9X_embedded-control заголовков программы и ее содержимое, оставив 9X_embedded все остальное в ведре с битами. Он может 9X_embedded удалить только части файл, который появляется 9X_embedded-control в конце, после частей, которые нужно сохранить. Тем 9X_embedded-systems не мение, это почти всегда включает в 9X_embedded-systems себя таблицу заголовков разделов, а иногда 9X_embedded-control и несколько случайных разделов, которые 9X_embedded не используются при запуске программы.
Обратите 9X_arm внимание, что из-за части информации, которую 9X_embedded-control он удаляет, исполняемый файл sstrip с некоторыми 9X_embedded-control инструментами называется rumoured to have issues. Об этом подробнее 9X_embedded-control говорится в комментариях источника.
Также 9X_embedded-control ... для увлекательного / сумасшедшего чтения 9X_embedded-systems о том, как сделать исполняемый файл минимально 9X_embedded-systems возможного размера, стоит прочитать this article.
Ответ #6
Ответ на вопрос: Процесс уменьшения размера исполняемого файла
Итак, в конце концов я просто уменьшил проект 9X_embedded-systems до его простейшей формы, а затем медленно 9X_embedded добавил файлы один за другим, пока функция, которую 9X_embedded-control я хотел удалить, не появилась в файле readelf. Затем, когда 9X_arm у меня был файл, я все закомментировал и 9X_embedded-control медленно добавлял, пока функция не появилась 9X_embedded снова. Итак, в конце концов я узнал, что 9X_embedded-systems это вызвало, и удалил все эти вызовы ... Теперь 9X_arm все работает как надо ... мило!
Должен быть 9X_embedded лучший способ сделать это.
-
11
-
2
-
1
-
4
-
1
-
1
-
3
-
2
-
2
-
5
-
3
-
1
-
1
-
1
-
4
-
14
-
6
-
3
-
3
-
3
-
6
-
9
-
28
-
8
-
5
-
4
-
6
-
4
-
7
-
3
-
18
-
28
-
10
-
7
-
13
-
10
-
9
-
13
-
3
-
15
-
4
-
9
-
13
-
8
-
9
-
5
-
11
-
9
-
4
-
2