2016-10-09 3 views
1

La communication avec les fonctions du noyau mach se fait à l'aide de messages mach. La bibliothèque système libsystem_kernel.dylib implémente une fonction auxiliaire mach_msg (...) pour envoyer/recevoir des messages mach arbitraires, mais elle contient aussi des méthodes préparées pour utiliser certaines fonctions du noyau comme task_get_special_port (qui ont le même nom de fonction). Cela peut être vu en désassemblant le binaire lib. La source mach_msg peut être trouvée here mais les sources pour les helpers spécifiques à la fonction comme task_get_special_port ne semblent pas apparaître n'importe où dans l'arborescence des sources de libsyscall. Où ces adaptateurs kernelFunction-to-machMsg sont-ils implémentés ou générés?Où les assistants mach_msg pour les fonctions du noyau sont-ils implémentés ou générés?

Où est également le récepteur du message mach implémenté qui traduit entre le message et l'appel de la fonction noyau? (La mise en œuvre réelle du noyau pour task_get_special_port se trouve here)

Répondre

1

Où sont ces adaptateurs kernelFunction-à-machMsg mises en œuvre ou produit?

Ils sont générés par le Mach Interface Generator (MIG). Si vous recherchez dans les sources du noyau des fichiers avec l'extension .defs, vous pouvez voir les définitions utilisées pour la génération par MIG.

A déclaré dans le Apple Docs: Au niveau du piège

, l'interface à la plupart des abstractions Mach se compose des messages envoyés vers et depuis les ports du noyau représentant ces objets. Les interfaces de niveau trap (telles que mach_msg_overwrite_trap) et les formats de messages sont eux-mêmes extraits en utilisation normale par le Mach Interface Generator (MIG). MIG est utilisé pour compiler des interfaces procédurales vers les API basées sur des messages, en fonction des descriptions de ces API.

Pour task_get_special_port, vous pouvez voir le fichier de défauts here.

Si vous appelez mig sur ce fichier, il générera trois fichiers.

  • Un fichier .c pour l'expéditeur (taskUser.c)
  • Un fichier .c pour le récepteur (taskServer.c)
  • Un fichier d'en-tête qui définit le protocole de communication entre l'émetteur et le récepteur (task.h)

En examinant le fichier Server.c, vous pouvez voir cette fonction, avec l'appel direct à task_get_special_port.

mig_internal novalue _Xtask_get_special_port 
     (mach_msg_header_t *InHeadP, mach_msg_header_t *OutHeadP) 
{ 
    ... 

     RetCode = task_get_special_port(In0P->Head.msgh_request_port, In0P->which_port, &OutP->special_port.name); 
     if (RetCode != KERN_SUCCESS) { 
       MIG_RETURN_ERROR(OutP, RetCode); 
     } 

    ... 
} 

L'utilisation mig est beaucoup moins sujette aux erreurs que d'avoir à écrire manuellement les protocoles client et serveur.