A.OUT(4) A.OUT(4) НАЗВАНИЕ a.out - результат работы стандартного ассемблера и ре- дактора связей СИНТАКСИС |#include ОПИСАНИЕ По умолчанию редактор связей ld(1) выводит собранную программу в файл с именем a.out в обычном формате объ- ектных файлов. Если в процессе сборки не было ошибок, то редактор связей делает этот файл выполняемым. Выход- ной файл ассемблера as(1) по умолчанию называется ина- че, но имеет тот же формат, что и a.out. Объектный файл обычного формата состоит из заголовка файла, вспомогательного заголовка системы UNIX (если файл создан редактором связей), таблицы заголовков сек- ций, содержимого секций, информации о настройке ссылок, необязательной информации о номерах строк, таблицы имен и таблицы цепочек. Порядок этих частей приведен ниже: Заголовок файла. UNIX-заголовок. Заголовок секции 1. ... Заголовок секции n. Содержимое секции 1. ... Содержимое секции n. Настройка ссылок секции 1. ... Настройка ссылок секции n. Номера строк секции 1. ... Номера строк секции n. Таблица имен. Таблица цепочек. Последние 3 части объектного файла (номера строк, таб- лица имен и таблица цепочек) могут отсутствовать, программа была собрана ld(1) с опцией -s, или если эти секции были удалены командой strip(1). Заметим также что информации о настройке ссылок не останется после редактирования связей, если не была использована опция -r. Кроме того, таблица цепочек существует лишь при ус- ловии, что в таблице имен есть имена с текстом длиннее 8 символов. Содержащийся в каждом заголовке (см. описание ниже) размер секции измеряется в байтах. Когда файл a.out загружен в память для выполнения, то существуют 3 логических сегмента: сегмент команд, сег- мент данных (сначала инициализированные данные, затем неинициализированные, которые позднее будут инициализи- рованы нулями), и стек. Сегмент команд начинается с ад- реса 0. Сегмент данных начинается с минимального адреса, крат- ного 1024 Кб, идущего вслед за сегментом команд. Стек начинается с адреса 0x80000000 и растет в сторону уменьшения адресов. В случае необходимости стек расши ряется автоматически. Сегмент данных расширяется только в результате выполнения системного вызова brk(2). В перемещаемых файлах содержимое слов, не являющихся ссылкой на неопределенное внешнее имя, в точности сов- падает с содержимым соответствующего слова памяти перед началом выполнения файла. Если же команда содержит ссылку на неопределенное внешнее имя, в файле существу- ет информация о настройке этой ссылки. В частности, указан элемент таблицы имен, описывающий объект, на ко- торый обращена ссылка. У этого объекта в таблице указан класс памяти "внешнее имя", а номер секции и значение не определены. Когда файл обрабатывается редактором связей и имя определяется, то значение имени добавляет ся к ссылке в файле. Заголовок файла Каждый объектный файл обычного формата начинается с 20- байтного заголовка. Этот заголовок описывается следую- щей C-структурой: |struct filehdr { | unsigned short f_magic; /* Магическое число */ | unsigned short f_nscns; /* Количество секций */ | long f_timdat; /* Время и дата создания */ | long f_symptr; /* Указатель в файле на | таблицу имен */ | long f_nsyms; /* Число элементов в таблице | имен */ | unsigned short f_opthdr; /* Размер вспомогательного | заголовка */ | unsigned short f_flags; /* Флаги */ |}; Заголовок UNIX-системы Структура этого заголовка такова: |typedef struct aouthdr { | short magic; /* Магическое число */ | short vstamp; /* Метка версии */ | long tsize; /* Размер сегмента команд в байтах | */ | long dsize; /* Размер секции .data (инициали- | зированные данные) */ | long bsize; /* Размер секции .bss (неинициали- | зированные данные) */ | long entry; /* Точка входа */ | long text_start; /* Адрес, с которого размещается | сегмент команд */ | long data_start; /* Адрес, с которого размещается | сегмент данных */ |} AOUTHDR; Заголовок секции Заголовки секций имеют следующий формат: |struct scnhdr { | char s_name[8]; /* Имя секции */ | long s_paddr; /* Физический адрес */ | long s_vaddr; /* Виртуальный адрес */ | long s_size; /* Размер секции */ | long s_scnptr; /* Указатель на бесструк- | турные данные в файле */ | long s_relptr; /* Указатель в файле на | инф. о настр. ссылок */ | long s_lnnoptr; /* Указатель в файле на | инф. о номерах строк */ | unsigned short s_nreloc; /* Число ссылок, требующих | настройки */ | unsigned short s_nlnno; /* Число элементов в таблице | номеров строк */ | long s_flags; /* Флаги */ |}; Настройка Для каждой ссылки в командах или данных, которую требу- ется настраивать при редактировании связей, в объектном файле есть элемент, содержащий информацию, достаточную для настройки. Формат этой информации следующий: |struct reloc { | long r_vaddr; /* Виртуальный адрес ссылки */ | long r_symndx; /* Номер в таблице имен */ | unsigned short r_type; /* Тип ссылки */ |}; Начало информации о настройке ссылок секции указывается в заголовке секции в поле s_relptr. Если этой информа- ции нет, то значение s_relptr равно 0. Таблица имен Элементы таблицы имен имеют следующий формат: |#define SYMNMLEN 8 /* Максимальное количество символов | в тексте имени */ |#define FILNMLEN 14 /* Максимальное количество символов | в имени файла */ |#define DIMNUM 4 /* Размерность массива во вспомога- | тельном разделе */ |struct syment { | union { /* Все способы описать текст имени */ | char _n_name[SYMNMLEN]; /* Текст имени */ | struct { | long _n_zeroes; /* Если == 0, то в таблице цепочек */ | long _n_offset; /* Смещение в табл. цепочек */ | } _n_n; | char *_n_nptr[2]; | } _n; | long n_value; /* Значение имени */ | short n_scnum; /* Номер секции */ | unsigned short n_type; /* Тип и производный тип */ | char n_sclass; /* Класс памяти */ | char n_numaux; /* Число вспомогательных | элементов */ |}; |#define n_name _n._n_name |#define n_zeroes _n._n_n._n_zeroes |#define n_offset _n._n_n._n_offset |#define n_nptr _n._n_nptr[1] Для описания некоторых имен требуется больше информа- ции, чем содержится в одном элементе; в таком случае за первым элементом, описывающим имя, следуют вспомога- тельные элементы. Вспомогательные элементы имеют тот же размер, что и основные; их формат приведен ниже: |union auxent { | struct { | long x_tagndx; /* Индекс описателя структуры, | объединения или перечисления */ | union { | struct { | unsigned short x_lnno; /* Номер строки | определения */ | unsigned short x_size; /* Размер массива, структуры | или объединения */ | } x_lnsz; | long x_fsize; /* Размер функции */ | } x_misc; | union { | struct { | long x_lnnoptr; | long x_endndx; | } x_fcn; | struct { /* Если массив, то его размерности (до 4) */ | unsigned short x_dimen [DIMNUM]; | } x_ary; | } x_fcnary; | unsigned short x_tvndx; | } x_sym; | struct { | char x_fname [FILNMLEN]; /* Имя файла (занимает весь | элемент) */ | } x_file; | struct { | long x_scnlen; /* Длина секции */ | unsigned short x_nreloc; /* Число элем. с инф. о | настройке ссылок */ | unsigned short x_nlinno; /* Число элем. с инф. о | номерах строк */ | } x_scn; | struct { | long x_tvfill; | unsigned short x_tvlen; | unsigned short x_tvran[2]; | } x_tv; |}; Элементы таблицы имен нумеруются, начиная с 0. Начало таблицы имен указывается полем f_symptr в заголовке файла как смещение в байтах относительно начала файла. Если таблица имен удалена, то поле f_symptr равно нулю. Таблица цепочек (если она существует) начинается со смещением f_symptr+(f_nsyms*SYMESZ) байт от начала фай- ла. СМ. ТАКЖЕ brk(2), filehdr(4), ldfcn(4), linenum(4), reloc(4), scnhdr(4), syms(4). as(1), cc(1), ld(1) в Справочнике пользователя.