Разрядность .NET сборок

Вскоре после написания поста про определение разрядности исполняемых файлов выяснилось, что в мире .NET «всё совсем по-другому».

Для начала небольшое лирическое отступление. Компилятор Visual C++ использует ключ /clr для указания разрешенных типов кода в .NET сборке:

С точки зрения разрядности получаемых модулей тут важно то, что управляемый код по определению может выполняться на любой платформе (x86, amd64 и ia64), в то время как неуправляемый код предназначен для конкретного процессора. Т.е. можно бы было ожидать, что модули, собранные с /clr:pure или /clr:safe, можно использовать на любой платформе. На самом деле это не совсем так, о чём я и расскажу ниже.

Далее. Модули, содержащие управляемый код, можно отличить от «нормальных» модулей по непустой «COM Descriptor Directory». Команда “link /dump /headers” показывает её в конце списка директорий в «PE Optional Header»:

OPTIONAL HEADER VALUES
             10B magic # (PE32)
            8.00 linker version

            ...

               0 loader flags
              10 number of directories
               0 [       0] RVA [size] of Export Directory
            87C4 [      64] RVA [size] of Import Directory
            A000 [     6A8] RVA [size] of Resource Directory
               0 [       0] RVA [size] of Exception Directory
               0 [       0] RVA [size] of Certificates Directory
            B000 [     190] RVA [size] of Base Relocation Directory
            3100 [      1C] RVA [size] of Debug Directory
               0 [       0] RVA [size] of Architecture Directory
               0 [       0] RVA [size] of Global Pointer Directory
               0 [       0] RVA [size] of Thread Storage Directory
            3188 [      40] RVA [size] of Load Configuration Directory
               0 [       0] RVA [size] of Bound Import Directory
            3000 [      A8] RVA [size] of Import Address Table Directory
               0 [       0] RVA [size] of Delay Import Directory
            311C [      48] RVA [size] of COM Descriptor Directory
               0 [       0] RVA [size] of Reserved Directory

Несмотря на название, эта директория не имеет отношения к COM. Насколько я понимаю, название осталось с тех времен, когда CLR еще только начинал разрабатываться. Содержимое этой директории, или, по крайней мере, часть её содержимого, можно посмотреть с помощью утилиты CorFlags.exe из .NET SDK.

> CorFlags.exe clr_rabbit.exe
    Microsoft (R) .NET Framework CorFlags Conversion Tool.  Version  2.0.50727.42
    Copyright (c) Microsoft Corporation.  All rights reserved.

    Version   : v2.0.50727
    CLR Header: 2.5
    PE        : PE32
    CorFlags  : 0
    ILONLY    : 0
    32BIT     : 0
    Signed    : 0

Нас будут интересовать флаги ILONLY (только управляемый код) и 32BIT (32-х битный код), поскольку они непосредственно связаны с разрядностью сборки.

Я попробовал скомпилировать x86 и amd64 варианты стандартного “Hello World” для всех трёх значений флага /clr и посмотреть что получится. Получилась вот такая табличка:

Конфигурация PE заголовок Флаг ILONLY Флаг 32BIT Разрядность процесса в 32-х битной системе Разрядность процесса в 64-х битной системе
x86, /clr x86 0 0 32 32
x86, /clr:pure x86 1 1 32 32
x86, /clr:safe x86 1 0 32 64
amd64, /clr x64 0 0 - 64
amd64, /clr:pure x64 1 0 - 64
amd64, /clr:safe x86 1 0 32 64

Отсюда можно сделать вот такие выводы:

comments powered by Disqus