LINK148¶
LINK148 (Cawas Linker for i80148) - компоновщик, который собирает объектные файлы .o и статические библиотеки .a в единый плоский бинарник .bin + .hex.
| Параметр | Значение |
|---|---|
| Версия | 0.1 |
| Целевая архитектура | i80148 (32-бит, flat) |
| Порядок байтов | Big Endian |
| Вход | .o (binary/JSON), .a, .ld |
| Выход | .bin + .hex |
| Файл | LINK148.py |
Использование¶
# Простая сборка из объектных файлов
python LINK148.py startup.o main.o -o program.bin --entry _start
# С библиотекой
python LINK148.py startup.o main.o libio.a -o program.bin --entry _start
# С собственным скриптом линковки
python LINK148.py -T program.ld startup.o main.o -o program.bin
| Опция | Описание |
|---|---|
-o file |
Выходной бинарник (по умолчанию output.bin) |
-T file |
Скрипт линковки |
--base addr |
Базовый адрес для дефолтной раскладки |
--entry SYM |
Переопределить точку входа |
Скрипт линковки можно передавать без -T - достаточно, чтобы имя заканчивалось на .ld.
Порядок разрешения точки входа¶
ENTRY(symbol)в скрипте линковки.--entryв командной строке.- Поле
.entryв первом объектном файле. - Символ
_startпо умолчанию.
Объектный формат¶
Объектный файл версии 1 содержит:
| Часть | Размер | Описание |
|---|---|---|
| Header | 64 B | Магия CWO\0, версия, архитектура, размеры, смещение данных, имя entry |
| Section headers | 32 B × n | Имя, тип, адрес, размер, смещение данных |
| Symbol table | 48 B × n | Имя, индекс секции, смещение, флаги |
| Relocation table | 48 B × n | Имя, индекс секции, смещение, тип, pc_after |
| Section data | var | Сырые байты для text/data, для bss - только размер |
- Все многобайтовые поля - big-endian.
- Индекс секции
0xFFFFFFFFозначает неопределённый (внешний) символ. - Флаг символа: бит 0 - глобальный.
Секции¶
| Имя | Назначение |
|---|---|
text |
Код |
data |
Инициализированные данные |
bss |
Нулевые данные (только размер) |
Типы релокаций¶
| Тип | Описание |
|---|---|
abs32 |
Абсолютный 32-битный адрес |
rel32 |
PC-относительное 32-битное смещение |
rel32используется дляCALLиJMP.abs32- дляLDI.DWи плоских адресов вSTR/LOD.
Разрешение символов¶
- Каждый объектный файл отдаёт свои
.globalсимволы в общую таблицу. - Релокация сначала ищется в локальных символах объекта.
- Если не найдена - в глобальной таблице.
- Архивы (
.a) сканируются итеративно, пока не перестанут появляться новые определённые символы.
Раскладка по умолчанию¶
Без скрипта секции располагаются подряд от --base:
Скрипт линковки¶
Поддерживаются комментарии // и /* */.
Синтаксис¶
| Элемент | Описание |
|---|---|
ENTRY(symbol); |
Объявить точку входа |
SECTIONS { ... } |
Определить выходные секции |
symbol = expr; |
Определить символ |
. = expr; |
Установить текущий location counter |
.name [addr] : { *(input...) } |
Слить входные секции в выходную |
Выражения¶
| Символ | Описание |
|---|---|
number |
Число (dec или 0x...) |
. |
Текущий адрес |
+ - * / |
Арифметика |
ALIGN(n) |
Выровнять адрес на n байт |
SIZEOF(.name) |
Размер выходной секции |
Пример¶
ENTRY(_start);
SECTIONS
{
. = 0x00060000;
.text : { *(.text) }
.data : { *(.data) }
.bss : { *(.bss) }
}
Имена входных секций можно писать без ведущей точки.
Runtime-символы¶
Линкер автоматически определяет:
| Символ | Описание |
|---|---|
_DATA_START |
Адрес .data |
_DATA_END |
Конец .data |
_BSS_START |
Адрес .bss |
_BSS_END |
Конец .bss |
_END |
Конец .bss |
Архивный формат¶
Статические библиотеки .a создаются через AR148. Формат архива версии 1:
| Поле | Размер | Описание |
|---|---|---|
| Magic | 4 B | CWA\0 |
| Version | 4 B | 1 (big-endian) |
| Count | 4 B | Число членов |
| Reserved | 4 B | Нули |
| Member headers | 40 B × n | Имя + смещение + размер |
| Member data | var | Сырые данные |
Члены архива могут быть бинарными (CWO\0) или JSON-объектами.
Пример¶
$ python LINK148.py startup.o main.o libio.a -o program.bin --entry _start
Linked 1024 bytes
Sections: text=0x00060000 (512 bytes), data=0x00050200 (256 bytes), bss=0x00050300 (256 bytes)
Global symbols: {_START, _DATA_START, _DATA_END, _BSS_START, _BSS_END, _END}
Entry point: _START = 0x00060000
Written: program.bin and program.hex