/ / Lion 32bit kext не успя да се зареди за чиста виртуална функция, но 64bit работи - usb, osx-lion, 32-bit, kernel-extension

Lion 32bit kext не успя да се зареди за чиста виртуална функция, но 64bit работи - usb, osx-lion, 32-bit, разширение на ядрото

Създавам виртуална USB шина (комуникираща чрез мрежа с Linux кутия) като kext за OSX. Основният клас се извлича от IOUSBControllerV3.

Работи под 10.6 32Bit, 10.7.5 64bit, 10.8 64bit, но не успя да се зареди под 10.7.5 32bit поради (а?) чиста виртуална функция. kextutil ми каза това.

Компилирах (Xcode 4.6) kext под същата система, опитах много вариации коя целева система или версии на SDK, но проблемът все още е налице?

Знам, че има някои #ifdef LP64 разлики в заглавията на. \ t базови класове, особено в контекста на чистите виртуални функции.

Но след два дни на сравняване и сравняване на претоварване на чисти виртуални функции Нямам представа защо само 32bit създава проблеми?

Същият код работи и при другите системи, но Lion 32bit не го прави.

Благодаря предварително за всеки намек,

за разбирането Markus

=========== изход на терминала:

MacProTest:Developer ms$ sudo kextutil -t -v 2   MaCute.kext
Password:
Notice: MaCute.kext has debug properties set.
MaCute.kext appears to be loadable (not including linkage for on-disk libraries).
Loading MaCute.kext.
Reading load info for 13 kexts.
Created mkext for architecture i386 containing 1 kexts.
Loading MaCute.kext.
(kernel) Received request from user space to load kext de.seh.utn.MaCute.
(kernel) Loading kext de.seh.utn.MaCute.
(kernel) Allocated link buffer for kext de.seh.utn.MaCute at 0x1507000 (200704 bytes).
(kernel) kxld[de.seh.utn.MaCute]: This kext calls a pure virtual function. Make sure your kext"s OSObject-derived classes implement all pure virtual functions.
(kernel) Can"t load kext de.seh.utn.MaCute - link failed.
(kernel) Failed to load executable for kext de.seh.utn.MaCute.
(kernel) Kext de.seh.utn.MaCute failed to load (0xdc008016).
(kernel) Failed to load kext de.seh.utn.MaCute (error 0xdc008016).
Failed to load MaCute.kext - (libkern/kext) link error.
Failed to load MaCute.kext - (libkern/kext) link error.
Check library declarations for your kext with kextlibs(8).

Отговори:

1 за отговор № 1

Тъй като не мога да открия очевидни виновници в. \ T IOUSBControllerV3.h в заглавния файл, реших Google да съобщи за грешка в опит да намеря съответния изходен код. Проследих я обратно към функцията check_for_direct_pure_virtual_call() в kxld_reloc.c:

    entry = kxld_vtable_get_entry_for_offset(relocator->current_vtable,
offset, relocator->is_32_bit);
require_action(!entry || !entry->patched.name ||
!kxld_sym_name_is_pure_virtual(entry->patched.name),
finish, rval=KERN_FAILURE;
kxld_log(kKxldLogLinking, kKxldLogErr,
kKxldLogDirectPureVirtualCall));

kKxldLogDirectPureVirtualCall е #defineг като тази грешка.

Ако бях на ваше място, изтеглих xnu източника на пакета за тази версия на osx (1699.32.7) и създадох свой собствен бинарник на ядрото, като използвам инструкциите на този сайт, След това променете горната функция за извеждане entry->patched.name ако условието за твърдение не е успешно, така че поставете това преди require_action() ред:

if (entry && entry->patched.name && kxld_sym_name_is_pure_virtual(entry->patched.name))
printf("pure virtual function called by kext: %sn", entry->patched.name);

След това възстановете и заредете новото ядро. Мисля, че това трябва да отпечата (разваленото) име на функцията в дневника на ядрото. Това е доста усилие, но мисля, че ще ви заведа там!

Update:

От коментарите е ясно, че все още не сме там. На i386, check_for_direct_pure_virtual_call() се нарича от generic_process_reloc(), който ще съобщи за неуспех, ако чистата виртуална проверка не успее:

rval = check_for_direct_pure_virtual_call(relocator, instr_data);
require_noerr(rval, finish);

Няма нищо ужасно полезно за нас в тази функция, но то от своя страна се извиква от две функции: kxld_relocator_process_sect_reloc() и kxld_relocator_process_table_reloc(), Не знам кой се прилага в този случай, но кодът и в двата вида изглежда много сходен, така че можем да ги модифицираме по един и същи начин с изхода за дебаг:

rval = relocator->process_reloc(relocator, instruction, reloc->length,
reloc->pcrel, base_pc, link_pc, link_disp, reloc->reloc_type, target,
pair_target, relocator->swap);
require_noerr(rval, finish);

Искаме да вмъкнем код между тези двеизявления: първият е разговорът за преместване, който се проваля, а вторият - от функцията. Искаме да хванем неуспехи и да генерираме някакъв изход за отстраняване на грешки за тях. Така че, нещо подобно:

rval = relocator->process_reloc(relocator, instruction, reloc->length,
reloc->pcrel, base_pc, link_pc, link_disp, reloc->reloc_type, target,
pair_target, relocator->swap);

if (rval)
{
// try to find the symbol corresponding to this relocation entry
KXLDSym* sym = kxld_reloc_get_symbol(relocator, reloc, NULL);
const char* symname = (sym && sym->name) ? sym->name : "[NULL]";
const char* symalias = (sym && sym->alias) ? sym->alias : "[NULL]";
printf("Relocation failed for relocation %p, symbol %p: name = "%s", alias = "%s"n",
reloc, sym, symname, symalias);
}

require_noerr(rval, finish);

Промяна на двете функции, изграждане на ядрото, зареждане и опит за зареждане на kext. Надявам се, че това ще ви накара да работите с нещо.

Имайте предвид, че не съм тествал горния код, тъй като в момента нямам начин да възпроизвеждам проблема.