Связывание проблем при создании библиотеки для iOS 7
При создании библиотеки для iOS 7 на iPhone возникает проблема со связыванием (ARM64).
Сообщение об ошибке:
ld: in /long_path/libHEVCCodec.a(inv_xforms_arm64.o), in section TEXT,text reloc 0:
ARM64_RELOC_SUBTRACTOR must have r_length of 2 or 3 for architecture arm64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
Эта ошибка появляется в результате этого кода (это своего рода переключатель):
adr addr, .L.dct_add_switch
ldrh offset, [addr, ta, lsl #1]
add addr, addr, offset, uxth
br addr
.L.dct_add_switch:
.hword .L.dct_add_4 - .L.dct_add_switch
.hword .L.dst_add_4 - .L.dct_add_switch
...
ta
, addr
, offset
общие регистры x3
, x4
, w5
соответственно.
Кто-нибудь знает, как справиться с этой ситуацией?
PS: с GNU GCC & Android проблем нет.
EDIT1: кажется, что проблема не в самом компоновщике, а в компиляторе. Я проверил объектный файл (objdump) и вместо констант разницы просто нули.
.L.dct_add_switch:
0000000000000010 .long 0x00000000
0000000000000014 .long 0x00000000
0000000000000018 .long 0x00000000
000000000000001c nop
Когда я помещаю вычисленные вручную константы вместо выражений ".L.dct_add_4 - .L.dct_add_switch" и т. Д., Все идет хорошо.
Может быть, есть какие-то ключи компилятора, которые заставят компилятор делать это правильно?
Благодарю.
2 ответа
Ну, есть проблема компилятора и компоновщика, и это зависит от размера данных, которые используются для смещений. Clang не очень дружелюбен ко всему, что отличается от 4 байтов.
Обсуждение и возможные решения в другой теме: создание таблицы постоянных переходов; Xcode; лязг; как м
Проблема в том, что формат объектного файла Mach-O для 64-разрядных целей ARM не поддерживает перемещение 16-разрядной разницы между двумя символами. Похоже, что разница должна быть 32-битной или 64-битной. Похоже, это не проблема с компилятором или компоновщиком. Код сборки, который вы цитировали в своем вопросе, выглядит как сборка, созданная вручную, а не как вывод компилятора.
Решением было бы переписать сборку, чтобы использовать 32-разрядные значения разности. Что-то вроде этого:
adr addr, .L.dct_add_switch
ldr offset, [addr, ta, lsl #2]
add addr, addr, offset, uxtw
br addr
.L.dct_add_switch:
.word .L.dct_add_4 - .L.dct_add_switch
.word .L.dst_add_4 - .L.dct_add_switch