Map-файл
Прошивка перестала влезать во флеш-память, и непонятно, какая функция съела последние килобайты. Ответ лежит рядом с ELF-файлом — в map-файле. Компоновщик записывает в него, какой объектный файл куда положен, какие функции попали в образ и откуда они взялись.
Обновлено Редакция GAW
Map-файл (link map) — текстовый отчёт компоновщика о том, как он собрал программу: куда положены секции каждого объектного файла, какие модули библиотек включены и почему, какие адреса получили символы. В GNU ld его включают ключом -Map=файл или выводят на экран ключом -M (LD manual, разд. 2.1).
Что в нём есть
| Что показывает | Пример вопроса |
|---|---|
| какие модули библиотек включены и каким символом они затянуты | откуда в прошивке взялся printf |
выброшенные секции, в том числе удалённые --gc-sections | почему функция не попала в образ |
| куда положены секции каждого объектного файла | где лежит обработчик прерывания |
| значения символов | где начинается и кончается .data |
Список выброшенных секций выводится по умолчанию, его отключает --no-print-map-discarded. Если символ в скрипте пересчитывается через своё же прежнее значение, ld не хранит промежуточных результатов и показывает у таких строк итоговое значение в квадратных скобках.
Как включить
- arm-none-eabi-gcc, avr-gcc:
-Wl,-Map=firmware.map. Ключ-Wlпередаёт параметр компоновщику,%в имени заменяется именем выходного файла. - Сводка по памяти:
-Wl,--print-memory-usageпечатает для каждой области MEMORY занятый и полный размер и процент заполнения — удобно видеть рост прошивки в каждой сборке.
Для чего используют
- Переполнение флеш-памяти и ОЗУ. По map-файлу видно, какие функции и библиотеки самые крупные и что попало в образ без нужды.
- Поиск места отказа. Адрес из HardFault сопоставляют с диапазонами функций.
- Проверка скрипта компоновщика. Видно, где реально оказались секции, их адреса загрузки и выполнения, начало и конец .data и .bss, положение стека и кучи.
- Абсолютные адреса. Таблица векторов, загрузчик, данные во флеш-памяти по фиксированному адресу — map-файл подтверждает, что они на месте.
Как устроен сам скрипт и как читать map-файл на примере STM32F103, разобрано в статье о скриптах компоновщика; связь ELF, HEX и BIN — в статье о файлах прошивки, а сборка для AVR — в статье об инструментах avr-gcc.
Частые вопросы
Как получить map-файл в arm-none-eabi-gcc или avr-gcc?
Передать компоновщику ключ через gcc: -Wl,-Map=firmware.map (LD manual, разд. 2.1). Вариант -Wl,-Map=% создаёт файл с именем выходного файла и расширением .map. В Microchip Studio этот ключ есть в настройках компоновщика проекта, а map-файл среда описывает как отчёт о решениях компоновщика (DS50002718).
Как найти по map-файлу, что занимает больше всего флеш-памяти?
Посмотреть секцию .text: в ней для каждого объектного файла и функции указаны адрес и размер в шестнадцатеричном виде. Крупные блоки часто приходят из библиотек; раздел о включённых членах архивов показывает, какой символ притянул каждый модуль (LD manual, ключ -M).
Как по адресу из HardFault найти функцию?
Взять сохранённый PC из кадра стека исключения и найти в map-файле функцию, в чей диапазон адресов он попадает: у каждой функции указаны начальный адрес и размер её секции. Точнее покажет дизассемблер objdump -d, но map-файл даёт ответ без инструментов.
Источники
- GNU. LD manual, 2.1 Command-line Options — -M, --print-map: карта компоновки — где размещены объектные файлы, как распределены общие символы, какие члены архивов включены и каким символом они затянуты, значения символов; для символов, вычисленных через предыдущее значение, выводится итог в квадратных скобках; --print-map-discarded — список выброшенных и собранных мусорщиком секций, включён по умолчанию; --print-map-locals — локальные символы; -Map=mapfile — карта в файл, % подставляет имя выходного файла; пример gcc foo.o bar.o -Wl,-eENTRY -Wl,-Map=a.map; --print-memory-usage — занятый и полный размер каждой области MEMORY; --gc-sections — удаление неиспользуемых секций
- GigaDevice. AN200 GD32 Embedded Builder Linker Script Files Introduction for Arm Cortex-M Processor, Rev 1.0 (Dec. 2025) — разд. 3.1 и 3.2: после изменения скрипта компоновщика размещение кода в SRAM и данных в TCM SRAM проверяют по map-файлу
- Microchip. Microchip Studio User Guide, DS50002718 — состав выходных файлов проекта: MAP-файл — сведения компоновщика о том, что он сделал и куда что положил; параметр -Wl,-Map в настройках компоновщика создаёт map-файл
Нашли ошибку?
Смотрите также
- Скрипт компоновщика GNU ldMEMORY, SECTIONS, VMA и LMA, KEEP, стек и куча, map-файл, переполнение
- LMA и VMAАдрес загрузки секции и адрес, по которому она работает во время выполнения
- HardFaultИсключение Cortex-M при необработанной ошибке
- Секции .data и .bssГде лежат глобальные переменные: копирование и обнуление при старте
- Файлы прошивки: HEX, BIN, ELFELF, Intel HEX, S-record, BIN и UF2: адреса, секции, objcopy, size
- avr-gcc и avr-libcКомпилятор, binutils, avr-libc, avrdude: установка, команды сборки, Makefile, заголовки, ошибки
- Скрипт компоновщикаФайл .ld с картой памяти и правилами размещения секций прошивки