РЕДАКТИРОВАТЬ: я сделал ошибку при тестировании с компилятором clang. Это работает, как и ожидалось с Clang. Неожиданные результаты получены в Visual Studio 2015. Мой вывод заключается в том, что в Visual Studio 2015 есть что-то подозрительное.
Я сделал замечание, которое не могу объяснить относительно значения символов объектного файла, которые представляют неинициализированные массивы C в объектных файлах COFF, созданных Visual Studio 2015. Это значение должно представлять размер массива в байтах, но это не то, что я наблюдаю. Я надеюсь, что кто-то может объяснить, что здесь происходит.
Рассмотрим исходный файл testdata_works.c
char testb[0x10002];
Рассмотрим исходный файл testdata_fails.c:
char testa[0x10001];
char testb[0x10002];
Теперь скомпилируйте:
cl -c testdata_works.c
cl -c testdata_fails.c
Теперь запустите «dumpbin / symbols» для обоих объектных файлов и обратите внимание на то, как
Значение символа «testb» отличается между двумя объектными файлами (!) См. ниже
для кровавых подробностей.
dumpbin /symbols testdata_works.obj
006 00010002 UNDEF notype External | testb
Теперь для testdata_fails.obj
dumpbin /symbols testdata_fails.obj
006 00010001 UNDEF notype External | testa
007 00010041 UNDEF notype External | testb
Заметим, что символ testb имеет ожидаемое значение 0x10002 в
testdata_works.obj, но имеет неожиданное значение 0x10041 в testdata_fails.obj.
Я сохранил действительно странную часть последней, которая может вызвать
Поговорка «а-ха» у тех, кто хорошо разбирается в объектном файле COFF
Формат:
Уменьшите размер массивов в testdata_fails.c ниже
0x10000, например:
char testa[0x0001];
char testb[0x0002];
и скомпилировать
cl -c testdata_fails.c
Команда dumpbin теперь выдает ожидаемые результаты для символов testa и
testb:
006 00000001 UNDEF notype External | testa
007 00000002 UNDEF notype External | testb
Есть ли какие-либо предложения относительно того, что здесь происходит и как это исправить, чтобы получить ожидаемые результаты для значений символов, превышающих 64 КБ?
Заключительные замечания:
Я воспроизвел это, используя clang / llvm-nm 7.0.1 вместо Visual
Studio 2015 / dumpbin, так что может быть связано с форматом COFF?
Вы можете справедливо спросить, как я наткнулся на это. Я изучал BSD
Ядро genassym.sh и решил написать небольшую программу на C ++ STL, которая
достиг той же задачи из любого формата объектного файла, который может быть прочитан библиотеками LLVM. Я построил эту программу, но она не работает должным образом, потому что данные в объектных файлах не соответствуют ожиданиям.