/ / Lion 32 bit kext non è riuscito a caricare per pura funzione virtuale ma funziona a 64 bit - usb, osx-lion, 32-bit, estensione kernel

Lion 32bit kext non è riuscito a caricare per pura funzione virtuale ma funziona a 64 bit - usb, osx-lion, 32-bit, estensione kernel

Costruisco un bus USB virtuale (che comunica via rete con una macchina Linux) come kext per OSX. La classe principale è derivata da un IOUSBControllerV3.

Funziona con meno di 10.6 32 bit, 10.7.5 64 bit, 10.8 64 bit, ma non è riuscito a caricare sotto 10.7.5 32 bit a causa della (a?) pura funzione virtuale. me lo ha detto kextutil.

Ho compilato (Xcode 4.6) il kext sotto lo stesso sistema, ho provato molte varianti quale sistema di destinazione o versioni di SDK, ma il problema è ancora residente?

So che ci sono alcuni #ifdef LP64 differenze nelle intestazioni del classi base, specialmente nel contesto delle pure funzioni virtuali.

Ma dopo due giorni di confronto e confronto tra i sovraccarichi del funzioni virtuali pure non ho idea del perché solo 32 bit crei problemi?

Lo stesso codice funziona con gli altri sistemi, ma Lion 32bit no.

Molte grazie in anticipo per ogni suggerimento

Saluti Markus

=========== output del terminale:

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).

risposte:

1 per risposta № 1

Dal momento che non riesco a trovare colpevoli evidenti nel IOUSBControllerV3.h File di intestazione, ho deciso di Google per il messaggio di errore nel tentativo di trovare il codice sorgente pertinente. L'ho ricondotto alla funzione check_for_direct_pure_virtual_call() in 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 è #defined come quell'errore.

Se fossi in te, avrei scaricato il pacchetto sorgente di xnu per quella versione osx (1699.32.7) e creato il tuo binario del kernel, usando le istruzioni su questo sito. Quindi, modificare la funzione sopra per l'output entry->patched.name se la condizione di asserzione fallisce, quindi inseriscila prima del require_action() linea:

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);

Quindi ricostruire e avviare il nuovo kernel. Penso che questo dovrebbe stampare il nome (deformato) della funzione nel log del kernel. È un bel po 'di sforzo, ma penso che ti porteremo lì!

Aggiornare:

Dai commenti è chiaro che non siamo ancora arrivati. Sulla i386, check_for_direct_pure_virtual_call() viene chiamato da generic_process_reloc(), che segnalerà un errore se il controllo virtuale puro fallisce:

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

Non c'è nulla di estremamente utile per noi in questa funzione, ma a sua volta è chiamato da 2 funzioni: kxld_relocator_process_sect_reloc() e kxld_relocator_process_table_reloc(). Non so quale si applica in questo caso, ma il codice in entrambi gli aspetti è molto simile, quindi possiamo modificarli entrambi allo stesso modo con l'output di debug:

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);

Vogliamo inserire il codice tra questi dueaffermazioni: la prima è la chiamata di riposizionamento che non riesce, il secondo balla fuori dalla funzione. Vogliamo catturare i guasti e generare un output di debug per loro. Quindi, qualcosa del genere:

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);

Modifica entrambe le funzioni, crea un kernel, avvialo e prova a caricare il tuo kext. Spero che questo ti porterà qualcosa su cui lavorare. Facci sapere come vai avanti!

Nota che non ho testato il codice sopra perché attualmente non ho modo di riprodurre il problema.