Формат объектных файлов
Модератор: Модераторы
shade,
Может подскажите как выглядит содержимое секций .data .text. ?
Может подскажите как выглядит содержимое секций .data .text. ?
- shade
- энтузиаст
- Сообщения: 879
- Зарегистрирован: 21.02.2006 19:15:48
- Откуда: http://shamangrad.net/
- Контактная информация:
Как простой снимок памяти.
По крайней мере для a.out и COFF (включая модификацию от M$)
По крайней мере для a.out и COFF (включая модификацию от M$)
Если есть возможность хотелось бы уточнить.
1 Секция инициализированных данных. Есть Переменная есть ее значение (инициализации) . Как я предполагаю есть в секции ссылка на элемент в таблице имен. В памяти выделяется место под переменную. Непосредственно заполнение значением этой области памяти, кто занимается ?
2. Как загружается значение в секции данных.
[код команды LOAD] [флаг что загрузить значение] [значение]
Примерно так ?
Или создается временная переменная и заносится в таблицу имен ?
Добавлено спустя 7 минут 58 секунд:
Вот если можно поподробнее это как ?
1 Секция инициализированных данных. Есть Переменная есть ее значение (инициализации) . Как я предполагаю есть в секции ссылка на элемент в таблице имен. В памяти выделяется место под переменную. Непосредственно заполнение значением этой области памяти, кто занимается ?
2. Как загружается значение в секции данных.
[код команды LOAD] [флаг что загрузить значение] [значение]
Примерно так ?
Или создается временная переменная и заносится в таблицу имен ?
Добавлено спустя 7 минут 58 секунд:
shade писал(а):Как простой снимок памяти.
Вот если можно поподробнее это как ?
- shade
- энтузиаст
- Сообщения: 879
- Зарегистрирован: 21.02.2006 19:15:48
- Откуда: http://shamangrad.net/
- Контактная информация:
если значение может быть вычислено на этапе компиляции (например, константа),то оно будет просто записано в образе.
если это указатель, то там будет адрес, который корректируется с помощью таблицы релокаций (тут уже зависит от формата и компилятора, адрес может храниться в таблице релокаций, а на месте значния будут нули).
если выжение, которое не может быть вычислено на этапе компиляции, то будет сгенерирован код, который будет вызыван в момент инициализации модуля.
Например, в С/C++
переменная скорее всего окажется в секции неинициализированных данных и будет создан код, в котором будет вызов some_func. Точнее будет создан один код инициазации, который вычислит все подобные выражения...
В таблице имен просто "указатель" на значение в секции (например, смещение к ячейки памяти относительно начала образа секции, как точно не помню)
----------------------------
Проще понять процесс загрузки. В общих чертах так:
1. динамический компоновщик читает секцию из файла и загружает её как есть по определенному адресу
2. редактируются связи между секциями (с помощью таблицы имен), например в секции кода используется переменная из секции данных, с помощью таблицы имен вычисляется виртуальный адрес этой переменной и записывается в соответсвующую ячейку.
3. если фактический адрес секции не совпадет с виртуальным адресом который прописан в секции, то требуется релокация
3.1. релокация: запускается цикл по таблице релокаций секции и по определенной формуле просто пересчитываются значения в ячейках, например, добавляется разность между фактическим и виртуальным адресом. Тип формы зависит от типа релокации. Типы в свою очередь зависят от архитектуры процессора.
если это указатель, то там будет адрес, который корректируется с помощью таблицы релокаций (тут уже зависит от формата и компилятора, адрес может храниться в таблице релокаций, а на месте значния будут нули).
если выжение, которое не может быть вычислено на этапе компиляции, то будет сгенерирован код, который будет вызыван в момент инициализации модуля.
Например, в С/C++
Код: Выделить всё
int x = some_func("bla bla bla");переменная скорее всего окажется в секции неинициализированных данных и будет создан код, в котором будет вызов some_func. Точнее будет создан один код инициазации, который вычислит все подобные выражения...
В таблице имен просто "указатель" на значение в секции (например, смещение к ячейки памяти относительно начала образа секции, как точно не помню)
----------------------------
Проще понять процесс загрузки. В общих чертах так:
1. динамический компоновщик читает секцию из файла и загружает её как есть по определенному адресу
2. редактируются связи между секциями (с помощью таблицы имен), например в секции кода используется переменная из секции данных, с помощью таблицы имен вычисляется виртуальный адрес этой переменной и записывается в соответсвующую ячейку.
3. если фактический адрес секции не совпадет с виртуальным адресом который прописан в секции, то требуется релокация
3.1. релокация: запускается цикл по таблице релокаций секции и по определенной формуле просто пересчитываются значения в ячейках, например, добавляется разность между фактическим и виртуальным адресом. Тип формы зависит от типа релокации. Типы в свою очередь зависят от архитектуры процессора.
Видимо я сильно туплю ... Но не могу ссебе представить...
Есть Глобальная переменная int x = 50;
есть код x=60;
есть запись в итаблице имен. для х.
Какой формат записи для x в .data .text. Ведь они же должны содержать какието ссылки или еще чего на эту запись ...
Например, по моим предположениям это могло бы выглядеть так:
.data
[номер записи х в таблице имен] [значение инициализации =50]
.text
[код команды загрузки] [значение =60]
[код команды сохранения] [номер записи х в таблице имен]
или я не прав ?
Есть Глобальная переменная int x = 50;
есть код x=60;
есть запись в итаблице имен. для х.
Какой формат записи для x в .data .text. Ведь они же должны содержать какието ссылки или еще чего на эту запись ...
Например, по моим предположениям это могло бы выглядеть так:
.data
[номер записи х в таблице имен] [значение инициализации =50]
.text
[код команды загрузки] [значение =60]
[код команды сохранения] [номер записи х в таблице имен]
или я не прав ?
- shade
- энтузиаст
- Сообщения: 879
- Зарегистрирован: 21.02.2006 19:15:48
- Откуда: http://shamangrad.net/
- Контактная информация:
1. в секции .data будет просто записано 50
2. в секции .text будет код типа
Вторая команда будет скомпилирована примерно так:
<опкод 1-2 байта> <адрес-X 4-байта>
Вот при редактировании связей будет обновлено 4 байта (<адрес-X 4-байта>)
В таблице имен, будет указано, что по такому то адресу P (смещение к <адрес-X 4-байта>) находиться ссылка на имя (переменную) в другой секции, что нужно найти в таблице имен эту переменную и записать указатель этой перемнной по адресу P...
2. в секции .text будет код типа
Код: Выделить всё
mov eax, 50
mov [x], eaxВторая команда будет скомпилирована примерно так:
<опкод 1-2 байта> <адрес-X 4-байта>
Вот при редактировании связей будет обновлено 4 байта (<адрес-X 4-байта>)
В таблице имен, будет указано, что по такому то адресу P (смещение к <адрес-X 4-байта>) находиться ссылка на имя (переменную) в другой секции, что нужно найти в таблице имен эту переменную и записать указатель этой перемнной по адресу P...
shade писал(а):1. в секции .data будет просто записано 50
Кто должен значть что 50 - именно значение инициализации для x
Если нету указателя на таблицу имен в секции инициализированных данных . Значит Таблица имен и секция инициализированных данных должны заполняться в строкгом порядке и при изменении порядка данных инициализации - это приведет к неправильной инициализации (анологичное произойдет если поменять номера записей в таблице имен местами). - Рассуждения мои верны или как?
Код: Выделить всё
struct syment {
union { /* Все способы описать текст имени */
} _n;
long n_value; /* Значение имени */
short n_scnum; /* Номер секци
unsigned short n_type; /* Тип и производный тип */
char n_sclass; /* Класс памяти */
char n_numaux; /* Число вспомогательныхэлементов */
};
shade писал(а):В таблице имен, будет указано, что по такому то адресу P (смещение к <адрес-X 4-байта>)
А в эолементе таблицы имен syment нету адреса, есть только номер секции.
- shade
- энтузиаст
- Сообщения: 879
- Зарегистрирован: 21.02.2006 19:15:48
- Откуда: http://shamangrad.net/
- Контактная информация:
Seraphim писал(а):А в эолементе таблицы имен syment нету адреса, есть только номер секции.
n_value - для некоторых классов символов является толи указателем, толи смещением в секции.
Например в COFF, если
e_sclass = C_EXT && e_scnum = 0
то это ссылка на символ определенный в другой секции т.е. COFF_EXTERN
и в n_value находиться смещение относительно начала секции.
Пусть начало секции ImagePtr, pSym наш символ который надо разрешить (внешнее имя), pFoundSymbol - глобальное имя (COFF_GLOBAL) тогда редактирование связи будет просто (в терминах Pascal)
pDWORD(ImagePtr + pSym.n_value)^ := Sections[ pFoundSymbol.n_scnum ].Addr + pFoundSymbol.n_value
