Как я могу сказать с чем-то как objdump, если объектный файл был создан с-fPIC?

Двоичный файл плавающая точка математика похож на это. На большинстве языков программирования это основано стандарт IEEE 754 . JavaScript использует 64-разрядное представление с плавающей точкой, которое совпадает с Java double. Затруднение проблемы - то, что числа представлены в этом формате в целом времена числа питание два; рациональные числа (такой как 0.1, который является 1/10), чей знаменатель не является питанием два, не могут быть точно представлены.

Для 0.1 в стандарте binary64 формат, представление может быть записано точно как [1 138]

  • 0.1000000000000000055511151231257827021181583404541015625 в десятичном числе, или
  • 0x1.999999999999ap-4 в [1 127] нотация .

C99 hexfloat Напротив, рациональное число 0.1, которое является 1/10, может быть записано точно как [1 139]

  • 0.1 в десятичном числе, или
  • 0x1.99999999999999...p-4 в аналоге нотации C99 hexfloat, где эти ... представляет бесконечную последовательность 9's.

константы 0.2 и 0.3 в Вашей программе также будут приближениями к своим истинным значениям. Это происходит, что самое близкое double к [1 115] больше, чем рациональное число 0.2, но что самое близкое double к [1 118] меньше, чем рациональное число 0.3. Сумма [1 120] и 0.2 завершает то, чтобы быть больше, чем рациональное число 0.3 и следовательно не соглашающийся с константой в Вашем коде.

А довольно всесторонняя обработка арифметических проблем с плавающей точкой , Что Каждый Программист Должен Знать Об Арифметике С плавающей точкой . Для более легкого к обзору объяснения см. floating-point-gui.de .

Примечание Стороны: Все позиционные (основные-N) системы счисления совместно используют эту проблему с точностью

Простое десятичное число (базируйтесь 10), числа имеют те же проблемы, который является, почему числа как 1/3 заканчиваются как 0,333333333...

Вы только что наткнулись на номер (3/10), который, оказывается, легко представить с десятичной системой счисления, но не соответствует двоичной системе счисления. Это идет обоими путями (до некоторого маленького градуса) также: 1/16 является ужасным числом в десятичном числе (0.0625), но в двоичном файле это выглядит столь же аккуратным, как 10,000-е делает в десятичном числе (0.0001) ** - если бы мы имели привычку использовать основу 2 системы счисления в наших повседневных жизнях, то Вы даже посмотрели бы на то число и инстинктивно поняли бы, что могли прибыть туда путем сокращения вдвое чего-то, сокращения вдвое его снова, и снова и снова.

**, Конечно, это не точно, как числа с плавающей запятой хранятся в памяти (они используют форму экспоненциального представления). Однако это действительно иллюстрирует тезис, что двоичные ошибки точности с плавающей точкой имеют тенденцию неожиданно возникать, потому что числа "реального мира", с которыми мы обычно интересуемся работой, так часто полномочия десять - но только потому, что мы используем ежедневную десятичную систему счисления. Это также, почему мы скажем вещи как 71% вместо "5 из каждых 7" (71% приближение, так как 5/7 не может быть представлен точно ни с каким десятичным числом).

Так нет: двоичные числа с плавающей точкой не повреждаются, они просто, оказывается, так же несовершенны как любая основная-N система счисления:)

Примечание Стороны Стороны: Работая с Плаваниями в Программировании

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

также необходимо заменить тесты равенства сравнениями, которые позволяют некоторый объем допуска, что означает:

Делают не , делают if (float1 == float2) { ... }

, Вместо этого делают if (Math.Abs(float1 - float2) < myToleranceValue) { ... }.

myToleranceValue должен быть выбран для Вашего конкретного приложения - и это будет иметь много, чтобы сделать с тем, сколько "пространства для маневра" Вы готовы позволить, и что наибольшее число Вы собираетесь быть сравнением, может быть (из-за потери проблем точности). Остерегайтесь "дважды. Эпсилон" константы стиля на Вашем предпочтительном языке (Число. ЭПСИЛОН в JavaScript). Это не , чтобы использоваться в качестве значений допуска.

53
задан ks1322 27 January 2013 в 04:29
поделиться

3 ответа

Ответ зависит от платформы. На большинстве платформ, если вывод из

readelf --relocs foo.o | egrep '(GOT|PLT|JU?MP_SLOT)'

пуст, то либо foo.o не был скомпилирован с -fPIC , либо foo.o не скомпилирован содержать любой код, имеющий значение -fPIC .

61
ответ дан 7 November 2019 в 08:46
поделиться

Мне просто нужно было сделать это на целевом компьютере PowerPC, чтобы определить, какой общий объект (.so) создавался без -fPIC. Я запустил readelf -d libMyLib1.so и поискал TEXTREL. Если вы видите TEXTREL, один или несколько исходных файлов, составляющих ваш .so, не были созданы с использованием -fPIC. Вы можете заменить readelf на elfdump , если необходимо.

Например,

[user@host lib]$ readelf -d libMyLib1.so | grep TEXT   # Bad, not -fPIC
 0x00000016 (TEXTREL)
[user@host lib]$ readelf -d libMyLib2.so | grep TEXT   # Good, -fPIC
[user@host lib]$

И чтобы помочь людям искать решения, я получал следующую ошибку при запуске исполняемого файла:

root@target:/# ./program: error while loading shared libraries: /usr/lib/libMyLi
b1.so:  R_PPC_REL24 relocation at 0x0fc5987c for symbol 'memcpy' out of range

Я не знаю, применима ли эта информация ко всем архитектурам.

Источник: blogs.oracle.com/rie

13
ответ дан 7 November 2019 в 08:46
поделиться

Другой вариант, позволяющий определить, создается ли ваша программа с параметром -fPIC:

при условии, что в вашем коде включена опция -g3 -gdwarf-2 при компиляции.

другой формат отладки gcc также может содержать информацию о макросе:

Обратите внимание, что следующий синтаксис $ '..' предполагает, что bash

echo $' main() { printf("%d\\n", \n#ifdef __PIC__\n__PIC__\n#else\n0\n#endif\n); }' | gcc -fPIC -g3 
-gdwarf-2 -o test -x c -

readelf --debug-dump=macro ./test | grep __PIC__

такой метод работает, потому что руководство gcc объявляет, что если используется -fpic, PIC определяется как 1, а если используется -fPIC, PIC равно 2.

Приведенные выше ответы с проверкой GOT - лучший способ. Поскольку предварительный запрос -g3 -gdwarf-2, я думаю, используется редко.

0
ответ дан 7 November 2019 в 08:46
поделиться
Другие вопросы по тегам:

Похожие вопросы: