Что означает «Rva Base» в файле карты, сгенерированном компоновщиком MSVC?

#c #linker #static-linking

#c #компоновщик #статическое связывание

Вопрос:

Я скомпилировал программу на C и связался с компоновщиком Microsoftlink.exe. Компоновщик сгенерировал файл *.map. Ниже приведены некоторые фрагменты:

  Start         Length     Name                   Class
 0001:00000000 00000180H .text                   CODE
 0001:00000180 00049158H .text$mn                CODE
 0002:00000000 000090c4H .rdata                  DATA
 0002:000090c4 00000130H .rdata$zzzdbg           DATA
 0003:00000000 00002060H .data                   DATA
 0003:00002060 00001370H .bss                    DATA
 0004:00000000 00002790H .pdata                  DATA
 0005:00000000 000003e4H .xdata                  DATA

  Address         Publics by Value       Rva Base             Lib:Object
 0002:000000c0       _gVar               0000000000049660     MyLib:File1.obj
  

Насколько я понимаю,:

.rdata Раздел имеет индекс 0002 с указанием длины 0x90c4 .

_gVar Глобальная переменная имеет адрес like 0002:000000c0 , поэтому она находится в .rdata разделе со смещением раздела. ………. 0xc0

Базовый адрес .rdata раздела определяется загрузчиком во время выполнения.

Мое замешательство связано с Rva Base колонкой.

Я проверил двоичный файл со смещением 0x49660 . Он содержит именно то значение, которое я присвоил для _gVar . Похоже, что это Rva Base это смещение от начала файла.

Но я думаю, что Rva Base должно быть равно absolute virtual address , что может быть определено только загрузчиком во время выполнения.

Как это может быть смещение файла? Или неудачная опечатка в имени столбца?

(Кстати, я много искал авторитетную ссылку на файл .map, созданный link.exe . Но пока безуспешно. Если кто-нибудь может поделиться каким-либо ресурсом, это будет высоко оценено.)

ДОБАВИТЬ 1 — 5:31 ВЕЧЕРА, 4/8/2019

Основываясь на 500 - Internal Server Error комментарии, я использую CFF Explorer для проверки разделов PE. Это выглядит следующим образом:

Разделы PE

Согласно PE sepc:

Виртуальный адрес: для исполняемых изображений — адрес первого байта раздела относительно базы изображений, когда раздел загружен в память.

Необработанный адрес/PointerToRawData: указатель файла на первую страницу раздела в файле COFF.

Эти 2 столбца имеют одинаковые данные в моем сценарии.

А в необязательном заголовке PE база изображений равна 0 (это из-за моего флага ссылки /BASE:0 ):

База изображений

Когда компоновщик сгенерировал файл .map, он не имеет представления о том, где изображение будет загружено во время выполнения. Поэтому он должен использовать ImageBase=0 для вычисления Rva Base столбца.

_gVar Абсолютный виртуальный адрес = база изображений (0) виртуальный адрес .rdata (0x495A0) смещение в .rdata (0xc0) = 0x49660

В моем случае,

  1. Virtual Address Столбец имеет то же значение, что и Raw Address столбец.
  2. И ImageBase = 0 имеет тот же эффект file beginning offset = 0

Таким образом, конечное значение absolute virtual address равно file offset , но это относится только к моему сценарию.

Комментарии:

1. Проанализируйте заголовок PE. У него есть таблица с расположением каждого раздела, как в виде смещения в файл на диске, так и в виде смещения к адресу загрузки модуля в памяти, когда PE загружается как исполняемый файл или dll. Вот ссылка на спецификацию PE.