Rosetta 2 على Mac مزود بسيليكون Apple
يمكن لأجهزة كمبيوتر Mac المزودة بسيليكون Apple تشغيل التعليمات البرمجية التي يتم تجميعها لمجموعة التعليمات x86_64 باستخدام آلية ترجمة تسمى Rosetta 2. هناك نوعان من الترجمة المعروضة: في الوقت المناسب، وقبل الموعد.
الترجمة في الوقت المناسب
في قناة الترجمة في الوقت المناسب (JIT)، يتم تحديد كائن x86_64 Mach مبكرًا في مسار تنفيذ الصورة. عند مواجهة هذه الصور، ينقل kernel التحكم إلى كعب روتين ترجمة Rosetta خاصة بدلاً من محرر الروابط الديناميكي dyld(1)
. يقوم كعب روتين الترجمة بعد ذلك بترجمة صفحات x86_64 أثناء تنفيذ الصورة. تحدث هذه الترجمة بالكامل داخل العملية. ويظل kernel يتحقق من تجزئات التعليمات البرمجية لكل صفحة x86_64 مقابل توقيع التعليمات البرمجية المرفق بالملف الثنائي كما هو خاطئ. في حالة عدم تطابق التجزئة، يفرض kernel سياسة الإصلاح المناسبة لتلك العملية.
الترجمة قبل الموعد
في مسار الترجمة قبل الموعد (AOT)، تتم قراءة ثنائيات x86_64 من وحدة التخزين في الأوقات التي يراها النظام مثالية للاستجابة بالنسبة لتلك التعليمات البرمجية. تتم كتابة الأعمال المُترجمة إلى وحدة التخزين كنوع خاص من ملف كائنات Mach. ويشبه هذا الملف صورة قابلة للتنفيذ، ولكن يتم تمييزها للإشارة إلى أنها المنتج المُترجَم لصورة أخرى.
في هذا النموذج، تستمد أعمال AOT جميع معلومات الهوية الخاصة بها من صورة x86_64 الأصلية القابلة للتنفيذ. لفرض هذا الارتباط، يقوم كيان ذو امتيازات خاص بمساحة المستخدم بالتوقيع على أعمال الترجمة باستخدام مفتاح خاص بالجهاز تتم إدارته بواسطة Secure Enclave. لا يتم تحرير هذا المفتاح إلا إلى الكيان ذي الامتيازات الخاص بمساحة المستخدم، والذي يتم تعريفه على أنه يستخدم استحقاقات مُقيّدة. يتضمن دليل التعليمات البرمجية الذي تم إنشاؤه لأعمال الترجمة تجزئة دليل التعليمات البرمجية لصورة x86_64 الأصلية القابلة للتنفيذ. يُعرف التوقيع على أعمال الترجمة نفسها باسم التوقيع التكميلي.
تبدأ قناة AOT بشكل مشابه لقناة JIT، حيث تنقل kernel التحكم إلى Rosetta وقت التشغيل بدلاً من محرر الروابط الديناميكية dyld(1)
. ولكن Rosetta وقت التشغيل يُرسل بعد ذلك استعلام التواصل بين العمليات (IPC) إلى خدمة نظام Rosetta، والذي يسأل عما إذا كانت هناك ترجمة AOT متاحة للصورة الحالية القابلة للتنفيذ أم لا. وفي حالة العثور عليها، توفر خدمة Rosetta مؤشرًا لهذه الترجمة، ويتم تعيينها في العملية وتنفيذها. أثناء التنفيذ، يفرض kernel تجزئات دليل التعليمات البرمجية لأعمال الترجمة التي تمت مصادقتها من خلال التوقيع المتجذر في مفتاح التوقيع الخاص بالجهاز. ولا يتم تضمين تجزئات دليل التعليمات البرمجية الخاصة بصورة x86_64 الأصلية في هذه العملية.
يتم تخزين الأعمال المترجمة في مخزن بيانات لا يمكن لأي كيان الوصول إليه في وقت التشغيل باستثناء خدمة Rosetta. وتدير خدمة Rosetta الوصول إلى ذاكرة التخزين المؤقت الخاصة بها عن طريق توزيع واصفات ملفات للقراءة فقط على أعمال الترجمة الفردية؛ وهذا يحد من الوصول إلى ذاكرة التخزين المؤقت لأعمال AOT. يتم عن عمد تضييق نطاق التواصل بين العمليات الخاص بهذه الخدمة وكذلك البصمة التابعة لها بغرض تقليل أجزائها المعرضة للهجوم.
إذا كانت تجزئة دليل التعليمات البرمجية لصورة x86_64 الأصلية لا تتطابق مع نظيرتها المشفرة في توقيع أعمال ترجمة AOT، فإن هذه النتيجة تعتبر مكافئة لتوقيع تعليمات برمجية غير صالح، ويتم اتخاذ إجراء الإنفاذ المناسب.
إذا قامت عملية عن بُعد بالاستعلام عن kernel للاستحقاقات أو خصائص هوية تعليمات برمجية أخرى لملف AOT تنفيذي مُترجَم، يتم إرجاع خصائص الهوية لصورة x86_64 الأصلية إليها.
محتوى ذاكرة التخزين المؤقتة الموثوق بها الثابتة
يأتي macOS 11 أو أحدث مزودًا بثنائيات Mach “fat” تحتوي على شرائح من التعليمات البرمجية للكمبيوتر x86_64 و arm64. على أجهزة كمبيوتر Mac المزودة بسيليكون Apple، قد يقرر المستخدم تنفيذ شريحة x86_64 لملف نظام ثنائي من خلال قناة Rosetta، على سبيل المثال لتحميل مكون إضافي لا يحتوي على متغير arm64 أصلي. ولدعم هذا الأسلوب، تحتوي ذاكرة التخزين المؤقتة الموثوق بها الثابتة التي تأتي مع macOS، بشكل عام، على ثلاث تجزئات دليل تعليمات برمجية لكل ملف من ملفات كائنات Mach:
تجزئة دليل تعليمات برمجية لشريحة arm64
تجزئة دليل تعليمات برمجية لشريحة x86_64
تجزئة دليل تعليمات برمجية لترجمة AOT لشريحة x86_64
يعتبر إجراء ترجمة Rosetta AOT حتميًا إذ يعيد إنتاج مخرجات متطابقة لأي إدخال معين، بغض النظر عن وقت إجراء الترجمة أو نوع الجهاز الذي يتم إجراؤها عليه.
أثناء إنشاء macOS، يتم تشغيل كل ملف من ملفات كائنات Mach من خلال قناة ترجمة Rosetta AOT المرتبطة بإصدار macOS الجاري إنشاؤه، ويتم تسجيل تجزئة دليل التعليمات البرمجية الناتجة في ذاكرة التخزين المؤقتة الموثوق بها. لتحقيق الكفاءة، لا يتم توفير المنتجات المترجمة الفعلية مع نظام التشغيل ويتم إعادة تكوينها عند الطلب عندما يطلبها المستخدم.
عند تنفيذ صورة x86_64 على كمبيوتر Mac مزود بسيليكون Apple، إذا كانت تجزئة دليل التعليمات البرمجية لهذه الصورة موجودة في ذاكرة التخزين المؤقتة الموثوق بها الثابتة، فمن المتوقع أيضًا أن تكون تجزئة دليل التعليمات البرمجية لأعمال AOT الناتجة موجودة في ذاكرة التخزين المؤقتة الموثوق بها الثابتة. ولا يتم توقيع مثل هذه المنتجات بواسطة المفتاح الخاص بالجهاز، لأن سلطة التوقيع تكون متجذرة في سلسلة التمهيد الآمن في Apple.
تعليمات x86_64 البرمجية غير المُوقَّعة
لا تسمح أجهزة كمبيوتر Mac المزودة بسيليكون Apple بتنفيذ تعليمات arm64 البرمجية الأصلية بدون إرفاق توقيع تعليمات برمجية صالح. يمكن أن يكون هذا التوقيع بسيطًا مثل التوقيع الذي يُسمى بتوقيع التعليمات البرمجية "المخصص" (cf. codesign(1)
) الذي لا يحمل أي هوية فعلية من النصف السري لزوج مفاتيح غير متماثل (إنه ببساطة قياس غير مصادق عليه للملف الثنائي).
يُسمح بتنفيذ تعليمات x86_64 البرمجية المترجمة من خلال Rosetta بدون معلومات توقيع، لأسباب تتعلق بتوافق الملف الثنائي. لا يتم نقل أي هوية محددة إلى هذه التعليمات البرمجية من خلال إجراء توقيع Secure Enclave الخاص بالجهاز، ويتم تنفيذه بدقة بالقيود ذاتها التي تنفذها التعليمات البرمجية الأصلية غير المُوقَّعة على أجهزة كمبيوتر Mac المستندة إلى Intel.