配備 Apple 晶片的 Mac 上之 Rosetta 2
配備 Apple 晶片的 Mac 可執行使用 Rosetta 2 轉譯機制來針對 x86_64 指令集編譯的程式碼。提供兩種類型的轉譯:即時和提前。
即時轉譯
即時(JIT)轉譯流程中,系統會在映像執行路徑早期階段識別 x86_64 Mach 物件。遇到這些映像時,核心會將控制權轉移給特殊的 Rosetta 轉譯虛設常式,而非動態連結編輯器 dyld(1)
。接着這個轉譯虛設常式會在映像執行期間轉譯 x86_64 頁面。這項轉譯作業完全在程序中進行。核心仍會根據頁面發生錯誤時附加至二進位檔的程式碼簽署,驗證每個 x86_64 頁面的程式碼雜湊值。如雜湊值不相符,核心就會強制執行適用於該程序的修復規則。
提前轉譯
如採用提前(AOT)轉譯路徑,系統認為該程式碼的回應能力最佳時,就會從儲存體讀取 x86_64 二進位檔。轉譯完的成品會作為特殊類型的 Mach 物件檔案寫入儲存體中。該檔案類似可執行的映像,但是系統會將其標記以指出它是轉譯另一個映像所產生的成品。
在這個模式中,AOT 成品會從原始的 x86_64 可執行映像衍生出所有識別資料。為了強制這種綁定關係,有特殊權限的用户空間實體會使用裝置專屬的密鑰(受到「安全隔離區」管理)來簽署轉譯成品。這個密鑰只會發佈給有特殊權限的用户空間實體,而系統會利用受限制的權限來識別這個實體。為了轉譯成品製作的程式碼目錄中,包含原始 x86_64 可執行映像的程式碼目錄雜湊值。轉譯成品本身上的簽署也稱為補充簽署。
AOT 流程的開始方式類似 JIT 流程,核心會將控制權轉移給 Rosetta 執行階段,而非動態連結編輯器 dyld(1)
。但是接着 Rosetta 執行階段會傳送程序間通訊(IPC)查詢給 Rosetta 系統服務,詢問目前的可執行映像是否有可用的 AOT 轉譯。如果有找到,Rosetta 服務會提供一個控制代碼給該轉譯,再對映到程序中並執行。執行期間,核心會強制執行轉譯成品(藉由根植在裝置專屬簽署密鑰中的簽署進行認證)的程式碼目錄雜湊值。這項程序與原始 x86_64 映像的程式碼目錄雜湊值無關。
轉譯後的成品會儲存在 Data Vault 中;除了 Rosetta 服務以外,任何實體都不能在執行階段存取 Data Vault。Rosetta 服務藉由分發唯讀檔案描述元給個別轉譯成品;這樣可限制存取 AOT 成品快取。這個服務的程序間通訊和從屬的磁碟使用量會刻意維持在極小的範圍內,藉此限制其攻擊面。
如果原始 x86_64 映像的程式碼目錄雜湊值不符合編碼為 AOT 轉譯成品的簽署,系統就會將此結果視為等同於無效的程式碼簽署,並採取適當的強制措施。
如果遙距程序向核心查詢 AOT 轉譯可執行檔的權限或其他程式碼識別屬性,則會傳回原始 x86_64 映像的識別屬性。
靜態信任快取內容
macOS 11 或較新版本隨附 Mach「厚實」二進位檔,其中包含 x86_64 和 arm64 電腦程式碼的配量。在配備 Apple 晶片的 Mac 上,用户可選擇透過 Rosetta 流程執行系統二進位檔的 x86_64 配量,例如需載入不含原生 arm64 變體的外掛模組。為支援此作法,macOS 隨附的靜態信任快取通常包含每個 Mach 物件檔案的三個程式碼目錄雜湊值。
arm64 配量的程式碼目錄雜湊值
x86_64 配量的程式碼目錄雜湊值
x86_64 配量之 AOT 轉譯的程式碼目錄雜湊值
Rosetta AOT 轉譯程序具確定性,因為它會為任何提供的輸入重製相同的輸出,無論轉譯何時執行或是在哪個裝置上執行結果都一樣。
建立 macOS 期間,每個 Mach 物件檔案都會經歷與建立中的 macOS 版本相關聯的 Rosetta AOT 轉譯流程,藉此將程式碼目錄雜湊值記錄在信任快取中。為求效率,實際的轉譯產品不會隨作業系統提供,且會在用户提出要求時隨需要重新建構。
當 x86_64 映像在配備 Apple 晶片的 Mac 上執行時,如果該映像的程式碼目錄雜湊值位於靜態信任快取中,所產生 AOT 成品的程式碼目錄雜湊值也預期會存在於靜態信任快取中。這類產品沒有經過裝置專屬密鑰簽署,因為簽署管理中心根植在 Apple 安全啟動鏈中。
未簽署的 x86_64 程式碼
配備 Apple 晶片的 Mac 不允許原生 arm64 程式碼在沒有附加有效簽署的情況下執行。這個簽署可以像「臨機操作」程式碼簽署(cf. codesign(1)
)一樣簡單,不包含來自非對稱式密鑰配對秘密部份的任何實際的識別資料(只是二進位檔的未認證測量值)。
為求二進位檔相容性,系統允許轉譯的 x86_64 程式碼在沒有簽署的情況下透過 Rosetta 執行。不會有任何識別資料透過裝置專用的「安全隔離區」簽署程序傳達到這個程式碼中,且其執行限制與在以 Intel 為基礎的 Mac 上執行的原生未簽署程式碼完全一致。