Есть ли способ узнать, где находятся глобальные и статические переменные внутри сегмента данных (.data + .bss)? - PullRequest
0 голосов
/ 03 января 2012

Я хочу сбросить все глобальные и статические переменные в файл и загрузить их обратно при следующем вызове программы. Решение, о котором я подумал, - сбросить сегмент .data в файл. Но сегмент .data на 32-битной машине занимает более 2 ^ 32 адресного пространства (4 ГБ). В какой части этого адресного пространства находятся переменные? Как мне узнать, какую часть сегмента .data мне следует выбросить?

И при загрузке выгруженного файла, я предполагаю, что, поскольку переменные ссылаются на смещение в сегменте данных, будет безопасно просто записать весь дамп в предполагаемую начальную точку «области переменных». Пожалуйста, поправьте меня, если я ошибаюсь.

EDIT

Хорошее начало - этот вопрос .

Ответы [ 5 ]

1 голос
/ 03 января 2012

Ваша проблема в том, как найти начало и конец сегмента данных. Я не уверен, как это сделать, но я мог бы дать вам пару идей.

Если все ваши данные относительно автономны (они объявлены в одном и том же модуле, а не в отдельных модулях), вы можете объявить их в какой-то структуре, поэтому началом будет адрес структура, и конец будет некоторой переменной, которую вы объявите сразу после структуры. Если я хорошо помню, у MASM была директива «RECORD» или что-то подобное, что вы могли бы использовать для группировки переменных.

В качестве альтернативы, вы можете объявить два дополнительных модуля, один с переменной «начало», а другой с переменной «конец», и убедиться, что первый связан раньше всего, а второй связан после всего остального. Таким образом, эти переменные могут на самом деле помечать начало и конец сегмента данных. Но я не уверен в этом, я просто даю вам указатель.

Следует помнить, что ваши данные неизбежно будут содержать указатели, поэтому сохранение и загрузка всех ваших данных будут работать только в том случае, если ОС, в которой вы работаете, может гарантировать, что ваша программа всегда будет загружаться по одному и тому же адресу. Если нет, забудь об этом. Но если вы можете иметь эту гарантию, тогда да, загрузка данных должна работать. Вам даже не понадобится memcpy, просто установите буфер для операции чтения как начало сегмента данных.

0 голосов
/ 04 января 2012

В ответ на ваш вопрос о заголовке, в Windows местоположение и размер данных и сегменты bss могут быть получены из PE-заголовка в памяти. Как это изложено и как его анализировать, описано в этой спецификации:

http://msdn.microsoft.com/en-us/windows/hardware/gg463119

0 голосов
/ 04 января 2012

Предполагается, что вы используете инструменты gnu (gcc, binutils), если вы посмотрите на скрипты компоновщика, которые используют встроенные люди, такие как разработчики gba и разработчики микроконтроллеров, использующие roms (например, yagarto или devkit-arm).В сценарии компоновщика они окружают интересующие сегменты переменными, которые они могут использовать в других местах своего кода.Например, для программного обеспечения на основе rom вы указываете сегмент данных с ram AT rom или rom AT ram в сценарии компоновщика, означая ссылку, как если бы сегмент данных находился в ram в этом адресном пространстве, но также связываете сами данные в rom по этому адресупробел, загрузочный код затем копирует сегмент .data из диска в оперативную память, используя эти переменные.Я не понимаю, почему вы не можете сделать то же самое, чтобы инструменты компилятора / компоновщика сообщали вам, где что находится, а затем во время выполнения используют эти переменные, чтобы извлечь данные из памяти и сохранить их где-нибудь для гибернации или завершения работы, а затем восстановить эти данные откуда угодно.Переменные, которые вы используете для восстановления, конечно же, не должны быть частью сегмента .data, иначе вы удаляете переменные, которые используете для восстановления сегмента.

0 голосов
/ 03 января 2012

Состояние всей программы может быть очень сложным и включать не только переменные, но и значения в регистрах. Вам почти наверняка будет лучше отслеживать, какие данные вы хотите сохранить, а затем сохранять их в файле самостоятельно. Это может быть относительно безболезненно при правильной настройке и инкапсуляции. Затем, когда вы возобновите работу приложения, прочитайте информацию о состоянии программы и возобновите работу.

0 голосов
/ 03 января 2012

Я не верю, что есть гарантия, что при каждом выполнении вы будете иметь последовательность переменных sam, поэтому смещения могут указывать на неправильный контент.

...